Implement feature test macros using a script.

Summary:
This patch implements all the feature test macros libc++ currently supports, as specified by the standard or cppreference prior to C++2a.

The tests and `<version>` header are generated using a script. The script contains a table of each feature test macro, the headers it should be accessible from, and its values of each dialect of C++.
When a new feature test macro is added or needed, the table should be updated and the script re-run.



Reviewers: mclow.lists, jfb, serge-sans-paille

Reviewed By: mclow.lists

Subscribers: arphaman, jfb, ldionne, libcxx-commits

Differential Revision: https://reviews.llvm.org/D56750

llvm-svn: 351286
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 32784a740a0282dc6f4390b683ed6c6516f4d66c
diff --git a/docs/DesignDocs/FeatureTestMacros.rst b/docs/DesignDocs/FeatureTestMacros.rst
new file mode 100644
index 0000000..d55af96
--- /dev/null
+++ b/docs/DesignDocs/FeatureTestMacros.rst
@@ -0,0 +1,44 @@
+===================
+Feature Test Macros
+===================
+
+.. contents::
+   :local:
+
+Overview
+========
+
+Libc++ implements the C++ feature test macros as specified in the C++2a standard,
+and before that in non-normative guiding documents (`See cppreference <https://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros>`)
+
+Design
+======
+
+Feature test macros are tricky to track, implement, test, and document correctly.
+They must be available from a list of headers, they may have different values in
+different dialects, and they may or may not be implemented by libc++. In order to
+track all of these conditions correctly and easily, we want a Single Source of
+Truth (SSoT) that defines each feature test macro, its values, the headers it
+lives in, and whether or not is is implemented by libc++. From this SSoA we
+have enough information to automatically generate the `<version>` header,
+the tests, and the documentation.
+
+Therefore we maintain a SSoA in
+`libcxx/test/std/language.support/support.limits/support.limits.general/generate_feature_test_macro_components.py`
+which doubles as a script to generate the following components:
+
+* The `<version>` header.
+* The version tests under `support.limits.general`.
+* Documentation of libc++'s implementation of each macro.
+
+Usage
+=====
+
+The `generate_feature_test_macro_components.py` script is used to track and
+update feature test macros in libc++.
+
+Whenever a feature test macro is added or changed, the table should be updated
+and the script should be re-ran. The script will clobber the existing test files
+and the documentation and it will generate a new `<version>` header as a
+temporary file. The generated `<version>` header should be merged with the
+existing one.
\ No newline at end of file
diff --git a/docs/FeatureTestMacroTable.rst b/docs/FeatureTestMacroTable.rst
new file mode 100644
index 0000000..d900497
--- /dev/null
+++ b/docs/FeatureTestMacroTable.rst
@@ -0,0 +1,200 @@
+.. _FeatureTestMacroTable:
+
+==========================
+Feature Test Macro Support
+==========================
+
+.. contents::
+   :local:
+
+Overview
+========
+
+This file documents the feature test macros currently supported by libc++.
+
+.. _feature-status:
+
+Status
+======
+
+.. table:: Current Status
+     :name: feature-status-table
+     :widths: auto
+     
+    ================================================= =================
+    Macro Name                                        Value            
+    ================================================= =================
+    **C++ 14**                                                         
+    -------------------------------------------------------------------
+    ``__cpp_lib_chrono_udls``                         ``201304L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_complex_udls``                        ``201309L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_exchange_function``                   ``201304L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_generic_associative_lookup``          ``201304L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_integer_sequence``                    ``201304L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_integral_constant_callable``          ``201304L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_is_final``                            ``201402L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_is_null_pointer``                     ``201309L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_make_reverse_iterator``               ``201402L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_make_unique``                         ``201304L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_null_iterators``                      ``201304L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_quoted_string_io``                    ``201304L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_result_of_sfinae``                    ``201210L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_robust_nonmodifying_seq_ops``         ``201304L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_shared_timed_mutex``                  ``201402L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_string_udls``                         ``201304L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_transformation_trait_aliases``        ``201304L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_transparent_operators``               ``201210L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_tuple_element_t``                     ``201402L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_tuples_by_type``                      ``201304L``      
+    ------------------------------------------------- -----------------
+    **C++ 17**                                                         
+    -------------------------------------------------------------------
+    ``__cpp_lib_addressof_constexpr``                 ``201603L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_allocator_traits_is_always_equal``    ``201411L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_any``                                 ``201606L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_apply``                               ``201603L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_array_constexpr``                     ``201603L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_as_const``                            ``201510L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_atomic_is_always_lock_free``          ``201603L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_bool_constant``                       ``201505L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_boyer_moore_searcher``                *unimplemented*  
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_byte``                                ``201603L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_chrono``                              ``201611L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_clamp``                               ``201603L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_enable_shared_from_this``             ``201603L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_execution``                           *unimplemented*  
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_filesystem``                          ``201703L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_gcd_lcm``                             ``201606L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_hardware_interference_size``          ``201703L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_has_unique_object_representations``   ``201606L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_hypot``                               ``201603L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_incomplete_container_elements``       ``201505L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_invoke``                              ``201411L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_is_aggregate``                        ``201703L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_is_invocable``                        ``201703L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_is_swappable``                        ``201603L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_launder``                             ``201606L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_logical_traits``                      ``201510L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_make_from_tuple``                     ``201606L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_map_try_emplace``                     ``201411L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_math_special_functions``              *unimplemented*  
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_memory_resource``                     *unimplemented*  
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_node_extract``                        ``201606L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_nonmember_container_access``          ``201411L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_not_fn``                              ``201603L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_optional``                            ``201606L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_parallel_algorithm``                  *unimplemented*  
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_raw_memory_algorithms``               ``201606L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_sample``                              ``201603L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_scoped_lock``                         ``201703L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_shared_mutex``                        ``201505L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_shared_ptr_arrays``                   *unimplemented*  
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_shared_ptr_weak_type``                ``201606L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_string_view``                         ``201606L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_to_chars``                            *unimplemented*  
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_transparent_operators``               ``201510L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_type_trait_variable_templates``       ``201510L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_uncaught_exceptions``                 ``201411L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_unordered_map_try_emplace``           ``201411L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_variant``                             ``201606L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_void_t``                              ``201411L``      
+    ------------------------------------------------- -----------------
+    **C++ 2a**                                                         
+    -------------------------------------------------------------------
+    ``__cpp_lib_atomic_ref``                          *unimplemented*  
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_bind_front``                          *unimplemented*  
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_bit_cast``                            *unimplemented*  
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_char8_t``                             ``201811L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_concepts``                            *unimplemented*  
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_constexpr_misc``                      *unimplemented*  
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_constexpr_swap_algorithms``           *unimplemented*  
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_destroying_delete``                   *unimplemented*  
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_erase_if``                            ``201811L``      
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_generic_unordered_lookup``            *unimplemented*  
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_is_constant_evaluated``               *unimplemented*  
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_list_remove_return_type``             *unimplemented*  
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_ranges``                              *unimplemented*  
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_three_way_comparison``                *unimplemented*  
+    ================================================= =================
+
+
diff --git a/docs/index.rst b/docs/index.rst
index bb56f2d..fddf74b 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -40,6 +40,11 @@
    TestingLibcxx
 
 
+.. toctree::
+    :hidden:
+
+    FeatureTestMacroTable
+
 Current Status
 --------------
 
@@ -107,6 +112,7 @@
 * `C++14 - Complete <http://libcxx.llvm.org/cxx1y_status.html>`__
 * `C++17 - In Progress <http://libcxx.llvm.org/cxx1z_status.html>`__
 * `Post C++14 Technical Specifications - In Progress <http://libcxx.llvm.org/ts1z_status.html>`__
+* :ref:`C++ Feature Test Macro Status <feature-status>`
 
 Notes and Known Issues
 ----------------------
@@ -136,6 +142,7 @@
    DesignDocs/VisibilityMacros
    DesignDocs/ThreadingSupportAPI
    DesignDocs/FileTimeType
+   DesignDocs/FeatureTestMacros
 
 * `<atomic> design <http://libcxx.llvm.org/atomic_design.html>`_
 * `<type_traits> design <http://libcxx.llvm.org/type_traits_design.html>`_