@@ -2125,56 +2125,6 @@ def generate_version_header_implementation(
21252125{tests}\
21262126 """
21272127
2128- #
2129- # The templates used for a single FTM block in the tests.
2130- #
2131-
2132- ftm_unavailable_in_dialect = """
2133- # ifdef {ftm}
2134- # error "{ftm} should not be defined before {dialect}"
2135- # endif
2136- """
2137-
2138- libcxx_ftm_not_implemented = """
2139- # if !defined(_LIBCPP_VERSION)
2140- # ifndef {ftm}
2141- # error "{ftm} should be defined in {dialect}"
2142- # endif
2143- # if {ftm} != {value}
2144- # error "{ftm} should have the value {value} in {dialect}"
2145- # endif
2146- # else
2147- # ifdef {ftm}
2148- # error "{ftm} should not be defined because it is unimplemented in libc++!"
2149- # endif
2150- # endif
2151- """
2152-
2153- libcxx_ftm_conditionally_implemented = """
2154- # if {condition}
2155- # ifndef {ftm}
2156- # error "{ftm} should be defined in {dialect}"
2157- # endif
2158- # if {ftm} != {value}
2159- # error "{ftm} should have the value {value} in {dialect}"
2160- # endif
2161- # else
2162- # ifdef {ftm}
2163- # error "{ftm} should not be defined when the requirement '{condition}' is not met!"
2164- # endif
2165- # endif
2166- """
2167-
2168- libcxx_ftm_implemented = """
2169- # ifndef {ftm}
2170- # error "{ftm} should be defined in {dialect}"
2171- # endif
2172- # if {ftm} != {value}
2173- # error "{ftm} should have the value {value} in {dialect}"
2174- # endif
2175- """
2176-
2177-
21782128class FeatureTestMacros :
21792129 """Provides all feature-test macro (FTM) output components.
21802130
@@ -2424,7 +2374,7 @@ def version_header(self) -> str:
24242374 )
24252375 )
24262376
2427- def header_ftm (self , header : str ) -> Dict [Std , List [Dict [Ftm , FtmHeaderTest ]]]:
2377+ def header_ftm_data (self , header : str ) -> Dict [Std , List [Dict [Ftm , FtmHeaderTest ]]]:
24282378 """Generates the FTM information for a `header`."""
24292379
24302380 result = dict ()
@@ -2440,19 +2390,17 @@ def header_ftm(self, header: str) -> Dict[Std, List[Dict[Ftm, FtmHeaderTest]]]:
24402390
24412391 for std in self .std_dialects :
24422392 if not std in values .keys ():
2443- result [get_std_number (std )].append (dict ( {ftm : None }) )
2393+ result [get_std_number (std )].append ({ftm : None })
24442394 continue
24452395
24462396 result [get_std_number (std )].append (
2447- dict (
24482397 {
24492398 ftm : FtmHeaderTest (
24502399 values [std ],
24512400 self .is_implemented (ftm , std ),
24522401 self .ftm_metadata [ftm ].test_suite_guard ,
24532402 )
24542403 }
2455- )
24562404 )
24572405
24582406 return result
@@ -2466,25 +2414,70 @@ def generate_header_test_ftm(self, std: Std, ftm: Ftm, value: FtmHeaderTest) ->
24662414 this is 14, since FTM have been introduced in C++14.)
24672415 """
24682416
2417+ ftm_unavailable_in_dialect = """
2418+ # ifdef {ftm}
2419+ # error "{ftm} should not be defined before {dialect}"
2420+ # endif
2421+ """
2422+
2423+ ftm_not_implemented = """
2424+ # if !defined(_LIBCPP_VERSION)
2425+ # ifndef {ftm}
2426+ # error "{ftm} should be defined in {dialect}"
2427+ # endif
2428+ # if {ftm} != {value}
2429+ # error "{ftm} should have the value {value} in {dialect}"
2430+ # endif
2431+ # else
2432+ # ifdef {ftm}
2433+ # error "{ftm} should not be defined because it is unimplemented in libc++!"
2434+ # endif
2435+ # endif
2436+ """
2437+
2438+ ftm_conditionally_implemented = """
2439+ # if {condition}
2440+ # ifndef {ftm}
2441+ # error "{ftm} should be defined in {dialect}"
2442+ # endif
2443+ # if {ftm} != {value}
2444+ # error "{ftm} should have the value {value} in {dialect}"
2445+ # endif
2446+ # else
2447+ # ifdef {ftm}
2448+ # error "{ftm} should not be defined when the requirement '{condition}' is not met!"
2449+ # endif
2450+ # endif
2451+ """
2452+
2453+ ftm_implemented = """
2454+ # ifndef {ftm}
2455+ # error "{ftm} should be defined in {dialect}"
2456+ # endif
2457+ # if {ftm} != {value}
2458+ # error "{ftm} should have the value {value} in {dialect}"
2459+ # endif
2460+ """
2461+
24692462 if std == None or value == None :
24702463 return ftm_unavailable_in_dialect .format (
24712464 ftm = ftm , dialect = self .ftm_metadata [ftm ].available_since
24722465 )
24732466
24742467 if not value .implemented :
2475- return libcxx_ftm_not_implemented .format (
2468+ return ftm_not_implemented .format (
24762469 ftm = ftm , value = value .value , dialect = std
24772470 )
24782471
24792472 if self .ftm_metadata [ftm ].test_suite_guard :
2480- return libcxx_ftm_conditionally_implemented .format (
2473+ return ftm_conditionally_implemented .format (
24812474 ftm = ftm ,
24822475 value = value .value ,
24832476 dialect = std ,
24842477 condition = self .ftm_metadata [ftm ].test_suite_guard ,
24852478 )
24862479
2487- return libcxx_ftm_implemented .format (ftm = ftm , value = value .value , dialect = std )
2480+ return ftm_implemented .format (ftm = ftm , value = value .value , dialect = std )
24882481
24892482 def generate_header_test_dialect (
24902483 self , std : Std , data : List [Dict [Ftm , FtmHeaderTest ]]
@@ -2502,47 +2495,49 @@ def generate_lit_markup(self, header:str) -> str:
25022495
25032496 return "\n " .join (f"// { markup } " for markup in lit_markup [header ]) + "\n \n "
25042497
2505- def generate_header_test (self , header : str ) -> str :
2498+ def generate_header_test_file (self , header : str ) -> str :
25062499 """Returns the body for the FTM test of a `header`."""
25072500
2508- return ftm_header_test_file_contents .format (
2509- script_name = script_name ,
2510- lit_markup = self .generate_lit_markup (header ),
2511- header = header ,
2512- include = (
2513- ftm_header_test_file_include_conditional .format (header = header )
2514- if header in self .__unavailable_headers
2515- else ftm_header_test_file_include_unconditional .format (header = header )
2516- ),
2517- data =
2518- # FTM block before the first Standard that introduced them.
2519- # This test the macros are not available before this version.
2520- ftm_header_test_file_dialect_block .format (
2501+ # FTM block before the first Standard that introduced them.
2502+ # This test the macros are not available before this version.
2503+ data = ftm_header_test_file_dialect_block .format (
25212504 pp_if = "if" ,
25222505 operator = "<" ,
2523- dialect = self .std_dialects [0 ][ 3 :] ,
2506+ dialect = get_std_number ( self .std_dialects [0 ]) ,
25242507 tests = self .generate_header_test_dialect (
2525- None , next (iter (self .header_ftm (header ).values ()))
2508+ None , next (iter (self .header_ftm_data (header ).values ()))
25262509 ),
25272510 )
2528- +
2529- # FTM for all Standards that have FTM defined.
2530- # Note in libc++ the TEST_STD_VER contains 99 for the Standard
2531- # in development, therefore the last entry uses a different #elif.
2532- "" .join (
2511+
2512+ # FTM for all Standards that have FTM defined.
2513+ # Note in libc++ the TEST_STD_VER contains 99 for the Standard
2514+ # in development, therefore the last entry uses a different #elif.
2515+ data += "" .join (
25332516 ftm_header_test_file_dialect_block .format (
25342517 pp_if = "elif" ,
2535- operator = "==" if std != self .std_dialects [- 1 ][ 3 :] else ">" ,
2518+ operator = "==" if std != get_std_number ( self .std_dialects [- 1 ]) else ">" ,
25362519 dialect = std
2537- if std != self .std_dialects [- 1 ][ 3 :]
2538- else self .std_dialects [- 2 ][ 3 :] ,
2520+ if std != get_std_number ( self .std_dialects [- 1 ])
2521+ else get_std_number ( self .std_dialects [- 2 ]) ,
25392522 tests = self .generate_header_test_dialect (f"c++{ std } " , values ),
25402523 )
2541- for std , values in self .header_ftm (header ).items ()
2524+ for std , values in self .header_ftm_data (header ).items ()
25422525 )
2543- +
2544- # The final #endif for the last #elif block.
2545- f"\n #endif // TEST_STD_VER > { self .std_dialects [- 2 ][3 :]} " ,
2526+
2527+ # The final #endif for the last #elif block.
2528+ data += f"\n #endif // TEST_STD_VER > { get_std_number (self .std_dialects [- 2 ])} "
2529+
2530+ # Generate the test for the requested header.
2531+ return ftm_header_test_file_contents .format (
2532+ script_name = script_name ,
2533+ lit_markup = self .generate_lit_markup (header ),
2534+ header = header ,
2535+ include = (
2536+ ftm_header_test_file_include_conditional .format (header = header )
2537+ if header in self .__unavailable_headers
2538+ else ftm_header_test_file_include_unconditional .format (header = header )
2539+ ),
2540+ data = data
25462541 )
25472542
25482543 def generate_header_test_directory (self , path : os .path ) -> None :
@@ -2557,7 +2552,7 @@ def generate_header_test_directory(self, path: os.path) -> None:
25572552 "w" ,
25582553 newline = "\n " ,
25592554 ) as f :
2560- f .write (self .generate_header_test (header ))
2555+ f .write (self .generate_header_test_file (header ))
25612556
25622557
25632558def main ():
0 commit comments