CMakeLists.txt 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. cmake_minimum_required(VERSION 3.1)
  2. cmake_policy(SET CMP0057 NEW)
  3. project(CompileFeatures)
  4. macro(run_test feature lang)
  5. if (${feature} IN_LIST CMAKE_${lang}_COMPILE_FEATURES)
  6. add_library(test_${feature} OBJECT ${feature})
  7. set_property(TARGET test_${feature}
  8. PROPERTY COMPILE_FEATURES "${feature}"
  9. )
  10. else()
  11. list(APPEND ${lang}_non_features ${feature})
  12. endif()
  13. endmacro()
  14. get_property(c_features GLOBAL PROPERTY CMAKE_C_KNOWN_FEATURES)
  15. list(FILTER c_features EXCLUDE REGEX "^c_std_[0-9][0-9]")
  16. foreach(feature ${c_features})
  17. run_test(${feature} C)
  18. endforeach()
  19. get_property(cxx_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)
  20. list(FILTER cxx_features EXCLUDE REGEX "^cxx_std_[0-9][0-9]")
  21. foreach(feature ${cxx_features})
  22. run_test(${feature} CXX)
  23. endforeach()
  24. if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang"
  25. AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.1)
  26. # AppleClang prior to 5.1 does not set any preprocessor define to distinguish
  27. # c++1y from c++11, so CMake does not support c++1y features before AppleClang 5.1.
  28. list(REMOVE_ITEM CXX_non_features
  29. cxx_attribute_deprecated
  30. cxx_binary_literals
  31. )
  32. endif()
  33. if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang"
  34. AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.2)
  35. # AppleClang prior to 4.1 reports false for __has_feature(cxx_local_type_template_args)
  36. # and __has_feature(cxx_unrestricted_unions) but it happens to pass these tests.
  37. list(REMOVE_ITEM CXX_non_features
  38. cxx_local_type_template_args
  39. cxx_unrestricted_unions
  40. )
  41. endif()
  42. if (CMAKE_CXX_COMPILER_ID STREQUAL SunPro)
  43. list(REMOVE_ITEM CXX_non_features
  44. cxx_attribute_deprecated
  45. cxx_contextual_conversions
  46. cxx_extended_friend_declarations
  47. cxx_long_long_type
  48. cxx_sizeof_member
  49. cxx_variadic_macros
  50. )
  51. endif()
  52. if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
  53. AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.5)
  54. # The cxx_raw_string_literals feature happens to work in some distributions
  55. # of GNU 4.4, but it is first documented as available with GNU 4.5.
  56. list(REMOVE_ITEM CXX_non_features
  57. cxx_raw_string_literals
  58. )
  59. endif()
  60. if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
  61. AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)
  62. # The cxx_constexpr feature happens to work (for *this* testcase) with
  63. # GNU 4.5, but it is first documented as available with GNU 4.6.
  64. list(REMOVE_ITEM CXX_non_features
  65. cxx_constexpr
  66. )
  67. endif()
  68. if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
  69. AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
  70. # The cxx_alignof feature happens to work (for *this* testcase) with
  71. # GNU 4.7, but it is first documented as available with GNU 4.8.
  72. list(REMOVE_ITEM CXX_non_features
  73. cxx_alignof
  74. )
  75. endif()
  76. if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
  77. AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)
  78. # GNU prior to 4.9 does not set any preprocessor define to distinguish
  79. # c++1y from c++11, so CMake does not support c++1y features before GNU 4.9.
  80. list(REMOVE_ITEM CXX_non_features
  81. # GNU 4.8 knows cxx_attributes, but doesn't know [[deprecated]]
  82. # and warns that it is unknown and ignored.
  83. cxx_attribute_deprecated
  84. cxx_binary_literals
  85. cxx_lambda_init_captures
  86. cxx_return_type_deduction
  87. )
  88. endif()
  89. if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
  90. if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0)
  91. list(REMOVE_ITEM CXX_non_features
  92. # The cxx_contextual_conversions feature happens to work
  93. # (for *this* testcase) with VS 2010 and VS 2012, but
  94. # they do not document support until VS 2013.
  95. cxx_contextual_conversions
  96. )
  97. elseif (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0)
  98. list(REMOVE_ITEM CXX_non_features
  99. # The cxx_deleted_functions and cxx_nonstatic_member_init
  100. # features happen to work (for *this* testcase) with VS 2013,
  101. # but they do not document support until VS 2015.
  102. cxx_deleted_functions
  103. cxx_nonstatic_member_init
  104. )
  105. endif()
  106. endif()
  107. if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
  108. if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 16.0)
  109. if (CMAKE_CXX_COMIPLER_VERSION VERSION_EQUAL 15.0)
  110. list(REMOVE_ITEM CXX_non_features
  111. # The cxx_contextual_conversions feature happens to work
  112. # (for *this* testcase) with Intel 13/14/15, but they do not
  113. # document support until 16.
  114. cxx_contextual_conversions
  115. )
  116. elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14.0)
  117. list(REMOVE_ITEM CXX_non_features
  118. cxx_alignof
  119. # not supposed to work until 15
  120. cxx_attribute_deprecated
  121. # The cxx_contextual_conversions feature happens to work
  122. # (for *this* testcase) with Intel 13/14/15, but they do not
  123. # document support until 16.
  124. cxx_contextual_conversions
  125. )
  126. elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.1)
  127. list(REMOVE_ITEM CXX_non_features
  128. # These features happen to work but aren't documented to
  129. # do so until 14.0
  130. cxx_constexpr
  131. cxx_enum_forward_declarations
  132. cxx_sizeof_member
  133. cxx_strong_enums
  134. cxx_unicode_literals
  135. # not supposed to work until 15
  136. cxx_attribute_deprecated
  137. cxx_nonstatic_member_init
  138. # The cxx_contextual_conversions feature happens to work
  139. # (for *this* testcase) with Intel 13/14/15, but they do not
  140. # document support until 16.
  141. cxx_contextual_conversions
  142. # This is an undocumented feature; it does not work in future versions
  143. cxx_aggregate_default_initializers
  144. )
  145. endif()
  146. endif()
  147. endif()
  148. if (CMAKE_C_COMPILER_ID STREQUAL "Intel")
  149. if (CMAKE_C_COMPILER_VERSION VERSION_LESS 15.0.2)
  150. # This works on some pre-15.0.2 versions and not others.
  151. list(REMOVE_ITEM C_non_features
  152. c_static_assert
  153. )
  154. endif()
  155. endif()
  156. if (CMAKE_C_COMPILE_FEATURES)
  157. set(C_expected_features ${CMAKE_C_COMPILE_FEATURES})
  158. list(FILTER C_expected_features EXCLUDE REGEX "^c_std_[0-9][0-9]")
  159. endif()
  160. if (CMAKE_CXX_COMPILE_FEATURES)
  161. set(CXX_expected_features ${CMAKE_CXX_COMPILE_FEATURES})
  162. list(FILTER CXX_expected_features EXCLUDE REGEX "^cxx_std_[0-9][0-9]")
  163. endif ()
  164. set(C_ext c)
  165. set(C_standard_flag 11)
  166. set(CXX_ext cpp)
  167. set(CXX_standard_flag 14)
  168. foreach(lang CXX C)
  169. if (${lang}_expected_features)
  170. foreach(feature ${${lang}_non_features})
  171. message("Testing feature : ${feature}")
  172. try_compile(${feature}_works
  173. "${CMAKE_CURRENT_BINARY_DIR}/${feature}_test"
  174. "${CMAKE_CURRENT_SOURCE_DIR}/feature_test.${${lang}_ext}"
  175. COMPILE_DEFINITIONS "-DTEST=${feature}.${${lang}_ext}"
  176. CMAKE_FLAGS "-DCMAKE_${lang}_STANDARD=${${lang}_standard_flag}"
  177. "-DINCLUDE_DIRECTORIES=${CMAKE_CURRENT_SOURCE_DIR}"
  178. OUTPUT_VARIABLE OUTPUT
  179. )
  180. if (${feature}_works)
  181. message(SEND_ERROR
  182. "Feature ${feature} expected not to work for ${lang} ${CMAKE_${lang}_COMPILER_ID}-${CMAKE_${lang}_COMPILER_VERSION}.
  183. Update the supported features or blacklist it.\n${OUTPUT}")
  184. else()
  185. message("Testing feature : ${feature} -- Fails, as expected.")
  186. endif()
  187. endforeach()
  188. endif()
  189. endforeach()
  190. if (C_expected_features)
  191. if (CMAKE_C_STANDARD_DEFAULT)
  192. string(FIND "${CMAKE_C_FLAGS}" "-std=" std_flag_idx)
  193. if (std_flag_idx EQUAL -1)
  194. add_executable(default_dialect_C default_dialect.c)
  195. target_compile_definitions(default_dialect_C PRIVATE
  196. DEFAULT_C11=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},11>
  197. DEFAULT_C99=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},99>
  198. DEFAULT_C90=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},90>
  199. )
  200. endif()
  201. endif()
  202. add_executable(CompileFeaturesGenex_C genex_test.c)
  203. set_property(TARGET CompileFeaturesGenex_C PROPERTY C_STANDARD 11)
  204. if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
  205. if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.6)
  206. list(APPEND expected_defs
  207. EXPECT_C_STATIC_ASSERT=1
  208. )
  209. else()
  210. list(APPEND expected_defs
  211. EXPECT_C_STATIC_ASSERT=0
  212. )
  213. endif()
  214. elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang"
  215. OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
  216. list(APPEND expected_defs
  217. EXPECT_C_STATIC_ASSERT=1
  218. )
  219. elseif (CMAKE_C_COMPILER_ID STREQUAL "Intel")
  220. if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 15)
  221. list(APPEND expected_defs
  222. EXPECT_C_STATIC_ASSERT=1
  223. )
  224. else()
  225. list(APPEND expected_defs
  226. EXPECT_C_STATIC_ASSERT=0
  227. )
  228. endif()
  229. elseif (CMAKE_C_COMPILER_ID STREQUAL "SunPro")
  230. if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.13)
  231. list(APPEND expected_defs
  232. EXPECT_C_STATIC_ASSERT=1
  233. )
  234. else()
  235. list(APPEND expected_defs
  236. EXPECT_C_STATIC_ASSERT=0
  237. )
  238. endif()
  239. endif()
  240. list(APPEND expected_defs
  241. EXPECT_C_FUNCTION_PROTOTYPES=1
  242. EXPECT_C_RESTRICT=1
  243. )
  244. target_compile_definitions(CompileFeaturesGenex_C PRIVATE
  245. HAVE_C_FUNCTION_PROTOTYPES=$<COMPILE_FEATURES:c_function_prototypes>
  246. HAVE_C_RESTRICT=$<COMPILE_FEATURES:c_restrict>
  247. HAVE_C_STATIC_ASSERT=$<COMPILE_FEATURES:c_static_assert>
  248. ${expected_defs}
  249. )
  250. endif()
  251. if (CMAKE_CXX_COMPILE_FEATURES)
  252. if (CMAKE_CXX_STANDARD_DEFAULT)
  253. string(FIND "${CMAKE_CXX_FLAGS}" "-std=" std_flag_idx)
  254. if (std_flag_idx EQUAL -1)
  255. add_executable(default_dialect default_dialect.cpp)
  256. target_compile_definitions(default_dialect PRIVATE
  257. DEFAULT_CXX17=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},17>
  258. DEFAULT_CXX14=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},14>
  259. DEFAULT_CXX11=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},11>
  260. DEFAULT_CXX98=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},98>
  261. )
  262. endif()
  263. endif()
  264. endif ()
  265. # always add a target "CompileFeatures"
  266. if ((NOT CXX_expected_features) OR
  267. (NOT cxx_auto_type IN_LIST CXX_expected_features))
  268. file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp"
  269. "int main(int,char**) { return 0; }\n"
  270. )
  271. add_executable(CompileFeatures "${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp")
  272. else()
  273. # these tests only work if at least cxx_auto_type is available
  274. add_executable(CompileFeatures main.cpp)
  275. set_property(TARGET CompileFeatures
  276. PROPERTY COMPILE_FEATURES "cxx_auto_type"
  277. )
  278. set_property(TARGET CompileFeatures
  279. PROPERTY CXX_STANDARD_REQUIRED TRUE
  280. )
  281. add_executable(GenexCompileFeatures main.cpp)
  282. set_property(TARGET GenexCompileFeatures
  283. PROPERTY COMPILE_FEATURES "$<1:cxx_auto_type>;$<0:not_a_feature>"
  284. )
  285. add_library(iface INTERFACE)
  286. set_property(TARGET iface
  287. PROPERTY INTERFACE_COMPILE_FEATURES "cxx_auto_type"
  288. )
  289. add_executable(IfaceCompileFeatures main.cpp)
  290. target_link_libraries(IfaceCompileFeatures iface)
  291. if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
  292. if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
  293. add_definitions(
  294. -DEXPECT_OVERRIDE_CONTROL=1
  295. -DEXPECT_INHERITING_CONSTRUCTORS=1
  296. -DEXPECT_FINAL=1
  297. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
  298. )
  299. elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7)
  300. add_definitions(
  301. -DEXPECT_OVERRIDE_CONTROL=1
  302. -DEXPECT_INHERITING_CONSTRUCTORS=0
  303. -DEXPECT_FINAL=1
  304. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
  305. )
  306. else()
  307. add_definitions(
  308. -DEXPECT_OVERRIDE_CONTROL=0
  309. -DEXPECT_INHERITING_CONSTRUCTORS=0
  310. -DEXPECT_FINAL=0
  311. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
  312. )
  313. endif()
  314. elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
  315. add_definitions(
  316. -DEXPECT_OVERRIDE_CONTROL=1
  317. -DEXPECT_INHERITING_CONSTRUCTORS=1
  318. -DEXPECT_FINAL=1
  319. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
  320. )
  321. elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
  322. if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
  323. add_definitions(
  324. -DEXPECT_OVERRIDE_CONTROL=1
  325. -DEXPECT_INHERITING_CONSTRUCTORS=1
  326. -DEXPECT_FINAL=1
  327. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
  328. )
  329. else()
  330. add_definitions(
  331. -DEXPECT_OVERRIDE_CONTROL=1
  332. -DEXPECT_INHERITING_CONSTRUCTORS=0
  333. -DEXPECT_FINAL=1
  334. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
  335. )
  336. endif()
  337. elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
  338. if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0)
  339. add_definitions(
  340. -DEXPECT_OVERRIDE_CONTROL=1
  341. -DEXPECT_INHERITING_CONSTRUCTORS=1
  342. -DEXPECT_FINAL=1
  343. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
  344. )
  345. elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 17.0)
  346. add_definitions(
  347. -DEXPECT_OVERRIDE_CONTROL=1
  348. -DEXPECT_INHERITING_CONSTRUCTORS=0
  349. -DEXPECT_FINAL=1
  350. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
  351. )
  352. else()
  353. add_definitions(
  354. -DEXPECT_OVERRIDE_CONTROL=0
  355. -DEXPECT_INHERITING_CONSTRUCTORS=0
  356. -DEXPECT_FINAL=0
  357. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
  358. )
  359. endif()
  360. elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro")
  361. add_definitions(
  362. -DEXPECT_OVERRIDE_CONTROL=1
  363. -DEXPECT_INHERITING_CONSTRUCTORS=1
  364. -DEXPECT_FINAL=1
  365. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
  366. )
  367. elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
  368. if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 15)
  369. add_definitions(
  370. -DEXPECT_OVERRIDE_CONTROL=1
  371. -DEXPECT_INHERITING_CONSTRUCTORS=1
  372. -DEXPECT_FINAL=1
  373. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
  374. )
  375. elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14)
  376. add_definitions(
  377. -DEXPECT_OVERRIDE_CONTROL=1
  378. -DEXPECT_INHERITING_CONSTRUCTORS=0
  379. -DEXPECT_FINAL=1
  380. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
  381. )
  382. else()
  383. add_definitions(
  384. -DEXPECT_OVERRIDE_CONTROL=0
  385. -DEXPECT_INHERITING_CONSTRUCTORS=0
  386. -DEXPECT_FINAL=0
  387. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
  388. )
  389. endif()
  390. endif()
  391. add_executable(CompileFeaturesGenex genex_test.cpp)
  392. set_property(TARGET CompileFeaturesGenex PROPERTY CXX_STANDARD 11)
  393. target_compile_definitions(CompileFeaturesGenex PRIVATE
  394. HAVE_OVERRIDE_CONTROL=$<COMPILE_FEATURES:cxx_final,cxx_override>
  395. HAVE_AUTO_TYPE=$<COMPILE_FEATURES:cxx_auto_type>
  396. HAVE_INHERITING_CONSTRUCTORS=$<COMPILE_FEATURES:cxx_inheriting_constructors>
  397. HAVE_FINAL=$<COMPILE_FEATURES:cxx_final>
  398. HAVE_INHERITING_CONSTRUCTORS_AND_FINAL=$<COMPILE_FEATURES:cxx_inheriting_constructors,cxx_final>
  399. )
  400. if (CMAKE_CXX_STANDARD_DEFAULT)
  401. target_compile_definitions(CompileFeaturesGenex PRIVATE
  402. TEST_CXX_STD
  403. HAVE_CXX_STD_11=$<COMPILE_FEATURES:cxx_std_11>
  404. HAVE_CXX_STD_14=$<COMPILE_FEATURES:cxx_std_14>
  405. HAVE_CXX_STD_17=$<COMPILE_FEATURES:cxx_std_17>
  406. )
  407. endif()
  408. add_executable(CompileFeaturesGenex2 genex_test.cpp)
  409. target_compile_features(CompileFeaturesGenex2 PRIVATE cxx_std_11)
  410. target_compile_definitions(CompileFeaturesGenex2 PRIVATE
  411. HAVE_OVERRIDE_CONTROL=$<COMPILE_FEATURES:cxx_final,cxx_override>
  412. HAVE_AUTO_TYPE=$<COMPILE_FEATURES:cxx_auto_type>
  413. HAVE_INHERITING_CONSTRUCTORS=$<COMPILE_FEATURES:cxx_inheriting_constructors>
  414. HAVE_FINAL=$<COMPILE_FEATURES:cxx_final>
  415. HAVE_INHERITING_CONSTRUCTORS_AND_FINAL=$<COMPILE_FEATURES:cxx_inheriting_constructors,cxx_final>
  416. )
  417. add_library(std_11_iface INTERFACE)
  418. target_compile_features(std_11_iface INTERFACE cxx_std_11)
  419. add_executable(CompileFeaturesGenex3 genex_test.cpp)
  420. target_link_libraries(CompileFeaturesGenex3 PRIVATE std_11_iface)
  421. target_compile_definitions(CompileFeaturesGenex3 PRIVATE
  422. HAVE_OVERRIDE_CONTROL=$<COMPILE_FEATURES:cxx_final,cxx_override>
  423. HAVE_AUTO_TYPE=$<COMPILE_FEATURES:cxx_auto_type>
  424. HAVE_INHERITING_CONSTRUCTORS=$<COMPILE_FEATURES:cxx_inheriting_constructors>
  425. HAVE_FINAL=$<COMPILE_FEATURES:cxx_final>
  426. HAVE_INHERITING_CONSTRUCTORS_AND_FINAL=$<COMPILE_FEATURES:cxx_inheriting_constructors,cxx_final>
  427. )
  428. endif()