[llvm-branch-commits] [libcxx] [libc++] Implements the new FTM documentation generator. (PR #139774)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue May 13 11:39:05 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: Mark de Wever (mordante)
<details>
<summary>Changes</summary>
The new documentation will look like
https://discourse.llvm.org/t/rfc-improving-the-feature-test-macro-status-page/78327/5?u=mordante
---
Full diff: https://github.com/llvm/llvm-project/pull/139774.diff
2 Files Affected:
- (added) libcxx/test/libcxx/feature_test_macro/documentation.sh.py (+187)
- (modified) libcxx/utils/generate_feature_test_macro_components.py (+161-1)
``````````diff
diff --git a/libcxx/test/libcxx/feature_test_macro/documentation.sh.py b/libcxx/test/libcxx/feature_test_macro/documentation.sh.py
new file mode 100644
index 0000000000000..1c35e0eafc771
--- /dev/null
+++ b/libcxx/test/libcxx/feature_test_macro/documentation.sh.py
@@ -0,0 +1,187 @@
+# ===----------------------------------------------------------------------===##
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+# ===----------------------------------------------------------------------===##
+
+# RUN: %{python} %s %{libcxx-dir}/utils %{libcxx-dir}/test/libcxx/feature_test_macro/test_data.json
+
+import sys
+import unittest
+
+UTILS = sys.argv[1]
+TEST_DATA = sys.argv[2]
+del sys.argv[1:3]
+
+sys.path.append(UTILS)
+from generate_feature_test_macro_components import FeatureTestMacros
+
+
+class Test(unittest.TestCase):
+ def setUp(self):
+ self.ftm = FeatureTestMacros(TEST_DATA, ["charconv"])
+ self.maxDiff = None # This causes the diff to be printed when the test fails
+
+ def test_implementeation(self):
+ expected = """\
+.. _FeatureTestMacroTable:
+
+==========================
+Feature Test Macro Support
+==========================
+
+.. contents::
+ :local:
+
+Overview
+========
+
+This page documents libc++'s implementation status of the Standard library
+feature test macros. This page does not list all details, that information can
+be found at the `isoccp
+<https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations#library-feature-test-macros>`__.
+
+.. _feature-status:
+
+Status
+======
+
+.. list-table:: Current Status
+ :widths: auto
+ :header-rows: 1
+ :align: left
+
+ * - Macro Name
+ - Libc++ Value
+ - Standard Value
+ -
+ - Paper
+ * - | **C++17**
+ - |
+ - |
+ - |
+ - |
+ * - | ``__cpp_lib_any``
+ - | 201606L
+ - | 201606L
+ - | ✅
+ - |
+ * - | ``__cpp_lib_clamp``
+ - | 201603L
+ - | 201603L
+ - | ✅
+ - |
+ * - | ``__cpp_lib_parallel_algorithm``
+ - | 201603L
+ - | 201603L
+ - | ✅
+ - |
+ * - | ``__cpp_lib_to_chars``
+ - | *unimplemented*
+ - | 201611L
+ - | ❌
+ - |
+ * - | ``__cpp_lib_variant``
+ - | 202102L
+ - | 202102L
+ - | ✅
+ - | ``std::visit`` for classes derived from ``std::variant``
+ * - | ``__cpp_lib_zz_missing_FTM_in_older_standard``
+ - | *unimplemented*
+ - | 2017L
+ - | ❌
+ - | Some FTM missing a paper in an older Standard mode, which should result in the FTM never being defined.
+ * - | **C++20**
+ - |
+ - |
+ - |
+ - |
+ * - | ``__cpp_lib_barrier``
+ - | 201907L
+ - | 201907L
+ - | ✅
+ - |
+ * - | ``__cpp_lib_format``
+ |
+ |
+ |
+ |
+ - | *unimplemented*
+ |
+ |
+ |
+ |
+ - | 201907L
+ |
+ | 202106L
+ | 202110L
+ |
+ - | ✅
+ | ❌
+ | ✅
+ | ❌
+ | ✅
+ - | `P0645R10 <https://wg21.link/P0645R10>`__ Text Formatting
+ | `P1361R2 <https://wg21.link/P1361R2>`__ Integration of chrono with text formatting
+ | `P2216R3 <https://wg21.link/P2216R3>`__ std::format improvements
+ | `P2372R3 <https://wg21.link/P2372R3>`__ Fixing locale handling in chrono formatters
+ | `P2418R2 <https://wg21.link/P2418R2>`__ FAdd support for std::generator-like types to std::format
+ * - | ``__cpp_lib_variant``
+ - | *unimplemented*
+ - | 202106L
+ - | ❌
+ - | Fully constexpr ``std::variant``
+ * - | ``__cpp_lib_zz_missing_FTM_in_older_standard``
+ - | *unimplemented*
+ - | 2020L
+ - | ✅
+ - |
+ * - | **C++23**
+ - |
+ - |
+ - |
+ - |
+ * - | ``__cpp_lib_format``
+ - | *unimplemented*
+ - | 202207L
+ - | ❌
+ - | `P2419R2 <https://wg21.link/P2419R2>`__ Clarify handling of encodings in localized formatting of chrono types
+ * - | **C++26**
+ - |
+ - |
+ - |
+ - |
+ * - | ``__cpp_lib_barrier``
+ - | 299900L
+ - | 299900L
+ - | ✅
+ - |
+ * - | ``__cpp_lib_format``
+ |
+ - | *unimplemented*
+ |
+ - | 202306L
+ | 202311L
+ - | ✅
+ | ✅
+ - | `P2637R3 <https://wg21.link/P2637R3>`__ Member Visit
+ | `P2918R2 <https://wg21.link/P2918R2>`__ Runtime format strings II
+ * - | ``__cpp_lib_variant``
+ - | *unimplemented*
+ - | 202306L
+ - | ✅
+ - | Member visit
+ * - | ``__cpp_lib_zz_missing_FTM_in_older_standard``
+ - | *unimplemented*
+ - | 2026L
+ - | ✅
+ - |
+
+"""
+ self.assertEqual(self.ftm.documentation, expected)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 7256e56145233..472158eadcb91 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -2125,6 +2125,97 @@ def generate_version_header_implementation(
{tests}\
"""
+#
+# The templates used to create a FTM documentation
+#
+
+ftm_documentation = """.. _FeatureTestMacroTable:
+
+==========================
+Feature Test Macro Support
+==========================
+
+.. contents::
+ :local:
+
+Overview
+========
+
+This page documents libc++'s implementation status of the Standard library
+feature test macros. This page does not list all details, that information can
+be found at the `isoccp
+<https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations#library-feature-test-macros>`__.
+
+.. _feature-status:
+
+Status
+======
+
+.. list-table:: Current Status
+ :widths: auto
+ :header-rows: 1
+ :align: left
+
+ * - Macro Name
+ - Libc++ Value
+ - Standard Value
+ -
+ - Paper
+{status_list_table}
+"""
+
+def create_table_row(data: List[List[str]]) -> str:
+ """Creates an RST list-table row from the contents of `data`.
+
+ Data contains one or more elements for a single row for a RST list-table.
+ When the list contains more than one element, the data is considered to be
+ a multi-row entry. The for a table cell is stored like
+ cell = data[row][column].
+
+ All rows in the table need to have the same number of columns. (This also
+ holds true for the "Standard version header rows".)
+
+ A row for an RST list-table has the following structure:
+ * - column 1
+ - column 2
+ - column 3
+
+ Note the output is indented.
+
+ Alternatively it is possible to have cells that "span" multiple rows. This
+ is not a real span since all cells are created, however creating an empty
+ cell gives the wanted visual effect. These rows have the following
+ structure: A row for an RST list-table has the following structure:
+ * - | row 1, column 1
+ | row 2, column 1
+ - | row 1, column 2
+ | row 2, column 2
+ - | row 1, column 3
+ | row 2, column 3
+
+ Note it is allowed to use the following for a single row:
+ * - | column 1
+ - | column 2
+ - | column 3
+
+ However the algorithm does not do that.
+ """
+
+ result = ""
+
+ cell = "*" # The marker for the first cell in the row
+ multi_row = "| " if len(data) > 0 else ""
+ # As described above the rows and columns are traversed column first.
+ for c in range(len(data[0])):
+ column = "-" # The marker for the columns
+ for r in range(len(data)):
+ result += f" {cell} {column} {multi_row}{data[r][c]}\n"
+ cell = " "
+ column = " "
+
+ return result
+
+
class FeatureTestMacros:
"""Provides all feature-test macro (FTM) output components.
@@ -2284,7 +2375,6 @@ def implemented_ftms(self) -> Dict[Ftm, Dict[Std, Optional[Value]]]:
return get_ftms(self.__data, self.std_dialects, True)
-
def is_implemented(self, ftm: Ftm, std: Std) -> bool:
"""Has the FTM `ftm` been implemented in the dialect `std`?"""
@@ -2555,6 +2645,72 @@ def generate_header_test_directory(self, path: os.path) -> None:
f.write(self.generate_header_test_file(header))
+ @functools.cached_property
+ def status_list_table(self) -> str:
+ """Creates the rst status table using a list-table."""
+
+ result = ""
+ for std in self.std_dialects:
+ result += create_table_row(
+ [[f'**{std.replace("c++", "C++")}**', "", "", "", ""]]
+ )
+
+ for feature in self.__data:
+ if std not in feature["values"].keys():
+ continue
+
+ row = list()
+
+ ftm = feature["name"]
+ libcxx_value = (
+ f"{self.standard_ftms[ftm][std]}"
+ if self.is_implemented(ftm, std)
+ else "*unimplemented*"
+ )
+
+ values = feature["values"][std]
+ assert len(values) > 0, f"{feature['name']}[{std}] has no entries"
+ for value in values:
+ std_value = f"{value}L"
+ papers = list(values[value])
+ assert (
+ len(papers) > 0
+ ), f"{feature['name']}[{std}][{value}] has no entries"
+
+ for paper in papers:
+ number = "" if not "number" in paper.keys() else paper["number"]
+ title = "" if not "title" in paper.keys() else paper["title"]
+ implemented = paper["implemented"]
+
+ row += [
+ [
+ f"``{ftm}``" if ftm else "",
+ libcxx_value,
+ std_value,
+ "✅" if implemented else "❌",
+ (
+ f"`{number} <https://wg21.link/{number}>`__ {title}"
+ if number
+ else f"{title}"
+ ),
+ ]
+ ]
+ ftm = ""
+ libcxx_value = ""
+ std_value = ""
+
+ result += create_table_row(row)
+
+ return result
+
+
+ @functools.cached_property
+ def documentation(self) -> str:
+ """Generates the FTM documentation."""
+
+ return ftm_documentation.format(status_list_table=self.status_list_table)
+
+
def main():
produce_version_header()
produce_tests()
@@ -2573,6 +2729,10 @@ def main():
ftm.generate_header_test_directory(macro_test_path)
+ documentation_path = os.path.join(docs_path, "FeatureTestMacroTable.rst")
+ with open(documentation_path, "w", newline="\n") as f:
+ f.write(ftm.documentation)
+
if __name__ == "__main__":
main()
``````````
</details>
https://github.com/llvm/llvm-project/pull/139774
More information about the llvm-branch-commits
mailing list