mirror of
https://github.com/darlinghq/darling-libcxx.git
synced 2024-11-23 03:49:42 +00:00
Update libcxx source to llvmorg-14.0.6
This commit is contained in:
parent
bb80d09b3f
commit
e3bbeb7fdc
File diff suppressed because it is too large
Load Diff
58
CREDITS.TXT
58
CREDITS.TXT
@ -12,6 +12,13 @@ N: Saleem Abdulrasool
|
||||
E: compnerd@compnerd.org
|
||||
D: Minor patches and Linux fixes.
|
||||
|
||||
N: Ulf Adams
|
||||
D: Invented the Ryu and Ryu Printf algorithms used in floating-point to_chars, and wrote the initial code.
|
||||
|
||||
N: Muiez Ahmed
|
||||
E: muiez@ibm.com
|
||||
D: z/OS port.
|
||||
|
||||
N: Dan Albert
|
||||
E: danalbert@google.com
|
||||
D: Android support and test runner improvements.
|
||||
@ -24,9 +31,8 @@ N: Holger Arnold
|
||||
E: holgerar@gmail.com
|
||||
D: Minor fix.
|
||||
|
||||
N: Ruben Van Boxem
|
||||
E: vanboxem dot ruben at gmail dot com
|
||||
D: Initial Windows patches.
|
||||
N: Jorg Brown
|
||||
D: Ported floating-point to_chars from MSVC to libc++.
|
||||
|
||||
N: David Chisnall
|
||||
E: theraven at theravensnest dot org
|
||||
@ -41,6 +47,15 @@ N: Jonathan B Coe
|
||||
E: jbcoe@me.com
|
||||
D: Implementation of propagate_const.
|
||||
|
||||
N: Matthew Dempsky
|
||||
E: matthew@dempsky.org
|
||||
D: Minor patches and bug fixes.
|
||||
|
||||
N: Christopher Di Bella
|
||||
E: cjdb@google.com
|
||||
E: cjdb.ns@gmail.com
|
||||
D: Library concepts.
|
||||
|
||||
N: Glen Joseph Fernandes
|
||||
E: glenjofe@gmail.com
|
||||
D: Implementation of to_address.
|
||||
@ -53,10 +68,6 @@ N: Bill Fisher
|
||||
E: william.w.fisher@gmail.com
|
||||
D: Regex bug fixes.
|
||||
|
||||
N: Matthew Dempsky
|
||||
E: matthew@dempsky.org
|
||||
D: Minor patches and bug fixes.
|
||||
|
||||
N: Google Inc.
|
||||
D: Copyright owner and contributor of the CityHash algorithm
|
||||
|
||||
@ -64,6 +75,10 @@ N: Howard Hinnant
|
||||
E: hhinnant@apple.com
|
||||
D: Architect and primary author of libc++
|
||||
|
||||
N: Sergej Jaskiewicz
|
||||
E: jaskiewiczs@icloud.com
|
||||
D: Minor improvements in the testing infrastructure
|
||||
|
||||
N: Hyeon-bin Jeong
|
||||
E: tuhertz@gmail.com
|
||||
D: Minor patches and bug fixes.
|
||||
@ -72,6 +87,14 @@ N: Argyrios Kyrtzidis
|
||||
E: kyrtzidis@apple.com
|
||||
D: Bug fixes.
|
||||
|
||||
N: Stephan T. Lavavej
|
||||
E: stl@microsoft.com
|
||||
E: stl@nuwen.net
|
||||
D: Implemented floating-point to_chars.
|
||||
|
||||
N: Microsoft Corporation
|
||||
D: Contributed floating-point to_chars.
|
||||
|
||||
N: Bruce Mitchener, Jr.
|
||||
E: bruce.mitchener@gmail.com
|
||||
D: Emscripten-related changes.
|
||||
@ -104,6 +127,10 @@ N: Jon Roelofs
|
||||
E: jroelofS@jroelofs.com
|
||||
D: Remote testing, Newlib port, baremetal/single-threaded support.
|
||||
|
||||
N: Kent Ross
|
||||
E: k@mad.cash
|
||||
D: Patches for operator<=> support
|
||||
|
||||
N: Jonathan Sauer
|
||||
D: Minor patches, mostly related to constexpr
|
||||
|
||||
@ -122,6 +149,10 @@ N: Stephan Tolksdorf
|
||||
E: st@quanttec.com
|
||||
D: Minor <atomic> fix
|
||||
|
||||
N: Ruben Van Boxem
|
||||
E: vanboxem dot ruben at gmail dot com
|
||||
D: Initial Windows patches.
|
||||
|
||||
N: Michael van der Westhuizen
|
||||
E: r1mikey at gmail dot com
|
||||
|
||||
@ -132,6 +163,11 @@ N: Klaas de Vries
|
||||
E: klaas at klaasgaaf dot nl
|
||||
D: Minor bug fix.
|
||||
|
||||
N: Mark de Wever
|
||||
E: koraq at xs4all dot nl
|
||||
D: Format library support.
|
||||
D: Finalized the porting of MSVC's to_chars to libc++.
|
||||
|
||||
N: Zhang Xiongpang
|
||||
E: zhangxiongpang@gmail.com
|
||||
D: Minor patches and bug fixes.
|
||||
@ -140,11 +176,11 @@ N: Xing Xue
|
||||
E: xingxue@ca.ibm.com
|
||||
D: AIX port
|
||||
|
||||
N: Zhihao Yuan
|
||||
E: lichray@gmail.com
|
||||
D: Standard compatibility fixes.
|
||||
|
||||
N: Jeffrey Yasskin
|
||||
E: jyasskin@gmail.com
|
||||
E: jyasskin@google.com
|
||||
D: Linux fixes.
|
||||
|
||||
N: Zhihao Yuan
|
||||
E: lichray@gmail.com
|
||||
D: Standard compatibility fixes.
|
||||
|
29
NOTES.TXT
29
NOTES.TXT
@ -1,29 +0,0 @@
|
||||
//===---------------------------------------------------------------------===//
|
||||
// Notes relating to various libc++ tasks
|
||||
//===---------------------------------------------------------------------===//
|
||||
|
||||
This file contains notes about various libc++ tasks and processes.
|
||||
|
||||
//===---------------------------------------------------------------------===//
|
||||
// Post-Release TODO
|
||||
//===---------------------------------------------------------------------===//
|
||||
|
||||
These notes contain a list of things that must be done after branching for
|
||||
an LLVM release.
|
||||
|
||||
1. Update _LIBCPP_VERSION in `__config`
|
||||
2. Update the __libcpp_version file.
|
||||
3. Update the version number in `docs/conf.py`
|
||||
4. Create ABI lists for the previous release under `lib/abi`
|
||||
|
||||
//===---------------------------------------------------------------------===//
|
||||
// Adding a new header TODO
|
||||
//===---------------------------------------------------------------------===//
|
||||
|
||||
These notes contain a list of things that must be done upon adding a new header
|
||||
to libc++.
|
||||
|
||||
1. Add a test under `test/libcxx` that the header defines `_LIBCPP_VERSION`.
|
||||
2. Update `test/libcxx/double_include.sh.cpp` to include the new header.
|
||||
3. Create a submodule in `include/module.modulemap` for the new header.
|
||||
4. Update the include/CMakeLists.txt file to include the new header.
|
53
TODO.TXT
53
TODO.TXT
@ -2,7 +2,6 @@ This is meant to be a general place to list things that should be done "someday"
|
||||
|
||||
CXX Runtime Library Tasks
|
||||
=========================
|
||||
* Fix that CMake always link to /usr/lib/libc++abi.dylib on OS X.
|
||||
* Look into mirroring libsupc++'s typeinfo vtable layout when libsupc++/libstdc++
|
||||
is used as the runtime library.
|
||||
* Investigate and document interoperability between libc++ and libstdc++ on
|
||||
@ -17,60 +16,8 @@ Test Suite Tasks
|
||||
* Improve the quality and portability of the locale test data.
|
||||
* Convert failure tests to use Clang Verify.
|
||||
|
||||
Filesystem Tasks
|
||||
================
|
||||
* P0492r2 - Implement National body comments for Filesystem
|
||||
* INCOMPLETE - US 25: has_filename() is equivalent to just !empty()
|
||||
* INCOMPLETE - US 31: Everything is defined in terms of one implicit host system
|
||||
* INCOMPLETE - US 32: Meaning of 27.10.2.1 unclear
|
||||
* INCOMPLETE - US 33: Definition of canonical path problematic
|
||||
* INCOMPLETE - US 34: Are there attributes of a file that are not an aspect of the file system?
|
||||
* INCOMPLETE - US 35: What synchronization is required to avoid a file system race?
|
||||
* INCOMPLETE - US 36: Symbolic links themselves are attached to a directory via (hard) links
|
||||
* INCOMPLETE - US 37: The term “redundant current directory (dot) elements” is not defined
|
||||
* INCOMPLETE - US 38: Duplicates §17.3.16
|
||||
* INCOMPLETE - US 39: Remove note: Dot and dot-dot are not directories
|
||||
* INCOMPLETE - US 40: Not all directories have a parent.
|
||||
* INCOMPLETE - US 41: The term “parent directory” for a (non-directory) file is unusual
|
||||
* INCOMPLETE - US 42: Pathname resolution does not always resolve a symlink
|
||||
* INCOMPLETE - US 43: Concerns about encoded character types
|
||||
* INCOMPLETE - US 44: Definition of path in terms of a string requires leaky abstraction
|
||||
* INCOMPLETE - US 45: Generic format portability compromised by unspecified root-name
|
||||
* INCOMPLETE - US 46: filename can be empty so productions for relative-path are redundant
|
||||
* INCOMPLETE - US 47: “.” and “..” already match the name production
|
||||
* INCOMPLETE - US 48: Multiple separators are often meaningful in a root-name
|
||||
* INCOMPLETE - US 49: What does “method of conversion method” mean?
|
||||
* INCOMPLETE - US 50: 27.10.8.1 ¶ 1.4 largely redundant with ¶ 1.3
|
||||
* INCOMPLETE - US 51: Failing to add / when appending empty string prevents useful apps
|
||||
* INCOMPLETE - US 52: remove_filename() postcondition is not by itself a definition
|
||||
* INCOMPLETE - US 53: remove_filename()'s name does not correspond to its behavior
|
||||
* INCOMPLETE - US 54: remove_filename() is broken
|
||||
* INCOMPLETE - US 55: replace_extension()'s use of path as parameter is inappropriate
|
||||
* INCOMPLETE - US 56: Remove replace_extension()'s conditional addition of period
|
||||
* INCOMPLETE - US 57: On Windows, absolute paths will sort in among relative paths
|
||||
* INCOMPLETE - US 58: parent_path() behavior for root paths is useless
|
||||
* INCOMPLETE - US 59: filename() returning path for single path components is bizarre
|
||||
* INCOMPLETE - US 60: path("/foo/").filename()==path(".") is surprising
|
||||
* INCOMPLETE - US 61: Leading dots in filename() should not begin an extension
|
||||
* INCOMPLETE - US 62: It is important that stem()+extension()==filename()
|
||||
* INCOMPLETE - US 63: lexically_normal() inconsistently treats trailing "/" but not "/.." as directory
|
||||
* INCOMPLETE - US 73, CA 2: root-name is effectively implementation defined
|
||||
* INCOMPLETE - US 74, CA 3: The term “pathname” is ambiguous in some contexts
|
||||
* INCOMPLETE - US 75, CA 4: Extra flag in path constructors is needed
|
||||
* INCOMPLETE - US 76, CA 5: root-name definition is over-specified.
|
||||
* INCOMPLETE - US 77, CA 6: operator/ and other appends not useful if arg has root-name
|
||||
* INCOMPLETE - US 78, CA 7: Member absolute() in 27.10.4.1 is overspecified for non-POSIX-like O/S
|
||||
* INCOMPLETE - US 79, CA 8: Some operation functions are overspecified for implementation-defined file types
|
||||
* INCOMPLETE - US 185: Fold error_code and non-error_code signatures into one signature
|
||||
* INCOMPLETE - FI 14: directory_entry comparisons are members
|
||||
* INCOMPLETE - Late 36: permissions() error_code overload should be noexcept
|
||||
* INCOMPLETE - Late 37: permissions() actions should be separate parameter
|
||||
* INCOMPLETE - Late 42: resize_file() Postcondition missing argument
|
||||
|
||||
Misc Tasks
|
||||
==========
|
||||
* Find all sequences of >2 underscores and eradicate them.
|
||||
* run clang-tidy on libc++
|
||||
* Document the "conditionally-supported" bits of libc++
|
||||
* Look at basic_string's move assignment operator, re LWG 2063 and POCMA
|
||||
* Put a static_assert in std::allocator to deny const/volatile types (LWG 2447)
|
||||
|
@ -1,3 +1,14 @@
|
||||
if (CMAKE_VERSION VERSION_LESS 3.17)
|
||||
message(WARNING "The libc++ benchmarks won't be available because the version of CMake is too old to support them.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (LIBCXX_STANDALONE_BUILD)
|
||||
message(WARNING "The libc++ benchmarks are not available in a standalone build. Please migrate to an official build "
|
||||
"as documented in https://libcxx.llvm.org/BuildingLibcxx.html.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
include(ExternalProject)
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
@ -5,29 +16,32 @@ include(CheckCXXCompilerFlag)
|
||||
# Build Google Benchmark for libc++
|
||||
#==============================================================================
|
||||
|
||||
set(CMAKE_FOLDER "${CMAKE_FOLDER}/Benchmarks")
|
||||
|
||||
set(BENCHMARK_LIBCXX_COMPILE_FLAGS
|
||||
-Wno-unused-command-line-argument
|
||||
-nostdinc++
|
||||
-isystem ${LIBCXX_SOURCE_DIR}/include
|
||||
-isystem "${LIBCXX_GENERATED_INCLUDE_DIR}"
|
||||
-L${LIBCXX_LIBRARY_DIR}
|
||||
-Wl,-rpath,${LIBCXX_LIBRARY_DIR}
|
||||
${SANITIZER_FLAGS}
|
||||
)
|
||||
if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE)
|
||||
list(APPEND BENCHMARK_LIBCXX_COMPILE_FLAGS
|
||||
-isystem "${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}")
|
||||
endif()
|
||||
if (DEFINED LIBCXX_CXX_ABI_LIBRARY_PATH)
|
||||
list(APPEND BENCHMARK_LIBCXX_COMPILE_FLAGS
|
||||
-L${LIBCXX_CXX_ABI_LIBRARY_PATH}
|
||||
-Wl,-rpath,${LIBCXX_CXX_ABI_LIBRARY_PATH})
|
||||
endif()
|
||||
if (LIBCXX_NEEDS_SITE_CONFIG)
|
||||
list(APPEND BENCHMARK_LIBCXX_COMPILE_FLAGS -include "${LIBCXX_BINARY_DIR}/__config_site")
|
||||
endif()
|
||||
split_list(BENCHMARK_LIBCXX_COMPILE_FLAGS)
|
||||
|
||||
ExternalProject_Add(google-benchmark-libcxx
|
||||
EXCLUDE_FROM_ALL ON
|
||||
DEPENDS cxx cxx-headers
|
||||
PREFIX benchmark-libcxx
|
||||
SOURCE_DIR ${LIBCXX_SOURCE_DIR}/utils/google-benchmark
|
||||
SOURCE_DIR ${LLVM_THIRD_PARTY_DIR}/benchmark
|
||||
INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/benchmark-libcxx
|
||||
CMAKE_CACHE_ARGS
|
||||
-DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER}
|
||||
@ -44,7 +58,7 @@ ExternalProject_Add(google-benchmark-libcxx
|
||||
set(BENCHMARK_NATIVE_TARGET_FLAGS)
|
||||
if (LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN)
|
||||
set(BENCHMARK_NATIVE_TARGET_FLAGS
|
||||
-gcc-toolchain ${LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN})
|
||||
--gcc-toolchain=${LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN})
|
||||
endif()
|
||||
split_list(BENCHMARK_NATIVE_TARGET_FLAGS)
|
||||
|
||||
@ -52,7 +66,7 @@ if (LIBCXX_BENCHMARK_NATIVE_STDLIB)
|
||||
ExternalProject_Add(google-benchmark-native
|
||||
EXCLUDE_FROM_ALL ON
|
||||
PREFIX benchmark-native
|
||||
SOURCE_DIR ${LIBCXX_SOURCE_DIR}/utils/google-benchmark
|
||||
SOURCE_DIR ${LLVM_THIRD_PARTY_DIR}/benchmark
|
||||
INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/benchmark-native
|
||||
CMAKE_CACHE_ARGS
|
||||
-DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER}
|
||||
@ -72,67 +86,43 @@ set(BENCHMARK_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||
set(BENCHMARK_LIBCXX_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/benchmark-libcxx)
|
||||
set(BENCHMARK_NATIVE_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/benchmark-native)
|
||||
|
||||
check_flag_supported("-std=c++17")
|
||||
mangle_name("LIBCXX_SUPPORTS_STD_EQ_c++17_FLAG" BENCHMARK_SUPPORTS_STD_CXX17_FLAG)
|
||||
if (${BENCHMARK_SUPPORTS_STD_CXX17_FLAG})
|
||||
set(BENCHMARK_DIALECT_FLAG "-std=c++17")
|
||||
else()
|
||||
# If the compiler doesn't support -std=c++17, attempt to fall back to -std=c++1z while still
|
||||
# requiring C++17 language features.
|
||||
set(BENCHMARK_DIALECT_FLAG "-std=c++1z")
|
||||
endif()
|
||||
|
||||
set(BENCHMARK_TEST_COMPILE_FLAGS
|
||||
${BENCHMARK_DIALECT_FLAG} -O2
|
||||
-fsized-deallocation
|
||||
-I${BENCHMARK_LIBCXX_INSTALL}/include
|
||||
-I${LIBCXX_SOURCE_DIR}/test/support
|
||||
)
|
||||
set(BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS
|
||||
-nostdinc++
|
||||
-isystem ${LIBCXX_SOURCE_DIR}/include
|
||||
${BENCHMARK_TEST_COMPILE_FLAGS}
|
||||
${SANITIZER_FLAGS}
|
||||
-Wno-user-defined-literals
|
||||
)
|
||||
|
||||
set(BENCHMARK_TEST_LIBCXX_LINK_FLAGS
|
||||
-nodefaultlibs
|
||||
-L${BENCHMARK_LIBCXX_INSTALL}/lib/
|
||||
${SANITIZER_FLAGS}
|
||||
)
|
||||
set(BENCHMARK_TEST_NATIVE_COMPILE_FLAGS
|
||||
${BENCHMARK_NATIVE_TARGET_FLAGS}
|
||||
${BENCHMARK_TEST_COMPILE_FLAGS}
|
||||
)
|
||||
set(BENCHMARK_TEST_NATIVE_LINK_FLAGS
|
||||
${BENCHMARK_NATIVE_TARGET_FLAGS}
|
||||
-L${BENCHMARK_NATIVE_INSTALL}/lib
|
||||
)
|
||||
split_list(BENCHMARK_TEST_COMPILE_FLAGS)
|
||||
split_list(BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS)
|
||||
split_list(BENCHMARK_TEST_LIBCXX_LINK_FLAGS)
|
||||
split_list(BENCHMARK_TEST_NATIVE_COMPILE_FLAGS)
|
||||
split_list(BENCHMARK_TEST_NATIVE_LINK_FLAGS)
|
||||
add_library( cxx-benchmarks-flags INTERFACE)
|
||||
target_compile_features( cxx-benchmarks-flags INTERFACE cxx_std_20)
|
||||
target_compile_options( cxx-benchmarks-flags INTERFACE -O2 -fsized-deallocation -nostdinc++)
|
||||
target_include_directories(cxx-benchmarks-flags INTERFACE "${LIBCXX_GENERATED_INCLUDE_DIR}"
|
||||
INTERFACE "${BENCHMARK_LIBCXX_INSTALL}/include"
|
||||
INTERFACE "${LIBCXX_SOURCE_DIR}/test/support")
|
||||
|
||||
add_library( cxx-benchmarks-flags-native INTERFACE)
|
||||
target_link_libraries( cxx-benchmarks-flags-native INTERFACE cxx-benchmarks-flags)
|
||||
target_compile_options(cxx-benchmarks-flags-native INTERFACE ${BENCHMARK_NATIVE_TARGET_FLAGS})
|
||||
target_link_options( cxx-benchmarks-flags-native INTERFACE ${BENCHMARK_NATIVE_TARGET_FLAGS} "-L${BENCHMARK_NATIVE_INSTALL}/lib")
|
||||
if (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libstdc++")
|
||||
find_library(LIBSTDCXX_FILESYSTEM_TEST stdc++fs
|
||||
PATHS ${LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN}
|
||||
PATH_SUFFIXES lib lib64
|
||||
DOC "The libstdc++ filesystem library used by the benchmarks"
|
||||
)
|
||||
if (NOT "${LIBSTDCXX_FILESYSTEM_TEST}" STREQUAL "LIBSTDCXX_FILESYSTEM_TEST-NOTFOUND")
|
||||
set(LIBSTDCXX_FILESYSTEM_LIB "stdc++fs")
|
||||
endif()
|
||||
if (LIBSTDCXX_FILESYSTEM_TEST)
|
||||
target_link_libraries(cxx-benchmarks-flags-native INTERFACE -lstdc++fs)
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries(cxx-benchmarks-flags-native INTERFACE -lc++fs -lc++experimental)
|
||||
endif()
|
||||
|
||||
add_library( cxx-benchmarks-flags-libcxx INTERFACE)
|
||||
target_link_libraries( cxx-benchmarks-flags-libcxx INTERFACE cxx-benchmarks-flags)
|
||||
target_compile_options(cxx-benchmarks-flags-libcxx INTERFACE ${SANITIZER_FLAGS} -Wno-user-defined-literals -Wno-suggest-override)
|
||||
target_link_options( cxx-benchmarks-flags-libcxx INTERFACE -nodefaultlibs "-L${BENCHMARK_LIBCXX_INSTALL}/lib" ${SANITIZER_FLAGS})
|
||||
|
||||
set(libcxx_benchmark_targets)
|
||||
|
||||
function(add_benchmark_test name source_file)
|
||||
set(libcxx_target ${name}_libcxx)
|
||||
list(APPEND libcxx_benchmark_targets ${libcxx_target})
|
||||
add_executable(${libcxx_target} EXCLUDE_FROM_ALL ${source_file})
|
||||
add_dependencies(${libcxx_target} cxx cxx-headers google-benchmark-libcxx)
|
||||
target_link_libraries(${libcxx_target} PRIVATE cxx-benchmarks-flags-libcxx)
|
||||
add_dependencies(${libcxx_target} cxx google-benchmark-libcxx)
|
||||
add_dependencies(cxx-benchmarks ${libcxx_target})
|
||||
if (LIBCXX_ENABLE_SHARED)
|
||||
target_link_libraries(${libcxx_target} PRIVATE cxx_shared)
|
||||
@ -150,24 +140,15 @@ function(add_benchmark_test name source_file)
|
||||
PROPERTIES
|
||||
OUTPUT_NAME "${name}.libcxx.out"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${BENCHMARK_OUTPUT_DIR}"
|
||||
COMPILE_FLAGS "${BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS}"
|
||||
LINK_FLAGS "${BENCHMARK_TEST_LIBCXX_LINK_FLAGS}")
|
||||
CXX_EXTENSIONS NO)
|
||||
cxx_link_system_libraries(${libcxx_target})
|
||||
if (LIBCXX_BENCHMARK_NATIVE_STDLIB)
|
||||
if (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libstdc++" AND NOT DEFINED LIBSTDCXX_FILESYSTEM_LIB
|
||||
AND "${name}" STREQUAL "filesystem")
|
||||
return()
|
||||
endif()
|
||||
set(native_target ${name}_native)
|
||||
add_executable(${native_target} EXCLUDE_FROM_ALL ${source_file})
|
||||
target_link_libraries(${native_target} PRIVATE cxx-benchmarks-flags-native)
|
||||
add_dependencies(${native_target} google-benchmark-native
|
||||
google-benchmark-libcxx)
|
||||
target_link_libraries(${native_target} PRIVATE -lbenchmark)
|
||||
if (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libstdc++")
|
||||
target_link_libraries(${native_target} PRIVATE ${LIBSTDCXX_FILESYSTEM_LIB})
|
||||
elseif (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libc++")
|
||||
target_link_libraries(${native_target} PRIVATE -lc++fs -lc++experimental)
|
||||
endif()
|
||||
if (LIBCXX_HAS_PTHREAD_LIB)
|
||||
target_link_libraries(${native_target} PRIVATE -pthread)
|
||||
endif()
|
||||
@ -176,9 +157,7 @@ function(add_benchmark_test name source_file)
|
||||
PROPERTIES
|
||||
OUTPUT_NAME "${name}.native.out"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${BENCHMARK_OUTPUT_DIR}"
|
||||
INCLUDE_DIRECTORIES ""
|
||||
COMPILE_FLAGS "${BENCHMARK_TEST_NATIVE_COMPILE_FLAGS}"
|
||||
LINK_FLAGS "${BENCHMARK_TEST_NATIVE_LINK_FLAGS}")
|
||||
CXX_EXTENSIONS NO)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
@ -187,6 +166,11 @@ endfunction()
|
||||
# Register Benchmark tests
|
||||
#==============================================================================
|
||||
file(GLOB BENCHMARK_TESTS "*.bench.cpp")
|
||||
|
||||
if (NOT LIBCXX_ENABLE_INCOMPLETE_FEATURES)
|
||||
list(FILTER BENCHMARK_TESTS EXCLUDE REGEX "(format_to_n|format_to|format|formatted_size|formatter_float|std_format_spec_string_unicode).bench.cpp")
|
||||
endif()
|
||||
|
||||
foreach(test_path ${BENCHMARK_TESTS})
|
||||
get_filename_component(test_file "${test_path}" NAME)
|
||||
string(REPLACE ".bench.cpp" "" test_name "${test_file}")
|
||||
@ -217,4 +201,3 @@ if (LIBCXX_INCLUDE_TESTS)
|
||||
DEPENDS cxx-benchmarks ${LIBCXX_TEST_DEPS}
|
||||
ARGS ${BENCHMARK_LIT_ARGS})
|
||||
endif()
|
||||
|
||||
|
@ -131,4 +131,3 @@ TEST_ALWAYS_INLINE inline T maybeOpaque(T value, bool opaque) {
|
||||
if (opaque) benchmark::DoNotOptimize(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -36,10 +36,9 @@ inline char getRandomChar() {
|
||||
}
|
||||
|
||||
template <class IntT>
|
||||
inline IntT getRandomInteger(IntT Min = 0,
|
||||
IntT Max = std::numeric_limits<IntT>::max()) {
|
||||
std::uniform_int_distribution<IntT> dist(Min, Max);
|
||||
return dist(getRandomEngine());
|
||||
inline IntT getRandomInteger(IntT Min, IntT Max) {
|
||||
std::uniform_int_distribution<unsigned long long> dist(Min, Max);
|
||||
return static_cast<IntT>(dist(getRandomEngine()));
|
||||
}
|
||||
|
||||
inline std::string getRandomString(std::size_t Len) {
|
||||
@ -102,7 +101,7 @@ template <class IntT>
|
||||
std::vector<IntT> getRandomIntegerInputs(size_t N) {
|
||||
std::vector<IntT> inputs;
|
||||
for (size_t i=0; i < N; ++i) {
|
||||
inputs.push_back(getRandomInteger<IntT>());
|
||||
inputs.push_back(getRandomInteger<IntT>(0, std::numeric_limits<IntT>::max()));
|
||||
}
|
||||
return inputs;
|
||||
}
|
||||
|
58
benchmarks/VariantBenchmarks.h
Normal file
58
benchmarks/VariantBenchmarks.h
Normal file
@ -0,0 +1,58 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef BENCHMARK_VARIANT_BENCHMARKS_H
|
||||
#define BENCHMARK_VARIANT_BENCHMARKS_H
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <variant>
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
#include "GenerateInput.h"
|
||||
|
||||
namespace VariantBenchmarks {
|
||||
|
||||
template <std::size_t I>
|
||||
struct S {
|
||||
static constexpr size_t v = I;
|
||||
};
|
||||
|
||||
template <std::size_t N, std::size_t... Is>
|
||||
static auto genVariants(std::index_sequence<Is...>) {
|
||||
using V = std::variant<S<Is>...>;
|
||||
using F = V (*)();
|
||||
static constexpr F fs[] = {[] { return V(std::in_place_index<Is>); }...};
|
||||
|
||||
std::array<V, N> result = {};
|
||||
for (auto& v : result) {
|
||||
v = fs[getRandomInteger(0ul, sizeof...(Is) - 1)]();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <std::size_t N, std::size_t Alts>
|
||||
static void BM_Visit(benchmark::State& state) {
|
||||
auto args = genVariants<N>(std::make_index_sequence<Alts>{});
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(std::apply(
|
||||
[](auto... vs) {
|
||||
return std::visit([](auto... is) { return (is.v + ... + 0); }, vs...);
|
||||
},
|
||||
args));
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace VariantBenchmarks
|
||||
|
||||
#endif // BENCHMARK_VARIANT_BENCHMARKS_H
|
@ -14,14 +14,23 @@
|
||||
|
||||
namespace {
|
||||
|
||||
enum class ValueType { Uint32, String };
|
||||
struct AllValueTypes : EnumValuesAsTuple<AllValueTypes, ValueType, 2> {
|
||||
static constexpr const char* Names[] = {"uint32", "string"};
|
||||
enum class ValueType { Uint32, Uint64, Pair, Tuple, String };
|
||||
struct AllValueTypes : EnumValuesAsTuple<AllValueTypes, ValueType, 5> {
|
||||
static constexpr const char* Names[] = {
|
||||
"uint32", "uint64", "pair<uint32, uint32>",
|
||||
"tuple<uint32, uint64, uint32>", "string"};
|
||||
};
|
||||
|
||||
template <class V>
|
||||
using Value =
|
||||
std::conditional_t<V() == ValueType::Uint32, uint32_t, std::string>;
|
||||
using Value = std::conditional_t<
|
||||
V() == ValueType::Uint32, uint32_t,
|
||||
std::conditional_t<
|
||||
V() == ValueType::Uint64, uint64_t,
|
||||
std::conditional_t<
|
||||
V() == ValueType::Pair, std::pair<uint32_t, uint32_t>,
|
||||
std::conditional_t<V() == ValueType::Tuple,
|
||||
std::tuple<uint32_t, uint64_t, uint32_t>,
|
||||
std::string> > > >;
|
||||
|
||||
enum class Order {
|
||||
Random,
|
||||
@ -29,30 +38,114 @@ enum class Order {
|
||||
Descending,
|
||||
SingleElement,
|
||||
PipeOrgan,
|
||||
Heap
|
||||
Heap,
|
||||
QuickSortAdversary,
|
||||
};
|
||||
struct AllOrders : EnumValuesAsTuple<AllOrders, Order, 6> {
|
||||
struct AllOrders : EnumValuesAsTuple<AllOrders, Order, 7> {
|
||||
static constexpr const char* Names[] = {"Random", "Ascending",
|
||||
"Descending", "SingleElement",
|
||||
"PipeOrgan", "Heap"};
|
||||
"PipeOrgan", "Heap",
|
||||
"QuickSortAdversary"};
|
||||
};
|
||||
|
||||
void fillValues(std::vector<uint32_t>& V, size_t N, Order O) {
|
||||
// fillAdversarialQuickSortInput fills the input vector with N int-like values.
|
||||
// These values are arranged in such a way that they would invoke O(N^2)
|
||||
// behavior on any quick sort implementation that satisifies certain conditions.
|
||||
// Details are available in the following paper:
|
||||
// "A Killer Adversary for Quicksort", M. D. McIlroy, Software—Practice &
|
||||
// ExperienceVolume 29 Issue 4 April 10, 1999 pp 341–344.
|
||||
// https://dl.acm.org/doi/10.5555/311868.311871.
|
||||
template <class T>
|
||||
void fillAdversarialQuickSortInput(T& V, size_t N) {
|
||||
assert(N > 0);
|
||||
// If an element is equal to gas, it indicates that the value of the element
|
||||
// is still to be decided and may change over the course of time.
|
||||
const int gas = N - 1;
|
||||
V.resize(N);
|
||||
for (int i = 0; i < N; ++i) {
|
||||
V[i] = gas;
|
||||
}
|
||||
// Candidate for the pivot position.
|
||||
int candidate = 0;
|
||||
int nsolid = 0;
|
||||
// Populate all positions in the generated input to gas.
|
||||
std::vector<int> ascVals(V.size());
|
||||
// Fill up with ascending values from 0 to V.size()-1. These will act as
|
||||
// indices into V.
|
||||
std::iota(ascVals.begin(), ascVals.end(), 0);
|
||||
std::sort(ascVals.begin(), ascVals.end(), [&](int x, int y) {
|
||||
if (V[x] == gas && V[y] == gas) {
|
||||
// We are comparing two inputs whose value is still to be decided.
|
||||
if (x == candidate) {
|
||||
V[x] = nsolid++;
|
||||
} else {
|
||||
V[y] = nsolid++;
|
||||
}
|
||||
}
|
||||
if (V[x] == gas) {
|
||||
candidate = x;
|
||||
} else if (V[y] == gas) {
|
||||
candidate = y;
|
||||
}
|
||||
return V[x] < V[y];
|
||||
});
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void fillValues(std::vector<T>& V, size_t N, Order O) {
|
||||
if (O == Order::SingleElement) {
|
||||
V.resize(N, 0);
|
||||
} else if (O == Order::QuickSortAdversary) {
|
||||
fillAdversarialQuickSortInput(V, N);
|
||||
} else {
|
||||
while (V.size() < N)
|
||||
V.push_back(V.size());
|
||||
}
|
||||
}
|
||||
|
||||
void fillValues(std::vector<std::string>& V, size_t N, Order O) {
|
||||
|
||||
template <typename T>
|
||||
void fillValues(std::vector<std::pair<T, T> >& V, size_t N, Order O) {
|
||||
if (O == Order::SingleElement) {
|
||||
V.resize(N, getRandomString(1024));
|
||||
V.resize(N, std::make_pair(0, 0));
|
||||
} else {
|
||||
while (V.size() < N)
|
||||
V.push_back(getRandomString(1024));
|
||||
// Half of array will have the same first element.
|
||||
if (V.size() % 2) {
|
||||
V.push_back(std::make_pair(V.size(), V.size()));
|
||||
} else {
|
||||
V.push_back(std::make_pair(0, V.size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3>
|
||||
void fillValues(std::vector<std::tuple<T1, T2, T3> >& V, size_t N, Order O) {
|
||||
if (O == Order::SingleElement) {
|
||||
V.resize(N, std::make_tuple(0, 0, 0));
|
||||
} else {
|
||||
while (V.size() < N)
|
||||
// One third of array will have the same first element.
|
||||
// One third of array will have the same first element and the same second element.
|
||||
switch (V.size() % 3) {
|
||||
case 0:
|
||||
V.push_back(std::make_tuple(V.size(), V.size(), V.size()));
|
||||
break;
|
||||
case 1:
|
||||
V.push_back(std::make_tuple(0, V.size(), V.size()));
|
||||
break;
|
||||
case 2:
|
||||
V.push_back(std::make_tuple(0, 0, V.size()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fillValues(std::vector<std::string>& V, size_t N, Order O) {
|
||||
if (O == Order::SingleElement) {
|
||||
V.resize(N, getRandomString(64));
|
||||
} else {
|
||||
while (V.size() < N)
|
||||
V.push_back(getRandomString(64));
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,24 +175,30 @@ void sortValues(T& V, Order O) {
|
||||
case Order::Heap:
|
||||
std::make_heap(V.begin(), V.end());
|
||||
break;
|
||||
case Order::QuickSortAdversary:
|
||||
// Nothing to do
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr size_t TestSetElements =
|
||||
#if !TEST_HAS_FEATURE(memory_sanitizer)
|
||||
1 << 18;
|
||||
#else
|
||||
1 << 14;
|
||||
#endif
|
||||
|
||||
template <class ValueType>
|
||||
std::vector<std::vector<Value<ValueType> > > makeOrderedValues(size_t N,
|
||||
Order O) {
|
||||
// Let's make sure that all random sequences of the same size are the same.
|
||||
// That way we can compare the different algorithms with the same input.
|
||||
static std::map<std::pair<size_t, Order>, std::vector<Value<ValueType> > >
|
||||
Cached;
|
||||
|
||||
auto& Values = Cached[{N, O}];
|
||||
if (Values.empty()) {
|
||||
fillValues(Values, N, O);
|
||||
sortValues(Values, O);
|
||||
};
|
||||
const size_t NumCopies = std::max(size_t{1}, 1000 / N);
|
||||
return { NumCopies, Values };
|
||||
std::vector<std::vector<Value<ValueType> > > Ret;
|
||||
const size_t NumCopies = std::max(size_t{1}, TestSetElements / N);
|
||||
Ret.resize(NumCopies);
|
||||
for (auto& V : Ret) {
|
||||
fillValues(V, N, O);
|
||||
sortValues(V, O);
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
@ -111,19 +210,28 @@ TEST_ALWAYS_INLINE void resetCopies(benchmark::State& state, T& Copies,
|
||||
state.ResumeTiming();
|
||||
}
|
||||
|
||||
enum class BatchSize {
|
||||
CountElements,
|
||||
CountBatch,
|
||||
};
|
||||
|
||||
template <class ValueType, class F>
|
||||
void runOpOnCopies(benchmark::State& state, size_t Quantity, Order O,
|
||||
bool CountElements, F f) {
|
||||
BatchSize Count, F Body) {
|
||||
auto Copies = makeOrderedValues<ValueType>(Quantity, O);
|
||||
const auto Orig = Copies[0];
|
||||
auto Orig = Copies;
|
||||
|
||||
const size_t Batch = CountElements ? Copies.size() * Quantity : Copies.size();
|
||||
const size_t Batch = Count == BatchSize::CountElements
|
||||
? Copies.size() * Quantity
|
||||
: Copies.size();
|
||||
while (state.KeepRunningBatch(Batch)) {
|
||||
for (auto& Copy : Copies) {
|
||||
f(Copy);
|
||||
Body(Copy);
|
||||
benchmark::DoNotOptimize(Copy);
|
||||
}
|
||||
resetCopies(state, Copies, Orig);
|
||||
state.PauseTiming();
|
||||
Copies = Orig;
|
||||
state.ResumeTiming();
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,9 +240,9 @@ struct Sort {
|
||||
size_t Quantity;
|
||||
|
||||
void run(benchmark::State& state) const {
|
||||
runOpOnCopies<ValueType>(state, Quantity, Order(), false, [](auto& Copy) {
|
||||
std::sort(Copy.begin(), Copy.end());
|
||||
});
|
||||
runOpOnCopies<ValueType>(
|
||||
state, Quantity, Order(), BatchSize::CountElements,
|
||||
[](auto& Copy) { std::sort(Copy.begin(), Copy.end()); });
|
||||
}
|
||||
|
||||
bool skip() const { return Order() == ::Order::Heap; }
|
||||
@ -150,9 +258,9 @@ struct StableSort {
|
||||
size_t Quantity;
|
||||
|
||||
void run(benchmark::State& state) const {
|
||||
runOpOnCopies<ValueType>(state, Quantity, Order(), false, [](auto& Copy) {
|
||||
std::stable_sort(Copy.begin(), Copy.end());
|
||||
});
|
||||
runOpOnCopies<ValueType>(
|
||||
state, Quantity, Order(), BatchSize::CountElements,
|
||||
[](auto& Copy) { std::stable_sort(Copy.begin(), Copy.end()); });
|
||||
}
|
||||
|
||||
bool skip() const { return Order() == ::Order::Heap; }
|
||||
@ -168,9 +276,9 @@ struct MakeHeap {
|
||||
size_t Quantity;
|
||||
|
||||
void run(benchmark::State& state) const {
|
||||
runOpOnCopies<ValueType>(state, Quantity, Order(), false, [](auto& Copy) {
|
||||
std::make_heap(Copy.begin(), Copy.end());
|
||||
});
|
||||
runOpOnCopies<ValueType>(
|
||||
state, Quantity, Order(), BatchSize::CountElements,
|
||||
[](auto& Copy) { std::make_heap(Copy.begin(), Copy.end()); });
|
||||
}
|
||||
|
||||
std::string name() const {
|
||||
@ -185,7 +293,7 @@ struct SortHeap {
|
||||
|
||||
void run(benchmark::State& state) const {
|
||||
runOpOnCopies<ValueType>(
|
||||
state, Quantity, Order::Heap, false,
|
||||
state, Quantity, Order::Heap, BatchSize::CountElements,
|
||||
[](auto& Copy) { std::sort_heap(Copy.begin(), Copy.end()); });
|
||||
}
|
||||
|
||||
@ -199,10 +307,11 @@ struct MakeThenSortHeap {
|
||||
size_t Quantity;
|
||||
|
||||
void run(benchmark::State& state) const {
|
||||
runOpOnCopies<ValueType>(state, Quantity, Order(), false, [](auto& Copy) {
|
||||
std::make_heap(Copy.begin(), Copy.end());
|
||||
std::sort_heap(Copy.begin(), Copy.end());
|
||||
});
|
||||
runOpOnCopies<ValueType>(state, Quantity, Order(), BatchSize::CountElements,
|
||||
[](auto& Copy) {
|
||||
std::make_heap(Copy.begin(), Copy.end());
|
||||
std::sort_heap(Copy.begin(), Copy.end());
|
||||
});
|
||||
}
|
||||
|
||||
std::string name() const {
|
||||
@ -216,11 +325,12 @@ struct PushHeap {
|
||||
size_t Quantity;
|
||||
|
||||
void run(benchmark::State& state) const {
|
||||
runOpOnCopies<ValueType>(state, Quantity, Order(), true, [](auto& Copy) {
|
||||
for (auto I = Copy.begin(), E = Copy.end(); I != E; ++I) {
|
||||
std::push_heap(Copy.begin(), I + 1);
|
||||
}
|
||||
});
|
||||
runOpOnCopies<ValueType>(
|
||||
state, Quantity, Order(), BatchSize::CountElements, [](auto& Copy) {
|
||||
for (auto I = Copy.begin(), E = Copy.end(); I != E; ++I) {
|
||||
std::push_heap(Copy.begin(), I + 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bool skip() const { return Order() == ::Order::Heap; }
|
||||
@ -236,11 +346,12 @@ struct PopHeap {
|
||||
size_t Quantity;
|
||||
|
||||
void run(benchmark::State& state) const {
|
||||
runOpOnCopies<ValueType>(state, Quantity, Order(), true, [](auto& Copy) {
|
||||
for (auto B = Copy.begin(), I = Copy.end(); I != B; --I) {
|
||||
std::pop_heap(B, I);
|
||||
}
|
||||
});
|
||||
runOpOnCopies<ValueType>(
|
||||
state, Quantity, Order(), BatchSize::CountElements, [](auto& Copy) {
|
||||
for (auto B = Copy.begin(), I = Copy.end(); I != B; --I) {
|
||||
std::pop_heap(B, I);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
std::string name() const {
|
||||
|
@ -30,7 +30,7 @@ struct TestIntBase {
|
||||
static std::vector<IntT> generateInput(size_t size) {
|
||||
std::vector<IntT> Res(size);
|
||||
std::generate(Res.begin(), Res.end(),
|
||||
[] { return getRandomInteger<IntT>(); });
|
||||
[] { return getRandomInteger<IntT>(0, std::numeric_limits<IntT>::max()); });
|
||||
return Res;
|
||||
}
|
||||
};
|
||||
|
@ -97,7 +97,6 @@ static void BM_DeallocateOnly(benchmark::State& st) {
|
||||
const size_t alloc_size = st.range(0);
|
||||
const auto NumAllocs = st.max_iterations;
|
||||
|
||||
using PtrT = void*;
|
||||
std::vector<void*> Pointers(NumAllocs);
|
||||
for (auto& p : Pointers) {
|
||||
p = AllocWrapper::Allocate(alloc_size);
|
||||
|
@ -1,4 +1,3 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
|
@ -62,7 +62,7 @@ void BM_PathConstructIter(benchmark::State &st, GenInputs gen) {
|
||||
}
|
||||
template <class GenInputs>
|
||||
void BM_PathConstructInputIter(benchmark::State &st, GenInputs gen) {
|
||||
BM_PathConstructIter<input_iterator>(st, gen);
|
||||
BM_PathConstructIter<cpp17_input_iterator>(st, gen);
|
||||
}
|
||||
template <class GenInputs>
|
||||
void BM_PathConstructForwardIter(benchmark::State &st, GenInputs gen) {
|
||||
@ -83,7 +83,7 @@ void BM_PathIterateMultipleTimes(benchmark::State &st, GenInputs gen) {
|
||||
PP /= Part;
|
||||
benchmark::DoNotOptimize(PP.native().data());
|
||||
while (st.KeepRunning()) {
|
||||
for (auto &E : PP) {
|
||||
for (auto const& E : PP) {
|
||||
benchmark::DoNotOptimize(E.native().data());
|
||||
}
|
||||
benchmark::ClobberMemory();
|
||||
@ -104,7 +104,7 @@ void BM_PathIterateOnce(benchmark::State &st, GenInputs gen) {
|
||||
benchmark::DoNotOptimize(PP.native().data());
|
||||
while (st.KeepRunning()) {
|
||||
const path P = PP.native();
|
||||
for (auto &E : P) {
|
||||
for (auto const& E : P) {
|
||||
benchmark::DoNotOptimize(E.native().data());
|
||||
}
|
||||
benchmark::ClobberMemory();
|
||||
|
36
benchmarks/format.bench.cpp
Normal file
36
benchmarks/format.bench.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <format>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
#include "make_string.h"
|
||||
|
||||
#define CSTR(S) MAKE_CSTRING(CharT, S)
|
||||
|
||||
template <class CharT>
|
||||
static void BM_format_string(benchmark::State& state) {
|
||||
size_t size = state.range(0);
|
||||
std::basic_string<CharT> str(size, CharT('*'));
|
||||
|
||||
while (state.KeepRunningBatch(str.size()))
|
||||
benchmark::DoNotOptimize(std::format(CSTR("{}"), str));
|
||||
|
||||
state.SetBytesProcessed(state.iterations() * size * sizeof(CharT));
|
||||
}
|
||||
BENCHMARK_TEMPLATE(BM_format_string, char)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_string, wchar_t)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
benchmark::Initialize(&argc, argv);
|
||||
if (benchmark::ReportUnrecognizedArguments(argc, argv))
|
||||
return 1;
|
||||
|
||||
benchmark::RunSpecifiedBenchmarks();
|
||||
}
|
107
benchmarks/format_to.bench.cpp
Normal file
107
benchmarks/format_to.bench.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <format>
|
||||
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <list>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
#include "make_string.h"
|
||||
|
||||
#define CSTR(S) MAKE_CSTRING(CharT, S)
|
||||
|
||||
/*** Back inserter ***/
|
||||
|
||||
template <class Container>
|
||||
static void BM_format_to_string_back_inserter(benchmark::State& state) {
|
||||
using CharT = typename Container::value_type;
|
||||
size_t size = state.range(0);
|
||||
auto str = std::basic_string<CharT>(size, CharT('*'));
|
||||
|
||||
for (auto _ : state) {
|
||||
Container output;
|
||||
benchmark::DoNotOptimize(std::format_to(std::back_inserter(output), CSTR("{}"), str));
|
||||
}
|
||||
state.SetBytesProcessed(state.iterations() * size * sizeof(CharT));
|
||||
}
|
||||
|
||||
/*** Begin ***/
|
||||
|
||||
template <class Container>
|
||||
static void BM_format_to_string_begin(benchmark::State& state) {
|
||||
using CharT = typename Container::value_type;
|
||||
size_t size = state.range(0);
|
||||
auto str = std::basic_string<CharT>(size, CharT('*'));
|
||||
|
||||
Container output(size, CharT('-'));
|
||||
for (auto _ : state)
|
||||
benchmark::DoNotOptimize(std::format_to(std::begin(output), CSTR("{}"), str));
|
||||
|
||||
state.SetBytesProcessed(state.iterations() * size * sizeof(CharT));
|
||||
}
|
||||
|
||||
/*** Pointer ***/
|
||||
|
||||
template <class CharT>
|
||||
static void BM_format_to_string_span(benchmark::State& state) {
|
||||
size_t size = state.range(0);
|
||||
auto str = std::basic_string<CharT>(size, CharT('*'));
|
||||
|
||||
auto buffer = std::basic_string<CharT>(size, CharT('-'));
|
||||
std::span<CharT> output{buffer};
|
||||
for (auto _ : state)
|
||||
benchmark::DoNotOptimize(std::format_to(std::begin(output), CSTR("{}"), str));
|
||||
|
||||
state.SetBytesProcessed(state.iterations() * size * sizeof(CharT));
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
static void BM_format_to_string_pointer(benchmark::State& state) {
|
||||
size_t size = state.range(0);
|
||||
auto str = std::basic_string<CharT>(size, CharT('*'));
|
||||
|
||||
auto buffer = std::basic_string<CharT>(size, CharT('-'));
|
||||
CharT* output = buffer.data();
|
||||
for (auto _ : state)
|
||||
benchmark::DoNotOptimize(std::format_to(output, CSTR("{}"), str));
|
||||
|
||||
state.SetBytesProcessed(state.iterations() * size * sizeof(CharT));
|
||||
}
|
||||
|
||||
/*** Main ***/
|
||||
|
||||
BENCHMARK_TEMPLATE(BM_format_to_string_back_inserter, std::string)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_string_back_inserter, std::vector<char>)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_string_back_inserter, std::list<char>)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_string_begin, std::string)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_string_begin, std::vector<char>)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_string_begin, std::list<char>)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_string_span, char)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_string_pointer, char)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
|
||||
BENCHMARK_TEMPLATE(BM_format_to_string_back_inserter, std::wstring)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_string_back_inserter, std::vector<wchar_t>)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_string_back_inserter, std::list<wchar_t>)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_string_begin, std::wstring)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_string_begin, std::vector<wchar_t>)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_string_begin, std::list<wchar_t>)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_string_span, wchar_t)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_string_pointer, wchar_t)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
benchmark::Initialize(&argc, argv);
|
||||
if (benchmark::ReportUnrecognizedArguments(argc, argv))
|
||||
return 1;
|
||||
|
||||
benchmark::RunSpecifiedBenchmarks();
|
||||
}
|
107
benchmarks/format_to_n.bench.cpp
Normal file
107
benchmarks/format_to_n.bench.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <format>
|
||||
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <list>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
#include "make_string.h"
|
||||
|
||||
#define CSTR(S) MAKE_CSTRING(CharT, S)
|
||||
|
||||
/*** Back inserter ***/
|
||||
|
||||
template <class Container>
|
||||
static void BM_format_to_n_string_back_inserter(benchmark::State& state) {
|
||||
using CharT = typename Container::value_type;
|
||||
size_t size = state.range(0);
|
||||
auto str = std::basic_string<CharT>(2 * size, CharT('*'));
|
||||
|
||||
for (auto _ : state) {
|
||||
Container output;
|
||||
benchmark::DoNotOptimize(std::format_to_n(std::back_inserter(output), size, CSTR("{}"), str));
|
||||
}
|
||||
state.SetBytesProcessed(state.iterations() * size * sizeof(CharT));
|
||||
}
|
||||
|
||||
/*** Begin ***/
|
||||
|
||||
template <class Container>
|
||||
static void BM_format_to_n_string_begin(benchmark::State& state) {
|
||||
using CharT = typename Container::value_type;
|
||||
size_t size = state.range(0);
|
||||
auto str = std::basic_string<CharT>(2 * size, CharT('*'));
|
||||
|
||||
Container output(size, CharT('-'));
|
||||
for (auto _ : state)
|
||||
benchmark::DoNotOptimize(std::format_to_n(std::begin(output), size, CSTR("{}"), str));
|
||||
|
||||
state.SetBytesProcessed(state.iterations() * size * sizeof(CharT));
|
||||
}
|
||||
|
||||
/*** Pointer ***/
|
||||
|
||||
template <class CharT>
|
||||
static void BM_format_to_n_string_span(benchmark::State& state) {
|
||||
size_t size = state.range(0);
|
||||
auto str = std::basic_string<CharT>(2 * size, CharT('*'));
|
||||
|
||||
auto buffer = std::basic_string<CharT>(size, CharT('-'));
|
||||
std::span<CharT> output{buffer};
|
||||
for (auto _ : state)
|
||||
benchmark::DoNotOptimize(std::format_to_n(std::begin(output), size, CSTR("{}"), str));
|
||||
|
||||
state.SetBytesProcessed(state.iterations() * size * sizeof(CharT));
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
static void BM_format_to_n_string_pointer(benchmark::State& state) {
|
||||
size_t size = state.range(0);
|
||||
auto str = std::basic_string<CharT>(2 * size, CharT('*'));
|
||||
|
||||
auto buffer = std::basic_string<CharT>(size, CharT('-'));
|
||||
CharT* output = buffer.data();
|
||||
for (auto _ : state)
|
||||
benchmark::DoNotOptimize(std::format_to_n(output, size, CSTR("{}"), str));
|
||||
|
||||
state.SetBytesProcessed(state.iterations() * size * sizeof(CharT));
|
||||
}
|
||||
|
||||
/*** Main ***/
|
||||
|
||||
BENCHMARK_TEMPLATE(BM_format_to_n_string_back_inserter, std::string)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_n_string_back_inserter, std::vector<char>)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_n_string_back_inserter, std::list<char>)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_n_string_begin, std::string)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_n_string_begin, std::vector<char>)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_n_string_begin, std::list<char>)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_n_string_span, char)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_n_string_pointer, char)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
|
||||
BENCHMARK_TEMPLATE(BM_format_to_n_string_back_inserter, std::wstring)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_n_string_back_inserter, std::vector<wchar_t>)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_n_string_back_inserter, std::list<wchar_t>)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_n_string_begin, std::wstring)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_n_string_begin, std::vector<wchar_t>)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_n_string_begin, std::list<wchar_t>)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_n_string_span, wchar_t)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_format_to_n_string_pointer, wchar_t)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
benchmark::Initialize(&argc, argv);
|
||||
if (benchmark::ReportUnrecognizedArguments(argc, argv))
|
||||
return 1;
|
||||
|
||||
benchmark::RunSpecifiedBenchmarks();
|
||||
}
|
36
benchmarks/formatted_size.bench.cpp
Normal file
36
benchmarks/formatted_size.bench.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <format>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
#include "make_string.h"
|
||||
|
||||
#define CSTR(S) MAKE_CSTRING(CharT, S)
|
||||
|
||||
template <class CharT>
|
||||
static void BM_formatted_size_string(benchmark::State& state) {
|
||||
size_t size = state.range(0);
|
||||
std::basic_string<CharT> str(size, CharT('*'));
|
||||
|
||||
while (state.KeepRunningBatch(str.size()))
|
||||
benchmark::DoNotOptimize(std::formatted_size(CSTR("{}"), str));
|
||||
|
||||
state.SetBytesProcessed(state.iterations() * size * sizeof(CharT));
|
||||
}
|
||||
BENCHMARK_TEMPLATE(BM_formatted_size_string, char)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
BENCHMARK_TEMPLATE(BM_formatted_size_string, wchar_t)->RangeMultiplier(2)->Range(1, 1 << 20);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
benchmark::Initialize(&argc, argv);
|
||||
if (benchmark::ReportUnrecognizedArguments(argc, argv))
|
||||
return 1;
|
||||
|
||||
benchmark::RunSpecifiedBenchmarks();
|
||||
}
|
241
benchmarks/formatter_float.bench.cpp
Normal file
241
benchmarks/formatter_float.bench.cpp
Normal file
@ -0,0 +1,241 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <format>
|
||||
|
||||
#include <array>
|
||||
#include <limits>
|
||||
#include <random>
|
||||
#include <string>
|
||||
|
||||
#include "CartesianBenchmarks.h"
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
// *** Localization ***
|
||||
enum class LocalizationE { False, True };
|
||||
struct AllLocalizations : EnumValuesAsTuple<AllLocalizations, LocalizationE, 2> {
|
||||
static constexpr const char* Names[] = {"LocFalse", "LocTrue"};
|
||||
};
|
||||
|
||||
template <LocalizationE E>
|
||||
struct Localization {};
|
||||
|
||||
template <>
|
||||
struct Localization<LocalizationE::False> {
|
||||
static constexpr const char* fmt = "";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Localization<LocalizationE::True> {
|
||||
static constexpr const char* fmt = "L";
|
||||
};
|
||||
|
||||
// *** Types ***
|
||||
enum class TypeE { Float, Double, LongDouble };
|
||||
// TODO FMT Set to 3 after to_chars has long double suport.
|
||||
struct AllTypes : EnumValuesAsTuple<AllTypes, TypeE, 2> {
|
||||
static constexpr const char* Names[] = {"Float", "Double", "LongDouble"};
|
||||
};
|
||||
|
||||
template <TypeE E>
|
||||
struct Type {};
|
||||
|
||||
template <>
|
||||
struct Type<TypeE::Float> {
|
||||
using type = float;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Type<TypeE::Double> {
|
||||
using type = double;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Type<TypeE::LongDouble> {
|
||||
using type = long double;
|
||||
};
|
||||
|
||||
// *** Values ***
|
||||
enum class ValueE { Inf, Random };
|
||||
struct AllValues : EnumValuesAsTuple<AllValues, ValueE, 2> {
|
||||
static constexpr const char* Names[] = {"Inf", "Random"};
|
||||
};
|
||||
|
||||
template <ValueE E>
|
||||
struct Value {};
|
||||
|
||||
template <>
|
||||
struct Value<ValueE::Inf> {
|
||||
template <class F>
|
||||
static std::array<F, 1000> make_data() {
|
||||
std::array<F, 1000> result;
|
||||
std::fill(result.begin(), result.end(), -std::numeric_limits<F>::infinity());
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Value<ValueE::Random> {
|
||||
template <class F>
|
||||
static std::array<F, 1000> make_data() {
|
||||
std::random_device seed;
|
||||
std::mt19937 generator(seed());
|
||||
std::uniform_int_distribution<std::conditional_t<sizeof(F) == sizeof(uint32_t), uint32_t, uint64_t>> distribution;
|
||||
|
||||
std::array<F, 1000> result;
|
||||
std::generate(result.begin(), result.end(), [&] {
|
||||
while (true) {
|
||||
auto result = std::bit_cast<F>(distribution(generator));
|
||||
if (std::isfinite(result))
|
||||
return result;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
// *** Display Type ***
|
||||
enum class DisplayTypeE {
|
||||
Default,
|
||||
Hex,
|
||||
Scientific,
|
||||
Fixed,
|
||||
General,
|
||||
};
|
||||
struct AllDisplayTypes : EnumValuesAsTuple<AllDisplayTypes, DisplayTypeE, 5> {
|
||||
static constexpr const char* Names[] = {"DisplayDefault", "DisplayHex", "DisplayScientific", "DisplayFixed",
|
||||
"DisplayGeneral"};
|
||||
};
|
||||
|
||||
template <DisplayTypeE E>
|
||||
struct DisplayType {};
|
||||
|
||||
template <>
|
||||
struct DisplayType<DisplayTypeE::Default> {
|
||||
static constexpr const char* fmt = "";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct DisplayType<DisplayTypeE::Hex> {
|
||||
static constexpr const char* fmt = "a";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct DisplayType<DisplayTypeE::Scientific> {
|
||||
static constexpr const char* fmt = "e";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct DisplayType<DisplayTypeE::Fixed> {
|
||||
static constexpr const char* fmt = "f";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct DisplayType<DisplayTypeE::General> {
|
||||
static constexpr const char* fmt = "g";
|
||||
};
|
||||
|
||||
// *** Alignment ***
|
||||
enum class AlignmentE { None, Left, Center, Right, ZeroPadding };
|
||||
struct AllAlignments : EnumValuesAsTuple<AllAlignments, AlignmentE, 5> {
|
||||
static constexpr const char* Names[] = {"AlignNone", "AlignmentLeft", "AlignmentCenter", "AlignmentRight",
|
||||
"ZeroPadding"};
|
||||
};
|
||||
|
||||
template <AlignmentE E>
|
||||
struct Alignment {};
|
||||
|
||||
template <>
|
||||
struct Alignment<AlignmentE::None> {
|
||||
static constexpr const char* fmt = "";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Alignment<AlignmentE::Left> {
|
||||
// Width > PrecisionE::Huge
|
||||
static constexpr const char* fmt = "0<17500";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Alignment<AlignmentE::Center> {
|
||||
// Width > PrecisionE::Huge
|
||||
static constexpr const char* fmt = "0^17500";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Alignment<AlignmentE::Right> {
|
||||
// Width > PrecisionE::Huge
|
||||
static constexpr const char* fmt = "0>17500";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Alignment<AlignmentE::ZeroPadding> {
|
||||
// Width > PrecisionE::Huge
|
||||
static constexpr const char* fmt = "017500";
|
||||
};
|
||||
|
||||
enum class PrecisionE { None, Zero, Small, Huge };
|
||||
struct AllPrecisions : EnumValuesAsTuple<AllPrecisions, PrecisionE, 4> {
|
||||
static constexpr const char* Names[] = {"PrecNone", "PrecZero", "PrecSmall", "PrecHuge"};
|
||||
};
|
||||
|
||||
template <PrecisionE E>
|
||||
struct Precision {};
|
||||
|
||||
template <>
|
||||
struct Precision<PrecisionE::None> {
|
||||
static constexpr const char* fmt = "";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Precision<PrecisionE::Zero> {
|
||||
static constexpr const char* fmt = ".0";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Precision<PrecisionE::Small> {
|
||||
static constexpr const char* fmt = ".10";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Precision<PrecisionE::Huge> {
|
||||
// The maximum precision for a minimal sub normal long double is ±0x1p-16494.
|
||||
// This value is always larger than that value forcing the trailing zero path
|
||||
// to be executed.
|
||||
static constexpr const char* fmt = ".17000";
|
||||
};
|
||||
|
||||
template <class L, class DT, class T, class V, class A, class P>
|
||||
struct FloatingPoint {
|
||||
using F = typename Type<T::value>::type;
|
||||
|
||||
void run(benchmark::State& state) const {
|
||||
std::array<F, 1000> data{Value<V::value>::template make_data<F>()};
|
||||
std::array<char, 20'000> output;
|
||||
std::string fmt{std::string("{:") + Alignment<A::value>::fmt + Precision<P::value>::fmt +
|
||||
Localization<L::value>::fmt + DisplayType<DT::value>::fmt + "}"};
|
||||
|
||||
while (state.KeepRunningBatch(1000))
|
||||
for (F value : data)
|
||||
benchmark::DoNotOptimize(std::format_to(output.begin(), fmt, value));
|
||||
}
|
||||
|
||||
std::string name() const {
|
||||
return "FloatingPoint" + L::name() + DT::name() + T::name() + V::name() + A::name() + P::name();
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
benchmark::Initialize(&argc, argv);
|
||||
if (benchmark::ReportUnrecognizedArguments(argc, argv))
|
||||
return 1;
|
||||
|
||||
makeCartesianProductBenchmark<FloatingPoint, AllLocalizations, AllDisplayTypes, AllTypes, AllValues, AllAlignments,
|
||||
AllPrecisions>();
|
||||
|
||||
benchmark::RunSpecifiedBenchmarks();
|
||||
}
|
1037
benchmarks/map.bench.cpp
Normal file
1037
benchmarks/map.bench.cpp
Normal file
File diff suppressed because it is too large
Load Diff
196
benchmarks/std_format_spec_string_unicode.bench.cpp
Normal file
196
benchmarks/std_format_spec_string_unicode.bench.cpp
Normal file
@ -0,0 +1,196 @@
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_UNICODE
|
||||
|
||||
#include <array>
|
||||
#include <format>
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
template <class CharT, size_t N>
|
||||
class tester {
|
||||
static constexpr size_t size_ = N - 1;
|
||||
std::array<CharT, 100 * size_> data_;
|
||||
|
||||
public:
|
||||
explicit constexpr tester(const CharT (&input)[N]) {
|
||||
auto it = data_.begin();
|
||||
for (int i = 0; i < 100; ++i)
|
||||
it = std::copy_n(input, size_, it);
|
||||
}
|
||||
|
||||
constexpr size_t size() const noexcept { return data_.size(); }
|
||||
constexpr const CharT* begin() const noexcept { return data_.begin(); }
|
||||
constexpr const CharT* end() const noexcept { return data_.end(); }
|
||||
|
||||
void test(benchmark::State& state) const {
|
||||
for (auto _ : state)
|
||||
benchmark::DoNotOptimize(std::__format_spec::__get_string_alignment(
|
||||
begin(), end(), 1'000'000, 1'000'000));
|
||||
state.SetItemsProcessed(state.iterations() * size());
|
||||
}
|
||||
};
|
||||
|
||||
#define TEST(u8) \
|
||||
if constexpr (std::same_as<CharT, char>) { \
|
||||
constexpr auto p = tester{u8}; \
|
||||
p.test(state); \
|
||||
} else if constexpr (std::same_as<CharT, char16_t>) { \
|
||||
constexpr auto p = tester{TEST_CONCAT(u, u8)}; \
|
||||
p.test(state); \
|
||||
} else { \
|
||||
constexpr auto p = tester{TEST_CONCAT(U, u8)}; \
|
||||
p.test(state); \
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
static void BM_EstimateLengthNoMultiByte(benchmark::State& state) {
|
||||
TEST("The quick brown fox jumps over the lazy dog");
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
static void BM_EstimateLengthTwoByteDE(benchmark::State& state) {
|
||||
static_assert(sizeof("Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich") == 67);
|
||||
|
||||
// https://en.wikipedia.org/wiki/Pangram
|
||||
TEST("Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich");
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
static void BM_EstimateLengthTwoBytePL(benchmark::State& state) {
|
||||
static_assert(sizeof("Stróż pchnął kość w quiz gędźb vel fax myjń") == 53);
|
||||
|
||||
// https://en.wikipedia.org/wiki/Pangram
|
||||
TEST("Stróż pchnął kość w quiz gędźb vel fax myjń");
|
||||
}
|
||||
|
||||
// All values below are 1100, which is is the first multi column sequence.
|
||||
template <class CharT>
|
||||
static void BM_EstimateLengthThreeByteSingleColumnLow(benchmark::State& state) {
|
||||
static_assert(sizeof("\u0800\u0801\u0802\u0803\u0804\u0805\u0806\u0807"
|
||||
"\u0808\u0809\u080a\u080b\u080c\u080d\u080e\u080f") ==
|
||||
49);
|
||||
|
||||
TEST("\u0800\u0801\u0802\u0803\u0804\u0805\u0806\u0807"
|
||||
"\u0808\u0809\u080a\u080b\u080c\u080d\u080e\u080f");
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
static void
|
||||
BM_EstimateLengthThreeByteSingleColumnHigh(benchmark::State& state) {
|
||||
static_assert(sizeof("\u1800\u1801\u1802\u1803\u1804\u1805\u1806\u1807"
|
||||
"\u1808\u1809\u180a\u180b\u180c\u180d\u180e\u180f") ==
|
||||
49);
|
||||
|
||||
TEST("\u1800\u1801\u1802\u1803\u1804\u1805\u1806\u1807"
|
||||
"\u1808\u1809\u180a\u180b\u180c\u180d\u180e\u180f");
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
static void BM_EstimateLengthThreeByteDoubleColumn(benchmark::State& state) {
|
||||
static_assert(sizeof("\u1100\u0801\u0802\u0803\u0804\u0805\u0806\u0807"
|
||||
"\u1108\u0809\u080a\u080b\u080c\u080d\u080e\u080f") ==
|
||||
49);
|
||||
|
||||
TEST("\u1100\u0801\u0802\u0803\u0804\u0805\u0806\u0807"
|
||||
"\u1108\u0809\u080a\u080b\u080c\u080d\u080e\u080f");
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
static void BM_EstimateLengthThreeByte(benchmark::State& state) {
|
||||
static_assert(sizeof("\u1400\u1501\ubbbb\uff00\u0800\u4099\uabcd\u4000"
|
||||
"\u8ead\ubeef\u1111\u4987\u4321\uffff\u357a\ud50e") ==
|
||||
49);
|
||||
|
||||
TEST("\u1400\u1501\ubbbb\uff00\u0800\u4099\uabcd\u4000"
|
||||
"\u8ead\ubeef\u1111\u4987\u4321\uffff\u357a\ud50e");
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
static void BM_EstimateLengthFourByteSingleColumn(benchmark::State& state) {
|
||||
static_assert(sizeof("\U00010000\U00010001\U00010002\U00010003"
|
||||
"\U00010004\U00010005\U00010006\U00010007"
|
||||
"\U00010008\U00010009\U0001000a\U0001000b"
|
||||
"\U0001000c\U0001000d\U0001000e\U0001000f") == 65);
|
||||
|
||||
TEST("\U00010000\U00010001\U00010002\U00010003"
|
||||
"\U00010004\U00010005\U00010006\U00010007"
|
||||
"\U00010008\U00010009\U0001000a\U0001000b"
|
||||
"\U0001000c\U0001000d\U0001000e\U0001000f");
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
static void BM_EstimateLengthFourByteDoubleColumn(benchmark::State& state) {
|
||||
static_assert(sizeof("\U00020000\U00020002\U00020002\U00020003"
|
||||
"\U00020004\U00020005\U00020006\U00020007"
|
||||
"\U00020008\U00020009\U0002000a\U0002000b"
|
||||
"\U0002000c\U0002000d\U0002000e\U0002000f") == 65);
|
||||
|
||||
TEST("\U00020000\U00020002\U00020002\U00020003"
|
||||
"\U00020004\U00020005\U00020006\U00020007"
|
||||
"\U00020008\U00020009\U0002000a\U0002000b"
|
||||
"\U0002000c\U0002000d\U0002000e\U0002000f");
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
static void BM_EstimateLengthFourByte(benchmark::State& state) {
|
||||
static_assert(sizeof("\U00010000\U00010001\U00010002\U00010003"
|
||||
"\U00020004\U00020005\U00020006\U00020007"
|
||||
"\U00010008\U00010009\U0001000a\U0001000b"
|
||||
"\U0002000c\U0002000d\U0002000e\U0002000f") == 65);
|
||||
|
||||
TEST("\U00010000\U00010001\U00010002\U00010003"
|
||||
"\U00020004\U00020005\U00020006\U00020007"
|
||||
"\U00010008\U00010009\U0001000a\U0001000b"
|
||||
"\U0002000c\U0002000d\U0002000e\U0002000f");
|
||||
}
|
||||
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthNoMultiByte, char);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthTwoByteDE, char);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthTwoBytePL, char);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteSingleColumnLow, char);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteSingleColumnHigh, char);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteDoubleColumn, char);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByte, char);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthFourByteSingleColumn, char);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthFourByteDoubleColumn, char);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthFourByte, char);
|
||||
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthNoMultiByte, char16_t);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthTwoByteDE, char16_t);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthTwoBytePL, char16_t);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteSingleColumnLow, char16_t);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteSingleColumnHigh, char16_t);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteDoubleColumn, char16_t);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByte, char16_t);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthFourByteSingleColumn, char16_t);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthFourByteDoubleColumn, char16_t);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthFourByte, char16_t);
|
||||
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthNoMultiByte, char32_t);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthTwoByteDE, char32_t);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthTwoBytePL, char32_t);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteSingleColumnLow, char32_t);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteSingleColumnHigh, char32_t);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteDoubleColumn, char32_t);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByte, char32_t);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthFourByteSingleColumn, char32_t);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthFourByteDoubleColumn, char32_t);
|
||||
BENCHMARK_TEMPLATE(BM_EstimateLengthFourByte, char32_t);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
benchmark::Initialize(&argc, argv);
|
||||
if (benchmark::ReportUnrecognizedArguments(argc, argv))
|
||||
return 1;
|
||||
|
||||
benchmark::RunSpecifiedBenchmarks();
|
||||
}
|
||||
#else
|
||||
int main(int, char**) { return 0; }
|
||||
#endif
|
@ -124,6 +124,20 @@ TEST_ALWAYS_INLINE const char* getHugeString(DiffType D) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_ALWAYS_INLINE const char* getString(Length L,
|
||||
DiffType D = DiffType::Control) {
|
||||
switch (L) {
|
||||
case Length::Empty:
|
||||
return "";
|
||||
case Length::Small:
|
||||
return getSmallString(D);
|
||||
case Length::Large:
|
||||
return getLargeString(D);
|
||||
case Length::Huge:
|
||||
return getHugeString(D);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_ALWAYS_INLINE std::string makeString(Length L,
|
||||
DiffType D = DiffType::Control,
|
||||
Opacity O = Opacity::Transparent) {
|
||||
@ -220,6 +234,164 @@ struct StringMove {
|
||||
static std::string name() { return "BM_StringMove" + Length::name(); }
|
||||
};
|
||||
|
||||
template <class Length, class Opaque>
|
||||
struct StringResizeDefaultInit {
|
||||
static void run(benchmark::State& state) {
|
||||
constexpr bool opaque = Opaque{} == Opacity::Opaque;
|
||||
constexpr int kNumStrings = 4 << 10;
|
||||
size_t length = makeString(Length()).size();
|
||||
std::string strings[kNumStrings];
|
||||
while (state.KeepRunningBatch(kNumStrings)) {
|
||||
state.PauseTiming();
|
||||
for (int i = 0; i < kNumStrings; ++i) {
|
||||
std::string().swap(strings[i]);
|
||||
}
|
||||
benchmark::DoNotOptimize(strings);
|
||||
state.ResumeTiming();
|
||||
for (int i = 0; i < kNumStrings; ++i) {
|
||||
strings[i].__resize_default_init(maybeOpaque(length, opaque));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static std::string name() {
|
||||
return "BM_StringResizeDefaultInit" + Length::name() + Opaque::name();
|
||||
}
|
||||
};
|
||||
|
||||
template <class Length, class Opaque>
|
||||
struct StringAssignStr {
|
||||
static void run(benchmark::State& state) {
|
||||
constexpr bool opaque = Opaque{} == Opacity::Opaque;
|
||||
constexpr int kNumStrings = 4 << 10;
|
||||
std::string src = makeString(Length());
|
||||
std::string strings[kNumStrings];
|
||||
while (state.KeepRunningBatch(kNumStrings)) {
|
||||
state.PauseTiming();
|
||||
for (int i = 0; i < kNumStrings; ++i) {
|
||||
std::string().swap(strings[i]);
|
||||
}
|
||||
benchmark::DoNotOptimize(strings);
|
||||
state.ResumeTiming();
|
||||
for (int i = 0; i < kNumStrings; ++i) {
|
||||
strings[i] = *maybeOpaque(&src, opaque);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static std::string name() {
|
||||
return "BM_StringAssignStr" + Length::name() + Opaque::name();
|
||||
}
|
||||
};
|
||||
|
||||
template <class Length, class Opaque>
|
||||
struct StringAssignAsciiz {
|
||||
static void run(benchmark::State& state) {
|
||||
constexpr bool opaque = Opaque{} == Opacity::Opaque;
|
||||
constexpr int kNumStrings = 4 << 10;
|
||||
std::string strings[kNumStrings];
|
||||
while (state.KeepRunningBatch(kNumStrings)) {
|
||||
state.PauseTiming();
|
||||
for (int i = 0; i < kNumStrings; ++i) {
|
||||
std::string().swap(strings[i]);
|
||||
}
|
||||
benchmark::DoNotOptimize(strings);
|
||||
state.ResumeTiming();
|
||||
for (int i = 0; i < kNumStrings; ++i) {
|
||||
strings[i] = maybeOpaque(getString(Length()), opaque);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static std::string name() {
|
||||
return "BM_StringAssignAsciiz" + Length::name() + Opaque::name();
|
||||
}
|
||||
};
|
||||
|
||||
template <class Length, class Opaque>
|
||||
struct StringEraseToEnd {
|
||||
static void run(benchmark::State& state) {
|
||||
constexpr bool opaque = Opaque{} == Opacity::Opaque;
|
||||
constexpr int kNumStrings = 4 << 10;
|
||||
std::string strings[kNumStrings];
|
||||
const int mid = makeString(Length()).size() / 2;
|
||||
while (state.KeepRunningBatch(kNumStrings)) {
|
||||
state.PauseTiming();
|
||||
for (int i = 0; i < kNumStrings; ++i) {
|
||||
strings[i] = makeString(Length());
|
||||
}
|
||||
benchmark::DoNotOptimize(strings);
|
||||
state.ResumeTiming();
|
||||
for (int i = 0; i < kNumStrings; ++i) {
|
||||
strings[i].erase(maybeOpaque(mid, opaque),
|
||||
maybeOpaque(std::string::npos, opaque));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static std::string name() {
|
||||
return "BM_StringEraseToEnd" + Length::name() + Opaque::name();
|
||||
}
|
||||
};
|
||||
|
||||
template <class Length, class Opaque>
|
||||
struct StringEraseWithMove {
|
||||
static void run(benchmark::State& state) {
|
||||
constexpr bool opaque = Opaque{} == Opacity::Opaque;
|
||||
constexpr int kNumStrings = 4 << 10;
|
||||
std::string strings[kNumStrings];
|
||||
const int n = makeString(Length()).size() / 2;
|
||||
const int pos = n / 2;
|
||||
while (state.KeepRunningBatch(kNumStrings)) {
|
||||
state.PauseTiming();
|
||||
for (int i = 0; i < kNumStrings; ++i) {
|
||||
strings[i] = makeString(Length());
|
||||
}
|
||||
benchmark::DoNotOptimize(strings);
|
||||
state.ResumeTiming();
|
||||
for (int i = 0; i < kNumStrings; ++i) {
|
||||
strings[i].erase(maybeOpaque(pos, opaque), maybeOpaque(n, opaque));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static std::string name() {
|
||||
return "BM_StringEraseWithMove" + Length::name() + Opaque::name();
|
||||
}
|
||||
};
|
||||
|
||||
template <class Opaque>
|
||||
struct StringAssignAsciizMix {
|
||||
static void run(benchmark::State& state) {
|
||||
constexpr auto O = Opaque{};
|
||||
constexpr auto D = DiffType::Control;
|
||||
constexpr int kNumStrings = 4 << 10;
|
||||
std::string strings[kNumStrings];
|
||||
while (state.KeepRunningBatch(kNumStrings)) {
|
||||
state.PauseTiming();
|
||||
for (int i = 0; i < kNumStrings; ++i) {
|
||||
std::string().swap(strings[i]);
|
||||
}
|
||||
benchmark::DoNotOptimize(strings);
|
||||
state.ResumeTiming();
|
||||
for (int i = 0; i < kNumStrings - 7; i += 8) {
|
||||
strings[i + 0] = maybeOpaque(getSmallString(D), O == Opacity::Opaque);
|
||||
strings[i + 1] = maybeOpaque(getSmallString(D), O == Opacity::Opaque);
|
||||
strings[i + 2] = maybeOpaque(getLargeString(D), O == Opacity::Opaque);
|
||||
strings[i + 3] = maybeOpaque(getSmallString(D), O == Opacity::Opaque);
|
||||
strings[i + 4] = maybeOpaque(getSmallString(D), O == Opacity::Opaque);
|
||||
strings[i + 5] = maybeOpaque(getSmallString(D), O == Opacity::Opaque);
|
||||
strings[i + 6] = maybeOpaque(getLargeString(D), O == Opacity::Opaque);
|
||||
strings[i + 7] = maybeOpaque(getSmallString(D), O == Opacity::Opaque);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static std::string name() {
|
||||
return "BM_StringAssignAsciizMix" + Opaque::name();
|
||||
}
|
||||
};
|
||||
|
||||
enum class Relation { Eq, Less, Compare };
|
||||
struct AllRelations : EnumValuesAsTuple<AllRelations, Relation, 3> {
|
||||
static constexpr const char* Names[] = {"Eq", "Less", "Compare"};
|
||||
@ -426,9 +598,18 @@ int main(int argc, char** argv) {
|
||||
|
||||
makeCartesianProductBenchmark<StringConstructDestroyCStr, AllLengths,
|
||||
AllOpacity>();
|
||||
|
||||
makeCartesianProductBenchmark<StringAssignStr, AllLengths, AllOpacity>();
|
||||
makeCartesianProductBenchmark<StringAssignAsciiz, AllLengths, AllOpacity>();
|
||||
makeCartesianProductBenchmark<StringAssignAsciizMix, AllOpacity>();
|
||||
|
||||
makeCartesianProductBenchmark<StringCopy, AllLengths>();
|
||||
makeCartesianProductBenchmark<StringMove, AllLengths>();
|
||||
makeCartesianProductBenchmark<StringDestroy, AllLengths>();
|
||||
makeCartesianProductBenchmark<StringResizeDefaultInit, AllLengths,
|
||||
AllOpacity>();
|
||||
makeCartesianProductBenchmark<StringEraseToEnd, AllLengths, AllOpacity>();
|
||||
makeCartesianProductBenchmark<StringEraseWithMove, AllLengths, AllOpacity>();
|
||||
makeCartesianProductBenchmark<StringRelational, AllRelations, AllLengths,
|
||||
AllLengths, AllDiffTypes>();
|
||||
makeCartesianProductBenchmark<StringRelationalLiteral, AllRelations,
|
||||
|
58
benchmarks/to_chars.bench.cpp
Normal file
58
benchmarks/to_chars.bench.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <array>
|
||||
#include <charconv>
|
||||
#include <random>
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
#include "test_macros.h"
|
||||
|
||||
static const std::array<unsigned, 1000> input = [] {
|
||||
std::mt19937 generator;
|
||||
std::uniform_int_distribution<unsigned> distribution(0, std::numeric_limits<unsigned>::max());
|
||||
std::array<unsigned, 1000> result;
|
||||
std::generate_n(result.begin(), result.size(), [&] { return distribution(generator); });
|
||||
return result;
|
||||
}();
|
||||
|
||||
static void BM_to_chars_good(benchmark::State& state) {
|
||||
char buffer[128];
|
||||
int base = state.range(0);
|
||||
while (state.KeepRunningBatch(input.size()))
|
||||
for (auto value : input)
|
||||
benchmark::DoNotOptimize(std::to_chars(buffer, &buffer[128], value, base));
|
||||
}
|
||||
BENCHMARK(BM_to_chars_good)->DenseRange(2, 36, 1);
|
||||
|
||||
static void BM_to_chars_bad(benchmark::State& state) {
|
||||
char buffer[128];
|
||||
int base = state.range(0);
|
||||
struct sample {
|
||||
unsigned size;
|
||||
unsigned value;
|
||||
};
|
||||
std::array<sample, 1000> data;
|
||||
// Assume the failure occurs, on average, halfway during the conversion.
|
||||
std::transform(input.begin(), input.end(), data.begin(), [&](unsigned value) {
|
||||
std::to_chars_result result = std::to_chars(buffer, &buffer[128], value, base);
|
||||
return sample{unsigned((result.ptr - buffer) / 2), value};
|
||||
});
|
||||
|
||||
while (state.KeepRunningBatch(data.size()))
|
||||
for (auto element : data)
|
||||
benchmark::DoNotOptimize(std::to_chars(buffer, &buffer[element.size], element.value, base));
|
||||
}
|
||||
BENCHMARK(BM_to_chars_bad)->DenseRange(2, 36, 1);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
benchmark::Initialize(&argc, argv);
|
||||
if (benchmark::ReportUnrecognizedArguments(argc, argv))
|
||||
return 1;
|
||||
|
||||
benchmark::RunSpecifiedBenchmarks();
|
||||
}
|
@ -148,7 +148,7 @@ BENCHMARK_CAPTURE(BM_Hash,
|
||||
// ---------------------------------------------------------------------------//
|
||||
|
||||
|
||||
// Sorted Assending //
|
||||
// Sorted Ascending //
|
||||
BENCHMARK_CAPTURE(BM_InsertValue,
|
||||
unordered_set_uint32,
|
||||
std::unordered_set<uint32_t>{},
|
||||
@ -159,7 +159,7 @@ BENCHMARK_CAPTURE(BM_InsertValue,
|
||||
std::unordered_set<uint32_t>{},
|
||||
getSortedIntegerInputs<uint32_t>)->Arg(TestNumInputs);
|
||||
|
||||
// Top Bytes //
|
||||
// Top Bytes //
|
||||
BENCHMARK_CAPTURE(BM_InsertValue,
|
||||
unordered_set_top_bits_uint32,
|
||||
std::unordered_set<uint32_t>{},
|
||||
|
27
benchmarks/variant_visit_1.bench.cpp
Normal file
27
benchmarks/variant_visit_1.bench.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
#include "VariantBenchmarks.h"
|
||||
|
||||
using namespace VariantBenchmarks;
|
||||
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 1, 1);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 1, 2);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 1, 3);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 1, 4);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 1, 5);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 1, 6);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 1, 7);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 1, 8);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 1, 9);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 1, 10);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 1, 20);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 1, 30);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 1, 40);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 1, 50);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 1, 60);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 1, 70);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 1, 80);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 1, 90);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 1, 100);
|
||||
|
||||
BENCHMARK_MAIN();
|
22
benchmarks/variant_visit_2.bench.cpp
Normal file
22
benchmarks/variant_visit_2.bench.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
#include "VariantBenchmarks.h"
|
||||
|
||||
using namespace VariantBenchmarks;
|
||||
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 2, 1);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 2, 2);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 2, 3);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 2, 4);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 2, 5);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 2, 6);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 2, 7);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 2, 8);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 2, 9);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 2, 10);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 2, 20);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 2, 30);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 2, 40);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 2, 50);
|
||||
|
||||
BENCHMARK_MAIN();
|
20
benchmarks/variant_visit_3.bench.cpp
Normal file
20
benchmarks/variant_visit_3.bench.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
#include "VariantBenchmarks.h"
|
||||
|
||||
using namespace VariantBenchmarks;
|
||||
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 3, 1);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 3, 2);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 3, 3);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 3, 4);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 3, 5);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 3, 6);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 3, 7);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 3, 8);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 3, 9);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 3, 10);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 3, 15);
|
||||
BENCHMARK_TEMPLATE(BM_Visit, 3, 20);
|
||||
|
||||
BENCHMARK_MAIN();
|
@ -1,56 +0,0 @@
|
||||
INCLUDE(CheckCXXSourceCompiles)
|
||||
|
||||
# Sometimes linking against libatomic is required for atomic ops, if
|
||||
# the platform doesn't support lock-free atomics.
|
||||
#
|
||||
# We could modify LLVM's CheckAtomic module and have it check for 64-bit
|
||||
# atomics instead. However, we would like to avoid careless uses of 64-bit
|
||||
# atomics inside LLVM over time on 32-bit platforms.
|
||||
|
||||
function(check_cxx_atomics varname)
|
||||
set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nodefaultlibs -std=c++11 -nostdinc++ -isystem ${LIBCXX_SOURCE_DIR}/include")
|
||||
if (${LIBCXX_GCC_TOOLCHAIN})
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} --gcc-toolchain=${LIBCXX_GCC_TOOLCHAIN}")
|
||||
endif()
|
||||
if (CMAKE_C_FLAGS MATCHES -fsanitize OR CMAKE_CXX_FLAGS MATCHES -fsanitize)
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize=all")
|
||||
endif()
|
||||
if (CMAKE_C_FLAGS MATCHES -fsanitize-coverage OR CMAKE_CXX_FLAGS MATCHES -fsanitize-coverage)
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters")
|
||||
endif()
|
||||
check_cxx_source_compiles("
|
||||
#include <cstdint>
|
||||
#include <atomic>
|
||||
std::atomic<uintptr_t> x;
|
||||
std::atomic<uintmax_t> y;
|
||||
int main(int, char**) {
|
||||
return x + y;
|
||||
}
|
||||
" ${varname})
|
||||
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
|
||||
endfunction(check_cxx_atomics)
|
||||
|
||||
# Perform the check for 64bit atomics without libatomic. It may have been
|
||||
# added to the required libraries during in the configuration of LLVM, which
|
||||
# would cause the check for CXX atomics without libatomic to incorrectly pass.
|
||||
if (CMAKE_REQUIRED_LIBRARIES)
|
||||
set(OLD_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
|
||||
list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES "atomic")
|
||||
check_cxx_atomics(LIBCXX_HAVE_CXX_ATOMICS_WITHOUT_LIB)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OLD_CMAKE_REQUIRED_LIBRARIES})
|
||||
endif()
|
||||
|
||||
check_library_exists(atomic __atomic_fetch_add_8 "" LIBCXX_HAS_ATOMIC_LIB)
|
||||
# If not, check if the library exists, and atomics work with it.
|
||||
if(NOT LIBCXX_HAVE_CXX_ATOMICS_WITHOUT_LIB)
|
||||
if(LIBCXX_HAS_ATOMIC_LIB)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
|
||||
check_cxx_atomics(LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB)
|
||||
if (NOT LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB)
|
||||
message(WARNING "Host compiler must support std::atomic!")
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "Host compiler appears to require libatomic, but cannot find it.")
|
||||
endif()
|
||||
endif()
|
@ -31,13 +31,17 @@ function(define_linker_script target)
|
||||
set(link_libraries)
|
||||
if (interface_libs)
|
||||
foreach(lib IN LISTS interface_libs)
|
||||
if (TARGET "${lib}" OR
|
||||
(${lib} MATCHES "cxxabi(_static|_shared)?" AND HAVE_LIBCXXABI) OR
|
||||
(${lib} MATCHES "unwind(_static|_shared)?" AND HAVE_LIBUNWIND))
|
||||
list(APPEND link_libraries "${CMAKE_LINK_LIBRARY_FLAG}$<TARGET_PROPERTY:${lib},OUTPUT_NAME>")
|
||||
else()
|
||||
list(APPEND link_libraries "${CMAKE_LINK_LIBRARY_FLAG}${lib}")
|
||||
if ("${lib}" MATCHES "cxx-headers|ParallelSTL")
|
||||
continue()
|
||||
endif()
|
||||
# If ${lib} is not a target, we use a dummy target which we know will
|
||||
# have an OUTPUT_NAME property so that CMake doesn't fail when evaluating
|
||||
# the non-selected branch of the `IF`. It doesn't matter what it evaluates
|
||||
# to because it's not selected, but it must not cause an error.
|
||||
# See https://gitlab.kitware.com/cmake/cmake/-/issues/21045.
|
||||
set(output_name_tgt "$<IF:$<TARGET_EXISTS:${lib}>,${lib},${target}>")
|
||||
set(libname "$<IF:$<TARGET_EXISTS:${lib}>,$<TARGET_PROPERTY:${output_name_tgt},OUTPUT_NAME>,${lib}>")
|
||||
list(APPEND link_libraries "${CMAKE_LINK_LIBRARY_FLAG}${libname}")
|
||||
endforeach()
|
||||
endif()
|
||||
string(REPLACE ";" " " link_libraries "${link_libraries}")
|
||||
|
@ -1,64 +0,0 @@
|
||||
function(find_compiler_rt_library name dest)
|
||||
if (NOT DEFINED LIBCXX_COMPILE_FLAGS)
|
||||
message(FATAL_ERROR "LIBCXX_COMPILE_FLAGS must be defined when using this function")
|
||||
endif()
|
||||
set(dest "" PARENT_SCOPE)
|
||||
set(CLANG_COMMAND ${CMAKE_CXX_COMPILER} ${LIBCXX_COMPILE_FLAGS}
|
||||
"--rtlib=compiler-rt" "--print-libgcc-file-name")
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES Clang AND CMAKE_CXX_COMPILER_TARGET)
|
||||
list(APPEND CLANG_COMMAND "--target=${CMAKE_CXX_COMPILER_TARGET}")
|
||||
endif()
|
||||
get_property(LIBCXX_CXX_FLAGS CACHE CMAKE_CXX_FLAGS PROPERTY VALUE)
|
||||
string(REPLACE " " ";" LIBCXX_CXX_FLAGS "${LIBCXX_CXX_FLAGS}")
|
||||
list(APPEND CLANG_COMMAND ${LIBCXX_CXX_FLAGS})
|
||||
execute_process(
|
||||
COMMAND ${CLANG_COMMAND}
|
||||
RESULT_VARIABLE HAD_ERROR
|
||||
OUTPUT_VARIABLE LIBRARY_FILE
|
||||
)
|
||||
string(STRIP "${LIBRARY_FILE}" LIBRARY_FILE)
|
||||
file(TO_CMAKE_PATH "${LIBRARY_FILE}" LIBRARY_FILE)
|
||||
string(REPLACE "builtins" "${name}" LIBRARY_FILE "${LIBRARY_FILE}")
|
||||
if (NOT HAD_ERROR AND EXISTS "${LIBRARY_FILE}")
|
||||
message(STATUS "Found compiler-rt library: ${LIBRARY_FILE}")
|
||||
set(${dest} "${LIBRARY_FILE}" PARENT_SCOPE)
|
||||
else()
|
||||
message(STATUS "Failed to find compiler-rt library")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(find_compiler_rt_dir dest)
|
||||
if (NOT DEFINED LIBCXX_COMPILE_FLAGS)
|
||||
message(FATAL_ERROR "LIBCXX_COMPILE_FLAGS must be defined when using this function")
|
||||
endif()
|
||||
set(dest "" PARENT_SCOPE)
|
||||
if (APPLE)
|
||||
set(CLANG_COMMAND ${CMAKE_CXX_COMPILER} ${LIBCXX_COMPILE_FLAGS}
|
||||
"-print-file-name=lib")
|
||||
execute_process(
|
||||
COMMAND ${CLANG_COMMAND}
|
||||
RESULT_VARIABLE HAD_ERROR
|
||||
OUTPUT_VARIABLE LIBRARY_DIR
|
||||
)
|
||||
string(STRIP "${LIBRARY_DIR}" LIBRARY_DIR)
|
||||
file(TO_CMAKE_PATH "${LIBRARY_DIR}" LIBRARY_DIR)
|
||||
set(LIBRARY_DIR "${LIBRARY_DIR}/darwin")
|
||||
else()
|
||||
set(CLANG_COMMAND ${CMAKE_CXX_COMPILER} ${LIBCXX_COMPILE_FLAGS}
|
||||
"--rtlib=compiler-rt" "--print-libgcc-file-name")
|
||||
execute_process(
|
||||
COMMAND ${CLANG_COMMAND}
|
||||
RESULT_VARIABLE HAD_ERROR
|
||||
OUTPUT_VARIABLE LIBRARY_FILE
|
||||
)
|
||||
string(STRIP "${LIBRARY_FILE}" LIBRARY_FILE)
|
||||
file(TO_CMAKE_PATH "${LIBRARY_FILE}" LIBRARY_FILE)
|
||||
get_filename_component(LIBRARY_DIR "${LIBRARY_FILE}" DIRECTORY)
|
||||
endif()
|
||||
if (NOT HAD_ERROR AND EXISTS "${LIBRARY_DIR}")
|
||||
message(STATUS "Found compiler-rt directory: ${LIBRARY_DIR}")
|
||||
set(${dest} "${LIBRARY_DIR}" PARENT_SCOPE)
|
||||
else()
|
||||
message(STATUS "Failed to find compiler-rt directory")
|
||||
endif()
|
||||
endfunction()
|
@ -1,8 +1,9 @@
|
||||
|
||||
#===============================================================================
|
||||
# Add an ABI library if appropriate
|
||||
#===============================================================================
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
#
|
||||
# _setup_abi: Set up the build to use an ABI library
|
||||
#
|
||||
@ -37,8 +38,10 @@ macro(setup_abi_lib abidefines abishared abistatic abifiles abidirs)
|
||||
foreach(fpath ${LIBCXX_ABILIB_FILES})
|
||||
set(found FALSE)
|
||||
foreach(incpath ${LIBCXX_CXX_ABI_INCLUDE_PATHS})
|
||||
message(STATUS "Looking for ${fpath} in ${incpath}")
|
||||
if (EXISTS "${incpath}/${fpath}")
|
||||
set(found TRUE)
|
||||
message(STATUS "Looking for ${fpath} in ${incpath} - found")
|
||||
get_filename_component(dstdir ${fpath} PATH)
|
||||
get_filename_component(ifile ${fpath} NAME)
|
||||
set(src ${incpath}/${fpath})
|
||||
@ -50,26 +53,28 @@ macro(setup_abi_lib abidefines abishared abistatic abifiles abidirs)
|
||||
COMMENT "Copying C++ ABI header ${fpath}...")
|
||||
list(APPEND abilib_headers "${dst}")
|
||||
|
||||
if (NOT LIBCXX_USING_INSTALLED_LLVM AND LIBCXX_HEADER_DIR)
|
||||
set(dst "${LIBCXX_HEADER_DIR}/include/c++/v1/${dstdir}/${fpath}")
|
||||
add_custom_command(OUTPUT ${dst}
|
||||
DEPENDS ${src}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
|
||||
COMMENT "Copying C++ ABI header ${fpath}...")
|
||||
list(APPEND abilib_headers "${dst}")
|
||||
endif()
|
||||
# TODO: libc++ shouldn't be responsible for copying the libc++abi
|
||||
# headers into the right location.
|
||||
set(dst "${LIBCXX_GENERATED_INCLUDE_DIR}/${dstdir}/${fpath}")
|
||||
add_custom_command(OUTPUT ${dst}
|
||||
DEPENDS ${src}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
|
||||
COMMENT "Copying C++ ABI header ${fpath}...")
|
||||
list(APPEND abilib_headers "${dst}")
|
||||
|
||||
if (LIBCXX_INSTALL_HEADERS)
|
||||
install(FILES "${LIBCXX_BINARY_INCLUDE_DIR}/${fpath}"
|
||||
DESTINATION ${LIBCXX_INSTALL_HEADER_PREFIX}include/c++/v1/${dstdir}
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/c++/v1/${dstdir}"
|
||||
COMPONENT cxx-headers
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
|
||||
)
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Looking for ${fpath} in ${incpath} - not found")
|
||||
endif()
|
||||
endforeach()
|
||||
if (NOT found)
|
||||
message(WARNING "Failed to find ${fpath}")
|
||||
message(WARNING "Failed to find ${fpath} in ${LIBCXX_CXX_ABI_INCLUDE_PATHS}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
@ -98,34 +103,41 @@ if ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libstdc++" OR
|
||||
"${_LIBSUPCXX_LIBNAME}" "${_LIBSUPCXX_LIBNAME}" "${_LIBSUPCXX_INCLUDE_FILES}" "bits"
|
||||
)
|
||||
elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libcxxabi")
|
||||
if (LIBCXX_CXX_ABI_INTREE)
|
||||
# Link against just-built "cxxabi" target.
|
||||
set(CXXABI_SHARED_LIBNAME cxxabi_shared)
|
||||
set(CXXABI_STATIC_LIBNAME cxxabi_static)
|
||||
else()
|
||||
# Assume c++abi is installed in the system, rely on -lc++abi link flag.
|
||||
set(CXXABI_SHARED_LIBNAME "c++abi")
|
||||
set(CXXABI_STATIC_LIBNAME "c++abi")
|
||||
if(NOT LIBCXX_CXX_ABI_INCLUDE_PATHS)
|
||||
set(LIBCXX_CXX_ABI_INCLUDE_PATHS "${LIBCXX_SOURCE_DIR}/../libcxxabi/include")
|
||||
endif()
|
||||
if (LIBCXX_CXX_ABI_SYSTEM)
|
||||
set(HEADERS "")
|
||||
|
||||
if(LIBCXX_STANDALONE_BUILD AND NOT (LIBCXX_CXX_ABI_INTREE OR HAVE_LIBCXXABI))
|
||||
set(shared c++abi)
|
||||
set(static c++abi)
|
||||
else()
|
||||
set(HEADERS "cxxabi.h;__cxxabi_config.h")
|
||||
set(shared cxxabi_shared)
|
||||
set(static cxxabi_static)
|
||||
endif()
|
||||
|
||||
setup_abi_lib(
|
||||
"-DLIBCXX_BUILDING_LIBCXXABI"
|
||||
"${CXXABI_SHARED_LIBNAME}" "${CXXABI_STATIC_LIBNAME}" "${HEADERS}" "")
|
||||
"${shared}" "${static}" "cxxabi.h;__cxxabi_config.h" "")
|
||||
elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "system-libcxxabi")
|
||||
setup_abi_lib(
|
||||
"-DLIBCXX_BUILDING_LIBCXXABI"
|
||||
"c++abi" "c++abi" "cxxabi.h;__cxxabi_config.h" "")
|
||||
elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libcxxrt")
|
||||
if(NOT LIBCXX_CXX_ABI_INCLUDE_PATHS)
|
||||
set(LIBCXX_CXX_ABI_INCLUDE_PATHS "/usr/include/c++/v1")
|
||||
endif()
|
||||
# libcxxrt does not provide aligned new and delete operators
|
||||
set(LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS ON)
|
||||
setup_abi_lib(
|
||||
"-DLIBCXXRT"
|
||||
"cxxrt" "cxxrt" "cxxabi.h;unwind.h;unwind-arm.h;unwind-itanium.h" ""
|
||||
)
|
||||
elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "vcruntime")
|
||||
# Nothing TODO
|
||||
# Nothing to do
|
||||
elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "none")
|
||||
list(APPEND LIBCXX_COMPILE_FLAGS "-D_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY")
|
||||
elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "default")
|
||||
# Nothing TODO
|
||||
# Nothing to do
|
||||
else()
|
||||
message(FATAL_ERROR
|
||||
"Unsupported c++ abi: '${LIBCXX_CXX_ABI_LIBNAME}'. \
|
||||
|
@ -88,20 +88,17 @@ endmacro()
|
||||
macro(config_define_if condition def)
|
||||
if (${condition})
|
||||
set(${def} ON)
|
||||
set(LIBCXX_NEEDS_SITE_CONFIG ON)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(config_define_if_not condition def)
|
||||
if (NOT ${condition})
|
||||
set(${def} ON)
|
||||
set(LIBCXX_NEEDS_SITE_CONFIG ON)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(config_define value def)
|
||||
set(${def} ${value})
|
||||
set(LIBCXX_NEEDS_SITE_CONFIG ON)
|
||||
endmacro()
|
||||
|
||||
# Add a list of flags to all of 'CMAKE_CXX_FLAGS', 'CMAKE_C_FLAGS',
|
||||
@ -124,6 +121,17 @@ macro(add_target_flags_if condition)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Add all the flags supported by the compiler to all of
|
||||
# 'CMAKE_CXX_FLAGS', 'CMAKE_C_FLAGS', 'LIBCXX_COMPILE_FLAGS'
|
||||
# and 'LIBCXX_LINK_FLAGS'.
|
||||
macro(add_target_flags_if_supported)
|
||||
foreach(flag ${ARGN})
|
||||
mangle_name("${flag}" flagname)
|
||||
check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG")
|
||||
add_target_flags_if(LIBCXX_SUPPORTS_${flagname}_FLAG ${flag})
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
# Add a specified list of flags to both 'LIBCXX_COMPILE_FLAGS' and
|
||||
# 'LIBCXX_LINK_FLAGS'.
|
||||
macro(add_flags)
|
||||
|
@ -1,142 +0,0 @@
|
||||
macro(find_llvm_parts)
|
||||
# Rely on llvm-config.
|
||||
set(CONFIG_OUTPUT)
|
||||
if(NOT LLVM_CONFIG_PATH)
|
||||
find_program(LLVM_CONFIG_PATH "llvm-config")
|
||||
endif()
|
||||
if(DEFINED LLVM_PATH)
|
||||
set(LLVM_INCLUDE_DIR ${LLVM_INCLUDE_DIR} CACHE PATH "Path to llvm/include")
|
||||
set(LLVM_PATH ${LLVM_PATH} CACHE PATH "Path to LLVM source tree")
|
||||
set(LLVM_MAIN_SRC_DIR ${LLVM_PATH})
|
||||
set(LLVM_CMAKE_PATH "${LLVM_PATH}/cmake/modules")
|
||||
if (NOT IS_DIRECTORY "${LLVM_PATH}")
|
||||
message(FATAL_ERROR "The provided LLVM_PATH (${LLVM_PATH}) is not a valid directory")
|
||||
endif()
|
||||
elseif(LLVM_CONFIG_PATH)
|
||||
message(STATUS "Found LLVM_CONFIG_PATH as ${LLVM_CONFIG_PATH}")
|
||||
set(LIBCXX_USING_INSTALLED_LLVM 1)
|
||||
set(CONFIG_COMMAND ${LLVM_CONFIG_PATH}
|
||||
"--includedir"
|
||||
"--prefix"
|
||||
"--src-root")
|
||||
execute_process(
|
||||
COMMAND ${CONFIG_COMMAND}
|
||||
RESULT_VARIABLE HAD_ERROR
|
||||
OUTPUT_VARIABLE CONFIG_OUTPUT
|
||||
)
|
||||
if(NOT HAD_ERROR)
|
||||
string(REGEX REPLACE
|
||||
"[ \t]*[\r\n]+[ \t]*" ";"
|
||||
CONFIG_OUTPUT ${CONFIG_OUTPUT})
|
||||
else()
|
||||
string(REPLACE ";" " " CONFIG_COMMAND_STR "${CONFIG_COMMAND}")
|
||||
message(STATUS "${CONFIG_COMMAND_STR}")
|
||||
message(FATAL_ERROR "llvm-config failed with status ${HAD_ERROR}")
|
||||
endif()
|
||||
|
||||
list(GET CONFIG_OUTPUT 0 INCLUDE_DIR)
|
||||
list(GET CONFIG_OUTPUT 1 LLVM_OBJ_ROOT)
|
||||
list(GET CONFIG_OUTPUT 2 MAIN_SRC_DIR)
|
||||
|
||||
set(LLVM_INCLUDE_DIR ${INCLUDE_DIR} CACHE PATH "Path to llvm/include")
|
||||
set(LLVM_BINARY_DIR ${LLVM_OBJ_ROOT} CACHE PATH "Path to LLVM build tree")
|
||||
set(LLVM_MAIN_SRC_DIR ${MAIN_SRC_DIR} CACHE PATH "Path to LLVM source tree")
|
||||
|
||||
# --cmakedir is supported since llvm r291218 (4.0 release)
|
||||
execute_process(
|
||||
COMMAND ${LLVM_CONFIG_PATH} --cmakedir
|
||||
RESULT_VARIABLE HAD_ERROR
|
||||
OUTPUT_VARIABLE CONFIG_OUTPUT
|
||||
ERROR_QUIET)
|
||||
if(NOT HAD_ERROR)
|
||||
string(STRIP "${CONFIG_OUTPUT}" LLVM_CMAKE_PATH_FROM_LLVM_CONFIG)
|
||||
file(TO_CMAKE_PATH "${LLVM_CMAKE_PATH_FROM_LLVM_CONFIG}" LLVM_CMAKE_PATH)
|
||||
else()
|
||||
file(TO_CMAKE_PATH "${LLVM_BINARY_DIR}" LLVM_BINARY_DIR_CMAKE_STYLE)
|
||||
set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR_CMAKE_STYLE}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm")
|
||||
endif()
|
||||
else()
|
||||
set(LLVM_FOUND OFF)
|
||||
message(WARNING "UNSUPPORTED LIBCXX CONFIGURATION DETECTED: "
|
||||
"llvm-config not found and LLVM_PATH not defined.\n"
|
||||
"Reconfigure with -DLLVM_CONFIG_PATH=path/to/llvm-config "
|
||||
"or -DLLVM_PATH=path/to/llvm-source-root.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (EXISTS "${LLVM_CMAKE_PATH}")
|
||||
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}")
|
||||
elseif (EXISTS "${LLVM_MAIN_SRC_DIR}/cmake/modules")
|
||||
list(APPEND CMAKE_MODULE_PATH "${LLVM_MAIN_SRC_DIR}/cmake/modules")
|
||||
else()
|
||||
set(LLVM_FOUND OFF)
|
||||
message(WARNING "Neither ${LLVM_CMAKE_PATH} nor ${LLVM_MAIN_SRC_DIR}/cmake/modules found")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(LLVM_FOUND ON)
|
||||
endmacro(find_llvm_parts)
|
||||
|
||||
macro(configure_out_of_tree_llvm)
|
||||
message(STATUS "Configuring for standalone build.")
|
||||
set(LIBCXX_STANDALONE_BUILD 1)
|
||||
|
||||
find_llvm_parts()
|
||||
|
||||
# Add LLVM Functions --------------------------------------------------------
|
||||
if (LLVM_FOUND AND LIBCXX_USING_INSTALLED_LLVM)
|
||||
include(LLVMConfig) # For TARGET_TRIPLE
|
||||
else()
|
||||
if (WIN32)
|
||||
set(LLVM_ON_UNIX 0)
|
||||
set(LLVM_ON_WIN32 1)
|
||||
else()
|
||||
set(LLVM_ON_UNIX 1)
|
||||
set(LLVM_ON_WIN32 0)
|
||||
endif()
|
||||
endif()
|
||||
if (LLVM_FOUND)
|
||||
include(AddLLVM OPTIONAL)
|
||||
endif()
|
||||
|
||||
# LLVM Options --------------------------------------------------------------
|
||||
if (NOT DEFINED LLVM_INCLUDE_TESTS)
|
||||
set(LLVM_INCLUDE_TESTS ${LLVM_FOUND})
|
||||
endif()
|
||||
if (NOT DEFINED LLVM_INCLUDE_DOCS)
|
||||
set(LLVM_INCLUDE_DOCS ${LLVM_FOUND})
|
||||
endif()
|
||||
if (NOT DEFINED LLVM_ENABLE_SPHINX)
|
||||
set(LLVM_ENABLE_SPHINX OFF)
|
||||
endif()
|
||||
|
||||
# In a standalone build, we don't have llvm to automatically generate the
|
||||
# llvm-lit script for us. So we need to provide an explicit directory that
|
||||
# the configurator should write the script into.
|
||||
set(LLVM_LIT_OUTPUT_DIR "${libcxx_BINARY_DIR}/bin")
|
||||
|
||||
if (LLVM_INCLUDE_TESTS)
|
||||
# Required LIT Configuration ------------------------------------------------
|
||||
# Define the default arguments to use with 'lit', and an option for the user
|
||||
# to override.
|
||||
set(LLVM_DEFAULT_EXTERNAL_LIT "${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py")
|
||||
set(LIT_ARGS_DEFAULT "-sv --show-xfail --show-unsupported")
|
||||
if (MSVC OR XCODE)
|
||||
set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar")
|
||||
endif()
|
||||
set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit")
|
||||
endif()
|
||||
|
||||
# Required doc configuration
|
||||
if (LLVM_ENABLE_SPHINX)
|
||||
find_package(Sphinx REQUIRED)
|
||||
endif()
|
||||
|
||||
if (LLVM_ON_UNIX AND NOT APPLE)
|
||||
set(LLVM_HAVE_LINK_VERSION_SCRIPT 1)
|
||||
else()
|
||||
set(LLVM_HAVE_LINK_VERSION_SCRIPT 0)
|
||||
endif()
|
||||
endmacro(configure_out_of_tree_llvm)
|
||||
|
||||
configure_out_of_tree_llvm()
|
2
cmake/caches/AArch64.cmake
Normal file
2
cmake/caches/AArch64.cmake
Normal file
@ -0,0 +1,2 @@
|
||||
set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "")
|
||||
set(LIBCXX_TARGET_TRIPLE "aarch64-linux-gnu" CACHE STRING "")
|
16
cmake/caches/AIX.cmake
Normal file
16
cmake/caches/AIX.cmake
Normal file
@ -0,0 +1,16 @@
|
||||
set(CMAKE_BUILD_TYPE Release CACHE STRING "")
|
||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON CACHE BOOL "")
|
||||
set(CMAKE_C_FLAGS "-D__LIBC_NO_CPP_MATH_OVERLOADS__" CACHE STRING "")
|
||||
set(CMAKE_CXX_FLAGS "-D__LIBC_NO_CPP_MATH_OVERLOADS__" CACHE STRING "")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-G -Wl,-bcdtors:all:-2147483548:s" CACHE STRING "")
|
||||
|
||||
set(LIBCXX_USE_COMPILER_RT ON CACHE BOOL "")
|
||||
set(LIBCXX_ENABLE_ASSERTIONS OFF CACHE BOOL "")
|
||||
set(LIBCXX_ABI_VERSION "1" CACHE STRING "")
|
||||
set(LIBCXX_ENABLE_ABI_LINKER_SCRIPT OFF CACHE BOOL "")
|
||||
set(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY OFF CACHE BOOL "")
|
||||
set(LIBCXX_ENABLE_SHARED ON CACHE BOOL "")
|
||||
set(LIBCXX_ENABLE_STATIC OFF CACHE BOOL "")
|
||||
set(LIBCXXABI_ENABLE_SHARED ON CACHE BOOL "")
|
||||
set(LIBCXXABI_ENABLE_STATIC OFF CACHE BOOL "")
|
||||
set(LIBCXX_CXX_ABI libcxxabi CACHE STRING "")
|
@ -2,14 +2,22 @@ set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "")
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE OFF CACHE BOOL "")
|
||||
|
||||
set(LIBCXX_USE_COMPILER_RT ON CACHE BOOL "")
|
||||
set(LIBCXX_ENABLE_ASSERTIONS ON CACHE BOOL "")
|
||||
|
||||
set(LIBCXX_ENABLE_ASSERTIONS OFF CACHE BOOL "")
|
||||
set(LIBCXX_ABI_VERSION "1" CACHE STRING "")
|
||||
|
||||
set(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY OFF CACHE BOOL "")
|
||||
set(LIBCXX_ENABLE_STATIC OFF CACHE BOOL "")
|
||||
|
||||
set(LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS OFF CACHE BOOL "")
|
||||
set(LIBCXXABI_ENABLE_NEW_DELETE_DEFINITIONS ON CACHE BOOL "")
|
||||
|
||||
set(LIBCXX_ENABLE_STATIC ON CACHE BOOL "")
|
||||
set(LIBCXX_ENABLE_SHARED ON CACHE BOOL "")
|
||||
set(LIBCXX_CXX_ABI libcxxabi CACHE STRING "")
|
||||
set(LIBCXX_HIDE_FROM_ABI_PER_TU_BY_DEFAULT ON CACHE BOOL "")
|
||||
set(LIBCXX_ENABLE_DEBUG_MODE_SUPPORT OFF CACHE BOOL "")
|
||||
set(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS ON CACHE BOOL "")
|
||||
set(LIBCXX_ENABLE_INCOMPLETE_FEATURES OFF CACHE BOOL "")
|
||||
|
||||
set(LIBCXX_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "")
|
||||
set(LIBCXXABI_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "")
|
||||
|
||||
set(LIBCXXABI_ENABLE_ASSERTIONS OFF CACHE BOOL "")
|
||||
set(LIBCXXABI_ENABLE_FORGIVING_DYNAMIC_CAST ON CACHE BOOL "")
|
||||
|
||||
set(LIBCXX_TEST_PARAMS "stdlib=apple-libc++" CACHE STRING "")
|
||||
set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
|
||||
|
4
cmake/caches/Armv7Arm.cmake
Normal file
4
cmake/caches/Armv7Arm.cmake
Normal file
@ -0,0 +1,4 @@
|
||||
set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "")
|
||||
set(LIBCXX_TARGET_TRIPLE "armv7l-linux-gnueabihf" CACHE STRING "")
|
||||
set(CMAKE_CXX_FLAGS "-marm" CACHE STRING "")
|
||||
set(CMAKE_C_FLAGS "-marm" CACHE STRING "")
|
6
cmake/caches/Armv7Thumb-noexceptions.cmake
Normal file
6
cmake/caches/Armv7Thumb-noexceptions.cmake
Normal file
@ -0,0 +1,6 @@
|
||||
set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "")
|
||||
set(LIBCXX_TARGET_TRIPLE "armv7l-linux-gnueabihf" CACHE STRING "")
|
||||
set(CMAKE_CXX_FLAGS "-mthumb" CACHE STRING "")
|
||||
set(CMAKE_C_FLAGS "-mthumb" CACHE STRING "")
|
||||
set(LIBCXX_ENABLE_EXCEPTIONS OFF CACHE BOOL "")
|
||||
set(LIBCXXABI_ENABLE_EXCEPTIONS OFF CACHE BOOL "")
|
4
cmake/caches/Armv8Arm.cmake
Normal file
4
cmake/caches/Armv8Arm.cmake
Normal file
@ -0,0 +1,4 @@
|
||||
set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "")
|
||||
set(LIBCXX_TARGET_TRIPLE "armv8l-linux-gnueabihf" CACHE STRING "")
|
||||
set(CMAKE_CXX_FLAGS "-marm" CACHE STRING "")
|
||||
set(CMAKE_C_FLAGS "-marm" CACHE STRING "")
|
6
cmake/caches/Armv8Thumb-noexceptions.cmake
Normal file
6
cmake/caches/Armv8Thumb-noexceptions.cmake
Normal file
@ -0,0 +1,6 @@
|
||||
set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "")
|
||||
set(LIBCXX_TARGET_TRIPLE "armv8l-linux-gnueabihf" CACHE STRING "")
|
||||
set(CMAKE_CXX_FLAGS "-mthumb" CACHE STRING "")
|
||||
set(CMAKE_C_FLAGS "-mthumb" CACHE STRING "")
|
||||
set(LIBCXX_ENABLE_EXCEPTIONS OFF CACHE BOOL "")
|
||||
set(LIBCXXABI_ENABLE_EXCEPTIONS OFF CACHE BOOL "")
|
9
cmake/caches/FreeBSD.cmake
Normal file
9
cmake/caches/FreeBSD.cmake
Normal file
@ -0,0 +1,9 @@
|
||||
set(CMAKE_BUILD_TYPE Release CACHE STRING "")
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON CACHE BOOL "")
|
||||
|
||||
set(LIBCXX_ENABLE_ASSERTIONS OFF CACHE BOOL "")
|
||||
set(LIBCXX_ABI_VERSION "1" CACHE STRING "")
|
||||
set(LIBCXX_ENABLE_STATIC ON CACHE BOOL "")
|
||||
set(LIBCXX_ENABLE_SHARED ON CACHE BOOL "")
|
||||
set(LIBCXX_CXX_ABI libcxxrt CACHE STRING "")
|
||||
set(LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS ON CACHE BOOL "")
|
3
cmake/caches/Generic-asan.cmake
Normal file
3
cmake/caches/Generic-asan.cmake
Normal file
@ -0,0 +1,3 @@
|
||||
set(LLVM_USE_SANITIZER "Address" CACHE STRING "")
|
||||
# This is a temporary (hopefully) workaround for an ASan issue (see https://llvm.org/D119410).
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mllvm -asan-use-private-alias=1" CACHE INTERNAL "")
|
1
cmake/caches/Generic-assertions.cmake
Normal file
1
cmake/caches/Generic-assertions.cmake
Normal file
@ -0,0 +1 @@
|
||||
set(LIBCXX_ENABLE_ASSERTIONS ON CACHE BOOL "")
|
2
cmake/caches/Generic-cxx03.cmake
Normal file
2
cmake/caches/Generic-cxx03.cmake
Normal file
@ -0,0 +1,2 @@
|
||||
set(LIBCXX_TEST_PARAMS "std=c++03" CACHE STRING "")
|
||||
set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
|
2
cmake/caches/Generic-cxx11.cmake
Normal file
2
cmake/caches/Generic-cxx11.cmake
Normal file
@ -0,0 +1,2 @@
|
||||
set(LIBCXX_TEST_PARAMS "std=c++11" CACHE STRING "")
|
||||
set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
|
2
cmake/caches/Generic-cxx14.cmake
Normal file
2
cmake/caches/Generic-cxx14.cmake
Normal file
@ -0,0 +1,2 @@
|
||||
set(LIBCXX_TEST_PARAMS "std=c++14" CACHE STRING "")
|
||||
set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
|
2
cmake/caches/Generic-cxx17.cmake
Normal file
2
cmake/caches/Generic-cxx17.cmake
Normal file
@ -0,0 +1,2 @@
|
||||
set(LIBCXX_TEST_PARAMS "std=c++17" CACHE STRING "")
|
||||
set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
|
2
cmake/caches/Generic-cxx20.cmake
Normal file
2
cmake/caches/Generic-cxx20.cmake
Normal file
@ -0,0 +1,2 @@
|
||||
set(LIBCXX_TEST_PARAMS "std=c++20" CACHE STRING "")
|
||||
set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
|
2
cmake/caches/Generic-cxx2b.cmake
Normal file
2
cmake/caches/Generic-cxx2b.cmake
Normal file
@ -0,0 +1,2 @@
|
||||
set(LIBCXX_TEST_PARAMS "std=c++2b" CACHE STRING "")
|
||||
set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
|
2
cmake/caches/Generic-debug-iterators.cmake
Normal file
2
cmake/caches/Generic-debug-iterators.cmake
Normal file
@ -0,0 +1,2 @@
|
||||
set(LIBCXX_TEST_PARAMS "debug_level=1" CACHE STRING "")
|
||||
set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
|
2
cmake/caches/Generic-modules.cmake
Normal file
2
cmake/caches/Generic-modules.cmake
Normal file
@ -0,0 +1,2 @@
|
||||
set(LIBCXX_TEST_PARAMS "enable_modules=True" CACHE STRING "")
|
||||
set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
|
1
cmake/caches/Generic-msan.cmake
Normal file
1
cmake/caches/Generic-msan.cmake
Normal file
@ -0,0 +1 @@
|
||||
set(LLVM_USE_SANITIZER "MemoryWithOrigins" CACHE STRING "")
|
1
cmake/caches/Generic-no-debug.cmake
Normal file
1
cmake/caches/Generic-no-debug.cmake
Normal file
@ -0,0 +1 @@
|
||||
set(LIBCXX_ENABLE_DEBUG_MODE_SUPPORT OFF CACHE BOOL "")
|
2
cmake/caches/Generic-no-experimental.cmake
Normal file
2
cmake/caches/Generic-no-experimental.cmake
Normal file
@ -0,0 +1,2 @@
|
||||
set(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY OFF CACHE BOOL "")
|
||||
set(LIBCXX_ENABLE_INCOMPLETE_FEATURES OFF CACHE BOOL "")
|
1
cmake/caches/Generic-no-filesystem.cmake
Normal file
1
cmake/caches/Generic-no-filesystem.cmake
Normal file
@ -0,0 +1 @@
|
||||
set(LIBCXX_ENABLE_FILESYSTEM OFF CACHE BOOL "")
|
1
cmake/caches/Generic-no-localization.cmake
Normal file
1
cmake/caches/Generic-no-localization.cmake
Normal file
@ -0,0 +1 @@
|
||||
set(LIBCXX_ENABLE_LOCALIZATION OFF CACHE BOOL "")
|
1
cmake/caches/Generic-no-random_device.cmake
Normal file
1
cmake/caches/Generic-no-random_device.cmake
Normal file
@ -0,0 +1 @@
|
||||
set(LIBCXX_ENABLE_RANDOM_DEVICE OFF CACHE BOOL "")
|
1
cmake/caches/Generic-no-unicode.cmake
Normal file
1
cmake/caches/Generic-no-unicode.cmake
Normal file
@ -0,0 +1 @@
|
||||
set(LIBCXX_ENABLE_UNICODE OFF CACHE BOOL "")
|
1
cmake/caches/Generic-no-wide-characters.cmake
Normal file
1
cmake/caches/Generic-no-wide-characters.cmake
Normal file
@ -0,0 +1 @@
|
||||
set(LIBCXX_ENABLE_WIDE_CHARACTERS OFF CACHE BOOL "")
|
2
cmake/caches/Generic-noexceptions.cmake
Normal file
2
cmake/caches/Generic-noexceptions.cmake
Normal file
@ -0,0 +1,2 @@
|
||||
set(LIBCXX_ENABLE_EXCEPTIONS OFF CACHE BOOL "")
|
||||
set(LIBCXXABI_ENABLE_EXCEPTIONS OFF CACHE BOOL "")
|
3
cmake/caches/Generic-singlethreaded.cmake
Normal file
3
cmake/caches/Generic-singlethreaded.cmake
Normal file
@ -0,0 +1,3 @@
|
||||
set(LIBCXX_ENABLE_THREADS OFF CACHE BOOL "")
|
||||
set(LIBCXXABI_ENABLE_THREADS OFF CACHE BOOL "")
|
||||
set(LIBCXX_ENABLE_MONOTONIC_CLOCK OFF CACHE BOOL "")
|
3
cmake/caches/Generic-static.cmake
Normal file
3
cmake/caches/Generic-static.cmake
Normal file
@ -0,0 +1,3 @@
|
||||
set(LIBCXX_ENABLE_SHARED OFF CACHE BOOL "")
|
||||
set(LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "")
|
||||
set(LIBUNWIND_ENABLE_SHARED OFF CACHE BOOL "")
|
1
cmake/caches/Generic-tsan.cmake
Normal file
1
cmake/caches/Generic-tsan.cmake
Normal file
@ -0,0 +1 @@
|
||||
set(LLVM_USE_SANITIZER "Thread" CACHE STRING "")
|
2
cmake/caches/Generic-ubsan.cmake
Normal file
2
cmake/caches/Generic-ubsan.cmake
Normal file
@ -0,0 +1,2 @@
|
||||
set(LLVM_USE_SANITIZER "Undefined" CACHE STRING "")
|
||||
set(LIBCXX_ABI_UNSTABLE ON CACHE BOOL "")
|
18
cmake/caches/MinGW.cmake
Normal file
18
cmake/caches/MinGW.cmake
Normal file
@ -0,0 +1,18 @@
|
||||
set(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY OFF CACHE BOOL "")
|
||||
set(LIBCXX_HAS_WIN32_THREAD_API ON CACHE BOOL "")
|
||||
|
||||
set(LIBCXX_CXX_ABI libcxxabi CACHE STRING "")
|
||||
set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "")
|
||||
|
||||
set(LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "")
|
||||
set(LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "")
|
||||
|
||||
set(LIBCXX_USE_COMPILER_RT ON CACHE BOOL "")
|
||||
set(LIBCXXABI_USE_COMPILER_RT ON CACHE BOOL "")
|
||||
set(LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "")
|
||||
|
||||
set(LIBCXX_TARGET_INFO "libcxx.test.target_info.MingwLocalTI" CACHE STRING "")
|
||||
|
||||
# Without this flag, 'long double' (which is 80 bit on x86 mingw, but
|
||||
# 64 bit in MSVC) isn't handled correctly in printf.
|
||||
set(LIBCXX_EXTRA_SITE_DEFINES "__USE_MINGW_ANSI_STDIO=1" CACHE STRING "")
|
13
cmake/caches/README.md
Normal file
13
cmake/caches/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
# libc++ / libc++abi configuration caches
|
||||
|
||||
This directory contains CMake caches for the supported configurations of libc++.
|
||||
Some of the configurations are specific to a vendor, others are generic and not
|
||||
tied to any vendor.
|
||||
|
||||
While we won't explicitly work to break configurations not listed here, any
|
||||
configuration not listed here is not explicitly supported. If you use or ship
|
||||
libc++ under a configuration not listed here, you should work with the libc++
|
||||
maintainers to make it into a supported configuration and add it here.
|
||||
|
||||
Similarly, adding any new configuration that's not already covered must be
|
||||
discussed with the libc++ maintainers as it entails a maintenance burden.
|
@ -1,9 +1,22 @@
|
||||
include(CMakePushCheckState)
|
||||
include(CheckLibraryExists)
|
||||
include(LLVMCheckCompilerLinkerFlag)
|
||||
include(CheckCCompilerFlag)
|
||||
include(CheckCXXCompilerFlag)
|
||||
include(CheckCSourceCompiles)
|
||||
|
||||
# The compiler driver may be implicitly trying to link against libunwind.
|
||||
# This is normally ok (libcxx relies on an unwinder), but if libunwind is
|
||||
# built in the same cmake invocation as libcxx and we've got
|
||||
# LIBCXXABI_USE_LLVM_UNWINDER set, we'd be linking against the just-built
|
||||
# libunwind (and the compiler implicit -lunwind wouldn't succeed as the newly
|
||||
# built libunwind isn't installed yet). For those cases, it'd be good to
|
||||
# link with --uwnindlib=none. Check if that option works.
|
||||
llvm_check_compiler_linker_flag(C "--unwindlib=none" LIBCXX_SUPPORTS_UNWINDLIB_NONE_FLAG)
|
||||
if (LIBCXX_SUPPORTS_UNWINDLIB_NONE_FLAG)
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} --unwindlib=none")
|
||||
endif()
|
||||
|
||||
if(WIN32 AND NOT MINGW)
|
||||
# NOTE(compnerd) this is technically a lie, there is msvcrt, but for now, lets
|
||||
# let the default linking take care of that.
|
||||
@ -16,27 +29,44 @@ if (NOT LIBCXX_USE_COMPILER_RT)
|
||||
if(WIN32 AND NOT MINGW)
|
||||
set(LIBCXX_HAS_GCC_S_LIB NO)
|
||||
else()
|
||||
check_library_exists(gcc_s __gcc_personality_v0 "" LIBCXX_HAS_GCC_S_LIB)
|
||||
if(ANDROID)
|
||||
check_library_exists(gcc __gcc_personality_v0 "" LIBCXX_HAS_GCC_LIB)
|
||||
else()
|
||||
check_library_exists(gcc_s __gcc_personality_v0 "" LIBCXX_HAS_GCC_S_LIB)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# libc++ is built with -nodefaultlibs, so we want all our checks to also
|
||||
# use this option, otherwise we may end up with an inconsistency between
|
||||
# libc++ is using -nostdlib++ at the link step when available,
|
||||
# otherwise -nodefaultlibs is used. We want all our checks to also
|
||||
# use one of these options, otherwise we may end up with an inconsistency between
|
||||
# the flags we think we require during configuration (if the checks are
|
||||
# performed without -nodefaultlibs) and the flags that are actually
|
||||
# required during compilation (which has the -nodefaultlibs). libc is
|
||||
# performed without one of those options) and the flags that are actually
|
||||
# required during compilation (which has the -nostdlib++ or -nodefaultlibs). libc is
|
||||
# required for the link to go through. We remove sanitizers from the
|
||||
# configuration checks to avoid spurious link errors.
|
||||
check_c_compiler_flag(-nodefaultlibs LIBCXX_SUPPORTS_NODEFAULTLIBS_FLAG)
|
||||
if (LIBCXX_SUPPORTS_NODEFAULTLIBS_FLAG)
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nodefaultlibs")
|
||||
|
||||
check_c_compiler_flag(-nostdlib++ LIBCXX_SUPPORTS_NOSTDLIBXX_FLAG)
|
||||
if (LIBCXX_SUPPORTS_NOSTDLIBXX_FLAG)
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nostdlib++")
|
||||
else()
|
||||
check_c_compiler_flag(-nodefaultlibs LIBCXX_SUPPORTS_NODEFAULTLIBS_FLAG)
|
||||
if (LIBCXX_SUPPORTS_NODEFAULTLIBS_FLAG)
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nodefaultlibs")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (LIBCXX_SUPPORTS_NOSTDLIBXX_FLAG OR LIBCXX_SUPPORTS_NODEFAULTLIBS_FLAG)
|
||||
if (LIBCXX_HAS_C_LIB)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES c)
|
||||
endif ()
|
||||
if (LIBCXX_USE_COMPILER_RT)
|
||||
list(APPEND CMAKE_REQUIRED_FLAGS -rtlib=compiler-rt)
|
||||
find_compiler_rt_library(builtins LIBCXX_BUILTINS_LIBRARY)
|
||||
include(HandleCompilerRT)
|
||||
find_compiler_rt_library(builtins LIBCXX_BUILTINS_LIBRARY
|
||||
FLAGS ${LIBCXX_COMPILE_FLAGS})
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "${LIBCXX_BUILTINS_LIBRARY}")
|
||||
elseif (LIBCXX_HAS_GCC_LIB)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES gcc)
|
||||
elseif (LIBCXX_HAS_GCC_S_LIB)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES gcc_s)
|
||||
endif ()
|
||||
@ -57,7 +87,7 @@ if (LIBCXX_SUPPORTS_NODEFAULTLIBS_FLAG)
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize=all")
|
||||
endif ()
|
||||
if (CMAKE_C_FLAGS MATCHES -fsanitize-coverage OR CMAKE_CXX_FLAGS MATCHES -fsanitize-coverage)
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters")
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fsanitize-coverage=0")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
@ -72,10 +102,6 @@ int main() { return 0; }
|
||||
cmake_pop_check_state()
|
||||
endif()
|
||||
|
||||
if(NOT WIN32 OR MINGW)
|
||||
include(CheckLibcxxAtomic)
|
||||
endif()
|
||||
|
||||
# Check libraries
|
||||
if(WIN32 AND NOT MINGW)
|
||||
# TODO(compnerd) do we want to support an emulation layer that allows for the
|
||||
@ -84,14 +110,23 @@ if(WIN32 AND NOT MINGW)
|
||||
set(LIBCXX_HAS_M_LIB NO)
|
||||
set(LIBCXX_HAS_RT_LIB NO)
|
||||
set(LIBCXX_HAS_SYSTEM_LIB NO)
|
||||
set(LIBCXX_HAS_ATOMIC_LIB NO)
|
||||
elseif(APPLE)
|
||||
check_library_exists(System write "" LIBCXX_HAS_SYSTEM_LIB)
|
||||
set(LIBCXX_HAS_PTHREAD_LIB NO)
|
||||
set(LIBCXX_HAS_M_LIB NO)
|
||||
set(LIBCXX_HAS_RT_LIB NO)
|
||||
set(LIBCXX_HAS_ATOMIC_LIB NO)
|
||||
elseif(FUCHSIA)
|
||||
set(LIBCXX_HAS_M_LIB NO)
|
||||
set(LIBCXX_HAS_PTHREAD_LIB NO)
|
||||
set(LIBCXX_HAS_RT_LIB NO)
|
||||
set(LIBCXX_HAS_SYSTEM_LIB NO)
|
||||
check_library_exists(atomic __atomic_fetch_add_8 "" LIBCXX_HAS_ATOMIC_LIB)
|
||||
else()
|
||||
check_library_exists(pthread pthread_create "" LIBCXX_HAS_PTHREAD_LIB)
|
||||
check_library_exists(m ccos "" LIBCXX_HAS_M_LIB)
|
||||
check_library_exists(rt clock_gettime "" LIBCXX_HAS_RT_LIB)
|
||||
set(LIBCXX_HAS_SYSTEM_LIB NO)
|
||||
check_library_exists(atomic __atomic_fetch_add_8 "" LIBCXX_HAS_ATOMIC_LIB)
|
||||
endif()
|
||||
|
66
docs/AddingNewCIJobs.rst
Normal file
66
docs/AddingNewCIJobs.rst
Normal file
@ -0,0 +1,66 @@
|
||||
.. _AddingNewCIJobs:
|
||||
|
||||
==================
|
||||
Adding New CI Jobs
|
||||
==================
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
Adding The Job
|
||||
==============
|
||||
|
||||
libc++ uses Buildkite for running its CI. Setting up new CI jobs is easy, and
|
||||
these jobs can run either on our existing infrastructure, or on your own.
|
||||
|
||||
If you need to run the job on your own machines, please follow the
|
||||
`Buildkite guide <https://buildkite.com/docs/agent/v3>`_ to setup your
|
||||
own agents. Make sure you tag your agents in a way that you'll be able
|
||||
to recognize them when defining your job below. Finally, in order for the
|
||||
agent to register itself to Buildkite, it will need a BuildKite Agent token.
|
||||
Please contact a maintainer to get your token.
|
||||
|
||||
Then, simply add a job to the Buildkite pipeline by editing ``libcxx/utils/ci/buildkite-pipeline.yml``.
|
||||
Take a look at how the surrounding jobs are defined and do something similar.
|
||||
An example of a job definition is:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- label: "C++11"
|
||||
command: "libcxx/utils/ci/run-buildbot generic-cxx11"
|
||||
artifact_paths:
|
||||
- "**/test-results.xml"
|
||||
agents:
|
||||
queue: "libcxx-builders"
|
||||
os: "linux"
|
||||
retry:
|
||||
[...]
|
||||
|
||||
If you create your own agents, put them in the ``libcxx-builders`` queue and
|
||||
use agent tags to allow targetting your agents from the Buildkite pipeline
|
||||
config appropriately.
|
||||
|
||||
We try to keep the pipeline definition file as simple as possible, and to
|
||||
keep any script used for CI inside ``libcxx/utils/ci``. This ensures that
|
||||
it's possible to reproduce CI issues locally with ease, understanding of
|
||||
course that some setups may require access to special hardware that is not
|
||||
available.
|
||||
|
||||
Testing Your New Job
|
||||
====================
|
||||
|
||||
Testing your new job is easy -- once your agent is set up (if any), just open
|
||||
a code review and the libc++ CI pipeline will run, including any changes you
|
||||
might have made to the pipeline definition itself.
|
||||
|
||||
Service Level Agreement
|
||||
=======================
|
||||
|
||||
To keep the libc++ CI useful for everyone, we aim for a quick turnaround time
|
||||
for all CI jobs. This allows the overall pipeline to finish in a reasonable
|
||||
amount of time, which is important because it directly affects our development
|
||||
velocity. We also try to make sure that jobs run on reliable infrastructure in
|
||||
order to avoid flaky failures, which reduce the value of CI for everyone.
|
||||
|
||||
We may be reluctant to add and support CI jobs that take a long time to finish
|
||||
or that are too flaky.
|
@ -9,114 +9,166 @@ Building libc++
|
||||
|
||||
.. _build instructions:
|
||||
|
||||
Getting Started
|
||||
===============
|
||||
The instructions on this page are aimed at vendors who ship libc++ as part of an
|
||||
operating system distribution, a toolchain or similar shipping vehicules. If you
|
||||
are a user merely trying to use libc++ in your program, you most likely want to
|
||||
refer to your vendor's documentation, or to the general documentation for using
|
||||
libc++ :ref:`here <using-libcxx>`.
|
||||
|
||||
On Mac OS 10.7 (Lion) and later, the easiest way to get this library is to install
|
||||
Xcode 4.2 or later. However if you want to install tip-of-trunk from here
|
||||
(getting the bleeding edge), read on.
|
||||
|
||||
The basic steps needed to build libc++ are:
|
||||
|
||||
#. Checkout and configure LLVM (including libc++ and libc++abi), according to the `LLVM
|
||||
getting started <https://llvm.org/docs/GettingStarted.html>`_ documentation. Make sure
|
||||
to include ``libcxx`` and ``libcxxabi`` in the ``LLVM_ENABLE_PROJECTS`` option passed
|
||||
to CMake.
|
||||
|
||||
For more information about configuring libc++ see :ref:`CMake Options`.
|
||||
|
||||
* ``make cxx`` --- will build libc++ and libc++abi.
|
||||
* ``make check-cxx check-cxxabi`` --- will run the test suites.
|
||||
|
||||
Shared libraries for libc++ and libc++ abi should now be present in llvm/build/lib.
|
||||
See :ref:`using an alternate libc++ installation <alternate libcxx>`
|
||||
|
||||
#. **Optional**: Install libc++ and libc++abi
|
||||
|
||||
If your system already provides a libc++ installation it is important to be
|
||||
careful not to replace it. Remember Use the CMake option ``CMAKE_INSTALL_PREFIX`` to
|
||||
select a safe place to install libc++.
|
||||
|
||||
* ``make install-cxx install-cxxabi`` --- Will install the libraries and the headers
|
||||
|
||||
.. warning::
|
||||
* Replacing your systems libc++ installation could render the system non-functional.
|
||||
* macOS will not boot without a valid copy of ``libc++.1.dylib`` in ``/usr/lib``.
|
||||
.. warning::
|
||||
If your operating system already provides libc++, it is important to be careful
|
||||
not to replace it. Replacing your system's libc++ installation could render it
|
||||
non-functional. Use the CMake option ``CMAKE_INSTALL_PREFIX`` to select a safe
|
||||
place to install libc++.
|
||||
|
||||
|
||||
The instructions are for building libc++ on
|
||||
FreeBSD, Linux, or Mac using `libc++abi`_ as the C++ ABI library.
|
||||
On Linux, it is also possible to use :ref:`libsupc++ <libsupcxx>` or libcxxrt.
|
||||
The default build
|
||||
=================
|
||||
|
||||
It is sometimes beneficial to build separately from the full LLVM build. An
|
||||
out-of-tree build would look like this:
|
||||
The default way of building libc++, libc++abi and libunwind is to root the CMake
|
||||
invocation at ``<monorepo>/runtimes``. While those projects are under the LLVM
|
||||
umbrella, they are different in nature from other build tools, so it makes sense
|
||||
to treat them as a separate set of entities. The default build can be achieved
|
||||
with the following CMake invocation:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ cd where-you-want-libcxx-to-live
|
||||
$ # Check out the sources (includes everything, but we'll only use libcxx)
|
||||
$ ``git clone https://github.com/llvm/llvm-project.git``
|
||||
$ cd where-you-want-to-build
|
||||
$ mkdir build && cd build
|
||||
$ export CC=clang CXX=clang++
|
||||
$ cmake -DLLVM_PATH=path/to/separate/llvm \
|
||||
-DLIBCXX_CXX_ABI=libcxxabi \
|
||||
-DLIBCXX_CXX_ABI_INCLUDE_PATHS=path/to/separate/libcxxabi/include \
|
||||
path/to/llvm-project/libcxx
|
||||
$ make
|
||||
$ make check-libcxx # optional
|
||||
$ git clone https://github.com/llvm/llvm-project.git
|
||||
$ cd llvm-project
|
||||
$ mkdir build
|
||||
$ cmake -G Ninja -S runtimes -B build -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" # Configure
|
||||
$ ninja -C build cxx cxxabi unwind # Build
|
||||
$ ninja -C build check-cxx check-cxxabi check-unwind # Test
|
||||
$ ninja -C build install-cxx install-cxxabi install-unwind # Install
|
||||
|
||||
.. note::
|
||||
See :ref:`CMake Options` below for more configuration options.
|
||||
|
||||
After building the various ``install-XXX`` targets, shared libraries for libc++, libc++abi and
|
||||
libunwind should now be present in ``<CMAKE_INSTALL_PREFIX>/lib``, and headers in
|
||||
``<CMAKE_INSTALL_PREFIX>/include/c++/v1``. See :ref:`using an alternate libc++ installation
|
||||
<alternate libcxx>` for information on how to use this libc++ over the default one.
|
||||
|
||||
In the default configuration, the runtimes will be built using the compiler available by default
|
||||
on your system. Of course, you can change what compiler is being used with the usual CMake
|
||||
variables. If you wish to build the runtimes from a just-built Clang, the bootstrapping build
|
||||
explained below makes this task easy.
|
||||
|
||||
|
||||
Experimental Support for Windows
|
||||
--------------------------------
|
||||
Bootstrapping build
|
||||
===================
|
||||
|
||||
The Windows support requires building with clang-cl as cl does not support one
|
||||
required extension: `#include_next`. Furthermore, VS 2015 or newer (19.00) is
|
||||
required. In the case of clang-cl, we need to specify the "MS Compatibility
|
||||
Version" as it defaults to 2014 (18.00).
|
||||
It is possible to build Clang and then build the runtimes using that just-built compiler in a
|
||||
single CMake invocation. This is usually the correct way to build the runtimes when putting together
|
||||
a toolchain, or when the system compiler is not adequate to build them (too old, unsupported, etc.).
|
||||
To do this, use the following CMake invocation, and in particular notice how we're now rooting the
|
||||
CMake invocation at ``<monorepo>/llvm``:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ mkdir build
|
||||
$ cmake -G Ninja -S llvm -B build -DLLVM_ENABLE_PROJECTS="clang" \ # Configure
|
||||
-DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \
|
||||
-DLLVM_RUNTIME_TARGETS="<target-triple>"
|
||||
$ ninja -C build runtimes # Build
|
||||
$ ninja -C build check-runtimes # Test
|
||||
$ ninja -C build install-runtimes # Install
|
||||
|
||||
.. note::
|
||||
This type of build is also commonly called a "Runtimes build", but we would like to move
|
||||
away from that terminology, which is too confusing.
|
||||
|
||||
Support for Windows
|
||||
===================
|
||||
|
||||
libcxx supports being built with clang-cl, but not with MSVC's cl.exe, as
|
||||
cl doesn't support the ``#include_next`` extension. Furthermore, VS 2017 or
|
||||
newer (19.14) is required.
|
||||
|
||||
libcxx also supports being built with clang targeting MinGW environments.
|
||||
|
||||
CMake + Visual Studio
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
---------------------
|
||||
|
||||
Building with Visual Studio currently does not permit running tests. However,
|
||||
it is the simplest way to build.
|
||||
|
||||
.. code-block:: batch
|
||||
|
||||
> cmake -G "Visual Studio 14 2015" ^
|
||||
-T "LLVM-vs2014" ^
|
||||
-DLIBCXX_ENABLE_SHARED=YES ^
|
||||
-DLIBCXX_ENABLE_STATIC=NO ^
|
||||
-DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=NO ^
|
||||
\path\to\libcxx
|
||||
> cmake --build .
|
||||
> cmake -G "Visual Studio 16 2019" -S libcxx -B build ^
|
||||
-T "ClangCL" ^
|
||||
-DLIBCXX_ENABLE_SHARED=YES ^
|
||||
-DLIBCXX_ENABLE_STATIC=NO ^
|
||||
-DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=NO
|
||||
> cmake --build build
|
||||
|
||||
CMake + ninja
|
||||
~~~~~~~~~~~~~
|
||||
CMake + ninja (MSVC)
|
||||
--------------------
|
||||
|
||||
Building with ninja is required for development to enable tests.
|
||||
Unfortunately, doing so requires additional configuration as we cannot
|
||||
just specify a toolset.
|
||||
A couple of tests require Bash to be available, and a couple dozens
|
||||
of tests require other posix tools (cp, grep and similar - LLVM's tests
|
||||
require the same). Without those tools the vast majority of tests
|
||||
can still be ran successfully.
|
||||
|
||||
If Git for Windows is available, that can be used to provide the bash
|
||||
shell by adding the right bin directory to the path, e.g.
|
||||
``set PATH=%PATH%;C:\Program Files\Git\usr\bin``.
|
||||
|
||||
Alternatively, one can also choose to run the whole build in a MSYS2
|
||||
shell. That can be set up e.g. by starting a Visual Studio Tools Command
|
||||
Prompt (for getting the environment variables pointing to the headers and
|
||||
import libraries), and making sure that clang-cl is available in the
|
||||
path. From there, launch an MSYS2 shell via e.g.
|
||||
``C:\msys64\msys2_shell.cmd -full-path -mingw64`` (preserving the earlier
|
||||
environment, allowing the MSVC headers/libraries and clang-cl to be found).
|
||||
|
||||
In either case, then run:
|
||||
|
||||
.. code-block:: batch
|
||||
|
||||
> cmake -G Ninja ^
|
||||
-DCMAKE_MAKE_PROGRAM=/path/to/ninja ^
|
||||
-DCMAKE_SYSTEM_NAME=Windows ^
|
||||
> cmake -G Ninja -S libcxx -B build ^
|
||||
-DCMAKE_C_COMPILER=clang-cl ^
|
||||
-DCMAKE_C_FLAGS="-fms-compatibility-version=19.00 --target=i686--windows" ^
|
||||
-DCMAKE_CXX_COMPILER=clang-cl ^
|
||||
-DCMAKE_CXX_FLAGS="-fms-compatibility-version=19.00 --target=i686--windows" ^
|
||||
-DLLVM_PATH=/path/to/llvm/tree ^
|
||||
-DLIBCXX_ENABLE_SHARED=YES ^
|
||||
-DLIBCXX_ENABLE_STATIC=NO ^
|
||||
-DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=NO ^
|
||||
\path\to\libcxx
|
||||
> /path/to/ninja cxx
|
||||
> /path/to/ninja check-cxx
|
||||
-DCMAKE_CXX_COMPILER=clang-cl ^
|
||||
-DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=NO
|
||||
> ninja -C build cxx
|
||||
> ninja -C build check-cxx
|
||||
|
||||
Note that the paths specified with backward slashes must use the `\\` as the
|
||||
directory separator as clang-cl may otherwise parse the path as an argument.
|
||||
If you are running in an MSYS2 shell and you have installed the
|
||||
MSYS2-provided clang package (which defaults to a non-MSVC target), you
|
||||
should add e.g. ``-DLIBCXX_TARGET_TRIPLE=x86_64-windows-msvc`` (replacing
|
||||
``x86_64`` with the architecture you're targeting) to the ``cmake`` command
|
||||
line above. This will instruct ``check-cxx`` to use the right target triple
|
||||
when invoking ``clang++``.
|
||||
|
||||
Also note that if not building in Release mode, a failed assert in the tests
|
||||
pops up a blocking dialog box, making it hard to run a larger number of tests.
|
||||
|
||||
CMake + ninja (MinGW)
|
||||
---------------------
|
||||
|
||||
libcxx can also be built in MinGW environments, e.g. with the MinGW
|
||||
compilers in MSYS2. This requires clang to be available (installed with
|
||||
e.g. the ``mingw-w64-x86_64-clang`` package), together with CMake and ninja.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
> cmake -G Ninja -S libcxx -B build \
|
||||
-DCMAKE_C_COMPILER=clang \
|
||||
-DCMAKE_CXX_COMPILER=clang++ \
|
||||
-DLIBCXX_HAS_WIN32_THREAD_API=ON \
|
||||
-DLIBCXX_CXX_ABI=libstdc++ \
|
||||
-DLIBCXX_TARGET_INFO="libcxx.test.target_info.MingwLocalTI"
|
||||
> ninja -C build cxx
|
||||
> cp /mingw64/bin/{libstdc++-6,libgcc_s_seh-1,libwinpthread-1}.dll lib
|
||||
> ninja -C build check-cxx
|
||||
|
||||
As this build configuration ends up depending on a couple other DLLs that
|
||||
aren't available in path while running tests, copy them into the same
|
||||
directory as the tested libc++ DLL.
|
||||
|
||||
(Building a libc++ that depends on libstdc++ isn't necessarily a config one
|
||||
would want to deploy, but it simplifies the config for testing purposes.)
|
||||
|
||||
.. _`libc++abi`: http://libcxxabi.llvm.org/
|
||||
|
||||
@ -162,15 +214,9 @@ libc++ specific options
|
||||
|
||||
.. option:: LIBCXX_ENABLE_ASSERTIONS:BOOL
|
||||
|
||||
**Default**: ``ON``
|
||||
|
||||
Build libc++ with assertions enabled.
|
||||
|
||||
.. option:: LIBCXX_BUILD_32_BITS:BOOL
|
||||
|
||||
**Default**: ``OFF``
|
||||
|
||||
Build libc++ as a 32 bit library. Also see `LLVM_BUILD_32_BITS`.
|
||||
Build libc++ with assertions enabled.
|
||||
|
||||
.. option:: LIBCXX_ENABLE_SHARED:BOOL
|
||||
|
||||
@ -191,12 +237,6 @@ libc++ specific options
|
||||
Extra suffix to append to the directory where libraries are to be installed.
|
||||
This option overrides `LLVM_LIBDIR_SUFFIX`.
|
||||
|
||||
.. option:: LIBCXX_INSTALL_PREFIX:STRING
|
||||
|
||||
**Default**: ``""``
|
||||
|
||||
Define libc++ destination prefix.
|
||||
|
||||
.. option:: LIBCXX_HERMETIC_STATIC_LIBRARY:BOOL
|
||||
|
||||
**Default**: ``OFF``
|
||||
@ -208,10 +248,50 @@ libc++ specific options
|
||||
|
||||
.. option:: LIBCXX_ENABLE_FILESYSTEM:BOOL
|
||||
|
||||
**Default**: ``ON`` except on Windows.
|
||||
**Default**: ``ON`` except on Windows when using MSVC.
|
||||
|
||||
This option can be used to enable or disable the filesystem components on
|
||||
platforms that may not support them. For example on Windows.
|
||||
platforms that may not support them. For example on Windows when using MSVC.
|
||||
|
||||
.. option:: LIBCXX_ENABLE_WIDE_CHARACTERS:BOOL
|
||||
|
||||
**Default**: ``ON``
|
||||
|
||||
This option can be used to disable support for ``wchar_t`` in the library. It also
|
||||
allows the library to work on top of a C Standard Library that does not provide
|
||||
support for ``wchar_t``. This is especially useful in embedded settings where
|
||||
C Standard Libraries don't always provide all the usual bells and whistles.
|
||||
|
||||
.. option:: LIBCXX_ENABLE_INCOMPLETE_FEATURES:BOOL
|
||||
|
||||
**Default**: ``ON``
|
||||
|
||||
Whether to enable support for incomplete library features. Incomplete features
|
||||
are new library features under development. These features don't guarantee
|
||||
ABI stability nor the quality of completed library features. Vendors
|
||||
shipping the library may want to disable this option.
|
||||
|
||||
.. option:: LIBCXX_INSTALL_LIBRARY_DIR:PATH
|
||||
|
||||
**Default**: ``lib${LIBCXX_LIBDIR_SUFFIX}``
|
||||
|
||||
Path where built libc++ libraries should be installed. If a relative path,
|
||||
relative to ``CMAKE_INSTALL_PREFIX``.
|
||||
|
||||
.. option:: LIBCXX_INSTALL_INCLUDE_DIR:PATH
|
||||
|
||||
**Default**: ``include/c++/v1``
|
||||
|
||||
Path where target-agnostic libc++ headers should be installed. If a relative
|
||||
path, relative to ``CMAKE_INSTALL_PREFIX``.
|
||||
|
||||
.. option:: LIBCXX_INSTALL_INCLUDE_TARGET_DIR:PATH
|
||||
|
||||
**Default**: ``include/c++/v1`` or
|
||||
``include/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/v1``
|
||||
|
||||
Path where target-specific libc++ headers should be installed. If a relative
|
||||
path, relative to ``CMAKE_INSTALL_PREFIX``.
|
||||
|
||||
.. _libc++experimental options:
|
||||
|
||||
@ -238,7 +318,7 @@ ABI Library Specific Options
|
||||
|
||||
.. option:: LIBCXX_CXX_ABI:STRING
|
||||
|
||||
**Values**: ``none``, ``libcxxabi``, ``libcxxrt``, ``libstdc++``, ``libsupc++``.
|
||||
**Values**: ``none``, ``libcxxabi``, ``system-libcxxabi``, ``libcxxrt``, ``libstdc++``, ``libsupc++``.
|
||||
|
||||
Select the ABI library to build libc++ against.
|
||||
|
||||
@ -290,7 +370,7 @@ libc++ Feature Options
|
||||
|
||||
.. option:: LIBCXX_INCLUDE_TESTS:BOOL
|
||||
|
||||
**Default**: ``ON`` (or value of ``LLVM_INCLUDE_DIR``)
|
||||
**Default**: ``ON`` (or value of ``LLVM_INCLUDE_TESTS``)
|
||||
|
||||
Build the libc++ tests.
|
||||
|
||||
@ -376,20 +456,6 @@ The following options allow building libc++ for a different ABI version.
|
||||
See ``include/__config`` for the list of ABI macros.
|
||||
|
||||
|
||||
.. option:: LIBCXX_HAS_MERGED_TYPEINFO_NAMES_DEFAULT
|
||||
|
||||
**Default**: ``None``. When defined this option overrides the libraries default configuration
|
||||
for whether merged type info names are present.
|
||||
|
||||
|
||||
Build ``std::type_info`` with the assumption that type info names for a type have been fully
|
||||
merged are unique across the entire program. This may not be the case for libraries built with
|
||||
``-Bsymbolic`` or due to compiler or linker bugs (Ex. llvm.org/PR37398).
|
||||
|
||||
When the value is ``ON`` typeinfo comparisons compare only the pointer value, otherwise ``strcmp``
|
||||
is used as a fallback.
|
||||
|
||||
|
||||
.. _LLVM-specific variables:
|
||||
|
||||
LLVM-specific options
|
||||
@ -416,8 +482,12 @@ LLVM-specific options
|
||||
Using Alternate ABI libraries
|
||||
=============================
|
||||
|
||||
In order to implement various features like exceptions, RTTI, ``dynamic_cast`` and
|
||||
more, libc++ requires what we refer to as an ABI library. Typically, that library
|
||||
implements the `Itanium C++ ABI <https://itanium-cxx-abi.github.io/cxx-abi/abi.html>`_.
|
||||
|
||||
.. _libsupcxx:
|
||||
By default, libc++ uses libc++abi as an ABI library. However, it is possible to use
|
||||
other ABI libraries too.
|
||||
|
||||
Using libsupc++ on Linux
|
||||
------------------------
|
||||
@ -447,17 +517,17 @@ You can also figure this out by running
|
||||
End of search list.
|
||||
|
||||
Note that the first two entries happen to be what we are looking for. This
|
||||
may not be correct on other platforms.
|
||||
may not be correct on all platforms.
|
||||
|
||||
We can now run CMake:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ CC=clang CXX=clang++ cmake -G "Unix Makefiles" \
|
||||
-DLIBCXX_CXX_ABI=libstdc++ \
|
||||
-DLIBCXX_CXX_ABI_INCLUDE_PATHS="/usr/include/c++/4.7/;/usr/include/c++/4.7/x86_64-linux-gnu/" \
|
||||
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr \
|
||||
<libc++-source-dir>
|
||||
$ cmake -G Ninja -S runtimes -B build \
|
||||
-DLLVM_ENABLE_RUNTIMES="libcxx" \
|
||||
-DLIBCXX_CXX_ABI=libstdc++ \
|
||||
-DLIBCXX_CXX_ABI_INCLUDE_PATHS="/usr/include/c++/4.7/;/usr/include/c++/4.7/x86_64-linux-gnu/"
|
||||
$ ninja -C build install-cxx
|
||||
|
||||
|
||||
You can also substitute ``-DLIBCXX_CXX_ABI=libsupc++``
|
||||
@ -468,16 +538,6 @@ GCC ships libsupc++ separately but only as a static library. If a
|
||||
program also needs to link against libstdc++, it will provide its
|
||||
own copy of libsupc++ and this can lead to subtle problems.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ make cxx
|
||||
$ make install
|
||||
|
||||
You can now run clang with -stdlib=libc++.
|
||||
|
||||
|
||||
.. _libcxxrt_ref:
|
||||
|
||||
Using libcxxrt on Linux
|
||||
------------------------
|
||||
|
||||
@ -489,14 +549,11 @@ We can now run CMake like:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ CC=clang CXX=clang++ cmake -G "Unix Makefiles" \
|
||||
-DLIBCXX_CXX_ABI=libcxxrt \
|
||||
-DLIBCXX_CXX_ABI_INCLUDE_PATHS=path/to/libcxxrt-sources/src \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
<libc++-source-directory>
|
||||
$ make cxx
|
||||
$ make install
|
||||
$ cmake -G Ninja -S runtimes -B build \
|
||||
-DLLVM_ENABLE_RUNTIMES="libcxx" \
|
||||
-DLIBCXX_CXX_ABI=libcxxrt \
|
||||
-DLIBCXX_CXX_ABI_INCLUDE_PATHS=path/to/libcxxrt-sources/src
|
||||
$ ninja -C build install-cxx
|
||||
|
||||
Unfortunately you can't simply run clang with "-stdlib=libc++" at this point, as
|
||||
clang is set up to link for libc++ linked to libsupc++. To get around this
|
||||
@ -514,32 +571,4 @@ situations will give the same result:
|
||||
|
||||
$ clang++ -stdlib=libc++ helloworld.cpp -lcxxrt
|
||||
|
||||
.. _`libcxxrt`: https://github.com/pathscale/libcxxrt/
|
||||
|
||||
|
||||
Using a local ABI library installation
|
||||
---------------------------------------
|
||||
|
||||
.. warning::
|
||||
This is not recommended in almost all cases.
|
||||
|
||||
These instructions should only be used when you can't install your ABI library.
|
||||
|
||||
Normally you must link libc++ against a ABI shared library that the
|
||||
linker can find. If you want to build and test libc++ against an ABI
|
||||
library not in the linker's path you need to set
|
||||
``-DLIBCXX_CXX_ABI_LIBRARY_PATH=/path/to/abi/lib`` when configuring CMake.
|
||||
|
||||
An example build using libc++abi would look like:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ CC=clang CXX=clang++ cmake \
|
||||
-DLIBCXX_CXX_ABI=libc++abi \
|
||||
-DLIBCXX_CXX_ABI_INCLUDE_PATHS="/path/to/libcxxabi/include" \
|
||||
-DLIBCXX_CXX_ABI_LIBRARY_PATH="/path/to/libcxxabi-build/lib" \
|
||||
path/to/libcxx
|
||||
$ make
|
||||
|
||||
When testing libc++ LIT will automatically link against the proper ABI
|
||||
library.
|
||||
.. _`libcxxrt`: https://github.com/libcxxrt/libcxxrt
|
||||
|
181
docs/Contributing.rst
Normal file
181
docs/Contributing.rst
Normal file
@ -0,0 +1,181 @@
|
||||
.. _ContributingToLibcxx:
|
||||
|
||||
======================
|
||||
Contributing to libc++
|
||||
======================
|
||||
|
||||
This file contains notes about various tasks and processes specific to contributing
|
||||
to libc++. If this is your first time contributing, please also read `this document
|
||||
<https://www.llvm.org/docs/Contributing.html>`__ on general rules for contributing to LLVM.
|
||||
|
||||
For libc++, please make sure you follow `these instructions <https://www.llvm.org/docs/Phabricator.html#requesting-a-review-via-the-command-line>`_
|
||||
for submitting a code review from the command-line using ``arc``, since we have some
|
||||
automation (e.g. CI) that depends on the review being submitted that way.
|
||||
|
||||
If you plan on contributing to libc++, it can be useful to join the ``#libcxx`` channel
|
||||
on `LLVM's Discord server <https://discord.gg/jzUbyP26tQ>`__.
|
||||
|
||||
Looking for pre-existing reviews
|
||||
================================
|
||||
|
||||
Before you start working on any feature, please take a look at the open reviews
|
||||
to avoid duplicating someone else's work. You can do that by going to the website
|
||||
where code reviews are held, `Differential <https://reviews.llvm.org/differential>`__,
|
||||
and clicking on ``Libc++ Open Reviews`` in the sidebar to the left. If you see
|
||||
that your feature is already being worked on, please consider chiming in instead
|
||||
of duplicating work!
|
||||
|
||||
Pre-commit check list
|
||||
=====================
|
||||
|
||||
Before committing or creating a review, please go through this check-list to make
|
||||
sure you don't forget anything:
|
||||
|
||||
- Do you have tests for every public class and/or function you're adding or modifying?
|
||||
- Did you update the synopsis of the relevant headers?
|
||||
- Did you update the relevant files to track implementation status (in ``docs/Status/``)?
|
||||
- Did you mark all functions and type declarations with the :ref:`proper visibility macro <visibility-macros>`?
|
||||
- If you added a header:
|
||||
|
||||
- Did you add it to ``include/module.modulemap``?
|
||||
- Did you add it to ``include/CMakeLists.txt``?
|
||||
- If it's a public header, did you add a test under ``test/libcxx`` that the new header defines ``_LIBCPP_VERSION``? See ``test/libcxx/algorithms/version.pass.cpp`` for an example. NOTE: This should be automated.
|
||||
- If it's a public header, did you update ``utils/generate_header_inclusion_tests.py``?
|
||||
|
||||
- Did you add the relevant feature test macro(s) for your feature? Did you update the ``generate_feature_test_macro_components.py`` script with it?
|
||||
- Did you run the ``libcxx-generate-files`` target and verify its output?
|
||||
|
||||
The review process
|
||||
==================
|
||||
|
||||
After uploading your patch, you should see that the "libc++" review group is automatically
|
||||
added as a reviewer for your patch. Once the group is marked as having approved your patch,
|
||||
you can commit it. However, if you get an approval very quickly for a significant patch,
|
||||
please try to wait a couple of business days before committing to give the opportunity for
|
||||
other reviewers to chime in. If you need someone else to commit the patch for you, please
|
||||
mention it and provide your ``Name <email@domain>`` for us to attribute the commit properly.
|
||||
|
||||
Note that the rule for accepting as the "libc++" review group is to wait for two members
|
||||
of the group to have approved the patch, excluding the patch author. This is not a hard
|
||||
rule -- for very simple patches, use your judgement. The `"libc++" review group <https://reviews.llvm.org/project/members/64/>`__
|
||||
consists of frequent libc++ contributors with a good understanding of the project's
|
||||
guidelines -- if you would like to be added to it, please reach out on Discord.
|
||||
|
||||
Post-release check list
|
||||
=======================
|
||||
|
||||
After branching for an LLVM release:
|
||||
|
||||
1. Update ``_LIBCPP_VERSION`` in ``include/__config``
|
||||
2. Update the ``include/__libcpp_version`` file
|
||||
3. Update the version number in ``docs/conf.py``
|
||||
|
||||
Exporting new symbols from the library
|
||||
======================================
|
||||
|
||||
When exporting new symbols from libc++, you must update the ABI lists located in ``lib/abi``.
|
||||
To test whether the lists are up-to-date, please run the target ``check-cxx-abilist``.
|
||||
To regenerate the lists, use the target ``generate-cxx-abilist``.
|
||||
The ABI lists must be updated for all supported platforms; currently Linux and
|
||||
Apple. If you don't have access to one of these platforms, you can download an
|
||||
updated list from the failed build at
|
||||
`Buildkite <https://buildkite.com/llvm-project/libcxx-ci>`__.
|
||||
Look for the failed build and select the ``artifacts`` tab. There, download the
|
||||
abilist for the platform, e.g.:
|
||||
|
||||
* C++20 for the Linux platform.
|
||||
* MacOS C++20 for the Apple platform.
|
||||
|
||||
Working on large features
|
||||
=========================
|
||||
|
||||
Libc++ makes no guarantees about the implementation status or the ABI stability
|
||||
of features that have not yet been ratified in the C++ Standard. After the C++
|
||||
Standard is ratified libc++ promises a conforming and ABI-stable
|
||||
implementation. When working on a large new feature in the ratified version of
|
||||
the C++ Standard that can't be finished before the next release branch is
|
||||
created, we can't honor this promise. Another reason for not being able to
|
||||
promise ABI stability happens when the C++ Standard committee retroactively
|
||||
accepts ABI breaking papers as defect reports against the ratified C++
|
||||
Standard.
|
||||
|
||||
When working on these features it should be possible for libc++ vendors to
|
||||
disable these incomplete features, so they can promise ABI stability to their
|
||||
customers. This is done by the CMake option
|
||||
``LIBCXX_ENABLE_INCOMPLETE_FEATURES``. When start working on a large feature
|
||||
the following steps are required to guard the new library with the CMake
|
||||
option.
|
||||
|
||||
* ``libcxx/CMakeLists.txt``: Add
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
config_define_if_not(LIBCXX_ENABLE_INCOMPLETE_FEATURES _LIBCPP_HAS_NO_INCOMPLETE_FOO)
|
||||
|
||||
* ``libcxx/include/__config_site.in``: Add
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
#cmakedefine _LIBCPP_HAS_NO_INCOMPLETE_FOO
|
||||
|
||||
* ``libcxx/include/foo``: The contents of the file should be guarded in an
|
||||
``ifdef`` and always include ``<version>``
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
#ifndef _LIBCPP_FOO
|
||||
#define _LIBCPP_FOO
|
||||
|
||||
// Make sure all feature-test macros are available.
|
||||
#include <version>
|
||||
// Enable the contents of the header only when libc++ was built with LIBCXX_ENABLE_INCOMPLETE_FEATURES.
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FOO)
|
||||
|
||||
...
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_FO0)
|
||||
#endif // _LIBCPP_FOO
|
||||
|
||||
* ``libcxx/src/CMakeLists.txt``: When the library has a file ``foo.cpp`` it
|
||||
should only be added when ``LIBCXX_ENABLE_INCOMPLETE_FEATURES`` is enabled
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
if(LIBCXX_ENABLE_INCOMPLETE_FEATURES)
|
||||
list(APPEND LIBCXX_SOURCES
|
||||
foo.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
* ``libcxx/utils/generate_feature_test_macro_components.py``: Add to
|
||||
``lit_markup``
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
"foo": ["UNSUPPORTED: libcpp-has-no-incomplete-foo"],
|
||||
|
||||
* ``libcxx/utils/generate_header_inclusion_tests.py``: Add to ``lit_markup``
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
"foo": ["UNSUPPORTED: libcpp-has-no-incomplete-foo"],
|
||||
|
||||
* ``libcxx/utils/generate_header_tests.py``: Add to ``header_markup``
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
"foo": ["ifndef _LIBCPP_HAS_NO_INCOMPLETE_FOO"],
|
||||
|
||||
* ``libcxx/utils/libcxx/test/features.py``: Add to ``macros``
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
'_LIBCPP_HAS_NO_INCOMPLETE_FOO': 'libcpp-has-no-incomplete-foo',
|
||||
|
||||
* All tests that include ``<foo>`` should contain
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
// UNSUPPORTED: libcpp-has-no-incomplete-foo
|
||||
|
||||
Once the library is complete these changes and guards should be removed.
|
@ -3,15 +3,22 @@
|
||||
Libc++ ABI stability
|
||||
====================
|
||||
|
||||
Libc++ aims to preserve stable ABI to avoid subtle bugs when code built to the old ABI
|
||||
is linked with the code build to the new ABI. At the same time, libc++ allows ABI-breaking
|
||||
improvements and bugfixes for the scenarios when ABI change is not a issue.
|
||||
Libc++ aims to preserve a stable ABI to avoid subtle bugs when code built under the old ABI
|
||||
is linked with code built under the new ABI. At the same time, libc++ wants to make
|
||||
ABI-breaking improvements and bugfixes in scenarios where the user doesn't mind ABI breaks.
|
||||
|
||||
To support both cases, libc++ allows specifying the ABI version at the
|
||||
build time. The version is defined with a cmake option
|
||||
LIBCXX_ABI_VERSION. Another option LIBCXX_ABI_UNSTABLE can be used to
|
||||
include all present ABI breaking features. These options translate
|
||||
into C++ macro definitions _LIBCPP_ABI_VERSION, _LIBCPP_ABI_UNSTABLE.
|
||||
To support both cases, libc++ allows specifying an ABI version at
|
||||
build time. The version is defined with CMake option ``LIBCXX_ABI_VERSION``.
|
||||
Currently supported values are ``1`` (the stable default)
|
||||
and ``2`` (the unstable "next" version). At some point "ABI version 2" will be
|
||||
frozen and new ABI-breaking changes will start being applied to version ``3``;
|
||||
but this has not happened yet.
|
||||
|
||||
Any ABI-changing feature is placed under it's own macro, _LIBCPP_ABI_XXX, which is enabled
|
||||
based on the value of _LIBCPP_ABI_VERSION. _LIBCPP_ABI_UNSTABLE, if set, enables all features at once.
|
||||
To always use the most cutting-edge, most unstable ABI (which is currently ``2``
|
||||
but at some point will become ``3``), set the CMake option ``LIBCXX_ABI_UNSTABLE``.
|
||||
|
||||
Internally, each ABI-changing feature is placed under its own C++ macro,
|
||||
``_LIBCPP_ABI_XXX``. These macros' definitions are controlled by the C++ macro
|
||||
``_LIBCPP_ABI_VERSION``, which is controlled by the ``LIBCXX_ABI_VERSION`` set
|
||||
at build time. Libc++ does not intend users to interact with these C++ macros
|
||||
directly.
|
||||
|
797
docs/DesignDocs/AtomicDesign.rst
Normal file
797
docs/DesignDocs/AtomicDesign.rst
Normal file
@ -0,0 +1,797 @@
|
||||
|
||||
====================
|
||||
``<atomic>`` Design
|
||||
====================
|
||||
|
||||
There were originally 3 designs under consideration. They differ in where most
|
||||
of the implementation work is done. The functionality exposed to the customer
|
||||
should be identical (and conforming) for all three designs.
|
||||
|
||||
|
||||
Design A: Minimal work for the library
|
||||
======================================
|
||||
The compiler supplies all of the intrinsics as described below. This list of
|
||||
intrinsics roughly parallels the requirements of the C and C++ atomics proposals.
|
||||
The C and C++ library implementations simply drop through to these intrinsics.
|
||||
Anything the platform does not support in hardware, the compiler
|
||||
arranges for a (compiler-rt) library call to be made which will do the job with
|
||||
a mutex, and in this case ignoring the memory ordering parameter (effectively
|
||||
implementing ``memory_order_seq_cst``).
|
||||
|
||||
Ultimate efficiency is preferred over run time error checking. Undefined
|
||||
behavior is acceptable when the inputs do not conform as defined below.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// In every intrinsic signature below, type* atomic_obj may be a pointer to a
|
||||
// volatile-qualified type. Memory ordering values map to the following meanings:
|
||||
// memory_order_relaxed == 0
|
||||
// memory_order_consume == 1
|
||||
// memory_order_acquire == 2
|
||||
// memory_order_release == 3
|
||||
// memory_order_acq_rel == 4
|
||||
// memory_order_seq_cst == 5
|
||||
|
||||
// type must be trivially copyable
|
||||
// type represents a "type argument"
|
||||
bool __atomic_is_lock_free(type);
|
||||
|
||||
// type must be trivially copyable
|
||||
// Behavior is defined for mem_ord = 0, 1, 2, 5
|
||||
type __atomic_load(const type* atomic_obj, int mem_ord);
|
||||
|
||||
// type must be trivially copyable
|
||||
// Behavior is defined for mem_ord = 0, 3, 5
|
||||
void __atomic_store(type* atomic_obj, type desired, int mem_ord);
|
||||
|
||||
// type must be trivially copyable
|
||||
// Behavior is defined for mem_ord = [0 ... 5]
|
||||
type __atomic_exchange(type* atomic_obj, type desired, int mem_ord);
|
||||
|
||||
// type must be trivially copyable
|
||||
// Behavior is defined for mem_success = [0 ... 5],
|
||||
// mem_failure <= mem_success
|
||||
// mem_failure != 3
|
||||
// mem_failure != 4
|
||||
bool __atomic_compare_exchange_strong(type* atomic_obj,
|
||||
type* expected, type desired,
|
||||
int mem_success, int mem_failure);
|
||||
|
||||
// type must be trivially copyable
|
||||
// Behavior is defined for mem_success = [0 ... 5],
|
||||
// mem_failure <= mem_success
|
||||
// mem_failure != 3
|
||||
// mem_failure != 4
|
||||
bool __atomic_compare_exchange_weak(type* atomic_obj,
|
||||
type* expected, type desired,
|
||||
int mem_success, int mem_failure);
|
||||
|
||||
// type is one of: char, signed char, unsigned char, short, unsigned short, int,
|
||||
// unsigned int, long, unsigned long, long long, unsigned long long,
|
||||
// char16_t, char32_t, wchar_t
|
||||
// Behavior is defined for mem_ord = [0 ... 5]
|
||||
type __atomic_fetch_add(type* atomic_obj, type operand, int mem_ord);
|
||||
|
||||
// type is one of: char, signed char, unsigned char, short, unsigned short, int,
|
||||
// unsigned int, long, unsigned long, long long, unsigned long long,
|
||||
// char16_t, char32_t, wchar_t
|
||||
// Behavior is defined for mem_ord = [0 ... 5]
|
||||
type __atomic_fetch_sub(type* atomic_obj, type operand, int mem_ord);
|
||||
|
||||
// type is one of: char, signed char, unsigned char, short, unsigned short, int,
|
||||
// unsigned int, long, unsigned long, long long, unsigned long long,
|
||||
// char16_t, char32_t, wchar_t
|
||||
// Behavior is defined for mem_ord = [0 ... 5]
|
||||
type __atomic_fetch_and(type* atomic_obj, type operand, int mem_ord);
|
||||
|
||||
// type is one of: char, signed char, unsigned char, short, unsigned short, int,
|
||||
// unsigned int, long, unsigned long, long long, unsigned long long,
|
||||
// char16_t, char32_t, wchar_t
|
||||
// Behavior is defined for mem_ord = [0 ... 5]
|
||||
type __atomic_fetch_or(type* atomic_obj, type operand, int mem_ord);
|
||||
|
||||
// type is one of: char, signed char, unsigned char, short, unsigned short, int,
|
||||
// unsigned int, long, unsigned long, long long, unsigned long long,
|
||||
// char16_t, char32_t, wchar_t
|
||||
// Behavior is defined for mem_ord = [0 ... 5]
|
||||
type __atomic_fetch_xor(type* atomic_obj, type operand, int mem_ord);
|
||||
|
||||
// Behavior is defined for mem_ord = [0 ... 5]
|
||||
void* __atomic_fetch_add(void** atomic_obj, ptrdiff_t operand, int mem_ord);
|
||||
void* __atomic_fetch_sub(void** atomic_obj, ptrdiff_t operand, int mem_ord);
|
||||
|
||||
// Behavior is defined for mem_ord = [0 ... 5]
|
||||
void __atomic_thread_fence(int mem_ord);
|
||||
void __atomic_signal_fence(int mem_ord);
|
||||
|
||||
If desired the intrinsics taking a single ``mem_ord`` parameter can default
|
||||
this argument to 5.
|
||||
|
||||
If desired the intrinsics taking two ordering parameters can default ``mem_success``
|
||||
to 5, and ``mem_failure`` to ``translate_memory_order(mem_success)`` where
|
||||
``translate_memory_order(mem_success)`` is defined as:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
int translate_memory_order(int o) {
|
||||
switch (o) {
|
||||
case 4:
|
||||
return 2;
|
||||
case 3:
|
||||
return 0;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
Below are representative C++ implementations of all of the operations. Their
|
||||
purpose is to document the desired semantics of each operation, assuming
|
||||
``memory_order_seq_cst``. This is essentially the code that will be called
|
||||
if the front end calls out to compiler-rt.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
template <class T>
|
||||
T __atomic_load(T const volatile* obj) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
return *obj;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void __atomic_store(T volatile* obj, T desr) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
*obj = desr;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T __atomic_exchange(T volatile* obj, T desr) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
T r = *obj;
|
||||
*obj = desr;
|
||||
return r;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool __atomic_compare_exchange_strong(T volatile* obj, T* exp, T desr) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
if (std::memcmp(const_cast<T*>(obj), exp, sizeof(T)) == 0) // if (*obj == *exp)
|
||||
{
|
||||
std::memcpy(const_cast<T*>(obj), &desr, sizeof(T)); // *obj = desr;
|
||||
return true;
|
||||
}
|
||||
std::memcpy(exp, const_cast<T*>(obj), sizeof(T)); // *exp = *obj;
|
||||
return false;
|
||||
}
|
||||
|
||||
// May spuriously return false (even if *obj == *exp)
|
||||
template <class T>
|
||||
bool __atomic_compare_exchange_weak(T volatile* obj, T* exp, T desr) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
if (std::memcmp(const_cast<T*>(obj), exp, sizeof(T)) == 0) // if (*obj == *exp)
|
||||
{
|
||||
std::memcpy(const_cast<T*>(obj), &desr, sizeof(T)); // *obj = desr;
|
||||
return true;
|
||||
}
|
||||
std::memcpy(exp, const_cast<T*>(obj), sizeof(T)); // *exp = *obj;
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T __atomic_fetch_add(T volatile* obj, T operand) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
T r = *obj;
|
||||
*obj += operand;
|
||||
return r;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T __atomic_fetch_sub(T volatile* obj, T operand) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
T r = *obj;
|
||||
*obj -= operand;
|
||||
return r;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T __atomic_fetch_and(T volatile* obj, T operand) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
T r = *obj;
|
||||
*obj &= operand;
|
||||
return r;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T __atomic_fetch_or(T volatile* obj, T operand) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
T r = *obj;
|
||||
*obj |= operand;
|
||||
return r;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T __atomic_fetch_xor(T volatile* obj, T operand) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
T r = *obj;
|
||||
*obj ^= operand;
|
||||
return r;
|
||||
}
|
||||
|
||||
void* __atomic_fetch_add(void* volatile* obj, ptrdiff_t operand) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
void* r = *obj;
|
||||
(char*&)(*obj) += operand;
|
||||
return r;
|
||||
}
|
||||
|
||||
void* __atomic_fetch_sub(void* volatile* obj, ptrdiff_t operand) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
void* r = *obj;
|
||||
(char*&)(*obj) -= operand;
|
||||
return r;
|
||||
}
|
||||
|
||||
void __atomic_thread_fence() {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
}
|
||||
|
||||
void __atomic_signal_fence() {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
}
|
||||
|
||||
|
||||
Design B: Something in between
|
||||
==============================
|
||||
This is a variation of design A which puts the burden on the library to arrange
|
||||
for the correct manipulation of the run time memory ordering arguments, and only
|
||||
calls the compiler for well-defined memory orderings. I think of this design as
|
||||
the worst of A and C, instead of the best of A and C. But I offer it as an
|
||||
option in the spirit of completeness.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// type must be trivially copyable
|
||||
bool __atomic_is_lock_free(const type* atomic_obj);
|
||||
|
||||
// type must be trivially copyable
|
||||
type __atomic_load_relaxed(const volatile type* atomic_obj);
|
||||
type __atomic_load_consume(const volatile type* atomic_obj);
|
||||
type __atomic_load_acquire(const volatile type* atomic_obj);
|
||||
type __atomic_load_seq_cst(const volatile type* atomic_obj);
|
||||
|
||||
// type must be trivially copyable
|
||||
type __atomic_store_relaxed(volatile type* atomic_obj, type desired);
|
||||
type __atomic_store_release(volatile type* atomic_obj, type desired);
|
||||
type __atomic_store_seq_cst(volatile type* atomic_obj, type desired);
|
||||
|
||||
// type must be trivially copyable
|
||||
type __atomic_exchange_relaxed(volatile type* atomic_obj, type desired);
|
||||
type __atomic_exchange_consume(volatile type* atomic_obj, type desired);
|
||||
type __atomic_exchange_acquire(volatile type* atomic_obj, type desired);
|
||||
type __atomic_exchange_release(volatile type* atomic_obj, type desired);
|
||||
type __atomic_exchange_acq_rel(volatile type* atomic_obj, type desired);
|
||||
type __atomic_exchange_seq_cst(volatile type* atomic_obj, type desired);
|
||||
|
||||
// type must be trivially copyable
|
||||
bool __atomic_compare_exchange_strong_relaxed_relaxed(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_strong_consume_relaxed(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_strong_consume_consume(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_strong_acquire_relaxed(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_strong_acquire_consume(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_strong_acquire_acquire(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_strong_release_relaxed(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_strong_release_consume(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_strong_release_acquire(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_strong_acq_rel_relaxed(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_strong_acq_rel_consume(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_strong_acq_rel_acquire(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_strong_seq_cst_relaxed(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_strong_seq_cst_consume(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_strong_seq_cst_acquire(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_strong_seq_cst_seq_cst(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
|
||||
// type must be trivially copyable
|
||||
bool __atomic_compare_exchange_weak_relaxed_relaxed(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_weak_consume_relaxed(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_weak_consume_consume(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_weak_acquire_relaxed(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_weak_acquire_consume(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_weak_acquire_acquire(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_weak_release_relaxed(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_weak_release_consume(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_weak_release_acquire(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_weak_acq_rel_relaxed(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_weak_acq_rel_consume(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_weak_acq_rel_acquire(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_weak_seq_cst_relaxed(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_weak_seq_cst_consume(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_weak_seq_cst_acquire(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
bool __atomic_compare_exchange_weak_seq_cst_seq_cst(volatile type* atomic_obj,
|
||||
type* expected,
|
||||
type desired);
|
||||
|
||||
// type is one of: char, signed char, unsigned char, short, unsigned short, int,
|
||||
// unsigned int, long, unsigned long, long long, unsigned long long,
|
||||
// char16_t, char32_t, wchar_t
|
||||
type __atomic_fetch_add_relaxed(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_add_consume(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_add_acquire(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_add_release(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_add_acq_rel(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_add_seq_cst(volatile type* atomic_obj, type operand);
|
||||
|
||||
// type is one of: char, signed char, unsigned char, short, unsigned short, int,
|
||||
// unsigned int, long, unsigned long, long long, unsigned long long,
|
||||
// char16_t, char32_t, wchar_t
|
||||
type __atomic_fetch_sub_relaxed(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_sub_consume(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_sub_acquire(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_sub_release(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_sub_acq_rel(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_sub_seq_cst(volatile type* atomic_obj, type operand);
|
||||
|
||||
// type is one of: char, signed char, unsigned char, short, unsigned short, int,
|
||||
// unsigned int, long, unsigned long, long long, unsigned long long,
|
||||
// char16_t, char32_t, wchar_t
|
||||
type __atomic_fetch_and_relaxed(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_and_consume(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_and_acquire(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_and_release(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_and_acq_rel(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_and_seq_cst(volatile type* atomic_obj, type operand);
|
||||
|
||||
// type is one of: char, signed char, unsigned char, short, unsigned short, int,
|
||||
// unsigned int, long, unsigned long, long long, unsigned long long,
|
||||
// char16_t, char32_t, wchar_t
|
||||
type __atomic_fetch_or_relaxed(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_or_consume(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_or_acquire(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_or_release(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_or_acq_rel(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_or_seq_cst(volatile type* atomic_obj, type operand);
|
||||
|
||||
// type is one of: char, signed char, unsigned char, short, unsigned short, int,
|
||||
// unsigned int, long, unsigned long, long long, unsigned long long,
|
||||
// char16_t, char32_t, wchar_t
|
||||
type __atomic_fetch_xor_relaxed(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_xor_consume(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_xor_acquire(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_xor_release(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_xor_acq_rel(volatile type* atomic_obj, type operand);
|
||||
type __atomic_fetch_xor_seq_cst(volatile type* atomic_obj, type operand);
|
||||
|
||||
void* __atomic_fetch_add_relaxed(void* volatile* atomic_obj, ptrdiff_t operand);
|
||||
void* __atomic_fetch_add_consume(void* volatile* atomic_obj, ptrdiff_t operand);
|
||||
void* __atomic_fetch_add_acquire(void* volatile* atomic_obj, ptrdiff_t operand);
|
||||
void* __atomic_fetch_add_release(void* volatile* atomic_obj, ptrdiff_t operand);
|
||||
void* __atomic_fetch_add_acq_rel(void* volatile* atomic_obj, ptrdiff_t operand);
|
||||
void* __atomic_fetch_add_seq_cst(void* volatile* atomic_obj, ptrdiff_t operand);
|
||||
|
||||
void* __atomic_fetch_sub_relaxed(void* volatile* atomic_obj, ptrdiff_t operand);
|
||||
void* __atomic_fetch_sub_consume(void* volatile* atomic_obj, ptrdiff_t operand);
|
||||
void* __atomic_fetch_sub_acquire(void* volatile* atomic_obj, ptrdiff_t operand);
|
||||
void* __atomic_fetch_sub_release(void* volatile* atomic_obj, ptrdiff_t operand);
|
||||
void* __atomic_fetch_sub_acq_rel(void* volatile* atomic_obj, ptrdiff_t operand);
|
||||
void* __atomic_fetch_sub_seq_cst(void* volatile* atomic_obj, ptrdiff_t operand);
|
||||
|
||||
void __atomic_thread_fence_relaxed();
|
||||
void __atomic_thread_fence_consume();
|
||||
void __atomic_thread_fence_acquire();
|
||||
void __atomic_thread_fence_release();
|
||||
void __atomic_thread_fence_acq_rel();
|
||||
void __atomic_thread_fence_seq_cst();
|
||||
|
||||
void __atomic_signal_fence_relaxed();
|
||||
void __atomic_signal_fence_consume();
|
||||
void __atomic_signal_fence_acquire();
|
||||
void __atomic_signal_fence_release();
|
||||
void __atomic_signal_fence_acq_rel();
|
||||
void __atomic_signal_fence_seq_cst();
|
||||
|
||||
Design C: Minimal work for the front end
|
||||
========================================
|
||||
The ``<atomic>`` header is one of the most closely coupled headers to the compiler.
|
||||
Ideally when you invoke any function from ``<atomic>``, it should result in highly
|
||||
optimized assembly being inserted directly into your application -- assembly that
|
||||
is not otherwise representable by higher level C or C++ expressions. The design of
|
||||
the libc++ ``<atomic>`` header started with this goal in mind. A secondary, but
|
||||
still very important goal is that the compiler should have to do minimal work to
|
||||
facilitate the implementation of ``<atomic>``. Without this second goal, then
|
||||
practically speaking, the libc++ ``<atomic>`` header would be doomed to be a
|
||||
barely supported, second class citizen on almost every platform.
|
||||
|
||||
Goals:
|
||||
|
||||
- Optimal code generation for atomic operations
|
||||
- Minimal effort for the compiler to achieve goal 1 on any given platform
|
||||
- Conformance to the C++0X draft standard
|
||||
|
||||
The purpose of this document is to inform compiler writers what they need to do
|
||||
to enable a high performance libc++ ``<atomic>`` with minimal effort.
|
||||
|
||||
The minimal work that must be done for a conforming ``<atomic>``
|
||||
----------------------------------------------------------------
|
||||
The only "atomic" operations that must actually be lock free in
|
||||
``<atomic>`` are represented by the following compiler intrinsics:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
__atomic_flag__ __atomic_exchange_seq_cst(__atomic_flag__ volatile* obj, __atomic_flag__ desr) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
__atomic_flag__ result = *obj;
|
||||
*obj = desr;
|
||||
return result;
|
||||
}
|
||||
|
||||
void __atomic_store_seq_cst(__atomic_flag__ volatile* obj, __atomic_flag__ desr) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
*obj = desr;
|
||||
}
|
||||
|
||||
Where:
|
||||
|
||||
- If ``__has_feature(__atomic_flag)`` evaluates to 1 in the preprocessor then
|
||||
the compiler must define ``__atomic_flag__`` (e.g. as a typedef to ``int``).
|
||||
- If ``__has_feature(__atomic_flag)`` evaluates to 0 in the preprocessor then
|
||||
the library defines ``__atomic_flag__`` as a typedef to ``bool``.
|
||||
- To communicate that the above intrinsics are available, the compiler must
|
||||
arrange for ``__has_feature`` to return 1 when fed the intrinsic name
|
||||
appended with an '_' and the mangled type name of ``__atomic_flag__``.
|
||||
|
||||
For example if ``__atomic_flag__`` is ``unsigned int``:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// __has_feature(__atomic_flag) == 1
|
||||
// __has_feature(__atomic_exchange_seq_cst_j) == 1
|
||||
// __has_feature(__atomic_store_seq_cst_j) == 1
|
||||
|
||||
typedef unsigned int __atomic_flag__;
|
||||
|
||||
unsigned int __atomic_exchange_seq_cst(unsigned int volatile*, unsigned int) {
|
||||
// ...
|
||||
}
|
||||
|
||||
void __atomic_store_seq_cst(unsigned int volatile*, unsigned int) {
|
||||
// ...
|
||||
}
|
||||
|
||||
That's it! Compiler writers do the above and you've got a fully conforming
|
||||
(though sub-par performance) ``<atomic>`` header!
|
||||
|
||||
|
||||
Recommended work for a higher performance ``<atomic>``
|
||||
------------------------------------------------------
|
||||
It would be good if the above intrinsics worked with all integral types plus
|
||||
``void*``. Because this may not be possible to do in a lock-free manner for
|
||||
all integral types on all platforms, a compiler must communicate each type that
|
||||
an intrinsic works with. For example, if ``__atomic_exchange_seq_cst`` works
|
||||
for all types except for ``long long`` and ``unsigned long long`` then:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
__has_feature(__atomic_exchange_seq_cst_b) == 1 // bool
|
||||
__has_feature(__atomic_exchange_seq_cst_c) == 1 // char
|
||||
__has_feature(__atomic_exchange_seq_cst_a) == 1 // signed char
|
||||
__has_feature(__atomic_exchange_seq_cst_h) == 1 // unsigned char
|
||||
__has_feature(__atomic_exchange_seq_cst_Ds) == 1 // char16_t
|
||||
__has_feature(__atomic_exchange_seq_cst_Di) == 1 // char32_t
|
||||
__has_feature(__atomic_exchange_seq_cst_w) == 1 // wchar_t
|
||||
__has_feature(__atomic_exchange_seq_cst_s) == 1 // short
|
||||
__has_feature(__atomic_exchange_seq_cst_t) == 1 // unsigned short
|
||||
__has_feature(__atomic_exchange_seq_cst_i) == 1 // int
|
||||
__has_feature(__atomic_exchange_seq_cst_j) == 1 // unsigned int
|
||||
__has_feature(__atomic_exchange_seq_cst_l) == 1 // long
|
||||
__has_feature(__atomic_exchange_seq_cst_m) == 1 // unsigned long
|
||||
__has_feature(__atomic_exchange_seq_cst_Pv) == 1 // void*
|
||||
|
||||
Note that only the ``__has_feature`` flag is decorated with the argument
|
||||
type. The name of the compiler intrinsic is not decorated, but instead works
|
||||
like a C++ overloaded function.
|
||||
|
||||
Additionally, there are other intrinsics besides ``__atomic_exchange_seq_cst``
|
||||
and ``__atomic_store_seq_cst``. They are optional. But if the compiler can
|
||||
generate faster code than provided by the library, then clients will benefit
|
||||
from the compiler writer's expertise and knowledge of the targeted platform.
|
||||
|
||||
Below is the complete list of *sequentially consistent* intrinsics, and
|
||||
their library implementations. Template syntax is used to indicate the desired
|
||||
overloading for integral and ``void*`` types. The template does not represent a
|
||||
requirement that the intrinsic operate on **any** type!
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// T is one of:
|
||||
// bool, char, signed char, unsigned char, short, unsigned short,
|
||||
// int, unsigned int, long, unsigned long,
|
||||
// long long, unsigned long long, char16_t, char32_t, wchar_t, void*
|
||||
|
||||
template <class T>
|
||||
T __atomic_load_seq_cst(T const volatile* obj) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
return *obj;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void __atomic_store_seq_cst(T volatile* obj, T desr) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
*obj = desr;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T __atomic_exchange_seq_cst(T volatile* obj, T desr) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
T r = *obj;
|
||||
*obj = desr;
|
||||
return r;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool __atomic_compare_exchange_strong_seq_cst_seq_cst(T volatile* obj, T* exp, T desr) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
if (std::memcmp(const_cast<T*>(obj), exp, sizeof(T)) == 0) {
|
||||
std::memcpy(const_cast<T*>(obj), &desr, sizeof(T));
|
||||
return true;
|
||||
}
|
||||
std::memcpy(exp, const_cast<T*>(obj), sizeof(T));
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool __atomic_compare_exchange_weak_seq_cst_seq_cst(T volatile* obj, T* exp, T desr) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
if (std::memcmp(const_cast<T*>(obj), exp, sizeof(T)) == 0)
|
||||
{
|
||||
std::memcpy(const_cast<T*>(obj), &desr, sizeof(T));
|
||||
return true;
|
||||
}
|
||||
std::memcpy(exp, const_cast<T*>(obj), sizeof(T));
|
||||
return false;
|
||||
}
|
||||
|
||||
// T is one of:
|
||||
// char, signed char, unsigned char, short, unsigned short,
|
||||
// int, unsigned int, long, unsigned long,
|
||||
// long long, unsigned long long, char16_t, char32_t, wchar_t
|
||||
|
||||
template <class T>
|
||||
T __atomic_fetch_add_seq_cst(T volatile* obj, T operand) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
T r = *obj;
|
||||
*obj += operand;
|
||||
return r;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T __atomic_fetch_sub_seq_cst(T volatile* obj, T operand) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
T r = *obj;
|
||||
*obj -= operand;
|
||||
return r;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T __atomic_fetch_and_seq_cst(T volatile* obj, T operand) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
T r = *obj;
|
||||
*obj &= operand;
|
||||
return r;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T __atomic_fetch_or_seq_cst(T volatile* obj, T operand) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
T r = *obj;
|
||||
*obj |= operand;
|
||||
return r;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T __atomic_fetch_xor_seq_cst(T volatile* obj, T operand) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
T r = *obj;
|
||||
*obj ^= operand;
|
||||
return r;
|
||||
}
|
||||
|
||||
void* __atomic_fetch_add_seq_cst(void* volatile* obj, ptrdiff_t operand) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
void* r = *obj;
|
||||
(char*&)(*obj) += operand;
|
||||
return r;
|
||||
}
|
||||
|
||||
void* __atomic_fetch_sub_seq_cst(void* volatile* obj, ptrdiff_t operand) {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
void* r = *obj;
|
||||
(char*&)(*obj) -= operand;
|
||||
return r;
|
||||
}
|
||||
|
||||
void __atomic_thread_fence_seq_cst() {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
}
|
||||
|
||||
void __atomic_signal_fence_seq_cst() {
|
||||
unique_lock<mutex> _(some_mutex);
|
||||
}
|
||||
|
||||
One should consult the (currently draft) `C++ Standard <https://wg21.link/n3126>`_
|
||||
for the details of the definitions for these operations. For example,
|
||||
``__atomic_compare_exchange_weak_seq_cst_seq_cst`` is allowed to fail
|
||||
spuriously while ``__atomic_compare_exchange_strong_seq_cst_seq_cst`` is not.
|
||||
|
||||
If on your platform the lock-free definition of ``__atomic_compare_exchange_weak_seq_cst_seq_cst``
|
||||
would be the same as ``__atomic_compare_exchange_strong_seq_cst_seq_cst``, you may omit the
|
||||
``__atomic_compare_exchange_weak_seq_cst_seq_cst`` intrinsic without a performance cost. The
|
||||
library will prefer your implementation of ``__atomic_compare_exchange_strong_seq_cst_seq_cst``
|
||||
over its own definition for implementing ``__atomic_compare_exchange_weak_seq_cst_seq_cst``.
|
||||
That is, the library will arrange for ``__atomic_compare_exchange_weak_seq_cst_seq_cst`` to call
|
||||
``__atomic_compare_exchange_strong_seq_cst_seq_cst`` if you supply an intrinsic for the strong
|
||||
version but not the weak.
|
||||
|
||||
Taking advantage of weaker memory synchronization
|
||||
-------------------------------------------------
|
||||
So far, all of the intrinsics presented require a **sequentially consistent** memory ordering.
|
||||
That is, no loads or stores can move across the operation (just as if the library had locked
|
||||
that internal mutex). But ``<atomic>`` supports weaker memory ordering operations. In all,
|
||||
there are six memory orderings (listed here from strongest to weakest):
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
memory_order_seq_cst
|
||||
memory_order_acq_rel
|
||||
memory_order_release
|
||||
memory_order_acquire
|
||||
memory_order_consume
|
||||
memory_order_relaxed
|
||||
|
||||
(See the `C++ Standard <https://wg21.link/n3126>`_ for the detailed definitions of each of these orderings).
|
||||
|
||||
On some platforms, the compiler vendor can offer some or even all of the above
|
||||
intrinsics at one or more weaker levels of memory synchronization. This might
|
||||
lead for example to not issuing an ``mfence`` instruction on the x86.
|
||||
|
||||
If the compiler does not offer any given operation, at any given memory ordering
|
||||
level, the library will automatically attempt to call the next highest memory
|
||||
ordering operation. This continues up to ``seq_cst``, and if that doesn't
|
||||
exist, then the library takes over and does the job with a ``mutex``. This
|
||||
is a compile-time search and selection operation. At run time, the application
|
||||
will only see the few inlined assembly instructions for the selected intrinsic.
|
||||
|
||||
Each intrinsic is appended with the 7-letter name of the memory ordering it
|
||||
addresses. For example a ``load`` with ``relaxed`` ordering is defined by:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
T __atomic_load_relaxed(const volatile T* obj);
|
||||
|
||||
And announced with:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
__has_feature(__atomic_load_relaxed_b) == 1 // bool
|
||||
__has_feature(__atomic_load_relaxed_c) == 1 // char
|
||||
__has_feature(__atomic_load_relaxed_a) == 1 // signed char
|
||||
...
|
||||
|
||||
The ``__atomic_compare_exchange_strong(weak)`` intrinsics are parameterized
|
||||
on two memory orderings. The first ordering applies when the operation returns
|
||||
``true`` and the second ordering applies when the operation returns ``false``.
|
||||
|
||||
Not every memory ordering is appropriate for every operation. ``exchange``
|
||||
and the ``fetch_XXX`` operations support all 6. But ``load`` only supports
|
||||
``relaxed``, ``consume``, ``acquire`` and ``seq_cst``. ``store`` only supports
|
||||
``relaxed``, ``release``, and ``seq_cst``. The ``compare_exchange`` operations
|
||||
support the following 16 combinations out of the possible 36:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
relaxed_relaxed
|
||||
consume_relaxed
|
||||
consume_consume
|
||||
acquire_relaxed
|
||||
acquire_consume
|
||||
acquire_acquire
|
||||
release_relaxed
|
||||
release_consume
|
||||
release_acquire
|
||||
acq_rel_relaxed
|
||||
acq_rel_consume
|
||||
acq_rel_acquire
|
||||
seq_cst_relaxed
|
||||
seq_cst_consume
|
||||
seq_cst_acquire
|
||||
seq_cst_seq_cst
|
||||
|
||||
Again, the compiler supplies intrinsics only for the strongest orderings where
|
||||
it can make a difference. The library takes care of calling the weakest
|
||||
supplied intrinsic that is as strong or stronger than the customer asked for.
|
||||
|
||||
Note about ABI
|
||||
==============
|
||||
With any design, the (back end) compiler writer should note that the decision to
|
||||
implement lock-free operations on any given type (or not) is an ABI-binding decision.
|
||||
One can not change from treating a type as not lock free, to lock free (or vice-versa)
|
||||
without breaking your ABI.
|
||||
|
||||
For example:
|
||||
|
||||
**TU1.cpp**:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
extern atomic<long long> A;
|
||||
int foo() { return A.compare_exchange_strong(w, x); }
|
||||
|
||||
|
||||
**TU2.cpp**:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
extern atomic<long long> A;
|
||||
void bar() { return A.compare_exchange_strong(y, z); }
|
||||
|
||||
If only **one** of these calls to ``compare_exchange_strong`` is implemented with
|
||||
mutex-locked code, then that mutex-locked code will not be executed mutually
|
||||
exclusively of the one implemented in a lock-free manner.
|
@ -1,105 +0,0 @@
|
||||
===================
|
||||
Availability Markup
|
||||
===================
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
Libc++ is used as a system library on macOS and iOS (amongst others). In order
|
||||
for users to be able to compile a binary that is intended to be deployed to an
|
||||
older version of the platform, clang provides the
|
||||
`availability attribute <https://clang.llvm.org/docs/AttributeReference.html#availability>`_
|
||||
that can be placed on declarations to describe the lifecycle of a symbol in the
|
||||
library.
|
||||
|
||||
Design
|
||||
======
|
||||
|
||||
When a new feature is introduced that requires dylib support, a macro should be
|
||||
created in include/__config to mark this feature as unavailable for all the
|
||||
systems. For example::
|
||||
|
||||
// Define availability macros.
|
||||
#if defined(_LIBCPP_USE_AVAILABILITY_APPLE)
|
||||
# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable))
|
||||
#else if defined(_LIBCPP_USE_AVAILABILITY_SOME_OTHER_VENDOR)
|
||||
# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable))
|
||||
#else
|
||||
# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
|
||||
#endif
|
||||
|
||||
When the library is updated by the platform vendor, the markup can be updated.
|
||||
For example::
|
||||
|
||||
#define _LIBCPP_AVAILABILITY_SHARED_MUTEX \
|
||||
__attribute__((availability(macosx,strict,introduced=10.12))) \
|
||||
__attribute__((availability(ios,strict,introduced=10.0))) \
|
||||
__attribute__((availability(tvos,strict,introduced=10.0))) \
|
||||
__attribute__((availability(watchos,strict,introduced=3.0)))
|
||||
|
||||
In the source code, the macro can be added on a class if the full class requires
|
||||
type info from the library for example::
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
|
||||
class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
|
||||
: public std::logic_error {
|
||||
|
||||
or on a particular symbol:
|
||||
|
||||
_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete(void* __p, std::size_t __sz) _NOEXCEPT;
|
||||
|
||||
Furthermore, a lit feature should be added to match that availability macro,
|
||||
so that tests depending on that feature can be marked to XFAIL if the feature
|
||||
is not supported. This way, the test suite will work on platforms that have
|
||||
not shipped the feature yet. This can be done by adding the appropriate lit
|
||||
feature in test/config.py.
|
||||
|
||||
|
||||
Testing
|
||||
=======
|
||||
|
||||
Some parameters can be passed to lit to run the test-suite and exercise the
|
||||
availability.
|
||||
|
||||
* The `platform` parameter controls the deployment target. For example lit can
|
||||
be invoked with `--param=platform=macosx10.8`. Default is the current host.
|
||||
* The `use_system_cxx_lib` parameter indicates to use another library than the
|
||||
just built one. Invoking lit with `--param=use_system_cxx_lib=true` will run
|
||||
the test-suite against the host system library. Alternatively a path to the
|
||||
directory containing a specific prebuilt libc++ can be used, for example:
|
||||
`--param=use_system_cxx_lib=/path/to/macOS/10.8/`.
|
||||
|
||||
Tests can be marked as XFAIL based on multiple features made available by lit:
|
||||
|
||||
|
||||
* if `--param=platform=macosx10.8` is passed, the following features will be available:
|
||||
|
||||
- availability
|
||||
- availability=x86_64
|
||||
- availability=macosx
|
||||
- availability=x86_64-macosx
|
||||
- availability=x86_64-apple-macosx10.8
|
||||
- availability=macosx10.8
|
||||
|
||||
This feature is used to XFAIL a test that *is* using a class or a method marked
|
||||
as unavailable *and* that is expected to *fail* if deployed on an older system.
|
||||
|
||||
* if `use_system_cxx_lib` and `--param=platform=macosx10.8` are passed to lit,
|
||||
the following features will also be available:
|
||||
|
||||
- with_system_cxx_lib
|
||||
- with_system_cxx_lib=x86_64
|
||||
- with_system_cxx_lib=macosx
|
||||
- with_system_cxx_lib=x86_64-macosx
|
||||
- with_system_cxx_lib=x86_64-apple-macosx10.8
|
||||
- with_system_cxx_lib=macosx10.8
|
||||
|
||||
This feature is used to XFAIL a test that is *not* using a class or a method
|
||||
marked as unavailable *but* that is expected to fail if deployed on an older
|
||||
system. For example, if the test exhibits a bug in the libc on a particular
|
||||
system version, or if the test uses a symbol that is not available on an
|
||||
older version of the dylib (but for which there is no availability markup,
|
||||
otherwise the XFAIL should use `availability` above).
|
@ -65,16 +65,12 @@ configuration all together. An example "__config" header generated when
|
||||
#ifndef _LIBCPP_CONFIG_SITE
|
||||
#define _LIBCPP_CONFIG_SITE
|
||||
|
||||
/* #undef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE */
|
||||
/* #undef _LIBCPP_HAS_NO_STDIN */
|
||||
/* #undef _LIBCPP_HAS_NO_STDOUT */
|
||||
#define _LIBCPP_HAS_NO_THREADS
|
||||
/* #undef _LIBCPP_HAS_NO_MONOTONIC_CLOCK */
|
||||
/* #undef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS */
|
||||
|
||||
#endif
|
||||
// -*- C++ -*-
|
||||
//===--------------------------- __config ---------------------------------===//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
|
@ -7,34 +7,68 @@ Debug Mode
|
||||
|
||||
.. _using-debug-mode:
|
||||
|
||||
Using Debug Mode
|
||||
================
|
||||
Using the debug mode
|
||||
====================
|
||||
|
||||
Libc++ provides a debug mode that enables assertions meant to detect incorrect
|
||||
usage of the standard library. By default these assertions are disabled but
|
||||
Libc++ provides a debug mode that enables special debugging checks meant to detect
|
||||
incorrect usage of the standard library. These checks are disabled by default, but
|
||||
they can be enabled using the ``_LIBCPP_DEBUG`` macro.
|
||||
|
||||
**_LIBCPP_DEBUG** Macro
|
||||
-----------------------
|
||||
Note that using the debug mode discussed in this document requires that the library
|
||||
has been compiled with support for the debug mode (see ``LIBCXX_ENABLE_DEBUG_MODE_SUPPORT``).
|
||||
|
||||
**_LIBCPP_DEBUG**:
|
||||
This macro is used to enable assertions and iterator debugging checks within
|
||||
libc++. By default it is undefined.
|
||||
Also note that while the debug mode has no effect on libc++'s ABI, it does have broad ODR
|
||||
implications. Users should compile their whole program at the same debugging level.
|
||||
|
||||
**Values**: ``0``, ``1``
|
||||
The various levels of checking provided by the debug mode follow.
|
||||
|
||||
Defining ``_LIBCPP_DEBUG`` to ``0`` or greater enables most of libc++'s
|
||||
assertions. Defining ``_LIBCPP_DEBUG`` to ``1`` enables "iterator debugging"
|
||||
which provides additional assertions about the validity of iterators used by
|
||||
the program.
|
||||
No debugging checks (``_LIBCPP_DEBUG`` not defined)
|
||||
---------------------------------------------------
|
||||
When ``_LIBCPP_DEBUG`` is not defined, there are no debugging checks performed by
|
||||
the library. This is the default.
|
||||
|
||||
Note that this option has no effect on libc++'s ABI; but it does have broad
|
||||
ODR implications. Users should compile their whole program at the same
|
||||
debugging level.
|
||||
Basic checks (``_LIBCPP_DEBUG == 0``)
|
||||
-------------------------------------
|
||||
When ``_LIBCPP_DEBUG`` is defined to ``0`` (to be understood as level ``0``), some
|
||||
debugging checks are enabled. The non-exhaustive list of things is:
|
||||
|
||||
- Many algorithms, such as ``binary_search``, ``merge``, ``next_permutation``, and ``sort``,
|
||||
wrap the user-provided comparator to assert that `!comp(y, x)` whenever
|
||||
`comp(x, y)`. This can cause the user-provided comparator to be evaluated
|
||||
up to twice as many times as it would be without ``_LIBCPP_DEBUG``, and
|
||||
causes the library to violate some of the Standard's complexity clauses.
|
||||
|
||||
- FIXME: Update this list
|
||||
|
||||
Iterator debugging checks (``_LIBCPP_DEBUG == 1``)
|
||||
--------------------------------------------------
|
||||
Defining ``_LIBCPP_DEBUG`` to ``1`` enables "iterator debugging", which provides
|
||||
additional assertions about the validity of iterators used by the program.
|
||||
|
||||
The following containers and classes support iterator debugging:
|
||||
|
||||
- ``std::string``
|
||||
- ``std::vector<T>`` (``T != bool``)
|
||||
- ``std::list``
|
||||
- ``std::unordered_map``
|
||||
- ``std::unordered_multimap``
|
||||
- ``std::unordered_set``
|
||||
- ``std::unordered_multiset``
|
||||
|
||||
The remaining containers do not currently support iterator debugging.
|
||||
Patches welcome.
|
||||
|
||||
Randomizing Unspecified Behavior (``_LIBCPP_DEBUG == 1``)
|
||||
---------------------------------------------------------
|
||||
This also enables the randomization of unspecified behavior, for
|
||||
example, for equal elements in ``std::sort`` or randomizing both parts of
|
||||
the partition after ``std::nth_element`` call. This effort helps you to migrate
|
||||
to potential future faster versions of these algorithms and deflake your tests
|
||||
which depend on such behavior. To fix the seed, use
|
||||
``_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY_SEED=seed`` definition.
|
||||
|
||||
Handling Assertion Failures
|
||||
---------------------------
|
||||
|
||||
===========================
|
||||
When a debug assertion fails the assertion handler is called via the
|
||||
``std::__libcpp_debug_function`` function pointer. It is possible to override
|
||||
this function pointer using a different handler function. Libc++ provides a
|
||||
@ -55,37 +89,3 @@ assertion handler as follows.
|
||||
str.insert(bad_it, '!'); // causes debug assertion
|
||||
// control flow doesn't return
|
||||
}
|
||||
|
||||
Debug Mode Checks
|
||||
=================
|
||||
|
||||
Libc++'s debug mode offers two levels of checking. The first enables various
|
||||
precondition checks throughout libc++. The second additionally enables
|
||||
"iterator debugging" which checks the validity of iterators used by the program.
|
||||
|
||||
Basic Checks
|
||||
============
|
||||
|
||||
These checks are enabled when ``_LIBCPP_DEBUG`` is defined to either 0 or 1.
|
||||
|
||||
The following checks are enabled by ``_LIBCPP_DEBUG``:
|
||||
|
||||
* FIXME: Update this list
|
||||
|
||||
Iterator Debugging Checks
|
||||
=========================
|
||||
|
||||
These checks are enabled when ``_LIBCPP_DEBUG`` is defined to 1.
|
||||
|
||||
The following containers and STL classes support iterator debugging:
|
||||
|
||||
* ``std::string``
|
||||
* ``std::vector<T>`` (``T != bool``)
|
||||
* ``std::list``
|
||||
* ``std::unordered_map``
|
||||
* ``std::unordered_multimap``
|
||||
* ``std::unordered_set``
|
||||
* ``std::unordered_multiset``
|
||||
|
||||
The remaining containers do not currently support iterator debugging.
|
||||
Patches welcome.
|
||||
|
@ -8,7 +8,7 @@ Feature Test Macros
|
||||
Overview
|
||||
========
|
||||
|
||||
Libc++ implements the C++ feature test macros as specified in the C++2a standard,
|
||||
Libc++ implements the C++ feature test macros as specified in the C++20 standard,
|
||||
and before that in non-normative guiding documents
|
||||
(`See cppreference <https://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros>`_)
|
||||
|
||||
@ -39,7 +39,5 @@ 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.
|
||||
and the script should be re-ran. The script will clobber the existing test files,
|
||||
the documentation and the `<version>` header.
|
||||
|
@ -18,7 +18,7 @@ type, which is a specialization of ``chrono::time_point`` for the
|
||||
trivial-clock is an implementation-defined type that satisfies the
|
||||
Cpp17TrivialClock requirements ([time.clock.req]) and that is capable of
|
||||
representing and measuring file time values. Implementations should ensure
|
||||
that the resolution and range of file_time_type reflect the operating
|
||||
that the resolution and range of file_time_type reflect the operating
|
||||
system dependent resolution and range of file time values.
|
||||
|
||||
|
||||
|
13
docs/DesignDocs/NoexceptPolicy.rst
Normal file
13
docs/DesignDocs/NoexceptPolicy.rst
Normal file
@ -0,0 +1,13 @@
|
||||
====================
|
||||
``noexcept`` Policy
|
||||
====================
|
||||
|
||||
Extended applications of ``noexcept``
|
||||
------------------------------------------
|
||||
|
||||
As of version 13 libc++ may mark functions that do not throw (i.e.,
|
||||
"Throws: Nothing") as ``noexcept``. This has two primary consequences:
|
||||
first, functions might not report precondition violations by throwing.
|
||||
Second, user-provided functions, such as custom predicates or custom
|
||||
traits, which throw might not be propagated up to the caller (unless
|
||||
specified otherwise by the Standard).
|
149
docs/DesignDocs/UniquePtrTrivialAbi.rst
Normal file
149
docs/DesignDocs/UniquePtrTrivialAbi.rst
Normal file
@ -0,0 +1,149 @@
|
||||
=============================================
|
||||
Enable std::unique_ptr [[clang::trivial_abi]]
|
||||
=============================================
|
||||
|
||||
Background
|
||||
==========
|
||||
|
||||
Consider the follow snippets
|
||||
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
void raw_func(Foo* raw_arg) { ... }
|
||||
void smart_func(std::unique_ptr<Foo> smart_arg) { ... }
|
||||
|
||||
Foo* raw_ptr_retval() { ... }
|
||||
std::unique_ptr<Foo*> smart_ptr_retval() { ... }
|
||||
|
||||
|
||||
|
||||
The argument ``raw_arg`` could be passed in a register but ``smart_arg`` could not, due to current
|
||||
implementation.
|
||||
|
||||
Specifically, in the ``smart_arg`` case, the caller secretly constructs a temporary ``std::unique_ptr``
|
||||
in its stack-frame, and then passes a pointer to it to the callee in a hidden parameter.
|
||||
Similarly, the return value from ``smart_ptr_retval`` is secretly allocated in the caller and
|
||||
passed as a secret reference to the callee.
|
||||
|
||||
|
||||
Goal
|
||||
===================
|
||||
|
||||
``std::unique_ptr`` is passed directly in a register.
|
||||
|
||||
Design
|
||||
======
|
||||
|
||||
* Annotate the two definitions of ``std::unique_ptr`` with ``clang::trivial_abi`` attribute.
|
||||
* Put the attribute behind a flag because this change has potential compilation and runtime breakages.
|
||||
|
||||
|
||||
This comes with some side effects:
|
||||
|
||||
* ``std::unique_ptr`` parameters will now be destroyed by callees, rather than callers.
|
||||
It is worth noting that destruction by callee is not unique to the use of trivial_abi attribute.
|
||||
In most Microsoft's ABIs, arguments are always destroyed by the callee.
|
||||
|
||||
Consequently, this may change the destruction order for function parameters to an order that is non-conforming to the standard.
|
||||
For example:
|
||||
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
struct A { ~A(); };
|
||||
struct B { ~B(); };
|
||||
struct C { C(A, unique_ptr<B>, A) {} };
|
||||
C c{{}, make_unique<B>, {}};
|
||||
|
||||
|
||||
In a conforming implementation, the destruction order for C::C's parameters is required to be ``~A(), ~B(), ~A()`` but with this mode enabled, we'll instead see ``~B(), ~A(), ~A()``.
|
||||
|
||||
* Reduced code-size.
|
||||
|
||||
|
||||
Performance impact
|
||||
------------------
|
||||
|
||||
Google has measured performance improvements of up to 1.6% on some large server macrobenchmarks, and a small reduction in binary sizes.
|
||||
|
||||
This also affects null pointer optimization
|
||||
|
||||
Clang's optimizer can now figure out when a `std::unique_ptr` is known to contain *non*-null.
|
||||
(Actually, this has been a *missed* optimization all along.)
|
||||
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
struct Foo {
|
||||
~Foo();
|
||||
};
|
||||
std::unique_ptr<Foo> make_foo();
|
||||
void do_nothing(const Foo&)
|
||||
|
||||
void bar() {
|
||||
auto x = make_foo();
|
||||
do_nothing(*x);
|
||||
}
|
||||
|
||||
|
||||
With this change, ``~Foo()`` will be called even if ``make_foo`` returns ``unique_ptr<Foo>(nullptr)``.
|
||||
The compiler can now assume that ``x.get()`` cannot be null by the end of ``bar()``, because
|
||||
the deference of ``x`` would be UB if it were ``nullptr``. (This dereference would not have caused
|
||||
a segfault, because no load is generated for dereferencing a pointer to a reference. This can be detected with ``-fsanitize=null``).
|
||||
|
||||
|
||||
Potential breakages
|
||||
-------------------
|
||||
|
||||
The following breakages were discovered by enabling this change and fixing the resulting issues in a large code base.
|
||||
|
||||
- Compilation failures
|
||||
|
||||
- Function definitions now require complete type ``T`` for parameters with type ``std::unique_ptr<T>``. The following code will no longer compile.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
class Foo;
|
||||
void func(std::unique_ptr<Foo> arg) { /* never use `arg` directly */ }
|
||||
|
||||
- Fix: Remove forward-declaration of ``Foo`` and include its proper header.
|
||||
|
||||
- Runtime Failures
|
||||
|
||||
- Lifetime of ``std::unique_ptr<>`` arguments end earlier (at the end of the callee's body, rather than at the end of the full expression containing the call).
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
util::Status run_worker(std::unique_ptr<Foo>);
|
||||
void func() {
|
||||
std::unique_ptr<Foo> smart_foo = ...;
|
||||
Foo* owned_foo = smart_foo.get();
|
||||
// Currently, the following would "work" because the argument to run_worker() is deleted at the end of func()
|
||||
// With the new calling convention, it will be deleted at the end of run_worker(),
|
||||
// making this an access to freed memory.
|
||||
owned_foo->Bar(run_worker(std::move(smart_foo)));
|
||||
^
|
||||
// <<<Crash expected here
|
||||
}
|
||||
|
||||
- Lifetime of local *returned* ``std::unique_ptr<>`` ends earlier.
|
||||
|
||||
Spot the bug:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
std::unique_ptr<Foo> create_and_subscribe(Bar* subscriber) {
|
||||
auto foo = std::make_unique<Foo>();
|
||||
subscriber->sub([&foo] { foo->do_thing();} );
|
||||
return foo;
|
||||
}
|
||||
|
||||
One could point out this is an obvious stack-use-after return bug.
|
||||
With the current calling convention, running this code with ASAN enabled, however, would not yield any "issue".
|
||||
So is this a bug in ASAN? (Spoiler: No)
|
||||
|
||||
This currently would "work" only because the storage for ``foo`` is in the caller's stackframe.
|
||||
In other words, ``&foo`` in callee and ``&foo`` in the caller are the same address.
|
||||
|
||||
ASAN can be used to detect both of these.
|
86
docs/DesignDocs/UnspecifiedBehaviorRandomization.rst
Normal file
86
docs/DesignDocs/UnspecifiedBehaviorRandomization.rst
Normal file
@ -0,0 +1,86 @@
|
||||
==================================
|
||||
Unspecified Behavior Randomization
|
||||
==================================
|
||||
|
||||
Background
|
||||
==========
|
||||
|
||||
Consider the follow snippet which steadily happens in tests:
|
||||
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
std::vector<std::pair<int, int>> v(SomeData());
|
||||
std::sort(v.begin(), v.end(), [](const auto& lhs, const auto& rhs) {
|
||||
return lhs.first < rhs.first;
|
||||
});
|
||||
|
||||
Under this assumption all elements in the vector whose first elements are equal
|
||||
do not guarantee any order. Unfortunately, this prevents libcxx introducing
|
||||
other implementatiosn because tests might silently fail and the users might
|
||||
heavily depend on the stability of implementations.
|
||||
|
||||
Goal
|
||||
===================
|
||||
|
||||
Provide functionality for randomizing the unspecified behavior so that the users
|
||||
can test and migrate their components and libcxx can introduce new sorting
|
||||
algorithms and optimizations to the containers.
|
||||
|
||||
For example, as of LLVM version 13, libcxx sorting algorithm takes
|
||||
`O(n^2) worst case <https://llvm.org/PR20837>`_ but according
|
||||
to the standard its worst case should be `O(n log n)`. This effort helps users
|
||||
to gradually fix their tests while updating to new faster algorithms.
|
||||
|
||||
Design
|
||||
======
|
||||
|
||||
* Introduce new macro `_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY` which should
|
||||
be a part of the libcxx config.
|
||||
* This macro randomizes the unspecified behavior of algorithms and containers.
|
||||
For example, for sorting algorithm the input range is shuffled and then
|
||||
sorted.
|
||||
* This macro is off by default because users should enable it only for testing
|
||||
purposes and/or migrations if they happen to libcxx.
|
||||
* This feature is only available for C++11 and further because of
|
||||
`std::shuffle` availability.
|
||||
* We may use `ASLR <https://en.wikipedia.org/wiki/Address_space_layout_randomization>`_ or
|
||||
static `std::random_device` for seeding the random number generator. This
|
||||
guarantees the same stability guarantee within a run but not through different
|
||||
runs, for example, for tests become flaky and eventually be seen as broken.
|
||||
For platforms which do not support ASLR, the seed is fixed during build.
|
||||
* The users can fix the seed of the random number generator by providing
|
||||
`_LIBCPP_RANDOMIZE_UNSPECIFIED_STABILITY_SEED=seed` definition.
|
||||
|
||||
This comes with some side effects if any of the flags is on:
|
||||
|
||||
* Computation penalty, we think users are OK with that if they use this feature.
|
||||
* Non reproducible results if they don't use the fixed seed.
|
||||
|
||||
|
||||
Impact
|
||||
------------------
|
||||
|
||||
Google has measured couple of thousands of tests to be dependent on the
|
||||
stability of sorting and selection algorithms. As we also plan on updating
|
||||
(or least, providing under flag more) sorting algorithms, this effort helps
|
||||
doing it gradually and sustainably. This is also bad for users to depend on the
|
||||
unspecified behavior in their tests, this effort helps to turn this flag in
|
||||
debug mode.
|
||||
|
||||
Potential breakages
|
||||
-------------------
|
||||
|
||||
None if the flag is off. If the flag is on, it may lead to some non-reproducible
|
||||
results, for example, for caching.
|
||||
|
||||
Currently supported randomization
|
||||
---------------------------------
|
||||
|
||||
* `std::sort`, there is no guarantee on the order of equal elements
|
||||
* `std::partial_sort`, there is no guarantee on the order of equal elements and
|
||||
on the order of the remaining part
|
||||
* `std::nth_element`, there is no guarantee on the order from both sides of the
|
||||
partition
|
||||
|
||||
Patches welcome.
|
@ -5,6 +5,8 @@ Symbol Visibility Macros
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
.. _visibility-macros:
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
@ -44,6 +46,10 @@ Visibility Macros
|
||||
Mark a function as not being part of the ABI of any final linked image that
|
||||
uses it.
|
||||
|
||||
**_LIBCPP_INLINE_VISIBILITY**
|
||||
Historical predecessor of ``_LIBCPP_HIDE_FROM_ABI`` -- please use
|
||||
``_LIBCPP_HIDE_FROM_ABI`` instead.
|
||||
|
||||
**_LIBCPP_HIDE_FROM_ABI_AFTER_V1**
|
||||
Mark a function as being hidden from the ABI (per `_LIBCPP_HIDE_FROM_ABI`)
|
||||
when libc++ is built with an ABI version after ABI v1. This macro is used to
|
||||
@ -131,12 +137,6 @@ Visibility Macros
|
||||
specified on the primary template and to export the member functions produced
|
||||
by the explicit instantiation in the dylib.
|
||||
|
||||
**GCC Behavior**: GCC ignores visibility attributes applied the type in
|
||||
extern template declarations and applying an attribute results in a warning.
|
||||
However since `_LIBCPP_TEMPLATE_VIS` is the same as
|
||||
`__attribute__((visibility("default"))` the visibility is already correct.
|
||||
The macro has an empty definition with GCC.
|
||||
|
||||
**Windows Behavior**: `extern template` and `dllexport` are fundamentally
|
||||
incompatible *on a class template* on Windows; the former suppresses
|
||||
instantiation, while the latter forces it. Specifying both on the same
|
||||
|
@ -18,185 +18,318 @@ Status
|
||||
======
|
||||
|
||||
.. table:: Current Status
|
||||
:name: feature-status-table
|
||||
:widths: auto
|
||||
|
||||
:name: feature-status-table
|
||||
:widths: auto
|
||||
|
||||
================================================= =================
|
||||
Macro Name Value
|
||||
Macro Name Value
|
||||
================================================= =================
|
||||
**C++ 14**
|
||||
**C++ 14**
|
||||
-------------------------------------------------------------------
|
||||
``__cpp_lib_chrono_udls`` ``201304L``
|
||||
``__cpp_lib_chrono_udls`` ``201304L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_complex_udls`` ``201309L``
|
||||
``__cpp_lib_complex_udls`` ``201309L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_exchange_function`` ``201304L``
|
||||
``__cpp_lib_exchange_function`` ``201304L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_generic_associative_lookup`` ``201304L``
|
||||
``__cpp_lib_generic_associative_lookup`` ``201304L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_integer_sequence`` ``201304L``
|
||||
``__cpp_lib_integer_sequence`` ``201304L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_integral_constant_callable`` ``201304L``
|
||||
``__cpp_lib_integral_constant_callable`` ``201304L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_is_final`` ``201402L``
|
||||
``__cpp_lib_is_final`` ``201402L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_is_null_pointer`` ``201309L``
|
||||
``__cpp_lib_is_null_pointer`` ``201309L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_make_reverse_iterator`` ``201402L``
|
||||
``__cpp_lib_make_reverse_iterator`` ``201402L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_make_unique`` ``201304L``
|
||||
``__cpp_lib_make_unique`` ``201304L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_null_iterators`` ``201304L``
|
||||
``__cpp_lib_null_iterators`` ``201304L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_quoted_string_io`` ``201304L``
|
||||
``__cpp_lib_quoted_string_io`` ``201304L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_result_of_sfinae`` ``201210L``
|
||||
``__cpp_lib_result_of_sfinae`` ``201210L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_robust_nonmodifying_seq_ops`` ``201304L``
|
||||
``__cpp_lib_robust_nonmodifying_seq_ops`` ``201304L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_shared_timed_mutex`` ``201402L``
|
||||
``__cpp_lib_shared_timed_mutex`` ``201402L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_string_udls`` ``201304L``
|
||||
``__cpp_lib_string_udls`` ``201304L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_transformation_trait_aliases`` ``201304L``
|
||||
``__cpp_lib_transformation_trait_aliases`` ``201304L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_transparent_operators`` ``201210L``
|
||||
``__cpp_lib_transparent_operators`` ``201210L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_tuple_element_t`` ``201402L``
|
||||
``__cpp_lib_tuple_element_t`` ``201402L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_tuples_by_type`` ``201304L``
|
||||
``__cpp_lib_tuples_by_type`` ``201304L``
|
||||
------------------------------------------------- -----------------
|
||||
**C++ 17**
|
||||
**C++ 17**
|
||||
-------------------------------------------------------------------
|
||||
``__cpp_lib_addressof_constexpr`` ``201603L``
|
||||
``__cpp_lib_addressof_constexpr`` ``201603L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_allocator_traits_is_always_equal`` ``201411L``
|
||||
``__cpp_lib_allocator_traits_is_always_equal`` ``201411L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_any`` ``201606L``
|
||||
``__cpp_lib_any`` ``201606L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_apply`` ``201603L``
|
||||
``__cpp_lib_apply`` ``201603L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_array_constexpr`` ``201603L``
|
||||
``__cpp_lib_array_constexpr`` ``201603L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_as_const`` ``201510L``
|
||||
``__cpp_lib_as_const`` ``201510L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_atomic_is_always_lock_free`` ``201603L``
|
||||
``__cpp_lib_atomic_is_always_lock_free`` ``201603L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_bool_constant`` ``201505L``
|
||||
``__cpp_lib_bool_constant`` ``201505L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_boyer_moore_searcher`` *unimplemented*
|
||||
``__cpp_lib_boyer_moore_searcher`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_byte`` ``201603L``
|
||||
``__cpp_lib_byte`` ``201603L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_chrono`` ``201611L``
|
||||
``__cpp_lib_chrono`` ``201611L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_clamp`` ``201603L``
|
||||
``__cpp_lib_clamp`` ``201603L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_enable_shared_from_this`` ``201603L``
|
||||
``__cpp_lib_enable_shared_from_this`` ``201603L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_execution`` *unimplemented*
|
||||
``__cpp_lib_execution`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_filesystem`` ``201703L``
|
||||
``__cpp_lib_filesystem`` ``201703L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_gcd_lcm`` ``201606L``
|
||||
``__cpp_lib_gcd_lcm`` ``201606L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_hardware_interference_size`` ``201703L``
|
||||
``__cpp_lib_hardware_interference_size`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_has_unique_object_representations`` ``201606L``
|
||||
``__cpp_lib_has_unique_object_representations`` ``201606L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_hypot`` ``201603L``
|
||||
``__cpp_lib_hypot`` ``201603L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_incomplete_container_elements`` ``201505L``
|
||||
``__cpp_lib_incomplete_container_elements`` ``201505L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_invoke`` ``201411L``
|
||||
``__cpp_lib_invoke`` ``201411L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_is_aggregate`` ``201703L``
|
||||
``__cpp_lib_is_aggregate`` ``201703L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_is_invocable`` ``201703L``
|
||||
``__cpp_lib_is_invocable`` ``201703L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_is_swappable`` ``201603L``
|
||||
``__cpp_lib_is_swappable`` ``201603L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_launder`` ``201606L``
|
||||
``__cpp_lib_launder`` ``201606L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_logical_traits`` ``201510L``
|
||||
``__cpp_lib_logical_traits`` ``201510L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_make_from_tuple`` ``201606L``
|
||||
``__cpp_lib_make_from_tuple`` ``201606L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_map_try_emplace`` ``201411L``
|
||||
``__cpp_lib_map_try_emplace`` ``201411L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_math_special_functions`` *unimplemented*
|
||||
``__cpp_lib_math_special_functions`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_memory_resource`` *unimplemented*
|
||||
``__cpp_lib_memory_resource`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_node_extract`` ``201606L``
|
||||
``__cpp_lib_node_extract`` ``201606L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_nonmember_container_access`` ``201411L``
|
||||
``__cpp_lib_nonmember_container_access`` ``201411L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_not_fn`` ``201603L``
|
||||
``__cpp_lib_not_fn`` ``201603L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_optional`` ``201606L``
|
||||
``__cpp_lib_optional`` ``201606L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_parallel_algorithm`` *unimplemented*
|
||||
``__cpp_lib_parallel_algorithm`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_raw_memory_algorithms`` ``201606L``
|
||||
``__cpp_lib_raw_memory_algorithms`` ``201606L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_sample`` ``201603L``
|
||||
``__cpp_lib_sample`` ``201603L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_scoped_lock`` ``201703L``
|
||||
``__cpp_lib_scoped_lock`` ``201703L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_shared_mutex`` ``201505L``
|
||||
``__cpp_lib_shared_mutex`` ``201505L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_shared_ptr_arrays`` *unimplemented*
|
||||
``__cpp_lib_shared_ptr_arrays`` ``201611L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_shared_ptr_weak_type`` ``201606L``
|
||||
``__cpp_lib_shared_ptr_weak_type`` ``201606L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_string_view`` ``201606L``
|
||||
``__cpp_lib_string_view`` ``201606L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_to_chars`` *unimplemented*
|
||||
``__cpp_lib_to_chars`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_transparent_operators`` ``201510L``
|
||||
``__cpp_lib_transparent_operators`` ``201510L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_type_trait_variable_templates`` ``201510L``
|
||||
``__cpp_lib_type_trait_variable_templates`` ``201510L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_uncaught_exceptions`` ``201411L``
|
||||
``__cpp_lib_uncaught_exceptions`` ``201411L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_unordered_map_try_emplace`` ``201411L``
|
||||
``__cpp_lib_unordered_map_try_emplace`` ``201411L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_variant`` ``201606L``
|
||||
``__cpp_lib_variant`` ``202102L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_void_t`` ``201411L``
|
||||
``__cpp_lib_void_t`` ``201411L``
|
||||
------------------------------------------------- -----------------
|
||||
**C++ 2a**
|
||||
**C++ 20**
|
||||
-------------------------------------------------------------------
|
||||
``__cpp_lib_atomic_ref`` *unimplemented*
|
||||
``__cpp_lib_array_constexpr`` ``201811L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_bind_front`` *unimplemented*
|
||||
``__cpp_lib_assume_aligned`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_bit_cast`` *unimplemented*
|
||||
``__cpp_lib_atomic_flag_test`` ``201907L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_char8_t`` ``201811L``
|
||||
``__cpp_lib_atomic_float`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_concepts`` *unimplemented*
|
||||
``__cpp_lib_atomic_lock_free_type_aliases`` ``201907L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_constexpr_misc`` *unimplemented*
|
||||
``__cpp_lib_atomic_ref`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_constexpr_swap_algorithms`` *unimplemented*
|
||||
``__cpp_lib_atomic_shared_ptr`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_destroying_delete`` ``201806L``
|
||||
``__cpp_lib_atomic_value_initialization`` ``201911L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_erase_if`` ``201811L``
|
||||
``__cpp_lib_atomic_wait`` ``201907L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_generic_unordered_lookup`` *unimplemented*
|
||||
``__cpp_lib_barrier`` ``201907L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_interpolate`` ``201902L``
|
||||
``__cpp_lib_bind_front`` ``201907L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_is_constant_evaluated`` ``201811L``
|
||||
``__cpp_lib_bit_cast`` ``201806L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_list_remove_return_type`` *unimplemented*
|
||||
``__cpp_lib_bitops`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_ranges`` *unimplemented*
|
||||
``__cpp_lib_bounded_array_traits`` ``201902L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_three_way_comparison`` *unimplemented*
|
||||
``__cpp_lib_char8_t`` ``201811L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_concepts`` ``202002L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_constexpr_algorithms`` ``201806L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_constexpr_complex`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_constexpr_dynamic_alloc`` ``201907L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_constexpr_functional`` ``201907L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_constexpr_iterator`` ``201811L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_constexpr_memory`` ``201811L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_constexpr_numeric`` ``201911L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_constexpr_string`` ``201811L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_constexpr_string_view`` ``201811L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_constexpr_tuple`` ``201811L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_constexpr_utility`` ``201811L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_constexpr_vector`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_coroutine`` ``201902L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_destroying_delete`` ``201806L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_endian`` ``201907L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_erase_if`` ``202002L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_execution`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_format`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_generic_unordered_lookup`` ``201811L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_int_pow2`` ``202002L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_integer_comparison_functions`` ``202002L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_interpolate`` ``201902L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_is_constant_evaluated`` ``201811L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_is_layout_compatible`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_is_nothrow_convertible`` ``201806L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_is_pointer_interconvertible`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_jthread`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_latch`` ``201907L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_list_remove_return_type`` ``201806L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_math_constants`` ``201907L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_polymorphic_allocator`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_ranges`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_remove_cvref`` ``201711L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_semaphore`` ``201907L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_shift`` ``201806L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_smart_ptr_for_overwrite`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_source_location`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_span`` ``202002L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_ssize`` ``201902L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_starts_ends_with`` ``201711L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_string_view`` ``201803L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_syncbuf`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_three_way_comparison`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_to_address`` ``201711L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_to_array`` ``201907L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_type_identity`` ``201806L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_unwrap_ref`` ``201811L``
|
||||
------------------------------------------------- -----------------
|
||||
**C++ 2b**
|
||||
-------------------------------------------------------------------
|
||||
``__cpp_lib_adaptor_iterator_pair_constructor`` ``202106L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_allocate_at_least`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_associative_heterogeneous_erasure`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_byteswap`` ``202110L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_constexpr_typeinfo`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_invoke_r`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_is_scoped_enum`` ``202011L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_monadic_optional`` ``202110L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_move_only_function`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_out_ptr`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_ranges_starts_ends_with`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_ranges_zip`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_spanstream`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_stacktrace`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_stdatomic_h`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_string_contains`` ``202011L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_string_resize_and_overwrite`` ``202110L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_to_underlying`` ``202102L``
|
||||
================================================= =================
|
||||
|
||||
|
||||
|
51
docs/Helpers/Styles.rst
Normal file
51
docs/Helpers/Styles.rst
Normal file
@ -0,0 +1,51 @@
|
||||
.. raw:: html
|
||||
|
||||
<style type="text/css">
|
||||
td { text-align: left; }
|
||||
.notstarted { opacity: 60%; }
|
||||
.nothingtodo {
|
||||
background-color: #99FF99;
|
||||
font-style: italic;
|
||||
}
|
||||
.inprogress {
|
||||
background-color: #FFFF99;
|
||||
font-style: italic;
|
||||
}
|
||||
.inreview { background-color: #FFFF99; }
|
||||
.partial {
|
||||
background-color: #2CCCFF;
|
||||
font-style: italic;
|
||||
}
|
||||
.complete { background-color: #99FF99; }
|
||||
.chrono { background-color: #D8BFD8; }
|
||||
.format { background-color: #FFE4B5; }
|
||||
.ranges { background-color: #7FFFD4; }
|
||||
.spaceship { background-color: #B0E0E6; }
|
||||
</style>
|
||||
|
||||
.. role:: notstarted
|
||||
.. role:: nothingtodo
|
||||
.. role:: inprogress
|
||||
.. role:: inreview
|
||||
.. role:: partial
|
||||
.. role:: complete
|
||||
|
||||
.. |Not Started| replace:: :notstarted:`Not Started`
|
||||
.. |Nothing To Do| replace:: :nothingtodo:`Nothing To Do`
|
||||
.. |In Progress| replace:: :inprogress:`In Progress`
|
||||
.. |Review| replace:: :inreview:`Review`
|
||||
.. |Partial| replace:: :partial:`Partial`
|
||||
.. |Complete| replace:: :complete:`Complete`
|
||||
|
||||
.. role:: chrono
|
||||
.. role:: format
|
||||
.. role:: ranges
|
||||
.. role:: spaceship
|
||||
|
||||
.. |chrono| replace:: :chrono:`chrono`
|
||||
.. |format| replace:: :format:`format`
|
||||
.. |ranges| replace:: :ranges:`ranges`
|
||||
.. |spaceship| replace:: :spaceship:`spaceship`
|
||||
|
||||
.. |sect| unicode:: U+00A7
|
||||
.. |hellip| unicode:: U+2026
|
@ -1,37 +0,0 @@
|
||||
# Makefile for Sphinx documentation
|
||||
#
|
||||
# FIXME: This hack is only in place to allow the libcxx.llvm.org/docs builder
|
||||
# to work with libcxx. This should be removed when that builder supports
|
||||
# out-of-tree builds.
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS = -n -W -v
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = _build
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
# the i18n builder cannot share the environment and doctrees with the others
|
||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
|
||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext default
|
||||
|
||||
default: html
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
|
||||
clean:
|
||||
-rm -rf $(BUILDDIR)/*
|
||||
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@# FIXME: Remove this `cp` once HTML->Sphinx transition is completed.
|
||||
@# Kind of a hack, but HTML-formatted docs are on the way out anyway.
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
@ -11,3 +11,7 @@ To build the documents into html configure libc++ with the following cmake optio
|
||||
|
||||
After configuring libc++ with these options the make rule `docs-libcxx-html`
|
||||
should be available.
|
||||
|
||||
The documentation in this directory is published at https://libcxx.llvm.org. It is kept up-to-date
|
||||
by a build bot: https://lab.llvm.org/buildbot/#/builders/publish-sphinx-docs. If you notice that the
|
||||
documentation is not updating anymore, please contact one of the maintainers.
|
||||
|
@ -1,5 +1,5 @@
|
||||
=========================================
|
||||
Libc++ 10.0.0 (In-Progress) Release Notes
|
||||
Libc++ 14.0.0 (In-Progress) Release Notes
|
||||
=========================================
|
||||
|
||||
.. contents::
|
||||
@ -10,7 +10,7 @@ Written by the `Libc++ Team <https://libcxx.llvm.org>`_
|
||||
|
||||
.. warning::
|
||||
|
||||
These are in-progress notes for the upcoming libc++ 10 release.
|
||||
These are in-progress notes for the upcoming libc++ 14 release.
|
||||
Release notes for previous releases can be found on
|
||||
`the Download Page <https://releases.llvm.org/download.html>`_.
|
||||
|
||||
@ -18,7 +18,7 @@ Introduction
|
||||
============
|
||||
|
||||
This document contains the release notes for the libc++ C++ Standard Library,
|
||||
part of the LLVM Compiler Infrastructure, release 10.0.0. Here we describe the
|
||||
part of the LLVM Compiler Infrastructure, release 14.0.0. Here we describe the
|
||||
status of libc++ in some detail, including major improvements from the previous
|
||||
release and new feature work. For the general LLVM release notes, see `the LLVM
|
||||
documentation <https://llvm.org/docs/ReleaseNotes.html>`_. All LLVM releases may
|
||||
@ -27,17 +27,219 @@ be downloaded from the `LLVM releases web site <https://llvm.org/releases/>`_.
|
||||
For more information about libc++, please see the `Libc++ Web Site
|
||||
<https://libcxx.llvm.org>`_ or the `LLVM Web Site <https://llvm.org>`_.
|
||||
|
||||
Note that if you are reading this file from a Subversion checkout or the
|
||||
Note that if you are reading this file from a Git checkout or the
|
||||
main Libc++ web page, this document applies to the *next* release, not
|
||||
the current one. To see the release notes for a specific release, please
|
||||
see the `releases page <https://llvm.org/releases/>`_.
|
||||
|
||||
What's New in Libc++ 10.0.0?
|
||||
What's New in Libc++ 14.0.0?
|
||||
============================
|
||||
|
||||
New Features
|
||||
------------
|
||||
|
||||
- There's support for the C++20 header ``<format>``. Some parts are still
|
||||
missing, most notably the compile-time format string validation. Some
|
||||
functions are known to be inefficient, both in memory usage and performance.
|
||||
The implementation isn't API- or ABI-stable and therefore considered
|
||||
experimental. (Some not-yet-implemented papers require an API-break.)
|
||||
As a result, it is disabled by default, however vendors can enable the
|
||||
header by using ``-DLIBCXX_ENABLE_INCOMPLETE_FEATURES=ON`` when
|
||||
configuring their build.
|
||||
|
||||
- More parts of ``<ranges>`` have been implemented. Since we still expect to make
|
||||
some API and ABI breaking changes, those are disabled by default. However,
|
||||
vendors that wish to enable ``<ranges>`` in their distribution may do so
|
||||
by defining ``-DLIBCXX_ENABLE_INCOMPLETE_FEATURES=ON`` when configuring
|
||||
their build.
|
||||
|
||||
- There's a new CMake option ``LIBCXX_ENABLE_UNICODE`` to disable Unicode
|
||||
support in the ``<format>`` header. This only affects the estimation of the
|
||||
output width of the format functions.
|
||||
|
||||
- Support for building libc++ on top of a C Standard Library that does not support ``wchar_t`` was
|
||||
added. This is useful for building libc++ in an embedded setting, and it adds itself to the various
|
||||
freestanding-friendly options provided by libc++.
|
||||
|
||||
- Defining ``_LIBCPP_DEBUG`` to ``1`` enables the randomization of unspecified
|
||||
behavior in standard algorithms (e.g. the ordering of equal elements in ``std::sort``, or
|
||||
the ordering of both sides of the partition in ``std::nth_element``).
|
||||
|
||||
- Floating-point support for ``std::to_chars`` support has been added.
|
||||
Thanks to Stephan T. Lavavej and Microsoft for providing their implementation
|
||||
to libc++.
|
||||
|
||||
- The C++20 ``<coroutine>`` implementation has been completed.
|
||||
|
||||
- More C++20 features have been implemented. :doc:`Status/Cxx20` has the full
|
||||
overview of libc++'s C++20 implementation status.
|
||||
|
||||
- More C++2b features have been implemented. :doc:`Status/Cxx2b` has the full
|
||||
overview of libc++'s C++2b implementation status.
|
||||
|
||||
- 16-bit ``wchar_t`` handling added for ``codecvt_utf8``, ``codecvt_utf16`` and
|
||||
``codecvt_utf8_utf16``.
|
||||
|
||||
API Changes
|
||||
-----------
|
||||
- ...
|
||||
|
||||
- The functions ``std::atomic<T*>::fetch_(add|sub)`` and
|
||||
``std::atomic_fetch_(add|sub)`` no longer accept a function pointer. While
|
||||
this is technically an API break, the invalid syntax isn't supported by
|
||||
libstdc++ and MSVC STL. See https://godbolt.org/z/49fvzz98d.
|
||||
|
||||
- The call of the functions ``std::atomic_(add|sub)(std::atomic<T*>*, ...)``
|
||||
with the explicit template argument ``T`` are now ill-formed. While this is
|
||||
technically an API break, the invalid syntax isn't supported by libstdc++ and
|
||||
MSVC STL. See https://godbolt.org/z/v9959re3v.
|
||||
|
||||
Due to this change it's now possible to call these functions with the
|
||||
explicit template argument ``T*``. This allows using the same syntax on the
|
||||
major Standard library implementations.
|
||||
See https://godbolt.org/z/oEfzPhTTb.
|
||||
|
||||
Calls to these functions where the template argument was deduced by the
|
||||
compiler are unaffected by this change.
|
||||
|
||||
- The functions ``std::allocator<T>::allocate`` and
|
||||
``std::experimental::pmr::polymorphic_allocator<T>::allocate`` now throw
|
||||
an exception of type ``std::bad_array_new_length`` when the requested size
|
||||
exceeds the maximum supported size, as required by the C++ standard.
|
||||
Previously the type ``std::length_error`` was used.
|
||||
|
||||
- Removed the nonstandard methods ``std::chrono::file_clock::to_time_t`` and
|
||||
``std::chrono::file_clock::from_time_t``; neither libstdc++ nor MSVC STL
|
||||
had such methods. Instead, in C++20, you can use ``std::chrono::file_clock::from_sys``
|
||||
and ``std::chrono::file_clock::to_sys``, which are specified in the Standard.
|
||||
If you are not using C++20, you should move to it.
|
||||
|
||||
- The declarations of functions ``declare_reachable``, ``undeclare_reachable``, ``declare_no_pointers``,
|
||||
``undeclare_no_pointers``, and ``get_pointer_safety`` have been removed not only from C++2b but
|
||||
from all modes. Their symbols are still provided by the dynamic library for the benefit of
|
||||
existing compiled code. All of these functions have always behaved as no-ops.
|
||||
|
||||
- ``std::filesystem::path::iterator``, which (in our implementation) stashes
|
||||
a ``path`` value inside itself similar to ``istream_iterator``, now sets its
|
||||
``reference`` type to ``path`` and its ``iterator_category`` to ``input_iterator_tag``,
|
||||
so that it is a conforming input iterator in C++17 and a conforming
|
||||
``std::bidirectional_iterator`` in C++20. Before this release, it had set its
|
||||
``reference`` type to ``const path&`` and its ``iterator_category`` to
|
||||
``bidirectional_iterator_tag``, making it a non-conforming bidirectional iterator.
|
||||
After this change, ``for`` loops of the form ``for (auto& c : path)`` must be rewritten
|
||||
as either ``for (auto&& c : path)`` or ``for (const auto& c : path)``.
|
||||
``std::reverse_iterator<path::iterator>`` is no longer rejected.
|
||||
|
||||
- Removed the nonstandard default constructor from ``std::chrono::month_weekday``.
|
||||
You must now explicitly initialize with a ``chrono::month`` and
|
||||
``chrono::weekday_indexed`` instead of "meh, whenever".
|
||||
|
||||
- C++20 requires that ``std::basic_string::reserve(n)`` never reduce the capacity
|
||||
of the string. (For that, use ``shrink_to_fit()``.) Prior to this release, libc++'s
|
||||
``std::basic_string::reserve(n)`` could reduce capacity in C++17 and before, but
|
||||
not in C++20 and later. This caused ODR violations when mixing code compiled under
|
||||
different Standard modes. After this change, libc++'s ``std::basic_string::reserve(n)``
|
||||
never reduces capacity, even in C++17 and before.
|
||||
C++20 deprecates the zero-argument overload of ``std::basic_string::reserve()``,
|
||||
but specifically permits it to reduce capacity. To avoid breaking existing code
|
||||
assuming that ``std::basic_string::reserve()`` will shrink, libc++ maintains
|
||||
the behavior to shrink, even though that makes ``std::basic_string::reserve()`` not
|
||||
a synonym for ``std::basic_string::reserve(0)`` in any Standard mode anymore.
|
||||
|
||||
- The ``<experimental/coroutine>`` header is deprecated, as is any
|
||||
use of coroutines without C++20. Use C++20's ``<coroutine>`` header
|
||||
instead. The ``<experimental/coroutine>`` header will be removed
|
||||
in LLVM 16.
|
||||
|
||||
- ``_VSTD`` is now an alias for ``std`` instead of ``std::_LIBCPP_ABI_NAMESPACE``.
|
||||
This is technically not a functional change, except for folks that might have been
|
||||
using ``_VSTD`` in creative ways (which has never been officially supported).
|
||||
|
||||
ABI Changes
|
||||
-----------
|
||||
|
||||
- The C++17 variable templates ``is_error_code_enum_v`` and
|
||||
``is_error_condition_enum_v`` are now of type ``bool`` instead of ``size_t``.
|
||||
|
||||
- The C++03 emulation type for ``std::nullptr_t`` has been removed in favor of
|
||||
using ``decltype(nullptr)`` in all standard modes. This is an ABI break for
|
||||
anyone compiling in C++03 mode and who has ``std::nullptr_t`` as part of their
|
||||
ABI. However, previously, these users' ABI would be incompatible with any other
|
||||
binary or static archive compiled with C++11 or later. If you start seeing linker
|
||||
errors involving ``std::nullptr_t`` against previously compiled binaries, this may
|
||||
be the cause. You can define the ``_LIBCPP_ABI_USE_CXX03_NULLPTR_EMULATION`` macro
|
||||
to return to the previous behavior. That macro will be removed in LLVM 15. Please
|
||||
comment `on D109459 <https://reviews.llvm.org/D109459>`_ if you are broken by this change
|
||||
and need to define the macro.
|
||||
|
||||
- On Apple platforms, ``std::random_device`` is now implemented on top of ``arc4random()``
|
||||
instead of reading from ``/dev/urandom``. Any implementation-defined token used when
|
||||
constructing a ``std::random_device`` will now be ignored instead of interpreted as a
|
||||
file to read entropy from.
|
||||
|
||||
- ``std::lognormal_distribution::param_type`` used to store a data member of type
|
||||
``std::normal_distribution``; now this member is stored in the ``lognormal_distribution``
|
||||
class itself, and the ``param_type`` stores only the mean and standard deviation,
|
||||
as required by the Standard. This changes ``sizeof(std::lognormal_distribution::param_type)``.
|
||||
You can define the ``_LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION`` macro to return to the
|
||||
previous behavior. That macro will be removed in LLVM 15. Please comment
|
||||
`on PR52906 <https://llvm.org/PR52906>`_ if you are broken by this change and need to
|
||||
define the macro.
|
||||
|
||||
Build System Changes
|
||||
--------------------
|
||||
|
||||
- Building the libc++ shared or static library requires a C++ 20 capable compiler.
|
||||
Consider using a Bootstrapping build to build libc++ with a fresh Clang if you
|
||||
can't use the system compiler to build libc++ anymore.
|
||||
|
||||
- Historically, there have been numerous ways of building libc++, libc++abi, and libunwind.
|
||||
This has led to at least 5 different ways to build the runtimes, which was impossible to
|
||||
maintain with a good level of support. Starting with this release, libc++, libc++abi, and
|
||||
libunwind support exactly two ways of being built, which should cater to all use-cases.
|
||||
Furthermore, these builds are as lightweight as possible and will work consistently even
|
||||
when targeting embedded platforms, which used not to be the case. :doc:`BuildingLibcxx`
|
||||
describes those two ways of building. Please migrate over to the appropriate build
|
||||
instructions as soon as possible.
|
||||
|
||||
All other ways to build are deprecated and will not be supported in the next release.
|
||||
We understand that making these changes can be daunting. For that reason, here's a
|
||||
summary of how to migrate from the two most common ways to build:
|
||||
|
||||
- If you were rooting your CMake invocation at ``<monorepo>/llvm`` and passing ``-DLLVM_ENABLE_PROJECTS=<...>``
|
||||
(which was the previously advertised way to build the runtimes), please simply root your CMake invocation at
|
||||
``<monorepo>/runtimes`` and pass ``-DLLVM_ENABLE_RUNTIMES=<...>``.
|
||||
|
||||
- If you were doing multiple CMake invocations, e.g. one rooted at ``<monorepo>/libcxx`` and one rooted
|
||||
at ``<monorepo>/libcxxabi`` (this used to be called a "Standalone build"), please move them to a
|
||||
single invocation like so:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ cmake -S <monorepo>/libcxx -B libcxx-build <LIBCXX-OPTIONS>
|
||||
$ cmake -S <monorepo>/libcxxabi -B libcxxabi-build <LIBCXXABI-OPTIONS>
|
||||
|
||||
should become
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ cmake -S <monorepo>/runtimes -B build -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" <LIBCXX-OPTIONS> <LIBCXXABI-OPTIONS>
|
||||
|
||||
- Support for building the runtimes using the GCC 32 bit multilib flag (``-m32``) has been removed. Support
|
||||
for this had been flaky for a while, and we didn't know of anyone depending on this. Instead, please perform
|
||||
a normal cross-compilation of the runtimes using the appropriate target, such as passing the following to
|
||||
your bootstrapping build:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
-DLLVM_RUNTIME_TARGETS=i386-unknown-linux
|
||||
|
||||
- Libc++, libc++abi, and libunwind will not be built with ``-fPIC`` by default anymore.
|
||||
If you want to build those runtimes with position-independent code, please specify
|
||||
``-DCMAKE_POSITION_INDEPENDENT_CODE=ON`` explicitly when configuring the build, or
|
||||
``-DRUNTIMES_<target-name>_CMAKE_POSITION_INDEPENDENT_CODE=ON`` if using the
|
||||
bootstrapping build.
|
||||
|
||||
- The ``{LIBCXX,LIBCXXABI,LIBUNWIND}_TARGET_TRIPLE``, ``{LIBCXX,LIBCXXABI,LIBUNWIND}_SYSROOT`` and
|
||||
``{LIBCXX,LIBCXXABI,LIBUNWIND}_GCC_TOOLCHAIN`` CMake variables are deprecated. Instead, please use
|
||||
the ``CMAKE_CXX_COMPILER_TARGET``, ``CMAKE_SYSROOT`` and ``CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN``
|
||||
variables provided by CMake.
|
||||
|
50
docs/Status/Cxx14.rst
Normal file
50
docs/Status/Cxx14.rst
Normal file
@ -0,0 +1,50 @@
|
||||
.. _cxx14-status:
|
||||
|
||||
================================
|
||||
libc++ C++14 Status
|
||||
================================
|
||||
|
||||
.. include:: ../Helpers/Styles.rst
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
|
||||
Overview
|
||||
================================
|
||||
|
||||
In April 2013, the C++ standard committee approved the draft for the next version of the C++ standard, initially known as "C++1y".
|
||||
|
||||
The draft standard includes papers and issues that were voted on at the previous three meetings (Kona, Portland, and Bristol).
|
||||
|
||||
In August 2014, this draft was approved by ISO as C++14.
|
||||
|
||||
This page shows the status of libc++; the status of clang's support of the language features is `here <https://clang.llvm.org/cxx_status.html#cxx14>`__.
|
||||
|
||||
The groups that have contributed papers:
|
||||
|
||||
- CWG - Core Language Working group
|
||||
- LWG - Library working group
|
||||
- SG1 - Study group #1 (Concurrency working group)
|
||||
|
||||
|
||||
.. _paper-status-cxx14:
|
||||
|
||||
Paper Status
|
||||
====================================
|
||||
|
||||
.. csv-table::
|
||||
:file: Cxx14Papers.csv
|
||||
:header-rows: 1
|
||||
:widths: auto
|
||||
|
||||
|
||||
.. _issues-status-cxx14:
|
||||
|
||||
Library Working Group Issues Status
|
||||
====================================
|
||||
|
||||
.. csv-table::
|
||||
:file: Cxx14Issues.csv
|
||||
:header-rows: 1
|
||||
:widths: auto
|
157
docs/Status/Cxx14Issues.csv
Normal file
157
docs/Status/Cxx14Issues.csv
Normal file
@ -0,0 +1,157 @@
|
||||
"Issue #","Issue Name","Meeting","Status"
|
||||
"`1214 <https://wg21.link/lwg1214>`__","Insufficient/inconsistent key immutability requirements for associative containers","Kona","|Complete|"
|
||||
"`2009 <https://wg21.link/lwg2009>`__","Reporting out-of-bound values on numeric string conversions","Kona","|Complete|"
|
||||
"`2010 <https://wg21.link/lwg2010>`__","``is_*``\ traits for binding operations can't be meaningfully specialized","Kona","|Complete|"
|
||||
"`2015 <https://wg21.link/lwg2015>`__","Incorrect pre-conditions for some type traits","Kona","|Complete|"
|
||||
"`2021 <https://wg21.link/lwg2021>`__","Further incorrect usages of result_of","Kona","|Complete|"
|
||||
"`2028 <https://wg21.link/lwg2028>`__","messages_base::catalog overspecified","Kona","|Complete|"
|
||||
"`2033 <https://wg21.link/lwg2033>`__","Preconditions of reserve, shrink_to_fit, and resize functions","Kona","|Complete|"
|
||||
"`2039 <https://wg21.link/lwg2039>`__","Issues with std::reverse and std::copy_if","Kona","|Complete|"
|
||||
"`2044 <https://wg21.link/lwg2044>`__","No definition of ""Stable"" for copy algorithms","Kona","|Complete|"
|
||||
"`2045 <https://wg21.link/lwg2045>`__","forward_list::merge and forward_list::splice_after with unequal allocators","Kona","|Complete|"
|
||||
"`2047 <https://wg21.link/lwg2047>`__","Incorrect ""mixed"" move-assignment semantics of unique_ptr","Kona","|Complete|"
|
||||
"`2050 <https://wg21.link/lwg2050>`__","Unordered associative containers do not use allocator_traits to define member types","Kona","|Complete|"
|
||||
"`2053 <https://wg21.link/lwg2053>`__","Errors in regex bitmask types","Kona","|Complete|"
|
||||
"`2061 <https://wg21.link/lwg2061>`__","make_move_iterator and arrays","Kona","|Complete|"
|
||||
"`2064 <https://wg21.link/lwg2064>`__","More noexcept issues in basic_string","Kona","|Complete|"
|
||||
"`2065 <https://wg21.link/lwg2065>`__","Minimal allocator interface","Kona","|Complete|"
|
||||
"`2067 <https://wg21.link/lwg2067>`__","packaged_task should have deleted copy c'tor with const parameter","Kona","|Complete|"
|
||||
"`2069 <https://wg21.link/lwg2069>`__","Inconsistent exception spec for basic_string move constructor","Kona","|Complete|"
|
||||
"`2096 <https://wg21.link/lwg2096>`__","Incorrect constraints of future::get in regard to MoveAssignable","Kona","|Complete|"
|
||||
"`2102 <https://wg21.link/lwg2102>`__","Why is std::launch an implementation-defined type?","Kona","|Complete|"
|
||||
"","","",""
|
||||
"`2071 <https://wg21.link/lwg2071>`__","std::valarray move-assignment","Portland","|Complete|"
|
||||
"`2074 <https://wg21.link/lwg2074>`__","Off by one error in std::reverse_copy","Portland","|Complete|"
|
||||
"`2081 <https://wg21.link/lwg2081>`__","Allocator requirements should include CopyConstructible","Portland","|Complete|"
|
||||
"`2083 <https://wg21.link/lwg2083>`__","const-qualification on weak_ptr::owner_before","Portland","|Complete|"
|
||||
"`2086 <https://wg21.link/lwg2086>`__","Overly generic type support for math functions","Portland","|Complete|"
|
||||
"`2099 <https://wg21.link/lwg2099>`__","Unnecessary constraints of va_start() usage","Portland","|Complete|"
|
||||
"`2103 <https://wg21.link/lwg2103>`__","std::allocator_traits<std::allocator<T>>::propagate_on_container_move_assignment","Portland","|Complete|"
|
||||
"`2105 <https://wg21.link/lwg2105>`__","Inconsistent requirements on ``const_iterator``'s value_type","Portland","|Complete|"
|
||||
"`2110 <https://wg21.link/lwg2110>`__","remove can't swap but note says it might","Portland","|Complete|"
|
||||
"`2123 <https://wg21.link/lwg2123>`__","merge() allocator requirements for lists versus forward lists","Portland","|Complete|"
|
||||
"`2005 <https://wg21.link/lwg2005>`__","unordered_map::insert(T&&) protection should apply to map too","Portland","|Complete|"
|
||||
"`2011 <https://wg21.link/lwg2011>`__","Unexpected output required of strings","Portland","|Complete|"
|
||||
"`2048 <https://wg21.link/lwg2048>`__","Unnecessary mem_fn overloads","Portland","|Complete|"
|
||||
"`2049 <https://wg21.link/lwg2049>`__","``is_destructible``\ is underspecified","Portland","|Complete|"
|
||||
"`2056 <https://wg21.link/lwg2056>`__","future_errc enums start with value 0 (invalid value for broken_promise)","Portland","|Complete|"
|
||||
"`2058 <https://wg21.link/lwg2058>`__","valarray and begin/end","Portland","|Complete|"
|
||||
"","","",""
|
||||
"`2091 <https://wg21.link/lwg2091>`__","Misplaced effect in m.try_lock_for()","Bristol","|Complete|"
|
||||
"`2092 <https://wg21.link/lwg2092>`__","Vague Wording for condition_variable_any","Bristol","|Complete|"
|
||||
"`2093 <https://wg21.link/lwg2093>`__","Throws clause of condition_variable::wait with predicate","Bristol","|Complete|"
|
||||
"`2094 <https://wg21.link/lwg2094>`__","duration conversion overflow shouldn't participate in overload resolution","Bristol","|Complete|"
|
||||
"`2122 <https://wg21.link/lwg2122>`__","merge() stability for lists versus forward lists","Bristol","|Complete|"
|
||||
"`2128 <https://wg21.link/lwg2128>`__","Absence of global functions cbegin/cend","Bristol","|Complete|"
|
||||
"`2145 <https://wg21.link/lwg2145>`__","error_category default constructor","Bristol","|Complete|"
|
||||
"`2147 <https://wg21.link/lwg2147>`__","Unclear hint type in Allocator's allocate function","Bristol","|Complete|"
|
||||
"`2148 <https://wg21.link/lwg2148>`__","Hashing enums should be supported directly by std::hash","Bristol","|Complete|"
|
||||
"`2149 <https://wg21.link/lwg2149>`__","Concerns about 20.8/5","Bristol","|Complete|"
|
||||
"`2162 <https://wg21.link/lwg2162>`__","allocator_traits::max_size missing noexcept","Bristol","|Complete|"
|
||||
"`2163 <https://wg21.link/lwg2163>`__","nth_element requires inconsistent post-conditions","Bristol","|Complete|"
|
||||
"`2169 <https://wg21.link/lwg2169>`__","Missing reset() requirements in unique_ptr specialization","Bristol","|Complete|"
|
||||
"`2172 <https://wg21.link/lwg2172>`__","Does ``atomic_compare_exchange_*``\ accept v == nullptr arguments?","Bristol","|Complete|"
|
||||
"`2080 <https://wg21.link/lwg2080>`__","Specify when once_flag becomes invalid","Bristol","|Complete|"
|
||||
"`2098 <https://wg21.link/lwg2098>`__","promise throws clauses","Bristol","|Complete|"
|
||||
"`2109 <https://wg21.link/lwg2109>`__","Incorrect requirements for hash specializations","Bristol","|Complete|"
|
||||
"`2130 <https://wg21.link/lwg2130>`__","missing ordering constraints for fences","Bristol","|Complete|"
|
||||
"`2138 <https://wg21.link/lwg2138>`__","atomic_flag::clear ordering constraints","Bristol","|Complete|"
|
||||
"`2140 <https://wg21.link/lwg2140>`__","notify_all_at_thread_exit synchronization","Bristol","|Complete|"
|
||||
"`2144 <https://wg21.link/lwg2144>`__","Missing noexcept specification in type_index","Bristol","|Complete|"
|
||||
"`2174 <https://wg21.link/lwg2174>`__","wstring_convert::converted() should be noexcept","Bristol","|Complete|"
|
||||
"`2175 <https://wg21.link/lwg2175>`__","string_convert and wbuffer_convert validity","Bristol","|Complete|"
|
||||
"`2176 <https://wg21.link/lwg2176>`__","Special members for wstring_convert and wbuffer_convert","Bristol","|Complete|"
|
||||
"`2177 <https://wg21.link/lwg2177>`__","Requirements on Copy/MoveInsertable","Bristol","|Complete|"
|
||||
"`2185 <https://wg21.link/lwg2185>`__","Missing throws clause for future/shared_future::wait_for/wait_until","Bristol","|Complete|"
|
||||
"`2187 <https://wg21.link/lwg2187>`__","vector<bool> is missing emplace and emplace_back member functions","Bristol","|Complete|"
|
||||
"`2190 <https://wg21.link/lwg2190>`__","ordering of condition variable operations, reflects Posix discussion","Bristol","|Complete|"
|
||||
"`2196 <https://wg21.link/lwg2196>`__","Specification of ``is_*[copy/move]_[constructible/assignable]``\ unclear for non-referencable types","Bristol","|Complete|"
|
||||
"`2197 <https://wg21.link/lwg2197>`__","Specification of ``is_[un]signed``\ unclear for non-arithmetic types","Bristol","|Complete|"
|
||||
"`2200 <https://wg21.link/lwg2200>`__","Data race avoidance for all containers, not only for sequences","Bristol","|Complete|"
|
||||
"`2203 <https://wg21.link/lwg2203>`__","scoped_allocator_adaptor uses wrong argument types for piecewise construction","Bristol","|Complete|"
|
||||
"`2207 <https://wg21.link/lwg2207>`__","basic_string::at should not have a Requires clause","Bristol","|Complete|"
|
||||
"`2209 <https://wg21.link/lwg2209>`__","assign() overspecified for sequence containers","Bristol","|Complete|"
|
||||
"`2210 <https://wg21.link/lwg2210>`__","Missing allocator-extended constructor for allocator-aware containers","Bristol","|Complete|"
|
||||
"`2211 <https://wg21.link/lwg2211>`__","Replace ambiguous use of ""Allocator"" in container requirements","Bristol","|Complete|"
|
||||
"`2222 <https://wg21.link/lwg2222>`__","Inconsistency in description of forward_list::splice_after single-element overload","Bristol","|Complete|"
|
||||
"`2225 <https://wg21.link/lwg2225>`__","Unrealistic header inclusion checks required","Bristol","|Complete|"
|
||||
"`2229 <https://wg21.link/lwg2229>`__","Standard code conversion facets underspecified","Bristol","|Complete|"
|
||||
"`2231 <https://wg21.link/lwg2231>`__","DR 704 removes complexity guarantee for clear()","Bristol","|Complete|"
|
||||
"`2235 <https://wg21.link/lwg2235>`__","Undefined behavior without proper requirements on basic_string constructors","Bristol","|Complete|"
|
||||
"","","",""
|
||||
"`2141 <https://wg21.link/lwg2141>`__","common_type trait produces reference types","Chicago","|Complete|"
|
||||
"`2246 <https://wg21.link/lwg2246>`__","unique_ptr assignment effects w.r.t. deleter","Chicago","|Complete|"
|
||||
"`2247 <https://wg21.link/lwg2247>`__","Type traits and std::nullptr_t","Chicago","|Complete|"
|
||||
"`2085 <https://wg21.link/lwg2085>`__","Wrong description of effect 1 of basic_istream::ignore","Chicago","|Complete|"
|
||||
"`2087 <https://wg21.link/lwg2087>`__","iostream_category() and noexcept","Chicago","|Complete|"
|
||||
"`2143 <https://wg21.link/lwg2143>`__","ios_base::xalloc should be thread-safe","Chicago","|Complete|"
|
||||
"`2150 <https://wg21.link/lwg2150>`__","Unclear specification of find_end","Chicago","|Complete|"
|
||||
"`2180 <https://wg21.link/lwg2180>`__","Exceptions from std::seed_seq operations","Chicago","|Complete|"
|
||||
"`2194 <https://wg21.link/lwg2194>`__","Impossible container requirements for adaptor types","Chicago","|Complete|"
|
||||
"`2013 <https://wg21.link/lwg2013>`__","Do library implementers have the freedom to add constexpr?","Chicago","|Complete|"
|
||||
"`2018 <https://wg21.link/lwg2018>`__","regex_traits::isctype Returns clause is wrong","Chicago","|Complete|"
|
||||
"`2078 <https://wg21.link/lwg2078>`__","Throw specification of async() incomplete","Chicago","|Complete|"
|
||||
"`2097 <https://wg21.link/lwg2097>`__","packaged_task constructors should be constrained","Chicago","|Complete|"
|
||||
"`2100 <https://wg21.link/lwg2100>`__","Timed waiting functions cannot timeout if launch::async policy used","Chicago","|Complete|"
|
||||
"`2120 <https://wg21.link/lwg2120>`__","What should async do if neither 'async' nor 'deferred' is set in policy?","Chicago","|Complete|"
|
||||
"`2159 <https://wg21.link/lwg2159>`__","atomic_flag initialization","Chicago","|Complete|"
|
||||
"`2275 <https://wg21.link/lwg2275>`__","Why is forward_as_tuple not constexpr?","Chicago","|Complete|"
|
||||
"`2284 <https://wg21.link/lwg2284>`__","Inconsistency in allocator_traits::max_size","Chicago","|Complete|"
|
||||
"`2298 <https://wg21.link/lwg2298>`__","``is_nothrow_constructible``\ is always false because of create<>","Chicago","|Complete|"
|
||||
"`2300 <https://wg21.link/lwg2300>`__","Redundant sections for map and multimap members should be removed","Chicago","|Complete|"
|
||||
"NB comment: GB9","Remove gets from C++14","Chicago","|Complete|"
|
||||
"","","",""
|
||||
"`2135 <https://wg21.link/lwg2135>`__","Unclear requirement for exceptions thrown in condition_variable::wait()","Issaquah","|Complete|"
|
||||
"`2291 <https://wg21.link/lwg2291>`__","std::hash is vulnerable to collision DoS attack","Issaquah","|Complete|"
|
||||
"`2142 <https://wg21.link/lwg2142>`__","packaged_task::operator() synchronization too broad?","Issaquah","|Complete|"
|
||||
"`2240 <https://wg21.link/lwg2240>`__","Probable misuse of term ""function scope"" in [thread.condition]","Issaquah","|Complete|"
|
||||
"`2252 <https://wg21.link/lwg2252>`__","Strong guarantee on vector::push_back() still broken with C++11?","Issaquah","|Complete|"
|
||||
"`2257 <https://wg21.link/lwg2257>`__","Simplify container requirements with the new algorithms","Issaquah","|Complete|"
|
||||
"`2268 <https://wg21.link/lwg2268>`__","Setting a default argument in the declaration of a member function assign of std::basic_string","Issaquah","|Complete|"
|
||||
"`2271 <https://wg21.link/lwg2271>`__","regex_traits::lookup_classname specification unclear","Issaquah","|Complete|"
|
||||
"`2272 <https://wg21.link/lwg2272>`__","quoted should use char_traits::eq for character comparison","Issaquah","|Complete|"
|
||||
"`2278 <https://wg21.link/lwg2278>`__","User-defined literals for Standard Library types","Issaquah","|Complete|"
|
||||
"`2280 <https://wg21.link/lwg2280>`__","begin / end for arrays should be constexpr and noexcept","Issaquah","|Complete|"
|
||||
"`2285 <https://wg21.link/lwg2285>`__","make_reverse_iterator","Issaquah","|Complete|"
|
||||
"`2299 <https://wg21.link/lwg2299>`__","Effects of inaccessible ``key_compare::is_transparent``\ type are not clear","Issaquah","|Complete|"
|
||||
"`1450 <https://wg21.link/lwg1450>`__","Contradiction in regex_constants","Issaquah","|Complete|"
|
||||
"`2003 <https://wg21.link/lwg2003>`__","String exception inconsistency in erase.","Issaquah","|Complete|"
|
||||
"`2112 <https://wg21.link/lwg2112>`__","User-defined classes that cannot be derived from","Issaquah","|Complete|"
|
||||
"`2132 <https://wg21.link/lwg2132>`__","std::function ambiguity","Issaquah","|Complete|"
|
||||
"`2182 <https://wg21.link/lwg2182>`__","``Container::[const_]reference`` types are misleadingly specified","Issaquah","|Complete|"
|
||||
"`2188 <https://wg21.link/lwg2188>`__","Reverse iterator does not fully support targets that overload operator&","Issaquah","|Complete|"
|
||||
"`2193 <https://wg21.link/lwg2193>`__","Default constructors for standard library containers are explicit","Issaquah","|Complete|"
|
||||
"`2205 <https://wg21.link/lwg2205>`__","Problematic postconditions of regex_match and regex_search","Issaquah","|Complete|"
|
||||
"`2213 <https://wg21.link/lwg2213>`__","Return value of std::regex_replace","Issaquah","|Complete|"
|
||||
"`2258 <https://wg21.link/lwg2258>`__","a.erase(q1, q2) unable to directly return q2","Issaquah","|Complete|"
|
||||
"`2263 <https://wg21.link/lwg2263>`__","Comparing iterators and allocator pointers with different const-character","Issaquah","|Complete|"
|
||||
"`2293 <https://wg21.link/lwg2293>`__","Wrong facet used by num_put::do_put","Issaquah","|Complete|"
|
||||
"`2301 <https://wg21.link/lwg2301>`__","Why is std::tie not constexpr?","Issaquah","|Complete|"
|
||||
"`2304 <https://wg21.link/lwg2304>`__","Complexity of count in unordered associative containers","Issaquah","|Complete|"
|
||||
"`2306 <https://wg21.link/lwg2306>`__","match_results::reference should be value_type&, not const value_type&","Issaquah","|Complete|"
|
||||
"`2308 <https://wg21.link/lwg2308>`__","Clarify container destructor requirements w.r.t. std::array","Issaquah","|Complete|"
|
||||
"`2313 <https://wg21.link/lwg2313>`__","tuple_size should always derive from integral_constant<size_t, N>","Issaquah","|Complete|"
|
||||
"`2314 <https://wg21.link/lwg2314>`__","apply() should return decltype(auto) and use decay_t before tuple_size","Issaquah","|Complete|"
|
||||
"`2315 <https://wg21.link/lwg2315>`__","weak_ptr should be movable","Issaquah","|Complete|"
|
||||
"`2316 <https://wg21.link/lwg2316>`__","weak_ptr::lock() should be atomic","Issaquah","|Complete|"
|
||||
"`2317 <https://wg21.link/lwg2317>`__","The type property queries should be UnaryTypeTraits returning size_t","Issaquah","|Complete|"
|
||||
"`2320 <https://wg21.link/lwg2320>`__","select_on_container_copy_construction() takes allocators, not containers","Issaquah","|Complete|"
|
||||
"`2322 <https://wg21.link/lwg2322>`__","Associative(initializer_list, stuff) constructors are underspecified","Issaquah","|Complete|"
|
||||
"`2323 <https://wg21.link/lwg2323>`__","vector::resize(n, t)'s specification should be simplified","Issaquah","|Complete|"
|
||||
"`2324 <https://wg21.link/lwg2324>`__","Insert iterator constructors should use addressof()","Issaquah","|Complete|"
|
||||
"`2329 <https://wg21.link/lwg2329>`__","regex_match()/regex_search() with match_results should forbid temporary strings","Issaquah","|Complete|"
|
||||
"`2330 <https://wg21.link/lwg2330>`__","regex(""meow"", regex::icase) is technically forbidden but should be permitted","Issaquah","|Complete|"
|
||||
"`2332 <https://wg21.link/lwg2332>`__","regex_iterator/regex_token_iterator should forbid temporary regexes","Issaquah","|Complete|"
|
||||
"`2339 <https://wg21.link/lwg2339>`__","Wording issue in nth_element","Issaquah","|Complete|"
|
||||
"`2341 <https://wg21.link/lwg2341>`__","Inconsistency between basic_ostream::seekp(pos) and basic_ostream::seekp(off, dir)","Issaquah","|Complete|"
|
||||
"`2344 <https://wg21.link/lwg2344>`__","quoted()'s interaction with padding is unclear","Issaquah","|Complete|"
|
||||
"`2346 <https://wg21.link/lwg2346>`__","integral_constant's member functions should be marked noexcept","Issaquah","|Complete|"
|
||||
"`2350 <https://wg21.link/lwg2350>`__","min, max, and minmax should be constexpr","Issaquah","|Complete|"
|
||||
"`2356 <https://wg21.link/lwg2356>`__","Stability of erasure in unordered associative containers","Issaquah","|Complete|"
|
||||
"`2357 <https://wg21.link/lwg2357>`__","Remaining ""Assignable"" requirement","Issaquah","|Complete|"
|
||||
"`2359 <https://wg21.link/lwg2359>`__","How does regex_constants::nosubs affect basic_regex::mark_count()?","Issaquah","|Complete|"
|
||||
"`2360 <https://wg21.link/lwg2360>`__","``reverse_iterator::operator*()``\ is unimplementable","Issaquah","|Complete|"
|
||||
"`2104 <https://wg21.link/lwg2104>`__","unique_lock move-assignment should not be noexcept","Issaquah","|Complete|"
|
||||
"`2186 <https://wg21.link/lwg2186>`__","Incomplete action on async/launch::deferred","Issaquah","|Complete|"
|
||||
"`2075 <https://wg21.link/lwg2075>`__","Progress guarantees, lock-free property, and scheduling assumptions","Issaquah","|Complete|"
|
||||
"`2288 <https://wg21.link/lwg2288>`__","Inconsistent requirements for shared mutexes","Issaquah","|Complete|"
|
|
32
docs/Status/Cxx14Papers.csv
Normal file
32
docs/Status/Cxx14Papers.csv
Normal file
@ -0,0 +1,32 @@
|
||||
"Paper #","Group","Paper Name","Meeting","Status","First released version"
|
||||
"`3346 <https://wg21.link/n3346>`__","LWG","Terminology for Container Element Requirements - Rev 1","Kona","|Complete|","3.4"
|
||||
"","","","","",""
|
||||
"`3421 <https://wg21.link/n3421>`__","LWG","Making Operator Functors greater<>","Portland","|Complete|","3.4"
|
||||
"`3462 <https://wg21.link/n3462>`__","LWG","std::result_of and SFINAE","Portland","|Complete|","3.4"
|
||||
"`3469 <https://wg21.link/n3469>`__","LWG","Constexpr Library Additions: chrono, v3","Portland","|Complete|","3.4"
|
||||
"`3470 <https://wg21.link/n3470>`__","LWG","Constexpr Library Additions: containers, v2","Portland","|Complete|","3.4"
|
||||
"`3471 <https://wg21.link/n3471>`__","LWG","Constexpr Library Additions: utilities, v3","Portland","|Complete|","3.4"
|
||||
"`3302 <https://wg21.link/n3302>`__","LWG","Constexpr Library Additions: complex, v2","Portland","|Complete|","3.4"
|
||||
"","","","","",""
|
||||
"`3545 <https://wg21.link/n3545>`__","LWG","An Incremental Improvement to integral_constant","Bristol","|Complete|","3.4"
|
||||
"`3644 <https://wg21.link/n3644>`__","LWG","Null Forward Iterators","Bristol","|Complete|","3.4"
|
||||
"`3668 <https://wg21.link/n3668>`__","LWG","std::exchange()","Bristol","|Complete|","3.4"
|
||||
"`3658 <https://wg21.link/n3658>`__","LWG","Compile-time integer sequences","Bristol","|Complete|","3.4"
|
||||
"`3670 <https://wg21.link/n3670>`__","LWG","Addressing Tuples by Type","Bristol","|Complete|","3.4"
|
||||
"`3671 <https://wg21.link/n3671>`__","LWG","Making non-modifying sequence operations more robust","Bristol","|Complete|","3.4"
|
||||
"`3656 <https://wg21.link/n3656>`__","LWG","make_unique","Bristol","|Complete|","3.4"
|
||||
"`3654 <https://wg21.link/n3654>`__","LWG","Quoted Strings","Bristol","|Complete|","3.4"
|
||||
"`3642 <https://wg21.link/n3642>`__","LWG","User-defined Literals","Bristol","|Complete|","3.4"
|
||||
"`3655 <https://wg21.link/n3655>`__","LWG","TransformationTraits Redux (excluding part 4)","Bristol","|Complete|","3.4"
|
||||
"`3657 <https://wg21.link/n3657>`__","LWG","Adding heterogeneous comparison lookup to associative containers","Bristol","|Complete|","3.4"
|
||||
"`3672 <https://wg21.link/n3672>`__","LWG","A proposal to add a utility class to represent optional objects","Bristol","*Removed from Draft Standard*","n/a"
|
||||
"`3669 <https://wg21.link/n3669>`__","LWG","Fixing constexpr member functions without const","Bristol","|Complete|","3.4"
|
||||
"`3662 <https://wg21.link/n3662>`__","LWG","C++ Dynamic Arrays (dynarray)","Bristol","*Removed from Draft Standard*","n/a"
|
||||
"`3659 <https://wg21.link/n3659>`__","SG1","Shared Locking in C++","Bristol","|Complete|","3.4"
|
||||
"","","","","",""
|
||||
"`3779 <https://wg21.link/n3779>`__","LWG","User-defined Literals for std::complex","Chicago","|Complete|","3.4"
|
||||
"`3789 <https://wg21.link/n3789>`__","LWG","Constexpr Library Additions: functional","Chicago","|Complete|","3.4"
|
||||
"","","","","",""
|
||||
"`3924 <https://wg21.link/n3924>`__","LWG","Discouraging rand() in C++14","Issaquah","|Complete|","3.5"
|
||||
"`3887 <https://wg21.link/n3887>`__","LWG","Consistent Metafunction Aliases","Issaquah","|Complete|","3.5"
|
||||
"`3891 <https://wg21.link/n3891>`__","SG1","A proposal to rename shared_mutex to shared_timed_mutex","Issaquah","|Complete|","3.5"
|
|
55
docs/Status/Cxx17.rst
Normal file
55
docs/Status/Cxx17.rst
Normal file
@ -0,0 +1,55 @@
|
||||
.. _cxx17-status:
|
||||
|
||||
================================
|
||||
libc++ C++17 Status
|
||||
================================
|
||||
|
||||
.. include:: ../Helpers/Styles.rst
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
|
||||
Overview
|
||||
================================
|
||||
|
||||
In November 2014, the C++ standard committee created a draft for the next version of the C++ standard, initially known as "C++1z".
|
||||
In February 2017, the C++ standard committee approved this draft, and sent it to ISO for approval as C++17.
|
||||
|
||||
This page shows the status of libc++; the status of clang's support of the language features is `here <https://clang.llvm.org/cxx_status.html#cxx17>`__.
|
||||
|
||||
.. attention:: Features in unreleased drafts of the standard are subject to change.
|
||||
|
||||
The groups that have contributed papers:
|
||||
|
||||
- CWG - Core Language Working group
|
||||
- LWG - Library working group
|
||||
- SG1 - Study group #1 (Concurrency working group)
|
||||
|
||||
.. note:: "Nothing to do" means that no library changes were needed to implement this change.
|
||||
|
||||
.. _paper-status-cxx17:
|
||||
|
||||
Paper Status
|
||||
====================================
|
||||
|
||||
.. csv-table::
|
||||
:file: Cxx17Papers.csv
|
||||
:header-rows: 1
|
||||
:widths: auto
|
||||
|
||||
.. note::
|
||||
|
||||
.. [#note-P0067] P0067: ``std::(to|from)_chars`` for integrals has been available since version 7.0. ``std::to_chars`` for ``float`` and ``double`` since version 14.0 ``std::to_chars`` for ``long double`` uses the implementation for ``double``.
|
||||
.. [#note-P0607] P0607: The parts of P0607 that are not done are the ``<regex>`` bits.
|
||||
|
||||
|
||||
.. _issues-status-cxx17:
|
||||
|
||||
Library Working Group Issues Status
|
||||
====================================
|
||||
|
||||
.. csv-table::
|
||||
:file: Cxx17Issues.csv
|
||||
:header-rows: 1
|
||||
:widths: auto
|
318
docs/Status/Cxx17Issues.csv
Normal file
318
docs/Status/Cxx17Issues.csv
Normal file
@ -0,0 +1,318 @@
|
||||
"Issue #","Issue Name","Meeting","Status","First released version"
|
||||
"`2016 <https://wg21.link/LWG2016>`__","Allocators must be no-throw swappable","Urbana","|Complete|",""
|
||||
"`2118 <https://wg21.link/LWG2376>`__","``unique_ptr``\ for array does not support cv qualification conversion of actual argument","Urbana","|Complete|",""
|
||||
"`2170 <https://wg21.link/LWG2170>`__","Aggregates cannot be ``DefaultConstructible``\ ","Urbana","|Complete|",""
|
||||
"`2308 <https://wg21.link/LWG2308>`__","Clarify container destructor requirements w.r.t. ``std::array``\ ","Urbana","|Complete|",""
|
||||
"`2340 <https://wg21.link/LWG2340>`__","Replacement allocation functions declared as inline","Urbana","|Complete|",""
|
||||
"`2354 <https://wg21.link/LWG2354>`__","Unnecessary copying when inserting into maps with braced-init syntax","Urbana","|Complete|",""
|
||||
"`2377 <https://wg21.link/LWG2377>`__","``std::align``\ requirements overly strict","Urbana","|Complete|",""
|
||||
"`2396 <https://wg21.link/LWG2396>`__","``underlying_type``\ doesn't say what to do for an incomplete enumeration type","Urbana","|Complete|",""
|
||||
"`2399 <https://wg21.link/LWG2399>`__","``shared_ptr``\ 's constructor from ``unique_ptr``\ should be constrained","Urbana","|Complete|",""
|
||||
"`2400 <https://wg21.link/LWG2400>`__","``shared_ptr``\ 's ``get_deleter()``\ should use ``addressof()``\ ","Urbana","|Complete|",""
|
||||
"`2401 <https://wg21.link/LWG2401>`__","``std::function``\ needs more noexcept","Urbana","|Complete|",""
|
||||
"`2404 <https://wg21.link/LWG2404>`__","``mismatch()``\ 's complexity needs to be updated","Urbana","|Complete|",""
|
||||
"`2408 <https://wg21.link/LWG2408>`__","SFINAE-friendly ``common_type``\ / ``iterator_traits``\ is missing in C++14","Urbana","|Complete|",""
|
||||
"","","","",""
|
||||
"`2106 <https://wg21.link/LWG2106>`__","``move_iterator``\ wrapping iterators returning prvalues","Urbana","|Complete|",""
|
||||
"`2129 <https://wg21.link/LWG2129>`__","User specializations of ``std::initializer_list``\ ","Urbana","|Complete|",""
|
||||
"`2212 <https://wg21.link/LWG2212>`__","``tuple_size``\ for ``const pair``\ request <tuple> header","Urbana","|Complete|",""
|
||||
"`2217 <https://wg21.link/LWG2217>`__","``operator==(sub_match, string)``\ slices on embedded '\0's","Urbana","|Complete|",""
|
||||
"`2230 <https://wg21.link/LWG2230>`__","""see below"" for ``initializer_list``\ constructors of unordered containers","Urbana","|Complete|",""
|
||||
"`2233 <https://wg21.link/LWG2233>`__","``bad_function_call::what()``\ unhelpful","Urbana","|Complete|",""
|
||||
"`2266 <https://wg21.link/LWG2266>`__","``vector``\ and ``deque``\ have incorrect insert requirements","Urbana","|Complete|",""
|
||||
"`2325 <https://wg21.link/LWG2325>`__","``minmax_element()``\ 's behavior differing from ``max_element()``\ 's should be noted","Urbana","|Complete|",""
|
||||
"`2361 <https://wg21.link/LWG2361>`__","Apply 2299 resolution throughout library","Urbana","|Complete|",""
|
||||
"`2365 <https://wg21.link/LWG2365>`__","Missing noexcept in ``shared_ptr::shared_ptr(nullptr_t)``\ ","Urbana","|Complete|",""
|
||||
"`2376 <https://wg21.link/LWG2376>`__","``bad_weak_ptr::what()``\ overspecified","Urbana","|Complete|",""
|
||||
"`2387 <https://wg21.link/LWG2387>`__","More nested types that must be accessible and unambiguous","Urbana","|Complete|",""
|
||||
"","","","",""
|
||||
"`2059 <https://wg21.link/LWG2059>`__","C++0x ambiguity problem with map::erase","Lenexa","|Complete|",""
|
||||
"`2063 <https://wg21.link/LWG2063>`__","Contradictory requirements for string move assignment","Lenexa","|Complete|",""
|
||||
"`2076 <https://wg21.link/LWG2076>`__","Bad CopyConstructible requirement in set constructors","Lenexa","|Complete|",""
|
||||
"`2160 <https://wg21.link/LWG2160>`__","Unintended destruction ordering-specification of resize","Lenexa","|Complete|",""
|
||||
"`2168 <https://wg21.link/LWG2168>`__","Inconsistent specification of uniform_real_distribution constructor","Lenexa","|Complete|",""
|
||||
"`2239 <https://wg21.link/LWG2239>`__","min/max/minmax requirements","Lenexa","|Complete|",""
|
||||
"`2364 <https://wg21.link/LWG2364>`__","deque and vector pop_back don't specify iterator invalidation requirements","Lenexa","|Complete|",""
|
||||
"`2369 <https://wg21.link/LWG2369>`__","constexpr max(initializer_list) vs max_element","Lenexa","|Complete|",""
|
||||
"`2378 <https://wg21.link/LWG2378>`__","Behaviour of standard exception types","Lenexa","|Complete|",""
|
||||
"`2403 <https://wg21.link/LWG2403>`__","stof() should call strtof() and wcstof()","Lenexa","|Complete|",""
|
||||
"`2406 <https://wg21.link/LWG2406>`__","negative_binomial_distribution should reject p == 1","Lenexa","|Complete|",""
|
||||
"`2407 <https://wg21.link/LWG2407>`__","packaged_task(allocator_arg_t, const Allocator&, F&&) should neither be constrained nor explicit","Lenexa","|Complete|",""
|
||||
"`2411 <https://wg21.link/LWG2411>`__","shared_ptr is only contextually convertible to bool","Lenexa","|Complete|",""
|
||||
"`2415 <https://wg21.link/LWG2415>`__","Inconsistency between unique_ptr and shared_ptr","Lenexa","|Complete|",""
|
||||
"`2420 <https://wg21.link/LWG2420>`__","function<void(ArgTypes...)> does not discard the return value of the target object","Lenexa","|Complete|",""
|
||||
"`2425 <https://wg21.link/LWG2425>`__","``operator delete(void*, size_t)``\ doesn't invalidate pointers sufficiently","Lenexa","|Complete|",""
|
||||
"`2427 <https://wg21.link/LWG2427>`__","Container adaptors as sequence containers, redux","Lenexa","|Complete|",""
|
||||
"`2428 <https://wg21.link/LWG2428>`__","""External declaration"" used without being defined","Lenexa","|Complete|",""
|
||||
"`2433 <https://wg21.link/LWG2433>`__","``uninitialized_copy()``\ /etc. should tolerate overloaded operator&","Lenexa","|Complete|",""
|
||||
"`2434 <https://wg21.link/LWG2434>`__","``shared_ptr::use_count()``\ is efficient","Lenexa","|Complete|",""
|
||||
"`2437 <https://wg21.link/LWG2437>`__","``iterator_traits::reference``\ can and can't be void","Lenexa","|Complete|",""
|
||||
"`2438 <https://wg21.link/LWG2438>`__","``std::iterator``\ inheritance shouldn't be mandated","Lenexa","|Complete|",""
|
||||
"`2439 <https://wg21.link/LWG2439>`__","``unique_copy()``\ sometimes can't fall back to reading its output","Lenexa","|Complete|",""
|
||||
"`2440 <https://wg21.link/LWG2440>`__","``seed_seq::size()``\ should be noexcept","Lenexa","|Complete|",""
|
||||
"`2442 <https://wg21.link/LWG2442>`__","``call_once()``\ shouldn't DECAY_COPY()","Lenexa","|Complete|",""
|
||||
"`2448 <https://wg21.link/LWG2448>`__","Non-normative Container destructor specification","Lenexa","|Complete|",""
|
||||
"`2454 <https://wg21.link/LWG2454>`__","Add ``raw_storage_iterator::base()``\ member","Lenexa","|Complete|",""
|
||||
"`2455 <https://wg21.link/LWG2455>`__","Allocator default construction should be allowed to throw","Lenexa","|Complete|",""
|
||||
"`2458 <https://wg21.link/LWG2458>`__","N3778 and new library deallocation signatures","Lenexa","|Complete|",""
|
||||
"`2459 <https://wg21.link/LWG2459>`__","``std::polar``\ should require a non-negative rho","Lenexa","|Complete|",""
|
||||
"`2464 <https://wg21.link/LWG2464>`__","``try_emplace``\ and ``insert_or_assign``\ misspecified","Lenexa","|Complete|",""
|
||||
"`2467 <https://wg21.link/LWG2467>`__","``is_always_equal``\ has slightly inconsistent default","Lenexa","|Complete|",""
|
||||
"`2470 <https://wg21.link/LWG2470>`__","Allocator's destroy function should be allowed to fail to instantiate","Lenexa","|Complete|",""
|
||||
"`2482 <https://wg21.link/LWG2482>`__","[c.strings] Table 73 mentions nonexistent functions","Lenexa","|Complete|",""
|
||||
"`2488 <https://wg21.link/LWG2488>`__","Placeholders should be allowed and encouraged to be constexpr","Lenexa","|Complete|",""
|
||||
"","","","",""
|
||||
"`1169 <https://wg21.link/LWG1169>`__","``num_get``\ not fully compatible with ``strto*``\ ","Kona","|Complete|",""
|
||||
"`2072 <https://wg21.link/LWG2072>`__","Unclear wording about capacity of temporary buffers","Kona","|Complete|",""
|
||||
"`2101 <https://wg21.link/LWG2101>`__","Some transformation types can produce impossible types","Kona","|Complete|",""
|
||||
"`2111 <https://wg21.link/LWG2111>`__","Which ``unexpected``\ /``terminate``\ handler is called from the exception handling runtime?","Kona","|Complete|",""
|
||||
"`2119 <https://wg21.link/LWG2119>`__","Missing ``hash``\ specializations for extended integer types","Kona","|Complete|",""
|
||||
"`2127 <https://wg21.link/LWG2127>`__","Move-construction with ``raw_storage_iterator``\ ","Kona","|Complete|",""
|
||||
"`2133 <https://wg21.link/LWG2133>`__","Attitude to overloaded comma for iterators","Kona","|Complete|",""
|
||||
"`2156 <https://wg21.link/LWG2156>`__","Unordered containers' ``reserve(n)``\ reserves for ``n-1``\ elements","Kona","|Complete|",""
|
||||
"`2218 <https://wg21.link/LWG2218>`__","Unclear how containers use ``allocator_traits::construct()``\ ","Kona","|Complete|",""
|
||||
"`2219 <https://wg21.link/LWG2219>`__","``*INVOKE*``\ -ing a pointer to member with a ``reference_wrapper``\ as the object expression","Kona","|Complete|",""
|
||||
"`2224 <https://wg21.link/LWG2224>`__","Ambiguous status of access to non-live objects","Kona","|Complete|",""
|
||||
"`2234 <https://wg21.link/LWG2234>`__","``assert()``\ should allow usage in constant expressions","Kona","|Complete|",""
|
||||
"`2244 <https://wg21.link/LWG2244>`__","Issue on ``basic_istream::seekg``\ ","Kona","|Complete|",""
|
||||
"`2250 <https://wg21.link/LWG2250>`__","Follow-up On Library Issue 2207","Kona","|Complete|",""
|
||||
"`2259 <https://wg21.link/LWG2259>`__","Issues in 17.6.5.5 rules for member functions","Kona","|Complete|",""
|
||||
"`2273 <https://wg21.link/LWG2273>`__","``regex_match``\ ambiguity","Kona","|Complete|",""
|
||||
"`2336 <https://wg21.link/LWG2336>`__","``is_trivially_constructible``\ /``is_trivially_assignable``\ traits are always false","Kona","|Complete|",""
|
||||
"`2353 <https://wg21.link/LWG2353>`__","``std::next``\ is over-constrained","Kona","|Complete|",""
|
||||
"`2367 <https://wg21.link/LWG2367>`__","``pair``\ and ``tuple``\ are not correctly implemented for ``is_constructible``\ with no args","Kona","|Complete|",""
|
||||
"`2380 <https://wg21.link/LWG2380>`__","May ``<cstdlib>``\ provide ``long ::abs(long)``\ and ``long long ::abs(long long)``\ ?","Kona","|Complete|",""
|
||||
"`2384 <https://wg21.link/LWG2384>`__","Allocator's ``deallocate``\ function needs better specification","Kona","|Complete|",""
|
||||
"`2385 <https://wg21.link/LWG2385>`__","``function::assign``\ allocator argument doesn't make sense","Kona","|Complete|",""
|
||||
"`2435 <https://wg21.link/LWG2435>`__","``reference_wrapper::operator()``\ 's Remark should be deleted","Kona","|Complete|",""
|
||||
"`2447 <https://wg21.link/LWG2447>`__","Allocators and ``volatile``\ -qualified value types","Kona","|Complete|",""
|
||||
"`2462 <https://wg21.link/LWG2462>`__","``std::ios_base::failure``\ is overspecified","Kona","|Complete|",""
|
||||
"`2466 <https://wg21.link/LWG2466>`__","``allocator_traits::max_size()``\ default behavior is incorrect","Kona","|Complete|",""
|
||||
"`2469 <https://wg21.link/LWG2469>`__","Wrong specification of Requires clause of ``operator[]``\ for ``map``\ and ``unordered_map``\ ","Kona","|Complete|",""
|
||||
"`2473 <https://wg21.link/LWG2473>`__","``basic_filebuf``\ 's relation to C ``FILE``\ semantics","Kona","|Complete|",""
|
||||
"`2476 <https://wg21.link/LWG2476>`__","``scoped_allocator_adaptor``\ is not assignable","Kona","|Complete|",""
|
||||
"`2477 <https://wg21.link/LWG2477>`__","Inconsistency of wordings in ``std::vector::erase()``\ and ``std::deque::erase()``\ ","Kona","|Complete|",""
|
||||
"`2483 <https://wg21.link/LWG2483>`__","``throw_with_nested()``\ should use ``is_final``\ ","Kona","|Complete|",""
|
||||
"`2484 <https://wg21.link/LWG2484>`__","``rethrow_if_nested()``\ is doubly unimplementable","Kona","|Complete|",""
|
||||
"`2485 <https://wg21.link/LWG2485>`__","``get()``\ should be overloaded for ``const tuple&&``\ ","Kona","|Complete|",""
|
||||
"`2486 <https://wg21.link/LWG2486>`__","``mem_fn()``\ should be required to use perfect forwarding","Kona","|Complete|",""
|
||||
"`2487 <https://wg21.link/LWG2487>`__","``bind()``\ should be ``const``\ -overloaded, not *cv*-overloaded","Kona","|Complete|",""
|
||||
"`2489 <https://wg21.link/LWG2489>`__","``mem_fn()``\ should be ``noexcept``\ ","Kona","|Complete|",""
|
||||
"`2492 <https://wg21.link/LWG2492>`__","Clarify requirements for ``comp``\ ","Kona","|Complete|",""
|
||||
"`2495 <https://wg21.link/LWG2495>`__","There is no such thing as an Exception Safety element","Kona","|Complete|",""
|
||||
"","","","",""
|
||||
"`2192 <https://wg21.link/LWG2192>`__","Validity and return type of ``std::abs(0u)``\ is unclear","Jacksonville","|Complete|",""
|
||||
"`2276 <https://wg21.link/LWG2276>`__","Missing requirement on ``std::promise::set_exception``\ ","Jacksonville","|Complete|",""
|
||||
"`2296 <https://wg21.link/LWG2296>`__","``std::addressof``\ should be ``constexpr``\ ","Jacksonville","|Complete|",""
|
||||
"`2450 <https://wg21.link/LWG2450>`__","``(greater|less|greater_equal|less_equal)<void>``\ do not yield a total order for pointers","Jacksonville","|Complete|",""
|
||||
"`2520 <https://wg21.link/LWG2520>`__","N4089 broke initializing ``unique_ptr<T[]>``\ from a ``nullptr``\ ","Jacksonville","|Complete|",""
|
||||
"`2522 <https://wg21.link/LWG2522>`__","[fund.ts.v2] Contradiction in ``set_default_resource``\ specification","Jacksonville","|Complete|",""
|
||||
"`2523 <https://wg21.link/LWG2523>`__","``std::promise``\ synopsis shows two ``set_value_at_thread_exit()``\ 's for no apparent reason","Jacksonville","|Complete|",""
|
||||
"`2537 <https://wg21.link/LWG2537>`__","Constructors for ``priority_queue``\ taking allocators should call ``make_heap``\ ","Jacksonville","|Complete|",""
|
||||
"`2539 <https://wg21.link/LWG2539>`__","[fund.ts.v2] ``invocation_trait``\ definition definition doesn't work for surrogate call functions","Jacksonville","",""
|
||||
"`2545 <https://wg21.link/LWG2545>`__","Simplify wording for ``bind``\ without explicitly specified return type","Jacksonville","|Complete|",""
|
||||
"`2557 <https://wg21.link/LWG2557>`__","Logical operator traits are broken in the zero-argument case","Jacksonville","|Complete|",""
|
||||
"`2558 <https://wg21.link/LWG2558>`__","[fund.ts.v2] Logical operator traits are broken in the zero-argument case","Jacksonville","|Complete|",""
|
||||
"`2559 <https://wg21.link/LWG2559>`__","Error in LWG 2234's resolution","Jacksonville","|Complete|",""
|
||||
"`2560 <https://wg21.link/LWG2560>`__","``is_constructible``\ underspecified when applied to a function type","Jacksonville","|Complete|",""
|
||||
"`2565 <https://wg21.link/LWG2565>`__","``std::function``\ 's move constructor should guarantee nothrow for ``reference_wrapper``\ s and function pointers","Jacksonville","|Complete|",""
|
||||
"`2566 <https://wg21.link/LWG2566>`__","Requirements on the first template parameter of container adaptors","Jacksonville","|Complete|",""
|
||||
"`2571 <https://wg21.link/LWG2571>`__","|sect|\ [map.modifiers]/2 imposes nonsensical requirement on ``insert(InputIterator, InputIterator)``\ ","Jacksonville","|Complete|",""
|
||||
"`2572 <https://wg21.link/LWG2572>`__","The remarks for ``shared_ptr::operator*``\ should apply to *cv*-qualified ``void``\ as well","Jacksonville","|Complete|",""
|
||||
"`2574 <https://wg21.link/LWG2574>`__","[fund.ts.v2] ``std::experimental::function::operator=(F&&)``\ should be constrained","Jacksonville","|Complete|",""
|
||||
"`2575 <https://wg21.link/LWG2575>`__","[fund.ts.v2] ``experimental::function::assign``\ should be removed","Jacksonville","",""
|
||||
"`2576 <https://wg21.link/LWG2576>`__","``istream_iterator``\ and ``ostream_iterator``\ should use ``std::addressof``\ ","Jacksonville","|Complete|",""
|
||||
"`2577 <https://wg21.link/LWG2577>`__","``{shared,unique}_lock``\ should use ``std::addressof``\ ","Jacksonville","|Complete|",""
|
||||
"`2579 <https://wg21.link/LWG2579>`__","Inconsistency wrt Allocators in ``basic_string``\ assignment vs. ``basic_string::assign``\ ","Jacksonville","|Complete|",""
|
||||
"`2581 <https://wg21.link/LWG2581>`__","Specialization of ``<type_traits>``\ variable templates should be prohibited","Jacksonville","|Complete|",""
|
||||
"`2582 <https://wg21.link/LWG2582>`__","|sect|\ [res.on.functions]/2's prohibition against incomplete types shouldn't apply to type traits","Jacksonville","|Complete|",""
|
||||
"`2583 <https://wg21.link/LWG2583>`__","There is no way to supply an allocator for ``basic_string(str, pos)``\ ","Jacksonville","|Complete|",""
|
||||
"`2585 <https://wg21.link/LWG2585>`__","``forward_list::resize(size_type, const value_type&)``\ effects incorrect","Jacksonville","|Complete|",""
|
||||
"`2586 <https://wg21.link/LWG2586>`__","Wrong value category used in ``scoped_allocator_adaptor::construct()``\ ","Jacksonville","|Complete|",""
|
||||
"`2590 <https://wg21.link/LWG2590>`__","Aggregate initialization for ``std::array``\ ","Jacksonville","|Complete|",""
|
||||
"","","","",""
|
||||
"`2181 <https://wg21.link/LWG2181>`__","Exceptions from seed sequence operations","Oulu","|Complete|",""
|
||||
"`2309 <https://wg21.link/LWG2309>`__","mutex::lock() should not throw device_or_resource_busy","Oulu","|Complete|",""
|
||||
"`2310 <https://wg21.link/LWG2310>`__","Public exposition only member in std::array","Oulu","|Complete|",""
|
||||
"`2312 <https://wg21.link/LWG2312>`__","tuple's constructor constraints need to be phrased more precisely","Oulu","|Complete|",""
|
||||
"`2328 <https://wg21.link/LWG2328>`__","Rvalue stream extraction should use perfect forwarding","Oulu","|Complete|",""
|
||||
"`2393 <https://wg21.link/LWG2393>`__","std::function's Callable definition is broken","Oulu","|Complete|",""
|
||||
"`2422 <https://wg21.link/LWG2422>`__","``std::numeric_limits<T>::is_modulo``\ description: ""most machines"" errata","Oulu","|Complete|",""
|
||||
"`2426 <https://wg21.link/LWG2426>`__","Issue about compare_exchange","Oulu","",""
|
||||
"`2436 <https://wg21.link/LWG2436>`__","Comparators for associative containers should always be CopyConstructible","Oulu","|Complete|",""
|
||||
"`2441 <https://wg21.link/LWG2441>`__","Exact-width atomic typedefs should be provided","Oulu","|Complete|",""
|
||||
"`2451 <https://wg21.link/LWG2451>`__","[fund.ts.v2] optional should 'forward' T's implicit conversions","Oulu","|Nothing To Do|",""
|
||||
"`2509 <https://wg21.link/LWG2509>`__","[fund.ts.v2] any_cast doesn't work with rvalue reference targets and cannot move with a value target","Oulu","|Complete|",""
|
||||
"`2516 <https://wg21.link/LWG2516>`__","[fund.ts.v2] Public ""exposition only"" members in observer_ptr","Oulu","",""
|
||||
"`2542 <https://wg21.link/LWG2542>`__","Missing const requirements for associative containers","Oulu","",""
|
||||
"`2549 <https://wg21.link/LWG2549>`__","Tuple EXPLICIT constructor templates that take tuple parameters end up taking references to temporaries and will create dangling references","Oulu","|Complete|",""
|
||||
"`2550 <https://wg21.link/LWG2550>`__","Wording of unordered container's clear() method complexity","Oulu","|Complete|",""
|
||||
"`2551 <https://wg21.link/LWG2551>`__","[fund.ts.v2] ""Exception safety"" cleanup in library fundamentals required","Oulu","|Complete|",""
|
||||
"`2555 <https://wg21.link/LWG2555>`__","[fund.ts.v2] No handling for over-aligned types in optional","Oulu","|Complete|",""
|
||||
"`2573 <https://wg21.link/LWG2573>`__","[fund.ts.v2] std::hash<std::experimental::shared_ptr> does not work for arrays","Oulu","",""
|
||||
"`2596 <https://wg21.link/LWG2596>`__","vector::data() should use addressof","Oulu","|Complete|",""
|
||||
"`2667 <https://wg21.link/LWG2667>`__","path::root_directory() description is confusing","Oulu","|Complete|",""
|
||||
"`2669 <https://wg21.link/LWG2669>`__","recursive_directory_iterator effects refers to non-existent functions","Oulu","|Complete|",""
|
||||
"`2670 <https://wg21.link/LWG2670>`__","system_complete refers to undefined variable 'base'","Oulu","|Complete|",""
|
||||
"`2671 <https://wg21.link/LWG2671>`__","Errors in Copy","Oulu","|Complete|",""
|
||||
"`2673 <https://wg21.link/LWG2673>`__","status() effects cannot be implemented as specified","Oulu","|Complete|",""
|
||||
"`2674 <https://wg21.link/LWG2674>`__","Bidirectional iterator requirement on path::iterator is very expensive","Oulu","|Complete|",""
|
||||
"`2683 <https://wg21.link/LWG2683>`__","filesystem::copy() says ""no effects""","Oulu","|Complete|",""
|
||||
"`2684 <https://wg21.link/LWG2684>`__","priority_queue lacking comparator typedef","Oulu","|Complete|",""
|
||||
"`2685 <https://wg21.link/LWG2685>`__","shared_ptr deleters must not throw on move construction","Oulu","|Complete|",""
|
||||
"`2687 <https://wg21.link/LWG2687>`__","{inclusive,exclusive}_scan misspecified","Oulu","",""
|
||||
"`2688 <https://wg21.link/LWG2688>`__","clamp misses preconditions and has extraneous condition on result","Oulu","|Complete|",""
|
||||
"`2689 <https://wg21.link/LWG2689>`__","Parallel versions of std::copy and std::move shouldn't be in order","Oulu","",""
|
||||
"`2698 <https://wg21.link/LWG2698>`__","Effect of assign() on iterators/pointers/references","Oulu","|Complete|",""
|
||||
"`2704 <https://wg21.link/LWG2704>`__","recursive_directory_iterator's members should require '``*this`` is dereferenceable'","Oulu","|Complete|",""
|
||||
"`2706 <https://wg21.link/LWG2706>`__","Error reporting for recursive_directory_iterator::pop() is under-specified","Oulu","|Complete|",""
|
||||
"`2707 <https://wg21.link/LWG2707>`__","path construction and assignment should have ""string_type&&"" overloads","Oulu","|Complete|",""
|
||||
"`2709 <https://wg21.link/LWG2709>`__","offsetof is unnecessarily imprecise","Oulu","",""
|
||||
"`2710 <https://wg21.link/LWG2710>`__","""Effects: Equivalent to ..."" doesn't count ""Synchronization:"" as determined semantics","Oulu","|Complete|",""
|
||||
"`2711 <https://wg21.link/LWG2711>`__","path is convertible from approximately everything under the sun","Oulu","|Complete|",""
|
||||
"`2716 <https://wg21.link/LWG2716>`__","Specification of shuffle and sample disallows lvalue URNGs","Oulu","|Complete|",""
|
||||
"`2718 <https://wg21.link/LWG2718>`__","Parallelism bug in [algorithms.parallel.exec] p2","Oulu","",""
|
||||
"`2719 <https://wg21.link/LWG2719>`__","permissions function should not be noexcept due to narrow contract","Oulu","|Complete|",""
|
||||
"`2720 <https://wg21.link/LWG2720>`__","permissions function incorrectly specified for symlinks","Oulu","|Complete|",""
|
||||
"`2721 <https://wg21.link/LWG2721>`__","remove_all has incorrect post conditions","Oulu","|Complete|",""
|
||||
"`2723 <https://wg21.link/LWG2723>`__","Do directory_iterator and recursive_directory_iterator become the end iterator upon error?","Oulu","|Complete|",""
|
||||
"`2724 <https://wg21.link/LWG2724>`__","The protected virtual member functions of memory_resource should be private","Oulu","",""
|
||||
"`2725 <https://wg21.link/LWG2725>`__","filesystem::exists(const path&, error_code&) error reporting","Oulu","|Complete|",""
|
||||
"`2726 <https://wg21.link/LWG2726>`__","``[recursive_]directory_iterator::increment(error_code&)`` is underspecified","Oulu","|Complete|",""
|
||||
"`2727 <https://wg21.link/LWG2727>`__","Parallel algorithms with constexpr specifier","Oulu","",""
|
||||
"`2728 <https://wg21.link/LWG2728>`__","status(p).permissions() and symlink_status(p).permissions() are not specified","Oulu","|Complete|",""
|
||||
"","","","",""
|
||||
"`2062 <https://wg21.link/LWG2062>`__","Effect contradictions w/o no-throw guarantee of std::function swaps","Issaquah","|Complete|",""
|
||||
"`2166 <https://wg21.link/LWG2166>`__","Heap property underspecified?","Issaquah","",""
|
||||
"`2221 <https://wg21.link/LWG2221>`__","No formatted output operator for nullptr","Issaquah","|Complete|",""
|
||||
"`2223 <https://wg21.link/LWG2223>`__","shrink_to_fit effect on iterator validity","Issaquah","|Complete|",""
|
||||
"`2261 <https://wg21.link/LWG2261>`__","Are containers required to use their 'pointer' type internally?","Issaquah","",""
|
||||
"`2394 <https://wg21.link/LWG2394>`__","locale::name specification unclear - what is implementation-defined?","Issaquah","|Complete|",""
|
||||
"`2460 <https://wg21.link/LWG2460>`__","LWG issue 2408 and value categories","Issaquah","|Complete|",""
|
||||
"`2468 <https://wg21.link/LWG2468>`__","Self-move-assignment of library types","Issaquah","",""
|
||||
"`2475 <https://wg21.link/LWG2475>`__","Allow overwriting of std::basic_string terminator with charT() to allow cleaner interoperation with legacy APIs","Issaquah","|Complete|",""
|
||||
"`2503 <https://wg21.link/LWG2503>`__","multiline option should be added to syntax_option_type","Issaquah","|Complete|",""
|
||||
"`2510 <https://wg21.link/LWG2510>`__","Tag types should not be DefaultConstructible","Issaquah","|Complete|",""
|
||||
"`2514 <https://wg21.link/LWG2514>`__","Type traits must not be final","Issaquah","|Complete|",""
|
||||
"`2518 <https://wg21.link/LWG2518>`__","[fund.ts.v2] Non-member swap for propagate_const should call member swap","Issaquah","|Complete|",""
|
||||
"`2519 <https://wg21.link/LWG2519>`__","Iterator operator-= has gratuitous undefined behaviour","Issaquah","|Complete|",""
|
||||
"`2521 <https://wg21.link/LWG2521>`__","[fund.ts.v2] weak_ptr's converting move constructor should be modified as well for array support","Issaquah","",""
|
||||
"`2525 <https://wg21.link/LWG2525>`__","[fund.ts.v2] get_memory_resource should be const and noexcept","Issaquah","",""
|
||||
"`2527 <https://wg21.link/LWG2527>`__","[fund.ts.v2] ALLOCATOR_OF for function::operator= has incorrect default","Issaquah","",""
|
||||
"`2531 <https://wg21.link/LWG2531>`__","future::get should explicitly state that the shared state is released","Issaquah","",""
|
||||
"`2534 <https://wg21.link/LWG2534>`__","Constrain rvalue stream operators","Issaquah","|Complete|",""
|
||||
"`2536 <https://wg21.link/LWG2536>`__","What should <complex.h> do?","Issaquah","|Complete|",""
|
||||
"`2540 <https://wg21.link/LWG2540>`__","unordered_multimap::insert hint iterator","Issaquah","|Complete|",""
|
||||
"`2543 <https://wg21.link/LWG2543>`__","LWG 2148 (hash support for enum types) seems under-specified","Issaquah","|Complete|",""
|
||||
"`2544 <https://wg21.link/LWG2544>`__","``istreambuf_iterator(basic_streambuf<charT, traits>* s)``\ effects unclear when s is 0","Issaquah","|Complete|",""
|
||||
"`2556 <https://wg21.link/LWG2556>`__","Wide contract for future::share()","Issaquah","|Complete|",""
|
||||
"`2562 <https://wg21.link/LWG2562>`__","Consistent total ordering of pointers by comparison functors","Issaquah","",""
|
||||
"`2567 <https://wg21.link/LWG2567>`__","Specification of logical operator traits uses BaseCharacteristic, which is defined only for UnaryTypeTraits and BinaryTypeTraits","Issaquah","|Complete|",""
|
||||
"`2568 <https://wg21.link/LWG2568>`__","[fund.ts.v2] Specification of logical operator traits uses BaseCharacteristic, which is defined only for UnaryTypeTraits and BinaryTypeTraits","Issaquah","",""
|
||||
"`2569 <https://wg21.link/LWG2569>`__","conjunction and disjunction requirements are too strict","Issaquah","|Complete|",""
|
||||
"`2570 <https://wg21.link/LWG2570>`__","[fund.ts.v2] conjunction and disjunction requirements are too strict","Issaquah","",""
|
||||
"`2578 <https://wg21.link/LWG2578>`__","Iterator requirements should reference iterator traits","Issaquah","|Complete|",""
|
||||
"`2584 <https://wg21.link/LWG2584>`__","<regex> ECMAScript IdentityEscape is ambiguous","Issaquah","",""
|
||||
"`2587 <https://wg21.link/LWG2587>`__","""Convertible to bool"" requirement in conjunction and disjunction","Issaquah","Resolved by 2567",""
|
||||
"`2588 <https://wg21.link/LWG2588>`__","[fund.ts.v2] ""Convertible to bool"" requirement in conjunction and disjunction","Issaquah","",""
|
||||
"`2589 <https://wg21.link/LWG2589>`__","match_results can't satisfy the requirements of a container","Issaquah","|Complete|",""
|
||||
"`2591 <https://wg21.link/LWG2591>`__","std::function's member template target() should not lead to undefined behaviour","Issaquah","|Complete|",""
|
||||
"`2598 <https://wg21.link/LWG2598>`__","addressof works on temporaries","Issaquah","|Complete|",""
|
||||
"`2664 <https://wg21.link/LWG2664>`__","operator/ (and other append) semantics not useful if argument has root","Issaquah","|Complete|",""
|
||||
"`2665 <https://wg21.link/LWG2665>`__","remove_filename() post condition is incorrect","Issaquah","|Complete|",""
|
||||
"`2672 <https://wg21.link/LWG2672>`__","Should ``is_empty``\ use error_code in its specification?","Issaquah","|Complete|",""
|
||||
"`2678 <https://wg21.link/LWG2678>`__","std::filesystem enum classes overspecified","Issaquah","|Complete|",""
|
||||
"`2679 <https://wg21.link/LWG2679>`__","Inconsistent Use of Effects and Equivalent To","Issaquah","|Complete|",""
|
||||
"`2680 <https://wg21.link/LWG2680>`__","Add ""Equivalent to"" to filesystem","Issaquah","|Complete|",""
|
||||
"`2681 <https://wg21.link/LWG2681>`__","filesystem::copy() cannot copy symlinks","Issaquah","|Complete|",""
|
||||
"`2682 <https://wg21.link/LWG2682>`__","filesystem::copy() won't create a symlink to a directory","Issaquah","|Complete|",""
|
||||
"`2686 <https://wg21.link/LWG2686>`__","Why is std::hash specialized for error_code, but not error_condition?","Issaquah","|Complete|",""
|
||||
"`2694 <https://wg21.link/LWG2694>`__","Application of LWG 436 accidentally deleted definition of ""facet""","Issaquah","|Complete|",""
|
||||
"`2696 <https://wg21.link/LWG2696>`__","Interaction between make_shared and enable_shared_from_this is underspecified","Issaquah","|Nothing To Do|",""
|
||||
"`2699 <https://wg21.link/LWG2699>`__","Missing restriction in [numeric.requirements]","Issaquah","|Complete|",""
|
||||
"`2712 <https://wg21.link/LWG2712>`__","copy_file(from, to, ...) has a number of unspecified error conditions","Issaquah","|Complete|",""
|
||||
"`2722 <https://wg21.link/LWG2722>`__","equivalent incorrectly specifies throws clause","Issaquah","|Complete|",""
|
||||
"`2729 <https://wg21.link/LWG2729>`__","Missing SFINAE on std::pair::operator=","Issaquah","|Complete|",""
|
||||
"`2732 <https://wg21.link/LWG2732>`__","Questionable specification of path::operator/= and path::append","Issaquah","|Complete|",""
|
||||
"`2733 <https://wg21.link/LWG2733>`__","[fund.ts.v2] gcd / lcm and bool","Issaquah","|Complete|",""
|
||||
"`2735 <https://wg21.link/LWG2735>`__","std::abs(short), std::abs(signed char) and others should return int instead of double in order to be compatible with C++98 and C","Issaquah","|Complete|",""
|
||||
"`2736 <https://wg21.link/LWG2736>`__","nullopt_t insufficiently constrained","Issaquah","|Complete|",""
|
||||
"`2738 <https://wg21.link/LWG2738>`__","``is_constructible``\ with void types","Issaquah","|Complete|",""
|
||||
"`2739 <https://wg21.link/LWG2739>`__","Issue with time_point non-member subtraction with an unsigned duration","Issaquah","|Complete|",""
|
||||
"`2740 <https://wg21.link/LWG2740>`__","constexpr optional<T>::operator->","Issaquah","|Complete|",""
|
||||
"`2742 <https://wg21.link/LWG2742>`__","Inconsistent string interface taking string_view","Issaquah","|Complete|",""
|
||||
"`2744 <https://wg21.link/LWG2744>`__","any's in_place constructors","Issaquah","|Complete|",""
|
||||
"`2745 <https://wg21.link/LWG2745>`__","[fund.ts.v2] Implementability of LWG 2451","Issaquah","|Complete|",""
|
||||
"`2747 <https://wg21.link/LWG2747>`__","Possibly redundant std::move in [alg.foreach]","Issaquah","|Complete|",""
|
||||
"`2748 <https://wg21.link/LWG2748>`__","swappable traits for optionals","Issaquah","|Complete|",""
|
||||
"`2749 <https://wg21.link/LWG2749>`__","swappable traits for variants","Issaquah","|Complete|",""
|
||||
"`2750 <https://wg21.link/LWG2750>`__","[fund.ts.v2] LWG 2451 conversion constructor constraint","Issaquah","|Nothing To Do|",""
|
||||
"`2752 <https://wg21.link/LWG2752>`__","""Throws:"" clauses of async and packaged_task are unimplementable","Issaquah","",""
|
||||
"`2755 <https://wg21.link/LWG2755>`__","[string.view.io] uses non-existent basic_string_view::to_string function","Issaquah","|Complete|",""
|
||||
"`2756 <https://wg21.link/LWG2756>`__","C++ WP optional<T> should 'forward' T's implicit conversions","Issaquah","|Complete|",""
|
||||
"`2758 <https://wg21.link/LWG2758>`__","std::string{}.assign(""ABCDE"", 0, 1) is ambiguous","Issaquah","|Complete|",""
|
||||
"`2759 <https://wg21.link/LWG2759>`__","gcd / lcm and bool for the WP","Issaquah","|Complete|",""
|
||||
"`2760 <https://wg21.link/LWG2760>`__","non-const basic_string::data should not invalidate iterators","Issaquah","|Complete|",""
|
||||
"`2765 <https://wg21.link/LWG2765>`__","Did LWG 1123 go too far?","Issaquah","|Complete|",""
|
||||
"`2767 <https://wg21.link/LWG2767>`__","not_fn call_wrapper can form invalid types","Issaquah","|Complete|",""
|
||||
"`2769 <https://wg21.link/LWG2769>`__","Redundant const in the return type of any_cast(const any&)","Issaquah","|Complete|",""
|
||||
"`2771 <https://wg21.link/LWG2771>`__","Broken Effects of some basic_string::compare functions in terms of basic_string_view","Issaquah","|Complete|",""
|
||||
"`2773 <https://wg21.link/LWG2773>`__","Making std::ignore constexpr","Issaquah","|Complete|",""
|
||||
"`2777 <https://wg21.link/LWG2777>`__","basic_string_view::copy should use char_traits::copy","Issaquah","|Complete|",""
|
||||
"`2778 <https://wg21.link/LWG2778>`__","basic_string_view is missing constexpr","Issaquah","|Complete|",""
|
||||
"","","","",""
|
||||
"`2260 <https://wg21.link/LWG2260>`__","Missing requirement for Allocator::pointer","Kona","|Complete|",""
|
||||
"`2676 <https://wg21.link/LWG2676>`__","Provide filesystem::path overloads for File-based streams","Kona","|Complete|",""
|
||||
"`2768 <https://wg21.link/LWG2768>`__","any_cast and move semantics","Kona","|Complete|",""
|
||||
"`2769 <https://wg21.link/LWG2769>`__","Redundant const in the return type of any_cast(const any&)","Kona","|Complete|",""
|
||||
"`2781 <https://wg21.link/LWG2781>`__","Contradictory requirements for std::function and std::reference_wrapper","Kona","|Complete|",""
|
||||
"`2782 <https://wg21.link/LWG2782>`__","scoped_allocator_adaptor constructors must be constrained","Kona","|Complete|",""
|
||||
"`2784 <https://wg21.link/LWG2784>`__","Resolution to LWG 2484 is missing ""otherwise, no effects"" and is hard to parse","Kona","|Complete|",""
|
||||
"`2785 <https://wg21.link/LWG2785>`__","quoted should work with basic_string_view","Kona","|Complete|",""
|
||||
"`2786 <https://wg21.link/LWG2786>`__","Annex C should mention shared_ptr changes for array support","Kona","|Complete|",""
|
||||
"`2787 <https://wg21.link/LWG2787>`__","|sect|\ [file_status.cons] doesn't match class definition","Kona","|Complete|",""
|
||||
"`2788 <https://wg21.link/LWG2788>`__","basic_string range mutators unintentionally require a default constructible allocator","Kona","|Complete|",""
|
||||
"`2789 <https://wg21.link/LWG2789>`__","Equivalence of contained objects","Kona","|Complete|",""
|
||||
"`2790 <https://wg21.link/LWG2790>`__","Missing specification of istreambuf_iterator::operator->","Kona","|Complete|",""
|
||||
"`2794 <https://wg21.link/LWG2794>`__","Missing requirements for allocator pointers","Kona","|Nothing To Do|",""
|
||||
"`2795 <https://wg21.link/LWG2795>`__","|sect|\ [global.functions] provides incorrect example of ADL use","Kona","|Complete|",""
|
||||
"`2796 <https://wg21.link/LWG2796>`__","tuple should be a literal type","Kona","|Complete|",""
|
||||
"`2801 <https://wg21.link/LWG2801>`__","Default-constructibility of unique_ptr","Kona","|Complete|",""
|
||||
"`2802 <https://wg21.link/LWG2802>`__","shared_ptr constructor requirements for a deleter","Kona","|Complete|",""
|
||||
"`2804 <https://wg21.link/LWG2804>`__","Unconditional constexpr default constructor for istream_iterator","Kona","|Complete|",""
|
||||
"`2806 <https://wg21.link/LWG2806>`__","Base class of bad_optional_access","Kona","|Complete|",""
|
||||
"`2807 <https://wg21.link/LWG2807>`__","std::invoke should use ``std::is_nothrow_callable``\ ","Kona","|Complete|",""
|
||||
"`2812 <https://wg21.link/LWG2812>`__","Range access is available with <string_view>","Kona","|Complete|",""
|
||||
"`2824 <https://wg21.link/LWG2824>`__","list::sort should say that the order of elements is unspecified if an exception is thrown","Kona","|Complete|",""
|
||||
"`2826 <https://wg21.link/LWG2826>`__","string_view iterators use old wording","Kona","|Complete|",""
|
||||
"`2834 <https://wg21.link/LWG2834>`__","Resolution LWG 2223 is missing wording about end iterators","Kona","|Complete|",""
|
||||
"`2835 <https://wg21.link/LWG2835>`__","LWG 2536 seems to misspecify <tgmath.h>","Kona","|Complete|",""
|
||||
"`2837 <https://wg21.link/LWG2837>`__","gcd and lcm should support a wider range of input values","Kona","|Complete|",""
|
||||
"`2838 <https://wg21.link/LWG2838>`__","is_literal_type specification needs a little cleanup","Kona","|Complete|",""
|
||||
"`2842 <https://wg21.link/LWG2842>`__","in_place_t check for optional::optional(U&&) should decay U","Kona","|Complete|",""
|
||||
"`2850 <https://wg21.link/LWG2850>`__","std::function move constructor does unnecessary work","Kona","|Complete|",""
|
||||
"`2853 <https://wg21.link/LWG2853>`__","Possible inconsistency in specification of erase in [vector.modifiers]","Kona","|Complete|",""
|
||||
"`2855 <https://wg21.link/LWG2855>`__","std::throw_with_nested(""string_literal"")","Kona","|Complete|",""
|
||||
"`2857 <https://wg21.link/LWG2857>`__","{variant,optional,any}::emplace should return the constructed value","Kona","|Complete|",""
|
||||
"`2861 <https://wg21.link/LWG2861>`__","basic_string should require that charT match traits::char_type","Kona","|Complete|",""
|
||||
"`2866 <https://wg21.link/LWG2866>`__","Incorrect derived classes constraints","Kona","|Nothing To Do|",""
|
||||
"`2868 <https://wg21.link/LWG2868>`__","Missing specification of bad_any_cast::what()","Kona","|Complete|",""
|
||||
"`2872 <https://wg21.link/LWG2872>`__","Add definition for direct-non-list-initialization","Kona","|Complete|",""
|
||||
"`2873 <https://wg21.link/LWG2873>`__","Add noexcept to several shared_ptr related functions","Kona","|Complete|",""
|
||||
"`2874 <https://wg21.link/LWG2874>`__","Constructor ``shared_ptr::shared_ptr(Y*)``\ should be constrained","Kona","|Complete|","13.0"
|
||||
"`2875 <https://wg21.link/LWG2875>`__","shared_ptr::shared_ptr(Y\*, D, [|hellip|\ ]) constructors should be constrained","Kona","|Complete|",""
|
||||
"`2876 <https://wg21.link/LWG2876>`__","``shared_ptr::shared_ptr(const weak_ptr<Y>&)``\ constructor should be constrained","Kona","",""
|
||||
"`2878 <https://wg21.link/LWG2878>`__","Missing DefaultConstructible requirement for istream_iterator default constructor","Kona","|Complete|",""
|
||||
"`2890 <https://wg21.link/LWG2890>`__","The definition of 'object state' applies only to class types","Kona","|Complete|",""
|
||||
"`2900 <https://wg21.link/LWG2900>`__","The copy and move constructors of optional are not constexpr","Kona","|Complete|",""
|
||||
"`2903 <https://wg21.link/LWG2903>`__","The form of initialization for the emplace-constructors is not specified","Kona","|Complete|",""
|
||||
"`2904 <https://wg21.link/LWG2904>`__","Make variant move-assignment more exception safe","Kona","|Complete|",""
|
||||
"`2905 <https://wg21.link/LWG2905>`__","is_constructible_v<unique_ptr<P, D>, P, D const &> should be false when D is not copy constructible","Kona","|Complete|",""
|
||||
"`2908 <https://wg21.link/LWG2908>`__","The less-than operator for shared pointers could do more","Kona","|Complete|",""
|
||||
"`2911 <https://wg21.link/LWG2911>`__","An is_aggregate type trait is needed","Kona","|Complete|",""
|
||||
"`2921 <https://wg21.link/LWG2921>`__","packaged_task and type-erased allocators","Kona","|Complete|",""
|
||||
"`2934 <https://wg21.link/LWG2934>`__","optional<const T> doesn't compare with T","Kona","|Complete|",""
|
||||
"","","","",""
|
||||
"`2901 <https://wg21.link/LWG2901>`__","Variants cannot properly support allocators","Toronto","|Complete|",""
|
||||
"`2955 <https://wg21.link/LWG2955>`__","``to_chars / from_chars``\ depend on ``std::string``\ ","Toronto","Resolved by `P0682R1 <https://wg21.link/P0682R1>`__",""
|
||||
"`2956 <https://wg21.link/LWG2956>`__","``filesystem::canonical()``\ still defined in terms of ``absolute(p, base)``\ ","Toronto","|Complete|",""
|
|
113
docs/Status/Cxx17Papers.csv
Normal file
113
docs/Status/Cxx17Papers.csv
Normal file
@ -0,0 +1,113 @@
|
||||
"Paper #","Group","Paper Name","Meeting","Status","First released version"
|
||||
"`N3911 <https://wg21.link/n3911>`__","LWG","TransformationTrait Alias ``void_t``\ .","Urbana","|Complete|","3.6"
|
||||
"`N4089 <https://wg21.link/n4089>`__","LWG","Safe conversions in ``unique_ptr<T[]>``\ .","Urbana","|In Progress|","3.9"
|
||||
"`N4169 <https://wg21.link/n4169>`__","LWG","A proposal to add invoke function template","Urbana","|Complete|","3.7"
|
||||
"`N4190 <https://wg21.link/n4190>`__","LWG","Removing auto_ptr, random_shuffle(), And Old <functional> Stuff.","Urbana","|In Progress|",""
|
||||
"`N4258 <https://wg21.link/n4258>`__","LWG","Cleaning-up noexcept in the Library.","Urbana","|In Progress|","3.7"
|
||||
"`N4259 <https://wg21.link/n4259>`__","CWG","Wording for std::uncaught_exceptions","Urbana","|Complete|","3.7"
|
||||
"`N4277 <https://wg21.link/n4277>`__","LWG","TriviallyCopyable ``reference_wrapper``\ .","Urbana","|Complete|","3.2"
|
||||
"`N4279 <https://wg21.link/n4279>`__","LWG","Improved insertion interface for unique-key maps.","Urbana","|Complete|","3.7"
|
||||
"`N4280 <https://wg21.link/n4280>`__","LWG","Non-member size() and more","Urbana","|Complete|","3.6"
|
||||
"`N4284 <https://wg21.link/n4284>`__","LWG","Contiguous Iterators.","Urbana","|Complete|","3.6"
|
||||
"`N4285 <https://wg21.link/n4285>`__","CWG","Cleanup for exception-specification and throw-expression.","Urbana","|Complete|","4.0"
|
||||
"","","","","",""
|
||||
"`N4387 <https://wg21.link/n4387>`__","LWG","improving pair and tuple","Lenexa","|Complete|","4.0"
|
||||
"`N4389 <https://wg21.link/n4389>`__","LWG","bool_constant","Lenexa","|Complete|","3.7"
|
||||
"`N4508 <https://wg21.link/n4508>`__","LWG","shared_mutex for C++17","Lenexa","|Complete|","3.7"
|
||||
"`N4366 <https://wg21.link/n4366>`__","LWG","LWG 2228 missing SFINAE rule","Lenexa","|Complete|","3.1"
|
||||
"`N4510 <https://wg21.link/n4510>`__","LWG","Minimal incomplete type support for standard containers, revision 4","Lenexa","|Complete|","3.6"
|
||||
"","","","","",""
|
||||
"`P0004R1 <https://wg21.link/p0004r1>`__","LWG","Remove Deprecated iostreams aliases.","Kona","|Complete|","3.8"
|
||||
"`P0006R0 <https://wg21.link/p0006r0>`__","LWG","Adopt Type Traits Variable Templates for C++17.","Kona","|Complete|","3.8"
|
||||
"`P0092R1 <https://wg21.link/p0092r1>`__","LWG","Polishing <chrono>","Kona","|Complete|","3.8"
|
||||
"`P0007R1 <https://wg21.link/p0007r1>`__","LWG","Constant View: A proposal for a ``std::as_const``\ helper function template.","Kona","|Complete|","3.8"
|
||||
"`P0156R0 <https://wg21.link/p0156r0>`__","LWG","Variadic lock_guard(rev 3).","Kona","*Reverted in Kona*","3.9"
|
||||
"`P0074R0 <https://wg21.link/p0074r0>`__","LWG","Making ``std::owner_less``\ more flexible","Kona","|Complete|","3.8"
|
||||
"`P0013R1 <https://wg21.link/p0013r1>`__","LWG","Logical type traits rev 2","Kona","|Complete|","3.8"
|
||||
"","","","","",""
|
||||
"`P0024R2 <https://wg21.link/P0024R2>`__","LWG","The Parallelism TS Should be Standardized","Jacksonville","",""
|
||||
"`P0226R1 <https://wg21.link/P0226R1>`__","LWG","Mathematical Special Functions for C++17","Jacksonville","",""
|
||||
"`P0220R1 <https://wg21.link/P0220R1>`__","LWG","Adopt Library Fundamentals V1 TS Components for C++17","Jacksonville","|In Progress|",""
|
||||
"`P0218R1 <https://wg21.link/P0218R1>`__","LWG","Adopt the File System TS for C++17","Jacksonville","|Complete|","7.0"
|
||||
"`P0033R1 <https://wg21.link/P0033R1>`__","LWG","Re-enabling shared_from_this","Jacksonville","|Complete|","3.9"
|
||||
"`P0005R4 <https://wg21.link/P0005R4>`__","LWG","Adopt not_fn from Library Fundamentals 2 for C++17","Jacksonville","|Complete|","3.9"
|
||||
"`P0152R1 <https://wg21.link/P0152R1>`__","LWG","constexpr ``atomic::is_always_lock_free``\ ","Jacksonville","|Complete|","3.9"
|
||||
"`P0185R1 <https://wg21.link/P0185R1>`__","LWG","Adding [nothrow-]swappable traits","Jacksonville","|Complete|","3.9"
|
||||
"`P0253R1 <https://wg21.link/P0253R1>`__","LWG","Fixing a design mistake in the searchers interface","Jacksonville","|Complete|","3.9"
|
||||
"`P0025R0 <https://wg21.link/P0025R0>`__","LWG","An algorithm to ""clamp"" a value between a pair of boundary values","Jacksonville","|Complete|","3.9"
|
||||
"`P0154R1 <https://wg21.link/P0154R1>`__","LWG","constexpr std::hardware_{constructive,destructive}_interference_size","Jacksonville","",""
|
||||
"`P0030R1 <https://wg21.link/P0030R1>`__","LWG","Proposal to Introduce a 3-Argument Overload to std::hypot","Jacksonville","|Complete|","3.9"
|
||||
"`P0031R0 <https://wg21.link/P0031R0>`__","LWG","A Proposal to Add Constexpr Modifiers to reverse_iterator, move_iterator, array and Range Access","Jacksonville","|Complete|","4.0"
|
||||
"`P0272R1 <https://wg21.link/P0272R1>`__","LWG","Give ``std::string``\ a non-const ``.data()``\ member function","Jacksonville","|Complete|","3.9"
|
||||
"`P0077R2 <https://wg21.link/P0077R2>`__","LWG","``is_callable``\ , the missing INVOKE related trait","Jacksonville","|Complete|","3.9"
|
||||
"","","","","",""
|
||||
"`p0032r3 <https://wg21.link/p0032r3>`__","LWG","Homogeneous interface for variant, any and optional","Oulu","|Complete|","4.0"
|
||||
"`p0040r3 <https://wg21.link/p0040r3>`__","LWG","Extending memory management tools","Oulu","|Complete|","4.0"
|
||||
"`p0063r3 <https://wg21.link/p0063r3>`__","LWG","C++17 should refer to C11 instead of C99","Oulu","|Complete|","7.0"
|
||||
"`p0067r3 <https://wg21.link/p0067r3>`__","LWG","Elementary string conversions","Oulu","Now `P0067R5 <https://wg21.link/P0067R5>`__","n/a"
|
||||
"`p0083r3 <https://wg21.link/p0083r3>`__","LWG","Splicing Maps and Sets","Oulu","|Complete|","8.0"
|
||||
"`p0084r2 <https://wg21.link/p0084r2>`__","LWG","Emplace Return Type","Oulu","|Complete|","4.0"
|
||||
"`p0088r3 <https://wg21.link/p0088r3>`__","LWG","Variant: a type-safe union for C++17","Oulu","|Complete|","4.0"
|
||||
"`p0137r1 <https://wg21.link/p0137r1>`__","CWG","Core Issue 1776: Replacement of class objects containing reference members","Oulu","|Complete|","6.0"
|
||||
"`p0163r0 <https://wg21.link/p0163r0>`__","LWG","shared_ptr::weak_type","Oulu","|Complete|","3.9"
|
||||
"`p0174r2 <https://wg21.link/p0174r2>`__","LWG","Deprecating Vestigial Library Parts in C++17","Oulu","|Partial|",""
|
||||
"`p0175r1 <https://wg21.link/p0175r1>`__","LWG","Synopses for the C library","Oulu","",""
|
||||
"`p0180r2 <https://wg21.link/p0180r2>`__","LWG","Reserve a New Library Namespace for Future Standardization","Oulu","|Nothing To Do|","n/a"
|
||||
"`p0181r1 <https://wg21.link/p0181r1>`__","LWG","Ordered by Default","Oulu","*Removed in Kona*","n/a"
|
||||
"`p0209r2 <https://wg21.link/p0209r2>`__","LWG","make_from_tuple: apply for construction","Oulu","|Complete|","3.9"
|
||||
"`p0219r1 <https://wg21.link/p0219r1>`__","LWG","Relative Paths for Filesystem","Oulu","|Complete|","7.0"
|
||||
"`p0254r2 <https://wg21.link/p0254r2>`__","LWG","Integrating std::string_view and std::string","Oulu","|Complete|","4.0"
|
||||
"`p0258r2 <https://wg21.link/p0258r2>`__","LWG","has_unique_object_representations","Oulu","|Complete|","6.0"
|
||||
"`p0295r0 <https://wg21.link/p0295r0>`__","LWG","Adopt Selected Library Fundamentals V2 Components for C++17","Oulu","|Complete|","4.0"
|
||||
"`p0302r1 <https://wg21.link/p0302r1>`__","LWG","Removing Allocator Support in std::function","Oulu","|Complete|","4.0"
|
||||
"`p0307r2 <https://wg21.link/p0307r2>`__","LWG","Making Optional Greater Equal Again","Oulu","|Complete|","4.0"
|
||||
"`p0336r1 <https://wg21.link/p0336r1>`__","LWG","Better Names for Parallel Execution Policies in C++17","Oulu","",""
|
||||
"`p0337r0 <https://wg21.link/p0337r0>`__","LWG","Delete ``operator=``\ for polymorphic_allocator","Oulu","|Complete|","3.9"
|
||||
"`p0346r1 <https://wg21.link/p0346r1>`__","LWG","A <random> Nomenclature Tweak","Oulu","|Complete|","3.9"
|
||||
"`p0358r1 <https://wg21.link/p0358r1>`__","LWG","Fixes for not_fn","Oulu","|Complete|","3.9"
|
||||
"`p0371r1 <https://wg21.link/p0371r1>`__","LWG","Temporarily discourage memory_order_consume","Oulu","|Nothing To Do|","n/a"
|
||||
"`p0392r0 <https://wg21.link/p0392r0>`__","LWG","Adapting string_view by filesystem paths","Oulu","|Complete|","4.0"
|
||||
"`p0393r3 <https://wg21.link/p0393r3>`__","LWG","Making Variant Greater Equal","Oulu","|Complete|","4.0"
|
||||
"`P0394r4 <https://wg21.link/P0394r4>`__","LWG","Hotel Parallelifornia: terminate() for Parallel Algorithms Exception Handling","Oulu","",""
|
||||
"","","","","",""
|
||||
"`P0003R5 <https://wg21.link/P0003R5>`__","LWG","Removing Deprecated Exception Specifications from C++17","Issaquah","|Complete|","5.0"
|
||||
"`P0067R5 <https://wg21.link/P0067R5>`__","LWG","Elementary string conversions, revision 5","Issaquah","|Partial| [#note-P0067]",""
|
||||
"`P0403R1 <https://wg21.link/P0403R1>`__","LWG","Literal suffixes for ``basic_string_view``\ ","Issaquah","|Complete|","4.0"
|
||||
"`P0414R2 <https://wg21.link/P0414R2>`__","LWG","Merging shared_ptr changes from Library Fundamentals to C++17","Issaquah","|Complete|","11.0"
|
||||
"`P0418R2 <https://wg21.link/P0418R2>`__","LWG","Fail or succeed: there is no atomic lattice","Issaquah","",""
|
||||
"`P0426R1 <https://wg21.link/P0426R1>`__","LWG","Constexpr for ``std::char_traits``\ ","Issaquah","|Complete|","4.0"
|
||||
"`P0435R1 <https://wg21.link/P0435R1>`__","LWG","Resolving LWG Issues re ``common_type``\ ","Issaquah","|Complete|","4.0"
|
||||
"`P0502R0 <https://wg21.link/P0502R0>`__","LWG","Throwing out of a parallel algorithm terminates - but how?","Issaquah","",""
|
||||
"`P0503R0 <https://wg21.link/P0503R0>`__","LWG","Correcting library usage of ""literal type""","Issaquah","|Complete|","4.0"
|
||||
"`P0504R0 <https://wg21.link/P0504R0>`__","LWG","Revisiting in-place tag types for any/optional/variant","Issaquah","|Complete|","4.0"
|
||||
"`P0505R0 <https://wg21.link/P0505R0>`__","LWG","Wording for GB 50 - constexpr for chrono","Issaquah","|Complete|","4.0"
|
||||
"`P0508R0 <https://wg21.link/P0508R0>`__","LWG","Wording for GB 58 - structured bindings for node_handles","Issaquah","",""
|
||||
"`P0509R1 <https://wg21.link/P0509R1>`__","LWG","Updating ""Restrictions on exception handling""","Issaquah","|Nothing To Do|","n/a"
|
||||
"`P0510R0 <https://wg21.link/P0510R0>`__","LWG","Disallowing references, incomplete types, arrays, and empty variants","Issaquah","|Complete|","4.0"
|
||||
"`P0513R0 <https://wg21.link/P0513R0>`__","LWG","Poisoning the Hash","Issaquah","|Complete|","5.0"
|
||||
"`P0516R0 <https://wg21.link/P0516R0>`__","LWG","Clarify That shared_future's Copy Operations have Wide Contracts","Issaquah","|Complete|","4.0"
|
||||
"`P0517R0 <https://wg21.link/P0517R0>`__","LWG","Make future_error Constructible","Issaquah","|Complete|","4.0"
|
||||
"`P0521R0 <https://wg21.link/P0521R0>`__","LWG","Proposed Resolution for CA 14 (shared_ptr use_count/unique)","Issaquah","|Nothing To Do|","n/a"
|
||||
"","","","","",""
|
||||
"`P0156R2 <https://wg21.link/P0156R2>`__","LWG","Variadic Lock guard(rev 5)","Kona","|Complete|","5.0"
|
||||
"`P0270R3 <https://wg21.link/P0270R3>`__","CWG","Removing C dependencies from signal handler wording","Kona","",""
|
||||
"`P0298R3 <https://wg21.link/P0298R3>`__","CWG","A byte type definition","Kona","|Complete|","5.0"
|
||||
"`P0317R1 <https://wg21.link/P0317R1>`__","LWG","Directory Entry Caching for Filesystem","Kona","|Complete|","7.0"
|
||||
"`P0430R2 <https://wg21.link/P0430R2>`__","LWG","File system library on non-POSIX-like operating systems","Kona","|Complete|","7.0"
|
||||
"`P0433R2 <https://wg21.link/P0433R2>`__","LWG","Toward a resolution of US7 and US14: Integrating template deduction for class templates into the standard library","Kona","|Complete|","14.0"
|
||||
"`P0452R1 <https://wg21.link/P0452R1>`__","LWG","Unifying <numeric> Parallel Algorithms","Kona","",""
|
||||
"`P0467R2 <https://wg21.link/P0467R2>`__","LWG","Iterator Concerns for Parallel Algorithms","Kona","",""
|
||||
"`P0492R2 <https://wg21.link/P0492R2>`__","LWG","Proposed Resolution of C++17 National Body Comments for Filesystems","Kona","|Complete|","7.0"
|
||||
"`P0518R1 <https://wg21.link/P0518R1>`__","LWG","Allowing copies as arguments to function objects given to parallel algorithms in response to CH11","Kona","",""
|
||||
"`P0523R1 <https://wg21.link/P0523R1>`__","LWG","Wording for CH 10: Complexity of parallel algorithms","Kona","",""
|
||||
"`P0548R1 <https://wg21.link/P0548R1>`__","LWG","common_type and duration","Kona","|Complete|","5.0"
|
||||
"`P0558R1 <https://wg21.link/P0558R1>`__","LWG","Resolving atomic<T> named base class inconsistencies","Kona","|Complete|",""
|
||||
"`P0574R1 <https://wg21.link/P0574R1>`__","LWG","Algorithm Complexity Constraints and Parallel Overloads","Kona","",""
|
||||
"`P0599R1 <https://wg21.link/P0599R1>`__","LWG","noexcept for hash functions","Kona","|Complete|","5.0"
|
||||
"`P0604R0 <https://wg21.link/P0604R0>`__","LWG","Resolving GB 55, US 84, US 85, US 86","Kona","|Complete|",""
|
||||
"`P0607R0 <https://wg21.link/P0607R0>`__","LWG","Inline Variables for the Standard Library","Kona","|In Progress| [#note-P0607]_","6.0"
|
||||
"`P0618R0 <https://wg21.link/P0618R0>`__","LWG","Deprecating <codecvt>","Kona","",""
|
||||
"`P0623R0 <https://wg21.link/P0623R0>`__","LWG","Final C++17 Parallel Algorithms Fixes","Kona","",""
|
||||
"","","","","",""
|
||||
"`P0682R1 <https://wg21.link/P0682R1>`__","LWG","Repairing elementary string conversions","Toronto","",""
|
||||
"`P0739R0 <https://wg21.link/P0739R0>`__","LWG","Some improvements to class template argument deduction integration into the standard library","Toronto","|Complete|","5.0"
|
|
58
docs/Status/Cxx20.rst
Normal file
58
docs/Status/Cxx20.rst
Normal file
@ -0,0 +1,58 @@
|
||||
.. _cxx20-status:
|
||||
|
||||
================================
|
||||
libc++ C++20 Status
|
||||
================================
|
||||
|
||||
.. include:: ../Helpers/Styles.rst
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
|
||||
Overview
|
||||
================================
|
||||
|
||||
In July 2017, the C++ standard committee created a draft for the next version of the C++ standard, initially known as "C++2a".
|
||||
In September 2020, the C++ standard committee approved this draft, and sent it to ISO for approval as C++20.
|
||||
|
||||
This page shows the status of libc++; the status of clang's support of the language features is `here <https://clang.llvm.org/cxx_status.html#cxx20>`__.
|
||||
|
||||
.. attention:: Features in unreleased drafts of the standard are subject to change.
|
||||
|
||||
The groups that have contributed papers:
|
||||
|
||||
- CWG - Core Language Working group
|
||||
- LWG - Library working group
|
||||
- SG1 - Study group #1 (Concurrency working group)
|
||||
|
||||
.. note:: "Nothing to do" means that no library changes were needed to implement this change.
|
||||
|
||||
.. _paper-status-cxx20:
|
||||
|
||||
Paper Status
|
||||
====================================
|
||||
|
||||
.. csv-table::
|
||||
:file: Cxx20Papers.csv
|
||||
:header-rows: 1
|
||||
:widths: auto
|
||||
|
||||
.. note::
|
||||
|
||||
.. [#note-P0600] P0600: The missing bits in P0600 are in |sect|\ [mem.res.class] and |sect|\ [mem.poly.allocator.class].
|
||||
.. [#note-P0645] P0645: The paper is implemented but still marked as an incomplete feature. Not yet implemented LWG-issues will cause API and ABI breakage.
|
||||
.. [#note-P0966] P0966: It was previously erroneously marked as complete in version 8.0. See `bug 45368 <https://llvm.org/PR45368>`__.
|
||||
.. [#note-P0619] P0619: Only sections D.8, D.9, D.10 and D.13 are implemented. Sections D.4, D.7, D.11, D.12, and D.14 remain undone.
|
||||
.. [#note-P0883] P0883: shared_ptr and floating-point changes weren't applied as they themselves aren't implemented yet.
|
||||
|
||||
|
||||
.. _issues-status-cxx20:
|
||||
|
||||
Library Working Group Issues Status
|
||||
====================================
|
||||
|
||||
.. csv-table::
|
||||
:file: Cxx20Issues.csv
|
||||
:header-rows: 1
|
||||
:widths: auto
|
300
docs/Status/Cxx20Issues.csv
Normal file
300
docs/Status/Cxx20Issues.csv
Normal file
@ -0,0 +1,300 @@
|
||||
"Issue #","Issue Name","Meeting","Status","First released version","Labels"
|
||||
"`2070 <https://wg21.link/LWG2070>`__","``allocate_shared``\ should use ``allocator_traits<A>::construct``\ ","Toronto","Resolved by `P0674R1 <https://wg21.link/P0674R1>`__",""
|
||||
"`2444 <https://wg21.link/LWG2444>`__","Inconsistent complexity for ``std::sort_heap``\ ","Toronto","",""
|
||||
"`2593 <https://wg21.link/LWG2593>`__","Moved-from state of Allocators","Toronto","",""
|
||||
"`2597 <https://wg21.link/LWG2597>`__","``std::log``\ misspecified for complex numbers","Toronto","",""
|
||||
"`2783 <https://wg21.link/LWG2783>`__","``stack::emplace()``\ and ``queue::emplace()``\ should return ``decltype(auto)``\ ","Toronto","|Complete|",""
|
||||
"`2932 <https://wg21.link/LWG2932>`__","Constraints on parallel algorithm implementations are underspecified","Toronto","",""
|
||||
"`2937 <https://wg21.link/LWG2937>`__","Is ``equivalent(""existing_thing"", ""not_existing_thing"")``\ an error","Toronto","|Complete|",""
|
||||
"`2940 <https://wg21.link/LWG2940>`__","``result_of``\ specification also needs a little cleanup","Toronto","",""
|
||||
"`2942 <https://wg21.link/LWG2942>`__","LWG 2873's resolution missed ``weak_ptr::owner_before``\ ","Toronto","|Complete|",""
|
||||
"`2954 <https://wg21.link/LWG2954>`__","Specialization of the convenience variable templates should be prohibited","Toronto","|Complete|",""
|
||||
"`2961 <https://wg21.link/LWG2961>`__","Bad postcondition for ``set_default_resource``\ ","Toronto","",""
|
||||
"`2966 <https://wg21.link/LWG2966>`__","Incomplete resolution of US 74","Toronto","|Nothing To Do|",""
|
||||
"`2974 <https://wg21.link/LWG2974>`__","Diagnose out of bounds ``tuple_element/variant_alternative``\ ","Toronto","|Complete|",""
|
||||
"","","","",""
|
||||
"`2779 <https://wg21.link/LWG2779>`__","[networking.ts] Relax requirements on buffer sequence iterators","Albuquerque","",""
|
||||
"`2870 <https://wg21.link/LWG2870>`__","Default value of parameter theta of polar should be dependent","Albuquerque","|Complete|",""
|
||||
"`2935 <https://wg21.link/LWG2935>`__","What should create_directories do when p already exists but is not a directory?","Albuquerque","|Nothing To Do|",""
|
||||
"`2941 <https://wg21.link/LWG2941>`__","[thread.req.timing] wording should apply to both member and namespace-level functions","Albuquerque","|Nothing To Do|",""
|
||||
"`2944 <https://wg21.link/LWG2944>`__","LWG 2905 accidentally removed requirement that construction of the deleter doesn't throw an exception","Albuquerque","|Nothing To Do|",""
|
||||
"`2945 <https://wg21.link/LWG2945>`__","Order of template parameters in optional comparisons","Albuquerque","|Complete|",""
|
||||
"`2948 <https://wg21.link/LWG2948>`__","unique_ptr does not define operator<< for stream output","Albuquerque","|Complete|",""
|
||||
"`2950 <https://wg21.link/LWG2950>`__","std::byte operations are misspecified","Albuquerque","|Complete|",""
|
||||
"`2952 <https://wg21.link/LWG2952>`__","iterator_traits should work for pointers to cv T","Albuquerque","|Complete|",""
|
||||
"`2953 <https://wg21.link/LWG2953>`__","LWG 2853 should apply to deque::erase too","Albuquerque","|Complete|",""
|
||||
"`2958 <https://wg21.link/LWG2958>`__","Moves improperly defined as deleted","Albuquerque","|Complete|",""
|
||||
"`2964 <https://wg21.link/LWG2964>`__","Apparently redundant requirement for dynamic_pointer_cast","Albuquerque","",""
|
||||
"`2965 <https://wg21.link/LWG2965>`__","Non-existing path::native_string() in filesystem_error::what() specification","Albuquerque","|Nothing To Do|",""
|
||||
"`2972 <https://wg21.link/LWG2972>`__","What is ``is_trivially_destructible_v<int>``\ ?","Albuquerque","|Complete|",""
|
||||
"`2976 <https://wg21.link/LWG2976>`__","Dangling uses_allocator specialization for packaged_task","Albuquerque","|Complete|",""
|
||||
"`2977 <https://wg21.link/LWG2977>`__","unordered_meow::merge() has incorrect Throws: clause","Albuquerque","|Nothing To Do|",""
|
||||
"`2978 <https://wg21.link/LWG2978>`__","Hash support for pmr::string and friends","Albuquerque","",""
|
||||
"`2979 <https://wg21.link/LWG2979>`__","aligned_union should require complete object types","Albuquerque","|Complete|",""
|
||||
"`2980 <https://wg21.link/LWG2980>`__","Cannot compare_exchange empty pointers","Albuquerque","",""
|
||||
"`2981 <https://wg21.link/LWG2981>`__","Remove redundant deduction guides from standard library","Albuquerque","|Nothing To Do|",""
|
||||
"`2982 <https://wg21.link/LWG2982>`__","Making size_type consistent in associative container deduction guides","Albuquerque","",""
|
||||
"`2988 <https://wg21.link/LWG2988>`__","Clause 32 cleanup missed one typename","Albuquerque","|Complete|","13.0"
|
||||
"`2993 <https://wg21.link/LWG2993>`__","reference_wrapper<T> conversion from T&&","Albuquerque","|Complete|","13.0"
|
||||
"`2998 <https://wg21.link/LWG2998>`__","Requirements on function objects passed to {``forward_``,}list-specific algorithms","Albuquerque","|Nothing To Do|",""
|
||||
"`3001 <https://wg21.link/LWG3001>`__","weak_ptr::element_type needs remove_extent_t","Albuquerque","|Complete|","14.0"
|
||||
"`3024 <https://wg21.link/LWG3024>`__","variant's copies must be deleted instead of disabled via SFINAE","Albuquerque","|Complete|",""
|
||||
"","","","",""
|
||||
"`2164 <https://wg21.link/LWG2164>`__","What are the semantics of ``vector.emplace(vector.begin(), vector.back())``\ ?","Jacksonville","|Complete|",""
|
||||
"`2243 <https://wg21.link/LWG2243>`__","``istream::putback``\ problem","Jacksonville","|Complete|",""
|
||||
"`2816 <https://wg21.link/LWG2816>`__","``resize_file``\ has impossible postcondition","Jacksonville","|Nothing To Do|",""
|
||||
"`2843 <https://wg21.link/LWG2843>`__","Unclear behavior of ``std::pmr::memory_resource::do_allocate()``\ ","Jacksonville","|Complete|",""
|
||||
"`2849 <https://wg21.link/LWG2849>`__","Why does ``!is_regular_file(from)``\ cause ``copy_file``\ to report a ""file already exists"" error?","Jacksonville","|Nothing To Do|",""
|
||||
"`2851 <https://wg21.link/LWG2851>`__","``std::filesystem``\ enum classes are now underspecified","Jacksonville","|Nothing To Do|",""
|
||||
"`2946 <https://wg21.link/LWG2946>`__","LWG 2758's resolution missed further corrections","Jacksonville","|Complete|",""
|
||||
"`2969 <https://wg21.link/LWG2969>`__","``polymorphic_allocator::construct()``\ shouldn't pass ``resource()``\ ","Jacksonville","|Complete|",""
|
||||
"`2975 <https://wg21.link/LWG2975>`__","Missing case for ``pair``\ construction in scoped and polymorphic allocators","Jacksonville","",""
|
||||
"`2989 <https://wg21.link/LWG2989>`__","``path``\ 's stream insertion operator lets you insert everything under the sun","Jacksonville","|Complete|",""
|
||||
"`3000 <https://wg21.link/LWG3000>`__","``monotonic_memory_resource::do_is_equal``\ uses ``dynamic_cast``\ unnecessarily","Jacksonville","",""
|
||||
"`3002 <https://wg21.link/LWG3002>`__","[networking.ts] ``basic_socket_acceptor::is_open()``\ isn't ``noexcept``\ ","Jacksonville","",""
|
||||
"`3004 <https://wg21.link/LWG3004>`__","|sect|\ [string.capacity] and |sect|\ [vector.capacity] should specify time complexity for ``capacity()``\ ","Jacksonville","|Nothing To Do|",""
|
||||
"`3005 <https://wg21.link/LWG3005>`__","Destruction order of arrays by ``make_shared/allocate_shared``\ only recommended?","Jacksonville","",""
|
||||
"`3007 <https://wg21.link/LWG3007>`__","``allocate_shared``\ should rebind allocator to *cv*-unqualified ``value_type``\ for construction","Jacksonville","",""
|
||||
"`3009 <https://wg21.link/LWG3009>`__","Including ``<string_view>``\ doesn't provide ``std::size/empty/data``\ ","Jacksonville","|Complete|",""
|
||||
"`3010 <https://wg21.link/LWG3010>`__","[networking.ts] ``uses_executor``\ says ""if a type ``T::executor_type``\ exists""","Jacksonville","",""
|
||||
"`3013 <https://wg21.link/LWG3013>`__","``(recursive_)directory_iterator``\ construction and traversal should not be ``noexcept``\ ","Jacksonville","|Complete|",""
|
||||
"`3014 <https://wg21.link/LWG3014>`__","More ``noexcept``\ issues with filesystem operations","Jacksonville","|Complete|",""
|
||||
"`3015 <https://wg21.link/LWG3015>`__","``copy_options::*unspecified*``\ underspecified","Jacksonville","|Nothing To Do|",""
|
||||
"`3017 <https://wg21.link/LWG3017>`__","``list splice``\ functions should use ``addressof``\ ","Jacksonville","|Complete|",""
|
||||
"`3020 <https://wg21.link/LWG3020>`__","[networking.ts] Remove spurious nested ``value_type``\ buffer sequence requirement","Jacksonville","",""
|
||||
"`3026 <https://wg21.link/LWG3026>`__","``filesystem::weakly_canonical``\ still defined in terms of ``canonical(p, base)``\ ","Jacksonville","|Complete|",""
|
||||
"`3030 <https://wg21.link/LWG3030>`__","Who shall meet the requirements of ``try_lock``\ ?","Jacksonville","|Nothing To Do|",""
|
||||
"`3034 <https://wg21.link/LWG3034>`__","P0767R1 breaks previously-standard-layout types","Jacksonville","|Complete|",""
|
||||
"`3035 <https://wg21.link/LWG3035>`__","``std::allocator``\ 's constructors should be ``constexpr``\ ","Jacksonville","|Complete|",""
|
||||
"`3039 <https://wg21.link/LWG3039>`__","Unnecessary ``decay``\ in ``thread``\ and ``packaged_task``\ ","Jacksonville","|Complete|",""
|
||||
"`3041 <https://wg21.link/LWG3041>`__","Unnecessary ``decay``\ in ``reference_wrapper``\ ","Jacksonville","|Complete|",""
|
||||
"`3042 <https://wg21.link/LWG3042>`__","``is_literal_type_v``\ should be inline","Jacksonville","|Complete|",""
|
||||
"`3043 <https://wg21.link/LWG3043>`__","Bogus postcondition for ``filesystem_error``\ constructor","Jacksonville","|Complete|",""
|
||||
"`3045 <https://wg21.link/LWG3045>`__","``atomic<floating-point>``\ doesn't have ``value_type``\ or ``difference_type``\ ","Jacksonville","",""
|
||||
"`3048 <https://wg21.link/LWG3048>`__","``transform_reduce(exec, first1, last1, first2, init)``\ discards execution policy","Jacksonville","",""
|
||||
"`3051 <https://wg21.link/LWG3051>`__","Floating point classifications were inadvertently changed in P0175","Jacksonville","|Nothing To Do|",""
|
||||
"`3075 <https://wg21.link/LWG3075>`__","``basic_string``\ needs deduction guides from ``basic_string_view``\ ","Jacksonville","|Complete|",""
|
||||
"","","","",""
|
||||
"`2139 <https://wg21.link/LWG2139>`__","What is a user-defined type?","Rapperswil","",""
|
||||
"`2970 <https://wg21.link/LWG2970>`__","Return type of std::visit misspecified","Rapperswil","",""
|
||||
"`3058 <https://wg21.link/LWG3058>`__","Parallel adjacent_difference shouldn't require creating temporaries","Rapperswil","",""
|
||||
"`3062 <https://wg21.link/LWG3062>`__","Unnecessary decay_t in is_execution_policy_v should be remove_cvref_t","Rapperswil","",""
|
||||
"`3067 <https://wg21.link/LWG3067>`__","recursive_directory_iterator::pop must invalidate","Rapperswil","|Nothing To Do|",""
|
||||
"`3071 <https://wg21.link/LWG3071>`__","[networking.ts] read_until still refers to ""input sequence""","Rapperswil","|Nothing To Do|",""
|
||||
"`3074 <https://wg21.link/LWG3074>`__","Non-member functions for valarray should only deduce from the valarray","Rapperswil","",""
|
||||
"`3076 <https://wg21.link/LWG3076>`__","basic_string CTAD ambiguity","Rapperswil","|Complete|",""
|
||||
"`3079 <https://wg21.link/LWG3079>`__","LWG 2935 forgot to fix the existing_p overloads of create_directory","Rapperswil","|Nothing To Do|",""
|
||||
"`3080 <https://wg21.link/LWG3080>`__","Floating point from_chars pattern specification breaks round-tripping","Rapperswil","",""
|
||||
"`3083 <https://wg21.link/LWG3083>`__","What should ios::iword(-1) do?","Rapperswil","|Nothing To Do|",""
|
||||
"`3094 <https://wg21.link/LWG3094>`__","[time.duration.io]p4 makes surprising claims about encoding","Rapperswil","",""
|
||||
"`3100 <https://wg21.link/LWG3100>`__","Unnecessary and confusing ""empty span"" wording","Rapperswil","|Nothing To Do|",""
|
||||
"`3102 <https://wg21.link/LWG3102>`__","Clarify span iterator and ``const_iterator`` behavior","Rapperswil","|Complete|",""
|
||||
"`3104 <https://wg21.link/LWG3104>`__","Fixing duration division","Rapperswil","|Complete|",""
|
||||
"","","","",""
|
||||
"`2183 <https://wg21.link/LWG2183>`__","Muddled allocator requirements for ``match_results``\ constructors","San Diego","|Complete|",""
|
||||
"`2184 <https://wg21.link/LWG2184>`__","Muddled allocator requirements for ``match_results``\ assignments","San Diego","|Complete|",""
|
||||
"`2412 <https://wg21.link/LWG2412>`__","``promise::set_value()``\ and ``promise::get_future()``\ should not race","San Diego","",""
|
||||
"`2499 <https://wg21.link/LWG2499>`__","``operator>>(basic_istream&, CharT*)``\ makes it hard to avoid buffer overflows","San Diego","Resolved by P0487R1",""
|
||||
"`2682 <https://wg21.link/LWG2682>`__","``filesystem::copy()``\ won't create a symlink to a directory","San Diego","|Nothing To Do|",""
|
||||
"`2697 <https://wg21.link/LWG2697>`__","[concurr.ts] Behavior of ``future/shared_future``\ unwrapping constructor when given an invalid ``future``\ ","San Diego","",""
|
||||
"`2797 <https://wg21.link/LWG2797>`__","Trait precondition violations","San Diego","Resolved by 1285R0",""
|
||||
"`2936 <https://wg21.link/LWG2936>`__","Path comparison is defined in terms of the generic format","San Diego","|Complete|",""
|
||||
"`2943 <https://wg21.link/LWG2943>`__","Problematic specification of the wide version of ``basic_filebuf::open``\ ","San Diego","|Nothing To Do|",""
|
||||
"`2960 <https://wg21.link/LWG2960>`__","[fund.ts.v3] ``nonesuch``\ is insufficiently useless","San Diego","|Complete|",""
|
||||
"`2995 <https://wg21.link/LWG2995>`__","``basic_stringbuf``\ default constructor forbids it from using SSO capacity","San Diego","",""
|
||||
"`2996 <https://wg21.link/LWG2996>`__","Missing rvalue overloads for ``shared_ptr``\ operations","San Diego","",""
|
||||
"`3008 <https://wg21.link/LWG3008>`__","``make_shared``\ (sub)object destruction semantics are not specified","San Diego","",""
|
||||
"`3022 <https://wg21.link/LWG3022>`__","``is_convertible<derived*, base*>``\ may lead to ODR","San Diego","Resolved by 1285R0",""
|
||||
"`3025 <https://wg21.link/LWG3025>`__","Map-like container deduction guides should use ``pair<Key, T>``\ , not ``pair<const Key, T>``\ ","San Diego","|Complete|",""
|
||||
"`3031 <https://wg21.link/LWG3031>`__","Algorithms and predicates with non-const reference arguments","San Diego","",""
|
||||
"`3037 <https://wg21.link/LWG3037>`__","``polymorphic_allocator``\ and incomplete types","San Diego","",""
|
||||
"`3038 <https://wg21.link/LWG3038>`__","``polymorphic_allocator::allocate``\ should not allow integer overflow to create vulnerabilities","San Diego","|Complete|","14.0"
|
||||
"`3054 <https://wg21.link/LWG3054>`__","``uninitialized_copy``\ appears to not be able to meet its exception-safety guarantee","San Diego","",""
|
||||
"`3065 <https://wg21.link/LWG3065>`__","LWG 2989 missed that all ``path``\ 's other operators should be hidden friends as well","San Diego","|Complete|",""
|
||||
"`3096 <https://wg21.link/LWG3096>`__","``path::lexically_relative``\ is confused by trailing slashes","San Diego","|Complete|",""
|
||||
"`3116 <https://wg21.link/LWG3116>`__","``OUTERMOST_ALLOC_TRAITS``\ needs ``remove_reference_t``\ ","San Diego","",""
|
||||
"`3122 <https://wg21.link/LWG3122>`__","``__cpp_lib_chrono_udls``\ was accidentally dropped","San Diego","|Complete|",""
|
||||
"`3127 <https://wg21.link/LWG3127>`__","``basic_osyncstream::rdbuf``\ needs a ``const_cast``\ ","San Diego","",""
|
||||
"`3128 <https://wg21.link/LWG3128>`__","``strstream::rdbuf``\ needs a ``const_cast``\ ","San Diego","|Nothing To Do|",""
|
||||
"`3129 <https://wg21.link/LWG3129>`__","``regex_token_iterator``\ constructor uses wrong pointer arithmetic","San Diego","",""
|
||||
"`3130 <https://wg21.link/LWG3130>`__","|sect|\ [input.output] needs many ``addressof``\ ","San Diego","",""
|
||||
"`3131 <https://wg21.link/LWG3131>`__","``addressof``\ all the things","San Diego","",""
|
||||
"`3132 <https://wg21.link/LWG3132>`__","Library needs to ban macros named ``expects``\ or ``ensures``\ ","San Diego","|Nothing To Do|",""
|
||||
"`3134 <https://wg21.link/LWG3134>`__","[fund.ts.v3] LFTSv3 contains extraneous [meta] variable templates that should have been deleted by P09961","San Diego","Resolved by P1210R0",""
|
||||
"`3137 <https://wg21.link/LWG3137>`__","Header for ``__cpp_lib_to_chars``\ ","San Diego","|Complete|",""
|
||||
"`3145 <https://wg21.link/LWG3145>`__","``file_clock``\ breaks ABI for C++17 implementations","San Diego","|Complete|",""
|
||||
"`3147 <https://wg21.link/LWG3147>`__","Definitions of ""likely"" and ""unlikely"" are likely to cause problems","San Diego","",""
|
||||
"`3148 <https://wg21.link/LWG3148>`__","``<concepts>``\ should be freestanding","San Diego","",""
|
||||
"`3153 <https://wg21.link/LWG3153>`__","``Common``\ and ``common_type``\ have too little in common","San Diego","|Complete|","13.0"
|
||||
"`3154 <https://wg21.link/LWG3154>`__","``Common``\ and ``CommonReference``\ have a common defect","San Diego","",""
|
||||
"","","","",""
|
||||
"`3012 <https://wg21.link/LWG3012>`__","``atomic<T>``\ is unimplementable for non-``is_trivially_copy_constructible T``\ ","Kona","",""
|
||||
"`3040 <https://wg21.link/LWG3040>`__","``basic_string_view::starts_with``\ *Effects* are incorrect","Kona","|Complete|",""
|
||||
"`3077 <https://wg21.link/LWG3077>`__","``(push|emplace)_back``\ should invalidate the ``end``\ iterator","Kona","|Nothing To Do|",""
|
||||
"`3087 <https://wg21.link/LWG3087>`__","One final ``&x``\ in |sect|\ [list.ops]","Kona","|Nothing To Do|",""
|
||||
"`3101 <https://wg21.link/LWG3101>`__","``span``\ 's ``Container``\ constructors need another constraint","Kona","|Complete|",""
|
||||
"`3112 <https://wg21.link/LWG3112>`__","``system_error``\ and ``filesystem_error``\ constructors taking a ``string``\ may not be able to meet their postconditions","Kona","",""
|
||||
"`3119 <https://wg21.link/LWG3119>`__","Program-definedness of closure types","Kona","|Nothing To Do|",""
|
||||
"`3133 <https://wg21.link/LWG3133>`__","Modernizing numeric type requirements","Kona","",""
|
||||
"`3144 <https://wg21.link/LWG3144>`__","``span``\ does not have a ``const_pointer``\ typedef","Kona","|Complete|",""
|
||||
"`3173 <https://wg21.link/LWG3173>`__","Enable CTAD for ``ref-view``\ ","Kona","","","|ranges|"
|
||||
"`3179 <https://wg21.link/LWG3179>`__","``subrange``\ should always model ``Range``\ ","Kona","","","|ranges|"
|
||||
"`3180 <https://wg21.link/LWG3180>`__","Inconsistently named return type for ``ranges::minmax_element``\ ","Kona","","","|ranges|"
|
||||
"`3182 <https://wg21.link/LWG3182>`__","Specification of ``Same``\ could be clearer","Kona","",""
|
||||
"","","","",""
|
||||
"`2899 <https://wg21.link/LWG2899>`__","``is_(nothrow_)move_constructible``\ and ``tuple``\ , ``optional``\ and ``unique_ptr``\ ","Cologne","",""
|
||||
"`3055 <https://wg21.link/LWG3055>`__","``path::operator+=(*single-character*)``\ misspecified","Cologne","|Complete|","7.0"
|
||||
"`3158 <https://wg21.link/LWG3158>`__","``tuple(allocator_arg_t, const Alloc&)``\ should be conditionally explicit","Cologne","|Complete|","10.0"
|
||||
"`3169 <https://wg21.link/LWG3169>`__","``ranges``\ permutation generators discard useful information","Cologne","","","|ranges|"
|
||||
"`3183 <https://wg21.link/LWG3183>`__","Normative permission to specialize Ranges variable templates","Cologne","","","|ranges|"
|
||||
"`3184 <https://wg21.link/LWG3184>`__","Inconsistencies in ``bind_front``\ wording","Cologne","|Complete|","13.0"
|
||||
"`3185 <https://wg21.link/LWG3185>`__","Uses-allocator construction functions missing ``constexpr``\ and ``noexcept``\ ","Cologne","",""
|
||||
"`3186 <https://wg21.link/LWG3186>`__","``ranges``\ removal, partition, and ``partial_sort_copy``\ algorithms discard useful information","Cologne","","","|ranges|"
|
||||
"`3187 <https://wg21.link/LWG3187>`__","`P0591R4 <https://wg21.link/p0591r4>`__ reverted DR 2586 fixes to ``scoped_allocator_adaptor::construct()``\ ","Cologne","",""
|
||||
"`3191 <https://wg21.link/LWG3191>`__","``std::ranges::shuffle``\ synopsis does not match algorithm definition","Cologne","","","|ranges|"
|
||||
"`3196 <https://wg21.link/LWG3196>`__","``std::optional<T>``\ is ill-formed is ``T``\ is an array","Cologne","|Complete|",""
|
||||
"`3198 <https://wg21.link/LWG3198>`__","Bad constraint on ``std::span::span()``\ ","Cologne","|Complete|",""
|
||||
"`3199 <https://wg21.link/LWG3199>`__","``istream >> bitset<0>``\ fails","Cologne","",""
|
||||
"`3202 <https://wg21.link/LWG3202>`__","P0318R1 was supposed to be revised","Cologne","|Complete|",""
|
||||
"`3206 <https://wg21.link/LWG3206>`__","``year_month_day``\ conversion to ``sys_days``\ uses not-existing member function","Cologne","|Complete|",""
|
||||
"`3208 <https://wg21.link/LWG3208>`__","``Boolean``\ 's expression requirements are ordered inconsistently","Cologne","|Nothing To Do|",""
|
||||
"`3209 <https://wg21.link/LWG3209>`__","Expression in ``year::ok()``\ returns clause is ill-formed","Cologne","|Complete|",""
|
||||
"","","","",""
|
||||
"`3231 <https://wg21.link/LWG3231>`__","``year_month_day_last::day``\ specification does not cover ``!ok()``\ values","Belfast","|Nothing To Do|",""
|
||||
"`3225 <https://wg21.link/LWG3225>`__","``zoned_time``\ converting constructor shall not be ``noexcept``\ ","Belfast","","","|chrono|"
|
||||
"`3190 <https://wg21.link/LWG3190>`__","``std::allocator::allocate``\ sometimes returns too little storage","Belfast","|Complete|","14.0"
|
||||
"`3218 <https://wg21.link/LWG3218>`__","Modifier for ``%d``\ parse flag does not match POSIX and ``format``\ specification","Belfast","","","|chrono| |format|"
|
||||
"`3224 <https://wg21.link/LWG3224>`__","``zoned_time``\ constructor from ``TimeZonePtr``\ does not specify initialization of ``tp_``\ ","Belfast","","","|chrono|"
|
||||
"`3230 <https://wg21.link/LWG3230>`__","Format specifier ``%y/%Y``\ is missing locale alternative versions","Belfast","","","|chrono| |format|"
|
||||
"`3232 <https://wg21.link/LWG3232>`__","Inconsistency in ``zoned_time``\ deduction guides","Belfast","","","|chrono|"
|
||||
"`3222 <https://wg21.link/LWG3222>`__","P0574R1 introduced preconditions on non-existent parameters","Belfast","",""
|
||||
"`3221 <https://wg21.link/LWG3221>`__","Result of ``year_month``\ arithmetic with ``months``\ is ambiguous","Belfast","|Complete|","8.0"
|
||||
"`3235 <https://wg21.link/LWG3235>`__","``parse``\ manipulator without abbreviation is not callable","Belfast","",""
|
||||
"`3246 <https://wg21.link/LWG3246>`__","What are the constraints on the template parameter of ``basic_format_arg``\ ?","Belfast","","","|format|"
|
||||
"`3253 <https://wg21.link/LWG3253>`__","``basic_syncbuf::basic_syncbuf()``\ should not be explicit","Belfast","",""
|
||||
"`3245 <https://wg21.link/LWG3245>`__","Unnecessary restriction on ``'%p'``\ parse specifier","Belfast","","","|chrono|"
|
||||
"`3244 <https://wg21.link/LWG3244>`__","Constraints for ``Source``\ in |sect|\ [fs.path.req] insufficiently constrainty","Belfast","",""
|
||||
"`3241 <https://wg21.link/LWG3241>`__","``chrono-spec``\ grammar ambiguity in |sect|\ [time.format]","Belfast","","","|chrono| |format|"
|
||||
"`3257 <https://wg21.link/LWG3257>`__","Missing feature testing macro update from P0858","Belfast","",""
|
||||
"`3256 <https://wg21.link/LWG3256>`__","Feature testing macro for ``constexpr``\ algorithms","Belfast","|Complete|","13.0"
|
||||
"`3273 <https://wg21.link/LWG3273>`__","Specify ``weekday_indexed``\ to range of ``[0, 7]``\ ","Belfast","","","|chrono|"
|
||||
"`3070 <https://wg21.link/LWG3070>`__","``path::lexically_relative``\ causes surprising results if a filename can also be a *root-name*","Belfast","",""
|
||||
"`3266 <https://wg21.link/LWG3266>`__","``to_chars(bool)``\ should be deleted","Belfast","|Complete|","14.0"
|
||||
"`3272 <https://wg21.link/LWG3272>`__","``%I%p``\ should parse/format ``duration``\ since midnight","Belfast","","","|chrono| |format|"
|
||||
"`3259 <https://wg21.link/LWG3259>`__","The definition of *constexpr iterators* should be adjusted","Belfast","","","|ranges|"
|
||||
"`3103 <https://wg21.link/LWG3103>`__","Errors in taking subview of ``span``\ should be ill-formed where possible","Belfast","",""
|
||||
"`3274 <https://wg21.link/LWG3274>`__","Missing feature test macro for ``<span>``\ ","Belfast","|Complete|","11.0"
|
||||
"`3276 <https://wg21.link/LWG3276>`__","Class ``split_view::outer_iterator::value_type``\ should inherit from ``view_interface``\ ","Belfast","","","|ranges|"
|
||||
"`3277 <https://wg21.link/LWG3277>`__","Pre-increment on prvalues is not a requirement of ``weakly_incrementable``\ ","Belfast","","","|ranges|"
|
||||
"`3149 <https://wg21.link/LWG3149>`__","``DefaultConstructible``\ should require default initialization","Belfast","|Complete|","13.0"
|
||||
"","","","",""
|
||||
"`1203 <https://wg21.link/LWG1203>`__","More useful rvalue stream insertion","Prague","|Complete|","12.0"
|
||||
"`2859 <https://wg21.link/LWG2859>`__","Definition of *reachable* in [ptr.launder] misses pointer arithmetic from pointer-interconvertible object","Prague","",""
|
||||
"`3018 <https://wg21.link/LWG3018>`__","``shared_ptr``\ of function type","Prague","",""
|
||||
"`3050 <https://wg21.link/LWG3050>`__","Conversion specification problem in ``chrono::duration``\ constructor","Prague","","","|chrono|"
|
||||
"`3141 <https://wg21.link/LWG3141>`__","``CopyConstructible``\ doesn't preserve source values","Prague","|Nothing to do|",""
|
||||
"`3150 <https://wg21.link/LWG3150>`__","``UniformRandomBitGenerator``\ should validate ``min``\ and ``max``\ ","Prague","|Complete|","13.0"
|
||||
"`3175 <https://wg21.link/LWG3175>`__","The ``CommonReference``\ requirement of concept ``SwappableWith``\ is not satisfied in the example","Prague","|Complete|","13.0"
|
||||
"`3194 <https://wg21.link/LWG3194>`__","``ConvertibleTo``\ prose does not match code","Prague","|Complete|","13.0"
|
||||
"`3200 <https://wg21.link/LWG3200>`__","``midpoint``\ should not constrain ``T``\ is complete","Prague","|Nothing To Do|",""
|
||||
"`3201 <https://wg21.link/LWG3201>`__","``lerp``\ should be marked as ``noexcept``\ ","Prague","|Complete|",""
|
||||
"`3226 <https://wg21.link/LWG3226>`__","``zoned_time``\ constructor from ``string_view``\ should accept ``zoned_time<Duration2, TimeZonePtr2>``\ ","Prague","","","|chrono|"
|
||||
"`3233 <https://wg21.link/LWG3233>`__","Broken requirements for ``shared_ptr``\ converting constructors","Prague","",""
|
||||
"`3237 <https://wg21.link/LWG3237>`__","LWG 3038 and 3190 have inconsistent PRs","Prague","|Complete|","14.0"
|
||||
"`3238 <https://wg21.link/LWG3238>`__","Insufficiently-defined behavior of ``std::function``\ deduction guides","Prague","",""
|
||||
"`3242 <https://wg21.link/LWG3242>`__","``std::format``\ : missing rules for ``arg-id``\ in ``width``\ and ``precision``\ ","Prague","|Complete|","Clang 14","|format|"
|
||||
"`3243 <https://wg21.link/LWG3243>`__","``std::format``\ and negative zeroes","Prague","|Complete|","14.0","|format|"
|
||||
"`3247 <https://wg21.link/LWG3247>`__","``ranges::iter_move``\ should perform ADL-only lookup of ``iter_move``\ ","Prague","","","|ranges|"
|
||||
"`3248 <https://wg21.link/LWG3248>`__","``std::format``\ ``#b``\ , ``#B``\ , ``#o``\ , ``#x``\ , and ``#X``\ presentation types misformat negative numbers","Prague","|Complete|","14.0","|format|"
|
||||
"`3250 <https://wg21.link/LWG3250>`__","``std::format``\ : ``#``\ (alternate form) for NaN and inf","Prague","|Complete|","14.0","|format|"
|
||||
"`3251 <https://wg21.link/LWG3251>`__","Are ``std::format``\ alignment specifiers applied to string arguments?","Prague","|Complete|","14.0","|format|"
|
||||
"`3252 <https://wg21.link/LWG3252>`__","Parse locale's aware modifiers for commands are not consistent with POSIX spec","Prague","","","|chrono|"
|
||||
"`3254 <https://wg21.link/LWG3254>`__","Strike ``stop_token``\ 's ``operator!=``\ ","Prague","",""
|
||||
"`3255 <https://wg21.link/LWG3255>`__","``span``\ 's ``array``\ constructor is too strict","Prague","|Complete|",""
|
||||
"`3260 <https://wg21.link/LWG3260>`__","``year_month*``\ arithmetic rejects durations convertible to years","Prague","","","|chrono|"
|
||||
"`3262 <https://wg21.link/LWG3262>`__","Formatting of negative durations is not specified","Prague","","","|chrono| |format|"
|
||||
"`3264 <https://wg21.link/LWG3264>`__","``sized_range``\ and ``ranges::size``\ redundantly use ``disable_sized_range``\ ","Prague","","","|ranges|"
|
||||
"`3269 <https://wg21.link/LWG3269>`__","Parse manipulators do not specify the result of the extraction from stream","Prague","","","|chrono|"
|
||||
"`3270 <https://wg21.link/LWG3270>`__","Parsing and formatting ``%j``\ with ``duration``\ s","Prague","","","|chrono| |format|"
|
||||
"`3280 <https://wg21.link/LWG3280>`__","View converting constructors can cause constraint recursion and are unneeded","Prague","","","|ranges|"
|
||||
"`3281 <https://wg21.link/LWG3281>`__","Conversion from ``*pair-like*``\ types to ``subrange``\ is a silent semantic promotion","Prague","","","|ranges|"
|
||||
"`3282 <https://wg21.link/LWG3282>`__","``subrange``\ converting constructor should disallow derived to base conversions","Prague","","","|ranges|"
|
||||
"`3284 <https://wg21.link/LWG3284>`__","``random_access_iterator``\ semantic constraints accidentally promote difference type using unary negate","Prague","","","|ranges|"
|
||||
"`3285 <https://wg21.link/LWG3285>`__","The type of a customization point object shall satisfy ``semiregular``\ ","Prague","",""
|
||||
"`3286 <https://wg21.link/LWG3286>`__","``ranges::size``\ is not required to be valid after a call to ``ranges::begin``\ on an input range","Prague","","","|ranges|"
|
||||
"`3291 <https://wg21.link/LWG3291>`__","``iota_view::iterator``\ has the wrong ``iterator_category``\ ","Prague","","","|ranges|"
|
||||
"`3292 <https://wg21.link/LWG3292>`__","``iota_view``\ is under-constrained","Prague","","","|ranges|"
|
||||
"`3294 <https://wg21.link/LWG3294>`__","``zoned_time``\ deduction guides misinterprets ``string``\ /``char*``\ ","Prague","","","|chrono|"
|
||||
"`3296 <https://wg21.link/LWG3296>`__","Inconsistent default argument for ``basic_regex<>::assign``\ ","Prague","|Complete|",""
|
||||
"`3299 <https://wg21.link/LWG3299>`__","Pointers don't need customized iterator behavior","Prague","","","|ranges|"
|
||||
"`3300 <https://wg21.link/LWG3300>`__","Non-array ``ssize``\ overload is underconstrained","Prague","",""
|
||||
"`3301 <https://wg21.link/LWG3301>`__","``transform_view::iterator``\ has incorrect ``iterator_category``\ ","Prague","","","|ranges|"
|
||||
"`3302 <https://wg21.link/LWG3302>`__","Range adaptor objects ``keys``\ and ``values``\ are unspecified","Prague","","","|ranges|"
|
||||
"`3303 <https://wg21.link/LWG3303>`__","Bad ""``constexpr``\ "" marker for ``destroy/destroy_n``\ ","Prague","",""
|
||||
"`3304 <https://wg21.link/LWG3304>`__","Allocate functions of ``std::polymorphic_allocator``\ should require ``[[nodiscard]]``\ ","Prague","",""
|
||||
"`3307 <https://wg21.link/LWG3307>`__","``std::allocator<void>().allocate(n)``\ ","Prague","",""
|
||||
"`3310 <https://wg21.link/LWG3310>`__","Replace ``SIZE_MAX``\ with ``numeric_limits<size_t>::max()``\ ","Prague","",""
|
||||
"`3313 <https://wg21.link/LWG3313>`__","``join_view::iterator::operator--``\ is incorrectly constrained","Prague","","","|ranges|"
|
||||
"`3314 <https://wg21.link/LWG3314>`__","Is stream insertion behavior locale dependent when ``Period::type``\ is ``micro``\ ?","Prague","","","|chrono|"
|
||||
"`3315 <https://wg21.link/LWG3315>`__","Correct Allocator Default Behavior","Prague","",""
|
||||
"`3316 <https://wg21.link/LWG3316>`__","Correctly define epoch for ``utc_clock``\ / ``utc_timepoint``\ ","Prague","","","|chrono|"
|
||||
"`3317 <https://wg21.link/LWG3317>`__","Incorrect ``operator<<``\ for floating-point durations","Prague","","","|chrono|"
|
||||
"`3318 <https://wg21.link/LWG3318>`__","Clarify whether clocks can represent time before their epoch","Prague","","","|chrono|"
|
||||
"`3319 <https://wg21.link/LWG3319>`__","Properly reference specification of IANA time zone database","Prague","","","|chrono|"
|
||||
"`3320 <https://wg21.link/LWG3320>`__","``span::cbegin/cend``\ methods produce different results than ``std::[ranges::]cbegin/cend``\ ","Prague","|Complete|",""
|
||||
"`3321 <https://wg21.link/LWG3321>`__","``uninitialized_construct_using_allocator``\ should use ``construct_at``\ ","Prague","",""
|
||||
"`3323 <https://wg21.link/LWG3323>`__","``*has-tuple-element*``\ helper concept needs ``convertible_to``\ ","Prague","","","|ranges|"
|
||||
"`3324 <https://wg21.link/LWG3324>`__","Special-case ``std::strong/weak/partial_order``\ for pointers","Prague","|Complete|","14.0","|spaceship|"
|
||||
"`3325 <https://wg21.link/LWG3325>`__","Constrain return type of transformation function for ``transform_view``\ ","Prague","","","|ranges|"
|
||||
"`3326 <https://wg21.link/LWG3326>`__","``enable_view``\ has false positives","Prague","|In progress|","","|ranges|"
|
||||
"`3327 <https://wg21.link/LWG3327>`__","Format alignment specifiers vs. text direction","Prague","|Nothing To Do|","","|format|"
|
||||
"`3328 <https://wg21.link/LWG3328>`__","Clarify that ``std::string``\ is not good for UTF-8","Prague","",""
|
||||
"`3329 <https://wg21.link/LWG3329>`__","``totally_ordered_with``\ both directly and indirectly requires ``common_reference_with``\ ","Prague","|Complete|","13.0"
|
||||
"`3330 <https://wg21.link/LWG3330>`__","Include ``<compare>``\ from most library headers","Prague","|Complete|","13.0","|spaceship|"
|
||||
"`3331 <https://wg21.link/LWG3331>`__","Define ``totally_ordered/_with``\ in terms of ``partially-ordered-with``\ ","Prague","|Complete|","13.0"
|
||||
"`3332 <https://wg21.link/LWG3332>`__","Issue in |sect|\ [time.format]","Prague","","","|chrono| |format|"
|
||||
"`3334 <https://wg21.link/LWG3334>`__","``basic_osyncstream``\ move assignment and destruction calls ``basic_syncbuf::emit()``\ twice","Prague","",""
|
||||
"`3335 <https://wg21.link/LWG3335>`__","Resolve C++20 NB comments US 273 and GB 274","Prague","","","|ranges|"
|
||||
"`3338 <https://wg21.link/LWG3338>`__","Rename ``default_constructible``\ to ``default_initializable``\ ","Prague","|Complete|","13.0"
|
||||
"`3340 <https://wg21.link/LWG3340>`__","Formatting functions should throw on argument/format string mismatch in |sect|\ [format.functions]","Prague","|Complete|","14.0","|format|"
|
||||
"`3346 <https://wg21.link/LWG3346>`__","``pair``\ and ``tuple``\ copy and move constructor have backwards specification","Prague","",""
|
||||
"`3347 <https://wg21.link/LWG3347>`__","``std::pair<T, U>``\ now requires ``T``\ and ``U``\ to be less-than-comparable","Prague","",""
|
||||
"`3348 <https://wg21.link/LWG3348>`__","``__cpp_lib_unwrap_ref``\ in wrong header","Prague","|Complete|","12.0"
|
||||
"`3349 <https://wg21.link/LWG3349>`__","Missing ``__cpp_lib_constexpr_complex``\ for P0415R1","Prague","",""
|
||||
"`3350 <https://wg21.link/LWG3350>`__","Simplify return type of ``lexicographical_compare_three_way``\ ","Prague","","","|spaceship|"
|
||||
"`3351 <https://wg21.link/LWG3351>`__","``ranges::enable_safe_range``\ should not be constrained","Prague","","","|ranges|"
|
||||
"`3352 <https://wg21.link/LWG3352>`__","``strong_equality``\ isn't a thing","Prague","|Nothing To Do|","","|spaceship|"
|
||||
"`3354 <https://wg21.link/LWG3354>`__","``has_strong_structural_equality``\ has a meaningless definition","Prague","","","|spaceship|"
|
||||
"`3355 <https://wg21.link/LWG3355>`__","The memory algorithms should support move-only input iterators introduced by P1207","Prague","","","|ranges|"
|
||||
"`3356 <https://wg21.link/LWG3356>`__","``__cpp_lib_nothrow_convertible``\ should be ``__cpp_lib_is_nothrow_convertible``\ ","Prague","|Complete|","12.0"
|
||||
"`3358 <https://wg21.link/LWG3358>`__","|sect|\ [span.cons] is mistaken that ``to_address``\ can throw","Prague","",""
|
||||
"`3359 <https://wg21.link/LWG3359>`__","``<chrono>``\ leap second support should allow for negative leap seconds","Prague","","","|chrono|"
|
||||
"`3360 <https://wg21.link/LWG3360>`__","``three_way_comparable_with``\ is inconsistent with similar concepts","Prague","|Nothing To Do|","","|spaceship|"
|
||||
"`3362 <https://wg21.link/LWG3362>`__","Strike ``stop_source``\ 's ``operator!=``\ ","Prague","",""
|
||||
"`3363 <https://wg21.link/LWG3363>`__","``drop_while_view``\ should opt-out of ``sized_range``\ ","Prague","","","|ranges|"
|
||||
"`3364 <https://wg21.link/LWG3364>`__","Initialize data members of ranges and their iterators","Prague","","","|ranges|"
|
||||
"`3367 <https://wg21.link/LWG3367>`__","Integer-class conversions should not throw","Prague","",""
|
||||
"`3369 <https://wg21.link/LWG3369>`__","``span``\ 's deduction-guide for built-in arrays doesn't work","Prague","|Complete|","14.0"
|
||||
"`3371 <https://wg21.link/LWG3371>`__","``visit_format_arg``\ and ``make_format_args``\ are not hidden friends","Prague","|Complete|","14.0","|format|"
|
||||
"`3372 <https://wg21.link/LWG3372>`__","``vformat_to``\ should not try to deduce ``Out``\ twice","Prague","|Complete|","14.0","|format|"
|
||||
"`3373 <https://wg21.link/LWG3373>`__","``{to,from}_chars_result``\ and ``format_to_n_result``\ need the ""we really mean what we say"" wording","Prague","|Complete|","14.0","|format|"
|
||||
"`3374 <https://wg21.link/LWG3374>`__","P0653 + P1006 should have made the other ``std::to_address``\ overload ``constexpr``\ ","Prague","|Complete|","12.0"
|
||||
"`3375 <https://wg21.link/LWG3375>`__","``decay``\ in ``viewable_range``\ should be ``remove_cvref``\ ","Prague","","","|ranges|"
|
||||
"`3377 <https://wg21.link/LWG3377>`__","``elements_view::iterator``\ befriends a specialization of itself","Prague","","","|ranges|"
|
||||
"`3379 <https://wg21.link/LWG3379>`__","""``safe``\ "" in several library names is misleading","Prague","|In Progress|",""
|
||||
"`3380 <https://wg21.link/LWG3380>`__","``common_type``\ and comparison categories","Prague","","","|spaceship|"
|
||||
"`3381 <https://wg21.link/LWG3381>`__","``begin``\ and ``data``\ must agree for ``contiguous_range``\ ","Prague","","","|ranges|"
|
||||
"`3382 <https://wg21.link/LWG3382>`__","NTTP for ``pair``\ and ``array``\ ","Prague","",""
|
||||
"`3383 <https://wg21.link/LWG3383>`__","|sect|\ [time.zone.leap.nonmembers] ``sys_seconds``\ should be replaced with ``seconds``\ ","Prague","","","|chrono|"
|
||||
"`3384 <https://wg21.link/LWG3384>`__","``transform_view::*sentinel*``\ has an incorrect ``operator-``\ ","Prague","","","|ranges|"
|
||||
"`3385 <https://wg21.link/LWG3385>`__","``common_iterator``\ is not sufficiently constrained for non-copyable iterators","Prague","","","|ranges|"
|
||||
"`3387 <https://wg21.link/LWG3387>`__","|sect|\ [range.reverse.view] ``reverse_view<V>``\ unintentionally requires ``range<const V>``\ ","Prague","","","|ranges|"
|
||||
"`3388 <https://wg21.link/LWG3388>`__","``view``\ iterator types have ill-formed ``<=>``\ operators","Prague","","","|ranges|"
|
||||
"`3389 <https://wg21.link/LWG3389>`__","A move-only iterator still does not have a ``counted_iterator``\ ","Prague","","","|ranges|"
|
||||
"`3390 <https://wg21.link/LWG3390>`__","``make_move_iterator()``\ cannot be used to construct a ``move_iterator``\ for a move-only iterator","Prague","|Complete|","14.0","|ranges|"
|
||||
"`3393 <https://wg21.link/LWG3393>`__","Missing/incorrect feature test macro for coroutines","Prague","|Complete|","14.0"
|
||||
"`3395 <https://wg21.link/LWG3395>`__","Definition for three-way comparison needs to be updated (US 152)","Prague","","","|spaceship|"
|
||||
"`3396 <https://wg21.link/LWG3396>`__","Clarify point of reference for ``source_location::current()``\ (DE 169)","Prague","",""
|
||||
"`3397 <https://wg21.link/LWG3397>`__","``ranges::basic_istream_view::iterator``\ should not provide ``iterator_category``\ ","Prague","","","|ranges|"
|
||||
"`3398 <https://wg21.link/LWG3398>`__","``tuple_element_t``\ is also wrong for ``const subrange``\ ","Prague","|Complete|","14.0","|ranges|"
|
||||
"`3446 <https://wg21.link/LWG3446>`__","``indirectly_readable_traits``\ ambiguity for types with both ``value_type``\ and ``element_type``\ ","November virtual meeting","|Complete|","13.0"
|
Can't render this file because it has a wrong number of fields in line 2.
|
207
docs/Status/Cxx20Papers.csv
Normal file
207
docs/Status/Cxx20Papers.csv
Normal file
@ -0,0 +1,207 @@
|
||||
"Paper #","Group","Paper Name","Meeting","Status","First released version"
|
||||
"`P0463R1 <https://wg21.link/P0463R1>`__","LWG","Endian just Endian","Toronto","|Complete|","7.0"
|
||||
"`P0674R1 <https://wg21.link/P0674R1>`__","LWG","Extending make_shared to Support Arrays","Toronto","",""
|
||||
"","","","","",""
|
||||
"`P0020R6 <https://wg21.link/P0020R6>`__","LWG","Floating Point Atomic","Albuquerque","",""
|
||||
"`P0053R7 <https://wg21.link/P0053R7>`__","LWG","C++ Synchronized Buffered Ostream","Albuquerque","",""
|
||||
"`P0202R3 <https://wg21.link/P0202R3>`__","LWG","Add constexpr modifiers to functions in <algorithm> and <utility> Headers","Albuquerque","|Complete|","12.0"
|
||||
"`P0415R1 <https://wg21.link/P0415R1>`__","LWG","Constexpr for ``std::complex``\ ","Albuquerque","|In Progress|","7.0"
|
||||
"`P0439R0 <https://wg21.link/P0439R0>`__","LWG","Make ``std::memory_order``\ a scoped enumeration","Albuquerque","|Complete|",""
|
||||
"`P0457R2 <https://wg21.link/P0457R2>`__","LWG","String Prefix and Suffix Checking","Albuquerque","|Complete|","6.0"
|
||||
"`P0550R2 <https://wg21.link/P0550R2>`__","LWG","Transformation Trait ``remove_cvref``\ ","Albuquerque","|Complete|","6.0"
|
||||
"`P0600R1 <https://wg21.link/P0600R1>`__","LWG","nodiscard in the Library","Albuquerque","|In Progress| [#note-P0600]_","7.0"
|
||||
"`P0616R0 <https://wg21.link/P0616R0>`__","LWG","de-pessimize legacy <numeric> algorithms with std::move","Albuquerque","|Complete|","12.0"
|
||||
"`P0653R2 <https://wg21.link/P0653R2>`__","LWG","Utility to convert a pointer to a raw pointer","Albuquerque","|Complete|","6.0"
|
||||
"`P0718R2 <https://wg21.link/P0718R2>`__","LWG","Atomic shared_ptr","Albuquerque","",""
|
||||
"`P0767R1 <https://wg21.link/P0767R1>`__","CWG","Deprecate POD","Albuquerque","|Complete|","7.0"
|
||||
"`P0768R1 <https://wg21.link/P0768R1>`__","CWG","Library Support for the Spaceship (Comparison) Operator","Albuquerque","|Complete|",""
|
||||
"`P0777R1 <https://wg21.link/P0777R1>`__","LWG","Treating Unnecessary ``decay``\ ","Albuquerque","|Complete|","7.0"
|
||||
"`P0122R7 <https://wg21.link/P0122R7>`__","LWG","<span>","Jacksonville","|Complete|","7.0"
|
||||
"`P0355R7 <https://wg21.link/P0355R7>`__","LWG","Extending chrono to Calendars and Time Zones","Jacksonville","|In Progress|",""
|
||||
"`P0551R3 <https://wg21.link/P0551R3>`__","LWG","Thou Shalt Not Specialize ``std``\ Function Templates!","Jacksonville","|Complete|","11.0"
|
||||
"`P0753R2 <https://wg21.link/P0753R2>`__","LWG","Manipulators for C++ Synchronized Buffered Ostream","Jacksonville","",""
|
||||
"`P0754R2 <https://wg21.link/P0754R2>`__","LWG","<version>","Jacksonville","|Complete|","7.0"
|
||||
"`P0809R0 <https://wg21.link/P0809R0>`__","LWG","Comparing Unordered Containers","Jacksonville","|Nothing To Do|",""
|
||||
"`P0858R0 <https://wg21.link/P0858R0>`__","LWG","Constexpr iterator requirements","Jacksonville","|Complete|","12.0"
|
||||
"`P0905R1 <https://wg21.link/P0905R1>`__","CWG","Symmetry for spaceship","Jacksonville","",""
|
||||
"`P0966R1 <https://wg21.link/P0966R1>`__","LWG","``string::reserve``\ Should Not Shrink","Jacksonville","|Complete| [#note-P0966]_","12.0"
|
||||
"","","","","",""
|
||||
"`P0019R8 <https://wg21.link/P0019R8>`__","LWG","Atomic Ref","Rapperswil","",""
|
||||
"`P0458R2 <https://wg21.link/P0458R2>`__","LWG","Checking for Existence of an Element in Associative Containers","Rapperswil","|Complete|","13.0"
|
||||
"`P0475R1 <https://wg21.link/P0475R1>`__","LWG","LWG 2511: guaranteed copy elision for piecewise construction","Rapperswil","|Complete|",""
|
||||
"`P0476R2 <https://wg21.link/P0476R2>`__","LWG","Bit-casting object representations","Rapperswil","|Complete|","14.0"
|
||||
"`P0528R3 <https://wg21.link/P0528R3>`__","CWG","The Curious Case of Padding Bits, Featuring Atomic Compare-and-Exchange","Rapperswil","",""
|
||||
"`P0542R5 <https://wg21.link/P0542R5>`__","CWG","Support for contract based programming in C++","Rapperswil","*Removed in Cologne*","n/a"
|
||||
"`P0556R3 <https://wg21.link/P0556R3>`__","LWG","Integral power-of-2 operations","Rapperswil","|Complete|","9.0"
|
||||
"`P0619R4 <https://wg21.link/P0619R4>`__","LWG","Reviewing Deprecated Facilities of C++17 for C++20","Rapperswil","|Partial| [#note-P0619]_",""
|
||||
"`P0646R1 <https://wg21.link/P0646R1>`__","LWG","Improving the Return Value of Erase-Like Algorithms","Rapperswil","|Complete|","10.0"
|
||||
"`P0722R3 <https://wg21.link/P0722R3>`__","CWG","Efficient sized delete for variable sized classes","Rapperswil","|Complete|","9.0"
|
||||
"`P0758R1 <https://wg21.link/P0758R1>`__","LWG","Implicit conversion traits and utility functions","Rapperswil","|Complete|",""
|
||||
"`P0759R1 <https://wg21.link/P0759R1>`__","LWG","fpos Requirements","Rapperswil","|Complete|","11.0"
|
||||
"`P0769R2 <https://wg21.link/P0769R2>`__","LWG","Add shift to <algorithm>","Rapperswil","|Complete|","12.0"
|
||||
"`P0788R3 <https://wg21.link/P0788R3>`__","LWG","Standard Library Specification in a Concepts and Contracts World","Rapperswil","*Removed in Cologne*","n/a"
|
||||
"`P0879R0 <https://wg21.link/P0879R0>`__","LWG","Constexpr for swap and swap related functions Also resolves LWG issue 2800.","Rapperswil","|Complete|","13.0"
|
||||
"`P0887R1 <https://wg21.link/P0887R1>`__","LWG","The identity metafunction","Rapperswil","|Complete|","8.0"
|
||||
"`P0892R2 <https://wg21.link/P0892R2>`__","CWG","explicit(bool)","Rapperswil","",""
|
||||
"`P0898R3 <https://wg21.link/P0898R3>`__","LWG","Standard Library Concepts","Rapperswil","|Complete|","13.0"
|
||||
"`P0935R0 <https://wg21.link/P0935R0>`__","LWG","Eradicating unnecessarily explicit default constructors from the standard library","Rapperswil","|Complete|","12.0"
|
||||
"`P0941R2 <https://wg21.link/P0941R2>`__","CWG","Integrating feature-test macros into the C++ WD","Rapperswil","|In Progress|",""
|
||||
"`P1023R0 <https://wg21.link/P1023R0>`__","LWG","constexpr comparison operators for std::array","Rapperswil","|Complete|","8.0"
|
||||
"`P1025R1 <https://wg21.link/P1025R1>`__","CWG","Update The Reference To The Unicode Standard","Rapperswil","",""
|
||||
"`P1120R0 <https://wg21.link/P1120R0>`__","CWG","Consistency improvements for <=> and other comparison operators","Rapperswil","",""
|
||||
"","","","","",""
|
||||
"`P0318R1 <https://wg21.link/P0318R1>`__","LWG","unwrap_ref_decay and unwrap_reference","San Diego","|Complete|","8.0"
|
||||
"`P0356R5 <https://wg21.link/P0356R5>`__","LWG","Simplified partial function application","San Diego","|Complete|","13.0"
|
||||
"`P0357R3 <https://wg21.link/P0357R3>`__","LWG","reference_wrapper for incomplete types","San Diego","|Complete|","8.0"
|
||||
"`P0482R6 <https://wg21.link/P0482R6>`__","CWG","char8_t: A type for UTF-8 characters and strings","San Diego","|In Progress|",""
|
||||
"`P0487R1 <https://wg21.link/P0487R1>`__","LWG","Fixing ``operator>>(basic_istream&, CharT*)``\ (LWG 2499)","San Diego","|Complete|","8.0"
|
||||
"`P0591R4 <https://wg21.link/P0591R4>`__","LWG","Utility functions to implement uses-allocator construction","San Diego","* *",""
|
||||
"`P0595R2 <https://wg21.link/P0595R2>`__","CWG","P0595R2 std::is_constant_evaluated()","San Diego","|Complete|","9.0"
|
||||
"`P0602R4 <https://wg21.link/P0602R4>`__","LWG","variant and optional should propagate copy/move triviality","San Diego","|Complete|","8.0"
|
||||
"`P0608R3 <https://wg21.link/P0608R3>`__","LWG","A sane variant converting constructor","San Diego","|Complete|","9.0"
|
||||
"`P0655R1 <https://wg21.link/P0655R1>`__","LWG","visit<R>: Explicit Return Type for visit","San Diego","|Complete|","12.0"
|
||||
"`P0771R1 <https://wg21.link/P0771R1>`__","LWG","std::function move constructor should be noexcept","San Diego","|Complete|","6.0"
|
||||
"`P0896R4 <https://wg21.link/P0896R4>`__","LWG","The One Ranges Proposal","San Diego","|In Progress|",""
|
||||
"`P0899R1 <https://wg21.link/P0899R1>`__","LWG","P0899R1 - LWG 3016 is not a defect","San Diego","|Nothing To Do|",""
|
||||
"`P0919R3 <https://wg21.link/P0919R3>`__","LWG","Heterogeneous lookup for unordered containers","San Diego","|Complete|","12.0"
|
||||
"`P0972R0 <https://wg21.link/P0972R0>`__","LWG","<chrono> ``zero()``\ , ``min()``\ , and ``max()``\ should be noexcept","San Diego","|Complete|","8.0"
|
||||
"`P1006R1 <https://wg21.link/P1006R1>`__","LWG","Constexpr in std::pointer_traits","San Diego","|Complete|","8.0"
|
||||
"`P1007R3 <https://wg21.link/P1007R3>`__","LWG","``std::assume_aligned``\ ","San Diego","* *",""
|
||||
"`P1020R1 <https://wg21.link/P1020R1>`__","LWG","Smart pointer creation with default initialization","San Diego","* *",""
|
||||
"`P1032R1 <https://wg21.link/P1032R1>`__","LWG","Misc constexpr bits","San Diego","|Complete|","13.0"
|
||||
"`P1085R2 <https://wg21.link/P1085R2>`__","LWG","Should Span be Regular?","San Diego","|Complete|","8.0"
|
||||
"`P1123R0 <https://wg21.link/P1123R0>`__","LWG","Editorial Guidance for merging P0019r8 and P0528r3","San Diego","* *",""
|
||||
"`P1148R0 <https://wg21.link/P1148R0>`__","LWG","Cleaning up Clause 20","San Diego","* *",""
|
||||
"`P1165R1 <https://wg21.link/P1165R1>`__","LWG","Make stateful allocator propagation more consistent for ``operator+(basic_string)``\ ","San Diego","* *",""
|
||||
"`P1209R0 <https://wg21.link/P1209R0>`__","LWG","Adopt Consistent Container Erasure from Library Fundamentals 2 for C++20","San Diego","|Complete|","8.0"
|
||||
"`P1210R0 <https://wg21.link/P1210R0>`__","LWG","Completing the Rebase of Library Fundamentals, Version 3, Working Draft","San Diego","* *",""
|
||||
"`P1236R1 <https://wg21.link/P1236R1>`__","CWG","Alternative Wording for P0907R4 Signed Integers are Two's Complement","San Diego","* *",""
|
||||
"`P1248R1 <https://wg21.link/P1248R1>`__","LWG","Remove CommonReference requirement from StrictWeakOrdering (a.k.a Fixing Relations)","San Diego","|Complete|","13.0"
|
||||
"`P1285R0 <https://wg21.link/P1285R0>`__","LWG","Improving Completeness Requirements for Type Traits","San Diego","* *",""
|
||||
"`P1353R0 <https://wg21.link/P1353R0>`__","CWG","Missing feature test macros","San Diego","* *",""
|
||||
"","","","","",""
|
||||
"`P0339R6 <https://wg21.link/P0339R6>`__","LWG","polymorphic_allocator<> as a vocabulary type","Kona","",""
|
||||
"`P0340R3 <https://wg21.link/P0340R3>`__","LWG","Making std::underlying_type SFINAE-friendly","Kona","|Complete|","9.0"
|
||||
"`P0738R2 <https://wg21.link/P0738R2>`__","LWG","I Stream, You Stream, We All Stream for istream_iterator","Kona","",""
|
||||
"`P0811R3 <https://wg21.link/P0811R3>`__","LWG","Well-behaved interpolation for numbers and pointers","Kona","|Complete|","9.0"
|
||||
"`P0920R2 <https://wg21.link/P0920R2>`__","LWG","Precalculated hash values in lookup","Kona","Reverted by `P1661 <https://wg21.link/P1661>`__",""
|
||||
"`P1001R2 <https://wg21.link/P1001R2>`__","LWG","Target Vectorization Policies from Parallelism V2 TS to C++20","Kona","",""
|
||||
"`P1024R3 <https://wg21.link/P1024R3>`__","LWG","Usability Enhancements for std::span","Kona","|Complete|","9.0"
|
||||
"`P1164R1 <https://wg21.link/P1164R1>`__","LWG","Make create_directory() Intuitive","Kona","|Complete|","12.0"
|
||||
"`P1227R2 <https://wg21.link/P1227R2>`__","LWG","Signed ssize() functions, unsigned size() functions","Kona","|Complete|","9.0"
|
||||
"`P1252R2 <https://wg21.link/P1252R2>`__","LWG","Ranges Design Cleanup","Kona","",""
|
||||
"`P1286R2 <https://wg21.link/P1286R2>`__","CWG","Contra CWG DR1778","Kona","",""
|
||||
"`P1357R1 <https://wg21.link/P1357R1>`__","LWG","Traits for [Un]bounded Arrays","Kona","|Complete|","9.0"
|
||||
"`P1458R1 <https://wg21.link/P1458R1>`__","LWG","Mandating the Standard Library: Clause 16 - Language support library","Kona","|Complete|","9.0"
|
||||
"`P1459R1 <https://wg21.link/P1459R1>`__","LWG","Mandating the Standard Library: Clause 18 - Diagnostics library","Kona","|Complete|","9.0"
|
||||
"`P1462R1 <https://wg21.link/P1462R1>`__","LWG","Mandating the Standard Library: Clause 20 - Strings library","Kona","|Complete|","9.0"
|
||||
"`P1463R1 <https://wg21.link/P1463R1>`__","LWG","Mandating the Standard Library: Clause 21 - Containers library","Kona","",""
|
||||
"`P1464R1 <https://wg21.link/P1464R1>`__","LWG","Mandating the Standard Library: Clause 22 - Iterators library","Kona","|Complete|","9.0"
|
||||
"","","","","",""
|
||||
"`P0325R4 <https://wg21.link/P0325R4>`__","LWG","to_array from LFTS with updates","Cologne","|Complete|","10.0"
|
||||
"`P0408R7 <https://wg21.link/P0408R7>`__","LWG","Efficient Access to basic_stringbuf's Buffer","Cologne","",""
|
||||
"`P0466R5 <https://wg21.link/P0466R5>`__","LWG","Layout-compatibility and Pointer-interconvertibility Traits","Cologne","",""
|
||||
"`P0553R4 <https://wg21.link/P0553R4>`__","LWG","Bit operations","Cologne","|Complete|","9.0"
|
||||
"`P0631R8 <https://wg21.link/P0631R8>`__","LWG","Math Constants","Cologne","|Complete|","11.0"
|
||||
"`P0645R10 <https://wg21.link/P0645R10>`__","LWG","Text Formatting","Cologne","|Complete| [#note-P0645]_","14.0"
|
||||
"`P0660R10 <https://wg21.link/P0660R10>`__","LWG","Stop Token and Joining Thread, Rev 10","Cologne","",""
|
||||
"`P0784R7 <https://wg21.link/P0784R7>`__","CWG","More constexpr containers","Cologne","|Complete|","12.0"
|
||||
"`P0980R1 <https://wg21.link/P0980R1>`__","LWG","Making std::string constexpr","Cologne","",""
|
||||
"`P1004R2 <https://wg21.link/P1004R2>`__","LWG","Making std::vector constexpr","Cologne","",""
|
||||
"`P1035R7 <https://wg21.link/P1035R7>`__","LWG","Input Range Adaptors","Cologne","",""
|
||||
"`P1065R2 <https://wg21.link/P1065R2>`__","LWG","Constexpr INVOKE","Cologne","|Complete|","12.0"
|
||||
"`P1135R6 <https://wg21.link/P1135R6>`__","LWG","The C++20 Synchronization Library","Cologne","|Complete|","11.0"
|
||||
"`P1207R4 <https://wg21.link/P1207R4>`__","LWG","Movability of Single-pass Iterators","Cologne","",""
|
||||
"`P1208R6 <https://wg21.link/P1208R6>`__","LWG","Adopt source_location for C++20","Cologne","",""
|
||||
"`P1355R2 <https://wg21.link/P1355R2>`__","LWG","Exposing a narrow contract for ceil2","Cologne","|Complete|","9.0"
|
||||
"`P1361R2 <https://wg21.link/P1361R2>`__","LWG","Integration of chrono with text formatting","Cologne","",""
|
||||
"`P1423R3 <https://wg21.link/P1423R3>`__","LWG","char8_t backward compatibility remediation","Cologne","|In Progress|",""
|
||||
"`P1424R1 <https://wg21.link/P1424R1>`__","LWG","'constexpr' feature macro concerns","Cologne","Superseded by `P1902 <https://wg21.link/P1902>`__",""
|
||||
"`P1466R3 <https://wg21.link/P1466R3>`__","LWG","Miscellaneous minor fixes for chrono","Cologne","",""
|
||||
"`P1474R1 <https://wg21.link/P1474R1>`__","LWG","Helpful pointers for ContiguousIterator","Cologne","",""
|
||||
"`P1502R1 <https://wg21.link/P1502R1>`__","LWG","Standard library header units for C++20","Cologne","",""
|
||||
"`P1522R1 <https://wg21.link/P1522R1>`__","LWG","Iterator Difference Type and Integer Overflow","Cologne","",""
|
||||
"`P1523R1 <https://wg21.link/P1523R1>`__","LWG","Views and Size Types","Cologne","",""
|
||||
"`P1612R1 <https://wg21.link/P1612R1>`__","LWG","Relocate Endian's Specification","Cologne","|Complete|","10.0"
|
||||
"`P1614R2 <https://wg21.link/P1614R2>`__","LWG","The Mothership has Landed","Cologne","|In Progress|",""
|
||||
"`P1638R1 <https://wg21.link/P1638R1>`__","LWG","basic_istream_view::iterator should not be copyable","Cologne","",""
|
||||
"`P1643R1 <https://wg21.link/P1643R1>`__","LWG","Add wait/notify to atomic_ref","Cologne","",""
|
||||
"`P1644R0 <https://wg21.link/P1644R0>`__","LWG","Add wait/notify to atomic<shared_ptr>","Cologne","",""
|
||||
"`P1650R0 <https://wg21.link/P1650R0>`__","LWG","Output std::chrono::days with 'd' suffix","Cologne","",""
|
||||
"`P1651R0 <https://wg21.link/P1651R0>`__","LWG","bind_front should not unwrap reference_wrapper","Cologne","|Complete|","13.0"
|
||||
"`P1652R1 <https://wg21.link/P1652R1>`__","LWG","Printf corner cases in std::format","Cologne","|Complete|","14.0"
|
||||
"`P1661R1 <https://wg21.link/P1661R1>`__","LWG","Remove dedicated precalculated hash lookup interface","Cologne","|Nothing To Do|",""
|
||||
"`P1754R1 <https://wg21.link/P1754R1>`__","LWG","Rename concepts to standard_case for C++20, while we still can","Cologne","|In Progress|",""
|
||||
"","","","","",""
|
||||
"`P0883R2 <https://wg21.link/P0883R2>`__","LWG","Fixing Atomic Initialization","Belfast","|Complete| [#note-P0883]_","14.0"
|
||||
"`P1391R4 <https://wg21.link/P1391R4>`__","LWG","Range constructor for std::string_view","Belfast","|Complete|","14.0"
|
||||
"`P1394R4 <https://wg21.link/P1394R4>`__","LWG","Range constructor for std::span","Belfast","|Complete|","14.0"
|
||||
"`P1456R1 <https://wg21.link/P1456R1>`__","LWG","Move-only views","Belfast","* *",""
|
||||
"`P1622R3 <https://wg21.link/P1622R3>`__","LWG","Mandating the Standard Library: Clause 32 - Thread support library","Belfast","* *",""
|
||||
"`P1645R1 <https://wg21.link/P1645R1>`__","LWG","constexpr for numeric algorithms","Belfast","|Complete|","12.0"
|
||||
"`P1686R2 <https://wg21.link/P1686R2>`__","LWG","Mandating the Standard Library: Clause 27 - Time library","Belfast","* *",""
|
||||
"`P1690R1 <https://wg21.link/P1690R1>`__","LWG","Refinement Proposal for P0919 Heterogeneous lookup for unordered containers","Belfast","|Complete|","12.0"
|
||||
"`P1716R3 <https://wg21.link/P1716R3>`__","LWG","ranges compare algorithm are over-constrained","Belfast","* *",""
|
||||
"`P1718R2 <https://wg21.link/P1718R2>`__","LWG","Mandating the Standard Library: Clause 25 - Algorithms library","Belfast","* *",""
|
||||
"`P1719R2 <https://wg21.link/P1719R2>`__","LWG","Mandating the Standard Library: Clause 26 - Numerics library","Belfast","* *",""
|
||||
"`P1720R2 <https://wg21.link/P1720R2>`__","LWG","Mandating the Standard Library: Clause 28 - Localization library","Belfast","* *",""
|
||||
"`P1721R2 <https://wg21.link/P1721R2>`__","LWG","Mandating the Standard Library: Clause 29 - Input/Output library","Belfast","* *",""
|
||||
"`P1722R2 <https://wg21.link/P1722R2>`__","LWG","Mandating the Standard Library: Clause 30 - Regular Expression library","Belfast","* *",""
|
||||
"`P1723R2 <https://wg21.link/P1723R2>`__","LWG","Mandating the Standard Library: Clause 31 - Atomics library","Belfast","* *",""
|
||||
"`P1855R0 <https://wg21.link/P1855R0>`__","LWG","Make ``<compare>``\ freestanding","Belfast","* *",""
|
||||
"`P1862R1 <https://wg21.link/P1862R1>`__","LWG","Ranges adaptors for non-copyable iterators","Belfast","* *",""
|
||||
"`P1865R1 <https://wg21.link/P1865R1>`__","LWG","Add max() to latch and barrier","Belfast","|Complete|","11.0"
|
||||
"`P1869R1 <https://wg21.link/P1869R1>`__","LWG","Rename 'condition_variable_any' interruptible wait methods","Belfast","* *",""
|
||||
"`P1870R1 <https://wg21.link/P1870R1>`__","LWG","forwarding-range is too subtle","Belfast","|In Progress|",""
|
||||
"`P1871R1 <https://wg21.link/P1871R1>`__","LWG","Should concepts be enabled or disabled?","Belfast","|Complete|","14.0"
|
||||
"`P1872R0 <https://wg21.link/P1872R0>`__","LWG","span should have size_type, not index_type","Belfast","|Complete|","10.0"
|
||||
"`P1878R1 <https://wg21.link/P1878R1>`__","LWG","Constraining Readable Types","Belfast","* *",""
|
||||
"`P1892R1 <https://wg21.link/P1892R1>`__","LWG","Extended locale-specific presentation specifiers for std::format","Belfast","|Complete|","14.0"
|
||||
"`P1902R1 <https://wg21.link/P1902R1>`__","LWG","Missing feature-test macros 2018-2019","Belfast","* *",""
|
||||
"`P1959R0 <https://wg21.link/P1959R0>`__","LWG","Remove std::weak_equality and std::strong_equality","Belfast","* *",""
|
||||
"`P1960R0 <https://wg21.link/P1960R0>`__","LWG","NB Comment Changes Reviewed by SG1","Belfast","* *",""
|
||||
"`P1961R0 <https://wg21.link/P1961R0>`__","LWG","Harmonizing the definitions of total order for pointers","Belfast","* *",""
|
||||
"`P1965R0 <https://wg21.link/P1965R0>`__","LWG","Blanket Wording for Specifying ""Hidden Friends""","Belfast","* *",""
|
||||
"","","","","",""
|
||||
"`P0586R2 <https://wg21.link/P0586R2>`__","LWG","Safe integral comparisons","Prague","|Complete|","13.0"
|
||||
"`P0593R6 <https://wg21.link/P0593R6>`__","CWG","Implicit creation of objects for low-level object manipulation","Prague","* *",""
|
||||
"`P1115R3 <https://wg21.link/P1115R3>`__","LWG","Improving the Return Value of Erase-Like Algorithms II: Free erase/erase if","Prague","|Complete|","11.0"
|
||||
"`P1243R4 <https://wg21.link/P1243R4>`__","LWG","Rangify New Algorithms","Prague","* *",""
|
||||
"`P1460R1 <https://wg21.link/P1460R1>`__","LWG","Mandating the Standard Library: Clause 20 - Utilities library","Prague","* *",""
|
||||
"`P1739R4 <https://wg21.link/P1739R4>`__","LWG","Avoid template bloat for safe_ranges in combination with ""subrange-y"" view adaptors","Prague","* *",""
|
||||
"`P1831R1 <https://wg21.link/P1831R1>`__","LWG","Deprecating volatile: library","Prague","* *",""
|
||||
"`P1868R2 <https://wg21.link/P1868R2>`__","LWG","width: clarifying units of width and precision in std::format","Prague","|Complete|","14.0"
|
||||
"`P1908R1 <https://wg21.link/P1908R1>`__","CWG","Reserving Attribute Namespaces for Future Use","Prague","* *",""
|
||||
"`P1937R2 <https://wg21.link/P1937R2>`__","CWG","Fixing inconsistencies between constexpr and consteval functions","Prague","* *",""
|
||||
"`P1956R1 <https://wg21.link/P1956R1>`__","LWG","On the names of low-level bit manipulation functions","Prague","|Complete|","12.0"
|
||||
"`P1957R2 <https://wg21.link/P1957R2>`__","CWG","Converting from ``T*``\ to bool should be considered narrowing (re: US 212)","Prague","* *",""
|
||||
"`P1963R0 <https://wg21.link/P1963R0>`__","LWG","Fixing US 313","Prague","* *",""
|
||||
"`P1964R2 <https://wg21.link/P1964R2>`__","LWG","Wording for boolean-testable","Prague","|Complete|","13.0"
|
||||
"`P1970R2 <https://wg21.link/P1970R2>`__","LWG","Consistency for size() functions: Add ranges::ssize","Prague","* *",""
|
||||
"`P1973R1 <https://wg21.link/P1973R1>`__","LWG","Rename ""_default_init"" Functions, Rev1","Prague","* *",""
|
||||
"`P1976R2 <https://wg21.link/P1976R2>`__","LWG","Fixed-size span construction from dynamic range","Prague","|Complete|","11.0"
|
||||
"`P1981R0 <https://wg21.link/P1981R0>`__","LWG","Rename leap to leap_second","Prague","* *",""
|
||||
"`P1982R0 <https://wg21.link/P1982R0>`__","LWG","Rename link to time_zone_link","Prague","* *",""
|
||||
"`P1983R0 <https://wg21.link/P1983R0>`__","LWG","Wording for GB301, US296, US292, US291, and US283","Prague","* *",""
|
||||
"`P1994R1 <https://wg21.link/P1994R1>`__","LWG","elements_view needs its own sentinel","Prague","* *",""
|
||||
"`P2002R1 <https://wg21.link/P2002R1>`__","CWG","Defaulted comparison specification cleanups","Prague","* *",""
|
||||
"`P2045R1 <https://wg21.link/P2045R1>`__","LWG","Missing Mandates for the standard library","Prague","* *",""
|
||||
"`P2085R0 <https://wg21.link/P2085R0>`__","CWG","Consistent defaulted comparisons","Prague","* *",""
|
||||
"`P2091R0 <https://wg21.link/P2091R0>`__","LWG","Issues with range access CPOs","Prague","* *",""
|
||||
"`P2101R0 <https://wg21.link/P2101R0>`__","LWG","'Models' subsumes 'satisfies' (Wording for US298 and US300)","Prague","* *",""
|
||||
"`P2102R0 <https://wg21.link/P2102R0>`__","LWG","Make 'implicit expression variations' more explicit (Wording for US185)","Prague","* *",""
|
||||
"`P2106R0 <https://wg21.link/P2106R0>`__","LWG","Alternative wording for GB315 and GB316","Prague","* *",""
|
||||
"`P2116R0 <https://wg21.link/P2116R0>`__","LWG","Remove tuple-like protocol support from fixed-extent span","Prague","|Complete|","11.0"
|
||||
"","","","","",""
|
||||
"`P2231R1 <https://wg21.link/P2231R1>`__","LWG","Missing constexpr in std::optional and std::variant","June 2021","|In progress|","13.0"
|
||||
"`P2325R3 <https://wg21.link/P2325R3>`__","LWG","Views should not be required to be default constructible","June 2021","|In progress|",""
|
||||
"`P2210R2 <https://wg21.link/P2210R2>`__","LWG",Superior String Splitting,"June 2021","",""
|
||||
"`P2216R3 <https://wg21.link/P2216R3>`__","LWG",std::format improvements,"June 2021","|Partial|",""
|
||||
"`P2281R1 <https://wg21.link/P2281R1>`__","LWG",Clarifying range adaptor objects,"June 2021","|Complete|","14.0"
|
||||
"`P2328R1 <https://wg21.link/P2328R1>`__","LWG",join_view should join all views of ranges,"June 2021","",""
|
||||
"`P2367R0 <https://wg21.link/P2367R0>`__","LWG",Remove misuses of list-initialization from Clause 24,"June 2021","",""
|
||||
"","","","","",""
|
||||
"`P2372R3 <https://wg21.link/P2372R3>`__","LWG","Fixing locale handling in chrono formatters","October 2021","",""
|
||||
"`P2415R2 <https://wg21.link/P2415R2>`__","LWG","What is a ``view``","October 2021","|Complete|","14.0"
|
||||
"`P2418R2 <https://wg21.link/P2418R2>`__","LWG","Add support for ``std::generator``-like types to ``std::format``","October 2021","",""
|
||||
"`P2432R1 <https://wg21.link/P2432R1>`__","LWG","Fix ``istream_view``","October 2021","",""
|
|
48
docs/Status/Cxx2b.rst
Normal file
48
docs/Status/Cxx2b.rst
Normal file
@ -0,0 +1,48 @@
|
||||
.. _cxx2b-status:
|
||||
|
||||
================================
|
||||
libc++ C++2b Status
|
||||
================================
|
||||
|
||||
.. include:: ../Helpers/Styles.rst
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
|
||||
Overview
|
||||
================================
|
||||
|
||||
In November 2020, the C++ standard committee adopted the first changes to the next version of the C++ standard, known here as "C++2b" (probably to be C++23).
|
||||
|
||||
This page shows the status of libc++; the status of clang's support of the language features is `here <https://clang.llvm.org/cxx_status.html#cxx23>`__.
|
||||
|
||||
.. attention:: Features in unreleased drafts of the standard are subject to change.
|
||||
|
||||
The groups that have contributed papers:
|
||||
|
||||
- CWG - Core Language Working group
|
||||
- LWG - Library working group
|
||||
- SG1 - Study group #1 (Concurrency working group)
|
||||
|
||||
.. note:: "Nothing to do" means that no library changes were needed to implement this change.
|
||||
|
||||
.. _paper-status-cxx2b:
|
||||
|
||||
Paper Status
|
||||
====================================
|
||||
|
||||
.. csv-table::
|
||||
:file: Cxx2bPapers.csv
|
||||
:header-rows: 1
|
||||
:widths: auto
|
||||
|
||||
.. _issues-status-cxx2b:
|
||||
|
||||
Library Working Group Issues Status
|
||||
====================================
|
||||
|
||||
.. csv-table::
|
||||
:file: Cxx2bIssues.csv
|
||||
:header-rows: 1
|
||||
:widths: auto
|
141
docs/Status/Cxx2bIssues.csv
Normal file
141
docs/Status/Cxx2bIssues.csv
Normal file
@ -0,0 +1,141 @@
|
||||
"Issue #","Issue Name","Meeting","Status","First released version","Labels"
|
||||
"`2839 <https://wg21.link/LWG2839>`__","Self-move-assignment of library types, again","November 2020","|Nothing To Do|",""
|
||||
"`3117 <https://wg21.link/LWG3117>`__","Missing ``packaged_task`` deduction guides","November 2020","",""
|
||||
"`3143 <https://wg21.link/LWG3143>`__","``monotonic_buffer_resource`` growth policy is unclear","November 2020","",""
|
||||
"`3195 <https://wg21.link/LWG3195>`__","What is the stored pointer value of an empty ``weak_ptr``?","November 2020","|Nothing To Do|",""
|
||||
"`3211 <https://wg21.link/LWG3211>`__","``std::tuple<>`` should be trivially constructible","November 2020","|Complete|","9.0"
|
||||
"`3236 <https://wg21.link/LWG3236>`__","Random access iterator requirements lack limiting relational operators domain to comparing those from the same range","November 2020","|Nothing To Do|","","|ranges|"
|
||||
"`3265 <https://wg21.link/LWG3265>`__","``move_iterator``'s conversions are more broken after P1207","November 2020","Fixed by `LWG3435 <https://wg21.link/LWG3435>`__",""
|
||||
"`3435 <https://wg21.link/LWG3435>`__","``three_way_comparable_with<reverse_iterator<int*>, reverse_iterator<const int*>>``","November 2020","|Complete|","13.0"
|
||||
"`3432 <https://wg21.link/LWG3432>`__","Missing requirement for ``comparison_category``","November 2020","","","|spaceship|"
|
||||
"`3447 <https://wg21.link/LWG3447>`__","Deduction guides for ``take_view`` and ``drop_view`` have different constraints","November 2020","|Complete|","14.0"
|
||||
"`3450 <https://wg21.link/LWG3450>`__","The const overloads of ``take_while_view::begin/end`` are underconstrained","November 2020","","","|ranges|"
|
||||
"`3464 <https://wg21.link/LWG3464>`__","``istream::gcount()`` can overflow","November 2020","",""
|
||||
"`2731 <https://wg21.link/LWG2731>`__","Existence of ``lock_guard<MutexTypes...>::mutex_type`` typedef unclear","November 2020","|Complete|","5.0"
|
||||
"`2743 <https://wg21.link/LWG2743>`__","P0083R3 ``node_handle`` private members missing ""exposition only"" comment","November 2020","|Nothing To Do|",""
|
||||
"`2820 <https://wg21.link/LWG2820>`__","Clarify ``<cstdint>`` macros","November 2020","|Nothing To Do|",""
|
||||
"`3120 <https://wg21.link/LWG3120>`__","Unclear behavior of ``monotonic_buffer_resource::release()``","November 2020","",""
|
||||
"`3170 <https://wg21.link/LWG3170>`__","``is_always_equal`` added to ``std::allocator`` makes the standard library treat derived types as always equal","November 2020","",""
|
||||
"`3036 <https://wg21.link/LWG3036>`__","``polymorphic_allocator::destroy`` is extraneous","November 2020","",""
|
||||
"`3171 <https://wg21.link/LWG3171>`__","LWG2989 breaks ``directory_entry`` stream insertion","November 2020","|Complete|","14.0"
|
||||
"`3306 <https://wg21.link/LWG3306>`__","``ranges::advance`` violates its preconditions","November 2020","|Complete|","14.0","|ranges|"
|
||||
"`3403 <https://wg21.link/LWG3403>`__","Domain of ``ranges::ssize(E)`` doesn't ``match ranges::size(E)``","November 2020","","","|ranges|"
|
||||
"`3404 <https://wg21.link/LWG3404>`__","Finish removing subrange's conversions from pair-like","November 2020","","","|ranges|"
|
||||
"`3405 <https://wg21.link/LWG3405>`__","``common_view``'s converting constructor is bad, too","November 2020","|Complete|","14.0","|ranges|"
|
||||
"`3406 <https://wg21.link/LWG3406>`__","``elements_view::begin()`` and ``elements_view::end()`` have incompatible constraints","November 2020","","","|ranges|"
|
||||
"`3419 <https://wg21.link/LWG3419>`__","[algorithms.requirements]/15 doesn't reserve as many rights as it intends to","November 2020","|Nothing To Do|",""
|
||||
"`3420 <https://wg21.link/LWG3420>`__","cpp17-iterator should check that the type looks like an iterator first","November 2020","|Complete|","14.0","|ranges|"
|
||||
"`3421 <https://wg21.link/LWG3421>`__","Imperfect ADL emulation for boolean-testable","November 2020","|Nothing To Do|","","|ranges|"
|
||||
"`3425 <https://wg21.link/LWG3425>`__","``condition_variable_any`` fails to constrain its Lock parameters","November 2020","|Nothing To Do|",""
|
||||
"`3426 <https://wg21.link/LWG3426>`__","``operator<=>(const unique_ptr<T, D>&, nullptr_t)`` can't get no satisfaction","November 2020","","","|spaceship|"
|
||||
"`3427 <https://wg21.link/LWG3427>`__","``operator<=>(const shared_ptr<T>&, nullptr_t)`` definition ill-formed","November 2020","","","|spaceship|"
|
||||
"`3428 <https://wg21.link/LWG3428>`__","``single_view``'s in place constructor should be explicit","November 2020","|Complete|","14.0","|ranges|"
|
||||
"`3434 <https://wg21.link/LWG3434>`__","``ios_base`` never reclaims memory for iarray and parray","November 2020","|Nothing To Do|",""
|
||||
"`3437 <https://wg21.link/LWG3437>`__","``__cpp_lib_polymorphic_allocator`` is in the wrong header","November 2020","|Complete|","14.0"
|
||||
"`3446 <https://wg21.link/LWG3446>`__","``indirectly_readable_traits`` ambiguity for types with both ``value_type`` and ``element_type``","November 2020","|Complete|","14.0","|ranges|"
|
||||
"`3448 <https://wg21.link/LWG3448>`__","``transform_view``'s ``sentinel<false>`` not comparable with ``iterator<true>``","November 2020","","","|ranges|"
|
||||
"`3449 <https://wg21.link/LWG3449>`__","``take_view`` and ``take_while_view``'s ``sentinel<false>`` not comparable with their ``const iterator``","November 2020","","","|ranges|"
|
||||
"`3453 <https://wg21.link/LWG3453>`__","Generic code cannot call ``ranges::advance(i, s)``","November 2020","|Nothing To Do|","","|ranges|"
|
||||
"`3455 <https://wg21.link/LWG3455>`__","Incorrect Postconditions on ``unique_ptr`` move assignment","November 2020","|Nothing To Do|",""
|
||||
"`3460 <https://wg21.link/LWG3460>`__","Unimplementable ``noop_coroutine_handle`` guarantees","November 2020","|Complete|","14.0"
|
||||
"`3461 <https://wg21.link/LWG3461>`__","``convertible_to``'s description mishandles cv-qualified ``void``","November 2020","|Nothing To Do|",""
|
||||
"`3465 <https://wg21.link/LWG3465>`__","``compare_partial_order_fallback`` requires ``F < E``","November 2020","|Complete|","14.0","|spaceship|"
|
||||
"`3466 <https://wg21.link/LWG3466>`__","Specify the requirements for ``promise``/``future``/``shared_future`` consistently","November 2020","|Nothing To Do|",""
|
||||
"`3467 <https://wg21.link/LWG3467>`__","``bool`` can't be an integer-like type","November 2020","|Complete|","14.0"
|
||||
"`3472 <https://wg21.link/LWG3472>`__","``counted_iterator`` is missing preconditions","November 2020","|Complete|","14.0","|ranges|"
|
||||
"`3473 <https://wg21.link/LWG3473>`__","Normative encouragement in non-normative note","November 2020","|Nothing To Do|","","|format|"
|
||||
"`3474 <https://wg21.link/LWG3474>`__","Nesting ``join_views`` is broken because of CTAD","November 2020","","","|ranges|"
|
||||
"`3476 <https://wg21.link/LWG3476>`__","``thread`` and ``jthread`` constructors require that the parameters be move-constructible but never move construct the parameters","November 2020","",""
|
||||
"`3477 <https://wg21.link/LWG3477>`__","Simplify constraints for ``semiregular-box``","November 2020","","","|ranges|"
|
||||
"`3482 <https://wg21.link/LWG3482>`__","``drop_view``'s const begin should additionally require ``sized_range``","November 2020","|Complete|","14.0","|ranges|"
|
||||
"`3483 <https://wg21.link/LWG3483>`__","``transform_view::iterator``'s difference is overconstrained","November 2020","|Complete|","14.0","|ranges|"
|
||||
"","","","",""
|
||||
"`3391 <https://wg21.link/LWG3391>`__","Problems with ``counted_iterator``/``move_iterator::base() const &``","February 2021","","","|ranges|"
|
||||
"`3433 <https://wg21.link/LWG3433>`__","``subrange::advance(n)`` has UB when ``n < 0``","February 2021","|Complete|","14.0","|ranges|"
|
||||
"`3490 <https://wg21.link/LWG3490>`__","``ranges::drop_while_view::begin()`` is missing a precondition","February 2021","|Nothing To Do|","","|ranges|"
|
||||
"`3492 <https://wg21.link/LWG3492>`__","Minimal improvements to ``elements_view::iterator``","February 2021","","","|ranges|"
|
||||
"`3494 <https://wg21.link/LWG3494>`__","Allow ranges to be conditionally borrowed","February 2021","Superseded by `P2017R1 <https://wg21.link/P2017R1>`__","","|ranges|"
|
||||
"`3495 <https://wg21.link/LWG3495>`__","``constexpr launder`` makes pointers to inactive members of unions usable","February 2021","|Nothing To Do|",""
|
||||
"`3500 <https://wg21.link/LWG3500>`__","``join_view::iterator::operator->()`` is bogus","February 2021","","","|ranges|"
|
||||
"`3502 <https://wg21.link/LWG3502>`__","``elements_view`` should not be allowed to return dangling reference","February 2021","","","|ranges|"
|
||||
"`3505 <https://wg21.link/LWG3505>`__","``split_view::outer-iterator::operator++`` misspecified","February 2021","","","|ranges|"
|
||||
"","","","",""
|
||||
`2774 <https://wg21.link/LWG2774>`__,"``std::function`` construction vs assignment","June 2021","",""
|
||||
`2818 <https://wg21.link/LWG2818>`__,"``::std::`` everywhere rule needs tweaking","June 2021","|Nothing To Do|",""
|
||||
`2997 <https://wg21.link/LWG2997>`__,"LWG 491 and the specification of ``{forward_,}list::unique``","June 2021","",""
|
||||
`3410 <https://wg21.link/LWG3410>`__,"``lexicographical_compare_three_way`` is overspecified","June 2021","","","|spaceship|"
|
||||
`3430 <https://wg21.link/LWG3430>`__,"``std::fstream`` & co. should be constructible from string_view","June 2021","",""
|
||||
`3462 <https://wg21.link/LWG3462>`__,"§[formatter.requirements]: Formatter requirements forbid use of ``fc.arg()``","June 2021","","","|format|"
|
||||
`3481 <https://wg21.link/LWG3481>`__,"``viewable_range`` mishandles lvalue move-only views","June 2021","Superseded by `P2415R2 <https://wg21.link/P2415R2>`__","","|ranges|"
|
||||
`3506 <https://wg21.link/LWG3506>`__,"Missing allocator-extended constructors for ``priority_queue``","June 2021","|Complete|","14.0"
|
||||
`3517 <https://wg21.link/LWG3517>`__,"``join_view::iterator``'s ``iter_swap`` is underconstrained","June 2021","","","|ranges|"
|
||||
`3518 <https://wg21.link/LWG3518>`__,"Exception requirements on char trait operations unclear","June 2021","|Nothing To Do|",""
|
||||
`3519 <https://wg21.link/LWG3519>`__,"Incomplete synopses for ``<random>`` classes","June 2021","",""
|
||||
`3520 <https://wg21.link/LWG3520>`__,"``iter_move`` and ``iter_swap`` are inconsistent for ``transform_view::iterator``","June 2021","|Complete|","14.0","|ranges|"
|
||||
`3521 <https://wg21.link/LWG3521>`__,"Overly strict requirements on ``qsort`` and ``bsearch``","June 2021","|Nothing To Do|",""
|
||||
`3522 <https://wg21.link/LWG3522>`__,"Missing requirement on ``InputIterator`` template parameter for ``priority_queue`` constructors","June 2021","|Complete|","14.0","|ranges|"
|
||||
`3523 <https://wg21.link/LWG3523>`__,"``iota_view::sentinel`` is not always ``iota_view``'s sentinel","June 2021","","","|ranges|"
|
||||
`3526 <https://wg21.link/LWG3526>`__,"Return types of ``uses_allocator_construction_args`` unspecified","June 2021","",""
|
||||
`3527 <https://wg21.link/LWG3527>`__,"``uses_allocator_construction_args`` handles rvalue pairs of rvalue references incorrectly","June 2021","",""
|
||||
`3528 <https://wg21.link/LWG3528>`__,"``make_from_tuple`` can perform (the equivalent of) a C-style cast","June 2021","",""
|
||||
`3529 <https://wg21.link/LWG3529>`__,"``priority_queue(first, last)`` should construct ``c`` with ``(first, last)``","June 2021","|Complete|","14.0"
|
||||
`3530 <https://wg21.link/LWG3530>`__,"``BUILTIN-PTR-MEOW`` should not opt the type out of syntactic checks","June 2021","",""
|
||||
`3532 <https://wg21.link/LWG3532>`__,"``split_view<V, P>::inner-iterator<true>::operator++(int)`` should depend on ``Base``","June 2021","","","|ranges|"
|
||||
`3533 <https://wg21.link/LWG3533>`__,"Make ``base() const &`` consistent across iterator wrappers that supports ``input_iterators``","June 2021","|Complete|","14.0","|ranges|"
|
||||
`3536 <https://wg21.link/LWG3536>`__,"Should ``chrono::from_stream()`` assign zero to duration for failure?","June 2021","","","|chrono|"
|
||||
`3539 <https://wg21.link/LWG3539>`__,"``format_to`` must not copy models of ``output_iterator<const charT&>``","June 2021","","","|format|"
|
||||
`3540 <https://wg21.link/LWG3540>`__,"§[format.arg] There should be no const in ``basic_format_arg(const T* p)``","June 2021","|Complete|","14.0","|format|"
|
||||
`3541 <https://wg21.link/LWG3541>`__,"``indirectly_readable_traits`` should be SFINAE-friendly for all types","June 2021","|Complete|","14.0","|ranges|"
|
||||
`3542 <https://wg21.link/LWG3542>`__,"``basic_format_arg`` mishandles ``basic_string_view`` with custom traits","June 2021","|Complete|","14.0","|format|"
|
||||
`3543 <https://wg21.link/LWG3543>`__,"Definition of when ``counted_iterators`` refer to the same sequence isn't quite right","June 2021","|Nothing To Do|","","|ranges|"
|
||||
`3544 <https://wg21.link/LWG3544>`__,"``format-arg-store::args`` is unintentionally not exposition-only","June 2021","|Complete|","14.0","|format|"
|
||||
`3546 <https://wg21.link/LWG3546>`__,"``common_iterator``'s postfix-proxy is not quite right","June 2021","","","|ranges|"
|
||||
`3548 <https://wg21.link/LWG3548>`__,"``shared_ptr`` construction from ``unique_ptr`` should move (not copy) the deleter","June 2021","",""
|
||||
`3549 <https://wg21.link/LWG3549>`__,"``view_interface`` is overspecified to derive from ``view_base``","June 2021","|Complete|","14.0","|ranges|"
|
||||
`3551 <https://wg21.link/LWG3551>`__,"``borrowed_{iterator,subrange}_t`` are overspecified","June 2021","|Nothing To Do|","","|ranges|"
|
||||
`3552 <https://wg21.link/LWG3552>`__,"Parallel specialized memory algorithms should require forward iterators","June 2021","",""
|
||||
`3553 <https://wg21.link/LWG3553>`__,"Useless constraint in ``split_view::outer-iterator::value_type::begin()``","June 2021","","","|ranges|"
|
||||
`3555 <https://wg21.link/LWG3555>`__,"``{transform,elements}_view::iterator::iterator_concept`` should consider const-qualification of the underlying range","June 2021","","","|ranges|"
|
||||
"","","","",""
|
||||
`2191 <https://wg21.link/LWG2191>`__,"Incorrect specification of ``match_results(match_results&&)``","October 2021","|Nothing To Do|",""
|
||||
`2381 <https://wg21.link/LWG2381>`__,"Inconsistency in parsing floating point numbers","October 2021","",""
|
||||
`2762 <https://wg21.link/LWG2762>`__,"``unique_ptr operator*()`` should be ``noexcept``","October 2021","",""
|
||||
`3121 <https://wg21.link/LWG3121>`__,"``tuple`` constructor constraints for ``UTypes&&...`` overloads","October 2021","",""
|
||||
`3123 <https://wg21.link/LWG3123>`__,"``duration`` constructor from representation shouldn't be effectively non-throwing","October 2021","","","|chrono|"
|
||||
`3146 <https://wg21.link/LWG3146>`__,"Excessive unwrapping in ``std::ref/cref``","October 2021","|Complete|","14.0"
|
||||
`3152 <https://wg21.link/LWG3152>`__,"``common_type`` and ``common_reference`` have flaws in common","October 2021","",""
|
||||
`3293 <https://wg21.link/LWG3293>`__,"``move_iterator operator+()`` has incorrect constraints","October 2021","","","|ranges|"
|
||||
`3361 <https://wg21.link/LWG3361>`__,"``safe_range<SomeRange&>`` case","October 2021","|Nothing To Do|","","|ranges|"
|
||||
`3392 <https://wg21.link/LWG3392>`__,"``ranges::distance()`` cannot be used on a move-only iterator with a sized sentinel","October 2021","|Complete|","14.0","|ranges|"
|
||||
`3407 <https://wg21.link/LWG3407>`__,"Some problems with the wording changes of P1739R4","October 2021","","","|ranges|"
|
||||
`3422 <https://wg21.link/LWG3422>`__,"Issues of ``seed_seq``'s constructors","October 2021","|Complete|","14.0"
|
||||
`3470 <https://wg21.link/LWG3470>`__,"``convertible-to-non-slicing`` seems to reject valid case","October 2021","|Complete|","14.0","|ranges|"
|
||||
`3480 <https://wg21.link/LWG3480>`__,"``directory_iterator`` and ``recursive_directory_iterator`` are not C++20 ranges","October 2021","|Complete|","14.0","|ranges|"
|
||||
`3498 <https://wg21.link/LWG3498>`__,"Inconsistent ``noexcept``-specifiers for ``basic_syncbuf``","October 2021","",""
|
||||
`3535 <https://wg21.link/LWG3535>`__,"``join_view::iterator::iterator_category`` and ``::iterator_concept`` lie","October 2021","","","|ranges|"
|
||||
`3554 <https://wg21.link/LWG3554>`__,"``chrono::parse`` needs ``const charT*`` and ``basic_string_view<charT>`` overloads","October 2021","","","|chrono|"
|
||||
`3557 <https://wg21.link/LWG3557>`__,"The ``static_cast`` expression in ``convertible_to`` has the wrong operand","October 2021","|Complete|","14.0"
|
||||
`3559 <https://wg21.link/LWG3559>`__,"Semantic requirements of ``sized_range`` is circular","October 2021","|Nothing To Do|","","|ranges|"
|
||||
`3560 <https://wg21.link/LWG3560>`__,"``ranges::equal`` and ``ranges::is_permutation`` should short-circuit for ``sized_ranges``","October 2021","","","|ranges|"
|
||||
`3561 <https://wg21.link/LWG3561>`__,"Issue with internal counter in ``discard_block_engine``","October 2021","",""
|
||||
`3563 <https://wg21.link/LWG3563>`__,"``keys_view`` example is broken","October 2021","","","|ranges|"
|
||||
`3566 <https://wg21.link/LWG3566>`__,"Constraint recursion for ``operator<=>(optional<T>, U)``","October 2021","","","|spaceship|"
|
||||
`3567 <https://wg21.link/LWG3567>`__,"Formatting move-only iterators take two","October 2021","","","|format|"
|
||||
`3568 <https://wg21.link/LWG3568>`__,"``basic_istream_view`` needs to initialize ``value_``","October 2021","","","|ranges|"
|
||||
`3570 <https://wg21.link/LWG3570>`__,"``basic_osyncstream::emit`` should be an unformatted output function","October 2021","",""
|
||||
`3571 <https://wg21.link/LWG3571>`__,"``flush_emit`` should set ``badbit`` if the ``emit`` call fails","October 2021","",""
|
||||
`3572 <https://wg21.link/LWG3572>`__,"``copyable-box`` should be fully ``constexpr``","October 2021","|Complete|","14.0","|ranges|"
|
||||
`3573 <https://wg21.link/LWG3573>`__,"Missing Throws element for ``basic_string_view(It begin, End end)``","October 2021","|Complete|","14.0"
|
||||
`3574 <https://wg21.link/LWG3574>`__,"``common_iterator`` should be completely ``constexpr``-able","October 2021","|Complete|","14.0","|ranges|"
|
||||
`3580 <https://wg21.link/LWG3580>`__,"``iota_view``'s ``iterator``'s binary ``operator+`` should be improved","October 2021","|Complete|","14.0","|ranges|"
|
||||
`3581 <https://wg21.link/LWG3581>`__,"The range constructor makes ``basic_string_view`` not trivially move constructible","October 2021","|Complete|","14.0","|ranges|"
|
||||
`3585 <https://wg21.link/LWG3585>`__,"``variant`` converting assignment with immovable alternative","October 2021","",""
|
||||
`3589 <https://wg21.link/LWG3589>`__,"The ``const`` lvalue reference overload of ``get`` for ``subrange`` does not constrain ``I`` to be ``copyable`` when ``N == 0``","October 2021","|Complete|","14.0","|ranges|"
|
||||
`3590 <https://wg21.link/LWG3590>`__,"``split_view::base() const &`` is overconstrained","October 2021","","","|ranges|"
|
||||
`3591 <https://wg21.link/LWG3591>`__,"``lazy_split_view<input_view>::inner-iterator::base() &&`` invalidates outer iterators","October 2021","","","|ranges|"
|
||||
`3592 <https://wg21.link/LWG3592>`__,"``lazy_split_view`` needs to check the simpleness of Pattern","October 2021","","","|ranges|"
|
||||
`3593 <https://wg21.link/LWG3593>`__,"Several iterators' ``base() const &`` and ``lazy_split_view::outer-iterator::value_type::end()`` missing ``noexcept``","October 2021","","","|ranges|"
|
||||
`3595 <https://wg21.link/LWG3595>`__,"Exposition-only classes proxy and postfix-proxy for ``common_iterator`` should be fully ``constexpr``","October 2021","|Complete|","14.0","|ranges|"
|
||||
"","","","",""
|
||||
`3645 <https://wg21.link/LWG3645>`__,"``resize_and_overwrite`` is overspecified to call its callback with lvalues", "Not voted in","|Complete|","14.0",""
|
||||
"","","","",""
|
Can't render this file because it has a wrong number of fields in line 2.
|
40
docs/Status/Cxx2bPapers.csv
Normal file
40
docs/Status/Cxx2bPapers.csv
Normal file
@ -0,0 +1,40 @@
|
||||
"Paper #","Group","Paper Name","Meeting","Status","First released version"
|
||||
"`P0881R7 <https://wg21.link/P0881R7>`__","LWG","A Proposal to add stacktrace library","Autumn 2020","",""
|
||||
"`P0943R6 <https://wg21.link/P0943R6>`__","LWG","Support C atomics in C++","Autumn 2020","",""
|
||||
"`P1048R1 <https://wg21.link/P1048R1>`__","LWG","A proposal for a type trait to detect scoped enumerations","Autumn 2020","|Complete|","12.0"
|
||||
"`P1679R3 <https://wg21.link/P1679R3>`__","LWG","string contains function","Autumn 2020","|Complete|","12.0"
|
||||
"","","","","",""
|
||||
"`P1682R3 <https://wg21.link/P1682R3>`__","LWG","std::to_underlying for enumerations","February 2021","|Complete|","13.0"
|
||||
"`P2017R1 <https://wg21.link/P2017R1>`__","LWG","Conditionally borrowed ranges","February 2021","",""
|
||||
"`P2160R1 <https://wg21.link/P2160R1>`__","LWG","Locks lock lockables","February 2021","",""
|
||||
"`P2162R2 <https://wg21.link/P2162R2>`__","LWG","Inheriting from std::variant","February 2021","|Complete|","13.0"
|
||||
"`P2212R2 <https://wg21.link/P2212R2>`__","LWG","Relax Requirements for time_point::clock","February 2021","",""
|
||||
"`P2259R1 <https://wg21.link/P2259R1>`__","LWG","Repairing input range adaptors and counted_iterator","February 2021","",""
|
||||
"","","","","",""
|
||||
"`P0401R6 <https://wg21.link/P0401R6>`__","LWG","Providing size feedback in the Allocator interface","June 2021","",
|
||||
"`P0448R4 <https://wg21.link/P0448R4>`__","LWG","A strstream replacement using span<charT> as buffer","June 2021","",""
|
||||
"`P1132R8 <https://wg21.link/P1132R8>`__","LWG","out_ptr - a scalable output pointer abstraction","June 2021","",""
|
||||
"`P1328R1 <https://wg21.link/P1328R1>`__","LWG","Making std::type_info::operator== constexpr","June 2021","",""
|
||||
"`P1425R4 <https://wg21.link/P1425R4>`__","LWG","Iterators pair constructors for stack and queue","June 2021","|Complete|","14.0"
|
||||
"`P1518R2 <https://wg21.link/P1518R2>`__","LWG","Stop overconstraining allocators in container deduction guides","June 2021","|Complete|","13.0"
|
||||
"`P1659R3 <https://wg21.link/P1659R3>`__","LWG","starts_with and ends_with","June 2021","",""
|
||||
"`P1951R1 <https://wg21.link/P1951R1>`__","LWG","Default Arguments for pair Forwarding Constructor","June 2021","|Complete|","14.0"
|
||||
"`P1989R2 <https://wg21.link/P1989R2>`__","LWG","Range constructor for std::string_view","June 2021","|Complete|","14.0"
|
||||
"`P2136R3 <https://wg21.link/P2136R3>`__","LWG","invoke_r","June 2021","",""
|
||||
"`P2166R1 <https://wg21.link/P2166R1>`__","LWG","A Proposal to Prohibit std::basic_string and std::basic_string_view construction from nullptr","June 2021","|Complete|","13.0"
|
||||
"","","","","",""
|
||||
"`P0288R9 <https://wg21.link/P0288R9>`__","LWG","``any_invocable``","October 2021","",""
|
||||
"`P0798R8 <https://wg21.link/P0798R8>`__","LWG","Monadic operations for ``std::optional``","October 2021","|Complete|","14.0"
|
||||
"`P0849R8 <https://wg21.link/P0849R8>`__","LWG","``auto(x)``: ``DECAY_COPY`` in the language","October 2021","|Complete|","14.0"
|
||||
"`P1072R10 <https://wg21.link/P1072R10>`__","LWG","``basic_string::resize_and_overwrite``","October 2021","|Complete|","14.0"
|
||||
"`P1147R1 <https://wg21.link/P1147R1>`__","LWG","Printing ``volatile`` Pointers","October 2021","|Complete|","14.0"
|
||||
"`P1272R4 <https://wg21.link/P1272R4>`__","LWG","Byteswapping for fun&&nuf","October 2021","|Complete|","14.0"
|
||||
"`P1675R2 <https://wg21.link/P1675R2>`__","LWG","``rethrow_exception`` must be allowed to copy","October 2021","",""
|
||||
"`P2077R3 <https://wg21.link/P2077R3>`__","LWG","Heterogeneous erasure overloads for associative containers","October 2021","",""
|
||||
"`P2251R1 <https://wg21.link/P2251R1>`__","LWG","Require ``span`` & ``basic_string_view`` to be Trivially Copyable","October 2021","|Complete|","14.0"
|
||||
"`P2301R1 <https://wg21.link/P2301R1>`__","LWG","Add a ``pmr`` alias for ``std::stacktrace``","October 2021","",""
|
||||
"`P2321R2 <https://wg21.link/P2321R2>`__","LWG","``zip``","October 2021","|In Progress|",""
|
||||
"`P2340R1 <https://wg21.link/P2340R1>`__","LWG","Clarifying the status of the 'C headers'","October 2021","",""
|
||||
"`P2393R1 <https://wg21.link/P2393R1>`__","LWG","Cleaning up ``integer``-class types","October 2021","",""
|
||||
"`P2401R0 <https://wg21.link/P2401R0>`__","LWG","Add a conditional ``noexcept`` specification to ``std::exchange``","October 2021","|Complete|","14.0"
|
||||
"","","","","",""
|
|
49
docs/Status/Format.rst
Normal file
49
docs/Status/Format.rst
Normal file
@ -0,0 +1,49 @@
|
||||
.. format-status:
|
||||
|
||||
================================
|
||||
libc++ Format Status
|
||||
================================
|
||||
|
||||
.. include:: ../Helpers/Styles.rst
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
This document contains the status of the C++20 Format library in libc++. It is used to
|
||||
track both the status of the sub-projects of the Format library and who is assigned to
|
||||
these sub-projects. This is imperative to effective implementation so that work is not
|
||||
duplicated and implementors are not blocked by each other.
|
||||
|
||||
|
||||
If you are interested in contributing to the libc++ Format library, please send
|
||||
a message to the #libcxx channel in the LLVM discord. Please *do not* start
|
||||
working on any of the assigned items below.
|
||||
|
||||
|
||||
Sub-Projects in the Format library
|
||||
==================================
|
||||
|
||||
.. csv-table::
|
||||
:file: FormatPaper.csv
|
||||
:header-rows: 1
|
||||
:widths: auto
|
||||
|
||||
|
||||
Misc. Items and TODOs
|
||||
=====================
|
||||
|
||||
(Please mark all Format-related TODO comments with the string ``TODO FMT``, so we
|
||||
can find them easily.)
|
||||
|
||||
|
||||
Paper and Issue Status
|
||||
======================
|
||||
|
||||
.. csv-table::
|
||||
:file: FormatIssues.csv
|
||||
:header-rows: 1
|
||||
:widths: auto
|
10
docs/Status/FormatIssues.csv
Normal file
10
docs/Status/FormatIssues.csv
Normal file
@ -0,0 +1,10 @@
|
||||
Number,Name,Assignee,Patch,Status,First released version
|
||||
`P0645 <https://wg21.link/P0645>`_,"Text Formatting",Mark de Wever,,|Complete|,Clang 14
|
||||
`P1652 <https://wg21.link/P1652>`_,"Printf corner cases in std::format",Mark de Wever,"`D103433 <https://reviews.llvm.org/D103433>`__, `D114001 <https://reviews.llvm.org/D114001>`__",|Complete|,Clang 14
|
||||
`P1892 <https://wg21.link/P1892>`_,"Extended locale-specific presentation specifiers for std::format",Mark de Wever,`D103368 <https://reviews.llvm.org/D103368>`__,|Complete|,Clang 14
|
||||
`P1868 <https://wg21.link/P1868>`_,"width: clarifying units of width and precision in std::format (Implements the unicode support.)",Mark de Wever,"`D103413 <https://reviews.llvm.org/D103413>`__ `D103425 <https://reviews.llvm.org/D103425>`__ `D103670 <https://reviews.llvm.org/D103670>`__",|Complete|,Clang 14
|
||||
`P2216 <https://wg21.link/P2216>`_,"std::format improvements",Mark de Wever,,|In Progress|,
|
||||
`P2418 <https://wg21.link/P2418>`__,"Add support for ``std::generator``-like types to ``std::format``",Mark de Wever,,|In Progress|,
|
||||
|
||||
`P1361 <https://wg21.link/P1361>`_,"Integration of chrono with text formatting",,,|Not Started|,
|
||||
`P2372 <https://wg21.link/P2372>`__,"Fixing locale handling in chrono formatters",,,|Not Started|,
|
|
49
docs/Status/FormatPaper.csv
Normal file
49
docs/Status/FormatPaper.csv
Normal file
@ -0,0 +1,49 @@
|
||||
Section,Description,Dependencies,Assignee,Patch,Status,First released version
|
||||
`[charconv.to.chars] <https://wg21.link/charconv.to.chars>`_,"Fix integral conformance",,Mark de Wever,`D100722 <https://llvm.org/D100722>`__,|Complete|,Clang 13
|
||||
`[charconv.to.chars] <https://wg21.link/charconv.to.chars>`_,"Add floating-point conversion",`D100722 <https://llvm.org/D100722>`__,"Mark de Wever (Code provided by Stephan T. Lavavej of Microsoft)",`D70631 <https://llvm.org/D70631>`__,|Complete|,Clang 14
|
||||
`[format.error] <https://wg21.link/format.error>`_,"Class format_error",,Mark de Wever,`D92214 <https://llvm.org/D92214>`__,|Complete|,Clang 13
|
||||
`[format.parse.ctx] <https://wg21.link/format.parse.ctx>`_,"Class template basic_format_parse_context",,Mark de Wever,`D93166 <https://llvm.org/D93166>`__,|Complete|,Clang 13
|
||||
`[format.context] <https://wg21.link/format.context>`_,"Class template basic_format_context",,Mark de Wever,`D103357 <https://llvm.org/D103357>`__,|Complete|,Clang 14
|
||||
`[format.args] <https://wg21.link/format.args>`_,"Class template basic_format_args",,Mark de Wever,`D103357 <https://llvm.org/D103357>`__,|Complete|,Clang 14
|
||||
`[format.arg] <https://wg21.link/format.arg>`_,"Class template basic_format_arg",,Mark de Wever,`D103357 <https://llvm.org/D103357>`__,|Complete|,Clang 14
|
||||
`[format.arg] <https://wg21.link/format.arg>`_,"Class template basic_format_arg - handle",,Mark de Wever,,|Complete|,Clang 14
|
||||
`[format.arg] <https://wg21.link/format.arg>`_,"Class template basic_format_arg - pointers",,Mark de Wever,,|Complete|,Clang 14
|
||||
`[format.arg.store] <https://wg21.link/format.arg.store>`_,"Class template format-arg-store",,Mark de Wever,`D103357 <https://llvm.org/D103357>`__,|Complete|,Clang 14
|
||||
`[format.formatter.spec] <https://wg21.link/format.formatter.spec>`_,"Formatter specializations - character types",,Mark de Wever,"`D96664 <https://llvm.org/D96664>`__ `D103466 <https://llvm.org/D103466>`__",|Complete|,Clang 14
|
||||
`[format.formatter.spec] <https://wg21.link/format.formatter.spec>`_,"Formatter specializations - string types",,Mark de Wever,"`D96664 <https://llvm.org/D96664>`__ `D103425 <https://reviews.llvm.org/D103425>`__",|Complete|,Clang 14
|
||||
`[format.formatter.spec] <https://wg21.link/format.formatter.spec>`_,"Formatter specializations - boolean type",,Mark de Wever,"`D96664 <https://llvm.org/D96664>`__ `D103670 <https://reviews.llvm.org/D103670>`__",|Complete|,Clang 14
|
||||
`[format.formatter.spec] <https://wg21.link/format.formatter.spec>`_,"Formatter specializations - integral types",,Mark de Wever,"`D96664 <https://llvm.org/D96664>`__ `D103433 <https://reviews.llvm.org/D103433>`__",|Complete|,Clang 14
|
||||
`[format.formatter.spec] <https://wg21.link/format.formatter.spec>`_,"Formatter specializations - floating-point types",`D70631 <https://llvm.org/D70631>`__,Mark de Wever,`D114001 <https://reviews.llvm.org/D114001>`__,|Complete|,Clang 14
|
||||
`[format.formatter.spec] <https://wg21.link/format.formatter.spec>`_,"Formatter specializations - pointer types",,Mark de Wever,,|Complete|,Clang 14
|
||||
`[format.string.std] <https://wg21.link/format.string.std>`_,"Standard format specifiers - character types",,Mark de Wever,`D103368 <https://reviews.llvm.org/D103368>`__,|Complete|,Clang 14
|
||||
`[format.string.std] <https://wg21.link/format.string.std>`_,"Standard format specifiers - string types",`D103379 <https://reviews.llvm.org/D103379>`__,Mark de Wever,"`D103368 <https://reviews.llvm.org/D103368>`__ `D103413 <https://reviews.llvm.org/D103413>`__",|Complete|,Clang 14
|
||||
`[format.string.std] <https://wg21.link/format.string.std>`_,"Standard format specifiers - boolean type",`D103379 <https://reviews.llvm.org/D103379>`__,Mark de Wever,"`D103368 <https://reviews.llvm.org/D103368>`__ `D103413 <https://reviews.llvm.org/D103413>`__",|Complete|,Clang 14
|
||||
`[format.string.std] <https://wg21.link/format.string.std>`_,"Standard format specifiers - integral types",,Mark de Wever,`D103368 <https://reviews.llvm.org/D103368>`__,|Complete|,Clang 14
|
||||
`[format.string.std] <https://wg21.link/format.string.std>`_,"Standard format specifiers - floating-point types",,Mark de Wever,`D114001 <https://reviews.llvm.org/D114001>`__,|Complete|,Clang 14
|
||||
`[format.string.std] <https://wg21.link/format.string.std>`_,"Standard format specifiers - pointer types",,Mark de Wever,,|Complete|,Clang 14
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"Format functions - format(string_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,|Complete|,Clang 14
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"Format functions - format(wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,|Complete|,Clang 14
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"Format functions - format(const locale& loc, string_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,|Complete|,Clang 14
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"Format functions - format(const locale& loc, wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,|Complete|,Clang 14
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"Format functions - vformat(string_view fmt, format_args args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,|Complete|,Clang 14
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"Format functions - vformat(wstring_view fmt, wformat_args args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,|Complete|,Clang 14
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"Format functions - vformat(const locale& loc, string_view fmt, format_args args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,|Complete|,Clang 14
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"Format functions - vformat(const locale& loc, wstring_view fmt, wformat_args args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,|Complete|,Clang 14
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"Format functions - format_to(Out out, wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,|Complete|,Clang 14
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"Format functions - format_to(Out out, const locale& loc, wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,|Complete|,Clang 14
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"Format functions - vformat_to(Out out, string_view fmt, format_args_t<type_identity_t<Out>, char> args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,|Complete|,Clang 14
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"Format functions - vformat_to(Out out, wstring_view fmt, format_args_t<type_identity_t<Out>, char> args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,|Complete|,Clang 14
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"Format functions - vformat_to(Out out, const locale& loc, string_view fmt, format_args_t<type_identity_t<Out>, char> args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,|Complete|,Clang 14
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"Format functions - vformat_to(Out out, const locale& loc, wstring_view fmt,format_args_t<type_identity_t<Out>, wchar_t> args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,|Complete|,Clang 14
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"Format functions - format_to_n(Out out, iter_difference_t<Out> n, string_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,|Complete|,Clang 14
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"Format functions - format_to_n(Out out, iter_difference_t<Out> n, wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,|Complete|,Clang 14
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"Format functions - format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, const locale& loc, string_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,|Complete|,Clang 14
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"Format functions - format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, const locale& loc, wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,|Complete|,Clang 14
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"Format functions - formatted_size(string_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,|Complete|,Clang 14
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"Format functions - formatted_size(wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,|Complete|,Clang 14
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"Format functions - formatted_size(const locale& loc, string_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,|Complete|,Clang 14
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"Format functions - formatted_size(const locale& loc, wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,|Complete|,Clang 14
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"Format functions - Improve performance format_to_n",,Mark de Wever,`D110499 <https://llvm.org/D110499>`__,|Review|,
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"Format functions - Improve performance formatted size",,Mark de Wever,`D110500 <https://llvm.org/D110500>`__,|Review|,
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"`P2216 <https://wg21.link/P2216>`_ - Compile-time checks",,Mark de Wever,,|In Progress|,
|
||||
`[format.functions] <https://wg21.link/format.functions>`_,"`P2216 <https://wg21.link/P2216>`_ - Binary size",,Mark de Wever,`D110494 <https://llvm.org/D110494>`__,|Complete|,Clang 14
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user