2
2
3
3
import os
4
4
from builtins import range
5
+ from dataclasses import dataclass
5
6
from functools import reduce
6
- from typing import Any , Dict , List # Needed for python 3.8 compatibility.
7
+ from typing import (
8
+ Any ,
9
+ Dict ,
10
+ List , # Needed for python 3.8 compatibility.
11
+ NewType ,
12
+ Optional ,
13
+ )
7
14
import functools
8
15
import json
9
16
@@ -1944,9 +1951,28 @@ def produce_docs():
1944
1951
f .write (doc_str )
1945
1952
1946
1953
1954
+ Std = NewType ("Std" , str ) # Standard version number
1955
+ Ftm = NewType ("Ftm" , str ) # The name of a feature test macro
1956
+ Value = NewType ("Value" , str ) # The value of a feature test macro including the L suffix
1957
+
1958
+ @dataclass
1959
+ class Metadata :
1960
+ headers : list [str ] = None
1961
+ test_suite_guard : str = None
1962
+ libcxx_guard : str = None
1963
+
1964
+
1965
+ @dataclass
1966
+ class VersionHeader :
1967
+ value : Value = None
1968
+ implemented : bool = None
1969
+ need_undef : bool = None
1970
+ condition : str = None
1971
+
1972
+
1947
1973
def get_ftms (
1948
- data , std_dialects : List [str ], use_implemented_status : bool
1949
- ) -> Dict [str , Dict [str , Any ]]:
1974
+ data , std_dialects : List [Std ], use_implemented_status : bool
1975
+ ) -> Dict [Ftm , Dict [Std , Optional [ Value ] ]]:
1950
1976
"""Impementation for FeatureTestMacros.(standard|implemented)_ftms()."""
1951
1977
result = dict ()
1952
1978
for feature in data :
@@ -1983,7 +2009,7 @@ def get_ftms(
1983
2009
return result
1984
2010
1985
2011
1986
- def generate_version_header_dialect_block (data : Dict [str , Any ]) -> str :
2012
+ def generate_version_header_dialect_block (data : Dict [Ftm , VersionHeader ]) -> str :
1987
2013
"""Generates the contents of the version header for a dialect.
1988
2014
1989
2015
This generates the contents of a
@@ -1994,27 +2020,29 @@ def generate_version_header_dialect_block(data: Dict[str, Any]) -> str:
1994
2020
result = ""
1995
2021
for element in data :
1996
2022
for ftm , entry in element .items ():
1997
- if not entry [ " implemented" ] :
2023
+ if not entry . implemented :
1998
2024
# When a FTM is not implemented don't add the guards
1999
2025
# or undefine the (possibly) defined macro.
2000
- result += f' // define { ftm } { entry [ " value" ] } \n '
2026
+ result += f" // define { ftm } { entry . value } \n "
2001
2027
else :
2002
- need_undef = entry [ " need_undef" ]
2003
- if entry [ " condition" ] :
2004
- result += f' # if { entry [ " condition" ] } \n '
2005
- if entry [ " need_undef" ] :
2028
+ need_undef = entry . need_undef
2029
+ if entry . condition :
2030
+ result += f" # if { entry . condition } \n "
2031
+ if entry . need_undef :
2006
2032
result += f"# undef { ftm } \n "
2007
- result += f' # define { ftm } { entry [ " value" ] } \n '
2033
+ result += f" # define { ftm } { entry . value } \n "
2008
2034
result += f"# endif\n "
2009
2035
else :
2010
- if entry [ " need_undef" ] :
2036
+ if entry . need_undef :
2011
2037
result += f"# undef { ftm } \n "
2012
- result += f' # define { ftm } { entry [ " value" ] } \n '
2038
+ result += f" # define { ftm } { entry . value } \n "
2013
2039
2014
2040
return result
2015
2041
2016
2042
2017
- def generate_version_header_implementation (data : Dict [str , Dict [str , Any ]]) -> str :
2043
+ def generate_version_header_implementation (
2044
+ data : Dict [Std , Dict [Ftm , VersionHeader ]]
2045
+ ) -> str :
2018
2046
"""Generates the body of the version header."""
2019
2047
2020
2048
template = """#if _LIBCPP_STD_VER >= {dialect}
@@ -2132,7 +2160,7 @@ def __init__(self, filename: str):
2132
2160
self .__data = json .load (f )
2133
2161
2134
2162
@functools .cached_property
2135
- def std_dialects (self ) -> List [str ]:
2163
+ def std_dialects (self ) -> List [Std ]:
2136
2164
"""Returns the C++ dialects avaiable.
2137
2165
2138
2166
The available dialects are based on the 'c++xy' keys found the 'values'
@@ -2151,63 +2179,44 @@ def std_dialects(self) -> List[str]:
2151
2179
return sorted (list (dialects ))
2152
2180
2153
2181
@functools .cached_property
2154
- def standard_ftms (self ) -> Dict [str , Dict [str , Any ]]:
2182
+ def standard_ftms (self ) -> Dict [Ftm , Dict [Std , Optional [ Value ] ]]:
2155
2183
"""Returns the FTM versions per dialect in the Standard.
2156
2184
2157
2185
This function does not use the 'implemented' flag. The output contains
2158
2186
the versions used in the Standard. When a FTM in libc++ is not
2159
2187
implemented according to the Standard to output may opt to show the
2160
2188
expected value.
2161
-
2162
- The result is a dict with the following content
2163
- - key: Name of the feature test macro.
2164
- - value: A dict with the following content:
2165
- * key: The version of the C++ dialect.
2166
- * value: The value of the feature-test macro.
2167
2189
"""
2168
2190
return get_ftms (self .__data , self .std_dialects , False )
2169
2191
2170
2192
@functools .cached_property
2171
- def implemented_ftms (self ) -> Dict [str , Dict [str , Any ]]:
2193
+ def implemented_ftms (self ) -> Dict [Ftm , Dict [Std , Optional [ Value ] ]]:
2172
2194
"""Returns the FTM versions per dialect implemented in libc++.
2173
2195
2174
2196
Unlike `get_std_dialect_versions` this function uses the 'implemented'
2175
2197
flag. This returns the actual implementation status in libc++.
2176
-
2177
- The result is a dict with the following content
2178
- - key: Name of the feature test macro.
2179
- - value: A dict with the following content:
2180
- * key: The version of the C++ dialect.
2181
- * value: The value of the feature-test macro. When a feature-test
2182
- macro is not implemented its value is None.
2183
2198
"""
2184
2199
2185
2200
return get_ftms (self .__data , self .std_dialects , True )
2186
2201
2187
2202
@functools .cached_property
2188
- def ftm_metadata (self ) -> Dict [str , Dict [ str , Any ] ]:
2203
+ def ftm_metadata (self ) -> Dict [Ftm , Metadata ]:
2189
2204
"""Returns the metadata of the FTMs defined in the Standard.
2190
2205
2191
2206
The metadata does not depend on the C++ dialect used.
2192
- The result is a dict with the following contents:
2193
- - key: Name of the feature test macro.
2194
- - value: A dict with the following content:
2195
- * headers: The list of headers that should provide the FTM
2196
- * test_suite_guard: The condition for testing the FTM in the test suite.
2197
- * test_suite_guard: The condition for testing the FTM in the version header.
2198
2207
"""
2199
2208
result = dict ()
2200
2209
for feature in self .__data :
2201
- entry = dict ()
2202
- entry [ "headers" ] = feature ["headers" ]
2203
- entry [ "test_suite_guard" ] = feature .get ("test_suite_guard" , None )
2204
- entry [ "libcxx_guard" ] = feature .get ("libcxx_guard" , None )
2205
- result [ feature [ "name" ]] = entry
2210
+ result [ feature [ "name" ]] = Metadata (
2211
+ feature ["headers" ],
2212
+ feature .get ("test_suite_guard" , None ),
2213
+ feature .get ("libcxx_guard" , None ),
2214
+ )
2206
2215
2207
2216
return result
2208
2217
2209
2218
@property
2210
- def version_header_implementation (self ) -> Dict [str , List [ Dict [str , Any ] ]]:
2219
+ def version_header_implementation (self ) -> Dict [Std , Dict [Ftm , VersionHeader ]]:
2211
2220
"""Generates the body of the version header."""
2212
2221
result = dict ()
2213
2222
for std in self .std_dialects :
@@ -2223,13 +2232,15 @@ def version_header_implementation(self) -> Dict[str, List[Dict[str, Any]]]:
2223
2232
continue
2224
2233
last_value = value
2225
2234
2226
- entry = dict ()
2227
- entry ["value" ] = value
2228
- entry ["implemented" ] = self .implemented_ftms [ftm ][std ] == self .standard_ftms [ftm ][std ]
2229
- entry ["need_undef" ] = last_entry is not None and last_entry ["implemented" ] and entry ["implemented" ]
2230
- entry ["condition" ] = self .ftm_metadata [ftm ]["libcxx_guard" ]
2235
+ entry = VersionHeader (
2236
+ value ,
2237
+ self .implemented_ftms [ftm ][std ] != None ,
2238
+ need_undef ,
2239
+ self .ftm_metadata [ftm ].libcxx_guard ,
2240
+ )
2231
2241
2232
2242
last_entry = entry
2243
+
2233
2244
result [get_std_number (std )].append (dict ({ftm : entry }))
2234
2245
2235
2246
return result
0 commit comments