diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index aa851fd..6680155 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -2,6 +2,6 @@
-
+
\ No newline at end of file
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index c633c66..0cbf0a3 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -8,31 +8,18 @@ android {
ndkVersion = "26.1.10909125"
buildToolsVersion = "34.0.0"
- packaging {
- jniLibs {
- excludes += "**/liblog.so"
- excludes += "**/libdobby.so"
- }
- }
-
defaultConfig {
applicationId = "es.chiteroman.playintegrityfix"
minSdk = 26
targetSdk = 34
- versionCode = 15200
- versionName = "v15.2"
+ versionCode = 15300
+ versionName = "v15.3"
externalNativeBuild {
- cmake {
- arguments += "-DANDROID_STL=none"
- arguments += "-DCMAKE_BUILD_TYPE=MinSizeRel"
- arguments += "-DPlugin.Android.BionicLinkerUtil=ON"
-
- cppFlags += "-std=c++20"
- cppFlags += "-fno-exceptions"
- cppFlags += "-fno-rtti"
- cppFlags += "-fvisibility=hidden"
- cppFlags += "-fvisibility-inlines-hidden"
+ ndk {
+ abiFilters += "arm64-v8a"
+ abiFilters += "armeabi-v7a"
+ jobs = Runtime.getRuntime().availableProcessors()
}
}
}
@@ -53,9 +40,8 @@ android {
}
externalNativeBuild {
- cmake {
- path = file("src/main/cpp/CMakeLists.txt")
- version = "3.22.1"
+ ndkBuild {
+ path = file("src/main/cpp/Android.mk")
}
}
}
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index e6b9f2d..c65bd56 100644
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -1,2 +1,3 @@
-keep class es.chiteroman.playintegrityfix.EntryPoint {public ;}
--keep class es.chiteroman.playintegrityfix.CustomProvider
\ No newline at end of file
+-keep class es.chiteroman.playintegrityfix.CustomProvider
+-keep class es.chiteroman.playintegrityfix.CustomKeyStoreSpi
\ No newline at end of file
diff --git a/app/src/main/cpp/Android.mk b/app/src/main/cpp/Android.mk
new file mode 100644
index 0000000..dbcf9d4
--- /dev/null
+++ b/app/src/main/cpp/Android.mk
@@ -0,0 +1,31 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := zygisk
+LOCAL_SRC_FILES := $(LOCAL_PATH)/main.cpp
+LOCAL_C_INCLUDES := $(LOCAL_PATH)
+
+LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/shadowhook/*.c)
+LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/shadowhook/common/*.c)
+LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/shadowhook/third_party/xdl/*.c)
+
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/shadowhook
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/shadowhook/common
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/shadowhook/include
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/shadowhook/third_party/bsd
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/shadowhook/third_party/lss
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/shadowhook/third_party/xdl
+
+ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
+ LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/shadowhook/arch/arm/*.c)
+ LOCAL_C_INCLUDES += $(LOCAL_PATH)/shadowhook/arch/arm
+else ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
+ LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/shadowhook/arch/arm64/*.c)
+ LOCAL_C_INCLUDES += $(LOCAL_PATH)/shadowhook/arch/arm64
+endif
+
+LOCAL_STATIC_LIBRARIES := libcxx
+LOCAL_LDLIBS := -llog
+include $(BUILD_SHARED_LIBRARY)
+
+include $(LOCAL_PATH)/libcxx/Android.mk
\ No newline at end of file
diff --git a/app/src/main/cpp/Application.mk b/app/src/main/cpp/Application.mk
new file mode 100644
index 0000000..b054338
--- /dev/null
+++ b/app/src/main/cpp/Application.mk
@@ -0,0 +1,5 @@
+APP_STL := none
+APP_ABI := arm64-v8a armeabi-v7a
+APP_CFLAGS := -Oz -flto -fvisibility=hidden -fvisibility-inlines-hidden
+APP_CPPFLAGS := -std=c++20 -fno-exceptions -fno-rtti
+APP_LDFLAGS := -Oz -flto
\ No newline at end of file
diff --git a/app/src/main/cpp/CMakeLists.txt b/app/src/main/cpp/CMakeLists.txt
deleted file mode 100644
index e0525a2..0000000
--- a/app/src/main/cpp/CMakeLists.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-cmake_minimum_required(VERSION 3.22.1)
-
-project("playintegrityfix")
-
-include_directories(${CMAKE_SOURCE_DIR}/libcxx/include)
-
-link_libraries(${CMAKE_SOURCE_DIR}/libcxx/${CMAKE_ANDROID_ARCH_ABI}/libcxx.a)
-
-add_library(${CMAKE_PROJECT_NAME} SHARED
- main.cpp)
-
-if (NOT TARGET dobby)
- set(DOBBY_DIR ${CMAKE_SOURCE_DIR}/Dobby)
- macro(SET_OPTION option value)
- set(${option} ${value} CACHE INTERNAL "" FORCE)
- endmacro()
- SET_OPTION(DOBBY_DEBUG OFF)
- SET_OPTION(DOBBY_GENERATE_SHARED OFF)
- SET_OPTION(Plugin.Android.BionicLinkerUtil ON)
- add_subdirectory(${DOBBY_DIR} dobby)
- get_property(DOBBY_INCLUDE_DIRECTORIES
- TARGET dobby
- PROPERTY INCLUDE_DIRECTORIES)
- include_directories(
- .
- ${DOBBY_INCLUDE_DIRECTORIES}
- $
- )
-endif ()
-
-target_link_libraries(${CMAKE_PROJECT_NAME}
- log
- dobby)
\ No newline at end of file
diff --git a/app/src/main/cpp/Dobby b/app/src/main/cpp/Dobby
deleted file mode 160000
index 6813ca7..0000000
--- a/app/src/main/cpp/Dobby
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 6813ca76ddeafcaece525bf8c6cde7ff4c21d3ce
diff --git a/app/src/main/cpp/libcxx/.clang-format b/app/src/main/cpp/libcxx/.clang-format
new file mode 100644
index 0000000..77ffa23
--- /dev/null
+++ b/app/src/main/cpp/libcxx/.clang-format
@@ -0,0 +1,88 @@
+BasedOnStyle: LLVM
+
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: Consecutive
+AlignConsecutiveBitFields: Consecutive
+AlignEscapedNewlines: Right
+AlignOperands: AlignAfterOperator
+AlignTrailingComments: true
+AllowAllArgumentsOnNextLine: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortFunctionsOnASingleLine: true
+AllowShortLambdasOnASingleLine: All
+AttributeMacros: ['_LIBCPP_HIDE_FROM_ABI',
+ '_LIBCPP_CONSTEXPR',
+ '_LIBCPP_CONSTEXPR_SINCE_CXX14',
+ '_LIBCPP_CONSTEXPR_SINCE_CXX17',
+ '_LIBCPP_CONSTEXPR_SINCE_CXX20',
+ '_LIBCPP_CONSTEXPR_SINCE_CXX23',
+ '_LIBCPP_ALIGNOF',
+ '_ALIGNAS_TYPE',
+ '_ALIGNAS',
+ '_LIBCPP_NORETURN',
+ '_LIBCPP_ALWAYS_INLINE',
+ '_LIBCPP_DISABLE_EXTENTSION_WARNING',
+ '_LIBCPP_HIDDEN',
+ '_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS',
+ '_LIBCPP_FUNC_VIS',
+ '_LIBCPP_TYPE_VIS',
+ '_LIBCPP_TEMPLATE_VIS',
+ '_LIBCPP_TEMPLATE_DATA_VIS',
+ '_LIBCPP_EXPORTED_FROM_ABI',
+ '_LIBCPP_OVERRIDABLE_FUNC_VIS',
+ '_LIBCPP_EXCEPTION_ABI',
+ '_LIBCPP_ENUM_VIS',
+ '_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS',
+ '_LIBCPP_INTERNAL_LINKAGE',
+ '_LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION',
+ '_LIBCPP_HIDE_FROM_ABI_AFTER_V1',
+ '_LIBCPP_INLINE_VISIBILITY',
+ '_LIBCPP_CONSTEVAL',
+ '_LIBCPP_NOALIAS',
+ '_LIBCPP_USING_IF_EXISTS',
+ '_LIBCPP_DEPRECATED',
+ '_LIBCPP_DEPRECATED_IN_CXX11',
+ '_LIBCPP_DEPRECATED_IN_CXX14',
+ '_LIBCPP_DEPRECATED_IN_CXX17',
+ '_LIBCPP_DEPRECATED_IN_CXX20',
+ '_LIBCPP_NODISCARD',
+ '_LIBCPP_NODISCARD_EXT',
+ '_LIBCPP_NO_DESTROY',
+ '_LIBCPP_WEAK',
+ '_LIBCPP_CONSTINIT',
+ '_LIBCPP_FALLTHROUGH',
+ '_LIBCPP_STANDALONE_DEBUG',
+ '_LIBCPP_NO_UNIQUE_ADDRESS',
+ ]
+BinPackArguments: false
+BinPackParameters: false
+BreakBeforeConceptDeclarations: true
+BreakInheritanceList: BeforeColon
+EmptyLineAfterAccessModifier: Never
+EmptyLineBeforeAccessModifier: Always
+IndentWrappedFunctionNames: false
+IndentRequires: true
+InsertTrailingCommas: Wrapped
+KeepEmptyLinesAtTheStartOfBlocks: false
+MaxEmptyLinesToKeep: 1
+PackConstructorInitializers: NextLine
+
+PenaltyIndentedWhitespace: 2
+
+Language: Cpp
+Standard: c++20
+SpacesInAngles: Leave
+
+AlwaysBreakTemplateDeclarations: true
+PointerAlignment: Left
+
+
+# Disable formatting options which may break tests.
+SortIncludes: false
+ReflowComments: false
+
+# libc++'s preferred indentions of preprocessor statements.
+IndentPPDirectives: AfterHash
+
+# libc++ has some long names so we need more than the 80 column limit imposed by LLVM style, for sensible formatting
+ColumnLimit: 120
diff --git a/app/src/main/cpp/libcxx/.clang-tidy b/app/src/main/cpp/libcxx/.clang-tidy
new file mode 100644
index 0000000..4bc25c3
--- /dev/null
+++ b/app/src/main/cpp/libcxx/.clang-tidy
@@ -0,0 +1,67 @@
+Checks: >
+ bugprone-copy-constructor-init,
+ bugprone-dangling-handle,
+ bugprone-infinite-loop,
+ bugprone-stringview-nullptr,
+ bugprone-use-after-move,
+
+ llvm-include-order,
+ llvm-namespace-comment,
+
+ misc-definitions-in-headers,
+ misc-misplaced-const,
+ misc-non-copyable-objects,
+ misc-uniqueptr-reset-release,
+
+ modernize-loop-convert,
+ modernize-redundant-void-arg,
+ modernize-use-override,
+
+ readability-duplicate-include,
+ readability-identifier-naming,
+ readability-function-cognitive-complexity,
+ readability-function-size,
+ readability-misplaced-array-index,
+ readability-redundant-control-flow,
+ readability-redundant-function-ptr-dereference,
+ readability-redundant-preprocessor,
+ readability-simplify-boolean-expr,
+ readability-simplify-subscript-expr,
+ readability-uniqueptr-delete-release,
+
+CheckOptions:
+ - key: readability-function-cognitive-complexity.Threshold
+ value: 143 # TODO: bring that number down
+ - key: readability-function-size.LineThreshold
+ value: 194 # TODO: bring that number down
+ - key: readability-identifier-naming.GetConfigPerFile
+ value: false
+ - key: readability-identifier-naming.ParameterCase
+ value: lower_case
+ - key: readability-identifier-naming.ParameterPrefix
+ value: __
+ - key: readability-identifier-naming.PrivateMemberCase
+ value: lower_case
+ - key: readability-identifier-naming.PrivateMemberPrefix
+ value: __
+ - key: readability-identifier-naming.PrivateMemberSuffix
+ value: _
+
+# TODO: investigate these checks
+# bugprone-branch-clone,
+# bugprone-macro-parentheses,
+# cppcoreguidelines-prefer-member-initializer,
+# misc-unused-parameters,
+# modernize-use-bool-literals,
+# modernize-use-default-member-init,
+# modernize-use-equals-default,
+# modernize-use-equals-delete,
+# modernize-use-nullptr,
+# portability-restrict-system-includes,
+# readability-function-cognitive-complexity,
+# readability-implicit-bool-conversion,
+# readability-isolate-declaration,
+# readability-redundant-access-specifiers,
+# readability-redundant-declaration,
+# readability-redundant-member-init,
+#
diff --git a/app/src/main/cpp/libcxx/.gitignore b/app/src/main/cpp/libcxx/.gitignore
new file mode 100644
index 0000000..4b214ca
--- /dev/null
+++ b/app/src/main/cpp/libcxx/.gitignore
@@ -0,0 +1,55 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+env/
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+#lib/ # We actually have things checked in to lib/
+lib64/
+parts/
+sdist/
+var/
+*.egg-info/
+.installed.cfg
+*.egg
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.coverage
+.cache
+nosetests.xml
+coverage.xml
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+# MSVC libraries test harness
+env.lst
+keep.lst
+
+# Editor by-products
+.vscode/
diff --git a/app/src/main/cpp/libcxx/Android.mk b/app/src/main/cpp/libcxx/Android.mk
new file mode 100644
index 0000000..55b8705
--- /dev/null
+++ b/app/src/main/cpp/libcxx/Android.mk
@@ -0,0 +1,114 @@
+# This file is dual licensed under the MIT and the University of Illinois Open
+# Source Licenses. See LICENSE.TXT for details.
+
+LOCAL_PATH := $(call my-dir)
+
+# libcxx defines
+libcxx_includes := $(LOCAL_PATH)/include $(LOCAL_PATH)/src
+libcxx_export_includes := $(libcxx_includes)
+libcxx_sources := \
+ algorithm.cpp \
+ any.cpp \
+ atomic.cpp \
+ barrier.cpp \
+ bind.cpp \
+ charconv.cpp \
+ chrono.cpp \
+ condition_variable.cpp \
+ condition_variable_destructor.cpp \
+ debug.cpp \
+ exception.cpp \
+ filesystem/directory_iterator.cpp \
+ filesystem/int128_builtins.cpp \
+ filesystem/operations.cpp \
+ functional.cpp \
+ future.cpp \
+ hash.cpp \
+ ios.cpp \
+ ios.instantiations.cpp \
+ iostream.cpp \
+ legacy_debug_handler.cpp \
+ legacy_pointer_safety.cpp \
+ locale.cpp \
+ memory.cpp \
+ memory_resource.cpp \
+ mutex.cpp \
+ mutex_destructor.cpp \
+ new.cpp \
+ optional.cpp \
+ random_shuffle.cpp \
+ random.cpp \
+ regex.cpp \
+ shared_mutex.cpp \
+ stdexcept.cpp \
+ string.cpp \
+ strstream.cpp \
+ system_error.cpp \
+ thread.cpp \
+ typeinfo.cpp \
+ utility.cpp \
+ valarray.cpp \
+ variant.cpp \
+ vector.cpp \
+ verbose_abort.cpp \
+
+libcxx_sources := $(libcxx_sources:%=src/%)
+
+libcxx_export_cxxflags :=
+
+libcxx_cxxflags := \
+ -std=c++20 \
+ -fvisibility-global-new-delete-hidden \
+ -fvisibility=hidden -fvisibility-inlines-hidden \
+ -DLIBCXX_BUILDING_LIBCXXABI \
+ -D_LIBCPP_NO_EXCEPTIONS \
+ -D_LIBCPP_NO_RTTI \
+ -D_LIBCPP_BUILDING_LIBRARY \
+ -D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS \
+ -D__STDC_FORMAT_MACROS \
+ $(libcxx_export_cxxflags) \
+
+
+libcxx_ldflags :=
+libcxx_export_ldflags :=
+
+# libcxxabi defines
+libcxxabi_src_files := \
+ abort_message.cpp \
+ cxa_aux_runtime.cpp \
+ cxa_default_handlers.cpp \
+ cxa_exception_storage.cpp \
+ cxa_guard.cpp \
+ cxa_handlers.cpp \
+ cxa_noexception.cpp \
+ cxa_thread_atexit.cpp \
+ cxa_vector.cpp \
+ cxa_virtual.cpp \
+ stdlib_exception.cpp \
+ stdlib_new_delete.cpp \
+ stdlib_stdexcept.cpp \
+ stdlib_typeinfo.cpp \
+
+libcxxabi_src_files := $(libcxxabi_src_files:%=src/abi/%)
+
+libcxxabi_includes := \
+ $(LOCAL_PATH)/include \
+ $(LOCAL_PATH)/include/abi \
+
+libcxxabi_cflags := -D__STDC_FORMAT_MACROS
+libcxxabi_cppflags := \
+ -D_LIBCXXABI_NO_EXCEPTIONS \
+ -Wno-macro-redefined \
+ -Wno-unknown-attributes \
+ -DHAS_THREAD_LOCAL
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libcxx
+LOCAL_SRC_FILES := $(libcxx_sources) $(libcxxabi_src_files)
+LOCAL_C_INCLUDES := $(libcxx_includes) $(libcxxabi_includes)
+LOCAL_CPPFLAGS := $(libcxx_cxxflags) $(libcxxabi_cppflags) -ffunction-sections -fdata-sections
+LOCAL_EXPORT_C_INCLUDES := $(libcxx_export_includes)
+LOCAL_EXPORT_CPPFLAGS := $(libcxx_export_cxxflags)
+LOCAL_EXPORT_LDFLAGS := $(libcxx_export_ldflags)
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/app/src/main/cpp/libcxx/CMakeLists.txt b/app/src/main/cpp/libcxx/CMakeLists.txt
new file mode 100644
index 0000000..74eff20
--- /dev/null
+++ b/app/src/main/cpp/libcxx/CMakeLists.txt
@@ -0,0 +1,937 @@
+# See https://libcxx.llvm.org/docs/BuildingLibcxx.html for instructions on how
+# to build libcxx with CMake.
+
+#===============================================================================
+# Setup Project
+#===============================================================================
+cmake_minimum_required(VERSION 3.13.4)
+
+set(LLVM_COMMON_CMAKE_UTILS "${CMAKE_CURRENT_SOURCE_DIR}/../cmake")
+
+# Add path for custom modules
+list(INSERT CMAKE_MODULE_PATH 0
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake"
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules"
+ "${LLVM_COMMON_CMAKE_UTILS}"
+ "${LLVM_COMMON_CMAKE_UTILS}/Modules"
+ )
+
+set(CMAKE_FOLDER "libc++")
+
+set(LIBCXX_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+set(LIBCXX_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
+set(LIBCXX_BINARY_INCLUDE_DIR "${LIBCXX_BINARY_DIR}/include/c++build")
+
+include(GNUInstallDirs)
+
+# Require out of source build.
+include(MacroEnsureOutOfSourceBuild)
+MACRO_ENSURE_OUT_OF_SOURCE_BUILD(
+ "${PROJECT_NAME} requires an out of source build. Please create a separate
+ build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there."
+ )
+if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC")
+ message(STATUS "Configuring for clang-cl")
+ set(LIBCXX_TARGETING_CLANG_CL ON)
+endif()
+
+if (MSVC)
+ set(LIBCXX_TARGETING_MSVC ON)
+ message(STATUS "Configuring for MSVC")
+else()
+ set(LIBCXX_TARGETING_MSVC OFF)
+endif()
+
+#===============================================================================
+# Setup CMake Options
+#===============================================================================
+include(CMakeDependentOption)
+include(HandleCompilerRT)
+
+# Basic options ---------------------------------------------------------------
+option(LIBCXX_ENABLE_ASSERTIONS
+ "Enable assertions inside the compiled library, and at the same time make it the
+ default when compiling user code. Note that assertions can be enabled or disabled
+ by users in their own code regardless of this option." OFF)
+option(LIBCXX_ENABLE_SHARED "Build libc++ as a shared library." ON)
+option(LIBCXX_ENABLE_STATIC "Build libc++ as a static library." ON)
+set(ENABLE_FILESYSTEM_DEFAULT ON)
+if (WIN32 AND NOT MINGW)
+ # Filesystem is buildable for windows, but it requires __int128 helper
+ # functions, that currently are provided by libgcc or compiler_rt builtins.
+ # These are available in MinGW environments, but not currently in MSVC
+ # environments.
+ set(ENABLE_FILESYSTEM_DEFAULT OFF)
+endif()
+option(LIBCXX_ENABLE_FILESYSTEM "Build filesystem as part of the main libc++ library"
+ ${ENABLE_FILESYSTEM_DEFAULT})
+option(LIBCXX_INCLUDE_TESTS "Build the libc++ tests." ${LLVM_INCLUDE_TESTS})
+option(LIBCXX_ENABLE_PARALLEL_ALGORITHMS "Enable the parallel algorithms library. This requires the PSTL to be available." OFF)
+option(LIBCXX_ENABLE_DEBUG_MODE
+ "Whether to build libc++ with the debug mode enabled.
+ By default, this is turned off. Turning it on results in a different ABI (additional
+ symbols but also potentially different layouts of types), and one should not mix code
+ built against a dylib that has debug mode and code built against a regular dylib." OFF)
+option(LIBCXX_ENABLE_RANDOM_DEVICE
+ "Whether to include support for std::random_device in the library. Disabling
+ this can be useful when building the library for platforms that don't have
+ a source of randomness, such as some embedded platforms. When this is not
+ supported, most of will still be available, but std::random_device
+ will not." ON)
+option(LIBCXX_ENABLE_LOCALIZATION
+ "Whether to include support for localization in the library. Disabling
+ localization can be useful when porting to platforms that don't support
+ the C locale API (e.g. embedded). When localization is not supported,
+ several parts of the library will be disabled: , ,
+ will be completely unusable, and other parts may be only partly available." ON)
+option(LIBCXX_ENABLE_UNICODE
+ "Whether to include support for Unicode in the library. Disabling Unicode can
+ be useful when porting to platforms that don't support UTF-8 encoding (e.g.
+ embedded)." ON)
+option(LIBCXX_ENABLE_WIDE_CHARACTERS
+ "Whether to include support for wide characters in the library. Disabling
+ wide character support can be useful when porting to platforms that don't
+ support the C functionality for wide characters. When wide characters are
+ not supported, several parts of the library will be disabled, notably the
+ wide character specializations of std::basic_string." ON)
+option(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS
+ "Whether to turn on vendor availability annotations on declarations that depend
+ on definitions in a shared library. By default, we assume that we're not building
+ libc++ for any specific vendor, and we disable those annotations. Vendors wishing
+ to provide compile-time errors when using features unavailable on some version of
+ the shared library they shipped should turn this on and see `include/__availability`
+ for more details." OFF)
+
+if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-shared-gcc.cfg.in")
+elseif(MINGW)
+ set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-mingw.cfg.in")
+elseif(WIN32) # clang-cl
+ if (LIBCXX_ENABLE_SHARED)
+ set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-shared-clangcl.cfg.in")
+ else()
+ set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-static-clangcl.cfg.in")
+ endif()
+else()
+ if (LIBCXX_ENABLE_SHARED)
+ set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-shared.cfg.in")
+ else()
+ set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-static.cfg.in")
+ endif()
+endif()
+set(LIBCXX_TEST_CONFIG "${LIBCXX_DEFAULT_TEST_CONFIG}" CACHE STRING
+ "The path to the Lit testing configuration to use when running the tests.
+ If a relative path is provided, it is assumed to be relative to '/libcxx/test/configs'.")
+if (NOT IS_ABSOLUTE "${LIBCXX_TEST_CONFIG}")
+ set(LIBCXX_TEST_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/test/configs/${LIBCXX_TEST_CONFIG}")
+endif()
+message(STATUS "Using libc++ testing configuration: ${LIBCXX_TEST_CONFIG}")
+set(LIBCXX_TEST_PARAMS "" CACHE STRING
+ "A list of parameters to run the Lit test suite with.")
+
+# Benchmark options -----------------------------------------------------------
+option(LIBCXX_INCLUDE_BENCHMARKS "Build the libc++ benchmarks and their dependencies" ON)
+
+set(LIBCXX_BENCHMARK_TEST_ARGS_DEFAULT --benchmark_min_time=0.01)
+set(LIBCXX_BENCHMARK_TEST_ARGS "${LIBCXX_BENCHMARK_TEST_ARGS_DEFAULT}" CACHE STRING
+ "Arguments to pass when running the benchmarks using check-cxx-benchmarks")
+
+set(LIBCXX_BENCHMARK_NATIVE_STDLIB "" CACHE STRING
+ "Build the benchmarks against the specified native STL.
+ The value must be one of libc++/libstdc++")
+set(LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN "" CACHE STRING
+ "Use alternate GCC toolchain when building the native benchmarks")
+
+if (LIBCXX_BENCHMARK_NATIVE_STDLIB)
+ if (NOT (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libc++"
+ OR LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libstdc++"))
+ message(FATAL_ERROR "Invalid value for LIBCXX_BENCHMARK_NATIVE_STDLIB: "
+ "'${LIBCXX_BENCHMARK_NATIVE_STDLIB}'")
+ endif()
+endif()
+
+option(LIBCXX_INCLUDE_DOCS "Build the libc++ documentation." ${LLVM_INCLUDE_DOCS})
+set(LIBCXX_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" CACHE STRING
+ "Define suffix of library directory name (32/64)")
+option(LIBCXX_INSTALL_HEADERS "Install the libc++ headers." ON)
+option(LIBCXX_INSTALL_LIBRARY "Install the libc++ library." ON)
+cmake_dependent_option(LIBCXX_INSTALL_STATIC_LIBRARY
+ "Install the static libc++ library." ON
+ "LIBCXX_ENABLE_STATIC;LIBCXX_INSTALL_LIBRARY" OFF)
+cmake_dependent_option(LIBCXX_INSTALL_SHARED_LIBRARY
+ "Install the shared libc++ library." ON
+ "LIBCXX_ENABLE_SHARED;LIBCXX_INSTALL_LIBRARY" OFF)
+
+option(LIBCXX_ABI_UNSTABLE "Use the unstable ABI of libc++. This is equivalent to specifying LIBCXX_ABI_VERSION=n, where n is the not-yet-stable version." OFF)
+if (LIBCXX_ABI_UNSTABLE)
+ set(abi_version "2")
+else()
+ set(abi_version "1")
+endif()
+set(LIBCXX_ABI_VERSION "${abi_version}" CACHE STRING
+ "ABI version of libc++. Can be either 1 or 2, where 2 is currently the unstable ABI.
+ Defaults to 1 unless LIBCXX_ABI_UNSTABLE is specified, in which case this is 2.")
+set(LIBCXX_LIBRARY_VERSION "${LIBCXX_ABI_VERSION}.0" CACHE STRING
+ "Version of libc++. This will be reflected in the name of the shared library produced.
+ For example, -DLIBCXX_LIBRARY_VERSION=x.y will result in the library being named
+ libc++.x.y.dylib, along with the usual symlinks pointing to that. On Apple platforms,
+ this also controls the linker's 'current_version' property.")
+set(LIBCXX_ABI_NAMESPACE "__${LIBCXX_ABI_VERSION}" CACHE STRING "The inline ABI namespace used by libc++. It defaults to __n where `n` is the current ABI version.")
+if (NOT LIBCXX_ABI_NAMESPACE MATCHES "__.*")
+ message(FATAL_ERROR "LIBCXX_ABI_NAMESPACE must be a reserved identifier, got '${LIBCXX_ABI_NAMESPACE}'.")
+endif()
+option(LIBCXX_ABI_FORCE_ITANIUM "Ignore auto-detection and force use of the Itanium ABI.")
+option(LIBCXX_ABI_FORCE_MICROSOFT "Ignore auto-detection and force use of the Microsoft ABI.")
+
+set(LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION "default" CACHE STRING
+ "Override the implementation to use for comparing typeinfos. By default, this
+ is detected automatically by the library, but this option allows overriding
+ which implementation is used unconditionally.
+
+ See the documentation in for details on what each
+ value means.")
+set(TYPEINFO_COMPARISON_VALUES "default;1;2;3")
+if (NOT ("${LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION}" IN_LIST TYPEINFO_COMPARISON_VALUES))
+ message(FATAL_ERROR "Value '${LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION}' is not a valid value for
+ LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION")
+endif()
+
+set(LIBCXX_ABI_DEFINES "" CACHE STRING "A semicolon separated list of ABI macros to define in the site config header.")
+option(LIBCXX_EXTRA_SITE_DEFINES "Extra defines to add into __config_site")
+option(LIBCXX_USE_COMPILER_RT "Use compiler-rt instead of libgcc" OFF)
+
+option(LIBCXX_ENABLE_BACKWARDS_COMPATIBILITY_DEBUG_MODE_SYMBOLS
+ "Whether to include the old Debug mode symbols in the compiled library. This
+ is provided for backwards compatibility since the compiled library used to
+ always contain those symbols, regardless of whether the library was built
+ with the debug mode enabled. This is OFF by default, please contact the libc++
+ developers if you need to turn this on, as this will be removed in LLVM 16." OFF)
+
+# ABI Library options ---------------------------------------------------------
+if (LIBCXX_TARGETING_MSVC)
+ set(LIBCXX_DEFAULT_ABI_LIBRARY "vcruntime")
+elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
+ set(LIBCXX_DEFAULT_ABI_LIBRARY "libcxxrt")
+else()
+ set(LIBCXX_DEFAULT_ABI_LIBRARY "libcxxabi")
+endif()
+
+set(LIBCXX_SUPPORTED_ABI_LIBRARIES none libcxxabi system-libcxxabi libcxxrt libstdc++ libsupc++ vcruntime)
+set(LIBCXX_CXX_ABI "${LIBCXX_DEFAULT_ABI_LIBRARY}" CACHE STRING "Specify C++ ABI library to use. Supported values are ${LIBCXX_SUPPORTED_ABI_LIBRARIES}.")
+if (NOT "${LIBCXX_CXX_ABI}" IN_LIST LIBCXX_SUPPORTED_ABI_LIBRARIES)
+ message(FATAL_ERROR "Unsupported C++ ABI library: '${LIBCXX_CXX_ABI}'. Supported values are ${LIBCXX_SUPPORTED_ABI_LIBRARIES}.")
+endif()
+
+option(LIBCXX_ENABLE_STATIC_ABI_LIBRARY
+ "Use a static copy of the ABI library when linking libc++.
+ This option cannot be used with LIBCXX_ENABLE_ABI_LINKER_SCRIPT." OFF)
+
+cmake_dependent_option(LIBCXX_STATICALLY_LINK_ABI_IN_STATIC_LIBRARY
+ "Statically link the ABI library to static library" ON
+ "LIBCXX_ENABLE_STATIC_ABI_LIBRARY" OFF)
+
+cmake_dependent_option(LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY
+ "Statically link the ABI library to shared library" ON
+ "LIBCXX_ENABLE_STATIC_ABI_LIBRARY" OFF)
+
+# Generate and install a linker script inplace of libc++.so. The linker script
+# will link libc++ to the correct ABI library. This option is on by default
+# on UNIX platforms other than Apple unless 'LIBCXX_ENABLE_STATIC_ABI_LIBRARY'
+# is on. This option is also disabled when the ABI library is not specified
+# or is specified to be "none".
+set(ENABLE_LINKER_SCRIPT_DEFAULT_VALUE OFF)
+if (LLVM_HAVE_LINK_VERSION_SCRIPT AND NOT LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY
+ AND NOT LIBCXX_CXX_ABI STREQUAL "none"
+ AND Python3_EXECUTABLE
+ AND LIBCXX_ENABLE_SHARED)
+ set(ENABLE_LINKER_SCRIPT_DEFAULT_VALUE ON)
+endif()
+
+option(LIBCXX_ENABLE_ABI_LINKER_SCRIPT
+ "Use and install a linker script for the given ABI library"
+ ${ENABLE_LINKER_SCRIPT_DEFAULT_VALUE})
+
+option(LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS
+ "Build libc++ with definitions for operator new/delete. These are normally
+ defined in libc++abi, but this option can be used to define them in libc++
+ instead. If you define them in libc++, make sure they are NOT defined in
+ libc++abi. Doing otherwise is an ODR violation." OFF)
+# Build libc++abi with libunwind. We need this option to determine whether to
+# link with libunwind or libgcc_s while running the test cases.
+option(LIBCXXABI_USE_LLVM_UNWINDER "Build and use the LLVM unwinder." OFF)
+
+# Target options --------------------------------------------------------------
+option(LIBCXX_BUILD_32_BITS "Build 32 bit multilib libc++. This option is not supported anymore when building the runtimes. Please specify a full triple instead." ${LLVM_BUILD_32_BITS})
+if (LIBCXX_BUILD_32_BITS)
+ message(FATAL_ERROR "LIBCXX_BUILD_32_BITS is not supported anymore when building the runtimes, please specify a full triple instead.")
+endif()
+
+# TODO: Remove this after branching for LLVM 15
+if(LIBCXX_SYSROOT OR LIBCXX_TARGET_TRIPLE OR LIBCXX_GCC_TOOLCHAIN)
+ message(WARNING "LIBCXX_SYSROOT, LIBCXX_TARGET_TRIPLE and LIBCXX_GCC_TOOLCHAIN are not supported anymore, please use the native CMake equivalents instead")
+endif()
+
+# Feature options -------------------------------------------------------------
+option(LIBCXX_ENABLE_EXCEPTIONS "Use exceptions." ON)
+option(LIBCXX_ENABLE_RTTI "Use run time type information." ON)
+option(LIBCXX_ENABLE_THREADS "Build libc++ with support for threads." ON)
+option(LIBCXX_ENABLE_MONOTONIC_CLOCK
+ "Build libc++ with support for a monotonic clock.
+ This option may only be set to OFF when LIBCXX_ENABLE_THREADS=OFF." ON)
+option(LIBCXX_HAS_MUSL_LIBC "Build libc++ with support for the Musl C library" OFF)
+option(LIBCXX_HAS_PTHREAD_API "Ignore auto-detection and force use of pthread API" OFF)
+option(LIBCXX_HAS_WIN32_THREAD_API "Ignore auto-detection and force use of win32 thread API" OFF)
+option(LIBCXX_HAS_EXTERNAL_THREAD_API
+ "Build libc++ with an externalized threading API.
+ This option may only be set to ON when LIBCXX_ENABLE_THREADS=ON." OFF)
+option(LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY
+ "Build libc++ with an externalized threading library.
+ This option may only be set to ON when LIBCXX_ENABLE_THREADS=ON" OFF)
+
+# Misc options ----------------------------------------------------------------
+# FIXME: Turn -pedantic back ON. It is currently off because it warns
+# about #include_next which is used everywhere.
+option(LIBCXX_ENABLE_PEDANTIC "Compile with pedantic enabled." OFF)
+option(LIBCXX_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF)
+option(LIBCXX_DISABLE_MACRO_CONFLICT_WARNINGS "Disable #warnings about conflicting macros." OFF)
+
+option(LIBCXX_GENERATE_COVERAGE "Enable generating code coverage." OFF)
+set(LIBCXX_COVERAGE_LIBRARY "" CACHE STRING
+ "The Profile-rt library used to build with code coverage")
+
+set(LIBCXX_CONFIGURE_IDE_DEFAULT OFF)
+if (XCODE OR MSVC_IDE)
+ set(LIBCXX_CONFIGURE_IDE_DEFAULT ON)
+endif()
+option(LIBCXX_CONFIGURE_IDE "Configure libcxx for use within an IDE"
+ ${LIBCXX_CONFIGURE_IDE_DEFAULT})
+
+set(LIBCXX_HERMETIC_STATIC_LIBRARY_DEFAULT OFF)
+if (WIN32)
+ set(LIBCXX_HERMETIC_STATIC_LIBRARY_DEFAULT ON)
+endif()
+option(LIBCXX_HERMETIC_STATIC_LIBRARY
+ "Do not export any symbols from the static library." ${LIBCXX_HERMETIC_STATIC_LIBRARY_DEFAULT})
+
+#===============================================================================
+# Check option configurations
+#===============================================================================
+
+# Ensure LIBCXX_ENABLE_MONOTONIC_CLOCK is set to ON only when
+# LIBCXX_ENABLE_THREADS is on.
+if(LIBCXX_ENABLE_THREADS AND NOT LIBCXX_ENABLE_MONOTONIC_CLOCK)
+ message(FATAL_ERROR "LIBCXX_ENABLE_MONOTONIC_CLOCK can only be set to OFF"
+ " when LIBCXX_ENABLE_THREADS is also set to OFF.")
+endif()
+
+if(NOT LIBCXX_ENABLE_THREADS)
+ if(LIBCXX_HAS_PTHREAD_API)
+ message(FATAL_ERROR "LIBCXX_HAS_PTHREAD_API can only be set to ON"
+ " when LIBCXX_ENABLE_THREADS is also set to ON.")
+ endif()
+ if(LIBCXX_HAS_EXTERNAL_THREAD_API)
+ message(FATAL_ERROR "LIBCXX_HAS_EXTERNAL_THREAD_API can only be set to ON"
+ " when LIBCXX_ENABLE_THREADS is also set to ON.")
+ endif()
+ if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY)
+ message(FATAL_ERROR "LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY can only be set "
+ "to ON when LIBCXX_ENABLE_THREADS is also set to ON.")
+ endif()
+ if (LIBCXX_HAS_WIN32_THREAD_API)
+ message(FATAL_ERROR "LIBCXX_HAS_WIN32_THREAD_API can only be set to ON"
+ " when LIBCXX_ENABLE_THREADS is also set to ON.")
+ endif()
+
+endif()
+
+if (LIBCXX_HAS_EXTERNAL_THREAD_API)
+ if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY)
+ message(FATAL_ERROR "The options LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY and "
+ "LIBCXX_HAS_EXTERNAL_THREAD_API cannot both be ON at "
+ "the same time")
+ endif()
+ if (LIBCXX_HAS_PTHREAD_API)
+ message(FATAL_ERROR "The options LIBCXX_HAS_EXTERNAL_THREAD_API"
+ "and LIBCXX_HAS_PTHREAD_API cannot be both"
+ "set to ON at the same time.")
+ endif()
+ if (LIBCXX_HAS_WIN32_THREAD_API)
+ message(FATAL_ERROR "The options LIBCXX_HAS_EXTERNAL_THREAD_API"
+ "and LIBCXX_HAS_WIN32_THREAD_API cannot be both"
+ "set to ON at the same time.")
+ endif()
+endif()
+
+if (LIBCXX_HAS_PTHREAD_API)
+ if (LIBCXX_HAS_WIN32_THREAD_API)
+ message(FATAL_ERROR "The options LIBCXX_HAS_PTHREAD_API"
+ "and LIBCXX_HAS_WIN32_THREAD_API cannot be both"
+ "set to ON at the same time.")
+ endif()
+endif()
+
+# Ensure LLVM_USE_SANITIZER is not specified when LIBCXX_GENERATE_COVERAGE
+# is ON.
+if (LLVM_USE_SANITIZER AND LIBCXX_GENERATE_COVERAGE)
+ message(FATAL_ERROR "LLVM_USE_SANITIZER cannot be used with LIBCXX_GENERATE_COVERAGE")
+endif()
+
+# Warn users that LIBCXX_ENABLE_STATIC_ABI_LIBRARY is an experimental option.
+if (LIBCXX_ENABLE_STATIC_ABI_LIBRARY)
+ message(WARNING "LIBCXX_ENABLE_STATIC_ABI_LIBRARY is an experimental option")
+ if (LIBCXX_ENABLE_STATIC AND NOT Python3_EXECUTABLE)
+ message(FATAL_ERROR "LIBCXX_ENABLE_STATIC_ABI_LIBRARY requires python but it was not found.")
+ endif()
+endif()
+
+if (LIBCXX_ENABLE_ABI_LINKER_SCRIPT)
+ if (APPLE)
+ message(FATAL_ERROR "LIBCXX_ENABLE_ABI_LINKER_SCRIPT cannot be used on APPLE targets")
+ endif()
+ if (NOT LIBCXX_ENABLE_SHARED)
+ message(FATAL_ERROR "LIBCXX_ENABLE_ABI_LINKER_SCRIPT is only available for shared library builds.")
+ endif()
+endif()
+
+if (LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY AND LIBCXX_ENABLE_ABI_LINKER_SCRIPT)
+ message(FATAL_ERROR "Conflicting options given.
+ LIBCXX_ENABLE_STATIC_ABI_LIBRARY cannot be specified with
+ LIBCXX_ENABLE_ABI_LINKER_SCRIPT")
+endif()
+
+if (LIBCXX_ABI_FORCE_ITANIUM AND LIBCXX_ABI_FORCE_MICROSOFT)
+ message(FATAL_ERROR "Only one of LIBCXX_ABI_FORCE_ITANIUM and LIBCXX_ABI_FORCE_MICROSOFT can be specified.")
+endif ()
+
+#===============================================================================
+# Configure System
+#===============================================================================
+
+# TODO: Projects that depend on libc++ should use LIBCXX_GENERATED_INCLUDE_DIR
+# instead of hard-coding include/c++/v1.
+
+set(LIBCXX_INSTALL_INCLUDE_DIR "${CMAKE_INSTALL_INCLUDEDIR}/c++/v1" CACHE PATH
+ "Path where target-agnostic libc++ headers should be installed.")
+set(LIBCXX_INSTALL_RUNTIME_DIR "${CMAKE_INSTALL_BINDIR}" CACHE PATH
+ "Path where built libc++ runtime libraries should be installed.")
+
+if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE)
+ set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE})
+ set(LIBCXX_GENERATED_INCLUDE_DIR "${LLVM_BINARY_DIR}/include/c++/v1")
+ set(LIBCXX_GENERATED_INCLUDE_TARGET_DIR "${LLVM_BINARY_DIR}/include/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/v1")
+ set(LIBCXX_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE PATH
+ "Path where built libc++ libraries should be installed.")
+ set(LIBCXX_INSTALL_INCLUDE_TARGET_DIR "${CMAKE_INSTALL_INCLUDEDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/v1" CACHE PATH
+ "Path where target-specific libc++ headers should be installed.")
+ if(LIBCXX_LIBDIR_SUBDIR)
+ string(APPEND LIBCXX_LIBRARY_DIR /${LIBCXX_LIBDIR_SUBDIR})
+ string(APPEND LIBCXX_INSTALL_LIBRARY_DIR /${LIBCXX_LIBDIR_SUBDIR})
+ endif()
+else()
+ if(LLVM_LIBRARY_OUTPUT_INTDIR)
+ set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
+ set(LIBCXX_GENERATED_INCLUDE_DIR "${LLVM_BINARY_DIR}/include/c++/v1")
+ else()
+ set(LIBCXX_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LIBCXX_LIBDIR_SUFFIX})
+ set(LIBCXX_GENERATED_INCLUDE_DIR "${CMAKE_BINARY_DIR}/include/c++/v1")
+ endif()
+ set(LIBCXX_GENERATED_INCLUDE_TARGET_DIR "${LIBCXX_GENERATED_INCLUDE_DIR}")
+ set(LIBCXX_INSTALL_LIBRARY_DIR lib${LIBCXX_LIBDIR_SUFFIX} CACHE PATH
+ "Path where built libc++ libraries should be installed.")
+ set(LIBCXX_INSTALL_INCLUDE_TARGET_DIR "${LIBCXX_INSTALL_INCLUDE_DIR}" CACHE PATH
+ "Path where target-specific libc++ headers should be installed.")
+endif()
+
+file(MAKE_DIRECTORY "${LIBCXX_BINARY_INCLUDE_DIR}")
+
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIBCXX_LIBRARY_DIR})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIBCXX_LIBRARY_DIR})
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LIBCXX_LIBRARY_DIR})
+
+# Declare libc++ configuration variables.
+# They are intended for use as follows:
+# LIBCXX_CXX_FLAGS: General flags for both the compiler and linker.
+# LIBCXX_COMPILE_FLAGS: Compile only flags.
+# LIBCXX_LINK_FLAGS: Linker only flags.
+# LIBCXX_LIBRARIES: libraries libc++ is linked to.
+set(LIBCXX_COMPILE_FLAGS "")
+set(LIBCXX_LINK_FLAGS "")
+set(LIBCXX_LIBRARIES "")
+
+# Include macros for adding and removing libc++ flags.
+include(HandleLibcxxFlags)
+
+# Target flags ================================================================
+# These flags get added to CMAKE_CXX_FLAGS and CMAKE_C_FLAGS so that
+# 'config-ix' use them during feature checks. It also adds them to both
+# 'LIBCXX_COMPILE_FLAGS' and 'LIBCXX_LINK_FLAGS'
+if(ZOS)
+ add_target_flags_if_supported("-fzos-le-char-mode=ebcdic")
+endif()
+
+if (${CMAKE_SYSTEM_NAME} MATCHES "AIX")
+ add_target_flags_if_supported("-mdefault-visibility-export-mapping=explicit")
+ set(CMAKE_AIX_EXPORT_ALL_SYMBOLS OFF)
+endif()
+
+# Configure compiler.
+include(config-ix)
+
+# Configure coverage options.
+if (LIBCXX_GENERATE_COVERAGE)
+ include(CodeCoverage)
+ set(CMAKE_BUILD_TYPE "COVERAGE" CACHE STRING "" FORCE)
+endif()
+
+string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE)
+if (uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG")
+ set(LIBCXX_DEBUG_BUILD ON)
+else()
+ set(LIBCXX_DEBUG_BUILD OFF)
+endif()
+
+#===============================================================================
+# Setup Compiler Flags
+#===============================================================================
+
+include(HandleLibCXXABI) # Setup the ABI library flags
+
+# Remove flags that may have snuck in.
+# TODO: This shouldn't be necessary anymore since we don't support the Project
+# build anymore, so the rest of LLVM can't pollute our flags.
+remove_flags(-DNDEBUG -UNDEBUG -D_DEBUG -lc++abi)
+remove_flags(--stdlib=libc++ -stdlib=libc++ --stdlib=libstdc++ -stdlib=libstdc++)
+
+# FIXME: Remove all debug flags and flags that change which Windows
+# default libraries are linked. Currently we only support linking the
+# non-debug DLLs
+remove_flags("/D_DEBUG" "/MTd" "/MDd" "/MT" "/Md")
+
+# FIXME(EricWF): See the FIXME on LIBCXX_ENABLE_PEDANTIC.
+# Remove the -pedantic flag and -Wno-pedantic and -pedantic-errors
+# so they don't get transformed into -Wno and -errors respectively.
+remove_flags(-Wno-pedantic -pedantic-errors -pedantic)
+
+# Required flags ==============================================================
+function(cxx_add_basic_build_flags target)
+
+ # Require C++20 for all targets. C++17 is needed to use aligned allocation
+ # in the dylib. C++20 is needed to use char8_t.
+ set_target_properties(${target} PROPERTIES
+ CXX_STANDARD 20
+ CXX_STANDARD_REQUIRED YES
+ CXX_EXTENSIONS NO)
+
+ # When building the dylib, don't warn for unavailable aligned allocation
+ # functions based on the deployment target -- they are always available
+ # because they are provided by the dylib itself with the excepton of z/OS.
+ if (ZOS)
+ target_add_compile_flags_if_supported(${target} PRIVATE -fno-aligned-allocation)
+ else()
+ target_add_compile_flags_if_supported(${target} PRIVATE -faligned-allocation)
+ endif()
+
+ # On all systems the system c++ standard library headers need to be excluded.
+ # MSVC only has -X, which disables all default includes; including the crt.
+ # Thus, we do nothing and hope we don't accidentally include any of the C++
+ # headers
+ target_add_compile_flags_if_supported(${target} PUBLIC -nostdinc++)
+
+ # Hide all inline function definitions which have not explicitly been marked
+ # visible. This prevents new definitions for inline functions from appearing in
+ # the dylib when get ODR used by another function.
+ target_add_compile_flags_if_supported(${target} PRIVATE -fvisibility-inlines-hidden)
+
+ # Our visibility annotations are not quite right for non-Clang compilers,
+ # so we end up not exporting all the symbols we should. In the future, we
+ # can improve the situation by providing an explicit list of exported
+ # symbols on all compilers.
+ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ target_add_compile_flags_if_supported(${target} PRIVATE -fvisibility=hidden)
+ endif()
+
+ if (LIBCXX_CONFIGURE_IDE)
+ # This simply allows IDE to process
+ target_add_compile_flags_if_supported(${target} PRIVATE -fcoroutines-ts)
+ endif()
+
+ # Let the library headers know they are currently being used to build the
+ # library.
+ target_compile_definitions(${target} PRIVATE -D_LIBCPP_BUILDING_LIBRARY)
+
+ if (NOT LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS)
+ target_compile_definitions(${target} PRIVATE -D_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS)
+ endif()
+
+ if (C_SUPPORTS_COMMENT_LIB_PRAGMA)
+ if (LIBCXX_HAS_PTHREAD_LIB)
+ target_compile_definitions(${target} PRIVATE -D_LIBCPP_LINK_PTHREAD_LIB)
+ endif()
+ if (LIBCXX_HAS_RT_LIB)
+ target_compile_definitions(${target} PRIVATE -D_LIBCPP_LINK_RT_LIB)
+ endif()
+ endif()
+endfunction()
+
+# Warning flags ===============================================================
+function(cxx_add_warning_flags target)
+ target_compile_definitions(${target} PUBLIC -D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+ if (MSVC)
+ # -W4 is the cl.exe/clang-cl equivalent of -Wall. (In cl.exe and clang-cl,
+ # -Wall is equivalent to -Weverything in GCC style compiler drivers.)
+ target_add_compile_flags_if_supported(${target} PRIVATE -W4)
+ else()
+ target_add_compile_flags_if_supported(${target} PRIVATE -Wall)
+ endif()
+ target_add_compile_flags_if_supported(${target} PRIVATE -Wextra -W -Wwrite-strings
+ -Wno-unused-parameter -Wno-long-long
+ -Werror=return-type -Wextra-semi -Wundef
+ -Wformat-nonliteral)
+ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
+ target_add_compile_flags_if_supported(${target} PRIVATE
+ -Wno-user-defined-literals
+ -Wno-covered-switch-default
+ -Wno-suggest-override
+ )
+ if (LIBCXX_TARGETING_CLANG_CL)
+ target_add_compile_flags_if_supported(${target} PRIVATE
+ -Wno-c++98-compat
+ -Wno-c++98-compat-pedantic
+ -Wno-c++11-compat
+ -Wno-undef
+ -Wno-reserved-id-macro
+ -Wno-gnu-include-next
+ -Wno-gcc-compat # For ignoring "'diagnose_if' is a clang extension" warnings
+ -Wno-zero-as-null-pointer-constant # FIXME: Remove this and fix all occurrences.
+ -Wno-deprecated-dynamic-exception-spec # For auto_ptr
+ -Wno-sign-conversion
+ -Wno-old-style-cast
+ -Wno-deprecated # FIXME: Remove this and fix all occurrences.
+ -Wno-shift-sign-overflow # FIXME: Why do we need this with clang-cl but not clang?
+ -Wno-double-promotion # FIXME: remove me
+ )
+ endif()
+ elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
+ target_add_compile_flags_if_supported(${target} PRIVATE
+ -Wno-attributes
+ -Wno-literal-suffix
+ -Wno-c++14-compat
+ -Wno-noexcept-type
+ -Wno-suggest-override)
+ endif()
+ if (LIBCXX_ENABLE_WERROR)
+ target_add_compile_flags_if_supported(${target} PRIVATE -Werror)
+ target_add_compile_flags_if_supported(${target} PRIVATE -WX)
+ else()
+ # TODO(EricWF) Remove this. We shouldn't be suppressing errors when -Werror is
+ # added elsewhere.
+ target_add_compile_flags_if_supported(${target} PRIVATE -Wno-error)
+ endif()
+ if (LIBCXX_ENABLE_PEDANTIC)
+ target_add_compile_flags_if_supported(${target} PRIVATE -pedantic)
+ endif()
+endfunction()
+
+# Exception flags =============================================================
+function(cxx_add_exception_flags target)
+ if (LIBCXX_ENABLE_EXCEPTIONS)
+ # Catches C++ exceptions only and tells the compiler to assume that extern C
+ # functions never throw a C++ exception.
+ target_add_compile_flags_if_supported(${target} PUBLIC -EHsc)
+ else()
+ target_add_compile_flags_if_supported(${target} PUBLIC -EHs- -EHa-)
+ target_add_compile_flags_if_supported(${target} PUBLIC -fno-exceptions)
+ endif()
+endfunction()
+
+# RTTI flags ==================================================================
+function(cxx_add_rtti_flags target)
+ if (NOT LIBCXX_ENABLE_RTTI)
+ target_add_compile_flags_if_supported(${target} PUBLIC -GR-)
+ target_add_compile_flags_if_supported(${target} PUBLIC -fno-rtti)
+ endif()
+endfunction()
+
+# Threading flags =============================================================
+if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY AND LIBCXX_ENABLE_SHARED)
+ # Need to allow unresolved symbols if this is to work with shared library builds
+ if (APPLE)
+ add_link_flags("-undefined dynamic_lookup")
+ else()
+ # Relax this restriction from HandleLLVMOptions
+ string(REPLACE "-Wl,-z,defs" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
+ endif()
+endif()
+
+# Assertion flags =============================================================
+define_if(LIBCXX_DEBUG_BUILD -D_DEBUG)
+if (LIBCXX_ENABLE_ASSERTIONS AND NOT LIBCXX_DEBUG_BUILD)
+ # MSVC doesn't like _DEBUG on release builds. See PR 4379.
+ define_if_not(LIBCXX_TARGETING_MSVC -D_DEBUG)
+endif()
+
+# Modules flags ===============================================================
+# FIXME The libc++ sources are fundamentally non-modular. They need special
+# versions of the headers in order to provide C++03 and legacy ABI definitions.
+# NOTE: The public headers can be used with modules in all other contexts.
+function(cxx_add_module_flags target)
+ if (LLVM_ENABLE_MODULES)
+ # Ignore that the rest of the modules flags are now unused.
+ target_add_compile_flags_if_supported(${target} PUBLIC -Wno-unused-command-line-argument)
+ target_compile_options(${target} PUBLIC -fno-modules)
+ endif()
+endfunction()
+
+# Sanitizer flags =============================================================
+
+function(get_sanitizer_flags OUT_VAR USE_SANITIZER)
+ set(SANITIZER_FLAGS)
+ set(USE_SANITIZER "${USE_SANITIZER}")
+ # NOTE: LLVM_USE_SANITIZER checks for a UNIX like system instead of MSVC.
+ # But we don't have LLVM_ON_UNIX so checking for MSVC is the best we can do.
+ if (USE_SANITIZER AND NOT MSVC)
+ append_flags_if_supported(SANITIZER_FLAGS "-fno-omit-frame-pointer")
+ append_flags_if_supported(SANITIZER_FLAGS "-gline-tables-only")
+
+ if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG" AND
+ NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "RELWITHDEBINFO")
+ append_flags_if_supported(SANITIZER_FLAGS "-gline-tables-only")
+ endif()
+ if (USE_SANITIZER STREQUAL "Address")
+ append_flags(SANITIZER_FLAGS "-fsanitize=address")
+ elseif (USE_SANITIZER MATCHES "Memory(WithOrigins)?")
+ append_flags(SANITIZER_FLAGS -fsanitize=memory)
+ if (USE_SANITIZER STREQUAL "MemoryWithOrigins")
+ append_flags(SANITIZER_FLAGS "-fsanitize-memory-track-origins")
+ endif()
+ elseif (USE_SANITIZER STREQUAL "Undefined")
+ append_flags(SANITIZER_FLAGS "-fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all")
+ elseif (USE_SANITIZER STREQUAL "Address;Undefined" OR
+ USE_SANITIZER STREQUAL "Undefined;Address")
+ append_flags(SANITIZER_FLAGS "-fsanitize=address,undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all")
+ elseif (USE_SANITIZER STREQUAL "Thread")
+ append_flags(SANITIZER_FLAGS -fsanitize=thread)
+ elseif (USE_SANITIZER STREQUAL "DataFlow")
+ append_flags(SANITIZER_FLAGS -fsanitize=dataflow)
+ else()
+ message(WARNING "Unsupported value of LLVM_USE_SANITIZER: ${USE_SANITIZER}")
+ endif()
+ elseif(USE_SANITIZER AND MSVC)
+ message(WARNING "LLVM_USE_SANITIZER is not supported on this platform.")
+ endif()
+ set(${OUT_VAR} "${SANITIZER_FLAGS}" PARENT_SCOPE)
+endfunction()
+
+get_sanitizer_flags(SANITIZER_FLAGS "${LLVM_USE_SANITIZER}")
+
+# Link system libraries =======================================================
+function(cxx_link_system_libraries target)
+
+# In order to remove just libc++ from the link step
+# we need to use -nostdlib++ whenever it is supported.
+# Unfortunately this cannot be used universally because for example g++ supports
+# only -nodefaultlibs in which case all libraries will be removed and
+# all libraries but c++ have to be added in manually.
+ if (CXX_SUPPORTS_NOSTDLIBXX_FLAG)
+ target_add_link_flags_if_supported(${target} PRIVATE "-nostdlib++")
+ else()
+ target_add_link_flags_if_supported(${target} PRIVATE "-nodefaultlibs")
+ target_add_compile_flags_if_supported(${target} PRIVATE "/Zl")
+ target_add_link_flags_if_supported(${target} PRIVATE "/nodefaultlib")
+ endif()
+
+ if (CXX_SUPPORTS_UNWINDLIB_EQ_NONE_FLAG AND LIBCXXABI_USE_LLVM_UNWINDER)
+ # If we're linking directly against the libunwind that we're building
+ # in the same invocation, don't try to link in the toolchain's
+ # default libunwind (which may be missing still).
+ target_add_link_flags_if_supported(${target} PRIVATE "--unwindlib=none")
+ endif()
+
+ if (LIBCXX_HAS_SYSTEM_LIB)
+ target_link_libraries(${target} PRIVATE System)
+ endif()
+
+ if (LIBCXX_HAS_PTHREAD_LIB)
+ target_link_libraries(${target} PRIVATE pthread)
+ endif()
+
+ if (LIBCXX_HAS_C_LIB)
+ target_link_libraries(${target} PRIVATE c)
+ endif()
+
+ if (LIBCXX_HAS_M_LIB)
+ target_link_libraries(${target} PRIVATE m)
+ endif()
+
+ if (LIBCXX_HAS_RT_LIB)
+ target_link_libraries(${target} PRIVATE rt)
+ endif()
+
+ if (LIBCXX_USE_COMPILER_RT)
+ find_compiler_rt_library(builtins LIBCXX_BUILTINS_LIBRARY)
+ if (LIBCXX_BUILTINS_LIBRARY)
+ target_link_libraries(${target} PRIVATE "${LIBCXX_BUILTINS_LIBRARY}")
+ endif()
+ elseif (LIBCXX_HAS_GCC_LIB)
+ target_link_libraries(${target} PRIVATE gcc)
+ elseif (LIBCXX_HAS_GCC_S_LIB)
+ target_link_libraries(${target} PRIVATE gcc_s)
+ endif()
+
+ if (LIBCXX_HAS_ATOMIC_LIB)
+ target_link_libraries(${target} PRIVATE atomic)
+ endif()
+
+ if (MINGW)
+ target_link_libraries(${target} PRIVATE "${MINGW_LIBRARIES}")
+ endif()
+
+ if (LIBCXX_TARGETING_MSVC)
+ if (LIBCXX_DEBUG_BUILD)
+ set(LIB_SUFFIX "d")
+ else()
+ set(LIB_SUFFIX "")
+ endif()
+
+ target_link_libraries(${target} PRIVATE ucrt${LIB_SUFFIX}) # Universal C runtime
+ target_link_libraries(${target} PRIVATE vcruntime${LIB_SUFFIX}) # C++ runtime
+ target_link_libraries(${target} PRIVATE msvcrt${LIB_SUFFIX}) # C runtime startup files
+ target_link_libraries(${target} PRIVATE msvcprt${LIB_SUFFIX}) # C++ standard library. Required for exception_ptr internals.
+ # Required for standards-complaint wide character formatting functions
+ # (e.g. `printfw`/`scanfw`)
+ target_link_libraries(${target} PRIVATE iso_stdio_wide_specifiers)
+ endif()
+
+ if (ANDROID AND ANDROID_PLATFORM_LEVEL LESS 21)
+ target_link_libraries(${target} PUBLIC android_support)
+ endif()
+endfunction()
+
+# Windows-related flags =======================================================
+function(cxx_add_windows_flags target)
+ if(WIN32 AND NOT MINGW)
+ target_compile_definitions(${target} PRIVATE
+ # Ignore the -MSC_VER mismatch, as we may build
+ # with a different compatibility version.
+ _ALLOW_MSC_VER_MISMATCH
+ # Don't check the msvcprt iterator debug levels
+ # as we will define the iterator types; libc++
+ # uses a different macro to identify the debug
+ # level.
+ _ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH
+ # We are building the c++ runtime, don't pull in
+ # msvcprt.
+ _CRTBLD
+ # Don't warn on the use of "deprecated"
+ # "insecure" functions which are standards
+ # specified.
+ _CRT_SECURE_NO_WARNINGS
+ # Use the ISO conforming behaviour for conversion
+ # in printf, scanf.
+ _CRT_STDIO_ISO_WIDE_SPECIFIERS)
+ endif()
+endfunction()
+
+# Configuration file flags =====================================================
+config_define(${LIBCXX_ABI_VERSION} _LIBCPP_ABI_VERSION)
+config_define(${LIBCXX_ABI_NAMESPACE} _LIBCPP_ABI_NAMESPACE)
+config_define_if(LIBCXX_ABI_FORCE_ITANIUM _LIBCPP_ABI_FORCE_ITANIUM)
+config_define_if(LIBCXX_ABI_FORCE_MICROSOFT _LIBCPP_ABI_FORCE_MICROSOFT)
+config_define_if_not(LIBCXX_ENABLE_THREADS _LIBCPP_HAS_NO_THREADS)
+config_define_if_not(LIBCXX_ENABLE_MONOTONIC_CLOCK _LIBCPP_HAS_NO_MONOTONIC_CLOCK)
+if (NOT LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION STREQUAL "default")
+ config_define("${LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION}" _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION)
+endif()
+config_define_if(LIBCXX_HAS_PTHREAD_API _LIBCPP_HAS_THREAD_API_PTHREAD)
+config_define_if(LIBCXX_HAS_EXTERNAL_THREAD_API _LIBCPP_HAS_THREAD_API_EXTERNAL)
+config_define_if(LIBCXX_HAS_WIN32_THREAD_API _LIBCPP_HAS_THREAD_API_WIN32)
+config_define_if(LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY _LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL)
+config_define_if(LIBCXX_HAS_MUSL_LIBC _LIBCPP_HAS_MUSL_LIBC)
+config_define_if(LIBCXX_NO_VCRUNTIME _LIBCPP_NO_VCRUNTIME)
+config_define_if(LIBCXX_ENABLE_PARALLEL_ALGORITHMS _LIBCPP_HAS_PARALLEL_ALGORITHMS)
+config_define_if_not(LIBCXX_ENABLE_FILESYSTEM _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
+config_define_if_not(LIBCXX_ENABLE_RANDOM_DEVICE _LIBCPP_HAS_NO_RANDOM_DEVICE)
+config_define_if_not(LIBCXX_ENABLE_LOCALIZATION _LIBCPP_HAS_NO_LOCALIZATION)
+config_define_if_not(LIBCXX_ENABLE_UNICODE _LIBCPP_HAS_NO_UNICODE)
+config_define_if_not(LIBCXX_ENABLE_WIDE_CHARACTERS _LIBCPP_HAS_NO_WIDE_CHARACTERS)
+config_define_if_not(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS)
+config_define_if(LIBCXX_ENABLE_DEBUG_MODE _LIBCPP_ENABLE_DEBUG_MODE)
+if (LIBCXX_ENABLE_ASSERTIONS)
+ config_define(1 _LIBCPP_ENABLE_ASSERTIONS_DEFAULT)
+else()
+ config_define(0 _LIBCPP_ENABLE_ASSERTIONS_DEFAULT)
+endif()
+
+if (LIBCXX_ABI_DEFINES)
+ set(abi_defines)
+ foreach (abi_define ${LIBCXX_ABI_DEFINES})
+ if (NOT abi_define MATCHES "^_LIBCPP_ABI_")
+ message(SEND_ERROR "Invalid ABI macro ${abi_define} in LIBCXX_ABI_DEFINES")
+ endif()
+ list(APPEND abi_defines "#define ${abi_define}")
+ endforeach()
+ string(REPLACE ";" "\n" abi_defines "${abi_defines}")
+ config_define(${abi_defines} _LIBCPP_ABI_DEFINES)
+endif()
+
+if (LIBCXX_EXTRA_SITE_DEFINES)
+ set(extra_site_defines)
+ foreach (extra_site_define ${LIBCXX_EXTRA_SITE_DEFINES})
+ # Allow defines such as DEFINE=VAL, transformed into "#define DEFINE VAL".
+ string(REPLACE "=" " " extra_site_define "${extra_site_define}")
+ list(APPEND extra_site_defines "#define ${extra_site_define}")
+ endforeach()
+ string(REPLACE ";" "\n" extra_site_defines "${extra_site_defines}")
+ config_define(${extra_site_defines} _LIBCPP_EXTRA_SITE_DEFINES)
+endif()
+
+# By default libc++ on Windows expects to use a shared library, which requires
+# the headers to use DLL import/export semantics. However when building a
+# static library only we modify the headers to disable DLL import/export.
+if (DEFINED WIN32 AND LIBCXX_ENABLE_STATIC AND NOT LIBCXX_ENABLE_SHARED)
+ message(STATUS "Generating custom __config for non-DLL Windows build")
+ config_define(ON _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
+endif()
+
+if (WIN32 AND LIBCXX_ENABLE_STATIC_ABI_LIBRARY)
+ # If linking libcxxabi statically into libcxx, skip the dllimport attributes
+ # on symbols we refer to from libcxxabi.
+ add_definitions(-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS)
+endif()
+
+# Setup all common build flags =================================================
+function(cxx_add_common_build_flags target)
+ cxx_add_basic_build_flags(${target})
+ cxx_add_warning_flags(${target})
+ cxx_add_windows_flags(${target})
+ cxx_add_exception_flags(${target})
+ cxx_add_rtti_flags(${target})
+ cxx_add_module_flags(${target})
+ cxx_link_system_libraries(${target})
+endfunction()
+
+#===============================================================================
+# Setup Source Code And Tests
+#===============================================================================
+add_subdirectory(include)
+add_subdirectory(src)
+add_subdirectory(utils)
+
+set(LIBCXX_TEST_DEPS "cxx_experimental")
+
+if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY)
+ list(APPEND LIBCXX_TEST_DEPS cxx_external_threads)
+endif()
+
+if (LIBCXX_INCLUDE_BENCHMARKS)
+ add_subdirectory(benchmarks)
+endif()
+
+if (LIBCXX_INCLUDE_TESTS)
+ add_subdirectory(test)
+ add_subdirectory(lib/abi)
+endif()
+
+if (LIBCXX_INCLUDE_DOCS)
+ add_subdirectory(docs)
+endif()
diff --git a/app/src/main/cpp/libcxx/CREDITS.TXT b/app/src/main/cpp/libcxx/CREDITS.TXT
new file mode 100644
index 0000000..cd5bc08
--- /dev/null
+++ b/app/src/main/cpp/libcxx/CREDITS.TXT
@@ -0,0 +1,186 @@
+This file is a partial list of people who have contributed to the LLVM/libc++
+project. If you have contributed a patch or made some other contribution to
+LLVM/libc++, please submit a patch to this file to add yourself, and it will be
+done!
+
+The list is sorted by surname and formatted to allow easy grepping and
+beautification by scripts. The fields are: name (N), email (E), web-address
+(W), PGP key ID and fingerprint (P), description (D), and snail-mail address
+(S).
+
+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.
+
+N: Dimitry Andric
+E: dimitry@andric.com
+D: Visibility fixes, minor FreeBSD portability patches.
+
+N: Holger Arnold
+E: holgerar@gmail.com
+D: Minor fix.
+
+N: Jorg Brown
+D: Ported floating-point to_chars from MSVC to libc++.
+
+N: David Chisnall
+E: theraven at theravensnest dot org
+D: FreeBSD and Solaris ports, libcxxrt support, some atomics work.
+
+N: Marshall Clow
+E: mclow.lists@gmail.com
+E: marshall@idio.com
+D: C++14 support, patches and bug fixes.
+
+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.
+
+N: Eric Fiselier
+E: eric@efcs.ca
+D: LFTS support, patches and bug fixes.
+
+N: Bill Fisher
+E: william.w.fisher@gmail.com
+D: Regex bug fixes.
+
+N: Google Inc.
+D: Copyright owner and contributor of the CityHash algorithm
+
+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.
+
+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.
+
+N: Michel Morin
+E: mimomorin@gmail.com
+D: Minor patches to is_convertible.
+
+N: Andrew Morrow
+E: andrew.c.morrow@gmail.com
+D: Minor patches and Linux fixes.
+
+N: Michael Park
+E: mcypark@gmail.com
+D: Implementation of .
+
+N: Arvid Picciani
+E: aep at exys dot org
+D: Minor patches and musl port.
+
+N: Bjorn Reese
+E: breese@users.sourceforge.net
+D: Initial regex prototype
+
+N: Nico Rieck
+E: nico.rieck@gmail.com
+D: Windows fixes
+
+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
+
+N: Craig Silverstein
+E: csilvers@google.com
+D: Implemented Cityhash as the string hash function on 64-bit machines
+
+N: Richard Smith
+D: Minor patches.
+
+N: Joerg Sonnenberger
+E: joerg@NetBSD.org
+D: NetBSD port.
+
+N: Stephan Tolksdorf
+E: st@quanttec.com
+D: Minor 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
+
+N: Larisse Voufo
+D: Minor patches.
+
+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.
+
+N: Xing Xue
+E: xingxue@ca.ibm.com
+D: AIX port
+
+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.
diff --git a/app/src/main/cpp/libcxx/LICENSE.TXT b/app/src/main/cpp/libcxx/LICENSE.TXT
new file mode 100644
index 0000000..e159d28
--- /dev/null
+++ b/app/src/main/cpp/libcxx/LICENSE.TXT
@@ -0,0 +1,311 @@
+==============================================================================
+The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:
+==============================================================================
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+---- LLVM Exceptions to the Apache 2.0 License ----
+
+As an exception, if, as a result of your compiling your source code, portions
+of this Software are embedded into an Object form of such source code, you
+may redistribute such embedded portions in such Object form without complying
+with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
+
+In addition, if you combine or link compiled forms of this Software with
+software that is licensed under the GPLv2 ("Combined Software") and if a
+court of competent jurisdiction determines that the patent provision (Section
+3), the indemnity provision (Section 9) or other Section of the License
+conflicts with the conditions of the GPLv2, you may retroactively and
+prospectively choose to deem waived or otherwise exclude such Section(s) of
+the License, but only in their entirety and only with respect to the Combined
+Software.
+
+==============================================================================
+Software from third parties included in the LLVM Project:
+==============================================================================
+The LLVM Project contains third party software which is under different license
+terms. All such code will be identified clearly using at least one of two
+mechanisms:
+1) It will be in a separate directory tree with its own `LICENSE.txt` or
+ `LICENSE` file at the top containing the specific license and restrictions
+ which apply to that software, or
+2) It will contain specific license and restriction terms at the top of every
+ file.
+
+==============================================================================
+Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy):
+==============================================================================
+
+The libc++ library is dual licensed under both the University of Illinois
+"BSD-Like" license and the MIT license. As a user of this code you may choose
+to use it under either license. As a contributor, you agree to allow your code
+to be used under both.
+
+Full text of the relevant licenses is included below.
+
+==============================================================================
+
+University of Illinois/NCSA
+Open Source License
+
+Copyright (c) 2009-2019 by the contributors listed in CREDITS.TXT
+
+All rights reserved.
+
+Developed by:
+
+ LLVM Team
+
+ University of Illinois at Urbana-Champaign
+
+ http://llvm.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+SOFTWARE.
+
+==============================================================================
+
+Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/app/src/main/cpp/libcxx/README.md b/app/src/main/cpp/libcxx/README.md
new file mode 100644
index 0000000..2eb34c7
--- /dev/null
+++ b/app/src/main/cpp/libcxx/README.md
@@ -0,0 +1,5 @@
+## libc++
+
+LLVM libc++, specifically for Android, removing exception and RTTI support.
+
+Source code is extracted from both the upstrean and AOSP `llvm-project` repository.
diff --git a/app/src/main/cpp/libcxx/TODO.TXT b/app/src/main/cpp/libcxx/TODO.TXT
new file mode 100644
index 0000000..bc78554
--- /dev/null
+++ b/app/src/main/cpp/libcxx/TODO.TXT
@@ -0,0 +1,23 @@
+This is meant to be a general place to list things that should be done "someday"
+
+CXX Runtime Library Tasks
+=========================
+* 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
+ linux. Do this for every supported c++ runtime library.
+
+Atomic Related Tasks
+====================
+* future should use for synchronization.
+
+Test Suite Tasks
+================
+* Improve the quality and portability of the locale test data.
+* Convert failure tests to use Clang Verify.
+
+Misc Tasks
+==========
+* Find all sequences of >2 underscores and eradicate them.
+* run clang-tidy on libc++
+* Document the "conditionally-supported" bits of libc++
diff --git a/app/src/main/cpp/libcxx/appveyor-reqs-install.cmd b/app/src/main/cpp/libcxx/appveyor-reqs-install.cmd
new file mode 100644
index 0000000..e3bd018
--- /dev/null
+++ b/app/src/main/cpp/libcxx/appveyor-reqs-install.cmd
@@ -0,0 +1,53 @@
+@echo on
+
+if NOT EXIST C:\projects\deps (
+ mkdir C:\projects\deps
+)
+cd C:\projects\deps
+
+::###########################################################################
+:: Setup Compiler
+::###########################################################################
+if NOT EXIST llvm-installer.exe (
+ appveyor DownloadFile https://prereleases.llvm.org/win-snapshots/LLVM-9.0.0-r357435-win32.exe -FileName llvm-installer.exe
+)
+if "%CLANG_VERSION%"=="ToT" (
+ START /WAIT llvm-installer.exe /S /D=C:\"Program Files\LLVM"
+)
+if DEFINED CLANG_VERSION @set PATH="C:\Program Files\LLVM\bin";%PATH%
+if DEFINED CLANG_VERSION clang-cl -v
+
+if DEFINED MINGW_PATH rename "C:\Program Files\Git\usr\bin\sh.exe" "sh-ignored.exe"
+if DEFINED MINGW_PATH @set "PATH=%PATH:C:\Program Files (x86)\Git\bin=%"
+if DEFINED MINGW_PATH @set "PATH=%PATH%;%MINGW_PATH%"
+if DEFINED MINGW_PATH g++ -v
+
+::###########################################################################
+:: Install a recent CMake
+::###########################################################################
+if NOT EXIST cmake (
+ appveyor DownloadFile https://cmake.org/files/v3.7/cmake-3.7.2-win64-x64.zip -FileName cmake.zip
+ 7z x cmake.zip -oC:\projects\deps > nul
+ move C:\projects\deps\cmake-* C:\projects\deps\cmake
+ rm cmake.zip
+)
+@set PATH=C:\projects\deps\cmake\bin;%PATH%
+cmake --version
+
+::###########################################################################
+:: Install Ninja
+::###########################################################################
+if NOT EXIST ninja (
+ appveyor DownloadFile https://github.com/ninja-build/ninja/releases/download/v1.6.0/ninja-win.zip -FileName ninja.zip
+ 7z x ninja.zip -oC:\projects\deps\ninja > nul
+ rm ninja.zip
+)
+@set PATH=C:\projects\deps\ninja;%PATH%
+ninja --version
+
+::###########################################################################
+:: Setup the cached copy of LLVM
+::###########################################################################
+git clone --depth=1 http://llvm.org/git/llvm.git
+
+@echo off
diff --git a/app/src/main/cpp/libcxx/appveyor.yml b/app/src/main/cpp/libcxx/appveyor.yml
new file mode 100644
index 0000000..ea2c88e
--- /dev/null
+++ b/app/src/main/cpp/libcxx/appveyor.yml
@@ -0,0 +1,71 @@
+version: '{build}'
+
+shallow_clone: true
+
+build:
+ verbosity: detailed
+
+configuration:
+ - Debug
+
+environment:
+ matrix:
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+ CMAKE_OPTIONS: -DCMAKE_C_COMPILER=clang-cl.exe -DCMAKE_CXX_COMPILER=clang-cl.exe
+ CLANG_VERSION: ToT
+ MSVC_SETUP_PATH: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat
+ MSVC_SETUP_ARG: x86
+ GENERATOR: Ninja
+ MAKE_PROGRAM: ninja
+ APPVEYOR_SAVE_CACHE_ON_ERROR: true
+# TODO: Maybe re-enable this configuration? Do we want to support MSVC 2015's runtime?
+# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+# MINGW_PATH: C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin
+# GENERATOR: MinGW Makefiles
+# MAKE_PROGRAM: mingw32-make
+# APPVEYOR_SAVE_CACHE_ON_ERROR: true
+
+install:
+ ############################################################################
+ # All external dependencies are installed in C:\projects\deps
+ ############################################################################
+ - call "%APPVEYOR_BUILD_FOLDER%\\appveyor-reqs-install.cmd"
+
+before_build:
+ - if DEFINED MSVC_SETUP_PATH call "%MSVC_SETUP_PATH%" %MSVC_SETUP_ARG%
+ - cd %APPVEYOR_BUILD_FOLDER%
+
+build_script:
+ - md C:\projects\build-libcxx
+ - cd C:\projects\build-libcxx
+ - echo %configuration%
+
+ #############################################################################
+ # Configuration Step
+ #############################################################################
+ - cmake -G "%GENERATOR%" %CMAKE_OPTIONS%
+ "-DCMAKE_BUILD_TYPE=%configuration%"
+ "-DLLVM_PATH=C:\projects\deps\llvm"
+ -DLLVM_LIT_ARGS="-sv --show-xfail --show-unsupported"
+ %APPVEYOR_BUILD_FOLDER%
+
+ #############################################################################
+ # Build Step
+ #############################################################################
+ - "%MAKE_PROGRAM%"
+
+test_script:
+ - "%MAKE_PROGRAM% check-cxx"
+
+on_failure:
+ - appveyor PushArtifact CMakeFiles/CMakeOutput.log
+ - appveyor PushArtifact CMakeFiles/CMakeError.log
+
+artifacts:
+ - path: '_build/CMakeFiles/*.log'
+ name: logs
+
+cache:
+ - C:\projects\deps\ninja
+ - C:\projects\deps\cmake
+ - C:\projects\deps\llvm-installer.exe
diff --git a/app/src/main/cpp/libcxx/arm64-v8a/libcxx.a b/app/src/main/cpp/libcxx/arm64-v8a/libcxx.a
deleted file mode 100644
index a923662..0000000
Binary files a/app/src/main/cpp/libcxx/arm64-v8a/libcxx.a and /dev/null differ
diff --git a/app/src/main/cpp/libcxx/armeabi-v7a/libcxx.a b/app/src/main/cpp/libcxx/armeabi-v7a/libcxx.a
deleted file mode 100644
index 5e94371..0000000
Binary files a/app/src/main/cpp/libcxx/armeabi-v7a/libcxx.a and /dev/null differ
diff --git a/app/src/main/cpp/libcxx/benchmarks/CMakeLists.txt b/app/src/main/cpp/libcxx/benchmarks/CMakeLists.txt
new file mode 100644
index 0000000..7eb76ac
--- /dev/null
+++ b/app/src/main/cpp/libcxx/benchmarks/CMakeLists.txt
@@ -0,0 +1,233 @@
+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()
+
+include(ExternalProject)
+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_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()
+split_list(BENCHMARK_LIBCXX_COMPILE_FLAGS)
+
+ExternalProject_Add(google-benchmark-libcxx
+ EXCLUDE_FROM_ALL ON
+ DEPENDS cxx cxx-headers
+ PREFIX benchmark-libcxx
+ 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}
+ -DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER}
+ -DCMAKE_BUILD_TYPE:STRING=RELEASE
+ -DCMAKE_INSTALL_PREFIX:PATH=
+ -DCMAKE_CXX_FLAGS:STRING=${BENCHMARK_LIBCXX_COMPILE_FLAGS}
+ -DBENCHMARK_USE_LIBCXX:BOOL=ON
+ -DBENCHMARK_ENABLE_TESTING:BOOL=OFF)
+
+#==============================================================================
+# Build Google Benchmark for the native stdlib
+#==============================================================================
+set(BENCHMARK_NATIVE_TARGET_FLAGS)
+if (LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN)
+ set(BENCHMARK_NATIVE_TARGET_FLAGS
+ --gcc-toolchain=${LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN})
+endif()
+split_list(BENCHMARK_NATIVE_TARGET_FLAGS)
+
+if (LIBCXX_BENCHMARK_NATIVE_STDLIB)
+ ExternalProject_Add(google-benchmark-native
+ EXCLUDE_FROM_ALL ON
+ PREFIX benchmark-native
+ 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}
+ -DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER}
+ -DCMAKE_CXX_FLAGS:STRING=${BENCHMARK_NATIVE_TARGET_FLAGS}
+ -DCMAKE_BUILD_TYPE:STRING=RELEASE
+ -DCMAKE_INSTALL_PREFIX:PATH=
+ -DBENCHMARK_ENABLE_TESTING:BOOL=OFF)
+endif()
+
+
+#==============================================================================
+# Benchmark tests configuration
+#==============================================================================
+add_custom_target(cxx-benchmarks)
+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)
+
+add_library( cxx-benchmarks-flags INTERFACE)
+target_compile_features( cxx-benchmarks-flags INTERFACE cxx_std_20)
+target_compile_options( cxx-benchmarks-flags INTERFACE -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 (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})
+ 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)
+ else()
+ target_link_libraries(${libcxx_target} PRIVATE cxx_static)
+ endif()
+ target_link_libraries(${libcxx_target} PRIVATE cxx_experimental benchmark)
+ if (LLVM_USE_SANITIZER)
+ target_link_libraries(${libcxx_target} PRIVATE -ldl)
+ endif()
+ set_target_properties(${libcxx_target}
+ PROPERTIES
+ OUTPUT_NAME "${name}.libcxx.out"
+ RUNTIME_OUTPUT_DIRECTORY "${BENCHMARK_OUTPUT_DIR}"
+ CXX_EXTENSIONS NO)
+ cxx_link_system_libraries(${libcxx_target})
+ if (LIBCXX_BENCHMARK_NATIVE_STDLIB)
+ 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_HAS_PTHREAD_LIB)
+ target_link_libraries(${native_target} PRIVATE -pthread)
+ endif()
+ add_dependencies(cxx-benchmarks ${native_target})
+ set_target_properties(${native_target}
+ PROPERTIES
+ OUTPUT_NAME "${name}.native.out"
+ RUNTIME_OUTPUT_DIRECTORY "${BENCHMARK_OUTPUT_DIR}"
+ CXX_EXTENSIONS NO)
+ endif()
+endfunction()
+
+
+#==============================================================================
+# Register Benchmark tests
+#==============================================================================
+set(BENCHMARK_TESTS
+ algorithms.partition_point.bench.cpp
+ algorithms/lower_bound.bench.cpp
+ algorithms/make_heap.bench.cpp
+ algorithms/make_heap_then_sort_heap.bench.cpp
+ algorithms/min_max_element.bench.cpp
+ algorithms/pop_heap.bench.cpp
+ algorithms/push_heap.bench.cpp
+ algorithms/ranges_make_heap.bench.cpp
+ algorithms/ranges_make_heap_then_sort_heap.bench.cpp
+ algorithms/ranges_pop_heap.bench.cpp
+ algorithms/ranges_push_heap.bench.cpp
+ algorithms/ranges_sort.bench.cpp
+ algorithms/ranges_sort_heap.bench.cpp
+ algorithms/ranges_stable_sort.bench.cpp
+ algorithms/sort.bench.cpp
+ algorithms/sort_heap.bench.cpp
+ algorithms/stable_sort.bench.cpp
+ allocation.bench.cpp
+ deque.bench.cpp
+ deque_iterator.bench.cpp
+ filesystem.bench.cpp
+ format_to_n.bench.cpp
+ format_to.bench.cpp
+ format.bench.cpp
+ formatted_size.bench.cpp
+ formatter_float.bench.cpp
+ formatter_int.bench.cpp
+ function.bench.cpp
+ join_view.bench.cpp
+ map.bench.cpp
+ monotonic_buffer.bench.cpp
+ ordered_set.bench.cpp
+ std_format_spec_string_unicode.bench.cpp
+ string.bench.cpp
+ stringstream.bench.cpp
+ to_chars.bench.cpp
+ unordered_set_operations.bench.cpp
+ util_smartptr.bench.cpp
+ variant_visit_1.bench.cpp
+ variant_visit_2.bench.cpp
+ variant_visit_3.bench.cpp
+ vector_operations.bench.cpp
+ )
+
+foreach(test_path ${BENCHMARK_TESTS})
+ get_filename_component(test_file "${test_path}" NAME)
+ string(REPLACE ".bench.cpp" "" test_name "${test_file}")
+ if (NOT DEFINED ${test_name}_REPORTED)
+ message(STATUS "Adding Benchmark: ${test_file}")
+ # Only report the adding of the benchmark once.
+ set(${test_name}_REPORTED ON CACHE INTERNAL "")
+ endif()
+ add_benchmark_test(${test_name} ${test_path})
+endforeach()
+
+if (LIBCXX_INCLUDE_TESTS)
+ include(AddLLVM)
+
+ if (NOT DEFINED LIBCXX_TEST_DEPS)
+ message(FATAL_ERROR "Expected LIBCXX_TEST_DEPS to be defined")
+ endif()
+
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
+ ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py)
+
+ set(BENCHMARK_LIT_ARGS "--show-all --show-xfail --show-unsupported ${LIT_ARGS_DEFAULT}")
+
+ add_lit_target(check-cxx-benchmarks
+ "Running libcxx benchmarks tests"
+ ${CMAKE_CURRENT_BINARY_DIR}
+ DEPENDS cxx-benchmarks ${LIBCXX_TEST_DEPS}
+ ARGS ${BENCHMARK_LIT_ARGS})
+endif()
diff --git a/app/src/main/cpp/libcxx/benchmarks/CartesianBenchmarks.h b/app/src/main/cpp/libcxx/benchmarks/CartesianBenchmarks.h
new file mode 100644
index 0000000..2eea156
--- /dev/null
+++ b/app/src/main/cpp/libcxx/benchmarks/CartesianBenchmarks.h
@@ -0,0 +1,133 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+#include
+#include
+#include
+
+#include "benchmark/benchmark.h"
+#include "test_macros.h"
+
+namespace internal {
+
+template
+struct EnumValue : std::integral_constant(I)> {
+ static std::string name() { return std::string("_") + D::Names[I]; }
+};
+
+template
+constexpr auto makeEnumValueTuple(std::index_sequence) {
+ return std::make_tuple(EnumValue{}...);
+}
+
+template
+static auto skip(const B& Bench, int) -> decltype(Bench.skip()) {
+ return Bench.skip();
+}
+template
+static auto skip(const B& Bench, char) {
+ return false;
+}
+
+template
+void makeBenchmarkFromValuesImpl(const Args& A, std::index_sequence) {
+ for (auto& V : A) {
+ B Bench{std::get(V)...};
+ if (!internal::skip(Bench, 0)) {
+ benchmark::RegisterBenchmark(Bench.name().c_str(),
+ [=](benchmark::State& S) { Bench.run(S); });
+ }
+ }
+}
+
+template
+void makeBenchmarkFromValues(const std::vector >& A) {
+ makeBenchmarkFromValuesImpl(A, std::index_sequence_for());
+}
+
+template class B, class Args, class... U>
+void makeBenchmarkImpl(const Args& A, std::tuple t) {
+ makeBenchmarkFromValues >(A);
+}
+
+template class B, class Args, class... U,
+ class... T, class... Tuples>
+void makeBenchmarkImpl(const Args& A, std::tuple, std::tuple,
+ Tuples... rest) {
+ (internal::makeBenchmarkImpl(A, std::tuple(), rest...), ...);
+}
+
+template
+void allValueCombinations(R& Result, const T& Final) {
+ return Result.push_back(Final);
+}
+
+template
+void allValueCombinations(R& Result, const T& Prev, const V& Value,
+ const Vs&... Values) {
+ for (const auto& E : Value) {
+ allValueCombinations(Result, std::tuple_cat(Prev, std::make_tuple(E)),
+ Values...);
+ }
+}
+
+} // namespace internal
+
+// CRTP class that enables using enum types as a dimension for
+// makeCartesianProductBenchmark below.
+// The type passed to `B` will be a std::integral_constant, with the
+// additional static function `name()` that returns the stringified name of the
+// label.
+//
+// Eg:
+// enum class MyEnum { A, B };
+// struct AllMyEnum : EnumValuesAsTuple {
+// static constexpr absl::string_view Names[] = {"A", "B"};
+// };
+template
+using EnumValuesAsTuple =
+ decltype(internal::makeEnumValueTuple(
+ std::make_index_sequence{}));
+
+// Instantiates B where are the combinations in the
+// cartesian product of `Tuples...`, and pass (arg0, ..., argN) as constructor
+// arguments where `(argi...)` are the combination in the cartesian product of
+// the runtime values of `A...`.
+// B requires:
+// - std::string name(args...): The name of the benchmark.
+// - void run(benchmark::State&, args...): The body of the benchmark.
+// It can also optionally provide:
+// - bool skip(args...): When `true`, skips the combination. Default is false.
+//
+// Returns int to facilitate registration. The return value is unspecified.
+template class B, class... Tuples, class... Args>
+int makeCartesianProductBenchmark(const Args&... A) {
+ std::vector > V;
+ internal::allValueCombinations(V, std::tuple<>(), A...);
+ internal::makeBenchmarkImpl(V, std::tuple<>(), Tuples()...);
+ return 0;
+}
+
+template
+int makeCartesianProductBenchmark(const Args&... A) {
+ std::vector > V;
+ internal::allValueCombinations(V, std::tuple<>(), A...);
+ internal::makeBenchmarkFromValues(V);
+ return 0;
+}
+
+// When `opaque` is true, this function hides the runtime state of `value` from
+// the optimizer.
+// It returns `value`.
+template
+TEST_ALWAYS_INLINE inline T maybeOpaque(T value, bool opaque) {
+ if (opaque) benchmark::DoNotOptimize(value);
+ return value;
+}
diff --git a/app/src/main/cpp/libcxx/benchmarks/ContainerBenchmarks.h b/app/src/main/cpp/libcxx/benchmarks/ContainerBenchmarks.h
new file mode 100644
index 0000000..f64869a
--- /dev/null
+++ b/app/src/main/cpp/libcxx/benchmarks/ContainerBenchmarks.h
@@ -0,0 +1,154 @@
+// -*- 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_CONTAINER_BENCHMARKS_H
+#define BENCHMARK_CONTAINER_BENCHMARKS_H
+
+#include
+
+#include "Utilities.h"
+#include "benchmark/benchmark.h"
+
+namespace ContainerBenchmarks {
+
+template
+void BM_ConstructSize(benchmark::State& st, Container) {
+ auto size = st.range(0);
+ for (auto _ : st) {
+ Container c(size);
+ DoNotOptimizeData(c);
+ }
+}
+
+template
+void BM_ConstructSizeValue(benchmark::State& st, Container, typename Container::value_type const& val) {
+ const auto size = st.range(0);
+ for (auto _ : st) {
+ Container c(size, val);
+ DoNotOptimizeData(c);
+ }
+}
+
+template
+void BM_ConstructIterIter(benchmark::State& st, Container, GenInputs gen) {
+ auto in = gen(st.range(0));
+ const auto begin = in.begin();
+ const auto end = in.end();
+ benchmark::DoNotOptimize(&in);
+ while (st.KeepRunning()) {
+ Container c(begin, end);
+ DoNotOptimizeData(c);
+ }
+}
+
+template
+void BM_InsertValue(benchmark::State& st, Container c, GenInputs gen) {
+ auto in = gen(st.range(0));
+ const auto end = in.end();
+ while (st.KeepRunning()) {
+ c.clear();
+ for (auto it = in.begin(); it != end; ++it) {
+ benchmark::DoNotOptimize(&(*c.insert(*it).first));
+ }
+ benchmark::ClobberMemory();
+ }
+}
+
+template
+void BM_InsertValueRehash(benchmark::State& st, Container c, GenInputs gen) {
+ auto in = gen(st.range(0));
+ const auto end = in.end();
+ while (st.KeepRunning()) {
+ c.clear();
+ c.rehash(16);
+ for (auto it = in.begin(); it != end; ++it) {
+ benchmark::DoNotOptimize(&(*c.insert(*it).first));
+ }
+ benchmark::ClobberMemory();
+ }
+}
+
+
+template
+void BM_InsertDuplicate(benchmark::State& st, Container c, GenInputs gen) {
+ auto in = gen(st.range(0));
+ const auto end = in.end();
+ c.insert(in.begin(), in.end());
+ benchmark::DoNotOptimize(&c);
+ benchmark::DoNotOptimize(&in);
+ while (st.KeepRunning()) {
+ for (auto it = in.begin(); it != end; ++it) {
+ benchmark::DoNotOptimize(&(*c.insert(*it).first));
+ }
+ benchmark::ClobberMemory();
+ }
+}
+
+
+template
+void BM_EmplaceDuplicate(benchmark::State& st, Container c, GenInputs gen) {
+ auto in = gen(st.range(0));
+ const auto end = in.end();
+ c.insert(in.begin(), in.end());
+ benchmark::DoNotOptimize(&c);
+ benchmark::DoNotOptimize(&in);
+ while (st.KeepRunning()) {
+ for (auto it = in.begin(); it != end; ++it) {
+ benchmark::DoNotOptimize(&(*c.emplace(*it).first));
+ }
+ benchmark::ClobberMemory();
+ }
+}
+
+template
+static void BM_Find(benchmark::State& st, Container c, GenInputs gen) {
+ auto in = gen(st.range(0));
+ c.insert(in.begin(), in.end());
+ benchmark::DoNotOptimize(&(*c.begin()));
+ const auto end = in.data() + in.size();
+ while (st.KeepRunning()) {
+ for (auto it = in.data(); it != end; ++it) {
+ benchmark::DoNotOptimize(&(*c.find(*it)));
+ }
+ benchmark::ClobberMemory();
+ }
+}
+
+template
+static void BM_FindRehash(benchmark::State& st, Container c, GenInputs gen) {
+ c.rehash(8);
+ auto in = gen(st.range(0));
+ c.insert(in.begin(), in.end());
+ benchmark::DoNotOptimize(&(*c.begin()));
+ const auto end = in.data() + in.size();
+ while (st.KeepRunning()) {
+ for (auto it = in.data(); it != end; ++it) {
+ benchmark::DoNotOptimize(&(*c.find(*it)));
+ }
+ benchmark::ClobberMemory();
+ }
+}
+
+template
+static void BM_Rehash(benchmark::State& st, Container c, GenInputs gen) {
+ auto in = gen(st.range(0));
+ c.max_load_factor(3.0);
+ c.insert(in.begin(), in.end());
+ benchmark::DoNotOptimize(c);
+ const auto bucket_count = c.bucket_count();
+ while (st.KeepRunning()) {
+ c.rehash(bucket_count + 1);
+ c.rehash(bucket_count);
+ benchmark::ClobberMemory();
+ }
+}
+
+} // end namespace ContainerBenchmarks
+
+#endif // BENCHMARK_CONTAINER_BENCHMARKS_H
diff --git a/app/src/main/cpp/libcxx/benchmarks/GenerateInput.h b/app/src/main/cpp/libcxx/benchmarks/GenerateInput.h
new file mode 100644
index 0000000..3e63f84
--- /dev/null
+++ b/app/src/main/cpp/libcxx/benchmarks/GenerateInput.h
@@ -0,0 +1,143 @@
+#ifndef BENCHMARK_GENERATE_INPUT_H
+#define BENCHMARK_GENERATE_INPUT_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+static const char Letters[] = {
+ '0','1','2','3','4',
+ '5','6','7','8','9',
+ 'A','B','C','D','E','F',
+ 'G','H','I','J','K',
+ 'L','M','N','O','P',
+ 'Q','R','S','T','U',
+ 'V','W','X','Y','Z',
+ 'a','b','c','d','e','f',
+ 'g','h','i','j','k',
+ 'l','m','n','o','p',
+ 'q','r','s','t','u',
+ 'v','w','x','y','z'
+};
+static const std::size_t LettersSize = sizeof(Letters);
+
+inline std::default_random_engine& getRandomEngine() {
+ static std::default_random_engine RandEngine(std::random_device{}());
+ return RandEngine;
+}
+
+
+inline char getRandomChar() {
+ std::uniform_int_distribution<> LettersDist(0, LettersSize-1);
+ return Letters[LettersDist(getRandomEngine())];
+}
+
+template
+inline IntT getRandomInteger(IntT Min, IntT Max) {
+ std::uniform_int_distribution dist(Min, Max);
+ return static_cast(dist(getRandomEngine()));
+}
+
+inline std::string getRandomString(std::size_t Len) {
+ std::string str(Len, 0);
+ std::generate_n(str.begin(), Len, &getRandomChar);
+ return str;
+}
+
+template
+inline std::vector getDuplicateIntegerInputs(size_t N) {
+ std::vector inputs(N, static_cast(-1));
+ return inputs;
+}
+
+template
+inline std::vector getSortedIntegerInputs(size_t N) {
+ std::vector inputs;
+ for (size_t i=0; i < N; i += 1)
+ inputs.push_back(i);
+ return inputs;
+}
+
+template
+std::vector getSortedLargeIntegerInputs(size_t N) {
+ std::vector inputs;
+ for (size_t i=0; i < N; ++i) {
+ inputs.push_back(i + N);
+ }
+ return inputs;
+}
+
+template
+std::vector getSortedTopBitsIntegerInputs(size_t N) {
+ std::vector inputs = getSortedIntegerInputs(N);
+ for (auto& E : inputs) E <<= ((sizeof(IntT) / 2) * CHAR_BIT);
+ return inputs;
+}
+
+template
+inline std::vector getReverseSortedIntegerInputs(size_t N) {
+ std::vector inputs;
+ std::size_t i = N;
+ while (i > 0) {
+ --i;
+ inputs.push_back(i);
+ }
+ return inputs;
+}
+
+template
+std::vector getPipeOrganIntegerInputs(size_t N) {
+ std::vector v; v.reserve(N);
+ for (size_t i = 0; i < N/2; ++i) v.push_back(i);
+ for (size_t i = N/2; i < N; ++i) v.push_back(N - i);
+ return v;
+}
+
+
+template
+std::vector getRandomIntegerInputs(size_t N) {
+ std::vector inputs;
+ for (size_t i=0; i < N; ++i) {
+ inputs.push_back(getRandomInteger(0, std::numeric_limits::max()));
+ }
+ return inputs;
+}
+
+inline std::vector getDuplicateStringInputs(size_t N) {
+ std::vector inputs(N, getRandomString(1024));
+ return inputs;
+}
+
+inline std::vector getRandomStringInputs(size_t N) {
+ std::vector inputs;
+ for (size_t i=0; i < N; ++i) {
+ inputs.push_back(getRandomString(1024));
+ }
+ return inputs;
+}
+
+inline std::vector getSortedStringInputs(size_t N) {
+ std::vector inputs = getRandomStringInputs(N);
+ std::sort(inputs.begin(), inputs.end());
+ return inputs;
+}
+
+inline std::vector getReverseSortedStringInputs(size_t N) {
+ std::vector inputs = getSortedStringInputs(N);
+ std::reverse(inputs.begin(), inputs.end());
+ return inputs;
+}
+
+inline std::vector getRandomCStringInputs(size_t N) {
+ static std::vector inputs = getRandomStringInputs(N);
+ std::vector cinputs;
+ for (auto const& str : inputs)
+ cinputs.push_back(str.c_str());
+ return cinputs;
+}
+
+
+#endif // BENCHMARK_GENERATE_INPUT_H
diff --git a/app/src/main/cpp/libcxx/benchmarks/Utilities.h b/app/src/main/cpp/libcxx/benchmarks/Utilities.h
new file mode 100644
index 0000000..9ad2a58
--- /dev/null
+++ b/app/src/main/cpp/libcxx/benchmarks/Utilities.h
@@ -0,0 +1,33 @@
+// -*- 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_UTILITIES_H
+#define BENCHMARK_UTILITIES_H
+
+#include
+#include
+
+#include "benchmark/benchmark.h"
+
+namespace UtilitiesInternal {
+ template
+ auto HaveDataImpl(int) -> decltype((std::declval().data(), std::true_type{}));
+ template
+ auto HaveDataImpl(long) -> std::false_type;
+ template
+ using HasData = decltype(HaveDataImpl(0));
+} // namespace UtilitiesInternal
+
+template ::value>* = nullptr>
+void DoNotOptimizeData(Container &c) { benchmark::DoNotOptimize(c.data()); }
+template ::value>* = nullptr>
+void DoNotOptimizeData(Container &c) { benchmark::DoNotOptimize(&c); }
+
+
+#endif // BENCHMARK_UTILITIES_H
diff --git a/app/src/main/cpp/libcxx/benchmarks/VariantBenchmarks.h b/app/src/main/cpp/libcxx/benchmarks/VariantBenchmarks.h
new file mode 100644
index 0000000..2feaeab
--- /dev/null
+++ b/app/src/main/cpp/libcxx/benchmarks/VariantBenchmarks.h
@@ -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
+#include
+#include
+#include
+#include
+
+#include "benchmark/benchmark.h"
+
+#include "GenerateInput.h"
+
+namespace VariantBenchmarks {
+
+template
+struct S {
+ static constexpr size_t v = I;
+};
+
+template
+static auto genVariants(std::index_sequence) {
+ using V = std::variant...>;
+ using F = V (*)();
+ static constexpr F fs[] = {[] { return V(std::in_place_index); }...};
+
+ std::array result = {};
+ for (auto& v : result) {
+ v = fs[getRandomInteger(0ul, sizeof...(Is) - 1)]();
+ }
+
+ return result;
+}
+
+template
+static void BM_Visit(benchmark::State& state) {
+ auto args = genVariants(std::make_index_sequence{});
+ 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
diff --git a/app/src/main/cpp/libcxx/benchmarks/algorithms.partition_point.bench.cpp b/app/src/main/cpp/libcxx/benchmarks/algorithms.partition_point.bench.cpp
new file mode 100644
index 0000000..8192f97
--- /dev/null
+++ b/app/src/main/cpp/libcxx/benchmarks/algorithms.partition_point.bench.cpp
@@ -0,0 +1,124 @@
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "benchmark/benchmark.h"
+
+#include "CartesianBenchmarks.h"
+#include "GenerateInput.h"
+
+namespace {
+
+template
+std::array every_10th_percentile_N(I first, N n) {
+ N step = n / 10;
+ std::array res;
+
+ for (size_t i = 0; i < 10; ++i) {
+ res[i] = first;
+ std::advance(first, step);
+ }
+
+ return res;
+}
+
+template
+struct TestIntBase {
+ static std::vector generateInput(size_t size) {
+ std::vector Res(size);
+ std::generate(Res.begin(), Res.end(),
+ [] { return getRandomInteger(0, std::numeric_limits::max()); });
+ return Res;
+ }
+};
+
+struct TestInt32 : TestIntBase {
+ static constexpr const char* Name = "TestInt32";
+};
+
+struct TestInt64 : TestIntBase {
+ static constexpr const char* Name = "TestInt64";
+};
+
+struct TestUint32 : TestIntBase {
+ static constexpr const char* Name = "TestUint32";
+};
+
+struct TestMediumString {
+ static constexpr const char* Name = "TestMediumString";
+ static constexpr size_t StringSize = 32;
+
+ static std::vector generateInput(size_t size) {
+ std::vector Res(size);
+ std::generate(Res.begin(), Res.end(), [] { return getRandomString(StringSize); });
+ return Res;
+ }
+};
+
+using AllTestTypes = std::tuple;
+
+struct LowerBoundAlg {
+ template
+ I operator()(I first, I last, const V& value) const {
+ return std::lower_bound(first, last, value);
+ }
+
+ static constexpr const char* Name = "LowerBoundAlg";
+};
+
+struct UpperBoundAlg {
+ template
+ I operator()(I first, I last, const V& value) const {
+ return std::upper_bound(first, last, value);
+ }
+
+ static constexpr const char* Name = "UpperBoundAlg";
+};
+
+struct EqualRangeAlg {
+ template
+ std::pair operator()(I first, I last, const V& value) const {
+ return std::equal_range(first, last, value);
+ }
+
+ static constexpr const char* Name = "EqualRangeAlg";
+};
+
+using AllAlgs = std::tuple;
+
+template
+struct PartitionPointBench {
+ size_t Quantity;
+
+ std::string name() const {
+ return std::string("PartitionPointBench_") + Alg::Name + "_" +
+ TestType::Name + '/' + std::to_string(Quantity);
+ }
+
+ void run(benchmark::State& state) const {
+ auto Data = TestType::generateInput(Quantity);
+ std::sort(Data.begin(), Data.end());
+ auto Every10Percentile = every_10th_percentile_N(Data.begin(), Data.size());
+
+ for (auto _ : state) {
+ for (auto Test : Every10Percentile)
+ benchmark::DoNotOptimize(Alg{}(Data.begin(), Data.end(), *Test));
+ }
+ }
+};
+
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+
+ const std::vector Quantities = {1 << 8, 1 << 10, 1 << 20};
+ makeCartesianProductBenchmark(
+ Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/app/src/main/cpp/libcxx/benchmarks/algorithms/common.h b/app/src/main/cpp/libcxx/benchmarks/algorithms/common.h
new file mode 100644
index 0000000..ffa39e2
--- /dev/null
+++ b/app/src/main/cpp/libcxx/benchmarks/algorithms/common.h
@@ -0,0 +1,244 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 LIBCXX_ALGORITHMS_COMMON_H
+#define LIBCXX_ALGORITHMS_COMMON_H
+
+#include
+#include
+#include
+#include
+
+#include "../CartesianBenchmarks.h"
+#include "../GenerateInput.h"
+
+enum class ValueType { Uint32, Uint64, Pair, Tuple, String, Float };
+struct AllValueTypes : EnumValuesAsTuple {
+ static constexpr const char* Names[] = {"uint32", "uint64", "pair", "tuple",
+ "string", "float"};
+};
+
+using Types = std::tuple< uint32_t, uint64_t, std::pair, std::tuple,
+ std::string, float >;
+
+template
+using Value = std::tuple_element_t<(int)V::value, Types>;
+
+enum class Order {
+ Random,
+ Ascending,
+ Descending,
+ SingleElement,
+ PipeOrgan,
+ Heap,
+ QuickSortAdversary,
+};
+struct AllOrders : EnumValuesAsTuple {
+ static constexpr const char* Names[] = {"Random", "Ascending",
+ "Descending", "SingleElement",
+ "PipeOrgan", "Heap",
+ "QuickSortAdversary"};
+};
+
+// 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 &
+// Experience Volume 29 Issue 4 April 10, 1999 pp 341-344.
+// https://dl.acm.org/doi/10.5555/311868.311871.
+template
+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 unsigned int gas = N - 1;
+ V.resize(N);
+ for (unsigned 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 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
+void fillValues(std::vector& 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());
+ }
+}
+
+template
+void fillValues(std::vector >& V, size_t N, Order O) {
+ if (O == Order::SingleElement) {
+ V.resize(N, std::make_pair(0, 0));
+ } else {
+ while (V.size() < N)
+ // 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
+void fillValues(std::vector >& 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;
+ }
+ }
+}
+
+inline void fillValues(std::vector& 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));
+ }
+}
+
+template
+void sortValues(T& V, Order O) {
+ switch (O) {
+ case Order::Random: {
+ std::random_device R;
+ std::mt19937 M(R());
+ std::shuffle(V.begin(), V.end(), M);
+ break;
+ }
+ case Order::Ascending:
+ std::sort(V.begin(), V.end());
+ break;
+ case Order::Descending:
+ std::sort(V.begin(), V.end(), std::greater<>());
+ break;
+ case Order::SingleElement:
+ // Nothing to do
+ break;
+ case Order::PipeOrgan:
+ std::sort(V.begin(), V.end());
+ std::reverse(V.begin() + V.size() / 2, V.end());
+ break;
+ 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
+std::vector > > makeOrderedValues(size_t N,
+ Order O) {
+ std::vector > > 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
+TEST_ALWAYS_INLINE void resetCopies(benchmark::State& state, T& Copies,
+ U& Orig) {
+ state.PauseTiming();
+ for (auto& Copy : Copies)
+ Copy = Orig;
+ state.ResumeTiming();
+}
+
+enum class BatchSize {
+ CountElements,
+ CountBatch,
+};
+
+template
+void runOpOnCopies(benchmark::State& state, size_t Quantity, Order O,
+ BatchSize Count, F Body) {
+ auto Copies = makeOrderedValues(Quantity, O);
+ auto Orig = Copies;
+
+ const size_t Batch = Count == BatchSize::CountElements
+ ? Copies.size() * Quantity
+ : Copies.size();
+ while (state.KeepRunningBatch(Batch)) {
+ for (auto& Copy : Copies) {
+ Body(Copy);
+ benchmark::DoNotOptimize(Copy);
+ }
+ state.PauseTiming();
+ Copies = Orig;
+ state.ResumeTiming();
+ }
+}
+
+
+const std::vector Quantities = {1 << 0, 1 << 2, 1 << 4, 1 << 6,
+ 1 << 8, 1 << 10, 1 << 14,
+ // Running each benchmark in parallel consumes too much memory with MSAN
+ // and can lead to the test process being killed.
+#if !TEST_HAS_FEATURE(memory_sanitizer)
+ 1 << 18
+#endif
+};
+
+#endif // LIBCXX_ALGORITHMS_COMMON_H
diff --git a/app/src/main/cpp/libcxx/benchmarks/algorithms/lower_bound.bench.cpp b/app/src/main/cpp/libcxx/benchmarks/algorithms/lower_bound.bench.cpp
new file mode 100644
index 0000000..ce366d5
--- /dev/null
+++ b/app/src/main/cpp/libcxx/benchmarks/algorithms/lower_bound.bench.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+#include
+#include
+#include
+
+#include "common.h"
+
+namespace {
+template
+struct LowerBound {
+ size_t Quantity;
+
+ mutable std::mt19937_64 rng { std::random_device{}() };
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies(state, Quantity, Order::Ascending, BatchSize::CountBatch, [&](auto& Copy) {
+ auto result = std::lower_bound(Copy.begin(), Copy.end(), Copy[rng() % Copy.size()]);
+ benchmark::DoNotOptimize(result);
+ });
+ }
+
+ std::string name() const {
+ return "BM_LowerBound" + ValueType::name() + "_" + std::to_string(Quantity);
+ }
+};
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+ makeCartesianProductBenchmark(Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/app/src/main/cpp/libcxx/benchmarks/algorithms/make_heap.bench.cpp b/app/src/main/cpp/libcxx/benchmarks/algorithms/make_heap.bench.cpp
new file mode 100644
index 0000000..e2caf84
--- /dev/null
+++ b/app/src/main/cpp/libcxx/benchmarks/algorithms/make_heap.bench.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+#include "common.h"
+
+namespace {
+template
+struct MakeHeap {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies(
+ state, Quantity, Order(), BatchSize::CountElements,
+ [](auto& Copy) { std::make_heap(Copy.begin(), Copy.end()); });
+ }
+
+ std::string name() const {
+ return "BM_MakeHeap" + ValueType::name() + Order::name() + "_" +
+ std::to_string(Quantity);
+ };
+};
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+ makeCartesianProductBenchmark(Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/app/src/main/cpp/libcxx/benchmarks/algorithms/make_heap_then_sort_heap.bench.cpp b/app/src/main/cpp/libcxx/benchmarks/algorithms/make_heap_then_sort_heap.bench.cpp
new file mode 100644
index 0000000..5254c26
--- /dev/null
+++ b/app/src/main/cpp/libcxx/benchmarks/algorithms/make_heap_then_sort_heap.bench.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+#include "common.h"
+
+namespace {
+template
+struct MakeThenSortHeap {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies(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 {
+ return "BM_MakeThenSortHeap" + ValueType::name() + Order::name() + "_" +
+ std::to_string(Quantity);
+ };
+};
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+ makeCartesianProductBenchmark(Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/app/src/main/cpp/libcxx/benchmarks/algorithms/min_max_element.bench.cpp b/app/src/main/cpp/libcxx/benchmarks/algorithms/min_max_element.bench.cpp
new file mode 100644
index 0000000..e2c6423
--- /dev/null
+++ b/app/src/main/cpp/libcxx/benchmarks/algorithms/min_max_element.bench.cpp
@@ -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
+
+#include "common.h"
+
+namespace {
+template
+struct MinMaxElement {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies(state, Quantity, Order(), BatchSize::CountElements, [](auto& Copy) {
+ benchmark::DoNotOptimize(std::minmax_element(Copy.begin(), Copy.end()));
+ });
+ }
+
+ std::string name() const {
+ return "BM_MinMaxElement" + ValueType::name() + Order::name() + "_" + std::to_string(Quantity);
+ }
+};
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+ makeCartesianProductBenchmark(Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/app/src/main/cpp/libcxx/benchmarks/algorithms/pop_heap.bench.cpp b/app/src/main/cpp/libcxx/benchmarks/algorithms/pop_heap.bench.cpp
new file mode 100644
index 0000000..ef6e5a6
--- /dev/null
+++ b/app/src/main/cpp/libcxx/benchmarks/algorithms/pop_heap.bench.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+#include "common.h"
+
+namespace {
+template
+struct PopHeap {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies(
+ 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 {
+ return "BM_PopHeap" + ValueType::name() + "_" + std::to_string(Quantity);
+ };
+};
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+ makeCartesianProductBenchmark(Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/app/src/main/cpp/libcxx/benchmarks/algorithms/push_heap.bench.cpp b/app/src/main/cpp/libcxx/benchmarks/algorithms/push_heap.bench.cpp
new file mode 100644
index 0000000..8c33324
--- /dev/null
+++ b/app/src/main/cpp/libcxx/benchmarks/algorithms/push_heap.bench.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+#include "common.h"
+
+namespace {
+template
+struct PushHeap {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies(
+ 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; }
+
+ std::string name() const {
+ return "BM_PushHeap" + ValueType::name() + Order::name() + "_" +
+ std::to_string(Quantity);
+ };
+};
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+ makeCartesianProductBenchmark(Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/app/src/main/cpp/libcxx/benchmarks/algorithms/ranges_make_heap.bench.cpp b/app/src/main/cpp/libcxx/benchmarks/algorithms/ranges_make_heap.bench.cpp
new file mode 100644
index 0000000..b5b6132
--- /dev/null
+++ b/app/src/main/cpp/libcxx/benchmarks/algorithms/ranges_make_heap.bench.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+#include "common.h"
+
+namespace {
+template
+struct RangesMakeHeap {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies(
+ state, Quantity, Order(), BatchSize::CountElements,
+ [](auto& Copy) { std::ranges::make_heap(Copy); });
+ }
+
+ std::string name() const {
+ return "BM_RangesMakeHeap" + ValueType::name() + Order::name() + "_" +
+ std::to_string(Quantity);
+ };
+};
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+ makeCartesianProductBenchmark(Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/app/src/main/cpp/libcxx/benchmarks/algorithms/ranges_make_heap_then_sort_heap.bench.cpp b/app/src/main/cpp/libcxx/benchmarks/algorithms/ranges_make_heap_then_sort_heap.bench.cpp
new file mode 100644
index 0000000..f286951
--- /dev/null
+++ b/app/src/main/cpp/libcxx/benchmarks/algorithms/ranges_make_heap_then_sort_heap.bench.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+#include "common.h"
+
+namespace {
+template
+struct RangesMakeThenSortHeap {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies(state, Quantity, Order(), BatchSize::CountElements,
+ [](auto& Copy) {
+ std::ranges::make_heap(Copy);
+ std::ranges::sort_heap(Copy);
+ });
+ }
+
+ std::string name() const {
+ return "BM_RangesMakeThenSortHeap" + ValueType::name() + Order::name() + "_" +
+ std::to_string(Quantity);
+ };
+};
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+ makeCartesianProductBenchmark(Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/app/src/main/cpp/libcxx/benchmarks/algorithms/ranges_pop_heap.bench.cpp b/app/src/main/cpp/libcxx/benchmarks/algorithms/ranges_pop_heap.bench.cpp
new file mode 100644
index 0000000..b26ccdd
--- /dev/null
+++ b/app/src/main/cpp/libcxx/benchmarks/algorithms/ranges_pop_heap.bench.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+#include "common.h"
+
+namespace {
+template
+struct RangesPopHeap {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies(
+ state, Quantity, Order(), BatchSize::CountElements, [](auto& Copy) {
+ for (auto B = Copy.begin(), I = Copy.end(); I != B; --I) {
+ std::ranges::pop_heap(B, I);
+ }
+ });
+ }
+
+ std::string name() const {
+ return "BM_RangesPopHeap" + ValueType::name() + "_" + std::to_string(Quantity);
+ };
+};
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+ makeCartesianProductBenchmark(Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/app/src/main/cpp/libcxx/benchmarks/algorithms/ranges_push_heap.bench.cpp b/app/src/main/cpp/libcxx/benchmarks/algorithms/ranges_push_heap.bench.cpp
new file mode 100644
index 0000000..28ccf41
--- /dev/null
+++ b/app/src/main/cpp/libcxx/benchmarks/algorithms/ranges_push_heap.bench.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+#include "common.h"
+
+namespace {
+template
+struct RangesPushHeap {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies(
+ state, Quantity, Order(), BatchSize::CountElements, [](auto& Copy) {
+ for (auto I = Copy.begin(), E = Copy.end(); I != E; ++I) {
+ std::ranges::push_heap(Copy.begin(), I + 1);
+ }
+ });
+ }
+
+ bool skip() const { return Order() == ::Order::Heap; }
+
+ std::string name() const {
+ return "BM_RangesPushHeap" + ValueType::name() + Order::name() + "_" +
+ std::to_string(Quantity);
+ };
+};
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+ makeCartesianProductBenchmark(Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/app/src/main/cpp/libcxx/benchmarks/algorithms/ranges_sort.bench.cpp b/app/src/main/cpp/libcxx/benchmarks/algorithms/ranges_sort.bench.cpp
new file mode 100644
index 0000000..b9299d3
--- /dev/null
+++ b/app/src/main/cpp/libcxx/benchmarks/algorithms/ranges_sort.bench.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+#include "common.h"
+
+namespace {
+template
+struct Sort {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies(
+ state, Quantity, Order(), BatchSize::CountElements,
+ [](auto& Copy) { std::ranges::sort(Copy); });
+ }
+
+ bool skip() const { return Order() == ::Order::Heap; }
+
+ std::string name() const {
+ return "BM_RangesSort" + ValueType::name() + Order::name() + "_" +
+ std::to_string(Quantity);
+ }
+};
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+ makeCartesianProductBenchmark(Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/app/src/main/cpp/libcxx/benchmarks/algorithms/ranges_sort_heap.bench.cpp b/app/src/main/cpp/libcxx/benchmarks/algorithms/ranges_sort_heap.bench.cpp
new file mode 100644
index 0000000..12828a0
--- /dev/null
+++ b/app/src/main/cpp/libcxx/benchmarks/algorithms/ranges_sort_heap.bench.cpp
@@ -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
+
+#include "common.h"
+
+namespace {
+template
+struct RangesSortHeap {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies(
+ state, Quantity, Order::Heap, BatchSize::CountElements,
+ [](auto& Copy) { std::ranges::sort_heap(Copy); });
+ }
+
+ std::string name() const {
+ return "BM_RangesSortHeap" + ValueType::name() + "_" + std::to_string(Quantity);
+ };
+};
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+ makeCartesianProductBenchmark(Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/app/src/main/cpp/libcxx/benchmarks/algorithms/ranges_stable_sort.bench.cpp b/app/src/main/cpp/libcxx/benchmarks/algorithms/ranges_stable_sort.bench.cpp
new file mode 100644
index 0000000..94f8003
--- /dev/null
+++ b/app/src/main/cpp/libcxx/benchmarks/algorithms/ranges_stable_sort.bench.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+#include "common.h"
+
+namespace {
+template
+struct StableSort {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies(
+ state, Quantity, Order(), BatchSize::CountElements,
+ [](auto& Copy) { std::ranges::stable_sort(Copy); });
+ }
+
+ bool skip() const { return Order() == ::Order::Heap; }
+
+ std::string name() const {
+ return "BM_RangesStableSort" + ValueType::name() + Order::name() + "_" +
+ std::to_string(Quantity);
+ }
+};
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+ makeCartesianProductBenchmark(Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/app/src/main/cpp/libcxx/benchmarks/algorithms/sort.bench.cpp b/app/src/main/cpp/libcxx/benchmarks/algorithms/sort.bench.cpp
new file mode 100644
index 0000000..6f8b12e
--- /dev/null
+++ b/app/src/main/cpp/libcxx/benchmarks/algorithms/sort.bench.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+#include "common.h"
+
+namespace {
+template
+struct Sort {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies(
+ state, Quantity, Order(), BatchSize::CountElements,
+ [](auto& Copy) { std::sort(Copy.begin(), Copy.end()); });
+ }
+
+ bool skip() const { return Order() == ::Order::Heap; }
+
+ std::string name() const {
+ return "BM_Sort" + ValueType::name() + Order::name() + "_" +
+ std::to_string(Quantity);
+ };
+};
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+ makeCartesianProductBenchmark(Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/app/src/main/cpp/libcxx/benchmarks/algorithms/sort_heap.bench.cpp b/app/src/main/cpp/libcxx/benchmarks/algorithms/sort_heap.bench.cpp
new file mode 100644
index 0000000..a217211
--- /dev/null
+++ b/app/src/main/cpp/libcxx/benchmarks/algorithms/sort_heap.bench.cpp
@@ -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
+
+#include "common.h"
+
+namespace {
+template
+struct SortHeap {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies(
+ state, Quantity, Order::Heap, BatchSize::CountElements,
+ [](auto& Copy) { std::sort_heap(Copy.begin(), Copy.end()); });
+ }
+
+ std::string name() const {
+ return "BM_SortHeap" + ValueType::name() + "_" + std::to_string(Quantity);
+ };
+};
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+ makeCartesianProductBenchmark