From f7f37ef623b4d66cd13b0414f0a6a6117c7763c2 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Tue, 9 Jun 2026 23:21:49 +0300 Subject: [PATCH 01/11] Update Vectorized STL algorithm documentation to reflect the current stae (#5937) Since the last update: * ARM64 and ARM64EC vectorization was added. Mention of x64 and x86 is removed, as vectorization is now supported on any target, except deprecated `/clr:pure` and `/clr:safe` modes. * `includes` is now manually vectorized too * `replace_copy` is now manually vectorized too Also moved `find_end` to `search` / `search_n` group, where it fits better. --- docs/standard-library/vectorized-stl-algorithms.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/standard-library/vectorized-stl-algorithms.md b/docs/standard-library/vectorized-stl-algorithms.md index 13cad087a01..1291e5ab6c1 100644 --- a/docs/standard-library/vectorized-stl-algorithms.md +++ b/docs/standard-library/vectorized-stl-algorithms.md @@ -24,7 +24,7 @@ Algorithms like `transform`, `reduce`, and `accumulate` benefit heavily from aut ## Manual vectorization in the MSVC STL -Certain algorithms for x64 and x86 include manual vectorization. This implementation is separately compiled and relies on runtime CPU dispatch, so it applies only to suitable CPUs. +Certain algorithms include manual vectorization. This implementation is separately compiled and relies on runtime CPU dispatch, so it applies only to suitable CPUs. Manually vectorized algorithms use template metaprogramming to detect if the element type is suitable for vectorization. As a result, they're only vectorized for simple types such as standard integer types. @@ -35,17 +35,18 @@ Assign the same value to `_USE_STD_VECTOR_ALGORITHMS` for all linked translation The `_USE_STD_VECTOR_ALGORITHMS` macro controls the behavior of these manually vectorized algorithms: - `contains`, `contains_subrange` - - `find`, `find_last`, `find_end`, `find_first_of`, `adjacent_find` + - `find`, `find_last`, `find_first_of`, `adjacent_find` - `count` - `mismatch` - - `search`, `search_n` + - `search`, `search_n`, `find_end` - `swap_ranges` - - `replace` + - `replace`, `replace_copy` - `remove`, `remove_copy` - `unique`, `unique_copy` - `reverse`, `reverse_copy` - `rotate` - `is_sorted`, `is_sorted_until` + - `includes` - `lexicographical_compare`, `lexicographical_compare_three_way` - `max`, `min`, `minmax` - `max_element`, `min_element`, `minmax_element` From 7dc1ad36a325fe8579a8974a18f34c0fceac14cb Mon Sep 17 00:00:00 2001 From: veganaiZe <7102064+veganaiZe@users.noreply.github.com> Date: Mon, 15 Jun 2026 07:24:28 -0700 Subject: [PATCH 02/11] Update header-files-cpp.md (#5938) Clarify intent of section --- docs/cpp/header-files-cpp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cpp/header-files-cpp.md b/docs/cpp/header-files-cpp.md index b0460d00fd4..72fe57771e4 100644 --- a/docs/cpp/header-files-cpp.md +++ b/docs/cpp/header-files-cpp.md @@ -94,7 +94,7 @@ namespace N #endif /* MY_CLASS_H */ ``` -## What to put in a header file +## What to avoid in a header file Because a header file might potentially be included by multiple files, it cannot contain definitions that might produce multiple definitions of the same name. The following are not allowed, or are considered very bad practice: From fbd0d29b812a5cfabbb508a77d663b7238126fe6 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Tue, 7 Jul 2026 07:15:33 -0700 Subject: [PATCH 03/11] Update documentation on accessing System.String characters (#5940) * Update documentation on accessing System.String characters Added important note about treating interior pointers as const and linked to unsafe code best practices. * Update docs/dotnet/how-to-access-characters-in-a-system-string.md Co-authored-by: Jan Kotas * Apply suggestions from code review Co-authored-by: Aaron R Robinson * Apply suggestions from code review Co-authored-by: Aaron R Robinson --------- Co-authored-by: Jan Kotas --- docs/dotnet/how-to-access-characters-in-a-system-string.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/dotnet/how-to-access-characters-in-a-system-string.md b/docs/dotnet/how-to-access-characters-in-a-system-string.md index c16e9e87202..5f84ef0092e 100644 --- a/docs/dotnet/how-to-access-characters-in-a-system-string.md +++ b/docs/dotnet/how-to-access-characters-in-a-system-string.md @@ -9,6 +9,10 @@ helpviewer_keywords: ["characters [C++], accessing in System::String", "examples You can access characters of a object for high-performance calls to unmanaged functions that take `wchar_t*` strings. The method yields an interior pointer to the first character of the object. This pointer can be manipulated directly or pinned and passed to a function expecting an ordinary **`wchar_t`** string. +> [!IMPORTANT] +> Interior pointers into objects must be treated as `const`. A object is considered immutable and changing its content can destabilize the runtime. +> For more information see [Unsafe code best practices - 17. String mutations](/dotnet/standard/unsafe-code/best-practices). + ## Examples `PtrToStringChars` returns a , which is an interior pointer (also known as a `byref`). As such, it is subject to garbage collection. You don't have to pin this pointer unless you're going to pass it to a native function. From 51001e61b1851e888cc4bd28ee593a99bd0d135c Mon Sep 17 00:00:00 2001 From: Eric Brumer Date: Tue, 28 Jul 2026 07:11:42 -0700 Subject: [PATCH 04/11] Clarify version prefix for Visual Studio Command Prompt (#5946) Updated instructions for starting Visual Studio Command Prompt to reflect changes in version specification. --- docs/overview/acquire-msvc.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/overview/acquire-msvc.md b/docs/overview/acquire-msvc.md index cbd86ef4549..b70d02b277e 100644 --- a/docs/overview/acquire-msvc.md +++ b/docs/overview/acquire-msvc.md @@ -184,10 +184,10 @@ cmake -G "Visual Studio 18 2026" -T "version=14.52" ..\ Some build systems need the command prompt to have the `PATH`, `LIB`, `INCLUDE`, and related environment variables set before you run them. -To start a Visual Studio Command Prompt that targets a supported Build Tools version, add `-vcvars_ver=` where `` matches the folder name under `\VC\Tools\MSVC\`. +To start a Visual Studio Command Prompt that targets a supported Build Tools version, add `-vcvars_ver=` where `` matches the prefix of a folder name under `\VC\Tools\MSVC\`. ```cmd -\VC\Auxiliary\Build\vcvars64.bat -vcvars_ver=14.50.35717 +\VC\Auxiliary\Build\vcvars64.bat -vcvars_ver=14.50 ``` To start a Visual Studio Command Prompt targeting the MSVC preview tools, use `-vcvars_ver=preview`: From 15ff2437d704b823f4bbed90d9fb9ab9f26fc347 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Knobloch?= <67308900+vitknobloch@users.noreply.github.com> Date: Wed, 19 Aug 2026 16:30:00 +0200 Subject: [PATCH 05/11] Add new ARM64 feature arguments to documentation (#5950) Add new extensions `cssc` and `faminmax` to the `/feature` flag arguments documentation --- docs/build/reference/feature-arm64.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/build/reference/feature-arm64.md b/docs/build/reference/feature-arm64.md index 2954b4fed11..63869f6bbc4 100644 --- a/docs/build/reference/feature-arm64.md +++ b/docs/build/reference/feature-arm64.md @@ -16,6 +16,8 @@ To enable one or more features the targeted ARM64 extension supports, specify on | Feature argument | Feature identifier | Optional from | Enabled by default | Description | Supported in version |--|--|--|--|--|--| +|**`cssc`** | `FEAT_CSSC` | Armv8.7 | Armv8.9 | Common Short Sequence Compression instructions. | Visual Studio 2026 18.10 (14.52) +|**`faminmax`** | `FEAT_FAMINMAX` | Armv9.2 | Armv9.5 | Floating-point maximum and minimum absolute value instructions. | Visual Studio 2026 18.10 (14.52) |**`lse`** | `FEAT_LSE` | Armv8.0 | Armv8.1 | Large System Extensions. | Visual Studio 2022 17.10 |**`rcpc`** | `FEAT_LRCPC` | Armv8.2 | Armv8.3 | Load-Acquire RCpc instructions. | Visual Studio 2022 17.10 |**`rcpc2`** | `FEAT_LRCPC2` | Armv8.2 | Armv8.4 | Load-Acquire RCpc instructions v2. | Visual Studio 2022 17.11 From 58ed50da5659b1fb5fb01f9701db8e86e89ee798 Mon Sep 17 00:00:00 2001 From: Jay Satiro Date: Wed, 19 Aug 2026 10:39:46 -0400 Subject: [PATCH 06/11] atexit: Clarify DLL behavior is the same as _onexit (#5952) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * atexit: Clarify DLL behavior is the same as _onexit - Document that atexit called from within a DLL will register the routine to run when the DLL is unloaded. atexit is a wrapper around _onexit which already documents this behavior. Ref: https://github.com/curl/curl/pull/22383#discussion_r3753438017 Reported-by: Michał Petryka Closes #xxxx * Revise atexit documentation for accuracy Update the date and clarify DLL behavior for atexit. --------- Co-authored-by: Tyler Whitney --- docs/c-runtime-library/reference/atexit.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/c-runtime-library/reference/atexit.md b/docs/c-runtime-library/reference/atexit.md index 1264498d49f..f3fa82b4a7d 100644 --- a/docs/c-runtime-library/reference/atexit.md +++ b/docs/c-runtime-library/reference/atexit.md @@ -1,7 +1,7 @@ --- description: "Learn more about: atexit" title: "atexit" -ms.date: "11/04/2016" +ms.date: "8/18/2026" api_name: ["atexit"] api_location: ["msvcrt.dll", "msvcr80.dll", "msvcr90.dll", "msvcr100.dll", "msvcr100_clr0400.dll", "msvcr110.dll", "msvcr110_clr0400.dll", "msvcr120.dll", "msvcr120_clr0400.dll", "ucrtbase.dll"] api_type: ["DLLExport"] @@ -36,6 +36,8 @@ The **`atexit`** function is passed the address of a function *`func`* to be cal The code in the **`atexit`** function shouldn't contain any dependency on any DLL that could have already been unloaded when the **`atexit`** function is called. +**Microsoft-specific DLL behavior**: When a DLL unloads, after `DLLMain` receives `DLL_PROCESS_DETACH`, the DLL's `atexit` callbacks run in reverse registration order, with the last callback registered running first. + To generate an ANSI-conformant application, use the ANSI-standard **`atexit`** function (rather than the similar **`_onexit`** function). ## Requirements From f0c81b71ff4a4ba61e5c02fa60255278d93913c8 Mon Sep 17 00:00:00 2001 From: "learn-build-service-prod[bot]" <113403604+learn-build-service-prod[bot]@users.noreply.github.com> Date: Mon, 24 Aug 2026 16:28:09 -0700 Subject: [PATCH 07/11] Resolve syncing conflicts from FromPrivateLiveToMaster to main (#5953) --- docs/build/reference/arch-x64.md | 14 +-- docs/build/reference/feature-arm64.md | 4 +- ...creating-and-using-a-static-library-cpp.md | 104 +++++++++--------- docs/c-runtime-library/reference/atexit.md | 14 +-- docs/cpp/function-call-cpp.md | 3 +- docs/cpp/static-function-call-operator.md | 88 +++++++++++++++ docs/cpp/static-subscript-operator.md | 70 ++++++++++++ docs/cpp/subscripting.md | 5 +- docs/cpp/toc.yml | 4 + docs/overview/acquire-msvc.md | 19 +++- docs/sanitizers/asan-known-issues.md | 15 ++- 11 files changed, 270 insertions(+), 70 deletions(-) create mode 100644 docs/cpp/static-function-call-operator.md create mode 100644 docs/cpp/static-subscript-operator.md diff --git a/docs/build/reference/arch-x64.md b/docs/build/reference/arch-x64.md index da9e57733f8..f75dd9acbee 100644 --- a/docs/build/reference/arch-x64.md +++ b/docs/build/reference/arch-x64.md @@ -16,25 +16,25 @@ Specifies the architecture for code generation on x64. These switches apply to t ## Arguments **`/arch:SSE2`**\ -Enables Intel Streaming SIMD Extensions 2. The default instruction set is SSE2 if no **`/arch`** option is specified. +Enables x64 Streaming SIMD Extensions 2. If you don't specify a **`/arch`** option, the default instruction set is SSE2. **`/arch:SSE4.2`**\ -Enables Intel Streaming SIMD Extensions 4.2. +Enables x64 Streaming SIMD Extensions 4.2. **`/arch:AVX`**\ -Enables Intel Advanced Vector Extensions. +Enables x64 Advanced Vector Extensions. **`/arch:AVX2`**\ -Enables Intel Advanced Vector Extensions 2. +Enables x64 Advanced Vector Extensions 2. **`/arch:AVX512`**\ -Enables Intel Advanced Vector Extensions 512. +Enables x64 Advanced Vector Extensions 512. **`/arch:AVX10.1`**\ -Enables Intel Advanced Vector Extensions 10 version 1. +Enables x64 Advanced Vector Extensions 10 version 1. **`/arch:AVX10.2`**\ -Enables Intel Advanced Vector Extensions 10 version 2. +Enables x64 Advanced Vector Extensions 10 version 2. ## Remarks diff --git a/docs/build/reference/feature-arm64.md b/docs/build/reference/feature-arm64.md index 63869f6bbc4..b4a81178d93 100644 --- a/docs/build/reference/feature-arm64.md +++ b/docs/build/reference/feature-arm64.md @@ -16,8 +16,8 @@ To enable one or more features the targeted ARM64 extension supports, specify on | Feature argument | Feature identifier | Optional from | Enabled by default | Description | Supported in version |--|--|--|--|--|--| -|**`cssc`** | `FEAT_CSSC` | Armv8.7 | Armv8.9 | Common Short Sequence Compression instructions. | Visual Studio 2026 18.10 (14.52) -|**`faminmax`** | `FEAT_FAMINMAX` | Armv9.2 | Armv9.5 | Floating-point maximum and minimum absolute value instructions. | Visual Studio 2026 18.10 (14.52) +|**`cssc`** | `FEAT_CSSC` | Armv8.7 | Armv8.9 | Common Short Sequence Compression instructions. | Visual Studio 2026 18.10 (MSVC 14.52) +|**`faminmax`** | `FEAT_FAMINMAX` | Armv9.2 | Armv9.5 | Floating-point maximum and minimum absolute value instructions. | Visual Studio 2026 18.10 (MSVC 14.52) |**`lse`** | `FEAT_LSE` | Armv8.0 | Armv8.1 | Large System Extensions. | Visual Studio 2022 17.10 |**`rcpc`** | `FEAT_LRCPC` | Armv8.2 | Armv8.3 | Load-Acquire RCpc instructions. | Visual Studio 2022 17.10 |**`rcpc2`** | `FEAT_LRCPC2` | Armv8.2 | Armv8.4 | Load-Acquire RCpc instructions v2. | Visual Studio 2022 17.11 diff --git a/docs/build/walkthrough-creating-and-using-a-static-library-cpp.md b/docs/build/walkthrough-creating-and-using-a-static-library-cpp.md index 6ca15699093..80c6daafcfe 100644 --- a/docs/build/walkthrough-creating-and-using-a-static-library-cpp.md +++ b/docs/build/walkthrough-creating-and-using-a-static-library-cpp.md @@ -1,14 +1,15 @@ --- title: "Walkthrough: Create and use a static library (C++)" -description: "Use C++ to create a static library (.lib) in Visual Studio." +description: Learn to create and use a static library in C++ using Visual Studio. This walkthrough covers building a .lib file, adding a class, and referencing it in an app. ms.custom: "get-started-article" -ms.date: 10/28/2021 +ms.date: 07/14/2026 helpviewer_keywords: ["libraries [C++], static", "static libraries [C++]"] ms.assetid: 3cc36411-7d66-4240-851e-dacb9a8fd6ac +#customer intent: As a C++ developer, I want to create a static library in Visual Studio, so that I can reuse common code across multiple apps. --- # Walkthrough: Create and use a static library -This step-by-step walkthrough shows how to create a static library (.lib file) for use with C++ apps. Using a static library is a great way to reuse code. Rather than reimplementing the same routines in every app that requires the functionality, you write them one time in a static library and then reference it from the apps. Code linked from a static library becomes part of your app—you don't have to install another file to use the code. +This step-by-step walkthrough shows how to create a static library (.lib file) for use with C++ apps. Using a static library is a great way to reuse code. Rather than reimplementing the same routines in every app that requires the functionality, write them one time in a static library and then reference it from the apps. Code linked from a static library becomes part of your app. You don't have to install another file to use the code. This walkthrough covers these tasks: @@ -32,19 +33,19 @@ The instructions for how to create the project vary depending on your version of ::: moniker range=">=msvc-160" -### To create a static library project in Visual Studio +To create a static library project in Visual Studio: -1. On the menu bar, choose **File** > **New** > **Project** to open the **Create a New Project** dialog. +1. On the menu bar, choose **File** > **New** > **Project** to open the **Create a new project** dialog. 1. At the top of the dialog, set **Language** to **C++**, set **Platform** to **Windows**, and set **Project type** to **Library**. -1. From the filtered list of project types, select **Windows Desktop Wizard**, then choose **Next**. +1. From the filtered list of project types, select **Windows Desktop Wizard**, and then choose **Next**. 1. In the **Configure your new project** page, enter *MathLibrary* in the **Project name** box to specify a name for the project. Enter *StaticMath* in the **Solution name** box. Choose the **Create** button to open the **Windows Desktop Project** dialog. 1. In the **Windows Desktop Project** dialog, under **Application type**, select **Static Library (.lib)**. -1. Under **Additional options**, uncheck the **Precompiled header** check box if it's checked. Check the **Empty project** box. +1. Under **Additional options**, clear the **Precompiled header** check box if it's selected. Select **Empty project**. 1. Choose **OK** to create the project. @@ -52,17 +53,17 @@ The instructions for how to create the project vary depending on your version of ::: moniker range="msvc-150" -### To create a static library project in Visual Studio 2017 +To create a static library project in Visual Studio 2017: 1. On the menu bar, choose **File** > **New** > **Project**. -1. In the **New Project** dialog box, select **Installed** > **Visual C++** > **Windows Desktop**. In the center pane, select **Windows Desktop Wizard**. +1. In the **New Project** dialog, select **Installed** > **Visual C++** > **Windows Desktop**. In the center pane, select **Windows Desktop Wizard**. -1. Specify a name for the project—for example, *MathLibrary*—in the **Name** box. Specify a name for the solution—for example, *StaticMath*—in the **Solution Name** box. Choose the **OK** button. +1. Specify a name for the project, such as *MathLibrary*, in the **Name** box. Specify a name for the solution, such as *StaticMath*, in the **Solution Name** box. Choose **OK**. 1. In the **Windows Desktop Project** dialog, under **Application type**, select **Static Library (.lib)**. -1. Under **Additional Options**, uncheck the **Precompiled header** check box if it's checked. Check the **Empty project** box. +1. Under **Additional Options**, clear the **Precompiled header** check box if it's selected. Select **Empty project**. 1. Choose **OK** to create the project. @@ -70,27 +71,27 @@ The instructions for how to create the project vary depending on your version of ::: moniker range="msvc-140" -### To create a static library project in Visual Studio 2015 +To create a static library project in Visual Studio 2015: 1. On the menu bar, choose **File** > **New** > **Project**. -1. In the **New Project** dialog box, select **Installed** > **Templates** > **Visual C++** > **Win32**. In the center pane, select **Win32 Console Application**. +1. In the **New Project** dialog, select **Installed** > **Templates** > **Visual C++** > **Win32**. In the center pane, select **Win32 Console Application**. -1. Specify a name for the project—for example, *MathLibrary*—in the **Name** box. Specify a name for the solution—for example, *StaticMath*—in the **Solution Name** box. Choose the **OK** button. +1. Specify a name for the project, such as *MathLibrary*, in the **Name** box. Specify a name for the solution, such as *StaticMath*, in the **Solution Name** box. Choose **OK**. 1. In the **Win32 Application Wizard**, choose **Next**. -1. In the **Application Settings** page, under **Application type**, select **Static library**. Under **Additional options**, uncheck the **Precompiled header** checkbox. Choose **Finish** to create the project. +1. In the **Application Settings** page, under **Application type**, select **Static library**. Under **Additional options**, clear the **Precompiled header** checkbox. Choose **Finish** to create the project. ::: moniker-end ## Add a class to the static library -### To add a class to the static library +To add a class to the static library: -1. To create a header file for a new class, right-click to open the shortcut menu for the **MathLibrary** project in **Solution Explorer**, and then choose **Add** > **New Item**. +1. Create a header file for a new class. In **Solution Explorer**, right-click **MathLibrary** to open the context menu for the project. Select **Add** > **New Item**. -1. In the **Add New Item** dialog box, select **Visual C++** > **Code**. In the center pane, select **Header File (.h)**. Specify a name for the header file—for example, *MathLibrary.h*—and then choose the **Add** button. A nearly blank header file is displayed. +1. In the **Add New Item** dialog, select **Visual C++** > **Code**. In the center pane, select **Header File (.h)**. Specify a name for the header file, such as *MathLibrary.h*, and then select **Add**. A nearly blank header file is displayed. 1. Add a declaration for a class named `Arithmetic` to do common mathematical operations such as addition, subtraction, multiplication, and division. The code should resemble: @@ -118,9 +119,9 @@ The instructions for how to create the project vary depending on your version of } ``` -1. To create a source file for the new class, open the shortcut menu for the **MathLibrary** project in **Solution Explorer**, and then choose **Add** > **New Item**. +1. To create a source file for the new class, open the context menu for the **MathLibrary** project in **Solution Explorer**, and then choose **Add** > **New Item**. -1. In the **Add New Item** dialog box, in the center pane, select **C++ File (.cpp)**. Specify a name for the source file—for example, *MathLibrary.cpp*—and then choose the **Add** button. A blank source file is displayed. +1. In the **Add New Item** dialog, in the center pane, select **C++ File (.cpp)**. Specify a name for the source file, such as *MathLibrary.cpp*. Then select **Add**. A blank source file is displayed. 1. Use this source file to implement the functionality for class `Arithmetic`. The code should resemble: @@ -155,42 +156,45 @@ The instructions for how to create the project vary depending on your version of } ``` -1. To build the static library, select **Build** > **Build Solution** on the menu bar. The build creates a static library, *MathLibrary.lib*, that can be used by other programs. +1. To build the static library, select **Build** > **Build Solution** on the menu bar. The build creates a static library, *MathLibrary.lib*, that other programs can use. > [!NOTE] - > When you build on the Visual Studio command line, you must build the program in two steps. First, run `cl /c /EHsc MathLibrary.cpp` to compile the code and create an object file that's named *MathLibrary.obj*. (The `cl` command invokes the compiler, Cl.exe, and the `/c` option specifies compile without linking. For more information, see [/c (Compile Without Linking)](../build/reference/c-compile-without-linking.md).) Second, run `lib MathLibrary.obj` to link the code and create the static library *MathLibrary.lib*. (The `lib` command invokes the Library Manager, Lib.exe. For more information, see [LIB Reference](../build/reference/lib-reference.md).) + > When you build on the Visual Studio command line, you must build the program in two steps. + > + > 1. Run `cl /c /EHsc MathLibrary.cpp` to compile the code and create an object file named *MathLibrary.obj*. The `cl` command invokes the compiler, Cl.exe, and the `/c` option specifies compile without linking. For more information, see [/c (Compile Without Linking)](../build/reference/c-compile-without-linking.md). + > 1. Run `lib MathLibrary.obj` to link the code and create the static library *MathLibrary.lib*. The `lib` command invokes the Library Manager, Lib.exe. For more information, see [LIB Reference](../build/reference/lib-reference.md). ## Create a C++ console app that references the static library ::: moniker range=">=msvc-160" -### To create a C++ console app that references the static library in Visual Studio +To create a C++ console app that references the static library in Visual Studio: -1. In **Solution Explorer**, right-click on the top node, **Solution 'StaticMath'**, to open the shortcut menu. Choose **Add** > **New Project** to open the **Add a New Project** dialog. +1. In **Solution Explorer**, right-click on the top node, **Solution 'StaticMath'**, to open the context menu. Choose **Add** > **New Project** to open the **Add a New Project** dialog. 1. At the top of the dialog, set the **Project type** filter to **Console**. -1. From the filtered list of project types, choose **Console App** then choose **Next**. In the next page, enter *MathClient* in the **Name** box to specify a name for the project. +1. From the filtered list of project types, choose **Console App** then choose **Next**. In the next page, enter *MathClient* as the name for the project. -1. Choose the **Create** button to create the client project. +1. Choose **Create** to create the client project. -1. After you create a console app, an empty program is created for you. The name for the source file is the same as the name that you chose earlier. In the example, it's named `MathClient.cpp`. + After you create a console app, an empty program is created for you. The name for the source file is the same as the name that you chose earlier. In the example, it's named `MathClient.cpp`. ::: moniker-end ::: moniker range="msvc-150" -### To create a C++ console app that references the static library in Visual Studio 2017 +To create a C++ console app that references the static library in Visual Studio 2017: -1. In **Solution Explorer**, right-click on the top node, **Solution 'StaticMath'**, to open the shortcut menu. Choose **Add** > **New Project** to open the **Add a New Project** dialog box. +1. In **Solution Explorer**, right-click on the top node, **Solution 'StaticMath'**, to open the context menu. Choose **Add** > **New Project** to open the **Add a New Project** dialog. -1. In the **Add New Project** dialog box, select **Installed** > **Visual C++** > **Windows Desktop**. In the center pane, select **Windows Desktop Wizard**. +1. In the **Add New Project** dialog, select **Installed** > **Visual C++** > **Windows Desktop**. In the center pane, select **Windows Desktop Wizard**. 1. Specify a name for the project—for example, *MathClient*—in the **Name** box. Choose the **OK** button. 1. In the **Windows Desktop Project** dialog, under **Application type**, select **Console Application (.exe)**. -1. Under **Additional Options**, uncheck the **Precompiled header** check box if it's checked. +1. Under **Additional Options**, clear the **Precompiled header** check box if it's selected. 1. Choose **OK** to create the project. @@ -200,35 +204,35 @@ The instructions for how to create the project vary depending on your version of ::: moniker range="msvc-140" -### To create a C++ console app that references the static library in Visual Studio 2015 +To create a C++ console app that references the static library in Visual Studio 2015: -1. In **Solution Explorer**, right-click on the top node, **Solution 'StaticMath'**, to open the shortcut menu. Choose **Add** > **New Project** to open the **Add a New Project** dialog box. +1. In **Solution Explorer**, right-click on the top node, **Solution 'StaticMath'**, to open the context menu. Choose **Add** > **New Project** to open the **Add a New Project** dialog. -1. In the **Add New Project** dialog box, select **Installed** > **Visual C++** > **Win32**. In the center pane, select **Win32 Console Application**. +1. In the **Add New Project** dialog, select **Installed** > **Visual C++** > **Win32**. In the center pane, select **Win32 Console Application**. 1. Specify a name for the project—for example, *MathClient*—in the **Name** box. Choose the **OK** button. 1. In the **Win32 Application Wizard** dialog, choose **Next**. -1. On the **Application Settings** page, under **Application type**, make sure **Console application** is selected. Under **Additional options**, uncheck **Precompiled header**, then check the **Empty Project** checkbox. Choose **Finish** to create the project. +1. On the **Application Settings** page, under **Application type**, make sure **Console application** is selected. Under **Additional options**, clear **Precompiled header**, and then select **Empty Project**. Choose **Finish** to create the project. -1. To add a source file to the empty project, right-click to open the shortcut menu for the **MathClient** project in **Solution Explorer**, and then choose **Add** > **New Item**. +1. To add a source file to the empty project, right-click to open the context menu for the **MathClient** project in **Solution Explorer**, and then choose **Add** > **New Item**. -1. In the **Add New Item** dialog box, select **Visual C++** > **Code**. In the center pane, select **C++ File (.cpp)**. Specify a name for the source file—for example, *MathClient.cpp*—and then choose the **Add** button. A blank source file is displayed. +1. In the **Add New Item** dialog, select **Visual C++** > **Code**. In the center pane, select **C++ File (.cpp)**. Specify a name for the source file—for example, *MathClient.cpp*—and then choose the **Add** button. A blank source file is displayed. ::: moniker-end ## Use the functionality from the static library in the app -### To use the functionality from the static library in the app +To use the functionality from the static library in the app: -1. Before you can use the math routines in the static library, you must reference it. Open the shortcut menu for the **MathClient** project in **Solution Explorer**, and then choose **Add** > **Reference**. +1. Reference the static library before using the math routines in it. Open the context menu for the **MathClient** project in **Solution Explorer**, and then choose **Add** > **Reference**. -1. The **Add Reference** dialog box lists the libraries that you can reference. The **Projects** tab lists the projects in the current solution and any libraries they reference. Open the **Projects** tab, select the **MathLibrary** check box, and then choose the **OK** button. +1. The **Add Reference** dialog lists the libraries that you can reference. The **Projects** tab lists the projects in the current solution and any libraries they reference. Open the **Projects** tab, select **MathLibrary**, and then select **OK**. -1. To reference the `MathLibrary.h` header file, you must modify the included directories path. In **Solution Explorer**, right-click on **MathClient** to open the shortcut menu. Choose **Properties** to open the **MathClient Property Pages** dialog box. +1. Modify the included directories path to reference the `MathLibrary.h` header file. In **Solution Explorer**, right-click on **MathClient** to open the context menu. Choose **Properties** to open the **MathClient Property Pages** dialog. -1. In the **MathClient Property Pages** dialog box, set the **Configuration** drop-down to **All Configurations**. Set the **Platform** drop-down to **All Platforms**. +1. In the **MathClient Property Pages** dialog, set the **Configuration** value to **All Configurations**. Set **Platform** to **All Platforms**. 1. Select the **Configuration Properties** > **C/C++** > **General** property page. In the **Additional Include Directories** property, specify the path of the **MathLibrary** directory, or browse for it. @@ -236,13 +240,13 @@ The instructions for how to create the project vary depending on your version of 1. Open the **Additional Include Directories** property value drop-down list, and then choose **Edit**. - 1. In the **Additional Include Directories** dialog box, double-click in the top of the text box. Then choose the ellipsis button (**...**) at the end of the line. + 1. In the **Additional Include Directories** dialog, double-click in the top of the text box. Then choose the ellipsis button (**...**) at the end of the line. - 1. In the **Select Directory** dialog box, navigate up a level, and then select the **MathLibrary** directory. Then choose the **Select Folder** button to save your selection. + 1. In the **Select Directory** dialog, navigate up a level, and then select the **MathLibrary** directory. Then choose the **Select Folder** button to save your selection. - 1. In the **Additional Include Directories** dialog box, choose the **OK** button. + 1. In the **Additional Include Directories** dialog, choose the **OK** button. - 1. In the **Property Pages** dialog box, choose the **OK** button to save your changes to the project. + 1. In the **Property Pages** dialog, choose the **OK** button to save your changes to the project. 1. You can now use the `Arithmetic` class in this app by including the `#include "MathLibrary.h"` header in your code. Replace the contents of `MathClient.cpp` with this code: @@ -275,11 +279,11 @@ The instructions for how to create the project vary depending on your version of ## Run the app -### To run the app +To run the app: -1. Make sure that **MathClient** is selected as the default project. To select it, right-click to open the shortcut menu for **MathClient** in **Solution Explorer**, and then choose **Set as StartUp Project**. +1. Make sure that **MathClient** is selected as the default project. To select it, right-click **MathClient** in **Solution Explorer** to open the context menu, and then choose **Set as StartUp Project**. -1. To run the project, on the menu bar, choose **Debug** > **Start Without Debugging**. The output should resemble: +1. On the menu bar, choose **Debug** > **Start Without Debugging** to run the project. The output should resemble: ```Output a + b = 106.4 @@ -290,4 +294,4 @@ The instructions for how to create the project vary depending on your version of ## See also -[Walkthrough: Creating and Using a Dynamic Link Library (C++)](../build/walkthrough-creating-and-using-a-dynamic-link-library-cpp.md) \ No newline at end of file +[Walkthrough: Creating and Using a Dynamic Link Library (C++)](../build/walkthrough-creating-and-using-a-dynamic-link-library-cpp.md) diff --git a/docs/c-runtime-library/reference/atexit.md b/docs/c-runtime-library/reference/atexit.md index f3fa82b4a7d..392566beb4d 100644 --- a/docs/c-runtime-library/reference/atexit.md +++ b/docs/c-runtime-library/reference/atexit.md @@ -28,27 +28,27 @@ Function to be called. ## Return value -**`atexit`** returns 0 if successful, or a nonzero value if an error occurs. +`atexit` returns 0 if successful, or a nonzero value if an error occurs. ## Remarks -The **`atexit`** function is passed the address of a function *`func`* to be called when the program terminates normally. Successive calls to **`atexit`** create a register of functions that are executed in last-in, first-out (LIFO) order. The functions passed to **`atexit`** can't take parameters. **`atexit`** and **`_onexit`** use the heap to hold the register of functions. Thus, the number of functions that can be registered is limited only by heap memory. +The `atexit` function gets the address of a function *`func`* to call when the program terminates normally. Successive calls to `atexit` create a register of functions that execute in last-in, first-out (LIFO) order. The functions passed to `atexit` can't take parameters. `atexit` and `_onexit` use the heap to hold the register of functions. Thus, the number of functions you can register is limited only by heap memory. -The code in the **`atexit`** function shouldn't contain any dependency on any DLL that could have already been unloaded when the **`atexit`** function is called. +The code in the `atexit` function shouldn't contain any dependency on any DLL that could already be unloaded when the `atexit` function is called. -**Microsoft-specific DLL behavior**: When a DLL unloads, after `DLLMain` receives `DLL_PROCESS_DETACH`, the DLL's `atexit` callbacks run in reverse registration order, with the last callback registered running first. +**Microsoft-specific DLL behavior**: When a DLL unloads, after `DllMain` receives `DLL_PROCESS_DETACH`, the DLL's `atexit` callbacks run in reverse registration order, with the last callback registered running first. -To generate an ANSI-conformant application, use the ANSI-standard **`atexit`** function (rather than the similar **`_onexit`** function). +To generate an ANSI-conformant application, use the ANSI-standard `atexit` function (rather than the similar `_onexit` function). ## Requirements | Routine | Required header | |---|---| -| **`atexit`** | `` | +| `atexit` | `` | ## Example -This program pushes four functions onto the stack of functions to be executed when **`atexit`** is called. When the program exits, these programs are executed on a last in, first out basis. +This program pushes four functions onto the stack of functions to execute when `atexit` is called. When the program exits, it executes these functions in last-in, first-out order. ```C // crt_atexit.c diff --git a/docs/cpp/function-call-cpp.md b/docs/cpp/function-call-cpp.md index 804b63b3b5e..8c0cd68810a 100644 --- a/docs/cpp/function-call-cpp.md +++ b/docs/cpp/function-call-cpp.md @@ -17,7 +17,7 @@ primary-expression ( expression-list ) ## Remarks -In this context, `primary-expression` is the first operand, and `expression-list`, a possibly empty list of arguments, is the second operand. The function-call operator is used for operations that require a number of parameters. This works because `expression-list` is a list instead of a single operand. The function-call operator must be a nonstatic member function. +In this context, `primary-expression` is the first operand, and `expression-list`, a possibly empty list of arguments, is the second operand. The function-call operator is useful for operations that require a number of parameters. This usefulness comes from the fact that `expression-list` is a list instead of a single operand. Before C++23, the function-call operator had to be a nonstatic member function. In C++23 and later, it can be a static member function. For more information, see [Static function call operator](static-function-call-operator.md). The function-call operator, when overloaded, does not modify how functions are called; rather, it modifies how the operator is to be interpreted when applied to objects of a given class type. For example, the following code would usually be meaningless: @@ -73,4 +73,5 @@ int main() ## See also +[Static function call operator](static-function-call-operator.md)\ [Operator Overloading](../cpp/operator-overloading.md) diff --git a/docs/cpp/static-function-call-operator.md b/docs/cpp/static-function-call-operator.md new file mode 100644 index 00000000000..b1fbb12d625 --- /dev/null +++ b/docs/cpp/static-function-call-operator.md @@ -0,0 +1,88 @@ +--- +description: "Learn how to declare and use the static function call operator in C++." +title: "Static function call operator (C++)" +ms.date: 08/19/2026 +ai-usage: ai-assisted +helpviewer_keywords: ["static function call operator [C++]", "static operator() [C++]", "operator overloading [C++]"] +--- + +# Static function call operator (C++) + +In C++23, you can declare the function call operator (`operator()`) as a static member function. A static function call operator doesn't have an implicit object parameter. Use it when a callable type doesn't need to access instance data. + +Support for this feature was introduced in Visual Studio 2022 version 17.14 (MSVC 14.44). Use the `/std:c++latest` compiler option. + +## Syntax + +```cpp +static return-type operator()(parameter-list); +``` + +You can also declare the function call operator generated for a lambda expression as static: + +```cpp +[](parameter-list) static { function-body } +``` + +## Remarks + +A static function call operator doesn't have a `this` pointer. It can't be `virtual` or have a cv-qualifier (`const` or `volatile`) or ref-qualifier (`&`, `&&`). + +You can call a static function call operator by using an object of its class, which allows the object to work as a function object. You can also call it by using its qualified name. Taking its address produces a regular function pointer instead of a pointer-to-member function. + +A lambda expression can specify `static` after its parameter list. A static lambda can't have captures or be declared `mutable`. Declaring a captureless lambda doesn't make it static automatically; you must specify `static` to opt in to this behavior. + +The feature-test macro `__cpp_static_call_operator` is defined when the static function call operator is available. + +## Example + +The following example defines a stateless function object and calls its static function call operator in three ways: + +```cpp +// Compile with: /std:c++latest + +#include + +struct Multiply +{ + static constexpr int operator()(int left, int right) noexcept + { + return left * right; + } +}; + +int main() +{ + Multiply multiply; + + std::cout << "multiply(6, 7) = " << multiply(6, 7) << std::endl; + std::cout << "Multiply::operator()(3, 4) = " + << Multiply::operator()(3, 4) << std::endl; + + auto multiply_function = &Multiply::operator(); + std::cout << "multiply_function(5, 5) = " + << multiply_function(5, 5) << std::endl; + + auto twice = [](int value) static noexcept + { + return value * 2; + }; + + std::cout << "twice(21) = " << twice(21) << std::endl; +} +``` + +```output +multiply(6, 7) = 42 +Multiply::operator()(3, 4) = 12 +multiply_function(5, 5) = 25 +twice(21) = 42 +``` + +## See also + +[Function call](function-call-cpp.md)\ +[Function-call operator](function-call-operator-parens.md)\ +[Operator overloading](operator-overloading.md)\ +[`static` members](static-members-cpp.md)\ +[Proposal P1169R4: static `operator()`](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1169r4.html) \ No newline at end of file diff --git a/docs/cpp/static-subscript-operator.md b/docs/cpp/static-subscript-operator.md new file mode 100644 index 00000000000..fd0498a3bf3 --- /dev/null +++ b/docs/cpp/static-subscript-operator.md @@ -0,0 +1,70 @@ +--- +description: "Learn how to declare and use the static subscript operator in C++." +title: "Static subscript operator (C++)" +ms.date: 08/19/2026 +ai-usage: ai-assisted +helpviewer_keywords: ["static subscript operator [C++]", "static operator[] [C++]", "operator overloading [C++]"] +--- + +# Static subscript operator (C++) + +In C++23, you can declare the subscript operator (`operator[]`) as a static member function. A static subscript operator doesn't have an implicit object parameter. Use it when a subscript operation doesn't need to access instance data. + +Support for this feature was introduced in Visual Studio 2022 version 17.14 (MSVC 14.44). Use the `/std:c++latest` compiler option. + +## Syntax + +```cpp +static return-type operator[](parameter-list); +``` + +## Remarks + +A static subscript operator doesn't have a `this` pointer. It can't be `virtual` or have a cv-qualifier (`const` or `volatile`) or ref-qualifier (`&`, `&&`). + +You can call a static subscript operator by using an object of its class, which allows the object to use subscript syntax. You can also call it by using its qualified name. Taking its address produces a regular function pointer instead of a pointer-to-member function. + +The feature-test macro `__cpp_static_call_operator` is defined when the static subscript operator is available. + +## Example + +The following example defines a stateless type that calculates powers of two and calls its static subscript operator in three ways: + +```cpp +// Compile with: /std:c++latest + +#include + +struct PowersOfTwo +{ + static constexpr unsigned int operator[](unsigned int exponent) noexcept + { + return 1U << exponent; + } +}; + +int main() +{ + PowersOfTwo powers_of_two; + + std::cout << "powers_of_two[6] = " << powers_of_two[6] << std::endl; + std::cout << "PowersOfTwo::operator[](4) = " + << PowersOfTwo::operator[](4) << std::endl; + + auto power_function = &PowersOfTwo::operator[]; + std::cout << "power_function(5) = " << power_function(5) << std::endl; +} +``` + +```output +powers_of_two[6] = 64 +PowersOfTwo::operator[](4) = 16 +power_function(5) = 32 +``` + +## See also + +[Subscripting](subscripting.md)\ +[Operator overloading](operator-overloading.md)\ +[`static` members](static-members-cpp.md)\ +[Proposal P2589R1: static `operator[]`](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2589r1.pdf) \ No newline at end of file diff --git a/docs/cpp/subscripting.md b/docs/cpp/subscripting.md index 62fc228c211..fca0cb6b2a8 100644 --- a/docs/cpp/subscripting.md +++ b/docs/cpp/subscripting.md @@ -7,7 +7,9 @@ ms.assetid: eb151281-6733-401d-9787-39ab6754c62c --- # Subscripting -The subscript operator (**[ ]**), like the function-call operator, is considered a binary operator. The subscript operator must be a nonstatic member function that takes a single argument. This argument can be of any type and designates the desired array subscript. +The subscript operator (**[ ]**), like the function-call operator, is a binary operator. Before C++23, the subscript operator must be a nonstatic member function. In C++23 and later, it can be a static member function. For more information, see [Static subscript operator](static-subscript-operator.md). + +The argument can be any type and designates the desired array subscript. ## Example @@ -86,4 +88,5 @@ Note that the function **operator[]** returns a reference type. This causes it t ## See also +[Static subscript operator](static-subscript-operator.md)\ [Operator Overloading](../cpp/operator-overloading.md) diff --git a/docs/cpp/toc.yml b/docs/cpp/toc.yml index 1f17ade4e51..111d9c465ec 100644 --- a/docs/cpp/toc.yml +++ b/docs/cpp/toc.yml @@ -336,8 +336,12 @@ items: href: ../cpp/assignment.md - name: Function call href: ../cpp/function-call-cpp.md + - name: Static function call operator + href: ../cpp/static-function-call-operator.md - name: Subscripting href: ../cpp/subscripting.md + - name: Static subscript operator + href: ../cpp/static-subscript-operator.md - name: Member access href: ../cpp/member-access.md - name: Classes and structs diff --git a/docs/overview/acquire-msvc.md b/docs/overview/acquire-msvc.md index b70d02b277e..0acc6adb724 100644 --- a/docs/overview/acquire-msvc.md +++ b/docs/overview/acquire-msvc.md @@ -1,8 +1,9 @@ --- title: "Install the Microsoft C++ (MSVC) Build Tools" description: "Install the MSVC Build Tools using the Visual Studio Installer UI, command line, winget, or a .vsconfig file. Choose Preview, latest release, or an older in-support toolset, and target it from MSBuild, CMake, or the Visual Studio Command Prompt." -ms.date: 07/13/2026 +ms.date: 08/20/2026 ms.topic: how-to +ai-usage: ai-assisted ms.service: "visual-cpp" ms.subservice: "tools" ms.custom: intro-installation @@ -164,6 +165,22 @@ msbuild /p:Platform= /p:Configuration= / `` matches the folder name under `\VC\Tools\MSVC\`. +#### Discover an MSVC toolset in another installation + +> [!NOTE] +> Cross-install discovery requires Visual Studio version 18.8 or later. + +The current Visual Studio installation might not find the exact `VCToolsVersion` you specify. To search all Visual Studio and Visual Studio Build Tools installations, add the following properties to your `.vcxproj` file or a `Directory.Build.props` file: + +```xml + + true + 14.43.34604 + +``` + +With discovery enabled, Visual Studio finds the specified version, potentially from a different installation. This behavior supports reproducible builds without manually setting `VCToolsInstallDir`. The requested MSVC toolset must already be installed on the machine. + To build with the MSVC preview tools, add `/p:MSVCPreviewEnabled=true`: ```cmd diff --git a/docs/sanitizers/asan-known-issues.md b/docs/sanitizers/asan-known-issues.md index 6b43a47598c..20608c02b2d 100644 --- a/docs/sanitizers/asan-known-issues.md +++ b/docs/sanitizers/asan-known-issues.md @@ -1,7 +1,7 @@ --- title: "AddressSanitizer known issues and limitations" description: "Technical description of the AddressSanitizer for Microsoft C/C++ known issues." -ms.date: 11/19/2025 +ms.date: 8/18/2026 helpviewer_keywords: ["AddressSanitizer known issues"] --- @@ -105,6 +105,19 @@ On x64, MSVC ASan's [shadow bytes](./asan-shadow-bytes.md) region occupies sever The Visual Studio debugger handles this gracefully, and doesn't show these traces. However, debuggers like WinDbgX may break on every exception by default. Disabling breaking on first-chance exceptions is recommended. For example, in WinDbgX, this corresponds to the [`sxd av`](/windows-hardware/drivers/debuggercmds/sx--sxd--sxe--sxi--sxn--sxr--sx---set-exceptions-) command. +## ASan support for C++/CLI is experimental + +For reliable AddressSanitizer (ASan) diagnostics, isolate memory-unsafe code in native translation units or DLLs compiled without `/clr` and with `/fsanitize=address`. Call the native code from C++/CLI wrappers. + + +The CLR manages memory and JIT-generated code, so C++/CLI code isn't guaranteed to receive ASan load and store instrumentation. As a result: + +- C++/CLI and STL code: Memory accesses within C++/CLI methods might not be instrumented, including accesses performed by STL code. +- Managed arrays: Out-of-range access produces CLR behavior, such as `IndexOutOfRangeException`, rather than an ERROR: AddressSanitizer report. +- Managed threads: Native memory accesses emitted within C++/CLI method bodies might not produce ASan diagnostics. +- Finalization and shutdown: Reports during finalization, process shutdown, or mixed-mode unloading might not reliably indicate user-code memory bugs. +- Native hosts: Loading an ASan-enabled C++/CLI wrapper DLL from a native host might produce misleading runtime failures, such as access-violation reports for unknown addresses. + ## See also [AddressSanitizer overview](asan.md)\ From 9b9329f808c2bc858f184022ba50984219ecfadb Mon Sep 17 00:00:00 2001 From: Daniel Nikolov <114946180+danikolovv@users.noreply.github.com> Date: Wed, 26 Aug 2026 23:23:57 +0300 Subject: [PATCH 08/11] Clarify sentence about updating UI item states (#5955) Added a question mark to clarify the sentence about updating the state of user-interface items. --- docs/mfc/how-to-update-user-interface-objects.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/mfc/how-to-update-user-interface-objects.md b/docs/mfc/how-to-update-user-interface-objects.md index 0a9e902847d..11d935d65cb 100644 --- a/docs/mfc/how-to-update-user-interface-objects.md +++ b/docs/mfc/how-to-update-user-interface-objects.md @@ -11,7 +11,7 @@ helpviewer_keywords: ["menus [MFC], updating as context changes", "user interfac Typically, menu items and toolbar buttons have more than one state. For example, a menu item is grayed (dimmed) if it is unavailable in the present context. Menu items can also be checked or unchecked. A toolbar button can also be disabled if unavailable, or it can be checked. -Who updates the state of these items as program conditions change Logically, if a menu item generates a command that is handled by, say, a document, it makes sense to have the document update the menu item. The document probably contains the information on which the update is based. +Who updates the state of these items as program conditions change? Logically, if a menu item generates a command that is handled by, say, a document, it makes sense to have the document update the menu item. The document probably contains the information on which the update is based. If a command has multiple user-interface objects (perhaps a menu item and a toolbar button), both are routed to the same handler function. This encapsulates your user-interface update code for all of the equivalent user-interface objects in a single place. From 186f69d07d68c55f5dcc2dbd55fb3a954398b06e Mon Sep 17 00:00:00 2001 From: Eric Brumer Date: Thu, 27 Aug 2026 13:03:16 -0700 Subject: [PATCH 09/11] Update acquisition doc for vcpkg (#5957) * Update acquisition doc for vcpkg * remove en-us from URL * use relative link to vcpkg docs --- docs/overview/acquire-msvc.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/overview/acquire-msvc.md b/docs/overview/acquire-msvc.md index 0acc6adb724..e26f0ab46b2 100644 --- a/docs/overview/acquire-msvc.md +++ b/docs/overview/acquire-msvc.md @@ -197,6 +197,20 @@ cmake -G "Visual Studio 18 2026" -T "version=14.51" ..\ cmake -G "Visual Studio 18 2026" -T "version=14.52" ..\ ``` +### vcpkg + +Configure vcpkg with the [VCPKG_PLATFORM_TOOLSET_VERSION](/vcpkg/users/triplets#vcpkg_platform_toolset_version) triplet. For example: + +``` +set(VCPKG_PLATFORM_TOOLSET_VERSION "14.50") +``` + +or + +``` +set(VCPKG_PLATFORM_TOOLSET_VERSION "14.51") +``` + ### Visual Studio Command Prompt Some build systems need the command prompt to have the `PATH`, `LIB`, `INCLUDE`, and related environment variables set before you run them. From ba2be146e8750a823567884da81ad7438388783e Mon Sep 17 00:00:00 2001 From: "learn-build-service-prod[bot]" <113403604+learn-build-service-prod[bot]@users.noreply.github.com> Date: Tue, 1 Sep 2026 10:45:40 -0400 Subject: [PATCH 10/11] Resolve syncing conflicts from FromPrivateLiveToMaster to main (#5959) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Filesystem (#6805) * sorting out deprecated filsystem * refactor docs so that experiemental stuff is in its own location and doesn't overlap * Apply batched suggestions from code review Co-authored-by: learn-build-service-prod-05[bot] <274429479+learn-build-service-prod-05[bot]@users.noreply.github.com> * Apply batched suggestions from code review Co-authored-by: learn-build-service-prod-05[bot] <274429479+learn-build-service-prod-05[bot]@users.noreply.github.com> * Fix formatting of function descriptions in documentation * small edits * tech review and add spaceship operator to the director_entry class --------- Co-authored-by: TylerMSFT <12305055+TylerMSFT@users.noreply.github.com> Co-authored-by: learn-build-service-prod-05[bot] <274429479+learn-build-service-prod-05[bot]@users.noreply.github.com> * Confirm merge from FromPublicMasterBranch to main to sync with https://github.com/MicrosoftDocs/cpp-docs (branch main) (#6802) * Update Vectorized STL algorithm documentation to reflect the current stae (#5937) Since the last update: * ARM64 and ARM64EC vectorization was added. Mention of x64 and x86 is removed, as vectorization is now supported on any target, except deprecated `/clr:pure` and `/clr:safe` modes. * `includes` is now manually vectorized too * `replace_copy` is now manually vectorized too Also moved `find_end` to `search` / `search_n` group, where it fits better. * Update header-files-cpp.md (#5938) Clarify intent of section * Update documentation on accessing System.String characters (#5940) * Update documentation on accessing System.String characters Added important note about treating interior pointers as const and linked to unsafe code best practices. * Update docs/dotnet/how-to-access-characters-in-a-system-string.md Co-authored-by: Jan Kotas * Apply suggestions from code review Co-authored-by: Aaron R Robinson * Apply suggestions from code review Co-authored-by: Aaron R Robinson --------- Co-authored-by: Jan Kotas * Clarify version prefix for Visual Studio Command Prompt (#5946) Updated instructions for starting Visual Studio Command Prompt to reflect changes in version specification. * Add new ARM64 feature arguments to documentation (#5950) Add new extensions `cssc` and `faminmax` to the `/feature` flag arguments documentation * atexit: Clarify DLL behavior is the same as _onexit (#5952) * atexit: Clarify DLL behavior is the same as _onexit - Document that atexit called from within a DLL will register the routine to run when the DLL is unloaded. atexit is a wrapper around _onexit which already documents this behavior. Ref: https://github.com/curl/curl/pull/22383#discussion_r3753438017 Reported-by: Michał Petryka Closes #xxxx * Revise atexit documentation for accuracy Update the date and clarify DLL behavior for atexit. --------- Co-authored-by: Tyler Whitney * Resolve syncing conflicts from FromPrivateLiveToMaster to main (#5953) * Clarify sentence about updating UI item states (#5955) Added a question mark to clarify the sentence about updating the state of user-interface items. * Update acquisition doc for vcpkg (#5957) * Update acquisition doc for vcpkg * remove en-us from URL * use relative link to vcpkg docs * Update docs/mfc/how-to-update-user-interface-objects.md Co-authored-by: learn-build-service-prod-08[bot] <274430765+learn-build-service-prod-08[bot]@users.noreply.github.com> --------- Co-authored-by: learn-build-service-prod[bot] <113403604+learn-build-service-prod[bot]@users.noreply.github.com> Co-authored-by: Learn Build Service GitHub App Co-authored-by: Alex Guteniev Co-authored-by: veganaiZe <7102064+veganaiZe@users.noreply.github.com> Co-authored-by: Aaron R Robinson Co-authored-by: Jan Kotas Co-authored-by: Eric Brumer Co-authored-by: Vít Knobloch <67308900+vitknobloch@users.noreply.github.com> Co-authored-by: Jay Satiro Co-authored-by: Tyler Whitney Co-authored-by: Daniel Nikolov <114946180+danikolovv@users.noreply.github.com> Co-authored-by: Hector Co-authored-by: learn-build-service-prod-08[bot] <274430765+learn-build-service-prod-08[bot]@users.noreply.github.com> --------- Co-authored-by: Tyler Whitney Co-authored-by: TylerMSFT <12305055+TylerMSFT@users.noreply.github.com> Co-authored-by: learn-build-service-prod-05[bot] <274429479+learn-build-service-prod-05[bot]@users.noreply.github.com> Co-authored-by: learn-build-service-prod[bot] <113403604+learn-build-service-prod[bot]@users.noreply.github.com> Co-authored-by: Learn Build Service GitHub App Co-authored-by: Alex Guteniev Co-authored-by: veganaiZe <7102064+veganaiZe@users.noreply.github.com> Co-authored-by: Aaron R Robinson Co-authored-by: Jan Kotas Co-authored-by: Eric Brumer Co-authored-by: Vít Knobloch <67308900+vitknobloch@users.noreply.github.com> Co-authored-by: Jay Satiro Co-authored-by: Daniel Nikolov <114946180+danikolovv@users.noreply.github.com> Co-authored-by: Hector Co-authored-by: learn-build-service-prod-08[bot] <274430765+learn-build-service-prod-08[bot]@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: v-regandowner <97987445+v-regandowner@users.noreply.github.com> --- .github/workflows/generate-preview-links.yml | 25 - .../how-to-update-user-interface-objects.md | 2 +- .../standard-library/directory-entry-class.md | 551 ++++++++--- .../directory-iterator-class.md | 26 +- ...mental-filesystem-directory-entry-class.md | 272 ++++++ ...tal-filesystem-directory-iterator-class.md | 169 ++++ .../experimental-filesystem-enumerations.md | 162 ++++ .../experimental-filesystem-error-class.md | 105 +++ ...perimental-filesystem-file-status-class.md | 120 +++ .../experimental-filesystem-functions.md | 497 ++++++++++ .../experimental-filesystem-operators.md | 108 +++ .../experimental-filesystem-path-class.md | 852 ++++++++++++++++++ ...stem-recursive-directory-iterator-class.md | 258 ++++++ ...imental-filesystem-space-info-structure.md | 44 + .../experimental-filesystem.md | 67 ++ docs/standard-library/file-status-class.md | 16 +- .../file-system-navigation.md | 8 +- .../filesystem-enumerations.md | 84 +- .../filesystem-error-class.md | 11 +- docs/standard-library/filesystem-functions.md | 111 +-- docs/standard-library/filesystem-operators.md | 53 +- docs/standard-library/filesystem.md | 43 +- docs/standard-library/path-class.md | 214 +++-- .../recursive-directory-iterator-class.md | 28 +- docs/standard-library/space-info-structure.md | 13 +- docs/standard-library/toc.yml | 27 +- 26 files changed, 3466 insertions(+), 400 deletions(-) delete mode 100644 .github/workflows/generate-preview-links.yml create mode 100644 docs/standard-library/experimental-filesystem-directory-entry-class.md create mode 100644 docs/standard-library/experimental-filesystem-directory-iterator-class.md create mode 100644 docs/standard-library/experimental-filesystem-enumerations.md create mode 100644 docs/standard-library/experimental-filesystem-error-class.md create mode 100644 docs/standard-library/experimental-filesystem-file-status-class.md create mode 100644 docs/standard-library/experimental-filesystem-functions.md create mode 100644 docs/standard-library/experimental-filesystem-operators.md create mode 100644 docs/standard-library/experimental-filesystem-path-class.md create mode 100644 docs/standard-library/experimental-filesystem-recursive-directory-iterator-class.md create mode 100644 docs/standard-library/experimental-filesystem-space-info-structure.md create mode 100644 docs/standard-library/experimental-filesystem.md diff --git a/.github/workflows/generate-preview-links.yml b/.github/workflows/generate-preview-links.yml deleted file mode 100644 index 784d2be5b6e..00000000000 --- a/.github/workflows/generate-preview-links.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: 'Preview link generator' - -on: - pull_request_target: - types: [opened, synchronize, reopened] - -permissions: - contents: read - -jobs: - preview_link_generator_job: - name: Generate preview link table - runs-on: ubuntu-latest - permissions: - statuses: read - pull-requests: write - steps: - - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 - with: - egress-policy: audit - - - uses: dotnet/docs-tools/actions/preview-link-generator@main - with: - repo_token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/docs/mfc/how-to-update-user-interface-objects.md b/docs/mfc/how-to-update-user-interface-objects.md index 11d935d65cb..66899aff533 100644 --- a/docs/mfc/how-to-update-user-interface-objects.md +++ b/docs/mfc/how-to-update-user-interface-objects.md @@ -11,7 +11,7 @@ helpviewer_keywords: ["menus [MFC], updating as context changes", "user interfac Typically, menu items and toolbar buttons have more than one state. For example, a menu item is grayed (dimmed) if it is unavailable in the present context. Menu items can also be checked or unchecked. A toolbar button can also be disabled if unavailable, or it can be checked. -Who updates the state of these items as program conditions change? Logically, if a menu item generates a command that is handled by, say, a document, it makes sense to have the document update the menu item. The document probably contains the information on which the update is based. +Who updates the state of these items as program conditions change? Logically, if a menu item generates a command that a document handles, it makes sense to have the document update the menu item. The document probably contains the information on which the update is based. If a command has multiple user-interface objects (perhaps a menu item and a toolbar button), both are routed to the same handler function. This encapsulates your user-interface update code for all of the equivalent user-interface objects in a single place. diff --git a/docs/standard-library/directory-entry-class.md b/docs/standard-library/directory-entry-class.md index 872cabb4b9c..3aca916761f 100644 --- a/docs/standard-library/directory-entry-class.md +++ b/docs/standard-library/directory-entry-class.md @@ -1,16 +1,15 @@ --- description: "Learn more about: directory_entry Class" title: "directory_entry Class" -ms.date: 06/10/2022 -f1_keywords: ["filesystem/std::experimental::filesystem::directory_entry", "filesystem/std::experimental::filesystem::directory_entry::operator const std::experimental::filesystem::path &", "filesystem/std::experimental::filesystem::directory_entry::directory_entry", "filesystem/std::experimental::filesystem::directory_entry::operator=", "filesystem/std::experimental::filesystem::directory_entry::assign", "filesystem/std::experimental::filesystem::directory_entry::replace_filename", "filesystem/std::experimental::filesystem::directory_entry::path", "filesystem/std::experimental::filesystem::directory_entry::status", "filesystem/std::experimental::filesystem::directory_entry::symlink_status", "filesystem/std::experimental::filesystem::directory_entry::operator<", "filesystem/std::experimental::filesystem::directory_entry::operator==", "filesystem/std::experimental::filesystem::directory_entry::operator!=", "filesystem/std::experimental::filesystem::directory_entry::operator<=", "filesystem/std::experimental::filesystem::directory_entry::operator>", "filesystem/std::experimental::filesystem::directory_entry::operator>="] -ms.assetid: 1827c67b-4137-4548-adb0-f955f7acaf08 -helpviewer_keywords: ["std::experimental::filesystem::directory_entry", "std::experimental::filesystem::directory_entry::operator const std::experimental::filesystem::path &", "std::experimental::filesystem::directory_entry::directory_entry", "std::experimental::filesystem::directory_entry::operator=", "std::experimental::filesystem::directory_entry::assign", "std::experimental::filesystem::directory_entry::replace_filename", "std::experimental::filesystem::directory_entry::path", "std::experimental::filesystem::directory_entry::status", "std::experimental::filesystem::directory_entry::symlink_status", "std::experimental::filesystem::directory_entry::operator<", "std::experimental::filesystem::directory_entry::operator==", "std::experimental::filesystem::directory_entry::operator!=", "std::experimental::filesystem::directory_entry::operator<=", "std::experimental::filesystem::directory_entry::operator>", "std::experimental::filesystem::directory_entry::operator>="] +ms.date: 08/28/2026 +f1_keywords: ["filesystem/std::filesystem::directory_entry", "filesystem/std::filesystem::directory_entry::directory_entry", "filesystem/std::filesystem::directory_entry::operator=", "filesystem/std::filesystem::directory_entry::assign", "filesystem/std::filesystem::directory_entry::replace_filename", "filesystem/std::filesystem::directory_entry::refresh", "filesystem/std::filesystem::directory_entry::path", "filesystem/std::filesystem::directory_entry::operator const std::filesystem::path &", "filesystem/std::filesystem::directory_entry::exists", "filesystem/std::filesystem::directory_entry::is_block_file", "filesystem/std::filesystem::directory_entry::is_character_file", "filesystem/std::filesystem::directory_entry::is_directory", "filesystem/std::filesystem::directory_entry::is_fifo", "filesystem/std::filesystem::directory_entry::is_other", "filesystem/std::filesystem::directory_entry::is_regular_file", "filesystem/std::filesystem::directory_entry::is_socket", "filesystem/std::filesystem::directory_entry::is_symlink", "filesystem/std::filesystem::directory_entry::file_size", "filesystem/std::filesystem::directory_entry::hard_link_count", "filesystem/std::filesystem::directory_entry::last_write_time", "filesystem/std::filesystem::directory_entry::status", "filesystem/std::filesystem::directory_entry::symlink_status", "filesystem/std::filesystem::directory_entry::operator==", "filesystem/std::filesystem::directory_entry::operator<=>"] +helpviewer_keywords: ["std::filesystem::directory_entry", "std::filesystem::directory_entry::directory_entry", "std::filesystem::directory_entry::operator=", "std::filesystem::directory_entry::assign", "std::filesystem::directory_entry::replace_filename", "std::filesystem::directory_entry::refresh", "std::filesystem::directory_entry::path", "std::filesystem::directory_entry::operator const std::filesystem::path &", "std::filesystem::directory_entry::exists", "std::filesystem::directory_entry::is_block_file", "std::filesystem::directory_entry::is_character_file", "std::filesystem::directory_entry::is_directory", "std::filesystem::directory_entry::is_fifo", "std::filesystem::directory_entry::is_other", "std::filesystem::directory_entry::is_regular_file", "std::filesystem::directory_entry::is_socket", "std::filesystem::directory_entry::is_symlink", "std::filesystem::directory_entry::file_size", "std::filesystem::directory_entry::hard_link_count", "std::filesystem::directory_entry::last_write_time", "std::filesystem::directory_entry::status", "std::filesystem::directory_entry::symlink_status", "std::filesystem::directory_entry::operator==", "std::filesystem::directory_entry::operator<=>"] ms.custom: devdivchpfy22 --- -# directory_entry Class +# `directory_entry` class -Describes an object that is returned by `*X`, where *X* is a [directory_iterator](../standard-library/directory-iterator-class.md) or a [recursive_directory_iterator](../standard-library/recursive-directory-iterator-class.md). +Describes an object that's returned by dereferencing a [`directory_iterator`](../standard-library/directory-iterator-class.md) or a [`recursive_directory_iterator`](../standard-library/recursive-directory-iterator-class.md). A `directory_entry` wraps a [`path`](../standard-library/path-class.md) and, as an optimization, can cache file attributes that are obtained while iterating a directory. ## Syntax @@ -20,253 +19,577 @@ class directory_entry; ## Remarks -The class stores an object of type [path](../standard-library/path-class.md). The stored `path` can be an instance of the [path Class](../standard-library/path-class.md) or of a type that is derived from `path`. It also stores two [file_type](../standard-library/filesystem-enumerations.md#file_type) values. One value represents the status of the stored file name. The other represents the symbolic link status of the file name. +A `directory_entry` object stores a [`path`](../standard-library/path-class.md). As an optimization, it can also cache the attributes and status of the file that the path refers to. The cached data is populated when the entry is created by a directory iterator, or when you call [`refresh`](#refresh). Observers such as [`file_size`](#file_size), [`last_write_time`](#last_write_time), [`status`](#status), and the various `is_*` predicates return the cached data when it's available; otherwise, they query the file system. For more information and code examples, see [File System Navigation (C++)](../standard-library/file-system-navigation.md). ### Constructors -|Constructor|Description| +| Constructor | Description | |-|-| -|[directory_entry](#directory_entry)|The defaulted constructors behave as expected. The fourth constructor initializes `mypath` to *pval*, `mystat` to *stat_arg*, and `mysymstat` to *symstat_arg*.| +| [`directory_entry`](#directory_entry) | Constructs a `directory_entry`. | ### Member functions -|Member function|Description| +| Member function | Description | |-|-| -|[assign](#assign)|The member function assigns *pval* to `mypath`, *stat* to `mystat`, and *symstat* to `mysymstat`.| -|[path](#path)|The member function returns `mypath`.| -|[replace_filename](#replace_filename)|The member function replaces `mypath` with `mypath.parent_path()` / *pval*, `mystat` with *stat_arg*, and `mysymstat` with *symstat_arg*| -|[status](#status)|Both member functions return `mystat` possibly first altered.| -|[symlink_status](#symlink_status)|Both member functions return `mysymstat` possibly first altered.| +| [`assign`](#assign) | Replaces the stored path and refreshes the cached attributes. | +| [`exists`](#exists) | Checks whether the entry refers to an existing file. | +| [`file_size`](#file_size) | Gets the size, in bytes, of the referenced file. | +| [`hard_link_count`](#hard_link_count) | Gets the number of hard links to the referenced file. | +| [`is_block_file`](#is_block_file) | Checks whether the referenced file is a block special file. | +| [`is_character_file`](#is_character_file) | Checks whether the referenced file is a character special file. | +| [`is_directory`](#is_directory) | Checks whether the referenced file is a directory. | +| [`is_fifo`](#is_fifo) | Checks whether the referenced file is a named pipe (FIFO). | +| [`is_other`](#is_other) | Checks whether the referenced file is an other file. | +| [`is_regular_file`](#is_regular_file) | Checks whether the referenced file is a regular file. | +| [`is_socket`](#is_socket) | Checks whether the referenced file is a socket. | +| [`is_symlink`](#is_symlink) | Checks whether the referenced file is a symbolic link. | +| [`last_write_time`](#last_write_time) | Gets the time of the last data modification of the referenced file. | +| [`path`](#path) | Returns the stored path. | +| [`refresh`](#refresh) | Refreshes the cached file attributes. | +| [`replace_filename`](#replace_filename) | Replaces the filename of the stored path and refreshes the cached attributes. | +| [`status`](#status) | Gets the status of the referenced file, following symbolic links. | +| [`symlink_status`](#symlink_status) | Gets the status of the referenced file, without following symbolic links. | ### Operators -|Operator|Description| +| Operator | Description | |-|-| -|[operator!=](#op_neq)|Replaces the elements of the list with a copy of another list.| -|[operator=](#op_as)|The defaulted member assignment operators behave as expected.| -|[operator==](#op_eq)|Returns `mypath == right.mypath`.| -|[operator<](#op_lt)|Returns `mypath < right.mypath`.| -|[operator<=](#op_lteq)|Returns `!(right < *this)`.| -|[operator>](#op_gt)|Returns `right < *this`.| -|[operator>=](#op_gteq)|Returns `!(*this < right)`.| -|[operator const path_type&](#path_type)|Returns `mypath`.| +| [`operator=`](#op_as) | Assigns to the `directory_entry`. | +| [`operator const path&`](#path_type) | Returns the stored path. | +| [`operator==`](#op_eq) | Checks whether two `directory_entry` objects are equal. | +| [`operator<=>`](#op_spaceship) | Performs a three-way comparison of two `directory_entry` objects. (C++20) | +| [`operator!=`](#op_neq) | Checks whether two `directory_entry` objects are unequal. An explicit member in C++17; supported through rewritten comparisons in C++20 and later. | +| [`operator<`](#op_lt) | Checks whether the `directory_entry` sorts before another `directory_entry`. An explicit member in C++17; supported through rewritten comparisons in C++20 and later. | +| [`operator<=`](#op_lteq) | Checks whether the `directory_entry` sorts before or equal to another `directory_entry`. An explicit member in C++17; supported through rewritten comparisons in C++20 and later. | +| [`operator>`](#op_gt) | Checks whether the `directory_entry` sorts after another `directory_entry`. An explicit member in C++17; supported through rewritten comparisons in C++20 and later. | +| [`operator>=`](#op_gteq) | Checks whether the `directory_entry` sorts after or equal to another `directory_entry`. An explicit member in C++17; supported through rewritten comparisons in C++20 and later. | ## Requirements -**Header:** \ +**Header:** `` -**Namespace:** std::experimental::filesystem +**Namespace:** `std::filesystem` + +## directory_entry + +Constructs a `directory_entry`. + +```cpp +directory_entry() noexcept = default; +directory_entry(const directory_entry&) = default; +directory_entry(directory_entry&&) noexcept = default; + +explicit directory_entry(const std::filesystem::path& p); +directory_entry(const std::filesystem::path& p, std::error_code& ec); + +~directory_entry(); +``` + +### Parameters + +*p*\ +The path to the file that the entry refers to. + +*ec*\ +The output error code for the operation. + +### Remarks + +The default, copy, and move constructors behave as expected. The constructors that take a `path` store *p* and then call [`refresh`](#refresh) to populate the cached attributes. The overload that takes an `error_code` reports errors in *ec* instead of throwing, and clears the stored path if the refresh fails. + +## operator= + +Assigns to the `directory_entry`. + +```cpp +directory_entry& operator=(const directory_entry&) = default; +directory_entry& operator=(directory_entry&&) noexcept = default; +``` + +### Parameters + +*right*\ +The `directory_entry` to copy or move into this `directory_entry`. + +### Remarks + +The defaulted assignment operators behave as expected. ## assign -The member function assigns *pval* to `mypath`, *stat_arg* to `mystat`, and *symstat_arg* to `mysymstat`. +Replaces the stored path and refreshes the cached attributes. ```cpp -void assign(const std::experimental::filesystem::path& pval, - file_status stat_arg = file_status(), - file_status symstat_arg = file_status()); +void assign(const std::filesystem::path& p); +void assign(const std::filesystem::path& p, std::error_code& ec); ``` ### Parameters -*pval*\ -The stored file name path. +*p*\ +The new path to store. + +*ec*\ +The output error code for the operation. -*stat_arg*\ -The status of the stored file name. +### Remarks -*symstat_arg*\ -The symbolic link status of the stored file name. +Replaces the stored path with *p*, then calls [`refresh`](#refresh) to update the cached attributes. The overload that takes an `error_code` reports errors in *ec* instead of throwing. -## directory_entry +## replace_filename -The defaulted constructors behave as expected. The fourth constructor initializes `mypath` to *pval*, `mystat` to *stat_arg*, and `mysymstat` to *symstat_arg*. +Replaces the filename of the stored path and refreshes the cached attributes. ```cpp -directory_entry() = default; -directory_entry(const directory_entry&) = default; -directory_entry(directory_entry&&) noexcept = default; -explicit directory_entry(const std::experimental::filesystem::path& pval, - file_status stat_arg = file_status(), - file_status symstat_arg = file_status()); +void replace_filename(const std::filesystem::path& p); +void replace_filename(const std::filesystem::path& p, std::error_code& ec); ``` ### Parameters -*pval*\ -The stored file name path. +*p*\ +The replacement filename. -*stat_arg*\ -The status of the stored file name. +*ec*\ +The output error code for the operation. -*symstat_arg*\ -The symbolic link status of the stored file name. +### Remarks -## operator!= +Replaces the filename component of the stored path with *p*, as if by `path().replace_filename(p)`, then calls [`refresh`](#refresh). The overload that takes an `error_code` reports errors in *ec* instead of throwing. + +## refresh -The member function returns `!(*this == right)`. +Refreshes the cached file attributes. ```cpp -bool operator!=(const directory_entry& right) const noexcept; +void refresh(); +void refresh(std::error_code& ec) noexcept; ``` ### Parameters -*right*\ -The [directory_entry](../standard-library/directory-entry-class.md) being compared to the `directory_entry`. +*ec*\ +The output error code for the operation. -## operator= +### Remarks + +Reads the attributes of the file that the stored path refers to and caches them in the `directory_entry`. Call `refresh` to update the cached data after the referenced file changes. The overload that takes an `error_code` reports errors in *ec* instead of throwing. -The defaulted member assignment operators behave as expected. +## path + +Returns the stored path. ```cpp -directory_entry& operator=(const directory_entry&) = default; -directory_entry& operator=(directory_entry&&) noexcept = default; +const std::filesystem::path& path() const noexcept; +``` + +## operator const path& + +Returns the stored path. + +```cpp +operator const std::filesystem::path&() const noexcept; +``` + +## exists + +Checks whether the entry refers to an existing file. + +```cpp +bool exists() const; +bool exists(std::error_code& ec) const noexcept; ``` ### Parameters -*right*\ -The [directory_entry](../standard-library/directory-entry-class.md) being copied into the `directory_entry`. +*ec*\ +The output error code for the operation. -## operator== +### Return value + +`true` if the stored path refers to an existing file; otherwise, `false`. Equivalent to calling `filesystem::exists(status())`. + +## is_block_file -The member function returns `mypath == right.mypath`. +Checks whether the referenced file is a block special file. ```cpp -bool operator==(const directory_entry& right) const noexcept; +bool is_block_file() const; +bool is_block_file(std::error_code& ec) const noexcept; ``` ### Parameters -*right*\ -The [directory_entry](../standard-library/directory-entry-class.md) being compared to the `directory_entry`. +*ec*\ +The output error code for the operation. -## `operator<` +### Return value -The member function returns `mypath < right.mypath`. +`true` if the referenced file is a block special file; otherwise, `false`. This function always returns `false` on Windows. + +## is_character_file + +Checks whether the referenced file is a character special file. ```cpp -bool operator<(const directory_entry& right) const noexcept; +bool is_character_file() const; +bool is_character_file(std::error_code& ec) const noexcept; ``` ### Parameters -*right*\ -The [directory_entry](../standard-library/directory-entry-class.md) being compared to the `directory_entry`. +*ec*\ +The output error code for the operation. -## `operator<=` +### Return value + +`true` if the referenced file is a character special file; otherwise, `false`. This function always returns `false` on Windows. + +## is_directory -The member function returns `!(right < *this)`. +Checks whether the referenced file is a directory. ```cpp -bool operator<=(const directory_entry& right) const noexcept; +bool is_directory() const; +bool is_directory(std::error_code& ec) const noexcept; ``` ### Parameters -*right*\ -The [directory_entry](../standard-library/directory-entry-class.md) being compared to the `directory_entry`. +*ec*\ +The output error code for the operation. -## `operator>` +### Return value + +`true` if the referenced file is a directory; otherwise, `false`. Equivalent to calling `filesystem::is_directory(status())`. -The member function returns `right < *this`. +## is_fifo + +Checks whether the referenced file is a named pipe (FIFO). ```cpp -bool operator>(const directory_entry& right) const noexcept; +bool is_fifo() const; +bool is_fifo(std::error_code& ec) const noexcept; ``` ### Parameters -*right*\ -The [directory_entry](../standard-library/directory-entry-class.md) being compared to the `directory_entry`. +*ec*\ +The output error code for the operation. -## `operator>=` +### Return value -The member function returns `!(*this < right)`. +`true` if the referenced file is a FIFO; otherwise, `false`. This function always returns `false` on Windows. + +## is_other + +Checks whether the referenced file is an other file. ```cpp -bool operator>=(const directory_entry& right) const noexcept; +bool is_other() const; +bool is_other(std::error_code& ec) const noexcept; ``` ### Parameters -*right*\ -The [directory_entry](../standard-library/directory-entry-class.md) being compared to the `directory_entry`. +*ec*\ +The output error code for the operation. -## operator const path_type& +### Return value -The member operator returns `mypath`. +`true` if the referenced file exists but isn't a regular file, directory, or symbolic link; otherwise, `false`. Equivalent to calling `filesystem::is_other(status())`. + +## is_regular_file + +Checks whether the referenced file is a regular file. ```cpp -operator const std::experimental::filesystem::path&() const; +bool is_regular_file() const; +bool is_regular_file(std::error_code& ec) const noexcept; ``` -## path +### Parameters + +*ec*\ +The output error code for the operation. + +### Return value -The member function returns `mypath`. +`true` if the referenced file is a regular file; otherwise, `false`. Equivalent to calling `filesystem::is_regular_file(status())`. + +## is_socket + +Checks whether the referenced file is a socket. ```cpp -const std::experimental::filesystem::path& path() const noexcept; +bool is_socket() const; +bool is_socket(std::error_code& ec) const noexcept; ``` -## replace_filename +### Parameters -The member function replaces `mypath` with `mypath.parent_path()` / *pval*, `mystat` with *stat_arg*, and `mysymstat` with *symstat_arg* +*ec*\ +The output error code for the operation. + +### Return value + +`true` if the referenced file is a socket; otherwise, `false`. This function always returns `false` on Windows. + +## is_symlink + +Checks whether the referenced file is a symbolic link. ```cpp -void replace_filename( - const std::experimental::filesystem::path& pval, - file_status stat_arg = file_status(), - file_status symstat_arg = file_status()); +bool is_symlink() const; +bool is_symlink(std::error_code& ec) const noexcept; ``` ### Parameters -*pval*\ -The stored file name path. +*ec*\ +The output error code for the operation. -*stat_arg*\ -The status of the stored file name. +### Return value -*symstat_arg*\ -The symbolic link status of the stored file name. +`true` if the referenced file is a symbolic link; otherwise, `false`. Equivalent to calling `filesystem::is_symlink(symlink_status())`. -## status +## file_size + +Gets the size, in bytes, of the referenced file. + +```cpp +uintmax_t file_size() const; +uintmax_t file_size(std::error_code& ec) const noexcept; +``` + +### Parameters + +*ec*\ +The output error code for the operation. + +### Return value + +The size, in bytes, of the referenced file, as if by `filesystem::file_size(path())`. Uses cached data when it's available. + +## hard_link_count + +Gets the number of hard links to the referenced file. + +```cpp +uintmax_t hard_link_count() const; +uintmax_t hard_link_count(std::error_code& ec) const noexcept; +``` + +### Parameters + +*ec*\ +The output error code for the operation. + +### Return value + +The number of hard links to the referenced file, as if by `filesystem::hard_link_count(path())`. Uses cached data when it's available. + +## last_write_time + +Gets the time of the last data modification of the referenced file. + +```cpp +file_time_type last_write_time() const; +file_time_type last_write_time(std::error_code& ec) const noexcept; +``` + +### Parameters + +*ec*\ +The output error code for the operation. + +### Return value -Both member functions return `mystat` possibly first altered as follows: +The time of the last data modification of the referenced file, as if by `filesystem::last_write_time(path())`. Uses cached data when it's available. -1. If `status_known(mystat)` then do nothing. +## status -1. Otherwise, if `!status_known(mysymstat) && !is_symlink(mysymstat)` then `mystat = mysymstat`. +Gets the status of the referenced file, following symbolic links. ```cpp file_status status() const; -file_status status(error_code& ec) const noexcept; +file_status status(std::error_code& ec) const noexcept; ``` ### Parameters *ec*\ -The status error code. +The output error code for the operation. + +### Return value + +The status of the referenced file, as if by `filesystem::status(path())`. Uses cached data when it's available. ## symlink_status -Both member functions return `mysymstat` possibly first altered as follows: If `status_known(mysymstat)` then do nothing. Otherwise, `mysymstat = symlink_status(mypval)`. +Gets the status of the referenced file, without following symbolic links. ```cpp file_status symlink_status() const; -file_status symlink_status(error_code& ec) const noexcept; +file_status symlink_status(std::error_code& ec) const noexcept; ``` ### Parameters *ec*\ -The status error code. +The output error code for the operation. + +### Return value + +The symlink status of the referenced file, as if by `filesystem::symlink_status(path())`. Uses cached data when it's available. + +## operator== + +Checks whether two `directory_entry` objects are equal. + +```cpp +bool operator==(const directory_entry& right) const noexcept; +``` + +### Parameters + +*right*\ +The `directory_entry` to compare against. + +### Return value + +Returns `path() == right.path()`. + +## `operator<=>` + +Performs a three-way comparison of two `directory_entry` objects. + +```cpp +std::strong_ordering operator<=>(const directory_entry& right) const noexcept; // C++20 +``` + +### Parameters + +*right*\ +The `directory_entry` to compare against. + +### Return value + +Returns `path() <=> right.path()`. + +### Remarks + +Available in C++20 and later. The compiler rewrites comparisons that use `operator<`, `operator<=`, `operator>`, or `operator>=` to use this operator. It rewrites comparisons that use `operator!=` to use [`operator==`](#op_eq). + +## operator!= + +Checks whether two `directory_entry` objects are unequal. + +```cpp +bool operator!=(const directory_entry& right) const noexcept; // C++17 +``` + +### Parameters + +*right*\ +The `directory_entry` to compare against. + +### Return value + +Returns `!(*this == right)`. + +### Remarks + +In C++17, this operator is an explicitly declared member function. In C++20 and later, an expression that uses `operator!=` is rewritten to use [`operator==`](#op_eq). + +## `operator<` + +Checks whether the `directory_entry` sorts before another `directory_entry`. + +```cpp +bool operator<(const directory_entry& right) const noexcept; // C++17 +``` + +### Parameters + +*right*\ +The `directory_entry` to compare against. + +### Return value + +Returns `path() < right.path()`. + +### Remarks + +In C++17, this operator is an explicitly declared member function. In C++20 and later, an expression that uses `operator<` is rewritten to use [`operator<=>`](#op_spaceship). + +## `operator<=` + +Checks whether the `directory_entry` sorts before or equal to another `directory_entry`. + +```cpp +bool operator<=(const directory_entry& right) const noexcept; // C++17 +``` + +### Parameters + +*right*\ +The `directory_entry` to compare against. + +### Return value + +Returns `!(right < *this)`. + +### Remarks + +In C++17, this operator is an explicitly declared member function. In C++20 and later, an expression that uses `operator<=` is rewritten to use [`operator<=>`](#op_spaceship). + +## `operator>` + +Checks whether the `directory_entry` sorts after another `directory_entry`. + +```cpp +bool operator>(const directory_entry& right) const noexcept; // C++17 +``` + +### Parameters + +*right*\ +The `directory_entry` to compare against. + +### Return value + +Returns `right < *this`. + +### Remarks + +In C++17, this operator is an explicitly declared member function. In C++20 and later, an expression that uses `operator>` is rewritten to use [`operator<=>`](#op_spaceship). + +## `operator>=` + +Checks whether the `directory_entry` sorts after or equal to another `directory_entry`. + +```cpp +bool operator>=(const directory_entry& right) const noexcept; // C++17 +``` + +### Parameters + +*right*\ +The `directory_entry` to compare against. + +### Return value + +Returns `!(*this < right)`. + +### Remarks + +In C++17, this operator is an explicitly declared member function. In C++20 and later, an expression that uses `operator>=` is rewritten to use [`operator<=>`](#op_spaceship). ## See also [Header Files Reference](../standard-library/cpp-standard-library-header-files.md)\ -[``](../standard-library/filesystem.md) +[``](../standard-library/filesystem.md)\ +[File System Navigation (C++)](../standard-library/file-system-navigation.md) diff --git a/docs/standard-library/directory-iterator-class.md b/docs/standard-library/directory-iterator-class.md index b377693eee2..59ace314944 100644 --- a/docs/standard-library/directory-iterator-class.md +++ b/docs/standard-library/directory-iterator-class.md @@ -1,10 +1,9 @@ --- description: "Learn more about: directory_iterator Class" title: "directory_iterator Class" -ms.date: 04/28/2023 +ms.date: 08/27/2026 f1_keywords: ["filesystem/std::filesystem::directory_iterator", "filesystem/std::filesystem::_Directory_iterator::_Directory_iterator", "filesystem/std::filesystem::directory_iterator::directory_iterator", "filesystem/std::filesystem::directory_iterator::increment", "filesystem/std::filesystem::directory_iterator::operator=", "filesystem/std::filesystem::directory_iterator::operator==", "filesystem/std::filesystem::directory_iterator::operator!=", "filesystem/std::filesystem::directory_iterator::operator*", "filesystem/std::filesystem::directory_iterator::operator->", "filesystem/std::filesystem::directory_iterator::operator++"] -ms.assetid: dca2ecf8-3e69-4644-a83d-705061e10cc8 -helpviewer_keywords: ["std::filesystem::directory_iterator", "std::filesystem::_Directory_iterator::_Directory_iterator", "std::filesystem::directory_iterator", "std::filesystem::directory_iterator::directory_iterator", "std::filesystem::directory_iterator::increment", "std::filesystem::directory_iterator::operator=", "std::filesystem::directory_iterator::operator==", "std::filesystem::directory_iterator::operator!=", "std::filesystem::directory_iterator::operator*", "std::filesystem::directory_iterator::operator->", "std::filesystem::directory_iterator::operator++"] +helpviewer_keywords: ["std::filesystem::directory_iterator", "std::filesystem::_Directory_iterator::_Directory_iterator", "std::filesystem::directory_iterator::directory_iterator", "std::filesystem::directory_iterator::increment", "std::filesystem::directory_iterator::operator=", "std::filesystem::directory_iterator::operator==", "std::filesystem::directory_iterator::operator!=", "std::filesystem::directory_iterator::operator*", "std::filesystem::directory_iterator::operator->", "std::filesystem::directory_iterator::operator++"] ms.custom: devdivchpfy22 --- @@ -59,15 +58,14 @@ class directory_iterator; ## `directory_iterator::directory_iterator` -The first constructor produces an end-of-sequence iterator. The second and third constructors store *`pval`* in `mydir`, then attempt to open and read `mydir` as a directory. If successful, they store the first filename in the directory in `myentry`; otherwise they produce an end-of-sequence iterator. - -The default constructor behaves as expected. +The first constructor produces an end-of-sequence iterator. The constructors that take a *`pval`* argument store it in `mydir`, then attempt to open and read `mydir` as a directory. If successful, they store the first filename in the directory in `myentry`; otherwise they produce an end-of-sequence iterator. The overloads that take an *`options`* argument control how the directory is enumerated. The overloads that take an *`ec`* argument report errors in *`ec`* instead of throwing an exception. The copy and move constructors behave as expected. ```cpp directory_iterator() noexcept; explicit directory_iterator(const path& pval); - +directory_iterator(const path& pval, directory_options options); directory_iterator(const path& pval, error_code& ec) noexcept; +directory_iterator(const path& pval, directory_options options, error_code& ec) noexcept; directory_iterator(const directory_iterator&) = default; directory_iterator(directory_iterator&&) noexcept = default; ``` @@ -77,6 +75,9 @@ directory_iterator(directory_iterator&&) noexcept = default; *`pval`*\ The stored file name path. +*`options`*\ +The `directory_options` value that controls how the directory is enumerated. The default is `directory_options::none`. + *`ec`*\ The status error code. @@ -88,9 +89,14 @@ The stored object. The function attempts to advance to the next filename in the directory. If successful, it stores that filename in `myentry`; otherwise it produces an end-of-sequence iterator. ```cpp -directory_iterator& increment(error_code& ec) noexcept; +directory_iterator& increment(error_code& ec); ``` +### Parameters + +*`ec`*\ +The status error code. + ## `directory_iterator::operator!=` The member operator returns `!(*this == right)`. @@ -153,13 +159,13 @@ The first member function calls `increment()`, then returns **`*this`**. The sec ```cpp directory_iterator& operator++(); -directory_iterator& operator++(int); +directory_iterator operator++(int); ``` ### Parameters *`int`*\ -The number of increments. +Dummy argument. It's a C++ convention used only to distinguish the postfix increment operator from the prefix increment operator. The C++ standard requires the postfix form to take a dummy int parameter. ## See also diff --git a/docs/standard-library/experimental-filesystem-directory-entry-class.md b/docs/standard-library/experimental-filesystem-directory-entry-class.md new file mode 100644 index 00000000000..2b9227a4b4e --- /dev/null +++ b/docs/standard-library/experimental-filesystem-directory-entry-class.md @@ -0,0 +1,272 @@ +--- +description: "Learn more about: directory_entry class" +title: " directory_entry class" +ms.date: 08/27/2026 +f1_keywords: ["filesystem/std::experimental::filesystem::directory_entry", "filesystem/std::experimental::filesystem::directory_entry::operator const std::experimental::filesystem::path &", "filesystem/std::experimental::filesystem::directory_entry::directory_entry", "filesystem/std::experimental::filesystem::directory_entry::operator=", "filesystem/std::experimental::filesystem::directory_entry::assign", "filesystem/std::experimental::filesystem::directory_entry::replace_filename", "filesystem/std::experimental::filesystem::directory_entry::path", "filesystem/std::experimental::filesystem::directory_entry::status", "filesystem/std::experimental::filesystem::directory_entry::symlink_status", "filesystem/std::experimental::filesystem::directory_entry::operator<", "filesystem/std::experimental::filesystem::directory_entry::operator==", "filesystem/std::experimental::filesystem::directory_entry::operator!=", "filesystem/std::experimental::filesystem::directory_entry::operator<=", "filesystem/std::experimental::filesystem::directory_entry::operator>", "filesystem/std::experimental::filesystem::directory_entry::operator>="] +helpviewer_keywords: ["std::experimental::filesystem::directory_entry", "std::experimental::filesystem::directory_entry::operator const std::experimental::filesystem::path &", "std::experimental::filesystem::directory_entry::directory_entry", "std::experimental::filesystem::directory_entry::operator=", "std::experimental::filesystem::directory_entry::assign", "std::experimental::filesystem::directory_entry::replace_filename", "std::experimental::filesystem::directory_entry::path", "std::experimental::filesystem::directory_entry::status", "std::experimental::filesystem::directory_entry::symlink_status", "std::experimental::filesystem::directory_entry::operator<", "std::experimental::filesystem::directory_entry::operator==", "std::experimental::filesystem::directory_entry::operator!=", "std::experimental::filesystem::directory_entry::operator<=", "std::experimental::filesystem::directory_entry::operator>", "std::experimental::filesystem::directory_entry::operator>="] +ms.custom: devdivchpfy22 +--- + +# `` `directory_entry` class + +> [!IMPORTANT] +> This article describes the prestandard `std::experimental::filesystem` implementation of `directory_entry`. This implementation is based on the File System Technical Specification, found in [ISO/IEC JTC 1/SC 22/WG 21 N4100](https://wg21.link/n4100). It isn't `std::filesystem`, and it isn't compatible with the C++17 `std::filesystem` implementation. The experimental implementation was removed starting in MSVC toolset version 14.51. For the current C++17 `std::filesystem` version, see [`directory_entry` class](../standard-library/directory-entry-class.md). + +Describes an object that is returned by `*X`, where *X* is a [`directory_iterator`](../standard-library/experimental-filesystem-directory-iterator-class.md) or a [`recursive_directory_iterator`](../standard-library/experimental-filesystem-recursive-directory-iterator-class.md). + +## Syntax + +```cpp +class directory_entry; +``` + +## Remarks + +The class stores an object of type [`path`](../standard-library/experimental-filesystem-path-class.md). The stored `path` can be an instance of the `path` class or of a type that is derived from `path`. It also stores two [`file_type`](../standard-library/experimental-filesystem-enumerations.md#file_type) values. One value represents the status of the stored file name. The other represents the symbolic link status of the file name. + +### Constructors + +|Constructor|Description| +|-|-| +|[`directory_entry`](#directory_entry)|The defaulted constructors behave as expected. The fourth constructor initializes `mypath` to *pval*, `mystat` to *stat_arg*, and `mysymstat` to *symstat_arg*.| + +### Member functions + +|Member function|Description| +|-|-| +|[`assign`](#assign)|The member function assigns *pval* to `mypath`, *stat* to `mystat`, and *symstat* to `mysymstat`.| +|[`path`](#path)|The member function returns `mypath`.| +|[`replace_filename`](#replace_filename)|The member function replaces `mypath` with `mypath.parent_path()` / *pval*, `mystat` with *stat_arg*, and `mysymstat` with *symstat_arg*| +|[`status`](#status)|Both member functions return `mystat` possibly first altered.| +|[`symlink_status`](#symlink_status)|Both member functions return `mysymstat` possibly first altered.| + +### Operators + +|Operator|Description| +|-|-| +|[`operator!=`](#op_neq)|Returns `!(*this == right)`.| +|[`operator=`](#op_as)|The defaulted member assignment operators behave as expected.| +|[`operator==`](#op_eq)|Returns `mypath == right.mypath`.| +|[`operator<`](#op_lt)|Returns `mypath < right.mypath`.| +|[`operator<=`](#op_lteq)|Returns `!(right < *this)`.| +|[`operator>`](#op_gt)|Returns `right < *this`.| +|[`operator>=`](#op_gteq)|Returns `!(*this < right)`.| +|[`operator const path_type&`](#path_type)|Returns `mypath`.| + +## Requirements + +**Header:** `` + +**Namespace:** `std::experimental::filesystem` + +## assign + +The member function assigns *pval* to `mypath`, *stat_arg* to `mystat`, and *symstat_arg* to `mysymstat`. + +```cpp +void assign(const std::experimental::filesystem::path& pval, + file_status stat_arg = file_status(), + file_status symstat_arg = file_status()); +``` + +### Parameters + +*pval*\ +The stored file name path. + +*stat_arg*\ +The status of the stored file name. + +*symstat_arg*\ +The symbolic link status of the stored file name. + +## directory_entry + +The defaulted constructors behave as expected. The fourth constructor initializes `mypath` to *pval*, `mystat` to *stat_arg*, and `mysymstat` to *symstat_arg*. + +```cpp +directory_entry() = default; +directory_entry(const directory_entry&) = default; +directory_entry(directory_entry&&) noexcept = default; +explicit directory_entry(const std::experimental::filesystem::path& pval, + file_status stat_arg = file_status(), + file_status symstat_arg = file_status()); +``` + +### Parameters + +*pval*\ +The stored file name path. + +*stat_arg*\ +The status of the stored file name. + +*symstat_arg*\ +The symbolic link status of the stored file name. + +## operator!= + +The member function returns `!(*this == right)`. + +```cpp +bool operator!=(const directory_entry& right) const noexcept; +``` + +### Parameters + +*right*\ +The [directory_entry](../standard-library/experimental-filesystem-directory-entry-class.md) being compared to the `directory_entry`. + +## operator= + +The defaulted member assignment operators behave as expected. + +```cpp +directory_entry& operator=(const directory_entry&) = default; +directory_entry& operator=(directory_entry&&) noexcept = default; +``` + +### Parameters + +*right*\ +The [directory_entry](../standard-library/experimental-filesystem-directory-entry-class.md) being copied into the `directory_entry`. + +## operator== + +The member function returns `mypath == right.mypath`. + +```cpp +bool operator==(const directory_entry& right) const noexcept; +``` + +### Parameters + +*right*\ +The [directory_entry](../standard-library/experimental-filesystem-directory-entry-class.md) being compared to the `directory_entry`. + +## `operator<` + +The member function returns `mypath < right.mypath`. + +```cpp +bool operator<(const directory_entry& right) const noexcept; +``` + +### Parameters + +*right*\ +The [directory_entry](../standard-library/experimental-filesystem-directory-entry-class.md) being compared to the `directory_entry`. + +## `operator<=` + +The member function returns `!(right < *this)`. + +```cpp +bool operator<=(const directory_entry& right) const noexcept; +``` + +### Parameters + +*right*\ +The [directory_entry](../standard-library/experimental-filesystem-directory-entry-class.md) being compared to the `directory_entry`. + +## `operator>` + +The member function returns `right < *this`. + +```cpp +bool operator>(const directory_entry& right) const noexcept; +``` + +### Parameters + +*right*\ +The [directory_entry](../standard-library/experimental-filesystem-directory-entry-class.md) being compared to the `directory_entry`. + +## `operator>=` + +The member function returns `!(*this < right)`. + +```cpp +bool operator>=(const directory_entry& right) const noexcept; +``` + +### Parameters + +*right*\ +The [directory_entry](../standard-library/experimental-filesystem-directory-entry-class.md) being compared to the `directory_entry`. + +## operator const path_type& + +The member operator returns `mypath`. + +```cpp +operator const std::experimental::filesystem::path&() const; +``` + +## path + +The member function returns `mypath`. + +```cpp +const std::experimental::filesystem::path& path() const noexcept; +``` + +## replace_filename + +The member function replaces `mypath` with `mypath.parent_path()` / *pval*, `mystat` with *stat_arg*, and `mysymstat` with *symstat_arg* + +```cpp +void replace_filename( + const std::experimental::filesystem::path& pval, + file_status stat_arg = file_status(), + file_status symstat_arg = file_status()); +``` + +### Parameters + +*pval*\ +The stored file name path. + +*stat_arg*\ +The status of the stored file name. + +*symstat_arg*\ +The symbolic link status of the stored file name. + +## status + +Both member functions return `mystat` possibly first altered as follows: + +1. If `status_known(mystat)` then do nothing. + +1. Otherwise, if `!status_known(mysymstat) && !is_symlink(mysymstat)` then `mystat = mysymstat`. + +```cpp +file_status status() const; +file_status status(error_code& ec) const noexcept; +``` + +### Parameters + +*ec*\ +The status error code. + +## symlink_status + +Both member functions return `mysymstat` possibly first altered as follows: If `status_known(mysymstat)` then do nothing. Otherwise, `mysymstat = symlink_status(mypval)`. + +```cpp +file_status symlink_status() const; +file_status symlink_status(error_code& ec) const noexcept; +``` + +### Parameters + +*ec*\ +The status error code. + +## See also + +[``](../standard-library/experimental-filesystem.md)\ +[`path` class](../standard-library/experimental-filesystem-path-class.md) diff --git a/docs/standard-library/experimental-filesystem-directory-iterator-class.md b/docs/standard-library/experimental-filesystem-directory-iterator-class.md new file mode 100644 index 00000000000..e957505d84a --- /dev/null +++ b/docs/standard-library/experimental-filesystem-directory-iterator-class.md @@ -0,0 +1,169 @@ +--- +description: "Learn more about: directory_iterator class" +title: " directory_iterator class" +ms.date: 08/27/2026 +f1_keywords: ["filesystem/std::experimental::filesystem::directory_iterator", "filesystem/std::experimental::filesystem::directory_iterator::directory_iterator", "filesystem/std::experimental::filesystem::directory_iterator::increment", "filesystem/std::experimental::filesystem::directory_iterator::operator=", "filesystem/std::experimental::filesystem::directory_iterator::operator==", "filesystem/std::experimental::filesystem::directory_iterator::operator!=", "filesystem/std::experimental::filesystem::directory_iterator::operator*", "filesystem/std::experimental::filesystem::directory_iterator::operator->", "filesystem/std::experimental::filesystem::directory_iterator::operator++"] +helpviewer_keywords: ["std::experimental::filesystem::directory_iterator", "std::experimental::filesystem::directory_iterator::directory_iterator", "std::experimental::filesystem::directory_iterator::increment", "std::experimental::filesystem::directory_iterator::operator=", "std::experimental::filesystem::directory_iterator::operator==", "std::experimental::filesystem::directory_iterator::operator!=", "std::experimental::filesystem::directory_iterator::operator*", "std::experimental::filesystem::directory_iterator::operator->", "std::experimental::filesystem::directory_iterator::operator++"] +--- + +# `` `directory_iterator` class + +> [!IMPORTANT] +> This page describes the `directory_iterator` class from the prestandard `` implementation of the ISO C++ Filesystem Technical Specification (N4100). This API isn't the same as the C++17 [`directory_iterator`](directory-iterator-class.md) class in ``. It uses different signatures, including a narrower set of constructors that has no `directory_options` overload. The experimental implementation was removed starting with the Microsoft Visual C++ (MSVC) 14.51 toolset. New code should use the C++17 [`directory_iterator`](directory-iterator-class.md) class instead. + +Describes an input iterator that sequences through the filenames in a directory. For an iterator `X`, the expression `*X` evaluates to an object of class `directory_entry` that wraps the filename and anything known about its status. + +The class stores an object of type `path`, called `mydir` here for the purposes of exposition, which represents the name of the directory to be sequenced, and an object of type `directory_entry` called `myentry` here, which represents the current filename in the directory sequence. A default constructed object of type `directory_entry` has an empty `mydir` pathname and represents the end-of-sequence iterator. + +For example, given the directory `abc` with entries `def` and `ghi`, the code: + +`for (directory_iterator next(path("abc")), end; next != end; ++next) visit(next->path());` + +calls `visit` with the arguments `path("abc/def")` and `path("abc/ghi")`. + +## Syntax + +```cpp +class directory_iterator; +``` + +### Constructors + +|Constructor|Description| +|-|-| +|[`directory_iterator`](#directory_iterator)|Constructs an input iterator that sequences through the filenames in a directory.| + +### Member functions + +|Member function|Description| +|-|-| +|[`increment`](#increment)|Attempts to advance to the next filename in the directory.| + +### Operators + +|Operator|Description| +|-|-| +|[`operator!=`](#op_neq)|Returns `!(*this == right)`.| +|[`operator=`](#op_as)|The defaulted member assignment operators behave as expected.| +|[`operator==`](#op_eq)|Returns **`true`** only if both **`*this`** and *`right`* are end-of-sequence iterators or both aren't end-of-sequence-iterators.| +|[`operator*`](#op_star)|Returns `myentry`.| +|[`operator->`](#op_cast)|Returns `&**this`.| +|[`operator++`](#op_increment)|Calls `increment()`, then returns **`*this`**, or makes a copy of the object, calls `increment()`, then returns the copy.| + +## Requirements + +**Header:** `` + +**Namespace:** `std::experimental::filesystem` + +## `directory_iterator::directory_iterator` + +The first constructor produces an end-of-sequence iterator. The constructors that take a *`pval`* argument store it in `mydir`, then attempt to open and read `mydir` as a directory. If successful, they store the first filename in the directory in `myentry`; otherwise they produce an end-of-sequence iterator. The overload that takes an *`ec`* argument reports errors in *`ec`* instead of throwing an exception. The copy and move constructors behave as expected. + +```cpp +directory_iterator() noexcept; +explicit directory_iterator(const path& pval); + +directory_iterator(const path& pval, error_code& ec) noexcept; +directory_iterator(const directory_iterator&) = default; +directory_iterator(directory_iterator&&) = default; +``` + +### Parameters + +*`pval`*\ +The stored file name path. + +*`ec`*\ +The status error code. + +*`directory_iterator`*\ +The stored object. + +## `directory_iterator::increment` + +The function attempts to advance to the next filename in the directory. If successful, it stores that filename in `myentry`; otherwise it produces an end-of-sequence iterator. + +```cpp +directory_iterator& increment(error_code& ec) noexcept; +``` + +### Parameters + +*`ec`*\ +The status error code. + +## `directory_iterator::operator!=` + +The operator returns `!(*this == right)`. + +```cpp +bool operator!=(const directory_iterator& right) const; +``` + +### Parameters + +*`right`*\ +The `directory_iterator` being compared to the `directory_iterator`. + +## `directory_iterator::operator=` + +The defaulted member assignment operators behave as expected. + +```cpp +directory_iterator& operator=(const directory_iterator&) = default; +directory_iterator& operator=(directory_iterator&&) = default; +``` + +### Parameters + +*`right`*\ +The `directory_iterator` being copied into the `directory_iterator`. + +## `directory_iterator::operator==` + +The operator returns **`true`** only if both **`*this`** and *`right`* are end-of-sequence iterators or both aren't end-of-sequence-iterators. + +```cpp +bool operator==(const directory_iterator& right) const; +``` + +### Parameters + +*`right`*\ +The `directory_iterator` being compared to the `directory_iterator`. + +## `directory_iterator::operator*` + +The member operator returns `myentry`. + +```cpp +const directory_entry& operator*() const; +``` + +## `directory_iterator::operator->` + +The member function returns `&**this`. + +```cpp +const directory_entry * operator->() const; +``` + +## `directory_iterator::operator++` + +The first member function calls `increment()`, then returns **`*this`**. The second member function makes a copy of the object, calls `increment()`, then returns the copy. + +```cpp +directory_iterator& operator++(); +directory_iterator operator++(int); +``` + +### Parameters + +*`int`*\ +Dummy argument. It's a C++ convention used only to distinguish the postfix increment operator from the prefix increment operator. The C++ standard requires the postfix form to take a dummy int parameter. + +## See also + +[``](../standard-library/experimental-filesystem.md)\ +[`directory_entry` class](../standard-library/experimental-filesystem-directory-entry-class.md) diff --git a/docs/standard-library/experimental-filesystem-enumerations.md b/docs/standard-library/experimental-filesystem-enumerations.md new file mode 100644 index 00000000000..2cc015abae6 --- /dev/null +++ b/docs/standard-library/experimental-filesystem-enumerations.md @@ -0,0 +1,162 @@ +--- +description: "Learn more about: enumerations" +title: " enumerations" +ms.date: 08/27/2026 +f1_keywords: ["filesystem/std::experimental::filesystem::copy_options", "filesystem/std::experimental::filesystem::directory_options", "filesystem/std::experimental::filesystem::file_type", "filesystem/std::experimental::filesystem::perms"] +helpviewer_keywords: ["std::experimental::filesystem::copy_options", "std::experimental::filesystem::directory_options", "std::experimental::filesystem::file_type", "std::experimental::filesystem::perms"] +--- +# `` enumerations + +> [!IMPORTANT] +> The `` header and the `std::experimental::filesystem` namespace provided a prestandard implementation of the File System Technical Specification (TS). This documentation is retained for code written against MSVC's original filesystem implementation, which was removed starting in MSVC version 14.51. For new code, use the C++17 [``](../standard-library/filesystem.md) header and the `std::filesystem` namespace instead. For the standard equivalents of these enumerations, see [`` enumerations](../standard-library/filesystem-enumerations.md). + +This article documents the enumerations in the historical prestandard `std::experimental::filesystem` implementation. + +## Requirements + +**Header:** `` + +**Namespace:** `std::experimental::filesystem` + +## copy_options + +An enumeration of bitmask values that is used with [copy](experimental-filesystem-functions.md#copy) and [copy_file](experimental-filesystem-functions.md#copy_file) functions to specify behavior. + +### Syntax + +```cpp +enum class copy_options { + none = 0, + skip_existing = 1, + overwrite_existing = 2, + update_existing = 4, + recursive = 8, + copy_symlinks = 16, + skip_symlinks = 32, + directories_only = 64, + create_symlinks = 128, + create_hard_links = 256 +}; +``` + +### Values + +| Name | Description | +|------------|-----------------| +|`none`|Perform the default behavior for the operation.| +|`skip_existing`|Do not copy if the file already exists, do not report an error.| +|`overwrite_existing`|Overwrite the file if it already exists.| +|`update_existing`|Overwrite the file if it already exists and is older than the replacement.| +|`recursive`|Recursively copy subdirectories and their contents.| +|`copy_symlinks`|Copy symbolic links as symbolic links, instead of copying the files they point to.| +|`skip_symlinks`|Ignore symbolic links.| +|`directories_only`|Only iterate over directories, ignore files.| +|`create_symlinks`|Make symbolic links instead of copying files. An absolute path must be used as the source path unless the destination is the current directory.| +|`create_hard_links`|Make hard links instead of copying files.| + +## directory_options + +A bitmask enumeration that controls how directory iteration handles symbolic links to directories. + +### Syntax + +```cpp +enum class directory_options { + none = 0, + follow_directory_symlink = 1 +}; +``` + +### Values + +|Name|Description| +|----------|-----------------| +|`none`|Default behavior: don't follow symbolic links to directories.| +|`follow_directory_symlink`|Follow symbolic links to directories rather than skipping them.| + +## file_type + +An enumeration for file types. + +### Syntax + +```cpp +enum class file_type { + not_found = -1, + none = 0, + regular, + directory, + symlink, + block, + character, + fifo, + socket, + unknown +}; +``` + +The underlying integer values of these enumerators aren't fixed, so don't depend on specific numeric values. + +### Values + +|Name|Description| +|----------|-----------------| +|`none`|The file type hasn't been evaluated yet, or an error occurred when evaluating it.| +|`not_found`|The file wasn't found.| +|`regular`|A regular file.| +|`directory`|A directory.| +|`symlink`|A symbolic link.| +|`block`|A block-special file. (Not used on Windows.)| +|`character`|A character-special file. (Not used on Windows.)| +|`fifo`|A FIFO or pipe file. (Not used on Windows.)| +|`socket`|A socket. (Not used on Windows.)| +|`unknown`|The file exists but its type can't be determined.| + +## perms + +A bitmask enumeration of file permission bits together with the control flags that the [`permissions`](experimental-filesystem-functions.md#permissions) function uses to decide how to apply those bits. On Windows, the supported permission values are essentially "read-only" and `all`. For a read-only file, none of the `*_write` bits are set. Otherwise, the `all` bit (0777) is set. + +### Syntax + +```cpp +enum class perms {// names for permissions + none = 0, + owner_read = 0400, // S_IRUSR + owner_write = 0200, // S_IWUSR + owner_exec = 0100, // S_IXUSR + owner_all = 0700, // S_IRWXU + group_read = 040, // S_IRGRP + group_write = 020, // S_IWGRP + group_exec = 010, // S_IXGRP + group_all = 070, // S_IRWXG + others_read = 04, // S_IROTH + others_write = 02, // S_IWOTH + others_exec = 01, // S_IXOTH + others_all = 07, // S_IRWXO + all = 0777, + set_uid = 04000, // S_ISUID + set_gid = 02000, // S_ISGID + sticky_bit = 01000, // S_ISVTX + mask = 07777, + unknown = 0xFFFF, + add_perms = 0x10000, // control flag + remove_perms = 0x20000, // control flag + resolve_symlinks = 0x40000 // control flag +}; +``` + +### Control flags + +Unlike the C++17 `std::filesystem` implementation, which controls the `permissions` function with a separate `perm_options` enumeration, the prestandard TS implementation carries the control flags in `perms` itself. + +|Name|Description| +|----------|-----------------| +|`add_perms`|Add the specified permission bits to the file's current permissions instead of replacing them.| +|`remove_perms`|Remove the specified permission bits from the file's current permissions.| +|`resolve_symlinks`|Resolve symbolic links so the permission change applies to the target file rather than the link.| + +## See also + +[``](../standard-library/experimental-filesystem.md)\ +[`` functions](../standard-library/experimental-filesystem-functions.md)\ +[`` operators](../standard-library/experimental-filesystem-operators.md) diff --git a/docs/standard-library/experimental-filesystem-error-class.md b/docs/standard-library/experimental-filesystem-error-class.md new file mode 100644 index 00000000000..1acb0db702d --- /dev/null +++ b/docs/standard-library/experimental-filesystem-error-class.md @@ -0,0 +1,105 @@ +--- +description: "Learn more about: filesystem_error Class" +title: " filesystem_error Class" +ms.date: 08/27/2026 +f1_keywords: ["filesystem/std::experimental::filesystem::filesystem_error"] +--- +# `` filesystem_error Class + +> [!IMPORTANT] +> This article describes the prestandard `` implementation of `filesystem_error`. It documents the historical File System Technical Specification ([ISO/IEC JTC 1/SC 22/WG 21 N4100](https://wg21.link/n4100)), not the C++17 `std::filesystem::filesystem_error` class. The experimental implementation was removed starting with MSVC version 14.51. For current code, use the standard [filesystem_error Class](../standard-library/filesystem-error-class.md). + +A base class for all exceptions that are thrown to report a low-level system error. + +## Syntax + +```cpp +class filesystem_error : public system_error; +``` + +## Remarks + +The class serves as the base class for all exceptions thrown to report an error in \ functions. It stores an object of type `string`, called `mymesg` here for the purposes of exposition. It also stores two objects of type `path`, called `mypval1` and `mypval2`. + +## Members + +### Constructors + +|Name|Description| +|-|-| +|[filesystem_error](#filesystem_error)|Constructs a `filesystem_error` message.| + +### Functions + +|Name|Description| +|-|-| +|[path1](#path1)|Returns `mypval1`| +|[path2](#path2)|Returns `mypval2`| +|[what](#what)|Returns a pointer to an `NTBS`.| + +## Requirements + +**Header:** \ + +**Namespace:** std::experimental::filesystem + +## filesystem_error + +The first constructor constructs its message from *what_arg* and *ec*. The second constructor also constructs its message from *pval1*, which it stores in `mypval1`. The third constructor also constructs its message from *pval1*, which it stores in `mypval1`, and from *pval2*, which it stores in `mypval2`. + +```cpp +filesystem_error(const string& what_arg, + error_code ec); + +filesystem_error(const string& what_arg, + const path& pval1, + error_code ec); + +filesystem_error(const string& what_arg, + const path& pval1, + const path& pval2, + error_code ec); +``` + +### Parameters + +*what_arg*\ +Specified message. + +*ec*\ +Specified error code. + +*mypval1*\ +Further specified message parameter. + +*mypval2*\ +Further specified message parameter. + +## path1 + +The member function returns `mypval1` + +```cpp +const path& path1() const noexcept; +``` + +## path2 + +The member function returns `mypval2` + +```cpp +const path& path2() const noexcept; +``` + +## what + +The member function returns a pointer to an `NTBS`, preferably composed from `runtime_error::what()`, `system_error::what()`, `mymesg`, `mypval1.native_string()`, and `mypval2.native_string()`. + +```cpp +const char *what() const noexcept; +``` + +## See also + +[``](../standard-library/experimental-filesystem.md)\ +[`path` class](../standard-library/experimental-filesystem-path-class.md) diff --git a/docs/standard-library/experimental-filesystem-file-status-class.md b/docs/standard-library/experimental-filesystem-file-status-class.md new file mode 100644 index 00000000000..9631d6b51f2 --- /dev/null +++ b/docs/standard-library/experimental-filesystem-file-status-class.md @@ -0,0 +1,120 @@ +--- +title: " file_status Class" +description: "Learn more about: file_status Class" +ms.date: 08/27/2026 +f1_keywords: ["filesystem/std::experimental::filesystem::file_status", "filesystem/std::experimental::filesystem::file_status::operator=", "filesystem/std::experimental::filesystem::file_status::type", "filesystem/std::experimental::filesystem::file_status::permissions"] +helpviewer_keywords: ["std::experimental::filesystem::file_status", "std::experimental::filesystem::file_status::operator=", "std::experimental::filesystem::file_status::type", "std::experimental::filesystem::file_status::permissions"] +--- +# `` file_status class + +> [!IMPORTANT] +> This article describes the prestandard `` implementation of `file_status`. It documents the historical File System Technical Specification ([ISO/IEC JTC 1/SC 22/WG 21 N4100](https://wg21.link/n4100)), not the C++17 `std::filesystem::file_status` class. The experimental implementation was removed starting with MSVC version 14.51. For current code, use the standard [file_status Class](../standard-library/file-status-class.md). + +Wraps a [`file_type`](../standard-library/experimental-filesystem-enumerations.md#file_type) and file [`perms`](../standard-library/experimental-filesystem-enumerations.md#perms). + +## Syntax + +```cpp +class file_status; +``` + +### Constructors + +|Constructor|Description| +|-|-| +|[file_status](#file_status)|Constructs a wrapper for [`file_type`](../standard-library/experimental-filesystem-enumerations.md#file_type) and file [`perms`](../standard-library/experimental-filesystem-enumerations.md#perms).| + +### Member functions + +|Member function|Description| +|-|-| +|[type](#type)|Gets or sets the `file_type`.| +|[permissions](#permissions)|Gets or sets the file permissions.| + +### Operators + +|Operator|Description| +|-|-| +|[operator=](#op_as)|The defaulted member assignment operators behave as expected.| + +## Requirements + +**Header:** \ + +**Namespace:** std::experimental::filesystem + +## file_status::file_status + +Constructs a wrapper for [`file_type`](../standard-library/experimental-filesystem-enumerations.md#file_type) and file [`perms`](../standard-library/experimental-filesystem-enumerations.md#perms). + +```cpp +explicit file_status( + file_type ftype = file_type::none, + perms mask = perms::unknown) noexcept; + +file_status(const file_status&) noexcept = default; + +file_status(file_status&&) noexcept = default; + +~file_status() noexcept = default; +``` + +### Parameters + +*ftype*\ +Specified `file_type`, defaults to `file_type::none`. + +*mask*\ +Specified file `perms`, defaults to `perms::unknown`. + +*file_status*\ +The stored object. + +## file_status::operator= + +The defaulted member assignment operators behave as expected. + +```cpp +file_status& operator=(const file_status&) noexcept = default; +file_status& operator=(file_status&&) noexcept = default; +``` + +### Parameters + +*file_status*\ +The [file_status](../standard-library/experimental-filesystem-file-status-class.md) being copied into the `file_status`. + +## type + +Gets or sets the `file_type`. + +```cpp +file_type type() const noexcept; +void type(file_type ftype) noexcept; +``` + +### Parameters + +*ftype*\ +Specified `file_type`. + +## permissions + +Gets or sets the file permissions. + +Use the setter to make a file `readonly` or remove the `readonly` attribute. + +```cpp +perms permissions() const noexcept; +void permissions(perms mask) noexcept; +``` + +### Parameters + +*mask*\ +Specified `perms`. + +## See also + +[``](../standard-library/experimental-filesystem.md)\ +[`path` class](../standard-library/experimental-filesystem-path-class.md) diff --git a/docs/standard-library/experimental-filesystem-functions.md b/docs/standard-library/experimental-filesystem-functions.md new file mode 100644 index 00000000000..c9d6bbc5ef5 --- /dev/null +++ b/docs/standard-library/experimental-filesystem-functions.md @@ -0,0 +1,497 @@ +--- +title: " functions" +description: "Learn more about: functions" +ms.date: 08/27/2026 +f1_keywords: ["filesystem/std::experimental::filesystem::absolute", "filesystem/std::experimental::filesystem::begin", "filesystem/std::experimental::filesystem::canonical", "filesystem/std::experimental::filesystem::copy", "filesystem/std::experimental::filesystem::copy_file", "filesystem/std::experimental::filesystem::copy_symlink", "filesystem/std::experimental::filesystem::create_directories", "filesystem/std::experimental::filesystem::create_directory", "filesystem/std::experimental::filesystem::create_directory_symlink", "filesystem/std::experimental::filesystem::create_hard_link", "filesystem/std::experimental::filesystem::create_symlink", "filesystem/std::experimental::filesystem::current_path", "filesystem/std::experimental::filesystem::end", "filesystem/std::experimental::filesystem::equivalent", "filesystem/std::experimental::filesystem::exists", "filesystem/std::experimental::filesystem::file_size", "filesystem/std::experimental::filesystem::hard_link_count", "filesystem/std::experimental::filesystem::hash_value", "filesystem/std::experimental::filesystem::is_block_file", "filesystem/std::experimental::filesystem::is_character_file", "filesystem/std::experimental::filesystem::is_directory", "filesystem/std::experimental::filesystem::is_empty", "filesystem/std::experimental::filesystem::is_fifo", "filesystem/std::experimental::filesystem::is_other", "filesystem/std::experimental::filesystem::is_regular_file", "filesystem/std::experimental::filesystem::is_socket", "filesystem/std::experimental::filesystem::is_symlink", "filesystem/std::experimental::filesystem::last_write_time", "filesystem/std::experimental::filesystem::permissions", "filesystem/std::experimental::filesystem::read_symlink", "filesystem/std::experimental::filesystem::remove", "filesystem/std::experimental::filesystem::remove_all", "filesystem/std::experimental::filesystem::rename", "filesystem/std::experimental::filesystem::resize_file", "filesystem/std::experimental::filesystem::space", "filesystem/std::experimental::filesystem::status", "filesystem/std::experimental::filesystem::status_known", "filesystem/std::experimental::filesystem::swap", "filesystem/std::experimental::filesystem::symlink_status", "filesystem/std::experimental::filesystem::system_complete", "filesystem/std::experimental::filesystem::temp_directory_path", "filesystem/std::experimental::filesystem::u8path"] +helpviewer_keywords: ["std::experimental::filesystem::absolute", "std::experimental::filesystem::begin", "std::experimental::filesystem::canonical", "std::experimental::filesystem::copy", "std::experimental::filesystem::copy_file", "std::experimental::filesystem::copy_symlink", "std::experimental::filesystem::create_directories", "std::experimental::filesystem::create_directory", "std::experimental::filesystem::create_directory_symlink", "std::experimental::filesystem::create_hard_link", "std::experimental::filesystem::create_symlink", "std::experimental::filesystem::current_path", "std::experimental::filesystem::end", "std::experimental::filesystem::equivalent", "std::experimental::filesystem::exists", "std::experimental::filesystem::file_size", "std::experimental::filesystem::hard_link_count", "std::experimental::filesystem::hash_value", "std::experimental::filesystem::is_block_file", "std::experimental::filesystem::is_character_file", "std::experimental::filesystem::is_directory", "std::experimental::filesystem::is_empty", "std::experimental::filesystem::is_fifo", "std::experimental::filesystem::is_other", "std::experimental::filesystem::is_regular_file", "std::experimental::filesystem::is_socket", "std::experimental::filesystem::is_symlink", "std::experimental::filesystem::last_write_time", "std::experimental::filesystem::permissions", "std::experimental::filesystem::read_symlink", "std::experimental::filesystem::remove", "std::experimental::filesystem::remove_all", "std::experimental::filesystem::rename", "std::experimental::filesystem::resize_file", "std::experimental::filesystem::space", "std::experimental::filesystem::status", "std::experimental::filesystem::status_known", "std::experimental::filesystem::swap", "std::experimental::filesystem::symlink_status", "std::experimental::filesystem::system_complete", "std::experimental::filesystem::temp_directory_path", "std::experimental::filesystem::u8path"] +--- +# `` functions + +> [!IMPORTANT] +> The `` header and the `std::experimental::filesystem` namespace provided a prestandard implementation of the File System Technical Specification (TS). This documentation is retained for code written against MSVC's original filesystem implementation, which was removed starting in MSVC version 14.51. For new code, use the C++17 [``](../standard-library/filesystem.md) header and the `std::filesystem` namespace instead. For the standard equivalents of these functions, see [`` functions](../standard-library/filesystem-functions.md). + +These free functions in the `` header do modifying and query operations on paths, files, symlinks, directories, and volumes. For more information and code examples, see [File System Navigation (C++)](../standard-library/file-system-navigation.md). + +## Requirements + +**Header:** `` + +**Namespace:** `std::experimental::filesystem` + +## `absolute` + +```cpp +path absolute(const path& pval, const path& base = current_path()); +``` + +The function returns the absolute pathname corresponding to *`pval`* relative to the pathname `base`: + +1. If `pval.has_root_name() && pval.has_root_directory()` the function returns *`pval`*. + +1. If `pval.has_root_name() && !pval.has_root_directory()` the function returns `pval.root_name()` / `absolute(base).root_directory()` / `absolute(base).relative_path()` / `pval.relative_path()`. + +1. If `!pval.has_root_name() && pval.has_root_directory()` the function returns `absolute(base).root_name()` / *`pval`*. + +1. If `!pval.has_root_name() && !pval.has_root_directory()` the function returns `absolute(base)` / *`pval`*. + +## `begin` + +```cpp +const directory_iterator& begin(const directory_iterator& iter) noexcept; +const recursive_directory_iterator& + begin(const recursive_directory_iterator& iter) noexcept; +``` + +Both functions return *`iter`*. + +## `canonical` + +```cpp +path canonical(const path& pval, const path& base = current_path()); +path canonical(const path& pval, error_code& ec); +path canonical(const path& pval, const path& base, error_code& ec); +``` + +The functions all form an absolute pathname `pabs = absolute(pval, base)` (or `pabs = absolute(pval)` for the overload with no base parameter), then reduce it to a canonical form in the following sequence of steps: + +1. Replace every path component `X` for which `is_symlink(X)` is **`true`** with `read_symlink(X)`. + +1. Remove every path component `.` (dot is the current directory established by previous path components). + +1. Remove every pair of path components `X`/`..` (dot-dot is the parent directory established by previous path components). + +The function then returns `pabs`. + +## `copy` + +```cpp +void copy(const path& from, const path& to); +void copy(const path& from, const path& to, error_code& ec) noexcept; +void copy(const path& from, const path& to, copy_options opts); +void copy(const path& from, const path& to, copy_options opts, error_code& ec) noexcept; +``` + +The functions all possibly copy or link one or more files at `from` to `to` under control of *`opts`*, which is taken as `copy_options::none` for the overloads with no *`opts`* parameter. *`opts`* shall contain at most one of: + +- `skip_existing`, `overwrite_existing`, or `update_existing` + +- `copy_symlinks` or `skip_symlinks` + +- `directories_only`, `create_symlinks`, or `create_hard_links` + +The functions first determine the `file_status` values `f` for `from` and `t` for `to`. They use `symlink_status` when *`opts`* contains `copy_options::create_symlinks`, `copy_options::skip_symlinks`, or `copy_options::copy_symlinks`, as required for the source or destination. Otherwise, they use `status`. + +If `!exists(f) || equivalent(f, t) || is_other(f) || is_other(t) || is_directory(f)&& is_regular_file(t)`, the functions report an error and stop. Otherwise, if `is_symlink(f)`, then: + + +- If `options & copy_options::skip_symlinks`, then do nothing. + +- Otherwise, if `!exists(t) && options & copy_options::copy_symlinks`, then `copy_symlink(from, to)`. + +- Otherwise, report an error. + +Otherwise, if `is_regular_file(f)`, then: + +- If `opts & copy_options::directories_only`, then do nothing. + +- Otherwise, if `opts & copy_options::create_symlinks`, then `create_symlink(from, to)`. + +- Otherwise, if `opts & copy_options::create_hard_links`, then `create_hard_link(from, to)`. + +- Otherwise, if `is_directory(t)`, then `copy_file(from, to / from.filename(), opts)`. + +- Otherwise, `copy_file(from, to, opts)`. + +Otherwise, if `is_directory(f) && (opts & copy_options::recursive || !opts)`, then: + +```cpp +if (!exists(t)) +{ // copy directory contents recursively + create_directory(to, from, ec); + + for (directory_iterator next(from), end; ec == error_code() && next != end; ++next) + { + copy(next->path(), to / next->path().filename(), opts, ec); + } +} +``` + +Otherwise, do nothing. + +## `copy_file` + +```cpp +bool copy_file(const path& from, const path& to); +bool copy_file(const path& from, const path& to, error_code& ec) noexcept; +bool copy_file(const path& from, const path& to, copy_options opts); +bool copy_file(const path& from, const path& to, copy_options opts, error_code& ec) noexcept; +``` + +The functions all possibly copy the file at `from` to `to` under control of *`opts`*, which is taken as `copy_options::none` for the overloads with no *`opts`* parameter. *`opts`* shall contain at most one of `skip_existing`, `overwrite_existing`, or `update_existing`. + +If `exists(to) && !(opts & (copy_options::skip_existing | copy_options::overwrite_existing | copy_options::update_existing))`, then report as an error that the file already exists. + +Otherwise, if `!exists(to) || opts & copy_options::overwrite_existing || opts & copy_options::update_existing&& last_write_time(to) < last_write_time(from) || !(opts & (copy_options::skip_existing | copy_options::overwrite_existing | copy_options::update_existing))`, then attempt to copy the contents and attributes of the file `from` to the file `to`. Report as an error if the copy attempt fails. + +The functions return **`true`** if the copy is successful, and **`false`** otherwise. + +## `copy_symlink` + +```cpp +void copy_symlink(const path& from, const path& to); +void copy_symlink(const path& from, const path& to, error_code& ec) noexcept; +``` + +If `is_directory(from)`, the function calls `create_directory_symlink(from, to)`. Otherwise, it calls `create_symlink(from, to)`. + +## `create_directories` + +```cpp +bool create_directories(const path& pval); +bool create_directories(const path& pval, error_code& ec) noexcept; +``` + +For a pathname such as `a\/b\/c`, the function creates directories `a` and `a\/b` as needed so that it can create the directory `a\/b\/c`. It returns **`true`** only if it actually creates the directory *`pval`*. + +## `create_directory` + +```cpp +bool create_directory(const path& pval); + +bool create_directory(const path& pval, error_code& ec) noexcept; +bool create_directory(const path& pval, const path& attr); +bool create_directory(const path& pval, const path& attr, error_code& ec) noexcept; +``` + +The function creates the directory *`pval`* as needed. It returns `true` only if it actually creates the directory *`pval`*. If you specify the `attr` parameter, the function copies permissions from the existing file. If you don't specify the `attr` parameter, the function uses `perms::all`. + +## `create_directory_symlink` + +```cpp +void create_directory_symlink(const path& to, const path& link); +void create_directory_symlink(const path& to, const path& link, error_code& ec) noexcept; +``` + +The function creates *`link`* as a symlink to the directory `to`. + +## `create_hard_link` + +```cpp +void create_hard_link(const path& to, const path& link); +void create_hard_link(const path& to, const path& link, error_code& ec) noexcept; +``` + +The function creates *`link`* as a hard link to the directory or file `to`. + +## `create_symlink` + +```cpp +void create_symlink(const path& to, const path& link); + +void create_symlink(const path& to, const path& link, error_code& ec) noexcept; +``` + +The function creates *`link`* as a symlink to the file `to`. + +## `current_path` + +```cpp +path current_path(); +path current_path(error_code& ec); +void current_path(const path& pval); +void current_path(const path& pval, error_code& ec) noexcept; +``` + +The functions with no parameter *`pval`* return the pathname for the current directory. The remaining functions set the current directory to *`pval`*. + +## `end` + +```cpp +directory_iterator end(const directory_iterator&) noexcept; +recursive_directory_iterator end(const recursive_directory_iterator&) noexcept; +``` + +The first function returns `directory_iterator()` and the second function returns `recursive_directory_iterator()`. + +## `equivalent` + +```cpp +bool equivalent(const path& left, const path& right); +bool equivalent(const path& left, const path& right, error_code& ec) noexcept; +``` + +The functions return **`true`** only if *left* and *right* refer to the same filesystem entity. + +## `exists` + +```cpp +bool exists(file_status stat) noexcept; +bool exists(const path& pval); +bool exists(const path& pval, error_code& ec) noexcept; +``` + +The first function returns `status_known(stat) && stat.type() != file_type::not_found`. The second and third functions return `exists(status(pval))`. + +## `file_size` + +```cpp +uintmax_t file_size(const path& pval); +uintmax_t file_size(const path& pval, error_code& ec) noexcept; +``` + +The functions return the size in bytes of the file chosen by *`pval`*, if `exists(pval) && is_regular_file(pval)` and the file size can be determined. Otherwise they report an error and return `uintmax_t(-1)`. + +## `hard_link_count` + +```cpp +uintmax_t hard_link_count(const path& pval); +uintmax_t hard_link_count(const path& pval, error_code& ec) noexcept; +``` + +The function returns the number of hard links for *`pval`*, or \-1 if an error occurs. + +## `hash_value` + +```cpp +size_t hash_value(const path& pval) noexcept; +``` + +The function returns a hash value for `pval.native()`. + +## `is_block_file` + +```cpp +bool is_block_file(file_status stat) noexcept; +bool is_block_file(const path& pval); +bool is_block_file(const path& pval, error_code& ec) noexcept; +``` + +The first function returns `stat.type() == file_type::block`. The remaining functions return `is_block_file(status(pval))`. + +## `is_character_file` + +```cpp +bool is_character_file(file_status stat) noexcept; +bool is_character_file(const path& pval); +bool is_character_file(const path& pval, error_code& ec) noexcept; +``` + +The first function returns `stat.type() == file_type::character`. The remaining functions return `is_character_file(status(pval))`. + +## `is_directory` + +```cpp +bool is_directory(file_status stat) noexcept; +bool is_directory(const path& pval); +bool is_directory(const path& pval, error_code& ec) noexcept; +``` + +The first function returns `stat.type() == file_type::directory`. The remaining functions return `is_directory(status(pval))`. + +## `is_empty` + +```cpp +bool is_empty(const path& pval); +bool is_empty(const path& pval, error_code& ec) noexcept; +``` + +If `is_directory(pval)`, the function returns `directory_iterator(pval) == directory_iterator()`. Otherwise, it returns `file_size(pval) == 0`. + +## `is_fifo` + +```cpp +bool is_fifo(file_status stat) noexcept; +bool is_fifo(const path& pval); +bool is_fifo(const path& pval, error_code& ec) noexcept; +``` + +The first function returns `stat.type() == file_type::fifo`. The remaining functions return `is_fifo(status(pval))`. + +## `is_other` + +```cpp +bool is_other(file_status stat) noexcept; +bool is_other(const path& pval); +bool is_other(const path& pval, error_code& ec) noexcept; +``` + +The first function returns `exists(stat) && !is_regular_file(stat) && !is_directory(stat) && !is_symlink(stat)`. The remaining functions return `is_other(status(pval))`. + +## `is_regular_file` + +```cpp +bool is_regular_file(file_status stat) noexcept; +bool is_regular_file(const path& pval); +bool is_regular_file(const path& pval, error_code& ec) noexcept; +``` + +The first function returns `stat.type() == file_type::regular`. The remaining functions return `is_regular_file(status(pval))`. + +## `is_socket` + +```cpp +bool is_socket(file_status stat) noexcept; +bool is_socket(const path& pval); +bool is_socket(const path& pval, error_code& ec) noexcept; +``` + +The first function returns `stat.type() == file_type::socket`. The remaining functions return `is_socket(status(pval))`. + +## `is_symlink` + +```cpp +bool is_symlink(file_status stat) noexcept; +bool is_symlink(const path& pval); +bool is_symlink(const path& pval, error_code& ec) noexcept; +``` + +The first function returns `stat.type() == file_type::symlink`. The remaining functions return `is_symlink(status(pval))`. + +## `last_write_time` + +```cpp +file_time_type last_write_time(const path& pval); +file_time_type last_write_time(const path& pval, error_code& ec) noexcept; +void last_write_time(const path& pval, file_time_type new_time); +void last_write_time(const path& pval, file_time_type new_time, error_code& ec) noexcept; +``` + +The first two functions return the time of last data modification for *`pval`*, or `file_time_type(-1)` if an error occurs. The last two functions set the time of last data modification for *`pval`* to *`new_time`*. + +## `permissions` + +```cpp +void permissions(const path& pval, perms mask); +void permissions(const path& pval, perms mask, error_code& ec) noexcept; +``` + +The functions set the permissions for the pathname chosen by *`pval`* to `mask & perms::mask` under control of `perms & (perms::add_perms | perms::remove_perms)`. *`mask`* contains at most one of `perms::add_perms` and `perms::remove_perms`. + +If `mask & perms::add_perms`, the functions set the permissions to `status(pval).permissions() | mask & perms::mask`. Otherwise, if `mask & perms::remove_perms`, the functions set the permissions to `status(pval).permissions() & ~(mask & perms::mask)`. Otherwise, the functions set the permissions to `mask & perms::mask`. + +## `read_symlink` + +```cpp +path read_symlink(const path& pval); +path read_symlink(const path& pval, error_code& ec); +``` + +The functions report an error and return `path()` if `!is_symlink(pval)`. Otherwise, the functions return an object of type `path` containing the symbolic link. + +## `remove` + +```cpp +bool remove(const path& pval); +bool remove(const path& pval, error_code& ec) noexcept; +``` + +The functions return **`true`** only if `exists(symlink_status(pval))` and the file is successfully removed. A symlink is itself removed, not the file it chooses. + +## `remove_all` + +```cpp +uintmax_t remove_all(const path& pval); +uintmax_t remove_all(const path& pval, error_code& ec) noexcept; +``` + +If *`pval`* is a directory, the functions recursively remove all directory entries, then the entry itself. Otherwise, the functions call `remove`. They return a count of all elements successfully removed. + +## `rename` + +```cpp +void rename(const path& from, const path& to); +void rename(const path& from, const path& to, error_code& ec) noexcept; +``` + +The functions rename `from` to `to`. A symlink is itself renamed, not the file it chooses. + +## `resize_file` + +```cpp +void resize_file(const path& pval, uintmax_t size); +void resize_file(const path& pval, uintmax_t size, error_code& ec) noexcept; +``` + +The functions alter the size of a file such that `file_size(pval) == size`. + +## `space` + +```cpp +space_info space(const path& pval); +space_info space(const path& pval, error_code& ec) noexcept; +``` + +The function returns information about the volume chosen by *`pval`*, in a structure of type `space_info`. The structure contains `uintmax_t(-1)` for any value that can't be determined. + +## `status` + +```cpp +file_status status(const path& pval); +file_status status(const path& pval, error_code& ec) noexcept; +``` + +The functions return the pathname status, the file type, and permissions, associated with *`pval`*. A symlink is itself not tested, but the file it chooses. + +## `status_known` + +```cpp +bool status_known(file_status stat) noexcept; +``` + +The function returns `stat.type() != file_type::none` + +## `swap` + +```cpp +void swap(path& left, path& right) noexcept; +``` + +The function exchanges the contents of *left* and *right*. + +## `symlink_status` + +```cpp +file_status symlink_status(const path& pval); +file_status symlink_status(const path& pval, error_code& ec) noexcept; +``` + +The functions return the pathname symlink status, the file type, and permissions, associated with *`pval`*. The functions behave the same as `status(pval)` except that a symlink is itself tested, not the file it chooses. + +## `system_complete` + +> [!NOTE] +> C++17 `std::filesystem` doesn't provide `system_complete`. For current code, use [`std::filesystem::absolute`](../standard-library/filesystem-functions.md#absolute) when it provides the required behavior. + +```cpp +path system_complete(const path& pval); +path system_complete(const path& pval, error_code& ec); +``` + +The functions return an absolute pathname that takes into account, as necessary, the current directory associated with its root name. For POSIX, the functions return `absolute(pval)`. + +## `temp_directory_path` + +```cpp +path temp_directory_path(); +path temp_directory_path(error_code& ec); +``` + +The functions return a pathname for a directory suitable for containing temporary files. + +## `u8path` + +```cpp +template +path u8path(const Source& source); + +template +path u8path(InIt first, InIt last); +``` + +The first function behaves the same as `path(source)` and the second function behaves the same as `path(first, last)` except that the chosen source in each case is taken as a sequence of char elements encoded as UTF-8, whatever the filesystem. + +## See also + +[``](../standard-library/experimental-filesystem.md)\ +[`` enumerations](../standard-library/experimental-filesystem-enumerations.md)\ +[`` operators](../standard-library/experimental-filesystem-operators.md) diff --git a/docs/standard-library/experimental-filesystem-operators.md b/docs/standard-library/experimental-filesystem-operators.md new file mode 100644 index 00000000000..2ee445fce0f --- /dev/null +++ b/docs/standard-library/experimental-filesystem-operators.md @@ -0,0 +1,108 @@ +--- +description: "Learn more about: operators" +title: " operators" +ms.date: 08/27/2026 +f1_keywords: ["filesystem/std::experimental::filesystem::operator==", "filesystem/std::experimental::filesystem::operator!=", "filesystem/std::experimental::filesystem::operator<", "filesystem/std::experimental::filesystem::operator<=", "filesystem/std::experimental::filesystem::operator>", "filesystem/std::experimental::filesystem::operator>=", "filesystem/std::experimental::filesystem::operator/", "filesystem/std::experimental::filesystem::operator<<", "filesystem/std::experimental::filesystem::operator>>"] +helpviewer_keywords: ["std::experimental::filesystem::operator==", "std::experimental::filesystem::operator!=", "std::experimental::filesystem::operator<", "std::experimental::filesystem::operator<=", "std::experimental::filesystem::operator>", "std::experimental::filesystem::operator>=", "std::experimental::filesystem::operator/", "std::experimental::filesystem::operator<<", "std::experimental::filesystem::operator>>"] +--- +# `` operators + +> [!IMPORTANT] +> The `` header and the `std::experimental::filesystem` namespace provided a prestandard implementation of the File System Technical Specification (TS). This documentation is retained for code written against MSVC's original filesystem implementation, which was removed starting in MSVC version 14.51. For new code, use the C++17 [``](../standard-library/filesystem.md) header and the `std::filesystem` namespace instead. For the standard equivalents of these operators, see [`` operators](../standard-library/filesystem-operators.md). + +These nonmember operators for `std::experimental::filesystem::path` are declared in the historical `` header. The comparison operators compare two paths element by element in generic format by using `path::compare`, not as raw strings. Use the [`equivalent`](../standard-library/experimental-filesystem-functions.md#equivalent) function to determine whether two paths (for example, a relative path and an absolute path) refer to the same file or directory on disk. + +For more information, see [File System Navigation (C++)](../standard-library/file-system-navigation.md). + +## Requirements + +**Header:** `` + +**Namespace:** `std::experimental::filesystem` + +## operator== + +```cpp +bool operator==(const path& left, const path& right) noexcept; +``` + +The function returns `left.compare(right) == 0`. + +## operator!= + +```cpp +bool operator!=(const path& left, const path& right) noexcept; +``` + +The function returns `!(left == right)`. + +## operator< + +```cpp +bool operator<(const path& left, const path& right) noexcept; +``` + +The function returns `left.compare(right) < 0`. + +## operator<= + +```cpp +bool operator<=(const path& left, const path& right) noexcept; +``` + +The function returns `!(right < left)`. + +## operator> + +```cpp +bool operator>(const path& left, const path& right) noexcept; +``` + +The function returns `right < left`. + +## operator>= + +```cpp +bool operator>=(const path& left, const path& right) noexcept; +``` + +The function returns `!(left < right)`. + +## operator/ + +```cpp +path operator/(const path& left, const path& right); +``` + +The function returns `path(left) /= right`. + +## operator<< + +```cpp +template +basic_ostream& operator<<(basic_ostream& os, const path& pval); +``` + +The function inserts the path's string representation into the stream. It returns `os << pval.string()`. + +## operator>> + +```cpp +template +basic_istream& operator>>(basic_istream& is, path& pval); +``` + +The function extracts a string from the stream and assigns it to *`pval`*. It executes: + +```cpp +basic_string str; +is >> str; +pval = str; +return is; +``` + +## See also + +[``](../standard-library/experimental-filesystem.md)\ +[`` functions](../standard-library/experimental-filesystem-functions.md)\ +[`` enumerations](../standard-library/experimental-filesystem-enumerations.md) diff --git a/docs/standard-library/experimental-filesystem-path-class.md b/docs/standard-library/experimental-filesystem-path-class.md new file mode 100644 index 00000000000..61de5d684ad --- /dev/null +++ b/docs/standard-library/experimental-filesystem-path-class.md @@ -0,0 +1,852 @@ +--- +title: " path class" +description: "Learn more about the removed Microsoft prestandard std::experimental::filesystem path class." +ms.date: 08/27/2026 +f1_keywords: ["filesystem/std::experimental::filesystem::path"] +helpviewer_keywords: ["std::experimental::filesystem::path class"] +--- +# `` path class + +> [!IMPORTANT] +> This page documents the removed Microsoft prestandard `std::experimental::filesystem::path` implementation provided by the `` header. It is **not** the C++17 `std::filesystem::path` class. This prestandard implementation is based on the *File System Technical Specification* (N4100) and predates C++17 `std::filesystem`. The `` header and the `std::experimental::filesystem` namespace are removed starting in the Microsoft Visual C++ toolset 14.51. For the current, supported C++17 implementation, see [`path` class](path-class.md). + +The **`path`** class stores an object of type `string_type`, called `myname` here for the purposes of exposition, suitable for use as a pathname. `string_type` is a synonym for `basic_string`, where `value_type` is a synonym for **`wchar_t`** on Windows. + +## Syntax + +```cpp +class path; +``` + +### Constructors + +|Constructor|Description| +|-|-| +|[`path`](#path)|Constructs a `path`.| + +### Typedefs + +|Type name|Description| +|-|-| +|[`const_iterator`](#const_iterator)|A synonym for `iterator`.| +|[`iterator`](#iterator)|A bidirectional constant iterator that designates the `path` components of `myname`.| +|[`string_type`](#string_type)|The type is a synonym for `basic_string`.| + +### Member functions + +|Member function|Description| +|-|-| +|[`append`](#append)|Appends the specified sequence to `myname`, converted and inserting a preferred_separator as needed.| +|[`assign`](#assign)|Replaces `myname` with the specified sequence, converted as needed.| +|[`begin`](#begin)|Returns a `path::iterator` designating the first path element in the pathname, if present.| +|[`c_str`](#c_str)|Returns a pointer to the first character in `myname`.| +|[`clear`](#clear)|Executes `myname.clear()`.| +|[`compare`](#compare)|Returns comparison values.| +|[`concat`](#concat)|Appends the specified sequence to `myname`, converted (but not inserting a separator) as needed.| +|[`empty`](#empty)|Returns `myname.empty()`.| +|[`end`](#end)|Returns an end-of-sequence iterator of type `iterator`.| +|[`extension`](#extension)|Returns the suffix of `filename()`.| +|[`filename`](#filename)|Returns the filename component of `myname`, specifically `empty() ? path() : *--end()`. The component may be empty.| +|[`generic_string`](#generic_string)|Returns `this->string(al)` with (under Windows) any backslash converted to a forward slash.| +|[`generic_u16string`](#generic_u16string)|Returns `u16string()` with (under Windows) any backslash converted to a forward slash.| +|[`generic_u32string`](#generic_u32string)|Deleted in the historical MSVC implementation.| +|[`generic_u8string`](#generic_u8string)|Returns `u8string()` with (under Windows) any backslash converted to a forward slash.| +|[`generic_wstring`](#generic_wstring)|Returns `wstring()` with (under Windows) any backslash converted to a forward slash.| +|[`has_extension`](#has_extension)|Returns `!extension().empty()`.| +|[`has_filename`](#has_filename)|Returns `!filename().empty()`.| +|[`has_parent_path`](#has_parent_path)|Returns `!parent_path().empty()`.| +|[`has_relative_path`](#has_relative_path)|Returns `!relative_path().empty()`.| +|[`has_root_directory`](#has_root_directory)|Returns `!root_directory().empty()`.| +|[`has_root_name`](#has_root_name)|Returns `!root_name().empty()`.| +|[`has_root_path`](#has_root_path)|Returns `!root_path().empty()`.| +|[`has_stem`](#has_stem)|Returns `!stem().empty()`.| +|[`is_absolute`](#is_absolute)|For Windows, the function returns `has_root_name() && has_root_directory()`. For POSIX, the function returns `has_root_directory()`.| +|[`is_relative`](#is_relative)|Returns `!is_absolute()`.| +|[`make_preferred`](#make_preferred)|Converts each separator to a `preferred_separator` as needed.| +|[`native`](#native)|Returns the native representation of the path.| +|[`parent_path`](#parent_path)|Returns the parent path component of `myname`.| +|[`preferred_separator`](#preferred_separator)|The constant object gives the preferred character for separating path components, depending on the host operating system. | +|[`relative_path`](#relative_path)|Returns the relative path component of `myname`. | +|[`remove_filename`](#remove_filename)|Removes the filename.| +|[`replace_extension`](#replace_extension)|Replaces the extension of `myname`. | +|[`replace_filename`](#replace_filename)|Replaces the filename.| +|[`root_directory`](#root_directory)|Returns the root directory component of `myname`. | +|[`root_name`](#root_name)|Returns the root name component of `myname`. | +|[`root_path`](#root_path)|Returns the root path component of `myname`.| +|[`stem`](#stem)|Returns the `stem` component of `myname`.| +|[`string`](#string)|Converts the sequence stored in `myname`.| +|[`swap`](#swap)|Executes `swap(myname, right.myname)`.| +|[`u16string`](#u16string)|Converts the sequence stored in `myname` to UTF-16 and returns it stored in an object of type `u16string`.| +|[`u32string`](#u32string)|Deleted in the historical MSVC implementation.| +|[`u8string`](#u8string)|Converts the sequence stored in `myname` to UTF-8 and returns it stored in an object of type `u8string`.| +|[`value_type`](#value_type)|The type describes the path elements favored by the host operating system.| +|[`wstring`](#wstring)|Converts the sequence stored in `myname` to the encoding favored by the host system for a **`wchar_t`** sequence and returns it stored in an object of type `wstring`.| + +### Operators + +|Operator|Description| +|-|-| +|[`operator=`](#op_as)|Replaces the elements of the path with a copy of another path.| +|[`operator+=`](#op_add)|Various `concat` expressions.| +|[`operator/=`](#op_divide)|Various `append` expressions.| +|[`operator string_type`](#op_string)|Returns `myname`.| + +## Requirements + +**Header:** `` + +**Namespace:** `std::experimental::filesystem` + +## `path::append` + +Appends the specified sequence to `myname`, converted and inserting a `preferred_separator` as needed. + +```cpp +template +path& append(const Source& source); + +template +path& append(InIt first, InIt last); +``` + +### Parameters + +*`source`*\ +Specified sequence. + +*`first`*\ +Start of specified sequence. + +*`last`*\ +End of specified sequence. + +## `path::assign` + +Replaces `myname` with the specified sequence, converted as needed. + +```cpp +template +path& assign(const Source& source); + +template +path& assign(InIt first, InIt last); +``` + +### Parameters + +*`source`*\ +Specified sequence. + +*`first`*\ +Start of specified sequence. + +*`last`*\ +End of specified sequence. + +## `path::begin` + +Returns a `path::iterator` designating the first path element in the pathname, if present. + +```cpp +iterator begin() const; +``` + +## `path::c_str` + +Returns a pointer to the first character in `myname`. + +```cpp +const value_type* c_str() const noexcept; +``` + +## `path::clear` + +Executes `myname.clear()`. + +```cpp +void clear() noexcept; +``` + +## `path::compare` + +The first function returns `myname.compare(pval.native())`. The second function returns `myname.compare(str)`. The third function returns `myname.compare(ptr)`. + +```cpp +int compare(const path& pval) const noexcept; +int compare(const string_type& str) const; +int compare(const value_type *ptr) const; +``` + +### Parameters + +*`pval`*\ +Path to compare. + +*`str`*\ +String to compare. + +*`ptr`*\ +Pointer to compare. + +## `path::concat` + +Appends the specified sequence to `myname`, converted (but not inserting a separator) as needed. + +```cpp +template +path& concat(const Source& source); + +template +path& concat(InIt first, InIt last); +``` + +### Parameters + +*`source`*\ +Specified sequence. + +*`first`*\ +Start of specified sequence. + +*`last`*\ +End of specified sequence. + +## `path::const_iterator` + +A synonym for `iterator`. + +```cpp +typedef iterator const_iterator; +``` + +## `path::empty` + +Returns `myname.empty()`. + +```cpp +bool empty() const noexcept; +``` + +## `path::end` + +Returns an end-of-sequence iterator of type `iterator`. + +```cpp +iterator end() const; +``` + +## `path::extension` + +Returns the suffix of `filename()`. + +```cpp +path extension() const; +``` + +### Remarks + +Returns the suffix of `filename() X` such that: + +If `X == path(".") || X == path("..")` or if `X` contains no dot, the suffix is empty. + +Otherwise, the suffix begins with (and includes) the rightmost dot. + +## `path::filename` + +Returns the filename component of `myname`, specifically `empty() ? path() : *--end()`. The component may be empty. + +```cpp +path filename() const; +``` + +## `path::generic_string` + +Returns `this->string(al)` with (under Windows) any backslash converted to a forward slash. + +```cpp +template , + class Alloc = allocator> + basic_string + generic_string(const Alloc& al = Alloc()) const; + +string generic_string() const; +``` + +## `path::generic_u16string` + +Returns `u16string()` with (under Windows) any backslash converted to a forward slash. + +```cpp +u16string generic_u16string() const; +``` + +## `path::generic_u32string` + +This function is deleted in the historical MSVC implementation. + +```cpp +u32string generic_u32string() const = delete; +``` + +## `path::generic_u8string` + +Returns `u8string()` with (under Windows) any backslash converted to a forward slash. + +```cpp +string generic_u8string() const; +``` + +## `path::generic_wstring` + +Returns `wstring()` with (under Windows) any backslash converted to a forward slash. + +```cpp +wstring generic_wstring() const; +``` + +## `path::has_extension` + +Returns `!extension().empty()`. + +```cpp +bool has_extension() const; +``` + +## `path::has_filename` + +Returns `!filename().empty()`. + +```cpp +bool has_filename() const; +``` + +## `path::has_parent_path` + +Returns `!parent_path().empty()`. + +```cpp +bool has_parent_path() const; +``` + +## `path::has_relative_path` + +Returns `!relative_path().empty()`. + +```cpp +bool has_relative_path() const; +``` + +## `path::has_root_directory` + +Returns `!root_directory().empty()`. + +```cpp +bool has_root_directory() const; +``` + +## `path::has_root_name` + +Returns `!root_name().empty()`. + +```cpp +bool has_root_name() const; +``` + +## `path::has_root_path` + +Returns `!root_path().empty()`. + +```cpp +bool has_root_path() const; +``` + +## `path::has_stem` + +Returns `!stem().empty()`. + +```cpp +bool has_stem() const; +``` + +## `path::is_absolute` + +For Windows, the function returns `has_root_name() && has_root_directory()`. For POSIX, the function returns `has_root_directory()`. + +```cpp +bool is_absolute() const; +``` + +## `path::is_relative` + +Returns `!is_absolute()`. + +```cpp +bool is_relative() const; +``` + +## `path::iterator` + +A bidirectional constant iterator that designates the path components of `myname`. + +```cpp +class iterator + { + // bidirectional iterator for path + typedef bidirectional_iterator_tag iterator_category; + typedef path_type value_type; + typedef ptrdiff_t difference_type; + typedef const value_type *pointer; + typedef const value_type& reference; + // ... + }; +``` + +### Remarks + +The class describes a bidirectional constant iterator that designates the `path` components of `myname` in the sequence: + +1. the root name, if present + +1. the root directory, if present + +1. the remaining directory elements of the parent `path`, if present, ending with the filename, if present + +For `pval` an object of type `path`: + +1. `path::iterator X = pval.begin()` designates the first `path` element in the pathname, if present. + +1. `X == pval.end()` is `true` when `X` points just past the end of the sequence of components. + +1. `*X` returns a string that matches the current component + +1. `++X` designates the next component in the sequence, if present. + +1. `--X` designates the preceding component in the sequence, if present. + +1. Altering `myname` invalidates all iterators designating elements in `myname`. + +## `path::make_preferred` + +Converts each separator to a `preferred_separator` as needed. + +```cpp +path& make_preferred(); +``` + +## `path::native` + +Get the native string representation of the path. + +```cpp +const string_type& native() const noexcept; +``` + +### Remarks + +The path is available in a portable generic format (see [`generic_string()`](#generic_string)) or the native format of the path. This function returns the native string. On a POSIX system, the generic format and the native format are the same. + +In the following example running on Windows, the generic path string is `c:/t/temp.txt` and the native string is `c:\t\temp.txt`. + +```cpp +// Compile with /std:c++14 and _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING defined. +#include + +int main() +{ + std::experimental::filesystem::path p(LR"(c:\t\temp.txt)"); + auto native = p.native(); // Windows: L"c:\\t\\temp.txt" + auto generic = p.generic_string(); // Windows: "c:/t/temp.txt" +} +``` + +## `path::operator=` + +Replaces the elements of the path with a copy of another path. + +```cpp +path& operator=(const path& right); +path& operator=(path&& right) noexcept; + +template +path& operator=(const Source& source); +``` + +### Parameters + +*`right`*\ +The [`path`](../standard-library/experimental-filesystem-path-class.md) being copied into the `path`. + +*`source`*\ +The source `path`. + +### Remarks + +The first member operator copies `right.myname` to `myname`. The second member operator moves `right.myname` to `myname`. The third member operator behaves the same as `*this = path(source)`. + +## `path::operator+=` + +Various `concat` expressions. + +```cpp +path& operator+=(const path& right); +path& operator+=(const string_type& str); +path& operator+=(const value_type *ptr); +path& operator+=(value_type elem); + +template +path& operator+=(const Source& source); + +template +path& operator+=(Elem elem); +``` + +### Parameters + +*`right`*\ +The added path. + +*`str`*\ +The added string. + +*`ptr`*\ +The added pointer. + +*`elem`*\ +The added `value_type` or `Elem`. + +*`source`*\ +The added source. + +### Remarks + +The member functions behave the same as the following corresponding expressions: + +1. `concat(right);` + +1. `concat(path(str));` + +1. `concat(ptr);` + +1. `concat(string_type(1, elem));` + +1. `concat(source);` + +1. `concat(path(basic_string(1, elem)));` + +## `path::operator/=` + +Various `append` expressions. + +```cpp +path& operator/=(const path& right); + +template +path& operator/=(const Source& source); +``` + +### Parameters + +*`right`*\ +The added path. + +*`source`*\ +The added source. + +### Remarks + +The member functions behave the same as the following corresponding expressions: + +1. `append(right);` + +1. `append(source);` + +## `path::operator string_type` + +Returns `myname`. + +```cpp +operator string_type() const; +``` + +## `path::parent_path` + +Returns the parent path component of `myname`. + +```cpp +path parent_path() const; +``` + +### Remarks + +Returns the parent path component of `myname`, specifically the prefix of `myname` after removing `filename().native()` and any immediately preceding directory separators. (Equally, if `begin() != end()`, it's the combining of all elements in the range `[begin(), --end())` by successively applying `operator/=`.) The component may be empty. + +## `path::path` + +Constructs a `path` in various ways. + +```cpp +path(); + +path(const path& right); +path(path&& right) noexcept; + +template +path(const Source& source); + +template +path(const Source& source, const locale& loc); + +template +path(InIt first, InIt last); + +template +path(InIt first, InIt last, const locale& loc); +``` + +### Parameters + +*`right`*\ +The path of which the constructed path is to be a copy. + +*`source`*\ +The source of which the constructed path is to be a copy. + +*`loc`*\ +The specified locale. + +*`first`*\ +The position of the first element to be copied. + +*`last`*\ +The position of the last element to be copied. + +### Remarks + +The constructors all construct `myname` in various ways: + +For `path()` it's `myname()`. + +For `path(const path& right`) it's `myname(right.myname)`. + +For `path(path&& right)` it's `myname(right.myname)`. + +For `template path(const Source& source)` it's `myname(source)`. + +For `template path(const Source& source, const locale& loc)` it's `myname(source)`, obtaining any needed `codecvt` facets from `loc`. + +For `template path(InIt first, InIt last)` it's `myname(first, last)`. + +For `template path(InIt first, InIt last, const locale& loc)` it's `myname(first, last)`, obtaining any needed `codecvt` facets from `loc`. + +## `path::preferred_separator` + +The constant object gives the preferred character for separating path components, depending on the host operating system. + +```cpp +#if _WIN32_C_LIB +static constexpr value_type preferred_separator = L'\\'; +#else // assume POSIX +static constexpr value_type preferred_separator = '/'; +#endif // filesystem model now defined +``` + +### Remarks + +It's equally permissible in most contexts under Windows to use `L'/'` in its place. + +## `path::relative_path` + +Returns the relative path component of `myname`. + +```cpp +path relative_path() const; +``` + +### Remarks + +Returns the relative path component of `myname`, specifically the suffix of `myname` after removing `root_path().native()` and any immediately subsequent redundant directory separators. The component may be empty. + +## `path::remove_filename` + +Removes the filename. + +```cpp +path& remove_filename(); +``` + +## `path::replace_extension` + +Replaces the extension of `myname`. + +```cpp +path& replace_extension(const path& newext = path()); +``` + +### Parameters + +*`newext`*\ +The new extension. + +### Remarks + +First removes the suffix `extension().native()` from `myname`. Then if `!newext.empty() && newext[0] != dot` (where *dot* is `*path(".").c_str()`), then *dot* is appended to `myname`. Then *`newext`* is appended to `myname`. + +## `path::replace_filename` + +Replaces the filename. + +```cpp +path& replace_filename(const path& pval); +``` + +### Parameters + +*`pval`*\ +The path of the filename. + +### Remarks + +The member function executes: + +```cpp +remove_filename(); + +*this /= pval; +return (*this); +``` + +## `path::root_directory` + +Returns the root directory component of `myname`. + +```cpp +path root_directory() const; +``` + +### Remarks + +The component may be empty. + +## `path::root_name` + +Returns the root name component of `myname`. + +```cpp +path root_name() const; +``` + +### Remarks + +The component may be empty. + +## `path::root_path` + +Returns the root path component of `myname`. + +```cpp +path root_path() const; +``` + +### Remarks + +Returns the root path component of `myname`, specifically `root_name()` / `root_directory`. The component may be empty. + +## `path::stem` + +Returns the `stem` component of `myname`. + +```cpp +path stem() const; +``` + +### Remarks + +Returns the `stem` component of `myname`, specifically `filename().native()` with any trailing `extension().native()` removed. The component may be empty. + +## `path::string` + +Converts the sequence stored in `myname`. + +```cpp +template , class Alloc = allocator> +basic_string string(const Alloc& al = Alloc()) const; +string string() const; +``` + +### Remarks + +The first (template) member function converts the sequence stored in `myname` the same way as: + +1. `string()` for `string()` + +1. `wstring()` for `string()` + +1. `u16string()` for `string()` + +The second member function converts the sequence stored in `myname` to the encoding favored by the host system for a **`char`** sequence and returns it stored in an object of type `string`. + +## `path::string_type` + +The type is a synonym for `basic_string`. + +```cpp +typedef basic_string string_type; +``` + +## `path::swap` + +Executes `swap(myname, right.myname)`. + +```cpp +void swap(path& right) noexcept; +``` + +## `path::u16string` + +Converts the sequence stored in `myname` to UTF-16 and returns it stored in an object of type `u16string`. + +```cpp +u16string u16string() const; +``` + +## `path::u32string` + +This function is deleted in the historical MSVC implementation. + +```cpp +u32string u32string() const = delete; +``` + +## `path::u8string` + +Converts the sequence stored in `myname` to UTF-8 and returns it stored in an object of type `u8string`. + +```cpp +string u8string() const; +``` + +## `path::value_type` + +The type describes the `path` elements favored by the host operating system. + +```cpp +#if _WIN32_C_LIB +typedef wchar_t value_type; +#else // assume POSIX +typedef char value_type; +#endif // filesystem model now defined +``` + +## `path::wstring` + +Converts the sequence stored in `myname` to the encoding favored by the host system for a **`wchar_t`** sequence and returns it stored in an object of type `wstring`. + +```cpp +wstring wstring() const; +``` + +## See also + +[``](../standard-library/experimental-filesystem.md)\ +[`` operators](../standard-library/experimental-filesystem-operators.md) diff --git a/docs/standard-library/experimental-filesystem-recursive-directory-iterator-class.md b/docs/standard-library/experimental-filesystem-recursive-directory-iterator-class.md new file mode 100644 index 00000000000..bd9a3b17b1d --- /dev/null +++ b/docs/standard-library/experimental-filesystem-recursive-directory-iterator-class.md @@ -0,0 +1,258 @@ +--- +description: "Learn more about: recursive_directory_iterator class" +title: " recursive_directory_iterator class" +ms.date: 08/27/2026 +f1_keywords: ["filesystem/std::experimental::filesystem::recursive_directory_iterator"] +helpviewer_keywords: ["std::experimental::filesystem::recursive_directory_iterator"] +--- + +# `` `recursive_directory_iterator` class + +> [!IMPORTANT] +> This article describes the `recursive_directory_iterator` class from the prestandard `` implementation of the ISO C++ Filesystem Technical Specification (N4100). This API isn't the same as the C++17 [`recursive_directory_iterator`](recursive-directory-iterator-class.md) class in ``. It uses different signatures, including a `noexcept` `increment` and a single-form `pop` with no `error_code` overload. The experimental implementation was removed starting with the Microsoft Visual C++ (MSVC) 14.51 toolset. New code should use the C++17 [`recursive_directory_iterator`](recursive-directory-iterator-class.md) class instead. + +Describes an input iterator that sequences through the filenames in a directory, possibly descending into subdirectories recursively. For an iterator `X`, the expression `*X` returns an object of class `directory_entry` that wraps the filename and anything known about its status. + +## Syntax + +```cpp +class recursive_directory_iterator; +``` + +## Remarks + +The class stores: + +1. an object of type `stack>`, called `mystack` here for the purposes of exposition, which represents the nest of directories to sequence + +1. an object of type `directory_entry` called `myentry` here, which represents the current filename in the directory sequence + +1. an object of type **`bool`**, called `no_push` here, which records whether recursive descent into subdirectories is disabled + +1. an object of type `directory_options`, called `myoptions` here, which records the options established at construction + +A default-constructed object of type `recursive_directory_iterator` has an end-of-sequence iterator at `mystack.top().first` and represents the end-of-sequence iterator. For example, given the directory `abc` with entries `def` (a directory), `def/ghi`, and `jkl`, the code: + +```cpp +for (recursive_directory_iterator next(path("abc")), end; next != end; ++next) + visit(next->path()); +``` + +calls `visit` with the arguments `path("abc/def/ghi")` and `path("abc/jkl")`. You can qualify sequencing through a directory subtree in two ways: + +1. A directory symlink is scanned only if you construct a `recursive_directory_iterator` with a `directory_options` argument whose value is `directory_options::follow_directory_symlink`. + +1. If you call `disable_recursion_pending`, a subsequent directory encountered during an increment isn't recursively scanned. + +### Constructors + +|Constructor|Description| +|-|-| +|[recursive_directory_iterator](#recursive_directory_iterator)|Constructs a `recursive_directory_iterator`.| + +### Member functions + +|Member function|Description| +|-|-| +|[depth](#depth)|Returns `mystack.size() - 1`, so `pval` is at depth zero.| +|[disable_recursion_pending](#disable_recursion_pending)|Stores **`true`** in `no_push`.| +|[increment](#increment)|Advances to the next filename in sequence.| +|[options](#options)|Returns `myoptions`.| +|[pop](#pop)|Moves the iterator to the next entry at the next lower depth.| +|[recursion_pending](#recursion_pending)|Returns `!no_push`.| + +### Operators + +|Operator|Description| +|-|-| +|[operator!=](#op_neq)|Returns `!(*this == right)`.| +|[operator=](#op_as)|The defaulted member assignment operators behave as expected.| +|[operator==](#op_eq)|Returns **`true`** only if both **`*this`** and *right* are end-of-sequence iterators or both aren't end-of-sequence-iterators.| +|[operator*](#op_multiply)|Returns `myentry`.| +|[operator->](#op_cast)|Returns `&**this`.| +|[operator++](#op_increment)|Increments the `recursive_directory_iterator`.| + +## Requirements + +**Header:** `` + +**Namespace:** `std::experimental::filesystem` + +## recursive_directory_iterator::depth + +Returns `mystack.size() - 1`, so `pval` is at depth zero. + +```cpp +int depth() const; +``` + +## recursive_directory_iterator::disable_recursion_pending + +Stores **`true`** in `no_push`. + +```cpp +void disable_recursion_pending(); +``` + +## recursive_directory_iterator::increment + +Advances to the next filename in sequence. + +```cpp +recursive_directory_iterator& increment(error_code& ec) noexcept; +``` + +### Parameters + +`ec`\ +Specified error code. + +### Remarks + +The function attempts to advance to the next filename in the nested sequence. If successful, it stores that filename in `myentry`; otherwise it produces an end-of-sequence iterator. + +## recursive_directory_iterator::operator!= + +Returns `!(*this == right)`. + +```cpp +bool operator!=(const recursive_directory_iterator& right) const; +``` + +### Parameters + +*right*\ +The `recursive_directory_iterator` for comparison. + +## recursive_directory_iterator::operator= + +The defaulted member assignment operators behave as expected. + +```cpp +recursive_directory_iterator& operator=(const recursive_directory_iterator&) = default; +recursive_directory_iterator& operator=(recursive_directory_iterator&&) = default; +``` + +### Parameters + +*recursive_directory_iterator*\ +The `recursive_directory_iterator` being copied into the `recursive_directory_iterator`. + +## recursive_directory_iterator::operator== + +Returns **`true`** only if both **`*this`** and *right* are end-of-sequence iterators or both aren't end-of-sequence iterators. + +```cpp +bool operator==(const recursive_directory_iterator& right) const; +``` + +### Parameters + +*right*\ +The `recursive_directory_iterator` for comparison. + +## recursive_directory_iterator::operator* + +Returns `myentry`. + +```cpp +const directory_entry& operator*() const; +``` + +## recursive_directory_iterator::operator-> + +Returns `&**this`. + +```cpp +const directory_entry * operator->() const; +``` + +## recursive_directory_iterator::operator++ + +Increments the `recursive_directory_iterator`. + +```cpp +recursive_directory_iterator& operator++(); + +recursive_directory_iterator operator++(int); +``` + +### Parameters + +*int*\ +Dummy argument. It's a C++ convention used only to distinguish the postfix increment operator from the prefix increment operator. The C++ standard requires the postfix form to take a dummy int parameter. + +### Remarks + +The first member function calls `increment()`, then returns **`*this`**. The second member function makes a copy of the object, calls `increment()`, then returns the copy. + +## recursive_directory_iterator::options + +Returns `myoptions`. + +```cpp +directory_options options() const; +``` + +## recursive_directory_iterator::pop + +Moves the iterator to the next entry at the next lower depth. + +```cpp +void pop(); +``` + +### Remarks + +If `depth() == 0`, the object becomes an end-of-sequence iterator. Otherwise, the member function terminates scanning of the current (deepest) directory and resumes at the next lower depth. + +## recursive_directory_iterator::recursion_pending + +Returns `!no_push`. + +```cpp +bool recursion_pending() const; +``` + +## recursive_directory_iterator::recursive_directory_iterator + +Constructs a `recursive_directory_iterator`. + +```cpp +recursive_directory_iterator() noexcept; +explicit recursive_directory_iterator(const path& pval, + directory_options opts = directory_options::none); + +recursive_directory_iterator(const path& pval, + directory_options opts, + error_code& ec) noexcept; +recursive_directory_iterator(const path& pval, + error_code& ec) noexcept; +recursive_directory_iterator(const recursive_directory_iterator&) = default; +recursive_directory_iterator(recursive_directory_iterator&&) = default; +``` + +### Parameters + +`pval`\ +The specified path. + +*error_code*\ +The specified error code. + +*opts*\ +The specified directory options. + +*recursive_directory_iterator*\ +The `recursive_directory_iterator` of which the constructed `recursive_directory_iterator` is to be a copy. + +### Remarks + +The first constructor creates an end-of-sequence iterator. The second constructor stores **`false`** in `no_push` and *opts* in `myoptions`, then tries to open and read *pval* as a directory. If it succeeds, it initializes `mystack` and `myentry` to point to the first non-directory filename in the nested sequence. If it fails, it creates an end-of-sequence iterator. + +The third and fourth constructors behave the same as the second, except that they report errors in *ec* instead of throwing an exception. The fourth constructor stores `directory_options::none` in `myoptions`. The default constructor behaves as expected. + +## See also + +[``](../standard-library/experimental-filesystem.md)\ +[`directory_entry` class](../standard-library/experimental-filesystem-directory-entry-class.md) diff --git a/docs/standard-library/experimental-filesystem-space-info-structure.md b/docs/standard-library/experimental-filesystem-space-info-structure.md new file mode 100644 index 00000000000..ab675f69c7f --- /dev/null +++ b/docs/standard-library/experimental-filesystem-space-info-structure.md @@ -0,0 +1,44 @@ +--- +description: "Learn more about: space_info Structure" +title: " space_info Structure" +ms.date: 08/27/2026 +f1_keywords: ["filesystem/std::experimental::filesystem::space_info"] +--- +# `` space_info Structure + +> [!IMPORTANT] +> This article describes the prestandard `` implementation of `space_info`. It documents the historical File System Technical Specification ([ISO/IEC JTC 1/SC 22/WG 21 N4100](https://wg21.link/n4100)), not the C++17 `std::filesystem::space_info` structure. The experimental implementation was removed starting with MSVC version 14.51. For current code, use the standard [space_info Structure](../standard-library/space-info-structure.md). + +Holds information about a volume. + +## Syntax + +```cpp +struct space_info +{ + uintmax_t capacity; + uintmax_t free; + uintmax_t available; +}; +``` + +## Members + +### Public Data Members + +|Name|Description| +|----------|-----------------| +|`uintmax_t capacity`|Represents the total number of bytes that the volume can represent.| +|`uintmax_t free`|Represents the number of bytes that are not used to represent data on the volume.| +|`uintmax_t available`|Represents the number of bytes that are available to represent data on the volume.| + +## Requirements + +**Header:** \ + +**Namespace:** std::experimental::filesystem + +## See also + +[``](../standard-library/experimental-filesystem.md)\ +[`space`](../standard-library/experimental-filesystem-functions.md#space) diff --git a/docs/standard-library/experimental-filesystem.md b/docs/standard-library/experimental-filesystem.md new file mode 100644 index 00000000000..7e41182c980 --- /dev/null +++ b/docs/standard-library/experimental-filesystem.md @@ -0,0 +1,67 @@ +--- +title: "" +description: "Describes the historical, prestandard MSVC experimental/filesystem header, which was removed starting in MSVC version 14.51." +ms.date: 08/27/2026 +f1_keywords: ["", "filesystem/std::experimental::filesystem", "std::experimental::filesystem"] +no-loc: [experimental, filesystem, char, wchar_t, char16_t, char32_t] +--- +# `` + +> [!IMPORTANT] +> This article documents the historical, prestandard MSVC implementation of the File System Technical Specification that was provided in the `` header. It's **not** the C++17 `std::filesystem` library. This experimental implementation was **removed starting in MSVC version 14.51**. For current file system support, use the C++17 [``](../standard-library/filesystem.md) header and the `std::filesystem` namespace. + +Use this documentation only when maintaining older code that includes `` or uses the `std::experimental::filesystem` namespace. The reference links on this page stay within that historical API unless they're explicitly labeled as current C++17 documentation. + +Before C++17 standardized file system support, MSVC shipped a prestandard implementation of the File System Technical Specification in the `` header, under the `std::experimental::filesystem` namespace. This article is retained for historical reference. New code should use the C++17 [``](../standard-library/filesystem.md) header instead. + +## Syntax + +```cpp +#include // Removed starting in MSVC version 14.51 +using namespace std::experimental::filesystem::v1; +``` + +## Visual Studio version history + +- When Visual Studio 2017 was released, the C++17 `` header wasn't yet standardized. C++ in Visual Studio 2017 implemented the prestandard File System Technical Specification in the `` header. +- Visual Studio 2017 version 15.7 and later added support for the new C++17 `` standard. This C++17 implementation is a completely new implementation, incompatible with the previous `std::experimental` version. +- In Visual Studio 2019 version 16.3 and later, including `` provides only the new `std::filesystem`, and including `` provides only the old experimental implementation. +- The experimental implementation was removed starting in MSVC Build Tools version 14.51, which became the default toolset in Visual Studio 2026 version 18.6. + +## Classes + +|Name|Description| +|-|-| +|[`directory_entry` class](../standard-library/experimental-filesystem-directory-entry-class.md)|Describes an object that is returned by a `directory_iterator` or a `recursive_directory_iterator` and contains a `path`.| +|[`directory_iterator` class](../standard-library/experimental-filesystem-directory-iterator-class.md)|Describes an input iterator that sequences through the file names in a file-system directory.| +|[`filesystem_error` class](../standard-library/experimental-filesystem-error-class.md)|A base class for exceptions that are thrown to report a low-level system error.| +|[`path` class](../standard-library/experimental-filesystem-path-class.md)|Defines a class that stores an object of template type `String` that is suitable for use as a file name.| +|[`recursive_directory_iterator` class](../standard-library/experimental-filesystem-recursive-directory-iterator-class.md)|Describes an input iterator that sequences through the file names in a file-system directory. The iterator can also descend into subdirectories.| +|[`file_status` class](../standard-library/experimental-filesystem-file-status-class.md)|Wraps a `file_type`.| + +## Structs + +|Name|Description| +|-|-| +|[`space_info` structure](../standard-library/experimental-filesystem-space-info-structure.md)|Holds information about a volume.| + +## Functions + +[`` functions](../standard-library/experimental-filesystem-functions.md) + +## Operators + +[`` operators](../standard-library/experimental-filesystem-operators.md) + +## Enumerations + +|Name|Description| +|-|-| +|[`copy_options`](../standard-library/experimental-filesystem-enumerations.md#copy_options)|An enumeration that is used with `copy_file` and determines behavior if a destination file already exists.| +|[`directory_options`](../standard-library/experimental-filesystem-enumerations.md#directory_options)|An enumeration that specifies options for directory iterators.| +|[`file_type`](../standard-library/experimental-filesystem-enumerations.md#file_type)|An enumeration for file types.| +|[`perms`](../standard-library/experimental-filesystem-enumerations.md#perms)|A bitmask type used to convey permissions and options to permissions.| + +## See also + +[Current `` documentation](../standard-library/filesystem.md) diff --git a/docs/standard-library/file-status-class.md b/docs/standard-library/file-status-class.md index 02d399d3cd9..2a547064dbc 100644 --- a/docs/standard-library/file-status-class.md +++ b/docs/standard-library/file-status-class.md @@ -1,9 +1,9 @@ --- title: "file_status Class" description: "Learn more about: file_status Class" -ms.date: 09/10/2018 -f1_keywords: ["filesystem/std::experimental::filesystem::file_status", "filesystem/std::experimental::filesystem::file_status::operator=", "filesystem/std::experimental::filesystem::file_status::type", "filesystem/std::experimental::filesystem::file_status::permissions"] -helpviewer_keywords: ["std::experimental::filesystem::file_status", "std::experimental::filesystem::file_status::operator=", "std::experimental::filesystem::file_status::type", "std::experimental::filesystem::file_status::permissions"] +ms.date: 08/27/2026 +f1_keywords: ["filesystem/std::filesystem::file_status", "filesystem/std::filesystem::file_status::operator=", "filesystem/std::filesystem::file_status::type", "filesystem/std::filesystem::file_status::permissions"] +helpviewer_keywords: ["std::filesystem::file_status", "std::filesystem::file_status::operator=", "std::filesystem::file_status::type", "std::filesystem::file_status::permissions"] --- # file_status Class @@ -38,7 +38,7 @@ class file_status; **Header:** \ -**Namespace:** std::experimental::filesystem, std::experimental::filesystem +**Namespace:** std::filesystem ## file_status::file_status @@ -86,8 +86,8 @@ The [file_status](../standard-library/file-status-class.md) being copied into th Gets or sets the `file_type`. ```cpp -file_type type() const noexcept -void type(file_type ftype) noexcept +file_type type() const noexcept; +void type(file_type ftype) noexcept; ``` ### Parameters @@ -102,8 +102,8 @@ Gets or sets the file permissions. Use the setter to make a file `readonly` or remove the `readonly` attribute. ```cpp -perms permissions() const noexcept -void permissions(perms mask) noexcept +perms permissions() const noexcept; +void permissions(perms mask) noexcept; ``` ### Parameters diff --git a/docs/standard-library/file-system-navigation.md b/docs/standard-library/file-system-navigation.md index 30b075f62b4..3cdab3a9b4f 100644 --- a/docs/standard-library/file-system-navigation.md +++ b/docs/standard-library/file-system-navigation.md @@ -1,12 +1,14 @@ --- title: "File System Navigation" description: "How to use the C++ Standard library filesystem APIs to navigate the file system." -ms.date: "04/13/2020" -ms.assetid: f7cc5f5e-a541-4e00-87c7-a3769ef6096d +ms.date: 08/27/2026 --- # File System Navigation -The `` header implements the C++ File System Technical Specification ISO/IEC TS 18822:2015 (Final draft: [ISO/IEC JTC 1/SC 22/WG 21 N4100](https://wg21.link/n4100)) and has types and functions that enable you to write platform-independent code for navigating the file system. Because it's cross-platform, it contains APIs that aren't relevant for Windows systems. For example, `is_fifo(const path&)` always returns **`false`** on Windows. +The C++17 `` header provides types and functions that enable you to write platform-independent code for navigating the file system. Because it's cross-platform, it contains APIs that aren't relevant for Windows systems. For example, `is_fifo(const path&)` always returns **`false`** on Windows. + +> [!NOTE] +> This article covers the current C++17 `std::filesystem` library. For the historical prestandard MSVC implementation that was removed starting in MSVC version 14.51, see [``](../standard-library/experimental-filesystem.md). ## Overview diff --git a/docs/standard-library/filesystem-enumerations.md b/docs/standard-library/filesystem-enumerations.md index fb87d4f2933..3252ccfd7d4 100644 --- a/docs/standard-library/filesystem-enumerations.md +++ b/docs/standard-library/filesystem-enumerations.md @@ -1,19 +1,22 @@ --- description: "Learn more about: enumerations" title: " enumerations" -ms.date: "11/04/2016" -f1_keywords: ["filesystem/std::filesystem::copy_options", "filesystem/std::experimental::filesystem::copy_options", "filesystem/std::filesystem::directory_options", "filesystem/std::experimental::filesystem::directory_options", "filesystem/std::filesystem::file_type", "filesystem/std::experimental::filesystem::file_type", "filesystem/std::filesystem::perms", "filesystem/std::experimental::filesystem::perms"] -ms.assetid: 0096c046-d101-464c-8259-b878a48280b0 +ms.date: 08/27/2026 +f1_keywords: ["filesystem/std::filesystem::copy_options", "filesystem/std::filesystem::directory_options", "filesystem/std::filesystem::file_type", "filesystem/std::filesystem::perm_options", "filesystem/std::filesystem::perms"] +helpviewer_keywords: ["std::filesystem::copy_options", "std::filesystem::directory_options", "std::filesystem::file_type", "std::filesystem::perm_options", "std::filesystem::perms"] --- # `` enumerations -This topic documents the enums in the filesystem header. +This article documents the enumerations in the C++17 `std::filesystem` implementation of the [``](../standard-library/filesystem.md) header. + +> [!NOTE] +> This page documents the C++17 `std::filesystem` enumerations. For the historical prestandard enumerations that MSVC provided in ``, see [`` enumerations](../standard-library/experimental-filesystem-enumerations.md). ## Requirements -**Header:** \ +**Header:** `` -**Namespace:** std::experimental::filesystem +**Namespace:** `std::filesystem` ## copy_options @@ -53,14 +56,15 @@ enum class copy_options { ## directory_options -Specifies whether to follow symbolic links to directories or to ignore them. +A bitmask enumeration that controls how directory iteration handles symbolic links to directories and permission-denied errors. ### Syntax ```cpp enum class directory_options { none = 0, - follow_directory_symlink + follow_directory_symlink = 1, + skip_permission_denied = 2 }; ``` @@ -68,19 +72,20 @@ enum class directory_options { |Name|Description| |----------|-----------------| -|`none`|Default behavior: ignore symbolic links to directories. Permission denied is an error.| -|`follow_directory_symlink`|Treat symbolic links to directories as actual directories.| +|`none`|Default behavior: don't follow symbolic links to directories, and treat permission denied as an error.| +|`follow_directory_symlink`|Follow symbolic links to directories rather than skipping them.| +|`skip_permission_denied`|Silently skip directories that would otherwise result in a permission-denied error.| ## file_type -An enumeration for file types. The supported values are regular, directory, not_found, and unknown. +An enumeration for file types. ### Syntax ```cpp enum class file_type { - not_found = -1, - none, + none = 0, + not_found, regular, directory, symlink, @@ -92,32 +97,50 @@ enum class file_type { }; ``` +The C++ standard doesn't fix the underlying integer values of these enumerators, so don't depend on specific numeric values. + ### Values -|Name|Value|Description| -|----------|-----------|-----------------| -|`not_found`|-1|Represents a file that does not exist.| -|`none`|0|Represents a file that has no type attribute. (Not supported.)| -|`regular`|1|Represents a conventional disk file.| -|`directory`|2|Represents a directory.| -|`symlink`|3|Represents a symbolic link. (Not supported.)| -|`block`|4|Represents a block-special file on UNIX-based systems. (Not supported.)| -|`character`|5|Represents a character-special file on UNIX-based systems. (Not supported.)| -|`fifo`|6|Represents a FIFO file on UNIX-based systems. (Not supported.)| -|`socket`|7|Represents a socket on UNIX based systems. (Not supported.)| -|`unknown`|8|Represents a file whose status cannot be determined.| +|Name|Description| +|----------|-----------------| +|`none`|The file type hasn't been evaluated yet, or an error occurred when evaluating it.| +|`not_found`|The file wasn't found.| +|`regular`|A regular file.| +|`directory`|A directory.| +|`symlink`|A symbolic link.| +|`block`|A block-special file. (Not used on Windows.)| +|`character`|A character-special file. (Not used on Windows.)| +|`fifo`|A FIFO or pipe file. (Not used on Windows.)| +|`socket`|A socket. (Not used on Windows.)| +|`unknown`|The file exists but its type can't be determined.| ## perm_options -Includes values `replace`, `add`, `remove`, and `nofollow`. +A bitmask enumeration that controls how the [`permissions`](../standard-library/filesystem-functions.md#permissions) function applies permission bits. + +### Syntax ```cpp -enum class perm_options; +enum class perm_options { + replace = 1, + add = 2, + remove = 4, + nofollow = 8 +}; ``` +### Values + +|Name|Description| +|----------|-----------------| +|`replace`|Replace the file's permission bits with the specified permissions.| +|`add`|Add the specified permission bits to the file's current permissions.| +|`remove`|Remove the specified permission bits from the file's current permissions.| +|`nofollow`|Change the permissions of a symbolic link itself rather than the file it resolves to.| + ## perms -Flags for file permissions. The supported values are essentially "readonly" and all. For a readonly file, none of the *_write bits are set. Otherwise the `all` bit (0x0777) is set. +A bitmask enumeration of file permission bits. On Windows, the supported values are essentially "read-only" and `all`. For a read-only file, none of the `*_write` bits are set. Otherwise, the `all` bit (0777) is set. ### Syntax @@ -141,10 +164,7 @@ enum class perms {// names for permissions set_gid = 02000, // S_ISGID sticky_bit = 01000, // S_ISVTX mask = 07777, - unknown = 0xFFFF, - add_perms = 0x10000, - remove_perms = 0x20000, - resolve_symlinks = 0x40000 + unknown = 0xFFFF }; ``` diff --git a/docs/standard-library/filesystem-error-class.md b/docs/standard-library/filesystem-error-class.md index 5e2dee1e4a4..182aea657bf 100644 --- a/docs/standard-library/filesystem-error-class.md +++ b/docs/standard-library/filesystem-error-class.md @@ -1,18 +1,17 @@ --- description: "Learn more about: filesystem_error Class" title: "filesystem_error Class" -ms.date: "09/10/2018" -f1_keywords: ["filesystem/std::experimental::filesystem::filesystem_error"] -ms.assetid: c53aac27-c1fa-43e4-8967-48ea8ba1f172 +ms.date: 08/27/2026 +f1_keywords: ["filesystem/std::filesystem::filesystem_error"] --- # filesystem_error Class -A base class for all exceptions that are thrown to report a low-level system overflow. +A base class for all exceptions that report a low-level system error. ## Syntax ```cpp -class filesystem_error : public system_error; +class filesystem_error : public system_error; ``` ## Remarks @@ -39,7 +38,7 @@ The class serves as the base class for all exceptions thrown to report an error **Header:** \ -**Namespace:** std::experimental::filesystem +**Namespace:** std::filesystem ## filesystem_error diff --git a/docs/standard-library/filesystem-functions.md b/docs/standard-library/filesystem-functions.md index 2c642f3180a..56fec50c3c9 100644 --- a/docs/standard-library/filesystem-functions.md +++ b/docs/standard-library/filesystem-functions.md @@ -1,57 +1,49 @@ --- title: " functions" description: "Learn more about: functions" -ms.date: "03/27/2019" -f1_keywords: ["FILESYSTEM/std::experimental::filesystem::absolute", "FILESYSTEM/std::experimental::filesystem::canonical", "FILESYSTEM/std::experimental::filesystem::copy", "FILESYSTEM/std::experimental::filesystem::copy_file", "FILESYSTEM/std::experimental::filesystem::copy_symlink", "FILESYSTEM/std::experimental::filesystem::create_directories", "FILESYSTEM/std::experimental::filesystem::create_directory", "FILESYSTEM/std::experimental::filesystem::create_directory_symlink", "FILESYSTEM/std::experimental::filesystem::create_hard_link", "FILESYSTEM/std::experimental::filesystem::create_symlink", "FILESYSTEM/std::experimental::filesystem::current_path", "FILESYSTEM/std::experimental::filesystem::equivalent", "FILESYSTEM/std::experimental::filesystem::exists", "FILESYSTEM/std::experimental::filesystem::file_size", "FILESYSTEM/std::experimental::filesystem::hard_link_count", "FILESYSTEM/std::experimental::filesystem::hash_value", "FILESYSTEM/std::experimental::filesystem::is_block_file", "FILESYSTEM/std::experimental::filesystem::is_character_file", "FILESYSTEM/std::experimental::filesystem::is_directory", "FILESYSTEM/std::experimental::filesystem::is_empty", "FILESYSTEM/std::experimental::filesystem::is_fifo", "FILESYSTEM/std::experimental::filesystem::is_other", "FILESYSTEM/std::experimental::filesystem::is_regular_file", "FILESYSTEM/std::experimental::filesystem::is_socket", "FILESYSTEM/std::experimental::filesystem::is_symlink", "FILESYSTEM/std::experimental::filesystem::last_write_time", "FILESYSTEM/std::experimental::filesystem::permissions", "FILESYSTEM/std::experimental::filesystem::read_symlink", "FILESYSTEM/std::experimental::filesystem::remove", "FILESYSTEM/std::experimental::filesystem::remove_all", "FILESYSTEM/std::experimental::filesystem::rename", "FILESYSTEM/std::experimental::filesystem::resize_file", "FILESYSTEM/std::experimental::filesystem::space", "FILESYSTEM/std::experimental::filesystem::status", "FILESYSTEM/std::experimental::filesystem::status_known", "FILESYSTEM/std::experimental::filesystem::swap", "FILESYSTEM/std::experimental::filesystem::symlink_status", "FILESYSTEM/std::experimental::filesystem::system_complete", "FILESYSTEM/std::experimental::filesystem::temp_directory_path", "FILESYSTEM/std::experimental::filesystem::u8path"] -helpviewer_keywords: ["std::experimental::filesystem::absolute", "std::experimental::filesystem::canonical", "std::experimental::filesystem::copy", "std::experimental::filesystem::copy_file", "std::experimental::filesystem::copy_symlink", "std::experimental::filesystem::create_directories", "std::experimental::filesystem::create_directory", "std::experimental::filesystem::create_directory_symlink", "std::experimental::filesystem::create_hard_link", "std::experimental::filesystem::create_symlink", "std::experimental::filesystem::current_path", "std::experimental::filesystem::equivalent", "std::experimental::filesystem::exists", "std::experimental::filesystem::file_size", "std::experimental::filesystem::hard_link_count", "std::experimental::filesystem::hash_value", "std::experimental::filesystem::is_block_file", "std::experimental::filesystem::is_character_file", "std::experimental::filesystem::is_directory", "std::experimental::filesystem::is_empty", "std::experimental::filesystem::is_fifo", "std::experimental::filesystem::is_other", "std::experimental::filesystem::is_regular_file", "std::experimental::filesystem::is_socket", "std::experimental::filesystem::is_symlink", "std::experimental::filesystem::last_write_time", "std::experimental::filesystem::permissions", "std::experimental::filesystem::read_symlink", "std::experimental::filesystem::remove", "std::experimental::filesystem::remove_all", "std::experimental::filesystem::rename", "std::experimental::filesystem::resize_file", "std::experimental::filesystem::space", "std::experimental::filesystem::status", "std::experimental::filesystem::status_known", "std::experimental::filesystem::swap", "std::experimental::filesystem::symlink_status", "std::experimental::filesystem::system_complete", "std::experimental::filesystem::temp_directory_path", "std::experimental::filesystem::u8path"] +ms.date: 08/27/2026 +f1_keywords: ["filesystem/std::filesystem::absolute", "filesystem/std::filesystem::canonical", "filesystem/std::filesystem::copy", "filesystem/std::filesystem::copy_file", "filesystem/std::filesystem::copy_symlink", "filesystem/std::filesystem::create_directories", "filesystem/std::filesystem::create_directory", "filesystem/std::filesystem::create_directory_symlink", "filesystem/std::filesystem::create_hard_link", "filesystem/std::filesystem::create_symlink", "filesystem/std::filesystem::current_path", "filesystem/std::filesystem::equivalent", "filesystem/std::filesystem::exists", "filesystem/std::filesystem::file_size", "filesystem/std::filesystem::hard_link_count", "filesystem/std::filesystem::hash_value", "filesystem/std::filesystem::is_block_file", "filesystem/std::filesystem::is_character_file", "filesystem/std::filesystem::is_directory", "filesystem/std::filesystem::is_empty", "filesystem/std::filesystem::is_fifo", "filesystem/std::filesystem::is_other", "filesystem/std::filesystem::is_regular_file", "filesystem/std::filesystem::is_socket", "filesystem/std::filesystem::is_symlink", "filesystem/std::filesystem::last_write_time", "filesystem/std::filesystem::permissions", "filesystem/std::filesystem::proximate", "filesystem/std::filesystem::read_symlink", "filesystem/std::filesystem::relative", "filesystem/std::filesystem::remove", "filesystem/std::filesystem::remove_all", "filesystem/std::filesystem::rename", "filesystem/std::filesystem::resize_file", "filesystem/std::filesystem::space", "filesystem/std::filesystem::status", "filesystem/std::filesystem::status_known", "filesystem/std::filesystem::swap", "filesystem/std::filesystem::symlink_status", "filesystem/std::filesystem::temp_directory_path", "filesystem/std::filesystem::u8path", "filesystem/std::filesystem::weakly_canonical"] +helpviewer_keywords: ["std::filesystem::absolute", "std::filesystem::canonical", "std::filesystem::copy", "std::filesystem::copy_file", "std::filesystem::copy_symlink", "std::filesystem::create_directories", "std::filesystem::create_directory", "std::filesystem::create_directory_symlink", "std::filesystem::create_hard_link", "std::filesystem::create_symlink", "std::filesystem::current_path", "std::filesystem::equivalent", "std::filesystem::exists", "std::filesystem::file_size", "std::filesystem::hard_link_count", "std::filesystem::hash_value", "std::filesystem::is_block_file", "std::filesystem::is_character_file", "std::filesystem::is_directory", "std::filesystem::is_empty", "std::filesystem::is_fifo", "std::filesystem::is_other", "std::filesystem::is_regular_file", "std::filesystem::is_socket", "std::filesystem::is_symlink", "std::filesystem::last_write_time", "std::filesystem::permissions", "std::filesystem::proximate", "std::filesystem::read_symlink", "std::filesystem::relative", "std::filesystem::remove", "std::filesystem::remove_all", "std::filesystem::rename", "std::filesystem::resize_file", "std::filesystem::space", "std::filesystem::status", "std::filesystem::status_known", "std::filesystem::swap", "std::filesystem::symlink_status", "std::filesystem::temp_directory_path", "std::filesystem::u8path", "std::filesystem::weakly_canonical"] --- # `` functions -These free functions in the [``](../standard-library/filesystem.md) header do modifying and query operations on paths, files, symlinks, directories, and volumes. For more information and code examples, see [File System Navigation (C++)](../standard-library/file-system-navigation.md). +These free functions in the C++17 [``](../standard-library/filesystem.md) header perform modifying and query operations on paths, files, symlinks, directories, and volumes. For more information and code examples, see [File System Navigation (C++)](../standard-library/file-system-navigation.md). -## `absolute` +> [!NOTE] +> This article documents the C++17 `std::filesystem` functions. For the historical prestandard functions that MSVC provided in ``, see [`` functions](../standard-library/experimental-filesystem-functions.md). -```cpp -path absolute(const path& pval, const path& base = current_path()); -``` +## Requirements -The function returns the absolute pathname corresponding to *`pval`* relative to the pathname `base`: +**Header:** `` -1. If `pval.has_root_name() && pval.has_root_directory()` the function returns *`pval`*. +**Namespace:** `std::filesystem` -1. If `pval.has_root_name() && !pval.has_root_directory()` the function returns `pval.root_name()` / `absolute(base).root_directory()` / `absolute(base).relative_path()` / `pval.relative_path()`. +## `absolute` -1. If `!pval.has_root_name() && pval.has_root_directory()` the function returns `absolute(base).root_name()` / *`pval`*. +```cpp +path absolute(const path& pval); +path absolute(const path& pval, error_code& ec); +``` -1. If `!pval.has_root_name() && !pval.has_root_directory()` the function returns `absolute(base)` / *`pval`*. +The functions compose an absolute path that refers to the same file system location as *`pval`*, according to operating-system semantics. The overload that takes *`ec`* returns `path()` if an error occurs. ## `begin` ```cpp -const directory_iterator& begin(const directory_iterator& iter) noexcept; -const recursive_directory_iterator& - begin(const recursive_directory_iterator& iter) noexcept; +directory_iterator begin(directory_iterator iter) noexcept; +recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept; ``` -Both functions return *`iter`*. +Both functions return *`iter`*. Together with `end`, they enable range-based `for` loops over a `directory_iterator` or `recursive_directory_iterator`. ## `canonical` ```cpp -path canonical(const path& pval, const path& base = current_path()); +path canonical(const path& pval); path canonical(const path& pval, error_code& ec); -path canonical(const path& pval, const path& base, error_code& ec); ``` -The functions all form an absolute pathname `pabs = absolute(pval, base)` (or `pabs = absolute(pval)` for the overload with no base parameter), then reduce it to a canonical form in the following sequence of steps: - -1. Every path component `X` for which `is_symlink(X)` is **`true`** is replaced by `read_symlink(X)`. - -1. Every path component `.` (dot is the current directory established by previous path components) is removed. - -1. Every pair of path components `X`/`..` (dot-dot is the parent directory established by previous path components) is removed. - -The function then returns `pabs`. +The functions convert *`pval`*, which must exist, to an absolute path that refers to the same file system object and has no symbolic-link, dot, or dot-dot elements. The overload that takes *`ec`* returns `path()` if an error occurs. ## `copy` @@ -70,13 +62,7 @@ The functions all possibly copy or link one or more files at *from* to *to* unde - `directories_only`, `create_symlinks`, or `create_hard_links` -The functions first determine the file_status values `f` for *from* and `t` for *to*: - -- if `opts & (copy_options::create_symlinks | copy_options::skip_symlinks)`, by calling `symlink_status` - -- otherwise, by calling `status` - -- Otherwise report an error. +The functions first determine the `file_status` values `f` for *from* and `t` for *to*. They use `symlink_status` when *`opts`* contains `copy_options::create_symlinks`, `copy_options::skip_symlinks`, or `copy_options::copy_symlinks`, as required for the source or destination. Otherwise, they use `status`. If `!exists(f) || equivalent(f, t) || is_other(f) || is_other(t) || is_directory(f)&& is_regular_file(t)`, they then report an error (and do nothing else). @@ -84,7 +70,7 @@ Otherwise, if `is_symlink(f)` then: - If `options & copy_options::skip_symlinks`, then do nothing. -- Otherwise, if `!exists(t)&& options & copy_options::copy_symlinks`, then `copy_symlink(from, to, opts)`. +- Otherwise, if `!exists(t) && options & copy_options::copy_symlinks`, then `copy_symlink(from, to)`. - Otherwise, report an error. @@ -92,11 +78,11 @@ Otherwise, if `is_regular_file(f)`, then: - If `opts & copy_options::directories_only`, then do nothing. -- Otherwise, if `opts & copy_options::create_symlinks`, then `create_symlink(to, from)`. +- Otherwise, if `opts & copy_options::create_symlinks`, then `create_symlink(from, to)`. -- Otherwise, if `opts & copy_options::create_hard_links`, then `create_hard_link(to, from)`. +- Otherwise, if `opts & copy_options::create_hard_links`, then `create_hard_link(from, to)`. -- Otherwise, if `is_directory(f)`, then `copy_file(from, to` / `from.filename(), opts)`. +- Otherwise, if `is_directory(t)`, then `copy_file(from, to / from.filename(), opts)`. - Otherwise, `copy_file(from, to, opts)`. @@ -205,11 +191,11 @@ The functions with no parameter *`pval`* return the pathname for the current dir ## `end` ```cpp -directory_iterator& end(const directory_iterator& iter) noexcept; -recursive_directory_iterator& end(const recursive_directory_iterator& iter) noexcept; +directory_iterator end(const directory_iterator&) noexcept; +recursive_directory_iterator end(const recursive_directory_iterator&) noexcept; ``` -The first function returns `directory_iterator()` and the second function returns `recursive_directory_iterator()` +The first function returns `directory_iterator()` and the second function returns `recursive_directory_iterator()`. ## `equivalent` @@ -228,7 +214,7 @@ bool exists(const path& pval); bool exists(const path& pval, error_code& ec) noexcept; ``` -The first function returns `status_known && stat.type() != file_not_found`. The second and third functions return `exists(status(pval))`. +The first function returns `status_known(stat) && stat.type() != file_type::not_found`. The second and third functions return `exists(status(pval))`. ## `file_size` @@ -284,12 +270,11 @@ bool is_directory(const path& pval); bool is_directory(const path& pval, error_code& ec) noexcept; ``` -The first function returns `stat.type() == file_type::directory`. The remaining functions return `is_directory_file(status(pval))`. +The first function returns `stat.type() == file_type::directory`. The remaining functions return `is_directory(status(pval))`. ## `is_empty` ```cpp -bool is_empty(file_status stat) noexcept; bool is_empty(const path& pval); bool is_empty(const path& pval, error_code& ec) noexcept; ``` @@ -314,7 +299,7 @@ bool is_other(const path& pval); bool is_other(const path& pval, error_code& ec) noexcept; ``` -The first function returns `stat.type() == file_type::other`. The remaining functions return `is_other(status(pval))`. +The first function returns `exists(stat) && !is_regular_file(stat) && !is_directory(stat) && !is_symlink(stat)`. The remaining functions return `is_other(status(pval))`. ## `is_regular_file` @@ -360,13 +345,14 @@ The first two functions return the time of last data modification for *`pval`*, ## `permissions` ```cpp -void permissions(const path& pval, perms mask); +void permissions(const path& pval, perms mask, perm_options opts = perm_options::replace); void permissions(const path& pval, perms mask, error_code& ec) noexcept; +void permissions(const path& pval, perms mask, perm_options opts, error_code& ec); ``` -The functions set the permissions for the pathname chosen by *`pval`* to `mask & perms::mask` under control of `perms & (perms::add_perms | perms::remove_perms)`. *`mask`* shall contain at most one of `perms::add_perms` and `perms::remove_perms`. +The functions set the permissions for the pathname chosen by *`pval`* to `mask & perms::mask` under control of *`opts`*. *`opts`* must contain exactly one of `perm_options::replace`, `perm_options::add`, or `perm_options::remove`, and optionally `perm_options::nofollow`. The overloads with no *`opts`* parameter behave as if *`opts`* is `perm_options::replace`. -If `mask & perms::add_perms`, the functions set the permissions to `status(pval).permissions() | mask & perms::mask`. Otherwise, if `mask & perms::remove_perms`, the functions set the permissions to `status(pval).permissions() & ~(mask & perms::mask)`. Otherwise, the functions set the permissions to `mask & perms::mask`. +If `opts & perm_options::add`, the functions set the permissions to `status(pval).permissions() | (mask & perms::mask)`. Otherwise, if `opts & perm_options::remove`, the functions set the permissions to `status(pval).permissions() & ~(mask & perms::mask)`. Otherwise, the functions set the permissions to `mask & perms::mask`. If `opts & perm_options::nofollow` and *`pval`* names a symbolic link, the functions change the permissions of the symbolic link itself rather than the file it resolves to. ## `proximate` @@ -376,6 +362,8 @@ path proximate(const path& p, const path& base = current_path()); path proximate(const path& p, const path& base, error_code& ec); ``` +The first overload returns `proximate(p, current_path(), ec)`. The other overloads return the result of applying `lexically_proximate` to the weakly canonical forms of *`p`* and *`base`*. The overload that takes *`ec`* returns `path()` if an error occurs. + ## `read_symlink` ```cpp @@ -393,6 +381,8 @@ path relative(const path& p, const path& base = current_path()); path relative(const path& p, const path& base, error_code& ec); ``` +The first overload returns `relative(p, current_path(), ec)`. The other overloads return the result of applying `lexically_relative` to the weakly canonical forms of *`p`* and *`base`*. The overload that takes *`ec`* returns `path()` if an error occurs. + ## `remove` ```cpp @@ -423,11 +413,11 @@ The functions rename *from* to *to*. A symlink is itself renamed, not the file i ## `resize_file` ```cpp -void resize(const path& pval, uintmax_t size); -void resize(const path& pval, uintmax_t size, error_code& ec) noexcept; +void resize_file(const path& pval, uintmax_t size); +void resize_file(const path& pval, uintmax_t size, error_code& ec) noexcept; ``` -The functions alter the size of a file such that `file_size(pval) == size` +The functions alter the size of a file such that `file_size(pval) == size`. ## `space` @@ -472,15 +462,6 @@ file_status symlink_status(const path& pval, error_code& ec) noexcept; The functions return the pathname symlink status, the file type, and permissions, associated with *`pval`*. The functions behave the same as `status(pval)` except that a symlink is itself tested, not the file it chooses. -## `system_complete` - -```cpp -path system_complete(const path& pval); -path system_complete(const path& pval, error_code& ec); -``` - -The functions return an absolute pathname that takes into account, as necessary, the current directory associated with its root name. (For POSIX, the functions return `absolute(pval)`). - ## `temp_directory_path` ```cpp @@ -508,3 +489,11 @@ The first function behaves the same as `path(source)` and the second function be path weakly_canonical(const path& p); path weakly_canonical(const path& p, error_code& ec); ``` + +These functions return a path in canonical form, like the `canonical` function, but the path doesn't need to exist. + +## See also + +[Header Files Reference](../standard-library/cpp-standard-library-header-files.md)\ +[``](../standard-library/filesystem.md)\ +[File System Navigation (C++)](../standard-library/file-system-navigation.md) diff --git a/docs/standard-library/filesystem-operators.md b/docs/standard-library/filesystem-operators.md index cb62d33dd91..82332b00605 100644 --- a/docs/standard-library/filesystem-operators.md +++ b/docs/standard-library/filesystem-operators.md @@ -1,23 +1,32 @@ --- description: "Learn more about: operators" title: " operators" -ms.date: "11/04/2016" -f1_keywords: ["FILESYSTEM/std::experimental::filesystem::operator==", "FILESYSTEM/std::experimental::filesystem::operator!=", "FILESYSTEM/std::experimental::filesystem::operator<", "FILESYSTEM/std::experimental::filesystem::operator<=", "FILESYSTEM/std::experimental::filesystem::operator>", "FILESYSTEM/std::experimental::filesystem::operator>=", "FILESYSTEM/std::experimental::filesystem::operator/", "FILESYSTEM/std::experimental::filesystem::operator<<", "FILESYSTEM/std::experimental::filesystem::operator>>"] -ms.assetid: 102c4833-aa3b-41a8-8998-f5003c546bfd +ms.date: 08/27/2026 +f1_keywords: ["filesystem/std::filesystem::operator==", "filesystem/std::filesystem::operator!=", "filesystem/std::filesystem::operator<", "filesystem/std::filesystem::operator<=", "filesystem/std::filesystem::operator>", "filesystem/std::filesystem::operator>=", "filesystem/std::filesystem::operator/", "filesystem/std::filesystem::operator<<", "filesystem/std::filesystem::operator>>"] +helpviewer_keywords: ["std::filesystem::operator==", "std::filesystem::operator!=", "std::filesystem::operator<", "std::filesystem::operator<=", "std::filesystem::operator>", "std::filesystem::operator>=", "std::filesystem::operator/", "std::filesystem::operator<<", "std::filesystem::operator>>"] --- # `` operators -The operators perform a lexical comparison of two paths as strings. Use the `equivalent` function to determine whether two paths (for example a relative path and an absolute path) refer to the same file or directory on disk. +These nonmember operators for [`std::filesystem::path`](../standard-library/path-class.md) are declared in the C++17 [``](../standard-library/filesystem.md) header. The comparison operators compare two paths element by element in generic format by using `path::compare`, not as raw strings. Use the [`equivalent`](../standard-library/filesystem-functions.md#equivalent) function to determine whether two paths (for example, a relative path and an absolute path) refer to the same file or directory on disk. + +> [!NOTE] +> This page documents the C++17 `std::filesystem` operators. For the historical prestandard operators that MSVC provided in ``, see [`` operators](../standard-library/experimental-filesystem-operators.md). For more information, see [File System Navigation (C++)](../standard-library/file-system-navigation.md). +## Requirements + +**Header:** `` + +**Namespace:** `std::filesystem` + ## operator== ```cpp bool operator==(const path& left, const path& right) noexcept; ``` -The function returns left.native() == right.native(). +The function returns `left.compare(right) == 0`. ## operator!= @@ -25,7 +34,7 @@ The function returns left.native() == right.native(). bool operator!=(const path& left, const path& right) noexcept; ``` -The function returns !(left == right). +The function returns `!(left == right)`. ## operator< @@ -33,7 +42,7 @@ The function returns !(left == right). bool operator<(const path& left, const path& right) noexcept; ``` -The function returns left.native() < right.native(). +The function returns `left.compare(right) < 0`. ## operator<= @@ -41,7 +50,7 @@ The function returns left.native() < right.native(). bool operator<=(const path& left, const path& right) noexcept; ``` -The function returns !(right \< left). +The function returns `!(right < left)`. ## operator> @@ -49,7 +58,7 @@ The function returns !(right \< left). bool operator>(const path& left, const path& right) noexcept; ``` -The function returns right \< left. +The function returns `right < left`. ## operator>= @@ -57,7 +66,7 @@ The function returns right \< left. bool operator>=(const path& left, const path& right) noexcept; ``` -The function returns !(left < right). +The function returns `!(left < right)`. ## operator/ @@ -65,13 +74,7 @@ The function returns !(left < right). path operator/(const path& left, const path& right); ``` -The function executes: - -```cpp -basic_string str; -path ans = left; -return (ans /= right); -``` +The function returns `path(left) /= right`. ## operator<< @@ -80,20 +83,26 @@ template basic_ostream& operator<<(basic_ostream& os, const path& pval); ``` -The function returns os << pval.string\(). +The function inserts the path into the stream as a quoted string. It returns `os << quoted(pval.string())`. ## operator>> ```cpp template -basic_istream& operator<<(basic_istream& is, const path& pval); +basic_istream& operator>>(basic_istream& is, path& pval); ``` -The function executes: +The function extracts a quoted string from the stream and assigns it to *`pval`*. It executes: ```cpp basic_string str; -is>> str; +is >> quoted(str); pval = str; -return (is); +return is; ``` + +## See also + +[Header Files Reference](../standard-library/cpp-standard-library-header-files.md)\ +[``](../standard-library/filesystem.md)\ +[File System Navigation (C++)](../standard-library/file-system-navigation.md) diff --git a/docs/standard-library/filesystem.md b/docs/standard-library/filesystem.md index 449d7f2bb7b..3b53ef8e6e1 100644 --- a/docs/standard-library/filesystem.md +++ b/docs/standard-library/filesystem.md @@ -1,50 +1,41 @@ --- title: "" description: "Describes the classes, functions, and types in the filesystem header of the Standard C++ library." -ms.date: "09/02/2021" -f1_keywords: ["", "filesystem/std::filesystem", "std::filesystem", "std::experimental::filesystem"] -no-loc: [filesystem, experimental, char, wchar_t, char16_t, char32_t] +ms.date: 08/27/2026 +f1_keywords: ["", "filesystem/std::filesystem", "std::filesystem"] +no-loc: [filesystem, char, wchar_t, char16_t, char32_t] --- -# `filesystem` +# `` -Include the header `` for access to classes and functions that manipulate and retrieve information about paths, files, and directories. +For current code, include the C++17 standard header `` and use the `std::filesystem` namespace for classes and functions that manipulate and retrieve information about paths, files, and directories. Compile with `/std:c++17` or later. ## Syntax ```cpp #include // C++17 standard header file name -#include // Header file for pre-standard implementation -using namespace std::experimental::filesystem::v1; +using namespace std::filesystem; ``` -> [!IMPORTANT] -> At the release of Visual Studio 2017, the `` header was not yet a C++ standard. C++ in Visual Studio 2017 RTW implements the final draft standard, found in [ISO/IEC JTC 1/SC 22/WG 21 N4100](https://wg21.link/n4100). Visual Studio 2017 version 15.7 and later supports the new C++17 `` standard. -> This is a completely new implementation, incompatible with the previous `std::experimental` version. It was made necessary by symlink support, bug fixes, and changes in standard-required behavior. In Visual Studio 2019 version 16.3 and later, including `` provides only the new `std::filesystem`. Including `` provides only the old experimental implementation. The experimental implementation will be removed in the next ABI-breaking release of the libraries. +> [!NOTE] +> Historical note: Before C++17 standardized ``, MSVC shipped a separate prestandard implementation in the `` header, which was removed starting in MSVC Build Tools version 14.51. For its documentation, see [``](../standard-library/experimental-filesystem.md). -This header supports file systems for one of two broad classes of host operating systems: Microsoft Windows and POSIX. +The `` header supports file systems for Microsoft Windows and POSIX. While most functionality is common to both operating systems, this document identifies where differences occur. For example: - Windows supports multiple root names, such as `c:` or `\\network_name`. A file system consists of a forest of trees, each with its own root directory, such as `c:\` or `\\network_name\`, and each with its own current directory, for completing a relative pathname (one that's not an absolute pathname). - - POSIX supports a single tree, with no root name, the single root directory `/`, and a single current directory. Another significant difference is the native representation of pathnames: - Windows uses a null-terminated sequence of **`wchar_t`**, encoded as UTF-16 (one or more elements for each character). - - POSIX uses a null-terminated sequence of **`char`**, encoded as UTF-8 (one or more elements for each character). - - An object of class `path` stores the pathname in native form, but supports easy conversion between this stored form and several external forms: - A null-terminated sequence of **`char`**, encoded as favored by the operating system. - - A null-terminated sequence of **`char`**, encoded as UTF-8. - - A null-terminated sequence of **`wchar_t`**, encoded as favored by the operating system. - - A null-terminated sequence of **`char16_t`**, encoded as UTF-16. - - A null-terminated sequence of **`char32_t`**, encoded as UTF-32. Interconversions between these representations are mediated, as needed, by the use of one or more `codecvt` facets. If no specific locale object is specified, these facets are obtained from the global locale. @@ -52,25 +43,17 @@ Another significant difference is the native representation of pathnames: Another difference is the detail with which each operating system lets you specify file or directory access permissions: - Windows records whether a file is read-only or writable, an attribute that has no meaning for directories. - - POSIX records whether a file can be read, written, or executed (scanned, if a directory). And, whether each operation is allowed for the owner, the owner's group, or for everybody, plus a few other permissions. Common to both systems is the structure imposed on a pathname once you get past the root name. For the pathname `c:/abc/xyz/def.ext`: - The root name is `c:`. - - The root directory is `/`. - - The root path is `c:/`. - - The relative path is `abc/xyz/def.ext`. - - The parent path is `c:/abc/xyz`. - - The filename is `def.ext`. - - The stem is `def`. - - The extension is `.ext`. A minor difference is the preferred separator between the sequence of directories in a pathname. Both operating systems let you write a forward slash `/`, but in some contexts Windows prefers a backslash `\`. The implementation stores its preferred separator in the data member `preferred_separator` in `path`. @@ -79,20 +62,18 @@ Finally, `path` objects have an important feature: You can use them wherever a f For more information and code examples, see [File system navigation (C++)](../standard-library/file-system-navigation.md). -## Members - -### Classes +## Classes |Name|Description| |-|-| |[`directory_entry` class](../standard-library/directory-entry-class.md)|Describes an object that is returned by a `directory_iterator` or a `recursive_directory_iterator` and contains a `path`.| |[`directory_iterator` class](../standard-library/directory-iterator-class.md)|Describes an input iterator that sequences through the file names in a file-system directory.| -|[`filesystem_error` class](../standard-library/filesystem-error-class.md)|A base class for exceptions that are thrown to report a low-level system overflow.| +|[`filesystem_error` class](../standard-library/filesystem-error-class.md)|A base class for exceptions that are thrown to report a low-level system error.| |[`path` class](../standard-library/path-class.md)|Defines a class that stores an object of template type `String` that is suitable for use as a file name.| |[`recursive_directory_iterator` class](../standard-library/recursive-directory-iterator-class.md)|Describes an input iterator that sequences through the file names in a file-system directory. The iterator can also descend into subdirectories.| |[`file_status` class](../standard-library/file-status-class.md)|Wraps a `file_type`.| -### Structs +## Structs |Name|Description| |-|-| diff --git a/docs/standard-library/path-class.md b/docs/standard-library/path-class.md index 8f7edbb9c17..b57cc27eb2b 100644 --- a/docs/standard-library/path-class.md +++ b/docs/standard-library/path-class.md @@ -1,14 +1,16 @@ --- title: "path Class" -description: "Learn more about: path Class" -ms.date: 06/17/2022 -f1_keywords: ["filesystem/std::experimental::filesystem::path"] +description: "Learn more about the C++17 std::filesystem path class in the header." +ms.date: 08/27/2026 +f1_keywords: ["filesystem/std::filesystem::path"] +helpviewer_keywords: ["std::filesystem::path class"] --- - -# `path` Class +# `path` class The **`path`** class stores an object of type `string_type`, called `myname` here for the purposes of exposition, suitable for use as a pathname. `string_type` is a synonym for `basic_string`, where `value_type` is a synonym for **`wchar_t`** on Windows or **`char`** on POSIX. +The `path` class described here is the C++17 `std::filesystem::path` class in the `` header. + For more information, and code examples, see [File System Navigation (C++)](../standard-library/file-system-navigation.md). ## Syntax @@ -31,21 +33,27 @@ class path; |[`iterator`](#iterator)|A bidirectional constant iterator that designates the `path` components of `myname`.| |[`string_type`](#string_type)|The type is a synonym for `basic_string`.| +### Enumerations + +|Type name|Description| +|-|-| +|[`format`](#format)|Specifies the pathname format for constructors: `auto_format`, `native_format`, or `generic_format`.| + ### Member functions |Member function|Description| |-|-| -|[`append`](#append)|Appends the specified sequence to `mypath`, converted and inserting a preferred_separator as needed.| -|[`assign`](#assign)|Replaces `mypath` with the specified sequence, converted as needed.| +|[`append`](#append)|Appends the specified sequence to `myname`, converted and inserting a preferred_separator as needed.| +|[`assign`](#assign)|Replaces `myname` with the specified sequence, converted as needed.| |[`begin`](#begin)|Returns a `path::iterator` designating the first path element in the pathname, if present.| -|[`c_str`](#c_str)|Returns a pointer to the first character in `mypath`.| -|[`clear`](#clear)|Executes `mypath.clear()`.| +|[`c_str`](#c_str)|Returns a pointer to the first character in `myname`.| +|[`clear`](#clear)|Executes `myname.clear()`.| |[`compare`](#compare)|Returns comparison values.| -|[`concat`](#concat)|Appends the specified sequence to `mypath`, converted (but not inserting a separator) as needed.| -|[`empty`](#empty)|Returns `mypath.empty()`.| +|[`concat`](#concat)|Appends the specified sequence to `myname`, converted (but not inserting a separator) as needed.| +|[`empty`](#empty)|Returns `myname.empty()`.| |[`end`](#end)|Returns an end-of-sequence iterator of type `iterator`.| |[`extension`](#extension)|Returns the suffix of `filename()`.| -|[`filename`](#filename)|Returns the root directory component of `myname`, specifically `empty() ? path() : *--end()`. The component may be empty.| +|[`filename`](#filename)|Returns the filename component of `myname`, specifically `empty() ? path() : *--end()`. The component may be empty.| |[`generic_string`](#generic_string)|Returns `this->string(al)` with (under Windows) any backslash converted to a forward slash.| |[`generic_u16string`](#generic_u16string)|Returns `u16string()` with (under Windows) any backslash converted to a forward slash.| |[`generic_u32string`](#generic_u32string)|Returns `u32string()` with (under Windows) any backslash converted to a forward slash.| @@ -61,6 +69,9 @@ class path; |[`has_stem`](#has_stem)|Returns `!stem().empty()`.| |[`is_absolute`](#is_absolute)|For Windows, the function returns `has_root_name() && has_root_directory()`. For POSIX, the function returns `has_root_directory()`.| |[`is_relative`](#is_relative)|Returns `!is_absolute()`.| +|[`lexically_normal`](#lexically_normal)|Returns `myname` converted to normal form.| +|[`lexically_proximate`](#lexically_proximate)|Returns `lexically_relative(base)`, or `*this` if that result is empty.| +|[`lexically_relative`](#lexically_relative)|Returns `myname` made relative to a base path, using lexical (string) analysis only.| |[`make_preferred`](#make_preferred)|Converts each separator to a `preferred_separator` as needed.| |[`native`](#native)|Returns the native representation of the path.| |[`parent_path`](#parent_path)|Returns the parent path component of `myname`.| @@ -73,13 +84,13 @@ class path; |[`root_name`](#root_name)|Returns the root name component of `myname`. | |[`root_path`](#root_path)|Returns the root path component of `myname`.| |[`stem`](#stem)|Returns the `stem` component of `myname`.| -|[`string`](#string)|Converts the sequence stored in `mypath`.| -|[`swap`](#swap)|Executes `swap(mypath, right.mypath)`.| -|[`u16string`](#u16string)|Converts the sequence stored in `mypath` to UTF-16 and returns it stored in an object of type `u16string`.| -|[`u32string`](#u32string)|Converts the sequence stored in `mypath` to UTF-32 and returns it stored in an object of type `u32string`.| -|[`u8string`](#u8string)|Converts the sequence stored in `mypath` to UTF-8 and returns it stored in an object of type `u8string`.| +|[`string`](#string)|Converts the sequence stored in `myname`.| +|[`swap`](#swap)|Executes `swap(myname, right.myname)`.| +|[`u16string`](#u16string)|Converts the sequence stored in `myname` to UTF-16 and returns it stored in an object of type `u16string`.| +|[`u32string`](#u32string)|Converts the sequence stored in `myname` to UTF-32 and returns it stored in an object of type `u32string`.| +|[`u8string`](#u8string)|Converts the sequence stored in `myname` to UTF-8 and returns it stored in an object of type `u8string`.| |[`value_type`](#value_type)|The type describes the path elements favored by the host operating system.| -|[`wstring`](#wstring)|Converts the sequence stored in `mypath` to the encoding favored by the host system for a **`wchar_t`** sequence and returns it stored in an object of type `wstring`.| +|[`wstring`](#wstring)|Converts the sequence stored in `myname` to the encoding favored by the host system for a **`wchar_t`** sequence and returns it stored in an object of type `wstring`.| ### Operators @@ -94,11 +105,11 @@ class path; **Header:** `` -**Namespace:** `std::experimental::filesystem` +**Namespace:** `std::filesystem` ## `path::append` -Appends the specified sequence to `mypath`, converted and inserting a `preferred_separator` as needed. +Appends the specified sequence to `myname`, converted and inserting a `preferred_separator` as needed. ```cpp template @@ -121,9 +132,11 @@ End of specified sequence. ## `path::assign` -Replaces `mypath` with the specified sequence, converted as needed. +Replaces `myname` with the specified sequence, converted as needed. ```cpp +path& assign(string_type&& source); + template path& assign(const Source& source); @@ -152,15 +165,15 @@ iterator begin() const; ## `path::c_str` -Returns a pointer to the first character in `mypath`. +Returns a pointer to the first character in `myname`. ```cpp -const value_type& *c_str() const noexcept; +const value_type* c_str() const noexcept; ``` ## `path::clear` -Executes `mypath.clear()`. +Executes `myname.clear()`. ```cpp void clear() noexcept; @@ -168,11 +181,12 @@ void clear() noexcept; ## `path::compare` -The first function returns `mypath.compare(pval.native())`. The second function returns `mypath.compare(str)`. The third function returns `mypath.compare(ptr)`. +The first function compares the elements of this path with *`pval`*. The other functions construct a path from their argument and return the result of comparing it with this path. ```cpp int compare(const path& pval) const noexcept; int compare(const string_type& str) const; +int compare(basic_string_view str) const; int compare(const value_type *ptr) const; ``` @@ -189,7 +203,7 @@ Pointer to compare. ## `path::concat` -Appends the specified sequence to `mypath`, converted (but not inserting a separator) as needed. +Appends the specified sequence to `myname`, converted (but not inserting a separator) as needed. ```cpp template @@ -220,7 +234,7 @@ typedef iterator const_iterator; ## `path::empty` -Returns `mypath.empty()`. +Returns `myname.empty()`. ```cpp bool empty() const noexcept; @@ -252,12 +266,36 @@ Otherwise, the suffix begins with (and includes) the rightmost dot. ## `path::filename` -Returns the root directory component of `myname`, specifically `empty() path() : *--end()`. The component may be empty. +Returns the filename component of `myname`, specifically `empty() ? path() : *--end()`. The component may be empty. ```cpp path filename() const; ``` +## `path::format` + +Specifies the pathname format used to interpret the character sequence passed to a `path` constructor. + +```cpp +enum format { + auto_format, + native_format, + generic_format +}; +``` + +### Members + +|Enumerator|Description| +|-|-| +|`auto_format`|The implementation autodetects the format. This is the default for the constructors that take a `format` argument.| +|`native_format`|Interpret the sequence in the native pathname format.| +|`generic_format`|Interpret the sequence in the generic pathname format.| + +### Remarks + +Because the native format and the generic format are interchangeable on Windows, the Microsoft implementation treats all three enumerators the same. The `format` parameter is provided for standard conformance and portability. For more information, see the WG21 N4659 [fs.class.path] specification. + ## `path::generic_string` Returns `this->string(al)` with (under Windows) any backslash converted to a forward slash. @@ -425,6 +463,48 @@ For `pval` an object of type `path`: 1. Altering `myname` invalidates all iterators designating elements in `myname`. +## `path::lexically_normal` + +Returns `myname` converted to normal form. The conversion is purely lexical: the filesystem isn't accessed. + +```cpp +path lexically_normal() const; +``` + +### Remarks + +Normalization collapses redundant elements such as `.` and `..` and directory separators. For example, `path("a/./b/../c").lexically_normal()` yields `a\c` on Windows. An empty path normalizes to an empty path; a path that reduces to nothing normalizes to `.`. For the full normalization algorithm, see the WG21 N4659 [fs.path.generic] specification. + +## `path::lexically_proximate` + +Returns the result of [`lexically_relative(base)`](#lexically_relative). If that result is an empty path, returns a copy of `*this` instead. + +```cpp +path lexically_proximate(const path& base) const; +``` + +### Parameters + +*`base`*\ +The base path to make `*this` proximate to. + +## `path::lexically_relative` + +Returns `myname` made relative to *`base`*, using lexical (string) analysis only. The filesystem isn't accessed. + +```cpp +path lexically_relative(const path& base) const; +``` + +### Parameters + +*`base`*\ +The base path to make `*this` relative to. + +### Remarks + +If `root_name() != base.root_name()`, or if one path is absolute and the other is relative, or if the path has a filename but no root directory while the base doesn't, returns an empty path. Otherwise, determines the relative path from *`base`* to `*this` by finding the first mismatched element and emitting `..` for each remaining element of *`base`*, followed by the remaining elements of `*this`. For example, `path("/a/d").lexically_relative("/a/b/c")` yields `..\..\d`. For the full algorithm, see the WG21 N4659 [fs.path.gen] specification. + ## `path::make_preferred` Converts each separator to a `preferred_separator` as needed. @@ -445,7 +525,7 @@ const string_type& native() const noexcept; The path is available in a portable generic format (see [`generic_string()`](#generic_string)) or the native format of the path. This function returns the native string. On a POSIX system, the generic format and the native format are the same. -In the following example running on Windows 11, the generic path string is `c:/t/temp/temp.txt` and the native string is `c:\\t\\temp.txt` +In the following example running on Windows, the generic path string is `c:/t/temp.txt` and the native string is `c:\t\temp.txt`. ```cpp // Compile with /std:c++17 or higher @@ -454,7 +534,7 @@ In the following example running on Windows 11, the generic path string is `c:/t int main() { std::filesystem::path p(R"(c:\t\temp.txt)"); - auto native = p.native(); // Windows: L"c:\\t\temp.txt" + auto native = p.native(); // Windows: L"c:\\t\\temp.txt" auto generic = p.generic_string(); // Windows: "c:/t/temp.txt" } ``` @@ -466,6 +546,7 @@ Replaces the elements of the path with a copy of another path. ```cpp path& operator=(const path& right); path& operator=(path&& right) noexcept; +path& operator=(string_type&& source); template path& operator=(const Source& source); @@ -481,7 +562,7 @@ The source `path`. ### Remarks -The first member operator copies `right.myname` to `myname`. The second member operator moves `right.myname` to `myname`. The third member operator behaves the same as `*this = path(source)`. +The first member operator copies `right.myname` to `myname`. The second member operator moves `right.myname` to `myname`. The third member operator moves *`source`* into `myname`. The fourth member operator behaves the same as `*this = path(source)`. ## `path::operator+=` @@ -490,6 +571,7 @@ Various `concat` expressions. ```cpp path& operator+=(const path& right); path& operator+=(const string_type& str); +path& operator+=(basic_string_view str); path& operator+=(const value_type *ptr); path& operator+=(value_type elem); @@ -519,19 +601,7 @@ The added source. ### Remarks -The member functions behave the same as the following corresponding expressions: - -1. `concat(right);` - -1. `concat(path(str));` - -1. `concat(ptr);` - -1. `concat(string_type(1, elem));` - -1. `concat(source);` - -1. `concat(path(basic_string(1, elem)));` +The member functions behave the same as calling [`concat`](#concat) with the argument. The `path`, `string_type`, `basic_string_view`, and null-terminated `value_type*` overloads concatenate the argument's character sequence. The `value_type` and `Elem` overloads concatenate a single character. The templated `Source` overload concatenates the converted source sequence. ## `path::operator/=` @@ -585,22 +655,24 @@ Returns the parent path component of `myname`, specifically the prefix of `mynam Constructs a `path` in various ways. ```cpp -path(); +path() noexcept; path(const path& right); path(path&& right) noexcept; -template -path(const Source& source); +path(string_type&& source, format fmt = auto_format); template -path(const Source& source, const locale& loc); +path(const Source& source, format fmt = auto_format); template -path(InIt first, InIt last); +path(InIt first, InIt last, format fmt = auto_format); + +template +path(const Source& source, const locale& loc, format fmt = auto_format); template -path(InIt first, InIt last, const locale& loc); +path(InIt first, InIt last, const locale& loc, format fmt = auto_format); ``` ### Parameters @@ -611,6 +683,9 @@ The path of which the constructed path is to be a copy. *`source`*\ The source of which the constructed path is to be a copy. +*`fmt`*\ +The pathname [`format`](#format) used to interpret *`source`* or the *`first`*/*`last`* range. Defaults to `auto_format`. + *`loc`*\ The specified locale. @@ -626,17 +701,21 @@ The constructors all construct `myname` in various ways: For `path()` it's `myname()`. -For `path(const path& right`) it's `myname(right.myname)`. +For `path(const path& right)` it's `myname(right.myname)`. For `path(path&& right)` it's `myname(right.myname)`. -For `template path(const Source& source)` it's `myname(source)`. +For `path(string_type&& source, format fmt)` it's `myname(move(source))`. + +For `template path(const Source& source, format fmt)` it's `myname(source)`. + +For `template path(const Source& source, const locale& loc, format fmt)` it's `myname(source)`, obtaining any needed `codecvt` facets from `loc`. -For `template path(const Source& source, const locale& loc)` it's `myname(source)`, obtaining any needed `codecvt` facets from `loc`. +For `template path(InIt first, InIt last, format fmt)` it's `myname(first, last)`. -For `template path(InIt first, InIt last)` it's `myname(first, last)`. +For `template path(InIt first, InIt last, const locale& loc, format fmt)` it's `myname(first, last)`, obtaining any needed `codecvt` facets from `loc`. -For `template path(InIt first, InIt last, const locale& loc)` it's `myname(first, last)`, obtaining any needed `codecvt` facets from `loc`. +The *`fmt`* parameter selects the pathname format. On Windows, the native and generic formats are interchangeable, so the Microsoft implementation ignores *`fmt`*. ## `path::preferred_separator` @@ -644,9 +723,9 @@ The constant object gives the preferred character for separating path components ```cpp #if _WIN32_C_LIB -static constexpr value_type preferred_separator == L'\\'; +static constexpr value_type preferred_separator = L'\\'; #else // assume POSIX -static constexpr value_type preferred_separator == '/'; +static constexpr value_type preferred_separator = '/'; #endif // filesystem model now defined ``` @@ -765,17 +844,17 @@ Returns the `stem` component of `myname`, specifically `filename().native()` wit ## `path::string` -Converts the sequence stored in `mypath`. +Converts the sequence stored in `myname`. ```cpp -template \, class Alloc = allocator\> -basic_string\ string(const Alloc& al = Alloc()) const; +template , class Alloc = allocator> +basic_string string(const Alloc& al = Alloc()) const; string string() const; ``` ### Remarks -The first (template) member function converts the sequence stored in `mypath` the same way as: +The first (template) member function converts the sequence stored in `myname` the same way as: 1. `string()` for `string()` @@ -785,7 +864,7 @@ The first (template) member function converts the sequence stored in `mypath` th 1. `u32string()` for `string()` -The second member function converts the sequence stored in `mypath` to the encoding favored by the host system for a **`char`** sequence and returns it stored in an object of type `string`. +The second member function converts the sequence stored in `myname` to the encoding favored by the host system for a **`char`** sequence and returns it stored in an object of type `string`. ## `path::string_type` @@ -797,7 +876,7 @@ typedef basic_string string_type; ## `path::swap` -Executes `swap(mypath, right.mypath)`. +Executes `swap(myname, right.myname)`. ```cpp void swap(path& right) noexcept; @@ -805,7 +884,7 @@ void swap(path& right) noexcept; ## `path::u16string` -Converts the sequence stored in `mypath` to UTF-16 and returns it stored in an object of type `u16string`. +Converts the sequence stored in `myname` to UTF-16 and returns it stored in an object of type `u16string`. ```cpp u16string u16string() const; @@ -813,7 +892,7 @@ u16string u16string() const; ## `path::u32string` -Converts the sequence stored in `mypath` to UTF-32 and returns it stored in an object of type `u32string`. +Converts the sequence stored in `myname` to UTF-32 and returns it stored in an object of type `u32string`. ```cpp u32string u32string() const; @@ -821,7 +900,7 @@ u32string u32string() const; ## `path::u8string` -Converts the sequence stored in `mypath` to UTF-8 and returns it stored in an object of type `u8string`. +Converts the sequence stored in `myname` to UTF-8 and returns it stored in an object of type `u8string`. ```cpp string u8string() const; @@ -841,7 +920,7 @@ typedef char value_type; ## `path::wstring` -Converts the sequence stored in `mypath` to the encoding favored by the host system for a **`wchar_t`** sequence and returns it stored in an object of type `wstring`. +Converts the sequence stored in `myname` to the encoding favored by the host system for a **`wchar_t`** sequence and returns it stored in an object of type `wstring`. ```cpp wstring wstring() const; @@ -849,4 +928,5 @@ wstring wstring() const; ## See also +[``](../standard-library/filesystem.md)\ [Header Files Reference](../standard-library/cpp-standard-library-header-files.md) diff --git a/docs/standard-library/recursive-directory-iterator-class.md b/docs/standard-library/recursive-directory-iterator-class.md index 12ce5fff52f..cecff5a423b 100644 --- a/docs/standard-library/recursive-directory-iterator-class.md +++ b/docs/standard-library/recursive-directory-iterator-class.md @@ -1,9 +1,8 @@ --- description: "Learn more about: recursive_directory_iterator Class" title: "recursive_directory_iterator Class" -ms.date: 06/17/2022 -f1_keywords: ["filesystem/std::tr2::sys::recursive_directory_iterator"] -ms.assetid: 79a061bd-5b64-404c-97e8-749c888c2ced +ms.date: 08/27/2026 +f1_keywords: ["filesystem/std::filesystem::recursive_directory_iterator"] ms.custom: devdivchpfy22 --- @@ -31,7 +30,7 @@ The class template stores: 1. an object of type `directory_options`, called `myoptions` here, which records the options established at construction -A default constructed object of type `recursive_directory_entry` has an end-of-sequence iterator at `mystack.top().first` and represents the end-of-sequence iterator. For example, given the directory `abc` with entries `def` (a directory), `def/ghi`, and `jkl`, the code: +A default-constructed object of type `recursive_directory_iterator` has an end-of-sequence iterator at `mystack.top().first` and represents the end-of-sequence iterator. For example, given the directory `abc` with entries `def` (a directory), `def/ghi`, and `jkl`, the code: ```cpp for (recursive_directory_iterator next(path("abc")), end; next != end; ++next) @@ -58,7 +57,7 @@ will call visit with the arguments `path("abc/def/ghi")` and `path("abc/jkl")`. |[disable_recursion_pending](#disable_recursion_pending)|Stores **`true`** in `no_push`.| |[increment](#increment)|Advances to the next filename in sequence.| |[options](#options)|Returns `myoptions`.| -|[pop](#pop)|Returns the next object.| +|[pop](#pop)|Moves the iterator to the next entry at the next lower depth.| |[recursion_pending](#recursion_pending)|Returns `!no_push`.| ### Operators @@ -74,9 +73,9 @@ will call visit with the arguments `path("abc/def/ghi")` and `path("abc/jkl")`. ## Requirements -**Header:** \ +**Header:** `` -**Namespace:** std::tr2::sys +**Namespace:** `std::filesystem` ## recursive_directory_iterator::depth @@ -99,7 +98,7 @@ void disable_recursion_pending(); Advances to the next filename in sequence. ```cpp -recursive_directory_iterator& increment(error_code& ec) noexcept; +recursive_directory_iterator& increment(error_code& ec); ``` ### Parameters @@ -173,14 +172,13 @@ Increments the `recursive_directory_iterator`. ```cpp recursive_directory_iterator& operator++(); - -recursive_directory_iterator& operator++(int); +recursive_directory_iterator operator++(int); ``` ### Parameters *int*\ -The specified increment. +Dummy argument. It's a C++ convention used only to distinguish the postfix increment operator from the prefix increment operator. The C++ standard requires the postfix form to take a dummy int parameter. ### Remarks @@ -196,12 +194,18 @@ directory_options options() const; ## recursive_directory_iterator::pop -Returns the next object. +Moves the iterator to the next entry at the next lower depth. ```cpp void pop(); +void pop(error_code& ec); ``` +### Parameters + +`ec`\ +The error code that reports the status of the operation. The overload that takes an *ec* argument reports errors in *ec* instead of throwing an exception. + ### Remarks If `depth() == 0` the object becomes an end-of-sequence iterator. Otherwise, the member function terminates scanning of the current (deepest) directory and resumes at the next lower depth. diff --git a/docs/standard-library/space-info-structure.md b/docs/standard-library/space-info-structure.md index bdb546b54b2..e305998f984 100644 --- a/docs/standard-library/space-info-structure.md +++ b/docs/standard-library/space-info-structure.md @@ -1,9 +1,8 @@ --- description: "Learn more about: space_info Structure" title: "space_info Structure" -ms.date: "09/10/2018" -f1_keywords: ["filesystem/std::tr2::sys::space_info"] -ms.assetid: f2b35b42-06ff-45bd-8617-39a0f5358a54 +ms.date: 08/27/2026 +f1_keywords: ["filesystem/std::filesystem::space_info"] --- # space_info Structure @@ -26,15 +25,15 @@ struct space_info |Name|Description| |----------|-----------------| -|`unsigned long long capacity`|Represents the total number of bytes that the volume can represent.| -|`unsigned long long free`|Represents the number of bytes that are not used to represent data on the volume.| -|`unsigned long long available`|Represents the number of bytes that are available to represent data on the volume.| +|`uintmax_t capacity`|Represents the total number of bytes that the volume can represent.| +|`uintmax_t free`|Represents the number of bytes that are not used to represent data on the volume.| +|`uintmax_t available`|Represents the number of bytes that are available to represent data on the volume.| ## Requirements **Header:** \ -**Namespace:** std::experimental::filesystem +**Namespace:** std::filesystem ## See also diff --git a/docs/standard-library/toc.yml b/docs/standard-library/toc.yml index bfb970bf6fa..abcc34e3e73 100644 --- a/docs/standard-library/toc.yml +++ b/docs/standard-library/toc.yml @@ -8,7 +8,7 @@ items: href: cpp-standard-library-header-files.md - name: expanded: false - items: + items: - name: href: algorithm.md - name: functions @@ -375,6 +375,31 @@ items: href: recursive-directory-iterator-class.md - name: space_info struct href: space-info-structure.md + - name: (removed) + expanded: false + items: + - name: + href: experimental-filesystem.md + - name: functions + href: experimental-filesystem-functions.md + - name: operators + href: experimental-filesystem-operators.md + - name: enumerations + href: experimental-filesystem-enumerations.md + - name: directory_entry class + href: experimental-filesystem-directory-entry-class.md + - name: directory_iterator class + href: experimental-filesystem-directory-iterator-class.md + - name: file_status class + href: experimental-filesystem-file-status-class.md + - name: filesystem_error class + href: experimental-filesystem-error-class.md + - name: path class + href: experimental-filesystem-path-class.md + - name: recursive_directory_iterator class + href: experimental-filesystem-recursive-directory-iterator-class.md + - name: space_info struct + href: experimental-filesystem-space-info-structure.md - name: expanded: false items: From 530c251ff51ad38ca84f90a5832f88b78ba2db06 Mon Sep 17 00:00:00 2001 From: Eulernion Date: Fri, 11 Sep 2026 15:44:06 +0200 Subject: [PATCH 11/11] revised `isfinite`, `_finite`, and `_finitef` documentation (#5962) * revised `isfinite`, `_finite`, and `_finitef` documentation this corrects some information of the `isfinite`, `_finite`, and `_finitef` reference page: the current page lists `` and `` as valid headers for `_finite` even though the current UCRT declares it only through `` and ``. its remarks section also name x86 instead of x64 as a supported `_finitef` target, while the UCRT implementation disagrees. the return value section benignly omitted signed zeros. this revision addresses the C and C++ header requirements, and makes it evident that normal numbers, subnormal numbers, and **both signed zeros** are finite. * Update documentation for isfinite and finite functions Minor wordsmithing --------- Co-authored-by: Tyler Whitney --- docs/c-runtime-library/reference/finite-finitef.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/c-runtime-library/reference/finite-finitef.md b/docs/c-runtime-library/reference/finite-finitef.md index 4bc7c14d38a..d80a82c72c5 100644 --- a/docs/c-runtime-library/reference/finite-finitef.md +++ b/docs/c-runtime-library/reference/finite-finitef.md @@ -42,18 +42,23 @@ The floating-point value to test. ## Return value -The `isfinite` macro and the `_finite` and `_finitef` functions return a non-zero value if *`x`* is either a normal or subnormal finite value. They return 0 if the argument is infinite or a NaN. The C++ inline template function `isfinite` behaves the same way, but returns **`true`** or **`false`**. +The `isfinite` macro and the `_finite` and `_finitef` functions return a non-zero value if *`x`* is a normal, subnormal, or signed zero (`±0`) finite value. They return 0 if the argument is infinite or Not a Number (NaN). The C++ inline template function `isfinite` behaves the same way but returns **`true`** or **`false`**. ## Remarks -`isfinite` is a macro when compiled as C, and an inline template function when compiled as C++. The `_finite` and `_finitef` functions are Microsoft-specific. The `_finitef` function is only available when compiled for x86, ARM, or ARM64 platforms. +`_finite` and `_finitef` are Microsoft-specific. + +`isfinite` is a macro when compiled as C, and an inline template function when compiled as C++. + +`_finitef` is only available when compiling for the x64, ARM, ARM64, or ARM64EC platforms. ## Requirements | Function | Required header (C) | Required header (C++) | |---|---|---| -| `_finite` | \ or \ | \, \, \, or \ | -| `isfinite`, `_finitef` | \ | \ or \ | +| `isfinite` | `` | `` or `` | +| `_finite` | `` | `` or `` | +| `_finitef` | `` | `` or `` | For more compatibility information, see [Compatibility](../compatibility.md).