From f4e0c5486c4c70e962cb391db111e60109b4324a Mon Sep 17 00:00:00 2001 From: chiteroman <98092901+chiteroman@users.noreply.github.com> Date: Fri, 19 Jan 2024 00:38:07 +0100 Subject: [PATCH] Remove old files --- .gitmodules | 6 +- app/proguard-rules.pro | 3 +- app/src/main/cpp/Dobby | 1 + app/src/main/cpp/Dobby/.clang-format | 18 - .../cpp/Dobby/.github/workflows/Builder.yaml | 114 - app/src/main/cpp/Dobby/.gitignore | 80 - .../cpp/Dobby/.vscode/c_cpp_properties.json | 74 - app/src/main/cpp/Dobby/.vscode/launch.json | 17 - app/src/main/cpp/Dobby/.vscode/settings.json | 121 - app/src/main/cpp/Dobby/.vscode/tags | 13 - app/src/main/cpp/Dobby/CMakeLists.txt | 362 - app/src/main/cpp/Dobby/LICENSE | 201 - app/src/main/cpp/Dobby/README.md | 26 - app/src/main/cpp/Dobby/README_zh-cn.md | 3 - .../MGCopyAnswerMonitor.cc | 46 - .../dynamic_loader_monitor.cc | 94 - .../file_operation_monitor.cc | 97 - .../memory_operation_instrument.cc | 58 - ...posix_file_descriptor_operation_monitor.cc | 120 - .../posix_socket_network_monitor.cc | 57 - .../BionicLinkerUtil/bionic_linker_demo.cc | 36 - .../BionicLinkerUtil/bionic_linker_util.cc | 197 - .../BionicLinkerUtil/bionic_linker_util.h | 23 - .../cpp/Dobby/builtin-plugin/CMakeLists.txt | 15 - .../ImportTableReplace/CMakeLists.txt | 3 - .../dobby_import_replace.cc | 192 - .../ImportTableReplace/dobby_import_replace.h | 11 - .../ObjcRuntimeReplace/CMakeLists.txt | 7 - .../ObjcRuntimeReplace/objc_runtime_repalce.h | 18 - .../objc_runtime_replace.mm | 56 - .../SupervisorCallMonitor/CMakeLists.txt | 23 - .../SupervisorCallMonitor/README | 1 - .../mach_system_call_log_handler.cc | 193 - .../SupervisorCallMonitor/misc_utility.cc | 44 - .../SupervisorCallMonitor/misc_utility.h | 28 - .../sensitive_api_monitor.cc | 95 - .../supervisor_call_monitor.cc | 138 - .../supervisor_call_monitor.h | 24 - .../system_call_log_handler.cc | 98 - .../test_supervisor_call_monitor.cc | 16 - .../SymbolResolver/CMakeLists.txt | 44 - .../SymbolResolver/dobby_symbol_resolver.h | 15 - .../elf/dobby_symbol_resolver.cc | 292 - .../macho/dobby_symbol_resolver.cc | 454 -- .../macho/dobby_symbol_resolver_priv.h | 46 - ...dyld_shared_cache_symbol_table_iterator.cc | 241 - .../macho/shared-cache/dyld_cache_format.h | 530 -- .../macho/shared_cache_internal.h | 70 - .../pe/dobby_symbol_resolver.cc | 26 - app/src/main/cpp/Dobby/cmake/Macros.cmake | 3 - app/src/main/cpp/Dobby/cmake/Util.cmake | 19 - .../cpp/Dobby/cmake/auto_source_group.cmake | 32 - .../Dobby/cmake/build_environment_check.cmake | 86 - .../cpp/Dobby/cmake/compiler_and_linker.cmake | 53 - .../cpp/Dobby/cmake/dobby.xcode.source.cmake | 94 - .../cmake/platform/platform-darwin.cmake | 30 - .../Dobby/cmake/xcode_generator_helper.cmake | 9 - app/src/main/cpp/Dobby/docs/compile.md | 90 - .../main/cpp/Dobby/examples/CMakeLists.txt | 17 - app/src/main/cpp/Dobby/examples/main.cc | 14 - .../main/cpp/Dobby/examples/socket_example.cc | 212 - .../cpp/Dobby/external/TINYSTL/allocator.h | 49 - .../main/cpp/Dobby/external/TINYSTL/buffer.h | 310 - .../main/cpp/Dobby/external/TINYSTL/hash.h | 53 - .../cpp/Dobby/external/TINYSTL/hash_base.h | 292 - app/src/main/cpp/Dobby/external/TINYSTL/new.h | 43 - .../main/cpp/Dobby/external/TINYSTL/stddef.h | 43 - .../main/cpp/Dobby/external/TINYSTL/string.h | 295 - .../cpp/Dobby/external/TINYSTL/string_view.h | 147 - .../main/cpp/Dobby/external/TINYSTL/traits.h | 100 - .../Dobby/external/TINYSTL/unordered_map.h | 289 - .../Dobby/external/TINYSTL/unordered_set.h | 265 - .../main/cpp/Dobby/external/TINYSTL/vector.h | 336 - .../deprecated/misc-helper/CMakeLists.txt | 18 - .../deprecated/misc-helper/async_logger.cc | 65 - .../misc-helper/deprecated/pthread_helper.cc | 129 - .../misc-helper/deprecated/pthread_helper.h | 85 - .../misc-helper/deprecated/unistd_helper.h | 30 - .../deprecated/misc-helper/format_printer.cc | 11 - .../misc-helper/misc-helper/async_logger.h | 8 - .../misc-helper/misc-helper/format_printer.h | 3 - .../misc-helper/misc-helper/variable_cache.h | 17 - .../deprecated/misc-helper/variable_cache.c | 118 - .../cpp/Dobby/external/logging/CMakeLists.txt | 17 - .../cpp/Dobby/external/logging/cxxlogging.cc | 36 - .../Dobby/external/logging/kernel_logging.c | 28 - .../main/cpp/Dobby/external/logging/logging.c | 124 - .../external/logging/logging/check_logging.h | 87 - .../external/logging/logging/cxxlogging.h | 15 - .../Dobby/external/logging/logging/logging.h | 88 - app/src/main/cpp/Dobby/include/dobby.h | 182 - app/src/main/cpp/Dobby/scripts/Dockerfile | 10 - .../cpp/Dobby/scripts/platform_builder.py | 240 - .../scripts/setup_linux_cross_compile.sh | 43 - .../scripts/setup_macos_cross_compile.sh | 22 - .../ExecMemory/clear-cache-tool-all.c | 3 - .../ExecMemory/code-patch-tool-darwin.cc | 109 - .../Darwin/ProcessRuntimeUtility.cc | 131 - .../PlatformUtil/ProcessRuntimeUtility.h | 26 - .../UnifiedInterface/exec_mem_placeholder.asm | 10 - .../UnifiedInterface/platform-darwin.cc | 106 - .../KernelMode/UnifiedInterface/platform.h | 26 - .../ExecMemory/clear-cache-tool-all.c | 145 - .../clear-cache-tool-arm-dummy.cc | 53 - .../clear-cache-tool-arm64-dummy.cc | 103 - .../ExecMemory/code-patch-tool-darwin.cc | 81 - .../ExecMemory/code-patch-tool-posix.cc | 37 - .../ExecMemory/code-patch-tool-windows.cc | 27 - .../mach_interface_support/substrated.defs | 24 - .../MultiThreadSupport/ThreadSupport.cpp | 22 - .../MultiThreadSupport/ThreadSupport.h | 63 - .../Darwin/ProcessRuntimeUtility.cc | 132 - .../Linux/ProcessRuntimeUtility.cc | 244 - .../PlatformUtil/ProcessRuntimeUtility.h | 26 - .../Windows/ProcessRuntimeUtility.cc | 81 - .../Backend/UserMode/Thread/PlatformThread.cc | 19 - .../Backend/UserMode/Thread/PlatformThread.h | 36 - .../UserMode/Thread/platform-thread-posix.cc | 71 - .../Thread/platform-thread-windows.cc | 25 - .../platform-darwin/mach_vm.h | 933 --- .../UnifiedInterface/platform-posix.cc | 205 - .../UnifiedInterface/platform-windows.cc | 87 - .../UserMode/UnifiedInterface/platform.h | 109 - .../UserMode/UnifiedInterface/semaphore.cc | 160 - .../UserMode/UnifiedInterface/semaphore.h | 98 - .../InstructionRelocation.h | 5 - .../arm/InstructionRelocationARM.cc | 917 --- .../arm/InstructionRelocationARM.h | 300 - .../arm64/InstructionRelocationARM64.cc | 366 - .../arm64/InstructionRelocationARM64.h | 13 - .../arm64/inst_constants.h | 49 - .../arm64/inst_decode_encode_kit.h | 110 - .../x64/InstructionRelocationX64.cc | 78 - .../x64/InstructionRelocationX64.h | 9 - .../x86/InstructionRelocationX86.cc | 79 - .../x86/InstructionRelocationX86.h | 9 - .../x86/InstructionRelocationX86Shared.cc | 196 - .../x86/InstructionRelocationX86Shared.h | 14 - .../x86/deprecated/Ia32Disassembler.cc | 388 - .../x86/deprecated/X86OpcodoDecodeTable.cc | 604 -- .../x86/deprecated/X86OpcodoDecodeTable.h | 142 - .../x86/x86_insn_decode/build_config.h | 144 - .../x86/x86_insn_decode/x86_insn_decode.c | 564 -- .../x86/x86_insn_decode/x86_insn_decode.h | 200 - .../x86/x86_insn_decode/x86_insn_reader.c | 87 - .../x86_opcode_modrm_reg_group.c | 218 - .../x86/x86_insn_decode/x86_opcode_one_byte.c | 215 - .../x86_insn_decode/x86_opcode_sse_group.c | 545 -- .../x86/x86_insn_decode/x86_opcode_two_byte.c | 249 - .../main/cpp/Dobby/source/InterceptEntry.cpp | 18 - .../main/cpp/Dobby/source/InterceptEntry.h | 30 - .../InterceptRouting/InterceptRouting.cpp | 98 - .../InterceptRouting/InterceptRouting.h | 62 - .../FunctionInlineHook/FunctionInlineHook.cc | 51 - .../FunctionInlineHookRouting.h | 22 - .../Routing/FunctionInlineHook/RoutingImpl.cc | 22 - .../FunctionWrapper/FunctionWrapperExport.cc | 27 - .../FunctionWrapper/function-wrapper.cc | 38 - .../FunctionWrapper/function-wrapper.h | 40 - .../intercept_routing_handler.cc | 79 - .../intercept_routing_handler.h | 27 - .../InstructionInstrument.cc | 44 - .../InstructionInstrumentRouting.h | 30 - .../InstructionInstrument/RoutingImpl.cc | 42 - .../instrument_routing_handler.cc | 21 - .../instrument_routing_handler.h | 7 - .../NearBranchTrampoline.cc | 47 - .../NearBranchTrampoline.h | 15 - .../near_trampoline_arm64.cc | 82 - .../RoutingPlugin/RoutingPlugin.cc | 11 - .../RoutingPlugin/RoutingPlugin.h | 30 - app/src/main/cpp/Dobby/source/Interceptor.cpp | 40 - app/src/main/cpp/Dobby/source/Interceptor.h | 25 - .../MemoryAllocator/AssemblyCodeBuilder.cc | 34 - .../MemoryAllocator/AssemblyCodeBuilder.h | 14 - .../CodeBuffer/CodeBufferBase.cc | 53 - .../CodeBuffer/CodeBufferBase.h | 40 - .../CodeBuffer/code-buffer-arm.h | 59 - .../CodeBuffer/code-buffer-arm64.h | 24 - .../CodeBuffer/code-buffer-x64.h | 17 - .../CodeBuffer/code-buffer-x86.cc | 18 - .../CodeBuffer/code-buffer-x86.h | 11 - .../CodeBuffer/code_buffer_arm.h | 56 - .../CodeBuffer/code_buffer_arm64.h | 21 - .../CodeBuffer/code_buffer_x64.h | 14 - .../CodeBuffer/code_buffer_x86.h | 13 - .../source/MemoryAllocator/MemoryAllocator.cc | 106 - .../MemoryAllocator/NearMemoryAllocator.cc | 234 - .../MemoryAllocator/NearMemoryAllocator.h | 30 - .../ExecMemory/ClearCacheTool.h | 11 - .../ExecMemory/CodePatchTool.h | 3 - .../MemoryAllocator.h | 101 - .../ClosureTrampoline.h | 39 - .../arm/ClosureTrampolineARM.cc | 49 - .../arm/closure_bridge_arm.cc | 90 - .../arm/dummy/closure-bridge-template-arm.cc | 65 - .../dummy/closure-trampoline-template-arm.S | 40 - .../ClosureTrampolineBridge/arm/helper_arm.cc | 13 - .../arm64/ClosureTrampolineARM64.cc | 63 - .../arm64/closure_bridge_arm64.cc | 159 - .../dummy/closure-bridge-template-arm64.c | 103 - .../dummy/closure-trampoline-template-arm64.S | 47 - ...ynamic-closure-trampoline-template-arm64.S | 31 - .../arm64/helper_arm64.cc | 17 - .../common_bridge_handler.cc | 22 - .../common_bridge_handler.h | 17 - .../x64/ClosureTrampolineX64.cc | 45 - .../x64/closure_bridge_x64.cc | 141 - .../x64/dummy/closure-bridge-template-x64.c | 70 - .../dummy/closure-trampoline-template-x64.S | 23 - .../ClosureTrampolineBridge/x64/helper_x64.cc | 17 - .../x86/ClosureTrampolineX86.cc | 44 - .../x86/closure_bridge_x86.cc | 112 - .../ClosureTrampolineBridge/x86/helper_x86.cc | 16 - .../TrampolineBridge/Trampoline/Trampoline.h | 5 - .../Trampoline/arm/trampoline_arm.cc | 61 - .../Trampoline/arm64/trampoline_arm64.cc | 41 - .../Trampoline/x64/trampoline_x64.cc | 54 - .../Trampoline/x86/trampoline_x86.cc | 33 - .../main/cpp/Dobby/source/core/arch/Cpu.cc | 5 - app/src/main/cpp/Dobby/source/core/arch/Cpu.h | 7 - .../cpp/Dobby/source/core/arch/CpuFeature.cc | 7 - .../cpp/Dobby/source/core/arch/CpuFeature.h | 19 - .../cpp/Dobby/source/core/arch/CpuRegister.cc | 10 - .../cpp/Dobby/source/core/arch/CpuRegister.h | 25 - .../cpp/Dobby/source/core/arch/CpuUtils.h | 17 - .../source/core/arch/arm/constants-arm.h | 70 - .../source/core/arch/arm/registers-arm.h | 58 - .../source/core/arch/arm64/constants-arm64.h | 387 - .../source/core/arch/arm64/registers-arm64.h | 142 - .../source/core/arch/x64/constants-x64.h | 21 - .../source/core/arch/x64/registers-x64.h | 244 - .../source/core/arch/x86/constants-x86.h | 19 - .../cpp/Dobby/source/core/arch/x86/cpu-x86.cc | 98 - .../cpp/Dobby/source/core/arch/x86/cpu-x86.h | 120 - .../source/core/arch/x86/registers-x86.h | 124 - .../core/assembler/AssemblerPseudoLabel.h | 94 - .../source/core/assembler/assembler-arch.h | 28 - .../source/core/assembler/assembler-arm.cc | 41 - .../source/core/assembler/assembler-arm.h | 357 - .../source/core/assembler/assembler-arm64.cc | 25 - .../source/core/assembler/assembler-arm64.h | 563 -- .../source/core/assembler/assembler-ia32.cc | 34 - .../source/core/assembler/assembler-ia32.h | 470 -- .../source/core/assembler/assembler-x64.cc | 34 - .../source/core/assembler/assembler-x64.h | 596 -- .../core/assembler/assembler-x86-shared.cc | 17 - .../core/assembler/assembler-x86-shared.h | 710 -- .../Dobby/source/core/assembler/assembler.cc | 65 - .../Dobby/source/core/assembler/assembler.h | 76 - .../Dobby/source/core/codegen/codegen-arm.cc | 19 - .../Dobby/source/core/codegen/codegen-arm.h | 22 - .../source/core/codegen/codegen-arm64.cc | 26 - .../Dobby/source/core/codegen/codegen-arm64.h | 21 - .../Dobby/source/core/codegen/codegen-ia32.cc | 23 - .../Dobby/source/core/codegen/codegen-ia32.h | 22 - .../Dobby/source/core/codegen/codegen-x64.cc | 25 - .../Dobby/source/core/codegen/codegen-x64.h | 22 - .../cpp/Dobby/source/core/codegen/codegen.h | 17 - .../cpp/Dobby/source/core/emulator/dummy.cc | 0 app/src/main/cpp/Dobby/source/dobby.cpp | 32 - .../main/cpp/Dobby/source/dobby_internal.h | 18 - .../cpp/Dobby/source/include/common_header.h | 9 - .../Dobby/source/include/kernel_mode_header.h | 57 - .../main/cpp/Dobby/source/include/list_c.h | 52 - .../Dobby/source/include/platform_header.h | 52 - .../cpp/Dobby/source/include/platform_macro.h | 15 - .../cpp/Dobby/source/include/type_header.h | 14 - .../cpp/Dobby/source/include/utility_macro.h | 62 - app/src/main/cpp/Dobby/tests/CMakeLists.txt | 120 - .../main/cpp/Dobby/tests/UniconEmulator.cpp | 219 - app/src/main/cpp/Dobby/tests/UniconEmulator.h | 73 - .../cpp/Dobby/tests/test_insn_decoder_x86.cpp | 267 - .../cpp/Dobby/tests/test_insn_relo_arm.cpp | 116 - .../cpp/Dobby/tests/test_insn_relo_arm64.cpp | 97 - .../cpp/Dobby/tests/test_insn_relo_x64.cpp | 38 - app/src/main/cpp/Dobby/tests/test_native.cpp | 30 - app/src/main/cpp/libcxx | 1 - app/src/main/cpp/libcxx/arm64-v8a/libcxx.a | Bin 0 -> 2030488 bytes app/src/main/cpp/libcxx/armeabi-v7a/libcxx.a | Bin 0 -> 2360796 bytes .../main/cpp/libcxx/include/CMakeLists.txt | 934 +++ .../include/__algorithm/adjacent_find.h | 53 + .../cpp/libcxx/include/__algorithm/all_of.h | 32 + .../cpp/libcxx/include/__algorithm/any_of.h | 32 + .../include/__algorithm/binary_search.h | 46 + .../cpp/libcxx/include/__algorithm/clamp.h | 46 + .../cpp/libcxx/include/__algorithm/comp.h | 66 + .../include/__algorithm/comp_ref_type.h | 79 + .../cpp/libcxx/include/__algorithm/copy.h | 126 + .../include/__algorithm/copy_backward.h | 143 + .../cpp/libcxx/include/__algorithm/copy_if.h | 39 + .../include/__algorithm/copy_move_common.h | 163 + .../cpp/libcxx/include/__algorithm/copy_n.h | 67 + .../cpp/libcxx/include/__algorithm/count.h | 35 + .../cpp/libcxx/include/__algorithm/count_if.h | 35 + .../cpp/libcxx/include/__algorithm/equal.h | 86 + .../libcxx/include/__algorithm/equal_range.h | 87 + .../cpp/libcxx/include/__algorithm/fill.h | 52 + .../cpp/libcxx/include/__algorithm/fill_n.h | 45 + .../cpp/libcxx/include/__algorithm/find.h | 32 + .../cpp/libcxx/include/__algorithm/find_end.h | 227 + .../include/__algorithm/find_first_of.h | 52 + .../cpp/libcxx/include/__algorithm/find_if.h | 32 + .../libcxx/include/__algorithm/find_if_not.h | 32 + .../cpp/libcxx/include/__algorithm/for_each.h | 32 + .../libcxx/include/__algorithm/for_each_n.h | 43 + .../cpp/libcxx/include/__algorithm/generate.h | 31 + .../libcxx/include/__algorithm/generate_n.h | 36 + .../include/__algorithm/half_positive.h | 49 + .../include/__algorithm/in_found_result.h | 49 + .../include/__algorithm/in_fun_result.h | 49 + .../include/__algorithm/in_in_out_result.h | 56 + .../libcxx/include/__algorithm/in_in_result.h | 53 + .../include/__algorithm/in_out_out_result.h | 54 + .../include/__algorithm/in_out_result.h | 53 + .../cpp/libcxx/include/__algorithm/includes.h | 75 + .../include/__algorithm/inplace_merge.h | 257 + .../cpp/libcxx/include/__algorithm/is_heap.h | 44 + .../include/__algorithm/is_heap_until.h | 66 + .../include/__algorithm/is_partitioned.h | 38 + .../include/__algorithm/is_permutation.h | 238 + .../libcxx/include/__algorithm/is_sorted.h | 44 + .../include/__algorithm/is_sorted_until.h | 56 + .../libcxx/include/__algorithm/iter_swap.h | 32 + .../include/__algorithm/iterator_operations.h | 175 + .../__algorithm/lexicographical_compare.h | 62 + .../libcxx/include/__algorithm/lower_bound.h | 68 + .../libcxx/include/__algorithm/make_heap.h | 56 + .../include/__algorithm/make_projected.h | 126 + .../main/cpp/libcxx/include/__algorithm/max.h | 71 + .../libcxx/include/__algorithm/max_element.h | 57 + .../cpp/libcxx/include/__algorithm/merge.h | 70 + .../main/cpp/libcxx/include/__algorithm/min.h | 71 + .../libcxx/include/__algorithm/min_element.h | 70 + .../include/__algorithm/min_max_result.h | 56 + .../cpp/libcxx/include/__algorithm/minmax.h | 69 + .../include/__algorithm/minmax_element.h | 101 + .../cpp/libcxx/include/__algorithm/mismatch.h | 63 + .../cpp/libcxx/include/__algorithm/move.h | 130 + .../include/__algorithm/move_backward.h | 139 + .../include/__algorithm/next_permutation.h | 78 + .../cpp/libcxx/include/__algorithm/none_of.h | 32 + .../libcxx/include/__algorithm/nth_element.h | 258 + .../libcxx/include/__algorithm/partial_sort.h | 96 + .../include/__algorithm/partial_sort_copy.h | 88 + .../libcxx/include/__algorithm/partition.h | 98 + .../include/__algorithm/partition_copy.h | 47 + .../include/__algorithm/partition_point.h | 48 + .../cpp/libcxx/include/__algorithm/pop_heap.h | 73 + .../include/__algorithm/prev_permutation.h | 79 + .../libcxx/include/__algorithm/push_heap.h | 77 + .../__algorithm/ranges_adjacent_find.h | 78 + .../include/__algorithm/ranges_all_of.h | 68 + .../include/__algorithm/ranges_any_of.h | 68 + .../__algorithm/ranges_binary_search.h | 63 + .../libcxx/include/__algorithm/ranges_clamp.h | 65 + .../libcxx/include/__algorithm/ranges_copy.h | 67 + .../__algorithm/ranges_copy_backward.h | 65 + .../include/__algorithm/ranges_copy_if.h | 81 + .../include/__algorithm/ranges_copy_n.h | 77 + .../libcxx/include/__algorithm/ranges_count.h | 62 + .../include/__algorithm/ranges_count_if.h | 72 + .../libcxx/include/__algorithm/ranges_equal.h | 115 + .../include/__algorithm/ranges_equal_range.h | 78 + .../libcxx/include/__algorithm/ranges_fill.h | 59 + .../include/__algorithm/ranges_fill_n.h | 48 + .../libcxx/include/__algorithm/ranges_find.h | 63 + .../include/__algorithm/ranges_find_end.h | 98 + .../__algorithm/ranges_find_first_of.h | 101 + .../include/__algorithm/ranges_find_if.h | 71 + .../include/__algorithm/ranges_find_if_not.h | 63 + .../include/__algorithm/ranges_for_each.h | 78 + .../include/__algorithm/ranges_for_each_n.h | 66 + .../include/__algorithm/ranges_generate.h | 73 + .../include/__algorithm/ranges_generate_n.h | 62 + .../include/__algorithm/ranges_includes.h | 95 + .../__algorithm/ranges_inplace_merge.h | 85 + .../include/__algorithm/ranges_is_heap.h | 74 + .../__algorithm/ranges_is_heap_until.h | 75 + .../__algorithm/ranges_is_partitioned.h | 81 + .../__algorithm/ranges_is_permutation.h | 89 + .../include/__algorithm/ranges_is_sorted.h | 61 + .../__algorithm/ranges_is_sorted_until.h | 76 + .../__algorithm/ranges_iterator_concept.h | 51 + .../ranges_lexicographical_compare.h | 98 + .../include/__algorithm/ranges_lower_bound.h | 66 + .../include/__algorithm/ranges_make_heap.h | 80 + .../libcxx/include/__algorithm/ranges_max.h | 93 + .../include/__algorithm/ranges_max_element.h | 61 + .../libcxx/include/__algorithm/ranges_merge.h | 142 + .../libcxx/include/__algorithm/ranges_min.h | 89 + .../include/__algorithm/ranges_min_element.h | 74 + .../include/__algorithm/ranges_minmax.h | 134 + .../__algorithm/ranges_minmax_element.h | 72 + .../include/__algorithm/ranges_mismatch.h | 85 + .../libcxx/include/__algorithm/ranges_move.h | 71 + .../__algorithm/ranges_move_backward.h | 73 + .../__algorithm/ranges_next_permutation.h | 73 + .../include/__algorithm/ranges_none_of.h | 68 + .../include/__algorithm/ranges_nth_element.h | 80 + .../include/__algorithm/ranges_partial_sort.h | 78 + .../__algorithm/ranges_partial_sort_copy.h | 92 + .../include/__algorithm/ranges_partition.h | 83 + .../__algorithm/ranges_partition_copy.h | 98 + .../__algorithm/ranges_partition_point.h | 88 + .../include/__algorithm/ranges_pop_heap.h | 81 + .../__algorithm/ranges_prev_permutation.h | 77 + .../include/__algorithm/ranges_push_heap.h | 80 + .../include/__algorithm/ranges_remove.h | 64 + .../include/__algorithm/ranges_remove_copy.h | 76 + .../__algorithm/ranges_remove_copy_if.h | 90 + .../include/__algorithm/ranges_remove_if.h | 85 + .../include/__algorithm/ranges_replace.h | 74 + .../include/__algorithm/ranges_replace_copy.h | 91 + .../__algorithm/ranges_replace_copy_if.h | 93 + .../include/__algorithm/ranges_replace_if.h | 77 + .../include/__algorithm/ranges_reverse.h | 83 + .../include/__algorithm/ranges_reverse_copy.h | 67 + .../include/__algorithm/ranges_rotate.h | 71 + .../include/__algorithm/ranges_rotate_copy.h | 68 + .../include/__algorithm/ranges_sample.h | 74 + .../include/__algorithm/ranges_search.h | 135 + .../include/__algorithm/ranges_search_n.h | 117 + .../__algorithm/ranges_set_difference.h | 106 + .../__algorithm/ranges_set_intersection.h | 117 + .../ranges_set_symmetric_difference.h | 117 + .../include/__algorithm/ranges_set_union.h | 121 + .../include/__algorithm/ranges_shuffle.h | 71 + .../libcxx/include/__algorithm/ranges_sort.h | 79 + .../include/__algorithm/ranges_sort_heap.h | 80 + .../__algorithm/ranges_stable_partition.h | 88 + .../include/__algorithm/ranges_stable_sort.h | 79 + .../include/__algorithm/ranges_swap_ranges.h | 68 + .../include/__algorithm/ranges_transform.h | 170 + .../include/__algorithm/ranges_unique.h | 79 + .../include/__algorithm/ranges_unique_copy.h | 116 + .../include/__algorithm/ranges_upper_bound.h | 75 + .../cpp/libcxx/include/__algorithm/remove.h | 45 + .../libcxx/include/__algorithm/remove_copy.h | 38 + .../include/__algorithm/remove_copy_if.h | 38 + .../libcxx/include/__algorithm/remove_if.h | 44 + .../cpp/libcxx/include/__algorithm/replace.h | 32 + .../libcxx/include/__algorithm/replace_copy.h | 36 + .../include/__algorithm/replace_copy_if.h | 36 + .../libcxx/include/__algorithm/replace_if.h | 32 + .../cpp/libcxx/include/__algorithm/reverse.h | 65 + .../libcxx/include/__algorithm/reverse_copy.h | 32 + .../cpp/libcxx/include/__algorithm/rotate.h | 221 + .../libcxx/include/__algorithm/rotate_copy.h | 31 + .../cpp/libcxx/include/__algorithm/sample.h | 112 + .../cpp/libcxx/include/__algorithm/search.h | 201 + .../cpp/libcxx/include/__algorithm/search_n.h | 181 + .../include/__algorithm/set_difference.h | 81 + .../include/__algorithm/set_intersection.h | 99 + .../__algorithm/set_symmetric_difference.h | 105 + .../libcxx/include/__algorithm/set_union.h | 101 + .../libcxx/include/__algorithm/shift_left.h | 56 + .../libcxx/include/__algorithm/shift_right.h | 102 + .../cpp/libcxx/include/__algorithm/shuffle.h | 175 + .../libcxx/include/__algorithm/sift_down.h | 114 + .../cpp/libcxx/include/__algorithm/sort.h | 1001 +++ .../libcxx/include/__algorithm/sort_heap.h | 55 + .../include/__algorithm/stable_partition.h | 329 + .../libcxx/include/__algorithm/stable_sort.h | 247 + .../libcxx/include/__algorithm/swap_ranges.h | 60 + .../libcxx/include/__algorithm/transform.h | 43 + .../uniform_random_bit_generator_adaptor.h | 62 + .../cpp/libcxx/include/__algorithm/unique.h | 59 + .../libcxx/include/__algorithm/unique_copy.h | 122 + .../libcxx/include/__algorithm/unwrap_iter.h | 74 + .../libcxx/include/__algorithm/unwrap_range.h | 97 + .../libcxx/include/__algorithm/upper_bound.h | 68 + app/src/main/cpp/libcxx/include/__assert | 55 + .../main/cpp/libcxx/include/__availability | 288 + .../main/cpp/libcxx/include/__bit/bit_cast.h | 36 + .../main/cpp/libcxx/include/__bit/bit_ceil.h | 46 + .../main/cpp/libcxx/include/__bit/bit_floor.h | 34 + .../main/cpp/libcxx/include/__bit/bit_log2.h | 34 + .../main/cpp/libcxx/include/__bit/bit_width.h | 33 + app/src/main/cpp/libcxx/include/__bit/blsr.h | 34 + .../main/cpp/libcxx/include/__bit/byteswap.h | 55 + .../main/cpp/libcxx/include/__bit/countl.h | 104 + .../main/cpp/libcxx/include/__bit/countr.h | 70 + .../main/cpp/libcxx/include/__bit/endian.h | 38 + .../cpp/libcxx/include/__bit/has_single_bit.h | 37 + .../main/cpp/libcxx/include/__bit/popcount.h | 61 + .../main/cpp/libcxx/include/__bit/rotate.h | 53 + .../main/cpp/libcxx/include/__bit_reference | 1360 ++++ .../libcxx/include/__bsd_locale_defaults.h | 36 + .../libcxx/include/__bsd_locale_fallbacks.h | 142 + .../libcxx/include/__charconv/chars_format.h | 77 + .../include/__charconv/from_chars_result.h | 37 + .../cpp/libcxx/include/__charconv/tables.h | 154 + .../include/__charconv/to_chars_base_10.h | 185 + .../include/__charconv/to_chars_result.h | 37 + .../cpp/libcxx/include/__chrono/calendar.h | 44 + .../include/__chrono/convert_to_timespec.h | 56 + .../libcxx/include/__chrono/convert_to_tm.h | 127 + .../main/cpp/libcxx/include/__chrono/day.h | 84 + .../cpp/libcxx/include/__chrono/duration.h | 622 ++ .../cpp/libcxx/include/__chrono/file_clock.h | 85 + .../cpp/libcxx/include/__chrono/formatter.h | 716 ++ .../cpp/libcxx/include/__chrono/hh_mm_ss.h | 112 + .../include/__chrono/high_resolution_clock.h | 36 + .../cpp/libcxx/include/__chrono/literals.h | 49 + .../main/cpp/libcxx/include/__chrono/month.h | 103 + .../libcxx/include/__chrono/month_weekday.h | 106 + .../cpp/libcxx/include/__chrono/monthday.h | 129 + .../cpp/libcxx/include/__chrono/ostream.h | 238 + .../include/__chrono/parser_std_format_spec.h | 410 + .../include/__chrono/statically_widen.h | 52 + .../libcxx/include/__chrono/steady_clock.h | 44 + .../libcxx/include/__chrono/system_clock.h | 54 + .../cpp/libcxx/include/__chrono/time_point.h | 251 + .../cpp/libcxx/include/__chrono/weekday.h | 185 + .../main/cpp/libcxx/include/__chrono/year.h | 102 + .../cpp/libcxx/include/__chrono/year_month.h | 101 + .../libcxx/include/__chrono/year_month_day.h | 307 + .../include/__chrono/year_month_weekday.h | 255 + .../__compare/common_comparison_category.h | 95 + .../compare_partial_order_fallback.h | 74 + .../__compare/compare_strong_order_fallback.h | 71 + .../include/__compare/compare_three_way.h | 41 + .../__compare/compare_three_way_result.h | 44 + .../__compare/compare_weak_order_fallback.h | 71 + .../main/cpp/libcxx/include/__compare/is_eq.h | 34 + .../cpp/libcxx/include/__compare/ordering.h | 326 + .../libcxx/include/__compare/partial_order.h | 74 + .../libcxx/include/__compare/strong_order.h | 139 + .../include/__compare/synth_three_way.h | 51 + .../include/__compare/three_way_comparable.h | 59 + .../cpp/libcxx/include/__compare/weak_order.h | 102 + .../libcxx/include/__concepts/arithmetic.h | 52 + .../libcxx/include/__concepts/assignable.h | 41 + .../include/__concepts/boolean_testable.h | 38 + .../libcxx/include/__concepts/class_or_enum.h | 40 + .../__concepts/common_reference_with.h | 37 + .../libcxx/include/__concepts/common_with.h | 50 + .../libcxx/include/__concepts/constructible.h | 56 + .../include/__concepts/convertible_to.h | 37 + .../cpp/libcxx/include/__concepts/copyable.h | 39 + .../libcxx/include/__concepts/derived_from.h | 35 + .../libcxx/include/__concepts/destructible.h | 32 + .../include/__concepts/different_from.h | 31 + .../include/__concepts/equality_comparable.h | 54 + .../cpp/libcxx/include/__concepts/invocable.h | 40 + .../cpp/libcxx/include/__concepts/movable.h | 39 + .../cpp/libcxx/include/__concepts/predicate.h | 35 + .../cpp/libcxx/include/__concepts/regular.h | 33 + .../cpp/libcxx/include/__concepts/relation.h | 44 + .../cpp/libcxx/include/__concepts/same_as.h | 35 + .../libcxx/include/__concepts/semiregular.h | 33 + .../cpp/libcxx/include/__concepts/swappable.h | 121 + .../include/__concepts/totally_ordered.h | 58 + app/src/main/cpp/libcxx/include/__config | 1255 +++ app/src/main/cpp/libcxx/include/__config_site | 39 + .../main/cpp/libcxx/include/__config_site.in | 49 + .../include/__coroutine/coroutine_handle.h | 203 + .../include/__coroutine/coroutine_traits.h | 53 + .../__coroutine/noop_coroutine_handle.h | 112 + .../include/__coroutine/trivial_awaitables.h | 46 + app/src/main/cpp/libcxx/include/__debug | 266 + .../include/__debug_utils/randomize_range.h | 43 + app/src/main/cpp/libcxx/include/__errc | 217 + .../include/__expected/bad_expected_access.h | 64 + .../cpp/libcxx/include/__expected/expected.h | 973 +++ .../cpp/libcxx/include/__expected/unexpect.h | 32 + .../libcxx/include/__expected/unexpected.h | 122 + .../include/__filesystem/copy_options.h | 84 + .../include/__filesystem/directory_entry.h | 527 ++ .../include/__filesystem/directory_iterator.h | 165 + .../include/__filesystem/directory_options.h | 82 + .../libcxx/include/__filesystem/file_status.h | 72 + .../include/__filesystem/file_time_type.h | 32 + .../libcxx/include/__filesystem/file_type.h | 43 + .../include/__filesystem/filesystem_error.h | 104 + .../libcxx/include/__filesystem/operations.h | 201 + .../cpp/libcxx/include/__filesystem/path.h | 1091 +++ .../include/__filesystem/path_iterator.h | 134 + .../include/__filesystem/perm_options.h | 77 + .../cpp/libcxx/include/__filesystem/perms.h | 95 + .../recursive_directory_iterator.h | 185 + .../libcxx/include/__filesystem/space_info.h | 43 + .../cpp/libcxx/include/__filesystem/u8path.h | 108 + .../main/cpp/libcxx/include/__format/buffer.h | 573 ++ .../cpp/libcxx/include/__format/concepts.h | 78 + .../include/__format/container_adaptor.h | 70 + .../include/__format/enable_insertable.h | 35 + .../include/__format/escaped_output_table.h | 1038 +++ .../extended_grapheme_cluster_table.h | 1661 ++++ .../cpp/libcxx/include/__format/format_arg.h | 302 + .../include/__format/format_arg_store.h | 254 + .../cpp/libcxx/include/__format/format_args.h | 80 + .../libcxx/include/__format/format_context.h | 223 + .../libcxx/include/__format/format_error.h | 55 + .../include/__format/format_functions.h | 661 ++ .../cpp/libcxx/include/__format/format_fwd.h | 39 + .../include/__format/format_parse_context.h | 100 + .../libcxx/include/__format/format_string.h | 163 + .../include/__format/format_to_n_result.h | 35 + .../cpp/libcxx/include/__format/formatter.h | 54 + .../libcxx/include/__format/formatter_bool.h | 78 + .../libcxx/include/__format/formatter_char.h | 93 + .../__format/formatter_floating_point.h | 757 ++ .../include/__format/formatter_integer.h | 107 + .../include/__format/formatter_integral.h | 363 + .../include/__format/formatter_output.h | 570 ++ .../include/__format/formatter_pointer.h | 73 + .../include/__format/formatter_string.h | 159 + .../libcxx/include/__format/formatter_tuple.h | 178 + .../include/__format/parser_std_format_spec.h | 954 +++ .../__format/range_default_formatter.h | 201 + .../libcxx/include/__format/range_formatter.h | 255 + .../cpp/libcxx/include/__format/unicode.h | 489 ++ .../include/__functional/binary_function.h | 54 + .../include/__functional/binary_negate.h | 50 + .../cpp/libcxx/include/__functional/bind.h | 389 + .../libcxx/include/__functional/bind_back.h | 64 + .../libcxx/include/__functional/bind_front.h | 58 + .../libcxx/include/__functional/binder1st.h | 53 + .../libcxx/include/__functional/binder2nd.h | 53 + .../__functional/boyer_moore_searcher.h | 315 + .../cpp/libcxx/include/__functional/compose.h | 52 + .../include/__functional/default_searcher.h | 57 + .../libcxx/include/__functional/function.h | 1216 +++ .../cpp/libcxx/include/__functional/hash.h | 693 ++ .../libcxx/include/__functional/identity.h | 46 + .../cpp/libcxx/include/__functional/invoke.h | 546 ++ .../include/__functional/is_transparent.h | 35 + .../cpp/libcxx/include/__functional/mem_fn.h | 59 + .../libcxx/include/__functional/mem_fun_ref.h | 173 + .../cpp/libcxx/include/__functional/not_fn.h | 54 + .../libcxx/include/__functional/operations.h | 580 ++ .../include/__functional/perfect_forward.h | 94 + .../__functional/pointer_to_binary_function.h | 46 + .../__functional/pointer_to_unary_function.h | 46 + .../include/__functional/ranges_operations.h | 100 + .../include/__functional/reference_wrapper.h | 105 + .../include/__functional/unary_function.h | 51 + .../include/__functional/unary_negate.h | 47 + .../libcxx/include/__functional/unwrap_ref.h | 58 + .../include/__functional/weak_result_type.h | 294 + app/src/main/cpp/libcxx/include/__fwd/array.h | 26 + app/src/main/cpp/libcxx/include/__fwd/get.h | 115 + app/src/main/cpp/libcxx/include/__fwd/hash.h | 25 + .../libcxx/include/__fwd/memory_resource.h | 27 + app/src/main/cpp/libcxx/include/__fwd/pair.h | 25 + app/src/main/cpp/libcxx/include/__fwd/span.h | 37 + .../main/cpp/libcxx/include/__fwd/string.h | 110 + .../cpp/libcxx/include/__fwd/string_view.h | 50 + .../main/cpp/libcxx/include/__fwd/subrange.h | 38 + app/src/main/cpp/libcxx/include/__fwd/tuple.h | 29 + app/src/main/cpp/libcxx/include/__hash_table | 2715 +++++++ app/src/main/cpp/libcxx/include/__ios/fpos.h | 79 + .../cpp/libcxx/include/__iterator/access.h | 129 + .../cpp/libcxx/include/__iterator/advance.h | 203 + .../include/__iterator/back_insert_iterator.h | 73 + .../libcxx/include/__iterator/bounded_iter.h | 231 + .../include/__iterator/common_iterator.h | 281 + .../cpp/libcxx/include/__iterator/concepts.h | 300 + .../include/__iterator/counted_iterator.h | 310 + .../main/cpp/libcxx/include/__iterator/data.h | 51 + .../include/__iterator/default_sentinel.h | 30 + .../cpp/libcxx/include/__iterator/distance.h | 108 + .../cpp/libcxx/include/__iterator/empty.h | 44 + .../include/__iterator/erase_if_container.h | 40 + .../__iterator/front_insert_iterator.h | 71 + .../include/__iterator/incrementable_traits.h | 78 + .../__iterator/indirectly_comparable.h | 34 + .../include/__iterator/insert_iterator.h | 81 + .../include/__iterator/istream_iterator.h | 105 + .../include/__iterator/istreambuf_iterator.h | 119 + .../cpp/libcxx/include/__iterator/iter_move.h | 104 + .../cpp/libcxx/include/__iterator/iter_swap.h | 113 + .../cpp/libcxx/include/__iterator/iterator.h | 35 + .../include/__iterator/iterator_traits.h | 539 ++ .../include/__iterator/iterator_with_data.h | 100 + .../cpp/libcxx/include/__iterator/mergeable.h | 41 + .../libcxx/include/__iterator/move_iterator.h | 335 + .../libcxx/include/__iterator/move_sentinel.h | 59 + .../main/cpp/libcxx/include/__iterator/next.h | 84 + .../include/__iterator/ostream_iterator.h | 71 + .../include/__iterator/ostreambuf_iterator.h | 77 + .../libcxx/include/__iterator/permutable.h | 35 + .../main/cpp/libcxx/include/__iterator/prev.h | 77 + .../cpp/libcxx/include/__iterator/projected.h | 41 + .../include/__iterator/readable_traits.h | 92 + .../include/__iterator/reverse_access.h | 100 + .../include/__iterator/reverse_iterator.h | 533 ++ .../include/__iterator/segmented_iterator.h | 79 + .../main/cpp/libcxx/include/__iterator/size.h | 59 + .../cpp/libcxx/include/__iterator/sortable.h | 37 + .../include/__iterator/unreachable_sentinel.h | 38 + .../cpp/libcxx/include/__iterator/wrap_iter.h | 286 + app/src/main/cpp/libcxx/include/__locale | 1816 +++++ app/src/main/cpp/libcxx/include/__mbstate_t.h | 44 + .../cpp/libcxx/include/__memory/addressof.h | 76 + .../main/cpp/libcxx/include/__memory/align.h | 25 + .../include/__memory/allocate_at_least.h | 62 + .../include/__memory/allocation_guard.h | 83 + .../cpp/libcxx/include/__memory/allocator.h | 273 + .../libcxx/include/__memory/allocator_arg_t.h | 80 + .../include/__memory/allocator_destructor.h | 42 + .../include/__memory/allocator_traits.h | 410 + .../libcxx/include/__memory/assume_aligned.h | 46 + .../cpp/libcxx/include/__memory/auto_ptr.h | 84 + .../include/__memory/builtin_new_allocator.h | 70 + .../libcxx/include/__memory/compressed_pair.h | 177 + .../cpp/libcxx/include/__memory/concepts.h | 69 + .../libcxx/include/__memory/construct_at.h | 120 + .../cpp/libcxx/include/__memory/destruct_n.h | 64 + .../libcxx/include/__memory/pointer_traits.h | 242 + .../include/__memory/ranges_construct_at.h | 125 + .../ranges_uninitialized_algorithms.h | 319 + .../include/__memory/raw_storage_iterator.h | 70 + .../cpp/libcxx/include/__memory/shared_ptr.h | 2008 +++++ .../libcxx/include/__memory/swap_allocator.h | 54 + .../cpp/libcxx/include/__memory/temp_value.h | 56 + .../include/__memory/temporary_buffer.h | 87 + .../__memory/uninitialized_algorithms.h | 646 ++ .../cpp/libcxx/include/__memory/unique_ptr.h | 746 ++ .../libcxx/include/__memory/uses_allocator.h | 59 + .../__memory/uses_allocator_construction.h | 221 + .../cpp/libcxx/include/__memory/voidify.h | 30 + .../__memory_resource/memory_resource.h | 75 + .../monotonic_buffer_resource.h | 120 + .../__memory_resource/polymorphic_allocator.h | 224 + .../include/__memory_resource/pool_options.h | 38 + .../synchronized_pool_resource.h | 94 + .../unsynchronized_pool_resource.h | 106 + app/src/main/cpp/libcxx/include/__mutex_base | 523 ++ app/src/main/cpp/libcxx/include/__node_handle | 254 + .../cpp/libcxx/include/__numeric/accumulate.h | 52 + .../include/__numeric/adjacent_difference.h | 72 + .../libcxx/include/__numeric/exclusive_scan.h | 53 + .../cpp/libcxx/include/__numeric/gcd_lcm.h | 100 + .../libcxx/include/__numeric/inclusive_scan.h | 60 + .../libcxx/include/__numeric/inner_product.h | 53 + .../main/cpp/libcxx/include/__numeric/iota.h | 32 + .../cpp/libcxx/include/__numeric/midpoint.h | 95 + .../libcxx/include/__numeric/partial_sum.h | 70 + .../cpp/libcxx/include/__numeric/reduce.h | 47 + .../__numeric/transform_exclusive_scan.h | 49 + .../__numeric/transform_inclusive_scan.h | 58 + .../include/__numeric/transform_reduce.h | 54 + .../include/__random/bernoulli_distribution.h | 145 + .../include/__random/binomial_distribution.h | 228 + .../include/__random/cauchy_distribution.h | 164 + .../__random/chi_squared_distribution.h | 144 + .../include/__random/clamp_to_integral.h | 60 + .../include/__random/default_random_engine.h | 25 + .../include/__random/discard_block_engine.h | 205 + .../include/__random/discrete_distribution.h | 263 + .../__random/exponential_distribution.h | 157 + .../__random/extreme_value_distribution.h | 163 + .../include/__random/fisher_f_distribution.h | 162 + .../include/__random/gamma_distribution.h | 215 + .../include/__random/generate_canonical.h | 53 + .../include/__random/geometric_distribution.h | 143 + .../__random/independent_bits_engine.h | 267 + .../include/__random/is_seed_sequence.h | 31 + .../cpp/libcxx/include/__random/is_valid.h | 61 + .../cpp/libcxx/include/__random/knuth_b.h | 26 + .../__random/linear_congruential_engine.h | 398 + .../main/cpp/libcxx/include/__random/log2.h | 71 + .../include/__random/lognormal_distribution.h | 299 + .../__random/mersenne_twister_engine.h | 534 ++ .../__random/negative_binomial_distribution.h | 183 + .../include/__random/normal_distribution.h | 210 + .../piecewise_constant_distribution.h | 358 + .../__random/piecewise_linear_distribution.h | 374 + .../include/__random/poisson_distribution.h | 280 + .../libcxx/include/__random/random_device.h | 84 + .../main/cpp/libcxx/include/__random/ranlux.h | 31 + .../cpp/libcxx/include/__random/seed_seq.h | 177 + .../include/__random/shuffle_order_engine.h | 283 + .../include/__random/student_t_distribution.h | 155 + .../__random/subtract_with_carry_engine.h | 352 + .../__random/uniform_int_distribution.h | 292 + .../__random/uniform_random_bit_generator.h | 45 + .../__random/uniform_real_distribution.h | 162 + .../include/__random/weibull_distribution.h | 155 + .../main/cpp/libcxx/include/__ranges/access.h | 230 + .../main/cpp/libcxx/include/__ranges/all.h | 84 + .../libcxx/include/__ranges/as_rvalue_view.h | 137 + .../cpp/libcxx/include/__ranges/common_view.h | 137 + .../cpp/libcxx/include/__ranges/concepts.h | 147 + .../libcxx/include/__ranges/copyable_box.h | 180 + .../cpp/libcxx/include/__ranges/counted.h | 82 + .../cpp/libcxx/include/__ranges/dangling.h | 42 + .../main/cpp/libcxx/include/__ranges/data.h | 112 + .../cpp/libcxx/include/__ranges/drop_view.h | 308 + .../libcxx/include/__ranges/drop_while_view.h | 129 + .../libcxx/include/__ranges/elements_view.h | 423 + .../main/cpp/libcxx/include/__ranges/empty.h | 82 + .../cpp/libcxx/include/__ranges/empty_view.h | 53 + .../include/__ranges/enable_borrowed_range.h | 40 + .../cpp/libcxx/include/__ranges/enable_view.h | 50 + .../cpp/libcxx/include/__ranges/filter_view.h | 280 + .../cpp/libcxx/include/__ranges/iota_view.h | 434 ++ .../libcxx/include/__ranges/istream_view.h | 149 + .../cpp/libcxx/include/__ranges/join_view.h | 452 ++ .../libcxx/include/__ranges/lazy_split_view.h | 465 ++ .../include/__ranges/non_propagating_cache.h | 114 + .../cpp/libcxx/include/__ranges/owning_view.h | 83 + .../libcxx/include/__ranges/range_adaptor.h | 77 + .../main/cpp/libcxx/include/__ranges/rbegin.h | 131 + .../cpp/libcxx/include/__ranges/ref_view.h | 88 + .../main/cpp/libcxx/include/__ranges/rend.h | 135 + .../libcxx/include/__ranges/reverse_view.h | 191 + .../cpp/libcxx/include/__ranges/single_view.h | 102 + .../main/cpp/libcxx/include/__ranges/size.h | 148 + .../cpp/libcxx/include/__ranges/split_view.h | 232 + .../cpp/libcxx/include/__ranges/subrange.h | 291 + .../cpp/libcxx/include/__ranges/take_view.h | 343 + .../libcxx/include/__ranges/take_while_view.h | 183 + .../libcxx/include/__ranges/transform_view.h | 467 ++ .../libcxx/include/__ranges/view_interface.h | 177 + .../main/cpp/libcxx/include/__ranges/views.h | 35 + .../cpp/libcxx/include/__ranges/zip_view.h | 512 ++ .../main/cpp/libcxx/include/__split_buffer | 656 ++ app/src/main/cpp/libcxx/include/__std_stream | 361 + .../cpp/libcxx/include/__string/char_traits.h | 836 ++ .../include/__string/extern_template_lists.h | 131 + .../include/__support/android/locale_bionic.h | 72 + .../include/__support/fuchsia/xlocale.h | 22 + .../libcxx/include/__support/ibm/gettod_zos.h | 54 + .../include/__support/ibm/locale_mgmt_zos.h | 53 + .../libcxx/include/__support/ibm/nanosleep.h | 55 + .../libcxx/include/__support/ibm/xlocale.h | 129 + .../libcxx/include/__support/musl/xlocale.h | 52 + .../libcxx/include/__support/newlib/xlocale.h | 23 + .../include/__support/openbsd/xlocale.h | 35 + .../include/__support/solaris/floatingpoint.h | 13 + .../libcxx/include/__support/solaris/wchar.h | 46 + .../include/__support/solaris/xlocale.h | 75 + .../include/__support/win32/locale_win32.h | 282 + .../__support/xlocale/__nop_locale_mgmt.h | 47 + .../__support/xlocale/__posix_l_fallback.h | 115 + .../__support/xlocale/__strtonum_fallback.h | 69 + .../include/__thread/poll_with_backoff.h | 71 + .../include/__thread/timed_backoff_policy.h | 46 + .../cpp/libcxx/include/__threading_support | 706 ++ app/src/main/cpp/libcxx/include/__tree | 2758 +++++++ .../cpp/libcxx/include/__tuple_dir/apply_cv.h | 70 + .../include/__tuple_dir/make_tuple_types.h | 84 + .../libcxx/include/__tuple_dir/pair_like.h | 32 + .../include/__tuple_dir/sfinae_helpers.h | 196 + .../include/__tuple_dir/tuple_element.h | 93 + .../include/__tuple_dir/tuple_indices.h | 37 + .../libcxx/include/__tuple_dir/tuple_like.h | 51 + .../include/__tuple_dir/tuple_like_ext.h | 44 + .../libcxx/include/__tuple_dir/tuple_size.h | 75 + .../libcxx/include/__tuple_dir/tuple_types.h | 24 + .../libcxx/include/__type_traits/add_const.h | 30 + .../cpp/libcxx/include/__type_traits/add_cv.h | 30 + .../__type_traits/add_lvalue_reference.h | 53 + .../include/__type_traits/add_pointer.h | 55 + .../__type_traits/add_rvalue_reference.h | 54 + .../include/__type_traits/add_volatile.h | 30 + .../include/__type_traits/aligned_storage.h | 138 + .../include/__type_traits/aligned_union.h | 56 + .../include/__type_traits/alignment_of.h | 32 + .../libcxx/include/__type_traits/apply_cv.h | 75 + .../include/__type_traits/can_extract_key.h | 56 + .../include/__type_traits/common_reference.h | 188 + .../include/__type_traits/common_type.h | 134 + .../include/__type_traits/conditional.h | 58 + .../include/__type_traits/conjunction.h | 58 + .../libcxx/include/__type_traits/copy_cv.h | 54 + .../libcxx/include/__type_traits/copy_cvref.h | 46 + .../cpp/libcxx/include/__type_traits/decay.h | 71 + .../include/__type_traits/dependent_type.h | 25 + .../include/__type_traits/disjunction.h | 58 + .../libcxx/include/__type_traits/enable_if.h | 31 + .../cpp/libcxx/include/__type_traits/extent.h | 55 + .../has_unique_object_representation.h | 36 + .../__type_traits/has_virtual_destructor.h | 31 + .../include/__type_traits/integral_constant.h | 50 + .../include/__type_traits/is_abstract.h | 31 + .../include/__type_traits/is_aggregate.h | 33 + .../include/__type_traits/is_allocator.h | 36 + .../__type_traits/is_always_bitcastable.h | 82 + .../include/__type_traits/is_arithmetic.h | 34 + .../libcxx/include/__type_traits/is_array.h | 52 + .../include/__type_traits/is_assignable.h | 31 + .../libcxx/include/__type_traits/is_base_of.h | 32 + .../include/__type_traits/is_bounded_array.h | 38 + .../include/__type_traits/is_callable.h | 32 + .../include/__type_traits/is_char_like_type.h | 28 + .../libcxx/include/__type_traits/is_class.h | 31 + .../include/__type_traits/is_compound.h | 46 + .../libcxx/include/__type_traits/is_const.h | 45 + .../__type_traits/is_constant_evaluated.h | 32 + .../include/__type_traits/is_constructible.h | 33 + .../include/__type_traits/is_convertible.h | 108 + .../__type_traits/is_copy_assignable.h | 37 + .../__type_traits/is_copy_constructible.h | 36 + .../__type_traits/is_core_convertible.h | 36 + .../__type_traits/is_default_constructible.h | 33 + .../include/__type_traits/is_destructible.h | 102 + .../libcxx/include/__type_traits/is_empty.h | 32 + .../libcxx/include/__type_traits/is_enum.h | 31 + .../libcxx/include/__type_traits/is_final.h | 36 + .../include/__type_traits/is_floating_point.h | 37 + .../include/__type_traits/is_function.h | 43 + .../include/__type_traits/is_fundamental.h | 49 + .../is_implicitly_default_constructible.h | 48 + .../include/__type_traits/is_integral.h | 72 + .../include/__type_traits/is_literal_type.h | 34 + .../is_member_function_pointer.h | 64 + .../__type_traits/is_member_object_pointer.h | 46 + .../include/__type_traits/is_member_pointer.h | 46 + .../__type_traits/is_move_assignable.h | 36 + .../__type_traits/is_move_constructible.h | 34 + .../__type_traits/is_nothrow_assignable.h | 32 + .../__type_traits/is_nothrow_constructible.h | 78 + .../__type_traits/is_nothrow_convertible.h | 53 + .../is_nothrow_copy_assignable.h | 38 + .../is_nothrow_copy_constructible.h | 48 + .../is_nothrow_default_constructible.h | 32 + .../__type_traits/is_nothrow_destructible.h | 89 + .../is_nothrow_move_assignable.h | 37 + .../is_nothrow_move_constructible.h | 45 + .../include/__type_traits/is_null_pointer.h | 41 + .../libcxx/include/__type_traits/is_object.h | 52 + .../cpp/libcxx/include/__type_traits/is_pod.h | 31 + .../libcxx/include/__type_traits/is_pointer.h | 57 + .../include/__type_traits/is_polymorphic.h | 32 + .../__type_traits/is_primary_template.h | 34 + .../include/__type_traits/is_reference.h | 70 + .../__type_traits/is_reference_wrapper.h | 31 + .../include/__type_traits/is_referenceable.h | 41 + .../libcxx/include/__type_traits/is_same.h | 44 + .../libcxx/include/__type_traits/is_scalar.h | 62 + .../include/__type_traits/is_scoped_enum.h | 42 + .../libcxx/include/__type_traits/is_signed.h | 57 + .../include/__type_traits/is_signed_integer.h | 33 + .../include/__type_traits/is_specialization.h | 45 + .../__type_traits/is_standard_layout.h | 32 + .../include/__type_traits/is_swappable.h | 165 + .../libcxx/include/__type_traits/is_trivial.h | 32 + .../__type_traits/is_trivially_assignable.h | 33 + .../is_trivially_constructible.h | 34 + .../is_trivially_copy_assignable.h | 38 + .../is_trivially_copy_constructible.h | 33 + .../__type_traits/is_trivially_copyable.h | 32 + .../is_trivially_default_constructible.h | 32 + .../__type_traits/is_trivially_destructible.h | 45 + .../is_trivially_move_assignable.h | 36 + .../is_trivially_move_constructible.h | 33 + .../__type_traits/is_unbounded_array.h | 37 + .../libcxx/include/__type_traits/is_union.h | 31 + .../include/__type_traits/is_unsigned.h | 57 + .../__type_traits/is_unsigned_integer.h | 33 + .../__type_traits/is_valid_expansion.h | 31 + .../libcxx/include/__type_traits/is_void.h | 47 + .../include/__type_traits/is_volatile.h | 45 + .../cpp/libcxx/include/__type_traits/lazy.h | 25 + .../__type_traits/make_32_64_or_128_bit.h | 48 + .../__type_traits/make_const_lvalue_ref.h | 26 + .../include/__type_traits/make_signed.h | 86 + .../include/__type_traits/make_unsigned.h | 99 + .../include/__type_traits/maybe_const.h | 26 + .../cpp/libcxx/include/__type_traits/nat.h | 32 + .../libcxx/include/__type_traits/negation.h | 33 + .../noexcept_move_assign_container.h | 35 + .../libcxx/include/__type_traits/promote.h | 99 + .../cpp/libcxx/include/__type_traits/rank.h | 46 + .../__type_traits/remove_all_extents.h | 47 + .../include/__type_traits/remove_const.h | 42 + .../include/__type_traits/remove_const_ref.h | 27 + .../libcxx/include/__type_traits/remove_cv.h | 44 + .../include/__type_traits/remove_cvref.h | 45 + .../include/__type_traits/remove_extent.h | 47 + .../include/__type_traits/remove_pointer.h | 45 + .../include/__type_traits/remove_reference.h | 44 + .../include/__type_traits/remove_volatile.h | 42 + .../libcxx/include/__type_traits/result_of.h | 39 + .../include/__type_traits/strip_signature.h | 79 + .../include/__type_traits/type_identity.h | 33 + .../libcxx/include/__type_traits/type_list.h | 44 + .../include/__type_traits/underlying_type.h | 41 + .../cpp/libcxx/include/__type_traits/void_t.h | 29 + .../main/cpp/libcxx/include/__undef_macros | 16 + .../cpp/libcxx/include/__utility/as_const.h | 33 + .../cpp/libcxx/include/__utility/auto_cast.h | 22 + .../main/cpp/libcxx/include/__utility/cmp.h | 111 + .../include/__utility/convert_to_integral.h | 72 + .../cpp/libcxx/include/__utility/declval.h | 34 + .../include/__utility/exception_guard.h | 128 + .../cpp/libcxx/include/__utility/exchange.h | 38 + .../cpp/libcxx/include/__utility/forward.h | 38 + .../libcxx/include/__utility/forward_like.h | 46 + .../cpp/libcxx/include/__utility/in_place.h | 59 + .../include/__utility/integer_sequence.h | 153 + .../main/cpp/libcxx/include/__utility/move.h | 44 + .../main/cpp/libcxx/include/__utility/pair.h | 721 ++ .../include/__utility/piecewise_construct.h | 29 + .../libcxx/include/__utility/priority_tag.h | 26 + .../cpp/libcxx/include/__utility/rel_ops.h | 59 + .../main/cpp/libcxx/include/__utility/swap.h | 54 + .../libcxx/include/__utility/to_underlying.h | 40 + .../libcxx/include/__utility/unreachable.h | 34 + .../cpp/libcxx/include/__variant/monostate.h | 64 + .../main/cpp/libcxx/include/__verbose_abort | 57 + .../cpp/libcxx/include/abi/CMakeLists.txt | 39 + .../cpp/libcxx/include/abi/__cxxabi_config.h | 106 + app/src/main/cpp/libcxx/include/abi/cxxabi.h | 177 + app/src/main/cpp/libcxx/include/algorithm | 1926 +++++ app/src/main/cpp/libcxx/include/any | 712 ++ app/src/main/cpp/libcxx/include/array | 542 ++ app/src/main/cpp/libcxx/include/atomic | 2673 +++++++ app/src/main/cpp/libcxx/include/barrier | 339 + app/src/main/cpp/libcxx/include/bit | 91 + app/src/main/cpp/libcxx/include/bitset | 1159 +++ app/src/main/cpp/libcxx/include/cassert | 32 + app/src/main/cpp/libcxx/include/ccomplex | 27 + app/src/main/cpp/libcxx/include/cctype | 129 + app/src/main/cpp/libcxx/include/cerrno | 42 + app/src/main/cpp/libcxx/include/cfenv | 91 + app/src/main/cpp/libcxx/include/cfloat | 89 + app/src/main/cpp/libcxx/include/charconv | 847 ++ app/src/main/cpp/libcxx/include/chrono | 788 ++ app/src/main/cpp/libcxx/include/cinttypes | 271 + app/src/main/cpp/libcxx/include/ciso646 | 25 + app/src/main/cpp/libcxx/include/climits | 57 + app/src/main/cpp/libcxx/include/clocale | 62 + app/src/main/cpp/libcxx/include/cmath | 836 ++ app/src/main/cpp/libcxx/include/codecvt | 571 ++ app/src/main/cpp/libcxx/include/compare | 167 + app/src/main/cpp/libcxx/include/complex | 1568 ++++ app/src/main/cpp/libcxx/include/complex.h | 32 + app/src/main/cpp/libcxx/include/concepts | 166 + .../cpp/libcxx/include/condition_variable | 276 + app/src/main/cpp/libcxx/include/coroutine | 63 + app/src/main/cpp/libcxx/include/csetjmp | 57 + app/src/main/cpp/libcxx/include/csignal | 65 + app/src/main/cpp/libcxx/include/cstdarg | 55 + app/src/main/cpp/libcxx/include/cstdbool | 32 + app/src/main/cpp/libcxx/include/cstddef | 146 + app/src/main/cpp/libcxx/include/cstdint | 200 + app/src/main/cpp/libcxx/include/cstdio | 179 + app/src/main/cpp/libcxx/include/cstdlib | 153 + app/src/main/cpp/libcxx/include/cstring | 152 + app/src/main/cpp/libcxx/include/ctgmath | 29 + app/src/main/cpp/libcxx/include/ctime | 87 + app/src/main/cpp/libcxx/include/ctype.h | 61 + app/src/main/cpp/libcxx/include/cuchar | 76 + app/src/main/cpp/libcxx/include/cwchar | 244 + app/src/main/cpp/libcxx/include/cwctype | 98 + app/src/main/cpp/libcxx/include/deque | 2443 ++++++ app/src/main/cpp/libcxx/include/errno.h | 399 + app/src/main/cpp/libcxx/include/exception | 384 + app/src/main/cpp/libcxx/include/execution | 25 + app/src/main/cpp/libcxx/include/expected | 54 + .../cpp/libcxx/include/experimental/__config | 66 + .../cpp/libcxx/include/experimental/__memory | 117 + .../cpp/libcxx/include/experimental/algorithm | 53 + .../cpp/libcxx/include/experimental/coroutine | 344 + .../cpp/libcxx/include/experimental/deque | 52 + .../libcxx/include/experimental/forward_list | 52 + .../libcxx/include/experimental/functional | 436 ++ .../cpp/libcxx/include/experimental/iterator | 126 + .../main/cpp/libcxx/include/experimental/list | 52 + .../main/cpp/libcxx/include/experimental/map | 62 + .../include/experimental/memory_resource | 443 ++ .../include/experimental/propagate_const | 581 ++ .../cpp/libcxx/include/experimental/regex | 69 + .../main/cpp/libcxx/include/experimental/set | 62 + .../main/cpp/libcxx/include/experimental/simd | 1585 ++++ .../cpp/libcxx/include/experimental/string | 73 + .../libcxx/include/experimental/type_traits | 155 + .../libcxx/include/experimental/unordered_map | 78 + .../libcxx/include/experimental/unordered_set | 64 + .../cpp/libcxx/include/experimental/utility | 47 + .../cpp/libcxx/include/experimental/vector | 52 + app/src/main/cpp/libcxx/include/ext/__hash | 135 + app/src/main/cpp/libcxx/include/ext/hash_map | 990 +++ app/src/main/cpp/libcxx/include/ext/hash_set | 670 ++ app/src/main/cpp/libcxx/include/fenv.h | 118 + app/src/main/cpp/libcxx/include/filesystem | 469 ++ app/src/main/cpp/libcxx/include/float.h | 95 + app/src/main/cpp/libcxx/include/format | 212 + app/src/main/cpp/libcxx/include/forward_list | 1803 +++++ app/src/main/cpp/libcxx/include/fstream | 1763 +++++ app/src/main/cpp/libcxx/include/functional | 550 ++ app/src/main/cpp/libcxx/include/future | 2457 ++++++ .../main/cpp/libcxx/include/initializer_list | 118 + app/src/main/cpp/libcxx/include/inttypes.h | 264 + app/src/main/cpp/libcxx/include/iomanip | 663 ++ app/src/main/cpp/libcxx/include/ios | 1054 +++ app/src/main/cpp/libcxx/include/iosfwd | 266 + app/src/main/cpp/libcxx/include/iostream | 68 + app/src/main/cpp/libcxx/include/istream | 1647 ++++ app/src/main/cpp/libcxx/include/iterator | 742 ++ app/src/main/cpp/libcxx/include/latch | 114 + app/src/main/cpp/libcxx/include/libcxx.imp | 45 + app/src/main/cpp/libcxx/include/limits | 830 ++ app/src/main/cpp/libcxx/include/limits.h | 71 + app/src/main/cpp/libcxx/include/list | 2386 ++++++ app/src/main/cpp/libcxx/include/locale | 4368 +++++++++++ app/src/main/cpp/libcxx/include/locale.h | 50 + app/src/main/cpp/libcxx/include/map | 2361 ++++++ app/src/main/cpp/libcxx/include/math.h | 1710 ++++ app/src/main/cpp/libcxx/include/memory | 934 +++ .../main/cpp/libcxx/include/memory_resource | 65 + .../cpp/libcxx/include/module.modulemap.in | 1724 +++++ app/src/main/cpp/libcxx/include/mutex | 712 ++ app/src/main/cpp/libcxx/include/new | 410 + app/src/main/cpp/libcxx/include/numbers | 138 + app/src/main/cpp/libcxx/include/numeric | 181 + app/src/main/cpp/libcxx/include/optional | 1591 ++++ app/src/main/cpp/libcxx/include/ostream | 1197 +++ app/src/main/cpp/libcxx/include/queue | 970 +++ app/src/main/cpp/libcxx/include/random | 1745 +++++ app/src/main/cpp/libcxx/include/ranges | 400 + app/src/main/cpp/libcxx/include/ratio | 532 ++ app/src/main/cpp/libcxx/include/regex | 6876 +++++++++++++++++ .../main/cpp/libcxx/include/scoped_allocator | 733 ++ app/src/main/cpp/libcxx/include/semaphore | 191 + app/src/main/cpp/libcxx/include/set | 1605 ++++ app/src/main/cpp/libcxx/include/setjmp.h | 46 + app/src/main/cpp/libcxx/include/shared_mutex | 509 ++ .../main/cpp/libcxx/include/source_location | 85 + app/src/main/cpp/libcxx/include/span | 598 ++ app/src/main/cpp/libcxx/include/sstream | 883 +++ app/src/main/cpp/libcxx/include/stack | 371 + app/src/main/cpp/libcxx/include/stdatomic.h | 235 + app/src/main/cpp/libcxx/include/stdbool.h | 40 + app/src/main/cpp/libcxx/include/stddef.h | 53 + app/src/main/cpp/libcxx/include/stdexcept | 310 + app/src/main/cpp/libcxx/include/stdint.h | 127 + app/src/main/cpp/libcxx/include/stdio.h | 121 + app/src/main/cpp/libcxx/include/stdlib.h | 163 + app/src/main/cpp/libcxx/include/streambuf | 503 ++ app/src/main/cpp/libcxx/include/string | 4633 +++++++++++ app/src/main/cpp/libcxx/include/string.h | 111 + app/src/main/cpp/libcxx/include/string_view | 1031 +++ app/src/main/cpp/libcxx/include/strstream | 409 + app/src/main/cpp/libcxx/include/system_error | 548 ++ app/src/main/cpp/libcxx/include/tgmath.h | 34 + app/src/main/cpp/libcxx/include/thread | 421 + app/src/main/cpp/libcxx/include/tuple | 1863 +++++ app/src/main/cpp/libcxx/include/type_traits | 545 ++ app/src/main/cpp/libcxx/include/typeindex | 126 + app/src/main/cpp/libcxx/include/typeinfo | 406 + app/src/main/cpp/libcxx/include/uchar.h | 54 + app/src/main/cpp/libcxx/include/unordered_map | 2653 +++++++ app/src/main/cpp/libcxx/include/unordered_set | 1824 +++++ app/src/main/cpp/libcxx/include/utility | 282 + app/src/main/cpp/libcxx/include/valarray | 4940 ++++++++++++ app/src/main/cpp/libcxx/include/variant | 1839 +++++ app/src/main/cpp/libcxx/include/vector | 3366 ++++++++ app/src/main/cpp/libcxx/include/version | 424 + app/src/main/cpp/libcxx/include/wchar.h | 188 + app/src/main/cpp/libcxx/include/wctype.h | 94 + app/src/main/cpp/libcxx/x86/libcxx.a | Bin 0 -> 1512352 bytes app/src/main/cpp/libcxx/x86_64/libcxx.a | Bin 0 -> 1897636 bytes 1159 files changed, 196592 insertions(+), 26527 deletions(-) create mode 160000 app/src/main/cpp/Dobby delete mode 100644 app/src/main/cpp/Dobby/.clang-format delete mode 100644 app/src/main/cpp/Dobby/.github/workflows/Builder.yaml delete mode 100644 app/src/main/cpp/Dobby/.gitignore delete mode 100644 app/src/main/cpp/Dobby/.vscode/c_cpp_properties.json delete mode 100644 app/src/main/cpp/Dobby/.vscode/launch.json delete mode 100644 app/src/main/cpp/Dobby/.vscode/settings.json delete mode 100644 app/src/main/cpp/Dobby/.vscode/tags delete mode 100644 app/src/main/cpp/Dobby/CMakeLists.txt delete mode 100644 app/src/main/cpp/Dobby/LICENSE delete mode 100644 app/src/main/cpp/Dobby/README.md delete mode 100644 app/src/main/cpp/Dobby/README_zh-cn.md delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/MGCopyAnswerMonitor.cc delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/dynamic_loader_monitor.cc delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/file_operation_monitor.cc delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/memory_operation_instrument.cc delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/posix_file_descriptor_operation_monitor.cc delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/posix_socket_network_monitor.cc delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/BionicLinkerUtil/bionic_linker_demo.cc delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/BionicLinkerUtil/bionic_linker_util.cc delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/BionicLinkerUtil/bionic_linker_util.h delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/CMakeLists.txt delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/ImportTableReplace/CMakeLists.txt delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/ImportTableReplace/dobby_import_replace.cc delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/ImportTableReplace/dobby_import_replace.h delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeReplace/CMakeLists.txt delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeReplace/objc_runtime_repalce.h delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeReplace/objc_runtime_replace.mm delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/CMakeLists.txt delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/README delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/mach_system_call_log_handler.cc delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/misc_utility.cc delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/misc_utility.h delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/sensitive_api_monitor.cc delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/supervisor_call_monitor.cc delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/supervisor_call_monitor.h delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/system_call_log_handler.cc delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/test_supervisor_call_monitor.cc delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/CMakeLists.txt delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/dobby_symbol_resolver.h delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/elf/dobby_symbol_resolver.cc delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dobby_symbol_resolver.cc delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dobby_symbol_resolver_priv.h delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dyld_shared_cache_symbol_table_iterator.cc delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/shared-cache/dyld_cache_format.h delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/shared_cache_internal.h delete mode 100644 app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/pe/dobby_symbol_resolver.cc delete mode 100644 app/src/main/cpp/Dobby/cmake/Macros.cmake delete mode 100644 app/src/main/cpp/Dobby/cmake/Util.cmake delete mode 100644 app/src/main/cpp/Dobby/cmake/auto_source_group.cmake delete mode 100644 app/src/main/cpp/Dobby/cmake/build_environment_check.cmake delete mode 100644 app/src/main/cpp/Dobby/cmake/compiler_and_linker.cmake delete mode 100644 app/src/main/cpp/Dobby/cmake/dobby.xcode.source.cmake delete mode 100644 app/src/main/cpp/Dobby/cmake/platform/platform-darwin.cmake delete mode 100644 app/src/main/cpp/Dobby/cmake/xcode_generator_helper.cmake delete mode 100644 app/src/main/cpp/Dobby/docs/compile.md delete mode 100644 app/src/main/cpp/Dobby/examples/CMakeLists.txt delete mode 100644 app/src/main/cpp/Dobby/examples/main.cc delete mode 100644 app/src/main/cpp/Dobby/examples/socket_example.cc delete mode 100644 app/src/main/cpp/Dobby/external/TINYSTL/allocator.h delete mode 100644 app/src/main/cpp/Dobby/external/TINYSTL/buffer.h delete mode 100644 app/src/main/cpp/Dobby/external/TINYSTL/hash.h delete mode 100644 app/src/main/cpp/Dobby/external/TINYSTL/hash_base.h delete mode 100644 app/src/main/cpp/Dobby/external/TINYSTL/new.h delete mode 100644 app/src/main/cpp/Dobby/external/TINYSTL/stddef.h delete mode 100644 app/src/main/cpp/Dobby/external/TINYSTL/string.h delete mode 100644 app/src/main/cpp/Dobby/external/TINYSTL/string_view.h delete mode 100644 app/src/main/cpp/Dobby/external/TINYSTL/traits.h delete mode 100644 app/src/main/cpp/Dobby/external/TINYSTL/unordered_map.h delete mode 100644 app/src/main/cpp/Dobby/external/TINYSTL/unordered_set.h delete mode 100644 app/src/main/cpp/Dobby/external/TINYSTL/vector.h delete mode 100644 app/src/main/cpp/Dobby/external/deprecated/misc-helper/CMakeLists.txt delete mode 100644 app/src/main/cpp/Dobby/external/deprecated/misc-helper/async_logger.cc delete mode 100644 app/src/main/cpp/Dobby/external/deprecated/misc-helper/deprecated/pthread_helper.cc delete mode 100644 app/src/main/cpp/Dobby/external/deprecated/misc-helper/deprecated/pthread_helper.h delete mode 100644 app/src/main/cpp/Dobby/external/deprecated/misc-helper/deprecated/unistd_helper.h delete mode 100644 app/src/main/cpp/Dobby/external/deprecated/misc-helper/format_printer.cc delete mode 100644 app/src/main/cpp/Dobby/external/deprecated/misc-helper/misc-helper/async_logger.h delete mode 100644 app/src/main/cpp/Dobby/external/deprecated/misc-helper/misc-helper/format_printer.h delete mode 100644 app/src/main/cpp/Dobby/external/deprecated/misc-helper/misc-helper/variable_cache.h delete mode 100644 app/src/main/cpp/Dobby/external/deprecated/misc-helper/variable_cache.c delete mode 100644 app/src/main/cpp/Dobby/external/logging/CMakeLists.txt delete mode 100644 app/src/main/cpp/Dobby/external/logging/cxxlogging.cc delete mode 100644 app/src/main/cpp/Dobby/external/logging/kernel_logging.c delete mode 100644 app/src/main/cpp/Dobby/external/logging/logging.c delete mode 100644 app/src/main/cpp/Dobby/external/logging/logging/check_logging.h delete mode 100644 app/src/main/cpp/Dobby/external/logging/logging/cxxlogging.h delete mode 100644 app/src/main/cpp/Dobby/external/logging/logging/logging.h delete mode 100644 app/src/main/cpp/Dobby/include/dobby.h delete mode 100644 app/src/main/cpp/Dobby/scripts/Dockerfile delete mode 100644 app/src/main/cpp/Dobby/scripts/platform_builder.py delete mode 100644 app/src/main/cpp/Dobby/scripts/setup_linux_cross_compile.sh delete mode 100644 app/src/main/cpp/Dobby/scripts/setup_macos_cross_compile.sh delete mode 100644 app/src/main/cpp/Dobby/source/Backend/KernelMode/ExecMemory/clear-cache-tool-all.c delete mode 100644 app/src/main/cpp/Dobby/source/Backend/KernelMode/ExecMemory/code-patch-tool-darwin.cc delete mode 100644 app/src/main/cpp/Dobby/source/Backend/KernelMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc delete mode 100644 app/src/main/cpp/Dobby/source/Backend/KernelMode/PlatformUtil/ProcessRuntimeUtility.h delete mode 100644 app/src/main/cpp/Dobby/source/Backend/KernelMode/UnifiedInterface/exec_mem_placeholder.asm delete mode 100644 app/src/main/cpp/Dobby/source/Backend/KernelMode/UnifiedInterface/platform-darwin.cc delete mode 100644 app/src/main/cpp/Dobby/source/Backend/KernelMode/UnifiedInterface/platform.h delete mode 100644 app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/clear-cache-tool-all.c delete mode 100644 app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/clear-cache-tool/clear-cache-tool-arm-dummy.cc delete mode 100644 app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/clear-cache-tool/clear-cache-tool-arm64-dummy.cc delete mode 100644 app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/code-patch-tool-darwin.cc delete mode 100644 app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/code-patch-tool-posix.cc delete mode 100644 app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/code-patch-tool-windows.cc delete mode 100644 app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/substrated/mach_interface_support/substrated.defs delete mode 100644 app/src/main/cpp/Dobby/source/Backend/UserMode/MultiThreadSupport/ThreadSupport.cpp delete mode 100644 app/src/main/cpp/Dobby/source/Backend/UserMode/MultiThreadSupport/ThreadSupport.h delete mode 100644 app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc delete mode 100644 app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/Linux/ProcessRuntimeUtility.cc delete mode 100644 app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/ProcessRuntimeUtility.h delete mode 100644 app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/Windows/ProcessRuntimeUtility.cc delete mode 100644 app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/PlatformThread.cc delete mode 100644 app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/PlatformThread.h delete mode 100644 app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/platform-thread-posix.cc delete mode 100644 app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/platform-thread-windows.cc delete mode 100644 app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform-darwin/mach_vm.h delete mode 100644 app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform-posix.cc delete mode 100644 app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform-windows.cc delete mode 100644 app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform.h delete mode 100644 app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/semaphore.cc delete mode 100644 app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/semaphore.h delete mode 100644 app/src/main/cpp/Dobby/source/InstructionRelocation/InstructionRelocation.h delete mode 100644 app/src/main/cpp/Dobby/source/InstructionRelocation/arm/InstructionRelocationARM.cc delete mode 100644 app/src/main/cpp/Dobby/source/InstructionRelocation/arm/InstructionRelocationARM.h delete mode 100644 app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/InstructionRelocationARM64.cc delete mode 100644 app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/InstructionRelocationARM64.h delete mode 100644 app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/inst_constants.h delete mode 100644 app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/inst_decode_encode_kit.h delete mode 100644 app/src/main/cpp/Dobby/source/InstructionRelocation/x64/InstructionRelocationX64.cc delete mode 100644 app/src/main/cpp/Dobby/source/InstructionRelocation/x64/InstructionRelocationX64.h delete mode 100644 app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86.cc delete mode 100644 app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86.h delete mode 100644 app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86Shared.cc delete mode 100644 app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86Shared.h delete mode 100644 app/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/Ia32Disassembler.cc delete mode 100644 app/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/X86OpcodoDecodeTable.cc delete mode 100644 app/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/X86OpcodoDecodeTable.h delete mode 100644 app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/build_config.h delete mode 100644 app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.c delete mode 100644 app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.h delete mode 100644 app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_reader.c delete mode 100644 app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_modrm_reg_group.c delete mode 100644 app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_one_byte.c delete mode 100644 app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_sse_group.c delete mode 100644 app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_two_byte.c delete mode 100644 app/src/main/cpp/Dobby/source/InterceptEntry.cpp delete mode 100644 app/src/main/cpp/Dobby/source/InterceptEntry.h delete mode 100644 app/src/main/cpp/Dobby/source/InterceptRouting/InterceptRouting.cpp delete mode 100644 app/src/main/cpp/Dobby/source/InterceptRouting/InterceptRouting.h delete mode 100644 app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineHook/FunctionInlineHook.cc delete mode 100644 app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineHook/FunctionInlineHookRouting.h delete mode 100644 app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineHook/RoutingImpl.cc delete mode 100644 app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/FunctionWrapperExport.cc delete mode 100644 app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/function-wrapper.cc delete mode 100644 app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/function-wrapper.h delete mode 100644 app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/intercept_routing_handler.cc delete mode 100644 app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/intercept_routing_handler.h delete mode 100644 app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/InstructionInstrument.cc delete mode 100644 app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/InstructionInstrumentRouting.h delete mode 100644 app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/RoutingImpl.cc delete mode 100644 app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/instrument_routing_handler.cc delete mode 100644 app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/instrument_routing_handler.h delete mode 100644 app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.cc delete mode 100644 app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.h delete mode 100644 app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/near_trampoline_arm64.cc delete mode 100644 app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/RoutingPlugin.cc delete mode 100644 app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/RoutingPlugin.h delete mode 100644 app/src/main/cpp/Dobby/source/Interceptor.cpp delete mode 100644 app/src/main/cpp/Dobby/source/Interceptor.h delete mode 100644 app/src/main/cpp/Dobby/source/MemoryAllocator/AssemblyCodeBuilder.cc delete mode 100644 app/src/main/cpp/Dobby/source/MemoryAllocator/AssemblyCodeBuilder.h delete mode 100644 app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/CodeBufferBase.cc delete mode 100644 app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/CodeBufferBase.h delete mode 100644 app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm.h delete mode 100644 app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm64.h delete mode 100644 app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x64.h delete mode 100644 app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x86.cc delete mode 100644 app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x86.h delete mode 100644 app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_arm.h delete mode 100644 app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_arm64.h delete mode 100644 app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_x64.h delete mode 100644 app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_x86.h delete mode 100644 app/src/main/cpp/Dobby/source/MemoryAllocator/MemoryAllocator.cc delete mode 100644 app/src/main/cpp/Dobby/source/MemoryAllocator/NearMemoryAllocator.cc delete mode 100644 app/src/main/cpp/Dobby/source/MemoryAllocator/NearMemoryAllocator.h delete mode 100644 app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/ExecMemory/ClearCacheTool.h delete mode 100644 app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/ExecMemory/CodePatchTool.h delete mode 100644 app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/MemoryAllocator.h delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/ClosureTrampolineARM.cc delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/closure_bridge_arm.cc delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/dummy/closure-bridge-template-arm.cc delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/dummy/closure-trampoline-template-arm.S delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/helper_arm.cc delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/ClosureTrampolineARM64.cc delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/closure_bridge_arm64.cc delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/closure-bridge-template-arm64.c delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/closure-trampoline-template-arm64.S delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/dynamic-closure-trampoline-template-arm64.S delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/helper_arm64.cc delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.cc delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/ClosureTrampolineX64.cc delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/closure_bridge_x64.cc delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/dummy/closure-bridge-template-x64.c delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/dummy/closure-trampoline-template-x64.S delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/helper_x64.cc delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/ClosureTrampolineX86.cc delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/closure_bridge_x86.cc delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/helper_x86.cc delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/Trampoline.h delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/arm/trampoline_arm.cc delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/arm64/trampoline_arm64.cc delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/x64/trampoline_x64.cc delete mode 100644 app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/x86/trampoline_x86.cc delete mode 100644 app/src/main/cpp/Dobby/source/core/arch/Cpu.cc delete mode 100644 app/src/main/cpp/Dobby/source/core/arch/Cpu.h delete mode 100644 app/src/main/cpp/Dobby/source/core/arch/CpuFeature.cc delete mode 100644 app/src/main/cpp/Dobby/source/core/arch/CpuFeature.h delete mode 100644 app/src/main/cpp/Dobby/source/core/arch/CpuRegister.cc delete mode 100644 app/src/main/cpp/Dobby/source/core/arch/CpuRegister.h delete mode 100644 app/src/main/cpp/Dobby/source/core/arch/CpuUtils.h delete mode 100644 app/src/main/cpp/Dobby/source/core/arch/arm/constants-arm.h delete mode 100644 app/src/main/cpp/Dobby/source/core/arch/arm/registers-arm.h delete mode 100644 app/src/main/cpp/Dobby/source/core/arch/arm64/constants-arm64.h delete mode 100644 app/src/main/cpp/Dobby/source/core/arch/arm64/registers-arm64.h delete mode 100644 app/src/main/cpp/Dobby/source/core/arch/x64/constants-x64.h delete mode 100644 app/src/main/cpp/Dobby/source/core/arch/x64/registers-x64.h delete mode 100644 app/src/main/cpp/Dobby/source/core/arch/x86/constants-x86.h delete mode 100644 app/src/main/cpp/Dobby/source/core/arch/x86/cpu-x86.cc delete mode 100644 app/src/main/cpp/Dobby/source/core/arch/x86/cpu-x86.h delete mode 100644 app/src/main/cpp/Dobby/source/core/arch/x86/registers-x86.h delete mode 100644 app/src/main/cpp/Dobby/source/core/assembler/AssemblerPseudoLabel.h delete mode 100644 app/src/main/cpp/Dobby/source/core/assembler/assembler-arch.h delete mode 100644 app/src/main/cpp/Dobby/source/core/assembler/assembler-arm.cc delete mode 100644 app/src/main/cpp/Dobby/source/core/assembler/assembler-arm.h delete mode 100644 app/src/main/cpp/Dobby/source/core/assembler/assembler-arm64.cc delete mode 100644 app/src/main/cpp/Dobby/source/core/assembler/assembler-arm64.h delete mode 100644 app/src/main/cpp/Dobby/source/core/assembler/assembler-ia32.cc delete mode 100644 app/src/main/cpp/Dobby/source/core/assembler/assembler-ia32.h delete mode 100644 app/src/main/cpp/Dobby/source/core/assembler/assembler-x64.cc delete mode 100644 app/src/main/cpp/Dobby/source/core/assembler/assembler-x64.h delete mode 100644 app/src/main/cpp/Dobby/source/core/assembler/assembler-x86-shared.cc delete mode 100644 app/src/main/cpp/Dobby/source/core/assembler/assembler-x86-shared.h delete mode 100644 app/src/main/cpp/Dobby/source/core/assembler/assembler.cc delete mode 100644 app/src/main/cpp/Dobby/source/core/assembler/assembler.h delete mode 100644 app/src/main/cpp/Dobby/source/core/codegen/codegen-arm.cc delete mode 100644 app/src/main/cpp/Dobby/source/core/codegen/codegen-arm.h delete mode 100644 app/src/main/cpp/Dobby/source/core/codegen/codegen-arm64.cc delete mode 100644 app/src/main/cpp/Dobby/source/core/codegen/codegen-arm64.h delete mode 100644 app/src/main/cpp/Dobby/source/core/codegen/codegen-ia32.cc delete mode 100644 app/src/main/cpp/Dobby/source/core/codegen/codegen-ia32.h delete mode 100644 app/src/main/cpp/Dobby/source/core/codegen/codegen-x64.cc delete mode 100644 app/src/main/cpp/Dobby/source/core/codegen/codegen-x64.h delete mode 100644 app/src/main/cpp/Dobby/source/core/codegen/codegen.h delete mode 100644 app/src/main/cpp/Dobby/source/core/emulator/dummy.cc delete mode 100644 app/src/main/cpp/Dobby/source/dobby.cpp delete mode 100644 app/src/main/cpp/Dobby/source/dobby_internal.h delete mode 100644 app/src/main/cpp/Dobby/source/include/common_header.h delete mode 100644 app/src/main/cpp/Dobby/source/include/kernel_mode_header.h delete mode 100644 app/src/main/cpp/Dobby/source/include/list_c.h delete mode 100644 app/src/main/cpp/Dobby/source/include/platform_header.h delete mode 100644 app/src/main/cpp/Dobby/source/include/platform_macro.h delete mode 100644 app/src/main/cpp/Dobby/source/include/type_header.h delete mode 100644 app/src/main/cpp/Dobby/source/include/utility_macro.h delete mode 100644 app/src/main/cpp/Dobby/tests/CMakeLists.txt delete mode 100644 app/src/main/cpp/Dobby/tests/UniconEmulator.cpp delete mode 100644 app/src/main/cpp/Dobby/tests/UniconEmulator.h delete mode 100644 app/src/main/cpp/Dobby/tests/test_insn_decoder_x86.cpp delete mode 100644 app/src/main/cpp/Dobby/tests/test_insn_relo_arm.cpp delete mode 100644 app/src/main/cpp/Dobby/tests/test_insn_relo_arm64.cpp delete mode 100644 app/src/main/cpp/Dobby/tests/test_insn_relo_x64.cpp delete mode 100644 app/src/main/cpp/Dobby/tests/test_native.cpp delete mode 160000 app/src/main/cpp/libcxx create mode 100644 app/src/main/cpp/libcxx/arm64-v8a/libcxx.a create mode 100644 app/src/main/cpp/libcxx/armeabi-v7a/libcxx.a create mode 100644 app/src/main/cpp/libcxx/include/CMakeLists.txt create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/adjacent_find.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/all_of.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/any_of.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/binary_search.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/clamp.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/comp.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/comp_ref_type.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/copy.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/copy_backward.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/copy_if.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/copy_move_common.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/copy_n.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/count.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/count_if.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/equal.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/equal_range.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/fill.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/fill_n.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/find.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/find_end.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/find_first_of.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/find_if.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/find_if_not.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/for_each.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/for_each_n.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/generate.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/generate_n.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/half_positive.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/in_found_result.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/in_fun_result.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/in_in_out_result.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/in_in_result.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/in_out_out_result.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/in_out_result.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/includes.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/inplace_merge.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/is_heap.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/is_heap_until.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/is_partitioned.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/is_permutation.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/is_sorted.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/is_sorted_until.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/iter_swap.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/iterator_operations.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/lexicographical_compare.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/lower_bound.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/make_heap.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/make_projected.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/max.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/max_element.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/merge.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/min.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/min_element.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/min_max_result.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/minmax.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/minmax_element.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/mismatch.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/move.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/move_backward.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/next_permutation.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/none_of.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/nth_element.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/partial_sort.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/partial_sort_copy.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/partition.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/partition_copy.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/partition_point.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/pop_heap.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/prev_permutation.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/push_heap.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_adjacent_find.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_all_of.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_any_of.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_binary_search.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_clamp.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_copy.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_copy_backward.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_copy_if.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_copy_n.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_count.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_count_if.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_equal.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_equal_range.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_fill.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_fill_n.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_find.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_find_end.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_find_first_of.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_find_if.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_find_if_not.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_for_each.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_for_each_n.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_generate.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_generate_n.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_includes.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_inplace_merge.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_is_heap.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_is_heap_until.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_is_partitioned.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_is_permutation.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_is_sorted.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_is_sorted_until.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_iterator_concept.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_lexicographical_compare.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_lower_bound.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_make_heap.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_max.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_max_element.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_merge.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_min.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_min_element.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_minmax.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_minmax_element.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_mismatch.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_move.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_move_backward.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_next_permutation.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_none_of.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_nth_element.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_partial_sort.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_partial_sort_copy.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_partition.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_partition_copy.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_partition_point.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_pop_heap.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_prev_permutation.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_push_heap.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_remove.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_remove_copy.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_remove_copy_if.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_remove_if.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_replace.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_replace_copy.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_replace_copy_if.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_replace_if.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_reverse.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_reverse_copy.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_rotate.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_rotate_copy.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_sample.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_search.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_search_n.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_set_difference.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_set_intersection.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_set_symmetric_difference.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_set_union.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_shuffle.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_sort.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_sort_heap.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_stable_partition.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_stable_sort.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_swap_ranges.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_transform.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_unique.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_unique_copy.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/ranges_upper_bound.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/remove.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/remove_copy.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/remove_copy_if.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/remove_if.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/replace.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/replace_copy.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/replace_copy_if.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/replace_if.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/reverse.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/reverse_copy.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/rotate.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/rotate_copy.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/sample.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/search.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/search_n.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/set_difference.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/set_intersection.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/set_symmetric_difference.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/set_union.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/shift_left.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/shift_right.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/shuffle.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/sift_down.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/sort.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/sort_heap.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/stable_partition.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/stable_sort.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/swap_ranges.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/transform.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/uniform_random_bit_generator_adaptor.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/unique.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/unique_copy.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/unwrap_iter.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/unwrap_range.h create mode 100644 app/src/main/cpp/libcxx/include/__algorithm/upper_bound.h create mode 100644 app/src/main/cpp/libcxx/include/__assert create mode 100644 app/src/main/cpp/libcxx/include/__availability create mode 100644 app/src/main/cpp/libcxx/include/__bit/bit_cast.h create mode 100644 app/src/main/cpp/libcxx/include/__bit/bit_ceil.h create mode 100644 app/src/main/cpp/libcxx/include/__bit/bit_floor.h create mode 100644 app/src/main/cpp/libcxx/include/__bit/bit_log2.h create mode 100644 app/src/main/cpp/libcxx/include/__bit/bit_width.h create mode 100644 app/src/main/cpp/libcxx/include/__bit/blsr.h create mode 100644 app/src/main/cpp/libcxx/include/__bit/byteswap.h create mode 100644 app/src/main/cpp/libcxx/include/__bit/countl.h create mode 100644 app/src/main/cpp/libcxx/include/__bit/countr.h create mode 100644 app/src/main/cpp/libcxx/include/__bit/endian.h create mode 100644 app/src/main/cpp/libcxx/include/__bit/has_single_bit.h create mode 100644 app/src/main/cpp/libcxx/include/__bit/popcount.h create mode 100644 app/src/main/cpp/libcxx/include/__bit/rotate.h create mode 100644 app/src/main/cpp/libcxx/include/__bit_reference create mode 100644 app/src/main/cpp/libcxx/include/__bsd_locale_defaults.h create mode 100644 app/src/main/cpp/libcxx/include/__bsd_locale_fallbacks.h create mode 100644 app/src/main/cpp/libcxx/include/__charconv/chars_format.h create mode 100644 app/src/main/cpp/libcxx/include/__charconv/from_chars_result.h create mode 100644 app/src/main/cpp/libcxx/include/__charconv/tables.h create mode 100644 app/src/main/cpp/libcxx/include/__charconv/to_chars_base_10.h create mode 100644 app/src/main/cpp/libcxx/include/__charconv/to_chars_result.h create mode 100644 app/src/main/cpp/libcxx/include/__chrono/calendar.h create mode 100644 app/src/main/cpp/libcxx/include/__chrono/convert_to_timespec.h create mode 100644 app/src/main/cpp/libcxx/include/__chrono/convert_to_tm.h create mode 100644 app/src/main/cpp/libcxx/include/__chrono/day.h create mode 100644 app/src/main/cpp/libcxx/include/__chrono/duration.h create mode 100644 app/src/main/cpp/libcxx/include/__chrono/file_clock.h create mode 100644 app/src/main/cpp/libcxx/include/__chrono/formatter.h create mode 100644 app/src/main/cpp/libcxx/include/__chrono/hh_mm_ss.h create mode 100644 app/src/main/cpp/libcxx/include/__chrono/high_resolution_clock.h create mode 100644 app/src/main/cpp/libcxx/include/__chrono/literals.h create mode 100644 app/src/main/cpp/libcxx/include/__chrono/month.h create mode 100644 app/src/main/cpp/libcxx/include/__chrono/month_weekday.h create mode 100644 app/src/main/cpp/libcxx/include/__chrono/monthday.h create mode 100644 app/src/main/cpp/libcxx/include/__chrono/ostream.h create mode 100644 app/src/main/cpp/libcxx/include/__chrono/parser_std_format_spec.h create mode 100644 app/src/main/cpp/libcxx/include/__chrono/statically_widen.h create mode 100644 app/src/main/cpp/libcxx/include/__chrono/steady_clock.h create mode 100644 app/src/main/cpp/libcxx/include/__chrono/system_clock.h create mode 100644 app/src/main/cpp/libcxx/include/__chrono/time_point.h create mode 100644 app/src/main/cpp/libcxx/include/__chrono/weekday.h create mode 100644 app/src/main/cpp/libcxx/include/__chrono/year.h create mode 100644 app/src/main/cpp/libcxx/include/__chrono/year_month.h create mode 100644 app/src/main/cpp/libcxx/include/__chrono/year_month_day.h create mode 100644 app/src/main/cpp/libcxx/include/__chrono/year_month_weekday.h create mode 100644 app/src/main/cpp/libcxx/include/__compare/common_comparison_category.h create mode 100644 app/src/main/cpp/libcxx/include/__compare/compare_partial_order_fallback.h create mode 100644 app/src/main/cpp/libcxx/include/__compare/compare_strong_order_fallback.h create mode 100644 app/src/main/cpp/libcxx/include/__compare/compare_three_way.h create mode 100644 app/src/main/cpp/libcxx/include/__compare/compare_three_way_result.h create mode 100644 app/src/main/cpp/libcxx/include/__compare/compare_weak_order_fallback.h create mode 100644 app/src/main/cpp/libcxx/include/__compare/is_eq.h create mode 100644 app/src/main/cpp/libcxx/include/__compare/ordering.h create mode 100644 app/src/main/cpp/libcxx/include/__compare/partial_order.h create mode 100644 app/src/main/cpp/libcxx/include/__compare/strong_order.h create mode 100644 app/src/main/cpp/libcxx/include/__compare/synth_three_way.h create mode 100644 app/src/main/cpp/libcxx/include/__compare/three_way_comparable.h create mode 100644 app/src/main/cpp/libcxx/include/__compare/weak_order.h create mode 100644 app/src/main/cpp/libcxx/include/__concepts/arithmetic.h create mode 100644 app/src/main/cpp/libcxx/include/__concepts/assignable.h create mode 100644 app/src/main/cpp/libcxx/include/__concepts/boolean_testable.h create mode 100644 app/src/main/cpp/libcxx/include/__concepts/class_or_enum.h create mode 100644 app/src/main/cpp/libcxx/include/__concepts/common_reference_with.h create mode 100644 app/src/main/cpp/libcxx/include/__concepts/common_with.h create mode 100644 app/src/main/cpp/libcxx/include/__concepts/constructible.h create mode 100644 app/src/main/cpp/libcxx/include/__concepts/convertible_to.h create mode 100644 app/src/main/cpp/libcxx/include/__concepts/copyable.h create mode 100644 app/src/main/cpp/libcxx/include/__concepts/derived_from.h create mode 100644 app/src/main/cpp/libcxx/include/__concepts/destructible.h create mode 100644 app/src/main/cpp/libcxx/include/__concepts/different_from.h create mode 100644 app/src/main/cpp/libcxx/include/__concepts/equality_comparable.h create mode 100644 app/src/main/cpp/libcxx/include/__concepts/invocable.h create mode 100644 app/src/main/cpp/libcxx/include/__concepts/movable.h create mode 100644 app/src/main/cpp/libcxx/include/__concepts/predicate.h create mode 100644 app/src/main/cpp/libcxx/include/__concepts/regular.h create mode 100644 app/src/main/cpp/libcxx/include/__concepts/relation.h create mode 100644 app/src/main/cpp/libcxx/include/__concepts/same_as.h create mode 100644 app/src/main/cpp/libcxx/include/__concepts/semiregular.h create mode 100644 app/src/main/cpp/libcxx/include/__concepts/swappable.h create mode 100644 app/src/main/cpp/libcxx/include/__concepts/totally_ordered.h create mode 100644 app/src/main/cpp/libcxx/include/__config create mode 100644 app/src/main/cpp/libcxx/include/__config_site create mode 100644 app/src/main/cpp/libcxx/include/__config_site.in create mode 100644 app/src/main/cpp/libcxx/include/__coroutine/coroutine_handle.h create mode 100644 app/src/main/cpp/libcxx/include/__coroutine/coroutine_traits.h create mode 100644 app/src/main/cpp/libcxx/include/__coroutine/noop_coroutine_handle.h create mode 100644 app/src/main/cpp/libcxx/include/__coroutine/trivial_awaitables.h create mode 100644 app/src/main/cpp/libcxx/include/__debug create mode 100644 app/src/main/cpp/libcxx/include/__debug_utils/randomize_range.h create mode 100644 app/src/main/cpp/libcxx/include/__errc create mode 100644 app/src/main/cpp/libcxx/include/__expected/bad_expected_access.h create mode 100644 app/src/main/cpp/libcxx/include/__expected/expected.h create mode 100644 app/src/main/cpp/libcxx/include/__expected/unexpect.h create mode 100644 app/src/main/cpp/libcxx/include/__expected/unexpected.h create mode 100644 app/src/main/cpp/libcxx/include/__filesystem/copy_options.h create mode 100644 app/src/main/cpp/libcxx/include/__filesystem/directory_entry.h create mode 100644 app/src/main/cpp/libcxx/include/__filesystem/directory_iterator.h create mode 100644 app/src/main/cpp/libcxx/include/__filesystem/directory_options.h create mode 100644 app/src/main/cpp/libcxx/include/__filesystem/file_status.h create mode 100644 app/src/main/cpp/libcxx/include/__filesystem/file_time_type.h create mode 100644 app/src/main/cpp/libcxx/include/__filesystem/file_type.h create mode 100644 app/src/main/cpp/libcxx/include/__filesystem/filesystem_error.h create mode 100644 app/src/main/cpp/libcxx/include/__filesystem/operations.h create mode 100644 app/src/main/cpp/libcxx/include/__filesystem/path.h create mode 100644 app/src/main/cpp/libcxx/include/__filesystem/path_iterator.h create mode 100644 app/src/main/cpp/libcxx/include/__filesystem/perm_options.h create mode 100644 app/src/main/cpp/libcxx/include/__filesystem/perms.h create mode 100644 app/src/main/cpp/libcxx/include/__filesystem/recursive_directory_iterator.h create mode 100644 app/src/main/cpp/libcxx/include/__filesystem/space_info.h create mode 100644 app/src/main/cpp/libcxx/include/__filesystem/u8path.h create mode 100644 app/src/main/cpp/libcxx/include/__format/buffer.h create mode 100644 app/src/main/cpp/libcxx/include/__format/concepts.h create mode 100644 app/src/main/cpp/libcxx/include/__format/container_adaptor.h create mode 100644 app/src/main/cpp/libcxx/include/__format/enable_insertable.h create mode 100644 app/src/main/cpp/libcxx/include/__format/escaped_output_table.h create mode 100644 app/src/main/cpp/libcxx/include/__format/extended_grapheme_cluster_table.h create mode 100644 app/src/main/cpp/libcxx/include/__format/format_arg.h create mode 100644 app/src/main/cpp/libcxx/include/__format/format_arg_store.h create mode 100644 app/src/main/cpp/libcxx/include/__format/format_args.h create mode 100644 app/src/main/cpp/libcxx/include/__format/format_context.h create mode 100644 app/src/main/cpp/libcxx/include/__format/format_error.h create mode 100644 app/src/main/cpp/libcxx/include/__format/format_functions.h create mode 100644 app/src/main/cpp/libcxx/include/__format/format_fwd.h create mode 100644 app/src/main/cpp/libcxx/include/__format/format_parse_context.h create mode 100644 app/src/main/cpp/libcxx/include/__format/format_string.h create mode 100644 app/src/main/cpp/libcxx/include/__format/format_to_n_result.h create mode 100644 app/src/main/cpp/libcxx/include/__format/formatter.h create mode 100644 app/src/main/cpp/libcxx/include/__format/formatter_bool.h create mode 100644 app/src/main/cpp/libcxx/include/__format/formatter_char.h create mode 100644 app/src/main/cpp/libcxx/include/__format/formatter_floating_point.h create mode 100644 app/src/main/cpp/libcxx/include/__format/formatter_integer.h create mode 100644 app/src/main/cpp/libcxx/include/__format/formatter_integral.h create mode 100644 app/src/main/cpp/libcxx/include/__format/formatter_output.h create mode 100644 app/src/main/cpp/libcxx/include/__format/formatter_pointer.h create mode 100644 app/src/main/cpp/libcxx/include/__format/formatter_string.h create mode 100644 app/src/main/cpp/libcxx/include/__format/formatter_tuple.h create mode 100644 app/src/main/cpp/libcxx/include/__format/parser_std_format_spec.h create mode 100644 app/src/main/cpp/libcxx/include/__format/range_default_formatter.h create mode 100644 app/src/main/cpp/libcxx/include/__format/range_formatter.h create mode 100644 app/src/main/cpp/libcxx/include/__format/unicode.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/binary_function.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/binary_negate.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/bind.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/bind_back.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/bind_front.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/binder1st.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/binder2nd.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/boyer_moore_searcher.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/compose.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/default_searcher.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/function.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/hash.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/identity.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/invoke.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/is_transparent.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/mem_fn.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/mem_fun_ref.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/not_fn.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/operations.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/perfect_forward.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/pointer_to_binary_function.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/pointer_to_unary_function.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/ranges_operations.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/reference_wrapper.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/unary_function.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/unary_negate.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/unwrap_ref.h create mode 100644 app/src/main/cpp/libcxx/include/__functional/weak_result_type.h create mode 100644 app/src/main/cpp/libcxx/include/__fwd/array.h create mode 100644 app/src/main/cpp/libcxx/include/__fwd/get.h create mode 100644 app/src/main/cpp/libcxx/include/__fwd/hash.h create mode 100644 app/src/main/cpp/libcxx/include/__fwd/memory_resource.h create mode 100644 app/src/main/cpp/libcxx/include/__fwd/pair.h create mode 100644 app/src/main/cpp/libcxx/include/__fwd/span.h create mode 100644 app/src/main/cpp/libcxx/include/__fwd/string.h create mode 100644 app/src/main/cpp/libcxx/include/__fwd/string_view.h create mode 100644 app/src/main/cpp/libcxx/include/__fwd/subrange.h create mode 100644 app/src/main/cpp/libcxx/include/__fwd/tuple.h create mode 100644 app/src/main/cpp/libcxx/include/__hash_table create mode 100644 app/src/main/cpp/libcxx/include/__ios/fpos.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/access.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/advance.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/back_insert_iterator.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/bounded_iter.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/common_iterator.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/concepts.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/counted_iterator.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/data.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/default_sentinel.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/distance.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/empty.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/erase_if_container.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/front_insert_iterator.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/incrementable_traits.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/indirectly_comparable.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/insert_iterator.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/istream_iterator.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/istreambuf_iterator.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/iter_move.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/iter_swap.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/iterator.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/iterator_traits.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/iterator_with_data.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/mergeable.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/move_iterator.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/move_sentinel.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/next.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/ostream_iterator.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/ostreambuf_iterator.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/permutable.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/prev.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/projected.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/readable_traits.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/reverse_access.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/reverse_iterator.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/segmented_iterator.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/size.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/sortable.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/unreachable_sentinel.h create mode 100644 app/src/main/cpp/libcxx/include/__iterator/wrap_iter.h create mode 100644 app/src/main/cpp/libcxx/include/__locale create mode 100644 app/src/main/cpp/libcxx/include/__mbstate_t.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/addressof.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/align.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/allocate_at_least.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/allocation_guard.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/allocator.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/allocator_arg_t.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/allocator_destructor.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/allocator_traits.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/assume_aligned.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/auto_ptr.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/builtin_new_allocator.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/compressed_pair.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/concepts.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/construct_at.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/destruct_n.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/pointer_traits.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/ranges_construct_at.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/ranges_uninitialized_algorithms.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/raw_storage_iterator.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/shared_ptr.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/swap_allocator.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/temp_value.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/temporary_buffer.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/uninitialized_algorithms.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/unique_ptr.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/uses_allocator.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/uses_allocator_construction.h create mode 100644 app/src/main/cpp/libcxx/include/__memory/voidify.h create mode 100644 app/src/main/cpp/libcxx/include/__memory_resource/memory_resource.h create mode 100644 app/src/main/cpp/libcxx/include/__memory_resource/monotonic_buffer_resource.h create mode 100644 app/src/main/cpp/libcxx/include/__memory_resource/polymorphic_allocator.h create mode 100644 app/src/main/cpp/libcxx/include/__memory_resource/pool_options.h create mode 100644 app/src/main/cpp/libcxx/include/__memory_resource/synchronized_pool_resource.h create mode 100644 app/src/main/cpp/libcxx/include/__memory_resource/unsynchronized_pool_resource.h create mode 100644 app/src/main/cpp/libcxx/include/__mutex_base create mode 100644 app/src/main/cpp/libcxx/include/__node_handle create mode 100644 app/src/main/cpp/libcxx/include/__numeric/accumulate.h create mode 100644 app/src/main/cpp/libcxx/include/__numeric/adjacent_difference.h create mode 100644 app/src/main/cpp/libcxx/include/__numeric/exclusive_scan.h create mode 100644 app/src/main/cpp/libcxx/include/__numeric/gcd_lcm.h create mode 100644 app/src/main/cpp/libcxx/include/__numeric/inclusive_scan.h create mode 100644 app/src/main/cpp/libcxx/include/__numeric/inner_product.h create mode 100644 app/src/main/cpp/libcxx/include/__numeric/iota.h create mode 100644 app/src/main/cpp/libcxx/include/__numeric/midpoint.h create mode 100644 app/src/main/cpp/libcxx/include/__numeric/partial_sum.h create mode 100644 app/src/main/cpp/libcxx/include/__numeric/reduce.h create mode 100644 app/src/main/cpp/libcxx/include/__numeric/transform_exclusive_scan.h create mode 100644 app/src/main/cpp/libcxx/include/__numeric/transform_inclusive_scan.h create mode 100644 app/src/main/cpp/libcxx/include/__numeric/transform_reduce.h create mode 100644 app/src/main/cpp/libcxx/include/__random/bernoulli_distribution.h create mode 100644 app/src/main/cpp/libcxx/include/__random/binomial_distribution.h create mode 100644 app/src/main/cpp/libcxx/include/__random/cauchy_distribution.h create mode 100644 app/src/main/cpp/libcxx/include/__random/chi_squared_distribution.h create mode 100644 app/src/main/cpp/libcxx/include/__random/clamp_to_integral.h create mode 100644 app/src/main/cpp/libcxx/include/__random/default_random_engine.h create mode 100644 app/src/main/cpp/libcxx/include/__random/discard_block_engine.h create mode 100644 app/src/main/cpp/libcxx/include/__random/discrete_distribution.h create mode 100644 app/src/main/cpp/libcxx/include/__random/exponential_distribution.h create mode 100644 app/src/main/cpp/libcxx/include/__random/extreme_value_distribution.h create mode 100644 app/src/main/cpp/libcxx/include/__random/fisher_f_distribution.h create mode 100644 app/src/main/cpp/libcxx/include/__random/gamma_distribution.h create mode 100644 app/src/main/cpp/libcxx/include/__random/generate_canonical.h create mode 100644 app/src/main/cpp/libcxx/include/__random/geometric_distribution.h create mode 100644 app/src/main/cpp/libcxx/include/__random/independent_bits_engine.h create mode 100644 app/src/main/cpp/libcxx/include/__random/is_seed_sequence.h create mode 100644 app/src/main/cpp/libcxx/include/__random/is_valid.h create mode 100644 app/src/main/cpp/libcxx/include/__random/knuth_b.h create mode 100644 app/src/main/cpp/libcxx/include/__random/linear_congruential_engine.h create mode 100644 app/src/main/cpp/libcxx/include/__random/log2.h create mode 100644 app/src/main/cpp/libcxx/include/__random/lognormal_distribution.h create mode 100644 app/src/main/cpp/libcxx/include/__random/mersenne_twister_engine.h create mode 100644 app/src/main/cpp/libcxx/include/__random/negative_binomial_distribution.h create mode 100644 app/src/main/cpp/libcxx/include/__random/normal_distribution.h create mode 100644 app/src/main/cpp/libcxx/include/__random/piecewise_constant_distribution.h create mode 100644 app/src/main/cpp/libcxx/include/__random/piecewise_linear_distribution.h create mode 100644 app/src/main/cpp/libcxx/include/__random/poisson_distribution.h create mode 100644 app/src/main/cpp/libcxx/include/__random/random_device.h create mode 100644 app/src/main/cpp/libcxx/include/__random/ranlux.h create mode 100644 app/src/main/cpp/libcxx/include/__random/seed_seq.h create mode 100644 app/src/main/cpp/libcxx/include/__random/shuffle_order_engine.h create mode 100644 app/src/main/cpp/libcxx/include/__random/student_t_distribution.h create mode 100644 app/src/main/cpp/libcxx/include/__random/subtract_with_carry_engine.h create mode 100644 app/src/main/cpp/libcxx/include/__random/uniform_int_distribution.h create mode 100644 app/src/main/cpp/libcxx/include/__random/uniform_random_bit_generator.h create mode 100644 app/src/main/cpp/libcxx/include/__random/uniform_real_distribution.h create mode 100644 app/src/main/cpp/libcxx/include/__random/weibull_distribution.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/access.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/all.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/as_rvalue_view.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/common_view.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/concepts.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/copyable_box.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/counted.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/dangling.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/data.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/drop_view.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/drop_while_view.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/elements_view.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/empty.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/empty_view.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/enable_borrowed_range.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/enable_view.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/filter_view.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/iota_view.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/istream_view.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/join_view.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/lazy_split_view.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/non_propagating_cache.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/owning_view.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/range_adaptor.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/rbegin.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/ref_view.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/rend.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/reverse_view.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/single_view.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/size.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/split_view.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/subrange.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/take_view.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/take_while_view.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/transform_view.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/view_interface.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/views.h create mode 100644 app/src/main/cpp/libcxx/include/__ranges/zip_view.h create mode 100644 app/src/main/cpp/libcxx/include/__split_buffer create mode 100644 app/src/main/cpp/libcxx/include/__std_stream create mode 100644 app/src/main/cpp/libcxx/include/__string/char_traits.h create mode 100644 app/src/main/cpp/libcxx/include/__string/extern_template_lists.h create mode 100644 app/src/main/cpp/libcxx/include/__support/android/locale_bionic.h create mode 100644 app/src/main/cpp/libcxx/include/__support/fuchsia/xlocale.h create mode 100644 app/src/main/cpp/libcxx/include/__support/ibm/gettod_zos.h create mode 100644 app/src/main/cpp/libcxx/include/__support/ibm/locale_mgmt_zos.h create mode 100644 app/src/main/cpp/libcxx/include/__support/ibm/nanosleep.h create mode 100644 app/src/main/cpp/libcxx/include/__support/ibm/xlocale.h create mode 100644 app/src/main/cpp/libcxx/include/__support/musl/xlocale.h create mode 100644 app/src/main/cpp/libcxx/include/__support/newlib/xlocale.h create mode 100644 app/src/main/cpp/libcxx/include/__support/openbsd/xlocale.h create mode 100644 app/src/main/cpp/libcxx/include/__support/solaris/floatingpoint.h create mode 100644 app/src/main/cpp/libcxx/include/__support/solaris/wchar.h create mode 100644 app/src/main/cpp/libcxx/include/__support/solaris/xlocale.h create mode 100644 app/src/main/cpp/libcxx/include/__support/win32/locale_win32.h create mode 100644 app/src/main/cpp/libcxx/include/__support/xlocale/__nop_locale_mgmt.h create mode 100644 app/src/main/cpp/libcxx/include/__support/xlocale/__posix_l_fallback.h create mode 100644 app/src/main/cpp/libcxx/include/__support/xlocale/__strtonum_fallback.h create mode 100644 app/src/main/cpp/libcxx/include/__thread/poll_with_backoff.h create mode 100644 app/src/main/cpp/libcxx/include/__thread/timed_backoff_policy.h create mode 100644 app/src/main/cpp/libcxx/include/__threading_support create mode 100644 app/src/main/cpp/libcxx/include/__tree create mode 100644 app/src/main/cpp/libcxx/include/__tuple_dir/apply_cv.h create mode 100644 app/src/main/cpp/libcxx/include/__tuple_dir/make_tuple_types.h create mode 100644 app/src/main/cpp/libcxx/include/__tuple_dir/pair_like.h create mode 100644 app/src/main/cpp/libcxx/include/__tuple_dir/sfinae_helpers.h create mode 100644 app/src/main/cpp/libcxx/include/__tuple_dir/tuple_element.h create mode 100644 app/src/main/cpp/libcxx/include/__tuple_dir/tuple_indices.h create mode 100644 app/src/main/cpp/libcxx/include/__tuple_dir/tuple_like.h create mode 100644 app/src/main/cpp/libcxx/include/__tuple_dir/tuple_like_ext.h create mode 100644 app/src/main/cpp/libcxx/include/__tuple_dir/tuple_size.h create mode 100644 app/src/main/cpp/libcxx/include/__tuple_dir/tuple_types.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/add_const.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/add_cv.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/add_lvalue_reference.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/add_pointer.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/add_rvalue_reference.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/add_volatile.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/aligned_storage.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/aligned_union.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/alignment_of.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/apply_cv.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/can_extract_key.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/common_reference.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/common_type.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/conditional.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/conjunction.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/copy_cv.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/copy_cvref.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/decay.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/dependent_type.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/disjunction.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/enable_if.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/extent.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/has_unique_object_representation.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/has_virtual_destructor.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/integral_constant.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_abstract.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_aggregate.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_allocator.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_always_bitcastable.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_arithmetic.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_array.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_assignable.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_base_of.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_bounded_array.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_callable.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_char_like_type.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_class.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_compound.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_const.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_constant_evaluated.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_constructible.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_convertible.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_copy_assignable.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_copy_constructible.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_core_convertible.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_default_constructible.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_destructible.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_empty.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_enum.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_final.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_floating_point.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_function.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_fundamental.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_implicitly_default_constructible.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_integral.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_literal_type.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_member_function_pointer.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_member_object_pointer.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_member_pointer.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_move_assignable.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_move_constructible.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_nothrow_assignable.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_nothrow_constructible.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_nothrow_convertible.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_nothrow_copy_assignable.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_nothrow_copy_constructible.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_nothrow_default_constructible.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_nothrow_destructible.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_nothrow_move_assignable.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_nothrow_move_constructible.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_null_pointer.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_object.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_pod.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_pointer.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_polymorphic.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_primary_template.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_reference.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_reference_wrapper.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_referenceable.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_same.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_scalar.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_scoped_enum.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_signed.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_signed_integer.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_specialization.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_standard_layout.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_swappable.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_trivial.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_trivially_assignable.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_trivially_constructible.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_trivially_copy_assignable.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_trivially_copy_constructible.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_trivially_copyable.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_trivially_default_constructible.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_trivially_destructible.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_trivially_move_assignable.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_trivially_move_constructible.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_unbounded_array.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_union.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_unsigned.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_unsigned_integer.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_valid_expansion.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_void.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/is_volatile.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/lazy.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/make_32_64_or_128_bit.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/make_const_lvalue_ref.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/make_signed.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/make_unsigned.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/maybe_const.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/nat.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/negation.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/noexcept_move_assign_container.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/promote.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/rank.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/remove_all_extents.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/remove_const.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/remove_const_ref.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/remove_cv.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/remove_cvref.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/remove_extent.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/remove_pointer.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/remove_reference.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/remove_volatile.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/result_of.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/strip_signature.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/type_identity.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/type_list.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/underlying_type.h create mode 100644 app/src/main/cpp/libcxx/include/__type_traits/void_t.h create mode 100644 app/src/main/cpp/libcxx/include/__undef_macros create mode 100644 app/src/main/cpp/libcxx/include/__utility/as_const.h create mode 100644 app/src/main/cpp/libcxx/include/__utility/auto_cast.h create mode 100644 app/src/main/cpp/libcxx/include/__utility/cmp.h create mode 100644 app/src/main/cpp/libcxx/include/__utility/convert_to_integral.h create mode 100644 app/src/main/cpp/libcxx/include/__utility/declval.h create mode 100644 app/src/main/cpp/libcxx/include/__utility/exception_guard.h create mode 100644 app/src/main/cpp/libcxx/include/__utility/exchange.h create mode 100644 app/src/main/cpp/libcxx/include/__utility/forward.h create mode 100644 app/src/main/cpp/libcxx/include/__utility/forward_like.h create mode 100644 app/src/main/cpp/libcxx/include/__utility/in_place.h create mode 100644 app/src/main/cpp/libcxx/include/__utility/integer_sequence.h create mode 100644 app/src/main/cpp/libcxx/include/__utility/move.h create mode 100644 app/src/main/cpp/libcxx/include/__utility/pair.h create mode 100644 app/src/main/cpp/libcxx/include/__utility/piecewise_construct.h create mode 100644 app/src/main/cpp/libcxx/include/__utility/priority_tag.h create mode 100644 app/src/main/cpp/libcxx/include/__utility/rel_ops.h create mode 100644 app/src/main/cpp/libcxx/include/__utility/swap.h create mode 100644 app/src/main/cpp/libcxx/include/__utility/to_underlying.h create mode 100644 app/src/main/cpp/libcxx/include/__utility/unreachable.h create mode 100644 app/src/main/cpp/libcxx/include/__variant/monostate.h create mode 100644 app/src/main/cpp/libcxx/include/__verbose_abort create mode 100644 app/src/main/cpp/libcxx/include/abi/CMakeLists.txt create mode 100644 app/src/main/cpp/libcxx/include/abi/__cxxabi_config.h create mode 100644 app/src/main/cpp/libcxx/include/abi/cxxabi.h create mode 100644 app/src/main/cpp/libcxx/include/algorithm create mode 100644 app/src/main/cpp/libcxx/include/any create mode 100644 app/src/main/cpp/libcxx/include/array create mode 100644 app/src/main/cpp/libcxx/include/atomic create mode 100644 app/src/main/cpp/libcxx/include/barrier create mode 100644 app/src/main/cpp/libcxx/include/bit create mode 100644 app/src/main/cpp/libcxx/include/bitset create mode 100644 app/src/main/cpp/libcxx/include/cassert create mode 100644 app/src/main/cpp/libcxx/include/ccomplex create mode 100644 app/src/main/cpp/libcxx/include/cctype create mode 100644 app/src/main/cpp/libcxx/include/cerrno create mode 100644 app/src/main/cpp/libcxx/include/cfenv create mode 100644 app/src/main/cpp/libcxx/include/cfloat create mode 100644 app/src/main/cpp/libcxx/include/charconv create mode 100644 app/src/main/cpp/libcxx/include/chrono create mode 100644 app/src/main/cpp/libcxx/include/cinttypes create mode 100644 app/src/main/cpp/libcxx/include/ciso646 create mode 100644 app/src/main/cpp/libcxx/include/climits create mode 100644 app/src/main/cpp/libcxx/include/clocale create mode 100644 app/src/main/cpp/libcxx/include/cmath create mode 100644 app/src/main/cpp/libcxx/include/codecvt create mode 100644 app/src/main/cpp/libcxx/include/compare create mode 100644 app/src/main/cpp/libcxx/include/complex create mode 100644 app/src/main/cpp/libcxx/include/complex.h create mode 100644 app/src/main/cpp/libcxx/include/concepts create mode 100644 app/src/main/cpp/libcxx/include/condition_variable create mode 100644 app/src/main/cpp/libcxx/include/coroutine create mode 100644 app/src/main/cpp/libcxx/include/csetjmp create mode 100644 app/src/main/cpp/libcxx/include/csignal create mode 100644 app/src/main/cpp/libcxx/include/cstdarg create mode 100644 app/src/main/cpp/libcxx/include/cstdbool create mode 100644 app/src/main/cpp/libcxx/include/cstddef create mode 100644 app/src/main/cpp/libcxx/include/cstdint create mode 100644 app/src/main/cpp/libcxx/include/cstdio create mode 100644 app/src/main/cpp/libcxx/include/cstdlib create mode 100644 app/src/main/cpp/libcxx/include/cstring create mode 100644 app/src/main/cpp/libcxx/include/ctgmath create mode 100644 app/src/main/cpp/libcxx/include/ctime create mode 100644 app/src/main/cpp/libcxx/include/ctype.h create mode 100644 app/src/main/cpp/libcxx/include/cuchar create mode 100644 app/src/main/cpp/libcxx/include/cwchar create mode 100644 app/src/main/cpp/libcxx/include/cwctype create mode 100644 app/src/main/cpp/libcxx/include/deque create mode 100644 app/src/main/cpp/libcxx/include/errno.h create mode 100644 app/src/main/cpp/libcxx/include/exception create mode 100644 app/src/main/cpp/libcxx/include/execution create mode 100644 app/src/main/cpp/libcxx/include/expected create mode 100644 app/src/main/cpp/libcxx/include/experimental/__config create mode 100644 app/src/main/cpp/libcxx/include/experimental/__memory create mode 100644 app/src/main/cpp/libcxx/include/experimental/algorithm create mode 100644 app/src/main/cpp/libcxx/include/experimental/coroutine create mode 100644 app/src/main/cpp/libcxx/include/experimental/deque create mode 100644 app/src/main/cpp/libcxx/include/experimental/forward_list create mode 100644 app/src/main/cpp/libcxx/include/experimental/functional create mode 100644 app/src/main/cpp/libcxx/include/experimental/iterator create mode 100644 app/src/main/cpp/libcxx/include/experimental/list create mode 100644 app/src/main/cpp/libcxx/include/experimental/map create mode 100644 app/src/main/cpp/libcxx/include/experimental/memory_resource create mode 100644 app/src/main/cpp/libcxx/include/experimental/propagate_const create mode 100644 app/src/main/cpp/libcxx/include/experimental/regex create mode 100644 app/src/main/cpp/libcxx/include/experimental/set create mode 100644 app/src/main/cpp/libcxx/include/experimental/simd create mode 100644 app/src/main/cpp/libcxx/include/experimental/string create mode 100644 app/src/main/cpp/libcxx/include/experimental/type_traits create mode 100644 app/src/main/cpp/libcxx/include/experimental/unordered_map create mode 100644 app/src/main/cpp/libcxx/include/experimental/unordered_set create mode 100644 app/src/main/cpp/libcxx/include/experimental/utility create mode 100644 app/src/main/cpp/libcxx/include/experimental/vector create mode 100644 app/src/main/cpp/libcxx/include/ext/__hash create mode 100644 app/src/main/cpp/libcxx/include/ext/hash_map create mode 100644 app/src/main/cpp/libcxx/include/ext/hash_set create mode 100644 app/src/main/cpp/libcxx/include/fenv.h create mode 100644 app/src/main/cpp/libcxx/include/filesystem create mode 100644 app/src/main/cpp/libcxx/include/float.h create mode 100644 app/src/main/cpp/libcxx/include/format create mode 100644 app/src/main/cpp/libcxx/include/forward_list create mode 100644 app/src/main/cpp/libcxx/include/fstream create mode 100644 app/src/main/cpp/libcxx/include/functional create mode 100644 app/src/main/cpp/libcxx/include/future create mode 100644 app/src/main/cpp/libcxx/include/initializer_list create mode 100644 app/src/main/cpp/libcxx/include/inttypes.h create mode 100644 app/src/main/cpp/libcxx/include/iomanip create mode 100644 app/src/main/cpp/libcxx/include/ios create mode 100644 app/src/main/cpp/libcxx/include/iosfwd create mode 100644 app/src/main/cpp/libcxx/include/iostream create mode 100644 app/src/main/cpp/libcxx/include/istream create mode 100644 app/src/main/cpp/libcxx/include/iterator create mode 100644 app/src/main/cpp/libcxx/include/latch create mode 100644 app/src/main/cpp/libcxx/include/libcxx.imp create mode 100644 app/src/main/cpp/libcxx/include/limits create mode 100644 app/src/main/cpp/libcxx/include/limits.h create mode 100644 app/src/main/cpp/libcxx/include/list create mode 100644 app/src/main/cpp/libcxx/include/locale create mode 100644 app/src/main/cpp/libcxx/include/locale.h create mode 100644 app/src/main/cpp/libcxx/include/map create mode 100644 app/src/main/cpp/libcxx/include/math.h create mode 100644 app/src/main/cpp/libcxx/include/memory create mode 100644 app/src/main/cpp/libcxx/include/memory_resource create mode 100644 app/src/main/cpp/libcxx/include/module.modulemap.in create mode 100644 app/src/main/cpp/libcxx/include/mutex create mode 100644 app/src/main/cpp/libcxx/include/new create mode 100644 app/src/main/cpp/libcxx/include/numbers create mode 100644 app/src/main/cpp/libcxx/include/numeric create mode 100644 app/src/main/cpp/libcxx/include/optional create mode 100644 app/src/main/cpp/libcxx/include/ostream create mode 100644 app/src/main/cpp/libcxx/include/queue create mode 100644 app/src/main/cpp/libcxx/include/random create mode 100644 app/src/main/cpp/libcxx/include/ranges create mode 100644 app/src/main/cpp/libcxx/include/ratio create mode 100644 app/src/main/cpp/libcxx/include/regex create mode 100644 app/src/main/cpp/libcxx/include/scoped_allocator create mode 100644 app/src/main/cpp/libcxx/include/semaphore create mode 100644 app/src/main/cpp/libcxx/include/set create mode 100644 app/src/main/cpp/libcxx/include/setjmp.h create mode 100644 app/src/main/cpp/libcxx/include/shared_mutex create mode 100644 app/src/main/cpp/libcxx/include/source_location create mode 100644 app/src/main/cpp/libcxx/include/span create mode 100644 app/src/main/cpp/libcxx/include/sstream create mode 100644 app/src/main/cpp/libcxx/include/stack create mode 100644 app/src/main/cpp/libcxx/include/stdatomic.h create mode 100644 app/src/main/cpp/libcxx/include/stdbool.h create mode 100644 app/src/main/cpp/libcxx/include/stddef.h create mode 100644 app/src/main/cpp/libcxx/include/stdexcept create mode 100644 app/src/main/cpp/libcxx/include/stdint.h create mode 100644 app/src/main/cpp/libcxx/include/stdio.h create mode 100644 app/src/main/cpp/libcxx/include/stdlib.h create mode 100644 app/src/main/cpp/libcxx/include/streambuf create mode 100644 app/src/main/cpp/libcxx/include/string create mode 100644 app/src/main/cpp/libcxx/include/string.h create mode 100644 app/src/main/cpp/libcxx/include/string_view create mode 100644 app/src/main/cpp/libcxx/include/strstream create mode 100644 app/src/main/cpp/libcxx/include/system_error create mode 100644 app/src/main/cpp/libcxx/include/tgmath.h create mode 100644 app/src/main/cpp/libcxx/include/thread create mode 100644 app/src/main/cpp/libcxx/include/tuple create mode 100644 app/src/main/cpp/libcxx/include/type_traits create mode 100644 app/src/main/cpp/libcxx/include/typeindex create mode 100644 app/src/main/cpp/libcxx/include/typeinfo create mode 100644 app/src/main/cpp/libcxx/include/uchar.h create mode 100644 app/src/main/cpp/libcxx/include/unordered_map create mode 100644 app/src/main/cpp/libcxx/include/unordered_set create mode 100644 app/src/main/cpp/libcxx/include/utility create mode 100644 app/src/main/cpp/libcxx/include/valarray create mode 100644 app/src/main/cpp/libcxx/include/variant create mode 100644 app/src/main/cpp/libcxx/include/vector create mode 100644 app/src/main/cpp/libcxx/include/version create mode 100644 app/src/main/cpp/libcxx/include/wchar.h create mode 100644 app/src/main/cpp/libcxx/include/wctype.h create mode 100644 app/src/main/cpp/libcxx/x86/libcxx.a create mode 100644 app/src/main/cpp/libcxx/x86_64/libcxx.a diff --git a/.gitmodules b/.gitmodules index 15d4b83..bc42722 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "app/src/main/cpp/libcxx"] - path = app/src/main/cpp/libcxx - url = https://github.com/topjohnwu/libcxx.git +[submodule "app/src/main/cpp/Dobby"] + path = app/src/main/cpp/Dobby + url = https://github.com/LSPosed/Dobby.git diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 47abbdb..e6b9f2d 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -1 +1,2 @@ --keep class es.chiteroman.playintegrityfix.EntryPoint {public ;} \ No newline at end of file +-keep class es.chiteroman.playintegrityfix.EntryPoint {public ;} +-keep class es.chiteroman.playintegrityfix.CustomProvider \ No newline at end of file diff --git a/app/src/main/cpp/Dobby b/app/src/main/cpp/Dobby new file mode 160000 index 0000000..6813ca7 --- /dev/null +++ b/app/src/main/cpp/Dobby @@ -0,0 +1 @@ +Subproject commit 6813ca76ddeafcaece525bf8c6cde7ff4c21d3ce diff --git a/app/src/main/cpp/Dobby/.clang-format b/app/src/main/cpp/Dobby/.clang-format deleted file mode 100644 index 17d6bc4..0000000 --- a/app/src/main/cpp/Dobby/.clang-format +++ /dev/null @@ -1,18 +0,0 @@ -BasedOnStyle: LLVM - -IndentWidth: 2 -TabWidth: 2 -UseTab: Never -ColumnLimit: 120 - -FixNamespaceComments: true - -# default is false -#AlignConsecutiveMacros: true -#AlignConsecutiveAssignments: true -#AlignConsecutiveDeclarations: true - -# default is true -ReflowComments: false -SortIncludes : false -AllowShortFunctionsOnASingleLine: false \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/.github/workflows/Builder.yaml b/app/src/main/cpp/Dobby/.github/workflows/Builder.yaml deleted file mode 100644 index 015497c..0000000 --- a/app/src/main/cpp/Dobby/.github/workflows/Builder.yaml +++ /dev/null @@ -1,114 +0,0 @@ -name: Builder - -on: - push: - branches: - - master - -env: - CMAKE_VERSION: 3.20.2 - LLVM_VERSION: 14.0.0 - NDK_VERSION: r25b - -jobs: - delete_latest_release: - runs-on: ubuntu-latest - steps: - - name: checkout master - uses: actions/checkout@master - - - name: delete latest release - uses: dev-drprasad/delete-tag-and-release@v0.2.0 - with: - delete_release: true - tag_name: latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - linux_and_android: - runs-on: ubuntu-latest - needs: delete_latest_release - steps: - - name: checkout master - uses: actions/checkout@master - - - name: init linux cross compile env - run: | - sh scripts/setup_linux_cross_compile.sh - mkdir -p artifact - shell: bash - - - name: compile linux - run: | - python3 scripts/platform_builder.py --platform=linux --arch=all --cmake_dir=$HOME/opt/cmake-$CMAKE_VERSION --llvm_dir=$HOME/opt/llvm-$LLVM_VERSION - cp include/dobby.h build/linux - tar -zcvf build/dobby-linux-all.tar.gz build/linux - cp build/dobby-linux-all.tar.gz artifact/ - - shell: bash - - - name: compile android - run: | - python3 scripts/platform_builder.py --platform=android --arch=all --cmake_dir=$HOME/opt/cmake-$CMAKE_VERSION --llvm_dir=$HOME/opt/llvm-$LLVM_VERSION --android_ndk_dir=$HOME/opt/ndk-$NDK_VERSION - cp include/dobby.h build/android - tar -zcvf build/dobby-android-all.tar.gz build/android - cp build/dobby-android-all.tar.gz artifact/ - shell: bash - - - name: print output - run: | - ls -lha . - - - name: update release - uses: ncipollo/release-action@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - tag: latest - body: "a lightweight, multi-platform, multi-architecture exploit hook framework" - artifacts: "build/dobby-linux-all.tar.gz,build/dobby-android-all.tar.gz" - allowUpdates: true - replacesArtifacts: true - - macos_and_iphoneos: - runs-on: macos-latest - needs: delete_latest_release - steps: - - name: checkout dev - uses: actions/checkout@master - - - name: init macos compile env - run: | - sh scripts/setup_macos_cross_compile.sh - mkdir -p artifact - shell: bash - - - name: compile macos - run: | - python3 scripts/platform_builder.py --platform=macos --arch=all --cmake_dir=$HOME/opt/cmake-$CMAKE_VERSION/CMake.app/Contents - cp include/dobby.h build/macos - tar -zcvf build/dobby-macos-all.tar.gz build/macos - cp build/dobby-macos-all.tar.gz artifact/ - - shell: bash - - - name: compile iphoneos - run: | - python3 scripts/platform_builder.py --platform=iphoneos --arch=all --cmake_dir=$HOME/opt/cmake-$CMAKE_VERSION/CMake.app/Contents - cp include/dobby.h build/iphoneos - tar -zcvf build/dobby-iphoneos-all.tar.gz build/iphoneos - cp build/dobby-iphoneos-all.tar.gz artifact/ - shell: bash - - - name: print output - run: | - ls -lha . - - - name: update release - uses: ncipollo/release-action@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - tag: latest - body: "a lightweight, multi-platform, multi-architecture exploit hook framework" - artifacts: "build/dobby-macos-all.tar.gz,build/dobby-iphoneos-all.tar.gz" - allowUpdates: true - replacesArtifacts: true \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/.gitignore b/app/src/main/cpp/Dobby/.gitignore deleted file mode 100644 index 4bbed76..0000000 --- a/app/src/main/cpp/Dobby/.gitignore +++ /dev/null @@ -1,80 +0,0 @@ -.DS_Store -.idea/ -*-build*/ -build-output/ - -CMakeLists.txt.user -CMakeCache.txt -CMakeFiles -CMakeScripts -Testing -Makefile -cmake_install.cmake -install_manifest.txt -compile_commands.json -CTestTestfile.cmake -_deps - -## Build generated -build/ -DerivedData/ - -## Various settings -*.pbxuser -!default.pbxuser -*.mode1v3 -!default.mode1v3 -*.mode2v3 -!default.mode2v3 -*.perspectivev3 -!default.perspectivev3 -xcuserdata/ - -## Other -*.moved-aside -*.xccheckout -*.xcscmblueprint - -## Obj-C/Swift specific -*.hmap -*.ipa -*.dSYM.zip -*.dSYM - -# Prerequisites -*.d - -# Compiled Object files -*.slo -*.lo -*.o -*.obj - -# Precompiled Headers -*.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Fortran module files -*.mod -*.smod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app - -# Prefab -/prefab/**/*.a -/prefab/**/*.h -/AndroidManifest.xml diff --git a/app/src/main/cpp/Dobby/.vscode/c_cpp_properties.json b/app/src/main/cpp/Dobby/.vscode/c_cpp_properties.json deleted file mode 100644 index c624a58..0000000 --- a/app/src/main/cpp/Dobby/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "configurations": [ - { - "name": "Mac", - "includePath": [ - "/usr/local/include", - "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1", - "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include", - "${workspaceRoot}" - ], - "defines": [], - "intelliSenseMode": "clang-x64", - "browse": { - "path": [ - "/usr/local/include", - "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include", - "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1", - "${workspaceRoot}" - ], - "limitSymbolsToIncludedHeaders": true, - "databaseFilename": "" - }, - "macFrameworkPath": [ - "/System/Library/Frameworks", - "/Library/Frameworks" - ], - "compilerPath": "/usr/bin/clang", - "cStandard": "c11", - "cppStandard": "c++11", - "configurationProvider": "vector-of-bool.cmake-tools", - "compileCommands": "${workspaceRoot}/ninja-build/compile_commands.json" - }, - { - "name": "Linux", - "includePath": [ - "/usr/include", - "/usr/local/include", - "${workspaceRoot}" - ], - "defines": [], - "intelliSenseMode": "clang-x64", - "browse": { - "path": [ - "/usr/include", - "/usr/local/include", - "${workspaceRoot}" - ], - "limitSymbolsToIncludedHeaders": true, - "databaseFilename": "" - } - }, - { - "name": "Win32", - "includePath": [ - "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include", - "${workspaceRoot}" - ], - "defines": [ - "_DEBUG", - "UNICODE" - ], - "intelliSenseMode": "msvc-x64", - "browse": { - "path": [ - "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include/*", - "${workspaceRoot}" - ], - "limitSymbolsToIncludedHeaders": true, - "databaseFilename": "" - } - } - ], - "version": 4 -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/.vscode/launch.json b/app/src/main/cpp/Dobby/.vscode/launch.json deleted file mode 100644 index 36ab19f..0000000 --- a/app/src/main/cpp/Dobby/.vscode/launch.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "name": "(lldb) Launch", - "type": "cppdbg", - "request": "launch", - "program": "enter program name, for example ${workspaceRoot}/a.out", - "args": [], - "stopAtEntry": false, - "cwd": "${workspaceRoot}", - "environment": [], - "externalConsole": true, - "MIMode": "lldb" - } - ] -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/.vscode/settings.json b/app/src/main/cpp/Dobby/.vscode/settings.json deleted file mode 100644 index e925cff..0000000 --- a/app/src/main/cpp/Dobby/.vscode/settings.json +++ /dev/null @@ -1,121 +0,0 @@ -{ - "files.autoSave": "onFocusChange", - "files.autoSaveDelay": 3000, - "editor.formatOnSave": true, - "cmake.environment": { - "ANDROID_NDK": "/Users/jmpews/Library/Android/sdk/ndk-bundle" - }, - "cmake.configureArgs": [ - "-DCMAKE_SYSTEM_NAME=Android", - "-DCMAKE_ANDROID_ARCH_ABI=armeabi-v7a", - "-DCMAKE_ANDROID_NDK=/Users/jmpews/Library/Android/sdk/ndk/21.3.6528147", - "-DCMAKE_SYSTEM_VERSION=16", - "-DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang" - ], - "cmake.buildArgs": [], - "cmake.buildToolArgs": [], - "cmake.parallelJobs": 1, - "files.associations": { - "stack": "cpp", - "regex": "cpp", - "bitset": "cpp", - "functional": "cpp", - "iterator": "cpp", - "memory": "cpp", - "__bit_reference": "cpp", - "__functional_base": "cpp", - "algorithm": "cpp", - "atomic": "cpp", - "chrono": "cpp", - "deque": "cpp", - "optional": "cpp", - "limits": "cpp", - "locale": "cpp", - "ratio": "cpp", - "system_error": "cpp", - "tuple": "cpp", - "type_traits": "cpp", - "vector": "cpp", - "utility": "cpp", - "__functional_03": "cpp", - "__locale": "cpp", - "__hash_table": "cpp", - "__split_buffer": "cpp", - "__tree": "cpp", - "hash_map": "cpp", - "hash_set": "cpp", - "map": "cpp", - "set": "cpp", - "string": "cpp", - "string_view": "cpp", - "unordered_map": "cpp", - "unordered_set": "cpp", - "initializer_list": "cpp", - "hashtable": "cpp", - "__config": "cpp", - "__nullptr": "cpp", - "cstddef": "cpp", - "exception": "cpp", - "new": "cpp", - "stdexcept": "cpp", - "typeinfo": "cpp", - "*.tcc": "cpp", - "xstring": "cpp", - "xlocmon": "cpp", - "xtr1common": "cpp", - "list": "cpp", - "xhash": "cpp", - "xtree": "cpp", - "xutility": "cpp", - "iosfwd": "cpp", - "__debug": "cpp", - "__mutex_base": "cpp", - "__string": "cpp", - "__threading_support": "cpp", - "__tuple": "cpp", - "cctype": "cpp", - "cstdarg": "cpp", - "cstdint": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "cstring": "cpp", - "ctime": "cpp", - "cwchar": "cpp", - "cwctype": "cpp", - "ios": "cpp", - "iostream": "cpp", - "istream": "cpp", - "mutex": "cpp", - "ostream": "cpp", - "streambuf": "cpp", - "cmath": "cpp", - "array": "cpp", - "fstream": "cpp", - "stdio.h": "c", - "__functional_base_03": "cpp", - "filesystem": "cpp", - "queue": "cpp", - "random": "cpp", - "__errc": "cpp", - "__node_handle": "cpp", - "bit": "cpp", - "complex": "cpp", - "iomanip": "cpp", - "sstream": "cpp", - "stdarg.h": "c", - "clocale": "cpp", - "codecvt": "cpp", - "condition_variable": "cpp", - "numeric": "cpp", - "shared_mutex": "cpp", - "thread": "cpp", - "memory_resource": "cpp", - "cinttypes": "cpp", - "shared_cache_internal.h": "c", - "coroutine": "cpp", - "__bits": "cpp" - }, - "C_Cpp.configurationWarnings": "Disabled", - "lldb.showDisassembly": "auto", - "lldb.dereferencePointers": true, -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/.vscode/tags b/app/src/main/cpp/Dobby/.vscode/tags deleted file mode 100644 index db0ba7e..0000000 --- a/app/src/main/cpp/Dobby/.vscode/tags +++ /dev/null @@ -1,13 +0,0 @@ -!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ -!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ -!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/ -!_TAG_PROGRAM_NAME Exuberant Ctags // -!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ -!_TAG_PROGRAM_VERSION 5.8 // -HookZzCodeSegment ../tools/zzsolidifyhook.py /^HookZzCodeSegment = [$/;" kind:variable line:4 -lief ../tools/zzsolidifyhook.py /^import lief$/;" kind:namespace line:2 -new_target_file ../tools/zzsolidifyhook.py /^new_target_file = "\/Users\/jmpews\/Desktop\/test\/test.hook.dylib"$/;" kind:variable line:31 -target_file ../tools/zzsolidifyhook.py /^target_file = "\/Users\/jmpews\/Desktop\/test\/test.dylib"$/;" kind:variable line:30 -zz_macho_get_segment_with_name ../tools/zzsolidifyhook.py /^def zz_macho_get_segment_with_name(target_parsed, seg_name):$/;" kind:function line:13 -zz_macho_insert_segment ../tools/zzsolidifyhook.py /^def zz_macho_insert_segment(target_file, new_target_file):$/;" kind:function line:20 -zzsolidifyhook.py ../tools/zzsolidifyhook.py 1;" kind:file line:1 diff --git a/app/src/main/cpp/Dobby/CMakeLists.txt b/app/src/main/cpp/Dobby/CMakeLists.txt deleted file mode 100644 index 20f87f0..0000000 --- a/app/src/main/cpp/Dobby/CMakeLists.txt +++ /dev/null @@ -1,362 +0,0 @@ -cmake_minimum_required(VERSION 3.5) -project(Dobby) -enable_language(ASM) - -include(cmake/Util.cmake) -include(cmake/Macros.cmake) -include(cmake/build_environment_check.cmake) -include(cmake/auto_source_group.cmake) -include(cmake/xcode_generator_helper.cmake) - -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_C_STANDARD 11) - -auto_source_group("." "auto-source-group" "\\.(cc|cpp|c|h)$") - -# ===== handle option ===== - -option(DOBBY_GENERATE_SHARED "Build shared library" ON) - -option(DOBBY_DEBUG "Enable debug logging" OFF) - -option(NearBranch "Enable near branch trampoline" ON) - -option(FullFloatingPointRegisterPack "Save and pack all floating-point registers" OFF) - -option(Plugin.SymbolResolver "Enable symbol resolver" ON) - -option(Plugin.ImportTableReplace "Enable import table replace " OFF) - -option(Plugin.Android.BionicLinkerUtil "Enable android bionic linker util" OFF) - -option(BUILD_EXAMPLE "Build example" OFF) - -option(BUILD_TEST "Build test" OFF) - -# private -option(Obfuscation "Enable llvm obfuscation" OFF) - -# private -option(BUILD_KERNEL_MODE "Build xnu kernel mode" OFF) - -# Enable debug will log more information -if ((NOT DEFINED CMAKE_BUILD_TYPE) OR (CMAKE_BUILD_TYPE STREQUAL "Debug")) - set(DOBBY_DEBUG ON) -endif () - -if (DOBBY_DEBUG) - add_definitions(-DDOBBY_DEBUG) - add_definitions(-DLOGGING_DEBUG) - message(STATUS "[Dobby] Enable debug logging") -endif () - -# Enable full floating point register pack -# for arm64, allow access q8 - q31 -if (FullFloatingPointRegisterPack) - add_definitions(-DFULL_FLOATING_POINT_REGISTER_PACK) - message(STATUS "[Dobby] Save and pack all floating-point registers") -endif () - -if (BUILD_KERNEL_MODE) - set(BUILDING_KERNEL ON) - add_definitions(-DBUILDING_KERNEL) - message(STATUS "[Dobby] Build xnu kernel mode") -endif () - -if (CMAKE_GENERATOR STREQUAL Xcode) -endif () - -include(cmake/compiler_and_linker.cmake) - -# --- - -include_directories( - . - ./include - ./source - ./source/include - - ./external - ./external/logging - - ./builtin-plugin -) - -if (SYSTEM.Darwin AND BUILDING_KERNEL) - include_directories( - source/Backend/KernelMode - ) -else () - include_directories( - source/Backend/UserMode - ) -endif () - -# --- - -set(DOBBY_DIR ${CMAKE_CURRENT_SOURCE_DIR}) -set(dobby.SOURCE_FILE_LIST ${dobby.SOURCE_FILE_LIST} - # cpu - source/core/arch/CpuFeature.cc - source/core/arch/CpuRegister.cc - - # assembler - source/core/assembler/assembler.cc - source/core/assembler/assembler-arm.cc - source/core/assembler/assembler-arm64.cc - source/core/assembler/assembler-ia32.cc - source/core/assembler/assembler-x64.cc - - # codegen - source/core/codegen/codegen-arm.cc - source/core/codegen/codegen-arm64.cc - source/core/codegen/codegen-ia32.cc - source/core/codegen/codegen-x64.cc - - # memory kit - source/MemoryAllocator/CodeBuffer/CodeBufferBase.cc - source/MemoryAllocator/AssemblyCodeBuilder.cc - source/MemoryAllocator/MemoryAllocator.cc - - # instruction relocation - source/InstructionRelocation/arm/InstructionRelocationARM.cc - source/InstructionRelocation/arm64/InstructionRelocationARM64.cc - source/InstructionRelocation/x86/InstructionRelocationX86.cc - source/InstructionRelocation/x86/InstructionRelocationX86Shared.cc - source/InstructionRelocation/x64/InstructionRelocationX64.cc - source/InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.c - - # intercept routing - source/InterceptRouting/InterceptRouting.cpp - - # intercept routing trampoline - source/TrampolineBridge/Trampoline/arm/trampoline_arm.cc - source/TrampolineBridge/Trampoline/arm64/trampoline_arm64.cc - source/TrampolineBridge/Trampoline/x86/trampoline_x86.cc - source/TrampolineBridge/Trampoline/x64/trampoline_x64.cc - - # closure trampoline bridge - arm - source/TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.cc - source/TrampolineBridge/ClosureTrampolineBridge/arm/helper_arm.cc - source/TrampolineBridge/ClosureTrampolineBridge/arm/closure_bridge_arm.cc - source/TrampolineBridge/ClosureTrampolineBridge/arm/ClosureTrampolineARM.cc - # closure trampoline bridge - arm64 - source/TrampolineBridge/ClosureTrampolineBridge/arm64/helper_arm64.cc - source/TrampolineBridge/ClosureTrampolineBridge/arm64/closure_bridge_arm64.cc - source/TrampolineBridge/ClosureTrampolineBridge/arm64/ClosureTrampolineARM64.cc - # closure trampoline bridge - x86 - source/TrampolineBridge/ClosureTrampolineBridge/x86/helper_x86.cc - source/TrampolineBridge/ClosureTrampolineBridge/x86/closure_bridge_x86.cc - source/TrampolineBridge/ClosureTrampolineBridge/x86/ClosureTrampolineX86.cc - # closure trampoline bridge - x64 - source/TrampolineBridge/ClosureTrampolineBridge/x64/helper_x64.cc - source/TrampolineBridge/ClosureTrampolineBridge/x64/closure_bridge_x64.cc - source/TrampolineBridge/ClosureTrampolineBridge/x64/ClosureTrampolineX64.cc - - source/InterceptRouting/Routing/InstructionInstrument/InstructionInstrument.cc - source/InterceptRouting/Routing/InstructionInstrument/RoutingImpl.cc - source/InterceptRouting/Routing/InstructionInstrument/instrument_routing_handler.cc - - source/InterceptRouting/Routing/FunctionInlineHook/FunctionInlineHook.cc - source/InterceptRouting/Routing/FunctionInlineHook/RoutingImpl.cc - - # plugin register - source/InterceptRouting/RoutingPlugin/RoutingPlugin.cc - - # main - source/dobby.cpp - source/Interceptor.cpp - source/InterceptEntry.cpp - ) - -if (SYSTEM.Darwin AND BUILDING_KERNEL) - set(dobby.SOURCE_FILE_LIST ${dobby.SOURCE_FILE_LIST} - # platform util - source/Backend/KernelMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc - - # kernel mode - platform interface - source/Backend/KernelMode/UnifiedInterface/platform-darwin.cc - source/Backend/KernelMode/UnifiedInterface/exec_mem_placeholder.asm - - # kernel mode - executable memory - source/Backend/KernelMode/ExecMemory/code-patch-tool-darwin.cc - source/Backend/KernelMode/ExecMemory/clear-cache-tool-all.c - ) -elseif (SYSTEM.Darwin) - set(dobby.SOURCE_FILE_LIST ${dobby.SOURCE_FILE_LIST} - # platform util - source/Backend/UserMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc - - # user mode - platform interface - source/Backend/UserMode/UnifiedInterface/platform-posix.cc - - # user mode - executable memory - source/Backend/UserMode/ExecMemory/code-patch-tool-darwin.cc - source/Backend/UserMode/ExecMemory/clear-cache-tool-all.c - ) - -elseif (SYSTEM.Linux OR SYSTEM.Android) - set(dobby.SOURCE_FILE_LIST ${dobby.SOURCE_FILE_LIST} - # platform util - source/Backend/UserMode/PlatformUtil/Linux/ProcessRuntimeUtility.cc - - # user mode - platform interface - source/Backend/UserMode/UnifiedInterface/platform-posix.cc - - # user mode - executable memory - source/Backend/UserMode/ExecMemory/code-patch-tool-posix.cc - source/Backend/UserMode/ExecMemory/clear-cache-tool-all.c - ) -elseif (SYSTEM.Windows) - set(dobby.SOURCE_FILE_LIST ${dobby.SOURCE_FILE_LIST} - # platform util - source/Backend/UserMode/PlatformUtil/Windows/ProcessRuntimeUtility.cc - - # user mode - platform interface - source/Backend/UserMode/UnifiedInterface/platform-windows.cc - - # user mode - executable memory - source/Backend/UserMode/ExecMemory/code-patch-tool-windows.cc - source/Backend/UserMode/ExecMemory/clear-cache-tool-all.c - ) -endif () - -if (PROCESSOR.X86_64 OR PROCESSOR.X86) - set(NearBranch ON) -endif () - -# --- - -if (0 AND SYSTEM.iOS AND (NOT BUILDING_KERNEL)) - include_directories( - source/Backend/UserMode/ExecMemory/substrated - ) - add_definitions(-DCODE_PATCH_WITH_SUBSTRATED) - set(dobby.SOURCE_FILE_LIST ${dobby.SOURCE_FILE_LIST} - source/Backend/UserMode/ExecMemory/substrated/mach_interface_support - ) -endif () - -# ----- instrument ----- - -if (FunctionWrapper) - set(dobby.SOURCE_FILE_LIST ${dobby.SOURCE_FILE_LIST} - # user mode - multi thread support - # source/UserMode/MultiThreadSupport/ThreadSupport.cpp - # source/UserMode/Thread/PlatformThread.cc - # source/UserMode/Thread/platform-thread-${platform1}.cc - ) - message(FATAL_ERROR "[!] FunctionWrapper plugin is not supported") -endif () - -# --- - -if (NearBranch) - message(STATUS "[Dobby] Enable near branch trampoline") - set(dobby.SOURCE_FILE_LIST ${dobby.SOURCE_FILE_LIST} - source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/near_trampoline_arm64.cc - source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.cc - source/MemoryAllocator/NearMemoryAllocator.cc) -endif () - -# --- - -# add logging library -add_subdirectory(external/logging) -get_target_property(logging.SOURCE_FILE_LIST logging SOURCES) - -# --- - -if (Plugin.SymbolResolver) - message(STATUS "[Dobby] Enable symbol resolver") - include_directories(builtin-plugin/SymbolResolver) - add_subdirectory(builtin-plugin/SymbolResolver) - get_target_property(symbol_resolver.SOURCE_FILE_LIST symbol_resolver SOURCES) - set(dobby.plugin.SOURCE_FILE_LIST ${dobby.plugin.SOURCE_FILE_LIST} - ${symbol_resolver.SOURCE_FILE_LIST} - ) -endif () - -# --- - -set(dobby.HEADER_FILE_LIST - include/dobby.h - ) - -# --- - -# add build version -if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git") - execute_process( - COMMAND git rev-parse --short --verify HEAD - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - OUTPUT_VARIABLE VERSION_COMMIT_HASH - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - if (VERSION_COMMIT_HASH) - set(VERSION_REVISION "${VERSION_COMMIT_HASH}") - endif () -endif () -set(DOBBY_BUILD_VERSION "Dobby${VERSION_REVISION}") -add_definitions(-D__DOBBY_BUILD_VERSION__="${DOBBY_BUILD_VERSION}") -message(STATUS "[Dobby] ${DOBBY_BUILD_VERSION}") - -# --- - -if (DOBBY_GENERATE_SHARED) - message(STATUS "[Dobby] Generate shared library") - set(DOBBY_LIBRARY_TYPE SHARED) -else () - message(STATUS "[Dobby] Generate static library") - set(DOBBY_LIBRARY_TYPE STATIC) -endif () -add_library(dobby ${DOBBY_LIBRARY_TYPE} ${dobby.HEADER_FILE_LIST} ${dobby.SOURCE_FILE_LIST} ${logging.SOURCE_FILE_LIST} ${misc_helper.SOURCE_FILE_LIST} ${dobby.plugin.SOURCE_FILE_LIST}) - -# --- - -target_include_directories(dobby PUBLIC include) - -# --- - -if (Obfuscation) - set(linker_flags "${linker_flags} -Wl,-mllvm -Wl,-obfuscator-conf=all") -endif () - -set_target_properties(dobby - PROPERTIES - LINK_FLAGS "${linker_flags}" - COMPILE_FLAGS "${compiler_flags}" - ) - -# --- - -if (SYSTEM.Android) - target_link_libraries(dobby log) - if (PROCESSOR.ARM) - set_target_properties(dobby - PROPERTIES - ANDROID_ARM_MODE arm - ) - endif () -endif () - -if (SYSTEM.Linux) - target_link_libraries(dobby dl) -endif () - -# --- - -if (BUILD_EXAMPLE AND (NOT BUILDING_KERNEL)) - add_subdirectory(examples) -endif () - -if (BUILD_TEST AND (NOT BUILDING_KERNEL)) - add_subdirectory(tests) -endif () - -# --- - -if (SYSTEM.Darwin AND (NOT BUILDING_KERNEL)) - include(cmake/platform/platform-darwin.cmake) -endif () diff --git a/app/src/main/cpp/Dobby/LICENSE b/app/src/main/cpp/Dobby/LICENSE deleted file mode 100644 index f49a4e1..0000000 --- a/app/src/main/cpp/Dobby/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - 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. \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/README.md b/app/src/main/cpp/Dobby/README.md deleted file mode 100644 index c0c0195..0000000 --- a/app/src/main/cpp/Dobby/README.md +++ /dev/null @@ -1,26 +0,0 @@ -## Dobby - -[![Contact me Telegram](https://img.shields.io/badge/Contact%20me-Telegram-blue.svg)](https://t.me/IOFramebuffer) [![Join group Telegram](https://img.shields.io/badge/Join%20group-Telegram-brightgreen.svg)](https://t.me/dobby_group) - -Dobby a lightweight, multi-platform, multi-architecture exploit hook framework. - -- Minimal and modular library -- Multi-platform support(Windows/macOS/iOS/Android/Linux) -- Multiple architecture support(X86, X86-64, ARM, ARM64) - -## Compile - -[docs/compile.md](docs/compile.md) - -## Download - -[download latest library](https://github.com/jmpews/Dobby/releases/tag/latest) - -## Credits - -1. [frida-gum](https://github.com/frida/frida-gum) -2. [minhook](https://github.com/TsudaKageyu/minhook) -3. [substrate](https://github.com/jevinskie/substrate). -4. [v8](https://github.com/v8/v8) -5. [dart](https://github.com/dart-lang/sdk) -6. [vixl](https://git.linaro.org/arm/vixl.git) diff --git a/app/src/main/cpp/Dobby/README_zh-cn.md b/app/src/main/cpp/Dobby/README_zh-cn.md deleted file mode 100644 index 2f528b4..0000000 --- a/app/src/main/cpp/Dobby/README_zh-cn.md +++ /dev/null @@ -1,3 +0,0 @@ -## Dobby - -**å¾…æ›´æ–°** \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/MGCopyAnswerMonitor.cc b/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/MGCopyAnswerMonitor.cc deleted file mode 100644 index ddf2ee2..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/MGCopyAnswerMonitor.cc +++ /dev/null @@ -1,46 +0,0 @@ -#include "./dobby_monitor.h" - -#include -#include - -#define LOG_TAG "MGCopyAnswer" - -static uintptr_t getCallFirstArg(DobbyRegisterContext *ctx) { - uintptr_t result; -#if defined(_M_X64) || defined(__x86_64__) -#if defined(_WIN32) - result = ctx->general.regs.rcx; -#else - result = ctx->general.regs.rdi; -#endif -#elif defined(__arm64__) || defined(__aarch64__) - result = ctx->general.regs.x0; -#elif defined(__arm__) - result = ctx->general.regs.r0; -#else -#error "Not Support Architecture." -#endif - return result; -} - -void common_handler(DobbyRegisterContext *ctx, const InterceptEntry *info) { - CFStringRef key_ = 0; - key_ = (CFStringRef)getCallFirstArg(ctx); - - char str_key[256] = {0}; - CFStringGetCString(key_, str_key, 256, kCFStringEncodingUTF8); - LOG("[#] MGCopyAnswer:: %s\n", str_key); -} - -#if 0 -__attribute__((constructor)) static void ctor() { - void *lib = dlopen("/usr/lib/libMobileGestalt.dylib", RTLD_NOW); - void *MGCopyAnswer_addr = DobbySymbolResolver("libMobileGestalt.dylib", "MGCopyAnswer"); - - sleep(1); - - dobby_enable_near_branch_trampoline(); - DobbyInstrument((void *)MGCopyAnswer_addr, common_handler); - dobby_disable_near_branch_trampoline(); -} -#endif diff --git a/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/dynamic_loader_monitor.cc b/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/dynamic_loader_monitor.cc deleted file mode 100644 index 5de4284..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/dynamic_loader_monitor.cc +++ /dev/null @@ -1,94 +0,0 @@ -#include /* getenv */ -#include -#include - -#include -#include - -#include -#include - -#include -#include - -#include "dobby.h" - -#include "common_header.h" - -#define LOG_TAG "DynamicLoaderMonitor" - -std::unordered_map traced_dlopen_handle_list; - -static void *(*orig_dlopen)(const char *__file, int __mode); -static void *fake_dlopen(const char *__file, int __mode) { - void *result = orig_dlopen(__file, __mode); - if (result != NULL && __file) { - char *traced_filename = (char *)malloc(MAXPATHLEN); - // FIXME: strncpy - strcpy(traced_filename, __file); - LOG(1, "[-] dlopen handle: %s", __file); - traced_dlopen_handle_list.insert(std::make_pair(result, (const char *)traced_filename)); - } - return result; -} - -static void *(*orig_loader_dlopen)(const char *filename, int flags, const void *caller_addr); -static void *fake_loader_dlopen(const char *filename, int flags, const void *caller_addr) { - void *result = orig_loader_dlopen(filename, flags, caller_addr); - if (result != NULL) { - char *traced_filename = (char *)malloc(MAXPATHLEN); - // FIXME: strncpy - strcpy(traced_filename, filename); - LOG(1, "[-] dlopen handle: %s", filename); - traced_dlopen_handle_list.insert(std::make_pair(result, (const char *)traced_filename)); - } - return result; -} - -static const char *get_traced_filename(void *handle, bool removed) { - std::unordered_map::iterator it; - it = traced_dlopen_handle_list.find(handle); - if (it != traced_dlopen_handle_list.end()) { - if (removed) - traced_dlopen_handle_list.erase(it); - return it->second; - } - return NULL; -} - -static void *(*orig_dlsym)(void *__handle, const char *__symbol); -static void *fake_dlsym(void *__handle, const char *__symbol) { - const char *traced_filename = get_traced_filename(__handle, false); - if (traced_filename) { - LOG(1, "[-] dlsym: %s, symbol: %s", traced_filename, __symbol); - } - return orig_dlsym(__handle, __symbol); -} - -static int (*orig_dlclose)(void *__handle); -static int fake_dlclose(void *__handle) { - const char *traced_filename = get_traced_filename(__handle, true); - if (traced_filename) { - LOG(1, "[-] dlclose: %s", traced_filename); - free((void *)traced_filename); - } - return orig_dlclose(__handle); -} - -#if 0 -__attribute__((constructor)) static void ctor() { -#if defined(__ANDROID__) -#if 0 - void *dl = dlopen("libdl.so", RTLD_LAZY); - void *__loader_dlopen = dlsym(dl, "__loader_dlopen"); -#endif - DobbyHook((void *)DobbySymbolResolver(NULL, "__loader_dlopen"), (void *)fake_loader_dlopen, - (void **)&orig_loader_dlopen); -#else - DobbyHook((void *)DobbySymbolResolver(NULL, "dlopen"), (void *)fake_dlopen, (void **)&orig_dlopen); -#endif - - DobbyHook((void *)dlsym, (void *)fake_dlsym, (void **)&orig_dlsym); - DobbyHook((void *)dlclose, (void *)fake_dlclose, (void **)&orig_dlclose); -} -#endif diff --git a/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/file_operation_monitor.cc b/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/file_operation_monitor.cc deleted file mode 100644 index d4f09ca..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/file_operation_monitor.cc +++ /dev/null @@ -1,97 +0,0 @@ -#include /* getenv */ -#include -#include - -#include -#include - -#include -#include - -#include - -#include "./dobby_monitor.h" - -std::unordered_map *TracedFopenFileList; - -FILE *(*orig_fopen)(const char *filename, const char *mode); -FILE *fake_fopen(const char *filename, const char *mode) { - FILE *result = NULL; - result = orig_fopen(filename, mode); - if (result != NULL) { - char *traced_filename = (char *)malloc(MAXPATHLEN); - // FIXME: strncpy - strcpy(traced_filename, filename); - std::cout << "[-] trace file: " << filename << std::endl; - TracedFopenFileList->insert(std::make_pair(result, traced_filename)); - } - return result; -} - -static const char *GetFileDescriptorTraced(FILE *stream, bool removed) { - std::unordered_map::iterator it; - it = TracedFopenFileList->find(stream); - if (it != TracedFopenFileList->end()) { - if (removed) - TracedFopenFileList->erase(it); - return it->second; - } - return NULL; -} - -size_t (*orig_fread)(void *ptr, size_t size, size_t count, FILE *stream); -size_t fake_fread(void *ptr, size_t size, size_t count, FILE *stream) { - const char *file_name = GetFileDescriptorTraced(stream, false); - if (file_name) { - LOG("[-] fread: %s, buffer: %p\n", file_name, ptr); - } - return orig_fread(ptr, size, count, stream); -} - -size_t (*orig_fwrite)(const void *ptr, size_t size, size_t count, FILE *stream); -size_t fake_fwrite(void *ptr, size_t size, size_t count, FILE *stream) { - const char *file_name = GetFileDescriptorTraced(stream, false); - if (file_name) { - LOG("[-] fwrite %s\n from %p\n", file_name, ptr); - } - return orig_fwrite(ptr, size, count, stream); -} - -__attribute__((constructor)) void __main() { - - TracedFopenFileList = new std::unordered_map(); - -#if defined(__APPLE__) -#include -#if (TARGET_OS_IPHONE || TARGET_OS_MAC) - std::ifstream file; - file.open("/System/Library/CoreServices/SystemVersion.plist"); - std::cout << file.rdbuf(); -#endif -#endif - - // DobbyHook((void *)fopen, (void *)fake_fopen, (void **)&orig_fopen); - // DobbyHook((void *)fwrite, (void *)fake_fwrite, (void **)&orig_fwrite); - // DobbyHook((void *)fread, (void *)fake_fread, (void **)&orig_fread); - - char *home = getenv("HOME"); - char *subdir = (char *)"/Library/Caches/"; - - std::string filePath = std::string(home) + std::string(subdir) + "temp.log"; - - char buffer[64]; - memset(buffer, 'B', 64); - - FILE *fd = fopen(filePath.c_str(), "w+"); - if (!fd) - std::cout << "[!] open " << filePath << "failed!\n"; - - fwrite(buffer, 64, 1, fd); - fflush(fd); - fseek(fd, 0, SEEK_SET); - memset(buffer, 0, 64); - - fread(buffer, 64, 1, fd); - - return; -} diff --git a/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/memory_operation_instrument.cc b/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/memory_operation_instrument.cc deleted file mode 100644 index 0298275..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/memory_operation_instrument.cc +++ /dev/null @@ -1,58 +0,0 @@ -#include "./dobby_monitor.h" - -#include -#include -#include - -static uintptr_t getCallFirstArg(DobbyRegisterContext *ctx) { - uintptr_t result; -#if defined(_M_X64) || defined(__x86_64__) -#if defined(_WIN32) - result = ctx->general.regs.rcx; -#else - result = ctx->general.regs.rdi; -#endif -#elif defined(__arm64__) || defined(__aarch64__) - result = ctx->general.regs.x0; -#elif defined(__arm__) - result = ctx->general.regs.r0; -#else -#error "Not Support Architecture." -#endif - return result; -} - -void format_integer_manually(char *buf, uint64_t integer) { - int tmp = 0; - for (tmp = (int)integer; tmp > 0; tmp = (tmp >> 4)) { - buf += (tmp % 16); - buf--; - } -} - -// [ATTENTION]: -// printf will call 'malloc' internally, and will crash in a loop. -// so, use 'puts' is a better choice. -void malloc_handler(DobbyRegisterContext *ctx, const InterceptEntry *info) { - size_t size_ = 0; - size_ = getCallFirstArg(ctx); - char *buffer_ = (char *)"[-] function malloc first arg: 0x00000000.\n"; - format_integer_manually(strchr(buffer_, '.') - 1, size_); - puts(buffer_); -} - -void free_handler(DobbyRegisterContext *ctx, const InterceptEntry *info) { - uintptr_t mem_ptr; - - mem_ptr = getCallFirstArg(ctx); - - char *buffer = (char *)"[-] function free first arg: 0x00000000.\n"; - format_integer_manually(strchr(buffer, '.') - 1, mem_ptr); - puts(buffer); -} - -__attribute__((constructor)) static void ctor() { - // DobbyInstrument((void *)mmap, malloc_handler); - // DobbyInstrument((void *)free, free_handler); - return; -} diff --git a/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/posix_file_descriptor_operation_monitor.cc b/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/posix_file_descriptor_operation_monitor.cc deleted file mode 100644 index 4aaa2f4..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/posix_file_descriptor_operation_monitor.cc +++ /dev/null @@ -1,120 +0,0 @@ -#include /* getenv */ -#include -#include - -#include -#include -#include - -#include - -#include -#include - -#include -#include - -#include - -#include "dobby.h" -#include "common_header.h" - -#define LOG_TAG "PosixFileOperationMonitor" - -std::unordered_map *posix_file_descriptors; - -int (*orig_open)(const char *pathname, int flags, ...); -int fake_open(const char *pathname, int flags, ...) { - mode_t mode = 0; - if (flags & O_CREAT) { - va_list args; - va_start(args, flags); - mode = (mode_t)va_arg(args, int); - va_end(args); - } - - int result = orig_open(pathname, flags, mode); - if (result != -1) { - char *traced_filename = (char *)malloc(MAXPATHLEN); - // FIXME: strncpy - strcpy(traced_filename, pathname); - LOG(1, "[-] trace open handle: %s", pathname); - - if (posix_file_descriptors == NULL) { - posix_file_descriptors = new std::unordered_map(); - } - posix_file_descriptors->insert(std::make_pair(result, (const char *)traced_filename)); - } - return result; -} - -int (*orig___open)(const char *pathname, int flags, int mode); -int fake___open(const char *pathname, int flags, int mode) { - char *traced_filename = NULL; - if (pathname) { - traced_filename = (char *)malloc(MAXPATHLEN); - // FIXME: strncpy - strcpy(traced_filename, pathname); - LOG(1, "[-] trace open handle: ", pathname); - } - int result = orig___open(pathname, flags, mode); - if (result != -1) { - if (posix_file_descriptors == NULL) { - posix_file_descriptors = new std::unordered_map(); - } - posix_file_descriptors->insert(std::make_pair(result, (const char *)traced_filename)); - } - return result; -} - -static const char *get_traced_filename(int fd, bool removed) { - if (posix_file_descriptors == NULL) - return NULL; - std::unordered_map::iterator it; - it = posix_file_descriptors->find(fd); - if (it != posix_file_descriptors->end()) { - if (removed) - posix_file_descriptors->erase(it); - return it->second; - } - return NULL; -} - -ssize_t (*orig_read)(int fd, void *buf, size_t count); -ssize_t fake_read(int fd, void *buf, size_t count) { - const char *traced_filename = get_traced_filename(fd, false); - if (traced_filename) { - LOG(1, "[-] read: %s, buffer: %p, size: %zu", traced_filename, buf, count); - } - return orig_read(fd, buf, count); -} - -ssize_t (*orig_write)(int fd, const void *buf, size_t count); -ssize_t fake_write(int fd, const void *buf, size_t count) { - const char *traced_filename = get_traced_filename(fd, false); - if (traced_filename) { - LOG(1, "[-] write: %s, buffer: %p, size: %zu", traced_filename, buf, count); - } - return orig_write(fd, buf, count); -} -int (*orig_close)(int fd); -int fake_close(int fd) { - const char *traced_filename = get_traced_filename(fd, true); - if (traced_filename) { - LOG(1, "[-] close: %s", traced_filename); - free((void *)traced_filename); - } - return orig_close(fd); -} - -#if 0 -__attribute__((constructor)) static void ctor() { - DobbyHook((void *)DobbySymbolResolver(NULL, "open"), (void *)fake_open, (void **)&orig_open); - - DobbyHook((void *)DobbySymbolResolver(NULL, "write"), (void *)fake_write, (void **)&orig_write); - - DobbyHook((void *)DobbySymbolResolver(NULL, "read"), (void *)fake_read, (void **)&orig_read); - - DobbyHook((void *)DobbySymbolResolver(NULL, "close"), (void *)fake_close, (void **)&orig_close); -} -#endif diff --git a/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/posix_socket_network_monitor.cc b/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/posix_socket_network_monitor.cc deleted file mode 100644 index 8314a18..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/posix_socket_network_monitor.cc +++ /dev/null @@ -1,57 +0,0 @@ -#include /* getenv */ -#include -#include - -#include -#include - -#include - -#include - -#include -#include - -std::unordered_map posix_socket_file_descriptors; - -int (*orig_bind)(int sockfd, const struct sockaddr *addr, socklen_t addrlen); -int fake_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { -} - -static const char *get_traced_socket(int fd, bool removed) { - std::unordered_map::iterator it; - it = posix_socket_file_descriptors.find(fd); - if (it != posix_socket_file_descriptors.end()) { - if (removed) - posix_socket_file_descriptors.erase(it); - return it->second; - } - return NULL; -} - -int (*orig_connect)(int sockfd, const struct sockaddr *addr, socklen_t addrlen); -int fake_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { - const char *traced_socket = get_traced_socket(sockfd, false); - if (traced_socket) { - LOG(1, "[-] connect: %s\n", traced_socket); - } - return orig_connect(sockfd, addr, addrlen); -} - -ssize_t (*orig_send)(int sockfd, const void *buf, size_t len, int flags); -ssize_t fake_send(int sockfd, const void *buf, size_t len, int flags) { - const char *traced_socket = get_traced_socket(sockfd, false); - if (traced_socket) { - LOG(1, "[-] send: %s, buf: %p, len: %zu\n", traced_socket, buf, len); - } - return orig_send(sockfd, buf, len, flags); -} - -ssize_t (*orig_recv)(int sockfd, void *buf, size_t len, int flags); -ssize_t fake_recv(int sockfd, void *buf, size_t len, int flags) { - const char *traced_socket = get_traced_socket(sockfd, false); - if (traced_socket) { - LOG(1, "[-] recv: %s, buf: %p, len: %zu\n", traced_socket, buf, len); - } - return orig_recv(sockfd, buf, len, flags); -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/BionicLinkerUtil/bionic_linker_demo.cc b/app/src/main/cpp/Dobby/builtin-plugin/BionicLinkerUtil/bionic_linker_demo.cc deleted file mode 100644 index 095d45b..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/BionicLinkerUtil/bionic_linker_demo.cc +++ /dev/null @@ -1,36 +0,0 @@ -#include "dobby.h" - -#include "bionic_linker_util.h" - -#include "logging/logging.h" - -#include - -#define LOG_TAG "BionicLinkerUtil" - -__attribute__((constructor)) static void ctor() { - const char *lib = NULL; - -#if defined(__LP64__) - lib = "/system/lib64/libandroid_runtime.so"; -#else - lib = "/system/lib/libandroid_runtime.so"; -#endif - - void *vm = NULL; - - vm = DobbySymbolResolver(lib, "_ZN7android14AndroidRuntime7mJavaVME"); - LOG(1, "DobbySymbolResolver::vm %p", vm); - -#if 0 - linker_disable_namespace_restriction(); - void *handle = NULL; - handle = dlopen(lib, RTLD_LAZY); - vm = dlsym(handle, "_ZN7android14AndroidRuntime7mJavaVME"); -#else - void *handle = NULL; - handle = linker_dlopen(lib, RTLD_LAZY); - vm = dlsym(handle, "_ZN7android14AndroidRuntime7mJavaVME"); -#endif - LOG(1, "vm %p", vm); -} diff --git a/app/src/main/cpp/Dobby/builtin-plugin/BionicLinkerUtil/bionic_linker_util.cc b/app/src/main/cpp/Dobby/builtin-plugin/BionicLinkerUtil/bionic_linker_util.cc deleted file mode 100644 index 8860ce1..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/BionicLinkerUtil/bionic_linker_util.cc +++ /dev/null @@ -1,197 +0,0 @@ -#include "bionic_linker_util.h" - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include "dobby.h" -#include "dobby_symbol_resolver.h" - -#include "common_header.h" - -#undef LOG_TAG -#define LOG_TAG "BionicLinkerUtil" - -#undef Q -#define Q 29 -// impl at "dobby_symbol_resolver.cc" -extern void *resolve_elf_internal_symbol(const char *library_name, const char *symbol_name); - -#include -static int get_android_system_version() { - char os_version_str[PROP_VALUE_MAX + 1]; - __system_property_get("ro.build.version.sdk", os_version_str); - int os_version_int = atoi(os_version_str); - return os_version_int; -} - -static const char *get_android_linker_path() { -#if __LP64__ - if (get_android_system_version() >= Q) { - return (const char *)"/apex/com.android.runtime/bin/linker64"; - } else { - return (const char *)"/system/bin/linker64"; - } -#else - if (get_android_system_version() >= Q) { - return (const char *)"/apex/com.android.runtime/bin/linker"; - } else { - return (const char *)"/system/bin/linker"; - } -#endif -} - -PUBLIC void *linker_dlopen(const char *filename, int flag) { - typedef void *(*__loader_dlopen_t)(const char *filename, int flags, const void *caller_addr); - static __loader_dlopen_t __loader_dlopen = NULL; - if (!__loader_dlopen) - __loader_dlopen = (__loader_dlopen_t)DobbySymbolResolver(NULL, "__loader_dlopen"); - - // fake caller address - void *open_ptr = dlsym(RTLD_DEFAULT, "open"); - return __loader_dlopen(filename, flag, (const void *)open_ptr); -} - -std::vector linker_solist; -std::vector linker_get_solist() { - if (!linker_solist.empty()) { - linker_solist.clear(); - } - - static soinfo_t (*solist_get_head)() = NULL; - if (!solist_get_head) - solist_get_head = - (soinfo_t(*)())resolve_elf_internal_symbol(get_android_linker_path(), "__dl__Z15solist_get_headv"); - - static soinfo_t (*solist_get_somain)() = NULL; - if (!solist_get_somain) - solist_get_somain = - (soinfo_t(*)())resolve_elf_internal_symbol(get_android_linker_path(), "__dl__Z17solist_get_somainv"); - - static addr_t *solist_head = NULL; - if (!solist_head) - solist_head = (addr_t *)solist_get_head(); - - static addr_t somain = 0; - if (!somain) - somain = (addr_t)solist_get_somain(); - - // Generate the name for an offset. -#define PARAM_OFFSET(type_, member_) __##type_##__##member_##__offset_ -#define STRUCT_OFFSET PARAM_OFFSET - int STRUCT_OFFSET(solist, next) = 0; - for (size_t i = 0; i < 1024 / sizeof(void *); i++) { - if (*(addr_t *)((addr_t)solist_head + i * sizeof(void *)) == somain) { - STRUCT_OFFSET(solist, next) = i * sizeof(void *); - break; - } - } - - linker_solist.push_back(solist_head); - - addr_t sonext = 0; - sonext = *(addr_t *)((addr_t)solist_head + STRUCT_OFFSET(solist, next)); - while (sonext) { - linker_solist.push_back((void *)sonext); - sonext = *(addr_t *)((addr_t)sonext + STRUCT_OFFSET(solist, next)); - } - - return linker_solist; -} - -char *linker_soinfo_get_realpath(soinfo_t soinfo) { - static char *(*_get_realpath)(soinfo_t) = NULL; - if (!_get_realpath) - _get_realpath = - (char *(*)(soinfo_t))resolve_elf_internal_symbol(get_android_linker_path(), "__dl__ZNK6soinfo12get_realpathEv"); - return _get_realpath(soinfo); -} - -uintptr_t linker_soinfo_to_handle(soinfo_t soinfo) { - static uintptr_t (*_linker_soinfo_to_handle)(soinfo_t) = NULL; - if (!_linker_soinfo_to_handle) - _linker_soinfo_to_handle = - (uintptr_t(*)(soinfo_t))resolve_elf_internal_symbol(get_android_linker_path(), "__dl__ZN6soinfo9to_handleEv"); - return _linker_soinfo_to_handle(soinfo); -} - -typedef void *android_namespace_t; -android_namespace_t linker_soinfo_get_primary_namespace(soinfo_t soinfo) { - static android_namespace_t (*_get_primary_namespace)(soinfo_t) = NULL; - if (!_get_primary_namespace) - _get_primary_namespace = (android_namespace_t(*)(soinfo_t))resolve_elf_internal_symbol( - get_android_linker_path(), "__dl__ZN6soinfo21get_primary_namespaceEv"); - return _get_primary_namespace(soinfo); -} - -void linker_iterate_soinfo(int (*cb)(soinfo_t soinfo)) { - auto solist = linker_get_solist(); - for (auto it = solist.begin(); it != solist.end(); it++) { - int ret = cb(*it); - if (ret != 0) - break; - } -} - -static int iterate_soinfo_cb(soinfo_t soinfo) { - android_namespace_t ns = NULL; - ns = linker_soinfo_get_primary_namespace(soinfo); - LOG(1, "lib: %s", linker_soinfo_get_realpath(soinfo)); - - // set is_isolated_ as false - // no need for this actually - int STRUCT_OFFSET(android_namespace_t, is_isolated_) = 0x8; - *(uint8_t *)((addr_t)ns + STRUCT_OFFSET(android_namespace_t, is_isolated_)) = false; - - std::vector ld_library_paths = {"/system/lib64", "/sytem/lib"}; - if (get_android_system_version() >= Q) { - ld_library_paths.push_back("/apex/com.android.runtime/lib64"); - ld_library_paths.push_back("/apex/com.android.runtime/lib"); - } - int STRUCT_OFFSET(android_namespace_t, ld_library_paths_) = 0x10; - if (*(void **)((addr_t)ns + STRUCT_OFFSET(android_namespace_t, ld_library_paths_))) { - std::vector orig_ld_library_paths = - *(std::vector *)((addr_t)ns + STRUCT_OFFSET(android_namespace_t, ld_library_paths_)); - orig_ld_library_paths.insert(orig_ld_library_paths.end(), ld_library_paths.begin(), ld_library_paths.end()); - - // remove duplicates - { - std::set paths(orig_ld_library_paths.begin(), orig_ld_library_paths.end()); - orig_ld_library_paths.assign(paths.begin(), paths.end()); - } - } else { - *(std::vector *)((addr_t)ns + STRUCT_OFFSET(android_namespace_t, ld_library_paths_)) = - std::move(ld_library_paths); - } - return 0; -} - -bool (*orig_linker_namespace_is_is_accessible)(android_namespace_t ns, const std::string &file); -bool linker_namespace_is_is_accessible(android_namespace_t ns, const std::string &file) { - LOG(1, "check %s", file.c_str()); - return true; - return orig_linker_namespace_is_is_accessible(ns, file); -} - -void linker_disable_namespace_restriction() { - linker_iterate_soinfo(iterate_soinfo_cb); - - // no need for this actually - void *linker_namespace_is_is_accessible_ptr = resolve_elf_internal_symbol( - get_android_linker_path(), "__dl__ZN19android_namespace_t13is_accessibleERKNSt3__112basic_" - "stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE"); - DobbyHook(linker_namespace_is_is_accessible_ptr, (void *)linker_namespace_is_is_accessible, - (void **)&orig_linker_namespace_is_is_accessible); - - LOG(1, "disable namespace restriction done"); -} diff --git a/app/src/main/cpp/Dobby/builtin-plugin/BionicLinkerUtil/bionic_linker_util.h b/app/src/main/cpp/Dobby/builtin-plugin/BionicLinkerUtil/bionic_linker_util.h deleted file mode 100644 index 55c2911..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/BionicLinkerUtil/bionic_linker_util.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void *soinfo_t; - -soinfo_t linker_dlopen(const char *filename, int flag); - -char *linker_soinfo_get_realpath(soinfo_t soinfo); - -uintptr_t linker_soinfo_to_handle(soinfo_t soinfo); - -void linker_iterate_soinfo(int (*cb)(soinfo_t soinfo)); - -void linker_disable_namespace_restriction(); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/CMakeLists.txt b/app/src/main/cpp/Dobby/builtin-plugin/CMakeLists.txt deleted file mode 100644 index 3730cb9..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -if (Plugin.ImportTableReplace AND SYSTEM.Darwin) - message(STATUS "[Dobby] Enable got hook") - include_directories(builtin-plugin/ImportTableReplace) - add_subdirectory(builtin-plugin/ImportTableReplace) -endif () - -if (Plugin.Android.BionicLinkerUtil) - if (NOT SYSTEM.Android) - message(FATAL_ERROR "[!] Plugin.Android.BionicLinkerUtil only works on Android.") - endif () - message(STATUS "[Dobby] Enable Plugin.Android.BionicLinkerUtil") - set(dobby.plugin.SOURCE_FILE_LIST ${dobby.plugin.SOURCE_FILE_LIST} - BionicLinkerUtil/bionic_linker_util.cc - ) -endif () \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/ImportTableReplace/CMakeLists.txt b/app/src/main/cpp/Dobby/builtin-plugin/ImportTableReplace/CMakeLists.txt deleted file mode 100644 index 44c513a..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/ImportTableReplace/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -add_library(import_table_repalce INTERFACE - dobby_import_replace.cc - ) \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/ImportTableReplace/dobby_import_replace.cc b/app/src/main/cpp/Dobby/builtin-plugin/ImportTableReplace/dobby_import_replace.cc deleted file mode 100644 index 900f063..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/ImportTableReplace/dobby_import_replace.cc +++ /dev/null @@ -1,192 +0,0 @@ -#include "dobby_import_replace.h" - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include - -#include "common_header.h" - -#include "logging/logging.h" - -#include "PlatformUtil/ProcessRuntimeUtility.h" - -#if defined(__LP64__) -typedef struct mach_header_64 mach_header_t; -typedef struct segment_command_64 segment_command_t; -typedef struct section_64 section_t; -typedef struct nlist_64 nlist_t; -#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT_64 -#else -typedef struct mach_header mach_header_t; -typedef struct segment_command segment_command_t; -typedef struct section section_t; -typedef struct nlist nlist_t; -#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT -#endif - -static void *iterate_indirect_symtab(char *symbol_name, section_t *section, intptr_t slide, nlist_t *symtab, - char *strtab, uint32_t *indirect_symtab) { - const bool is_data_const = strcmp(section->segname, "__DATA_CONST") == 0; - uint32_t *indirect_symbol_indices = indirect_symtab + section->reserved1; - void **indirect_symbol_bindings = (void **)((uintptr_t)slide + section->addr); - - vm_prot_t old_protection = VM_PROT_READ; - if (is_data_const) { - mprotect(indirect_symbol_bindings, section->size, PROT_READ | PROT_WRITE); - } - - for (uint i = 0; i < section->size / sizeof(void *); i++) { - uint32_t symtab_index = indirect_symbol_indices[i]; - if (symtab_index == INDIRECT_SYMBOL_ABS || symtab_index == INDIRECT_SYMBOL_LOCAL || - symtab_index == (INDIRECT_SYMBOL_LOCAL | INDIRECT_SYMBOL_ABS)) { - continue; - } - uint32_t strtab_offset = symtab[symtab_index].n_un.n_strx; - char *local_symbol_name = strtab + strtab_offset; - bool symbol_name_longer_than_1 = symbol_name[0] && symbol_name[1]; - if (strcmp(local_symbol_name, symbol_name) == 0) { - return &indirect_symbol_bindings[i]; - } - if (local_symbol_name[0] == '_') { - if (strcmp(symbol_name, &local_symbol_name[1]) == 0) { - return &indirect_symbol_bindings[i]; - } - } - } - - if (is_data_const && 0) { - int protection = 0; - if (old_protection & VM_PROT_READ) { - protection |= PROT_READ; - } - if (old_protection & VM_PROT_WRITE) { - protection |= PROT_WRITE; - } - if (old_protection & VM_PROT_EXECUTE) { - protection |= PROT_EXEC; - } - mprotect(indirect_symbol_bindings, section->size, protection); - } - return NULL; -} - -static void *get_global_offset_table_stub(mach_header_t *header, char *symbol_name) { - segment_command_t *curr_seg_cmd; - segment_command_t *text_segment, *data_segment, *linkedit_segment; - struct symtab_command *symtab_cmd = NULL; - struct dysymtab_command *dysymtab_cmd = NULL; - - uintptr_t cur = (uintptr_t)header + sizeof(mach_header_t); - for (uint i = 0; i < header->ncmds; i++, cur += curr_seg_cmd->cmdsize) { - curr_seg_cmd = (segment_command_t *)cur; - if (curr_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { - if (strcmp(curr_seg_cmd->segname, "__LINKEDIT") == 0) { - linkedit_segment = curr_seg_cmd; - } else if (strcmp(curr_seg_cmd->segname, "__DATA") == 0) { - data_segment = curr_seg_cmd; - } else if (strcmp(curr_seg_cmd->segname, "__TEXT") == 0) { - text_segment = curr_seg_cmd; - } - } else if (curr_seg_cmd->cmd == LC_SYMTAB) { - symtab_cmd = (struct symtab_command *)curr_seg_cmd; - } else if (curr_seg_cmd->cmd == LC_DYSYMTAB) { - dysymtab_cmd = (struct dysymtab_command *)curr_seg_cmd; - } - } - - if (!symtab_cmd || !linkedit_segment || !linkedit_segment) { - return NULL; - } - - uintptr_t slide = (uintptr_t)header - (uintptr_t)text_segment->vmaddr; - uintptr_t linkedit_base = (uintptr_t)slide + linkedit_segment->vmaddr - linkedit_segment->fileoff; - nlist_t *symtab = (nlist_t *)(linkedit_base + symtab_cmd->symoff); - char *strtab = (char *)(linkedit_base + symtab_cmd->stroff); - uint32_t symtab_count = symtab_cmd->nsyms; - - uint32_t *indirect_symtab = (uint32_t *)(linkedit_base + dysymtab_cmd->indirectsymoff); - - cur = (uintptr_t)header + sizeof(mach_header_t); - for (uint i = 0; i < header->ncmds; i++, cur += curr_seg_cmd->cmdsize) { - curr_seg_cmd = (segment_command_t *)cur; - if (curr_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { - if (strcmp(curr_seg_cmd->segname, "__DATA") != 0 && strcmp(curr_seg_cmd->segname, "__DATA_CONST") != 0) { - continue; - } - for (uint j = 0; j < curr_seg_cmd->nsects; j++) { - section_t *sect = (section_t *)(cur + sizeof(segment_command_t)) + j; - if ((sect->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS) { - void *stub = iterate_indirect_symtab(symbol_name, sect, slide, symtab, strtab, indirect_symtab); - if (stub) - return stub; - } - if ((sect->flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS) { - void *stub = iterate_indirect_symtab(symbol_name, sect, slide, symtab, strtab, indirect_symtab); - if (stub) - return stub; - } - } - } - } - - return NULL; -} - -PUBLIC int DobbyImportTableReplace(char *image_name, char *symbol_name, void *fake_func, void **orig_func_ptr) { - std::vector ProcessModuleMap = ProcessRuntimeUtility::GetProcessModuleMap(); - - for (auto module : ProcessModuleMap) { - if (image_name != NULL && strstr(module.path, image_name) == NULL) - continue; - - addr_t header = (addr_t)module.load_address; - size_t slide = 0; - -#if 0 - if (header) { - if (((struct mach_header *)header)->magic == MH_MAGIC_64) - slide = macho_kit_get_slide64(header); - } -#endif - -#if 0 - LOG(1, "resolve image: %s", module.path); -#endif - - uint32_t nlist_count = 0; - nlist_t *nlist_array = 0; - char *string_pool = 0; - - void *stub = get_global_offset_table_stub((mach_header_t *)header, symbol_name); - if (stub) { - void *orig_func; - orig_func = *(void **)stub; -#if __has_feature(ptrauth_calls) - orig_func = ptrauth_strip(orig_func, ptrauth_key_asia); - orig_func = ptrauth_sign_unauthenticated(orig_func, ptrauth_key_asia, 0); -#endif - *orig_func_ptr = orig_func; - -#if __has_feature(ptrauth_calls) - fake_func = (void *)ptrauth_strip(fake_func, ptrauth_key_asia); - fake_func = ptrauth_sign_unauthenticated(fake_func, ptrauth_key_asia, stub); -#endif - *(void **)stub = fake_func; - } - - if (image_name) - return 0; - } - return -1; -} diff --git a/app/src/main/cpp/Dobby/builtin-plugin/ImportTableReplace/dobby_import_replace.h b/app/src/main/cpp/Dobby/builtin-plugin/ImportTableReplace/dobby_import_replace.h deleted file mode 100644 index c51b0f7..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/ImportTableReplace/dobby_import_replace.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -// int DobbyImportTableReplace(char *image_name, char *symbol_name, void *fake_func, void **orig_func); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeReplace/CMakeLists.txt b/app/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeReplace/CMakeLists.txt deleted file mode 100644 index 754610b..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeReplace/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -add_library(objc_runtime_replace - objc_runtime_replace.mm - ) - -target_link_libraries(objc_runtime_replace - "-framework Foundation" - ) \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeReplace/objc_runtime_repalce.h b/app/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeReplace/objc_runtime_repalce.h deleted file mode 100644 index da959e7..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeReplace/objc_runtime_repalce.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -IMP DobbyObjcReplace(Class _class, SEL _selector, IMP replacement); - -void DobbyObjcReplaceEx(const char *class_name, const char *selector_name, void *fake_impl, void **orig_impl); - -void *DobbyObjcResolveMethodImp(const char *class_name, const char *selector_name); - -#ifdef __cplusplus -} -#endif diff --git a/app/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeReplace/objc_runtime_replace.mm b/app/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeReplace/objc_runtime_replace.mm deleted file mode 100644 index bd57340..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeReplace/objc_runtime_replace.mm +++ /dev/null @@ -1,56 +0,0 @@ -#include "ObjcRuntimeReplace/objc_runtime_repalce.h" -#include "dobby_internal.h" - -#include -#include - -/* clang -rewrite-objc main.m */ - -IMP DobbyObjcReplace(Class class_, SEL sel_, IMP fake_impl) { - Method method_ = class_getInstanceMethod(class_, sel_); - if (!method_) - method_ = class_getClassMethod(class_, sel_); - - if (!method_) { - DLOG(0, "Not found class: %s, selector: %s method\n", class_getName(class_), sel_getName(sel_)); - return NULL; - } - - return method_setImplementation(method_, (IMP)fake_impl); -} - -void DobbyObjcReplaceEx(const char *class_name, const char *selector_name, void *fake_impl, void **out_orig_impl) { - Class class_ = objc_getClass(class_name); - SEL sel_ = sel_registerName(selector_name); - - Method method_ = class_getInstanceMethod(class_, sel_); - if (!method_) - method_ = class_getClassMethod(class_, sel_); - - if (!method_) { - DLOG(0, "Not found class: %s, selector: %s method\n", class_name, selector_name); - return; - } - - void *orig_impl = NULL; - orig_impl = (void *)method_setImplementation(method_, (IMP)fake_impl); - if (out_orig_impl) { - *out_orig_impl = orig_impl; - } - return; -} - -void *DobbyObjcResolveMethodImp(const char *class_name, const char *selector_name) { - Class class_ = objc_getClass(class_name); - SEL sel_ = sel_registerName(selector_name); - - Method method_ = class_getInstanceMethod(class_, sel_); - if (!method_) - method_ = class_getClassMethod(class_, sel_); - - if (!method_) { - DLOG(0, "Not found class: %s, selector: %s method\n", class_name, selector_name); - return NULL; - } - return (void *)method_getImplementation(method_); -} diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/CMakeLists.txt b/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/CMakeLists.txt deleted file mode 100644 index ddddfd7..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -add_library(supervisor_call_monitor STATIC - mach_system_call_log_handler.cc - system_call_log_handler.cc - supervisor_call_monitor.cc - sensitive_api_monitor.cc - misc_utility.cc - ) -target_link_libraries(supervisor_call_monitor - misc_helper - dobby - ) - -add_library(test_supervisor_call_monitor SHARED - test_supervisor_call_monitor.cc - ) -target_link_libraries(test_supervisor_call_monitor - supervisor_call_monitor -) - -include_directories( - . -) - diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/README b/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/README deleted file mode 100644 index 3832eb5..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/README +++ /dev/null @@ -1 +0,0 @@ -Monitor all supervisor call \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/mach_system_call_log_handler.cc b/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/mach_system_call_log_handler.cc deleted file mode 100644 index 25b2043..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/mach_system_call_log_handler.cc +++ /dev/null @@ -1,193 +0,0 @@ -#include "dobby_internal.h" - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "misc-helper/async_logger.h" -#include "PlatformUtil/ProcessRuntimeUtility.h" -#include "SupervisorCallMonitor/misc_utility.h" -#include "SupervisorCallMonitor/supervisor_call_monitor.h" - -#include "XnuInternal/syscall_sw.c" - -#include "XnuInternal/mach/clock_priv.h" -#include "XnuInternal/mach/clock_reply.h" -#include "XnuInternal/mach/clock.h" -#include "XnuInternal/mach/exc.h" -#include "XnuInternal/mach/host_priv.h" -#include "XnuInternal/mach/host_security.h" -#include "XnuInternal/mach/lock_set.h" -#include "XnuInternal/mach/mach_host.h" -#include "XnuInternal/mach/mach_port.h" -#include "XnuInternal/mach/mach_vm.h" -#include "XnuInternal/mach/mach_voucher.h" -#include "XnuInternal/mach/memory_entry.h" -#include "XnuInternal/mach/processor_set.h" -#include "XnuInternal/mach/processor.h" -#include "XnuInternal/mach/task.h" -#include "XnuInternal/mach/thread_act.h" -#include "XnuInternal/mach/vm_map.h" - -typedef struct { - char *mach_msg_name; - int mach_msg_id; -} mach_msg_entry_t; - -// clang-format off -mach_msg_entry_t mach_msg_array[] = { - subsystem_to_name_map_clock_priv, - subsystem_to_name_map_clock_reply, - subsystem_to_name_map_clock, - subsystem_to_name_map_exc, - subsystem_to_name_map_host_priv, - subsystem_to_name_map_host_security, - subsystem_to_name_map_lock_set, - subsystem_to_name_map_mach_host, - subsystem_to_name_map_mach_port, - subsystem_to_name_map_mach_vm, - subsystem_to_name_map_mach_voucher, - subsystem_to_name_map_memory_entry, - subsystem_to_name_map_processor_set, - subsystem_to_name_map_processor, - subsystem_to_name_map_task, - subsystem_to_name_map_thread_act, - subsystem_to_name_map_vm_map, -}; -// clang-format on - -#define PRIME_NUMBER 8387 -char *mach_msg_name_table[PRIME_NUMBER] = {0}; -static int hash_mach_msg_num_to_ndx(int mach_msg_num) { - return mach_msg_num % PRIME_NUMBER; -} -static void mach_msg_id_hash_table_init() { - static bool initialized = false; - if (initialized == true) { - return; - } - initialized = true; - - int count = sizeof(mach_msg_array) / sizeof(mach_msg_array[0]); - for (size_t i = 0; i < count; i++) { - mach_msg_entry_t entry = mach_msg_array[i]; - int ndx = hash_mach_msg_num_to_ndx(entry.mach_msg_id); - mach_msg_name_table[ndx] = entry.mach_msg_name; - } -} - -const char *mach_syscall_num_to_str(int num) { - return mach_syscall_name_table[0 - num]; -} - -char *mach_msg_id_to_str(int msgh_id) { - int ndx = hash_mach_msg_num_to_ndx(msgh_id); - return mach_msg_name_table[ndx]; -} - -char *mach_msg_to_str(mach_msg_header_t *msg) { - static mach_port_t self_port = MACH_PORT_NULL; - - if (self_port == MACH_PORT_NULL) { - self_port = mach_task_self(); - } - - if (msg->msgh_remote_port == self_port) { - return mach_msg_id_to_str(msg->msgh_id); - } - return NULL; -} - -static addr_t getCallFirstArg(DobbyRegisterContext *ctx) { - addr_t result; -#if defined(_M_X64) || defined(__x86_64__) -#if defined(_WIN32) - result = ctx->general.regs.rcx; -#else - result = ctx->general.regs.rdi; -#endif -#elif defined(__arm64__) || defined(__aarch64__) - result = ctx->general.regs.x0; -#elif defined(__arm__) - result = ctx->general.regs.r0; -#else -#error "Not Support Architecture." -#endif - return result; -} - -static addr_t getRealLr(DobbyRegisterContext *ctx) { - addr_t closure_trampoline_reserved_stack = ctx->sp - sizeof(addr_t); - return *(addr_t *)closure_trampoline_reserved_stack; -} - -static addr_t fast_get_caller_from_main_binary(DobbyRegisterContext *ctx) { - static addr_t text_section_start = 0, text_section_end = 0; - static addr_t slide = 0; - if (text_section_start == 0 || text_section_end == 0) { - auto main = ProcessRuntimeUtility::GetProcessModule("mobilex"); - addr_t main_header = (addr_t)main.load_address; - - auto text_segment = macho_kit_get_segment_by_name((mach_header_t *)main_header, "__TEXT"); - slide = main_header - text_segment->vmaddr; - - auto text_section = macho_kit_get_section_by_name((mach_header_t *)main_header, "__TEXT", "__text"); - text_section_start = main_header + (addr_t)text_section->offset; - text_section_end = text_section_start + text_section->size; - } - - if (ctx == NULL) - return 0; - - addr_t lr = getRealLr(ctx); - if (lr > text_section_start && lr < text_section_end) - return lr - slide; - -#define MAX_STACK_ITERATE_LEVEL 8 - addr_t fp = ctx->fp; - if (fp == 0) - return 0; - for (int i = 0; i < MAX_STACK_ITERATE_LEVEL; i++) { - addr_t lr = *(addr_t *)(fp + sizeof(addr_t)); - if (lr > text_section_start && lr < text_section_end) - return lr - slide; - fp = *(addr_t *)fp; - if (fp == 0) - return 0; - } - return 0; -} - -static void mach_syscall_log_handler(DobbyRegisterContext *ctx, const InterceptEntry *info) { - addr_t caller = fast_get_caller_from_main_binary(ctx); - if (caller == 0) - return; - - char buffer[256] = {0}; - int syscall_rum = ctx->general.regs.x16; - if (syscall_rum == -31) { - // mach_msg_trap - mach_msg_header_t *msg = (typeof(msg))getCallFirstArg(ctx); - char *mach_msg_name = mach_msg_to_str(msg); - if (mach_msg_name) { - sprintf(buffer, "[mach msg svc] %s\n", mach_msg_name); - } else { - buffer[0] = 0; - } - } else if (syscall_rum < 0) { - sprintf(buffer, "[mach svc-%d] %s\n", syscall_rum, mach_syscall_num_to_str(syscall_rum)); - } - async_logger_print(buffer); -} - -void supervisor_call_monitor_register_mach_syscall_call_log_handler() { - mach_msg_id_hash_table_init(); - fast_get_caller_from_main_binary(NULL); - supervisor_call_monitor_register_handler(mach_syscall_log_handler); -} diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/misc_utility.cc b/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/misc_utility.cc deleted file mode 100644 index 2a0a05b..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/misc_utility.cc +++ /dev/null @@ -1,44 +0,0 @@ -#include "misc_utility.h" - -#include - -segment_command_t *macho_kit_get_segment_by_name(mach_header_t *header, const char *segname) { - segment_command_t *curr_seg_cmd = NULL; - - curr_seg_cmd = (segment_command_t *)((addr_t)header + sizeof(mach_header_t)); - for (int i = 0; i < header->ncmds; i++) { - if (curr_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { - if (!strncmp(curr_seg_cmd->segname, segname, sizeof(curr_seg_cmd->segname))) { - break; - } - } - curr_seg_cmd = (segment_command_t *)((addr_t)curr_seg_cmd + curr_seg_cmd->cmdsize); - } - - return curr_seg_cmd; -} - -section_t *macho_kit_get_section_by_name(mach_header_t *header, const char *segname, const char *sectname) { - section_t *section = NULL; - segment_command_t *segment = NULL; - - int i = 0; - - segment = macho_kit_get_segment_by_name(header, segname); - if (!segment) - goto finish; - - section = (section_t *)((addr_t)segment + sizeof(segment_command_t)); - for (i = 0; i < segment->nsects; ++i) { - if (!strncmp(section->sectname, sectname, sizeof(section->sectname))) { - break; - } - section += 1; - } - if (i == segment->nsects) { - section = NULL; - } - -finish: - return section; -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/misc_utility.h b/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/misc_utility.h deleted file mode 100644 index 1c356c0..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/misc_utility.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include -typedef uintptr_t addr_t; - -#include -#include -#include - -#if defined(__LP64__) -typedef struct mach_header_64 mach_header_t; -typedef struct segment_command_64 segment_command_t; -typedef struct section_64 section_t; -typedef struct nlist_64 nlist_t; -#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT_64 -#else -typedef struct mach_header mach_header_t; -typedef struct segment_command segment_command_t; -typedef struct section section_t; -typedef struct nlist nlist_t; -#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT -#endif - -// get macho segment by segment name -segment_command_t *macho_kit_get_segment_by_name(mach_header_t *mach_header, const char *segname); - -// get macho section by segment name and section name -section_t *macho_kit_get_section_by_name(mach_header_t *mach_header, const char *segname, const char *sectname); diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/sensitive_api_monitor.cc b/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/sensitive_api_monitor.cc deleted file mode 100644 index 140de57..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/sensitive_api_monitor.cc +++ /dev/null @@ -1,95 +0,0 @@ -#include "dobby_internal.h" - -#include -#include -#include - -#include "SupervisorCallMonitor/supervisor_call_monitor.h" -#include "misc-helper/async_logger.h" - -#define PT_DENY_ATTACH 31 - -static void sensitive_api_handler(DobbyRegisterContext *ctx, const InterceptEntry *info) { - char buffer[256] = {0}; - int syscall_rum = ctx->general.regs.x16; - if (syscall_rum == 0) { - syscall_rum = (int)ctx->general.x[0]; - if (syscall_rum == SYS_ptrace) { - int request = ctx->general.x[1]; - if (request == PT_DENY_ATTACH) { - ctx->general.x[1] = 0; - // LOG(2, "syscall svc ptrace deny"); - } - } - if (syscall_rum == SYS_exit) { - // LOG(2, "syscall svc exit"); - } - } else if (syscall_rum > 0) { - if (syscall_rum == SYS_ptrace) { - int request = ctx->general.x[0]; - if (request == PT_DENY_ATTACH) { - ctx->general.x[0] = 0; - // LOG(2, "svc ptrace deny"); - } - } - if (syscall_rum == SYS_exit) { - // LOG(2, "svc exit"); - } - } - async_logger_print(buffer); -} - -static int get_func_svc_offset(addr_t func_addr) { - typedef int32_t arm64_instr_t; - for (int i = 0; i < 8; i++) { - arm64_instr_t *insn = (arm64_instr_t *)func_addr + i; - if (*insn == 0xd4001001) { - return i * sizeof(arm64_instr_t); - } - } - return 0; -} - -#include -__typeof(sysctl) *orig_sysctl; -int fake_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { - struct kinfo_proc *info = NULL; - int ret = orig_sysctl(name, namelen, oldp, oldlenp, newp, newlen); - if (name[0] == CTL_KERN && name[1] == KERN_PROC && name[2] == KERN_PROC_PID) { - info = (struct kinfo_proc *)oldp; - info->kp_proc.p_flag &= ~(P_TRACED); - } - return ret; -} - -void supervisor_call_monitor_register_sensitive_api_handler() { - char *sensitive_func_array[] = {"ptrace", "exit"}; - size_t count = sizeof(sensitive_func_array) / sizeof(char *); - for (size_t i = 0; i < count; i++) { - - addr_t func_addr = 0; - - char func_name[64] = {0}; - sprintf(func_name, "__%s", sensitive_func_array[i]); - func_addr = (addr_t)DobbySymbolResolver("libsystem_kernel.dylib", func_name); - if (func_addr == 0) { - func_addr = (addr_t)DobbySymbolResolver("libsystem_kernel.dylib", sensitive_func_array[i]); - } - if (func_addr == 0) { - LOG(2, "not found func %s", sensitive_func_array[i]); - continue; - } - int func_svc_offset = get_func_svc_offset(func_addr); - if (func_svc_offset == 0) { - LOG(2, "not found svc %s", sensitive_func_array[i]); - continue; - } - addr_t func_svc_addr = func_addr + func_svc_offset; - supervisor_call_monitor_register_svc(func_svc_addr); - } - - // =============== - DobbyHook((void *)sysctl, (void *)fake_sysctl, (void **)&orig_sysctl); - - supervisor_call_monitor_register_handler(sensitive_api_handler); -} diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/supervisor_call_monitor.cc b/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/supervisor_call_monitor.cc deleted file mode 100644 index 762a2bb..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/supervisor_call_monitor.cc +++ /dev/null @@ -1,138 +0,0 @@ -#include "SupervisorCallMonitor/misc_utility.h" -#include "dobby_internal.h" -#include "PlatformUtil/ProcessRuntimeUtility.h" - -#include "misc-helper/async_logger.h" - -#include -std::vector *g_supervisor_call_handlers; - -static const char *fast_get_main_app_bundle_udid() { - static char *main_app_bundle_udid = NULL; - if (main_app_bundle_udid) - return main_app_bundle_udid; - - auto main = ProcessRuntimeUtility::GetProcessModuleMap()[0]; - char main_binary_path[2048] = {0}; - if (realpath(main.path, main_binary_path) == NULL) - return NULL; - - char *bundle_udid_ndx = main_binary_path + strlen("/private/var/containers/Bundle/Application/"); - main_app_bundle_udid = (char *)malloc(36 + 1); - strncpy(main_app_bundle_udid, bundle_udid_ndx, 36); - main_app_bundle_udid[36] = 0; - return main_app_bundle_udid; -} - -static void common_supervisor_call_monitor_handler(DobbyRegisterContext *ctx, const InterceptEntry *info) { - if (g_supervisor_call_handlers == NULL) { - return; - } - for (auto handler : *g_supervisor_call_handlers) { - handler(ctx, info); - } -} - -void supervisor_call_monitor_register_handler(DBICallTy handler) { - if (g_supervisor_call_handlers == NULL) { - g_supervisor_call_handlers = new std::vector(); - } - g_supervisor_call_handlers->push_back(handler); -} - -std::vector *g_svc_addr_array; - -void supervisor_call_monitor_register_svc(addr_t svc_addr) { - if (g_svc_addr_array == NULL) { - g_svc_addr_array = new std::vector(); - } - - if (g_svc_addr_array) { - auto iter = g_svc_addr_array->begin(); - for (; iter != g_svc_addr_array->end(); iter++) { - if (*iter == svc_addr) - return; - } - } - - g_svc_addr_array->push_back(svc_addr); - DobbyInstrument((void *)svc_addr, common_supervisor_call_monitor_handler); - DLOG(2, "register supervisor_call_monitor at %p", svc_addr); -} - -void supervisor_call_monitor_register_image(void *header) { - auto text_section = macho_kit_get_section_by_name((mach_header_t *)header, "__TEXT", "__text"); - - addr_t insn_addr = (addr_t)header + (addr_t)text_section->offset; - addr_t insn_addr_end = insn_addr + text_section->size; - - for (; insn_addr < insn_addr_end; insn_addr += sizeof(uint32_t)) { - if (*(uint32_t *)insn_addr == 0xd4001001) { - supervisor_call_monitor_register_svc((addr_t)insn_addr); - } - } -} - -void supervisor_call_monitor_register_main_app() { - const char *main_bundle_udid = fast_get_main_app_bundle_udid(); - auto module_map = ProcessRuntimeUtility::GetProcessModuleMap(); - for (auto module : module_map) { - if (strstr(module.path, main_bundle_udid)) { - LOG(2, "[supervisor_call_monitor] %s", module.path); - supervisor_call_monitor_register_image((void *)module.load_address); - } - } -} - -extern "C" int __shared_region_check_np(uint64_t *startaddress); - -struct dyld_cache_header *shared_cache_get_load_addr() { - static struct dyld_cache_header *shared_cache_load_addr = 0; - if (shared_cache_load_addr) - return shared_cache_load_addr; -#if 0 - if (syscall(294, &shared_cache_load_addr) == 0) { -#else - // FIXME: - if (__shared_region_check_np((uint64_t *)&shared_cache_load_addr) != 0) { -#endif - shared_cache_load_addr = 0; -} -return shared_cache_load_addr; -} -void supervisor_call_monitor_register_system_kernel() { - auto libsystem = ProcessRuntimeUtility::GetProcessModule("libsystem_kernel.dylib"); - addr_t libsystem_header = (addr_t)libsystem.load_address; - auto text_section = macho_kit_get_section_by_name((mach_header_t *)libsystem_header, "__TEXT", "__text"); - - addr_t shared_cache_load_addr = (addr_t)shared_cache_get_load_addr(); - addr_t insn_addr = shared_cache_load_addr + (addr_t)text_section->offset; - addr_t insn_addr_end = insn_addr + text_section->size; - - addr_t write_svc_addr = (addr_t)DobbySymbolResolver("libsystem_kernel.dylib", "write"); - write_svc_addr += 4; - - addr_t __psynch_mutexwait_svc_addr = (addr_t)DobbySymbolResolver("libsystem_kernel.dylib", "__psynch_mutexwait"); - __psynch_mutexwait_svc_addr += 4; - - for (; insn_addr < insn_addr_end; insn_addr += sizeof(uint32_t)) { - if (*(uint32_t *)insn_addr == 0xd4001001) { - if (insn_addr == write_svc_addr) - continue; - - if (insn_addr == __psynch_mutexwait_svc_addr) - continue; - supervisor_call_monitor_register_svc((addr_t)insn_addr); - } - } -} - -void supervisor_call_monitor_init() { - // create logger file - char logger_path[1024] = {0}; - sprintf(logger_path, "%s%s", getenv("HOME"), "/Documents/svc_monitor.txt"); - LOG(2, "HOME: %s", logger_path); - async_logger_init(logger_path); - - dobby_enable_near_branch_trampoline(); -} diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/supervisor_call_monitor.h b/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/supervisor_call_monitor.h deleted file mode 100644 index 45bde0a..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/supervisor_call_monitor.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -typedef uintptr_t addr_t; - -#include "dobby.h" - -void supervisor_call_monitor_init(); - -void supervisor_call_monitor_register_handler(DBICallTy handler); - -void supervisor_call_monitor_register_svc(addr_t svc_addr); - -void supervisor_call_monitor_register_image(void *header); - -void supervisor_call_monitor_register_main_app(); - -void supervisor_call_monitor_register_system_kernel(); - -void supervisor_call_monitor_register_syscall_call_log_handler(); - -void supervisor_call_monitor_register_mach_syscall_call_log_handler(); - -void supervisor_call_monitor_register_sensitive_api_handler(); \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/system_call_log_handler.cc b/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/system_call_log_handler.cc deleted file mode 100644 index c78db6a..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/system_call_log_handler.cc +++ /dev/null @@ -1,98 +0,0 @@ -#include "dobby_internal.h" - -#include - -#include "misc-helper/async_logger.h" -#include "PlatformUtil/ProcessRuntimeUtility.h" -#include "SupervisorCallMonitor/misc_utility.h" -#include "SupervisorCallMonitor/supervisor_call_monitor.h" - -#include "XnuInternal/syscalls.c" - -static const char *syscall_num_to_str(int num) { - return syscallnames[num]; -} - -static addr_t getCallFirstArg(DobbyRegisterContext *ctx) { - addr_t result; -#if defined(_M_X64) || defined(__x86_64__) -#if defined(_WIN32) - result = ctx->general.regs.rcx; -#else - result = ctx->general.regs.rdi; -#endif -#elif defined(__arm64__) || defined(__aarch64__) - result = ctx->general.regs.x0; -#elif defined(__arm__) - result = ctx->general.regs.r0; -#else -#error "Not Support Architecture." -#endif - return result; -} - -static addr_t getRealLr(DobbyRegisterContext *ctx) { - addr_t closure_trampoline_reserved_stack = ctx->sp - sizeof(addr_t); - return *(addr_t *)closure_trampoline_reserved_stack; -} - -static addr_t fast_get_caller_from_main_binary(DobbyRegisterContext *ctx) { - static addr_t text_section_start = 0, text_section_end = 0; - static addr_t slide = 0; - if (text_section_start == 0 || text_section_end == 0) { - auto main = ProcessRuntimeUtility::GetProcessModule(""); - addr_t main_header = (addr_t)main.load_address; - - auto text_segment = macho_kit_get_segment_by_name((mach_header_t *)main_header, "__TEXT"); - slide = main_header - text_segment->vmaddr; - - auto text_section = macho_kit_get_section_by_name((mach_header_t *)main_header, "__TEXT", "__text"); - text_section_start = main_header + (addr_t)text_section->offset; - text_section_end = text_section_start + text_section->size; - } - - if (ctx == NULL) - return 0; - - addr_t lr = getRealLr(ctx); - if (lr > text_section_start && lr < text_section_end) - return lr - slide; - -#define MAX_STACK_ITERATE_LEVEL 8 - addr_t fp = ctx->fp; - if (fp == 0) - return 0; - for (int i = 0; i < MAX_STACK_ITERATE_LEVEL; i++) { - addr_t lr = *(addr_t *)(fp + sizeof(addr_t)); - if (lr > text_section_start && lr < text_section_end) - return lr - slide; - fp = *(addr_t *)fp; - if (fp == 0) - return 0; - } - return 0; -} - -static void syscall_log_handler(DobbyRegisterContext *ctx, const InterceptEntry *info) { - addr_t caller = fast_get_caller_from_main_binary(ctx); - if (caller == 0) - return; - - char buffer[2048] = {0}; - int syscall_rum = ctx->general.regs.x16; - if (syscall_rum == 0) { - syscall_rum = (int)getCallFirstArg(ctx); - sprintf(buffer, "[syscall svc-%d] %s\n", syscall_rum, syscall_num_to_str(syscall_rum)); - } else if (syscall_rum > 0) { - sprintf(buffer, "[svc-%d] %s\n", syscall_rum, syscall_num_to_str(syscall_rum)); - if (syscall_rum == 5) { - sprintf(buffer, "[svc-%d] %s:%s\n", syscall_rum, syscall_num_to_str(syscall_rum), (char *)ctx->general.regs.x0); - } - } - async_logger_print(buffer); -} - -void supervisor_call_monitor_register_syscall_call_log_handler() { - fast_get_caller_from_main_binary(NULL); - supervisor_call_monitor_register_handler(syscall_log_handler); -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/test_supervisor_call_monitor.cc b/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/test_supervisor_call_monitor.cc deleted file mode 100644 index 862c4e1..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/test_supervisor_call_monitor.cc +++ /dev/null @@ -1,16 +0,0 @@ - -#include "dobby_internal.h" - -#include "SupervisorCallMonitor/supervisor_call_monitor.h" - -#if 1 -__attribute__((constructor)) static void ctor() { - log_set_level(2); - log_switch_to_syslog(); - - supervisor_call_monitor_init(); - supervisor_call_monitor_register_main_app(); - supervisor_call_monitor_register_syscall_call_log_handler(); - supervisor_call_monitor_register_mach_syscall_call_log_handler(); -} -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/CMakeLists.txt b/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/CMakeLists.txt deleted file mode 100644 index 0a0efe3..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/CMakeLists.txt +++ /dev/null @@ -1,44 +0,0 @@ -set(SOURCE_FILE_LIST ) - -if(NOT DEFINED DOBBY_DIR) - message(FATAL_ERROR "DOBBY_DIR must be set!") -endif() - -if(SYSTEM.Darwin AND (NOT BUILDING_KERNEL)) - set(SOURCE_FILE_LIST ${SOURCE_FILE_LIST} - ${CMAKE_CURRENT_SOURCE_DIR}/macho/dyld_shared_cache_symbol_table_iterator.cc - ${CMAKE_CURRENT_SOURCE_DIR}/macho/dobby_symbol_resolver.cc - - ${DOBBY_DIR}/source/Backend/UserMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc - ) -endif() -if(SYSTEM.Darwin AND BUILDING_KERNEL) - set(SOURCE_FILE_LIST ${SOURCE_FILE_LIST} - ${CMAKE_CURRENT_SOURCE_DIR}/macho/dobby_symbol_resolver.cc - - ${DOBBY_DIR}/source/Backend/KernelMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc - ) -endif() -if(SYSTEM.Linux OR SYSTEM.Android) - set(SOURCE_FILE_LIST ${SOURCE_FILE_LIST} - ${CMAKE_CURRENT_SOURCE_DIR}/elf/dobby_symbol_resolver.cc - - ${DOBBY_DIR}/source/Backend/UserMode/PlatformUtil/Linux/ProcessRuntimeUtility.cc - ) -endif() -if(SYSTEM.Windows) - set(SOURCE_FILE_LIST ${SOURCE_FILE_LIST} - ${CMAKE_CURRENT_SOURCE_DIR}/pe/dobby_symbol_resolver.cc - - ${DOBBY_DIR}/source/Backend/UserMode/PlatformUtil/Windows/ProcessRuntimeUtility.cc - ) -endif() - -add_library(symbol_resolver - ${SOURCE_FILE_LIST} - ) - -include_directories( - . -) - diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/dobby_symbol_resolver.h b/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/dobby_symbol_resolver.h deleted file mode 100644 index 22dee3c..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/dobby_symbol_resolver.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#if defined(BUILDING_INTERNAL) -#include "macho/dobby_symbol_resolver_priv.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -void *DobbySymbolResolver(const char *image_name, const char *symbol_name); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/elf/dobby_symbol_resolver.cc b/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/elf/dobby_symbol_resolver.cc deleted file mode 100644 index 75328cb..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/elf/dobby_symbol_resolver.cc +++ /dev/null @@ -1,292 +0,0 @@ -#include "SymbolResolver/dobby_symbol_resolver.h" -#include "common_header.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "PlatformUtil/ProcessRuntimeUtility.h" - -#include - -#undef LOG_TAG -#define LOG_TAG "DobbySymbolResolver" - -static void file_mmap(const char *file_path, uint8_t **data_ptr, size_t *data_size_ptr) { - uint8_t *mmap_data = NULL; - size_t file_size = 0; - - int fd = open(file_path, O_RDONLY, 0); - if (fd < 0) { - ERROR_LOG("%s open failed", file_path); - goto finished; - } - - { - struct stat s; - int rt = fstat(fd, &s); - if (rt != 0) { - ERROR_LOG("mmap failed"); - goto finished; - } - file_size = s.st_size; - } - - // auto align - mmap_data = (uint8_t *)mmap(0, file_size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_PRIVATE, fd, 0); - if (mmap_data == MAP_FAILED) { - ERROR_LOG("mmap failed"); - goto finished; - } - -finished: - close(fd); - - if (data_size_ptr) - *data_size_ptr = file_size; - if (data_ptr) - *data_ptr = mmap_data; -} - -static void file_unmap(void *data, size_t data_size) { - int ret = munmap(data, data_size); - if (ret != 0) { - ERROR_LOG("munmap failed"); - return; - } -} - -typedef struct elf_ctx { - void *header; - - uintptr_t load_bias; - - ElfW(Shdr) * sym_sh_; - ElfW(Shdr) * dynsym_sh_; - - const char *strtab_; - ElfW(Sym) * symtab_; - - const char *dynstrtab_; - ElfW(Sym) * dynsymtab_; - - size_t nbucket_; - size_t nchain_; - uint32_t *bucket_; - uint32_t *chain_; - - size_t gnu_nbucket_; - uint32_t *gnu_bucket_; - uint32_t *gnu_chain_; - uint32_t gnu_maskwords_; - uint32_t gnu_shift2_; - ElfW(Addr) * gnu_bloom_filter_; -} elf_ctx_t; - -static void get_syms(ElfW(Ehdr) * header, ElfW(Sym) * *symtab_ptr, char **strtab_ptr, int *count_ptr) { - ElfW(Shdr) *section_header = NULL; - section_header = (ElfW(Shdr) *)((addr_t)header + header->e_shoff); - - ElfW(Shdr) *section_strtab_section_header = NULL; - section_strtab_section_header = (ElfW(Shdr) *)((addr_t)section_header + header->e_shstrndx * header->e_shentsize); - char *section_strtab = NULL; - section_strtab = (char *)((addr_t)header + section_strtab_section_header->sh_offset); - - for (int i = 0; i < header->e_shnum; ++i) { - const char *section_name = (const char *)(section_strtab + section_header->sh_name); - if (section_header->sh_type == SHT_SYMTAB && strcmp(section_name, ".symtab") == 0) { - *symtab_ptr = (ElfW(Sym) *)((addr_t)header + section_header->sh_offset); - *count_ptr = section_header->sh_size / sizeof(ElfW(Sym)); - } - - if (section_header->sh_type == SHT_STRTAB && strcmp(section_name, ".strtab") == 0) { - *strtab_ptr = (char *)((addr_t)header + section_header->sh_offset); - } - section_header = (ElfW(Shdr) *)((addr_t)section_header + header->e_shentsize); - } -} - -int elf_ctx_init(elf_ctx_t *ctx, void *header_) { - ElfW(Ehdr) *ehdr = (ElfW(Ehdr) *)header_; - ctx->header = ehdr; - - ElfW(Addr) ehdr_addr = (ElfW(Addr))ehdr; - - // Handle dynamic segment - { - ElfW(Addr) addr = 0; - ElfW(Dyn) *dyn = NULL; - ElfW(Phdr) *phdr = reinterpret_cast(ehdr_addr + ehdr->e_phoff); - for (size_t i = 0; i < ehdr->e_phnum; i++) { - if (phdr[i].p_type == PT_DYNAMIC) { - dyn = reinterpret_cast(ehdr_addr + phdr[i].p_offset); - } else if (phdr[i].p_type == PT_LOAD) { - addr = ehdr_addr + phdr[i].p_offset - phdr[i].p_vaddr; - if (ctx->load_bias == 0) - ctx->load_bias = ehdr_addr - (phdr[i].p_vaddr - phdr[i].p_offset); - } else if (phdr[i].p_type == PT_PHDR) { - ctx->load_bias = (ElfW(Addr))phdr - phdr[i].p_vaddr; - } - } -// ctx->load_bias = -#if 0 - const char *strtab = nullptr; - ElfW(Sym) *symtab = nullptr; - for (ElfW(Dyn) *d = dyn; d->d_tag != DT_NULL; ++d) { - if (d->d_tag == DT_STRTAB) { - strtab = reinterpret_cast(addr + d->d_un.d_ptr); - } else if (d->d_tag == DT_SYMTAB) { - symtab = reinterpret_cast(addr + d->d_un.d_ptr); - } - } -#endif - } - - // Handle section - { - ElfW(Shdr) * dynsym_sh, *dynstr_sh; - ElfW(Shdr) * sym_sh, *str_sh; - - ElfW(Shdr) *shdr = reinterpret_cast(ehdr_addr + ehdr->e_shoff); - - ElfW(Shdr) *shstr_sh = NULL; - shstr_sh = &shdr[ehdr->e_shstrndx]; - char *shstrtab = NULL; - shstrtab = (char *)((addr_t)ehdr_addr + shstr_sh->sh_offset); - - for (size_t i = 0; i < ehdr->e_shnum; i++) { - if (shdr[i].sh_type == SHT_SYMTAB) { - sym_sh = &shdr[i]; - ctx->sym_sh_ = sym_sh; - ctx->symtab_ = (ElfW(Sym) *)(ehdr_addr + shdr[i].sh_offset); - } else if (shdr[i].sh_type == SHT_STRTAB && strcmp(shstrtab + shdr[i].sh_name, ".strtab") == 0) { - str_sh = &shdr[i]; - ctx->strtab_ = (const char *)(ehdr_addr + shdr[i].sh_offset); - } else if (shdr[i].sh_type == SHT_DYNSYM) { - dynsym_sh = &shdr[i]; - ctx->dynsym_sh_ = dynsym_sh; - ctx->dynsymtab_ = (ElfW(Sym) *)(ehdr_addr + shdr[i].sh_offset); - } else if (shdr[i].sh_type == SHT_STRTAB && strcmp(shstrtab + shdr[i].sh_name, ".dynstr") == 0) { - dynstr_sh = &shdr[i]; - ctx->dynstrtab_ = (const char *)(ehdr_addr + shdr[i].sh_offset); - } - } - } - - return 0; -} - -static void *iterate_symbol_table_impl(const char *symbol_name, ElfW(Sym) * symtab, const char *strtab, int count) { - for (int i = 0; i < count; ++i) { - ElfW(Sym) *sym = symtab + i; - const char *symbol_name_ = strtab + sym->st_name; - if (strcmp(symbol_name_, symbol_name) == 0) { - return (void *)sym->st_value; - } - } - return NULL; -} - -void *elf_ctx_iterate_symbol_table(elf_ctx_t *ctx, const char *symbol_name) { - void *result = NULL; - if (ctx->symtab_ && ctx->strtab_) { - size_t count = ctx->sym_sh_->sh_size / sizeof(ElfW(Sym)); - result = iterate_symbol_table_impl(symbol_name, ctx->symtab_, ctx->strtab_, count); - if (result) - return result; - } - - if (ctx->dynsymtab_ && ctx->dynstrtab_) { - size_t count = ctx->dynsym_sh_->sh_size / sizeof(ElfW(Sym)); - result = iterate_symbol_table_impl(symbol_name, ctx->dynsymtab_, ctx->dynstrtab_, count); - if (result) - return result; - } - return NULL; -} - -void *resolve_elf_internal_symbol(const char *library_name, const char *symbol_name) { - void *result = NULL; - - if (library_name) { - RuntimeModule module = ProcessRuntimeUtility::GetProcessModule(library_name); - - uint8_t *file_mem = NULL; - size_t file_mem_size = 0; - if (module.load_address) - file_mmap(module.path, &file_mem, &file_mem_size); - - elf_ctx_t ctx; - memset(&ctx, 0, sizeof(elf_ctx_t)); - if (file_mem) { - elf_ctx_init(&ctx, file_mem); - result = elf_ctx_iterate_symbol_table(&ctx, symbol_name); - } - - if (result) - result = (void *)((addr_t)result + (addr_t)module.load_address - ((addr_t)file_mem - (addr_t)ctx.load_bias)); - - if (file_mem) - file_unmap(file_mem, file_mem_size); - } - - if (!result) { - auto ProcessModuleMap = ProcessRuntimeUtility::GetProcessModuleMap(); - for (auto module : ProcessModuleMap) { - uint8_t *file_mem = NULL; - size_t file_mem_size = 0; - - if (module.load_address) - file_mmap(module.path, &file_mem, &file_mem_size); - - elf_ctx_t ctx; - memset(&ctx, 0, sizeof(elf_ctx_t)); - if (file_mem) { - elf_ctx_init(&ctx, file_mem); - result = elf_ctx_iterate_symbol_table(&ctx, symbol_name); - } - - if (result) - result = (void *)((addr_t)result + (addr_t)module.load_address - ((addr_t)file_mem - (addr_t)ctx.load_bias)); - - if (file_mem) - file_unmap(file_mem, file_mem_size); - - if (result) - break; - } - } - return result; -} - -// impl at "android_restriction.cc" -extern std::vector linker_get_solist(); - -PUBLIC void *DobbySymbolResolver(const char *image_name, const char *symbol_name_pattern) { - void *result = NULL; - -#if 0 - auto solist = linker_get_solist(); - for (auto soinfo : solist) { - uintptr_t handle = linker_soinfo_to_handle(soinfo); - if (image_name == NULL || strstr(linker_soinfo_get_realpath(soinfo), image_name) != 0) { - result = dlsym((void *)handle, symbol_name_pattern); - if (result) - return result; - } - } -#endif - result = dlsym(RTLD_DEFAULT, symbol_name_pattern); - if (result) - return result; - - result = resolve_elf_internal_symbol(image_name, symbol_name_pattern); - return result; -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dobby_symbol_resolver.cc b/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dobby_symbol_resolver.cc deleted file mode 100644 index 3ea6b1e..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dobby_symbol_resolver.cc +++ /dev/null @@ -1,454 +0,0 @@ -#include "dobby_symbol_resolver.h" -#include "macho/dobby_symbol_resolver_priv.h" - -#include "common_header.h" - -#include -#include - -#include "PlatformUtil/ProcessRuntimeUtility.h" - -#if defined(BUILDING_KERNEL) -#else - -#include -#include -#include "SymbolResolver/macho/shared_cache_internal.h" - -#endif - -#undef LOG_TAG -#define LOG_TAG "DobbySymbolResolver" - -uintptr_t read_uleb128(const uint8_t **pp, const uint8_t *end) { - uint8_t *p = (uint8_t *) *pp; - uint64_t result = 0; - int bit = 0; - do { - if (p == end) - ASSERT(p == end); - - uint64_t slice = *p & 0x7f; - - if (bit > 63) - ASSERT(bit > 63); - else { - result |= (slice << bit); - bit += 7; - } - } while (*p++ & 0x80); - - *pp = p; - - return (uintptr_t) result; -} - -intptr_t read_sleb128(const uint8_t **pp, const uint8_t *end) { - uint8_t *p = (uint8_t *) *pp; - - int64_t result = 0; - int bit = 0; - uint8_t byte; - do { - if (p == end) - ASSERT(p == end); - byte = *p++; - result |= (((int64_t) (byte & 0x7f)) << bit); - bit += 7; - } while (byte & 0x80); - // sign extend negative numbers - if ((byte & 0x40) != 0) - result |= (~0ULL) << bit; - - *pp = p; - - return (intptr_t) result; -} - -// dyld -uint8_t *walk_exported_trie(const uint8_t *start, const uint8_t *end, const char *symbol) { - const uint8_t *p = start; - while (p != NULL) { - uintptr_t terminalSize = *p++; - if (terminalSize > 127) { - // except for re-export-with-rename, all terminal sizes fit in one byte - --p; - terminalSize = read_uleb128(&p, end); - } - if ((*symbol == '\0') && (terminalSize != 0)) { - //dyld::log("trieWalk(%p) returning %p\n", start, p); - return (uint8_t *) p; - } - const uint8_t *children = p + terminalSize; - if (children > end) { - // dyld::log("trieWalk() malformed trie node, terminalSize=0x%lx extends past end of trie\n", terminalSize); - return NULL; - } - //dyld::log("trieWalk(%p) sym=%s, terminalSize=%lu, children=%p\n", start, s, terminalSize, children); - uint8_t childrenRemaining = *children++; - p = children; - uintptr_t nodeOffset = 0; - for (; childrenRemaining > 0; --childrenRemaining) { - const char *ss = symbol; - //dyld::log("trieWalk(%p) child str=%s\n", start, (char*)p); - bool wrongEdge = false; - // scan whole edge to get to next edge - // if edge is longer than target symbol name, don't read past end of symbol name - char c = *p; - while (c != '\0') { - if (!wrongEdge) { - if (c != *ss) - wrongEdge = true; - ++ss; - } - ++p; - c = *p; - } - if (wrongEdge) { - // advance to next child - ++p; // skip over zero terminator - // skip over uleb128 until last byte is found - while ((*p & 0x80) != 0) - ++p; - ++p; // skip over last byte of uleb128 - if (p > end) { - // dyld::log("trieWalk() malformed trie node, child node extends past end of trie\n"); - return NULL; - } - } else { - // the symbol so far matches this edge (child) - // so advance to the child's node - ++p; - nodeOffset = read_uleb128(&p, end); - if ((nodeOffset == 0) || (&start[nodeOffset] > end)) { - // dyld::log("trieWalk() malformed trie child, nodeOffset=0x%lx out of range\n", nodeOffset); - return NULL; - } - symbol = ss; - //dyld::log("trieWalk() found matching edge advancing to node 0x%lx\n", nodeOffset); - break; - } - } - if (nodeOffset != 0) - p = &start[nodeOffset]; - else - p = NULL; - } - //dyld::log("trieWalk(%p) return NULL\n", start); - return NULL; -} - -uintptr_t iterate_exported_symbol(mach_header_t *header, const char *symbol_name, uint64_t *out_flags) { - segment_command_t *curr_seg_cmd; - struct dyld_info_command *dyld_info_cmd = nullptr; - struct linkedit_data_command *exports_trie_cmd = nullptr; - segment_command_t *text_segment = nullptr, *data_segment = nullptr, *linkedit_segment = nullptr; - - curr_seg_cmd = (segment_command_t *) ((uintptr_t) header + sizeof(mach_header_t)); - for (int i = 0; i < header->ncmds; i++) { - switch (curr_seg_cmd->cmd) { - case LC_SEGMENT_ARCH_DEPENDENT: { - if (strcmp(curr_seg_cmd->segname, "__LINKEDIT") == 0) { - linkedit_segment = curr_seg_cmd; - } else if (strcmp(curr_seg_cmd->segname, "__TEXT") == 0) { - text_segment = curr_seg_cmd; - } - } - break; - case LC_DYLD_EXPORTS_TRIE: { - exports_trie_cmd = (struct linkedit_data_command *) curr_seg_cmd; - } - break; - case LC_DYLD_INFO: - case LC_DYLD_INFO_ONLY: { - dyld_info_cmd = (struct dyld_info_command *) curr_seg_cmd; - } - break; - default: - break; - }; - curr_seg_cmd = (segment_command_t *) ((uintptr_t) curr_seg_cmd + curr_seg_cmd->cmdsize); - } - - if (text_segment == NULL || linkedit_segment == NULL) { - return 0; - } - - if (exports_trie_cmd == NULL && dyld_info_cmd == NULL) - return 0; - - uint32_t trieFileOffset = dyld_info_cmd ? dyld_info_cmd->export_off : exports_trie_cmd->dataoff; - uint32_t trieFileSize = dyld_info_cmd ? dyld_info_cmd->export_size : exports_trie_cmd->datasize; - - uintptr_t slide = (uintptr_t) header - (uintptr_t) text_segment->vmaddr; - uintptr_t linkedit_base = (uintptr_t) slide + linkedit_segment->vmaddr - linkedit_segment->fileoff; - - void *exports = (void *) (linkedit_base + trieFileOffset); - if (exports == NULL) - return 0; - - uint8_t *exports_start = (uint8_t *) exports; - uint8_t *exports_end = exports_start + trieFileSize; - uint8_t *node = (uint8_t *) walk_exported_trie(exports_start, exports_end, symbol_name); - if (node == NULL) - return 0; - const uint8_t *p = node; - const uintptr_t flags = read_uleb128(&p, exports_end); - if (flags & EXPORT_SYMBOL_FLAGS_REEXPORT) { - return 0; - } - if (out_flags) - *out_flags = flags; - uint64_t trieValue = read_uleb128(&p, exports_end); - return trieValue; -#if 0 - if (off == (void *)0) { - if (symbol_name[0] != '_' && strlen(&symbol_name[1]) >= 1) { - char _symbol_name[1024] = {0}; - _symbol_name[0] = '_'; - strcpy(&_symbol_name[1], symbol_name); - off = (void *)walk_exported_trie((const uint8_t *)exports, (const uint8_t *)exports + trieFileSize, _symbol_name); - } - } -#endif -} - -void macho_ctx_init(macho_ctx_t *ctx, mach_header_t *header) { - ctx->header = header; - segment_command_t *curr_seg_cmd; - segment_command_t *text_segment = nullptr, *text_exec_segment = nullptr, *data_segment = nullptr, *data_const_segment = nullptr, - *linkedit_segment = nullptr; - struct symtab_command *symtab_cmd = nullptr; - struct dysymtab_command *dysymtab_cmd = nullptr; - struct dyld_info_command *dyld_info_cmd = nullptr; - - curr_seg_cmd = (segment_command_t *) ((uintptr_t) header + sizeof(mach_header_t)); - for (int i = 0; i < header->ncmds; i++) { - if (curr_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { - // BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB and REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB - ctx->segments[ctx->segments_count++] = curr_seg_cmd; - - if (strcmp(curr_seg_cmd->segname, "__LINKEDIT") == 0) { - linkedit_segment = curr_seg_cmd; - } else if (strcmp(curr_seg_cmd->segname, "__DATA") == 0) { - data_segment = curr_seg_cmd; - } else if (strcmp(curr_seg_cmd->segname, "__DATA_CONST") == 0) { - data_const_segment = curr_seg_cmd; - } else if (strcmp(curr_seg_cmd->segname, "__TEXT") == 0) { - text_segment = curr_seg_cmd; - } else if (strcmp(curr_seg_cmd->segname, "__TEXT_EXEC") == 0) { - text_exec_segment = curr_seg_cmd; - } - } else if (curr_seg_cmd->cmd == LC_SYMTAB) { - symtab_cmd = (struct symtab_command *) curr_seg_cmd; - } else if (curr_seg_cmd->cmd == LC_DYSYMTAB) { - dysymtab_cmd = (struct dysymtab_command *) curr_seg_cmd; - } else if (curr_seg_cmd->cmd == LC_DYLD_INFO || curr_seg_cmd->cmd == LC_DYLD_INFO_ONLY) { - dyld_info_cmd = (struct dyld_info_command *) curr_seg_cmd; - } - curr_seg_cmd = (segment_command_t *) ((uintptr_t) curr_seg_cmd + curr_seg_cmd->cmdsize); - } - - uintptr_t slide = (uintptr_t) header - (uintptr_t) text_segment->vmaddr; - uintptr_t linkedit_base = (uintptr_t) slide + linkedit_segment->vmaddr - linkedit_segment->fileoff; - - ctx->text_seg = text_segment; - ctx->text_exec_seg = text_exec_segment; - ctx->data_seg = data_segment; - ctx->data_const_seg = data_const_segment; - ctx->linkedit_seg = linkedit_segment; - - ctx->symtab_cmd = symtab_cmd; - ctx->dysymtab_cmd = dysymtab_cmd; - ctx->dyld_info_cmd = dyld_info_cmd; - - ctx->slide = slide; - ctx->linkedit_base = linkedit_base; - - ctx->symtab = (nlist_t *) (ctx->linkedit_base + ctx->symtab_cmd->symoff); - ctx->strtab = (char *) (ctx->linkedit_base + ctx->symtab_cmd->stroff); - ctx->indirect_symtab = (uint32_t *) (ctx->linkedit_base + ctx->dysymtab_cmd->indirectsymoff); -} - -uintptr_t iterate_symbol_table(char *name_pattern, nlist_t *symtab, uint32_t symtab_count, char *strtab) { - for (uint32_t i = 0; i < symtab_count; i++) { - if (symtab[i].n_value) { - uint32_t strtab_offset = symtab[i].n_un.n_strx; - char *symbol_name = strtab + strtab_offset; -#if 0 - LOG(1, "> %s", symbol_name); -#endif - if (strcmp(name_pattern, symbol_name) == 0) { - return symtab[i].n_value; - } - if (symbol_name[0] == '_') { - if (strcmp(name_pattern, &symbol_name[1]) == 0) { - return symtab[i].n_value; - } - } - } - } - return 0; -} - -static uintptr_t macho_kit_get_slide(mach_header_t *header) { - uintptr_t slide = 0; - - segment_command_t *curr_seg_cmd; - - curr_seg_cmd = (segment_command_t *) ((addr_t) header + sizeof(mach_header_t)); - for (int i = 0; i < header->ncmds; i++) { - if (curr_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { - if (strcmp(curr_seg_cmd->segname, "__TEXT") == 0) { - slide = (uintptr_t) header - curr_seg_cmd->vmaddr; - return slide; - } - } - curr_seg_cmd = (segment_command_t *) ((addr_t) curr_seg_cmd + curr_seg_cmd->cmdsize); - } - return 0; -} - -PUBLIC void *DobbyMachOSymbolResolverOptions(void *header_, const char *symbol_name, bool add_slide) { - mach_header_t *header = (mach_header_t *) header_; - uintptr_t result = 0; - - size_t slide = 0; - - if (add_slide) - slide = macho_kit_get_slide(header); - - // binary symbol table - macho_ctx_t macho_ctx; - memset(&macho_ctx, 0, sizeof(macho_ctx_t)); - macho_ctx_init(&macho_ctx, header); - result = iterate_symbol_table((char *) symbol_name, macho_ctx.symtab, macho_ctx.symtab_cmd->nsyms, macho_ctx.strtab); - if (result) { - result = result + slide; - return (void *) result; - } - return nullptr; -} - -PUBLIC void *DobbyMachOSymbolResolver(void *header_, const char *symbol_name) { - return DobbyMachOSymbolResolverOptions(header_, symbol_name, true); -} - -PUBLIC void *DobbySymbolResolver(const char *image_name, const char *symbol_name_pattern) { - uintptr_t result = 0; - - const std::vector modules = ProcessRuntimeUtility::GetProcessModuleMap(); - - for (auto iter = modules.begin(); iter != modules.end(); iter++) { - auto module = *iter; - // for (auto module : *modules) { - if (image_name != NULL && strnstr(module.path, image_name, strlen(module.path)) == NULL) - continue; - - mach_header_t *header = (mach_header_t *) module.load_address; - if (header == nullptr) - continue; - - size_t slide = 0; - if (header->magic == MH_MAGIC_64) - slide = macho_kit_get_slide(header); - -#if 0 - LOG(0, "resolve image: %s", module.path); -#endif - - nlist_t *symtab = NULL; - uint32_t symtab_count = 0; - char *strtab = NULL; - -#if !defined(BUILDING_KERNEL) -#if defined(__arm__) || defined(__aarch64__) - static int shared_cache_ctx_init_once = 0; - static shared_cache_ctx_t shared_cache_ctx; - if (shared_cache_ctx_init_once == 0) { - shared_cache_ctx_init_once = 1; - memset(&shared_cache_ctx, 0, sizeof(shared_cache_ctx_t)); - shared_cache_ctx_init(&shared_cache_ctx); - } - if (shared_cache_ctx.runtime_shared_cache) { - // shared cache library - if (shared_cache_is_contain(&shared_cache_ctx, (addr_t) header, 0)) { - shared_cache_get_symbol_table(&shared_cache_ctx, header, &symtab, &symtab_count, &strtab); - } - } - if (symtab && strtab) { - result = iterate_symbol_table((char *) symbol_name_pattern, symtab, symtab_count, strtab); - } - if (result) { - result = result + slide; - break; - } -#endif -#endif - - // binary symbol table - macho_ctx_t macho_ctx; - memset(&macho_ctx, 0, sizeof(macho_ctx_t)); - macho_ctx_init(&macho_ctx, header); - result = iterate_symbol_table((char *) symbol_name_pattern, macho_ctx.symtab, macho_ctx.symtab_cmd->nsyms, - macho_ctx.strtab); - if (result) { - result = result + slide; - break; - } - - // binary exported table(uleb128) - uint64_t flags; - result = iterate_exported_symbol((mach_header_t *) header, symbol_name_pattern, &flags); - if (result) { - switch (flags & EXPORT_SYMBOL_FLAGS_KIND_MASK) { - case EXPORT_SYMBOL_FLAGS_KIND_REGULAR: { - result += (uintptr_t) header; - } - break; - case EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL: { - result += (uintptr_t) header; - } - break; - case EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE: { - } - break; - default: - break; - } - return (void *) result; - } - } - -#if !defined(BUILDING_KERNEL) - mach_header_t *dyld_header = NULL; - if (image_name != NULL && strcmp(image_name, "dyld") == 0) { - // task info - task_dyld_info_data_t task_dyld_info; - mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT; - if (task_info(mach_task_self(), TASK_DYLD_INFO, (task_info_t) &task_dyld_info, &count)) { - return NULL; - } - - // get dyld load address - const struct dyld_all_image_infos *infos = - (struct dyld_all_image_infos *) (uintptr_t) task_dyld_info.all_image_info_addr; - dyld_header = (mach_header_t *) infos->dyldImageLoadAddress; - - macho_ctx_t dyld_ctx; - memset(&dyld_ctx, 0, sizeof(macho_ctx_t)); - macho_ctx_init(&dyld_ctx, dyld_header); - result = - iterate_symbol_table((char *) symbol_name_pattern, dyld_ctx.symtab, dyld_ctx.symtab_cmd->nsyms, dyld_ctx.strtab); - if (result) { - result = result + (addr_t) dyld_header; - } - } -#endif - - if (result == 0) { - LOG(0, "symbol resolver failed: %s", symbol_name_pattern); - } - - return (void *) result; -} diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dobby_symbol_resolver_priv.h b/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dobby_symbol_resolver_priv.h deleted file mode 100644 index 3d69448..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dobby_symbol_resolver_priv.h +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include - -#if defined(__LP64__) -typedef struct mach_header_64 mach_header_t; -typedef struct segment_command_64 segment_command_t; -typedef struct section_64 section_t; -typedef struct nlist_64 nlist_t; -#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT_64 -#else -typedef struct mach_header mach_header_t; -typedef struct segment_command segment_command_t; -typedef struct section section_t; -typedef struct nlist nlist_t; -#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT -#endif - -typedef struct macho_ctx { - mach_header_t *header; - - uintptr_t slide; - uintptr_t linkedit_base; - - segment_command_t *segments[64]; - int segments_count; - - segment_command_t *text_seg; - segment_command_t *data_seg; - segment_command_t *text_exec_seg; - segment_command_t *data_const_seg; - segment_command_t *linkedit_seg; - - struct symtab_command *symtab_cmd; - struct dysymtab_command *dysymtab_cmd; - struct dyld_info_command *dyld_info_cmd; - - nlist_t *symtab; - char *strtab; - uint32_t *indirect_symtab; - -} macho_ctx_t; - -void macho_ctx_init(macho_ctx_t *ctx, mach_header_t *header); - -uintptr_t iterate_symbol_table(char *name_pattern, nlist_t *symtab, uint32_t symtab_count, char *strtab); diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dyld_shared_cache_symbol_table_iterator.cc b/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dyld_shared_cache_symbol_table_iterator.cc deleted file mode 100644 index d7f85fb..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dyld_shared_cache_symbol_table_iterator.cc +++ /dev/null @@ -1,241 +0,0 @@ -#include -#include -#include -#include -#include - -#include // pthread_once -#include // mmap -#include // open - -#include "SymbolResolver/macho/shared_cache_internal.h" -#include "SymbolResolver/macho/shared-cache/dyld_cache_format.h" - -#include "logging/logging.h" - -#undef LOG_TAG -#define LOG_TAG "DobbySymbolResolverCache" - -#if 0 -extern "C" { -int __shared_region_check_np(uint64_t *startaddress); -} -#endif - -extern "C" const char *dyld_shared_cache_file_path(); - -static pthread_once_t mmap_dyld_shared_cache_once = PTHREAD_ONCE_INIT; - -extern "C" int __shared_region_check_np(uint64_t *startaddress); - -#include - -static char *fast_get_shared_cache_path() { -#if defined(_M_IX86) || defined(__i386__) || defined(_M_X64) || defined(__x86_64__) - return NULL; -#endif - char *result = NULL; - char path_buffer[2048] = {0}; - - const char *path = NULL; - do { - path = dyld_shared_cache_file_path(); - if (path != NULL) { - break; - } else { - struct stat statbuf; - int r = 0; - - path = IPHONE_DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME "arm64"; - r = stat(path, &statbuf); - if (r == 0) { - break; - } - path = IPHONE_DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME "arm64e"; - r = stat(path, &statbuf); - if (r == 0) { - break; - } - path = MACOSX_MRM_DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME "arm64"; - r = stat(path, &statbuf); - if (r == 0) { - break; - } - path = MACOSX_MRM_DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME "arm64e"; - r = stat(path, &statbuf); - if (r == 0) { - break; - } - } - } while (0); - - if (path != NULL) { - strcpy(path_buffer, path); - result = (char *)malloc(strlen(path_buffer) + 1); - strcpy(result, path_buffer); - } - - return result; -} - -#include -#include -#include -struct dyld_cache_header *shared_cache_get_load_addr() { - static struct dyld_cache_header *shared_cache_load_addr = 0; - - // task info - task_dyld_info_data_t task_dyld_info; - mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT; - if (task_info(mach_task_self(), TASK_DYLD_INFO, (task_info_t)&task_dyld_info, &count)) { - return NULL; - } - - // get dyld load address - const struct dyld_all_image_infos *infos = - (struct dyld_all_image_infos *)(uintptr_t)task_dyld_info.all_image_info_addr; - shared_cache_load_addr = (struct dyld_cache_header *)infos->sharedCacheBaseAddress; - - return shared_cache_load_addr; - -#if 0 - if (shared_cache_load_addr) - return shared_cache_load_addr; -#if 0 - if (syscall(294, &shared_cache_load_addr) == 0) { -#else - if (__shared_region_check_np((uint64_t *)&shared_cache_load_addr) != 0) { -#endif - shared_cache_load_addr = 0; -} -#endif - return shared_cache_load_addr; -} - -int shared_cache_ctx_init(shared_cache_ctx_t *ctx) { - int fd; - const char *cache_file_path = NULL; - - cache_file_path = fast_get_shared_cache_path(); - if (cache_file_path == NULL) { - return -1; - } - - fd = open(cache_file_path, O_RDONLY, 0); - if (fd == -1) { - return KERN_FAILURE; - } - - struct dyld_cache_header *runtime_shared_cache; - struct dyld_cache_header *mmap_shared_cache; - - // auto align - runtime_shared_cache = shared_cache_get_load_addr(); - if (runtime_shared_cache == NULL) { - return KERN_FAILURE; - } - - // maybe shared cache is apple silicon - if (runtime_shared_cache->localSymbolsSize == 0) { - return KERN_FAILURE; - } - - size_t mmap_length = runtime_shared_cache->localSymbolsSize; - off_t mmap_offset = runtime_shared_cache->localSymbolsOffset; - mmap_shared_cache = - (struct dyld_cache_header *)mmap(0, mmap_length, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, mmap_offset); - if (mmap_shared_cache == MAP_FAILED) { - DLOG(0, "mmap shared cache failed"); - return KERN_FAILURE; - } - - // fake shared cache header - mmap_shared_cache = - (struct dyld_cache_header *)((addr_t)mmap_shared_cache - runtime_shared_cache->localSymbolsOffset); - - ctx->runtime_shared_cache = runtime_shared_cache; - ctx->mmap_shared_cache = mmap_shared_cache; - - // shared cache slide - const struct dyld_cache_mapping_info *mappings = - (struct dyld_cache_mapping_info *)((char *)runtime_shared_cache + runtime_shared_cache->mappingOffset); - uintptr_t slide = (uintptr_t)runtime_shared_cache - (uintptr_t)(mappings[0].address); - ctx->runtime_slide = slide; - - // shared cache symbol table - static struct dyld_cache_local_symbols_info *localInfo = NULL; - localInfo = - (struct dyld_cache_local_symbols_info *)((char *)mmap_shared_cache + runtime_shared_cache->localSymbolsOffset); - - static struct dyld_cache_local_symbols_entry *localEntries = NULL; - localEntries = (struct dyld_cache_local_symbols_entry *)((char *)localInfo + localInfo->entriesOffset); - - ctx->local_symbols_info = localInfo; - ctx->local_symbols_entries = localEntries; - - ctx->symtab = (nlist_t *)((char *)localInfo + localInfo->nlistOffset); - ctx->strtab = ((char *)localInfo) + localInfo->stringsOffset; - return 0; -} - -// refer: dyld -bool shared_cache_is_contain(shared_cache_ctx_t *ctx, addr_t addr, size_t length) { - struct dyld_cache_header *runtime_shared_cache; - if (ctx) { - runtime_shared_cache = ctx->runtime_shared_cache; - } else { - runtime_shared_cache = shared_cache_get_load_addr(); - } - - const struct dyld_cache_mapping_info *mappings = - (struct dyld_cache_mapping_info *)((char *)runtime_shared_cache + runtime_shared_cache->mappingOffset); - uintptr_t slide = (uintptr_t)runtime_shared_cache - (uintptr_t)(mappings[0].address); - uintptr_t unslidStart = (uintptr_t)addr - slide; - - // quick out if after end of cache - if (unslidStart > (mappings[2].address + mappings[2].size)) - return false; - - // walk cache regions - const struct dyld_cache_mapping_info *mappingsEnd = &mappings[runtime_shared_cache->mappingCount]; - uintptr_t unslidEnd = unslidStart + length; - for (const struct dyld_cache_mapping_info *m = mappings; m < mappingsEnd; ++m) { - if ((unslidStart >= m->address) && (unslidEnd < (m->address + m->size))) { - return true; - } - } - return false; -} - -int shared_cache_get_symbol_table(shared_cache_ctx_t *ctx, mach_header_t *image_header, nlist_t **out_symtab, - uint32_t *out_symtab_count, char **out_strtab) { - struct dyld_cache_header *runtime_shared_cache = NULL; - - runtime_shared_cache = ctx->runtime_shared_cache; - - uint64_t textOffsetInCache = (uint64_t)image_header - (uint64_t)runtime_shared_cache; - - nlist_t *localNlists = NULL; - uint32_t localNlistCount = 0; - const char *localStrings = NULL; - - const uint32_t entriesCount = ctx->local_symbols_info->entriesCount; - for (uint32_t i = 0; i < entriesCount; ++i) { - if (ctx->local_symbols_entries[i].dylibOffset == textOffsetInCache) { - uint32_t localNlistStart = ctx->local_symbols_entries[i].nlistStartIndex; - localNlistCount = ctx->local_symbols_entries[i].nlistCount; - localNlists = &ctx->symtab[localNlistStart]; - -#if 0 - static struct dyld_cache_image_info *imageInfos = NULL; - imageInfos = (struct dyld_cache_image_info *)((addr_t)g_mmap_shared_cache + g_mmap_shared_cache->imagesOffset); - char *image_name = (char *)g_mmap_shared_cache + imageInfos[i].pathFileOffset; - LOG(1, "dyld image: %s", image_name); -#endif - } - } - *out_symtab = localNlists; - *out_symtab_count = (uint32_t)localNlistCount; - *out_strtab = (char *)ctx->strtab; - return 0; -} diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/shared-cache/dyld_cache_format.h b/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/shared-cache/dyld_cache_format.h deleted file mode 100644 index 29e046b..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/shared-cache/dyld_cache_format.h +++ /dev/null @@ -1,530 +0,0 @@ -/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- -* -* Copyright (c) 2006-2015 Apple Inc. All rights reserved. -* -* @APPLE_LICENSE_HEADER_START@ -* -* This file contains Original Code and/or Modifications of Original Code -* as defined in and that are subject to the Apple Public Source License -* Version 2.0 (the 'License'). You may not use this file except in -* compliance with the License. Please obtain a copy of the License at -* http://www.opensource.apple.com/apsl/ and read it before using this -* file. -* -* The Original Code and all software distributed under the License are -* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, -* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. -* Please see the License for the specific language governing rights and -* limitations under the License. -* -* @APPLE_LICENSE_HEADER_END@ -*/ -#ifndef __DYLD_CACHE_FORMAT__ -#define __DYLD_CACHE_FORMAT__ - -#include -#include -#include -#include - - -struct dyld_cache_header -{ - char magic[16]; // e.g. "dyld_v0 i386" - uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info - uint32_t mappingCount; // number of dyld_cache_mapping_info entries - uint32_t imagesOffset; // file offset to first dyld_cache_image_info - uint32_t imagesCount; // number of dyld_cache_image_info entries - uint64_t dyldBaseAddress; // base address of dyld when cache was built - uint64_t codeSignatureOffset; // file offset of code signature blob - uint64_t codeSignatureSize; // size of code signature blob (zero means to end of file) - uint64_t slideInfoOffsetUnused; // unused. Used to be file offset of kernel slid info - uint64_t slideInfoSizeUnused; // unused. Used to be size of kernel slid info - uint64_t localSymbolsOffset; // file offset of where local symbols are stored - uint64_t localSymbolsSize; // size of local symbols information - uint8_t uuid[16]; // unique value for each shared cache file - uint64_t cacheType; // 0 for development, 1 for production - uint32_t branchPoolsOffset; // file offset to table of uint64_t pool addresses - uint32_t branchPoolsCount; // number of uint64_t entries - uint64_t accelerateInfoAddr; // (unslid) address of optimization info - uint64_t accelerateInfoSize; // size of optimization info - uint64_t imagesTextOffset; // file offset to first dyld_cache_image_text_info - uint64_t imagesTextCount; // number of dyld_cache_image_text_info entries - uint64_t patchInfoAddr; // (unslid) address of dyld_cache_patch_info - uint64_t patchInfoSize; // Size of all of the patch information pointed to via the dyld_cache_patch_info - uint64_t otherImageGroupAddrUnused; // unused - uint64_t otherImageGroupSizeUnused; // unused - uint64_t progClosuresAddr; // (unslid) address of list of program launch closures - uint64_t progClosuresSize; // size of list of program launch closures - uint64_t progClosuresTrieAddr; // (unslid) address of trie of indexes into program launch closures - uint64_t progClosuresTrieSize; // size of trie of indexes into program launch closures - uint32_t platform; // platform number (macOS=1, etc) - uint32_t formatVersion : 8, // dyld3::closure::kFormatVersion - dylibsExpectedOnDisk : 1, // dyld should expect the dylib exists on disk and to compare inode/mtime to see if cache is valid - simulator : 1, // for simulator of specified platform - locallyBuiltCache : 1, // 0 for B&I built cache, 1 for locally built cache - builtFromChainedFixups : 1, // some dylib in cache was built using chained fixups, so patch tables must be used for overrides - padding : 20; // TBD - uint64_t sharedRegionStart; // base load address of cache if not slid - uint64_t sharedRegionSize; // overall size of region cache can be mapped into - uint64_t maxSlide; // runtime slide of cache can be between zero and this value - uint64_t dylibsImageArrayAddr; // (unslid) address of ImageArray for dylibs in this cache - uint64_t dylibsImageArraySize; // size of ImageArray for dylibs in this cache - uint64_t dylibsTrieAddr; // (unslid) address of trie of indexes of all cached dylibs - uint64_t dylibsTrieSize; // size of trie of cached dylib paths - uint64_t otherImageArrayAddr; // (unslid) address of ImageArray for dylibs and bundles with dlopen closures - uint64_t otherImageArraySize; // size of ImageArray for dylibs and bundles with dlopen closures - uint64_t otherTrieAddr; // (unslid) address of trie of indexes of all dylibs and bundles with dlopen closures - uint64_t otherTrieSize; // size of trie of dylibs and bundles with dlopen closures - uint32_t mappingWithSlideOffset; // file offset to first dyld_cache_mapping_and_slide_info - uint32_t mappingWithSlideCount; // number of dyld_cache_mapping_and_slide_info entries -}; - -// Uncomment this and check the build errors for the current mapping offset to check against when adding new fields. -// template class A { int x[-size]; }; A a; - - -struct dyld_cache_mapping_info { - uint64_t address; - uint64_t size; - uint64_t fileOffset; - uint32_t maxProt; - uint32_t initProt; -}; - -// Contains the flags for the dyld_cache_mapping_and_slide_info flgs field -enum { - DYLD_CACHE_MAPPING_AUTH_DATA = 1 << 0U, - DYLD_CACHE_MAPPING_DIRTY_DATA = 1 << 1U, - DYLD_CACHE_MAPPING_CONST_DATA = 1 << 2U, -}; - -struct dyld_cache_mapping_and_slide_info { - uint64_t address; - uint64_t size; - uint64_t fileOffset; - uint64_t slideInfoFileOffset; - uint64_t slideInfoFileSize; - uint64_t flags; - uint32_t maxProt; - uint32_t initProt; -}; - -struct dyld_cache_image_info -{ - uint64_t address; - uint64_t modTime; - uint64_t inode; - uint32_t pathFileOffset; - uint32_t pad; -}; - -struct dyld_cache_image_info_extra -{ - uint64_t exportsTrieAddr; // address of trie in unslid cache - uint64_t weakBindingsAddr; - uint32_t exportsTrieSize; - uint32_t weakBindingsSize; - uint32_t dependentsStartArrayIndex; - uint32_t reExportsStartArrayIndex; -}; - - -struct dyld_cache_accelerator_info -{ - uint32_t version; // currently 1 - uint32_t imageExtrasCount; // does not include aliases - uint32_t imagesExtrasOffset; // offset into this chunk of first dyld_cache_image_info_extra - uint32_t bottomUpListOffset; // offset into this chunk to start of 16-bit array of sorted image indexes - uint32_t dylibTrieOffset; // offset into this chunk to start of trie containing all dylib paths - uint32_t dylibTrieSize; // size of trie containing all dylib paths - uint32_t initializersOffset; // offset into this chunk to start of initializers list - uint32_t initializersCount; // size of initializers list - uint32_t dofSectionsOffset; // offset into this chunk to start of DOF sections list - uint32_t dofSectionsCount; // size of initializers list - uint32_t reExportListOffset; // offset into this chunk to start of 16-bit array of re-exports - uint32_t reExportCount; // size of re-exports - uint32_t depListOffset; // offset into this chunk to start of 16-bit array of dependencies (0x8000 bit set if upward) - uint32_t depListCount; // size of dependencies - uint32_t rangeTableOffset; // offset into this chunk to start of ss - uint32_t rangeTableCount; // size of dependencies - uint64_t dyldSectionAddr; // address of libdyld's __dyld section in unslid cache -}; - -struct dyld_cache_accelerator_initializer -{ - uint32_t functionOffset; // address offset from start of cache mapping - uint32_t imageIndex; -}; - -struct dyld_cache_range_entry -{ - uint64_t startAddress; // unslid address of start of region - uint32_t size; - uint32_t imageIndex; -}; - -struct dyld_cache_accelerator_dof -{ - uint64_t sectionAddress; // unslid address of start of region - uint32_t sectionSize; - uint32_t imageIndex; -}; - -struct dyld_cache_image_text_info -{ - uuid_t uuid; - uint64_t loadAddress; // unslid address of start of __TEXT - uint32_t textSegmentSize; - uint32_t pathOffset; // offset from start of cache file -}; - - -// The rebasing info is to allow the kernel to lazily rebase DATA pages of the -// dyld shared cache. Rebasing is adding the slide to interior pointers. -struct dyld_cache_slide_info -{ - uint32_t version; // currently 1 - uint32_t toc_offset; - uint32_t toc_count; - uint32_t entries_offset; - uint32_t entries_count; - uint32_t entries_size; // currently 128 - // uint16_t toc[toc_count]; - // entrybitmap entries[entries_count]; -}; - -struct dyld_cache_slide_info_entry { - uint8_t bits[4096/(8*4)]; // 128-byte bitmap -}; - - -// The version 2 of the slide info uses a different compression scheme. Since -// only interior pointers (pointers that point within the cache) are rebased -// (slid), we know the possible range of the pointers and thus know there are -// unused bits in each pointer. We use those bits to form a linked list of -// locations needing rebasing in each page. -// -// Definitions: -// -// pageIndex = (pageAddress - startOfAllDataAddress)/info->page_size -// pageStarts[] = info + info->page_starts_offset -// pageExtras[] = info + info->page_extras_offset -// valueMask = ~(info->delta_mask) -// deltaShift = __builtin_ctzll(info->delta_mask) - 2 -// -// There are three cases: -// -// 1) pageStarts[pageIndex] == DYLD_CACHE_SLIDE_PAGE_ATTR_NO_REBASE -// The page contains no values that need rebasing. -// -// 2) (pageStarts[pageIndex] & DYLD_CACHE_SLIDE_PAGE_ATTR_EXTRA) == 0 -// All rebase locations are in one linked list. The offset of the first -// rebase location in the page is pageStarts[pageIndex] * 4. -// -// 3) pageStarts[pageIndex] & DYLD_CACHE_SLIDE_PAGE_ATTR_EXTRA -// Multiple linked lists are needed for all rebase locations in a page. -// The pagesExtras array contains 2 or more entries each of which is the -// start of a new linked list in the page. The first is at: -// extrasStartIndex = (pageStarts[pageIndex] & 0x3FFF) -// The next is at extrasStartIndex+1. The last is denoted by -// having the high bit (DYLD_CACHE_SLIDE_PAGE_ATTR_END) of the pageExtras[] -// set. -// -// For 64-bit architectures, there is always enough free bits to encode all -// possible deltas. The info->delta_mask field shows where the delta is located -// in the pointer. That value must be masked off (valueMask) before the slide -// is added to the pointer. -// -// For 32-bit architectures, there are only three bits free (the three most -// significant bits). To extract the delta, you must first subtract value_add -// from the pointer value, then AND with delta_mask, then shift by deltaShift. -// That still leaves a maximum delta to the next rebase location of 28 bytes. -// To reduce the number or chains needed, an optimization was added. Turns -// out zero is common in the DATA region. A zero can be turned into a -// non-rebasing entry in the linked list. The can be done because nothing -// in the shared cache should point out of its dylib to the start of the shared -// cache. -// -// The code for processing a linked list (chain) is: -// -// uint32_t delta = 1; -// while ( delta != 0 ) { -// uint8_t* loc = pageStart + pageOffset; -// uintptr_t rawValue = *((uintptr_t*)loc); -// delta = ((rawValue & deltaMask) >> deltaShift); -// uintptr_t newValue = (rawValue & valueMask); -// if ( newValue != 0 ) { -// newValue += valueAdd; -// newValue += slideAmount; -// } -// *((uintptr_t*)loc) = newValue; -// pageOffset += delta; -// } -// -// -struct dyld_cache_slide_info2 -{ - uint32_t version; // currently 2 - uint32_t page_size; // currently 4096 (may also be 16384) - uint32_t page_starts_offset; - uint32_t page_starts_count; - uint32_t page_extras_offset; - uint32_t page_extras_count; - uint64_t delta_mask; // which (contiguous) set of bits contains the delta to the next rebase location - uint64_t value_add; - //uint16_t page_starts[page_starts_count]; - //uint16_t page_extras[page_extras_count]; -}; -#define DYLD_CACHE_SLIDE_PAGE_ATTRS 0xC000 // high bits of uint16_t are flags -#define DYLD_CACHE_SLIDE_PAGE_ATTR_EXTRA 0x8000 // index is into extras array (not starts array) -#define DYLD_CACHE_SLIDE_PAGE_ATTR_NO_REBASE 0x4000 // page has no rebasing -#define DYLD_CACHE_SLIDE_PAGE_ATTR_END 0x8000 // last chain entry for page - - - -// The version 3 of the slide info uses a different compression scheme. Since -// only interior pointers (pointers that point within the cache) are rebased -// (slid), we know the possible range of the pointers and thus know there are -// unused bits in each pointer. We use those bits to form a linked list of -// locations needing rebasing in each page. -// -// Definitions: -// -// pageIndex = (pageAddress - startOfAllDataAddress)/info->page_size -// pageStarts[] = info + info->page_starts_offset -// -// There are two cases: -// -// 1) pageStarts[pageIndex] == DYLD_CACHE_SLIDE_V3_PAGE_ATTR_NO_REBASE -// The page contains no values that need rebasing. -// -// 2) otherwise... -// All rebase locations are in one linked list. The offset of the first -// rebase location in the page is pageStarts[pageIndex]. -// -// A pointer is one of of the variants in dyld_cache_slide_pointer3 -// -// The code for processing a linked list (chain) is: -// -// uint32_t delta = pageStarts[pageIndex]; -// dyld_cache_slide_pointer3* loc = pageStart; -// do { -// loc += delta; -// delta = loc->offsetToNextPointer; -// if ( loc->auth.authenticated ) { -// newValue = loc->offsetFromSharedCacheBase + results->slide + auth_value_add; -// newValue = sign_using_the_various_bits(newValue); -// } -// else { -// uint64_t value51 = loc->pointerValue; -// uint64_t top8Bits = value51 & 0x0007F80000000000ULL; -// uint64_t bottom43Bits = value51 & 0x000007FFFFFFFFFFULL; -// uint64_t targetValue = ( top8Bits << 13 ) | bottom43Bits; -// newValue = targetValue + results->slide; -// } -// loc->raw = newValue; -// } while (delta != 0); -// -// -struct dyld_cache_slide_info3 -{ - uint32_t version; // currently 3 - uint32_t page_size; // currently 4096 (may also be 16384) - uint32_t page_starts_count; - uint64_t auth_value_add; - uint16_t page_starts[/* page_starts_count */]; -}; - -#define DYLD_CACHE_SLIDE_V3_PAGE_ATTR_NO_REBASE 0xFFFF // page has no rebasing - -union dyld_cache_slide_pointer3 -{ - uint64_t raw; - struct { - uint64_t pointerValue : 51, - offsetToNextPointer : 11, - unused : 2; - } plain; - - struct { - uint64_t offsetFromSharedCacheBase : 32, - diversityData : 16, - hasAddressDiversity : 1, - key : 2, - offsetToNextPointer : 11, - unused : 1, - authenticated : 1; // = 1; - } auth; -}; - - - -// The version 4 of the slide info is optimized for 32-bit caches up to 1GB. -// Since only interior pointers (pointers that point within the cache) are rebased -// (slid), we know the possible range of the pointers takes 30 bits. That -// gives us two bits to use to chain to the next rebase. -// -// Definitions: -// -// pageIndex = (pageAddress - startOfAllDataAddress)/info->page_size -// pageStarts[] = info + info->page_starts_offset -// pageExtras[] = info + info->page_extras_offset -// valueMask = ~(info->delta_mask) -// deltaShift = __builtin_ctzll(info->delta_mask) - 2 -// -// There are three cases: -// -// 1) pageStarts[pageIndex] == DYLD_CACHE_SLIDE4_PAGE_NO_REBASE -// The page contains no values that need rebasing. -// -// 2) (pageStarts[pageIndex] & DYLD_CACHE_SLIDE4_PAGE_USE_EXTRA) == 0 -// All rebase locations are in one linked list. The offset of the first -// rebase location in the page is pageStarts[pageIndex] * 4. -// -// 3) pageStarts[pageIndex] & DYLD_CACHE_SLIDE4_PAGE_USE_EXTRA -// Multiple chains are needed for all rebase locations in a page. -// The pagesExtras array contains 2 or more entries each of which is the -// start of a new chain in the page. The first is at: -// extrasStartIndex = (pageStarts[pageIndex] & DYLD_CACHE_SLIDE4_PAGE_INDEX) -// The next is at extrasStartIndex+1. The last is denoted by -// having the high bit (DYLD_CACHE_SLIDE4_PAGE_EXTRA_END) of the pageExtras[]. -// -// For 32-bit architectures, there are only two bits free (the two most -// significant bits). To extract the delta, you must first subtract value_add -// from the pointer value, then AND with delta_mask, then shift by deltaShift. -// That still leaves a maximum delta to the next rebase location of 12 bytes. -// To reduce the number or chains needed, an optimization was added. Turns -// most of the non-rebased data are small values and can be co-opt'ed into -// being used in the chain. The can be done because nothing -// in the shared cache should point to the first 64KB which are in the shared -// cache header information. So if the resulting pointer points to the -// start of the cache +/-32KB, then it is actually a small number that should -// not be rebased, but just reconstituted. -// -// The code for processing a linked list (chain) is: -// -// uint32_t delta = 1; -// while ( delta != 0 ) { -// uint8_t* loc = pageStart + pageOffset; -// uint32_t rawValue = *((uint32_t*)loc); -// delta = ((rawValue & deltaMask) >> deltaShift); -// uintptr_t newValue = (rawValue & valueMask); -// if ( (newValue & 0xFFFF8000) == 0 ) { -// // small positive non-pointer, use as-is -// } -// else if ( (newValue & 0x3FFF8000) == 0x3FFF8000 ) { -// // small negative non-pointer -// newValue |= 0xC0000000; -// } -// else { -// // pointer that needs rebasing -// newValue += valueAdd; -// newValue += slideAmount; -// } -// *((uint32_t*)loc) = newValue; -// pageOffset += delta; -// } -// -// -struct dyld_cache_slide_info4 -{ - uint32_t version; // currently 4 - uint32_t page_size; // currently 4096 (may also be 16384) - uint32_t page_starts_offset; - uint32_t page_starts_count; - uint32_t page_extras_offset; - uint32_t page_extras_count; - uint64_t delta_mask; // which (contiguous) set of bits contains the delta to the next rebase location (0xC0000000) - uint64_t value_add; // base address of cache - //uint16_t page_starts[page_starts_count]; - //uint16_t page_extras[page_extras_count]; -}; -#define DYLD_CACHE_SLIDE4_PAGE_NO_REBASE 0xFFFF // page has no rebasing -#define DYLD_CACHE_SLIDE4_PAGE_INDEX 0x7FFF // mask of page_starts[] values -#define DYLD_CACHE_SLIDE4_PAGE_USE_EXTRA 0x8000 // index is into extras array (not a chain start offset) -#define DYLD_CACHE_SLIDE4_PAGE_EXTRA_END 0x8000 // last chain entry for page - - - - -struct dyld_cache_local_symbols_info -{ - uint32_t nlistOffset; // offset into this chunk of nlist entries - uint32_t nlistCount; // count of nlist entries - uint32_t stringsOffset; // offset into this chunk of string pool - uint32_t stringsSize; // byte count of string pool - uint32_t entriesOffset; // offset into this chunk of array of dyld_cache_local_symbols_entry - uint32_t entriesCount; // number of elements in dyld_cache_local_symbols_entry array -}; - -struct dyld_cache_local_symbols_entry -{ - uint32_t dylibOffset; // offset in cache file of start of dylib - uint32_t nlistStartIndex; // start index of locals for this dylib - uint32_t nlistCount; // number of local symbols for this dylib -}; - -struct dyld_cache_patch_info -{ - uint64_t patchTableArrayAddr; // (unslid) address of array for dyld_cache_image_patches for each image - uint64_t patchTableArrayCount; // count of patch table entries - uint64_t patchExportArrayAddr; // (unslid) address of array for patch exports for each image - uint64_t patchExportArrayCount; // count of patch exports entries - uint64_t patchLocationArrayAddr; // (unslid) address of array for patch locations for each patch - uint64_t patchLocationArrayCount;// count of patch location entries - uint64_t patchExportNamesAddr; // blob of strings of export names for patches - uint64_t patchExportNamesSize; // size of string blob of export names for patches -}; - -struct dyld_cache_image_patches -{ - uint32_t patchExportsStartIndex; - uint32_t patchExportsCount; -}; - -struct dyld_cache_patchable_export -{ - uint32_t cacheOffsetOfImpl; - uint32_t patchLocationsStartIndex; - uint32_t patchLocationsCount; - uint32_t exportNameOffset; -}; - -struct dyld_cache_patchable_location -{ - uint64_t cacheOffset : 32, - high7 : 7, - addend : 5, // 0..31 - authenticated : 1, - usesAddressDiversity : 1, - key : 2, - discriminator : 16; -}; - - -// This is the location of the macOS shared cache on macOS 11.0 and later -#define MACOSX_MRM_DYLD_SHARED_CACHE_DIR "/System/Library/dyld/" - -// This is old define for the old location of the dyld cache -#define MACOSX_DYLD_SHARED_CACHE_DIR MACOSX_MRM_DYLD_SHARED_CACHE_DIR - -#define IPHONE_DYLD_SHARED_CACHE_DIR "/System/Library/Caches/com.apple.dyld/" -#if !TARGET_OS_SIMULATOR -#define DYLD_SHARED_CACHE_BASE_NAME "dyld_shared_cache_" -#else -#define DYLD_SHARED_CACHE_BASE_NAME "dyld_sim_shared_cache_" -#endif -#define DYLD_SHARED_CACHE_DEVELOPMENT_EXT ".development" - -static const uint64_t kDyldSharedCacheTypeDevelopment = 0; -static const uint64_t kDyldSharedCacheTypeProduction = 1; - - - - -#endif // __DYLD_CACHE_FORMAT__ - - diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/shared_cache_internal.h b/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/shared_cache_internal.h deleted file mode 100644 index 9facadf..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/shared_cache_internal.h +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include -#include - -#if defined(__LP64__) -typedef struct mach_header_64 mach_header_t; -typedef struct segment_command_64 segment_command_t; -typedef struct section_64 section_t; -typedef struct nlist_64 nlist_t; -#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT_64 -#else -typedef struct mach_header mach_header_t; -typedef struct segment_command segment_command_t; -typedef struct section section_t; -typedef struct nlist nlist_t; -#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT -#endif - -#if __i386__ -#define ARCH_NAME "i386" -#define ARCH_CACHE_MAGIC "dyld_v1 i386" -#elif __x86_64__ -#define ARCH_NAME "x86_64" -#define ARCH_CACHE_MAGIC "dyld_v1 x86_64" -#define ARCH_NAME_H "x86_64h" -#define ARCH_CACHE_MAGIC_H "dyld_v1 x86_64h" -#elif __ARM_ARCH_7K__ -#define ARCH_NAME "armv7k" -#define ARCH_CACHE_MAGIC "dyld_v1 armv7k" -#elif __ARM_ARCH_7A__ -#define ARCH_NAME "armv7" -#define ARCH_CACHE_MAGIC "dyld_v1 armv7" -#elif __ARM_ARCH_7S__ -#define ARCH_NAME "armv7s" -#define ARCH_CACHE_MAGIC "dyld_v1 armv7s" -#elif __arm64e__ -#define ARCH_NAME "arm64e" -#define ARCH_CACHE_MAGIC "dyld_v1 arm64e" -#elif __arm64__ -#if __LP64__ -#define ARCH_NAME "arm64" -#define ARCH_CACHE_MAGIC "dyld_v1 arm64" -#else -#define ARCH_NAME "arm64_32" -#define ARCH_CACHE_MAGIC "dyld_v1arm64_32" -#endif -#endif - -typedef uintptr_t addr_t; - -typedef struct shared_cache_ctx { - struct dyld_cache_header *runtime_shared_cache; - struct dyld_cache_header *mmap_shared_cache; - - uintptr_t runtime_slide; - - struct dyld_cache_local_symbols_info *local_symbols_info; - struct dyld_cache_local_symbols_entry *local_symbols_entries; - - nlist_t *symtab; - char *strtab; - -} shared_cache_ctx_t; - -int shared_cache_ctx_init(shared_cache_ctx_t *ctx); - -bool shared_cache_is_contain(shared_cache_ctx_t *ctx, addr_t addr, size_t length); - -int shared_cache_get_symbol_table(shared_cache_ctx_t *ctx, mach_header_t *image_header, nlist_t **out_symtab, - uint32_t *out_symtab_count, char **out_strtab); diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/pe/dobby_symbol_resolver.cc b/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/pe/dobby_symbol_resolver.cc deleted file mode 100644 index 65920a0..0000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/pe/dobby_symbol_resolver.cc +++ /dev/null @@ -1,26 +0,0 @@ -#include "SymbolResolver/dobby_symbol_resolver.h" -#include "common_header.h" - -#include - -#include -#include - -#include "PlatformUtil/ProcessRuntimeUtility.h" - -#include - -#undef LOG_TAG -#define LOG_TAG "DobbySymbolResolver" - -PUBLIC void *DobbySymbolResolver(const char *image_name, const char *symbol_name_pattern) { - void *result = NULL; - - HMODULE hMod = LoadLibraryExA(image_name, NULL, DONT_RESOLVE_DLL_REFERENCES); - result = GetProcAddress(hMod, symbol_name_pattern); - if (result) - return result; - - //result = resolve_elf_internal_symbol(image_name, symbol_name_pattern); - return result; -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/cmake/Macros.cmake b/app/src/main/cpp/Dobby/cmake/Macros.cmake deleted file mode 100644 index 5774bef..0000000 --- a/app/src/main/cpp/Dobby/cmake/Macros.cmake +++ /dev/null @@ -1,3 +0,0 @@ -macro(SET_OPTION option value) - set(${option} ${value} CACHE INTERNAL "" FORCE) -endmacro() \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/cmake/Util.cmake b/app/src/main/cpp/Dobby/cmake/Util.cmake deleted file mode 100644 index 6a722a2..0000000 --- a/app/src/main/cpp/Dobby/cmake/Util.cmake +++ /dev/null @@ -1,19 +0,0 @@ -# Check files list exist -function(check_files_exist CHECK_FILES) - foreach(file ${CHECK_FILES}) - if(NOT EXISTS "${file}") - message(FATAL_ERROR "${file} NOT EXISTS!") - endif() - endforeach() -endfunction(check_files_exist CHECK_FILES) - -# Search suffix files -function(search_suffix_files suffix INPUT_VARIABLE OUTPUT_VARIABLE) - set(ResultFiles ) - foreach(filePath ${${INPUT_VARIABLE}}) - # message(STATUS "[*] searching *.${suffix} from ${filePath}") - file(GLOB files ${filePath}/*.${suffix}) - set(ResultFiles ${ResultFiles} ${files}) - endforeach() - set(${OUTPUT_VARIABLE} ${ResultFiles} PARENT_SCOPE) -endfunction() diff --git a/app/src/main/cpp/Dobby/cmake/auto_source_group.cmake b/app/src/main/cpp/Dobby/cmake/auto_source_group.cmake deleted file mode 100644 index f563836..0000000 --- a/app/src/main/cpp/Dobby/cmake/auto_source_group.cmake +++ /dev/null @@ -1,32 +0,0 @@ -function (auto_source_group _folder _base _pattern) - if (ARGC GREATER 3) - set(_exclude ${ARGN}) - else () - set(_exclude) - endif () - file (GLOB _files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/ ${_folder}/*) - set (folder_files) - foreach (_fname ${_files}) - if (IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${_fname}) - auto_source_group ("${_fname}" "${_base}" "${_pattern}" "${_exclude}") - elseif (_fname MATCHES ${_pattern}) - if(_exclude) - if (NOT _fname MATCHES ${_exclude}) - set(folder_files ${folder_files} ${_fname}) - endif () - else () - set(folder_files ${folder_files} ${_fname}) - endif () - endif () - endforeach () - - string(REPLACE "./" "" _folder2 ${_folder}) - string(REPLACE "/" "\\" _folder2 ${_folder2}) - if (_folder2 STREQUAL ".") - source_group(${_base} FILES ${folder_files}) - else () - source_group(${_base}\\${_folder2} FILES ${folder_files}) - endif () - - set(AUTO_FILES_RESULT ${AUTO_FILES_RESULT} ${folder_files} PARENT_SCOPE) -endfunction () \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/cmake/build_environment_check.cmake b/app/src/main/cpp/Dobby/cmake/build_environment_check.cmake deleted file mode 100644 index 9e7a67f..0000000 --- a/app/src/main/cpp/Dobby/cmake/build_environment_check.cmake +++ /dev/null @@ -1,86 +0,0 @@ -if(__BUILD_ENVIRONMENT_CHECK) - return() -endif() -set(__BUILD_ENVIRONMENT_CHECK TRUE) - -message(STATUS "") -message(STATUS "********* build environment check ***********") - - -# The Compiler ID -if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") - set(COMPILER.Clang 1) -elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - set(COMPILER.Gcc 1) -elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") -elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") - set(COMPILER.MSVC 1) -else() - message (FATAL_ERROR "Compiler ${CMAKE_CXX_COMPILER_ID} not configured") -endif() -message(STATUS "\tCompiler: \t ${CMAKE_CXX_COMPILER_ID}") - -if(MSVC) - string(TOLOWER ${MSVC_CXX_ARCHITECTURE_ID} CMAKE_SYSTEM_PROCESSOR) - set(CMAKE_SYSTEM_PROCESSOR ${MSVC_CXX_ARCHITECTURE_ID}) -endif() - - -if(BUILDING_SILICON) - set(CMAKE_SYSTEM_PROCESSOR ${CMAKE_OSX_ARCHITECTURES}) -endif() - -string(TOLOWER ${CMAKE_SYSTEM_PROCESSOR} CMAKE_SYSTEM_PROCESSOR) - -# The Processor -if(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*|x64.*") - set(PROCESSOR.X86_64 1) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i686.*|i386.*|x86.*|amd64.*|AMD64.*") - set(PROCESSOR.X86 1) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm64.*") - set(PROCESSOR.AARCH64 1) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*)") - set(PROCESSOR.AARCH64 1) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm.*|ARM.*)") - set(PROCESSOR.ARM 1) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64le") - message(STATUS "NOT SUPPORT ${CMAKE_SYSTEM_PROCESSOR}") - set(PROCESSOR.PPC64LE 1) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64") - message(STATUS "NOT SUPPORT ${CMAKE_SYSTEM_PROCESSOR}") - set(PROCESSOR.PPC64 1) -else() - message (FATAL_ERROR "Processor ${CMAKE_SYSTEM_PROCESSOR} not configured") -endif() -message(STATUS "\tProcessor:\t ${CMAKE_SYSTEM_PROCESSOR}") - -# The System -if(CMAKE_SYSTEM_NAME MATCHES "^Android") - set(SYSTEM.Android 1) -elseif(CMAKE_SYSTEM_NAME MATCHES "^Windows") - set(SYSTEM.Windows 1) -elseif(CMAKE_SYSTEM_NAME MATCHES "^Linux") - set(SYSTEM.Linux 1) -elseif(CMAKE_SYSTEM_NAME MATCHES "^iOS") - set(SYSTEM.iOS 1) - set(SYSTEM.Darwin 1) -elseif(CMAKE_SYSTEM_NAME MATCHES "^macOS") - set(SYSTEM.macOS 1) - set(SYSTEM.Darwin 1) -elseif(CMAKE_SYSTEM_NAME MATCHES "^Darwin") - if(PROCESSOR.AARCH64 OR PROCESSOR.ARM) - set(CMAKE_SYSTEM_NAME "iOS or Silicon") - set(SYSTEM.iOS 1) - set(SYSTEM.Silicon 1) - elseif(PROCESSOR.X86 OR PROCESSOR.X86_64) - set(CMAKE_SYSTEM_NAME "macOS") - set(SYSTEM.macOS 1) - endif() - set(SYSTEM.Darwin 1) -else() - message (FATAL_ERROR "System ${CMAKE_SYSTEM_NAME} not configured") -endif() -message(STATUS "\tSystem: \t ${CMAKE_SYSTEM_NAME}") - -message(STATUS "***************************************") -message(STATUS "") diff --git a/app/src/main/cpp/Dobby/cmake/compiler_and_linker.cmake b/app/src/main/cpp/Dobby/cmake/compiler_and_linker.cmake deleted file mode 100644 index b45a229..0000000 --- a/app/src/main/cpp/Dobby/cmake/compiler_and_linker.cmake +++ /dev/null @@ -1,53 +0,0 @@ -# :< You Shall Not Pass! -if (0) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror") -endif () - -set(linker_flags "") -if (NOT DOBBY_DEBUG) - set(linker_flags "${linker_flags} -Wl,-x -Wl,-S") -endif () - -if (SYSTEM.Darwin) - # set(compiler_flags "${compiler_flags} -nostdinc++") -elseif (SYSTEM.Android) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fomit-frame-pointer") - if (NOT DOBBY_DEBUG) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections") - set(linker_flags "${linker_flags} -Wl,--gc-sections -Wl,--exclude-libs,ALL") - endif () -elseif (SYSTEM.Linux) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") - if (COMPILER.Clang) - if (PROCESSOR.ARM) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --target=armv7-unknown-linux-gnueabihf") - elseif (PROCESSOR.ARM64) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --target=aarch64-unknown-linux-gnu") - elseif (PROCESSOR.X86) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --target=i686-unknown-linux-gnu") - elseif (PROCESSOR.X86_64) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --target=x86_64-unknown-linux-gnu") - endif () - endif () -elseif (SYSTEM.Windows) -endif () - -if (NOT DOBBY_DEBUG) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-rtti -fvisibility=hidden -fvisibility-inlines-hidden") -endif () - -if (PROCESSOR.ARM) - set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -arch armv7 -x assembler-with-cpp") -elseif (PROCESSOR.AARCH64) - set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -arch arm64 -x assembler-with-cpp") -endif () - -# sync cxx with c flags -# set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_CXX_FLAGS}") - -message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}") -message(STATUS "CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}") -message(STATUS "CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}") -message(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") -message(STATUS "CMAKE_SHARED_LINKER_FLAGS: ${CMAKE_SHARED_LINKER_FLAGS}") diff --git a/app/src/main/cpp/Dobby/cmake/dobby.xcode.source.cmake b/app/src/main/cpp/Dobby/cmake/dobby.xcode.source.cmake deleted file mode 100644 index 64fb0e0..0000000 --- a/app/src/main/cpp/Dobby/cmake/dobby.xcode.source.cmake +++ /dev/null @@ -1,94 +0,0 @@ -set(dobby.SOURCE_FILE_LIST - # cpu - source/core/arch/CpuFeature.cc - source/core/arch/CpuRegister.cc - - # cpu - x86 - source/core/arch/x86/cpu-x86.cc - - # assembler - source/core/assembler/assembler.cc - source/core/assembler/assembler-arm.cc - source/core/assembler/assembler-arm64.cc - source/core/assembler/assembler-ia32.cc - source/core/assembler/assembler-x64.cc - - # codegen - source/core/codegen/codegen-arm.cc - source/core/codegen/codegen-arm64.cc - source/core/codegen/codegen-ia32.cc - source/core/codegen/codegen-x64.cc - - # executable memory - code buffer - source/MemoryAllocator/CodeBuffer/CodeBufferBase.cc - source/MemoryAllocator/CodeBuffer/code-buffer-x86.cc - - # executable memory - source/MemoryAllocator/AssemblyCodeBuilder.cc - source/MemoryAllocator/MemoryArena.cc - - # instruction relocation - source/InstructionRelocation/arm/InstructionRelocationARM.cc - source/InstructionRelocation/arm64/InstructionRelocationARM64.cc - source/InstructionRelocation/x86/X86InstructionRelocation.cc - source/InstructionRelocation/x64/InstructionRelocationX64.cc - - source/InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.c - - # intercept routing - source/InterceptRouting/InterceptRouting.cpp - - # intercept routing trampoline - source/TrampolineBridge/Trampoline/arm/trampoline-arm.cc - source/TrampolineBridge/Trampoline/arm64/trampoline-arm64.cc - source/TrampolineBridge/Trampoline/x86/trampoline-x86.cc - source/TrampolineBridge/Trampoline/x64/trampoline-x64.cc - - # intercept routing plugin (buildin) - source/InterceptRouting/Routing/FunctionInlineReplace/function-inline-replace.cc - source/InterceptRouting/Routing/FunctionInlineReplace/FunctionInlineReplaceExport.cc - - # plugin register - source/InterceptRouting/RoutingPlugin/RoutingPlugin.cc - - # unified interface - - # platform util - source/UserMode/PlatformUtil/${platform2}/ProcessRuntimeUtility.cc - - # user mode - platform interface - source/UserMode/UnifiedInterface/platform-${platform1}.cc - - # user mode - executable memory - source/UserMode/ExecMemory/code-patch-tool-${platform1}.cc - source/UserMode/ExecMemory/clear-cache-tool-all.c - - # main - source/dobby.cpp - source/Interceptor.cpp - source/InterceptEntry.cpp - ) - -if(FunctionWrapper OR DynamicBinaryInstrument) - set(dobby.SOURCE_FILE_LIST ${dobby.SOURCE_FILE_LIST} - # closure trampoline bridge - source/TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.cc - - source/TrampolineBridge/ClosureTrampolineBridge/arm/helper-arm.cc - source/TrampolineBridge/ClosureTrampolineBridge/arm/closure-bridge-arm.cc - source/TrampolineBridge/ClosureTrampolineBridge/arm/ClosureTrampolineARM.cc - - source/TrampolineBridge/ClosureTrampolineBridge/arm64/helper-arm64.cc - source/TrampolineBridge/ClosureTrampolineBridge/arm64/closure-bridge-arm64.cc - source/TrampolineBridge/ClosureTrampolineBridge/arm64/ClosureTrampolineARM64.cc - - source/TrampolineBridge/ClosureTrampolineBridge/x64/helper-x64.cc - source/TrampolineBridge/ClosureTrampolineBridge/x64/closure-bridge-x64.cc - source/TrampolineBridge/ClosureTrampolineBridge/x64/ClosureTrampolineX64.cc - - # user mode - multi thread support - source/UserMode/MultiThreadSupport/ThreadSupport.cpp - source/UserMode/Thread/PlatformThread.cc - source/UserMode/Thread/platform-thread-${platform1}.cc - ) -endif() \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/cmake/platform/platform-darwin.cmake b/app/src/main/cpp/Dobby/cmake/platform/platform-darwin.cmake deleted file mode 100644 index 4ea0af6..0000000 --- a/app/src/main/cpp/Dobby/cmake/platform/platform-darwin.cmake +++ /dev/null @@ -1,30 +0,0 @@ -# set(CMAKE_BUILD_WITH_INSTALL_NAME_DIR TRUE) -set(CMAKE_INSTALL_NAME_DIR "@rpath") -set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,") -add_library(DobbyX ${DOBBY_LIBRARY_TYPE} ${dobby.HEADER_FILE_LIST} ${dobby.SOURCE_FILE_LIST} ${logging.SOURCE_FILE_LIST} ${misc_helper.SOURCE_FILE_LIST} ${dobby.plugin.SOURCE_FILE_LIST}) - -set_target_properties(DobbyX - PROPERTIES - LINK_FLAGS "${linker_flags}" - COMPILE_FLAGS "${compiler_flags}" - ) - -# set framework property -set_target_properties(DobbyX PROPERTIES - FRAMEWORK TRUE - FRAMEWORK_VERSION A - MACOSX_FRAMEWORK_IDENTIFIER "com.dobby.dobby" - # MACOSX_FRAMEWORK_INFO_PLIST Info.plist - VERSION 1.0.0 # current version - SOVERSION 1.0.0 # compatibility version - PUBLIC_HEADER include/dobby.h - XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Development" - ) - -if ((SYSTEM.Darwin AND BUILDING_PLUGIN) AND (NOT BUILDING_KERNEL)) -add_subdirectory(builtin-plugin/Dyld2HideLibrary) -add_subdirectory(builtin-plugin/ObjcRuntimeHook) -if (PROCESSOR.AARCH64) - add_subdirectory(builtin-plugin/SupervisorCallMonitor) -endif () -endif() \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/cmake/xcode_generator_helper.cmake b/app/src/main/cpp/Dobby/cmake/xcode_generator_helper.cmake deleted file mode 100644 index 243593d..0000000 --- a/app/src/main/cpp/Dobby/cmake/xcode_generator_helper.cmake +++ /dev/null @@ -1,9 +0,0 @@ -if(CMAKE_GENERATOR STREQUAL Xcode) - message(STATUS "[*] Detect Xcode Project") - set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/build/Debug) - set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/build/Release) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/build/Debug) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/build/Release) - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/build/Debug) - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/build/Release) -endif() \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/docs/compile.md b/app/src/main/cpp/Dobby/docs/compile.md deleted file mode 100644 index 79ded1e..0000000 --- a/app/src/main/cpp/Dobby/docs/compile.md +++ /dev/null @@ -1,90 +0,0 @@ -# Build - -## CMake build options - -``` -option(DOBBY_GENERATE_SHARED "Build shared library" ON) - -option(DOBBY_DEBUG "Enable debug logging" OFF) - -option(NearBranch "Enable near branch trampoline" ON) - -option(FullFloatingPointRegisterPack "Save and pack all floating-point registers" OFF) - -option(Plugin.SymbolResolver "Enable symbol resolver" ON) - -option(Plugin.ImportTableReplace "Enable import table replace " OFF) - -option(Plugin.Android.BionicLinkerUtil "Enable android bionic linker util" OFF) - -option(BUILD_EXAMPLE "Build example" OFF) - -option(BUILD_TEST "Build test" OFF) -``` - -## Build with `scripts/platform_builder.py` - -#### Build for iphoneos - -```shell -python3 scripts/platform_builder.py --platform=iphoneos --arch=all -``` - -#### Build for macos - -``` -python3 scripts/platform_builder.py --platform=macos --arch=all -``` - -#### Build for linux - -``` -# prepare and download cmake/llvm -sh scripts/setup_linux_cross_compile.sh -python3 scripts/platform_builder.py --platform=linux --arch=all --cmake_dir=$HOME/opt/cmake-3.20.2 --llvm_dir=$HOME/opt/llvm-14.0.0 -``` - -#### Build for android - -``` -# prepare and download cmake/llvm/ndk -sh scripts/setup_linux_cross_compile.sh -sh scripts/setup_linux_cross_compile.sh -python3 scripts/platform_builder.py --platform=linux --arch=all --cmake_dir=$HOME/opt/cmake-3.20.2 --llvm_dir=$HOME/opt/llvm-14.0.0 --android_ndk_dir=$HOME/opt/ndk-r25b -``` - -## Build with CMake - -#### Build for host - -```shell -cd Dobby && mkdir cmake-build-host && cd cmake-build-host -cmake .. -make -j4 -``` - -## Build with Android Studio CMake - -``` -if(NOT TARGET dobby) -set(DOBBY_DIR /Users/jmpews/Workspace/Project.wrk/Dobby) -macro(SET_OPTION option value) - set(${option} ${value} CACHE INTERNAL "" FORCE) -endmacro() -SET_OPTION(DOBBY_DEBUG OFF) -SET_OPTION(DOBBY_GENERATE_SHARED OFF) -add_subdirectory(${DOBBY_DIR} dobby) -get_property(DOBBY_INCLUDE_DIRECTORIES - TARGET dobby - PROPERTY INCLUDE_DIRECTORIES) -include_directories( - . - ${DOBBY_INCLUDE_DIRECTORIES} - $ -) -endif() - -add_library(native-lib SHARED - ${DOBBY_DIR}/examples/socket_example.cc - native-lib.cpp) -``` diff --git a/app/src/main/cpp/Dobby/examples/CMakeLists.txt b/app/src/main/cpp/Dobby/examples/CMakeLists.txt deleted file mode 100644 index 71e8243..0000000 --- a/app/src/main/cpp/Dobby/examples/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -add_executable(socket_example - main.cc - socket_example.cc - ) - -target_link_libraries(socket_example - dobby - ) - - -add_library(socket_example_x SHARED - socket_example.cc - ) - -target_link_libraries(socket_example_x - dobby - ) \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/examples/main.cc b/app/src/main/cpp/Dobby/examples/main.cc deleted file mode 100644 index 33eeddf..0000000 --- a/app/src/main/cpp/Dobby/examples/main.cc +++ /dev/null @@ -1,14 +0,0 @@ -#include -#include -#include -#include -#include -#include - -int main(int argc, char const *argv[]) { - - std::cout << "Start..." << std::endl; - - sleep(100); - return 0; -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/examples/socket_example.cc b/app/src/main/cpp/Dobby/examples/socket_example.cc deleted file mode 100644 index 4be7468..0000000 --- a/app/src/main/cpp/Dobby/examples/socket_example.cc +++ /dev/null @@ -1,212 +0,0 @@ -#include "dobby.h" - -#include "logging/logging.h" - -#include -#include -#include -#include -#include - -#include -#include -#include - -std::map *func_map; - -// clang-format off -const char *func_array[] = { -// "__loader_dlopen", - - "dlsym", - "dlclose", - - "open", - "write", - "read", - "close", - - "socket", - "connect", - "bind", - "listen", - "accept", - "send", - "recv", - - // "pthread_create" -}; - -const char *func_short_array[] = { - "accept", -}; -// clang-format on - -#define pac_strip(symbol) -#if defined(__APPLE__) && __arm64e__ -#if __has_feature(ptrauth_calls) -#define pac_strip(symbol) -//#define pac_strip(symbol) *(void **)&symbol = (void *)ptrauth_sign_unauthenticated((void *)symbol, ptrauth_key_asia, 0) -#endif -#endif - -#define install_hook(name, fn_ret_t, fn_args_t...) \ - fn_ret_t (*orig_##name)(fn_args_t); \ - fn_ret_t fake_##name(fn_args_t); \ - /* __attribute__((constructor)) */ static void install_hook_##name() { \ - void *sym_addr = DobbySymbolResolver(NULL, #name); \ - DobbyHook(sym_addr, (dobby_dummy_func_t)fake_##name, (dobby_dummy_func_t *)&orig_##name); \ - pac_strip(orig_##name); \ - printf("install hook %s:%p:%p\n", #name, sym_addr, orig_##name); \ - } \ - fn_ret_t fake_##name(fn_args_t) - -install_hook(pthread_create, int, pthread_t *thread, const pthread_attr_t *attrs, void *(*start_routine)(void *), - void *arg, unsigned int create_flags) { - LOG(1, "pthread_create: %p", start_routine); - return orig_pthread_create(thread, attrs, start_routine, arg, create_flags); -} - -void common_handler(void *address, DobbyRegisterContext *ctx) { - auto iter = func_map->find(address); - if (iter != func_map->end()) { - LOG(1, "func %s:%p invoke", iter->second, iter->first); - } -} - -uint64_t socket_demo_server(void *ctx); - -uint64_t socket_demo_client(void *ctx); - -#if 1 - -__attribute__((constructor)) static void ctor() { - void *func = NULL; - log_set_level(0); - - func_map = new std::map(); - for (int i = 0; i < sizeof(func_array) / sizeof(char *); ++i) { - func = DobbySymbolResolver(NULL, func_array[i]); - if (func == NULL) { - LOG(1, "func %s not resolve", func_array[i]); - continue; - } - func_map->insert(std::pair(func, func_array[i])); - } - - for (auto iter = func_map->begin(), e = func_map->end(); iter != e; iter++) { - bool is_short = false; - for (int i = 0; i < sizeof(func_short_array) / sizeof(char *); ++i) { - if (strcmp(func_short_array[i], iter->second) == 0) { - is_short = true; - break; - } - } - if (is_short) { - dobby_enable_near_branch_trampoline(); - DobbyInstrument(iter->first, common_handler); - dobby_disable_near_branch_trampoline(); - } else { - DobbyInstrument(iter->first, common_handler); - } - } - -#if defined(__APPLE__) - // DobbyImportTableReplace(NULL, "_pthread_create", (void *)fake_pthread_create, (void **)&orig_pthread_create); -#endif - - install_hook_pthread_create(); - - pthread_t socket_server; - pthread_create(&socket_server, NULL, (void *(*)(void *))socket_demo_server, NULL); - - usleep(10000); - pthread_t socket_client; - pthread_create(&socket_client, NULL, (void *(*)(void *))socket_demo_client, NULL); - - // pthread_join(socket_client, 0); - // pthread_join(socket_server, 0); -} - -#include -#include -#include - -#define PORT 49494 - -uint64_t socket_demo_server(void *ctx) { - int server_fd, new_socket; - struct sockaddr_in address; - int opt = 1; - int addrlen = sizeof(address); - char buffer[1024] = {0}; - char *hello = "Hello from server"; - - if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { - ERROR_LOG("socket failed: %s", strerror(errno)); - return -1; - } - - if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) { - ERROR_LOG("setsockopt: %s", strerror(errno)); - return -1; - } - - address.sin_family = AF_INET; - address.sin_port = htons(PORT); - address.sin_addr.s_addr = INADDR_ANY; - - if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { - ERROR_LOG("bind failed: %s", strerror(errno)); - return -1; - } - if (listen(server_fd, 3) < 0) { - ERROR_LOG("listen failed: %s", strerror(errno)); - return -1; - } - if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0) { - ERROR_LOG("accept failed: %s", strerror(errno)); - return -1; - } - - int ret = recv(new_socket, buffer, 1024, 0); - LOG(1, "[server] %s", buffer); - - send(new_socket, hello, strlen(hello), 0); - LOG(1, "[server] Hello message sent"); - return 0; -} - -uint64_t socket_demo_client(void *ctx) { - int sock = 0; - struct sockaddr_in serv_addr; - char *hello = "Hello from client"; - char buffer[1024] = {0}; - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - ERROR_LOG("socket failed"); - return -1; - } - - serv_addr.sin_family = AF_INET; - serv_addr.sin_port = htons(PORT); - - // Convert IPv4 and IPv6 addresses from text to binary form - if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) { - ERROR_LOG("inet_pton failed"); - return -1; - } - - if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { - ERROR_LOG("connect failed"); - return -1; - } - - send(sock, hello, strlen(hello), 0); - LOG(1, "[client] Hello message sent"); - - int ret = recv(sock, buffer, 1024, 0); - LOG(1, "[client] %s", buffer); - return 0; -} - -#endif diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/allocator.h b/app/src/main/cpp/Dobby/external/TINYSTL/allocator.h deleted file mode 100644 index 685d98c..0000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/allocator.h +++ /dev/null @@ -1,49 +0,0 @@ -/*- - * Copyright 2012-2018 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYSTL_ALLOCATOR_H -#define TINYSTL_ALLOCATOR_H - -#include - -namespace tinystl { - - struct allocator { - static void* static_allocate(size_t bytes) { - return operator new(bytes); - } - - static void static_deallocate(void* ptr, size_t /*bytes*/) { - operator delete(ptr); - } - }; -} - -#ifndef TINYSTL_ALLOCATOR -# define TINYSTL_ALLOCATOR ::tinystl::allocator -#endif - -#endif diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/buffer.h b/app/src/main/cpp/Dobby/external/TINYSTL/buffer.h deleted file mode 100644 index 7ec5d19..0000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/buffer.h +++ /dev/null @@ -1,310 +0,0 @@ -/*- - * Copyright 2012-2018 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYSTL_BUFFER_H -#define TINYSTL_BUFFER_H - -#include -#include -#include - -namespace tinystl { - - template - struct buffer { - T* first; - T* last; - T* capacity; - }; - - template - static inline void buffer_destroy_range_traits(T* first, T* last, pod_traits) { - for (; first < last; ++first) - first->~T(); - } - - template - static inline void buffer_destroy_range_traits(T*, T*, pod_traits) { - } - - template - static inline void buffer_destroy_range(T* first, T* last) { - buffer_destroy_range_traits(first, last, pod_traits()); - } - - template - static inline void buffer_fill_urange_traits(T* first, T* last, pod_traits) { - for (; first < last; ++first) - new(placeholder(), first) T(); - } - - template - static inline void buffer_fill_urange_traits(T* first, T* last, pod_traits) { - for (; first < last; ++first) - *first = T(); - } - - template - static inline void buffer_fill_urange_traits(T* first, T* last, const T& value, pod_traits) { - for (; first < last; ++first) - new(placeholder(), first) T(value); - } - - template - static inline void buffer_fill_urange_traits(T* first, T* last, const T& value, pod_traits) { - for (; first < last; ++first) - *first = value; - } - - template - static inline void buffer_move_urange_traits(T* dest, T* first, T* last, pod_traits) { - for (T* it = first; it != last; ++it, ++dest) - move_construct(dest, *it); - buffer_destroy_range(first, last); - } - - template - static inline void buffer_move_urange_traits(T* dest, T* first, T* last, pod_traits) { - for (; first != last; ++first, ++dest) - *dest = *first; - } - - template - static inline void buffer_bmove_urange_traits(T* dest, T* first, T* last, pod_traits) { - dest += (last - first); - for (T* it = last; it != first; --it, --dest) { - move_construct(dest - 1, *(it - 1)); - buffer_destroy_range(it - 1, it); - } - } - - template - static inline void buffer_bmove_urange_traits(T* dest, T* first, T* last, pod_traits) { - dest += (last - first); - for (T* it = last; it != first; --it, --dest) - *(dest - 1) = *(it - 1); - } - - template - static inline void buffer_move_urange(T* dest, T* first, T* last) { - buffer_move_urange_traits(dest, first, last, pod_traits()); - } - - template - static inline void buffer_bmove_urange(T* dest, T* first, T* last) { - buffer_bmove_urange_traits(dest, first, last, pod_traits()); - } - - template - static inline void buffer_fill_urange(T* first, T* last) { - buffer_fill_urange_traits(first, last, pod_traits()); - } - - template - static inline void buffer_fill_urange(T* first, T* last, const T& value) { - buffer_fill_urange_traits(first, last, value, pod_traits()); - } - - template - static inline void buffer_init(buffer* b) { - b->first = b->last = b->capacity = 0; - } - - template - static inline void buffer_destroy(buffer* b) { - buffer_destroy_range(b->first, b->last); - Alloc::static_deallocate(b->first, (size_t)((char*)b->capacity - (char*)b->first)); - } - - template - static inline void buffer_reserve(buffer* b, size_t capacity) { - if (b->first + capacity <= b->capacity) - return; - - typedef T* pointer; - const size_t size = (size_t)(b->last - b->first); - pointer newfirst = (pointer)Alloc::static_allocate(sizeof(T) * capacity); - buffer_move_urange(newfirst, b->first, b->last); - Alloc::static_deallocate(b->first, sizeof(T) * capacity); - - b->first = newfirst; - b->last = newfirst + size; - b->capacity = newfirst + capacity; - } - - template - static inline void buffer_resize(buffer* b, size_t size) { - buffer_reserve(b, size); - - buffer_fill_urange(b->last, b->first + size); - buffer_destroy_range(b->first + size, b->last); - b->last = b->first + size; - } - - template - static inline void buffer_resize(buffer* b, size_t size, const T& value) { - buffer_reserve(b, size); - - buffer_fill_urange(b->last, b->first + size, value); - buffer_destroy_range(b->first + size, b->last); - b->last = b->first + size; - } - - template - static inline void buffer_shrink_to_fit(buffer* b) { - if (b->capacity != b->last) { - if (b->last == b->first) { - const size_t capacity = (size_t)(b->capacity - b->first); - Alloc::static_deallocate(b->first, sizeof(T)*capacity); - b->capacity = b->first = b->last = nullptr; - } else { - const size_t capacity = (size_t)(b->capacity - b->first); - const size_t size = (size_t)(b->last - b->first); - T* newfirst = (T*)Alloc::static_allocate(sizeof(T) * size); - buffer_move_urange(newfirst, b->first, b->last); - Alloc::static_deallocate(b->first, sizeof(T) * capacity); - b->first = newfirst; - b->last = newfirst + size; - b->capacity = b->last; - } - } - } - - template - static inline void buffer_clear(buffer* b) { - buffer_destroy_range(b->first, b->last); - b->last = b->first; - } - - template - static inline T* buffer_insert_common(buffer* b, T* where, size_t count) { - const size_t offset = (size_t)(where - b->first); - const size_t newsize = (size_t)((b->last - b->first) + count); - if (b->first + newsize > b->capacity) - buffer_reserve(b, (newsize * 3) / 2); - - where = b->first + offset; - - if (where != b->last) - buffer_bmove_urange(where + count, where, b->last); - - b->last = b->first + newsize; - - return where; - } - - template - static inline void buffer_insert(buffer* b, T* where, const Param* first, const Param* last) { - typedef const char* pointer; - const size_t count = last - first; - const bool frombuf = ((pointer)b->first <= (pointer)first && (pointer)b->last >= (pointer)last); - size_t offset; - if (frombuf) { - offset = (pointer)first - (pointer)b->first; - if ((pointer)where <= (pointer)first) - offset += count * sizeof(T); - where = buffer_insert_common(b, where, count); - first = (Param*)((pointer)b->first + offset); - last = first + count; - } - else { - where = buffer_insert_common(b, where, count); - } - for (; first != last; ++first, ++where) - new(placeholder(), where) T(*first); - } - - template - static inline void buffer_insert(buffer* b, T* where, size_t count) { - where = buffer_insert_common(b, where, count); - for (T* end = where+count; where != end; ++where) - new(placeholder(), where) T(); - } - - template - static inline void buffer_append(buffer* b, const Param* param) { - if (b->capacity != b->last) { - new(placeholder(), b->last) T(*param); - ++b->last; - } else { - buffer_insert(b, b->last, param, param + 1); - } - } - - template - static inline void buffer_append(buffer* b) { - if (b->capacity != b->last) { - new(placeholder(), b->last) T(); - ++b->last; - } else { - buffer_insert(b, b->last, 1); - } - } - - template - static inline T* buffer_erase(buffer* b, T* first, T* last) { - typedef T* pointer; - const size_t count = (last - first); - for (pointer it = last, end = b->last, dest = first; it != end; ++it, ++dest) - move(*dest, *it); - - buffer_destroy_range(b->last - count, b->last); - - b->last -= count; - return first; - } - - template - static inline T* buffer_erase_unordered(buffer* b, T* first, T* last) { - typedef T* pointer; - const size_t count = (last - first); - const size_t tail = (b->last - last); - pointer it = b->last - ((count < tail) ? count : tail); - for (pointer end = b->last, dest = first; it != end; ++it, ++dest) - move(*dest, *it); - - buffer_destroy_range(b->last - count, b->last); - - b->last -= count; - return first; - } - - template - static inline void buffer_swap(buffer* b, buffer* other) { - typedef T* pointer; - const pointer tfirst = b->first, tlast = b->last, tcapacity = b->capacity; - b->first = other->first, b->last = other->last, b->capacity = other->capacity; - other->first = tfirst, other->last = tlast, other->capacity = tcapacity; - } - - template - static inline void buffer_move(buffer* dst, buffer* src) { - dst->first = src->first, dst->last = src->last, dst->capacity = src->capacity; - src->first = src->last = src->capacity = nullptr; - } -} - -#endif //TINYSTL_BUFFER_H diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/hash.h b/app/src/main/cpp/Dobby/external/TINYSTL/hash.h deleted file mode 100644 index c03b326..0000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/hash.h +++ /dev/null @@ -1,53 +0,0 @@ -/*- - * Copyright 2012-2018 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYSTL_STRINGHASH_H -#define TINYSTL_STRINGHASH_H - -#include - -namespace tinystl { - - static inline size_t hash_string(const char* str, size_t len) { - // Implementation of sdbm a public domain string hash from Ozan Yigit - // see: http://www.eecs.harvard.edu/margo/papers/usenix91/paper.ps - - size_t hash = 0; - typedef const char* pointer; - for (pointer it = str, end = str + len; it != end; ++it) - hash = *it + (hash << 6) + (hash << 16) - hash; - - return hash; - } - - template - inline size_t hash(const T& value) { - const size_t asint = (size_t)value; - return hash_string((const char*)&asint, sizeof(asint)); - } -} - -#endif diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/hash_base.h b/app/src/main/cpp/Dobby/external/TINYSTL/hash_base.h deleted file mode 100644 index 30f449b..0000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/hash_base.h +++ /dev/null @@ -1,292 +0,0 @@ -/*- - * Copyright 2012-2018 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYSTL_HASH_BASE_H -#define TINYSTL_HASH_BASE_H - -#include -#include - -namespace tinystl { - - template - struct pair { - pair(); - pair(const pair& other); - pair(pair&& other); - pair(const Key& key, const Value& value); - pair(Key&& key, Value&& value); - - pair& operator=(const pair& other); - pair& operator=(pair&& other); - - Key first; - Value second; - }; - - template - inline pair::pair() { - } - - template - inline pair::pair(const pair& other) - : first(other.first) - , second(other.second) - { - } - - template - inline pair::pair(pair&& other) - : first(static_cast(other.first)) - , second(static_cast(other.second)) - { - } - - template - inline pair::pair(const Key& key, const Value& value) - : first(key) - , second(value) - { - } - - template - inline pair::pair(Key&& key, Value&& value) - : first(static_cast(key)) - , second(static_cast(value)) - { - } - - template - inline pair& pair::operator=(const pair& other) { - first = other.first; - second = other.second; - return *this; - } - - template - inline pair& pair::operator=(pair&& other) { - first = static_cast(other.first); - second = static_cast(other.second); - return *this; - } - - template - static inline pair::type, typename remove_reference::type> - make_pair(Key&& key, Value&& value) { - return pair::type, typename remove_reference::type>( - static_cast(key) - , static_cast(value) - ); - } - - - template - struct unordered_hash_node { - unordered_hash_node(const Key& key, const Value& value); - unordered_hash_node(Key&& key, Value&& value); - - const Key first; - Value second; - unordered_hash_node* next; - unordered_hash_node* prev; - - private: - unordered_hash_node& operator=(const unordered_hash_node&); - }; - - template - inline unordered_hash_node::unordered_hash_node(const Key& key, const Value& value) - : first(key) - , second(value) - { - } - - template - inline unordered_hash_node::unordered_hash_node(Key&& key, Value&& value) - : first(static_cast(key)) - , second(static_cast(value)) - { - } - - template - struct unordered_hash_node { - explicit unordered_hash_node(const Key& key); - explicit unordered_hash_node(Key&& key); - - const Key first; - unordered_hash_node* next; - unordered_hash_node* prev; - - private: - unordered_hash_node& operator=(const unordered_hash_node&); - }; - - template - inline unordered_hash_node::unordered_hash_node(const Key& key) - : first(key) - { - } - - template - inline unordered_hash_node::unordered_hash_node(Key&& key) - : first(static_cast(key)) - { - } - - template - static inline void unordered_hash_node_insert(unordered_hash_node* node, size_t hash, unordered_hash_node** buckets, size_t nbuckets) { - size_t bucket = hash & (nbuckets - 1); - - unordered_hash_node* it = buckets[bucket + 1]; - node->next = it; - if (it) { - node->prev = it->prev; - it->prev = node; - if (node->prev) - node->prev->next = node; - } else { - size_t newbucket = bucket; - while (newbucket && !buckets[newbucket]) - --newbucket; - - unordered_hash_node* prev = buckets[newbucket]; - while (prev && prev->next) - prev = prev->next; - - node->prev = prev; - if (prev) - prev->next = node; - } - - // propagate node through buckets - for (; it == buckets[bucket]; --bucket) { - buckets[bucket] = node; - if (!bucket) - break; - } - } - - template - static inline void unordered_hash_node_erase(const unordered_hash_node* where, size_t hash, unordered_hash_node** buckets, size_t nbuckets) { - size_t bucket = hash & (nbuckets - 1); - - unordered_hash_node* next = where->next; - for (; buckets[bucket] == where; --bucket) { - buckets[bucket] = next; - if (!bucket) - break; - } - - if (where->prev) - where->prev->next = where->next; - if (next) - next->prev = where->prev; - } - - template - struct unordered_hash_iterator { - Node* operator->() const; - Node& operator*() const; - Node* node; - }; - - template - struct unordered_hash_iterator { - - unordered_hash_iterator() {} - unordered_hash_iterator(unordered_hash_iterator other) - : node(other.node) - { - } - - const Node* operator->() const; - const Node& operator*() const; - const Node* node; - }; - - template - struct unordered_hash_iterator > { - const Key* operator->() const; - const Key& operator*() const; - unordered_hash_node* node; - }; - - template - static inline bool operator==(const unordered_hash_iterator& lhs, const unordered_hash_iterator& rhs) { - return lhs.node == rhs.node; - } - - template - static inline bool operator!=(const unordered_hash_iterator& lhs, const unordered_hash_iterator& rhs) { - return lhs.node != rhs.node; - } - - template - static inline void operator++(unordered_hash_iterator& lhs) { - lhs.node = lhs.node->next; - } - - template - inline Node* unordered_hash_iterator::operator->() const { - return node; - } - - template - inline Node& unordered_hash_iterator::operator*() const { - return *node; - } - - template - inline const Node* unordered_hash_iterator::operator->() const { - return node; - } - - template - inline const Node& unordered_hash_iterator::operator*() const { - return *node; - } - - template - inline const Key* unordered_hash_iterator >::operator->() const { - return &node->first; - } - - template - inline const Key& unordered_hash_iterator >::operator*() const { - return node->first; - } - - template - static inline Node unordered_hash_find(const Key& key, Node* buckets, size_t nbuckets) { - const size_t bucket = hash(key) & (nbuckets - 2); - for (Node it = buckets[bucket], end = buckets[bucket+1]; it != end; it = it->next) - if (it->first == key) - return it; - - return 0; - } -} -#endif diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/new.h b/app/src/main/cpp/Dobby/external/TINYSTL/new.h deleted file mode 100644 index 5f8a6f7..0000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/new.h +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * Copyright 2012-2018 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYSTL_NEW_H -#define TINYSTL_NEW_H - -#include - -namespace tinystl { - - struct placeholder {}; -} - -inline void* operator new(size_t, tinystl::placeholder, void* ptr) { - return ptr; -} - -inline void operator delete(void*, tinystl::placeholder, void*) throw() {} - -#endif diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/stddef.h b/app/src/main/cpp/Dobby/external/TINYSTL/stddef.h deleted file mode 100644 index a31dd34..0000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/stddef.h +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * Copyright 2012-2018 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYSTL_STDDEF_H -#define TINYSTL_STDDEF_H - -#if defined(_WIN64) - typedef long long unsigned int size_t; - typedef long long int ptrdiff_t; -#elif defined(_WIN32) - typedef unsigned int size_t; - typedef int ptrdiff_t; -#elif defined (__linux__) && defined(__SIZE_TYPE__) && defined(__PTRDIFF_TYPE__) - typedef __SIZE_TYPE__ size_t; - typedef __PTRDIFF_TYPE__ ptrdiff_t; -#else -# include -#endif - -#endif diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/string.h b/app/src/main/cpp/Dobby/external/TINYSTL/string.h deleted file mode 100644 index 3fe45d1..0000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/string.h +++ /dev/null @@ -1,295 +0,0 @@ -/*- - * Copyright 2012-2018 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYSTL_STRING_H -#define TINYSTL_STRING_H - -#include -#include -#include - -namespace tinystl { - - template - class basic_string { - public: - basic_string(); - basic_string(const basic_string& other); - basic_string(basic_string&& other); - basic_string(const char* sz); - basic_string(const char* sz, size_t len); - ~basic_string(); - - basic_string& operator=(const basic_string& other); - basic_string& operator=(basic_string&& other); - - const char* c_str() const; - size_t size() const; - - void reserve(size_t size); - void resize(size_t size); - - void clear(); - void append(const char* first, const char* last); - void assign(const char* s, size_t n); - - void shrink_to_fit(); - void swap(basic_string& other); - - private: - typedef char* pointer; - pointer m_first; - pointer m_last; - pointer m_capacity; - - static const size_t c_nbuffer = 12; - char m_buffer[12]; - }; - - template - inline basic_string::basic_string() - : m_first(m_buffer) - , m_last(m_buffer) - , m_capacity(m_buffer + c_nbuffer) - { - resize(0); - } - - template - inline basic_string::basic_string(const basic_string& other) - : m_first(m_buffer) - , m_last(m_buffer) - , m_capacity(m_buffer + c_nbuffer) - { - reserve(other.size()); - append(other.m_first, other.m_last); - } - - template - inline basic_string::basic_string(basic_string&& other) - { - if (other.m_first == other.m_buffer) { - m_first = m_buffer; - m_last = m_buffer; - m_capacity = m_buffer + c_nbuffer; - reserve(other.size()); - append(other.m_first, other.m_last); - } else { - m_first = other.m_first; - m_last = other.m_last; - m_capacity = other.m_capacity; - } - other.m_first = other.m_last = other.m_buffer; - other.m_capacity = other.m_buffer + c_nbuffer; - other.resize(0); - } - - template - inline basic_string::basic_string(const char* sz) - : m_first(m_buffer) - , m_last(m_buffer) - , m_capacity(m_buffer + c_nbuffer) - { - size_t len = 0; - for (const char* it = sz; *it; ++it) - ++len; - - reserve(len); - append(sz, sz + len); - } - - template - inline basic_string::basic_string(const char* sz, size_t len) - : m_first(m_buffer) - , m_last(m_buffer) - , m_capacity(m_buffer + c_nbuffer) - { - reserve(len); - append(sz, sz + len); - } - - template - inline basic_string::~basic_string() { - if (m_first != m_buffer) - allocator::static_deallocate(m_first, m_capacity - m_first); - } - - template - inline basic_string& basic_string::operator=(const basic_string& other) { - basic_string(other).swap(*this); - return *this; - } - - template - inline basic_string& basic_string::operator=(basic_string&& other) { - basic_string(static_cast(other)).swap(*this); - return *this; - } - - template - inline const char* basic_string::c_str() const { - return m_first; - } - - template - inline size_t basic_string::size() const - { - return (size_t)(m_last - m_first); - } - - template - inline void basic_string::reserve(size_t capacity) { - if (m_first + capacity + 1 <= m_capacity) - return; - - const size_t size = (size_t)(m_last - m_first); - - pointer newfirst = (pointer)allocator::static_allocate(capacity + 1); - for (pointer it = m_first, newit = newfirst, end = m_last; it != end; ++it, ++newit) - *newit = *it; - if (m_first != m_buffer) - allocator::static_deallocate(m_first, m_capacity - m_first); - - m_first = newfirst; - m_last = newfirst + size; - m_capacity = m_first + capacity; - } - - template - inline void basic_string::resize(size_t size) { - const size_t prevSize = m_last-m_first; - reserve(size); - if (size > prevSize) - for (pointer it = m_last, end = m_first + size + 1; it < end; ++it) - *it = 0; - else if (m_last != m_first) - m_first[size] = 0; - - m_last = m_first + size; - } - - template - inline void basic_string::clear() { - resize(0); - } - - template - inline void basic_string::append(const char* first, const char* last) { - const size_t newsize = (size_t)((m_last - m_first) + (last - first) + 1); - if (m_first + newsize > m_capacity) - reserve((newsize * 3) / 2); - - for (; first != last; ++m_last, ++first) - *m_last = *first; - *m_last = 0; - } - - template - inline void basic_string::assign(const char* sz, size_t n) { - clear(); - append(sz, sz+n); - } - - template - inline void basic_string::shrink_to_fit() { - if (m_first == m_buffer) { - } else if (m_last == m_first) { - const size_t capacity = (size_t)(m_capacity - m_first); - if (capacity) - allocator::static_deallocate(m_first, capacity+1); - m_capacity = m_first; - } else if (m_capacity != m_last) { - const size_t size = (size_t)(m_last - m_first); - char* newfirst = (pointer)allocator::static_allocate(size+1); - for (pointer in = m_first, out = newfirst; in != m_last + 1; ++in, ++out) - *out = *in; - if (m_first != m_capacity) - allocator::static_deallocate(m_first, m_capacity+1-m_first); - m_first = newfirst; - m_last = newfirst+size; - m_capacity = m_last; - } - } - - template - inline void basic_string::swap(basic_string& other) { - const pointer tfirst = m_first, tlast = m_last, tcapacity = m_capacity; - m_first = other.m_first, m_last = other.m_last, m_capacity = other.m_capacity; - other.m_first = tfirst, other.m_last = tlast, other.m_capacity = tcapacity; - - char tbuffer[c_nbuffer]; - - if (m_first == other.m_buffer) - for (pointer it = other.m_buffer, end = m_last, out = tbuffer; it != end; ++it, ++out) - *out = *it; - - if (other.m_first == m_buffer) { - other.m_last = other.m_last - other.m_first + other.m_buffer; - other.m_first = other.m_buffer; - other.m_capacity = other.m_buffer + c_nbuffer; - - for (pointer it = other.m_first, end = other.m_last, in = m_buffer; it != end; ++it, ++in) - *it = *in; - *other.m_last = 0; - } - - if (m_first == other.m_buffer) { - m_last = m_last - m_first + m_buffer; - m_first = m_buffer; - m_capacity = m_buffer + c_nbuffer; - - for (pointer it = m_first, end = m_last, in = tbuffer; it != end; ++it, ++in) - *it = *in; - *m_last = 0; - } - } - - template - inline bool operator==(const basic_string& lhs, const basic_string& rhs) { - typedef const char* pointer; - - const size_t lsize = lhs.size(), rsize = rhs.size(); - if (lsize != rsize) - return false; - - pointer lit = lhs.c_str(), rit = rhs.c_str(); - pointer lend = lit + lsize; - while (lit != lend) - if (*lit++ != *rit++) - return false; - - return true; - } - - template - static inline size_t hash(const basic_string& value) { - return hash_string(value.c_str(), value.size()); - } - - typedef basic_string string; -} - -#endif diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/string_view.h b/app/src/main/cpp/Dobby/external/TINYSTL/string_view.h deleted file mode 100644 index beae9c4..0000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/string_view.h +++ /dev/null @@ -1,147 +0,0 @@ -/*- - * Copyright 2012-1017 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYSTL_STRING_VIEW_H -#define TINYSTL_STRING_VIEW_H - -#include - -namespace tinystl { - - class string_view - { - public: - typedef char value_type; - typedef char* pointer; - typedef const char* const_pointer; - typedef char& reference; - typedef const char& const_reference; - typedef const_pointer iterator; - typedef const_pointer const_iterator; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - - static constexpr size_type npos = size_type(-1); - - constexpr string_view(); - constexpr string_view(const char* s, size_type count); - constexpr string_view(const char* s); - constexpr string_view(const string_view&) = default; - string_view& operator=(const string_view&) = default; - - constexpr const char* data() const; - constexpr char operator[](size_type pos) const; - constexpr size_type size() const; - constexpr bool empty() const; - constexpr iterator begin() const; - constexpr const_iterator cbegin() const; - constexpr iterator end() const; - constexpr const_iterator cend() const; - constexpr string_view substr(size_type pos = 0, size_type count = npos) const; - constexpr void swap(string_view& v); - - private: - string_view(decltype(nullptr)) = delete; - - static constexpr size_type strlen(const char*); - - const char* m_str; - size_type m_size; - }; - - constexpr string_view::string_view() - : m_str(nullptr) - , m_size(0) - { - } - - constexpr string_view::string_view(const char* s, size_type count) - : m_str(s) - , m_size(count) - { - } - - constexpr string_view::string_view(const char* s) - : m_str(s) - , m_size(strlen(s)) - { - } - - constexpr const char* string_view::data() const { - return m_str; - } - - constexpr char string_view::operator[](size_type pos) const { - return m_str[pos]; - } - - constexpr string_view::size_type string_view::size() const { - return m_size; - } - - constexpr bool string_view::empty() const { - return 0 == m_size; - } - - constexpr string_view::iterator string_view::begin() const { - return m_str; - } - - constexpr string_view::const_iterator string_view::cbegin() const { - return m_str; - } - - constexpr string_view::iterator string_view::end() const { - return m_str + m_size; - } - - constexpr string_view::const_iterator string_view::cend() const { - return m_str + m_size; - } - - constexpr string_view string_view::substr(size_type pos, size_type count) const { - return string_view(m_str + pos, npos == count ? m_size - pos : count); - } - - constexpr void string_view::swap(string_view& v) { - const char* strtmp = m_str; - size_type sizetmp = m_size; - m_str = v.m_str; - m_size = v.m_size; - v.m_str = strtmp; - v.m_size = sizetmp; - } - - constexpr string_view::size_type string_view::strlen(const char* s) { - for (size_t len = 0; ; ++len) { - if (0 == s[len]) { - return len; - } - } - } -} - -#endif // TINYSTL_STRING_VIEW_H diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/traits.h b/app/src/main/cpp/Dobby/external/TINYSTL/traits.h deleted file mode 100644 index 84574ee..0000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/traits.h +++ /dev/null @@ -1,100 +0,0 @@ -/*- - * Copyright 2012-2018 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYSTL_TRAITS_H -#define TINYSTL_TRAITS_H - -#include - -#if defined(__GNUC__) -# define TINYSTL_TRY_POD_OPTIMIZATION(t) __is_pod(t) -#elif defined(_MSC_VER) -# define TINYSTL_TRY_POD_OPTIMIZATION(t) (!__is_class(t) || __is_pod(t)) -#else -# define TINYSTL_TRY_POD_OPTIMIZATION(t) false -#endif - -namespace tinystl { - template struct pod_traits {}; - - template struct swap_holder; - - template - static inline void move_impl(T& a, T& b, ...) { - a = b; - } - - template - static inline void move_impl(T& a, T& b, T*, swap_holder* = 0) { - a.swap(b); - } - - template - static inline void move(T& a, T&b) { - move_impl(a, b, (T*)0); - } - - template - static inline void move_construct_impl(T* a, T& b, ...) { - new(placeholder(), a) T(b); - } - - template - static inline void move_construct_impl(T* a, T& b, void*, swap_holder* = 0) { - // If your type T does not have a default constructor, simply insert: - // struct tinystl_nomove_construct; - // in the class definition - new(placeholder(), a) T; - a->swap(b); - } - - template - static inline void move_construct_impl(T* a, T& b, T*, typename T::tinystl_nomove_construct* = 0) { - new(placeholder(), a) T(b); - } - - template - static inline void move_construct(T* a, T& b) { - move_construct_impl(a, b, (T*)0); - } - - template - struct remove_reference { - typedef T type; - }; - - template - struct remove_reference { - typedef T type; - }; - - template - struct remove_reference { - typedef T type; - }; -} - -#endif diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/unordered_map.h b/app/src/main/cpp/Dobby/external/TINYSTL/unordered_map.h deleted file mode 100644 index 4be6a78..0000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/unordered_map.h +++ /dev/null @@ -1,289 +0,0 @@ -/*- - * Copyright 2012-2018 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYSTL_UNORDERED_MAP_H -#define TINYSTL_UNORDERED_MAP_H - -#include -#include -#include -#include - -namespace tinystl { - - template - class unordered_map { - public: - unordered_map(); - unordered_map(const unordered_map& other); - unordered_map(unordered_map&& other); - ~unordered_map(); - - unordered_map& operator=(const unordered_map& other); - unordered_map& operator=(unordered_map&& other); - - typedef pair value_type; - - typedef unordered_hash_iterator > const_iterator; - typedef unordered_hash_iterator > iterator; - - iterator begin(); - iterator end(); - - const_iterator begin() const; - const_iterator end() const; - - void clear(); - bool empty() const; - size_t size() const; - - const_iterator find(const Key& key) const; - iterator find(const Key& key); - pair insert(const pair& p); - pair emplace(pair&& p); - void erase(const_iterator where); - - Value& operator[](const Key& key); - - void swap(unordered_map& other); - - private: - - void rehash(size_t nbuckets); - - typedef unordered_hash_node* pointer; - - size_t m_size; - tinystl::buffer m_buckets; - }; - - template - inline unordered_map::unordered_map() - : m_size(0) - { - buffer_init(&m_buckets); - buffer_resize(&m_buckets, 9, 0); - } - - template - inline unordered_map::unordered_map(const unordered_map& other) - : m_size(other.m_size) - { - const size_t nbuckets = (size_t)(other.m_buckets.last - other.m_buckets.first); - buffer_init(&m_buckets); - buffer_resize(&m_buckets, nbuckets, 0); - - for (pointer it = *other.m_buckets.first; it; it = it->next) { - unordered_hash_node* newnode = new(placeholder(), Alloc::static_allocate(sizeof(unordered_hash_node))) unordered_hash_node(it->first, it->second); - newnode->next = newnode->prev = 0; - - unordered_hash_node_insert(newnode, hash(it->first), m_buckets.first, nbuckets - 1); - } - } - - template - inline unordered_map::unordered_map(unordered_map&& other) - : m_size(other.m_size) - { - buffer_move(&m_buckets, &other.m_buckets); - other.m_size = 0; - } - - template - inline unordered_map::~unordered_map() { - if (m_buckets.first != m_buckets.last) - clear(); - buffer_destroy(&m_buckets); - } - - template - inline unordered_map& unordered_map::operator=(const unordered_map& other) { - unordered_map(other).swap(*this); - return *this; - } - - template - inline unordered_map& unordered_map::operator=(unordered_map&& other) { - unordered_map(static_cast(other)).swap(*this); - return *this; - } - - template - inline typename unordered_map::iterator unordered_map::begin() { - iterator it; - it.node = *m_buckets.first; - return it; - } - - template - inline typename unordered_map::iterator unordered_map::end() { - iterator it; - it.node = 0; - return it; - } - - template - inline typename unordered_map::const_iterator unordered_map::begin() const { - const_iterator cit; - cit.node = *m_buckets.first; - return cit; - } - - template - inline typename unordered_map::const_iterator unordered_map::end() const { - const_iterator cit; - cit.node = 0; - return cit; - } - - template - inline bool unordered_map::empty() const { - return m_size == 0; - } - - template - inline size_t unordered_map::size() const { - return m_size; - } - - template - inline void unordered_map::clear() { - pointer it = *m_buckets.first; - while (it) { - const pointer next = it->next; - it->~unordered_hash_node(); - Alloc::static_deallocate(it, sizeof(unordered_hash_node)); - - it = next; - } - - m_buckets.last = m_buckets.first; - buffer_resize(&m_buckets, 9, 0); - m_size = 0; - } - - template - inline typename unordered_map::iterator unordered_map::find(const Key& key) { - iterator result; - result.node = unordered_hash_find(key, m_buckets.first, (size_t)(m_buckets.last - m_buckets.first)); - return result; - } - - template - inline typename unordered_map::const_iterator unordered_map::find(const Key& key) const { - iterator result; - result.node = unordered_hash_find(key, m_buckets.first, (size_t)(m_buckets.last - m_buckets.first)); - return result; - } - - template - inline void unordered_map::rehash(size_t nbuckets) { - if (m_size + 1 > 4 * nbuckets) { - pointer root = *m_buckets.first; - - const size_t newnbuckets = ((size_t)(m_buckets.last - m_buckets.first) - 1) * 8; - m_buckets.last = m_buckets.first; - buffer_resize(&m_buckets, newnbuckets + 1, 0); - unordered_hash_node** buckets = m_buckets.first; - - while (root) { - const pointer next = root->next; - root->next = root->prev = 0; - unordered_hash_node_insert(root, hash(root->first), buckets, newnbuckets); - root = next; - } - } - } - - template - inline pair::iterator, bool> unordered_map::insert(const pair& p) { - pair result; - result.second = false; - - result.first = find(p.first); - if (result.first.node != 0) - return result; - - unordered_hash_node* newnode = new(placeholder(), Alloc::static_allocate(sizeof(unordered_hash_node))) unordered_hash_node(p.first, p.second); - newnode->next = newnode->prev = 0; - - const size_t nbuckets = (size_t)(m_buckets.last - m_buckets.first); - unordered_hash_node_insert(newnode, hash(p.first), m_buckets.first, nbuckets - 1); - - ++m_size; - rehash(nbuckets); - - result.first.node = newnode; - result.second = true; - return result; - } - - template - inline pair::iterator, bool> unordered_map::emplace(pair&& p) { - pair result; - result.second = false; - - result.first = find(p.first); - if (result.first.node != 0) - return result; - - const size_t keyhash = hash(p.first); - unordered_hash_node* newnode = new(placeholder(), Alloc::static_allocate(sizeof(unordered_hash_node))) unordered_hash_node(static_cast(p.first), static_cast(p.second)); - newnode->next = newnode->prev = 0; - - const size_t nbuckets = (size_t)(m_buckets.last - m_buckets.first); - unordered_hash_node_insert(newnode, keyhash, m_buckets.first, nbuckets - 1); - - ++m_size; - rehash(nbuckets); - - result.first.node = newnode; - result.second = true; - return result; - } - - template - inline void unordered_map::erase(const_iterator where) { - unordered_hash_node_erase(where.node, hash(where->first), m_buckets.first, (size_t)(m_buckets.last - m_buckets.first) - 1); - - where->~unordered_hash_node(); - Alloc::static_deallocate((void*)where.node, sizeof(unordered_hash_node)); - --m_size; - } - - template - inline Value& unordered_map::operator[](const Key& key) { - return insert(pair(key, Value())).first->second; - } - - template - inline void unordered_map::swap(unordered_map& other) { - size_t tsize = other.m_size; - other.m_size = m_size, m_size = tsize; - buffer_swap(&m_buckets, &other.m_buckets); - } -} -#endif diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/unordered_set.h b/app/src/main/cpp/Dobby/external/TINYSTL/unordered_set.h deleted file mode 100644 index 450fbc5..0000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/unordered_set.h +++ /dev/null @@ -1,265 +0,0 @@ -/*- - * Copyright 2012-2018 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYSTL_UNORDERED_SET_H -#define TINYSTL_UNORDERED_SET_H - -#include -#include -#include -#include - -namespace tinystl { - - template - class unordered_set { - public: - unordered_set(); - unordered_set(const unordered_set& other); - unordered_set(unordered_set&& other); - ~unordered_set(); - - unordered_set& operator=(const unordered_set& other); - unordered_set& operator=(unordered_set&& other); - - typedef unordered_hash_iterator > const_iterator; - typedef const_iterator iterator; - - iterator begin() const; - iterator end() const; - - void clear(); - bool empty() const; - size_t size() const; - - iterator find(const Key& key) const; - pair insert(const Key& key); - pair emplace(Key&& key); - void erase(iterator where); - size_t erase(const Key& key); - - void swap(unordered_set& other); - - private: - - void rehash(size_t nbuckets); - - typedef unordered_hash_node* pointer; - - size_t m_size; - tinystl::buffer m_buckets; - }; - - template - inline unordered_set::unordered_set() - : m_size(0) - { - buffer_init(&m_buckets); - buffer_resize(&m_buckets, 9, 0); - } - - template - inline unordered_set::unordered_set(const unordered_set& other) - : m_size(other.m_size) - { - const size_t nbuckets = (size_t)(other.m_buckets.last - other.m_buckets.first); - buffer_init(&m_buckets); - buffer_resize(&m_buckets, nbuckets, 0); - - for (pointer it = *other.m_buckets.first; it; it = it->next) { - unordered_hash_node* newnode = new(placeholder(), Alloc::static_allocate(sizeof(unordered_hash_node))) unordered_hash_node(*it); - newnode->next = newnode->prev = 0; - unordered_hash_node_insert(newnode, hash(it->first), m_buckets.first, nbuckets - 1); - } - } - - template - inline unordered_set::unordered_set(unordered_set&& other) - : m_size(other.m_size) - { - buffer_move(&m_buckets, &other.m_buckets); - other.m_size = 0; - } - - template - inline unordered_set::~unordered_set() { - if (m_buckets.first != m_buckets.last) - clear(); - buffer_destroy(&m_buckets); - } - - template - inline unordered_set& unordered_set::operator=(const unordered_set& other) { - unordered_set(other).swap(*this); - return *this; - } - - template - inline unordered_set& unordered_set::operator=(unordered_set&& other) { - unordered_set(static_cast(other)).swap(*this); - return *this; - } - - template - inline typename unordered_set::iterator unordered_set::begin() const { - iterator cit; - cit.node = *m_buckets.first; - return cit; - } - - template - inline typename unordered_set::iterator unordered_set::end() const { - iterator cit; - cit.node = 0; - return cit; - } - - template - inline bool unordered_set::empty() const { - return m_size == 0; - } - - template - inline size_t unordered_set::size() const { - return m_size; - } - - template - inline void unordered_set::clear() { - pointer it = *m_buckets.first; - while (it) { - const pointer next = it->next; - it->~unordered_hash_node(); - Alloc::static_deallocate(it, sizeof(unordered_hash_node)); - - it = next; - } - - m_buckets.last = m_buckets.first; - buffer_resize(&m_buckets, 9, 0); - m_size = 0; - } - - template - inline typename unordered_set::iterator unordered_set::find(const Key& key) const { - iterator result; - result.node = unordered_hash_find(key, m_buckets.first, (size_t)(m_buckets.last - m_buckets.first)); - return result; - } - - template - inline void unordered_set::rehash(size_t nbuckets) { - if (m_size + 1 > 4 * nbuckets) { - pointer root = *m_buckets.first; - - const size_t newnbuckets = ((size_t)(m_buckets.last - m_buckets.first) - 1) * 8; - m_buckets.last = m_buckets.first; - buffer_resize(&m_buckets, newnbuckets + 1, 0); - unordered_hash_node** buckets = m_buckets.first; - - while (root) { - const pointer next = root->next; - root->next = root->prev = 0; - unordered_hash_node_insert(root, hash(root->first), buckets, newnbuckets); - root = next; - } - } - } - - template - inline pair::iterator, bool> unordered_set::insert(const Key& key) { - pair result; - result.second = false; - - result.first = find(key); - if (result.first.node != 0) - return result; - - unordered_hash_node* newnode = new(placeholder(), Alloc::static_allocate(sizeof(unordered_hash_node))) unordered_hash_node(key); - newnode->next = newnode->prev = 0; - - const size_t nbuckets = (size_t)(m_buckets.last - m_buckets.first); - unordered_hash_node_insert(newnode, hash(key), m_buckets.first, nbuckets - 1); - - ++m_size; - rehash(nbuckets); - - result.first.node = newnode; - result.second = true; - return result; - } - - template - inline pair::iterator, bool> unordered_set::emplace(Key&& key) { - pair result; - result.second = false; - - result.first = find(key); - if (result.first.node != 0) - return result; - - const size_t keyhash = hash(key); - unordered_hash_node* newnode = new(placeholder(), Alloc::static_allocate(sizeof(unordered_hash_node))) unordered_hash_node(static_cast(key)); - newnode->next = newnode->prev = 0; - - const size_t nbuckets = (size_t)(m_buckets.last - m_buckets.first); - unordered_hash_node_insert(newnode, keyhash, m_buckets.first, nbuckets - 1); - - ++m_size; - rehash(nbuckets); - - result.first.node = newnode; - result.second = true; - return result; - } - - template - inline void unordered_set::erase(iterator where) { - unordered_hash_node_erase(where.node, hash(where.node->first), m_buckets.first, (size_t)(m_buckets.last - m_buckets.first) - 1); - - where.node->~unordered_hash_node(); - Alloc::static_deallocate((void*)where.node, sizeof(unordered_hash_node)); - --m_size; - } - - template - inline size_t unordered_set::erase(const Key& key) { - const iterator it = find(key); - if (it.node == 0) - return 0; - - erase(it); - return 1; - } - - template - void unordered_set::swap(unordered_set& other) { - size_t tsize = other.m_size; - other.m_size = m_size, m_size = tsize; - buffer_swap(&m_buckets, &other.m_buckets); - } -} -#endif diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/vector.h b/app/src/main/cpp/Dobby/external/TINYSTL/vector.h deleted file mode 100644 index 32eae1f..0000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/vector.h +++ /dev/null @@ -1,336 +0,0 @@ -/*- - * Copyright 2012-2018 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYSTL_VECTOR_H -#define TINYSTL_VECTOR_H - -#include -#include -#include -#include - -namespace tinystl { - template - class vector { - public: - vector(); - vector(const vector& other); - vector(vector&& other); - vector(size_t size); - vector(size_t size, const T& value); - vector(const T* first, const T* last); - ~vector(); - - vector& operator=(const vector& other); - vector& operator=(vector&& other); - - void assign(const T* first, const T* last); - - const T* data() const; - T* data(); - size_t size() const; - size_t capacity() const; - bool empty() const; - - T& operator[](size_t idx); - const T& operator[](size_t idx) const; - - const T& front() const; - T& front(); - const T& back() const; - T& back(); - - void resize(size_t size); - void resize(size_t size, const T& value); - void clear(); - void reserve(size_t capacity); - - void push_back(const T& t); - void pop_back(); - - void emplace_back(); - template - void emplace_back(const Param& param); - - void shrink_to_fit(); - - void swap(vector& other); - - typedef T value_type; - - typedef T* iterator; - iterator begin(); - iterator end(); - - typedef const T* const_iterator; - const_iterator begin() const; - const_iterator end() const; - - void insert(iterator where); - void insert(iterator where, const T& value); - void insert(iterator where, const T* first, const T* last); - - template - void emplace(iterator where, const Param& param); - - iterator erase(iterator where); - iterator erase(iterator first, iterator last); - - iterator erase_unordered(iterator where); - iterator erase_unordered(iterator first, iterator last); - - private: - buffer m_buffer; - }; - - template - inline vector::vector() { - buffer_init(&m_buffer); - } - - template - inline vector::vector(const vector& other) { - buffer_init(&m_buffer); - buffer_reserve(&m_buffer, other.size()); - buffer_insert(&m_buffer, m_buffer.last, other.m_buffer.first, other.m_buffer.last); - } - - template - inline vector::vector(vector&& other) { - buffer_move(&m_buffer, &other.m_buffer); - } - - template - inline vector::vector(size_t size) { - buffer_init(&m_buffer); - buffer_resize(&m_buffer, size); - } - - template - inline vector::vector(size_t size, const T& value) { - buffer_init(&m_buffer); - buffer_resize(&m_buffer, size, value); - } - - template - inline vector::vector(const T* first, const T* last) { - buffer_init(&m_buffer); - buffer_insert(&m_buffer, m_buffer.last, first, last); - } - - template - inline vector::~vector() { - buffer_destroy(&m_buffer); - } - - template - inline vector& vector::operator=(const vector& other) { - vector(other).swap(*this); - return *this; - } - - template - vector& vector::operator=(vector&& other) { - buffer_destroy(&m_buffer); - buffer_move(&m_buffer, &other.m_buffer); - return *this; - } - - template - inline void vector::assign(const T* first, const T* last) { - buffer_clear(&m_buffer); - buffer_insert(&m_buffer, m_buffer.last, first, last); - } - - template - inline const T* vector::data() const { - return m_buffer.first; - } - - template - inline T* vector::data() { - return m_buffer.first; - } - - template - inline size_t vector::size() const { - return (size_t)(m_buffer.last - m_buffer.first); - } - - template - inline size_t vector::capacity() const { - return (size_t)(m_buffer.capacity - m_buffer.first); - } - - template - inline bool vector::empty() const { - return m_buffer.last == m_buffer.first; - } - - template - inline T& vector::operator[](size_t idx) { - return m_buffer.first[idx]; - } - - template - inline const T& vector::operator[](size_t idx) const { - return m_buffer.first[idx]; - } - - template - inline const T& vector::front() const { - return m_buffer.first[0]; - } - - template - inline T& vector::front() { - return m_buffer.first[0]; - } - - template - inline const T& vector::back() const { - return m_buffer.last[-1]; - } - - template - inline T& vector::back() { - return m_buffer.last[-1]; - } - - template - inline void vector::resize(size_t size) { - buffer_resize(&m_buffer, size); - } - - template - inline void vector::resize(size_t size, const T& value) { - buffer_resize(&m_buffer, size, value); - } - - template - inline void vector::clear() { - buffer_clear(&m_buffer); - } - - template - inline void vector::reserve(size_t capacity) { - buffer_reserve(&m_buffer, capacity); - } - - template - inline void vector::push_back(const T& t) { - buffer_append(&m_buffer, &t); - } - - template - inline void vector::emplace_back() { - buffer_append(&m_buffer); - } - - template - template - inline void vector::emplace_back(const Param& param) { - buffer_append(&m_buffer, ¶m); - } - - template - inline void vector::pop_back() { - buffer_erase(&m_buffer, m_buffer.last - 1, m_buffer.last); - } - - template - inline void vector::shrink_to_fit() { - buffer_shrink_to_fit(&m_buffer); - } - - template - inline void vector::swap(vector& other) { - buffer_swap(&m_buffer, &other.m_buffer); - } - - template - inline typename vector::iterator vector::begin() { - return m_buffer.first; - } - - template - inline typename vector::iterator vector::end() { - return m_buffer.last; - } - - template - inline typename vector::const_iterator vector::begin() const { - return m_buffer.first; - } - - template - inline typename vector::const_iterator vector::end() const { - return m_buffer.last; - } - - template - inline void vector::insert(typename vector::iterator where) { - buffer_insert(&m_buffer, where, 1); - } - - template - inline void vector::insert(iterator where, const T& value) { - buffer_insert(&m_buffer, where, &value, &value + 1); - } - - template - inline void vector::insert(iterator where, const T* first, const T* last) { - buffer_insert(&m_buffer, where, first, last); - } - - template - inline typename vector::iterator vector::erase(iterator where) { - return buffer_erase(&m_buffer, where, where + 1); - } - - template - inline typename vector::iterator vector::erase(iterator first, iterator last) { - return buffer_erase(&m_buffer, first, last); - } - - template - inline typename vector::iterator vector::erase_unordered(iterator where) { - return buffer_erase_unordered(&m_buffer, where, where + 1); - } - - template - inline typename vector::iterator vector::erase_unordered(iterator first, iterator last) { - return buffer_erase_unordered(&m_buffer, first, last); - } - - template - template - void vector::emplace(typename vector::iterator where, const Param& param) { - buffer_insert(&m_buffer, where, ¶m, ¶m + 1); - } -} - -#endif // TINYSTL_VECTOR_H diff --git a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/CMakeLists.txt b/app/src/main/cpp/Dobby/external/deprecated/misc-helper/CMakeLists.txt deleted file mode 100644 index 115c9fd..0000000 --- a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -include_directories(.) - -if(NOT BUILDING_KERNEL) - set(SOURCE_FILE_LIST - ${CMAKE_CURRENT_SOURCE_DIR}/variable_cache.c - ${CMAKE_CURRENT_SOURCE_DIR}/async_logger.cc - ${CMAKE_CURRENT_SOURCE_DIR}/format_printer.cc - ) -else() - set(SOURCE_FILE_LIST - ${CMAKE_CURRENT_SOURCE_DIR}/format_printer.cc - ) -endif() - -add_library(misc_helper - ${SOURCE_FILE_LIST} - ${SOURCE_HEADER_LIST} -) \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/async_logger.cc b/app/src/main/cpp/Dobby/external/deprecated/misc-helper/async_logger.cc deleted file mode 100644 index 49b11cb..0000000 --- a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/async_logger.cc +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include -#include -#include - -#include - -#include -#include -#include - -#define aync_logger_buffer_size (20 * 1024 * 1024) -int async_logger_buffer_cursor = 0; -char async_logger_buffer[aync_logger_buffer_size]; - -static pthread_mutex_t async_logger_mutex = PTHREAD_MUTEX_INITIALIZER; - -static int output_fd = -1; - -void async_logger_print(char *str) { - pthread_mutex_lock(&async_logger_mutex); -#if 0 - { - write(STDOUT_FILENO, str, strlen(str) + 1); - } -#endif - memcpy(async_logger_buffer + async_logger_buffer_cursor, str, strlen(str)); - async_logger_buffer_cursor += strlen(str); - pthread_mutex_unlock(&async_logger_mutex); - return; -} - -static void *async_logger_print_impl(void *ctx) { - while (1) { - pthread_mutex_lock(&async_logger_mutex); - if (async_logger_buffer_cursor > 0) { - write(output_fd, async_logger_buffer, async_logger_buffer_cursor); - async_logger_buffer_cursor = 0; - } - pthread_mutex_unlock(&async_logger_mutex); - sleep(1); - } -} - -void async_logger_init(char *logger_path) { - static int async_logger_initialized = 0; - if (async_logger_initialized) - return; - async_logger_initialized = 1; - - // init stdout write lock - pthread_mutex_t write_mutex; - pthread_mutex_init(&write_mutex, NULL); - - output_fd = STDOUT_FILENO; - if (logger_path) { - int fd = open(logger_path, O_CREAT | O_WRONLY | O_TRUNC, 0644); - output_fd = fd; - } - - // init async logger - pthread_mutex_init(&async_logger_mutex, NULL); - pthread_t async_logger_thread; - int ret = pthread_create(&async_logger_thread, NULL, async_logger_print_impl, NULL); -} diff --git a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/deprecated/pthread_helper.cc b/app/src/main/cpp/Dobby/external/deprecated/misc-helper/deprecated/pthread_helper.cc deleted file mode 100644 index bc080f6..0000000 --- a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/deprecated/pthread_helper.cc +++ /dev/null @@ -1,129 +0,0 @@ -#include "pthread_helper.h" -#include -#ifdef _WIN32 - -typedef void (*windows_thread)(void *); - -int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { - uintptr_t handle = _beginthread((windows_thread)start_routine, 0, arg); - thread->handle = (HANDLE)handle; - if (thread->handle == (HANDLE)-1) { - return 1; - } else { - return 0; - } -} - -int pthread_detach(pthread_t thread) { - /* Do nothing */ - return 0; -} - -void pthread_exit(void *value_ptr) { - _endthread(); -} - -int pthread_join(pthread_t thread, void **value_ptr) { - DWORD retvalue = WaitForSingleObject(thread.handle, INFINITE); - if (retvalue == WAIT_OBJECT_0) { - return 0; - } else { - return EINVAL; - } -} - -pthread_t pthread_self(void) { - pthread_t pt; - pt.handle = GetCurrentThread(); - return pt; -} - -int pthread_cancel(pthread_t thread) { - fprintf(stderr, "DO NOT USE THIS FUNCTION. pthread_cancel\n"); - abort(); - return 0; -} - -/* --------------------- MUTEX --------------------*/ - -int pthread_mutexattr_destroy(pthread_mutexattr_t *attr) { - /* do nothing */ - return 0; -} - -int pthread_mutexattr_init(pthread_mutexattr_t *attr) { - /* do nothing */ - return 0; -} - -int pthread_mutex_destroy(pthread_mutex_t *mutex) { - return !CloseHandle(mutex->handle); -} - -int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) { - HANDLE handle = CreateMutex(NULL, FALSE, NULL); - if (handle != NULL) { - mutex->handle = handle; - return 0; - } else { - return 1; - } -} - -int pthread_mutex_lock(pthread_mutex_t *mutex) { - DWORD retvalue = WaitForSingleObject(mutex->handle, INFINITE); - if (retvalue == WAIT_OBJECT_0) { - return 0; - } else { - return EINVAL; - } -} - -int pthread_mutex_trylock(pthread_mutex_t *mutex) { - DWORD retvalue = WaitForSingleObject(mutex->handle, 0); - if (retvalue == WAIT_OBJECT_0) { - return 0; - } else if (retvalue == WAIT_TIMEOUT) { - return EBUSY; - } else { - return EINVAL; - } -} - -int pthread_mutex_unlock(pthread_mutex_t *mutex) { - return !ReleaseMutex(mutex->handle); -} - -/* ------------------- Thead Specific Data ------------------ */ - -int pthread_key_create(pthread_key_t *key, void (*destr_function)(void *)) { - DWORD dkey = TlsAlloc(); - if (dkey != 0xFFFFFFFF) { - *key = dkey; - return 0; - } else { - return EAGAIN; - } -} - -int pthread_key_delete(pthread_key_t key) { - if (TlsFree(key)) { - return 0; - } else { - return EINVAL; - } -} - -int pthread_setspecific(pthread_key_t key, const void *pointer) { - if (TlsSetValue(key, (LPVOID)pointer)) { - return 0; - } else { - return EINVAL; - } -} - -void *pthread_getspecific(pthread_key_t key) { - return TlsGetValue(key); -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/deprecated/pthread_helper.h b/app/src/main/cpp/Dobby/external/deprecated/misc-helper/deprecated/pthread_helper.h deleted file mode 100644 index 3ed01f6..0000000 --- a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/deprecated/pthread_helper.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * light weight pthread compatible library for Windows - * (C) 2009 Okamura Yasunobu - * - * WARNING This library does NOT support all future of pthread - * - */ - -#ifndef CROSS_THREAD_H -#define CROSS_THREAD_H - -#ifdef _WIN32 - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include - -typedef struct pthread_tag { - HANDLE handle; -} pthread_t; - -typedef struct pthread_mutex_tag { - HANDLE handle; -} pthread_mutex_t; - -/* stub */ -typedef struct pthread_attr_tag { - int attr; -} pthread_attr_t; - -typedef struct pthread_mutexattr_tag { - int attr; -} pthread_mutexattr_t; - -typedef DWORD pthread_key_t; - -/* ignore attribute */ -int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg); - -/* ignore value_ptr */ -void pthread_exit(void *value_ptr); - -/* ignore value_ptr */ -int pthread_join(pthread_t thread, void **value_ptr); - -pthread_t pthread_self(void); - -/* do nothing */ -int pthread_detach(pthread_t thread); - -/* DO NOT USE */ -int pthread_cancel(pthread_t thread); - -int pthread_mutexattr_destroy(pthread_mutexattr_t *attr); /* do nothing */ -int pthread_mutexattr_init(pthread_mutexattr_t *attr); /* do nothing */ - -int pthread_mutex_destroy(pthread_mutex_t *mutex); -int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); -int pthread_mutex_lock(pthread_mutex_t *mutex); -int pthread_mutex_trylock(pthread_mutex_t *mutex); -int pthread_mutex_unlock(pthread_mutex_t *mutex); - -/* ignore deconstructor */ -int pthread_key_create(pthread_key_t *key, void (*destr_function)(void *)); -int pthread_key_delete(pthread_key_t key); -int pthread_setspecific(pthread_key_t key, const void *pointer); -void *pthread_getspecific(pthread_key_t key); - -#define sleep(num) Sleep(1000 * (num)) - -#ifdef __cplusplus -} -#endif - -#else -#include -#include -#define Sleep(num) usleep(num * 1000) -#endif - -#endif /* CROSS_THREAD_H */ diff --git a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/deprecated/unistd_helper.h b/app/src/main/cpp/Dobby/external/deprecated/misc-helper/deprecated/unistd_helper.h deleted file mode 100644 index d990fa3..0000000 --- a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/deprecated/unistd_helper.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifdef _WIN32 - -#include -#define open _open -#define read _read -#define O_RDONLY _O_RDONLY -#define O_WRONLY _O_WRONLY -#define O_CREAT _O_CREAT -#define O_TRUNC _O_TRUNC - -#define ssize_t int - -#define STDIN_FILENO 0 -#define STDOUT_FILENO 1 -#define STDERR_FILENO 2 -/* should be in some equivalent to */ -typedef __int8 int8_t; -typedef __int16 int16_t; -typedef __int32 int32_t; -typedef __int64 int64_t; -typedef unsigned __int8 uint8_t; -typedef unsigned __int16 uint16_t; -typedef unsigned __int32 uint32_t; -typedef unsigned __int64 uint64_t; - -#else - -#include - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/format_printer.cc b/app/src/main/cpp/Dobby/external/deprecated/misc-helper/format_printer.cc deleted file mode 100644 index 07ca440..0000000 --- a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/format_printer.cc +++ /dev/null @@ -1,11 +0,0 @@ -#include "misc-helper/format_printer.h" - -void hexdump(const uint8_t *bytes, size_t len) { - size_t ix; - for (ix = 0; ix < len; ++ix) { - if (ix != 0 && !(ix % 16)) - RAW_LOG(0, "\n"); - RAW_LOG(0, "%02X ", bytes[ix]); - } - RAW_LOG(0, "\n"); -} diff --git a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/misc-helper/async_logger.h b/app/src/main/cpp/Dobby/external/deprecated/misc-helper/misc-helper/async_logger.h deleted file mode 100644 index 03e0d4e..0000000 --- a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/misc-helper/async_logger.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef ASYNC_LOGGER_H -#define ASYNC_LOGGER_H - -void async_logger_print(char *str); - -void async_logger_init(char *logger_path); - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/misc-helper/format_printer.h b/app/src/main/cpp/Dobby/external/deprecated/misc-helper/misc-helper/format_printer.h deleted file mode 100644 index 3f9a434..0000000 --- a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/misc-helper/format_printer.h +++ /dev/null @@ -1,3 +0,0 @@ -#include "common_header.h" - -void hexdump(const uint8_t *bytes, size_t len); \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/misc-helper/variable_cache.h b/app/src/main/cpp/Dobby/external/deprecated/misc-helper/misc-helper/variable_cache.h deleted file mode 100644 index bf490fd..0000000 --- a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/misc-helper/variable_cache.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef VARIABLE_CACHE_H -#define VARIABLE_CACHE_H - -#include - -#define cache_set stash -void cache_set(const char *name, uint64_t value); - -#define cache_get(x) cache(x) -#define assert_cache(x) (assert(cache(x)), cache(x)) -uint64_t cache_get(const char *name); - -int serialized_to_file(const char *filepath); - -int unserialized_from_file(const char *filepath); - -#endif diff --git a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/variable_cache.c b/app/src/main/cpp/Dobby/external/deprecated/misc-helper/variable_cache.c deleted file mode 100644 index 895a2cb..0000000 --- a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/variable_cache.c +++ /dev/null @@ -1,118 +0,0 @@ -#include "misc-helper/variable_cache.h" - -#include -#include -#include - -#include -#include "deprecated/unistd_helper.h" - -#include - -typedef struct queue_entry_t { - struct queue_entry *next; - struct queue_entry *prev; -} queue_entry_t; - -/* TODO: add a property or attribute indicate not serialized */ -typedef struct var_entry_t { - queue_entry_t entry_; - char key[128]; - uint64_t value; -} var_entry_t; - -var_entry_t *root = NULL; - -static var_entry_t *cache_get_entry_internal(const char *name) { - var_entry_t *entry; - entry = root; - while (entry != NULL) { - if (strcmp(name, entry->key) == 0) { - return entry; - } - entry = (var_entry_t *)entry->entry_.next; - } - return NULL; -} - -void cache_set(const char *name, uint64_t value) { - var_entry_t *entry = cache_get_entry_internal(name); - if (entry) { - entry->value = value; - return; - } - - entry = (var_entry_t *)malloc(sizeof(var_entry_t)); - strcpy(entry->key, name); - entry->value = value; - - entry->entry_.next = (struct queue_entry *)root; - root = entry; -} - -uint64_t cache_get(const char *name) { - var_entry_t *entry = cache_get_entry_internal(name); - if (entry) { - return entry->value; - } - return 0; -} - -typedef struct entry_block { - int key_length; - int value_length; -} entry_block_t; - -int serialized_to_file(const char *filepath) { - int fd = open(filepath, O_WRONLY | O_CREAT | O_TRUNC, 0660); - if (fd == -1) { - printf("open %s failed: %s\n", filepath, strerror(errno)); - return -1; - } - - var_entry_t *entry; - entry = root; - while (entry != NULL) { - entry_block_t block = {0}; - { - block.key_length = strlen(entry->key) + 1; - block.value_length = sizeof(uint64_t); - write(fd, &block, sizeof(block)); - } - - write(fd, entry->key, block.key_length); - write(fd, &entry->value, block.value_length); - - entry = (var_entry_t *)entry->entry_.next; - } - close(fd); - return 0; -} - -int unserialized_from_file(const char *filepath) { - int fd = open(filepath, O_RDONLY); - if (fd == -1) { - printf("open %s failed: %s\n", filepath, strerror(errno)); - return -1; - } - - entry_block_t block = {0}; - while (read(fd, &block, sizeof(block)) > 0) { - char key[128] = {0}; - uint64_t value = 0; - - read(fd, (void *)&key, block.key_length); - read(fd, (void *)&value, block.value_length); - - { - var_entry_t *entry = (var_entry_t *)malloc(sizeof(var_entry_t)); - strcpy(entry->key, key); - entry->value = value; - - entry->entry_.next = (struct queue_entry *)root; - root = entry; - } - } - - return 0; -} diff --git a/app/src/main/cpp/Dobby/external/logging/CMakeLists.txt b/app/src/main/cpp/Dobby/external/logging/CMakeLists.txt deleted file mode 100644 index d83925d..0000000 --- a/app/src/main/cpp/Dobby/external/logging/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -include_directories(.) - -if(NOT BUILDING_KERNEL) - set(SOURCE_FILE_LIST - ${CMAKE_CURRENT_SOURCE_DIR}/cxxlogging.cc - ${CMAKE_CURRENT_SOURCE_DIR}/logging.c - ) -else() - set(SOURCE_FILE_LIST - ${CMAKE_CURRENT_SOURCE_DIR}/cxxlogging.cc - ${CMAKE_CURRENT_SOURCE_DIR}/kernel_logging.c - ) -endif() -add_library(logging - ${SOURCE_FILE_LIST} - ${SOURCE_HEADER_LIST} -) \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/external/logging/cxxlogging.cc b/app/src/main/cpp/Dobby/external/logging/cxxlogging.cc deleted file mode 100644 index 430b4f9..0000000 --- a/app/src/main/cpp/Dobby/external/logging/cxxlogging.cc +++ /dev/null @@ -1,36 +0,0 @@ -#include "logging/cxxlogging.h" - -#if 1 || defined(BUILDING_KERNEL) -void Logger::setLogLevel(LogLevel level) { - log_level_ = level; -} - -void Logger::log(LogLevel level, const char *tag, const char *fmt, ...) { - -} - -void Logger::LogFatal(const char *fmt, ...) { -} -#else -#include -#include -#include -#include - -void Logger::setLogLevel(LogLevel level) { - log_level_ = level; -} - -void Logger::log(LogLevel level, const char *tag, const char *fmt, ...) { - if (level > log_level_) { - va_list ap; - - va_start(ap, fmt); - vprintf(fmt, ap); - va_end(ap); - } -} - -void Logger::LogFatal(const char *fmt, ...) { -} -#endif diff --git a/app/src/main/cpp/Dobby/external/logging/kernel_logging.c b/app/src/main/cpp/Dobby/external/logging/kernel_logging.c deleted file mode 100644 index 996f9f9..0000000 --- a/app/src/main/cpp/Dobby/external/logging/kernel_logging.c +++ /dev/null @@ -1,28 +0,0 @@ -#include "logging/logging.h" - -#include -#include "utility_macro.h" - -#if defined(BUILDING_KERNEL) -#define abort() -#else -#include -#endif - -static int _log_level = 1; -PUBLIC void log_set_level(int level) { - _log_level = level; -} - -PUBLIC int log_internal_impl(int level, const char *fmt, ...) { - if (level < _log_level) - return 0; - - va_list ap; - va_start(ap, fmt); - - vprintf(fmt, ap); - - va_end(ap); - return 0; -} diff --git a/app/src/main/cpp/Dobby/external/logging/logging.c b/app/src/main/cpp/Dobby/external/logging/logging.c deleted file mode 100644 index 2a9ebc7..0000000 --- a/app/src/main/cpp/Dobby/external/logging/logging.c +++ /dev/null @@ -1,124 +0,0 @@ -#include "logging/logging.h" - -#include -#include -#include -#include -#include -#include - -#if defined(__linux__) || defined(__APPLE__) -#include -#include -#include -#include -#include -#endif - -#if defined(__APPLE__) -#include -#endif - -#if defined(_WIN32) -#define PUBLIC -#else -#define PUBLIC __attribute__((visibility("default"))) -#define INTERNAL __attribute__((visibility("internal"))) -#endif - -static int g_log_level = 1; -static char g_log_tag[64] = {0}; -static bool time_tag_enabled = false; -static bool syslog_enabled = false; -static bool file_log_enabled = false; -static const char *log_file_path = NULL; -static int log_file_fd = -1; -static FILE *log_file_stream = NULL; - -PUBLIC void log_set_level(int level) { - g_log_level = level; -} - -PUBLIC void log_set_tag(const char *tag) { - sprintf(g_log_tag, "[%s] ", tag); -} - -PUBLIC void log_enable_time_tag() { - time_tag_enabled = true; -} - -PUBLIC void log_switch_to_syslog(void) { - syslog_enabled = 1; -} - -PUBLIC void log_switch_to_file(const char *path) { - file_log_enabled = 1; - log_file_path = strdup(path); - log_file_stream = fopen(log_file_path, "w+"); - if (log_file_stream == NULL) { - file_log_enabled = false; - ERROR_LOG("open log file %s failed, %s", path, strerror(errno)); - } -} - -PUBLIC int log_internal_impl(int level, const char *fmt, ...) { - if (level < g_log_level) - return 0; - - char buffer[4096] = {0}; - - if (g_log_tag[0] != 0) { - snprintf(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer), "%s ", g_log_tag); - } - - if (time_tag_enabled) { - time_t now = time(NULL); - struct tm *tm = localtime(&now); - snprintf(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer), "%04d-%02d-%02d %02d:%02d:%02d ", - tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); - } - - snprintf(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer), "%s\n", fmt); - - fmt = buffer; - - va_list ap; - va_start(ap, fmt); - -#pragma clang diagnostic ignored "-Wformat" - - if (syslog_enabled) { -#if defined(__APPLE__) - extern void *_os_log_default; - static void (*os_log_with_args)(void *oslog, char type, const char *format, va_list args, void *ret_addr) = 0; - if (!os_log_with_args) - os_log_with_args = (__typeof(os_log_with_args))dlsym((void *)-2, "os_log_with_args"); - os_log_with_args(&_os_log_default, 0x10, fmt, ap, os_log_with_args); -#elif defined(_POSIX_VERSION) - vsyslog(LOG_ERR, fmt, ap); -#endif - } - - if (file_log_enabled) { - char buffer[4096] = {0}; - vsnprintf(buffer, 4096 - 1, fmt, ap); - if (fwrite(buffer, sizeof(char), strlen(buffer) + 1, log_file_stream) == -1) { - file_log_enabled = false; - } - fflush(log_file_stream); - } - - if (!syslog_enabled && !file_log_enabled) { -#if defined(__ANDROID__) -#define ANDROID_LOG_TAG "Dobby" -#include - __android_log_vprint(ANDROID_LOG_INFO, ANDROID_LOG_TAG, fmt, ap); -#else - vprintf(fmt, ap); -#endif - } - -#pragma clang diagnostic warning "-Wformat" - va_end(ap); - return 0; -} diff --git a/app/src/main/cpp/Dobby/external/logging/logging/check_logging.h b/app/src/main/cpp/Dobby/external/logging/logging/check_logging.h deleted file mode 100644 index d13e947..0000000 --- a/app/src/main/cpp/Dobby/external/logging/logging/check_logging.h +++ /dev/null @@ -1,87 +0,0 @@ - -#ifndef CHECK_LOGGING_H_ -#define CHECK_LOGGING_H_ - -#include "logging.h" - -#define CHECK_WITH_MSG(condition, message) \ - do { \ - if (!(condition)) { \ - FATAL("Check failed: %s.\n", message); \ - } \ - } while (0) -#define CHECK(condition) CHECK_WITH_MSG(condition, #condition) - -#ifdef LOGGING_DEBUG - -#define DCHECK_WITH_MSG(condition, message) \ - do { \ - if (!(condition)) { \ - FATAL("%s", message); \ - } \ - } while (0) -#define DCHECK(condition) DCHECK_WITH_MSG(condition, #condition) - -// Helper macro for binary operators. -// Don't use this macro directly in your code, use CHECK_EQ et al below. -#define CHECK_OP(name, op, lhs, rhs) \ - do { \ - if (!(lhs op rhs)) { \ - FATAL(" Check failed: %s.\n", #lhs " " #op " " #rhs); \ - } \ - } while (0) - -#define DCHECK_OP(name, op, lhs, rhs) \ - do { \ - if (!((lhs)op(rhs))) { \ - FATAL("%s", ""); \ - } \ - } while (0) - -#else - -// Make all CHECK functions discard their log strings to reduce code -// bloat for official release builds. -#define CHECK_OP(name, op, lhs, rhs) \ - do { \ - bool _cond = lhs op rhs; \ - CHECK_WITH_MSG(_cond, #lhs " " #op " " #rhs "\n"); \ - } while (0) - -#define DCHECK_WITH_MSG(condition, msg) void(0); - -#endif - -#define CHECK_EQ(lhs, rhs) CHECK_OP(EQ, ==, lhs, rhs) -#define CHECK_NE(lhs, rhs) CHECK_OP(NE, !=, lhs, rhs) -#define CHECK_LE(lhs, rhs) CHECK_OP(LE, <=, lhs, rhs) -#define CHECK_LT(lhs, rhs) CHECK_OP(LT, <, lhs, rhs) -#define CHECK_GE(lhs, rhs) CHECK_OP(GE, >=, lhs, rhs) -#define CHECK_GT(lhs, rhs) CHECK_OP(GT, >, lhs, rhs) -#define CHECK_NULL(val) CHECK((val) == NULL) -#define CHECK_NOT_NULL(val) CHECK((val) != NULL) - -#ifdef LOGGING_DEBUG -#define DCHECK_EQ(lhs, rhs) DCHECK_OP(EQ, ==, lhs, rhs) -#define DCHECK_NE(lhs, rhs) DCHECK_OP(NE, !=, lhs, rhs) -#define DCHECK_GT(lhs, rhs) DCHECK_OP(GT, >, lhs, rhs) -#define DCHECK_GE(lhs, rhs) DCHECK_OP(GE, >=, lhs, rhs) -#define DCHECK_LT(lhs, rhs) DCHECK_OP(LT, <, lhs, rhs) -#define DCHECK_LE(lhs, rhs) DCHECK_OP(LE, <=, lhs, rhs) -#define DCHECK_NULL(val) DCHECK((val) == nullptr) -#define DCHECK_NOT_NULL(val) DCHECK((val) != nullptr) -#define DCHECK_IMPLIES(lhs, rhs) DCHECK_WITH_MSG(!(lhs) || (rhs), #lhs " implies " #rhs) -#else -#define DCHECK(condition) ((void)0) -#define DCHECK_EQ(v1, v2) ((void)0) -#define DCHECK_NE(v1, v2) ((void)0) -#define DCHECK_GT(v1, v2) ((void)0) -#define DCHECK_GE(v1, v2) ((void)0) -#define DCHECK_LT(v1, v2) ((void)0) -#define DCHECK_LE(v1, v2) ((void)0) -#define DCHECK_NULL(val) ((void)0) -#define DCHECK_NOT_NULL(val) ((void)0) -#define DCHECK_IMPLIES(v1, v2) ((void)0) -#endif - -#endif diff --git a/app/src/main/cpp/Dobby/external/logging/logging/cxxlogging.h b/app/src/main/cpp/Dobby/external/logging/logging/cxxlogging.h deleted file mode 100644 index e41b149..0000000 --- a/app/src/main/cpp/Dobby/external/logging/logging/cxxlogging.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "logging.h" - -class Logger { -public: - void setLogLevel(LogLevel level); - - void log(LogLevel level, const char *tag, const char *fmt, ...); - - void LogFatal(const char *fmt, ...); - -private: - LogLevel log_level_; -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/external/logging/logging/logging.h b/app/src/main/cpp/Dobby/external/logging/logging/logging.h deleted file mode 100644 index 8bf9075..0000000 --- a/app/src/main/cpp/Dobby/external/logging/logging/logging.h +++ /dev/null @@ -1,88 +0,0 @@ -#pragma once - -#define LOG_TAG NULL - -typedef enum { - LOG_LEVEL_VERBOSE = 0, - LOG_LEVEL_DEBUG = 1, - LOG_LEVEL_INFO = 2, - LOG_LEVEL_WARN = 3, - LOG_LEVEL_ERROR = 4, - LOG_LEVEL_FATAL = 5 -} LogLevel; - -#if 1 -#ifdef __cplusplus -extern "C" { -#endif - -void log_set_level(int level); - -void log_set_tag(const char *tag); - -void log_enable_time_tag(); - -void log_switch_to_syslog(); - -void log_switch_to_file(const char *path); - -#if !defined(LOG_FUNCTION_IMPL) -#define LOG_FUNCTION_IMPL log_internal_impl -#endif - -int log_internal_impl(int level, const char *, ...); - -#if defined(LOGGING_DISABLE) -#define LOG_FUNCTION_IMPL(...) -#endif - -#ifdef __cplusplus -} -#endif -#else -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif -#endif - -#define RAW_LOG(level, fmt, ...) \ - do { \ - LOG_FUNCTION_IMPL(level, fmt, ##__VA_ARGS__); \ - } while (0) - -#define LOG(level, fmt, ...) \ - do { \ - if (LOG_TAG) \ - LOG_FUNCTION_IMPL(level, "[%s] " fmt, LOG_TAG, ##__VA_ARGS__); \ - else \ - LOG_FUNCTION_IMPL(level, fmt, ##__VA_ARGS__); \ - } while (0) - -#define INFO_LOG(fmt, ...) \ - do { \ - LOG(LOG_LEVEL_INFO, "[*] " fmt, ##__VA_ARGS__); \ - } while (0) - -#define ERROR_LOG(fmt, ...) \ - do { \ - LOG(LOG_LEVEL_ERROR, "[!] [%s:%d:%s]" fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ - } while (0) - -#define FATAL(fmt, ...) \ - do { \ - LOG(LOG_LEVEL_ERROR, "[!] [%s:%d:%s]" fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ - assert(0); \ - } while (0) - -#if defined(LOGGING_DEBUG) -#define DLOG(level, fmt, ...) LOG(level, fmt, ##__VA_ARGS__) -#else -#define DLOG(level, fmt, ...) -#endif - -#define UNIMPLEMENTED() FATAL("%s\n", "unimplemented code!!!") -#define UNREACHABLE() FATAL("%s\n", "unreachable code!!!") \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/include/dobby.h b/app/src/main/cpp/Dobby/include/dobby.h deleted file mode 100644 index 45ec88b..0000000 --- a/app/src/main/cpp/Dobby/include/dobby.h +++ /dev/null @@ -1,182 +0,0 @@ -#ifndef dobby_h -#define dobby_h - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -void log_set_level(int level); -void log_set_tag(const char *tag); -void log_enable_time_tag(); -void log_switch_to_syslog(); -void log_switch_to_file(const char *path); - -typedef enum { - kMemoryOperationSuccess, - kMemoryOperationError, - kNotSupportAllocateExecutableMemory, - kNotEnough, - kNone -} MemoryOperationError; - -typedef uintptr_t addr_t; -typedef uint32_t addr32_t; -typedef uint64_t addr64_t; -typedef void (*dobby_dummy_func_t)(); -typedef void (*asm_func_t)(); - -MemoryOperationError DobbyCodePatch(void *address, uint8_t *buffer, uint32_t buffer_size); - -#if !defined(DISABLE_ARCH_DETECT) -#if defined(__arm__) -#define TARGET_ARCH_ARM 1 -#elif defined(__arm64__) || defined(__aarch64__) -#define TARGET_ARCH_ARM64 1 -#elif defined(_M_IX86) || defined(__i386__) -#define TARGET_ARCH_IA32 1 -#elif defined(_M_X64) || defined(__x86_64__) -#define TARGET_ARCH_X64 1 -#else -#error Target architecture was not detected as supported by Dobby -#endif -#endif - -#if defined(TARGET_ARCH_ARM) -typedef struct { - uint32_t dummy_0; - uint32_t dummy_1; - - uint32_t dummy_2; - uint32_t sp; - - union { - uint32_t r[13]; - struct { - uint32_t r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12; - } regs; - } general; - - uint32_t lr; -} DobbyRegisterContext; -#elif defined(TARGET_ARCH_ARM64) -#define ARM64_TMP_REG_NDX_0 17 - -typedef union _FPReg { - __int128_t q; - struct { - double d1; - double d2; - } d; - struct { - float f1; - float f2; - float f3; - float f4; - } f; -} FPReg; - -// register context -typedef struct { - uint64_t dmmpy_0; // dummy placeholder - uint64_t sp; - - uint64_t dmmpy_1; // dummy placeholder - union { - uint64_t x[29]; - struct { - uint64_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, - x23, x24, x25, x26, x27, x28; - } regs; - } general; - - uint64_t fp; - uint64_t lr; - - union { - FPReg q[32]; - struct { - FPReg q0, q1, q2, q3, q4, q5, q6, q7; - // [!!! READ ME !!!] - // for Arm64, can't access q8 - q31, unless you enable full floating-point register pack - FPReg q8, q9, q10, q11, q12, q13, q14, q15, q16, q17, q18, q19, q20, q21, q22, q23, q24, q25, q26, q27, q28, q29, - q30, q31; - } regs; - } floating; -} DobbyRegisterContext; -#elif defined(TARGET_ARCH_IA32) -typedef struct _RegisterContext { - uint32_t dummy_0; - uint32_t esp; - - uint32_t dummy_1; - uint32_t flags; - - union { - struct { - uint32_t eax, ebx, ecx, edx, ebp, esp, edi, esi; - } regs; - } general; - -} DobbyRegisterContext; -#elif defined(TARGET_ARCH_X64) -typedef struct { - uint64_t dummy_0; - uint64_t rsp; - - union { - struct { - uint64_t rax, rbx, rcx, rdx, rbp, rsp, rdi, rsi, r8, r9, r10, r11, r12, r13, r14, r15; - } regs; - } general; - - uint64_t dummy_1; - uint64_t flags; -} DobbyRegisterContext; -#endif - -#define RT_FAILED -1 -#define RT_SUCCESS 0 -typedef enum { RS_FAILED = -1, RS_SUCCESS = 0 } RetStatus; - -// DobbyWrap <==> DobbyInstrument, so use DobbyInstrument instead of DobbyWrap -#if 0 -// wrap function with pre_call and post_call -typedef void (*PreCallTy)(DobbyRegisterContext *ctx, const InterceptEntry *info); -typedef void (*PostCallTy)(DobbyRegisterContext *ctx, const InterceptEntry *info); -int DobbyWrap(void *function_address, PreCallTy pre_call, PostCallTy post_call); -#endif - -// function inline hook -int DobbyHook(void *address, dobby_dummy_func_t replace_func, dobby_dummy_func_t *origin_func); - -// dynamic binary instruction instrument -// [!!! READ ME !!!] -// for Arm64, can't access q8 - q31, unless enable full floating-point register pack -typedef void (*dobby_instrument_callback_t)(void *address, DobbyRegisterContext *ctx); -int DobbyInstrument(void *address, dobby_instrument_callback_t pre_handler); - -int DobbyDestroy(void *address); - -const char *DobbyGetVersion(); - -void *DobbySymbolResolver(const char *image_name, const char *symbol_name); - -int DobbyImportTableReplace(char *image_name, char *symbol_name, dobby_dummy_func_t fake_func, - dobby_dummy_func_t *orig_func); - -// [!!! READ ME !!!] -// for arm, Arm64, dobby will try use b xxx instead of ldr absolute indirect branch -// for x64, dobby always use absolute indirect jump -#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) || defined(_M_X64) || defined(__x86_64__) -void dobby_enable_near_branch_trampoline(); -void dobby_disable_near_branch_trampoline(); -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/app/src/main/cpp/Dobby/scripts/Dockerfile b/app/src/main/cpp/Dobby/scripts/Dockerfile deleted file mode 100644 index 149f448..0000000 --- a/app/src/main/cpp/Dobby/scripts/Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -FROM ubuntu:focal - -ARG DEBIAN_FRONTEND='noninteractive' - -RUN apt-key adv --keyserver 'keyserver.ubuntu.com' --recv-key 'C99B11DEB97541F0' && - apt-add-repository -y -u 'https://cli.github.com/packages' && - apt-add-repository 'deb https://apt.kitware.com/ubuntu/ focal main' - -ADD setup_linux_cross_compile.sh /root/setup_linux_cross_compile.sh -RUN sh /root/setup_linux_cross_compile.sh diff --git a/app/src/main/cpp/Dobby/scripts/platform_builder.py b/app/src/main/cpp/Dobby/scripts/platform_builder.py deleted file mode 100644 index ede9d30..0000000 --- a/app/src/main/cpp/Dobby/scripts/platform_builder.py +++ /dev/null @@ -1,240 +0,0 @@ -import os -import pipes -import re -import shutil -import subprocess -import sys -import logging - -import argparse - -platforms = { - "macos": ["x86_64", "arm64", "arm64e"], - "iphoneos": ["arm64", "arm64e"], - "linux": ["x86", "x86_64", "arm", "arm64"], - "android": ["x86", "x86_64", "armeabi-v7a", "arm64-v8a"] -} - - -class PlatformBuilder(object): - cmake_args = list() - cmake_build_type = "Release" - cmake_build_verbose = False - cmake_build_dir = "" - - library_build_type = "static" - - project_dir = "" - output_dir = "" - output_name = "" - - platform = "" - arch = "" - - def __init__(self, project_dir, library_build_type, platform, arch): - self.project_dir = project_dir - self.library_build_type = library_build_type - self.platform = platform - self.arch = arch - - self.cmake_build_dir = f"{self.project_dir}/build/cmake-build-{platform}-{arch}" - self.output_dir = f"{self.project_dir}/build/{platform}/{arch}" - - self.cmake = "cmake" if PlatformBuilder.cmake_dir is None else f"{PlatformBuilder.cmake_dir}/bin/cmake" - self.clang = "clang" if PlatformBuilder.llvm_dir is None else f"{PlatformBuilder.llvm_dir}/bin/clang" - self.clangxx = "clang++" if PlatformBuilder.llvm_dir is None else f"{PlatformBuilder.llvm_dir}/bin/clang++" - - self.setup_common_args() - - def cmake_generate_build_system(self): - cmake_cmd_options = ["-S {}".format(self.project_dir), "-B {}".format(self.cmake_build_dir)] - cmd = [f"{self.cmake}"] + cmake_cmd_options + self.cmake_args - # subprocess.run(cmd, check=True) - cmd_line = " ".join(cmd) - print(cmd_line) - os.system(cmd_line) - - def setup_common_args(self): - self.cmake_args += [f"-DCMAKE_C_COMPILER={self.clang}", f"-DCMAKE_CXX_COMPILER={self.clangxx}"] - - self.cmake_args += ["-DCMAKE_BUILD_TYPE={}".format(self.cmake_build_type)] - - if self.library_build_type == "shared": - self.cmake_args += ["-DDOBBY_GENERATE_SHARED=ON"] - elif self.library_build_type == "static": - self.cmake_args += ["-DDOBBY_GENERATE_SHARED=OFF"] - - def build(self): - subprocess.run(["mkdir", "-p", "{}".format(self.output_dir)], check=True) - self.cmake_generate_build_system() - - subprocess.run(["make", "-j8", "dobby"], cwd=self.cmake_build_dir, check=True) - - os.system(f"mkdir -p {self.output_dir}") - os.system(f"cp {self.cmake_build_dir}/{self.output_name} {self.output_dir}") - - -class WindowsPlatformBuilder(PlatformBuilder): - - def __init__(self, project_dir, library_build_type, platform, arch): - super().__init__(project_dir, library_build_type, platform, arch) - - if self.library_build_type == "shared": - self.output_name = "libdobby.dll" - else: - self.output_name = "libdobby.lib" - - triples = { - "x86": "i686-pc-windows-msvc", - "x64": "x86_64-pc-windows-msvc", - # "arm": "arm-pc-windows-msvc", - "arm64": "arm64-pc-windows-msvc", - } - - # self.cmake_args += ["--target {}".format(triples[arch])] - self.cmake_args += [ - "-DCMAKE_SYSTEM_PROCESSOR={}".format(arch), - ] - - -class LinuxPlatformBuilder(PlatformBuilder): - - def __init__(self, project_dir, library_build_type, arch): - super().__init__(project_dir, library_build_type, "linux", arch) - - if self.library_build_type == "shared": - self.output_name = "libdobby.so" - else: - self.output_name = "libdobby.a" - - targets = { - "x86": "i686-linux-gnu", - "x86_64": "x86_64-linux-gnu", - "arm": "arm-linux-gnueabi", - "aarch64": "aarch64-linux-gnu", - } - - # self.cmake_args += ["--target={}".format(targets[arch])] - self.cmake_args += [ - "-DCMAKE_SYSTEM_NAME=Linux", - "-DCMAKE_SYSTEM_PROCESSOR={}".format(arch), - ] - - -class AndroidPlatformBuilder(PlatformBuilder): - - def __init__(self, android_nkd_dir, project_dir, library_build_type, arch): - super().__init__(project_dir, library_build_type, "android", arch) - - if self.library_build_type == "shared": - self.output_name = "libdobby.so" - else: - self.output_name = "libdobby.a" - - android_api_level = 21 - if arch == "armeabi-v7a" or arch == "x86": - android_api_level = 19 - - self.cmake_args += [ - "-DCMAKE_SYSTEM_NAME=Android", f"-DCMAKE_ANDROID_NDK={android_nkd_dir}", f"-DCMAKE_ANDROID_ARCH_ABI={arch}", - f"-DCMAKE_SYSTEM_VERSION={android_api_level}" - ] - - -class DarwinPlatformBuilder(PlatformBuilder): - - def __init__(self, project_dir, library_build_type, platform, arch): - super().__init__(project_dir, library_build_type, platform, arch) - - self.cmake_args += [ - "-DCMAKE_OSX_ARCHITECTURES={}".format(arch), - "-DCMAKE_SYSTEM_PROCESSOR={}".format(arch), - ] - - if platform == "macos": - self.cmake_args += ["-DCMAKE_SYSTEM_NAME=Darwin"] - elif platform == "iphoneos": - self.cmake_args += ["-DCMAKE_SYSTEM_NAME=iOS", "-DCMAKE_OSX_DEPLOYMENT_TARGET=9.3"] - - if self.library_build_type == "shared": - self.output_name = "libdobby.dylib" - else: - self.output_name = "libdobby.a" - - @classmethod - def lipo_create_fat(cls, project_dir, platform, output_name): - files = list() - archs = platforms[platform] - for arch in archs: - file = f"{project_dir}/build/{platform}/{arch}/{output_name}" - files.append(file) - - cmd = ["lipo", "-create"] + files + ["-output", f"{project_dir}/build/{platform}/{output_name}"] - subprocess.run(cmd, check=True) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("--platform", type=str, required=True) - parser.add_argument("--arch", type=str, required=True) - parser.add_argument("--library_build_type", type=str, default="static") - parser.add_argument("--android_ndk_dir", type=str) - parser.add_argument("--cmake_dir", type=str) - parser.add_argument("--llvm_dir", type=str) - args = parser.parse_args() - - logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s") - - platform = args.platform - arch = args.arch - library_build_type = args.library_build_type - - PlatformBuilder.cmake_dir = args.cmake_dir - PlatformBuilder.llvm_dir = args.llvm_dir - - project_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) - logging.info("project dir: {}".format(project_dir)) - if not os.path.exists(f"{project_dir}/CMakeLists.txt"): - logging.error("Please run this script in Dobby project root directory") - sys.exit(1) - - if platform not in platforms: - logging.error("invalid platform {}".format(platform)) - sys.exit(-1) - - if arch != "all" and arch not in platforms[platform]: - logging.error("invalid arch {} for platform {}".format(arch, platform)) - sys.exit(-1) - - if platform == "android": - if args.android_ndk_dir is None: - logging.error("ndk dir is required for android platform") - sys.exit(-1) - - archs = list() - if arch == "all": - archs = platforms[platform] - else: - archs.append(arch) - logging.info("build platform: {}, archs: {}".format(platform, archs)) - - for arch_ in archs: - if platform == "macos": - builder = DarwinPlatformBuilder(project_dir, library_build_type, platform, arch_) - elif platform == "iphoneos": - builder = DarwinPlatformBuilder(project_dir, library_build_type, platform, arch_) - elif platform == "android": - builder = AndroidPlatformBuilder(args.android_ndk_dir, project_dir, library_build_type, arch_) - elif platform == "linux": - builder = LinuxPlatformBuilder(project_dir, library_build_type, arch_) - else: - logging.error("invalid platform {}".format(platform)) - sys.exit(-1) - logging.info( - f"build platform: {platform}, arch: {arch_}, cmake_build_dir: {builder.cmake_build_dir}, output_dir: {builder.output_dir}" - ) - builder.build() - - if platform in ["iphoneos", "macos"] and arch == "all": - output_name = "libdobby.dylib" if library_build_type == "shared" else "libdobby.a" - DarwinPlatformBuilder.lipo_create_fat(project_dir, platform, output_name) diff --git a/app/src/main/cpp/Dobby/scripts/setup_linux_cross_compile.sh b/app/src/main/cpp/Dobby/scripts/setup_linux_cross_compile.sh deleted file mode 100644 index 9900810..0000000 --- a/app/src/main/cpp/Dobby/scripts/setup_linux_cross_compile.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/sh - -# if error, exit -set - - -sudo apt update -sudo apt-get install -y \ - apt-utils \ - build-essential \ - curl \ - wget \ - unzip \ - gcc-multilib \ - make \ - zsh - -mkdir -p ~/opt - -cd ~/opt -CMAKE_VERSION=3.20.2 -CMAKE_DOWNLOAD_PACKAGE=cmake-$CMAKE_VERSION-linux-x86_64 -wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/$CMAKE_DOWNLOAD_PACKAGE.tar.gz && - tar -zxf $CMAKE_DOWNLOAD_PACKAGE.tar.gz >/dev/null && - mv $CMAKE_DOWNLOAD_PACKAGE cmake-$CMAKE_VERSION -CMAKE_HOME=~/opt/cmake-$CMAKE_VERSION - -cd ~/opt -LLVM_VERSION=14.0.0 -LLVM_DOWNLOAD_PACKAGE=clang+llvm-$LLVM_VERSION-x86_64-linux-gnu-ubuntu-18.04 -wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/$LLVM_DOWNLOAD_PACKAGE.tar.xz && - tar -xf $LLVM_DOWNLOAD_PACKAGE.tar.xz >/dev/null && - mv $LLVM_DOWNLOAD_PACKAGE llvm-$LLVM_VERSION -LLVM_HOME=~/opt/llvm-$LLVM_VERSION - -cd ~/opt -NDK_VERSION=r25b -NDK_DOWNLOAD_PACKAGE=android-ndk-$NDK_VERSION-linux -NDK_DOWNLOAD_UNZIP_PACKAGE=android-ndk-$NDK_VERSION -wget https://dl.google.com/android/repository/$NDK_DOWNLOAD_PACKAGE.zip && - unzip -q $NDK_DOWNLOAD_PACKAGE.zip >/dev/null && - mv $NDK_DOWNLOAD_UNZIP_PACKAGE ndk-$NDK_VERSION && - rm $NDK_DOWNLOAD_PACKAGE.zip -ANDROID_NDK_HOME=~/opt/android-ndk-$NDK_VERSION diff --git a/app/src/main/cpp/Dobby/scripts/setup_macos_cross_compile.sh b/app/src/main/cpp/Dobby/scripts/setup_macos_cross_compile.sh deleted file mode 100644 index 594877b..0000000 --- a/app/src/main/cpp/Dobby/scripts/setup_macos_cross_compile.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh - -# if error, exit -set - - -mkdir -p ~/opt - -cd ~/opt -CMAKE_VERSION=3.20.2 -CMAKE_DOWNLOAD_PACKAGE=cmake-$CMAKE_VERSION-macos-universal -wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/$CMAKE_DOWNLOAD_PACKAGE.tar.gz && - tar -zxf $CMAKE_DOWNLOAD_PACKAGE.tar.gz >/dev/null && - mv $CMAKE_DOWNLOAD_PACKAGE cmake-$CMAKE_VERSION -CMAKE_HOME=~/opt/cmake-$CMAKE_VERSION - -cd ~/opt -LLVM_VERSION=14.0.0 -LLVM_DOWNLOAD_PACKAGE=clang+llvm-$LLVM_VERSION-x86_64-apple-darwin -wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/$LLVM_DOWNLOAD_PACKAGE.tar.xz && - tar -xf $LLVM_DOWNLOAD_PACKAGE.tar.xz >/dev/null && - mv $LLVM_DOWNLOAD_PACKAGE llvm-$LLVM_VERSION -LLVM_HOME=~/opt/llvm-$LLVM_VERSION diff --git a/app/src/main/cpp/Dobby/source/Backend/KernelMode/ExecMemory/clear-cache-tool-all.c b/app/src/main/cpp/Dobby/source/Backend/KernelMode/ExecMemory/clear-cache-tool-all.c deleted file mode 100644 index 495257f..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/KernelMode/ExecMemory/clear-cache-tool-all.c +++ /dev/null @@ -1,3 +0,0 @@ -void ClearCache(void *start, void *end) { - return; -} diff --git a/app/src/main/cpp/Dobby/source/Backend/KernelMode/ExecMemory/code-patch-tool-darwin.cc b/app/src/main/cpp/Dobby/source/Backend/KernelMode/ExecMemory/code-patch-tool-darwin.cc deleted file mode 100644 index fb807ba..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/KernelMode/ExecMemory/code-patch-tool-darwin.cc +++ /dev/null @@ -1,109 +0,0 @@ -#include "dobby_internal.h" - -#include "PlatformUnifiedInterface/ExecMemory/ClearCacheTool.h" - -#include -#include -#include -#include - -#undef max -#undef min -#include - -#define DobbySymbolResolverAuth(o_var, name) \ - do { \ - static void *func_ptr = nullptr; \ - if (func_ptr == nullptr) { \ - func_ptr = DobbySymbolResolver(nullptr, name); \ - if (func_ptr) { \ - func_ptr = ptrauth_strip((void *)func_ptr, ptrauth_key_asia); \ - func_ptr = ptrauth_sign_unauthenticated(func_ptr, ptrauth_key_asia, 0); \ - } \ - } \ - o_var = (typeof(o_var))func_ptr; \ - } while (0); - -#define KERN_RETURN_ERROR(kr, failure) \ - do { \ - if (kr != KERN_SUCCESS) { \ - ERROR_LOG("mach error: %d", kr); \ - return failure; \ - } \ - } while (0); - -PUBLIC MemoryOperationError DobbyCodePatch(void *address, uint8_t *buffer, uint32_t buffer_size) { - if (address == nullptr || buffer == nullptr || buffer_size == 0) { - FATAL("invalid argument"); - return kMemoryOperationError; - } - - kern_return_t kr; - - { - - paddr_t dst_paddr = pmap_kit_kvtophys(kernel_pmap, (vaddr_t)address); - paddr_t src_paddr = pmap_kit_kvtophys(kernel_pmap, (vaddr_t)buffer); - pmap_kit_bcopy_phys((addr_t)buffer, dst_paddr, buffer_size, cppvPsnk); - LOG(0, "bcopy_phys: src: %p, dst: %p", src_paddr, dst_paddr); - - pmap_kit_kva_to_pte(kernel_pmap, (vaddr_t)address); - pmap_kit_set_perm(kernel_pmap, (vaddr_t)address, (vaddr_t)address + PAGE_SIZE, VM_PROT_READ | VM_PROT_EXECUTE); - - if (memcmp(address, buffer, buffer_size)) - return kMemoryOperationError; - } - - if (0) { - vm_map_t self_task = kernel_map; - - int page_size = PAGE_SIZE; - addr_t page_aligned_address = ALIGN_FLOOR(address, page_size); - int offset = (int)((addr_t)address - page_aligned_address); - - mach_vm_address_t remap_dummy_page = 0; - kr = mach_vm_allocate(self_task, &remap_dummy_page, page_size, VM_FLAGS_ANYWHERE); - KERN_RETURN_ERROR(kr, kMemoryOperationError); - - // copy original page - memcpy((void *)remap_dummy_page, (void *)page_aligned_address, page_size); - - // patch buffer - memcpy((void *)(remap_dummy_page + offset), buffer, buffer_size); - - // change permission - kr = mach_vm_protect(self_task, remap_dummy_page, page_size, false, VM_PROT_READ | VM_PROT_EXECUTE); - KERN_RETURN_ERROR(kr, kMemoryOperationError); - - static boolean_t (*vm_map_lookup_entry)(vm_map_t map, vm_map_offset_t address, vm_map_entry_t * entry) = nullptr; - if (vm_map_lookup_entry == nullptr) - vm_map_lookup_entry = (typeof(vm_map_lookup_entry))DobbySymbolResolver(nullptr, "_vm_map_lookup_entry"); - - vm_map_entry_t entry; - kr = vm_map_lookup_entry(kernel_map, (vm_map_offset_t)address, &entry); - KERN_RETURN_ERROR(kr, kMemoryOperationError); - - struct vm_map_entry_flags { - unsigned int dummy_bits : 17, permanent; - }; - struct vm_map_entry_flags *flags = (typeof(flags))((addr_t)entry + 0x48); - if (flags->permanent) { - flags->permanent = 0; - } - - mach_vm_address_t remap_dest_page = page_aligned_address; - vm_prot_t curr_protection, max_protection; - kr = mach_vm_remap(self_task, &remap_dest_page, page_size, 0, VM_FLAGS_OVERWRITE | VM_FLAGS_FIXED, self_task, - remap_dummy_page, TRUE, &curr_protection, &max_protection, VM_INHERIT_COPY); - KERN_RETURN_ERROR(kr, kMemoryOperationError); - - kr = mach_vm_deallocate(self_task, remap_dummy_page, page_size); - KERN_RETURN_ERROR(kr, kMemoryOperationError); - - ClearCache(address, (void *)((addr_t)address + buffer_size)); - flush_dcache((vm_offset_t)address, (vm_size_t)buffer_size, 0); - invalidate_icache((vm_offset_t)address, (vm_size_t)buffer_size, 0); - } - - return kMemoryOperationSuccess; -} diff --git a/app/src/main/cpp/Dobby/source/Backend/KernelMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc b/app/src/main/cpp/Dobby/source/Backend/KernelMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc deleted file mode 100644 index 94745ed..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/KernelMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc +++ /dev/null @@ -1,131 +0,0 @@ -#include "PlatformUtil/ProcessRuntimeUtility.h" - -#include - -typedef struct _loaded_kext_summary { - char name[KMOD_MAX_NAME]; - uuid_t uuid; - uint64_t address; - uint64_t size; - uint64_t version; - uint32_t loadTag; - uint32_t flags; - uint64_t reference_list; - uint64_t text_exec_address; - size_t text_exec_size; -} OSKextLoadedKextSummary; -typedef struct _loaded_kext_summary_header { - uint32_t version; - uint32_t entry_size; - uint32_t numSummaries; - uint32_t reserved; /* explicit alignment for gdb */ - OSKextLoadedKextSummary summaries[0]; -} OSKextLoadedKextSummaryHeader; - -#undef min -#undef max -#include -#include - -#include -#if defined(__LP64__) -typedef struct mach_header_64 mach_header_t; -typedef struct segment_command_64 segment_command_t; -typedef struct section_64 section_t; -typedef struct nlist_64 nlist_t; -#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT_64 -#else -typedef struct mach_header mach_header_t; -typedef struct segment_command segment_command_t; -typedef struct section section_t; -typedef struct nlist nlist_t; -#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT -#endif - -// Generate the name for an offset. -#define KERN_PARAM_OFFSET(type_, member_) __##type_##__##member_##__offset_ -#define KERN_STRUCT_OFFSET KERN_PARAM_OFFSET - -struct vm_map_links { - struct vm_map_entry *prev; - struct vm_map_entry *next; - vm_map_offset_t start; - vm_map_offset_t end; -}; - -struct vm_map_header { - struct vm_map_links links; - uint8_t placeholder_[]; -}; - -static inline vm_map_offset_t vme_start(vm_map_entry_t entry) { - uint KERN_STRUCT_OFFSET(vm_map_entry, links) = 0; - return ((vm_map_header *)((addr_t)entry + KERN_STRUCT_OFFSET(vm_map_entry, links)))->links.start; -} -static inline vm_map_entry_t vm_map_to_entry(vm_map_t map) { - return nullptr; -} -static inline vm_map_entry_t vm_map_first_entry(vm_map_t map) { - uint KERN_STRUCT_OFFSET(vm_map, hdr) = 4; - return ((vm_map_header *)((addr_t)map + KERN_STRUCT_OFFSET(vm_map, hdr)))->links.next; -} - -// --- - -static std::vector regions; -const std::vector &ProcessRuntimeUtility::GetProcessMemoryLayout() { - return regions; -} - -// --- - -#include - -extern "C" void *kernel_info_load_base();; - -std::vector modules; -const std::vector *ProcessRuntimeUtility::GetProcessModuleMap() { - modules.clear(); - - // brute force kernel base ? so rude :) - static void *kernel_base = nullptr; - static OSKextLoadedKextSummaryHeader *_gLoadedKextSummaries = nullptr; - if (kernel_base == nullptr) { - kernel_base = kernel_info_load_base(); - if (kernel_base == nullptr) { - ERROR_LOG("kernel base not found"); - return &modules; - } - LOG(0, "kernel base at: %p", kernel_base); - - extern void *DobbyMachOSymbolResolver(void *header_, const char *symbol_name); - OSKextLoadedKextSummaryHeader **_gLoadedKextSummariesPtr; - _gLoadedKextSummariesPtr = (typeof(_gLoadedKextSummariesPtr))DobbyMachOSymbolResolver(kernel_base, "_gLoadedKextSummaries"); - if (_gLoadedKextSummariesPtr == nullptr) { - ERROR_LOG("failed resolve gLoadedKextSummaries symbol"); - return &modules; - } - _gLoadedKextSummaries = *_gLoadedKextSummariesPtr; - LOG(0, "gLoadedKextSummaries at: %p", _gLoadedKextSummaries); - } - - // only kernel - RuntimeModule module = {0}; - strncpy(module.path, "kernel", sizeof(module.path)); - module.load_address = (void *)kernel_base; - modules.push_back(module); - - // kext - for (int i = 0; i < _gLoadedKextSummaries->numSummaries; ++i) { - strncpy(module.path, _gLoadedKextSummaries->summaries[i].name, sizeof(module.path)); - module.load_address = (void *)_gLoadedKextSummaries->summaries[i].address; - modules.push_back(module); - } - - return &modules; -} - -RuntimeModule ProcessRuntimeUtility::GetProcessModule(const char *name) { - const std::vector *modules = GetProcessModuleMap(); - return RuntimeModule{0}; -} diff --git a/app/src/main/cpp/Dobby/source/Backend/KernelMode/PlatformUtil/ProcessRuntimeUtility.h b/app/src/main/cpp/Dobby/source/Backend/KernelMode/PlatformUtil/ProcessRuntimeUtility.h deleted file mode 100644 index 4bd15c4..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/KernelMode/PlatformUtil/ProcessRuntimeUtility.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "PlatformUnifiedInterface/MemoryAllocator.h" - -#include "UnifiedInterface/platform.h" - -typedef struct _RuntimeModule { - char path[1024]; - void *load_address; -} RuntimeModule; - -struct MemRegion : MemRange { - MemoryPermission permission; - MemRegion(addr_t addr, size_t size, MemoryPermission perm): MemRange(addr, size), permission(perm) { - - } -}; - -class ProcessRuntimeUtility { -public: - static const std::vector &GetProcessMemoryLayout(); - - static const std::vector *GetProcessModuleMap(); - - static RuntimeModule GetProcessModule(const char *name); -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/Backend/KernelMode/UnifiedInterface/exec_mem_placeholder.asm b/app/src/main/cpp/Dobby/source/Backend/KernelMode/UnifiedInterface/exec_mem_placeholder.asm deleted file mode 100644 index 137da1e..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/KernelMode/UnifiedInterface/exec_mem_placeholder.asm +++ /dev/null @@ -1,10 +0,0 @@ -#include - -#define PAGE_SHIFT 14 -.align PAGE_SHIFT - - .globl EXT(kernel_executable_memory_placeholder) -EXT(kernel_executable_memory_placeholder): -.rept 0x4000/4 -.long 0x41414141 -.endr \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/Backend/KernelMode/UnifiedInterface/platform-darwin.cc b/app/src/main/cpp/Dobby/source/Backend/KernelMode/UnifiedInterface/platform-darwin.cc deleted file mode 100644 index f0c217d..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/KernelMode/UnifiedInterface/platform-darwin.cc +++ /dev/null @@ -1,106 +0,0 @@ -#include "UnifiedInterface/platform.h" - -#include -#include -#include -#include - -// ================================================================ -// base :: OSMemory - -static int GetProtectionFromMemoryPermission(MemoryPermission access) { - switch (access) { - case MemoryPermission::kNoAccess: - return PROT_NONE; - case MemoryPermission::kRead: - return PROT_READ; - case MemoryPermission::kReadWrite: - return PROT_READ | PROT_WRITE; - case MemoryPermission::kReadWriteExecute: - return PROT_READ | PROT_WRITE | PROT_EXEC; - case MemoryPermission::kReadExecute: - return PROT_READ | PROT_EXEC; - } - UNREACHABLE(); -} - -int OSMemory::PageSize() { - return static_cast(0x4000); -} - -void *OSMemory::Allocate(size_t size, MemoryPermission access) { - return OSMemory::Allocate(size, access, nullptr); -} - -extern "C" void *kernel_executable_memory_placeholder; -void *OSMemory::Allocate(size_t size, MemoryPermission access, void *fixed_address) { - int prot = GetProtectionFromMemoryPermission(access); - - void *addr = nullptr; - int flags = VM_FLAGS_ANYWHERE; - if (fixed_address != nullptr) { - flags = VM_FLAGS_FIXED; - addr = fixed_address; - } - - // fixme: wire at pmap - if (prot & PROT_EXEC || prot == PROT_NONE) { - addr = &kernel_executable_memory_placeholder; - } else { - kern_return_t ret = mach_vm_allocate(kernel_map, (mach_vm_address_t *)&addr, size, flags); - if (ret != KERN_SUCCESS) { - panic("mach_vm_allocate"); - return nullptr; - } - ret = vm_map_wire(kernel_map, (mach_vm_address_t)addr, (mach_vm_address_t)addr + size, PROT_NONE, false); - if (ret != KERN_SUCCESS) { - panic("vm_map_wire"); - return nullptr; - } - - // make fault before at rw prot - bzero(addr, size); - { memcpy(addr, "AAAAAAAA", 8); } - - if (access == kNoAccess) { - access = kReadExecute; - } - if (!OSMemory::SetPermission((void *)addr, size, access)) { - OSMemory::Free(addr, size); - return nullptr; - } - - { - if (memcmp(addr, "AAAAAAAA", 8) != 0) { - return nullptr; - } - } - } - - return addr; -} - -bool OSMemory::Free(void *address, size_t size) { - DCHECK_EQ(0, reinterpret_cast(address) % PageSize()); - DCHECK_EQ(0, size % PageSize()); - - auto ret = mach_vm_deallocate(kernel_map, (mach_vm_address_t)address, size); - return ret == KERN_SUCCESS; -} - -bool OSMemory::Release(void *address, size_t size) { - DCHECK_EQ(0, reinterpret_cast(address) % PageSize()); - DCHECK_EQ(0, size % PageSize()); - - auto ret = mach_vm_deallocate(kernel_map, (mach_vm_address_t)address, size); - return ret == KERN_SUCCESS; -} - -bool OSMemory::SetPermission(void *address, size_t size, MemoryPermission access) { - DCHECK_EQ(0, reinterpret_cast(address) % PageSize()); - DCHECK_EQ(0, size % PageSize()); - - int prot = GetProtectionFromMemoryPermission(access); - auto ret = mach_vm_protect(kernel_map, (mach_vm_address_t)address, size, false, prot); - return ret == KERN_SUCCESS; -} diff --git a/app/src/main/cpp/Dobby/source/Backend/KernelMode/UnifiedInterface/platform.h b/app/src/main/cpp/Dobby/source/Backend/KernelMode/UnifiedInterface/platform.h deleted file mode 100644 index 723a460..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/KernelMode/UnifiedInterface/platform.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef PLATFORM_INTERFACE_COMMON_PLATFORM_H -#define PLATFORM_INTERFACE_COMMON_PLATFORM_H - -#include "common_header.h" - -// ================================================================ -// base :: OSMemory - -enum MemoryPermission { kNoAccess, kRead, kReadWrite, kReadWriteExecute, kReadExecute }; - -class OSMemory { -public: - static int PageSize(); - - static void *Allocate(size_t size, MemoryPermission access); - - static void *Allocate(size_t size, MemoryPermission access, void *fixed_address); - - static bool Free(void *address, size_t size); - - static bool Release(void *address, size_t size); - - static bool SetPermission(void *address, size_t size, MemoryPermission access); -}; - -#endif diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/clear-cache-tool-all.c b/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/clear-cache-tool-all.c deleted file mode 100644 index 413ef48..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/clear-cache-tool-all.c +++ /dev/null @@ -1,145 +0,0 @@ -//===-- clear_cache.c - Implement __clear_cache ---------------------------===// -// -// 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 - -#if __APPLE__ -#include -#endif - -#if defined(_WIN32) -// Forward declare Win32 APIs since the GCC mode driver does not handle the -// newer SDKs as well as needed. -uint32_t FlushInstructionCache(uintptr_t hProcess, void *lpBaseAddress, uintptr_t dwSize); -uintptr_t GetCurrentProcess(void); -#endif - -// The compiler generates calls to __clear_cache() when creating -// trampoline functions on the stack for use with nested functions. -// It is expected to invalidate the instruction cache for the -// specified range. - -void _clear_cache(void *start, void *end) { -#if __i386__ || __x86_64__ || defined(_M_IX86) || defined(_M_X64) -// Intel processors have a unified instruction and data cache -// so there is nothing to do -#elif defined(_WIN32) && (defined(__arm__) || defined(__aarch64__)) - FlushInstructionCache(GetCurrentProcess(), start, end - start); -#elif defined(__arm__) && !defined(__APPLE__) -#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) - struct arm_sync_icache_args arg; - - arg.addr = (uintptr_t)start; - arg.len = (uintptr_t)end - (uintptr_t)start; - - sysarch(ARM_SYNC_ICACHE, &arg); -#elif defined(__linux__) -// We used to include asm/unistd.h for the __ARM_NR_cacheflush define, but -// it also brought many other unused defines, as well as a dependency on -// kernel headers to be installed. -// -// This value is stable at least since Linux 3.13 and should remain so for -// compatibility reasons, warranting it's re-definition here. -#define __ARM_NR_cacheflush 0x0f0002 - register int start_reg __asm("r0") = (int)(intptr_t)start; - const register int end_reg __asm("r1") = (int)(intptr_t)end; - const register int flags __asm("r2") = 0; - const register int syscall_nr __asm("r7") = __ARM_NR_cacheflush; - __asm __volatile("svc 0x0" : "=r"(start_reg) : "r"(syscall_nr), "r"(start_reg), "r"(end_reg), "r"(flags)); - assert(start_reg == 0 && "Cache flush syscall failed."); -#else - compilerrt_abort(); -#endif -#elif defined(__linux__) && defined(__mips__) - const uintptr_t start_int = (uintptr_t)start; - const uintptr_t end_int = (uintptr_t)end; - syscall(__NR_cacheflush, start, (end_int - start_int), BCACHE); -#elif defined(__mips__) && defined(__OpenBSD__) - cacheflush(start, (uintptr_t)end - (uintptr_t)start, BCACHE); -#elif defined(__aarch64__) && !defined(__APPLE__) - uint64_t xstart = (uint64_t)(uintptr_t)start; - uint64_t xend = (uint64_t)(uintptr_t)end; - - // Get Cache Type Info. - static uint64_t ctr_el0 = 0; - if (ctr_el0 == 0) - __asm __volatile("mrs %0, ctr_el0" : "=r"(ctr_el0)); - - // The DC and IC instructions must use 64-bit registers so we don't use - // uintptr_t in case this runs in an IPL32 environment. - uint64_t addr; - - // If CTR_EL0.IDC is set, data cache cleaning to the point of unification - // is not required for instruction to data coherence. - if (((ctr_el0 >> 28) & 0x1) == 0x0) { - const size_t dcache_line_size = 4 << ((ctr_el0 >> 16) & 15); - for (addr = xstart & ~(dcache_line_size - 1); addr < xend; addr += dcache_line_size) - __asm __volatile("dc cvau, %0" ::"r"(addr)); - } - __asm __volatile("dsb ish"); - - // If CTR_EL0.DIC is set, instruction cache invalidation to the point of - // unification is not required for instruction to data coherence. - if (((ctr_el0 >> 29) & 0x1) == 0x0) { - const size_t icache_line_size = 4 << ((ctr_el0 >> 0) & 15); - for (addr = xstart & ~(icache_line_size - 1); addr < xend; addr += icache_line_size) - __asm __volatile("ic ivau, %0" ::"r"(addr)); - __asm __volatile("dsb ish"); - } - __asm __volatile("isb sy"); -#elif defined(__powerpc64__) - const size_t line_size = 32; - const size_t len = (uintptr_t)end - (uintptr_t)start; - - const uintptr_t mask = ~(line_size - 1); - const uintptr_t start_line = ((uintptr_t)start) & mask; - const uintptr_t end_line = ((uintptr_t)start + len + line_size - 1) & mask; - - for (uintptr_t line = start_line; line < end_line; line += line_size) - __asm__ volatile("dcbf 0, %0" : : "r"(line)); - __asm__ volatile("sync"); - - for (uintptr_t line = start_line; line < end_line; line += line_size) - __asm__ volatile("icbi 0, %0" : : "r"(line)); - __asm__ volatile("isync"); -#elif defined(__sparc__) - const size_t dword_size = 8; - const size_t len = (uintptr_t)end - (uintptr_t)start; - - const uintptr_t mask = ~(dword_size - 1); - const uintptr_t start_dword = ((uintptr_t)start) & mask; - const uintptr_t end_dword = ((uintptr_t)start + len + dword_size - 1) & mask; - - for (uintptr_t dword = start_dword; dword < end_dword; dword += dword_size) - __asm__ volatile("flush %0" : : "r"(dword)); -#elif defined(__riscv) && defined(__linux__) - // See: arch/riscv/include/asm/cacheflush.h, arch/riscv/kernel/sys_riscv.c - register void *start_reg __asm("a0") = start; - const register void *end_reg __asm("a1") = end; - // "0" means that we clear cache for all threads (SYS_RISCV_FLUSH_ICACHE_ALL) - const register long flags __asm("a2") = 0; - const register long syscall_nr __asm("a7") = __NR_riscv_flush_icache; - __asm __volatile("ecall" : "=r"(start_reg) : "r"(start_reg), "r"(end_reg), "r"(flags), "r"(syscall_nr)); - assert(start_reg == 0 && "Cache flush syscall failed."); -#else -#if __APPLE__ - // On Darwin, sys_icache_invalidate() provides this functionality - sys_icache_invalidate(start, end - start); -#elif defined(__ve__) - __asm__ volatile("fencec 2"); -#else - compilerrt_abort(); -#endif -#endif -} - -void ClearCache(void *start, void *end) { - return _clear_cache(start, end); -} diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/clear-cache-tool/clear-cache-tool-arm-dummy.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/clear-cache-tool/clear-cache-tool-arm-dummy.cc deleted file mode 100644 index abe26c4..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/clear-cache-tool/clear-cache-tool-arm-dummy.cc +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef USER_MODE_CLEAR_CACHE_TOOL_H -#define USER_MODE_CLEAR_CACHE_TOOL_H - -#include "core/arch/Cpu.h" - -#include "PlatformInterface/globals.h" - -#if !HOST_OS_IOS -#include // for cache flushing. -#endif - -void CpuFeatures::FlushICache(void *startp, void *endp) { - -#if HOST_OS_IOS - // Precompilation never patches code so there should be no I cache flushes. - CpuFeatures::ClearCache(startp, endp); - -#else - - register uint32_t beg asm("r0") = reinterpret_cast(startp); - register uint32_t end asm("r1") = reinterpret_cast(endp); - register uint32_t flg asm("r2") = 0; - -#ifdef __clang__ - // This variant of the asm avoids a constant pool entry, which can be - // problematic when LTO'ing. It is also slightly shorter. - register uint32_t scno asm("r7") = __ARM_NR_cacheflush; - - asm volatile("svc 0\n" : : "r"(beg), "r"(end), "r"(flg), "r"(scno) : "memory"); -#else - // Use a different variant of the asm with GCC because some versions doesn't - // support r7 as an asm input. - asm volatile( - // This assembly works for both ARM and Thumb targets. - - // Preserve r7; it is callee-saved, and GCC uses it as a frame pointer for - // Thumb targets. - " push {r7}\n" - // r0 = beg - // r1 = end - // r2 = flags (0) - " ldr r7, =%c[scno]\n" // r7 = syscall number - " svc 0\n" - - " pop {r7}\n" - : - : "r"(beg), "r"(end), "r"(flg), [scno] "i"(__ARM_NR_cacheflush) - : "memory"); -#endif -#endif -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/clear-cache-tool/clear-cache-tool-arm64-dummy.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/clear-cache-tool/clear-cache-tool-arm64-dummy.cc deleted file mode 100644 index 60580a5..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/clear-cache-tool/clear-cache-tool-arm64-dummy.cc +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef USER_MODE_CLEAR_CACHE_TOOL_ARM64_H -#define USER_MODE_CLEAR_CACHE_TOOL_ARM64_H - -#include "core/arch/Cpu.h" - -#include "PlatformInterface/globals.h" - -class CacheLineSizes { -public: - CacheLineSizes() { - // Copy the content of the cache type register to a core register. - __asm__ __volatile__("mrs %x[ctr], ctr_el0" // NOLINT - : [ctr] "=r"(cache_type_register_)); - } - - uint32_t icache_line_size() const { - return ExtractCacheLineSize(0); - } - uint32_t dcache_line_size() const { - return ExtractCacheLineSize(16); - } - -private: - uint32_t ExtractCacheLineSize(int cache_line_size_shift) const { - // The cache type register holds the size of cache lines in words as a - // power of two. - return 4 << ((cache_type_register_ >> cache_line_size_shift) & 0xF); - } - - uint32_t cache_type_register_; -}; - -void CpuFeatures::FlushICache(void *startp, void *endp) { - // The code below assumes user space cache operations are allowed. The goal - // of this routine is to make sure the code generated is visible to the I - // side of the CPU. - -#if HOST_OS_IOS - // Precompilation never patches code so there should be no I cache flushes. - CpuFeatures::ClearCache(startp, endp); -#else - uintptr_t start = reinterpret_cast(startp); - // Sizes will be used to generate a mask big enough to cover a pointer. - CacheLineSizes sizes; - uintptr_t dsize = sizes.dcache_line_size(); - uintptr_t isize = sizes.icache_line_size(); - // Cache line sizes are always a power of 2. - uintptr_t dstart = start & ~(dsize - 1); - uintptr_t istart = start & ~(isize - 1); - uintptr_t end = reinterpret_cast(endp); - - __asm__ __volatile__( // NOLINT - // Clean every line of the D cache containing the target data. - "0: \n\t" - // dc : Data Cache maintenance - // c : Clean - // i : Invalidate - // va : by (Virtual) Address - // c : to the point of Coherency - // See ARM DDI 0406B page B2-12 for more information. - // We would prefer to use "cvau" (clean to the point of unification) here - // but we use "civac" to work around Cortex-A53 errata 819472, 826319, - // 827319 and 824069. - "dc civac, %[dline] \n\t" - "add %[dline], %[dline], %[dsize] \n\t" - "cmp %[dline], %[end] \n\t" - "b.lt 0b \n\t" - // Barrier to make sure the effect of the code above is visible to the rest - // of the world. - // dsb : Data Synchronisation Barrier - // ish : Inner SHareable domain - // The point of unification for an Inner Shareable shareability domain is - // the point by which the instruction and data caches of all the processors - // in that Inner Shareable shareability domain are guaranteed to see the - // same copy of a memory location. See ARM DDI 0406B page B2-12 for more - // information. - "dsb ish \n\t" - // Invalidate every line of the I cache containing the target data. - "1: \n\t" - // ic : instruction cache maintenance - // i : invalidate - // va : by address - // u : to the point of unification - "ic ivau, %[iline] \n\t" - "add %[iline], %[iline], %[isize] \n\t" - "cmp %[iline], %[end] \n\t" - "b.lt 1b \n\t" - // Barrier to make sure the effect of the code above is visible to the rest - // of the world. - "dsb ish \n\t" - // Barrier to ensure any prefetching which happened before this code is - // discarded. - // isb : Instruction Synchronisation Barrier - "isb \n\t" - : [dline] "+r"(dstart), [iline] "+r"(istart) - : [dsize] "r"(dsize), [isize] "r"(isize), [end] "r"(end) - // This code does not write to memory but without the dependency gcc might - // move this code before the code is generated. - : "cc", "memory"); // NOLINT -#endif -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/code-patch-tool-darwin.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/code-patch-tool-darwin.cc deleted file mode 100644 index 086cf6a..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/code-patch-tool-darwin.cc +++ /dev/null @@ -1,81 +0,0 @@ -#include "dobby_internal.h" - -#include "PlatformUnifiedInterface/ExecMemory/ClearCacheTool.h" - -#include - -#include -#include "UnifiedInterface/platform-darwin/mach_vm.h" - -#if defined(__APPLE__) -#include -#include -#endif - -#define KERN_RETURN_ERROR(kr, failure) \ - do { \ - if (kr != KERN_SUCCESS) { \ - ERROR_LOG("mach error: %s", mach_error_string(kr)); \ - return failure; \ - } \ - } while (0); - -PUBLIC MemoryOperationError DobbyCodePatch(void *address, uint8_t *buffer, uint32_t buffer_size) { - if (address == nullptr || buffer == nullptr || buffer_size == 0) { - FATAL("invalid argument"); - return kMemoryOperationError; - } - - int page_size = PAGE_SIZE; - addr_t patch_page = ALIGN_FLOOR(address, page_size); - - // cross over page - if ((addr_t)address + buffer_size > patch_page + page_size) { - MemoryOperationError err = kMemoryOperationSuccess; - - void *address_a = address; - uint8_t *buffer_a = buffer; - uint32_t buffer_size_a = (patch_page + page_size - (addr_t)address); - err = DobbyCodePatch(address_a, buffer_a, buffer_size_a); - if (err != kMemoryOperationSuccess) { - return err; - } - - void *address_b = (void *)((addr_t)address + buffer_size_a); - uint8_t *buffer_b = buffer + buffer_size_a; - uint32_t buffer_size_b = buffer_size - buffer_size_a; - err = DobbyCodePatch(address_b, buffer_b, buffer_size_b); - return err; - } - - kern_return_t kr; - vm_map_t self_task = mach_task_self(); - - mach_vm_address_t remap_dummy_page = 0; - kr = mach_vm_allocate(self_task, &remap_dummy_page, page_size, VM_FLAGS_ANYWHERE); - KERN_RETURN_ERROR(kr, kMemoryOperationError); - - // copy original page - memcpy((void *)remap_dummy_page, (void *)patch_page, page_size); - - // patch buffer - int offset = (int)((addr_t)address - patch_page); - memcpy((void *)(remap_dummy_page + offset), buffer, buffer_size); - - // change permission - kr = mach_vm_protect(self_task, remap_dummy_page, page_size, false, VM_PROT_READ | VM_PROT_EXECUTE); - KERN_RETURN_ERROR(kr, kMemoryOperationError); - - mach_vm_address_t remap_dest_page = patch_page; - vm_prot_t curr_protection, max_protection; - kr = mach_vm_remap(self_task, &remap_dest_page, page_size, 0, VM_FLAGS_OVERWRITE | VM_FLAGS_FIXED, self_task, - remap_dummy_page, TRUE, &curr_protection, &max_protection, VM_INHERIT_COPY); - KERN_RETURN_ERROR(kr, kMemoryOperationError); - - kr = mach_vm_deallocate(self_task, remap_dummy_page, page_size); - KERN_RETURN_ERROR(kr, kMemoryOperationError); - - ClearCache(address, (void *)((addr_t)address + buffer_size)); - - return kMemoryOperationSuccess; -} diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/code-patch-tool-posix.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/code-patch-tool-posix.cc deleted file mode 100644 index ccb948b..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/code-patch-tool-posix.cc +++ /dev/null @@ -1,37 +0,0 @@ - -#include "dobby_internal.h" -#include "core/arch/Cpu.h" - -#include -#include -#include - -#if !defined(__APPLE__) -PUBLIC MemoryOperationError DobbyCodePatch(void *address, uint8_t *buffer, uint32_t buffer_size) { -#if defined(__ANDROID__) || defined(__linux__) - int page_size = (int)sysconf(_SC_PAGESIZE); - uintptr_t patch_page = ALIGN_FLOOR(address, page_size); - uintptr_t patch_end_page = ALIGN_FLOOR((uintptr_t)address + buffer_size, page_size); - - // change page permission as rwx - mprotect((void *)patch_page, page_size, PROT_READ | PROT_WRITE | PROT_EXEC); - if (patch_page != patch_end_page) { - mprotect((void *)patch_end_page, page_size, PROT_READ | PROT_WRITE | PROT_EXEC); - } - - // patch buffer - memcpy(address, buffer, buffer_size); - - // restore page permission - mprotect((void *)patch_page, page_size, PROT_READ | PROT_EXEC); - if (patch_page != patch_end_page) { - mprotect((void *)patch_end_page, page_size, PROT_READ | PROT_EXEC); - } - - addr_t clear_start_ = (addr_t)address; - ClearCache((void *)clear_start_, (void *)(clear_start_ + buffer_size)); -#endif - return kMemoryOperationSuccess; -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/code-patch-tool-windows.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/code-patch-tool-windows.cc deleted file mode 100644 index 21ec8e2..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/code-patch-tool-windows.cc +++ /dev/null @@ -1,27 +0,0 @@ -#include "dobby_internal.h" - -#include - -using namespace zz; - -PUBLIC MemoryOperationError DobbyCodePatch(void *address, uint8_t *buffer, uint32_t buffer_size) { - DWORD oldProtect; - int page_size; - - // Get page size - SYSTEM_INFO si; - GetSystemInfo(&si); - page_size = si.dwPageSize; - - void *addressPageAlign = (void *)ALIGN(address, page_size); - - if (!VirtualProtect(addressPageAlign, page_size, PAGE_EXECUTE_READWRITE, &oldProtect)) - return kMemoryOperationError; - - memcpy(address, buffer, buffer_size); - - if (!VirtualProtect(addressPageAlign, page_size, oldProtect, &oldProtect)) - return kMemoryOperationError; - - return kMemoryOperationSuccess; -} diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/substrated/mach_interface_support/substrated.defs b/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/substrated/mach_interface_support/substrated.defs deleted file mode 100644 index f8b1640..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/substrated/mach_interface_support/substrated.defs +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Regenerate with: - * - * $(xcrun --sdk macosx -f mig) \ - * -isysroot $(xcrun --sdk macosx --show-sdk-path) \ - * -sheader substratedserver.h \ - * -server substratedserver.c \ - * -header substratedclient.h \ - * -user substratedclient.c \ - * substrated.defs - */ - -subsystem substrated 9000; - -#include -#include - -routine substrated_mark ( - server : mach_port_t; - task : vm_task_entry_t; - source_address : mach_vm_address_t; - source_size : mach_vm_size_t; - inout target_address : mach_vm_address_t -); diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/MultiThreadSupport/ThreadSupport.cpp b/app/src/main/cpp/Dobby/source/Backend/UserMode/MultiThreadSupport/ThreadSupport.cpp deleted file mode 100644 index 30be99c..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/MultiThreadSupport/ThreadSupport.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "MultiThreadSupport/ThreadSupport.h" - -using namespace zz; - -OSThread::LocalStorageKey ThreadSupport::thread_callstack_key_ = 0; - -// Get current CallStack -CallStack *ThreadSupport::CurrentThreadCallStack() { - - // TODO: __attribute__((destructor)) is better ? - if (!thread_callstack_key_) { - thread_callstack_key_ = OSThread::CreateThreadLocalKey(); - } - - if (OSThread::HasThreadLocal(thread_callstack_key_)) { - return static_cast(OSThread::GetThreadLocal(thread_callstack_key_)); - } else { - CallStack *callstack = new CallStack(); - OSThread::SetThreadLocal(thread_callstack_key_, callstack); - return callstack; - } -} diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/MultiThreadSupport/ThreadSupport.h b/app/src/main/cpp/Dobby/source/Backend/UserMode/MultiThreadSupport/ThreadSupport.h deleted file mode 100644 index 6538d8f..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/MultiThreadSupport/ThreadSupport.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef USER_MODE_MULTI_THREAD_SUPPORT_H -#define USER_MODE_MULTI_THREAD_SUPPORT_H - -#include -#include - -#include "dobby_internal.h" - -#include "source/Backend/UserMode/Thread/PlatformThread.h" - -// StackFrame base in CallStack -typedef struct _StackFrame { - // context between `pre_call` and `post_call` - std::map kv_context; - // origin function ret address - void *orig_ret; -} StackFrame; - -// (thead) CallStack base in thread -typedef struct _CallStack { - std::vector stackframes; -} CallStack; - -// ThreadSupport base on vm_core, support mutipl platforms. -class ThreadSupport { -public: - // Push stack frame - static void PushStackFrame(StackFrame *stackframe) { - CallStack *callstack = ThreadSupport::CurrentThreadCallStack(); - callstack->stackframes.push_back(stackframe); - } - - // Pop stack frame - static StackFrame *PopStackFrame() { - CallStack *callstack = ThreadSupport::CurrentThreadCallStack(); - StackFrame *stackframe = callstack->stackframes.back(); - callstack->stackframes.pop_back(); - return stackframe; - } - - // ===== - static void SetStackFrameContextValue(StackFrame *stackframe, char *key, void *value) { - std::map *kv_context = &stackframe->kv_context; - kv_context->insert(std::pair(key, value)); - }; - - static void *GetStackFrameContextValue(StackFrame *stackframe, char *key) { - std::map kv_context = stackframe->kv_context; - std::map::iterator it; - it = kv_context.find(key); - if (it != kv_context.end()) { - return (void *)it->second; - } - return NULL; - }; - - static CallStack *CurrentThreadCallStack(); - -private: - static zz::OSThread::LocalStorageKey thread_callstack_key_; -}; - -#endif diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc deleted file mode 100644 index 07ab59d..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc +++ /dev/null @@ -1,132 +0,0 @@ -#include "dobby_internal.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "UnifiedInterface/platform-darwin/mach_vm.h" -#include "PlatformUtil/ProcessRuntimeUtility.h" - -static bool memory_region_comparator(MemRegion a, MemRegion b) { - return (a.start < b.start); -} - -std::vector regions; - -const std::vector &ProcessRuntimeUtility::GetProcessMemoryLayout() { - regions.clear(); - - vm_region_submap_info_64 region_submap_info; - mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT_64; - mach_vm_address_t addr = 0; - mach_vm_size_t size = 0; - natural_t depth = 0; - while (true) { - count = VM_REGION_SUBMAP_INFO_COUNT_64; - kern_return_t kr = mach_vm_region_recurse(mach_task_self(), (mach_vm_address_t *)&addr, (mach_vm_size_t *)&size, &depth, (vm_region_recurse_info_t)®ion_submap_info, &count); - if (kr != KERN_SUCCESS) { - if (kr == KERN_INVALID_ADDRESS) { - break; - } else { - break; - } - } - - if (region_submap_info.is_submap) { - depth++; - } else { - MemoryPermission permission; - if ((region_submap_info.protection & PROT_READ) && (region_submap_info.protection & PROT_WRITE)) { - permission = MemoryPermission::kReadWrite; - } else if ((region_submap_info.protection & PROT_READ) == region_submap_info.protection) { - permission = MemoryPermission::kRead; - } else if ((region_submap_info.protection & PROT_READ) && (region_submap_info.protection & PROT_EXEC)) { - permission = MemoryPermission::kReadExecute; - } else { - permission = MemoryPermission::kNoAccess; - } -#if 0 - DLOG(0, "%p --- %p", addr, addr + size); -#endif - MemRegion region = MemRegion(addr, size, permission); - regions.push_back(region); - addr += size; - } - } - - // std::sort(ProcessMemoryLayout.begin(), ProcessMemoryLayout.end(), memory_region_comparator); - - return regions; -} - -static std::vector *modules; - -const std::vector &ProcessRuntimeUtility::GetProcessModuleMap() { - if (modules == nullptr) { - modules = new std::vector(); - } - modules->clear(); - - kern_return_t kr; - task_dyld_info_data_t task_dyld_info; - mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT; - kr = task_info(mach_task_self_, TASK_DYLD_INFO, (task_info_t)&task_dyld_info, &count); - if (kr != KERN_SUCCESS) { - return *modules; - } - - struct dyld_all_image_infos *infos = (struct dyld_all_image_infos *)task_dyld_info.all_image_info_addr; - const struct dyld_image_info *infoArray = infos->infoArray; - uint32_t infoArrayCount = infos->infoArrayCount; - - RuntimeModule module = {0}; - strncpy(module.path, "dummy-placeholder-module", sizeof(module.path)); - module.load_address = 0; - modules->push_back(module); - - for (int i = 0; i < infoArrayCount; ++i) { - const struct dyld_image_info *info = &infoArray[i]; - - { - strncpy(module.path, info->imageFilePath, sizeof(module.path)); - module.load_address = (void *)info->imageLoadAddress; - modules->push_back(module); - } - } - - return *modules; -} - -RuntimeModule ProcessRuntimeUtility::GetProcessModule(const char *name) { - auto modules = GetProcessModuleMap(); - for (auto module : modules) { - if (strstr(module.path, name) != 0) { - return module; - } - } - return RuntimeModule{0}; -} diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/Linux/ProcessRuntimeUtility.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/Linux/ProcessRuntimeUtility.cc deleted file mode 100644 index 218b8ec..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/Linux/ProcessRuntimeUtility.cc +++ /dev/null @@ -1,244 +0,0 @@ -#include "PlatformUtil/ProcessRuntimeUtility.h" - -#include -#include -#include -#include - -#include -#include - -#include -#include - -#define LINE_MAX 2048 - -// ================================================================ -// GetProcessMemoryLayout - -static bool memory_region_comparator(MemRange a, MemRange b) { - return (a.start < b.start); -} - -std::vector regions; -const std::vector &ProcessRuntimeUtility::GetProcessMemoryLayout() { - regions.clear(); - - FILE *fp = fopen("/proc/self/maps", "r"); - if (fp == nullptr) - return regions; - - while (!feof(fp)) { - char line_buffer[LINE_MAX + 1]; - fgets(line_buffer, LINE_MAX, fp); - - // ignore the rest of characters - if (strlen(line_buffer) == LINE_MAX && line_buffer[LINE_MAX] != '\n') { - // Entry not describing executable data. Skip to end of line to set up - // reading the next entry. - int c; - do { - c = getc(fp); - } while ((c != EOF) && (c != '\n')); - if (c == EOF) - break; - } - - addr_t region_start, region_end; - addr_t region_offset; - char permissions[5] = {'\0'}; // Ensure NUL-terminated string. - uint8_t dev_major = 0; - uint8_t dev_minor = 0; - long inode = 0; - int path_index = 0; - - // Sample format from man 5 proc: - // - // address perms offset dev inode pathname - // 08048000-08056000 r-xp 00000000 03:0c 64593 /usr/sbin/gpm - // - // The final %n term captures the offset in the input string, which is used - // to determine the path name. It *does not* increment the return value. - // Refer to man 3 sscanf for details. - if (sscanf(line_buffer, - "%" PRIxPTR "-%" PRIxPTR " %4c " - "%" PRIxPTR " %hhx:%hhx %ld %n", - ®ion_start, ®ion_end, permissions, ®ion_offset, &dev_major, &dev_minor, &inode, - &path_index) < 7) { - FATAL("/proc/self/maps parse failed!"); - fclose(fp); - return regions; - } - - MemoryPermission permission; - if (permissions[0] == 'r' && permissions[1] == 'w') { - permission = MemoryPermission::kReadWrite; - } else if (permissions[0] == 'r' && permissions[2] == 'x') { - permission = MemoryPermission::kReadExecute; - } else if (permissions[0] == 'r' && permissions[1] == 'w' && permissions[2] == 'x') { - permission = MemoryPermission::kReadWriteExecute; - } else { - permission = MemoryPermission::kNoAccess; - } - -#if 0 - DLOG(0, "%p --- %p", region_start, region_end); -#endif - - MemRegion region = MemRegion(region_start,region_end - region_start, permission); - regions.push_back(region); - } - std::qsort(®ions[0], regions.size(), sizeof(MemRegion), - +[](const void* a, const void* b) -> int { - const auto *i = static_cast(a); - const auto *j = static_cast(b); - if ((addr_t)i->start < (addr_t)j->start) return -1; - if ((addr_t)i->start > (addr_t)j->start) return 1; - return 0; - }); - - fclose(fp); - return regions; -} - -// ================================================================ -// GetProcessModuleMap - -static std::vector *modules; -static std::vector &get_process_map_with_proc_maps() { - if(modules == nullptr) { - modules = new std::vector(); - } - - FILE *fp = fopen("/proc/self/maps", "r"); - if (fp == nullptr) - return *modules; - - while (!feof(fp)) { - char line_buffer[LINE_MAX + 1]; - fgets(line_buffer, LINE_MAX, fp); - - // ignore the rest of characters - if (strlen(line_buffer) == LINE_MAX && line_buffer[LINE_MAX] != '\n') { - // Entry not describing executable data. Skip to end of line to set up - // reading the next entry. - int c; - do { - c = getc(fp); - } while ((c != EOF) && (c != '\n')); - if (c == EOF) - break; - } - - addr_t region_start, region_end; - addr_t region_offset; - char permissions[5] = {'\0'}; // Ensure NUL-terminated string. - uint8_t dev_major = 0; - uint8_t dev_minor = 0; - long inode = 0; - int path_index = 0; - - // Sample format from man 5 proc: - // - // address perms offset dev inode pathname - // 08048000-08056000 r-xp 00000000 03:0c 64593 /usr/sbin/gpm - // - // The final %n term captures the offset in the input string, which is used - // to determine the path name. It *does not* increment the return value. - // Refer to man 3 sscanf for details. - if (sscanf(line_buffer, - "%" PRIxPTR "-%" PRIxPTR " %4c " - "%" PRIxPTR " %hhx:%hhx %ld %n", - ®ion_start, ®ion_end, permissions, ®ion_offset, &dev_major, &dev_minor, &inode, - &path_index) < 7) { - FATAL("/proc/self/maps parse failed!"); - fclose(fp); - return *modules; - } - - // check header section permission - if (strcmp(permissions, "r--p") != 0 && strcmp(permissions, "r-xp") != 0) - continue; - - // check elf magic number - ElfW(Ehdr) *header = (ElfW(Ehdr) *)region_start; - if (memcmp(header->e_ident, ELFMAG, SELFMAG) != 0) { - continue; - } - - char *path_buffer = line_buffer + path_index; - if (*path_buffer == 0 || *path_buffer == '\n' || *path_buffer == '[') - continue; - RuntimeModule module; - - // strip - if (path_buffer[strlen(path_buffer) - 1] == '\n') { - path_buffer[strlen(path_buffer) - 1] = 0; - } - strncpy(module.path, path_buffer, sizeof(module.path)); - module.load_address = (void *)region_start; - modules->push_back(module); - -#if 0 - DLOG(0, "module: %s", module.path); -#endif - } - - fclose(fp); - return *modules; -} - -#if defined(__LP64__) -static std::vector get_process_map_with_linker_iterator() { - std::vector ProcessModuleMap; - - static int (*dl_iterate_phdr_ptr)(int (*)(struct dl_phdr_info *, size_t, void *), void *); - dl_iterate_phdr_ptr = (__typeof(dl_iterate_phdr_ptr))dlsym(RTLD_DEFAULT, "dl_iterate_phdr"); - if (dl_iterate_phdr_ptr == NULL) { - return ProcessModuleMap; - } - - dl_iterate_phdr_ptr( - [](dl_phdr_info *info, size_t size, void *data) { - RuntimeModule module = {0}; - if (info->dlpi_name && info->dlpi_name[0] == '/') - strcpy(module.path, info->dlpi_name); - - module.load_address = (void *)info->dlpi_addr; - for (size_t i = 0; i < info->dlpi_phnum; ++i) { - if (info->dlpi_phdr[i].p_type == PT_LOAD) { - uintptr_t load_bias = (info->dlpi_phdr[i].p_vaddr - info->dlpi_phdr[i].p_offset); - module.load_address = (void *)((addr_t)module.load_address + load_bias); - break; - } - } - - // push to vector - auto ProcessModuleMap = reinterpret_cast *>(data); - ProcessModuleMap->push_back(module); - return 0; - }, - (void *)&ProcessModuleMap); - - return ProcessModuleMap; -} -#endif - -const std::vector &ProcessRuntimeUtility::GetProcessModuleMap() { -#if defined(__LP64__) && 0 - // TODO: won't resolve main binary - return get_process_map_with_linker_iterator(); -#else - return get_process_map_with_proc_maps(); -#endif -} - -RuntimeModule ProcessRuntimeUtility::GetProcessModule(const char *name) { - auto modules = GetProcessModuleMap(); - for (auto module : modules) { - if (strstr(module.path, name) != 0) { - return module; - } - } - return RuntimeModule{0}; -} diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/ProcessRuntimeUtility.h b/app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/ProcessRuntimeUtility.h deleted file mode 100644 index 190c6b1..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/ProcessRuntimeUtility.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "PlatformUnifiedInterface/MemoryAllocator.h" - -#include "UnifiedInterface/platform.h" - -typedef struct _RuntimeModule { - char path[1024]; - void *load_address; -} RuntimeModule; - -struct MemRegion : MemRange { - MemoryPermission permission; - - MemRegion(addr_t addr, size_t size, MemoryPermission perm) : MemRange(addr, size), permission(perm) { - } -}; - -class ProcessRuntimeUtility { -public: - static const std::vector &GetProcessMemoryLayout(); - - static const std::vector &GetProcessModuleMap(); - - static RuntimeModule GetProcessModule(const char *name); -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/Windows/ProcessRuntimeUtility.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/Windows/ProcessRuntimeUtility.cc deleted file mode 100644 index 96235b8..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/Windows/ProcessRuntimeUtility.cc +++ /dev/null @@ -1,81 +0,0 @@ -#include "PlatformUtil/ProcessRuntimeUtility.h" - -#include - -#include - -#define LINE_MAX 2048 - -// ================================================================ -// GetProcessMemoryLayout - -static bool memory_region_comparator(MemRange a, MemRange b) { - return (a.address > b.address); -} - -// https://gist.github.com/jedwardsol/9d4fe1fd806043a5767affbd200088ca - -std::vector ProcessMemoryLayout; -std::vector ProcessRuntimeUtility::GetProcessMemoryLayout() { - if (!ProcessMemoryLayout.empty()) { - ProcessMemoryLayout.clear(); - } - - char *address{nullptr}; - MEMORY_BASIC_INFORMATION region; - - while (VirtualQuery(address, ®ion, sizeof(region))) { - address += region.RegionSize; - if (!(region.State & (MEM_COMMIT | MEM_RESERVE))) { - continue; - } - - MemoryPermission permission = MemoryPermission::kNoAccess; - auto mask = PAGE_GUARD | PAGE_NOCACHE | PAGE_WRITECOMBINE; - switch (region.Protect & ~mask) { - case PAGE_NOACCESS: - case PAGE_READONLY: - break; - - case PAGE_EXECUTE: - case PAGE_EXECUTE_READ: - permission = MemoryPermission::kReadExecute; - break; - - case PAGE_READWRITE: - case PAGE_WRITECOPY: - permission = MemoryPermission::kReadWrite; - break; - - case PAGE_EXECUTE_READWRITE: - case PAGE_EXECUTE_WRITECOPY: - permission = MemoryPermission::kReadWriteExecute; - break; - } - - ProcessMemoryLayout.push_back(MemRange{(void *)region.BaseAddress, region.RegionSize, permission}); - } - return ProcessMemoryLayout; -} - -// ================================================================ -// GetProcessModuleMap - -std::vector ProcessModuleMap; - -std::vector ProcessRuntimeUtility::GetProcessModuleMap() { - if (!ProcessMemoryLayout.empty()) { - ProcessMemoryLayout.clear(); - } - return ProcessModuleMap; -} - -RuntimeModule ProcessRuntimeUtility::GetProcessModule(const char *name) { - std::vector ProcessModuleMap = GetProcessModuleMap(); - for (auto module : ProcessModuleMap) { - if (strstr(module.path, name) != 0) { - return module; - } - } - return RuntimeModule{0}; -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/PlatformThread.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/PlatformThread.cc deleted file mode 100644 index 827d125..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/PlatformThread.cc +++ /dev/null @@ -1,19 +0,0 @@ -#include "./PlatformThread.h" - -namespace zz { -int OSThread::GetThreadLocalInt(LocalStorageKey key) { - return static_cast(reinterpret_cast(GetThreadLocal(key))); -} - -void OSThread::SetThreadLocalInt(LocalStorageKey key, int value) { - SetThreadLocal(key, reinterpret_cast(static_cast(value))); -} - -bool OSThread::HasThreadLocal(LocalStorageKey key) { - return GetThreadLocal(key) != nullptr; -} - -void *OSThread::GetExistingThreadLocal(LocalStorageKey key) { - return GetThreadLocal(key); -} -} // namespace zz \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/PlatformThread.h b/app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/PlatformThread.h deleted file mode 100644 index ea03091..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/PlatformThread.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef USER_MODE_PLATFORM_THREAD_H -#define USER_MODE_PLATFORM_THREAD_H - -#include "common_header.h" - -namespace zz { - -class OSThread { -public: - typedef int LocalStorageKey; - - static int GetCurrentProcessId(); - - static int GetCurrentThreadId(); - - // Thread-local storage. - static LocalStorageKey CreateThreadLocalKey(); - - static void DeleteThreadLocalKey(LocalStorageKey key); - - static void *GetThreadLocal(LocalStorageKey key); - - static int GetThreadLocalInt(LocalStorageKey key); - - static void SetThreadLocal(LocalStorageKey key, void *value); - - static void SetThreadLocalInt(LocalStorageKey key, int value); - - static bool HasThreadLocal(LocalStorageKey key); - - static void *GetExistingThreadLocal(LocalStorageKey key); -}; - -} // namespace zz - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/platform-thread-posix.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/platform-thread-posix.cc deleted file mode 100644 index 486618c..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/platform-thread-posix.cc +++ /dev/null @@ -1,71 +0,0 @@ -#include "Thread/PlatformThread.h" - -#include // getpid -#include // pthread -#include - -using namespace zz; - -int OSThread::GetCurrentProcessId() { - return static_cast(getpid()); -} - -int OSThread::GetCurrentThreadId() { -#if defined(__APPLE__) - return static_cast(pthread_mach_thread_np(pthread_self())); -#elif defined(__ANDROID__) - return static_cast(gettid()); -#elif defined(__linux__) - return static_cast(syscall(__NR_gettid)); -#else - return static_cast(reinterpret_cast(pthread_self())); -#endif -} - -static OSThread::LocalStorageKey PthreadKeyToLocalKey(pthread_key_t pthread_key) { -#if defined(__cygwin__) - // We need to cast pthread_key_t to OSThread::LocalStorageKey in two steps - // because pthread_key_t is a pointer type on Cygwin. This will probably not - // work on 64-bit platforms, but Cygwin doesn't support 64-bit anyway. - assert(sizeof(OSThread::LocalStorageKey) == sizeof(pthread_key_t)); - intptr_t ptr_key = reinterpret_cast(pthread_key); - return static_cast(ptr_key); -#else - return static_cast(pthread_key); -#endif -} - -static pthread_key_t LocalKeyToPthreadKey(OSThread::LocalStorageKey local_key) { -#if defined(__cygwin__) - assert(sizeof(OSThread::LocalStorageKey) == sizeof(pthread_key_t)); - intptr_t ptr_key = static_cast(local_key); - return reinterpret_cast(ptr_key); -#else - return static_cast(local_key); -#endif -} - -OSThread::LocalStorageKey OSThread::CreateThreadLocalKey() { - pthread_key_t key; - int result = pthread_key_create(&key, nullptr); - DCHECK_EQ(0, result); - LocalStorageKey local_key = PthreadKeyToLocalKey(key); - return local_key; -} - -void OSThread::DeleteThreadLocalKey(LocalStorageKey key) { - pthread_key_t pthread_key = LocalKeyToPthreadKey(key); - int result = pthread_key_delete(pthread_key); - DCHECK_EQ(0, result); -} - -void *OSThread::GetThreadLocal(LocalStorageKey key) { - pthread_key_t pthread_key = LocalKeyToPthreadKey(key); - return pthread_getspecific(pthread_key); -} - -void OSThread::SetThreadLocal(LocalStorageKey key, void *value) { - pthread_key_t pthread_key = LocalKeyToPthreadKey(key); - int result = pthread_setspecific(pthread_key, value); - DCHECK_EQ(0, result); -} diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/platform-thread-windows.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/platform-thread-windows.cc deleted file mode 100644 index 1428bb0..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/platform-thread-windows.cc +++ /dev/null @@ -1,25 +0,0 @@ -#include "PlatformThread.h" - -using namespace zz; - -int OSThread::GetCurrentProcessId() { - return 0; -} - -int OSThread::GetCurrentThreadId() { - return 0; -} - -OSThread::LocalStorageKey OSThread::CreateThreadLocalKey() { - return 0; -} - -void OSThread::DeleteThreadLocalKey(LocalStorageKey key) { -} - -void *OSThread::GetThreadLocal(LocalStorageKey key) { - return NULL; -} - -void OSThread::SetThreadLocal(LocalStorageKey key, void *value) { -} diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform-darwin/mach_vm.h b/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform-darwin/mach_vm.h deleted file mode 100644 index a9cab32..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform-darwin/mach_vm.h +++ /dev/null @@ -1,933 +0,0 @@ -#ifndef _mach_vm_user_ -#define _mach_vm_user_ - -/* Module mach_vm */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* BEGIN MIG_STRNCPY_ZEROFILL CODE */ - -#if defined(__has_include) -#if __has_include() -#ifndef USING_MIG_STRNCPY_ZEROFILL -#define USING_MIG_STRNCPY_ZEROFILL -#endif -#ifndef __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ -#define __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ -#ifdef __cplusplus -extern "C" { -#endif -extern int mig_strncpy_zerofill(char *dest, const char *src, int len) __attribute__((weak_import)); -#ifdef __cplusplus -} -#endif -#endif /* __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ */ -#endif /* __has_include() */ -#endif /* __has_include */ - -/* END MIG_STRNCPY_ZEROFILL CODE */ - -#ifdef AUTOTEST -#ifndef FUNCTION_PTR_T -#define FUNCTION_PTR_T -typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); -typedef struct { - char *name; - function_ptr_t function; -} function_table_entry; -typedef function_table_entry *function_table_t; -#endif /* FUNCTION_PTR_T */ -#endif /* AUTOTEST */ - -#ifndef mach_vm_MSG_COUNT -#define mach_vm_MSG_COUNT 20 -#endif /* mach_vm_MSG_COUNT */ - -#include -#include -#include -#include - -#ifdef __BeforeMigUserHeader -__BeforeMigUserHeader -#endif /* __BeforeMigUserHeader */ - -#include - - __BEGIN_DECLS - -/* Routine mach_vm_allocate */ -#ifdef mig_external - mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_allocate(vm_map_t target, mach_vm_address_t *address, mach_vm_size_t size, int flags); - -/* Routine mach_vm_deallocate */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_deallocate(vm_map_t target, mach_vm_address_t address, mach_vm_size_t size); - -/* Routine mach_vm_protect */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_protect(vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, boolean_t set_maximum, - vm_prot_t new_protection); - -/* Routine mach_vm_inherit */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_inherit(vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, vm_inherit_t new_inheritance); - -/* Routine mach_vm_read */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_read(vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, vm_offset_t *data, - mach_msg_type_number_t *dataCnt); - -/* Routine mach_vm_read_list */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_read_list(vm_map_t target_task, mach_vm_read_entry_t data_list, natural_t count); - -/* Routine mach_vm_write */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_write(vm_map_t target_task, mach_vm_address_t address, vm_offset_t data, mach_msg_type_number_t dataCnt); - -/* Routine mach_vm_copy */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_copy(vm_map_t target_task, mach_vm_address_t source_address, mach_vm_size_t size, - mach_vm_address_t dest_address); - -/* Routine mach_vm_read_overwrite */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_read_overwrite(vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, mach_vm_address_t data, - mach_vm_size_t *outsize); - -/* Routine mach_vm_msync */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_msync(vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, vm_sync_t sync_flags); - -/* Routine mach_vm_behavior_set */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_behavior_set(vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, - vm_behavior_t new_behavior); - -/* Routine mach_vm_map */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_map(vm_map_t target_task, mach_vm_address_t *address, mach_vm_size_t size, mach_vm_offset_t mask, int flags, - mem_entry_name_port_t object, memory_object_offset_t offset, boolean_t copy, vm_prot_t curr_protection, - vm_prot_t max_protection, vm_inherit_t inheritance); - -/* Routine mach_vm_machine_attribute */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_machine_attribute(vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, - vm_machine_attribute_t attribute, vm_machine_attribute_val_t *value); - -/* Routine mach_vm_remap */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_remap(vm_map_t target_task, mach_vm_address_t *target_address, mach_vm_size_t size, mach_vm_offset_t mask, - int flags, vm_map_t src_task, mach_vm_address_t src_address, boolean_t copy, - vm_prot_t *curr_protection, vm_prot_t *max_protection, vm_inherit_t inheritance); - -/* Routine mach_vm_page_query */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_page_query(vm_map_t target_map, mach_vm_offset_t offset, integer_t *disposition, integer_t *ref_count); - -/* Routine mach_vm_region_recurse */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_region_recurse(vm_map_t target_task, mach_vm_address_t *address, mach_vm_size_t *size, - natural_t *nesting_depth, vm_region_recurse_info_t info, mach_msg_type_number_t *infoCnt); - -/* Routine mach_vm_region */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_region(vm_map_t target_task, mach_vm_address_t *address, mach_vm_size_t *size, vm_region_flavor_t flavor, - vm_region_info_t info, mach_msg_type_number_t *infoCnt, mach_port_t *object_name); - -/* Routine _mach_make_memory_entry */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - _mach_make_memory_entry(vm_map_t target_task, memory_object_size_t *size, memory_object_offset_t offset, - vm_prot_t permission, mem_entry_name_port_t *object_handle, - mem_entry_name_port_t parent_handle); - -/* Routine mach_vm_purgable_control */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_purgable_control(vm_map_t target_task, mach_vm_address_t address, vm_purgable_t control, int *state); - -/* Routine mach_vm_page_info */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_page_info(vm_map_t target_task, mach_vm_address_t address, vm_page_info_flavor_t flavor, - vm_page_info_t info, mach_msg_type_number_t *infoCnt); - -__END_DECLS - -/********************** Caution **************************/ -/* The following data types should be used to calculate */ -/* maximum message sizes only. The actual message may be */ -/* smaller, and the position of the arguments within the */ -/* message layout may vary from what is presented here. */ -/* For example, if any of the arguments are variable- */ -/* sized, and less than the maximum is sent, the data */ -/* will be packed tight in the actual message to reduce */ -/* the presence of holes. */ -/********************** Caution **************************/ - -/* typedefs for all requests */ - -#ifndef __Request__mach_vm_subsystem__defined -#define __Request__mach_vm_subsystem__defined - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - mach_vm_size_t size; - int flags; -} __Request__mach_vm_allocate_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - mach_vm_size_t size; -} __Request__mach_vm_deallocate_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - mach_vm_size_t size; - boolean_t set_maximum; - vm_prot_t new_protection; -} __Request__mach_vm_protect_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - mach_vm_size_t size; - vm_inherit_t new_inheritance; -} __Request__mach_vm_inherit_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - mach_vm_size_t size; -} __Request__mach_vm_read_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_read_entry_t data_list; - natural_t count; -} __Request__mach_vm_read_list_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_ool_descriptor_t data; - /* end of the kernel processed data */ - NDR_record_t NDR; - mach_vm_address_t address; - mach_msg_type_number_t dataCnt; -} __Request__mach_vm_write_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t source_address; - mach_vm_size_t size; - mach_vm_address_t dest_address; -} __Request__mach_vm_copy_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - mach_vm_size_t size; - mach_vm_address_t data; -} __Request__mach_vm_read_overwrite_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - mach_vm_size_t size; - vm_sync_t sync_flags; -} __Request__mach_vm_msync_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - mach_vm_size_t size; - vm_behavior_t new_behavior; -} __Request__mach_vm_behavior_set_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t object; - /* end of the kernel processed data */ - NDR_record_t NDR; - mach_vm_address_t address; - mach_vm_size_t size; - mach_vm_offset_t mask; - int flags; - memory_object_offset_t offset; - boolean_t copy; - vm_prot_t curr_protection; - vm_prot_t max_protection; - vm_inherit_t inheritance; -} __Request__mach_vm_map_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - mach_vm_size_t size; - vm_machine_attribute_t attribute; - vm_machine_attribute_val_t value; -} __Request__mach_vm_machine_attribute_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t src_task; - /* end of the kernel processed data */ - NDR_record_t NDR; - mach_vm_address_t target_address; - mach_vm_size_t size; - mach_vm_offset_t mask; - int flags; - mach_vm_address_t src_address; - boolean_t copy; - vm_inherit_t inheritance; -} __Request__mach_vm_remap_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_offset_t offset; -} __Request__mach_vm_page_query_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - natural_t nesting_depth; - mach_msg_type_number_t infoCnt; -} __Request__mach_vm_region_recurse_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - vm_region_flavor_t flavor; - mach_msg_type_number_t infoCnt; -} __Request__mach_vm_region_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t parent_handle; - /* end of the kernel processed data */ - NDR_record_t NDR; - memory_object_size_t size; - memory_object_offset_t offset; - vm_prot_t permission; -} __Request___mach_make_memory_entry_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - vm_purgable_t control; - int state; -} __Request__mach_vm_purgable_control_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - vm_page_info_flavor_t flavor; - mach_msg_type_number_t infoCnt; -} __Request__mach_vm_page_info_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif -#endif /* !__Request__mach_vm_subsystem__defined */ - -/* union of all requests */ - -#ifndef __RequestUnion__mach_vm_subsystem__defined -#define __RequestUnion__mach_vm_subsystem__defined -union __RequestUnion__mach_vm_subsystem { - __Request__mach_vm_allocate_t Request_mach_vm_allocate; - __Request__mach_vm_deallocate_t Request_mach_vm_deallocate; - __Request__mach_vm_protect_t Request_mach_vm_protect; - __Request__mach_vm_inherit_t Request_mach_vm_inherit; - __Request__mach_vm_read_t Request_mach_vm_read; - __Request__mach_vm_read_list_t Request_mach_vm_read_list; - __Request__mach_vm_write_t Request_mach_vm_write; - __Request__mach_vm_copy_t Request_mach_vm_copy; - __Request__mach_vm_read_overwrite_t Request_mach_vm_read_overwrite; - __Request__mach_vm_msync_t Request_mach_vm_msync; - __Request__mach_vm_behavior_set_t Request_mach_vm_behavior_set; - __Request__mach_vm_map_t Request_mach_vm_map; - __Request__mach_vm_machine_attribute_t Request_mach_vm_machine_attribute; - __Request__mach_vm_remap_t Request_mach_vm_remap; - __Request__mach_vm_page_query_t Request_mach_vm_page_query; - __Request__mach_vm_region_recurse_t Request_mach_vm_region_recurse; - __Request__mach_vm_region_t Request_mach_vm_region; - __Request___mach_make_memory_entry_t Request__mach_make_memory_entry; - __Request__mach_vm_purgable_control_t Request_mach_vm_purgable_control; - __Request__mach_vm_page_info_t Request_mach_vm_page_info; -}; -#endif /* !__RequestUnion__mach_vm_subsystem__defined */ -/* typedefs for all replies */ - -#ifndef __Reply__mach_vm_subsystem__defined -#define __Reply__mach_vm_subsystem__defined - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - mach_vm_address_t address; -} __Reply__mach_vm_allocate_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; -} __Reply__mach_vm_deallocate_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; -} __Reply__mach_vm_protect_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; -} __Reply__mach_vm_inherit_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_ool_descriptor_t data; - /* end of the kernel processed data */ - NDR_record_t NDR; - mach_msg_type_number_t dataCnt; -} __Reply__mach_vm_read_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - mach_vm_read_entry_t data_list; -} __Reply__mach_vm_read_list_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; -} __Reply__mach_vm_write_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; -} __Reply__mach_vm_copy_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - mach_vm_size_t outsize; -} __Reply__mach_vm_read_overwrite_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; -} __Reply__mach_vm_msync_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; -} __Reply__mach_vm_behavior_set_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - mach_vm_address_t address; -} __Reply__mach_vm_map_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - vm_machine_attribute_val_t value; -} __Reply__mach_vm_machine_attribute_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - mach_vm_address_t target_address; - vm_prot_t curr_protection; - vm_prot_t max_protection; -} __Reply__mach_vm_remap_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - integer_t disposition; - integer_t ref_count; -} __Reply__mach_vm_page_query_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - mach_vm_address_t address; - mach_vm_size_t size; - natural_t nesting_depth; - mach_msg_type_number_t infoCnt; - int info[19]; -} __Reply__mach_vm_region_recurse_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t object_name; - /* end of the kernel processed data */ - NDR_record_t NDR; - mach_vm_address_t address; - mach_vm_size_t size; - mach_msg_type_number_t infoCnt; - int info[10]; -} __Reply__mach_vm_region_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t object_handle; - /* end of the kernel processed data */ - NDR_record_t NDR; - memory_object_size_t size; -} __Reply___mach_make_memory_entry_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int state; -} __Reply__mach_vm_purgable_control_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - mach_msg_type_number_t infoCnt; - int info[32]; -} __Reply__mach_vm_page_info_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif -#endif /* !__Reply__mach_vm_subsystem__defined */ - -/* union of all replies */ - -#ifndef __ReplyUnion__mach_vm_subsystem__defined -#define __ReplyUnion__mach_vm_subsystem__defined -union __ReplyUnion__mach_vm_subsystem { - __Reply__mach_vm_allocate_t Reply_mach_vm_allocate; - __Reply__mach_vm_deallocate_t Reply_mach_vm_deallocate; - __Reply__mach_vm_protect_t Reply_mach_vm_protect; - __Reply__mach_vm_inherit_t Reply_mach_vm_inherit; - __Reply__mach_vm_read_t Reply_mach_vm_read; - __Reply__mach_vm_read_list_t Reply_mach_vm_read_list; - __Reply__mach_vm_write_t Reply_mach_vm_write; - __Reply__mach_vm_copy_t Reply_mach_vm_copy; - __Reply__mach_vm_read_overwrite_t Reply_mach_vm_read_overwrite; - __Reply__mach_vm_msync_t Reply_mach_vm_msync; - __Reply__mach_vm_behavior_set_t Reply_mach_vm_behavior_set; - __Reply__mach_vm_map_t Reply_mach_vm_map; - __Reply__mach_vm_machine_attribute_t Reply_mach_vm_machine_attribute; - __Reply__mach_vm_remap_t Reply_mach_vm_remap; - __Reply__mach_vm_page_query_t Reply_mach_vm_page_query; - __Reply__mach_vm_region_recurse_t Reply_mach_vm_region_recurse; - __Reply__mach_vm_region_t Reply_mach_vm_region; - __Reply___mach_make_memory_entry_t Reply__mach_make_memory_entry; - __Reply__mach_vm_purgable_control_t Reply_mach_vm_purgable_control; - __Reply__mach_vm_page_info_t Reply_mach_vm_page_info; -}; -#endif /* !__RequestUnion__mach_vm_subsystem__defined */ - -#ifndef subsystem_to_name_map_mach_vm -#define subsystem_to_name_map_mach_vm \ - {"mach_vm_allocate", 4800}, {"mach_vm_deallocate", 4801}, {"mach_vm_protect", 4802}, {"mach_vm_inherit", 4803}, \ - {"mach_vm_read", 4804}, {"mach_vm_read_list", 4805}, {"mach_vm_write", 4806}, {"mach_vm_copy", 4807}, \ - {"mach_vm_read_overwrite", 4808}, {"mach_vm_msync", 4809}, {"mach_vm_behavior_set", 4810}, \ - {"mach_vm_map", 4811}, {"mach_vm_machine_attribute", 4812}, {"mach_vm_remap", 4813}, \ - {"mach_vm_page_query", 4814}, {"mach_vm_region_recurse", 4815}, {"mach_vm_region", 4816}, \ - {"_mach_make_memory_entry", 4817}, {"mach_vm_purgable_control", 4818}, { \ - "mach_vm_page_info", 4819 \ - } -#endif - -#ifdef __AfterMigUserHeader -__AfterMigUserHeader -#endif /* __AfterMigUserHeader */ - -#endif /* _mach_vm_user_ */ diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform-posix.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform-posix.cc deleted file mode 100644 index 00cab99..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform-posix.cc +++ /dev/null @@ -1,205 +0,0 @@ -#include -#include -#include -#include - -#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__) -#include // for pthread_set_name_np -#endif - -#include // for sched_yield -#include -#include -#include - -#include -#include -#include -#include -#include - -#if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) -#include // NOLINT, for sysctl -#endif - -#include "logging/logging.h" -#include "logging/check_logging.h" -#include "UnifiedInterface/platform.h" - -#if defined(__APPLE__) -#include -#include -#include -#endif - -#if defined(ANDROID) && !defined(ANDROID_LOG_STDOUT) -#define ANDROID_LOG_TAG "Dobby" - -#include - -#endif - -#include - -#if defined(__APPLE__) -const int kMmapFd = VM_MAKE_TAG(255); -#else -const int kMmapFd = -1; -#endif - -const int kMmapFdOffset = 0; - -// ================================================================ -// base :: Thread - -using namespace base; - -typedef struct thread_handle_t { - pthread_t thread; -} thread_handle_t; - -void ThreadInterface::SetName(const char *name) { -#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__) - pthread_set_name_np(pthread_self(), name); -#elif defined(__APPLE__) - pthread_setname_np(name); -#endif -} - -int ThreadInterface::CurrentId() { -#if defined(__APPLE__) - mach_port_t port = mach_thread_self(); - mach_port_deallocate(mach_task_self(), port); - return port; -#elif defined(_POSIX_VERSION) - return syscall(__NR_gettid); -#endif -} - -static void *thread_handler_wrapper(void *ctx) { - ThreadInterface::Delegate *d = (ThreadInterface::Delegate *)ctx; - d->ThreadMain(); - return nullptr; -} - -bool ThreadInterface::Create(ThreadInterface::Delegate *delegate, ThreadHandle *handle) { - thread_handle_t *handle_impl = new thread_handle_t; - - int err = 0; - err = pthread_create(&(handle_impl->thread), nullptr, thread_handler_wrapper, delegate); - if (err != 0) { - FATAL("pthread create failed"); - return false; - } - return true; -} - -Thread::Thread(const char *name) { - strncpy(name_, name, sizeof(name_)); -} - -bool Thread::Start() { - if (ThreadInterface::Create(this, &handle_) == false) { - return false; - } - return true; -} - -// --- OSMemory - -static int GetProtectionFromMemoryPermission(MemoryPermission access) { - switch (access) { - case MemoryPermission::kNoAccess: - return PROT_NONE; - case MemoryPermission::kRead: - return PROT_READ; - case MemoryPermission::kReadWrite: - return PROT_READ | PROT_WRITE; - case MemoryPermission::kReadWriteExecute: - return PROT_READ | PROT_WRITE | PROT_EXEC; - case MemoryPermission::kReadExecute: - return PROT_READ | PROT_EXEC; - } - UNREACHABLE(); -} - -int OSMemory::PageSize() { - return static_cast(sysconf(_SC_PAGESIZE)); -} - -void *OSMemory::Allocate(size_t size, MemoryPermission access) { - return OSMemory::Allocate(size, access, nullptr); -} - -void *OSMemory::Allocate(size_t size, MemoryPermission access, void *fixed_address) { - int prot = GetProtectionFromMemoryPermission(access); - - int flags = MAP_PRIVATE | MAP_ANONYMOUS; - if (fixed_address != nullptr) { - flags = flags | MAP_FIXED; - } - void *result = mmap(fixed_address, size, prot, flags, kMmapFd, kMmapFdOffset); - if (result == MAP_FAILED) - return nullptr; - - return result; -} - -bool OSMemory::Free(void *address, size_t size) { - DCHECK_EQ(0, reinterpret_cast(address) % PageSize()); - DCHECK_EQ(0, size % PageSize()); - - return munmap(address, size) == 0; -} - -bool OSMemory::Release(void *address, size_t size) { - DCHECK_EQ(0, reinterpret_cast(address) % PageSize()); - DCHECK_EQ(0, size % PageSize()); - - return munmap(address, size) == 0; -} - -bool OSMemory::SetPermission(void *address, size_t size, MemoryPermission access) { - DCHECK_EQ(0, reinterpret_cast(address) % PageSize()); - DCHECK_EQ(0, size % PageSize()); - - int prot = GetProtectionFromMemoryPermission(access); - int ret = mprotect(address, size, prot); - if (ret) { - ERROR_LOG("OSMemory::SetPermission: %s\n", ((const char *)strerror(errno))); - } - - return ret == 0; -} - -// --- OSPrint - -void OSPrint::Print(const char *format, ...) { - va_list args; - va_start(args, format); - VPrint(format, args); - va_end(args); -} - -void OSPrint::VPrint(const char *format, va_list args) { -#if defined(ANDROID) && !defined(ANDROID_LOG_STDOUT) - __android_log_vprint(ANDROID_LOG_INFO, ANDROID_LOG_TAG, format, args); -#else - vprintf(format, args); -#endif -} - -void OSPrint::PrintError(const char *format, ...) { - va_list args; - va_start(args, format); - VPrintError(format, args); - va_end(args); -} - -void OSPrint::VPrintError(const char *format, va_list args) { -#if defined(ANDROID) && !defined(ANDROID_LOG_STDOUT) - __android_log_vprint(ANDROID_LOG_ERROR, LOG_TAG, format, args); -#else - vfprintf(stderr, format, args); -#endif -} diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform-windows.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform-windows.cc deleted file mode 100644 index ef23325..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform-windows.cc +++ /dev/null @@ -1,87 +0,0 @@ -#include - -#include - - -#include "logging/logging.h" -#include "logging/check_logging.h" -#include "UnifiedInterface/platform.h" - -int GetProtectionFromMemoryPermission(MemoryPermission access) { - if (kReadWriteExecute == access) - return PAGE_EXECUTE_READWRITE; - else if (kReadExecute == access) - return PAGE_EXECUTE_READ; -} - -int OSMemory::AllocPageSize() { - static int lastRet = -1; - if (lastRet == -1) { - SYSTEM_INFO si; - GetSystemInfo(&si); - lastRet = si.dwAllocationGranularity; // should be used with VirtualAlloc(MEM_RESERVE) - } - return lastRet; -} - -int OSMemory::PageSize() { - static int lastRet = -1; - if (lastRet == -1) { - SYSTEM_INFO si; - GetSystemInfo(&si); - lastRet = si.dwPageSize; // should be used with VirtualAlloc(MEM_RESERVE) - } - return lastRet; -} - -void *OSMemory::Allocate(void *address, int size, MemoryPermission access) { - DCHECK_EQ(0, reinterpret_cast(address) % AllocPageSize()); - DCHECK_EQ(0, size % PageSize()); - - void *result = VirtualAlloc(address, size, MEM_COMMIT | MEM_RESERVE, PAGE_NOACCESS); - OSMemory::SetPermission(result, size, kReadWriteExecute); - if (result == nullptr) - return nullptr; - - // TODO: if need align - void *aligned_base = result; - return static_cast(aligned_base); -} - -// static -bool OSMemory::Free(void *address, const int size) { - DCHECK_EQ(0, reinterpret_cast(address) % PageSize()); - DCHECK_EQ(0, size % PageSize()); - - return VirtualFree(address, size, MEM_RELEASE); -} - -bool OSMemory::Release(void *address, int size) { - DCHECK_EQ(0, reinterpret_cast(address) % PageSize()); - DCHECK_EQ(0, size % PageSize()); - - return OSMemory::Free(address, size); -} - -bool OSMemory::SetPermission(void *address, int size, MemoryPermission access) { - DCHECK_EQ(0, reinterpret_cast(address) % PageSize()); - DCHECK_EQ(0, size % PageSize()); - - int prot = GetProtectionFromMemoryPermission(access); - - DWORD oldProtect; - return VirtualProtect(address, size, prot, &oldProtect); -} - -// ===== - -void OSPrint::Print(const char *format, ...) { - va_list args; - va_start(args, format); - VPrint(format, args); - va_end(args); -} - -void OSPrint::VPrint(const char *format, va_list args) { - vprintf(format, args); -} diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform.h b/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform.h deleted file mode 100644 index f54ddc9..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef PLATFORM_INTERFACE_COMMON_PLATFORM_H -#define PLATFORM_INTERFACE_COMMON_PLATFORM_H - -#include -#include - -namespace base { -// ================================================================ -// base :: ThreadLocalStorageInterface - -class ThreadLocalStorageInterface { - using LocalStorageKey = int32_t; - - // Thread-local storage. - static LocalStorageKey CreateThreadLocalKey(); - - static void DeleteThreadLocalKey(LocalStorageKey key); - - static void *GetThreadLocal(LocalStorageKey key); - - static int GetThreadLocalInt(LocalStorageKey key) { - return static_cast(reinterpret_cast(GetThreadLocal(key))); - } - - static void SetThreadLocal(LocalStorageKey key, void *value); - - static void SetThreadLocalInt(LocalStorageKey key, int value) { - SetThreadLocal(key, reinterpret_cast(static_cast(value))); - } - - static bool HasThreadLocal(LocalStorageKey key) { - return GetThreadLocal(key) != nullptr; - } -}; - -// ================================================================ -// base :: Thread - -typedef void *ThreadHandle; - -class ThreadInterface { -public: - class Delegate { - public: - virtual void ThreadMain() = 0; - }; - -public: - static bool Create(Delegate *delegate, ThreadHandle *handle); - - static int CurrentId(); - - static void SetName(const char *); -}; - -class Thread : public ThreadInterface, public ThreadInterface::Delegate { -public: - Thread(const char *name); - - bool Start(); - -private: - ThreadHandle handle_; - - char name_[256]; -}; -} // namespace base - -// ================================================================ -// base :: OSMemory - -enum MemoryPermission { kNoAccess, kRead, kReadWrite, kReadWriteExecute, kReadExecute }; - -class OSMemory { -public: - static int PageSize(); - - static void *Allocate(size_t size, MemoryPermission access); - - static void *Allocate(size_t size, MemoryPermission access, void *fixed_address); - - static bool Free(void *address, size_t size); - - static bool Release(void *address, size_t size); - - static bool SetPermission(void *address, size_t size, MemoryPermission access); -}; - -// ================================================================ -// base :: OSPrint - -class OSPrint { -public: - // Print output to console. This is mostly used for debugging output. - // On platforms that has standard terminal output, the output - // should go to stdout. - static void Print(const char *format, ...); - - static void VPrint(const char *format, va_list args); - - // Print error output to console. This is mostly used for error message - // output. On platforms that has standard terminal output, the output - // should go to stderr. - static void PrintError(const char *format, ...); - - static void VPrintError(const char *format, va_list args); -}; - -#endif diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/semaphore.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/semaphore.cc deleted file mode 100644 index 12a15e0..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/semaphore.cc +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright 2013 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "src/base/platform/semaphore.h" - -#if V8_OS_MACOSX -#include -#endif - -#include - -#include "src/base/logging.h" -#include "src/base/platform/elapsed-timer.h" -#include "src/base/platform/time.h" - -namespace v8 { -namespace base { - -#if V8_OS_MACOSX - -Semaphore::Semaphore(int count) { - native_handle_ = dispatch_semaphore_create(count); - DCHECK(native_handle_); -} - -Semaphore::~Semaphore() { - dispatch_release(native_handle_); -} - -void Semaphore::Signal() { - dispatch_semaphore_signal(native_handle_); -} - -void Semaphore::Wait() { - dispatch_semaphore_wait(native_handle_, DISPATCH_TIME_FOREVER); -} - -bool Semaphore::WaitFor(const TimeDelta &rel_time) { - dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, rel_time.InNanoseconds()); - return dispatch_semaphore_wait(native_handle_, timeout) == 0; -} - -#elif V8_OS_POSIX - -Semaphore::Semaphore(int count) { - DCHECK_GE(count, 0); - int result = sem_init(&native_handle_, 0, count); - DCHECK_EQ(0, result); - USE(result); -} - -Semaphore::~Semaphore() { - int result = sem_destroy(&native_handle_); - DCHECK_EQ(0, result); - USE(result); -} - -void Semaphore::Signal() { - int result = sem_post(&native_handle_); - // This check may fail with 0) { - // sem_timedwait in glibc prior to 2.3.4 returns the errno instead of -1. - errno = result; - result = -1; - } -#endif - if (result == -1 && errno == ETIMEDOUT) { - // Timed out while waiting for semaphore. - return false; - } - // Signal caused spurious wakeup. - DCHECK_EQ(-1, result); - DCHECK_EQ(EINTR, errno); - } -} - -#elif V8_OS_WIN - -Semaphore::Semaphore(int count) { - DCHECK_GE(count, 0); - native_handle_ = ::CreateSemaphoreA(nullptr, count, 0x7FFFFFFF, nullptr); - DCHECK_NOT_NULL(native_handle_); -} - -Semaphore::~Semaphore() { - BOOL result = CloseHandle(native_handle_); - DCHECK(result); - USE(result); -} - -void Semaphore::Signal() { - LONG dummy; - BOOL result = ReleaseSemaphore(native_handle_, 1, &dummy); - DCHECK(result); - USE(result); -} - -void Semaphore::Wait() { - DWORD result = WaitForSingleObject(native_handle_, INFINITE); - DCHECK(result == WAIT_OBJECT_0); - USE(result); -} - -bool Semaphore::WaitFor(const TimeDelta &rel_time) { - TimeTicks now = TimeTicks::Now(); - TimeTicks end = now + rel_time; - while (true) { - int64_t msec = (end - now).InMilliseconds(); - if (msec >= static_cast(INFINITE)) { - DWORD result = WaitForSingleObject(native_handle_, INFINITE - 1); - if (result == WAIT_OBJECT_0) { - return true; - } - DCHECK(result == WAIT_TIMEOUT); - now = TimeTicks::Now(); - } else { - DWORD result = WaitForSingleObject(native_handle_, (msec < 0) ? 0 : static_cast(msec)); - if (result == WAIT_TIMEOUT) { - return false; - } - DCHECK(result == WAIT_OBJECT_0); - return true; - } - } -} - -#endif // V8_OS_MACOSX - -} // namespace base -} // namespace v8 diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/semaphore.h b/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/semaphore.h deleted file mode 100644 index cff4cd4..0000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/semaphore.h +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2013 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef V8_BASE_PLATFORM_SEMAPHORE_H_ -#define V8_BASE_PLATFORM_SEMAPHORE_H_ - -#include "src/base/base-export.h" -#include "src/base/lazy-instance.h" -#if V8_OS_WIN -#include "src/base/win32-headers.h" -#endif - -#if V8_OS_MACOSX -#include // NOLINT -#elif V8_OS_POSIX -#include // NOLINT -#endif - -namespace v8 { -namespace base { - -// Forward declarations. -class TimeDelta; - -// ---------------------------------------------------------------------------- -// Semaphore -// -// A semaphore object is a synchronization object that maintains a count. The -// count is decremented each time a thread completes a wait for the semaphore -// object and incremented each time a thread signals the semaphore. When the -// count reaches zero, threads waiting for the semaphore blocks until the -// count becomes non-zero. - -class V8_BASE_EXPORT Semaphore final { -public: - explicit Semaphore(int count); - ~Semaphore(); - - // Increments the semaphore counter. - void Signal(); - - // Decrements the semaphore counter if it is positive, or blocks until it - // becomes positive and then decrements the counter. - void Wait(); - - // Like Wait() but returns after rel_time time has passed. If the timeout - // happens the return value is false and the counter is unchanged. Otherwise - // the semaphore counter is decremented and true is returned. - bool WaitFor(const TimeDelta &rel_time) V8_WARN_UNUSED_RESULT; - -#if V8_OS_MACOSX - using NativeHandle = dispatch_semaphore_t; -#elif V8_OS_POSIX - using NativeHandle = sem_t; -#elif V8_OS_WIN - using NativeHandle = HANDLE; -#endif - - NativeHandle &native_handle() { - return native_handle_; - } - const NativeHandle &native_handle() const { - return native_handle_; - } - -private: - NativeHandle native_handle_; - - DISALLOW_COPY_AND_ASSIGN(Semaphore); -}; - -// POD Semaphore initialized lazily (i.e. the first time Pointer() is called). -// Usage: -// // The following semaphore starts at 0. -// static LazySemaphore<0>::type my_semaphore = LAZY_SEMAPHORE_INITIALIZER; -// -// void my_function() { -// // Do something with my_semaphore.Pointer(). -// } -// - -template struct CreateSemaphoreTrait { - static Semaphore *Create() { - return new Semaphore(N); - } -}; - -template struct LazySemaphore { - using typename LazyDynamicInstance, ThreadSafeInitOnceTrait>::type; -}; - -#define LAZY_SEMAPHORE_INITIALIZER LAZY_DYNAMIC_INSTANCE_INITIALIZER - -} // namespace base -} // namespace v8 - -#endif // V8_BASE_PLATFORM_SEMAPHORE_H_ diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/InstructionRelocation.h b/app/src/main/cpp/Dobby/source/InstructionRelocation/InstructionRelocation.h deleted file mode 100644 index ebd0121..0000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/InstructionRelocation.h +++ /dev/null @@ -1,5 +0,0 @@ -#include "dobby_internal.h" - -void GenRelocateCode(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch); - -void GenRelocateCodeAndBranch(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated); diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/arm/InstructionRelocationARM.cc b/app/src/main/cpp/Dobby/source/InstructionRelocation/arm/InstructionRelocationARM.cc deleted file mode 100644 index 9b836c7..0000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/arm/InstructionRelocationARM.cc +++ /dev/null @@ -1,917 +0,0 @@ -#include "platform_macro.h" - -#if defined(TARGET_ARCH_ARM) - -#include "dobby_internal.h" - -#include "InstructionRelocation/arm/InstructionRelocationARM.h" - -#include "core/arch/arm/registers-arm.h" -#include "core/assembler/assembler-arm.h" -#include "core/codegen/codegen-arm.h" - -using namespace zz; -using namespace zz::arm; - -typedef struct { - addr_t mapped_addr; - - bool thumb_mode; - - uint8_t *buffer; - uint8_t *buffer_cursor; - size_t buffer_size; - - vmaddr_t src_vmaddr; - vmaddr_t dst_vmaddr; - - CodeMemBlock *relocated; - CodeBuffer *relocated_buffer; - - ExecuteState start_state; - ExecuteState curr_state; - Assembler *curr_assembler; - ThumbTurboAssembler *thumb_assembler; - TurboAssembler *arm_assembler; - - tinystl::unordered_map execute_state_map; - - tinystl::unordered_map relocated_offset_map; - - tinystl::unordered_map label_map; -} relo_ctx_t; - -// --- - -addr_t relo_cur_src_vmaddr(relo_ctx_t *ctx) { - int relocated_len = ctx->buffer_cursor - ctx->buffer; - if (ctx->curr_state == zz::arm::ARMExecuteState) { - return ctx->src_vmaddr + relocated_len + ARM_PC_OFFSET; - } else { - return ctx->src_vmaddr + relocated_len + Thumb_PC_OFFSET; - } -} - -static bool is_thumb2(uint32_t insn) { - uint16_t insn1, insn2; - insn1 = insn & 0x0000ffff; - insn2 = (insn & 0xffff0000) >> 16; - // refer: Top level T32 instruction set encoding - uint32_t op0 = bits(insn1, 13, 15); - uint32_t op1 = bits(insn1, 11, 12); - - if (op0 == 0b111 && op1 != 0b00) { - return true; - } - return false; -} - -bool check_execute_state_changed(relo_ctx_t *ctx, addr_t insn_addr) { - for (auto iter = ctx->execute_state_map.begin(); iter != ctx->execute_state_map.end(); ++iter) { - addr_t execute_state_changed_pc = iter->first; - auto state = iter->second; - if (execute_state_changed_pc == insn_addr) { - return true; - } - } - return false; -} - -static inline int32_t SignExtend(unsigned x, int M, int N) { -#if 1 - char sign_bit = bit(x, M - 1); - unsigned sign_mask = 0 - sign_bit; - x |= ((sign_mask >> M) << M); -#else - x = (long)((long)x << (N - M)) >> (N - M); -#endif - return (int32_t) x; -} - -enum arm_shift_type { - arm_shift_lsl, arm_shift_lsr, arm_shift_asr, arm_shift_ror, arm_shift_rrx -}; - -uint32_t arm_shift_c(uint32_t val, uint32_t shift_type, uint32_t shift_count, uint32_t carry_in, - uint32_t *carry_out) { - if (shift_count == 0) - return val; - uint32_t r_val; - uint32_t carry = carry_in; - switch (shift_type) { - case arm_shift_lsl: - r_val = val; - r_val = r_val << shift_count; - carry = (r_val >> 32) & 0x1; - val = r_val; - break; - case arm_shift_lsr: - r_val = val; - r_val = r_val >> (shift_count - 1); - carry = r_val & 0x1; - val = (r_val >> 1); - break; - case arm_shift_asr: - r_val = val; - if (val & 0x80000000) { - r_val |= 0xFFFFFFFF00000000ULL; - } - r_val = r_val >> (shift_count - 1); - carry = r_val & 0x1; - val = (r_val >> 1); - break; - case arm_shift_ror: - val = (val >> (shift_count % 32)) | (val << (32 - (shift_count % 32))); - carry = (val >> 31); - break; - case arm_shift_rrx: - carry = val & 0x1; - val = (carry_in << 31) | (val >> 1); - break; - break; - } - return val; -} - -uint32_t arm_expand_imm_c(uint32_t imm12) { - uint32_t unrotated_value = bits(imm12, 0, 7); - return arm_shift_c(unrotated_value, arm_shift_ror, 2 * bits(imm12, 8, 11), 0, 0); -} - -uint32_t A32ExpandImm(uint32_t imm12) { - return arm_expand_imm_c(imm12); -} - -static void ARMRelocateSingleInsn(relo_ctx_t *ctx, int32_t insn) { - auto turbo_assembler_ = static_cast(ctx->curr_assembler); -#define _ turbo_assembler_-> - - bool is_insn_relocated = false; - - // top level encoding - uint32_t cond, op0, op1; - cond = bits(insn, 28, 31); - op0 = bits(insn, 25, 27); - op1 = bit(insn, 4); - // Load/Store Word, Unsigned byte (immediate, literal) - if (cond != 0b1111 && op0 == 0b010) { - uint32_t P, U, o2, W, o1, Rn, Rt, imm12; - P = bit(insn, 24); - U = bit(insn, 23); - W = bit(insn, 21); - imm12 = bits(insn, 0, 11); - Rn = bits(insn, 16, 19); - Rt = bits(insn, 12, 15); - o1 = bit(insn, 20); - o2 = bit(insn, 22); - uint32_t P_W = (P << 1) | W; - do { - // LDR (literal) - DLOG(0, "%d:relo at %p", ctx->relocated_offset_map.size(), - relo_cur_src_vmaddr(ctx)); - if (o1 == 1 && o2 == 0 && P_W != 0b01 && Rn == 0b1111) { - goto load_literal_fix_scheme; - } - if (o1 == 1 && o2 == 1 && P_W != 0b01 && Rn == 0b1111) { - goto load_literal_fix_scheme; - } - break; - load_literal_fix_scheme: - addr32_t dst_vmaddr = 0; - if (U == 0b1) - dst_vmaddr = relo_cur_src_vmaddr(ctx) + imm12; - else - dst_vmaddr = relo_cur_src_vmaddr(ctx) - imm12; - Register regRt = Register::R(Rt); - - auto label = new RelocLabel(dst_vmaddr); - _ AppendRelocLabel(label); - - if (regRt.code() == pc.code()) { - _ Ldr(VOLATILE_REGISTER, label); - _ ldr(regRt, MemOperand(VOLATILE_REGISTER)); - } else { - _ Ldr(regRt, label); - _ ldr(regRt, MemOperand(regRt)); - } - - is_insn_relocated = true; - } while (0); - } - - // Data-processing and miscellaneous instructions - if (cond != 0b1111 && (op0 & 0b110) == 0b000) { - uint32_t op0, op1, op2, op3, op4; - op0 = bit(insn, 25); - // Data-processing immediate - if (op0 == 1) { - uint32_t op0, op1; - op0 = bits(insn, 23, 24); - op1 = bits(insn, 20, 21); - // Integer Data Processing (two register and immediate) - if ((op0 & 0b10) == 0b00) { - DLOG(0, "%d:relo at %p", ctx->relocated_offset_map.size(), - relo_cur_src_vmaddr(ctx)); - - uint32_t opc, S, Rn; - opc = bits(insn, 21, 23); - S = bit(insn, 20); - Rn = bits(insn, 16, 19); - - uint32_t dst_vmaddr = -1; - int Rd = bits(insn, 12, 15); - int imm12 = bits(insn, 0, 11); - uint32_t imm = arm_expand_imm_c(imm12); - if (opc == 0b010 && S == 0b0 && Rn == 0b1111) { // ADR - A2 variant - dst_vmaddr = relo_cur_src_vmaddr(ctx) - imm; - } else if (opc == 0b100 && S == 0b0 && Rn == 0b1111) { // ADR - A1 variant - dst_vmaddr = relo_cur_src_vmaddr(ctx) + imm; - } - - if (dst_vmaddr != -1) { - Register regRd = Register::R(Rd); - RelocLabel *pseudoDataLabel = new RelocLabel(dst_vmaddr); - _ AppendRelocLabel(pseudoDataLabel); - - _ Ldr(regRd, pseudoDataLabel); - - is_insn_relocated = true; - } - } - } - } - - // Branch, branch with link, and block data transfer - if ((op0 & 0b110) == 0b100) { - uint32_t cond, op0; - cond = bits(insn, 28, 31); - op0 = bit(insn, 25); - // Branch (immediate) on page F4-4034 - if (op0 == 1) { - DLOG(0, "%d:relo at %p", ctx->relocated_offset_map.size(), - relo_cur_src_vmaddr(ctx)); - - uint32_t H = 0, imm24 = 0; - H = bit(insn, 24); - imm24 = bits(insn, 0, 23); - int32_t label = SignExtend(imm24 << 2, 2 + 24, 32); - uint32_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + label; - bool branch_link; - if (cond != 0b1111 && H == 0) { // B - branch_link = false; - } else if (cond != 0b1111 && H == 1) { // BL, BLX (immediate) - A1 on page F5-4135 - branch_link = true; - } else if (cond == 0b1111) { // BL, BLX (immediate) - A2 on page F5-4135 - branch_link = true; - cond = AL; - dst_vmaddr |= 1; - } else - UNREACHABLE(); - - if (branch_link) - _ bl((Condition) cond, 0); // goto [dst_vmaddr] - else - _ b((Condition) cond, 0); // goto [dst_vmaddr] - _ b(4); // goto [rest_flow] - // [dst_vmaddr] - _ ldr(pc, MemOperand(pc, -4)); - _ EmitAddress(dst_vmaddr); - // [rest_flow] - _ mov(r8, r8); - - is_insn_relocated = true; - } - } - - // if the insn do not needed relocate, just rewrite the origin - if (!is_insn_relocated) { - _ EmitARMInst(insn); - } -} - -// relocate thumb-1 instructions -static void Thumb1RelocateSingleInsn(relo_ctx_t *ctx, int16_t insn) { - auto turbo_assembler_ = static_cast(ctx->curr_assembler); -#define _ turbo_assembler_-> - - bool is_insn_relocated = false; - - _ AlignThumbNop(); - - uint32_t op = 0, rt = 0, rm = 0, rn = 0, rd = 0, shift = 0, cond = 0; - int32_t offset = 0; - - int32_t op0 = 0, op1 = 0; - op0 = bits(insn, 10, 15); - // Special data instructions and branch and exchange on page F3-3942 - if (op0 == 0b010001) { - op0 = bits(insn, 8, 9); - // Add, subtract, compare, move (two high registers) - if (op0 != 0b11) { - int rs = bits(insn, 3, 6); - // rs is PC register - if (rs == 15) { - DLOG(0, "%d:relo at %p", ctx->relocated_offset_map.size(), - relo_cur_src_vmaddr(ctx)); - - thumb1_inst_t rewrite_inst = insn; - set_bits(rewrite_inst, 3, 6, VOLATILE_REGISTER.code()); - - auto label = new ThumbRelocLabelEntry(relo_cur_src_vmaddr(ctx), false); - _ AppendRelocLabel(label); - - _ T2_Ldr(VOLATILE_REGISTER, label); - _ EmitInt16(rewrite_inst); - - is_insn_relocated = true; - } - } - - // Branch and exchange - if (op0 == 0b11) { - int32_t L = bit(insn, 7); - rm = bits(insn, 3, 6); - // BX - if (L == 0b0) { - if (rm == pc.code()) { - DLOG(0, "%d:relo at %p", ctx->relocated_offset_map.size(), - relo_cur_src_vmaddr(ctx)); - - vmaddr_t dst_vmaddr = relo_cur_src_vmaddr(ctx); - auto label = new ThumbRelocLabelEntry(dst_vmaddr, true); - _ AppendRelocLabel(label); - - _ T2_Ldr(pc, label); - - ctx->execute_state_map[dst_vmaddr] = ARMExecuteState; - - is_insn_relocated = true; - } - } - // BLX - if (L == 0b1) { - if (rm == pc.code()) { - DLOG(0, "%d:relo at %p", ctx->relocated_offset_map.size(), - relo_cur_src_vmaddr(ctx)); - - vmaddr_t dst_vmaddr = relo_cur_src_vmaddr(ctx); - auto label = new ThumbRelocLabelEntry(dst_vmaddr, true); - _ AppendRelocLabel(label); - - _ t2_bl(4); - _ t2_b(4); // goto [rest flow] - _ T2_Ldr(pc, label); // goto [dst_vmaddr] - // [rest flow] - - ctx->execute_state_map[dst_vmaddr] = ARMExecuteState; - - is_insn_relocated = true; - } - } - } - } - - // LDR (literal) - T1 variant on page F5-4243 - // ldr literal - if ((insn & 0xf800) == 0x4800) { - DLOG(0, "%d:relo at %p", ctx->relocated_offset_map.size(), - relo_cur_src_vmaddr(ctx)); - - uint32_t imm8 = bits(insn, 0, 7); - uint32_t imm = imm8 << 2; - vmaddr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + imm; - dst_vmaddr = ALIGN_FLOOR(dst_vmaddr, 4); - rt = bits(insn, 8, 10); - - auto label = new ThumbRelocLabelEntry(dst_vmaddr, false); - _ AppendRelocLabel(label); - - _ T2_Ldr(Register::R(rt), label); - _ t2_ldr(Register::R(rt), MemOperand(Register::R(rt), 0)); - - is_insn_relocated = true; - } - - // Add PC/SP (immediate) on page F3-3939 - // adr - if ((insn & 0xf800) == 0xa000) { - DLOG(0, "%d:relo at %p", ctx->relocated_offset_map.size(), - relo_cur_src_vmaddr(ctx)); - - rd = bits(insn, 8, 10); - uint32_t imm8 = bits(insn, 0, 7); - int32_t imm32 = imm8 << 2; - vmaddr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + imm32; - - auto label = new ThumbRelocLabelEntry(dst_vmaddr, false); - _ AppendRelocLabel(label); - - _ T2_Ldr(Register::R(rd), label); - - is_insn_relocated = true; - } - - // Conditional branch, and Supervisor Call on page F3-3946 - // b - if ((insn & 0xf000) == 0xd000) { - DLOG(0, "%d:relo at %p", ctx->relocated_offset_map.size(), - relo_cur_src_vmaddr(ctx)); - - uint16_t cond = bits(insn, 8, 11); - // cond != 111x - if (cond >= 0b1110) { - UNREACHABLE(); - } - uint32_t imm8 = bits(insn, 0, 7); - int32_t imm = SignExtend(imm8 << 1, 8 + 1, 32); - vmaddr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + imm; - dst_vmaddr |= 1; - - auto label = new ThumbRelocLabelEntry(dst_vmaddr, true); - _ AppendRelocLabel(label); - - thumb1_inst_t b_cond_insn = 0xe000; - set_bits(b_cond_insn, 8, 11, cond); - _ EmitInt16(b_cond_insn | (4 >> 1)); - _ t1_nop(); // align - _ t2_b(4); - _ T2_Ldr(pc, label); - - is_insn_relocated = true; - } - - // Miscellaneous 16-bit instructions on page F3-3943 - // CBNZ, CBZ - if ((insn & 0xf500) == 0xb100) { - DLOG(0, "%d:relo at %p", ctx->relocated_offset_map.size(), - relo_cur_src_vmaddr(ctx)); - - uint32_t imm5 = bits(insn, 3, 7); - uint32_t i = bit(insn, 9); - uint32_t imm = (i << 6) | (imm5 << 1); - vmaddr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + imm; - - rn = bits(insn, 0, 2); - - auto label = new ThumbRelocLabelEntry(dst_vmaddr + 1, true); - _ AppendRelocLabel(label); - - imm5 = bits(0x4, 1, 5); - set_bits(insn, 3, 7, imm5); - i = bit(0x4, 6); - set_bit(insn, 9, i); - _ EmitInt16(insn); - _ t1_nop(); // align - _ t2_b(4); // goto [rest flow] - _ T2_Ldr(pc, label); - // [rest flow] - - is_insn_relocated = true; - } - - // F3.1 - // T32 instruction set encoding - // b - if ((insn & 0xf800) == 0xe000) { - DLOG(0, "%d:relo at %p", ctx->relocated_offset_map.size(), - relo_cur_src_vmaddr(ctx)); - - uint32_t imm11 = bits(insn, 0, 10); - int32_t imm = SignExtend(imm11 << 1, 11 + 1, 32); - vmaddr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + imm; - - auto label = new ThumbRelocLabelEntry(dst_vmaddr + 1, true); - _ AppendRelocLabel(label); - - _ T2_Ldr(pc, label); - - is_insn_relocated = true; - } - - // if the insn do not needed relocate, just rewrite the origin - if (!is_insn_relocated) { -#if 0 - if (relo_cur_src_vmaddr(ctx) % Thumb2_INST_LEN) - _ t1_nop(); -#endif - _ EmitInt16(insn); - } -} - -static void Thumb2RelocateSingleInsn(relo_ctx_t *ctx, thumb1_inst_t insn1, thumb1_inst_t insn2) { - auto turbo_assembler_ = static_cast(ctx->curr_assembler); -#define _ turbo_assembler_-> - - bool is_insn_relocated = false; - - // if (turbo_assembler->pc_offset() % 4) { - // _ t1_nop(); - // } - - _ AlignThumbNop(); - - // Branches and miscellaneous control on page F3-3979 - if ((insn1 & 0xf800) == 0xf000 && (insn2 & 0x8000) == 0x8000) { - uint32_t op1 = 0, op3 = 0; - op1 = bits(insn1, 6, 9); - op3 = bits(insn2, 12, 14); - - // B - T3 variant on page F5-4118 - if (((op1 & 0b1110) != 0b1110) && ((op3 & 0b101) == 0b000)) { - DLOG(0, "%d:relo at %p", ctx->relocated_offset_map.size(), - relo_cur_src_vmaddr(ctx)); - - uint32_t S = bit(insn1, 10); - uint32_t J1 = bit(insn2, 13); - uint32_t J2 = bit(insn2, 11); - uint32_t imm6 = bits(insn1, 0, 5); - uint32_t imm11 = bits(insn2, 0, 10); - - int32_t imm = - SignExtend((S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1), - 1 + 1 + 1 + 6 + 11 + 1, 32); - vmaddr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + imm; - dst_vmaddr |= 1; - - uint32_t cond = bits(insn1, 6, 9); - thumb1_inst_t b_cond_insn = 0xe000; - set_bits(b_cond_insn, 8, 11, cond); - _ EmitInt16(b_cond_insn | (4 >> 1)); - _ t1_nop(); // align - _ t2_b(8); - _ t2_ldr(pc, MemOperand(pc, 0)); - _ EmitAddress(dst_vmaddr); - - is_insn_relocated = true; - } - - // B - T4 variant on page F5-4118 - if ((op3 & 0b101) == 0b001) { - DLOG(0, "%d:relo at %p", ctx->relocated_offset_map.size(), - relo_cur_src_vmaddr(ctx)); - - uint32_t S = bit(insn1, 10); - uint32_t J1 = bit(insn2, 13); - uint32_t J2 = bit(insn2, 11); - uint32_t imm10 = bits(insn1, 0, 9); - uint32_t imm11 = bits(insn2, 0, 10); - uint32_t i1 = !(J1 ^ S); - uint32_t i2 = !(J2 ^ S); - - int32_t imm = - SignExtend((S << 24) | (i1 << 23) | (i2 << 22) | (imm10 << 12) | (imm11 << 1), - 1 + 1 + 1 + 10 + 11 + 1, 32); - vmaddr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + imm; - dst_vmaddr |= 1; - - _ t2_ldr(pc, MemOperand(pc, 0)); - _ EmitAddress(dst_vmaddr); - - is_insn_relocated = true; - } - - // BL, BLX (immediate) - T1 variant on page F5-4135 - if ((op3 & 0b101) == 0b101) { - DLOG(0, "%d:relo at %p", ctx->relocated_offset_map.size(), - relo_cur_src_vmaddr(ctx)); - - uint32_t S = bit(insn1, 10); - uint32_t J1 = bit(insn2, 13); - uint32_t J2 = bit(insn2, 11); - uint32_t i1 = !(J1 ^ S); - uint32_t i2 = !(J2 ^ S); - uint32_t imm11 = bits(insn2, 0, 10); - uint32_t imm10 = bits(insn1, 0, 9); - int32_t imm = - SignExtend((S << 24) | (i1 << 23) | (i2 << 22) | (imm10 << 12) | (imm11 << 1), - 1 + 1 + 1 + 10 + 11 + 1, 32); - vmaddr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + imm; - dst_vmaddr |= 1; - - _ t2_bl(4); - _ t2_b(8); - _ t2_ldr(pc, MemOperand(pc, 0)); - _ EmitAddress(dst_vmaddr); - - is_insn_relocated = true; - } - - // BL, BLX (immediate) - T2 variant on page F5-4136 - if ((op3 & 0b101) == 0b100) { - DLOG(0, "%d:relo at %p", ctx->relocated_offset_map.size(), - relo_cur_src_vmaddr(ctx)); - - uint32_t S = bit(insn1, 10); - uint32_t J1 = bit(insn2, 13); - uint32_t J2 = bit(insn2, 11); - uint32_t i1 = !(J1 ^ S); - uint32_t i2 = !(J2 ^ S); - uint32_t imm10h = bits(insn1, 0, 9); - uint32_t imm10l = bits(insn2, 1, 10); - int32_t imm = - SignExtend((S << 24) | (i1 << 23) | (i2 << 22) | (imm10h << 12) | (imm10l << 2), - 1 + 1 + 1 + 10 + 10 + 1, 32); - vmaddr_t dst_vmaddr = relo_cur_src_vmaddr(ctx); - dst_vmaddr = ALIGN_FLOOR(dst_vmaddr, 4); - dst_vmaddr+= imm; - - _ t2_bl(4); - _ t2_b(8); - _ t2_ldr(pc, MemOperand(pc, 0)); - _ EmitAddress(dst_vmaddr); - - is_insn_relocated = true; - } - } - - // Data-processing (plain binary immediate) on page F3-3983 - if ((insn1 & (0xfa10)) == 0xf200 & (insn2 & 0x8000) == 0) { - uint32_t op0 = 0, op1 = 0; - op0 = bit(insn1, 8); - op1 = bits(insn2, 5, 6); - - // Data-processing (simple immediate) - if (op0 == 0 && (op1 & 0b10) == 0b00) { - int o1 = bit(insn1, 7); - int o2 = bit(insn1, 5); - int rn = bits(insn1, 0, 3); - - // ADR - if (((o1 == 0 && o2 == 0) || (o1 == 1 && o2 == 1)) && rn == 0b1111) { - uint32_t i = bit(insn1, 10); - uint32_t imm3 = bits(insn2, 12, 14); - uint32_t imm8 = bits(insn2, 0, 7); - uint32_t rd = bits(insn2, 8, 11); - uint32_t imm = (i << 11) | (imm3 << 8) | imm8; - - vmaddr_t dst_vmaddr = 0; - if (o1 == 0 && o2 == 0) { // ADR - T3 on page F5-4098 - dst_vmaddr = relo_cur_src_vmaddr(ctx) + imm; - } else if (o1 == 1 && o2 == 1) { // ADR - T2 on page F5-4097 - dst_vmaddr = relo_cur_src_vmaddr(ctx) - imm; - } else { - UNREACHABLE(); - } - - _ t2_ldr(Register::R(rd), MemOperand(pc, 4)); - _ t2_b(0); - _ EmitAddress(dst_vmaddr); - - is_insn_relocated = true; - } - } - } - - // Load/store single on page F3-3988 - // Load, unsigned (literal) on page F3-3992 - // Load, signed (literal) on page F3-3996 - // LDR literal (T2) - if ((insn1 & 0xff7f) == 0xf85f) { - uint32_t U = bit(insn1, 7); - uint32_t imm12 = bits(insn2, 0, 11); - uint16_t rt = bits(insn2, 12, 15); - - uint32_t imm = imm12; - - vmaddr_t dst_vmaddr = 0; - if (U == 1) { - dst_vmaddr = relo_cur_src_vmaddr(ctx) + imm; - } else { - dst_vmaddr = relo_cur_src_vmaddr(ctx) - imm; - } - - Register regRt = Register::R(rt); - - _ t2_ldr(regRt, MemOperand(pc, 8)); - _ t2_ldr(regRt, MemOperand(regRt, 0)); - _ t2_b(4); - _ EmitAddress(dst_vmaddr); - - is_insn_relocated = true; - } - - // if the insn not needed relocate, just rewrite the origin - if (!is_insn_relocated) { -#if 0 - if (relo_cur_src_vmaddr(ctx) % Thumb2_INST_LEN) - _ t1_nop(); -#endif - _ EmitInt16(insn1); - _ EmitInt16(insn2); - } -} - -void gen_arm_relocate_code(relo_ctx_t *ctx) { - -#undef _ -#define _ turbo_assembler_-> - auto turbo_assembler_ = static_cast(ctx->curr_assembler); -#define _ turbo_assembler_-> - - auto relocated_buffer = turbo_assembler_->GetCodeBuffer(); - - DLOG(0, "[arm] ARM relocate %d start >>>>>", ctx->buffer_size); - - while (ctx->buffer_cursor < ctx->buffer + ctx->buffer_size) { - uint32_t orig_off = ctx->buffer_cursor - ctx->buffer; - uint32_t relocated_off = relocated_buffer->GetBufferSize(); - ctx->relocated_offset_map[orig_off] = relocated_off; - - arm_inst_t insn = *(arm_inst_t *) ctx->buffer_cursor; - - int last_relo_offset = turbo_assembler_->GetCodeBuffer()->GetBufferSize(); - - ARMRelocateSingleInsn(ctx, insn); - DLOG(0, "[arm] Relocate arm insn: 0x%x", insn); - - // move to next instruction - ctx->buffer_cursor += ARM_INST_LEN; - - // execute state changed - addr32_t next_insn_addr = relo_cur_src_vmaddr(ctx) - ARM_PC_OFFSET; - if (check_execute_state_changed(ctx, next_insn_addr)) { - break; - } - } - - bool is_relocate_interrupted = ctx->buffer_cursor < ctx->buffer + ctx->buffer_size; - if (is_relocate_interrupted) { - turbo_assembler_->SetExecuteState(ThumbExecuteState); - } -} - -void gen_thumb_relocate_code(relo_ctx_t *ctx) { - int relocated_insn_count = 0; - - auto turbo_assembler_ = static_cast(ctx->curr_assembler); -#define _ turbo_assembler_-> - - auto relocated_buffer = turbo_assembler_->GetCodeBuffer(); - - DLOG(0, "[arm] Thumb relocate %d start >>>>>", ctx->buffer_size); - - while (ctx->buffer_cursor < ctx->buffer + ctx->buffer_size) { - uint32_t orig_off = ctx->buffer_cursor - ctx->buffer; - uint32_t relocated_off = relocated_buffer->GetBufferSize(); - ctx->relocated_offset_map[orig_off] = relocated_off; - - // align nop - _ t1_nop(); - - thumb2_inst_t insn = *(thumb2_inst_t *) ctx->buffer_cursor; - - int last_relo_offset = relocated_buffer->GetBufferSize(); - if (is_thumb2(insn)) { - Thumb2RelocateSingleInsn(ctx, (uint16_t) insn, (uint16_t) (insn >> 16)); - DLOG(0, "[arm] Relocate thumb2 insn: 0x%x", insn); - } else { - Thumb1RelocateSingleInsn(ctx, (uint16_t) insn); - DLOG(0, "[arm] Relocate thumb1 insn: 0x%x", (uint16_t) insn); - } - - // Move to next instruction - if (is_thumb2(insn)) { - ctx->buffer_cursor += Thumb2_INST_LEN; - } else { - ctx->buffer_cursor += Thumb1_INST_LEN; - } - - // execute state changed - addr32_t next_insn_addr = relo_cur_src_vmaddr(ctx) - Thumb_PC_OFFSET; - if (check_execute_state_changed(ctx, next_insn_addr)) { - break; - } - } - - // .thumb1 bx pc - // .thumb1 mov r8, r8 - // .arm ldr pc, [pc, #-4] - - bool is_relocate_interrupted = ctx->buffer_cursor < ctx->buffer + ctx->buffer_size; - if (is_relocate_interrupted) { - turbo_assembler_->SetExecuteState(ARMExecuteState); - } -} - -void GenRelocateCode(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch) { - relo_ctx_t ctx; - - if ((addr_t) buffer % 2) { - ctx.start_state = ThumbExecuteState; - ctx.curr_state = ThumbExecuteState; - // remove thumb address flag - buffer = (void *) ((addr_t) buffer - 1); - } else { - ctx.start_state = ARMExecuteState; - ctx.curr_state = ARMExecuteState; - } - - ctx.buffer = ctx.buffer_cursor = (uint8_t *) buffer; - ctx.buffer_size = origin->size; - - ctx.src_vmaddr = (vmaddr_t) origin->addr; - ctx.dst_vmaddr = 0; - - auto *relocated_buffer = new CodeBuffer(); - ctx.relocated_buffer = relocated_buffer; - - ThumbTurboAssembler thumb_turbo_assembler_(0, ctx.relocated_buffer); -#define thumb_ thumb_turbo_assembler_. - TurboAssembler arm_turbo_assembler_(0, ctx.relocated_buffer); -#define arm_ arm_turbo_assembler_. - - if (ctx.start_state == ThumbExecuteState) - ctx.curr_assembler = &thumb_turbo_assembler_; - else - ctx.curr_assembler = &arm_turbo_assembler_; - - relocate_remain: - if (ctx.curr_state == ThumbExecuteState) { - ctx.curr_assembler = &thumb_turbo_assembler_; - gen_thumb_relocate_code(&ctx); - if (thumb_turbo_assembler_.GetExecuteState() == ARMExecuteState) { - // translate interrupt as execute state changed - bool is_translate_interrupted = ctx.buffer_cursor < ctx.buffer + ctx.buffer_size; - if (is_translate_interrupted) { - // add nop to align ARM - if (thumb_turbo_assembler_.pc_offset() % 4) - thumb_turbo_assembler_.t1_nop(); - goto relocate_remain; - } - } - } else { - ctx.curr_assembler = &arm_turbo_assembler_; - gen_arm_relocate_code(&ctx); - if (arm_turbo_assembler_.GetExecuteState() == ThumbExecuteState) { - bool is_translate_interrupted = ctx.buffer_cursor < ctx.buffer + ctx.buffer_size; - // translate interrupt as execute state changed - if (is_translate_interrupted) { - goto relocate_remain; - } - } - } - - // update origin - int new_origin_len = (addr_t)ctx.buffer_cursor - (addr_t)ctx.buffer; - origin->reset(origin->addr, new_origin_len); - - // TODO: if last insn is unlink branch, skip - if (branch) { - if (ctx.curr_state == ThumbExecuteState) { - // branch to the rest of instructions - thumb_ AlignThumbNop(); - thumb_ t2_ldr(pc, MemOperand(pc, 0)); - // get the real branch address - thumb_ EmitAddress(origin->addr + origin->size + THUMB_ADDRESS_FLAG); - } else { - // branch to the rest of instructions - CodeGen codegen(&arm_turbo_assembler_); - // get the real branch address - codegen.LiteralLdrBranch(origin->addr + origin->size); - } - } - - // fixup the insn branch into trampoline(has been modified) - arm_turbo_assembler_.RelocLabelFixup(&ctx.relocated_offset_map); - thumb_turbo_assembler_.RelocLabelFixup(&ctx.relocated_offset_map); - - // realize all the pseudo data label - thumb_turbo_assembler_.RelocBind(); - arm_turbo_assembler_.RelocBind(); - - // generate executable code - { - // assembler without specific memory address - auto relocated_mem = MemoryAllocator::SharedAllocator()->allocateExecMemory( - relocated_buffer->GetBufferSize()); - if (relocated_mem == nullptr) - return; - - thumb_turbo_assembler_.SetRealizedAddress((void *) relocated_mem); - arm_turbo_assembler_.SetRealizedAddress((void *) relocated_mem); - - AssemblyCode *code = NULL; - code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(ctx.curr_assembler); - relocated->reset(code->addr, code->size); - } - - // thumb - if (ctx.start_state == ThumbExecuteState) { - // add thumb address flag - relocated->reset(relocated->addr + THUMB_ADDRESS_FLAG, relocated->size); - } - - // clean - { - thumb_turbo_assembler_.ClearCodeBuffer(); - arm_turbo_assembler_.ClearCodeBuffer(); - - delete relocated_buffer; - } -} - -void GenRelocateCodeAndBranch(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated) { - GenRelocateCode(buffer, origin, relocated, true); -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/arm/InstructionRelocationARM.h b/app/src/main/cpp/Dobby/source/InstructionRelocation/arm/InstructionRelocationARM.h deleted file mode 100644 index e33413d..0000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/arm/InstructionRelocationARM.h +++ /dev/null @@ -1,300 +0,0 @@ -#pragma once -#include "dobby_internal.h" - -#include "core/arch/arm/constants-arm.h" -#include "core/assembler/assembler-arm.h" - -namespace zz { -namespace arm { - -// thumb1/thumb2 pseudo label type, only support Thumb1-Ldr | Thumb2-Ldr -enum ref_label_type_t { kThumb1Ldr, kThumb2LiteralLdr }; - -// custom thumb pseudo label for thumb/thumb2 -class ThumbPseudoLabel : public AssemblerPseudoLabel { -public: - // fix the instruction which not link to the label yet. - void link_confused_instructions(CodeBuffer *buffer) { - CodeBuffer *_buffer; - if (buffer) - _buffer = buffer; - - for (auto &ref_label_inst : ref_label_insts_) { - // instruction offset to label - thumb2_inst_t insn = _buffer->LoadThumb2Inst(ref_label_inst.offset_); - thumb1_inst_t insn1 = _buffer->LoadThumb1Inst(ref_label_inst.offset_); - thumb1_inst_t insn2 = _buffer->LoadThumb1Inst(ref_label_inst.offset_ + sizeof(thumb1_inst_t)); - - switch (ref_label_inst.type_) { - case kThumb1Ldr: { - UNREACHABLE(); - } break; - case kThumb2LiteralLdr: { - int64_t pc = ref_label_inst.offset_ + Thumb_PC_OFFSET; - assert(pc % 4 == 0); - int32_t imm12 = relocated_pos() - pc; - - if (imm12 > 0) { - set_bit(insn1, 7, 1); - } else { - set_bit(insn1, 7, 0); - imm12 = -imm12; - } - set_bits(insn2, 0, 11, imm12); - _buffer->RewriteThumb1Inst(ref_label_inst.offset_, insn1); - _buffer->RewriteThumb1Inst(ref_label_inst.offset_ + Thumb1_INST_LEN, insn2); - - DLOG(0, "[thumb label link] insn offset %d link offset %d", ref_label_inst.offset_, imm12); - } break; - default: - UNREACHABLE(); - break; - } - } - } -}; - -class ThumbRelocLabelEntry : public ThumbPseudoLabel, public RelocLabel { -public: - template - ThumbRelocLabelEntry(T value, bool is_pc_register) - : RelocLabel(value), ThumbPseudoLabel(), is_pc_register_(is_pc_register) { - } - - bool is_pc_register() { - return is_pc_register_; - } - -private: - bool is_pc_register_; -}; - -// --- - -class ThumbAssembler : public Assembler { -public: - ThumbAssembler(void *address) : Assembler(address) { - this->SetExecuteState(ThumbExecuteState); - } - - ThumbAssembler(void *address, CodeBuffer *buffer) : Assembler(address, buffer) { - this->SetExecuteState(ThumbExecuteState); - } - - void EmitInt16(int16_t val) { - buffer_->Emit16(val); - } - - void Emit2Int16(int16_t val1, int16_t val2) { - EmitInt16(val1); - EmitInt16(val2); - } - - void EmitAddress(uint32_t value) { - buffer_->Emit32(value); - } - - // ===== - void t1_nop() { - EmitInt16(0xbf00); - } - void t1_b(int32_t imm) { - ASSERT(CheckSignLength(imm, 12)); - ASSERT(CheckAlign(imm, 2)); - - int32_t imm11 = bits(imm >> 1, 0, 10); - EmitInt16(0xe000 | imm11); - } - - // ===== - void t2_b(uint32_t imm) { - EmitThumb2Branch(AL, imm, false); - } - void t2_bl(uint32_t imm) { - EmitThumb2Branch(AL, imm, true); - } - void t2_blx(uint32_t imm) { - UNIMPLEMENTED(); - } - - // ===== - void t2_ldr(Register dst, const MemOperand &src) { - // WARNNING: literal ldr, base = ALIGN(pc, 4) - EmitThumb2LoadStore(true, dst, src); - } - -private: - void EmitThumb2LoadLiteral(Register rt, const MemOperand x) { - bool add = true; - uint32_t U, imm12; - int32_t offset = x.offset(); - -#if 0 - // literal ldr, base = ALIGN(pc, 4) - if (rt.Is(pc)) { - // TODO: convert to `GetRealizedAddress()` ??? - addr_t curr_pc = pc_offset() + (addr_t)GetRealizedAddress(); - if (curr_pc % 4) { - t1_nop(); - } - } -#endif - - if (offset > 0) { - U = B7; - imm12 = offset; - } else { - U = 0; - imm12 = -offset; - } - EmitInt16(0xf85f | U); - EmitInt16(0x0 | (rt.code() << 12) | imm12); - } - void EmitThumb2LoadStore(bool load, Register rt, const MemOperand x) { - if (x.rn().Is(pc)) { - EmitThumb2LoadLiteral(rt, x); - return; - } - - bool index, add, wback; - if (x.IsRegisterOffset() && x.offset() >= 0) { - index = true, add = true, wback = false; - uint32_t imm12 = x.offset(); - EmitInt16(0xf8d0 | (x.rn().code() << 0)); - EmitInt16(0x0 | (rt.code() << 12) | imm12); - } else { - // use bit accelerate - uint32_t P = 0, W = 0, U = 0; - uint32_t imm8 = x.offset() > 0 ? x.offset() : -x.offset(); - U = x.offset() > 0 ? 0 : B9; - if (x.IsPostIndex()) { - P = 0, W = B8; - } else if (x.IsPreIndex()) { - P = B10, W = B8; - } - index = (P == B10); - add = (U == B9); - wback = (W == B8); - EmitInt16(0xf850 | (x.rn().code() << 0)); - EmitInt16(0x0800 | (rt.code() << 12) | P | U | W | imm8); - } - } - - void EmitThumb2Branch(Condition cond, int32_t imm, bool link) { - uint32_t operand = imm >> 1; - ASSERT(CheckSignLength(operand, 25)); - ASSERT(CheckAlign(operand, 2)); - - uint32_t signbit = (imm >> 31) & 0x1; - uint32_t i1 = (operand >> 22) & 0x1; - uint32_t i2 = (operand >> 21) & 0x1; - uint32_t imm10 = (operand >> 11) & 0x03ff; - uint32_t imm11 = operand & 0x07ff; - uint32_t j1 = (!(i1 ^ signbit)); - uint32_t j2 = (!(i2 ^ signbit)); - - if (cond != AL) { - UNIMPLEMENTED(); - } - - EmitInt16(0xf000 | LeftShift(signbit, 1, 10) | LeftShift(imm10, 10, 0)); - if (link) { - // Not use LeftShift(1, 1, 14), and use B14 for accelerate - EmitInt16(0x9000 | LeftShift(j1, 1, 13) | (LeftShift(j2, 1, 11)) | LeftShift(imm11, 11, 0) | B14); - } else { - EmitInt16(0x9000 | LeftShift(j1, 1, 13) | (LeftShift(j2, 1, 11)) | LeftShift(imm11, 11, 0)); - } - } -}; - -// --- - -class ThumbTurboAssembler : public ThumbAssembler { -public: - ThumbTurboAssembler(void *address) : ThumbAssembler(address) { - } - - ThumbTurboAssembler(void *address, CodeBuffer *buffer) : ThumbAssembler(address, buffer) { - } - - ~ThumbTurboAssembler() { - } - - void T1_Ldr(Register rt, ThumbPseudoLabel *label) { - UNREACHABLE(); - -// t1_ldr: rt can't be PC register -// === -#if 0 - if (label->is_bound()) { - const int64_t dest = label->pos() - buffer_.Size(); - ldr(rt, MemOperand(pc, dest)); - } else { - // record this ldr, and fix later. - label->link_to(buffer_.Size(), ThumbPseudoLabel::kThumb1Ldr); - ldr(rt, MemOperand(pc, 0)); - } -#endif - } - - void T2_Ldr(Register rt, ThumbPseudoLabel *label) { - if (label->relocated_pos()) { - int offset = label->relocated_pos() - buffer_->GetBufferSize(); - t2_ldr(rt, MemOperand(pc, offset)); - } else { - // record this ldr, and fix later. - label->link_to(kThumb2LiteralLdr, 0, buffer_->GetBufferSize()); - t2_ldr(rt, MemOperand(pc, 0)); - } - } - - void AlignThumbNop() { - addr32_t pc = this->GetCodeBuffer()->GetBufferSize() + (uintptr_t)GetRealizedAddress(); - if (pc % Thumb2_INST_LEN) { - t1_nop(); - } else { - } - } - - // --- - - void PseudoBind(ThumbPseudoLabel *label) { - const addr_t bound_pc = buffer_->GetBufferSize(); - label->bind_to(bound_pc); - // If some instructions have been wrote, before the label bound, we need link these `confused` instructions - if (label->has_confused_instructions()) { - label->link_confused_instructions(GetCodeBuffer()); - } - } - - void RelocBind() { - for (auto *data_label : data_labels_) { - PseudoBind(data_label); - reinterpret_cast(buffer_)->EmitBuffer(data_label->data_, data_label->data_size_); - } - } - - void AppendRelocLabel(ThumbRelocLabelEntry *label) { - data_labels_.push_back(label); - } - - void RelocLabelFixup(tinystl::unordered_map *relocated_offset_map) { - for (auto *data_label : data_labels_) { - auto val = data_label->data(); - auto iter = relocated_offset_map->find(val); - if (iter != relocated_offset_map->end()) { - data_label->fixup_data(iter->second); - } - } - } - -private: - std::vector data_labels_; -}; - -#if 0 -void GenRelocateCodeAndBranch(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated); -#endif - -} // namespace arm -} // namespace zz diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/InstructionRelocationARM64.cc b/app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/InstructionRelocationARM64.cc deleted file mode 100644 index 49d447c..0000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/InstructionRelocationARM64.cc +++ /dev/null @@ -1,366 +0,0 @@ -#include "platform_macro.h" - -#if defined(TARGET_ARCH_ARM64) - -#include "InstructionRelocation/arm64/InstructionRelocationARM64.h" - -#include "dobby_internal.h" - -#include "core/arch/arm64/registers-arm64.h" -#include "core/assembler/assembler-arm64.h" -#include "core/codegen/codegen-arm64.h" - -#include "inst_constants.h" -#include "inst_decode_encode_kit.h" - -using namespace zz::arm64; - -#if defined(DOBBY_DEBUG) -#define debug_nop() _ nop() -#else -#define debug_nop() -#endif - -#define arm64_trunc_page(x) ((x) & (~(0x1000 - 1))) -#define arm64_round_page(x) trunc_page((x) + (0x1000 - 1)) - -typedef struct { - addr_t mapped_addr; - - uint8_t *buffer; - uint8_t *buffer_cursor; - size_t buffer_size; - - vmaddr_t src_vmaddr; - vmaddr_t dst_vmaddr; - - CodeMemBlock *origin; - CodeMemBlock *relocated; - - tinystl::unordered_map relocated_offset_map; - - tinystl::unordered_map label_map; - -} relo_ctx_t; - -// --- - -addr_t relo_cur_src_vmaddr(relo_ctx_t *ctx) { - return ctx->src_vmaddr + (ctx->buffer_cursor - ctx->buffer); -} - -addr_t relo_cur_dst_vmaddr(relo_ctx_t *ctx, TurboAssembler *assembler) { - return ctx->dst_vmaddr + assembler->GetCodeBuffer()->GetBufferSize(); -} - -addr_t relo_src_offset_to_vmaddr(relo_ctx_t *ctx, off_t offset) { - return ctx->src_vmaddr + offset; -} - -addr_t relo_dst_offset_to_vmaddr(relo_ctx_t *ctx, off_t offset) { - return ctx->dst_vmaddr + offset; -} - -// --- - -#if 0 -bool has_relo_label_at(relo_ctx_t *ctx, vmaddr_t addr) { - if (ctx->label_map.count(addr)) { - return true; - } - return false; -} - -AssemblerPseudoLabel *relo_label_create_or_get(relo_ctx_t *ctx, vmaddr_t addr) { - if (!ctx->label_map.count(addr)) { - auto *label = new AssemblerPseudoLabel(addr); - ctx->label_map[addr] = label; - } - return ctx->label_map[addr]; -} - -int64_t relo_label_link_offset(relo_ctx_t *ctx, pcrel_type_t pcrel_type, int64_t offset) { - auto is_offset_undefined = [ctx](int64_t offset) -> bool { - if (ctx->buffer_cursor + offset < ctx->buffer || ctx->buffer_cursor + offset > ctx->buffer + ctx->buffer_size) { - return true; - } - return false; - }; - - auto is_offset_uninitialized = [ctx](int64_t offset) -> bool { - if (ctx->buffer_cursor + offset > ctx->buffer && ctx->buffer_cursor + offset < ctx->buffer + ctx->buffer_size) { - if (!ctx->relocated_offset_map.count(ctx->buffer_cursor + offset - ctx->buffer_cursor)) - return true; - } - return false; - }; - - addr_t label_vmaddr = relo_cur_src_vmaddr(ctx) + offset; - if (pcrel_type == RELO_ARM64_RELOC_PAGE21) { - label_vmaddr = arm64_trunc_page(label_vmaddr); - } - - auto *label = relo_label_create_or_get(ctx, label_vmaddr); - if (is_offset_undefined(offset)) { // pc relative target is beyond our scope - label->link_to(AssemblerPseudoLabel::kLabelImm19, relo_cur_src_vmaddr(ctx), (addr_t)ctx->buffer_cursor - ctx->mapped_addr); - return 0; - } else if (is_offset_uninitialized(offset)) { // pc relative target is in our control, but not handle yet - label->link_to(AssemblerPseudoLabel::kLabelImm19, relo_cur_src_vmaddr(ctx), (addr_t)ctx->buffer_cursor - ctx->mapped_addr); - return 0; - } else { // pc relative target is already handled - off_t off = ctx->buffer_cursor + offset - ctx->buffer; - off_t relocated_off = label->relocated_pos(); - int64_t new_offset = relo_dst_offset_to_vmaddr(ctx, relocated_off) - relo_src_offset_to_vmaddr(ctx, off); - return new_offset; - } -} -#endif - -// --- - -static inline bool inst_is_b_bl(uint32_t instr) { - return (instr & UnconditionalBranchFixedMask) == UnconditionalBranchFixed; -} - -static inline bool inst_is_ldr_literal(uint32_t instr) { - return ((instr & LoadRegLiteralFixedMask) == LoadRegLiteralFixed); -} - -static inline bool inst_is_adr(uint32_t instr) { - return (instr & PCRelAddressingFixedMask) == PCRelAddressingFixed && (instr & PCRelAddressingMask) == ADR; -} - -static inline bool inst_is_adrp(uint32_t instr) { - return (instr & PCRelAddressingFixedMask) == PCRelAddressingFixed && (instr & PCRelAddressingMask) == ADRP; -} - -static inline bool inst_is_b_cond(uint32_t instr) { - return (instr & ConditionalBranchFixedMask) == ConditionalBranchFixed; -} - -static inline bool inst_is_compare_b(uint32_t instr) { - return (instr & CompareBranchFixedMask) == CompareBranchFixed; -} - -static inline bool inst_is_test_b(uint32_t instr) { - return (instr & TestBranchFixedMask) == TestBranchFixed; -} - -// --- - -int relo_relocate(relo_ctx_t *ctx, bool branch) { - int relocated_insn_count = 0; - - TurboAssembler turbo_assembler_(0); -#define _ turbo_assembler_. - - auto relocated_buffer = turbo_assembler_.GetCodeBuffer(); - - while (ctx->buffer_cursor < ctx->buffer + ctx->buffer_size) { - uint32_t orig_off = ctx->buffer_cursor - ctx->buffer; - uint32_t relocated_off = relocated_buffer->GetBufferSize(); - ctx->relocated_offset_map[orig_off] = relocated_off; - -#if 0 - vmaddr_t inst_vmaddr = 0; - inst_vmaddr = relo_cur_src_vmaddr(ctx); - if (has_relo_label_at(ctx, inst_vmaddr)) { - auto *label = relo_label_create_or_get(ctx, inst_vmaddr); - label->bind_to(inst_vmaddr); - } -#endif - - arm64_inst_t inst = *(arm64_inst_t *)ctx->buffer_cursor; - if (inst_is_b_bl(inst)) { - DLOG(0, "%d:relo at %p", relocated_insn_count++, relo_cur_src_vmaddr(ctx)); - - int64_t offset = decode_imm26_offset(inst); - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + offset; - - RelocLabel *dst_label = new RelocLabel(dst_vmaddr); - _ AppendRelocLabel(dst_label); - - { - _ Ldr(TMP_REG_0, dst_label); - if ((inst & UnconditionalBranchMask) == BL) { - _ blr(TMP_REG_0); - } else { - _ br(TMP_REG_0); - } - } - - } else if (inst_is_ldr_literal(inst)) { - DLOG(0, "%d:relo at %p", relocated_insn_count++, relo_cur_src_vmaddr(ctx)); - - int64_t offset = decode_imm19_offset(inst); - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + offset; - - int rt = decode_rt(inst); - char opc = bits(inst, 30, 31); - - { - _ Mov(TMP_REG_0, dst_vmaddr); - if (opc == 0b00) - _ ldr(W(rt), MemOperand(TMP_REG_0, 0)); - else if (opc == 0b01) - _ ldr(X(rt), MemOperand(TMP_REG_0, 0)); - else { - UNIMPLEMENTED(); - } - } - } else if (inst_is_adr(inst)) { - DLOG(0, "%d:relo at %p", relocated_insn_count++, relo_cur_src_vmaddr(ctx)); - - int64_t offset = decode_immhi_immlo_offset(inst); - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + offset; - - int rd = decode_rd(inst); - - { - _ Mov(X(rd), dst_vmaddr); - ; - } - } else if (inst_is_adrp(inst)) { - DLOG(0, "%d:relo at %p", relocated_insn_count++, relo_cur_src_vmaddr(ctx)); - - int64_t offset = decode_immhi_immlo_zero12_offset(inst); - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + offset; - dst_vmaddr = arm64_trunc_page(dst_vmaddr); - - int rd = decode_rd(inst); - - { - _ Mov(X(rd), dst_vmaddr); - ; - } - } else if (inst_is_b_cond(inst)) { - DLOG(0, "%d:relo at %p", relocated_insn_count++, relo_cur_src_vmaddr(ctx)); - - int64_t offset = decode_imm19_offset(inst); - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + offset; - - arm64_inst_t branch_instr = inst; - { - char cond = bits(inst, 0, 3); - cond = cond ^ 1; - set_bits(branch_instr, 0, 3, cond); - - int64_t offset = 4 * 3; - uint32_t imm19 = offset >> 2; - set_bits(branch_instr, 5, 23, imm19); - } - - RelocLabel *dst_label = new RelocLabel(dst_vmaddr); - _ AppendRelocLabel(dst_label); - - { - _ Emit(branch_instr); - { - _ Ldr(TMP_REG_0, dst_label); - _ br(TMP_REG_0); - } - } - } else if (inst_is_compare_b(inst)) { - DLOG(0, "%d:relo at %p", relocated_insn_count++, relo_cur_src_vmaddr(ctx)); - - int64_t offset = decode_imm19_offset(inst); - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + offset; - - arm64_inst_t branch_instr = inst; - { - char op = bit(inst, 24); - op = op ^ 1; - set_bit(branch_instr, 24, op); - - int64_t offset = 4 * 3; - uint32_t imm19 = offset >> 2; - set_bits(branch_instr, 5, 23, imm19); - } - - RelocLabel *dst_label = new RelocLabel(dst_vmaddr); - _ AppendRelocLabel(dst_label); - - { - _ Emit(branch_instr); - { - _ Ldr(TMP_REG_0, dst_label); - _ br(TMP_REG_0); - } - } - } else if (inst_is_test_b(inst)) { - DLOG(0, "%d:relo at %p", relocated_insn_count++, relo_cur_src_vmaddr(ctx)); - - int64_t offset = decode_imm14_offset(inst); - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + offset; - - arm64_inst_t branch_instr = inst; - { - char op = bit(inst, 24); - op = op ^ 1; - set_bit(branch_instr, 24, op); - - int64_t offset = 4 * 3; - uint32_t imm14 = offset >> 2; - set_bits(branch_instr, 5, 18, imm14); - } - - RelocLabel *dst_label = new RelocLabel(dst_vmaddr); - _ AppendRelocLabel(dst_label); - - { - _ Emit(branch_instr); - { - _ Ldr(TMP_REG_0, dst_label); - _ br(TMP_REG_0); - } - } - } else { - _ Emit(inst); - } - - ctx->buffer_cursor += sizeof(arm64_inst_t); - } -#undef _ - - // update origin - int new_origin_len = (addr_t)ctx->buffer_cursor - (addr_t)ctx->buffer; - ctx->origin->reset(ctx->origin->addr, new_origin_len); - - // TODO: if last instr is unlink branch, ignore it - if (branch) { - CodeGen codegen(&turbo_assembler_); - codegen.LiteralLdrBranch(ctx->origin->addr + ctx->origin->size); - } - - // Bind all labels - turbo_assembler_.RelocBind(); - - // Generate executable code - { - auto code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); - ctx->relocated = code; - } - return 0; -} - -void GenRelocateCode(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch) { - relo_ctx_t ctx = {0}; - - ctx.buffer = ctx.buffer_cursor = (uint8_t *)buffer; - ctx.buffer_size = origin->size; - - ctx.src_vmaddr = (vmaddr_t)origin->addr; - ctx.dst_vmaddr = (vmaddr_t)relocated->addr; - - ctx.origin = origin; - - relo_relocate(&ctx, branch); - - relocated->reset(ctx.relocated->addr, ctx.relocated->size); -} - -void GenRelocateCodeAndBranch(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated) { - GenRelocateCode(buffer, origin, relocated, true); -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/InstructionRelocationARM64.h b/app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/InstructionRelocationARM64.h deleted file mode 100644 index c42bfd7..0000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/InstructionRelocationARM64.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "dobby_internal.h" - -#include "core/arch/arm64/constants-arm64.h" - -#if 0 -namespace zz { -namespace arm64 { -void GenRelocateCodeAndBranch(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated); -} // namespace arm64 -} // namespace zz -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/inst_constants.h b/app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/inst_constants.h deleted file mode 100644 index 228a952..0000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/inst_constants.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#if 0 -enum LoadRegLiteralOp { - LoadRegLiteralFixed = 0x18000000, - LoadRegLiteralFixedMask = 0x3B000000, - LoadRegLiteralMask = 0xFF000000, -}; - -// PC relative addressing. -enum PCRelAddressingOp { - PCRelAddressingFixed = 0x10000000, - PCRelAddressingFixedMask = 0x1F000000, - PCRelAddressingMask = 0x9F000000, - ADR = PCRelAddressingFixed | 0x00000000, - ADRP = PCRelAddressingFixed | 0x80000000 -}; - -// Unconditional branch. -enum UnconditionalBranchOp { - UnconditionalBranchFixed = 0x14000000, - UnconditionalBranchFixedMask = 0x7C000000, - UnconditionalBranchMask = 0xFC000000, - - B = UnconditionalBranchFixed | 0x00000000, - BL = UnconditionalBranchFixed | 0x80000000 -}; -#endif - -// Compare and branch. -enum CompareBranchOp { - CompareBranchFixed = 0x34000000, - CompareBranchFixedMask = 0x7E000000, - CompareBranchMask = 0xFF000000, -}; - -// Conditional branch. -enum ConditionalBranchOp { - ConditionalBranchFixed = 0x54000000, - ConditionalBranchFixedMask = 0xFE000000, - ConditionalBranchMask = 0xFF000010, -}; - -// Test and branch. -enum TestBranchOp { - TestBranchFixed = 0x36000000, - TestBranchFixedMask = 0x7E000000, - TestBranchMask = 0x7F000000, -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/inst_decode_encode_kit.h b/app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/inst_decode_encode_kit.h deleted file mode 100644 index 306618e..0000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/inst_decode_encode_kit.h +++ /dev/null @@ -1,110 +0,0 @@ -#pragma once - -#include "common_header.h" - -static inline int64_t SignExtend(unsigned long x, int M, int N) { -#if 1 - char sign_bit = bit(x, M - 1); - unsigned long sign_mask = 0 - sign_bit; - x |= ((sign_mask >> M) << M); -#else - x = (long)((long)x << (N - M)) >> (N - M); -#endif - return (int64_t )x; -} - -static inline int64_t decode_imm14_offset(uint32_t instr) { - int64_t offset; - { - int64_t imm14 = bits(instr, 5, 18); - offset = (imm14 << 2); - } - offset = SignExtend(offset, 2 + 14, 64); - return offset; -} -static inline uint32_t encode_imm14_offset(uint32_t instr, int64_t offset) { - uint32_t imm14 = bits((offset >> 2), 0, 13); - set_bits(instr, 5, 18, imm14); - return instr; -} - -static inline int64_t decode_imm19_offset(uint32_t instr) { - int64_t offset; - { - int64_t imm19 = bits(instr, 5, 23); - offset = (imm19 << 2); - } - offset = SignExtend(offset, 2 + 19, 64); - return offset; -} - -static inline uint32_t encode_imm19_offset(uint32_t instr, int64_t offset) { - uint32_t imm19 = bits((offset >> 2), 0, 18); - set_bits(instr, 5, 23, imm19); - return instr; -} - -static inline int64_t decode_imm26_offset(uint32_t instr) { - int64_t offset; - { - int64_t imm26 = bits(instr, 0, 25); - offset = (imm26 << 2); - } - offset = SignExtend(offset, 2 + 26, 64); - return offset; -} -static inline uint32_t encode_imm26_offset(uint32_t instr, int64_t offset) { - uint32_t imm26 = bits((offset >> 2), 0, 25); - set_bits(instr, 0, 25, imm26); - return instr; -} - -static inline int64_t decode_immhi_immlo_offset(uint32_t instr) { - typedef uint32_t instr_t; - struct { - instr_t Rd : 5; // Destination register - instr_t immhi : 19; // 19-bit upper immediate - instr_t dummy_0 : 5; // Must be 10000 == 0x10 - instr_t immlo : 2; // 2-bit lower immediate - instr_t op : 1; // 0 = ADR, 1 = ADRP - } instr_decode; - - *(instr_t *)&instr_decode = instr; - - int64_t imm = instr_decode.immlo + (instr_decode.immhi << 2); - imm = SignExtend(imm, 2 + 19, 64); - return imm; -} -static inline uint32_t encode_immhi_immlo_offset(uint32_t instr, int64_t offset) { - struct { - uint32_t Rd : 5; // Destination register - uint32_t immhi : 19; // 19-bit upper immediate - uint32_t dummy_0 : 5; // Must be 10000 == 0x10 - uint32_t immlo : 2; // 2-bit lower immediate - uint32_t op : 1; // 0 = ADR, 1 = ADRP - } instr_decode; - - *(uint32_t *)&instr_decode = instr; - instr_decode.immlo = bits(offset, 0, 2); - instr_decode.immhi = bits(offset, 2, 2 + 19); - - return *(uint32_t *)&instr_decode; -} - -static inline int64_t decode_immhi_immlo_zero12_offset(uint32_t instr) { - int64_t imm = decode_immhi_immlo_offset(instr); - imm = imm << 12; - return imm; -} -static inline uint32_t encode_immhi_immlo_zero12_offset(uint32_t instr, int64_t offset) { - offset = (offset >> 12); - return encode_immhi_immlo_offset(instr, offset); -} - -static inline int decode_rt(uint32_t instr) { - return bits(instr, 0, 4); -} - -static inline int decode_rd(uint32_t instr) { - return bits(instr, 0, 4); -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x64/InstructionRelocationX64.cc b/app/src/main/cpp/Dobby/source/InstructionRelocation/x64/InstructionRelocationX64.cc deleted file mode 100644 index eb052c9..0000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x64/InstructionRelocationX64.cc +++ /dev/null @@ -1,78 +0,0 @@ -#include "platform_macro.h" - -#if defined(TARGET_ARCH_X64) - -#include "dobby_internal.h" - -#include "InstructionRelocation/x64/InstructionRelocationX64.h" -#include "InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.h" - -#include "core/arch/x64/registers-x64.h" -#include "core/assembler/assembler-x64.h" -#include "core/codegen/codegen-x64.h" - -using namespace zz::x64; - -int GenRelocateCodeFixed(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch) { - TurboAssembler turbo_assembler_(0); - // Set fixed executable code chunk address - turbo_assembler_.SetRealizedAddress((void *)relocated->addr); -#define _ turbo_assembler_. -#define __ turbo_assembler_.GetCodeBuffer()-> - - auto curr_orig_ip = (addr64_t)origin->addr; - auto curr_relo_ip = (addr64_t)relocated->addr; - - uint8_t *buffer_cursor = (uint8_t *)buffer; - - int predefined_relocate_size = origin->size; - - while ((buffer_cursor < ((uint8_t *)buffer + predefined_relocate_size))) { - x86_insn_decode_t insn = {0}; - memset(&insn, 0, sizeof(insn)); - GenRelocateSingleX86Insn(curr_orig_ip, curr_relo_ip, buffer_cursor, turbo_assembler_.GetCodeBuffer(), insn, 64); - - // go next - curr_orig_ip += insn.length; - buffer_cursor += insn.length; - curr_relo_ip = (addr64_t)relocated->addr + turbo_assembler_.ip_offset(); - } - - // jmp to the origin rest instructions - if (branch) { - CodeGen codegen(&turbo_assembler_); - // TODO: 6 == jmp [RIP + disp32] instruction size - addr64_t stub_addr = curr_relo_ip + 6; - codegen.JmpNearIndirect(stub_addr); - turbo_assembler_.GetCodeBuffer()->Emit64(curr_orig_ip); - } - - // update origin - int new_origin_len = curr_orig_ip - (addr_t)origin->addr; - origin->reset(origin->addr, new_origin_len); - - int relo_len = turbo_assembler_.GetCodeBuffer()->GetBufferSize(); - if (relo_len > relocated->size) { - DLOG(0, "pre-alloc code chunk not enough"); - return RT_FAILED; - } - - // generate executable code - { - auto code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); - relocated->reset(code->addr, code->size); - delete code; - } - - return RT_SUCCESS; -} - -void GenRelocateCodeAndBranch(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated) { - GenRelocateCode(buffer, origin, relocated, true); -} - -void GenRelocateCode(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch) { - GenRelocateCodeX86Shared(buffer, origin, relocated, branch); -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x64/InstructionRelocationX64.h b/app/src/main/cpp/Dobby/source/InstructionRelocation/x64/InstructionRelocationX64.h deleted file mode 100644 index 04e6afa..0000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x64/InstructionRelocationX64.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "common_header.h" - -#include "core/arch/x64/constants-x64.h" - -#include "MemoryAllocator/AssemblyCodeBuilder.h" - -#include "InstructionRelocation/x86/InstructionRelocationX86Shared.h" diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86.cc b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86.cc deleted file mode 100644 index df1f62b..0000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86.cc +++ /dev/null @@ -1,79 +0,0 @@ -#include "platform_macro.h" - -#if defined(TARGET_ARCH_IA32) - -#include "dobby_internal.h" - -#include "InstructionRelocation/x86/InstructionRelocationX86.h" -#include "InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.h" - -#include "core/arch/x86/registers-x86.h" -#include "core/assembler/assembler-ia32.h" -#include "core/codegen/codegen-ia32.h" - -using namespace zz::x86; - -int GenRelocateCodeFixed(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch) { - TurboAssembler turbo_assembler_(0); - // Set fixed executable code chunk address - turbo_assembler_.SetRealizedAddress((void *)relocated->addr); -#define _ turbo_assembler_. -#define __ turbo_assembler_.GetCodeBuffer()-> - - auto curr_orig_ip = (addr32_t)origin->addr; - auto curr_relo_ip = (addr32_t)relocated->addr; - - uint8_t *buffer_cursor = (uint8_t *)buffer; - - x86_options_t conf = {0}; - conf.mode = 32; - - int predefined_relocate_size = origin->size; - - while ((buffer_cursor < ((uint8_t *)buffer + predefined_relocate_size))) { - x86_insn_decode_t insn = {0}; - memset(&insn, 0, sizeof(insn)); - GenRelocateSingleX86Insn(curr_orig_ip, curr_relo_ip, buffer_cursor, turbo_assembler_.GetCodeBuffer(), insn, 64); - - // go next - curr_orig_ip += insn.length; - buffer_cursor += insn.length; - curr_relo_ip = (addr32_t)relocated->addr + turbo_assembler_.ip_offset(); - } - - // jmp to the origin rest instructions - if (branch) { - CodeGen codegen(&turbo_assembler_); - addr32_t stub_addr = curr_relo_ip + 6; - codegen.JmpNear(curr_orig_ip); - } - - // update origin - int new_origin_len = curr_orig_ip - (addr_t)origin->addr; - origin->reset(origin->addr, new_origin_len); - - int relo_len = turbo_assembler_.GetCodeBuffer()->GetBufferSize(); - if (relo_len > relocated->size) { - DLOG(0, "pre-alloc code chunk not enough"); - return RT_FAILED; - } - - // generate executable code - { - auto code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); - relocated->reset(code->addr, code->size); - delete code; - } - - return RT_SUCCESS; -} - -void GenRelocateCodeAndBranch(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated) { - GenRelocateCode(buffer, origin, relocated, true); -} - -void GenRelocateCode(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch) { - GenRelocateCodeX86Shared(buffer, origin, relocated, branch); -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86.h b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86.h deleted file mode 100644 index df04f0d..0000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "common_header.h" - -#include "core/arch/x86/constants-x86.h" - -#include "MemoryAllocator/AssemblyCodeBuilder.h" - -#include "InstructionRelocation/x86/InstructionRelocationX86Shared.h" diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86Shared.cc b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86Shared.cc deleted file mode 100644 index 8b573fd..0000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86Shared.cc +++ /dev/null @@ -1,196 +0,0 @@ -#include "platform_macro.h" - -#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) - -#include "dobby_internal.h" - -#include "InstructionRelocation/x86/InstructionRelocationX86.h" -#include "InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.h" -#include "MemoryAllocator/NearMemoryAllocator.h" - -using namespace zz::x86; - -// x64 jmp absolute address -void codegen_x64_jmp_absolute_addr(CodeBufferBase *buffer, addr_t target) { - // jmp *(rip) - buffer->Emit8(0xFF); - buffer->Emit8(0x25); // ModR/M: 00 100 101 - buffer->Emit32(0x00); - // .long target - buffer->Emit64(target); -} - -int GenRelocateSingleX86Insn(addr_t curr_orig_ip, addr_t curr_relo_ip, uint8_t *buffer_cursor, - CodeBufferBase *code_buffer, x86_insn_decode_t &insn, int8_t mode) { -#define __ code_buffer-> - - int relocated_insn_len = -1; - - x86_options_t conf = {0}; - conf.mode = mode; - - // decode x86 insn - x86_insn_decode(&insn, (uint8_t *)buffer_cursor, &conf); - - // x86 ip register == next instruction - curr_orig_ip = curr_orig_ip + insn.length; - - int last_relo_offset = code_buffer->GetBufferSize(); - if (insn.primary_opcode >= 0x70 && insn.primary_opcode <= 0x7F) { // jc rel8 - DLOG(0, "[x86 relo] %p: jc rel8", buffer_cursor); - - int8_t offset = insn.immediate; - - uint8_t opcode = 0x80 | (insn.primary_opcode & 0x0f); - -#if defined(TARGET_ARCH_IA32) - curr_relo_ip = curr_relo_ip + 6; - int32_t new_offset = (int32_t)(curr_orig_ip + offset - curr_relo_ip); - - __ Emit8(0x0F); - __ Emit8(opcode); - __ Emit32(new_offset); -#else - curr_relo_ip = curr_relo_ip + 2 + 2 + 6 + 8; - uint64_t orig_insn_ref_addr = curr_orig_ip + offset; - - // jcc - __ Emit8(opcode); - __ Emit8(2); - - // jmp - __ Emit8(0xEB); - __ Emit8(6 + 8); - - // jmp abs addr - codegen_x64_jmp_absolute_addr(code_buffer, orig_insn_ref_addr); -#endif - - } else if (mode == 64 && (insn.flags & X86_INSN_DECODE_FLAG_IP_RELATIVE) && - (insn.operands[1].mem.base == RIP)) { // RIP - DLOG(0, "[x86 relo] %p: rip", buffer_cursor); - - curr_relo_ip = curr_relo_ip + 6 + 8; - - addr_t rip_insn_seq_addr = 0; - { - int32_t orig_disp = insn.operands[1].mem.disp; - addr_t orig_rip_ref_addr = curr_orig_ip + orig_disp; - - uint32_t jmp_near_range = (uint32_t)2 * 1024 * 1024 * 1024; - auto rip_insn_seq = (addr_t)NearMemoryAllocator::SharedAllocator()->allocateNearExecMemory( - insn.length + 6 + 8, orig_rip_ref_addr, jmp_near_range); - - rip_insn_seq_addr = rip_insn_seq; - - auto rip_insn_seq_buffer = CodeBufferBase(); -#define ___ rip_insn_seq_buffer. - - auto rip_insn_req_ip = rip_insn_seq; - rip_insn_req_ip = rip_insn_req_ip + insn.length; // next insn addr - int32_t new_disp = (int32_t)(orig_rip_ref_addr - rip_insn_req_ip); - - // keep orig insn opcode - ___ EmitBuffer(buffer_cursor, insn.displacement_offset); - ___ Emit32(new_disp); - // keep orig insn immediate - if (insn.immediate_offset) { - ___ EmitBuffer((buffer_cursor + insn.immediate_offset), insn.length - insn.immediate_offset); - } - - // jmp *(rip) => back to relo process - codegen_x64_jmp_absolute_addr(&rip_insn_seq_buffer, curr_relo_ip); - - DobbyCodePatch((void *)rip_insn_seq, rip_insn_seq_buffer.GetBuffer(), rip_insn_seq_buffer.GetBufferSize()); - } - - // jmp *(rip) => jmp to [rip insn seq] - __ Emit8(0xFF); - __ Emit8(0x25); // ModR/M: 00 100 101 - __ Emit32(0); - __ Emit64(rip_insn_seq_addr); - } else if (insn.primary_opcode == 0xEB) { // jmp rel8 - DLOG(0, "[x86 relo] %p: jmp rel8", buffer_cursor); - - int8_t offset = insn.immediate; - -#if defined(TARGET_ARCH_IA32) - curr_relo_ip = curr_relo_ip + 5; - int32_t new_offset = (int32_t)(curr_orig_ip + offset - curr_relo_ip); - - __ Emit8(0xE9); - __ Emit32(new_offset); -#else - curr_relo_ip = curr_relo_ip + 6 + 8; - uint64_t orig_insn_ref_addr = curr_orig_ip + offset; - - // jmp *(rip) - codegen_x64_jmp_absolute_addr(code_buffer, orig_insn_ref_addr); -#endif - } else if (insn.primary_opcode == 0xE8 || insn.primary_opcode == 0xE9) { // call or jmp rel32 - DLOG(0, "[x86 relo] %p:jmp or call rel32", buffer_cursor); - - int32_t offset = insn.immediate; - - assert(insn.immediate_offset == 1); - -#if defined(TARGET_ARCH_IA32) - curr_relo_ip = curr_relo_ip + 5; - int32_t new_offset = (int32_t)(curr_orig_ip + offset - curr_relo_ip); - - __ EmitBuffer(buffer_cursor, insn.immediate_offset); - __ Emit32(new_offset); -#else - curr_relo_ip = curr_relo_ip + 6 + 8; - uint64_t orig_insn_ref_addr = curr_orig_ip + offset; - - // jmp *(rip) - __ Emit8(0xFF); - if (insn.primary_opcode == 0xE8) - __ Emit8(0x15); // ModR/M: 00 010 101 - else - __ Emit8(0x25); // ModR/M: 00 100 101 - __ Emit32(0); - __ Emit64(orig_insn_ref_addr); -#endif - } else if (insn.primary_opcode >= 0xE0 && insn.primary_opcode <= 0xE2) { // LOOPNZ/LOOPZ/LOOP/JECXZ - // LOOP/LOOPcc - UNIMPLEMENTED(); - } else if (insn.primary_opcode == 0xE3) { - // JCXZ JCEXZ JCRXZ - UNIMPLEMENTED(); - } else { - __ EmitBuffer(buffer_cursor, insn.length); - } - - // insn -> relocated insn - { - int relo_offset = code_buffer->GetBufferSize(); - int relo_len = relo_offset - last_relo_offset; - DLOG(0, "insn -> relocated insn: %d -> %d", insn.length, relo_len); - } - return relocated_insn_len; -} - -void GenRelocateCodeX86Shared(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch) { - int expected_relocated_mem_size = 32; -x86_try_again: - if (!relocated->addr) { - auto relocated_mem = MemoryAllocator::SharedAllocator()->allocateExecMemory(expected_relocated_mem_size); - if (relocated_mem == nullptr) { - return; - } - relocated->reset((addr_t)relocated_mem, expected_relocated_mem_size); - } - - int ret = GenRelocateCodeFixed(buffer, origin, relocated, branch); - if (ret != RT_SUCCESS) { - const int step_size = 16; - expected_relocated_mem_size += step_size; - relocated->reset(0, 0); - - goto x86_try_again; - } -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86Shared.h b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86Shared.h deleted file mode 100644 index b4bb8f5..0000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86Shared.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "common_header.h" - -#include "MemoryAllocator/AssemblyCodeBuilder.h" - -#include "x86_insn_decode/x86_insn_decode.h" - -int GenRelocateCodeFixed(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch); - -void GenRelocateCodeX86Shared(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch); - -int GenRelocateSingleX86Insn(addr_t curr_orig_ip, addr_t curr_relo_ip, uint8_t *buffer_cursor, - CodeBufferBase *code_buffer, x86_insn_decode_t &insn, int8_t mode); \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/Ia32Disassembler.cc b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/Ia32Disassembler.cc deleted file mode 100644 index e9774d1..0000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/Ia32Disassembler.cc +++ /dev/null @@ -1,388 +0,0 @@ -#include -#include - -#include "logging/logging.h" - -enum SegmentPrefix { - kCs = 0x2e, - kSs = 0x36, - kDs = 0x3e, - kEs = 0x26, - kFs = 0x64, - kGs = 0x65, -}; - -bool supports_rex_ = false; - -void DecodeInstruction(uint8_t *instr) { - bool have_prefixes = true; - uint8_t prefix[4] = {0, 0, 0, 0}; - - // decode legacy prefix - do { - switch (*instr) { - // Group 1 - lock and repeat prefixes: - case 0xF0: - case 0xF2: - case 0xF3: - prefix[0] = *instr; - break; - // Group 2 - segment override prefixes: - case kCs: - case kSs: - case kDs: - case kEs: - case kFs: - case kGs: - prefix[1] = *instr; - break; - // Group 3 - operand size override: - case 0x66: - prefix[2] = *instr; - break; - // Group 4 - address size override: - case 0x67: - prefix[3] = *instr; - break; - default: - have_prefixes = false; - break; - } - if (have_prefixes) { - instr++; - } - } while (have_prefixes); - - // x64 rex - uint8_t rex = (supports_rex_ && (*instr >= 0x40) && (*instr <= 0x4F)) ? *instr : 0; - if (rex != 0) { - instr++; - } - - bool has_modrm = false; - bool reg_is_opcode = false; - - size_t immediate_bytes = 0; - -#define OpEn_MR \ - do { \ - has_modrm = true; \ - } while (0); \ - break; - -#define OpEn_RM \ - do { \ - has_modrm = true; \ - } while (0); \ - break; - -#define OpEn_I(immediate_size) \ - do { \ - immediate_bytes = immediate_size; \ - } while (0); \ - break; - -#define OpEn_RMI(immediate_size) \ - do { \ - immediate_bytes = immediate_size; \ - } while (0); \ - break; - -#define OpEn_O \ - do { \ - reg_is_opcode = true; \ - } while (0); \ - break; - -#define OpEn_D \ - do { \ - reg_is_opcode = true; \ - } while (0); \ - break; - -#define OpEn_ZO \ - do { \ - reg_is_opcode = true; \ - } while (0); \ - break; - -#define Op_Prefix \ - do { \ - reg_is_opcode = true; \ - } while (0); \ - break; - -#define UnImplOpcode \ - do { \ - DLOG(0, "opcode unreachable"); \ - } while (0); \ - break; - - typedef enum { - MR, - } OpEnTy; - - // decode opcode - switch (*instr) { - case 0x00: - OpEn_MR; - case 0x01: - OpEn_MR; - case 0x02: - OpEn_RM; - case 0x03: - OpEn_RM; - case 0x04: - OpEn_I(8); - case 0x05: - OpEn_I(16 | 32); - - case 0x06: - case 0x07: - UnImplOpcode; - - case 0x08: - OpEn_MR; - case 0x09: - OpEn_MR; - case 0x0a: - OpEn_RM; - case 0x0b: - OpEn_RM; - case 0x0c: - OpEn_I(8); - case 0x0d: - OpEn_I(16 | 32); - - case 0x0e: - case 0x0f: - UnImplOpcode; - - case 0x10: - OpEn_MR; - case 0x11: - OpEn_MR; - case 0x12: - OpEn_RM; - case 0x13: - OpEn_RM; - case 0x14: - OpEn_I(8); - case 0x15: - OpEn_I(16 | 32); - - case 0x16: - case 0x17: - UnImplOpcode; - - case 0x18: - OpEn_MR; - case 0x19: - OpEn_MR; - case 0x1a: - OpEn_RM; - case 0x1b: - OpEn_RM; - case 0x1c: - OpEn_I(8); - case 0x1d: - OpEn_I(16 | 32); - - case 0x1e: - case 0x1f: - UnImplOpcode; - - case 0x20: - OpEn_MR; - case 0x21: - OpEn_MR; - case 0x22: - OpEn_RM; - case 0x23: - OpEn_RM; - case 0x24: - OpEn_I(8); - case 0x25: - OpEn_I(16 | 32); - - case 0x26: - case 0x27: - UnImplOpcode; - - case 0x28: - OpEn_MR; - case 0x29: - OpEn_MR; - case 0x2a: - OpEn_RM; - case 0x2b: - OpEn_RM; - case 0x2c: - OpEn_I(8); - case 0x2d: - OpEn_I(16 | 32); - - case 0x2e: - case 0x2f: - UnImplOpcode; - - case 0x30: - OpEn_MR; - case 0x31: - OpEn_MR; - case 0x32: - OpEn_RM; - case 0x33: - OpEn_RM; - case 0x34: - OpEn_I(8); - case 0x35: - OpEn_I(16 | 32); - - case 0x36: - case 0x37: - UnImplOpcode; - - case 0x38: - OpEn_MR; - case 0x39: - OpEn_MR; - case 0x3a: - OpEn_RM; - case 0x3b: - OpEn_RM; - case 0x3c: - OpEn_I(8); - case 0x3d: - OpEn_I(16 | 32); - - case 0x40: - case 0x41: - case 0x42: - case 0x43: - case 0x44: - case 0x45: - case 0x46: - case 0x47: - case 0x48: - case 0x49: - case 0x4a: - case 0x4b: - case 0x4c: - case 0x4d: - case 0x4e: - case 0x4f: - UnImplOpcode; - - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - case 0x58: - case 0x59: - case 0x5A: - case 0x5B: - case 0x5C: - case 0x5D: - case 0x5E: - case 0x5F: - OpEn_O; - - case 0x60: - case 0x61: - case 0x62: - UnImplOpcode; - - case 0x63: - if ((rex & REX_W) != 0) { - OpEn_RM; - }; - break; - - case 0x64: - case 0x65: - case 0x66: - case 0x67: - Op_Prefix; - - case 0x68: - OpEn_I(16 | 32); - - case 0x69: - OpEn_RMI(16 | 32); - - case 0x6a: - OpEn_I(8); - - case 0x6b: - OpEn_RMI(8); - - case 0x70: - case 0x71: - case 0x72: - case 0x73: - case 0x74: - case 0x75: - case 0x76: - case 0x77: - case 0x78: - case 0x79: - case 0x7A: - case 0x7B: - case 0x7C: - case 0x7D: - case 0x7E: - case 0x7F: - OpEn_D; - - case 0x80: - case 0x81: - case 0x82: - case 0x83: - case 0x84: - case 0x85: - UnImplOpcode; - - case 0x86: - case 0x87: - OpEn_RM; - - case 0x88: - case 0x89: - case 0x8a: - case 0x8b: - OpEn_RM; - - case 0x8c: - case 0x8d: - case 0x8e: - case 0x8f: - case 0x90: - case 0x91: - case 0x92: - case 0x93: - case 0x94: - case 0x95: - case 0x96: - case 0x97: - case 0x98: - case 0x99: - case 0x9a: - case 0x9b: - case 0x9c: - UnImplOpcode; - - case 0x9d: - OpEn_ZO; - - case 0x0f: - DecodeExtendedOpcode - } -} - -void DecodeExtendedOpcode(uint8_t *instr) { -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/X86OpcodoDecodeTable.cc b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/X86OpcodoDecodeTable.cc deleted file mode 100644 index 84bfad7..0000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/X86OpcodoDecodeTable.cc +++ /dev/null @@ -1,604 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) - -#include "./X86OpcodoDecodeTable.h" - -// clang-format on - -#define _xUnknownOpHanlder -1, -1, OpSz_0, ImmSz_0, _UnknownOpHanlder -void _UnknownOpHanlder(InstrMnemonic *instr, addr_t p) { - // printf("Unknown Operand\n"); - return; -} - -#define _xInvalidOpHanlder -1, -1, OpSz_0, ImmSz_0, _InValidOpHanlder -void _InValidOpHanlder(InstrMnemonic *instr, addr_t p) { - // printf("Invalid Operand\n"); - return; -} - -inline void _ContinueDispatch(InstrMnemonic *instr, addr_t p) { - OpcodeDecodeItem *item = &OpcodeDecodeTable[*(unsigned char *)p]; - item->DecodeHandler(instr, p); -} - -// ===== Decode LegacyPrefix and REXPrefix ===== - -// clang-format off -#define _xDecodePrefix_0F 1, OpEn_NONE, OpSz_0, ImmSz_0, _DecodeLegacyPrefix -#define _xDecodePrefix_66 1, OpEn_NONE, OpSz_0, ImmSz_0, _DecodePrefix_66 -#define _xDecodePrefix_67 1, OpEn_NONE, OpSz_0, ImmSz_0, _DecodeLegacyPrefix -#define _xDecodeREXPrefix 1, OpEn_NONE, OpSz_0, ImmSz_0, _DecodeREXPrefix -#define _xDecodePrefix 1, OpEn_NONE, OpSz_0, ImmSz_0, _DecodeLegacyPrefix -#define _xDecodeSegPrefix 1, OpEn_NONE, OpSz_0, ImmSz_0, _DecodeLegacyPrefix -// clang-format on - -void _DecodeREXPrefix(InstrMnemonic *instr, addr_t p) { - instr->instr.REX = *(byte_t *)p; - instr->len++; - instr->OperandSz = OpSz_64; - - _ContinueDispatch(instr, p + 1); // continue decode -} - -void _DecodeLegacyPrefix(InstrMnemonic *instr, addr_t p) { - instr->instr.prefix = *(byte_t *)p; - instr->len++; - - _ContinueDispatch(instr, p + 1); // continue decode -} - -void _DecodePrefix_66(InstrMnemonic *instr, addr_t p) { - instr->OperandSz = OpSz_16; - _DecodeLegacyPrefix(instr, p); -} - -// ===== Decode Opcode ===== - -static void _DecodeOp(InstrMnemonic *instr, addr_t p) { - instr->instr.opcode1 = *(byte_t *)p; - instr->len++; -} - -static void _DecodeOpExtraOp(InstrMnemonic *instr, addr_t p) { - _DecodeOp(instr, p); -} - -static void _DecodeOpWithReg(InstrMnemonic *instr, addr_t p) { - _DecodeOp(instr, p); -} - -#define _xDecodeOpEn_ZO 1, OpEn_ZO, OpSz_0, ImmSz_0, _DecodeOpEn_ZO -void _DecodeOpEn_ZO(InstrMnemonic *instr, addr_t p) { - _DecodeOp(instr, p); -} - -#define _xDecodeOpEn_O 1, OpEn_O, OpSz_0, ImmSz_0, _DecodeOpEn_O -void _DecodeOpEn_O(InstrMnemonic *instr, addr_t p) { - _DecodeOpWithReg(instr, p); -} - -// ===== Decode Operand ===== - -// ===== Decode ModRM Operand ===== - -#define REX_W(byte) ((byte & 0b00001000) >> 3) -#define REX_R(byte) ((byte & 0b00000100) >> 2) -#define REX_X(byte) ((byte & 0b00000010) >> 1) -#define REX_B(byte) ((byte & 0b00000001) >> 0) - -#define ModRM_Mod(byte) ((byte & 0b11000000) >> 6) -#define ModRM_RegOpcode(byte) ((byte & 0b00111000) >> 3) -#define ModRM_RM(byte) (byte & 0b00000111) - -#define SIB_Scale(sib) ((sib & 0b11000000) >> 6) -#define SIB_Index(sib) ((sib & 0b00111000) >> 3) -#define SIB_Base(sib) ((sib & 0b00000111) >> 0) - -#define REX_SIB_Base(rex, sib) ((REX_B(rex) << 3) | SIB_Base(sib)) - -void _DecodeDisplacement8(InstrMnemonic *instr, addr_t p) { - *(byte_t *)&instr->instr.Displacement = *(byte_t *)p; - instr->len += 1; -} - -void _DecodeDisplacement32(InstrMnemonic *instr, addr_t p) { - instr->instr.DisplacementOffset = instr->len; - *(dword *)&instr->instr.Displacement = *(byte_t *)p; - instr->len += 4; -} - -void _DecodeSIB(InstrMnemonic *instr, addr_t p) { - instr->instr.SIB = *(byte_t *)p; - instr->len++; -} - -void _DecodeModRM(InstrMnemonic *instr, addr_t p) { - int init_len = instr->len; - - instr->instr.ModRM = *(byte_t *)p; - instr->len++; - -#if defined(_M_X64) || defined(__x86_64__) - if (ModRM_Mod(instr->instr.ModRM) == 0b00 && ModRM_RM(instr->instr.ModRM) == 0b101) { - // RIP-Relative Addressing - instr->flag = instr->flag | kIPRelativeAddress; - _DecodeDisplacement32(instr, p + (instr->len - init_len)); - return; - } -#endif - - // Addressing Forms with the SIB Byte - if (ModRM_Mod(instr->instr.ModRM) != 0b11 && ModRM_RM(instr->instr.ModRM) == 0b100) { - _DecodeSIB(instr, p + (instr->len - init_len)); - } - - // [REG] - if (ModRM_Mod(instr->instr.ModRM) == 0b00) { - if (ModRM_RM(instr->instr.ModRM) == 0b101) { - _DecodeDisplacement32(instr, p + (instr->len - init_len)); - return; - } - } - - // [REG+disp8} - if (ModRM_Mod(instr->instr.ModRM) == 0b01) { - _DecodeDisplacement8(instr, p + (instr->len - init_len)); - return; - } - - // [REG+disp32} - if (ModRM_Mod(instr->instr.ModRM) == 0b10) { - _DecodeDisplacement32(instr, p + (instr->len - init_len)); - return; - } - - // REG - if (ModRM_Mod(instr->instr.ModRM) == 0b11) { - } -} - -void _DecodeOpEn_M(InstrMnemonic *instr, addr_t p) { - _DecodeOp(instr, p); - _DecodeModRM(instr, p + 1); -} - -void _DecodeOpEn_RM(InstrMnemonic *instr, addr_t p) { - _DecodeOp(instr, p); - _DecodeModRM(instr, p + 1); -} - -void _DecodeOpEn_MR(InstrMnemonic *instr, addr_t p) { - _DecodeOp(instr, p); - _DecodeModRM(instr, p + 1); -} - -void _DecodeOpEn_M1(InstrMnemonic *instr, addr_t p) { - _DecodeOp(instr, p); - _DecodeModRM(instr, p + 1); -} - -void _DecodeOpEn_MC(InstrMnemonic *instr, addr_t p) { - _DecodeOp(instr, p); - _DecodeModRM(instr, p + 1); -} - -// ===== Decode Immediate Operand ===== - -void _DecodeImmedite(InstrMnemonic *instr, addr_t p, int sz) { - - instr->instr.ImmediateOffset = instr->len; - - OpcodeDecodeItem *item = &OpcodeDecodeTable[instr->instr.opcode1]; - if (sz == ImmSz_0) { - sz = item->ImmediteSz; - if (sz == (ImmSz_16 | ImmSz_32)) { - if (instr->instr.prefix == 0x66) { - sz = ImmSz_16; - } else { - sz = ImmSz_32; // Default Immedite Size - } - } - } - - if (sz == ImmSz_8) { - *(byte_t *)&instr->instr.Immediate = *(byte_t *)p; - instr->len += 1; - } else if (sz == ImmSz_16) { - *(word *)&instr->instr.Immediate = *(dword *)p; - instr->len += 2; - } else if (sz == ImmSz_32) { - *(dword *)&instr->instr.Immediate = *(dword *)p; - instr->len += 4; - } -} - -void _DecodeOpEn_I(InstrMnemonic *instr, addr_t p) { - _DecodeOp(instr, p); - _DecodeImmedite(instr, p + 1, instr->ImmediteSz); -} - -void _DecodeOpEn_OI(InstrMnemonic *instr, addr_t p) { - _DecodeOpWithReg(instr, p); - _DecodeImmedite(instr, p + 1, instr->ImmediteSz); -} - -void _DecodeOpEn_D(InstrMnemonic *instr, addr_t p) { - _DecodeOp(instr, p); - _DecodeImmedite(instr, p + 1, instr->ImmediteSz); -} - -// ===== Decode ModRM Immediate Operand ===== - -void _DecodeOpEn_RMI(InstrMnemonic *instr, addr_t p) { - _DecodeOp(instr, p); - _DecodeModRM(instr, p + 1); - _DecodeImmedite(instr, p + 2, instr->ImmediteSz); -} - -void _DecodeOpEn_MI(InstrMnemonic *instr, addr_t p) { - _DecodeOpExtraOp(instr, p); - _DecodeModRM(instr, p + 1); - _DecodeImmedite(instr, p + 2, instr->ImmediteSz); -} - -// ===== Decode Specific Opcode ===== - -#define _xDecodeOpC8 1, 0, OpSz_0, ImmSz_0, _DecodeOpC8 -void _DecodeOpC8(InstrMnemonic *instr, addr_t p) { - _DecodeOp(instr, p); - - instr->len = instr->len + 2 + 1; -} - -// http://ref.x86asm.net/coder.html#x04 -OpcodeDecodeItem OpcodeDecodeTable[257] = { - - {0x00, 2, OpEn_MR, OpSz_8, ImmSz_0, _DecodeOpEn_MR}, - {0x01, 2, OpEn_MR, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_MR}, - {0x02, 2, OpEn_RM, OpSz_8, ImmSz_0, _DecodeOpEn_RM}, - {0x03, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x04, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0x05, 1, OpEn_I, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_I}, -#if defined(_M_X64) || defined(__x86_64__) - {0x06, _xInvalidOpHanlder}, - {0x07, _xInvalidOpHanlder}, -#else - {0x06, _xDecodeOpEn_ZO}, - {0x07, _xDecodeOpEn_ZO}, -#endif - {0x08, 2, OpEn_MR, OpSz_8, ImmSz_0, _DecodeOpEn_MR}, - {0x09, 2, OpEn_MR, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_MR}, - {0x0A, 2, OpEn_RM, OpSz_8, ImmSz_0, _DecodeOpEn_RM}, - {0x0B, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x0C, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0x0D, 1, OpEn_I, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_I}, -#if defined(_M_X64) || defined(__x86_64__) - {0x0E, _xInvalidOpHanlder}, -#else - {0x0E, _xDecodeOpEn_ZO}, -#endif - {0x0F, _xDecodePrefix_0F}, - {0x10, 2, OpEn_MR, OpSz_8, ImmSz_0, _DecodeOpEn_MR}, - {0x11, 2, OpEn_MR, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_MR}, - {0x12, 2, OpEn_RM, OpSz_8, ImmSz_0, _DecodeOpEn_RM}, - {0x13, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x14, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0x15, 1, OpEn_I, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_I}, -#if defined(_M_X64) || defined(__x86_64__) - {0x16, _xInvalidOpHanlder}, - {0x17, _xInvalidOpHanlder}, -#else - {0x16, _xDecodeOpEn_ZO}, - {0x17, _xDecodeOpEn_ZO}, -#endif - {0x18, 2, OpEn_MR, OpSz_8, ImmSz_0, _DecodeOpEn_MR}, - {0x19, 2, OpEn_MR, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_MR}, - {0x1A, 2, OpEn_RM, OpSz_8, ImmSz_0, _DecodeOpEn_RM}, - {0x1B, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x1C, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0x1D, 1, OpEn_I, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_I}, -#if defined(_M_X64) || defined(__x86_64__) - {0x1E, _xInvalidOpHanlder}, - {0x1F, _xInvalidOpHanlder}, -#else - {0x1E, _xDecodeOpEn_ZO}, - {0x1F, _xDecodeOpEn_ZO}, -#endif - {0x20, 2, OpEn_MR, OpSz_8, ImmSz_0, _DecodeOpEn_MR}, - {0x21, 2, OpEn_MR, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_MR}, - {0x22, 2, OpEn_RM, OpSz_8, ImmSz_0, _DecodeOpEn_RM}, - {0x23, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x24, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0x25, 1, OpEn_I, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_I}, - {0x26, _xDecodeSegPrefix}, -#if defined(_M_X64) || defined(__x86_64__) - {0x27, _xInvalidOpHanlder}, -#else - {0x27, _xDecodeOpEn_ZO}, -#endif - {0x28, 2, OpEn_MR, OpSz_8, ImmSz_0, _DecodeOpEn_MR}, - {0x29, 2, OpEn_MR, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_MR}, - {0x2A, 2, OpEn_RM, OpSz_8, ImmSz_0, _DecodeOpEn_RM}, - {0x2B, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x2C, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0x2D, 1, OpEn_I, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_I}, - {0x2E, _xDecodeSegPrefix}, -#if defined(_M_X64) || defined(__x86_64__) - {0x2F, _xInvalidOpHanlder}, -#else - {0x2F, _xDecodeOpEn_ZO}, -#endif - {0x30, 2, OpEn_MR, OpSz_8, ImmSz_0, _DecodeOpEn_MR}, - {0x31, 2, OpEn_MR, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_MR}, - {0x32, 2, OpEn_RM, OpSz_8, ImmSz_0, _DecodeOpEn_RM}, - {0x33, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x34, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0x35, 1, OpEn_I, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_I}, - {0x36, _xDecodeSegPrefix}, -#if defined(_M_X64) || defined(__x86_64__) - {0x37, _xInvalidOpHanlder}, -#else - {0x37, _xDecodeOpEn_ZO}, -#endif - {0x38, 2, OpEn_MR, OpSz_8, ImmSz_0, _DecodeOpEn_MR}, - {0x39, 2, OpEn_MR, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_MR}, - {0x3A, 2, OpEn_RM, OpSz_8, ImmSz_0, _DecodeOpEn_RM}, - {0x3B, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x3C, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0x3D, 1, OpEn_I, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_I}, - {0x3E, _xDecodeSegPrefix}, -#if defined(_M_X64) || defined(__x86_64__) - {0x3F, _xInvalidOpHanlder}, -#else - {0x3F, _xDecodeOpEn_ZO}, -#endif -#if defined(_M_X64) || defined(__x86_64__) // For REX Prefix - {0x40, _xDecodeREXPrefix}, - {0x41, _xDecodeREXPrefix}, - {0x42, _xDecodeREXPrefix}, - {0x43, _xDecodeREXPrefix}, - {0x44, _xDecodeREXPrefix}, - {0x45, _xDecodeREXPrefix}, - {0x46, _xDecodeREXPrefix}, - {0x47, _xDecodeREXPrefix}, - {0x48, _xDecodeREXPrefix}, - {0x49, _xDecodeREXPrefix}, - {0x4A, _xDecodeREXPrefix}, - {0x4B, _xDecodeREXPrefix}, - {0x4C, _xDecodeREXPrefix}, - {0x4D, _xDecodeREXPrefix}, - {0x4E, _xDecodeREXPrefix}, - {0x4F, _xDecodeREXPrefix}, -#else - {0x40, _xDecodeOpEn_O}, - {0x41, _xDecodeOpEn_O}, - {0x42, _xDecodeOpEn_O}, - {0x43, _xDecodeOpEn_O}, - {0x44, _xDecodeOpEn_O}, - {0x45, _xDecodeOpEn_O}, - {0x46, _xDecodeOpEn_O}, - {0x47, _xDecodeOpEn_O}, - {0x48, _xDecodeOpEn_O}, - {0x49, _xDecodeOpEn_O}, - {0x4A, _xDecodeOpEn_O}, - {0x4B, _xDecodeOpEn_O}, - {0x4C, _xDecodeOpEn_O}, - {0x4D, _xDecodeOpEn_O}, - {0x4E, _xDecodeOpEn_O}, - {0x4F, _xDecodeOpEn_O}, -#endif - {0x50, _xDecodeOpEn_O}, - {0x51, _xDecodeOpEn_O}, - {0x52, _xDecodeOpEn_O}, - {0x53, _xDecodeOpEn_O}, - {0x54, _xDecodeOpEn_O}, - {0x55, _xDecodeOpEn_O}, - {0x56, _xDecodeOpEn_O}, - {0x57, _xDecodeOpEn_O}, - {0x58, _xDecodeOpEn_O}, - {0x59, _xDecodeOpEn_O}, - {0x5A, _xDecodeOpEn_O}, - {0x5B, _xDecodeOpEn_O}, - {0x5C, _xDecodeOpEn_O}, - {0x5D, _xDecodeOpEn_O}, - {0x5E, _xDecodeOpEn_O}, - {0x5F, _xDecodeOpEn_O}, -#if defined(_M_X64) || defined(__x86_64__) - {0x60, _xInvalidOpHanlder}, - {0x61, _xInvalidOpHanlder}, - {0x62, _xInvalidOpHanlder}, -#else - {0x60, _xDecodeOpEn_ZO}, - {0x61, _xDecodeOpEn_ZO}, - {0x62, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, -#endif - {0x63, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x64, _xDecodeSegPrefix}, - {0x65, _xDecodeSegPrefix}, - {0x66, _xDecodePrefix_66}, - {0x67, _xDecodePrefix_67}, - {0x68, 1, OpEn_I, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_I}, - {0x69, 2, OpEn_RMI, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_RMI}, - {0x6A, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0x6B, 1, OpEn_RMI, OpSz_16 | OpSz_32, ImmSz_8, _DecodeOpEn_RMI}, - {0x6C, _xDecodeOpEn_ZO}, - {0x6D, _xDecodeOpEn_ZO}, - {0x6E, _xDecodeOpEn_ZO}, - {0x6F, _xDecodeOpEn_ZO}, - {0x70, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x71, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x72, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x73, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x74, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x75, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x76, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x77, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x78, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x79, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x7A, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x7B, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x7C, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x7D, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x7E, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x7F, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x80, 2, OpEn_MI, OpSz_8, ImmSz_8, _DecodeOpEn_MI}, - {0x81, 2, OpEn_MI, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_MI}, -#if defined(_M_X64) || defined(__x86_64__) - {0x82, _xInvalidOpHanlder}, -#else - {0x82, _xUnknownOpHanlder}, -#endif - {0x83, 2, OpEn_MI, OpSz_16 | OpSz_32, ImmSz_8, _DecodeOpEn_MI}, - {0x84, 2, OpEn_MR, OpSz_8, ImmSz_0, _DecodeOpEn_MR}, - {0x85, 2, OpEn_MR, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_MR}, - {0x86, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x87, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x88, 2, OpEn_MR, OpSz_8, ImmSz_0, _DecodeOpEn_MR}, - {0x89, 2, OpEn_MR, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_MR}, - {0x8A, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x8B, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x8C, 2, OpEn_MR, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_MR}, - {0x8D, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x8E, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x8F, 2, OpEn_M, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_M}, - {0x90, _xDecodeOpEn_ZO}, - {0x91, _xInvalidOpHanlder}, - {0x92, _xInvalidOpHanlder}, - {0x93, _xInvalidOpHanlder}, - {0x94, _xInvalidOpHanlder}, - {0x95, _xInvalidOpHanlder}, - {0x96, _xInvalidOpHanlder}, - {0x97, _xInvalidOpHanlder}, - {0x98, _xDecodeOpEn_ZO}, - {0x99, _xDecodeOpEn_ZO}, -#if defined(_M_X64) || defined(__x86_64__) - {0x9A, _xInvalidOpHanlder}, -#else - {0x9A, _xDecodeOpEn_ZO}, -#endif - {0x9B, _xDecodeOpEn_ZO}, - {0x9C, _xDecodeOpEn_ZO}, - {0x9D, _xDecodeOpEn_ZO}, - {0x9E, _xDecodeOpEn_ZO}, - {0x9F, _xDecodeOpEn_ZO}, - {0xA0, _xUnknownOpHanlder}, - {0xA1, _xUnknownOpHanlder}, - {0xA2, _xUnknownOpHanlder}, - {0xA3, _xUnknownOpHanlder}, - {0xA4, _xDecodeOpEn_ZO}, - {0xA5, _xDecodeOpEn_ZO}, - {0xA6, _xDecodeOpEn_ZO}, - {0xA7, _xDecodeOpEn_ZO}, - {0xA8, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0xA9, 1, OpEn_I, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_I}, - {0xAA, _xDecodeOpEn_ZO}, - {0xAB, _xDecodeOpEn_ZO}, - {0xAC, _xDecodeOpEn_ZO}, - {0xAD, _xDecodeOpEn_ZO}, - {0xAE, _xDecodeOpEn_ZO}, - {0xAF, _xDecodeOpEn_ZO}, -#undef SAME_ITEM_LAZY -#define SAME_ITEM_LAZY 1, OpEn_OI, OpSz_0, ImmSz_8, _DecodeOpEn_OI - {0xB0, SAME_ITEM_LAZY}, - {0xB1, SAME_ITEM_LAZY}, - {0xB2, SAME_ITEM_LAZY}, - {0xB3, SAME_ITEM_LAZY}, - {0xB4, SAME_ITEM_LAZY}, - {0xB5, SAME_ITEM_LAZY}, - {0xB6, SAME_ITEM_LAZY}, - {0xB7, SAME_ITEM_LAZY}, -#undef SAME_ITEM_LAZY -#define SAME_ITEM_LAZY 1, OpEn_OI, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_OI - {0xB8, SAME_ITEM_LAZY}, - {0xB9, SAME_ITEM_LAZY}, - {0xBA, SAME_ITEM_LAZY}, - {0xBB, SAME_ITEM_LAZY}, - {0xBC, SAME_ITEM_LAZY}, - {0xBD, SAME_ITEM_LAZY}, - {0xBE, SAME_ITEM_LAZY}, - {0xBF, SAME_ITEM_LAZY}, - {0xC0, 2, OpEn_MI, OpSz_8, ImmSz_8, _DecodeOpEn_MI}, - {0xC1, 2, OpEn_MI, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_MI}, - {0xC2, 1, OpEn_I, OpSz_0, ImmSz_16, _DecodeOpEn_I}, - {0xC3, _xDecodeOpEn_ZO}, - {0xC4, _xInvalidOpHanlder}, - {0xC5, _xInvalidOpHanlder}, - {0xC6, _xUnknownOpHanlder}, - {0xC7, 2, OpEn_MI, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_MI}, - {0xC8, _xDecodeOpC8}, - {0xC9, _xDecodeOpEn_ZO}, - {0xCA, 1, OpEn_I, OpSz_0, ImmSz_16, _DecodeOpEn_I}, - {0xCB, _xDecodeOpEn_ZO}, - {0xCC, _xDecodeOpEn_ZO}, - {0xCD, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, -#if defined(_M_X64) || defined(__x86_64__) - {0xCE, _xInvalidOpHanlder}, -#else - {0xCE, _xDecodeOpEn_ZO}, -#endif - {0xCF, _xDecodeOpEn_ZO}, - {0xD0, 1, OpEn_M1, OpSz_8, ImmSz_0, _DecodeOpEn_M1}, - {0xD1, 1, OpEn_M1, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_M1}, - {0xD2, 1, OpEn_MC, OpSz_8, ImmSz_0, _DecodeOpEn_MC}, - {0xD3, 1, OpEn_MC, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_MC}, -#if defined(_M_X64) || defined(__x86_64__) - {0xD4, _xInvalidOpHanlder}, - {0xD5, _xInvalidOpHanlder}, -#else - {0xD4, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0xD5, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, -#endif - {0xD6, _xInvalidOpHanlder}, - {0xD7, _xDecodeOpEn_ZO}, - {0xD8, _xUnknownOpHanlder}, - {0xD9, _xUnknownOpHanlder}, - {0xDA, _xUnknownOpHanlder}, - {0xDB, _xUnknownOpHanlder}, - {0xDC, _xUnknownOpHanlder}, - {0xDD, _xUnknownOpHanlder}, - {0xDE, _xUnknownOpHanlder}, - {0xDF, _xUnknownOpHanlder}, - {0xE0, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0xE1, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0xE2, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0xE3, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0xE4, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0xE5, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0xE6, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0xE7, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0xE8, 1, OpEn_I, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_I}, - {0xE9, 1, OpEn_I, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_I}, -#if defined(_M_X64) || defined(__x86_64__) - {0xEA, _xInvalidOpHanlder}, -#else - {0xEA, _xUnknownOpHanlder}, -#endif - {0xEB, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0xEC, _xDecodeOpEn_ZO}, - {0xED, _xDecodeOpEn_ZO}, - {0xEE, _xDecodeOpEn_ZO}, - {0xEF, _xDecodeOpEn_ZO}, - {0xF0, _xDecodePrefix}, - {0xF1, _xDecodeOpEn_ZO}, - {0xF2, _xDecodeOpEn_ZO}, -#ifdef DETOURS_X86 - {0xF3, _CopyF3}, -#else - {0xF3, _xDecodeOpEn_ZO}, -#endif - {0xF4, _xDecodeOpEn_ZO}, - {0xF5, _xDecodeOpEn_ZO}, - {0xF6, 2, OpEn_MI, OpSz_8, ImmSz_8, _DecodeOpEn_MI}, - {0xF7, 2, OpEn_MI, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_MI}, - {0xF8, _xDecodeOpEn_ZO}, - {0xF9, _xDecodeOpEn_ZO}, - {0xFA, _xDecodeOpEn_ZO}, - {0xFB, _xDecodeOpEn_ZO}, - {0xFC, _xDecodeOpEn_ZO}, - {0xFD, _xDecodeOpEn_ZO}, - {0xFE, 2, OpEn_M, OpSz_8, ImmSz_0, _DecodeOpEn_M}, - {0xFF, 2, OpEn_M, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_M}, - {0, 0, 0, 0, 0}}; - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/X86OpcodoDecodeTable.h b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/X86OpcodoDecodeTable.h deleted file mode 100644 index 778fdb3..0000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/X86OpcodoDecodeTable.h +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef X86_OPCODE_DECODE_TABLE_H -#define X86_OPCODE_DECODE_TABLE_H - -#ifndef __addr_t_defined -#define __addr_t_defined -typedef unsigned long long addr_t; -#endif - -#ifndef __byte_defined -#define __byte_defined -typedef unsigned char byte_t; -#endif - -#ifndef __uint_defined -#define __uint_defined -typedef unsigned int uint; -#endif - -#ifndef __word_defined -#define __word_defined -typedef short word; -#endif - -#ifndef __dword_defined -#define __dword_defined -typedef int dword; -#endif - -enum OpcodeType { OpTy_Op1, OpTy_RegInOp1, OpTy_Op1ExtraOp }; - -struct Instr { - byte_t prefix; - - byte_t REX; - - union { - byte_t opcode[3]; - struct { - byte_t opcode1; - byte_t opcode2; - byte_t opcode3; - }; - }; - - union { - byte_t ModRM; - struct { - byte_t Mod : 2; - byte_t RegOpcode : 3; - byte_t RM : 3; - }; - }; - - union { - byte_t SIB; - struct { - byte_t base : 2; - byte_t index : 3; - byte_t scale : 3; - }; - }; - - byte_t Displacement[4]; - int DisplacementOffset; - - byte_t Immediate[4]; - int ImmediateOffset; -}; - -// clang-format off -enum OperandSize { - OpSz_0 = 0, - OpSz_8=1, - OpSz_16=2, - OpSz_32=4, - OpSz_64=8 -}; - -enum ImmediteSize { - ImmSz_0 = 0, - ImmSz_8=1, - ImmSz_16=2, - ImmSz_32=4, - ImmSz_64=8 -}; - -enum InstrFlag { - kNoFlag = 0, - kIPRelativeAddress = 1 -}; -// clang-format on - -struct InstrMnemonic { - uint len; - - int flag; - - OperandSize OperandSz; - - ImmediteSize ImmediteSz; - - struct Instr instr; -}; - -struct OpcodeDecodeItem { - unsigned char opcode; - - int FixedSize; - - int OpEn; - - int OperandSz; - - int ImmediteSz; - - void (*DecodeHandler)(InstrMnemonic *, addr_t); -}; - -// clang-format off -enum OperandEncodingType { - OpEn_NONE =0, - OpEn_ZO, - OpEn_M, - OpEn_I, - OpEn_D, - OpEn_O, - OpEn_RM, - OpEn_MR, - OpEn_MI, - OpEn_OI, - OpEn_M1, - OpEn_MC, - OpEn_RMI -}; - -// clang-format on - -extern OpcodeDecodeItem OpcodeDecodeTable[257]; - -void _DecodePrefix(InstrMnemonic *instr, addr_t p); - -#endif diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/build_config.h b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/build_config.h deleted file mode 100644 index 7c558c2..0000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/build_config.h +++ /dev/null @@ -1,144 +0,0 @@ -#ifndef BUILD_CONFIG_H -#define BUILD_CONFIG_H - -#if defined(__APPLE__) -// only include TargetConditions after testing ANDROID as some android builds -// on mac don't have this header available and it's not needed unless the target -// is really mac/ios. -#include -#define OS_MACOSX 1 -#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE -#define OS_IOS 1 -#endif // defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE -#elif defined(__linux__) -#define OS_LINUX 1 -// include a system header to pull in features.h for glibc/uclibc macros. -#include -#if defined(__GLIBC__) && !defined(__UCLIBC__) -// we really are using glibc, not uClibc pretending to be glibc -#define LIBC_GLIBC 1 -#endif -#elif defined(_WIN32) -#define OS_WIN 1 -#elif defined(__Fuchsia__) -#define OS_FUCHSIA 1 -#elif defined(__FreeBSD__) -#define OS_FREEBSD 1 -#elif defined(__NetBSD__) -#define OS_NETBSD 1 -#elif defined(__OpenBSD__) -#define OS_OPENBSD 1 -#elif defined(__sun) -#define OS_SOLARIS 1 -#elif defined(__QNXNTO__) -#define OS_QNX 1 -#elif defined(_AIX) -#define OS_AIX 1 -#elif defined(__asmjs__) || defined(__wasm__) -#define OS_ASMJS -#else -#error Please add support for your platform in build/build_config.h -#endif -// NOTE: Adding a new port? Please follow -// https://chromium.googlesource.com/chromium/src/+/master/docs/new_port_policy.md - -// For access to standard BSD features, use OS_BSD instead of a -// more specific macro. -#if defined(OS_FREEBSD) || defined(OS_NETBSD) || defined(OS_OPENBSD) -#define OS_BSD 1 -#endif - -// For access to standard POSIXish features, use OS_POSIX instead of a -// more specific macro. -#if defined(OS_AIX) || defined(OS_ANDROID) || defined(OS_ASMJS) || defined(OS_FREEBSD) || defined(OS_LINUX) || \ - defined(OS_MACOSX) || defined(OS_NACL) || defined(OS_NETBSD) || defined(OS_OPENBSD) || defined(OS_QNX) || \ - defined(OS_SOLARIS) -#define OS_POSIX 1 -#endif - -// Compiler detection. Note: clang masquerades as GCC on POSIX and as MSVC on -// Windows. -#if defined(__GNUC__) -#define COMPILER_GCC 1 -#elif defined(_MSC_VER) -#define COMPILER_MSVC 1 -#else -#error Please add support for your compiler in build/build_config.h -#endif - -// Processor architecture detection. For more info on what's defined, see: -// http://msdn.microsoft.com/en-us/library/b0084kay.aspx -// http://www.agner.org/optimize/calling_conventions.pdf -// or with gcc, run: "echo | gcc -E -dM -" -#if defined(_M_X64) || defined(__x86_64__) -#define ARCH_CPU_X86_FAMILY 1 -#define ARCH_CPU_X86_64 1 -#define ARCH_CPU_64_BITS 1 -#define ARCH_CPU_LITTLE_ENDIAN 1 -#elif defined(_M_IX86) || defined(__i386__) -#define ARCH_CPU_X86_FAMILY 1 -#define ARCH_CPU_X86 1 -#define ARCH_CPU_32_BITS 1 -#define ARCH_CPU_LITTLE_ENDIAN 1 -#elif defined(__s390x__) -#define ARCH_CPU_S390_FAMILY 1 -#define ARCH_CPU_S390X 1 -#define ARCH_CPU_64_BITS 1 -#define ARCH_CPU_BIG_ENDIAN 1 -#elif defined(__s390__) -#define ARCH_CPU_S390_FAMILY 1 -#define ARCH_CPU_S390 1 -#define ARCH_CPU_31_BITS 1 -#define ARCH_CPU_BIG_ENDIAN 1 -#elif (defined(__PPC64__) || defined(__PPC__)) && defined(__BIG_ENDIAN__) -#define ARCH_CPU_PPC64_FAMILY 1 -#define ARCH_CPU_PPC64 1 -#define ARCH_CPU_64_BITS 1 -#define ARCH_CPU_BIG_ENDIAN 1 -#elif defined(__PPC64__) -#define ARCH_CPU_PPC64_FAMILY 1 -#define ARCH_CPU_PPC64 1 -#define ARCH_CPU_64_BITS 1 -#define ARCH_CPU_LITTLE_ENDIAN 1 -#elif defined(__ARMEL__) -#define ARCH_CPU_ARM_FAMILY 1 -#define ARCH_CPU_ARMEL 1 -#define ARCH_CPU_32_BITS 1 -#define ARCH_CPU_LITTLE_ENDIAN 1 -#elif defined(__aarch64__) || defined(_M_ARM64) -#define ARCH_CPU_ARM_FAMILY 1 -#define ARCH_CPU_ARM64 1 -#define ARCH_CPU_64_BITS 1 -#define ARCH_CPU_LITTLE_ENDIAN 1 -#elif defined(__pnacl__) || defined(__asmjs__) || defined(__wasm__) -#define ARCH_CPU_32_BITS 1 -#define ARCH_CPU_LITTLE_ENDIAN 1 -#elif defined(__MIPSEL__) -#if defined(__LP64__) -#define ARCH_CPU_MIPS_FAMILY 1 -#define ARCH_CPU_MIPS64EL 1 -#define ARCH_CPU_64_BITS 1 -#define ARCH_CPU_LITTLE_ENDIAN 1 -#else -#define ARCH_CPU_MIPS_FAMILY 1 -#define ARCH_CPU_MIPSEL 1 -#define ARCH_CPU_32_BITS 1 -#define ARCH_CPU_LITTLE_ENDIAN 1 -#endif -#elif defined(__MIPSEB__) -#if defined(__LP64__) -#define ARCH_CPU_MIPS_FAMILY 1 -#define ARCH_CPU_MIPS64 1 -#define ARCH_CPU_64_BITS 1 -#define ARCH_CPU_BIG_ENDIAN 1 -#else -#define ARCH_CPU_MIPS_FAMILY 1 -#define ARCH_CPU_MIPS 1 -#define ARCH_CPU_32_BITS 1 -#define ARCH_CPU_BIG_ENDIAN 1 -#endif -#else -#error Please add support for your architecture in build/build_config.h -#endif - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.c b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.c deleted file mode 100644 index 1b5de10..0000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.c +++ /dev/null @@ -1,564 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) - -#include "x86_insn_decode.h" - -#include "logging/logging.h" - -#define REX_W(byte) ((byte & 0b00001000) >> 3) -#define REX_R(byte) ((byte & 0b00000100) >> 2) -#define REX_X(byte) ((byte & 0b00000010) >> 1) -#define REX_B(byte) ((byte & 0b00000001) >> 0) - -#define ModRM_Mod(byte) ((byte & 0b11000000) >> 6) -#define ModRM_RegOpcode(byte) ((byte & 0b00111000) >> 3) -#define ModRM_RM(byte) (byte & 0b00000111) - -#define SIB_Scale(sib) ((sib & 0b11000000) >> 6) -#define SIB_Index(sib) ((sib & 0b00111000) >> 3) -#define SIB_Base(sib) ((sib & 0b00000111) >> 0) - -#if 0 -/* Build an encoding specification from scratch. */ -#define SPEC_MAKE(op, opr1, opr2, opr3, opr4) \ - ((uint64_t)(uint16_t)(int16_t)(op) | ((uint64_t)(opr1) << 16) | ((uint64_t)(opr2) << 24) | \ - ((uint64_t)(opr3) << 32) | ((uint64_t)(opr4) << 40)) - -/* Get the operation in an encoding specification. */ -#define SPEC_INSN(spec) ((int16_t)((spec)&0xffff)) - -/* Get the given operand (zero-based) in an encoding specification. */ -#define SPEC_OPERAND(spec, i) ((uint8_t)(((spec) >> (16 + (i)*8)) & 0xff)) - -/* Get the operands part of an encoding specification. */ -#define SPEC_OPERANDS(spec) ((spec)&0xffffffffffff0000ULL) - -/* Merges two encoding specifications. */ -#define SPEC_MERGE(spec1, spec2) ((spec1) | (spec2)) - -#define OP4(insn, oper1, oper2, oper3, oper4) SPEC_MAKE(I_##insn, O_##oper1, O_##oper2, O_##oper3, O_##oper4) -#define OP3(insn, oper1, oper2, oper3) OP4(insn, oper1, oper2, oper3, NONE) -#define OP2(insn, oper1, oper2) OP3(insn, oper1, oper2, NONE) -#define OP1(insn, oper1) OP2(insn, oper1, NONE) -#define OP0(insn) OP1(insn, NONE) -#define OP_EMPTY OP0(NONE) -#define OP_EMPTY_4 OP_EMPTY, OP_EMPTY, OP_EMPTY, OP_EMPTY -#define OP_EMPTY_8 OP_EMPTY_4, OP_EMPTY_4 -#endif - -#define op3_flag(x, f, o0, o1, o2) \ - { \ - .name = #x, .flags = (f), .operands[0] = {.data = #o0}, .operands[1] = {.data = #o1}, \ - .operands[2] = {.data = #o2}, \ - } -#define op2_flag(x, f, o0, o1) op3_flag(x, f, o0, o1, __) -#define op1_flag(x, f, o0) op2_flag(x, f, o0, __) -#define op0_flag(x, f) op1_flag(x, f, __) - -#define op3f op3_flag -#define op2f op2_flag -#define op1f op1_flag -#define op0f op0_flag - -#define op3(x, o0, o1, o2) op3f(x, 0, o0, o1, o2) -#define op2(x, o0, o1) op2f(x, 0, o0, o1) -#define op1(x, o0) op1f(x, 0, o0) -#define op0(x) op0f(x, 0) - -/* Opcode extension in modrm byte reg field. */ -#define foreach_x86_insn_modrm_reg_group \ - _(1) _(1a) _(2) _(3) _(4) _(5) _(6) _(7) _(8) _(9) _(10) _(11) _(12) _(13) _(14) _(15) _(16) _(p) -#define foreach_x86_insn_sse_group \ - _(10) _(28) _(50) _(58) _(60) _(68) _(70) _(78) _(c0) _(d0) _(d8) _(e0) _(e8) _(f0) _(f8) -enum { - X86_INSN_GROUP_START = 0, - -#define _(x) X86_INSN_MODRM_REG_GROUP_##x, - foreach_x86_insn_modrm_reg_group -#undef _ - - X86_INSN_SSE_GROUP_START = 19, -#define _(x) X86_INSN_SSE_GROUP_##x, - foreach_x86_insn_sse_group -#undef _ - - X86_INSN_GROUP_END = 35 -}; - -#define X86_INSN_GROUP_END_MASK ((1 << 6) - 1) -#define X86_INSN_FLAG_SET_GROUP(n) ((n) << 5) -#define X86_INSN_FLAG_GET_GROUP(f) (((f) >> 5) & X86_INSN_GROUP_END_MASK) - -enum { -#define _(x) X86_INSN_FLAG_MODRM_REG_GROUP_##x = X86_INSN_FLAG_SET_GROUP(X86_INSN_MODRM_REG_GROUP_##x), - foreach_x86_insn_modrm_reg_group -#undef _ - -#define _(x) X86_INSN_FLAG_SSE_GROUP_##x = X86_INSN_FLAG_SET_GROUP(X86_INSN_SSE_GROUP_##x), - foreach_x86_insn_sse_group -#undef _ -}; - -// clang-format off - -#define foreach_x86_operand_combine(x, op1_type, op2_type) op2(x, Eb, Gb), op2(x, Ev, Gv), op2(x, Gb, Eb), op2(x, Gv, Ev), op2(x, AL, Ib), op2(x, AX, Iz) - -#define foreach_x86_gp_reg _(AX) _(CX) _(DX) _(BX) _(SP) _(BP) _(SI) _(DI) - -#define foreach_x86_condition _(o) _(no) _(b) _(nb) _(z) _(nz) _(be) _(nbe) _(s) _(ns) _(p) _(np) _(l) _(nl) _(le) _(nle) - -// clang-format on - -#include "./x86_opcode_one_byte.c" -#include "./x86_opcode_two_byte.c" - -typedef struct { - x86_insn_spec_t insns[8]; -} x86_insn_group8_t; - -#include "./x86_opcode_modrm_reg_group.c" -#include "./x86_opcode_sse_group.c" - -#include "./x86_insn_reader.c" - -static x86_insn_prefix_t x86_insn_decode_prefix(x86_insn_reader_t *rd, x86_insn_decode_t *insn, x86_options_t *conf) { - /* Decode each byte until the byte is not a prefix or is an REX prefix, - * because an REX prefix is required to immediately preceed the opcode. - */ - x86_insn_prefix_t insn_prefix = 0; - for (;;) { - uint8_t c = peek_byte(rd); - x86_insn_prefix_t t = 0; - - /* Check for REX prefix if we're in 64-bit mode. */ - if (conf->mode == 64) { - if (c >= 0x40 && c <= 0x4f) { - uint8_t rex = read_byte(rd); - - if (REX_W(rex)) { - insn->flags |= X86_INSN_DECODE_FLAG_OPERAND_SIZE_64; - } - - insn->rex = rex; - - break; - } - } - - /* Check for legacy prefixes. */ - switch (c) { - case 0xF0: - t = INSN_PREFIX_LOCK; - break; - case 0xF2: - t = INSN_PREFIX_REPNE; - break; - case 0xF3: - t = INSN_PREFIX_REPE; - break; - case 0x2E: - t = INSN_PREFIX_CS; - break; - case 0x36: - t = INSN_PREFIX_SS; - break; - case 0x3E: - t = INSN_PREFIX_DS; - break; - case 0x26: - t = INSN_PREFIX_ES; - break; - case 0x64: - t = INSN_PREFIX_FS; - break; - case 0x65: - t = INSN_PREFIX_GS; - break; - case 0x66: - t = INSN_PREFIX_OPERAND_SIZE; - break; - case 0x67: - t = INSN_PREFIX_ADDRESS_SIZE; - break; - } - if (t == 0) - break; - - /* Consume 1 byte. */ - read_byte(rd); - insn_prefix |= t; - } - - return insn_prefix; -} - -int x86_insn_has_modrm_byte(x86_insn_spec_t *insn) { - int i; - for (i = 0; i < sizeof(insn->operands) / sizeof(x86_insn_operand_spec_t); i++) - switch (insn->operands[i].code) { - case 'G': - case 'E': - case 'M': - case 'R': - return 1; - } - return 0; -} - -int x86_insn_immediate_type(x86_insn_spec_t *insn) { - int i; - for (i = 0; i < sizeof(insn->operands); i++) { - switch (insn->operands[i].code) { - case 'J': - case 'I': - case 'O': - return insn->operands[i].type; - } - } - return 0; -} - -int x86_insn_has_immediate(x86_insn_spec_t *insn) { - int i; - for (i = 0; i < sizeof(insn->operands) / sizeof(x86_insn_operand_spec_t); i++) { - switch (insn->operands[i].code) { - case 'J': - case 'I': - case 'O': - return 1; - } - } - return 0; -} - -static uint8_t *x86_insn_decode_number(x86_insn_reader_t *rd, uint8_t number_bits, int64_t *out_number) { - int64_t disp = 0; - switch (number_bits) { - case 64: - disp = read_uint64(rd); - break; - case 32: - disp = read_uint32(rd); - break; - case 16: - disp = read_uint16(rd); - break; - case 8: - disp = read_uint8(rd); - break; - default: - UNREACHABLE(); - } - - *out_number = disp; - return NULL; -} - -void x86_insn_decode_modrm_sib(x86_insn_reader_t *rd, x86_insn_decode_t *insn, x86_options_t *conf) { - uint8_t mod, rm, reg; - - x86_insn_modrm_t modrm; - modrm.byte = read_byte(rd); - insn->modrm = modrm; - - mod = modrm.mode; - rm = (uint8_t)((REX_B(insn->rex) << 3) | modrm.rm); - reg = (uint8_t)((REX_R(insn->rex) << 3) | modrm.reg); - - x86_insn_operand_t *reg_op = &insn->operands[0]; - x86_insn_operand_t *mem_op = &insn->operands[1]; - - reg_op->reg = reg; - - if (mod == 3) { - mem_op->reg = rm; - return; - } - - uint8_t disp_bits = -1; - - insn->flags |= X86_INSN_DECODE_FLAG_IS_ADDRESS; - - uint8_t effective_address_bits; - if (conf->mode == 64) - effective_address_bits = (insn->prefix & INSN_PREFIX_ADDRESS_SIZE) ? 32 : 64; - else if (conf->mode == 32) - effective_address_bits = (insn->prefix & INSN_PREFIX_ADDRESS_SIZE) ? 16 : 32; - else { - FATAL("16-bit address mode not supported"); - } - - if (effective_address_bits == 32 || effective_address_bits == 64) { - mem_op->mem.base = rm; - - insn->flags |= X86_INSN_DECODE_FLAG_HAS_BASE; - - if (mod == 0 && (rm & 7) == 5) { - insn->flags = X86_INSN_DECODE_FLAG_IP_RELATIVE; - mem_op->mem.base = RIP; - disp_bits = 32; - } else if (mod == 0) { - disp_bits = 0; - } else if (mod == 1) { - disp_bits = 8; - } else if (mod == 2) { - disp_bits = 32; - } else { - disp_bits = 0; - } - - uint8_t has_sib = 0; - if ((rm & 7) == 4) { - ASSERT(modrm.rm == (rm & 7)); - has_sib = 1; - } - - if (has_sib) { - x86_insn_sib_t sib = {0}; - sib.byte = read_byte(rd); - insn->sib = sib; - - uint8_t base = (uint8_t)(sib.base | (REX_B(insn->rex) << 3)); - uint8_t index = (uint8_t)(sib.index | (REX_X(insn->rex) << 3)); - uint8_t scale = (uint8_t)(1 << sib.log2_scale); - - insn->flags |= X86_INSN_DECODE_FLAG_HAS_BASE; - - if (sib.index != X86_INSN_GP_REG_SP) { - insn->flags |= X86_INSN_DECODE_FLAG_HAS_INDEX; - } - - insn->operands[1].mem.base = base; - insn->operands[1].mem.index = index; - insn->operands[1].mem.scale = scale; - - if (sib.index == X86_INSN_GP_REG_SP) { - insn->operands[1].mem.index = RNone; - insn->operands[1].mem.scale = 0; - } - - // for 64 bit - if (effective_address_bits == 64) { - if (mem_op->mem.base == RBP || mem_op->mem.base == R13) { - if (mod == 0) { - mem_op->mem.base = RNone; - } - if (mod == 1) { - disp_bits = 8; - } else { - disp_bits = 32; - } - } - - if (sib.index != X86_INSN_GP_REG_SP) { - insn->flags |= X86_INSN_DECODE_FLAG_HAS_INDEX; - } - } - - // for 32 bit - if (effective_address_bits == 32) { - if (mem_op->mem.base == RBP) { - if (mod == 0) { - mem_op->mem.base = RNone; - } - if (mod == 1) { - disp_bits = 8; - } else { - disp_bits = 32; - } - } - } - } - } - - // for 16 bit - if (effective_address_bits == 16) { - switch (modrm.mode) { - case 0: - if (modrm.rm == 6) { - /* [disp16] */ - disp_bits = 16; - break; - } - /* fall through */ - case 1: - case 2: - switch (modrm.rm) { - case 0: /* [bx + si/di] */ - case 1: - mem_op->mem.base = X86_INSN_GP_REG_BX; - mem_op->mem.index = X86_INSN_GP_REG_SI + (modrm.rm & 1); - insn->flags |= X86_INSN_DECODE_FLAG_HAS_BASE | X86_INSN_DECODE_FLAG_HAS_INDEX; - break; - - case 2: /* [bp + si/di] */ - case 3: - mem_op->mem.base = X86_INSN_GP_REG_BP; - mem_op->mem.index = X86_INSN_GP_REG_SI + (modrm.rm & 1); - insn->flags |= X86_INSN_DECODE_FLAG_HAS_BASE | X86_INSN_DECODE_FLAG_HAS_INDEX; - break; - - case 4: /* [si/di] */ - case 5: - mem_op->mem.base = X86_INSN_GP_REG_SI + (modrm.rm & 1); - insn->flags |= X86_INSN_DECODE_FLAG_HAS_BASE; - break; - - case 6: /* [bp + disp] */ - mem_op->mem.base = X86_INSN_GP_REG_BP; - insn->flags |= X86_INSN_DECODE_FLAG_HAS_BASE; - break; - - case 7: /* [bx + disp] */ - mem_op->mem.base = X86_INSN_GP_REG_BX; - insn->flags |= X86_INSN_DECODE_FLAG_HAS_BASE; - break; - } - - if (modrm.mode != 0) - disp_bits = modrm.mode == 1 ? 8 : 16; - break; - } - } - - if (disp_bits != 0) { - // update displacement offset - insn->displacement_offset = (uint8_t)reader_offset(rd); - - int64_t disp; - x86_insn_decode_number(rd, disp_bits, &disp); - mem_op->mem.disp = disp; - } -} - -/* Decodes the opcode of an instruction and returns its encoding - * specification. - */ -static void x86_insn_decode_opcode(x86_insn_reader_t *rd, x86_insn_decode_t *insn, x86_options_t *conf) { - uint8_t opcode = read_byte(rd); - - x86_insn_spec_t insn_spec; - if (opcode == 0x0f) { - opcode = read_byte(rd); - insn_spec = x86_opcode_map_two_byte[opcode]; - } else { - insn_spec = x86_opcode_map_one_byte[opcode]; - } - - // check sse group - if (X86_INSN_FLAG_GET_GROUP(insn_spec.flags) > X86_INSN_SSE_GROUP_START) { - UNIMPLEMENTED(); - } - - if (X86_INSN_FLAG_GET_GROUP(insn_spec.flags) > X86_INSN_GROUP_START && - X86_INSN_FLAG_GET_GROUP(insn_spec.flags) < X86_INSN_SSE_GROUP_START) { - // get group index - int group_ndx = X86_INSN_FLAG_GET_GROUP(insn_spec.flags); - - // get gp insn index in group - x86_insn_modrm_t modrm; - modrm.byte = peek_byte(rd); - int insn_ndx = modrm.reg; - - // get insn in group - x86_insn_spec_t *group_insn = NULL; - group_insn = &x86_insn_modrm_reg_groups[group_ndx].insns[insn_ndx]; - - // update the insn spec - insn_spec.name = group_insn->name; - insn_spec.flags = group_insn->flags; - } - - insn->primary_opcode = opcode; - insn->insn_spec = insn_spec; -} - -uint8_t x86_insn_imm_bits(x86_insn_spec_t *insn, uint8_t operand_bits) { - uint8_t imm_bits = 0; - switch (x86_insn_immediate_type(insn)) { - case 'b': - imm_bits = 8; - break; - case 'w': - imm_bits = 16; - break; - case 'd': - imm_bits = 32; - break; - case 'q': - imm_bits = 64; - break; - - case 'z': - imm_bits = operand_bits; - if (imm_bits == 64) - imm_bits = 32; - break; - - case 'v': - imm_bits = operand_bits; - break; - - default: - imm_bits = 0; - break; - } - - return imm_bits; -} - -void x86_insn_decode_immediate(x86_insn_reader_t *rd, x86_insn_decode_t *insn, x86_options_t *conf) { - uint8_t effective_operand_bits; - if (conf->mode == 64 || conf->mode == 32) { - effective_operand_bits = (insn->prefix & INSN_PREFIX_OPERAND_SIZE) ? 16 : 32; - } - effective_operand_bits = (insn->prefix & INSN_PREFIX_OPERAND_SIZE) ? 16 : 32; - - if (insn->flags & X86_INSN_DECODE_FLAG_OPERAND_SIZE_64) - effective_operand_bits = 64; - - if (conf->mode == 64 && insn->insn_spec.flags & X86_INSN_SPEC_DEFAULT_64_BIT) - effective_operand_bits = 64; - - int64_t immediate = 0; - uint8_t imm_bits = x86_insn_imm_bits(&insn->insn_spec, effective_operand_bits); - if (imm_bits == 0) - return; - - // update immediate offset - insn->immediate_offset = (uint8_t)reader_offset(rd); - - x86_insn_decode_number(rd, imm_bits, &immediate); - insn->immediate = immediate; -} - -void x86_insn_decode(x86_insn_decode_t *insn, uint8_t *buffer, x86_options_t *conf) { - // init reader - x86_insn_reader_t rd; - init_reader(&rd, buffer, buffer + 15); - - // decode prefix - insn->prefix = x86_insn_decode_prefix(&rd, insn, conf); - - // decode insn specp/x in - x86_insn_decode_opcode(&rd, insn, conf); - - if (x86_insn_has_modrm_byte(&insn->insn_spec)) { - // decode insn modrm sib (operand register, disp) - x86_insn_decode_modrm_sib(&rd, insn, conf); - } - - if (x86_insn_has_immediate(&insn->insn_spec)) { - // decode insn immeidate - x86_insn_decode_immediate(&rd, insn, conf); - } - -#if 1 - DLOG(0, "[x86 insn] %s", insn->insn_spec.name); -#endif - - // set insn length - insn->length = rd.buffer_cursor - rd.buffer; -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.h b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.h deleted file mode 100644 index bb395fd..0000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.h +++ /dev/null @@ -1,200 +0,0 @@ -#ifndef X86_INSN_DECODE_H -#define X86_INSN_DECODE_H - -#include -#include "common_header.h" - -typedef enum { - X86_INSN_SPEC_DEFAULT_64_BIT = 1 << 0, -} x86_insn_spec_flag_t; - -typedef enum { - X86_INSN_DECODE_FLAG_HAS_BASE = 1 << 0, - - X86_INSN_DECODE_FLAG_HAS_INDEX = 1 << 1, - - X86_INSN_DECODE_FLAG_IS_ADDRESS = 1 << 2, - - X86_INSN_DECODE_FLAG_IP_RELATIVE = 1 << 3, - - X86_INSN_DECODE_FLAG_OPERAND_SIZE_64 = 1 << 4, -} x86_insn_decode_flag_t; - -typedef enum { - INSN_PREFIX_NONE = 0, - - /* Group 1: lock and repeat prefixes */ - INSN_PREFIX_GROUP1 = 0x07, - INSN_PREFIX_LOCK = 0x01, /* F0 */ - INSN_PREFIX_REPNZ = 0x02, /* F2 */ - INSN_PREFIX_REPNE = INSN_PREFIX_REPNZ, - INSN_PREFIX_REP = 0x04, /* F3 */ - INSN_PREFIX_REPZ = INSN_PREFIX_REP, - INSN_PREFIX_REPE = INSN_PREFIX_REPZ, - - /* Group 2: segment override or branch hints */ - INSN_PREFIX_GROUP2 = 0x01f8, - INSN_PREFIX_ES = 0x0008, /* 26 */ - INSN_PREFIX_CS = 0x0010, /* 2E */ - INSN_PREFIX_SS = 0x0020, /* 36 */ - INSN_PREFIX_DS = 0x0040, /* 3E */ - INSN_PREFIX_FS = 0x0080, /* 64 */ - INSN_PREFIX_GS = 0x0100, /* 65 */ - INSN_PREFIX_BRANCH_TAKEN = INSN_PREFIX_CS, /* 2E */ - INSN_PREFIX_BRANCH_NOT_TAKEN = INSN_PREFIX_DS, /* 3E */ - - /* Group 3: operand-size override */ - INSN_PREFIX_OPERAND_SIZE = 0x0200, /* 66 */ - - /* Group 4: address-size override */ - INSN_PREFIX_ADDRESS_SIZE = 0x0400 /* 67 */ -} x86_insn_prefix_t; - -typedef union { - struct { - uint8_t code; - uint8_t type; - }; - uint8_t data[2]; -} x86_insn_operand_spec_t; - -typedef struct { - // insn name - char *name; - - // insn max 3 operands - x86_insn_operand_spec_t operands[3]; - - // insn flag - uint16_t flags; -#define X86_INSN_FLAG_SET_SSE_GROUP(n) ((n) << 5) -#define X86_INSN_FLAG_GET_SSE_GROUP(f) (((f) >> 5) & 0x1f) -#define X86_INSN_FLAG_SET_MODRM_REG_GROUP(n) (((n)&0x3f) << 10) -#define X86_INSN_FLAG_GET_MODRM_REG_GROUP(f) (((f) >> 10) & 0x3f) -} x86_insn_spec_t; - -#define foreach_x86_gp_register _(AX) _(CX) _(DX) _(BX) _(SP) _(BP) _(SI) _(DI) - -typedef enum { -#define _(r) X86_INSN_GP_REG_##r, - foreach_x86_gp_register -#undef _ -} x86_insn_gp_register_t; - -typedef enum { - RNone = 0, - RAX, - RBX, - RCX, - RDX, - RDI, - RSI, - RBP, - RSP, - R8, - R9, - R10, - R11, - R12, - R13, - R14, - R15, - RIP -} x86_ia32e_register_t; - -typedef union { - struct { - uint8_t rm : 3; - uint8_t reg : 3; - uint8_t mode : 2; - }; - uint8_t byte; -} x86_insn_modrm_t; - -typedef union { - struct { - uint8_t base : 3; - uint8_t index : 3; - uint8_t log2_scale : 2; - }; - uint8_t byte; -} x86_insn_sib_t; - -typedef struct { - uint8_t reg; - - struct { - uint8_t base; - uint8_t index; - uint8_t scale; - uint32_t disp; - } mem; -} x86_insn_operand_t; - -typedef struct x86_insn_decode_t { - // insn flag - uint32_t flags; - - // insn length - uint32_t length; - - // insn displacement offset - uint8_t displacement_offset; - - // insn immediate offset - uint8_t immediate_offset; - - // Registers in instruction - // [0] is modrm reg field - // [1] is base reg - // [2] is index reg - // union { - // struct { - // uint8_t modrm_reg; - // uint8_t op_base_reg; - // uint8_t op_index_reg; - // }; - // uint8_t regs[3]; - // }; - - x86_insn_operand_t operands[3]; - - struct { // insn field combine - // insn prefix - x86_insn_prefix_t prefix; - - // insn rex - uint8_t rex; - - // insn primary opcode - uint8_t primary_opcode; - - // insn modrm - x86_insn_modrm_t modrm; - - // insn sib - x86_insn_sib_t sib; - - // insn operand imm - int64_t immediate; - }; - - // insn pre-spec - x86_insn_spec_t insn_spec; -} x86_insn_decode_t; - -typedef struct x86_options_t { - int mode; /* 16, 32 or 64 bit */ -} x86_options_t; - -#ifdef __cplusplus -extern "C" { -#endif - -void x86_insn_decode(x86_insn_decode_t *insn, uint8_t *buffer, x86_options_t *conf); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_reader.c b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_reader.c deleted file mode 100644 index 059e547..0000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_reader.c +++ /dev/null @@ -1,87 +0,0 @@ -/* Specialized instruction reader. */ -typedef struct x86_insn_reader_t { - const unsigned char *prefix; /* pointer to beginning of instruction */ - const unsigned char *opcode; /* pointer to opcode */ - const unsigned char *modrm; /* pointer to modrm byte */ - - unsigned char buffer[20]; /* buffer used when few bytes left */ - const unsigned char *buffer_cursor; /* pointer to buffer_cursor of insn + 1 */ -} x86_insn_reader_t; - -/* Initializes a bytecode reader to read code from a given part of memory. */ -static void init_reader(x86_insn_reader_t *rd, const unsigned char *begin, const unsigned char *buffer_cursor) { - if (buffer_cursor - begin < sizeof(rd->buffer)) { - memset(rd->buffer, 0xcc, sizeof(rd->buffer)); /* debug token */ - memcpy(rd->buffer, begin, buffer_cursor - begin); - rd->prefix = rd->buffer; - } else { - rd->prefix = begin; - } - rd->opcode = rd->modrm = rd->buffer_cursor = rd->prefix; -} - -uint32_t reader_offset(x86_insn_reader_t *rd) { - return rd->buffer_cursor - rd->buffer; -} - -static uint8_t peek_byte(const x86_insn_reader_t *rd) { - return *rd->buffer_cursor; -} - -#define read_uint8 read_byte -static uint8_t read_byte(x86_insn_reader_t *rd) { - DLOG(0, "[x86 insn reader] %p - 1", rd->buffer_cursor); - - const unsigned char *p = rd->buffer_cursor; - rd->buffer_cursor++; - return *p; -} - -#define read_uint16 read_word -static uint16_t read_word(x86_insn_reader_t *rd) { - DLOG(0, "[x86 insn reader] %p - 2", rd->buffer_cursor); - - const unsigned char *p = rd->buffer_cursor; - rd->buffer_cursor += 2; - return (uint16_t)((uint16_t)p[0] | ((uint16_t)p[1] << 8)); -} - -#define read_uint32 read_dword -static uint32_t read_dword(x86_insn_reader_t *rd) { - DLOG(0, "[x86 insn reader] %p - 4", rd->buffer_cursor); - - const unsigned char *p = rd->buffer_cursor; - rd->buffer_cursor += 4; - return (uint32_t)p[0] | ((uint32_t)p[1] << 8) | ((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24); -} - -#define read_uint64 read_qword -static uint64_t read_qword(x86_insn_reader_t *rd) { - DLOG(0, "[x86 insn reader] %p - 8", rd->buffer_cursor); - - uint64_t *p = (uint64_t *)rd->buffer_cursor; - rd->buffer_cursor += 4; - return p[0]; -} - -static uint32_t read_imm(x86_insn_reader_t *rd, int size) { - DLOG(0, "[x86 insn reader] %p", rd->buffer_cursor); - - return (size == 8) ? read_byte(rd) : (size == 16) ? read_word(rd) : (size == 32) ? read_dword(rd) : 0; -} - -static unsigned char read_modrm(x86_insn_reader_t *rd) { - if (rd->buffer_cursor == rd->modrm) - rd->buffer_cursor++; - return *rd->modrm; -} - -/* Marks the next byte as ModR/M. */ -static void continue_modrm(x86_insn_reader_t *rd) { - rd->modrm = rd->buffer_cursor; -} - -/* Marks the next byte as opcode. */ -static void continue_opcode(x86_insn_reader_t *rd) { - rd->modrm = rd->opcode = rd->buffer_cursor; -} diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_modrm_reg_group.c b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_modrm_reg_group.c deleted file mode 100644 index 352ea1a..0000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_modrm_reg_group.c +++ /dev/null @@ -1,218 +0,0 @@ -/* Escape groups are indexed by modrm reg field. */ -static x86_insn_group8_t x86_insn_modrm_reg_groups[] = { - [X86_INSN_MODRM_REG_GROUP_1].insns = - { - op0(add), - op0(or), - op0(adc), - op0(sbb), - op0(and), - op0(sub), - op0(xor), - op0(cmp), - }, - - [X86_INSN_MODRM_REG_GROUP_1a].insns = - { - op0f(pop, X86_INSN_SPEC_DEFAULT_64_BIT), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_MODRM_REG_GROUP_2].insns = - { - op0(rol), - op0(ror), - op0(rcl), - op0(rcr), - op0(shl), - op0(shr), - op0(sal), - op0(sar), - }, - - [X86_INSN_MODRM_REG_GROUP_3].insns = - { - op0(test), - op0(test), - op0(not ), - op0(neg), - op0(mul), - op0(imul), - op0(div), - op0(idiv), - }, - - [X86_INSN_MODRM_REG_GROUP_4].insns = - { - op0(inc), - op0(dec), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_MODRM_REG_GROUP_5].insns = - { - op1(inc, Ev), - op1(dec, Ev), - op1f(call, X86_INSN_SPEC_DEFAULT_64_BIT, Ev), - op1(call, Mp), - op1f(jmp, X86_INSN_SPEC_DEFAULT_64_BIT, Ev), - op1(jmp, Mp), - op1f(push, X86_INSN_SPEC_DEFAULT_64_BIT, Ev), - op0(bad), - }, - - [X86_INSN_MODRM_REG_GROUP_6].insns = - { - op1(sldt, Ev), - op1(str, Ev), - op1(lldt, Ev), - op1(ltr, Ev), - op1(verr, Ev), - op1(verw, Ev), - op0(bad), - op0(bad), - }, - - [X86_INSN_MODRM_REG_GROUP_7].insns = - { - op1(sgdt, Mv), - op1(sidt, Mv), - op1(lgdt, Mv), - op1(lidt, Mv), - op1(smsw, Ev), - op0(bad), - op1(lmsw, Ew), - op1(invlpg, Mv), - }, - - [X86_INSN_MODRM_REG_GROUP_8].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op2(bt, Ev, Ib), - op2(bts, Ev, Ib), - op2(btr, Ev, Ib), - op2(btc, Ev, Ib), - }, - - [X86_INSN_MODRM_REG_GROUP_9].insns = - { - op0(bad), - op1(cmpxchg, Mx), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_MODRM_REG_GROUP_10].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_MODRM_REG_GROUP_11].insns = - { - op0(mov), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_MODRM_REG_GROUP_12].insns = - { - op0(bad), - op0(bad), - op2(psrlw, Rm, Ib), - op0(bad), - op2(psraw, Rm, Ib), - op0(bad), - op2(psllw, Rm, Ib), - op0(bad), - }, - - [X86_INSN_MODRM_REG_GROUP_13].insns = - { - op0(bad), - op0(bad), - op2(psrld, Rm, Ib), - op0(bad), - op2(psrad, Rm, Ib), - op0(bad), - op2(pslld, Rm, Ib), - op0(bad), - }, - - [X86_INSN_MODRM_REG_GROUP_14].insns = - { - op0(bad), - op0(bad), - op2(psrlq, Rm, Ib), - op0f(bad, 0), - op0(bad), - op0(bad), - op2(psllq, Rm, Ib), - op0f(bad, 0), - }, - - [X86_INSN_MODRM_REG_GROUP_15].insns = - { - op1(fxsave, Mv), - op1(fxrstor, Mv), - op1(ldmxcsr, Mv), - op1(stmxcsr, Mv), - op0(bad), - op1(lfence, Mv), - op1(mfence, Mv), - op1(sfence, Mv), - }, - - [X86_INSN_MODRM_REG_GROUP_16].insns = - { - op1(prefetch_nta, Mv), - op1(prefetch_t0, Mv), - op1(prefetch_t1, Mv), - op1(prefetch_t2, Mv), - op1(prefetch_nop, Mv), - op1(prefetch_nop, Mv), - op1(prefetch_nop, Mv), - op1(prefetch_nop, Mv), - }, - - [X86_INSN_MODRM_REG_GROUP_p].insns = - { - op1(prefetch_exclusive, Mv), - op1(prefetch_modified, Mv), - op1(prefetch_nop, Mv), - op1(prefetch_modified, Mv), - op1(prefetch_nop, Mv), - op1(prefetch_nop, Mv), - op1(prefetch_nop, Mv), - op1(prefetch_nop, Mv), - }, -}; diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_one_byte.c b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_one_byte.c deleted file mode 100644 index 44b1462..0000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_one_byte.c +++ /dev/null @@ -1,215 +0,0 @@ -// clang-format off -static x86_insn_spec_t x86_opcode_map_one_byte[256] = { - /* 0x00 */ - foreach_x86_operand_combine(add, op_dst, op_src), - op0(push_es), - op0f(pop_es, X86_INSN_SPEC_DEFAULT_64_BIT), - foreach_x86_operand_combine(or, op_dst, op_src), - op0f(push_cs, X86_INSN_SPEC_DEFAULT_64_BIT), - op0(escape_two_byte), - - /* 0x10 */ - foreach_x86_operand_combine(adc, op_dst, op_src), - op0(push_ss), - op0(pop_ss), - foreach_x86_operand_combine(sbb, op_dst, op_src), - op0(push_ds), - op0(pop_ds), - - /* 0x20 */ - foreach_x86_operand_combine(and, op_dst, op_src), - op0(segment_es), - op0(daa), - foreach_x86_operand_combine(sub, op_dst, op_src), - op0(segment_cs), - op0(das), - - /* 0x30 */ - foreach_x86_operand_combine(xor, op_dst, op_src), - op0(segment_ss), - op0(aaa), - foreach_x86_operand_combine(cmp, op_src, op_src), - op0(segment_ds), - op0(aas), - -/* 0x40 */ -#define _(r) op1(inc, r), - foreach_x86_gp_reg -#undef _ -#define _(r) op1(dec, r), - foreach_x86_gp_reg -#undef _ - -/* 0x50 */ -#define _(r) op1f(push, X86_INSN_SPEC_DEFAULT_64_BIT, r), - foreach_x86_gp_reg -#undef _ -#define _(r) op1f(pop, X86_INSN_SPEC_DEFAULT_64_BIT, r), - foreach_x86_gp_reg -#undef _ - - /* 0x60 */ - op0(pusha), - op0(popa), - op2(bound, Gv, Ma), - op2(movsxd, Gv, Ed), - op0(segment_fs), - op0(segment_gs), - op0(operand_type), - op0(address_size), - op1f(push, X86_INSN_SPEC_DEFAULT_64_BIT, Iz), - op3(imul, Gv, Ev, Iz), - op1f(push, X86_INSN_SPEC_DEFAULT_64_BIT, Ib), - op3(imul, Gv, Ev, Ib), - op1(insb, DX), - op1(insw, DX), - op1(outsb, DX), - op1(outsw, DX), - -/* 0x70 */ -#define _(x) op1(j##x, Jb), - foreach_x86_condition -#undef _ - - /* 0x80 */ - op2f(modrm_group_1, X86_INSN_FLAG_MODRM_REG_GROUP_1, Eb, Ib), - op2f(modrm_group_1, X86_INSN_FLAG_MODRM_REG_GROUP_1, Ev, Iz), - op2f(modrm_group_1, X86_INSN_FLAG_MODRM_REG_GROUP_1, Eb, Ib), - op2f(modrm_group_1, X86_INSN_FLAG_MODRM_REG_GROUP_1, Ev, Ib), - op2(test, Eb, Gb), - op2(test, Ev, Gv), - op2(xchg, Eb, Gb), - op2(xchg, Ev, Gv), - op2(mov, Eb, Gb), - op2(mov, Ev, Gv), - op2(mov, Gb, Eb), - op2(mov, Gv, Ev), - op2(mov, Ev, Sw), - op2(lea, Gv, Ev), - op2(mov, Sw, Ew), - op1f(modrm_group_1a, X86_INSN_FLAG_MODRM_REG_GROUP_1a, Ev), - - /* 0x90 */ - op0(nop), - op1(xchg, CX), - op1(xchg, DX), - op1(xchg, BX), - op1(xchg, SP), - op1(xchg, BP), - op1(xchg, SI), - op1(xchg, DI), - op0(cbw), - op0(cwd), - op1(call, Ap), - op0(wait), - op0(pushf), - op0(popf), - op0(sahf), - op0(lahf), - - /* 0xa0 */ - op2(mov, AL, Ob), - op2(mov, AX, Ov), - op2(mov, Ob, AL), - op2(mov, Ov, AX), - op0(movsb), - op0(movsw), - op0(cmpsb), - op0(cmpsw), - op2(test, AL, Ib), - op2(test, AX, Iz), - op1(stosb, AL), - op1(stosw, AX), - op1(lodsb, AL), - op1(lodsw, AX), - op1(scasb, AL), - op1(scasw, AX), - - /* 0xb0 */ - op2(mov, AL, Ib), - op2(mov, CL, Ib), - op2(mov, DL, Ib), - op2(mov, BL, Ib), - op2(mov, AH, Ib), - op2(mov, CH, Ib), - op2(mov, DH, Ib), - op2(mov, BH, Ib), -#define _(r) op2(mov, r, Iv), - foreach_x86_gp_reg -#undef _ - - /* 0xc0 */ - op2f(modrm_group_2, X86_INSN_FLAG_MODRM_REG_GROUP_2, Eb, Ib), - op2f(modrm_group_2, X86_INSN_FLAG_MODRM_REG_GROUP_2, Ev, Ib), - op1(ret, Iw), - op0(ret), - op2(les, Gz, Mp), - op2(lds, Gz, Mp), - op2f(modrm_group_11, X86_INSN_FLAG_MODRM_REG_GROUP_11, Eb, Ib), - op2f(modrm_group_11, X86_INSN_FLAG_MODRM_REG_GROUP_11, Ev, Iz), - op2(enter, Iw, Ib), - op0(leave), - op1(ret, Iw), - op0(ret), - op0(int3), - op1(int, Ib), - op0(into), - op0(iret), - - /* 0xd0 */ - op2f(modrm_group_2, X86_INSN_FLAG_MODRM_REG_GROUP_2, Eb, 1b), - op2f(modrm_group_2, X86_INSN_FLAG_MODRM_REG_GROUP_2, Ev, 1b), - op2f(modrm_group_2, X86_INSN_FLAG_MODRM_REG_GROUP_2, Eb, CL), - op2f(modrm_group_2, X86_INSN_FLAG_MODRM_REG_GROUP_2, Ev, CL), - op0(aam), - op0(aad), - op0(salc), - op0(xlat), - /* FIXME x87 */ - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - - /* 0xe0 */ - op1(loopnz, Jb), - op1(loopz, Jb), - op1(loop, Jb), - op1(jcxz, Jb), - op2(in, AL, Ib), - op2(in, AX, Ib), - op2(out, Ib, AL), - op2(out, Ib, AX), - op1f(call, X86_INSN_SPEC_DEFAULT_64_BIT, Jz), - op1f(jmp, X86_INSN_SPEC_DEFAULT_64_BIT, Jz), - op1(jmp, Ap), - op1(jmp, Jb), - op2(in, AL, DX), - op2(in, AX, DX), - op2(out, DX, AL), - op2(out, DX, AX), - - /* 0xf0 */ - op0(lock), - op0(int1), - op0(repne), - op0(rep), - op0(hlt), - op0(cmc), - op0f(modrm_group_3, X86_INSN_FLAG_MODRM_REG_GROUP_3), - op0f(modrm_group_3, X86_INSN_FLAG_MODRM_REG_GROUP_3), - op0(clc), - op0(stc), - op0(cli), - op0(sti), - op0(cld), - op0(std), - op1f(modrm_group_4, X86_INSN_FLAG_MODRM_REG_GROUP_4, Eb), - op0f(modrm_group_5, X86_INSN_FLAG_MODRM_REG_GROUP_5), -}; - -// clang-format on \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_sse_group.c b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_sse_group.c deleted file mode 100644 index 8e56a9b..0000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_sse_group.c +++ /dev/null @@ -1,545 +0,0 @@ -static x86_insn_group8_t x86_insn_sse_groups_repz[] = { - [X86_INSN_SSE_GROUP_10].insns = - { - op2(movss, Gx, Ex), - op2(movss, Ex, Gx), - op2(movsldup, Gx, Ex), - op0(bad), - op0(bad), - op0(bad), - op2(movshdup, Gx, Ex), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_28].insns = - { - op0(bad), - op0(bad), - op2(cvtsi2ss, Gx, Ev), - op0(bad), - op2(cvttss2si, Gv, Ex), - op2(cvtss2si, Gv, Ex), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_50].insns = - { - op0(bad), - op2(sqrtss, Gx, Ex), - op2(rsqrtps, Gx, Ex), - op2(rcpss, Gx, Ex), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_58].insns = - { - op2(addss, Gx, Ex), - op2(mulss, Gx, Ex), - op2(cvtss2sd, Gx, Ex), - op2(cvttps2dq, Gx, Ex), - op2(subss, Gx, Ex), - op2(minss, Gx, Ex), - op2(divss, Gx, Ex), - op2(maxss, Gx, Ex), - }, - - [X86_INSN_SSE_GROUP_60].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_68].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op2(movdqu, Gx, Ex), - }, - - [X86_INSN_SSE_GROUP_70].insns = - { - op3(pshufhw, Gx, Ex, Ib), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_78].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op2(movq, Gx, Ex), - op2(movdqu, Ex, Gx), - }, - - [X86_INSN_SSE_GROUP_c0].insns = - { - op0(bad), - op0(bad), - op3(cmpss, Gx, Ex, Ib), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_d0].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op2(movq2dq, Gx, Em), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_d8].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_e0].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op2(cvtdq2pd, Gx, Ex), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_e8].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_f0].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_f8].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, -}; - -static x86_insn_group8_t x86_insn_sse_groups_operand_size[] = { - [X86_INSN_SSE_GROUP_10].insns = - { - op2(movupd, Gx, Ex), - op2(movupd, Ex, Gx), - op2(movlpd, Gx, Ex), - op2(movlpd, Ex, Gx), - op2(unpcklpd, Gx, Ex), - op2(unpckhpd, Gx, Ex), - op2(movhpd, Gx, Mx), - op2(movhpd, Mx, Gx), - }, - - [X86_INSN_SSE_GROUP_28].insns = - { - op2(movapd, Gx, Ex), - op2(movapd, Ex, Gx), - op2(cvtpi2pd, Gx, Ex), - op2(movntpd, Mx, Gx), - op2(cvttpd2pi, Gx, Mx), - op2(cvtpd2pi, Gx, Mx), - op2(ucomisd, Gx, Ex), - op2(comisd, Gx, Ex), - }, - - [X86_INSN_SSE_GROUP_50].insns = - { - op2(movmskpd, Gd, Rx), - op2(sqrtpd, Gx, Ex), - op0(bad), - op0(bad), - op2(andpd, Gx, Ex), - op2(andnpd, Gx, Ex), - op2(orpd, Gx, Ex), - op2(xorpd, Gx, Ex), - }, - - [X86_INSN_SSE_GROUP_58].insns = - { - op2(addpd, Gx, Ex), - op2(mulpd, Gx, Ex), - op2(cvtpd2ps, Gx, Ex), - op2(cvtps2dq, Gx, Ex), - op2(subpd, Gx, Ex), - op2(minpd, Gx, Ex), - op2(divpd, Gx, Ex), - op2(maxpd, Gx, Ex), - }, - - [X86_INSN_SSE_GROUP_60].insns = - { - op2(punpcklbw, Gx, Ex), - op2(punpcklwd, Gx, Ex), - op2(punpckldq, Gx, Ex), - op2(packsswb, Gx, Ex), - op2(pcmpgtb, Gx, Ex), - op2(pcmpgtw, Gx, Ex), - op2(pcmpgtd, Gx, Ex), - op2(packuswb, Gx, Ex), - }, - - [X86_INSN_SSE_GROUP_68].insns = - { - op2(punpckhbw, Gx, Ex), - op2(punpckhwd, Gx, Ex), - op2(punpckhdq, Gx, Ex), - op2(packssdw, Gx, Ex), - op2(punpcklqdq, Gx, Ex), - op2(punpckhqdq, Gx, Ex), - op2(movd, Gx, Ev), - op2(movdqa, Gx, Ex), - }, - - [X86_INSN_SSE_GROUP_70].insns = - { - op3(pshufd, Gx, Ex, Ib), - op0f(modrm_group_12, X86_INSN_FLAG_MODRM_REG_GROUP_12), - op0f(modrm_group_13, X86_INSN_FLAG_MODRM_REG_GROUP_13), - op0f(modrm_group_14, X86_INSN_FLAG_MODRM_REG_GROUP_14), - op2(pcmpeqb, Gx, Ex), - op2(pcmpeqw, Gx, Ex), - op2(pcmpeqd, Gx, Ex), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_78].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op2(haddpd, Gx, Ex), - op2(hsubpd, Gx, Ex), - op2(movd, Ev, Gx), - op2(movdqa, Ex, Gx), - }, - - [X86_INSN_SSE_GROUP_c0].insns = - { - op0(bad), - op0(bad), - op3(cmppd, Gx, Ex, Ib), - op0(bad), - op3(pinsrw, Gx, Ew, Ib), - op3(pextrw, Gd, Gx, Ib), - op3(shufpd, Gx, Ex, Ib), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_d0].insns = - { - op2(addsubpd, Gx, Ex), - op2(psrlw, Gx, Ex), - op2(psrld, Gx, Ex), - op2(psrlq, Gx, Ex), - op2(paddq, Gx, Ex), - op2(pmullw, Gx, Ex), - op2(movq, Ex, Gx), - op2(pmovmskb, Gd, Rx), - }, - - [X86_INSN_SSE_GROUP_d8].insns = - { - op2(psubusb, Gx, Ex), - op2(psubusw, Gx, Ex), - op2(pminub, Gx, Ex), - op2(pand, Gx, Ex), - op2(paddusb, Gx, Ex), - op2(paddusw, Gx, Ex), - op2(pmaxub, Gx, Ex), - op2(pandn, Gx, Ex), - }, - - [X86_INSN_SSE_GROUP_e0].insns = - { - op2(pavgb, Gx, Ex), - op2(psraw, Gx, Ex), - op2(psrad, Gx, Ex), - op2(pavgw, Gx, Ex), - op2(pmulhuw, Gx, Ex), - op2(pmulhw, Gx, Ex), - op2(cvttpd2dq, Gx, Ex), - op2(movntdq, Mx, Gx), - }, - - [X86_INSN_SSE_GROUP_e8].insns = - { - op2(psubsb, Gx, Ex), - op2(psubsw, Gx, Ex), - op2(pminsw, Gx, Ex), - op2(por, Gx, Ex), - op2(paddsb, Gx, Ex), - op2(paddsw, Gx, Ex), - op2(pmaxsw, Gx, Ex), - op2(pxor, Gx, Ex), - }, - - [X86_INSN_SSE_GROUP_f0].insns = - { - op0(bad), - op2(psllw, Gx, Ex), - op2(pslld, Gx, Ex), - op2(psllq, Gx, Ex), - op2(pmuludq, Gx, Ex), - op2(pmaddwd, Gx, Ex), - op2(psadbw, Gx, Ex), - op2(maskmovdqu, Gx, Ex), - }, - - [X86_INSN_SSE_GROUP_f8].insns = - { - op2(psubb, Gx, Ex), - op2(psubw, Gx, Ex), - op2(psubd, Gx, Ex), - op2(psubq, Gx, Ex), - op2(paddb, Gx, Ex), - op2(paddw, Gx, Ex), - op2(paddd, Gx, Ex), - op0(bad), - }, -}; - -static x86_insn_group8_t x86_insn_sse_groups_repnz[] = { - [X86_INSN_SSE_GROUP_10].insns = - { - op2(movsd, Gx, Ex), - op2(movsd, Ex, Gx), - op2(movddup, Gx, Ex), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_28].insns = - { - op0(bad), - op0(bad), - op2(cvtsi2sd, Gx, Ev), - op0(bad), - op2(cvttsd2si, Gv, Ex), - op2(cvtsd2si, Gv, Ex), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_50].insns = - { - op0(bad), - op2(sqrtsd, Gx, Ex), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_58].insns = - { - op2(addsd, Gx, Ex), - op2(mulsd, Gx, Ex), - op2(cvtsd2ss, Gx, Ex), - op0(bad), - op2(subsd, Gx, Ex), - op2(minsd, Gx, Ex), - op2(divsd, Gx, Ex), - op2(maxsd, Gx, Ex), - }, - - [X86_INSN_SSE_GROUP_60].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_68].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_70].insns = - { - op3(pshuflw, Gx, Ex, Ib), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_78].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op2(haddps, Gx, Ex), - op2(hsubps, Gx, Ex), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_c0].insns = - { - op0(bad), - op0(bad), - op3(cmpsd, Gx, Ex, Ib), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_d0].insns = - { - op2(addsubps, Gx, Ex), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op2(movdq2q, Gm, Ex), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_d8].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_e0].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op2(cvtpd2dq, Gx, Ex), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_e8].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_f0].insns = - { - op2(lddqu, Gx, Mx), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_f8].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_two_byte.c b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_two_byte.c deleted file mode 100644 index 900d0b3..0000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_two_byte.c +++ /dev/null @@ -1,249 +0,0 @@ - -// clang-format off -static x86_insn_spec_t x86_opcode_map_two_byte[256] = { - /* 0x00 */ - op0f(modrm_group_6, X86_INSN_FLAG_MODRM_REG_GROUP_6), - op0f(modrm_group_7, X86_INSN_FLAG_MODRM_REG_GROUP_7), - op2(lar, Gv, Ew), - op2(lsl, Gv, Ew), - op0(bad), - op0(syscall), - op0(clts), - op0(sysret), - op0(invd), - op0(wbinvd), - op0(bad), - op0(ud2), - op0(bad), - op0f(modrm_group_p, X86_INSN_FLAG_MODRM_REG_GROUP_p), - op0(femms), - op0(escape_3dnow), - - /* 0x10 */ - op2f(movups, X86_INSN_FLAG_SSE_GROUP_10, Gx, Ex), - op2f(movups, X86_INSN_FLAG_SSE_GROUP_10, Ex, Gx), - op2f(movlps, X86_INSN_FLAG_SSE_GROUP_10, Ex, Gx), - op2f(movlps, X86_INSN_FLAG_SSE_GROUP_10, Gx, Ex), - op2f(unpcklps, X86_INSN_FLAG_SSE_GROUP_10, Gx, Ex), - op2f(unpckhps, X86_INSN_FLAG_SSE_GROUP_10, Gx, Ex), - op2f(movhps, X86_INSN_FLAG_SSE_GROUP_10, Ex, Gx), - op2f(movhps, X86_INSN_FLAG_SSE_GROUP_10, Gx, Ex), - op0f(modrm_group_16, X86_INSN_FLAG_MODRM_REG_GROUP_16), - op0(nop), - op0(nop), - op0(nop), - op0(nop), - op0(nop), - op0(nop), - op0(nop), - - /* 0x20 */ - op2(mov, Rv, Cv), - op2(mov, Rv, Dv), - op2(mov, Cv, Rv), - op2(mov, Dv, Rv), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op2f(movaps, X86_INSN_FLAG_SSE_GROUP_28, Gx, Ex), - op2f(movaps, X86_INSN_FLAG_SSE_GROUP_28, Ex, Gx), - op2f(cvtpi2ps, X86_INSN_FLAG_SSE_GROUP_28, Gx, Ex), - op2f(movntps, X86_INSN_FLAG_SSE_GROUP_28, Mx, Gx), - op2f(cvttps2pi, X86_INSN_FLAG_SSE_GROUP_28, Gx, Ex), - op2f(cvtps2pi, X86_INSN_FLAG_SSE_GROUP_28, Gx, Ex), - op2f(ucomiss, X86_INSN_FLAG_SSE_GROUP_28, Gx, Ex), - op2f(comiss, X86_INSN_FLAG_SSE_GROUP_28, Gx, Ex), - - /* 0x30 */ - op0(wrmsr), - op0(rdtsc), - op0(rdmsr), - op0(rdpmc), - op0(sysenter), - op0(sysexit), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - -/* 0x40 */ -#define _(x) op2(cmov##x, Gv, Ev), - foreach_x86_condition -#undef _ - - /* 0x50 */ - op2f(movmskps, X86_INSN_FLAG_SSE_GROUP_50, Gd, Rx), - op2f(sqrtps, X86_INSN_FLAG_SSE_GROUP_50, Gx, Ex), - op2f(rsqrtps, X86_INSN_FLAG_SSE_GROUP_50, Gx, Ex), - op2f(rcpps, X86_INSN_FLAG_SSE_GROUP_50, Gx, Ex), - op2f(andps, X86_INSN_FLAG_SSE_GROUP_50, Gx, Ex), - op2f(andnps, X86_INSN_FLAG_SSE_GROUP_50, Gx, Ex), - op2f(orps, X86_INSN_FLAG_SSE_GROUP_50, Gx, Ex), - op2f(xorps, X86_INSN_FLAG_SSE_GROUP_50, Gx, Ex), - op2f(addps, X86_INSN_FLAG_SSE_GROUP_58, Gx, Ex), - op2f(mulps, X86_INSN_FLAG_SSE_GROUP_58, Gx, Ex), - op2f(cvtps2pd, X86_INSN_FLAG_SSE_GROUP_58, Gx, Ex), - op2f(cvtdq2ps, X86_INSN_FLAG_SSE_GROUP_58, Gx, Ex), - op2f(subps, X86_INSN_FLAG_SSE_GROUP_58, Gx, Ex), - op2f(minps, X86_INSN_FLAG_SSE_GROUP_58, Gx, Ex), - op2f(divps, X86_INSN_FLAG_SSE_GROUP_58, Gx, Ex), - op2f(maxps, X86_INSN_FLAG_SSE_GROUP_58, Gx, Ex), - - /* 0x60 */ - op2f(punpcklbw, X86_INSN_FLAG_SSE_GROUP_60, Gm, Em), - op2f(punpcklwd, X86_INSN_FLAG_SSE_GROUP_60, Gm, Em), - op2f(punpckldq, X86_INSN_FLAG_SSE_GROUP_60, Gm, Em), - op2f(packsswb, X86_INSN_FLAG_SSE_GROUP_60, Gm, Em), - op2f(pcmpgtb, X86_INSN_FLAG_SSE_GROUP_60, Gm, Em), - op2f(pcmpgtw, X86_INSN_FLAG_SSE_GROUP_60, Gm, Em), - op2f(pcmpgtd, X86_INSN_FLAG_SSE_GROUP_60, Gm, Em), - op2f(packuswb, X86_INSN_FLAG_SSE_GROUP_60, Gm, Em), - op2f(punpckhbw, X86_INSN_FLAG_SSE_GROUP_68, Gm, Em), - op2f(punpckhwd, X86_INSN_FLAG_SSE_GROUP_68, Gm, Em), - op2f(punpckhdq, X86_INSN_FLAG_SSE_GROUP_68, Gm, Em), - op2f(packssdw, X86_INSN_FLAG_SSE_GROUP_68, Gm, Em), - op0f(bad, X86_INSN_FLAG_SSE_GROUP_68), - op0f(bad, X86_INSN_FLAG_SSE_GROUP_68), - op2f(movd, X86_INSN_FLAG_SSE_GROUP_68, Gm, Em), - op2f(movq, X86_INSN_FLAG_SSE_GROUP_68, Gm, Em), - - /* 0x70 */ - op3f(pshufw, X86_INSN_FLAG_SSE_GROUP_70, Gm, Em, Ib), - op0f(modrm_group_12, X86_INSN_FLAG_MODRM_REG_GROUP_12), - op0f(modrm_group_13, X86_INSN_FLAG_MODRM_REG_GROUP_13), - op0f(modrm_group_14, X86_INSN_FLAG_MODRM_REG_GROUP_14), - op2f(pcmpeqb, X86_INSN_FLAG_SSE_GROUP_70, Gm, Em), - op2f(pcmpeqw, X86_INSN_FLAG_SSE_GROUP_70, Gm, Em), - op2f(pcmpeqd, X86_INSN_FLAG_SSE_GROUP_70, Gm, Em), - op0f(emms, X86_INSN_FLAG_SSE_GROUP_70), - op0f(bad, X86_INSN_FLAG_SSE_GROUP_78), - op0f(bad, X86_INSN_FLAG_SSE_GROUP_78), - op0f(bad, X86_INSN_FLAG_SSE_GROUP_78), - op0f(bad, X86_INSN_FLAG_SSE_GROUP_78), - op0f(bad, X86_INSN_FLAG_SSE_GROUP_78), - op0f(bad, X86_INSN_FLAG_SSE_GROUP_78), - op2f(movd, X86_INSN_FLAG_SSE_GROUP_78, Em, Gm), - op2f(movq, X86_INSN_FLAG_SSE_GROUP_78, Em, Gm), - -/* 0x80 */ -#define _(x) op1(jmp##x, Jz), - foreach_x86_condition -#undef _ - -/* 0x90 */ -#define _(x) op1(set##x, Eb), - foreach_x86_condition -#undef _ - - /* 0xa0 */ - op0(push_fs), - op0(pop_fs), - op0(cpuid), - op2(bt, Ev, Gv), - op3(shld, Ev, Gv, Ib), - op3(shld, Ev, Gv, CL), - op0(bad), - op0(bad), - op0(push_gs), - op0(pop_gs), - op0(rsm), - op2(bts, Ev, Gv), - op3(shrd, Ev, Gv, Ib), - op3(shrd, Ev, Gv, CL), - op0f(modrm_group_15, X86_INSN_FLAG_MODRM_REG_GROUP_15), - op2(imul, Gv, Ev), - - /* 0xb0 */ - op2(cmpxchg, Eb, Gb), - op2(cmpxchg, Ev, Gv), - op2(lss, Gz, Mp), - op2(btr, Ev, Gv), - op2(lfs, Gz, Mp), - op2(lgs, Gz, Mp), - op2(movzbl, Gv, Eb), - op2(movzwl, Gv, Ew), - op0(bad), - op0f(modrm_group_10, X86_INSN_FLAG_MODRM_REG_GROUP_10), - op2f(modrm_group_8, X86_INSN_FLAG_MODRM_REG_GROUP_8, Ev, Ib), - op2(btc, Ev, Gv), - op2(bsf, Gv, Ev), - op2(bsr, Gv, Ev), - op2(movsx, Gv, Eb), - op2(movsx, Gv, Ew), - - /* 0xc0 */ - op2(xadd, Eb, Gb), - op2(xadd, Ev, Gv), - op3f(cmpps, X86_INSN_FLAG_SSE_GROUP_c0, Gx, Ex, Ib), - op2(movnti, Mv, Gv), - op3f(pinsrw, X86_INSN_FLAG_SSE_GROUP_c0, Gm, Ew, Ib), - op3f(pextrw, X86_INSN_FLAG_SSE_GROUP_c0, Gd, Rm, Ib), - op3f(shufps, X86_INSN_FLAG_SSE_GROUP_c0, Gx, Ex, Ib), - op1f(modrm_group_9, X86_INSN_FLAG_MODRM_REG_GROUP_9, Mx), -#define _(r) op1(bswap, r), - foreach_x86_gp_reg -#undef _ - - /* 0xd0 */ - op0f(bad, X86_INSN_FLAG_SSE_GROUP_d0), - op2f(psrlw, X86_INSN_FLAG_SSE_GROUP_d0, Gm, Em), - op2f(psrld, X86_INSN_FLAG_SSE_GROUP_d0, Gm, Em), - op2f(psrlq, X86_INSN_FLAG_SSE_GROUP_d0, Gm, Em), - op2f(paddq, X86_INSN_FLAG_SSE_GROUP_d0, Gm, Em), - op2f(pmullw, X86_INSN_FLAG_SSE_GROUP_d0, Gm, Em), - op0f(bad, X86_INSN_FLAG_SSE_GROUP_d0), - op2f(pmovmskb, X86_INSN_FLAG_SSE_GROUP_d0, Gd, Rm), - op2f(psubusb, X86_INSN_FLAG_SSE_GROUP_d8, Gm, Em), - op2f(psubusw, X86_INSN_FLAG_SSE_GROUP_d8, Gm, Em), - op2f(pminub, X86_INSN_FLAG_SSE_GROUP_d8, Gm, Em), - op2f(pand, X86_INSN_FLAG_SSE_GROUP_d8, Gm, Em), - op2f(paddusb, X86_INSN_FLAG_SSE_GROUP_d8, Gm, Em), - op2f(paddusw, X86_INSN_FLAG_SSE_GROUP_d8, Gm, Em), - op2f(pmaxub, X86_INSN_FLAG_SSE_GROUP_d8, Gm, Em), - op2f(pandn, X86_INSN_FLAG_SSE_GROUP_d8, Gm, Em), - - /* 0xe0 */ - op2f(pavgb, X86_INSN_FLAG_SSE_GROUP_e0, Gm, Em), - op2f(psraw, X86_INSN_FLAG_SSE_GROUP_e0, Gm, Em), - op2f(psrad, X86_INSN_FLAG_SSE_GROUP_e0, Gm, Em), - op2f(pavgw, X86_INSN_FLAG_SSE_GROUP_e0, Gm, Em), - op2f(pmulhuw, X86_INSN_FLAG_SSE_GROUP_e0, Gm, Em), - op2f(pmulhw, X86_INSN_FLAG_SSE_GROUP_e0, Gm, Em), - op2f(bad, X86_INSN_FLAG_SSE_GROUP_e0, Gm, Em), - op2f(movntq, X86_INSN_FLAG_SSE_GROUP_e0, Mm, Gm), - op2f(psubsb, X86_INSN_FLAG_SSE_GROUP_e8, Gm, Em), - op2f(psubsw, X86_INSN_FLAG_SSE_GROUP_e8, Gm, Em), - op2f(pminsw, X86_INSN_FLAG_SSE_GROUP_e8, Gm, Em), - op2f(por, X86_INSN_FLAG_SSE_GROUP_e8, Gm, Em), - op2f(paddsb, X86_INSN_FLAG_SSE_GROUP_e8, Gm, Em), - op2f(paddsw, X86_INSN_FLAG_SSE_GROUP_e8, Gm, Em), - op2f(pmaxsw, X86_INSN_FLAG_SSE_GROUP_e8, Gm, Em), - op2f(pxor, X86_INSN_FLAG_SSE_GROUP_e8, Gm, Em), - - /* 0xf0 */ - op0f(bad, X86_INSN_FLAG_SSE_GROUP_f0), - op2f(psllw, X86_INSN_FLAG_SSE_GROUP_f0, Gm, Em), - op2f(pslld, X86_INSN_FLAG_SSE_GROUP_f0, Gm, Em), - op2f(psllq, X86_INSN_FLAG_SSE_GROUP_f0, Gm, Em), - op2f(pmuludq, X86_INSN_FLAG_SSE_GROUP_f0, Gm, Em), - op2f(pmaddwd, X86_INSN_FLAG_SSE_GROUP_f0, Gm, Em), - op2f(psadbw, X86_INSN_FLAG_SSE_GROUP_f0, Gm, Em), - op2f(maskmovq, X86_INSN_FLAG_SSE_GROUP_f0, Gm, Em), - op2f(psubb, X86_INSN_FLAG_SSE_GROUP_f8, Gm, Em), - op2f(psubw, X86_INSN_FLAG_SSE_GROUP_f8, Gm, Em), - op2f(psubd, X86_INSN_FLAG_SSE_GROUP_f8, Gm, Em), - op2f(psubq, X86_INSN_FLAG_SSE_GROUP_f8, Gm, Em), - op2f(paddb, X86_INSN_FLAG_SSE_GROUP_f8, Gm, Em), - op2f(paddw, X86_INSN_FLAG_SSE_GROUP_f8, Gm, Em), - op2f(paddd, X86_INSN_FLAG_SSE_GROUP_f8, Gm, Em), - op0f(bad, X86_INSN_FLAG_SSE_GROUP_f8), -}; - -// clang-format on \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InterceptEntry.cpp b/app/src/main/cpp/Dobby/source/InterceptEntry.cpp deleted file mode 100644 index cf7184b..0000000 --- a/app/src/main/cpp/Dobby/source/InterceptEntry.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "InterceptEntry.h" -#include "Interceptor.h" - -InterceptEntry::InterceptEntry(InterceptEntryType type, addr_t address) { - this->type = type; - -#if defined(TARGET_ARCH_ARM) - if (address % 2) { - address -= 1; - this->thumb_mode = true; - } else { - this->thumb_mode = false; - } -#endif - - this->patched_addr = address; - this->id = Interceptor::SharedInstance()->count(); -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InterceptEntry.h b/app/src/main/cpp/Dobby/source/InterceptEntry.h deleted file mode 100644 index 0fff858..0000000 --- a/app/src/main/cpp/Dobby/source/InterceptEntry.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include -#include "common_header.h" - -typedef enum { kFunctionInlineHook, kInstructionInstrument } InterceptEntryType; - -class InterceptRouting; - -typedef struct InterceptEntry { - uint32_t id; - InterceptEntryType type; - InterceptRouting *routing; - - union { - addr_t addr; - addr_t patched_addr; - }; - uint32_t patched_size; - - addr_t relocated_addr; - uint32_t relocated_size; - - uint8_t origin_insns[256]; - uint32_t origin_insn_size; - - bool thumb_mode; - - InterceptEntry(InterceptEntryType type, addr_t address); -} InterceptEntry; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/InterceptRouting.cpp b/app/src/main/cpp/Dobby/source/InterceptRouting/InterceptRouting.cpp deleted file mode 100644 index b2e7b6d..0000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/InterceptRouting.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include "dobby_internal.h" - -#include "InterceptRouting/InterceptRouting.h" -#include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" - -using namespace zz; - -void log_hex_format(uint8_t *buffer, uint32_t buffer_size) { - char output[1024] = {0}; - for (int i = 0; i < buffer_size && i < sizeof(output); i++) { - snprintf(output + strlen(output), 3, "%02x ", *((uint8_t *)buffer + i)); - } - DLOG(0, "%s", output); -}; - -void InterceptRouting::Prepare() { -} - -// generate relocated code -bool InterceptRouting::GenerateRelocatedCode() { - uint32_t tramp_size = GetTrampolineBuffer()->GetBufferSize(); - origin_ = new CodeMemBlock(entry_->patched_addr, tramp_size); - relocated_ = new CodeMemBlock(); - - auto buffer = (void *)entry_->patched_addr; -#if defined(TARGET_ARCH_ARM) - if (entry_->thumb_mode) { - buffer = (void *)((addr_t)buffer + 1); - } -#endif - GenRelocateCodeAndBranch(buffer, origin_, relocated_); - if (relocated_->size == 0) { - ERROR_LOG("[insn relocate]] failed"); - return false; - } - - // set the relocated instruction address - entry_->relocated_addr = relocated_->addr; - - // save original prologue - memcpy((void *)entry_->origin_insns, (void *)origin_->addr, origin_->size); - entry_->origin_insn_size = origin_->size; - - // log - DLOG(0, "[insn relocate] origin %p - %d", origin_->addr, origin_->size); - log_hex_format((uint8_t *)origin_->addr, origin_->size); - - DLOG(0, "[insn relocate] relocated %p - %d", relocated_->addr, relocated_->size); - log_hex_format((uint8_t *)relocated_->addr, relocated_->size); - - return true; -} - -bool InterceptRouting::GenerateTrampolineBuffer(addr_t src, addr_t dst) { - // if near branch trampoline plugin enabled - if (RoutingPluginManager::near_branch_trampoline) { - auto plugin = static_cast(RoutingPluginManager::near_branch_trampoline); - if (plugin->GenerateTrampolineBuffer(this, src, dst) == false) { - DLOG(0, "Failed enable near branch trampoline plugin"); - } - } - - if (GetTrampolineBuffer() == nullptr) { - auto tramp_buffer = GenerateNormalTrampolineBuffer(src, dst); - SetTrampolineBuffer(tramp_buffer); - } - return true; -} - -// active routing, patch origin instructions as trampoline -void InterceptRouting::Active() { - MemoryOperationError err; - err = DobbyCodePatch((void *)entry_->patched_addr, trampoline_buffer_->GetBuffer(), - trampoline_buffer_->GetBufferSize()); - if (err != kMemoryOperationSuccess) { - ERROR_LOG("[intercept routing] active failed"); - return; - } - DLOG(0, "[intercept routing] active"); -} - -void InterceptRouting::Commit() { - this->Active(); -} - -#if 0 -int InterceptRouting::PredefinedTrampolineSize() { -#if __arm64__ - return 12; -#elif __arm__ - return 8; -#endif -} -#endif - -InterceptEntry *InterceptRouting::GetInterceptEntry() { - return entry_; -}; diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/InterceptRouting.h b/app/src/main/cpp/Dobby/source/InterceptRouting/InterceptRouting.h deleted file mode 100644 index e21ca32..0000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/InterceptRouting.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include "InterceptEntry.h" -#include "MemoryAllocator/AssemblyCodeBuilder.h" -#include "InstructionRelocation/InstructionRelocation.h" -#include "TrampolineBridge/Trampoline/Trampoline.h" - -class InterceptRouting { -public: - explicit InterceptRouting(InterceptEntry *entry) : entry_(entry) { - entry->routing = this; - - origin_ = nullptr; - relocated_ = nullptr; - - trampoline_ = nullptr; - trampoline_buffer_ = nullptr; - trampoline_target_ = 0; - } - - virtual void DispatchRouting() = 0; - - virtual void Prepare(); - - virtual void Active(); - - void Commit(); - - InterceptEntry *GetInterceptEntry(); - - void SetTrampolineBuffer(CodeBufferBase *buffer) { - trampoline_buffer_ = buffer; - } - - CodeBufferBase *GetTrampolineBuffer() { - return trampoline_buffer_; - } - - void SetTrampolineTarget(addr_t address) { - trampoline_target_ = address; - } - - addr_t GetTrampolineTarget() { - return trampoline_target_; - } - -protected: - bool GenerateRelocatedCode(); - - bool GenerateTrampolineBuffer(addr_t src, addr_t dst); - -protected: - InterceptEntry *entry_; - - CodeMemBlock *origin_; - CodeMemBlock *relocated_; - - CodeMemBlock *trampoline_; - // trampoline buffer before active - CodeBufferBase *trampoline_buffer_; - addr_t trampoline_target_; -}; diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineHook/FunctionInlineHook.cc b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineHook/FunctionInlineHook.cc deleted file mode 100644 index e85fb92..0000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineHook/FunctionInlineHook.cc +++ /dev/null @@ -1,51 +0,0 @@ -#include "dobby_internal.h" - -#include "Interceptor.h" -#include "InterceptRouting/Routing/FunctionInlineHook/FunctionInlineHookRouting.h" - -PUBLIC int DobbyHook(void *address, dobby_dummy_func_t replace_func, dobby_dummy_func_t *origin_func) { - if (!address) { - ERROR_LOG("function address is 0x0"); - return RS_FAILED; - } - -#if defined(__APPLE__) && defined(__arm64__) -#if __has_feature(ptrauth_calls) - address = ptrauth_strip(address, ptrauth_key_asia); - replace_func = ptrauth_strip(replace_func, ptrauth_key_asia); -#endif -#endif - -#if defined(ANDROID) - void *page_align_address = (void *)ALIGN_FLOOR(address, OSMemory::PageSize()); - if (!OSMemory::SetPermission(page_align_address, OSMemory::PageSize(), kReadExecute)) { - return RS_FAILED; - } -#endif - - DLOG(0, "----- [DobbyHook:%p] -----", address); - - // check if already register - auto entry = Interceptor::SharedInstance()->find((addr_t)address); - if (entry) { - ERROR_LOG("%p already been hooked.", address); - return RS_FAILED; - } - - entry = new InterceptEntry(kFunctionInlineHook, (addr_t)address); - - auto *routing = new FunctionInlineHookRouting(entry, replace_func); - routing->Prepare(); - routing->DispatchRouting(); - - // set origin func entry with as relocated instructions - if (origin_func) { - *origin_func = (dobby_dummy_func_t)entry->relocated_addr; - } - - routing->Commit(); - - Interceptor::SharedInstance()->add(entry); - - return RS_SUCCESS; -} diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineHook/FunctionInlineHookRouting.h b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineHook/FunctionInlineHookRouting.h deleted file mode 100644 index d308ace..0000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineHook/FunctionInlineHookRouting.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include "dobby_internal.h" - -#include "InterceptRouting/InterceptRouting.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" - -class FunctionInlineHookRouting : public InterceptRouting { -public: - FunctionInlineHookRouting(InterceptEntry *entry, dobby_dummy_func_t replace_func) : InterceptRouting(entry) { - this->replace_func = replace_func; - } - - void DispatchRouting() override; - -private: - void BuildRouting(); - -private: - dobby_dummy_func_t replace_func; -}; diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineHook/RoutingImpl.cc b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineHook/RoutingImpl.cc deleted file mode 100644 index 015c946..0000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineHook/RoutingImpl.cc +++ /dev/null @@ -1,22 +0,0 @@ -#include "dobby_internal.h" -#include "InterceptRouting/Routing/FunctionInlineHook/FunctionInlineHookRouting.h" - -void FunctionInlineHookRouting::BuildRouting() { - SetTrampolineTarget((addr_t)replace_func); - - // generate trampoline buffer, run before GenerateRelocatedCode - addr_t from = entry_->patched_addr; -#if defined(TARGET_ARCH_ARM) - if (entry_->thumb_mode) - from += 1; -#endif - addr_t to = GetTrampolineTarget(); - GenerateTrampolineBuffer(from, to); -} - -void FunctionInlineHookRouting::DispatchRouting() { - BuildRouting(); - - // generate relocated code which size == trampoline size - GenerateRelocatedCode(); -} diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/FunctionWrapperExport.cc b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/FunctionWrapperExport.cc deleted file mode 100644 index 18a6645..0000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/FunctionWrapperExport.cc +++ /dev/null @@ -1,27 +0,0 @@ -#include "dobby_internal.h" - -#include "logging/logging.h" - -#include "Interceptor.h" -#include "InterceptRouting/InterceptRouting.h" - -#include "function-wrapper.h" - -PUBLIC int DobbyWrap(void *function_address, PreCallTy pre_call, PostCallTy post_call) { - DLOG(0, "Initialize 'DobbyWrap' hook at %p", function_address); - - Interceptor *interceptor = Interceptor::SharedInstance(); - - InterceptEntry *entry = new InterceptEntry(); - entry->id = interceptor->entries->getCount(); - entry->type = kFunctionWrapper; - entry->function_address = function_address; - - FunctionWrapperRouting *routing = new FunctionWrapperRouting(entry); - routing->DispatchRouting(); - interceptor->addHookEntry(entry); - routing->Commit(); - - DLOG(0, "Finalize %p", function_address); - return RS_SUCCESS; -} diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/function-wrapper.cc b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/function-wrapper.cc deleted file mode 100644 index 354beeb..0000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/function-wrapper.cc +++ /dev/null @@ -1,38 +0,0 @@ -#include "dobby_internal.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" - -#include "intercept_routing_handler.h" - -#include "function-wrapper.h" - -void FunctionWrapperRouting::DispatchRouting() { - Prepare(); - BuildPreCallRouting(); - BuildPostCallRouting(); -} - -// Add pre_call(prologue) handler before running the origin function, -void FunctionWrapperRouting::BuildPreCallRouting() { - // create closure trampoline jump to prologue_routing_dispath with the `entry_` data - ClosureTrampolineEntry *cte = ClosureTrampoline::CreateClosureTrampoline(entry_, (void *)prologue_routing_dispatch); - this->prologue_dispatch_bridge = cte->address; - - DLOG(0, "Create pre call closure trampoline to 'prologue_routing_dispatch' at %p", cte->address); -} - -// Add post_call(epilogue) handler before `Return` of the origin function, as implementation is replace the origin -// `Return Address` of the function. -void FunctionWrapperRouting::BuildPostCallRouting() { - // create closure trampoline jump to prologue_routing_dispath with the `entry_` data - ClosureTrampolineEntry *closure_trampoline_entry; - // format trampoline - closure_trampoline_entry = ClosureTrampoline::CreateClosureTrampoline(entry_, (void *)epilogue_routing_dispatch); - DLOG(0, "Create post call closure trampoline to 'prologue_routing_dispatch' at %p", - closure_trampoline_entry->address); - - this->SetTrampolineTarget(closure_trampoline_entry->address); - this->epilogue_dispatch_bridge = closure_trampoline_entry->address; - - GenerateTrampolineBuffer(entry_->target_address, GetTrampolineTarget()); -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/function-wrapper.h b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/function-wrapper.h deleted file mode 100644 index 38903ef..0000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/function-wrapper.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef FUNCTION_WRAPPER_H -#define FUNCTION_WRAPPER_H - -#include "dobby_internal.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" -#include "InterceptRouting/InterceptRouting.h" -#include "Interceptor.h" - -#if TARGET_ARCH_IA32 -#elif TARGET_ARCH_X64 -#include "InterceptRouting/x64/X64InterceptRouting.h" -#elif TARGET_ARCH_ARM64 -#include "InterceptRouting/arm64/ARM64InterceptRouting.h" -#elif TARGET_ARCH_ARM -#else -#error "unsupported architecture" -#endif - -class FunctionWrapperRouting : public InterceptRouting { -public: - FunctionWrapperRouting(InterceptEntry *entry) : InterceptRouting(entry) { - } - - void DispatchRouting(); - - void *GetTrampolineTarget(); - -private: - void BuildPreCallRouting(); - - void BuildPostCallRouting(); - -private: - void *prologue_dispatch_bridge; - - void *epilogue_dispatch_bridge; -}; - -#endif diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/intercept_routing_handler.cc b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/intercept_routing_handler.cc deleted file mode 100644 index 85dbd12..0000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/intercept_routing_handler.cc +++ /dev/null @@ -1,79 +0,0 @@ - -#include "dobby_internal.h" - -#include "logging/logging.h" - -#include "intercept_routing_handler.h" - -#include "function-wrapper.h" -#include "intercept_routing_handler.h" - -#include "MultiThreadSupport/ThreadSupport.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h" - -void pre_call_forward_handler(DobbyRegisterContext *ctx, InterceptEntry *entry) { - FunctionWrapperRouting *routing = (FunctionWrapperRouting *)entry->routing; - - StackFrame *stackframe = new StackFrame(); - // create stack frame as common variable between pre_call and post_call - ThreadSupport::PushStackFrame(stackframe); - - // run the `pre_call` before execute origin function which has been relocated(fixed) - if (routing->pre_call) { - PreCallTy pre_call; - InterceptEntry entry; - entry.hook_id = entry->id; - entry.target_address = entry->target_address; - pre_call = routing->pre_call; - // run the pre_call with the power of accessing all registers - (*pre_call)(ctx, (const InterceptEntry *)&entry); - } - - // save the origin ret address, and use in `post_call_forword_handler` - stackframe->orig_ret = get_func_ret_address(ctx); - - // set the prologue bridge next hop address with the patched instructions has been relocated - set_routing_bridge_next_hop(ctx, entry->relocated_origin_function); - - // replace the function ret address with our epilogue_routing_dispatch - set_func_ret_address(ctx, entry->epilogue_dispatch_bridge); -} - -void post_call_forward_handler(DobbyRegisterContext *ctx, InterceptEntry *entry) { - FunctionWrapperRouting *routing = (FunctionWrapperRouting *)entry->routing; - - // pop stack frame as common variable between pre_call and post_call - StackFrame *stackframe = ThreadSupport::PopStackFrame(); - - // run the `post_call`, and access all the register value, as the origin function done, - if (routing->post_call) { - PostCallTy post_call; - InterceptEntry entry; - entry.hook_id = entry->id; - entry.target_address = entry->target_address; - post_call = routing->post_call; - - // run the post_call with the power of accessing all registers - (*post_call)(ctx, (const InterceptEntry *)&entry); - } - - // set epilogue bridge next hop address with origin ret address, restore the call. - set_routing_bridge_next_hop(ctx, stackframe->orig_ret); -} - -// run the user handler **before run the origin-instructions(which have been relocated)** -void prologue_routing_dispatch(DobbyRegisterContext *ctx, ClosureTrampolineEntry *closure_trampoline_entry) { - DLOG(0, "Catch prologue dispatch"); - InterceptEntry *entry = static_cast(closure_trampoline_entry->carry_data); - pre_call_forward_handler(ctx, entry); - return; -} - -// run the user handler **before the function return** by replace the lr register -void epilogue_routing_dispatch(DobbyRegisterContext *ctx, ClosureTrampolineEntry *closure_trampoline_entry) { - DLOG(0, "Catch epilogue dispatch"); - InterceptEntry *entry = static_cast(closure_trampoline_entry->carry_data); - post_call_forward_handler(ctx, entry); - return; -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/intercept_routing_handler.h b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/intercept_routing_handler.h deleted file mode 100644 index a7cbc48..0000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/intercept_routing_handler.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef FUNCTION_WRAPPER_INTERCEPT_ROUTING_HANDLER_H -#define FUNCTION_WRAPPER_INTERCEPT_ROUTING_HANDLER_H - -#include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" -#include "Interceptor.h" -#include "dobby_internal.h" - -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus - -// Dispatch the routing befor running the origin function -void prologue_routing_dispatch(DobbyRegisterContext *ctx, ClosureTrampolineEntry *entry); - -// Dispatch the routing before the function return . (as it's implementation by relpace `return address` in the stack -// ,or LR register) -void epilogue_routing_dispatch(DobbyRegisterContext *ctx, ClosureTrampolineEntry *entry); - -void pre_call_forward_handler(DobbyRegisterContext *ctx, InterceptEntry *entry); - -void post_call_forward_handler(DobbyRegisterContext *ctx, InterceptEntry *entry); - -#ifdef __cplusplus -} -#endif //__cplusplus - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/InstructionInstrument.cc b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/InstructionInstrument.cc deleted file mode 100644 index d96ed84..0000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/InstructionInstrument.cc +++ /dev/null @@ -1,44 +0,0 @@ -#include "dobby_internal.h" - -#include "Interceptor.h" -#include "InterceptRouting/InterceptRouting.h" -#include "InterceptRouting/Routing/InstructionInstrument/InstructionInstrumentRouting.h" - -PUBLIC int DobbyInstrument(void *address, dobby_instrument_callback_t pre_handler) { - if (!address) { - ERROR_LOG("address is 0x0.\n"); - return RS_FAILED; - } - -#if defined(__APPLE__) && defined(__arm64__) -#if __has_feature(ptrauth_calls) - address = ptrauth_strip(address, ptrauth_key_asia); -#endif -#endif - -#if defined(ANDROID) - void *page_align_address = (void *)ALIGN_FLOOR(address, OSMemory::PageSize()); - if (!OSMemory::SetPermission(page_align_address, OSMemory::PageSize(), kReadExecute)) { - return RS_FAILED; - } -#endif - - DLOG(0, "\n\n----- [DobbyInstrument:%p] -----", address); - - auto entry = Interceptor::SharedInstance()->find((addr_t)address); - if (entry) { - ERROR_LOG("%s already been instrumented.", address); - return RS_FAILED; - } - - entry = new InterceptEntry(kInstructionInstrument, (addr_t)address); - - auto routing = new InstructionInstrumentRouting(entry, pre_handler, nullptr); - routing->Prepare(); - routing->DispatchRouting(); - routing->Commit(); - - Interceptor::SharedInstance()->add(entry); - - return RS_SUCCESS; -} diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/InstructionInstrumentRouting.h b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/InstructionInstrumentRouting.h deleted file mode 100644 index e4eed62..0000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/InstructionInstrumentRouting.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "dobby_internal.h" - -#include "InterceptRouting/InterceptRouting.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" - -class InstructionInstrumentRouting : public InterceptRouting { -public: - InstructionInstrumentRouting(InterceptEntry *entry, dobby_instrument_callback_t pre_handler, - dobby_instrument_callback_t post_handler) - : InterceptRouting(entry) { - this->prologue_dispatch_bridge = nullptr; - this->pre_handler = pre_handler; - this->post_handler = post_handler; - } - - void DispatchRouting() override; - -private: - void BuildRouting(); - -public: - dobby_instrument_callback_t pre_handler; - dobby_instrument_callback_t post_handler; - -private: - void *prologue_dispatch_bridge; -}; diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/RoutingImpl.cc b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/RoutingImpl.cc deleted file mode 100644 index 1631431..0000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/RoutingImpl.cc +++ /dev/null @@ -1,42 +0,0 @@ - -#include "dobby_internal.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" - -#include "InterceptRouting/Routing/InstructionInstrument/InstructionInstrumentRouting.h" -#include "InterceptRouting/Routing/InstructionInstrument/instrument_routing_handler.h" - -// create closure trampoline jump to prologue_routing_dispatch with the `entry_` data -void InstructionInstrumentRouting::BuildRouting() { - void *handler = (void *)instrument_routing_dispatch; -#if defined(__APPLE__) && defined(__arm64__) -#if __has_feature(ptrauth_calls) - handler = ptrauth_strip(handler, ptrauth_key_asia); -#endif -#endif - auto closure_trampoline = ClosureTrampoline::CreateClosureTrampoline(entry_, handler); - this->SetTrampolineTarget((addr_t)closure_trampoline->address); - DLOG(0, "[closure trampoline] closure trampoline: %p, data: %p", closure_trampoline->address, entry_); - - // generate trampoline buffer, before `GenerateRelocatedCode` - addr_t from = entry_->patched_addr; -#if defined(TARGET_ARCH_ARM) - if (entry_->thumb_mode) - from += 1; -#endif - addr_t to = GetTrampolineTarget(); - GenerateTrampolineBuffer(from, to); -} - -void InstructionInstrumentRouting::DispatchRouting() { - BuildRouting(); - - // generate relocated code which size == trampoline size - GenerateRelocatedCode(); -} - -#if 0 -void *InstructionInstrumentRouting::GetTrampolineTarget() { - return this->prologue_dispatch_bridge; -} -#endif diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/instrument_routing_handler.cc b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/instrument_routing_handler.cc deleted file mode 100644 index baaa0cf..0000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/instrument_routing_handler.cc +++ /dev/null @@ -1,21 +0,0 @@ -#include "dobby_internal.h" - -#include "InterceptRouting/Routing/InstructionInstrument/InstructionInstrumentRouting.h" -#include "InterceptRouting/Routing/InstructionInstrument/instrument_routing_handler.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h" - -void instrument_forward_handler(InterceptEntry *entry, DobbyRegisterContext *ctx) { - auto routing = static_cast(entry->routing); - if (routing->pre_handler) { - auto handler = (dobby_instrument_callback_t)routing->pre_handler; - (*handler)((void *)entry->patched_addr, ctx); - } - - // set prologue bridge next hop address as relocated instructions - set_routing_bridge_next_hop(ctx, (void *)entry->relocated_addr); -} - -void instrument_routing_dispatch(InterceptEntry *entry, DobbyRegisterContext *ctx) { - instrument_forward_handler(entry, ctx); -} diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/instrument_routing_handler.h b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/instrument_routing_handler.h deleted file mode 100644 index 553f1eb..0000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/instrument_routing_handler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "dobby_internal.h" - -extern "C" { -void instrument_routing_dispatch(InterceptEntry *entry, DobbyRegisterContext *ctx); -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.cc b/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.cc deleted file mode 100644 index 951a8ec..0000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.cc +++ /dev/null @@ -1,47 +0,0 @@ -#include "InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.h" - -#include "dobby_internal.h" - -#include "MemoryAllocator/NearMemoryAllocator.h" - -#include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" - -using namespace zz; - -PUBLIC void dobby_enable_near_branch_trampoline() { - RoutingPluginInterface *plugin = new NearBranchTrampolinePlugin; - RoutingPluginManager::registerPlugin("near_branch_trampoline", plugin); - RoutingPluginManager::near_branch_trampoline = plugin; -} - -PUBLIC void dobby_disable_near_branch_trampoline() { - NearBranchTrampolinePlugin *plugin = (NearBranchTrampolinePlugin *)RoutingPluginManager::near_branch_trampoline; - delete plugin; - RoutingPluginManager::near_branch_trampoline = NULL; -} - -#if 0 -int NearBranchTrampolinePlugin::PredefinedTrampolineSize() { -#if __arm64__ - return 4; -#elif __arm__ - return 4; -#endif -} -#endif - -extern CodeBufferBase *GenerateNearTrampolineBuffer(InterceptRouting *routing, addr_t from, addr_t to); -bool NearBranchTrampolinePlugin::GenerateTrampolineBuffer(InterceptRouting *routing, addr_t src, addr_t dst) { - CodeBufferBase *trampoline_buffer; - trampoline_buffer = GenerateNearTrampolineBuffer(routing, src, dst); - if (trampoline_buffer == NULL) - return false; - routing->SetTrampolineBuffer(trampoline_buffer); - return true; -} - -// generate trampoline, patch the original entry -bool NearBranchTrampolinePlugin::Active(InterceptRouting *routing) { - InterceptEntry *entry = routing->GetInterceptEntry(); - return true; -} diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.h b/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.h deleted file mode 100644 index 8b8a948..0000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "dobby_internal.h" - -#include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" - -class NearBranchTrampolinePlugin : public RoutingPluginInterface { - bool Prepare(InterceptRouting *routing) { - return false; - }; - - bool Active(InterceptRouting *routing); - - bool GenerateTrampolineBuffer(InterceptRouting *routing, addr_t src, addr_t dst); -}; diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/near_trampoline_arm64.cc b/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/near_trampoline_arm64.cc deleted file mode 100644 index f168889..0000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/near_trampoline_arm64.cc +++ /dev/null @@ -1,82 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_ARM64) - -#include "dobby_internal.h" - -#include "core/assembler/assembler-arm64.h" -#include "core/codegen/codegen-arm64.h" - -#include "MemoryAllocator/NearMemoryAllocator.h" -#include "InstructionRelocation/arm64/InstructionRelocationARM64.h" -#include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" - -using namespace zz::arm64; - -#define ARM64_B_XXX_RANGE ((1 << 25) << 2) // signed - -// If BranchType is B_Branch and the branch_range of `B` is not enough -// build the transfer to forward the b branch -static AssemblyCode *GenerateFastForwardTrampoline(addr_t src, addr_t dst) { - TurboAssembler turbo_assembler_(nullptr); -#define _ turbo_assembler_. - - // [adrp + add + br branch] - auto tramp_size = 3 *4; - auto tramp_mem = NearMemoryAllocator::SharedAllocator()->allocateNearExecMemory(tramp_size, src, ARM64_B_XXX_RANGE); - if (tramp_mem == nullptr) { - ERROR_LOG("search near code block failed"); - return nullptr; - } - - // Use adrp + add branch - uint64_t distance = llabs((int64_t)(tramp_mem - dst)); - uint64_t adrp_range = ((uint64_t)1 << (2 + 19 + 12 - 1)); - if (distance < adrp_range) { - // use adrp + add + br branch == (3 * 4) trampoline size - _ AdrpAdd(TMP_REG_0, (uint64_t)tramp_mem, dst); - _ br(TMP_REG_0); - DLOG(0, "forward trampoline use [adrp, add, br]"); - } else { - // use mov + br == (4 * 5) trampoline size - _ Mov(TMP_REG_0, dst); - _ br(TMP_REG_0); - DLOG(0, "forward trampoline use [mov, br]"); - - auto tramp_size = turbo_assembler_.GetCodeBuffer()->GetBufferSize(); - tramp_mem = - NearMemoryAllocator::SharedAllocator()->allocateNearExecMemory(tramp_size, src, ARM64_B_XXX_RANGE); - if (tramp_mem == nullptr) { - ERROR_LOG("Can't found near code chunk"); - return nullptr; - } - } - - turbo_assembler_.SetRealizedAddress((void *)tramp_mem); - - AssemblyCode *code = nullptr; - code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); - return code; -} - -CodeBufferBase *GenerateNearTrampolineBuffer(InterceptRouting *routing, addr_t src, addr_t dst) { - CodeBufferBase *result = nullptr; - - TurboAssembler turbo_assembler_((void *)src); -#define _ turbo_assembler_. - - // branch to trampoline_target directly - if (llabs((long long)dst - (long long)src) < ARM64_B_XXX_RANGE) { - _ b(dst - src); - } else { - auto fast_forward_trampoline = GenerateFastForwardTrampoline(src, dst); - if (!fast_forward_trampoline) - return nullptr; - _ b(fast_forward_trampoline->addr - src); - } - - // free the original trampoline - result = turbo_assembler_.GetCodeBuffer()->Copy(); - return result; -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/RoutingPlugin.cc b/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/RoutingPlugin.cc deleted file mode 100644 index f945e4e..0000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/RoutingPlugin.cc +++ /dev/null @@ -1,11 +0,0 @@ -#include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" - -std::vector RoutingPluginManager::plugins; - -RoutingPluginInterface *RoutingPluginManager::near_branch_trampoline = NULL; - -void RoutingPluginManager::registerPlugin(const char *name, RoutingPluginInterface *plugin) { - DLOG(0, "register %s plugin", name); - - RoutingPluginManager::plugins.push_back(plugin); -} diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/RoutingPlugin.h b/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/RoutingPlugin.h deleted file mode 100644 index a692c22..0000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/RoutingPlugin.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "dobby_internal.h" - -#include "InterceptRouting/InterceptRouting.h" - -class RoutingPluginInterface { -public: - // @Return: if false will continue to iter next plugin - virtual bool Prepare(InterceptRouting *routing) = 0; - - // @Return: if false will continue to iter next plugin - virtual bool Active(InterceptRouting *routing) = 0; - - // @Return: if false will continue to iter next plugin - virtual bool GenerateTrampolineBuffer(InterceptRouting *routing, addr_t src, addr_t dst) = 0; - -private: - char name_[256]; -}; - -class RoutingPluginManager { -public: - static void registerPlugin(const char *name, RoutingPluginInterface *plugin); - -public: - static std::vector plugins; - - static RoutingPluginInterface *near_branch_trampoline; -}; diff --git a/app/src/main/cpp/Dobby/source/Interceptor.cpp b/app/src/main/cpp/Dobby/source/Interceptor.cpp deleted file mode 100644 index 7cfe113..0000000 --- a/app/src/main/cpp/Dobby/source/Interceptor.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "Interceptor.h" - -Interceptor *Interceptor::instance = nullptr; - -Interceptor *Interceptor::SharedInstance() { - if (Interceptor::instance == nullptr) { - Interceptor::instance = new Interceptor(); - } - return Interceptor::instance; -} - -InterceptEntry *Interceptor::find(addr_t addr) { - for (auto *entry : entries) { - if (entry->patched_addr == addr) { - return entry; - } - } - return nullptr; -} - -void Interceptor::add(InterceptEntry *entry) { - entries.push_back(entry); -} - -void Interceptor::remove(addr_t addr) { - for (auto iter = entries.begin(); iter != entries.end(); iter++) { - if ((*iter)->patched_addr == addr) { - entries.erase(iter); - break; - } - } -} - -const InterceptEntry *Interceptor::getEntry(int i) { - return entries[i]; -} - -int Interceptor::count() { - return entries.size(); -} diff --git a/app/src/main/cpp/Dobby/source/Interceptor.h b/app/src/main/cpp/Dobby/source/Interceptor.h deleted file mode 100644 index 0fa0c3d..0000000 --- a/app/src/main/cpp/Dobby/source/Interceptor.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "dobby_internal.h" -#include "InterceptEntry.h" - -class Interceptor { -public: - static Interceptor *SharedInstance(); - -public: - InterceptEntry *find(addr_t addr); - - void remove(addr_t addr); - - void add(InterceptEntry *entry); - - const InterceptEntry *getEntry(int i); - - int count(); - -private: - static Interceptor *instance; - - tinystl::vector entries; -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/AssemblyCodeBuilder.cc b/app/src/main/cpp/Dobby/source/MemoryAllocator/AssemblyCodeBuilder.cc deleted file mode 100644 index 774411a..0000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/AssemblyCodeBuilder.cc +++ /dev/null @@ -1,34 +0,0 @@ -#include "MemoryAllocator/AssemblyCodeBuilder.h" - -#include "dobby_internal.h" -#include "PlatformUnifiedInterface/ExecMemory/CodePatchTool.h" - -AssemblyCode *AssemblyCodeBuilder::FinalizeFromTurboAssembler(AssemblerBase *assembler) { - auto buffer = (CodeBufferBase *)assembler->GetCodeBuffer(); - auto realized_addr = (addr_t)assembler->GetRealizedAddress(); -#if defined(TEST_WITH_UNICORN) - // impl: unicorn emulator map memory - realized_addr = 0; -#endif - if (!realized_addr) { - size_t buffer_size = 0; - buffer_size = buffer->GetBufferSize(); -#if TARGET_ARCH_ARM - // extra bytes for align needed - buffer_size += 4; -#endif - - auto block = MemoryAllocator::SharedAllocator()->allocateExecBlock(buffer_size); - if (block == nullptr) - return nullptr; - - realized_addr = block->addr; - assembler->SetRealizedAddress((void *)realized_addr); - } - - // Realize the buffer code to the executable memory address, remove the external label, etc - DobbyCodePatch((void *)realized_addr, buffer->GetBuffer(), buffer->GetBufferSize()); - - auto block = new AssemblyCode(realized_addr, buffer->GetBufferSize()); - return block; -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/AssemblyCodeBuilder.h b/app/src/main/cpp/Dobby/source/MemoryAllocator/AssemblyCodeBuilder.h deleted file mode 100644 index d704c56..0000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/AssemblyCodeBuilder.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "PlatformUnifiedInterface/MemoryAllocator.h" - -#include "core/assembler/assembler.h" - -using namespace zz; - -using AssemblyCode = CodeMemBlock; - -class AssemblyCodeBuilder { -public: - static AssemblyCode *FinalizeFromTurboAssembler(AssemblerBase *assembler); -}; diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/CodeBufferBase.cc b/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/CodeBufferBase.cc deleted file mode 100644 index eab9622..0000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/CodeBufferBase.cc +++ /dev/null @@ -1,53 +0,0 @@ -#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" - -CodeBufferBase *CodeBufferBase::Copy() { - CodeBufferBase *result = new CodeBufferBase(); - result->EmitBuffer(GetBuffer(), GetBufferSize()); - return result; -} - -void CodeBufferBase::Emit8(uint8_t data) { - Emit(data); -} - -void CodeBufferBase::Emit16(uint16_t data) { - Emit(data); -} - -void CodeBufferBase::Emit32(uint32_t data) { - Emit(data); -} - -void CodeBufferBase::Emit64(uint64_t data) { - Emit(data); -} - -void CodeBufferBase::EmitBuffer(uint8_t *buffer, int buffer_size) { - buffer_.insert(buffer_.end(), buffer, buffer + buffer_size); -} - -uint8_t *CodeBufferBase::GetBuffer() { - return buffer_.data(); -} - -size_t CodeBufferBase::GetBufferSize() { - return buffer_.size(); -} - -#if 0 // Template Advanced won't enable even in userspace -template T CodeBufferBase::Load(int offset) { - return *reinterpret_cast(buffer + offset); -} - -template void CodeBufferBase::Store(int offset, T value) { - *reinterpret_cast(buffer + offset) = value; -} - -template void CodeBufferBase::Emit(T value) { - // Ensure the free space enough for the template T value - ensureCapacity(sizeof(T) + GetBufferSize()); - - *reinterpret_cast(buffer_cursor) = value; - buffer_cursor += sizeof(T); -} -#endif diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/CodeBufferBase.h b/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/CodeBufferBase.h deleted file mode 100644 index 8a2dc0c..0000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/CodeBufferBase.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include "common_header.h" - -class CodeBufferBase { -public: - CodeBufferBase() { - } - -public: - virtual CodeBufferBase *Copy(); - - void Emit8(uint8_t data); - - void Emit16(uint16_t data); - - void Emit32(uint32_t data); - - void Emit64(uint64_t data); - - template T Load(int offset) { - return *(T *)(buffer_.data() + offset); - } - - template void Store(int offset, T value) { - *(T *)(buffer_.data() + offset) = value; - } - - template void Emit(T value) { - EmitBuffer((uint8_t *)&value, sizeof(value)); - } - - void EmitBuffer(uint8_t *buffer, int len); - - uint8_t *GetBuffer(); - size_t GetBufferSize(); - -private: - tinystl::vector buffer_; -}; diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm.h b/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm.h deleted file mode 100644 index 0255947..0000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef CODE_BUFFER_ARM_H -#define CODE_BUFFER_ARM_H - -#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" - -typedef int32_t arm_inst_t; -typedef int16_t thumb1_inst_t; -typedef int32_t thumb2_inst_t; - -class CodeBuffer : public CodeBufferBase { - enum ExecuteState { ARMExecuteState, ThumbExecuteState }; - -public: - CodeBuffer() : CodeBufferBase() { - } - -public: - arm_inst_t LoadARMInst(uint32_t offset) { - return *reinterpret_cast(GetBuffer() + offset); - } - - thumb1_inst_t LoadThumb1Inst(uint32_t offset) { - return *reinterpret_cast(GetBuffer() + offset); - } - - thumb2_inst_t LoadThumb2Inst(uint32_t offset) { - return *reinterpret_cast(GetBuffer() + offset); - } - - void RewriteAddr(uint32_t offset, addr32_t addr) { - memcpy(GetBuffer() + offset, &addr, sizeof(addr)); - } - - void RewriteARMInst(uint32_t offset, arm_inst_t instr) { - *reinterpret_cast(GetBuffer() + offset) = instr; - } - - void RewriteThumb1Inst(uint32_t offset, thumb1_inst_t instr) { - *reinterpret_cast(GetBuffer() + offset) = instr; - } - - void RewriteThumb2Inst(uint32_t offset, thumb2_inst_t instr) { - memcpy(GetBuffer() + offset, &instr, sizeof(instr)); - } - - void EmitARMInst(arm_inst_t instr) { - Emit(instr); - } - - void EmitThumb1Inst(thumb1_inst_t instr) { - Emit(instr); - } - - void EmitThumb2Inst(thumb2_inst_t instr) { - Emit(instr); - } -}; - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm64.h b/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm64.h deleted file mode 100644 index 266e10b..0000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm64.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef CODE_BUFFER_ARM64_H -#define CODE_BUFFER_ARM64_H - -#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" - -typedef int32_t arm64_inst_t; - -class CodeBuffer : public CodeBufferBase { - -public: - CodeBuffer() : CodeBufferBase() { - } - -public: - arm64_inst_t LoadInst(uint32_t offset) { - return *reinterpret_cast(GetBuffer() + offset); - } - - void RewriteInst(uint32_t offset, arm64_inst_t instr) { - *reinterpret_cast(GetBuffer() + offset) = instr; - } -}; - -#endif diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x64.h b/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x64.h deleted file mode 100644 index 913ee8a..0000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x64.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef CODE_BUFFER_X64_H -#define CODE_BUFFER_X64_H - -#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" - -class CodeBuffer : public CodeBufferBase { -public: - CodeBuffer() : CodeBufferBase() { - } - -public: - void FixBindLabel(int offset, int32_t disp) { - Store(offset, disp); - } -}; - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x86.cc b/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x86.cc deleted file mode 100644 index 827eca0..0000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x86.cc +++ /dev/null @@ -1,18 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_IA32) - -#include "MemoryAllocator/CodeBuffer/code-buffer-x86.h" - -void CodeBuffer::Emit32(int32_t data) { - ensureCapacity(GetBufferSize() + sizeof(int32_t)); - *reinterpret_cast(getCursor()) = data; - buffer_cursor += sizeof(int32_t); - return; -} - -void CodeBuffer::FixBindLabel(int offset, int32_t disp) { - *reinterpret_cast(buffer + offset) = disp; - return; -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x86.h b/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x86.h deleted file mode 100644 index a66d29e..0000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x86.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" - -class CodeBuffer : public CodeBufferBase { -public: - CodeBuffer() : CodeBufferBase() { - } -public: - void FixBindLabel(int offset, int32_t disp); -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_arm.h b/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_arm.h deleted file mode 100644 index 0fe8346..0000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_arm.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" - -typedef int32_t arm_inst_t; -typedef int16_t thumb1_inst_t; -typedef int32_t thumb2_inst_t; - -class CodeBuffer : public CodeBufferBase { - enum ExecuteState { ARMExecuteState, ThumbExecuteState }; - -public: - CodeBuffer() : CodeBufferBase() { - } - -public: - arm_inst_t LoadARMInst(uint32_t offset) { - return *reinterpret_cast(GetBuffer() + offset); - } - - thumb1_inst_t LoadThumb1Inst(uint32_t offset) { - return *reinterpret_cast(GetBuffer() + offset); - } - - thumb2_inst_t LoadThumb2Inst(uint32_t offset) { - return *reinterpret_cast(GetBuffer() + offset); - } - - void RewriteAddr(uint32_t offset, addr32_t addr) { - memcpy(GetBuffer() + offset, &addr, sizeof(addr)); - } - - void RewriteARMInst(uint32_t offset, arm_inst_t instr) { - *reinterpret_cast(GetBuffer() + offset) = instr; - } - - void RewriteThumb1Inst(uint32_t offset, thumb1_inst_t instr) { - *reinterpret_cast(GetBuffer() + offset) = instr; - } - - void RewriteThumb2Inst(uint32_t offset, thumb2_inst_t instr) { - memcpy(GetBuffer() + offset, &instr, sizeof(instr)); - } - - void EmitARMInst(arm_inst_t instr) { - Emit(instr); - } - - void EmitThumb1Inst(thumb1_inst_t instr) { - Emit(instr); - } - - void EmitThumb2Inst(thumb2_inst_t instr) { - Emit(instr); - } -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_arm64.h b/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_arm64.h deleted file mode 100644 index 4c8d803..0000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_arm64.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" - -typedef int32_t arm64_inst_t; - -class CodeBuffer : public CodeBufferBase { - -public: - CodeBuffer() : CodeBufferBase() { - } - -public: - arm64_inst_t LoadInst(uint32_t offset) { - return *reinterpret_cast(GetBuffer() + offset); - } - - void RewriteInst(uint32_t offset, arm64_inst_t instr) { - *reinterpret_cast(GetBuffer() + offset) = instr; - } -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_x64.h b/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_x64.h deleted file mode 100644 index d80dfb8..0000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_x64.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" - -class CodeBuffer : public CodeBufferBase { -public: - CodeBuffer() : CodeBufferBase() { - } - -public: - void FixBindLabel(int offset, int32_t disp) { - Store(offset, disp); - } -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_x86.h b/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_x86.h deleted file mode 100644 index c75bc2d..0000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_x86.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" - -class CodeBuffer : public CodeBufferBase { -public: - CodeBuffer() : CodeBufferBase() { - } -public: - void FixBindLabel(int offset, int32_t disp) { - Store(offset, disp); - } -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/MemoryAllocator.cc b/app/src/main/cpp/Dobby/source/MemoryAllocator/MemoryAllocator.cc deleted file mode 100644 index a4b865c..0000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/MemoryAllocator.cc +++ /dev/null @@ -1,106 +0,0 @@ -#include "dobby_internal.h" - -#include "PlatformUnifiedInterface/MemoryAllocator.h" - -MemBlock *MemoryArena::allocMemBlock(size_t size) { - // insufficient memory - if (this->end - this->cursor_addr < size) { - return nullptr; - } - - auto result = new MemBlock(cursor_addr, size); - cursor_addr += size; - return result; -} - -MemoryAllocator *MemoryAllocator::shared_allocator = nullptr; -MemoryAllocator *MemoryAllocator::SharedAllocator() { - if (MemoryAllocator::shared_allocator == nullptr) { - MemoryAllocator::shared_allocator = new MemoryAllocator(); - } - return MemoryAllocator::shared_allocator; -} - -CodeMemoryArena *MemoryAllocator::allocateCodeMemoryArena(uint32_t size) { - CHECK_EQ(size % OSMemory::PageSize(), 0); - uint32_t arena_size = size; - auto arena_addr = OSMemory::Allocate(arena_size, kNoAccess); - OSMemory::SetPermission(arena_addr, arena_size, kReadExecute); - - auto result = new CodeMemoryArena((addr_t)arena_addr, (size_t)arena_size); - code_arenas.push_back(result); - return result; -} - -CodeMemBlock *MemoryAllocator::allocateExecBlock(uint32_t size) { - CodeMemBlock *block = nullptr; - for (auto iter = code_arenas.begin(); iter != code_arenas.end(); iter++) { - auto arena = static_cast(*iter); - block = arena->allocMemBlock(size); - if (block) - break; - } - if (!block) { - // allocate new arena - auto arena_size = ALIGN_CEIL(size, OSMemory::PageSize()); - auto arena = allocateCodeMemoryArena(arena_size); - block = arena->allocMemBlock(size); - CHECK_NOT_NULL(block); - } - - DLOG(0, "[memory allocator] allocate exec memory at: %p, size: %p", block->addr, block->size); - return block; -} - -uint8_t *MemoryAllocator::allocateExecMemory(uint32_t size) { - auto block = allocateExecBlock(size); - return (uint8_t *)block->addr; -} -uint8_t *MemoryAllocator::allocateExecMemory(uint8_t *buffer, uint32_t buffer_size) { - auto mem = allocateExecMemory(buffer_size); - auto ret = DobbyCodePatch(mem, buffer, buffer_size); - CHECK_EQ(ret, kMemoryOperationSuccess); - return mem; -} - -DataMemoryArena *MemoryAllocator::allocateDataMemoryArena(uint32_t size) { - DataMemoryArena *result = nullptr; - - uint32_t buffer_size = ALIGN_CEIL(size, OSMemory::PageSize()); - void *buffer = OSMemory::Allocate(buffer_size, kNoAccess); - OSMemory::SetPermission(buffer, buffer_size, kReadWrite); - - result = new DataMemoryArena((addr_t)buffer, (size_t)buffer_size); - data_arenas.push_back(result); - return result; -} - -DataMemBlock *MemoryAllocator::allocateDataBlock(uint32_t size) { - CodeMemBlock *block = nullptr; - for (auto iter = data_arenas.begin(); iter != data_arenas.end(); iter++) { - auto arena = static_cast(*iter); - block = arena->allocMemBlock(size); - if (block) - break; - } - if (!block) { - // allocate new arena - auto arena = allocateCodeMemoryArena(size); - block = arena->allocMemBlock(size); - CHECK_NOT_NULL(block); - } - - DLOG(0, "[memory allocator] allocate data memory at: %p, size: %p", block->addr, block->size); - return block; -} - -uint8_t *MemoryAllocator::allocateDataMemory(uint32_t size) { - auto block = allocateDataBlock(size); - return (uint8_t *)block->addr; -} - -uint8_t *MemoryAllocator::allocateDataMemory(uint8_t *buffer, uint32_t buffer_size) { - auto mem = allocateDataMemory(buffer_size); - memcpy(mem, buffer, buffer_size); - return mem; -} diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/NearMemoryAllocator.cc b/app/src/main/cpp/Dobby/source/MemoryAllocator/NearMemoryAllocator.cc deleted file mode 100644 index 800f740..0000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/NearMemoryAllocator.cc +++ /dev/null @@ -1,234 +0,0 @@ -#include "NearMemoryAllocator.h" - -#include "dobby_internal.h" - -#include "PlatformUtil/ProcessRuntimeUtility.h" - -using namespace zz; - -#define KB (1024uLL) -#define MB (1024uLL * KB) -#define GB (1024uLL * MB) - -#if defined(WIN32) -static const void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) { - if (!haystack || !needle) { - return haystack; - } else { - const char *h = (const char *)haystack; - const char *n = (const char *)needle; - size_t l = needlelen; - const char *r = h; - while (l && (l <= haystacklen)) { - if (*n++ != *h++) { - r = h; - n = (const char *)needle; - l = needlelen; - } else { - --l; - } - --haystacklen; - } - return l ? nullptr : r; - } -} -#endif - -#define min(a, b) (((a) < (b)) ? (a) : (b)) -#define max(a, b) (((a) > (b)) ? (a) : (b)) - -NearMemoryAllocator *NearMemoryAllocator::shared_allocator = nullptr; -NearMemoryAllocator *NearMemoryAllocator::SharedAllocator() { - if (NearMemoryAllocator::shared_allocator == nullptr) { - NearMemoryAllocator::shared_allocator = new NearMemoryAllocator(); - } - return NearMemoryAllocator::shared_allocator; -} - -MemBlock *NearMemoryAllocator::allocateNearBlockFromDefaultAllocator(uint32_t size, addr_t pos, size_t search_range, - bool executable) { - addr_t min_valid_addr, max_valid_addr; - min_valid_addr = pos - search_range; - max_valid_addr = pos + search_range; - - auto allocateFromDefaultArena = [&](MemoryArena *arena, uint32_t size) -> addr_t { - addr_t unused_mem_start = arena->cursor_addr; - addr_t unused_mem_end = arena->addr + arena->size; - - // check if unused region total out of search range - if (unused_mem_end < min_valid_addr || unused_mem_start > max_valid_addr) - return 0; - - unused_mem_start = max(unused_mem_start, min_valid_addr); - unused_mem_end = min(unused_mem_end, max_valid_addr); - - // check if invalid - if(unused_mem_start >= unused_mem_end) - return 0; - - - // check if has sufficient memory - if (unused_mem_end - unused_mem_start < size) - return 0; - - DLOG(0, "[near memory allocator] unused memory from default allocator %p(%p), within pos: %p, serach_range: %p", unused_mem_start, size, pos, search_range); - return unused_mem_start; - }; - - MemoryArena *arena = nullptr; - addr_t unused_mem = 0; - if (executable) { - for (auto iter = default_allocator->code_arenas.begin(); iter != default_allocator->code_arenas.end(); iter++) { - arena = *iter; - unused_mem = allocateFromDefaultArena(arena, size); - if (!unused_mem) - continue; - - break; - } - } else { - for (auto iter = default_allocator->data_arenas.begin(); iter != default_allocator->data_arenas.end(); iter++) { - arena = *iter; - unused_mem = allocateFromDefaultArena(arena, size); - if (unused_mem) - continue; - } - } - - if (!unused_mem) - return nullptr; - - // skip placeholder block - // FIXME: allocate the placeholder but mark it as freed - auto placeholder_block_size = unused_mem - arena->cursor_addr; - arena->allocMemBlock(placeholder_block_size); - - - auto block = arena->allocMemBlock(size); - return block; -} - -MemBlock *NearMemoryAllocator::allocateNearBlockFromUnusedRegion(uint32_t size, addr_t pos, size_t search_range, - bool executable) { - - addr_t min_valid_addr, max_valid_addr; - min_valid_addr = pos - search_range; - max_valid_addr = pos + search_range; - - auto check_has_sufficient_memory_between_region = [&](MemRegion region, MemRegion next_region, uint32_t size) -> addr_t { - addr_t unused_mem_start = region.start + region.size; - addr_t unused_mem_end = next_region.start; - - // check if unused region total out of search range - if (unused_mem_end < min_valid_addr || unused_mem_start > max_valid_addr) - return 0; - - // align - unused_mem_start = ALIGN_FLOOR(unused_mem_start, 4); - - unused_mem_start = max(unused_mem_start, min_valid_addr); - unused_mem_end = min(unused_mem_end, max_valid_addr); - - // check if invalid - if (unused_mem_start >= unused_mem_end) - return 0; - - // check if has sufficient memory - if (unused_mem_end - unused_mem_start < size) - return 0; - - DLOG(0, "[near memory allocator] unused memory from unused region %p(%p), within pos: %p, serach_range: %p", unused_mem_start, size, pos, search_range); - return unused_mem_start; - }; - - addr_t unused_mem = 0; - auto regions = ProcessRuntimeUtility::GetProcessMemoryLayout(); - for (size_t i = 0; i + 1 < regions.size(); i++) { - unused_mem = check_has_sufficient_memory_between_region(regions[i], regions[i + 1], size); - if (unused_mem == 0) - continue; - break; - } - - if (!unused_mem) - return nullptr; - - auto unused_arena_first_page_addr = (addr_t)ALIGN_FLOOR(unused_mem, OSMemory::PageSize()); - auto unused_arena_end_page_addr = ALIGN_FLOOR(unused_mem + size, OSMemory::PageSize()); - auto unused_arena_size = unused_arena_end_page_addr - unused_arena_first_page_addr + OSMemory::PageSize(); - auto unused_arena_addr = unused_arena_first_page_addr; - - if (OSMemory::Allocate(unused_arena_size, kNoAccess, (void *)unused_arena_addr) == nullptr) { - ERROR_LOG("[near memory allocator] allocate fixed page failed %p", unused_arena_addr); - return nullptr; - } - - auto register_near_arena = [&](addr_t arena_addr, size_t arena_size) -> MemoryArena * { - MemoryArena *arena = nullptr; - if (executable) { - arena = new CodeMemoryArena(arena_addr, arena_size); - default_allocator->code_arenas.push_back(arena); - } else { - arena = new DataMemoryArena(arena_addr, arena_size); - default_allocator->data_arenas.push_back(arena); - } - OSMemory::SetPermission((void *)arena->addr, arena->size, executable ? kReadExecute : kReadWrite); - return arena; - }; - - auto unused_arena = register_near_arena(unused_arena_addr, unused_arena_size); - - // skip placeholder block - // FIXME: allocate the placeholder but mark it as freed - auto placeholder_block_size = unused_mem - unused_arena->cursor_addr; - unused_arena->allocMemBlock(placeholder_block_size); - - auto block = unused_arena->allocMemBlock(size); - return block; -} - -MemBlock *NearMemoryAllocator::allocateNearBlock(uint32_t size, addr_t pos, size_t search_range, bool executable) { - MemBlock *result = nullptr; - result = allocateNearBlockFromDefaultAllocator(size, pos, search_range, executable); - if (!result) { - result = allocateNearBlockFromUnusedRegion(size, pos, search_range, executable); - } - - if (!result) { - ERROR_LOG("[near memory allocator] allocate near block failed (%p, %p, %p)", size, pos, search_range); - } - return result; -} - -uint8_t *NearMemoryAllocator::allocateNearExecMemory(uint32_t size, addr_t pos, size_t search_range) { - auto block = allocateNearBlock(size, pos, search_range, true); - if (!block) - return nullptr; - - DLOG(0, "[near memory allocator] allocate exec memory at: %p, size: %p", block->addr, block->size); - return (uint8_t *)block->addr; -} - -uint8_t *NearMemoryAllocator::allocateNearExecMemory(uint8_t *buffer, uint32_t buffer_size, addr_t pos, - size_t search_range) { - auto mem = allocateNearExecMemory(buffer_size, pos, search_range); - auto ret = DobbyCodePatch(mem, buffer, buffer_size); - CHECK_EQ(ret, kMemoryOperationSuccess); - return mem; -} - -uint8_t *NearMemoryAllocator::allocateNearDataMemory(uint32_t size, addr_t pos, size_t search_range) { - auto block = allocateNearBlock(size, pos, search_range, false); - if (!block) - return nullptr; - - DLOG(0, "[near memory allocator] allocate data memory at: %p, size: %p", block->addr, block->size); - return (uint8_t *)block->addr; -} - -uint8_t *NearMemoryAllocator::allocateNearDataMemory(uint8_t *buffer, uint32_t buffer_size, addr_t pos, - size_t search_range) { - auto mem = allocateNearExecMemory(buffer_size, pos, search_range); - memcpy(mem, buffer, buffer_size); - return mem; -} diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/NearMemoryAllocator.h b/app/src/main/cpp/Dobby/source/MemoryAllocator/NearMemoryAllocator.h deleted file mode 100644 index a1e39bc..0000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/NearMemoryAllocator.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "PlatformUnifiedInterface/MemoryAllocator.h" - -#include "common_header.h" - -class NearMemoryAllocator { -public: - MemoryAllocator *default_allocator; - NearMemoryAllocator() { - default_allocator = MemoryAllocator::SharedAllocator(); - } - -private: - static NearMemoryAllocator *shared_allocator; - -public: - static NearMemoryAllocator *SharedAllocator(); - -public: - MemBlock *allocateNearBlock(uint32_t size, addr_t pos, size_t search_range, bool executable); - MemBlock *allocateNearBlockFromDefaultAllocator(uint32_t size, addr_t pos, size_t search_range, bool executable); - MemBlock *allocateNearBlockFromUnusedRegion(uint32_t size, addr_t pos, size_t search_range, bool executable); - - uint8_t *allocateNearExecMemory(uint32_t size, addr_t pos, size_t search_range); - uint8_t *allocateNearExecMemory(uint8_t *buffer, uint32_t buffer_size, addr_t pos, size_t search_range); - - uint8_t *allocateNearDataMemory(uint32_t size, addr_t pos, size_t search_range); - uint8_t *allocateNearDataMemory(uint8_t *buffer, uint32_t buffer_size, addr_t pos, size_t search_range); -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/ExecMemory/ClearCacheTool.h b/app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/ExecMemory/ClearCacheTool.h deleted file mode 100644 index ee407cb..0000000 --- a/app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/ExecMemory/ClearCacheTool.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -void ClearCache(void *start, void *end); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/ExecMemory/CodePatchTool.h b/app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/ExecMemory/CodePatchTool.h deleted file mode 100644 index f6c1073..0000000 --- a/app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/ExecMemory/CodePatchTool.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -MemoryOperationError DobbyCodePatch(void *address, uint8_t *buffer, uint32_t buffer_size); \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/MemoryAllocator.h b/app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/MemoryAllocator.h deleted file mode 100644 index b4b928c..0000000 --- a/app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/MemoryAllocator.h +++ /dev/null @@ -1,101 +0,0 @@ -#pragma once - -#include "common_header.h" - -struct MemRange { - addr_t start; - addr_t end; - size_t size; - - MemRange(addr_t start, size_t size) : start(start), end(0), size(size) { - end = start + size; - } - - void reset(addr_t start, size_t size) { - this->start = start; - this->size = size; - end = start + size; - } -}; - -struct MemBlock : MemRange { - addr_t addr; - - MemBlock() : MemRange(0, 0), addr(0) { - } - - MemBlock(addr_t addr, size_t size) : MemRange(addr, size), addr(addr) { - } - - void reset(addr_t addr, size_t size) { - MemRange::reset(addr, size); - this->addr = addr; - } -}; - -struct MemoryArena : MemRange { - addr_t addr; - addr_t cursor_addr; - - std::vector memory_blocks; - - MemoryArena(addr_t addr, size_t size) : MemRange(addr, size), addr(addr), cursor_addr(addr) { - } - - virtual MemBlock *allocMemBlock(size_t size); -}; - -using CodeMemBlock = MemBlock; -using CodeMemoryArena = MemoryArena; - -#if 0 -struct CodeMemoryArena : MemoryArena { - CodeMemoryArena(addr_t addr, size_t size) : MemoryArena(addr, size) { - } - - CodeMemBlock *allocateCodeMemBlock(size_t size) { - return allocMemBlock(size); - } -}; -#endif - -using DataMemBlock = MemBlock; -using DataMemoryArena = MemoryArena; - -#if 0 -struct DataMemoryArena : MemoryArena { -public: - DataMemoryArena(addr_t addr, size_t size) : MemoryArena(addr, size) { - } - - DataMemBlock *allocateDataMemBlock(size_t size) { - return allocMemBlock(size); - } -}; -#endif - -class NearMemoryAllocator; -class MemoryAllocator { - friend class NearMemoryAllocator; - -private: - std::vector code_arenas; - std::vector data_arenas; - -private: - static MemoryAllocator *shared_allocator; - -public: - static MemoryAllocator *SharedAllocator(); - -public: - CodeMemoryArena *allocateCodeMemoryArena(uint32_t size); - CodeMemBlock *allocateExecBlock(uint32_t size); - uint8_t *allocateExecMemory(uint32_t size); - uint8_t *allocateExecMemory(uint8_t *buffer, uint32_t buffer_size); - - DataMemoryArena *allocateDataMemoryArena(uint32_t size); - DataMemBlock *allocateDataBlock(uint32_t size); - uint8_t *allocateDataMemory(uint32_t size); - uint8_t *allocateDataMemory(uint8_t *buffer, uint32_t buffer_size); -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h deleted file mode 100644 index 14db027..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include "dobby_internal.h" - -#ifdef ENABLE_CLOSURE_TRAMPOLINE_TEMPLATE -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus -void closure_trampoline_template(); -void closure_bridge_template(); -#ifdef __cplusplus -} -#endif //__cplusplus -#endif - -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus - -typedef struct { - void *address; - int size; - void *carry_handler; - void *carry_data; -} ClosureTrampolineEntry; - -asm_func_t get_closure_bridge(); - -#ifdef __cplusplus -} -#endif //__cplusplus - -class ClosureTrampoline { -private: - static std::vector *trampolines_; - -public: - static ClosureTrampolineEntry *CreateClosureTrampoline(void *carry_data, void *carry_handler); -}; diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/ClosureTrampolineARM.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/ClosureTrampolineARM.cc deleted file mode 100644 index 25720ad..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/ClosureTrampolineARM.cc +++ /dev/null @@ -1,49 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_ARM) - -#include "dobby_internal.h" - -#include "core/assembler/assembler-arm.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" - -using namespace zz; -using namespace zz::arm; - -ClosureTrampolineEntry *ClosureTrampoline::CreateClosureTrampoline(void *carry_data, void *carry_handler) { - ClosureTrampolineEntry *tramp_entry = nullptr; - tramp_entry = new ClosureTrampolineEntry; - -#ifdef ENABLE_CLOSURE_TRAMPOLINE_TEMPLATE -#define CLOSURE_TRAMPOLINE_SIZE (7 * 4) - // use closure trampoline template code, find the executable memory and patch it. - auto code = AssemblyCodeBuilder::FinalizeCodeFromAddress(closure_trampoline_template, CLOSURE_TRAMPOLINE_SIZE); -#else -// use assembler and codegen modules instead of template_code -#include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" -#define _ turbo_assembler_. - TurboAssembler turbo_assembler_(0); - - AssemblerPseudoLabel entry_label; - AssemblerPseudoLabel forward_bridge_label; - - _ Ldr(r12, &entry_label); - _ Ldr(pc, &forward_bridge_label); - _ PseudoBind(&entry_label); - _ EmitAddress((uint32_t)(uintptr_t)tramp_entry); - _ PseudoBind(&forward_bridge_label); - _ EmitAddress((uint32_t)(uintptr_t)get_closure_bridge()); - - auto closure_tramp = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); - tramp_entry->address = (void *)closure_tramp->addr; - tramp_entry->size = closure_tramp->size; - tramp_entry->carry_data = carry_data; - tramp_entry->carry_handler = carry_handler; - - delete closure_tramp; - - return tramp_entry; -#endif -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/closure_bridge_arm.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/closure_bridge_arm.cc deleted file mode 100644 index 1e0151e..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/closure_bridge_arm.cc +++ /dev/null @@ -1,90 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_ARM) - -#include "dobby_internal.h" - -#include "core/assembler/assembler-arm.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h" - -using namespace zz; -using namespace zz::arm; - -static asm_func_t closure_bridge = nullptr; - -asm_func_t get_closure_bridge() { - - // if already initialized, just return. - if (closure_bridge) - return closure_bridge; - -// check if enable the inline-assembly closure_bridge_template -#if ENABLE_CLOSURE_BRIDGE_TEMPLATE - extern void closure_bridge_tempate(); - closure_bridge = closure_bridge_template; -// otherwise, use the Assembler build the closure_bridge -#else -#define _ turbo_assembler_. - TurboAssembler turbo_assembler_(0); - - _ sub(sp, sp, Operand(14 * 4)); - _ str(lr, MemOperand(sp, 13 * 4)); - _ str(r12, MemOperand(sp, 12 * 4)); - _ str(r11, MemOperand(sp, 11 * 4)); - _ str(r10, MemOperand(sp, 10 * 4)); - _ str(r9, MemOperand(sp, 9 * 4)); - _ str(r8, MemOperand(sp, 8 * 4)); - _ str(r7, MemOperand(sp, 7 * 4)); - _ str(r6, MemOperand(sp, 6 * 4)); - _ str(r5, MemOperand(sp, 5 * 4)); - _ str(r4, MemOperand(sp, 4 * 4)); - _ str(r3, MemOperand(sp, 3 * 4)); - _ str(r2, MemOperand(sp, 2 * 4)); - _ str(r1, MemOperand(sp, 1 * 4)); - _ str(r0, MemOperand(sp, 0 * 4)); - - // store sp - _ add(r0, sp, Operand(14 * 4)); - _ sub(sp, sp, Operand(8)); - _ str(r0, MemOperand(sp, 4)); - - // stack align - _ sub(sp, sp, Operand(8)); - - _ mov(r0, Operand(sp)); - _ mov(r1, Operand(r12)); - _ CallFunction(ExternalReference((void *)common_closure_bridge_handler)); - - // stack align - _ add(sp, sp, Operand(8)); - - // restore sp placeholder stack - _ add(sp, sp, Operand(8)); - - _ ldr(r0, MemOperand(sp, 4, PostIndex)); - _ ldr(r1, MemOperand(sp, 4, PostIndex)); - _ ldr(r2, MemOperand(sp, 4, PostIndex)); - _ ldr(r3, MemOperand(sp, 4, PostIndex)); - _ ldr(r4, MemOperand(sp, 4, PostIndex)); - _ ldr(r5, MemOperand(sp, 4, PostIndex)); - _ ldr(r6, MemOperand(sp, 4, PostIndex)); - _ ldr(r7, MemOperand(sp, 4, PostIndex)); - _ ldr(r8, MemOperand(sp, 4, PostIndex)); - _ ldr(r9, MemOperand(sp, 4, PostIndex)); - _ ldr(r10, MemOperand(sp, 4, PostIndex)); - _ ldr(r11, MemOperand(sp, 4, PostIndex)); - _ ldr(r12, MemOperand(sp, 4, PostIndex)); - _ ldr(lr, MemOperand(sp, 4, PostIndex)); - - // auto switch A32 & T32 with `least significant bit`, refer `docs/A32_T32_states_switch.md` - _ mov(pc, Operand(r12)); - - auto code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); - closure_bridge = (asm_func_t)code->addr; - - DLOG(0, "[closure bridge] closure bridge at %p", closure_bridge); -#endif - return closure_bridge; -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/dummy/closure-bridge-template-arm.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/dummy/closure-bridge-template-arm.cc deleted file mode 100644 index 8e41525..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/dummy/closure-bridge-template-arm.cc +++ /dev/null @@ -1,65 +0,0 @@ -// .section __TEXT,__text,regular,pure_instructions -// .ios_version_min 11, 0 - -#if defined(ENABLE_CLOSURE_BRIDGE_TEMPLATE) - -#if defined(__WIN32__) || defined(__APPLE__) -#define cdecl(s) "_" s -#else -#define cdecl(s) s -#endif - -#define xASM(x) __asm(x) - -__attribute__((naked)) void closure_bridge_template() { - xASM(".arm"); - xASM("sub sp, sp, #(14*4)"); - xASM("str lr, [sp, #(13*4)]"); - xASM("str r12, [sp, #(12*4)]"); - xASM("str r11, [sp, #(11*4)]"); - xASM("str r10, [sp, #(10*4)]"); - xASM("str r9, [sp, #(9*4)]"); - xASM("str r8, [sp, #(8*4)]"); - xASM("str r7, [sp, #(7*4)]"); - xASM("str r6, [sp, #(6*4)]"); - xASM("str r5, [sp, #(5*4)]"); - xASM("str r4, [sp, #(4*4)]"); - xASM("str r3, [sp, #(3*4)]"); - xASM("str r2, [sp, #(2*4)]"); - xASM("str r1, [sp, #(1*4)]"); - xASM("str r0, [sp, #(0*4)]"); - - // dummy align - xASM("sub sp, sp, #8"); - - xASM("mov r0, sp"); - xASM("mov r1, r12"); - xASM("bl " cdecl("common_closure_bridge_handler")); - - // dummy align - xASM("add sp, sp, #8"); - - xASM("ldr r0, [sp], #4"); - xASM("ldr r1, [sp], #4"); - xASM("ldr r2, [sp], #4"); - xASM("ldr r3, [sp], #4"); - xASM("ldr r4, [sp], #4"); - xASM("ldr r5, [sp], #4"); - xASM("ldr r6, [sp], #4"); - xASM("ldr r7, [sp], #4"); - xASM("ldr r8, [sp], #4"); - xASM("ldr r9, [sp], #4"); - xASM("ldr r10, [sp], #4"); - xASM("ldr r11, [sp], #4"); - xASM("ldr r12, [sp], #4"); - xASM("ldr lr, [sp], #4"); - -#if 1 - xASM("str r12, [sp, #-4]"); - xASM("ldr pc, [sp, #-4]"); -#else - xASM("mov pc, r12"); -#endif -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/dummy/closure-trampoline-template-arm.S b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/dummy/closure-trampoline-template-arm.S deleted file mode 100644 index 2186324..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/dummy/closure-trampoline-template-arm.S +++ /dev/null @@ -1,40 +0,0 @@ -// .section __TEXT,__text,regular,pure_instructions - -#if defined(ENABLE_CLOSURE_BRIDGE_TEMPLATE) - -#if defined(__WIN32__) || defined(__APPLE__) -#define cdecl(s) _##s -#else -#define cdecl(s) s -#endif - -.align 4 - -#if !defined(ENABLE_CLOSURE_TRAMPOLINE_CARRY_OBJECT_PTR) - -// closure trampoline carray the object pointer, and fetch required members at the runtime assembly code. -// #include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" -// #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) -#define OFFSETOF_ClourseTrampolineEntry_carry_data 4 -#define OFFSETOF_ClourseTrampolineEntry_carry_handler 0 -.globl cdecl(closure_trampoline_template) -cdecl(closure_trampoline_template): - ldr r12, ClourseTrampolineEntryPtr - ldr pc, [r12, #0] -ClourseTrampolineEntryPtr: - .long 0 - -#else - -; closure trampoline just carray the required members from the object. -.globl cdecl(closure_trampoline_template) -cdecl(closure_trampoline_template): - ldr r12, =carry_data - ldr pc, =carry_handler -carry_data: - .long 0 -carry_handler: - .long 0 -#endif - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/helper_arm.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/helper_arm.cc deleted file mode 100644 index cf93095..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/helper_arm.cc +++ /dev/null @@ -1,13 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_ARM) - -#include "dobby_internal.h" - -void set_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { - *reinterpret_cast(&ctx->general.regs.r12) = address; -} - -void get_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/ClosureTrampolineARM64.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/ClosureTrampolineARM64.cc deleted file mode 100644 index 6dcb702..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/ClosureTrampolineARM64.cc +++ /dev/null @@ -1,63 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_ARM64) - -#include "dobby_internal.h" - -#include "core/assembler/assembler-arm64.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" - -using namespace zz; -using namespace zz::arm64; - -// // tips -// _ ldr(TMP_REG_1, OFFSETOF(ClosureTrampolineEntry, carry_data)); -// _ ldr(TMP_REG_0, OFFSETOF(ClosureTrampolineEntry, carry_handler)); - -// use assembler and codegen modules instead of template_code -ClosureTrampolineEntry *ClosureTrampoline::CreateClosureTrampoline(void *carry_data, void *carry_handler) { - ClosureTrampolineEntry *tramp_entry = nullptr; - tramp_entry = new ClosureTrampolineEntry; - -#define _ turbo_assembler_. - TurboAssembler turbo_assembler_(0); - - AssemblerPseudoLabel entry_label; - AssemblerPseudoLabel forward_bridge_label; - - // prologue: alloc stack, store lr - _ sub(SP, SP, 2 * 8); - _ str(x30, MemOperand(SP, 8)); - - // store data at stack - _ Ldr(TMP_REG_0, &entry_label); - _ str(TMP_REG_0, MemOperand(SP, 0)); - - _ Ldr(TMP_REG_0, &forward_bridge_label); - _ blr(TMP_REG_0); - - // epilogue: release stack(won't restore lr) - _ ldr(x30, MemOperand(SP, 8)); - _ add(SP, SP, 2 * 8); - - // branch to next hop - _ br(TMP_REG_0); - - _ PseudoBind(&entry_label); - _ EmitInt64((uint64_t)tramp_entry); - _ PseudoBind(&forward_bridge_label); - _ EmitInt64((uint64_t)get_closure_bridge()); - - auto closure_tramp = AssemblyCodeBuilder::FinalizeFromTurboAssembler(static_cast(&turbo_assembler_)); - - tramp_entry->address = (void *)closure_tramp->addr; - tramp_entry->size = closure_tramp->size; - tramp_entry->carry_data = carry_data; - tramp_entry->carry_handler = carry_handler; - - delete closure_tramp; - - return tramp_entry; -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/closure_bridge_arm64.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/closure_bridge_arm64.cc deleted file mode 100644 index d9159af..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/closure_bridge_arm64.cc +++ /dev/null @@ -1,159 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_ARM64) - -#include "dobby_internal.h" - -#include "core/assembler/assembler.h" -#include "core/assembler/assembler-arm64.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h" - -using namespace zz; -using namespace zz::arm64; - -static asm_func_t closure_bridge = nullptr; - -asm_func_t get_closure_bridge() { - // if already initialized, just return. - if (closure_bridge) - return closure_bridge; - -// check if enable the inline-assembly closure_bridge_template -#if ENABLE_CLOSURE_BRIDGE_TEMPLATE - extern void closure_bridge_tempate(); - closure_bridge = closure_bridge_template; -// otherwise, use the Assembler build the closure_bridge -#else -#define _ turbo_assembler_. -#define MEM(reg, offset) MemOperand(reg, offset) - TurboAssembler turbo_assembler_(0); - -#if defined(FULL_FLOATING_POINT_REGISTER_PACK) - - _ sub(SP, SP, 24 * 16); - _ stp(Q(30), Q(31), MEM(SP, 22 * 16)); - _ stp(Q(28), Q(29), MEM(SP, 20 * 16)); - _ stp(Q(26), Q(27), MEM(SP, 18 * 16)); - _ stp(Q(24), Q(25), MEM(SP, 16 * 16)); - _ stp(Q(22), Q(23), MEM(SP, 14 * 16)); - _ stp(Q(20), Q(21), MEM(SP, 12 * 16)); - _ stp(Q(18), Q(19), MEM(SP, 10 * 16)); - _ stp(Q(16), Q(17), MEM(SP, 8 * 16)); - _ stp(Q(14), Q(15), MEM(SP, 6 * 16)); - _ stp(Q(12), Q(13), MEM(SP, 4 * 16)); - _ stp(Q(10), Q(11), MEM(SP, 2 * 16)); - _ stp(Q(8), Q(9), MEM(SP, 0 * 16)); - -#endif - - // save {q0-q7} - _ sub(SP, SP, 8 * 16); - _ stp(Q(6), Q(7), MEM(SP, 6 * 16)); - _ stp(Q(4), Q(5), MEM(SP, 4 * 16)); - _ stp(Q(2), Q(3), MEM(SP, 2 * 16)); - _ stp(Q(0), Q(1), MEM(SP, 0 * 16)); - - // save {x1-x30} - _ sub(SP, SP, 30 * 8); - _ stp(X(29), X(30), MEM(SP, 28 * 8)); - _ stp(X(27), X(28), MEM(SP, 26 * 8)); - _ stp(X(25), X(26), MEM(SP, 24 * 8)); - _ stp(X(23), X(24), MEM(SP, 22 * 8)); - _ stp(X(21), X(22), MEM(SP, 20 * 8)); - _ stp(X(19), X(20), MEM(SP, 18 * 8)); - _ stp(X(17), X(18), MEM(SP, 16 * 8)); - _ stp(X(15), X(16), MEM(SP, 14 * 8)); - _ stp(X(13), X(14), MEM(SP, 12 * 8)); - _ stp(X(11), X(12), MEM(SP, 10 * 8)); - _ stp(X(9), X(10), MEM(SP, 8 * 8)); - _ stp(X(7), X(8), MEM(SP, 6 * 8)); - _ stp(X(5), X(6), MEM(SP, 4 * 8)); - _ stp(X(3), X(4), MEM(SP, 2 * 8)); - _ stp(X(1), X(2), MEM(SP, 0 * 8)); - - // save {x0} - _ sub(SP, SP, 2 * 8); - _ str(x0, MEM(SP, 8)); - - // calculate original sp - _ add(TMP_REG_0, SP, 2 * 8); // closure trampoline reserved - _ add(TMP_REG_0, TMP_REG_0, 2 * 8 + 30 * 8 + 8 * 16); // x0, x1-x30, q0-q7 reserved -#if defined(FULL_FLOATING_POINT_REGISTER_PACK) - _ add(TMP_REG_0, TMP_REG_0, 24 * 16); // q8-q31 reserved -#endif - - // alloc stack, store original sp - _ sub(SP, SP, 2 * 8); - _ str(TMP_REG_0, MEM(SP, 8)); - -#if defined(FULL_FLOATING_POINT_REGISTER_PACK) -#define REGISTER_CONTEXT_SIZE (sizeof(DobbyRegisterContext)) -#else -#define REGISTER_CONTEXT_SIZE (sizeof(DobbyRegisterContext) - 24 * 16) -#endif - // create function arm64 call convention - _ mov(x0, SP); // arg1: register context - // load package(closure trampoline entry reserved) - _ ldr(x1, MEM(SP, REGISTER_CONTEXT_SIZE + 0)); // arg2: closure trampoline entry - _ CallFunction(ExternalReference((void *)common_closure_bridge_handler)); - - // restore sp placeholder stack - _ add(SP, SP, 2 * 8); - - // restore {x0} - _ ldr(X(0), MEM(SP, 8)); - _ add(SP, SP, 2 * 8); - -#define MEM_EXT(reg, offset, addrmode) MemOperand(reg, offset, addrmode) - // restore {x1-x30} - _ ldp(X(1), X(2), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(3), X(4), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(5), X(6), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(7), X(8), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(9), X(10), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(11), X(12), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(13), X(14), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(15), X(16), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(17), X(18), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(19), X(20), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(21), X(22), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(23), X(24), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(25), X(26), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(27), X(28), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(29), X(30), MEM_EXT(SP, 16, PostIndex)); - - // restore {q0-q7} - _ ldp(Q(0), Q(1), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(2), Q(3), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(4), Q(5), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(6), Q(7), MEM_EXT(SP, 32, PostIndex)); - -#if defined(FULL_FLOATING_POINT_REGISTER_PACK) - _ ldp(Q(8), Q(9), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(10), Q(11), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(12), Q(13), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(14), Q(15), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(16), Q(17), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(18), Q(19), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(20), Q(21), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(22), Q(23), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(24), Q(25), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(26), Q(27), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(28), Q(29), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(30), Q(31), MEM_EXT(SP, 32, PostIndex)); -#endif - - // _ brk(0); // for debug - - // return to closure trampoline, but TMP_REG_0, had been modified with next hop address - _ ret(); // AKA br x30 - - auto code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); - closure_bridge = (asm_func_t)code->addr; - - DLOG(0, "[closure bridge] closure bridge at %p", closure_bridge); -#endif - return closure_bridge; -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/closure-bridge-template-arm64.c b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/closure-bridge-template-arm64.c deleted file mode 100644 index ee5323e..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/closure-bridge-template-arm64.c +++ /dev/null @@ -1,103 +0,0 @@ -#if defined(ENABLE_CLOSURE_BRIDGE_TEMPLATE) - -#if defined(__WIN32__) || defined(__APPLE__) -#define xcdecl(s) "_" s -#else -#define xcdecl(s) s -#endif - -#define xASM(x) __asm(x) - -__attribute__((naked)) void closure_bridge_template() { - // DO NOT USE prologue - // x29 == fp, x30 == lr - // xASM("stp x29, x30, [sp, #-16]!"); - // xASM("mov x29, sp"); - - // save {q0-q7} - xASM("sub sp, sp, #(8*16)"); - xASM("stp q6, q7, [sp, #(6*16)]"); - xASM("stp q4, q5, [sp, #(4*16)]"); - xASM("stp q2, q3, [sp, #(2*16)]"); - xASM("stp q0, q1, [sp, #(0*16)]"); - - // save {x1-x30} - xASM("sub sp, sp, #(30*8)"); - // stp fp, lr, [sp, #(28*8)]"); - xASM("stp x29, x30, [sp, #(28*8)]"); - xASM("stp x27, x28, [sp, #(26*8)]"); - xASM("stp x25, x26, [sp, #(24*8)]"); - xASM("stp x23, x24, [sp, #(22*8)]"); - xASM("stp x21, x22, [sp, #(20*8)]"); - xASM("stp x19, x20, [sp, #(18*8)]"); - xASM("stp x17, x18, [sp, #(16*8)]"); - xASM("stp x15, x16, [sp, #(14*8)]"); - xASM("stp x13, x14, [sp, #(12*8)]"); - xASM("stp x11, x12, [sp, #(10*8)]"); - xASM("stp x9, x10, [sp, #(8*8)]"); - xASM("stp x7, x8, [sp, #(6*8)]"); - xASM("stp x5, x6, [sp, #(4*8)]"); - xASM("stp x3, x4, [sp, #(2*8)]"); - xASM("stp x1, x2, [sp, #(0*8)]"); - -#if 1 - // save {x0} - xASM("sub sp, sp, #(2*8)"); - xASM("str x0, [sp, #8]"); -#else - // save {x0, sp} - // save x0 and reserve sp, but this is trick - xASM("sub sp, sp, #(2*8)"); - xASM("str x0, [sp, #8]"); - // save origin sp - xASM("add x1, sp, #0x190"); - xASM("str x1, [sp, #0]"); -#endif - - // ======= Jump to UnifiedInterface Bridge Handle ======= - - // prepare args - // @x0: data_address - // @x1: DobbyRegisterContext stack address - xASM("mov x0, sp"); - xASM("mov x1, x14"); - xASM("bl " xcdecl("common_closure_bridge_handler")); - - // ======= DobbyRegisterContext Restore ======= - // restore x0 - xASM("ldr x0, [sp, #8]"); - xASM("add sp, sp, #(2*8)"); - - // restore {x1-x30} - xASM("ldp x1, x2, [sp], #16"); - xASM("ldp x3, x4, [sp], #16"); - xASM("ldp x5, x6, [sp], #16"); - xASM("ldp x7, x8, [sp], #16"); - xASM("ldp x9, x10, [sp], #16"); - xASM("ldp x11, x12, [sp], #16"); - xASM("ldp x13, x14, [sp], #16"); - xASM("ldp x15, x16, [sp], #16"); - xASM("ldp x17, x18, [sp], #16"); - xASM("ldp x19, x20, [sp], #16"); - xASM("ldp x21, x22, [sp], #16"); - xASM("ldp x23, x24, [sp], #16"); - xASM("ldp x25, x26, [sp], #16"); - xASM("ldp x27, x28, [sp], #16"); - // ldp fp, lr, [sp], #16"); - xASM("ldp x29, x30, [sp], #16"); - - // restore {q0-q7} - xASM("ldp q0, q1, [sp], #32"); - xASM("ldp q2, q3, [sp], #32"); - xASM("ldp q4, q5, [sp], #32"); - xASM("ldp q6, q7, [sp], #32"); - - // DO NOT USE epilog - // x29 == fp, x30 == lr - // xASM("mov sp, x29"); - // xASM("ldp x29, x30, [sp], #16"); - - xASM("br x15"); -}; - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/closure-trampoline-template-arm64.S b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/closure-trampoline-template-arm64.S deleted file mode 100644 index 16116cf..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/closure-trampoline-template-arm64.S +++ /dev/null @@ -1,47 +0,0 @@ -// .section __TEXT,__text,regular,pure_instructions - -#if defined(ENABLE_CLOSURE_BRIDGE_TEMPLATE) - -#if defined(__WIN32__) || defined(__APPLE__) -#define cdecl(s) _##s -#else -#define cdecl(s) s -#endif - -.align 4 - -#if !defined(ENABLE_CLOSURE_TRAMPOLINE_CARRY_OBJECT_PTR) - -// closure trampoline carray the object pointer, and fetch required members at the runtime assembly code. -// #include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" -// #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) -#define OFFSETOF_ClourseTrampolineEntry_carry_data 8 -#define OFFSETOF_ClourseTrampolineEntry_carry_handler 0 -.globl cdecl(closure_trampoline_template) -cdecl(closure_trampoline_template): - ldr x17, ClourseTrampolineEntryPtr - ldr x16, OFFSETOF_ClourseTrampolineEntry_carry_data - ldr x17, OFFSETOF_ClourseTrampolineEntry_carry_handler - br x17 -ClourseTrampolineEntryPtr: - .long 0 - .long 0 - -#else - -; closure trampoline just carray the required members from the object. -.globl cdecl(closure_trampoline_template) -cdecl(closure_trampoline_template): - ldr x16, =carry_data - ldr x17, =carry_handler - br x17 -carry_data: - .long 0 - .long 0 -carry_handler: - .long 0 - .long 0 - -#endif - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/dynamic-closure-trampoline-template-arm64.S b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/dynamic-closure-trampoline-template-arm64.S deleted file mode 100644 index 593b57b..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/dynamic-closure-trampoline-template-arm64.S +++ /dev/null @@ -1,31 +0,0 @@ -// .section __TEXT,__text,regular,pure_instructions - -// For iOS, we can't allocate executable memory, but we can use `remap` doing some trick. -// For details, please refer `libffi` - -#if defined(ENABLE_CLOSURE_BRIDGE_TEMPLATE) - -#if defined(__WIN32__) || defined(__APPLE__) - #define cdecl(s) _##s -#else - #define cdecl(s) s -#endif - -#define PAGE_MAX_SIZE 4096 -#define PAGE_MAX_SHIFT 14 - -.align PAGE_MAX_SHIFT -.globl cdecl(dynamic_closure_trampoline_table_page) -cdecl(dynamic_closure_trampoline_table_page): -.rept (PAGE_MAX_SIZE - 4 * 4) / 8 // sub dynamic_closure_trampoline_forward size -adr x16, #0 -b cdecl(dynamic_closure_trampoline_forward) -.endr - -cdecl(dynamic_closure_trampoline_forward): -sub x16, x16, #0x4000 // [DynamicClosureTrampoline **] -ldr x16, [x16, #0] // [DynamicClosureTrampoline *] -ldr x17, [x16, #0] // trampolineTo -br x17 - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/helper_arm64.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/helper_arm64.cc deleted file mode 100644 index 8a9fabb..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/helper_arm64.cc +++ /dev/null @@ -1,17 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_ARM64) - -#include "core/assembler/assembler-arm64.h" - -#include "dobby_internal.h" - -using namespace zz::arm64; - -void set_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { - *reinterpret_cast(&ctx->general.x[TMP_REG_0.code()]) = address; -} - -void get_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.cc deleted file mode 100644 index 5fdf917..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.cc +++ /dev/null @@ -1,22 +0,0 @@ -#include "logging/logging.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h" - -PUBLIC void common_closure_bridge_handler(DobbyRegisterContext *ctx, ClosureTrampolineEntry *entry) { - DLOG(0, "common bridge handler: carry data: %p, carry handler: %p", (InterceptEntry *)entry->carry_data, - entry->carry_handler); - - typedef void (*routing_handler_t)(InterceptEntry *, DobbyRegisterContext *); - auto routing_handler = (routing_handler_t)entry->carry_handler; - -#if defined(__APPLE__) && __arm64e__ -#if __has_feature(ptrauth_calls) - uint64_t discriminator = 0; - // discriminator = __builtin_ptrauth_type_discriminator(__typeof(routing_handler)); - routing_handler = (__typeof(routing_handler))__builtin_ptrauth_sign_unauthenticated((void *)routing_handler, - ptrauth_key_asia, discriminator); -#endif -#endif - - routing_handler((InterceptEntry *)entry->carry_data, ctx); -} diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h deleted file mode 100644 index 52d8567..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef CLOSURE_TRAMPOLINE_COMMON_HANDLER_H -#define CLOSURE_TRAMPOLINE_COMMON_HANDLER_H - -#include "dobby_internal.h" - -#include "Interceptor.h" -#include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" - -extern "C" { -void common_closure_bridge_handler(DobbyRegisterContext *ctx, ClosureTrampolineEntry *entry); -} - -void get_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address); - -void set_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address); - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/ClosureTrampolineX64.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/ClosureTrampolineX64.cc deleted file mode 100644 index 2b8cc8c..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/ClosureTrampolineX64.cc +++ /dev/null @@ -1,45 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_X64) - -#include "dobby_internal.h" - -#include "core/assembler/assembler-x64.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" - -using namespace zz; -using namespace zz::x64; - -ClosureTrampolineEntry *ClosureTrampoline::CreateClosureTrampoline(void *carry_data, void *carry_handler) { - ClosureTrampolineEntry *tramp_entry = nullptr; - tramp_entry = new ClosureTrampolineEntry; - - auto tramp_size = 32; - auto tramp_mem = MemoryAllocator::SharedAllocator()->allocateExecMemory(tramp_size); - if (tramp_mem == nullptr) { - return nullptr; - } -#define _ turbo_assembler_. -#define __ turbo_assembler_.GetCodeBuffer()-> - TurboAssembler turbo_assembler_(0); - - uint8_t *push_rip_6 = (uint8_t *)"\xff\x35\x06\x00\x00\x00"; - uint8_t *jmp_rip_8 = (uint8_t *)"\xff\x25\x08\x00\x00\x00"; - - __ EmitBuffer(push_rip_6, 6); - __ EmitBuffer(jmp_rip_8, 6); - __ Emit64((uint64_t)tramp_entry); - __ Emit64((uint64_t)get_closure_bridge()); - - tramp_entry->address = tramp_mem; - tramp_entry->size = tramp_size; - tramp_entry->carry_data = carry_data; - tramp_entry->carry_handler = carry_handler; - - auto closure_tramp_buffer = static_cast(turbo_assembler_.GetCodeBuffer()); - DobbyCodePatch(tramp_mem, (uint8_t *)closure_tramp_buffer->GetBuffer(), closure_tramp_buffer->GetBufferSize()); - - return tramp_entry; -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/closure_bridge_x64.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/closure_bridge_x64.cc deleted file mode 100644 index dc82f99..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/closure_bridge_x64.cc +++ /dev/null @@ -1,141 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_X64) - -#include "dobby_internal.h" - -#include "core/assembler/assembler-x64.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h" - -using namespace zz; -using namespace zz::x64; - -static asm_func_t closure_bridge = nullptr; - -asm_func_t get_closure_bridge() { - // if already initialized, just return. - if (closure_bridge) - return closure_bridge; - -// Check if enable the inline-assembly closure_bridge_template -#if ENABLE_CLOSURE_BRIDGE_TEMPLATE - - extern void closure_bridge_tempate(); - closure_bridge = closure_bridge_template; - -#else - -// otherwise, use the Assembler build the closure_bridge -#define _ turbo_assembler_. -#define __ turbo_assembler_.GetCodeBuffer()-> - - uint8_t *pushfq = (uint8_t *)"\x9c"; - uint8_t *popfq = (uint8_t *)"\x9d"; - - TurboAssembler turbo_assembler_(0); - - // save flags register - __ EmitBuffer(pushfq, 1); - // align rsp 16-byte - _ sub(rsp, Immediate(8, 32)); - - // general register - _ sub(rsp, Immediate(16 * 8, 32)); - _ mov(Address(rsp, 8 * 0), rax); - _ mov(Address(rsp, 8 * 1), rbx); - _ mov(Address(rsp, 8 * 2), rcx); - _ mov(Address(rsp, 8 * 3), rdx); - _ mov(Address(rsp, 8 * 4), rbp); - _ mov(Address(rsp, 8 * 5), rsp); - _ mov(Address(rsp, 8 * 6), rdi); - _ mov(Address(rsp, 8 * 7), rsi); - _ mov(Address(rsp, 8 * 8), r8); - _ mov(Address(rsp, 8 * 9), r9); - _ mov(Address(rsp, 8 * 10), r10); - _ mov(Address(rsp, 8 * 11), r11); - _ mov(Address(rsp, 8 * 12), r12); - _ mov(Address(rsp, 8 * 13), r13); - _ mov(Address(rsp, 8 * 14), r14); - _ mov(Address(rsp, 8 * 15), r15); - - // save origin sp - _ mov(rax, rsp); - _ add(rax, Immediate(8 + 8 + 8 + 16 * 8, 32)); - _ sub(rsp, Immediate(2 * 8, 32)); - _ mov(Address(rsp, 8), rax); - - // ======= Jump to UnifiedInterface Bridge Handle ======= - - // prepare args - // @rdi: data_address - // @rsi: DobbyRegisterContext stack address - _ mov(rdi, rsp); - _ mov(rsi, Address(rsp, 8 + 8 + 16 * 8 + 2 * 8)); - - // [!!!] As we can't detect the sp is aligned or not, check if need stack align - { - // mov rax, rsp - __ EmitBuffer((uint8_t *)"\x48\x89\xE0", 3); - // and rax, 0xF - __ EmitBuffer((uint8_t *)"\x48\x83\xE0\x0F", 4); - // cmp rax, 0x0 - __ EmitBuffer((uint8_t *)"\x48\x83\xF8\x00", 4); - // jnz [stack_align_call_bridge] - __ EmitBuffer((uint8_t *)"\x75\x15", 2); - } - - // LABEL: call_bridge - _ CallFunction(ExternalReference((void *)common_closure_bridge_handler)); - - // jmp [restore_stack_register] - __ EmitBuffer((uint8_t *)"\xE9\x12\x00\x00\x00", 5); - - // LABEL: stack_align_call_bridge - // push rax - __ EmitBuffer((uint8_t *)"\x50", 1); - _ CallFunction(ExternalReference((void *)common_closure_bridge_handler)); - // pop rax - __ EmitBuffer((uint8_t *)"\x58", 1); - - // ======= DobbyRegisterContext Restore ======= - - // restore sp placeholder stack - _ add(rsp, Immediate(2 * 8, 32)); - - // general register - _ pop(rax); - _ pop(rbx); - _ pop(rcx); - _ pop(rdx); - _ pop(rbp); - _ add(rsp, Immediate(8, 32)); // => pop rsp - _ pop(rdi); - _ pop(rsi); - _ pop(r8); - _ pop(r9); - _ pop(r10); - _ pop(r11); - _ pop(r12); - _ pop(r13); - _ pop(r14); - _ pop(r15); - - // align rsp 16-byte - _ add(rsp, Immediate(8, 32)); - // restore flags register - __ EmitBuffer(popfq, 1); - - // trick: use the 'carry_data' stack(remain at closure trampoline) placeholder, as the return address - _ ret(); - - _ RelocBind(); - - auto code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); - closure_bridge = (asm_func_t)code->addr; - - DLOG(0, "[closure bridge] closure bridge at %p", closure_bridge); -#endif - return closure_bridge; -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/dummy/closure-bridge-template-x64.c b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/dummy/closure-bridge-template-x64.c deleted file mode 100644 index d59dcdc..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/dummy/closure-bridge-template-x64.c +++ /dev/null @@ -1,70 +0,0 @@ -#if defined(ENABLE_CLOSURE_BRIDGE_TEMPLATE) - -#if defined(__WIN32__) || defined(__APPLE__) -#define xcdecl(s) "_" s -#else -#define xcdecl(s) s -#endif - -#define xASM(x) __asm(x) - -__attribute__((naked)) void closure_bridge_template() { - // flags register - xASM("pushfq"); - - // general register - xASM("sub rsp, #(16*8)"); - xASM("mov [rsp+16*0], rax"); - xASM("mov [rsp+16*1], rbx"); - xASM("mov [rsp+16*2], rcx"); - xASM("mov [rsp+16*3], rdx"); - xASM("mov [rsp+16*4], rbp"); - xASM("mov [rsp+16*5], rsp"); - xASM("mov [rsp+16*6], rdi"); - xASM("mov [rsp+16*7], rsi"); - xASM("mov [rsp+16*8], r8"); - xASM("mov [rsp+16*9], r9"); - xASM("mov [rsp+16*10], r10"); - xASM("mov [rsp+16*11], r11"); - xASM("mov [rsp+16*12], r12"); - xASM("mov [rsp+16*13], r13"); - xASM("mov [rsp+16*14], r14"); - xASM("mov [rsp+16*15], r15"); - - // ======= Jump to UnifiedInterface Bridge Handle ======= - - // prepare args - // @rdi: data_address - // @rsi: DobbyRegisterContext stack address - xASM("mov rdi, rsp"); - xASM("mov rsi, [rsp-16*8]"); - xASM("call " xcdecl("common_closure_bridge_handler")); - - // ======= DobbyRegisterContext Restore ======= - - // general register - xASM("pop r15"); - xASM("pop r14"); - xASM("pop r13"); - xASM("pop r12"); - xASM("pop r11"); - xASM("pop r10"); - xASM("pop r9"); - xASM("pop r8"); - xASM("pop rsi"); - xASM("pop rdi"); - xASM("pop rsp"); - xASM("pop rbp"); - xASM("pop rdx"); - xASM("pop rcx"); - xASM("pop rbx"); - xASM("pop rax"); - - // flags register - xASM("popfq"); - - // trick: use the 'carry_data' placeholder, as the return address - xASM("ret"); -}; - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/dummy/closure-trampoline-template-x64.S b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/dummy/closure-trampoline-template-x64.S deleted file mode 100644 index b24b602..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/dummy/closure-trampoline-template-x64.S +++ /dev/null @@ -1,23 +0,0 @@ -#if defined(ENABLE_CLOSURE_BRIDGE_TEMPLATE) - -#if defined(__WIN32__) || defined(__APPLE__) -#define cdecl(s) _##s -#else -#define cdecl(s) s -#endif - -.align 4 - -; closure trampoline just carray the required members from the object. -.globl cdecl(closure_trampoline_template) -cdecl(closure_trampoline_template): - push [rip+6+6] - jmp [rip+6+8] -carry_data: - .long 0 - .long 0 -carry_handler: - .long 0 - .long 0 - -#endif diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/helper_x64.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/helper_x64.cc deleted file mode 100644 index 383651f..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/helper_x64.cc +++ /dev/null @@ -1,17 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_X64) - -#include "dobby_internal.h" - -void set_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { - addr_t rsp = ctx->rsp; - - // ClosureTrampolineEntry reserved stack - addr_t entry_placeholder_stack_addr = rsp - 8; - *(addr_t *)entry_placeholder_stack_addr = (addr_t)address; -} - -void get_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/ClosureTrampolineX86.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/ClosureTrampolineX86.cc deleted file mode 100644 index be86bbe..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/ClosureTrampolineX86.cc +++ /dev/null @@ -1,44 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_IA32) - -#include "dobby_internal.h" - -#include "core/assembler/assembler-ia32.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" - -using namespace zz; -using namespace zz::x86; - -ClosureTrampolineEntry *ClosureTrampoline::CreateClosureTrampoline(void *carry_data, void *carry_handler) { - ClosureTrampolineEntry *tramp_entry = nullptr; - tramp_entry = new ClosureTrampolineEntry; - - auto tramp_size = 32; - auto tramp_mem = MemoryAllocator::SharedAllocator()->allocateExecMemory(tramp_size); - if (tramp_mem == nullptr) { - return nullptr; - } - -#define _ turbo_assembler_. -#define __ turbo_assembler_.GetCodeBuffer()-> - TurboAssembler turbo_assembler_(tramp_mem); - - int32_t offset = (int32_t)((uintptr_t)get_closure_bridge() - ((uintptr_t)tramp_mem + 18)); - - _ sub(esp, Immediate(4, 32)); - _ mov(Address(esp, 4 * 0), Immediate((int32_t)(uintptr_t)tramp_entry, 32)); - _ jmp(Immediate(offset, 32)); - - tramp_entry->address = tramp_mem; - tramp_entry->size = tramp_size; - tramp_entry->carry_data = carry_data; - tramp_entry->carry_handler = carry_handler; - - auto closure_tramp_buffer = static_cast(turbo_assembler_.GetCodeBuffer()); - DobbyCodePatch(tramp_mem, (uint8_t *)closure_tramp_buffer->GetBuffer(), closure_tramp_buffer->GetBufferSize()); - - return tramp_entry; -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/closure_bridge_x86.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/closure_bridge_x86.cc deleted file mode 100644 index 3e03b57..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/closure_bridge_x86.cc +++ /dev/null @@ -1,112 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_IA32) - -#include "dobby_internal.h" - -#include "core/assembler/assembler-ia32.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h" - -using namespace zz; -using namespace zz::x86; - -static asm_func_t closure_bridge = NULL; - -asm_func_t get_closure_bridge() { - // if already initialized, just return. - if (closure_bridge) - return closure_bridge; - -// Check if enable the inline-assembly closure_bridge_template -#if ENABLE_CLOSURE_BRIDGE_TEMPLATE - - extern void closure_bridge_tempate(); - closure_bridge = closure_bridge_template; - -#else - -// otherwise, use the Assembler build the closure_bridge -#define _ turbo_assembler_. -#define __ turbo_assembler_.GetCodeBuffer()-> - - auto pushfd = (uint8_t *)"\x9c"; - auto popfd = (uint8_t *)"\x9d"; - - TurboAssembler turbo_assembler_(0); - - // general register - _ sub(esp, Immediate(8 * 4, 32)); - _ mov(Address(esp, 4 * 0), eax); - _ mov(Address(esp, 4 * 1), ebx); - _ mov(Address(esp, 4 * 2), ecx); - _ mov(Address(esp, 4 * 3), edx); - _ mov(Address(esp, 4 * 4), ebp); - _ mov(Address(esp, 4 * 5), esp); - _ mov(Address(esp, 4 * 6), edi); - _ mov(Address(esp, 4 * 7), esi); - - // save flags register - __ EmitBuffer(pushfd, 1); - _ pop(eax); - { // save to stack - _ sub(esp, Immediate(2 * 4, 32)); - _ mov(Address(esp, 4), eax); - } - - // save origin sp - _ mov(eax, esp); - _ add(eax, Immediate(8 * 4 + 2 * 4 + 4, 32)); - { // save to stack - _ sub(esp, Immediate(2 * 4, 32)); - _ mov(Address(esp, 4), eax); - } - - // ======= Jump to UnifiedInterface Bridge Handle ======= - - // prepare args - _ sub(esp, Immediate(2 * 4, 32)); - _ mov(eax, Address(esp, 8 * 4 + 2 * 4 + 2 * 4 + 2 * 4)); - _ mov(Address(esp, 4), eax); - _ mov(eax, esp); - _ add(eax, Immediate(2 * 4, 32)); - _ mov(Address(esp, 0), eax); - - // LABEL: call_bridge - _ CallFunction(ExternalReference((void *)common_closure_bridge_handler)); - - // ======= DobbyRegisterContext Restore ======= - - // restore argument reserved stack - _ add(esp, Immediate(2 * 4, 32)); - - // restore sp placeholder stack - _ add(esp, Immediate(2 * 4, 32)); - - _ add(esp, Immediate(4, 32)); - // restore flags register - __ EmitBuffer(popfd, 1); - - // general register - _ pop(eax); - _ pop(ebx); - _ pop(ecx); - _ pop(edx); - _ pop(ebp); - _ add(esp, Immediate(4, 32)); // => pop rsp - _ pop(edi); - _ pop(esi); - - // trick: use the 'carry_data' stack(remain at closure trampoline) placeholder, as the return address - _ ret(); - - _ RelocBind(); - - auto code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); - closure_bridge = (asm_func_t)code->addr; - - DLOG(0, "[closure bridge] closure bridge at %p", closure_bridge); -#endif - return closure_bridge; -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/helper_x86.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/helper_x86.cc deleted file mode 100644 index 5bf2529..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/helper_x86.cc +++ /dev/null @@ -1,16 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_IA32) - -#include "dobby_internal.h" - -void set_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { - addr_t esp = ctx->esp; - - addr_t entry_placeholder_stack_addr = esp - 4; - *(addr_t *)entry_placeholder_stack_addr = (addr_t)address; -} - -void get_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/Trampoline.h b/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/Trampoline.h deleted file mode 100644 index 53f3779..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/Trampoline.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include "MemoryAllocator/AssemblyCodeBuilder.h" - -CodeBufferBase *GenerateNormalTrampolineBuffer(addr_t from, addr_t to); \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/arm/trampoline_arm.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/arm/trampoline_arm.cc deleted file mode 100644 index f291302..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/arm/trampoline_arm.cc +++ /dev/null @@ -1,61 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_ARM) - -#include "dobby_internal.h" - -#include "core/assembler/assembler-arm.h" -#include "core/codegen/codegen-arm.h" - -#include "InstructionRelocation/arm/InstructionRelocationARM.h" -#include "MemoryAllocator/NearMemoryAllocator.h" -#include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" - -using namespace zz::arm; - -static CodeBufferBase *generate_arm_trampoline(addr32_t from, addr32_t to) { - TurboAssembler turbo_assembler_((void *)from); -#define _ turbo_assembler_. - - CodeGen codegen(&turbo_assembler_); - codegen.LiteralLdrBranch(to); - - return turbo_assembler_.GetCodeBuffer()->Copy(); -} - -CodeBufferBase *generate_thumb_trampoline(addr32_t from, addr32_t to) { - ThumbTurboAssembler thumb_turbo_assembler_((void *)from); -#undef _ -#define _ thumb_turbo_assembler_. - - _ AlignThumbNop(); - _ t2_ldr(pc, MemOperand(pc, 0)); - _ EmitAddress(to); - - return thumb_turbo_assembler_.GetCodeBuffer()->Copy(); -} - -CodeBufferBase *GenerateNormalTrampolineBuffer(addr_t from, addr_t to) { - enum ExecuteState { ARMExecuteState, ThumbExecuteState }; - - // set instruction running state - ExecuteState execute_state_; - execute_state_ = ARMExecuteState; - if ((addr_t)from % 2) { - execute_state_ = ThumbExecuteState; - } - - if (execute_state_ == ARMExecuteState) { - return generate_arm_trampoline(from, to); - } else { - // Check if needed pc align, (relative pc instructions needed 4 align) - from = from - THUMB_ADDRESS_FLAG; - return generate_thumb_trampoline(from, to); - } - return NULL; -} - -CodeBufferBase *GenerateNearTrampolineBuffer(InterceptRouting *routing, addr_t src, addr_t dst) { - return NULL; -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/arm64/trampoline_arm64.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/arm64/trampoline_arm64.cc deleted file mode 100644 index c921683..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/arm64/trampoline_arm64.cc +++ /dev/null @@ -1,41 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_ARM64) - -#include "dobby_internal.h" - -#include "core/assembler/assembler-arm64.h" -#include "core/codegen/codegen-arm64.h" - -#include "MemoryAllocator/NearMemoryAllocator.h" -#include "InstructionRelocation/arm64/InstructionRelocationARM64.h" -#include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" - -using namespace zz::arm64; - -CodeBufferBase *GenerateNormalTrampolineBuffer(addr_t from, addr_t to) { - TurboAssembler turbo_assembler_((void *)from); -#define _ turbo_assembler_. - - uint64_t distance = llabs((int64_t)(from - to)); - uint64_t adrp_range = ((uint64_t)1 << (2 + 19 + 12 - 1)); - if (distance < adrp_range) { - // adrp, add, br - _ AdrpAdd(TMP_REG_0, from, to); - _ br(TMP_REG_0); - DLOG(0, "[trampoline] use [adrp, add, br]"); - } else { - // ldr, br, branch-address - CodeGen codegen(&turbo_assembler_); - codegen.LiteralLdrBranch((uint64_t)to); - DLOG(0, "[trampoline] use [ldr, br, #label]"); - } -#undef _ - - // Bind all labels - turbo_assembler_.RelocBind(); - - auto result = turbo_assembler_.GetCodeBuffer()->Copy(); - return result; -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/x64/trampoline_x64.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/x64/trampoline_x64.cc deleted file mode 100644 index 92c7009..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/x64/trampoline_x64.cc +++ /dev/null @@ -1,54 +0,0 @@ -#include "platform_macro.h" - -#if defined(TARGET_ARCH_X64) - -#include "dobby_internal.h" - -#include "core/assembler/assembler-x64.h" -#include "core/codegen/codegen-x64.h" - -#include "InstructionRelocation/x64/InstructionRelocationX64.h" - -#include "MemoryAllocator/NearMemoryAllocator.h" -#include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" - -using namespace zz::x64; - -static addr_t allocate_indirect_stub(addr_t jmp_insn_addr) { - uint32_t jmp_near_range = (uint32_t)2 * 1024 * 1024 * 1024; - auto stub_addr = (addr_t)NearMemoryAllocator::SharedAllocator()->allocateNearDataMemory(sizeof(void *), jmp_insn_addr, - jmp_near_range); - if (stub_addr == 0) { - ERROR_LOG("Not found near forward stub"); - return 0; - } - - DLOG(0, "forward stub: %p", stub_addr); - return stub_addr; -} - -CodeBufferBase *GenerateNormalTrampolineBuffer(addr_t from, addr_t to) { - TurboAssembler turbo_assembler_((void *)from); -#define _ turbo_assembler_. - - // allocate forward stub - auto jump_near_next_insn_addr = from + 6; - addr_t forward_stub = allocate_indirect_stub(jump_near_next_insn_addr); - if (forward_stub == 0) - return nullptr; - - *(addr_t *)forward_stub = to; - - CodeGen codegen(&turbo_assembler_); - codegen.JmpNearIndirect((addr_t)forward_stub); - - auto buffer = turbo_assembler_.GetCodeBuffer()->Copy(); - return buffer; -} - -CodeBufferBase *GenerateNearTrampolineBuffer(InterceptRouting *routing, addr_t src, addr_t dst) { - DLOG(0, "x64 near branch trampoline enable default"); - return nullptr; -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/x86/trampoline_x86.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/x86/trampoline_x86.cc deleted file mode 100644 index 289b013..0000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/x86/trampoline_x86.cc +++ /dev/null @@ -1,33 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_IA32) - -#include "dobby_internal.h" - -#include "core/assembler/assembler-ia32.h" -#include "core/codegen/codegen-ia32.h" - -#include "InstructionRelocation/x86/InstructionRelocationX86.h" - -#include "MemoryAllocator/NearMemoryAllocator.h" -#include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" - -using namespace zz::x86; - -CodeBufferBase *GenerateNormalTrampolineBuffer(addr_t from, addr_t to) { - TurboAssembler turbo_assembler_((void *)from); -#define _ turbo_assembler_. - - CodeGen codegen(&turbo_assembler_); - codegen.JmpNear((uint32_t)to); - - CodeBufferBase *result = NULL; - result = turbo_assembler_.GetCodeBuffer()->Copy(); - return result; -} - -CodeBufferBase *GenerateNearTrampolineBuffer(InterceptRouting *routing, addr_t src, addr_t dst) { - DLOG(0, "x86 near branch trampoline enable default"); - return NULL; -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/arch/Cpu.cc b/app/src/main/cpp/Dobby/source/core/arch/Cpu.cc deleted file mode 100644 index 0716361..0000000 --- a/app/src/main/cpp/Dobby/source/core/arch/Cpu.cc +++ /dev/null @@ -1,5 +0,0 @@ - -#include "core/arch/Cpu.h" -#include "core/arch/CpuUtils.h" - -#include "xnucxx/LiteMemOpt.h" diff --git a/app/src/main/cpp/Dobby/source/core/arch/Cpu.h b/app/src/main/cpp/Dobby/source/core/arch/Cpu.h deleted file mode 100644 index e0361a7..0000000 --- a/app/src/main/cpp/Dobby/source/core/arch/Cpu.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef CORE_ARCH_CPU_H -#define CORE_ARCH_CPU_H - -#include "CpuRegister.h" -#include "CpuFeature.h" - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/arch/CpuFeature.cc b/app/src/main/cpp/Dobby/source/core/arch/CpuFeature.cc deleted file mode 100644 index d29f176..0000000 --- a/app/src/main/cpp/Dobby/source/core/arch/CpuFeature.cc +++ /dev/null @@ -1,7 +0,0 @@ - -#include "core/arch/CpuFeature.h" -#include "logging/logging.h" - -void CpuFeatures::ClearCache(void *start, void *end) { - UNIMPLEMENTED(); -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/arch/CpuFeature.h b/app/src/main/cpp/Dobby/source/core/arch/CpuFeature.h deleted file mode 100644 index b9a0736..0000000 --- a/app/src/main/cpp/Dobby/source/core/arch/CpuFeature.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef CORE_ARCH_CPU_FEATURE_H -#define CORE_ARCH_CPU_FEATURE_H - -#include "common_header.h" - -class CpuFeatures { -private: - static void FlushICache(void *start, size_t size) { - ClearCache(start, (void *)((addr_t)start + size)); - } - - static void FlushICache(void *start, void *end) { - ClearCache(start, end); - } - - static void ClearCache(void *start, void *end); -}; - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/arch/CpuRegister.cc b/app/src/main/cpp/Dobby/source/core/arch/CpuRegister.cc deleted file mode 100644 index 3617e4e..0000000 --- a/app/src/main/cpp/Dobby/source/core/arch/CpuRegister.cc +++ /dev/null @@ -1,10 +0,0 @@ - -#include "CpuRegister.h" - -constexpr RegisterBase RegisterBase::from_code(int code) { - return RegisterBase{code}; -} - -constexpr RegisterBase RegisterBase::no_reg() { - return RegisterBase{0}; -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/arch/CpuRegister.h b/app/src/main/cpp/Dobby/source/core/arch/CpuRegister.h deleted file mode 100644 index e12aff4..0000000 --- a/app/src/main/cpp/Dobby/source/core/arch/CpuRegister.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef CORE_ARCH_CPU_REGISTER_H -#define CORE_ARCH_CPU_REGISTER_H - -class RegisterBase { -public: - static constexpr RegisterBase from_code(int code); - - static constexpr RegisterBase no_reg(); - - virtual bool Is(const RegisterBase ®) const { - return (reg.reg_code_ == this->reg_code_); - } - - int code() const { - return reg_code_; - }; - -protected: - explicit constexpr RegisterBase(int code) : reg_code_(code) { - } - - int reg_code_; -}; - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/arch/CpuUtils.h b/app/src/main/cpp/Dobby/source/core/arch/CpuUtils.h deleted file mode 100644 index 3942363..0000000 --- a/app/src/main/cpp/Dobby/source/core/arch/CpuUtils.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef CPU_UTILITY_H -#define CPU_UTILITY_H - -/* Define the default attributes for the functions in this file. */ -#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__)) - -#if defined(__i386__) || defined(__x86_64__) -static __inline__ void __DEFAULT_FN_ATTRS __cpuid(int __info[4], int __level) { - __asm__("cpuid" : "=a"(__info[0]), "=b"(__info[1]), "=c"(__info[2]), "=d"(__info[3]) : "a"(__level)); -} - -static __inline__ void __DEFAULT_FN_ATTRS __cpuidex(int __info[4], int __level, int __ecx) { - __asm__("cpuid" : "=a"(__info[0]), "=b"(__info[1]), "=c"(__info[2]), "=d"(__info[3]) : "a"(__level), "c"(__ecx)); -} -#endif - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/arch/arm/constants-arm.h b/app/src/main/cpp/Dobby/source/core/arch/arm/constants-arm.h deleted file mode 100644 index b326d34..0000000 --- a/app/src/main/cpp/Dobby/source/core/arch/arm/constants-arm.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef CORE_ARCH_CONSTANTS_ARM_H -#define CORE_ARCH_CONSTANTS_ARM_H - -enum AddrMode { Offset = 0, PreIndex = 1, PostIndex = 2 }; - -enum Condition { - EQ = 0, // equal - NE = 1, // not equal - CS = 2, // carry set/unsigned higher or same - CC = 3, // carry clear/unsigned lower - MI = 4, // minus/negative - PL = 5, // plus/positive or zero - VS = 6, // overflow - VC = 7, // no overflow - HI = 8, // unsigned higher - LS = 9, // unsigned lower or same - GE = 10, // signed greater than or equal - LT = 11, // signed less than - GT = 12, // signed greater than - LE = 13, // signed less than or equal - AL = 14, // always (unconditional) - -}; - -enum Shift { - LSL = 0, // Logical shift left - LSR = 1, // Logical shift right - ASR = 2, // Arithmetic shift right - ROR = 3, // Rotate right -}; - -enum { - B0 = 1 << 0, - B4 = 1 << 4, - B5 = 1 << 5, - B6 = 1 << 6, - B7 = 1 << 7, - B8 = 1 << 8, - B9 = 1 << 9, - B10 = 1 << 10, - B12 = 1 << 12, - B14 = 1 << 14, - B15 = 1 << 15, - B16 = 1 << 16, - B17 = 1 << 17, - B18 = 1 << 18, - B19 = 1 << 19, - B20 = 1 << 20, - B21 = 1 << 21, - B22 = 1 << 22, - B23 = 1 << 23, - B24 = 1 << 24, - B25 = 1 << 25, - B26 = 1 << 26, - B27 = 1 << 27, - B28 = 1 << 28, -}; - -enum InstructionFields { - // Registers. - kRdShift = 12, - kRtShift = 12, - kRmShift = 10, - kRnShift = 16, - - // Condition - kConditionShift = 28, -}; - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/arch/arm/registers-arm.h b/app/src/main/cpp/Dobby/source/core/arch/arm/registers-arm.h deleted file mode 100644 index 88b7c2e..0000000 --- a/app/src/main/cpp/Dobby/source/core/arch/arm/registers-arm.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef ARCH_ARM_REGISTERS -#define ARCH_ARM_REGISTERS - -#include "core/arch/arm/constants-arm.h" -#include "core/arch/Cpu.h" - -namespace zz { -namespace arm { - -#define GENERAL_REGISTERS(V) \ - V(r0) V(r1) V(r2) V(r3) V(r4) V(r5) V(r6) V(r7) V(r8) V(r9) V(r10) V(r11) V(r12) V(sp) V(lr) V(pc) - -enum RegisterCode { -#define REGISTER_CODE(R) kRegCode_##R, - GENERAL_REGISTERS(REGISTER_CODE) -#undef REGISTER_CODE - kRegAfterLast -}; - -class Register : public RegisterBase { -public: - explicit constexpr Register(int code) : RegisterBase(code) { - } - - static constexpr Register Create(int code) { - return Register(code); - } - - static constexpr Register R(int code) { - return Register(code); - } - - bool Is(const Register ®) const { - return (reg.reg_code_ == this->reg_code_); - } - - bool IsValid() const { - return (reg_code_ != 0); - } - - int code() const { - return reg_code_; - } - -private: -}; - -typedef Register CPURegister; - -#define DECLARE_REGISTER(R) constexpr Register R = Register::Create(kRegCode_##R); -GENERAL_REGISTERS(DECLARE_REGISTER) -#undef DECLARE_REGISTER - -constexpr Register no_reg = Register::Create(0); - -} // namespace arm -} // namespace zz -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/arch/arm64/constants-arm64.h b/app/src/main/cpp/Dobby/source/core/arch/arm64/constants-arm64.h deleted file mode 100644 index 5540e6b..0000000 --- a/app/src/main/cpp/Dobby/source/core/arch/arm64/constants-arm64.h +++ /dev/null @@ -1,387 +0,0 @@ -#ifndef CORE_ARCH_CONSTANTS_ARM64_H -#define CORE_ARCH_CONSTANTS_ARM64_H - -#include "common_header.h" - -enum Shift { NO_SHIFT = -1, LSL = 0x0, LSR = 0x1, ASR = 0x2, ROR = 0x3, MSL = 0x4 }; - -enum Extend { NO_EXTEND = -1, UXTB = 0, UXTH = 1, UXTW = 2, UXTX = 3, SXTB = 4, SXTH = 5, SXTW = 6, SXTX = 7 }; - -enum AddrMode { Offset, PreIndex, PostIndex }; - -enum FlagsUpdate { SetFlags = 1, LeaveFlags = 0 }; - -enum InstructionFields { - - // Registers. - kRdShift = 0, - kRdBits = 5, - kRnShift = 5, - kRnBits = 5, - kRaShift = 10, - kRaBits = 5, - kRmShift = 16, - kRmBits = 5, - kRtShift = 0, - kRtBits = 5, - kRt2Shift = 10, - kRt2Bits = 5, - kRsShift = 16, - kRsBits = 5, - -}; - -#define OP(op) op -#define OP_W(op) op##_w -#define OP_X(op) op##_x -#define OP_B(op) op##_b -#define OP_H(op) op##_h -#define OP_S(op) op##_s -#define OP_D(op) op##_d -#define OP_Q(op) op##_q - -#define OPT(op, attribute) op##_##attribute -#define OPT_W(op, attribute) op##_w_##attribute -#define OPT_X(op, attribute) op##_x_##attribute -#define OPT_B(op, attribute) op##_b_##attribute -#define OPT_H(op, attribute) op##_h_##attribute -#define OPT_S(op, attribute) op##_s_##attribute -#define OPT_D(op, attribute) op##_d_##attribute -#define OPT_Q(op, attribute) op##_q_##attribute - -// ===== - -// Exception. -enum ExceptionOp { - ExceptionFixed = 0xD4000000, - ExceptionFMask = 0xFF000000, - ExceptionMask = 0xFFE0001F, - - HLT = ExceptionFixed | 0x00400000, - BRK = ExceptionFixed | 0x00200000, - SVC = ExceptionFixed | 0x00000001, - HVC = ExceptionFixed | 0x00000002, - SMC = ExceptionFixed | 0x00000003, - DCPS1 = ExceptionFixed | 0x00A00001, - DCPS2 = ExceptionFixed | 0x00A00002, - DCPS3 = ExceptionFixed | 0x00A00003 -}; - -// ===== - -// Unconditional branch. -enum UnconditionalBranchOp { - UnconditionalBranchFixed = 0x14000000, - UnconditionalBranchFixedMask = 0x7C000000, - UnconditionalBranchMask = 0xFC000000, - - B = UnconditionalBranchFixed | 0x00000000, - BL = UnconditionalBranchFixed | 0x80000000 -}; - -// ===== - -// Unconditional branch to register. -enum UnconditionalBranchToRegisterOp { - UnconditionalBranchToRegisterFixed = 0xD6000000, - UnconditionalBranchToRegisterFixedMask = 0xFE000000, - UnconditionalBranchToRegisterMask = 0xFFFFFC1F, - - BR = UnconditionalBranchToRegisterFixed | 0x001F0000, - BLR = UnconditionalBranchToRegisterFixed | 0x003F0000, - RET = UnconditionalBranchToRegisterFixed | 0x005F0000 -}; - -// ===== - -enum LoadRegLiteralOp { - LoadRegLiteralFixed = 0x18000000, - LoadRegLiteralFixedMask = 0x3B000000, - LoadRegLiteralMask = 0xFF000000, - -#define LoadRegLiteralSub(opc, V) LoadRegLiteralFixed | LeftShift(opc, 2, 30) | LeftShift(V, 1, 26) - OPT_W(LDR, literal) = LoadRegLiteralSub(0b00, 0), - OPT_X(LDR, literal) = LoadRegLiteralSub(0b01, 0), - OPT(LDRSW, literal) = LoadRegLiteralSub(0b10, 0), - OPT(PRFM, literal) = LoadRegLiteralSub(0b11, 0), - OPT_S(LDR, literal) = LoadRegLiteralSub(0b00, 1), - OPT_D(LDR, literal) = LoadRegLiteralSub(0b01, 1), - OPT_Q(LDR, literal) = LoadRegLiteralSub(0b10, 1), -}; - -// ===== - -// clang-format off -#define LOAD_STORE_OP_LIST(V) \ - V(OP_W(STRB), 0b00, 0, 0b00), \ - V(OP_W(LDRB), 0b00, 0, 0b01), \ - V(OP_X(LDRSB), 0b00, 0, 0b10), \ - V(OP_W(LDRSB), 0b00, 0, 0b11), \ - V(OP_B(STR), 0b00, 1, 0b00), \ - V(OP_B(LDR), 0b00, 1, 0b01), \ - V(OP_Q(STR), 0b00, 1, 0b10), \ - V(OP_Q(LDR), 0b00, 1, 0b11), \ - V(OP_W(STRH), 0b01, 0, 0b00), \ - V(OP_W(LDRH), 0b01, 0, 0b01), \ - V(OP_X(LDRSH), 0b01, 0, 0b10), \ - V(OP_W(LDRSH), 0b01, 0, 0b11), \ - V(OP_H(STR), 0b01, 1, 0b00), \ - V(OP_H(LDR), 0b01, 1, 0b01), \ - V(OP_W(STR), 0b10, 0, 0b00), \ - V(OP_W(LDR), 0b10, 0, 0b01), \ - V(OP(LDRSW), 0b10, 0, 0b10), \ - V(OP_S(STR), 0b10, 1, 0b00), \ - V(OP_S(LDR), 0b10, 1, 0b01), \ - V(OP_X(STR), 0b11, 0, 0b00), \ - V(OP_X(LDR), 0b11, 0, 0b01), \ - V(OP(PRFM), 0b11, 0, 0b10), \ - V(OP_D(STR), 0b11, 1, 0b00), \ - V(OP_D(LDR), 0b11, 1, 0b01), -// clang-format on - -// Load/store -enum LoadStoreOp { -#define LoadStoreOpSub(size, V, opc) LeftShift(size, 2, 30) | LeftShift(V, 1, 26) | LeftShift(opc, 2, 22) -#define LOAD_STORE(opname, size, V, opc) OP(opname) = LoadStoreOpSub(size, V, opc) - LOAD_STORE_OP_LIST(LOAD_STORE) -#undef LOAD_STORE -}; - -// Load/store register offset. -enum LoadStoreRegisterOffsetOp { - LoadStoreRegisterOffsetFixed = 0x38200800, - LoadStoreRegisterOffsetFixedMask = 0x3B200C00, - LoadStoreRegisterOffsetMask = 0xFFE00C00, - -#define LoadStoreRegisterOffsetOpSub(size, V, opc) \ - LoadStoreRegisterOffsetFixed | LeftShift(size, 2, 30) | LeftShift(V, 1, 26) | LeftShift(opc, 2, 22) -#define LOAD_STORE_REGISTER_OFFSET(opname, size, V, opc) \ - OPT(opname, register) = LoadStoreRegisterOffsetOpSub(size, V, opc) - LOAD_STORE_OP_LIST(LOAD_STORE_REGISTER_OFFSET) -#undef LOAD_STORE_REGISTER_OFFSET -}; - -// Load/store register (unscaled immediate) -enum LoadStoreUnscaledOffsetOp { - LoadStoreUnscaledOffsetFixed = 0x38000000, - LoadStoreUnscaledOffsetFixedMask = 0x3B200C00, - LoadStoreUnscaledOffsetMask = 0xFFE00C00, - -#define LoadStoreUnscaledOffsetOpSub(size, V, opc) \ - LoadStoreUnscaledOffsetFixed | LeftShift(size, 2, 30) | LeftShift(V, 1, 26) | LeftShift(opc, 2, 22) -#define LOAD_STORE_UNSCALED(opname, size, V, opc) OPT(opname, unscaled) = LoadStoreUnscaledOffsetOpSub(size, V, opc) - LOAD_STORE_OP_LIST(LOAD_STORE_UNSCALED) -#undef LOAD_STORE_UNSCALED -}; - -// Load/store unsigned offset. -enum LoadStoreUnsignedOffset { - LoadStoreUnsignedOffsetFixed = 0x39000000, - LoadStoreUnsignedOffsetFixedMask = 0x3B000000, - LoadStoreUnsignedOffsetMask = 0xFFC00000, - -#define LoadStoreUnsignedOffsetSub(size, V, opc) \ - LoadStoreUnsignedOffsetFixed | LeftShift(size, 2, 30) | LeftShift(V, 1, 26) | LeftShift(opc, 2, 22) -#define LOAD_STORE_UNSIGNED_OFFSET(opname, size, V, opc) \ - OPT(opname, unsigned) = LoadStoreUnsignedOffsetSub(size, V, opc) - LOAD_STORE_OP_LIST(LOAD_STORE_UNSIGNED_OFFSET) -#undef LOAD_STORE_UNSIGNED_OFFSET -}; - -// ===== - -// clang-format off -#define LOAD_STORE_PAIR_OP_LIST(V) \ - V(OP_W(STP), 0b00, 0, 0), \ - V(OP_W(LDP), 0b00, 0, 1), \ - V(OP_S(STP), 0b00, 1, 0), \ - V(OP_S(LDP), 0b00, 1, 1), \ - V(OP(LDPSW), 0b01, 0, 1), \ - V(OP_D(STP), 0b01, 1, 0), \ - V(OP_D(LDP), 0b01, 1, 1), \ - V(OP_X(STP), 0b10, 0, 0), \ - V(OP_X(LDP), 0b10, 0, 1), \ - V(OP_Q(STP), 0b10, 1, 0), \ - V(OP_Q(LDP), 0b10, 1, 1) -// clang-format on - -enum LoadStorePairOp { -#define LoadStorePairOpSub(opc, V, L) LeftShift(opc, 2, 30) | LeftShift(V, 1, 26) | LeftShift(L, 1, 22) -#define LOAD_STORE_PAIR(opname, opc, V, L) OP(opname) = LoadStorePairOpSub(opc, V, L) - LOAD_STORE_PAIR_OP_LIST(LOAD_STORE_PAIR) -#undef LOAD_STORE_PAIR -}; - -enum LoadStorePairOffsetOp { - LoadStorePairOffsetFixed = 0x29000000, - LoadStorePairOffsetFixedMask = 0x3B800000, - LoadStorePairOffsetMask = 0xFFC00000, - -#define LoadStorePairOffsetOpSub(opc, V, L) \ - LoadStorePairOffsetFixed | LeftShift(opc, 2, 30) | LeftShift(V, 1, 26) | LeftShift(L, 1, 22) -#define LOAD_STORE_PAIR_OFFSET(opname, opc, V, L) OPT(opname, offset) = LoadStorePairOffsetOpSub(opc, V, L) - LOAD_STORE_PAIR_OP_LIST(LOAD_STORE_PAIR_OFFSET) -#undef LOAD_STORE_PAIR_OFFSET -}; - -enum LoadStorePairPostIndexOp { - LoadStorePairPostIndexFixed = 0x28800000, - LoadStorePairPostIndexFixedMask = 0x3B800000, - LoadStorePairPostIndexMask = 0xFFC00000, - -#define LoadStorePairPostOpSub(opc, V, L) \ - LoadStorePairPostIndexFixed | LeftShift(opc, 2, 30) | LeftShift(V, 1, 26) | LeftShift(L, 1, 22) -#define LOAD_STORE_PAIR_POST_INDEX(opname, opc, V, L) OPT(opname, post) = LoadStorePairPostOpSub(opc, V, L) - LOAD_STORE_PAIR_OP_LIST(LOAD_STORE_PAIR_POST_INDEX) -#undef LOAD_STORE_PAIR_POST_INDEX -}; - -enum LoadStorePairPreIndexOp { - LoadStorePairPreIndexFixed = 0x29800000, - LoadStorePairPreIndexFixedMask = 0x3B800000, - LoadStorePairPreIndexMask = 0xFFC00000, - -#define LoadStorePairPreOpSub(opc, V, L) \ - LoadStorePairPreIndexFixed | LeftShift(opc, 2, 30) | LeftShift(V, 1, 26) | LeftShift(L, 1, 22) -#define LOAD_STORE_PAIR_PRE_INDEX(opname, opc, V, L) OPT(opname, pre) = LoadStorePairPreOpSub(opc, V, L) - LOAD_STORE_PAIR_OP_LIST(LOAD_STORE_PAIR_PRE_INDEX) -#undef LOAD_STORE_PAIR_PRE_INDEX -}; - -// ===== - -// Generic fields. -enum GenericInstrField { SixtyFourBits = 0x80000000, ThirtyTwoBits = 0x00000000, FP32 = 0x00000000, FP64 = 0x00400000 }; - -// Generic utils -// #define sf(rd) (rd.Is64Bits() ? SixtyFourBits : ThirtyTwoBits) - -// ===== - -// Move wide immediate. -enum MoveWideImmediateOp { - MoveWideImmediateFixed = 0x12800000, - MoveWideImmediateFixedMask = 0x1F800000, - MoveWideImmediateMask = 0xFF800000, - - OP(MOVN) = 0x00000000, - OP(MOVZ) = 0x40000000, - OP(MOVK) = 0x60000000, - -#define MoveWideImmediateOpSub(sf, opc) MoveWideImmediateFixed | LeftShift(sf, 1, 31) | LeftShift(opc, 2, 29) - OP_W(MOVN) = MoveWideImmediateFixed | MOVN, - OP_X(MOVN) = MoveWideImmediateFixed | MOVN | SixtyFourBits, - OP_W(MOVZ) = MoveWideImmediateFixed | MOVZ, - OP_X(MOVZ) = MoveWideImmediateFixed | MOVZ | SixtyFourBits, - OP_W(MOVK) = MoveWideImmediateFixed | MOVK, - OP_X(MOVK) = MoveWideImmediateFixed | MOVK | SixtyFourBits -}; - -// ===== - -enum AddSubImmediateOp { - AddSubImmediateFixed = 0x11000000, - AddSubImmediateFixedMask = 0x1F000000, - AddSubImmediateMask = 0xFF000000, - -#define AddSubImmediateOpSub(sf, op, S) \ - AddSubImmediateFixed | LeftShift(sf, 1, 31) | LeftShift(op, 1, 30) | LeftShift(S, 1, 29) - OPT_W(ADD, imm) = AddSubImmediateOpSub(0, 0, 0), - OPT_W(ADDS, imm) = AddSubImmediateOpSub(0, 0, 1), - OPT_W(SUB, imm) = AddSubImmediateOpSub(0, 1, 0), - OPT_W(SUBS, imm) = AddSubImmediateOpSub(0, 1, 1), - OPT_X(ADD, imm) = AddSubImmediateOpSub(1, 0, 0), - OPT_X(ADDS, imm) = AddSubImmediateOpSub(1, 0, 1), - OPT_X(SUB, imm) = AddSubImmediateOpSub(1, 1, 0), - OPT_X(SUBS, imm) = AddSubImmediateOpSub(1, 1, 1) -}; - -enum AddSubShiftedOp { - AddSubShiftedFixed = 0x0B000000, - AddSubShiftedFixedMask = 0x1F200000, - AddSubShiftedMask = 0xFF200000, - -#define AddSubShiftedOpSub(sf, op, S) \ - AddSubShiftedFixed | LeftShift(sf, 1, 31) | LeftShift(op, 1, 30) | LeftShift(S, 1, 29) - OPT_W(ADD, shift) = AddSubShiftedOpSub(0, 0, 0), - OPT_W(ADDS, shift) = AddSubShiftedOpSub(0, 0, 1), - OPT_W(SUB, shift) = AddSubShiftedOpSub(0, 1, 0), - OPT_W(SUBS, shift) = AddSubShiftedOpSub(0, 1, 1), - OPT_X(ADD, shift) = AddSubShiftedOpSub(1, 0, 0), - OPT_X(ADDS, shift) = AddSubShiftedOpSub(1, 0, 1), - OPT_X(SUB, shift) = AddSubShiftedOpSub(1, 1, 0), - OPT_X(SUBS, shift) = AddSubShiftedOpSub(1, 1, 1) -}; - -enum AddSubExtendedOp { - AddSubExtendedFixed = 0x0B200000, - AddSubExtendedFixedMask = 0x1F200000, - AddSubExtendedMask = 0xFFE00000, - -#define AddSubExtendedOpSub(sf, op, S) \ - AddSubExtendedFixed | LeftShift(sf, 1, 31) | LeftShift(op, 1, 30) | LeftShift(S, 1, 29) - OPT_W(ADD, extend) = AddSubExtendedOpSub(0, 0, 0), - OPT_W(ADDS, extend) = AddSubExtendedOpSub(0, 0, 1), - OPT_W(SUB, extend) = AddSubExtendedOpSub(0, 1, 0), - OPT_W(SUBS, extend) = AddSubExtendedOpSub(0, 1, 1), - OPT_X(ADD, extend) = AddSubExtendedOpSub(1, 0, 0), - OPT_X(ADDS, extend) = AddSubExtendedOpSub(1, 0, 1), - OPT_X(SUB, extend) = AddSubExtendedOpSub(1, 1, 0), - OPT_X(SUBS, extend) = AddSubExtendedOpSub(1, 1, 1) -}; - -// ===== - -// Logical (immediate and shifted register). -enum LogicalOp { - LogicalOpMask = 0x60200000, - NOT = 0x00200000, - AND = 0x00000000, - BIC = AND | NOT, - ORR = 0x20000000, - ORN = ORR | NOT, - EOR = 0x40000000, - EON = EOR | NOT, - ANDS = 0x60000000, - BICS = ANDS | NOT -}; - -// Logical immediate. -enum LogicalImmediateOp { - LogicalImmediateFixed = 0x12000000, - LogicalImmediateFixedMask = 0x1F800000, - LogicalImmediateMask = 0xFF800000, - -#define W_X_OP(opname, combine_fields) \ - OPT_W(opname, imm) = LogicalImmediateFixed | combine_fields | ThirtyTwoBits, \ - OPT_X(opname, imm) = LogicalImmediateFixed | combine_fields | SixtyFourBits -#define W_X_OP_LIST(V) V(AND, AND), V(ORR, ORR), V(EOR, EOR), V(ANDS, ANDS) -#undef W_X_OP -#undef W_X_OP_LIST -}; - -// Logical shifted register. -enum LogicalShiftedOp { - LogicalShiftedFixed = 0x0A000000, - LogicalShiftedFixedMask = 0x1F000000, - LogicalShiftedMask = 0xFF200000, - -#define W_X_OP(opname, combine_fields) \ - OPT_W(opname, shift) = LogicalShiftedFixed | combine_fields | ThirtyTwoBits, \ - OPT_X(opname, shift) = LogicalShiftedFixed | combine_fields | SixtyFourBits -#define W_X_OP_LIST(V) \ - V(AND, AND), V(BIC, BIC), V(ORR, ORR), V(ORN, ORN), V(EOR, EOR), V(EON, EON), V(ANDS, ANDS), V(BICS, BICS) -#undef W_X_OP -#undef W_X_OP_LIST -}; - -// PC relative addressing. -enum PCRelAddressingOp { - PCRelAddressingFixed = 0x10000000, - PCRelAddressingFixedMask = 0x1F000000, - PCRelAddressingMask = 0x9F000000, - ADR = PCRelAddressingFixed | 0x00000000, - ADRP = PCRelAddressingFixed | 0x80000000 -}; - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/arch/arm64/registers-arm64.h b/app/src/main/cpp/Dobby/source/core/arch/arm64/registers-arm64.h deleted file mode 100644 index 84a6d6b..0000000 --- a/app/src/main/cpp/Dobby/source/core/arch/arm64/registers-arm64.h +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef ARCH_ARM64_REGISTERS -#define ARCH_ARM64_REGISTERS - -#include "core/arch/arm64/constants-arm64.h" -#include "core/arch/Cpu.h" - -namespace zz { -namespace arm64 { - -class CPURegister : RegisterBase { -public: - enum RegisterType { - kRegister_32, - kRegister_W = kRegister_32, - kRegister_64, - kRegister_X = kRegister_64, - kRegister, - - kVRegister, - kSIMD_FP_Register_8, - kSIMD_FP_Register_B = kSIMD_FP_Register_8, - kSIMD_FP_Register_16, - kSIMD_FP_Register_H = kSIMD_FP_Register_16, - kSIMD_FP_Register_32, - kSIMD_FP_Register_S = kSIMD_FP_Register_32, - kSIMD_FP_Register_64, - kSIMD_FP_Register_D = kSIMD_FP_Register_64, - kSIMD_FP_Register_128, - kSIMD_FP_Register_Q = kSIMD_FP_Register_128, - - kInvalid - }; - - constexpr CPURegister(int code, int size, RegisterType type) : RegisterBase(code), reg_size_(size), reg_type_(type) { - } - - static constexpr CPURegister Create(int code, int size, RegisterType type) { - return CPURegister(code, size, type); - } - - // ===== - - static constexpr CPURegister X(int code) { - return CPURegister(code, 64, kRegister_64); - } - - static constexpr CPURegister W(int code) { - return CPURegister(code, 32, kRegister_32); - } - - static constexpr CPURegister Q(int code) { - return CPURegister(code, 128, kSIMD_FP_Register_128); - } - - static constexpr CPURegister InvalidRegister() { - return CPURegister(0, 0, kInvalid); - } - - // ===== - - bool Is(const CPURegister ®) const { - return (reg.reg_code_ == this->reg_code_); - } - - bool Is64Bits() const { - return reg_size_ == 64; - } - - bool IsRegister() const { - return reg_type_ < kRegister; - } - - bool IsVRegister() const { - return reg_type_ > kVRegister; - } - - // ===== - - RegisterType type() const { - return reg_type_; - } - - int32_t code() const { - return reg_code_; - }; - -private: - RegisterType reg_type_; - int reg_size_; -}; - -typedef CPURegister Register; -typedef CPURegister VRegister; - -// clang-format off -#define GENERAL_REGISTER_CODE_LIST(R) \ - R(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ - R(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) \ - R(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23) \ - R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31) - -#define DEFINE_REGISTER(register_class, name, ...) constexpr register_class name = register_class::Create(__VA_ARGS__) - -#define DEFINE_REGISTERS(N) \ - DEFINE_REGISTER(Register, w##N, N, 32, CPURegister::kRegister_32); \ - DEFINE_REGISTER(Register, x##N, N, 64, CPURegister::kRegister_64); - GENERAL_REGISTER_CODE_LIST(DEFINE_REGISTERS) -#undef DEFINE_REGISTERS - -#define DEFINE_VREGISTERS(N) \ - DEFINE_REGISTER(VRegister, b##N, N, 8, CPURegister::kSIMD_FP_Register_8); \ - DEFINE_REGISTER(VRegister, h##N, N, 16, CPURegister::kSIMD_FP_Register_16); \ - DEFINE_REGISTER(VRegister, s##N, N, 32, CPURegister::kSIMD_FP_Register_32); \ - DEFINE_REGISTER(VRegister, d##N, N, 64, CPURegister::kSIMD_FP_Register_64); \ - DEFINE_REGISTER(VRegister, q##N, N, 128, CPURegister::kSIMD_FP_Register_128); \ -GENERAL_REGISTER_CODE_LIST(DEFINE_VREGISTERS) -#undef DEFINE_VREGISTERS - -#undef DEFINE_REGISTER -// clang-format on - -// ===== - -constexpr Register wzr = w31; -constexpr Register xzr = x31; - -constexpr Register SP = x31; -constexpr Register wSP = w31; -constexpr Register FP = x29; -constexpr Register wFP = w29; -constexpr Register LR = x30; -constexpr Register wLR = w30; - -} // namespace arm64 -} // namespace zz - -#define W(code) CPURegister::W(code) -#define X(code) CPURegister::X(code) -#define Q(code) CPURegister::Q(code) -#define InvalidRegister CPURegister::InvalidRegister() - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/arch/x64/constants-x64.h b/app/src/main/cpp/Dobby/source/core/arch/x64/constants-x64.h deleted file mode 100644 index d72f44f..0000000 --- a/app/src/main/cpp/Dobby/source/core/arch/x64/constants-x64.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef CORE_ARCH_CONSTANTS_X64_H -#define CORE_ARCH_CONSTANTS_X64_H - -namespace zz { -namespace x64 { - -enum ScaleFactor { - TIMES_1 = 0, - TIMES_2 = 1, - TIMES_4 = 2, - TIMES_8 = 3, - TIMES_16 = 4, - TIMES_HALF_WORD_SIZE = sizeof(void *) / 2 - 1 -}; - -enum RexBits { REX_NONE = 0, REX_B = 1 << 0, REX_X = 1 << 1, REX_R = 1 << 2, REX_W = 1 << 3, REX_PREFIX = 1 << 6 }; - -} // namespace x64 -} // namespace zz - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/arch/x64/registers-x64.h b/app/src/main/cpp/Dobby/source/core/arch/x64/registers-x64.h deleted file mode 100644 index 4c7c612..0000000 --- a/app/src/main/cpp/Dobby/source/core/arch/x64/registers-x64.h +++ /dev/null @@ -1,244 +0,0 @@ -#ifndef ARCH_X64_REGISTERS -#define ARCH_X64_REGISTERS - -#include "core/arch/x64/constants-x64.h" -#include "core/arch/Cpu.h" - -namespace zz { -namespace x64 { - -#define GENERAL_REGISTERS(V) \ - V(rax) \ - V(rcx) \ - V(rdx) \ - V(rbx) \ - V(rsp) \ - V(rbp) \ - V(rsi) \ - V(rdi) \ - V(r8) \ - V(r9) \ - V(r10) \ - V(r11) \ - V(r12) \ - V(r13) \ - V(r14) \ - V(r15) - -#define GENERAL_32_REGISTERS(V) \ - V(eax) \ - V(ecx) \ - V(edx) \ - V(ebx) \ - V(esp) \ - V(ebp) \ - V(esi) \ - V(edi) - -#define GENERAL_16_REGISTERS(V) \ - V(ax) \ - V(cx) \ - V(dx) \ - V(bx) \ - V(sp) \ - V(bp) \ - V(si) \ - V(di) - -#define GENERAL_8H_REGISTERS(V) \ - V(ah) \ - V(ch) \ - V(dh) \ - V(bh) - -#define GENERAL_8L_REGISTERS(V) \ - V(al) \ - V(cl) \ - V(dl) \ - V(bl) - -// clang-format off -enum RegisterCode { -#define REGISTER_CODE(R) kRegCode_##R, - kRegisterCodeStart8L = -1, - GENERAL_8L_REGISTERS(REGISTER_CODE) - kRegisterCodeStart8H = -1, - GENERAL_8H_REGISTERS(REGISTER_CODE) - kRegisterCodeStart16 = -1, - GENERAL_16_REGISTERS(REGISTER_CODE) - kRegisterCodeStart32 = -1, - GENERAL_32_REGISTERS(REGISTER_CODE) - kRegisterCodeStart64 = -1, - GENERAL_REGISTERS(REGISTER_CODE) -#undef REGISTER_CODE - kRegAfterLast -}; -// clang-format on - -class CPURegister : public RegisterBase { -public: - enum RegisterType { kDefault, kInvalid }; - - constexpr CPURegister(int code, int size, RegisterType type) : RegisterBase(code), reg_size_(size), reg_type_(type) { - } - - static constexpr CPURegister Create(int code, int size, RegisterType type) { - return CPURegister(code, size, type); - } - - static constexpr CPURegister from_code(int code) { - return CPURegister(code, 0, kDefault); - } - - static constexpr CPURegister InvalidRegister() { - return CPURegister(0, 0, kInvalid); - } - - bool Is64Bits() const { - return reg_size_ == 64; - } - - RegisterType type() const { - return reg_type_; - } - -public: - bool is_byte_register() const { - return reg_code_ <= 3; - } - - // Return the high bit of the register code as a 0 or 1. Used often - // when constructing the REX prefix byte. - int high_bit() const { - return reg_code_ >> 3; - } - - // Return the 3 low bits of the register code. Used when encoding registers - // in modR/M, SIB, and opcode bytes. - int low_bits() const { - return reg_code_ & 0x7; - } - - int size() { - return reg_size_; - } - -private: - RegisterType reg_type_; - int reg_size_; -}; - -typedef CPURegister Register; - -#define DECLARE_REGISTER(R) constexpr Register R = Register::Create(kRegCode_##R, 64, CPURegister::kDefault); -GENERAL_REGISTERS(DECLARE_REGISTER) -#undef DECLARE_REGISTER - -#define DECLARE_REGISTER(R) constexpr Register R = Register::Create(kRegCode_##R, 8, CPURegister::kDefault); -GENERAL_8H_REGISTERS(DECLARE_REGISTER) -#undef DECLARE_REGISTER - -#define DECLARE_REGISTER(R) constexpr Register R = Register::Create(kRegCode_##R, 8, CPURegister::kDefault); -GENERAL_8L_REGISTERS(DECLARE_REGISTER) -#undef DECLARE_REGISTER - -#define DECLARE_REGISTER(R) constexpr Register R = Register::Create(kRegCode_##R, 16, CPURegister::kDefault); -GENERAL_16_REGISTERS(DECLARE_REGISTER) -#undef DECLARE_REGISTER - -#define DECLARE_REGISTER(R) constexpr Register R = Register::Create(kRegCode_##R, 32, CPURegister::kDefault); -GENERAL_32_REGISTERS(DECLARE_REGISTER) -#undef DECLARE_REGISTER - -#ifdef _WIN64 -// Windows calling convention -constexpr Register arg_reg_1 = rcx; -constexpr Register arg_reg_2 = rdx; -constexpr Register arg_reg_3 = r8; -constexpr Register arg_reg_4 = r9; -#else -// AMD64 calling convention -constexpr Register arg_reg_1 = rdi; -constexpr Register arg_reg_2 = rsi; -constexpr Register arg_reg_3 = rdx; -constexpr Register arg_reg_4 = rcx; -#endif // _WIN64 - -#define DOUBLE_REGISTERS(V) \ - V(xmm0) \ - V(xmm1) \ - V(xmm2) \ - V(xmm3) \ - V(xmm4) \ - V(xmm5) \ - V(xmm6) \ - V(xmm7) \ - V(xmm8) \ - V(xmm9) \ - V(xmm10) \ - V(xmm11) \ - V(xmm12) \ - V(xmm13) \ - V(xmm14) \ - V(xmm15) - -#define FLOAT_REGISTERS DOUBLE_REGISTERS -#define SIMD128_REGISTERS DOUBLE_REGISTERS - -constexpr bool kPadArguments = false; -constexpr bool kSimpleFPAliasing = true; -constexpr bool kSimdMaskRegisters = false; - -enum DoubleRegisterCode { -#define REGISTER_CODE(R) kDoubleCode_##R, - DOUBLE_REGISTERS(REGISTER_CODE) -#undef REGISTER_CODE - kDoubleAfterLast -}; - -class XMMRegister : public RegisterBase { -public: - enum RegisterType { kInvalid }; - - constexpr XMMRegister(int code) : RegisterBase(code) { - } - - static constexpr XMMRegister Create(int code) { - return XMMRegister(code); - } - - static constexpr XMMRegister InvalidRegister() { - return XMMRegister(0); - } - -public: - // Return the high bit of the register code as a 0 or 1. Used often - // when constructing the REX prefix byte. - int high_bit() const { - return reg_code_ >> 3; - } - // Return the 3 low bits of the register code. Used when encoding registers - // in modR/M, SIB, and opcode bytes. - int low_bits() const { - return reg_code_ & 0x7; - } - -private: -}; - -typedef XMMRegister FloatRegister; - -typedef XMMRegister DoubleRegister; - -typedef XMMRegister Simd128Register; - -typedef XMMRegister FPURegister; - -#define DECLARE_REGISTER(R) constexpr DoubleRegister R = DoubleRegister::Create(kDoubleCode_##R); -DOUBLE_REGISTERS(DECLARE_REGISTER) -#undef DECLARE_REGISTER - -} // namespace x64 -} // namespace zz - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/arch/x86/constants-x86.h b/app/src/main/cpp/Dobby/source/core/arch/x86/constants-x86.h deleted file mode 100644 index a243a76..0000000 --- a/app/src/main/cpp/Dobby/source/core/arch/x86/constants-x86.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef CORE_ARCH_CONSTANTS_X86_H -#define CORE_ARCH_CONSTANTS_X86_H - -namespace zz { -namespace x86 { - -enum ScaleFactor { - TIMES_1 = 0, - TIMES_2 = 1, - TIMES_4 = 2, - TIMES_8 = 3, - TIMES_16 = 4, - TIMES_HALF_WORD_SIZE = sizeof(void *) / 2 - 1 -}; - -} // namespace x86 -} // namespace zz - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/arch/x86/cpu-x86.cc b/app/src/main/cpp/Dobby/source/core/arch/x86/cpu-x86.cc deleted file mode 100644 index bd29a56..0000000 --- a/app/src/main/cpp/Dobby/source/core/arch/x86/cpu-x86.cc +++ /dev/null @@ -1,98 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) - -#include "cpu-x86.h" - -X86CpuInfo::X86CpuInfo() { - icache_line_size_ = 0; - dcache_line_size_ = 0; - has_fpu_ = false; - has_cmov_ = false; - has_sahf_ = false; - has_mmx_ = false; - has_sse_ = false; - has_sse2_ = false; - has_sse3_ = false; - has_ssse3_ = false; - has_sse41_ = false; - - has_sse42_ = false; - has_osxsave_ = false; - has_avx_ = false; - has_fma3_ = false; - has_bmi1_ = false; - has_bmi2_ = false; - has_lzcnt_ = false; - has_popcnt_ = false; - is_atom_ = false; - - memcpy(vendor_, (void *)"Unknown", 8); -#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 - int cpu_info[4]; - __cpuid(cpu_info, 0); - unsigned num_ids = cpu_info[0]; - std::swap(cpu_info[2], cpu_info[3]); - _memcpy(vendor_, cpu_info + 1, 12); - vendor_[12] = '\0'; - - // Interpret CPU feature information. - if (num_ids > 0) { - __cpuid(cpu_info, 1); - stepping_ = cpu_info[0] & 0xF; - model_ = ((cpu_info[0] >> 4) & 0xF) + ((cpu_info[0] >> 12) & 0xF0); - family_ = (cpu_info[0] >> 8) & 0xF; - type_ = (cpu_info[0] >> 12) & 0x3; - ext_model_ = (cpu_info[0] >> 16) & 0xF; - ext_family_ = (cpu_info[0] >> 20) & 0xFF; - has_fpu_ = (cpu_info[3] & 0x00000001) != 0; - has_cmov_ = (cpu_info[3] & 0x00008000) != 0; - has_mmx_ = (cpu_info[3] & 0x00800000) != 0; - has_sse_ = (cpu_info[3] & 0x02000000) != 0; - has_sse2_ = (cpu_info[3] & 0x04000000) != 0; - has_sse3_ = (cpu_info[2] & 0x00000001) != 0; - has_ssse3_ = (cpu_info[2] & 0x00000200) != 0; - has_sse41_ = (cpu_info[2] & 0x00080000) != 0; - has_sse42_ = (cpu_info[2] & 0x00100000) != 0; - has_popcnt_ = (cpu_info[2] & 0x00800000) != 0; - has_osxsave_ = (cpu_info[2] & 0x08000000) != 0; - has_avx_ = (cpu_info[2] & 0x10000000) != 0; - has_fma3_ = (cpu_info[2] & 0x00001000) != 0; - if (family_ == 0x6) { - switch (model_) { - case 0x1C: // SLT - case 0x26: - case 0x36: - case 0x27: - case 0x35: - case 0x37: // SLM - case 0x4A: - case 0x4D: - case 0x4C: // AMT - case 0x6E: - is_atom_ = true; - } - } - } - - // There are separate feature flags for VEX-encoded GPR instructions. - if (num_ids >= 7) { - __cpuid(cpu_info, 7); - has_bmi1_ = (cpu_info[1] & 0x00000008) != 0; - has_bmi2_ = (cpu_info[1] & 0x00000100) != 0; - } - - // Query extended IDs. - __cpuid(cpu_info, 0x80000000); - unsigned num_ext_ids = cpu_info[0]; - - // Interpret extended CPU feature information. - if (num_ext_ids > 0x80000000) { - __cpuid(cpu_info, 0x80000001); - has_lzcnt_ = (cpu_info[2] & 0x00000020) != 0; - // SAHF must be probed in long mode. - has_sahf_ = (cpu_info[2] & 0x00000001) != 0; - } -#endif -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/arch/x86/cpu-x86.h b/app/src/main/cpp/Dobby/source/core/arch/x86/cpu-x86.h deleted file mode 100644 index 68fd62c..0000000 --- a/app/src/main/cpp/Dobby/source/core/arch/x86/cpu-x86.h +++ /dev/null @@ -1,120 +0,0 @@ -#ifndef CORE_ARCH_CPU_X86_H -#define CORE_ARCH_CPU_X86_H - -#include "core/arch/Cpu.h" - -class X86CpuInfo { - -public: - X86CpuInfo(); - -public: - // General features - bool has_fpu() const { - return has_fpu_; - } - int icache_line_size() const { - return icache_line_size_; - } - int dcache_line_size() const { - return dcache_line_size_; - } - - static const int UNKNOWN_CACHE_LINE_SIZE = 0; - - // x86 features - bool has_cmov() const { - return has_cmov_; - } - bool has_sahf() const { - return has_sahf_; - } - bool has_mmx() const { - return has_mmx_; - } - bool has_sse() const { - return has_sse_; - } - bool has_sse2() const { - return has_sse2_; - } - bool has_sse3() const { - return has_sse3_; - } - bool has_ssse3() const { - return has_ssse3_; - } - bool has_sse41() const { - return has_sse41_; - } - bool has_sse42() const { - return has_sse42_; - } - bool has_osxsave() const { - return has_osxsave_; - } - bool has_avx() const { - return has_avx_; - } - bool has_fma3() const { - return has_fma3_; - } - bool has_bmi1() const { - return has_bmi1_; - } - bool has_bmi2() const { - return has_bmi2_; - } - bool has_lzcnt() const { - return has_lzcnt_; - } - bool has_popcnt() const { - return has_popcnt_; - } - bool is_atom() const { - return is_atom_; - } - -private: - char vendor_[13]; - - // General features - int icache_line_size_; - int dcache_line_size_; - bool has_fpu_; - - // x86 features - bool has_cmov_; - bool has_sahf_; - bool has_mmx_; - bool has_sse_; - bool has_sse2_; - bool has_sse3_; - bool has_ssse3_; - bool has_sse41_; - bool has_sse42_; - bool has_osxsave_; - bool has_avx_; - bool has_fma3_; - bool has_bmi1_; - bool has_bmi2_; - bool has_lzcnt_; - bool has_popcnt_; - bool is_atom_; -}; - -class X86CpuFeatures : public CpuFeatures { -public: - static bool sse2_supported() { - return X86CpuInfo().has_sse2(); - } - static bool sse4_1_supported() { - return X86CpuInfo().has_sse41(); - } - -private: - static bool sse2_supported_; - static bool sse4_1_supported_; -}; - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/arch/x86/registers-x86.h b/app/src/main/cpp/Dobby/source/core/arch/x86/registers-x86.h deleted file mode 100644 index 65b06b2..0000000 --- a/app/src/main/cpp/Dobby/source/core/arch/x86/registers-x86.h +++ /dev/null @@ -1,124 +0,0 @@ -#ifndef ARCH_IA32_REGISTERS -#define ARCH_IA32_REGISTERS - -#include "core/arch/x86/constants-x86.h" -#include "core/arch/Cpu.h" - -namespace zz { -namespace x86 { - -#define GENERAL_REGISTERS(V) \ - V(eax) \ - V(ecx) \ - V(edx) \ - V(ebx) \ - V(esp) \ - V(ebp) \ - V(esi) \ - V(edi) - -enum RegisterCode { -#define REGISTER_CODE(R) kRegCode_##R, - GENERAL_REGISTERS(REGISTER_CODE) -#undef REGISTER_CODE - kRegAfterLast -}; - -class CPURegister : public RegisterBase { -public: - enum RegisterType { kDefault, kInvalid }; - - constexpr CPURegister(int code, int size, RegisterType type) : RegisterBase(code), reg_size_(size), reg_type_(type) { - } - - static constexpr CPURegister Create(int code, int size, RegisterType type) { - return CPURegister(code, size, type); - } - - static constexpr CPURegister from_code(int code) { - return CPURegister(code, 0, kDefault); - } - - static constexpr CPURegister InvalidRegister() { - return CPURegister(0, 0, kInvalid); - } - - RegisterType type() const { - return reg_type_; - } - -public: - bool is_byte_register() const { - return reg_code_ <= 3; - } - - int size() { - return reg_size_; - } - -private: - RegisterType reg_type_; - int reg_size_; -}; - -typedef CPURegister Register; - -#define DEFINE_REGISTER(R) constexpr Register R = Register::Create(kRegCode_##R, 32, CPURegister::kDefault); -GENERAL_REGISTERS(DEFINE_REGISTER) -#undef DEFINE_REGISTER - -#define DOUBLE_REGISTERS(V) \ - V(xmm0) \ - V(xmm1) \ - V(xmm2) \ - V(xmm3) \ - V(xmm4) \ - V(xmm5) \ - V(xmm6) \ - V(xmm7) - -#define FLOAT_REGISTERS DOUBLE_REGISTERS -#define SIMD128_REGISTERS DOUBLE_REGISTERS - -constexpr bool kPadArguments = false; -constexpr bool kSimpleFPAliasing = true; -constexpr bool kSimdMaskRegisters = false; - -enum DoubleRegisterCode { -#define REGISTER_CODE(R) kDoubleCode_##R, - DOUBLE_REGISTERS(REGISTER_CODE) -#undef REGISTER_CODE - kDoubleAfterLast -}; - -class XMMRegister : public RegisterBase { -public: - enum RegisterType { kInvalid }; - - constexpr XMMRegister(int code) : RegisterBase(code) { - } - - static constexpr XMMRegister Create(int code) { - return XMMRegister(code); - } - - static constexpr XMMRegister InvalidRegister() { - return XMMRegister(0); - } - -private: -}; - -typedef XMMRegister FloatRegister; -typedef XMMRegister DoubleRegister; -typedef XMMRegister Simd128Register; -typedef XMMRegister FPURegister; - -#define DEFINE_REGISTER(R) constexpr DoubleRegister R = DoubleRegister::Create(kDoubleCode_##R); -DOUBLE_REGISTERS(DEFINE_REGISTER) -#undef DEFINE_REGISTER - -} // namespace x86 -} // namespace zz - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/assembler/AssemblerPseudoLabel.h b/app/src/main/cpp/Dobby/source/core/assembler/AssemblerPseudoLabel.h deleted file mode 100644 index 362d1e2..0000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/AssemblerPseudoLabel.h +++ /dev/null @@ -1,94 +0,0 @@ -#pragma once - -#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" - -class Label { -public: - Label(addr_t addr) : pos_(addr) { - } - -protected: - addr_t pos_; -}; - -class AssemblerPseudoLabel : public Label { -public: - typedef struct { - int type_; - vmaddr_t vmaddr_; - off_t offset_; - } ref_label_inst_t; - -public: - AssemblerPseudoLabel() : AssemblerPseudoLabel(0) { - } - - AssemblerPseudoLabel(vmaddr_t addr) : Label(addr) { - ref_label_insts_.reserve(4); - - pos_ = addr; - relocated_pos_ = 0; - } - - ~AssemblerPseudoLabel(void) { - } - - void link_confused_instructions(CodeBufferBase *buffer); - - bool has_confused_instructions() { - return ref_label_insts_.size(); - } - - void link_confused_instructions(); - - void link_to(int type, vmaddr_t inst_vmaddr, off_t offset) { - ref_label_inst_t inst; - inst.type_ = type; - inst.vmaddr_ = inst_vmaddr; - inst.offset_ = offset; - ref_label_insts_.push_back(inst); - } - -private: - addr_t relocated_pos_; - -public: - addr_t relocated_pos() { - return relocated_pos_; - }; - - void bind_to(vmaddr_t addr) { - relocated_pos_ = addr; - } - - void relocate_to(vmaddr_t addr) { - bind_to(addr); - } - -protected: - std::vector ref_label_insts_; -}; - -// --- - -struct RelocLabel : public AssemblerPseudoLabel { -public: - RelocLabel() : AssemblerPseudoLabel(0) { - } - - template RelocLabel(T value) : AssemblerPseudoLabel(0) { - *(T *)data_ = value; - data_size_ = sizeof(value); - } - - template T data() { - return *(T *)data_; - } - - template void fixup_data(T value) { - *(T *)data_ = value; - } - - uint8_t data_[8]; - int data_size_; -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler-arch.h b/app/src/main/cpp/Dobby/source/core/assembler/assembler-arch.h deleted file mode 100644 index 23ae9c3..0000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler-arch.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef CORE_ASSEMBLER_ARCH_H -#define CORE_ASSEMBLER_ARCH_H - -#include "src/assembler.h" - -#if 0 -#if TARGET_ARCH_IA32 -#include "src/ia32/assembler-ia32.h" -#elif TARGET_ARCH_X64 -#include "src/x64/assembler-x64.h" -#elif TARGET_ARCH_ARM64 -#include "src/arm64/assembler-arm64.h" -#elif TARGET_ARCH_ARM -#include "src/arm/assembler-arm.h" -#elif TARGET_ARCH_PPC -#include "src/ppc/assembler-ppc.h" -#elif TARGET_ARCH_MIPS -#include "src/mips/assembler-mips.h" -#elif TARGET_ARCH_MIPS64 -#include "src/mips64/assembler-mips64.h" -#elif TARGET_ARCH_S390 -#include "src/s390/assembler-s390.h" -#else -#error Unknown architecture. -#endif -#endif - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler-arm.cc b/app/src/main/cpp/Dobby/source/core/assembler/assembler-arm.cc deleted file mode 100644 index 56aaab5..0000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler-arm.cc +++ /dev/null @@ -1,41 +0,0 @@ -#include "platform_macro.h" -#if TARGET_ARCH_ARM - -#include "core/assembler/assembler-arm.h" - -void AssemblerPseudoLabel::link_confused_instructions(CodeBufferBase *buffer) { - CodeBuffer *_buffer = (CodeBuffer *)buffer; - - for (auto &ref_label_inst : ref_label_insts_) { - arm_inst_t inst = _buffer->LoadARMInst(ref_label_inst.offset_); - if (ref_label_inst.type_ == kLdrLiteral) { - int64_t pc = ref_label_inst.offset_ + ARM_PC_OFFSET; - assert(pc % 4 == 0); - int32_t imm12 = relocated_pos() - pc; - if (imm12 > 0) { - set_bit(inst, 23, 1); - } else { - set_bit(inst, 23, 0); - imm12 = -imm12; - } - set_bits(inst, 0, 11, imm12); - } - _buffer->RewriteARMInst(ref_label_inst.offset_, inst); - } -} - -namespace zz { -namespace arm { - -void Assembler::EmitARMInst(arm_inst_t instr) { - buffer_->EmitARMInst(instr); -} - -void Assembler::EmitAddress(uint32_t value) { - buffer_->Emit32(value); -} - -} // namespace arm -} // namespace zz - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler-arm.h b/app/src/main/cpp/Dobby/source/core/assembler/assembler-arm.h deleted file mode 100644 index af181ac..0000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler-arm.h +++ /dev/null @@ -1,357 +0,0 @@ -#ifndef CORE_ASSEMBLER_ARM_H -#define CORE_ASSEMBLER_ARM_H - -#include "common_header.h" - -#include "core/arch/arm/constants-arm.h" -#include "core/arch/arm/registers-arm.h" -#include "core/assembler/assembler.h" - -#include "MemoryAllocator/CodeBuffer/code_buffer_arm.h" - -enum ref_label_type_t { kLdrLiteral }; - -namespace zz { -namespace arm { - -// ARM design had a 3-stage pipeline (fetch-decode-execute) -#define ARM_PC_OFFSET 8 -#define Thumb_PC_OFFSET 4 - -// define instruction length -#define ARM_INST_LEN 4 -#define Thumb1_INST_LEN 2 -#define Thumb2_INST_LEN 4 - -// Thumb instructions address is odd -#define THUMB_ADDRESS_FLAG 1 - -constexpr Register TMP_REG_0 = r12; - -constexpr Register VOLATILE_REGISTER = r12; - -#define Rd(rd) (rd.code() << kRdShift) -#define Rt(rt) (rt.code() << kRtShift) -#define Rn(rn) (rn.code() << kRnShift) -#define Rm(rm) (rm.code() << kRmShift) - -// --- - -class Operand { - friend class OpEncode; - -public: - Operand(int immediate) : imm_(immediate), rm_(no_reg), shift_(LSL), shift_imm_(0), rs_(no_reg) { - } - - Operand(Register rm) : imm_(0), rm_(rm), shift_(LSL), shift_imm_(0), rs_(no_reg) { - } - - Operand(Register rm, Shift shift, uint32_t shift_imm) - : imm_(0), rm_(rm), shift_(shift), shift_imm_(shift_imm), rs_(no_reg) { - } - - Operand(Register rm, Shift shift, Register rs) : imm_(0), rm_(rm), shift_(shift), shift_imm_(0), rs_(rs) { - } - -public: - int GetImmediate() const { - return imm_; - } - -private: - Register rm_; - Register rs_; - - Shift shift_; - int shift_imm_; - - int imm_; - -private: - friend class EncodeUtility; -}; - -// --- - -class MemOperand { - friend class OpEncode; - -public: - MemOperand(Register rn, int32_t offset = 0, AddrMode addrmode = Offset) - : rn_(rn), offset_(offset), rm_(no_reg), shift_(LSL), shift_imm_(0), addrmode_(addrmode) { - } - - MemOperand(Register rn, Register rm, AddrMode addrmode = Offset) - : rn_(rn), offset_(0), rm_(rm), shift_(LSL), shift_imm_(0), addrmode_(addrmode) { - } - - MemOperand(Register rn, Register rm, Shift shift, uint32_t shift_imm, AddrMode addrmode = Offset) - : rn_(rn), offset_(0), rm_(rm), shift_(shift), shift_imm_(shift_imm), addrmode_(addrmode) { - } - - const Register &rn() const { - return rn_; - } - const Register &rm() const { - return rm_; - } - int32_t offset() const { - return offset_; - } - - bool IsImmediateOffset() const { - return (addrmode_ == Offset); - } - bool IsRegisterOffset() const { - return (addrmode_ == Offset); - } - bool IsPreIndex() const { - return addrmode_ == PreIndex; - } - bool IsPostIndex() const { - return addrmode_ == PostIndex; - } - -private: - Register rn_; // base - Register rm_; // register offset - - int32_t offset_; // valid if rm_ == no_reg - - Shift shift_; - uint32_t shift_imm_; // valid if rm_ != no_reg && rs_ == no_reg - - AddrMode addrmode_; // bits P, U, and W -}; - -// --- - -class OpEncode { -public: - static uint32_t MemOperand(const MemOperand operand) { - uint32_t encoding = 0; - if (operand.rm_.IsValid()) { - UNREACHABLE(); - } - - // sign - uint32_t U = 0; - if (operand.offset_ >= 0) { - U = (1 << 23); - } - encoding |= U; - - // offset - encoding |= bits(abs(operand.offset_), 0, 11); - - // addr mode - uint32_t P, W; - if (operand.addrmode_ == Offset) { - P = 1; - W = 0; - } else if (operand.addrmode_ == PostIndex) { - P = 0; - W = 0; - } else if (operand.addrmode_ == PreIndex) { - P = 1; - W = 1; - } - encoding |= ((P << 24) | (W << 21)); - - // rn - encoding |= Rn(operand.rn_); - - return encoding; - } - - static uint32_t Operand(const Operand operand) { - uint32_t encoding = 0; - if (operand.rm_.IsValid()) { - encoding = static_cast(operand.rm_.code()); - } else { - encoding = operand.GetImmediate(); - } - - return encoding; - } -}; - -// --- - -enum ExecuteState { ARMExecuteState, ThumbExecuteState }; - -class Assembler : public AssemblerBase { -private: - ExecuteState execute_state_; - -public: - Assembler(void *address) : AssemblerBase(address) { - execute_state_ = ARMExecuteState; - buffer_ = new CodeBuffer(); - } - - // shared_ptr is better choice - // but we can't use it at kernelspace - Assembler(void *address, CodeBuffer *buffer) : AssemblerBase(address) { - execute_state_ = ARMExecuteState; - buffer_ = buffer; - } - - void ClearCodeBuffer() { - buffer_ = NULL; - } - -public: - void SetExecuteState(ExecuteState state) { - execute_state_ = state; - } - ExecuteState GetExecuteState() { - return execute_state_; - } - - void SetRealizedAddress(void *address) { - DCHECK_EQ(0, reinterpret_cast(address) % 4); - AssemblerBase::SetRealizedAddress(address); - } - - void EmitARMInst(arm_inst_t instr); - - void EmitAddress(uint32_t value); - -public: - void sub(Register rd, Register rn, const Operand &operand) { - uint32_t encoding = B25 | B22; - add_sub(encoding, AL, rd, rn, operand); - } - - void add(Register rd, Register rn, const Operand &operand) { - uint32_t encoding = B25 | B23; - add_sub(encoding, AL, rd, rn, operand); - } - - void add_sub(uint32_t encoding, Condition cond, Register rd, Register rn, const Operand &operand) { - encoding |= (cond << kConditionShift); - - uint32_t imm = operand.GetImmediate(); - encoding |= imm; - - encoding |= Rd(rd); - - encoding |= Rn(rn); - - buffer_->EmitARMInst(encoding); - } - - void ldr(Register rt, const MemOperand &operand) { - uint32_t encoding = B20 | B26; - load_store(encoding, AL, rt, operand); - } - - void str(Register rt, const MemOperand &operand) { - uint32_t encoding = B26; - load_store(encoding, AL, rt, operand); - } - - void load_store(uint32_t encoding, Condition cond, Register rt, const MemOperand &operand) { - encoding |= (cond << kConditionShift); - encoding |= Rt(rt) | OpEncode::MemOperand(operand); - buffer_->EmitARMInst(encoding); - } - - void mov(Register rd, const Operand &operand) { - mov(AL, rd, operand); - } - - void mov(Condition cond, Register rd, const Operand &operand) { - uint32_t encoding = 0x01a00000; - encoding |= (cond << kConditionShift); - encoding |= Rd(rd) | OpEncode::Operand(operand); - buffer_->EmitARMInst(encoding); - } - - // Branch instructions. - void b(int branch_offset) { - b(AL, branch_offset); - } - void b(Condition cond, int branch_offset) { - uint32_t encoding = 0xa000000; - encoding |= (cond << kConditionShift); - uint32_t imm24 = bits(branch_offset >> 2, 0, 23); - encoding |= imm24; - buffer_->EmitARMInst(encoding); - } - - void bl(int branch_offset) { - bl(AL, branch_offset); - } - void bl(Condition cond, int branch_offset) { - uint32_t encoding = 0xb000000; - encoding |= (cond << kConditionShift); - uint32_t imm24 = bits(branch_offset >> 2, 0, 23); - encoding |= imm24; - buffer_->EmitARMInst(encoding); - } - - void blx(int branch_offset) { - UNIMPLEMENTED(); - } - void blx(Register target, Condition cond = AL) { - UNIMPLEMENTED(); - } - void bx(Register target, Condition cond = AL) { - UNIMPLEMENTED(); - } - -}; // namespace arm - -// --- - -class TurboAssembler : public Assembler { -public: - TurboAssembler(void *address) : Assembler(address) { - } - - ~TurboAssembler() { - } - - TurboAssembler(void *address, CodeBuffer *buffer) : Assembler(address, buffer) { - } - - void Ldr(Register rt, AssemblerPseudoLabel *label) { - if (label->relocated_pos()) { - int offset = label->relocated_pos() - buffer_->GetBufferSize(); - ldr(rt, MemOperand(pc, offset)); - } else { - // record this ldr, and fix later. - label->link_to(kLdrLiteral, 0, buffer_->GetBufferSize()); - ldr(rt, MemOperand(pc, 0)); - } - } - - void CallFunction(ExternalReference function) { - // trick: use bl to replace lr register - bl(0); - b(4); - ldr(pc, MemOperand(pc, -4)); - buffer_->Emit32((uint32_t)(uintptr_t)function.address()); - } - - void Move32Immeidate(Register rd, const Operand &x, Condition cond = AL) { - } - - void RelocLabelFixup(tinystl::unordered_map *relocated_offset_map) { - for (auto *data_label : data_labels_) { - auto val = data_label->data(); - auto iter = relocated_offset_map->find(val); - if (iter != relocated_offset_map->end()) { - data_label->fixup_data(iter->second); - } - } - } -}; - -} // namespace arm -} // namespace zz - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler-arm64.cc b/app/src/main/cpp/Dobby/source/core/assembler/assembler-arm64.cc deleted file mode 100644 index 1cb7836..0000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler-arm64.cc +++ /dev/null @@ -1,25 +0,0 @@ -#include "platform_macro.h" -#if TARGET_ARCH_ARM64 - -#include "core/assembler/assembler-arm64.h" - -void AssemblerPseudoLabel::link_confused_instructions(CodeBufferBase *buffer) { - CodeBuffer *_buffer = (CodeBuffer *)buffer; - - for (auto &ref_label_inst : ref_label_insts_) { - int64_t fixup_offset = relocated_pos() - ref_label_inst.offset_; - - arm64_inst_t inst = _buffer->LoadInst(ref_label_inst.offset_); - arm64_inst_t new_inst = 0; - - if (ref_label_inst.type_ == kLabelImm19) { - new_inst = encode_imm19_offset(inst, fixup_offset); - } - - _buffer->RewriteInst(ref_label_inst.offset_, new_inst); - } -} - -using namespace zz::arm64; - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler-arm64.h b/app/src/main/cpp/Dobby/source/core/assembler/assembler-arm64.h deleted file mode 100644 index 53b8c2a..0000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler-arm64.h +++ /dev/null @@ -1,563 +0,0 @@ -#ifndef CORE_ASSEMBLER_ARM64_H -#define CORE_ASSEMBLER_ARM64_H - -#include "dobby_internal.h" - -#include "core/arch/arm64/constants-arm64.h" -#include "core/arch/arm64/registers-arm64.h" -#include "core/assembler/assembler.h" - -#include "MemoryAllocator/CodeBuffer/code_buffer_arm64.h" - -#include "InstructionRelocation/arm64/inst_decode_encode_kit.h" - -static inline uint16_t Low16Bits(uint32_t value) { - return static_cast(value & 0xffff); -} - -static inline uint16_t High16Bits(uint32_t value) { - return static_cast(value >> 16); -} - -static inline uint32_t Low32Bits(uint64_t value) { - return static_cast(value); -} - -static inline uint32_t High32Bits(uint64_t value) { - return static_cast(value >> 32); -} - -enum ref_label_type_t { kLabelImm19 }; - -namespace zz { -namespace arm64 { - -constexpr Register TMP_REG_0 = X(ARM64_TMP_REG_NDX_0); - -#define Rd(rd) (rd.code() << kRdShift) -#define Rt(rt) (rt.code() << kRtShift) -#define Rt2(rt) (rt.code() << kRt2Shift) -#define Rn(rn) (rn.code() << kRnShift) -#define Rm(rm) (rm.code() << kRmShift) - -// --- - -class Operand { -public: - inline explicit Operand(int64_t imm) - : immediate_(imm), reg_(InvalidRegister), shift_(NO_SHIFT), extend_(NO_EXTEND), shift_extent_imm_(0) { - } - inline Operand(Register reg, Shift shift = LSL, int32_t shift_imm = 0) - : immediate_(0), reg_(reg), shift_(shift), extend_(NO_EXTEND), shift_extent_imm_(shift_imm) { - } - inline Operand(Register reg, Extend extend, int32_t shift_imm = 0) - : immediate_(0), reg_(reg), shift_(NO_SHIFT), extend_(extend), shift_extent_imm_(shift_imm) { - } - - bool IsImmediate() const { - return reg_.Is(InvalidRegister); - } - bool IsShiftedRegister() const { - return /* reg_.IsValid() && */ (shift_ != NO_SHIFT); - } - bool IsExtendedRegister() const { - return /* reg_.IsValid() && */ (extend_ != NO_EXTEND); - } - - Register reg() const { - DCHECK((IsShiftedRegister() || IsExtendedRegister())); - return reg_; - } - int64_t Immediate() const { - return immediate_; - } - Shift shift() const { - DCHECK(IsShiftedRegister()); - return shift_; - } - Extend extend() const { - DCHECK(IsExtendedRegister()); - return extend_; - } - int32_t shift_extend_imm() const { - return shift_extent_imm_; - } - -private: - int64_t immediate_; - - Register reg_; - - Shift shift_; - Extend extend_; - int32_t shift_extent_imm_; -}; - -// --- - -class MemOperand { -public: - inline explicit MemOperand(Register base, int64_t offset = 0, AddrMode addrmode = Offset) - : base_(base), regoffset_(InvalidRegister), offset_(offset), addrmode_(addrmode), shift_(NO_SHIFT), - extend_(NO_EXTEND), shift_extend_imm_(0) { - } - - inline explicit MemOperand(Register base, Register regoffset, Extend extend, unsigned extend_imm) - : base_(base), regoffset_(regoffset), offset_(0), addrmode_(Offset), shift_(NO_SHIFT), extend_(extend), - shift_extend_imm_(extend_imm) { - } - - inline explicit MemOperand(Register base, Register regoffset, Shift shift = LSL, unsigned shift_imm = 0) - : base_(base), regoffset_(regoffset), offset_(0), addrmode_(Offset), shift_(shift), extend_(NO_EXTEND), - shift_extend_imm_(shift_imm) { - } - - inline explicit MemOperand(Register base, const Operand &offset, AddrMode addrmode = Offset) - : base_(base), regoffset_(InvalidRegister), addrmode_(addrmode) { - if (offset.IsShiftedRegister()) { - regoffset_ = offset.reg(); - shift_ = offset.shift(); - shift_extend_imm_ = offset.shift_extend_imm(); - - extend_ = NO_EXTEND; - offset_ = 0; - } else if (offset.IsExtendedRegister()) { - regoffset_ = offset.reg(); - extend_ = offset.extend(); - shift_extend_imm_ = offset.shift_extend_imm(); - - shift_ = NO_SHIFT; - offset_ = 0; - } - } - - const Register &base() const { - return base_; - } - const Register ®offset() const { - return regoffset_; - } - int64_t offset() const { - return offset_; - } - AddrMode addrmode() const { - return addrmode_; - } - Shift shift() const { - return shift_; - } - Extend extend() const { - return extend_; - } - unsigned shift_extend_imm() const { - return shift_extend_imm_; - } - - bool IsImmediateOffset() const { - return (addrmode_ == Offset); - } - bool IsRegisterOffset() const { - return (addrmode_ == Offset); - } - bool IsPreIndex() const { - return addrmode_ == PreIndex; - } - bool IsPostIndex() const { - return addrmode_ == PostIndex; - } - -private: - Register base_; - Register regoffset_; - - int64_t offset_; - - Shift shift_; - Extend extend_; - uint32_t shift_extend_imm_; - - AddrMode addrmode_; -}; - -// --- - -class OpEncode { -public: - static int32_t sf(const Register ®, int32_t op) { - return (op | sf(reg)); - } - - // register operation size, 32 bits or 64 bits - static int32_t sf(const Register ®) { - if (reg.Is64Bits()) - return LeftShift(1, 1, 31); - return 0; - } - - static int32_t V(const Register ®, int32_t op) { - return (op | V(reg)); - } - - // register type, SIMD_FD register or general register - static int32_t V(const Register ®) { - if (reg.IsVRegister()) - return LeftShift(1, 1, 26); - return 0; - } - - // load or store - static int32_t L(bool load_or_store) { - if (load_or_store) { - return LeftShift(1, 1, 22); - } - return 0; - } - - // shift type - static int32_t shift(Shift shift) { - return LeftShift(shift, 2, 22); - } - - // LogicalImmeidate - static int32_t EncodeLogicalImmediate(const Register &rd, const Register &rn, const Operand &operand) { - int64_t imm = operand.Immediate(); - int32_t N, imms, immr; - immr = bits(imm, 0, 5); - imms = bits(imm, 6, 11); - N = bit(imm, 12); - - return (sf(rd) | LeftShift(immr, 6, 16) | LeftShift(imms, 6, 10) | Rd(rd) | Rn(rn)); - } - - // LogicalShift - static int32_t EncodeLogicalShift(const Register &rd, const Register &rn, const Operand &operand) { - return (sf(rd) | shift(operand.shift()) | Rm(operand.reg()) | LeftShift(operand.shift_extend_imm(), 6, 10) | - Rn(rn) | Rd(rd)); - } - - // LoadStore - static int32_t LoadStorePair(LoadStorePairOp op, CPURegister rt, CPURegister rt2, const MemOperand &addr) { - int32_t scale = 2; - int32_t opc = 0; - int imm7; - opc = bits(op, 30, 31); - if (rt.IsRegister()) { - scale += bit(opc, 1); - } else if (rt.IsVRegister()) { - scale += opc; - } - - imm7 = (int)(addr.offset() >> scale); - return LeftShift(imm7, 7, 15); - } - - // scale - static int32_t scale(int32_t op) { - int scale = 0; - if ((op & LoadStoreUnsignedOffsetFixed) == LoadStoreUnsignedOffsetFixed) { - scale = bits(op, 30, 31); - } - return scale; - } -}; - -// --- - -class Assembler : public AssemblerBase { -public: - Assembler(void *address) : AssemblerBase(address) { - buffer_ = new CodeBuffer(); - } - - ~Assembler() { - if (buffer_) - delete buffer_; - buffer_ = NULL; - } - -public: - void SetRealizedAddress(void *address) { - DCHECK_EQ(0, reinterpret_cast(address) % 4); - AssemblerBase::SetRealizedAddress(address); - } - - void Emit(uint32_t value) { - buffer_->Emit32(value); - } - - void EmitInt64(int64_t value) { - buffer_->Emit64(value); - } - - void bind(Label *label); - - void nop() { - Emit(0xD503201F); - } - - void brk(int code) { - Emit(BRK | LeftShift(code, 16, 5)); - } - - void ret() { - Emit(0xD65F03C0); - } - - void adrp(const Register &rd, int64_t imm) { - DCHECK(rd.Is64Bits()); - DCHECK((abs(imm) >> 12) < (1 << 21)); - - uint32_t immlo = LeftShift(bits(imm >> 12, 0, 1), 2, 29); - uint32_t immhi = LeftShift(bits(imm >> 12, 2, 20), 19, 5); - Emit(ADRP | Rd(rd) | immlo | immhi); - } - - void add(const Register &rd, const Register &rn, int64_t imm) { - if (rd.Is64Bits() && rn.Is64Bits()) - AddSubImmediate(rd, rn, Operand(imm), OPT_X(ADD, imm)); - else - AddSubImmediate(rd, rn, Operand(imm), OPT_W(ADD, imm)); - } - - void adds(const Register &rd, const Register &rn, int64_t imm) { - UNREACHABLE(); - } - void sub(const Register &rd, const Register &rn, int64_t imm) { - if (rd.Is64Bits() && rn.Is64Bits()) - AddSubImmediate(rd, rn, Operand(imm), OPT_X(SUB, imm)); - else - AddSubImmediate(rd, rn, Operand(imm), OPT_W(SUB, imm)); - } - void subs(const Register &rd, const Register &rn, int64_t imm) { - UNREACHABLE(); - } - - void b(int64_t imm) { - int32_t imm26 = bits(imm >> 2, 0, 25); - - Emit(B | imm26); - } - - void b(Label *label) { - int offset = LinkAndGetByteOffsetTo(label); - b(offset); - } - - void br(Register rn) { - Emit(BR | Rn(rn)); - } - - void blr(Register rn) { - Emit(BLR | Rn(rn)); - } - - void ldr(Register rt, int64_t imm) { - LoadRegLiteralOp op; - switch (rt.type()) { - case CPURegister::kRegister_32: - op = OPT_W(LDR, literal); - break; - case CPURegister::kRegister_X: - op = OPT_X(LDR, literal); - break; - case CPURegister::kSIMD_FP_Register_S: - op = OPT_S(LDR, literal); - break; - case CPURegister::kSIMD_FP_Register_D: - op = OPT_D(LDR, literal); - break; - case CPURegister::kSIMD_FP_Register_Q: - op = OPT_Q(LDR, literal); - break; - default: - UNREACHABLE(); - break; - } - EmitLoadRegLiteral(op, rt, imm); - } - - void ldr(const CPURegister &rt, const MemOperand &src) { - LoadStore(OP_X(LDR), rt, src); - } - - void str(const CPURegister &rt, const MemOperand &src) { - LoadStore(OP_X(STR), rt, src); - } - - void ldp(const Register &rt, const Register &rt2, const MemOperand &src) { - if (rt.type() == Register::kSIMD_FP_Register_128) { - LoadStorePair(OP_Q(LDP), rt, rt2, src); - } else if (rt.type() == Register::kRegister_X) { - LoadStorePair(OP_X(LDP), rt, rt2, src); - } else { - UNREACHABLE(); - } - } - - void stp(const Register &rt, const Register &rt2, const MemOperand &dst) { - if (rt.type() == Register::kSIMD_FP_Register_128) { - LoadStorePair(OP_Q(STP), rt, rt2, dst); - } else if (rt.type() == Register::kRegister_X) { - LoadStorePair(OP_X(STP), rt, rt2, dst); - } else { - UNREACHABLE(); - } - } - - void mov(const Register &rd, const Register &rn) { - if ((rd.Is(SP)) || (rn.Is(SP))) { - add(rd, rn, 0); - } else { - if (rd.Is64Bits()) - orr(rd, xzr, Operand(rn)); - else - orr(rd, wzr, Operand(rn)); - } - } - void movk(const Register &rd, uint64_t imm, int shift = -1) { - // Move and keep. - MoveWide(rd, imm, shift, MOVK); - } - void movn(const Register &rd, uint64_t imm, int shift = -1) { - // Move with non-zero. - MoveWide(rd, imm, shift, MOVN); - } - void movz(const Register &rd, uint64_t imm, int shift = -1) { - // Move with zero. - MoveWide(rd, imm, shift, MOVZ); - } - - void orr(const Register &rd, const Register &rn, const Operand &operand) { - Logical(rd, rn, operand, ORR); - } - -private: - // label helpers. - static constexpr int kStartOfLabelLinkChain = 0; - int LinkAndGetByteOffsetTo(Label *label); - - // load helpers. - void EmitLoadRegLiteral(LoadRegLiteralOp op, CPURegister rt, int64_t imm) { - const int32_t encoding = op | LeftShift(imm, 26, 5) | Rt(rt); - Emit(encoding); - } - - void LoadStore(LoadStoreOp op, CPURegister rt, const MemOperand &addr) { - int64_t imm12 = addr.offset(); - if (addr.IsImmediateOffset()) { - // TODO: check Scaled ??? - imm12 = addr.offset() >> OpEncode::scale(LoadStoreUnsignedOffsetFixed | op); - Emit(LoadStoreUnsignedOffsetFixed | op | LeftShift(imm12, 12, 10) | Rn(addr.base()) | Rt(rt)); - } else if (addr.IsRegisterOffset()) { - UNREACHABLE(); - } else { - // pre-index & post-index - UNREACHABLE(); - } - } - - void LoadStorePair(LoadStorePairOp op, CPURegister rt, CPURegister rt2, const MemOperand &addr) { - int32_t combine_fields_op = OpEncode::LoadStorePair(op, rt, rt2, addr) | Rt2(rt2) | Rn(addr.base()) | Rt(rt); - int32_t addrmodeop; - - if (addr.IsImmediateOffset()) { - addrmodeop = LoadStorePairOffsetFixed; - } else { - if (addr.IsPreIndex()) { - addrmodeop = LoadStorePairPreIndexFixed; - } else { - addrmodeop = LoadStorePairPostIndexFixed; - } - } - Emit(op | addrmodeop | combine_fields_op); - } - - void MoveWide(Register rd, uint64_t imm, int shift, MoveWideImmediateOp op) { - if (shift > 0) - shift /= 16; - else - shift = 0; - - int32_t imm16 = LeftShift(imm, 16, 5); - Emit(MoveWideImmediateFixed | op | OpEncode::sf(rd) | LeftShift(shift, 2, 21) | imm16 | Rd(rd)); - } - - void AddSubImmediate(const Register &rd, const Register &rn, const Operand &operand, AddSubImmediateOp op) { - if (operand.IsImmediate()) { - int64_t immediate = operand.Immediate(); - int32_t imm12 = LeftShift(immediate, 12, 10); - Emit(op | Rd(rd) | Rn(rn) | imm12); - } else { - UNREACHABLE(); - } - } - - void Logical(const Register &rd, const Register &rn, const Operand &operand, LogicalOp op) { - if (operand.IsImmediate()) { - LogicalImmediate(rd, rn, operand, op); - } else { - LogicalShift(rd, rn, operand, op); - } - } - void LogicalImmediate(const Register &rd, const Register &rn, const Operand &operand, LogicalOp op) { - int32_t combine_fields_op = OpEncode::EncodeLogicalImmediate(rd, rn, operand); - Emit(op | combine_fields_op); - } - void LogicalShift(const Register &rd, const Register &rn, const Operand &operand, LogicalOp op) { - int32_t combine_fields_op = OpEncode::EncodeLogicalShift(rd, rn, operand); - Emit(op | LogicalShiftedFixed | combine_fields_op); - } -}; - -// --- - -class TurboAssembler : public Assembler { -public: - TurboAssembler(void *address) : Assembler(address) { - } - - ~TurboAssembler() { - } - - void CallFunction(ExternalReference function) { - Mov(TMP_REG_0, (uint64_t)function.address()); - blr(TMP_REG_0); - } - - void Ldr(Register rt, AssemblerPseudoLabel *label) { - if (label->relocated_pos()) { - int offset = label->relocated_pos() - buffer_->GetBufferSize(); - ldr(rt, offset); - } else { - label->link_to(kLabelImm19, 0, buffer_->GetBufferSize()); - ldr(rt, 0); - } - } - - void Mov(Register rd, uint64_t imm) { - const uint32_t w0 = Low32Bits(imm); - const uint32_t w1 = High32Bits(imm); - const uint16_t h0 = Low16Bits(w0); - const uint16_t h1 = High16Bits(w0); - const uint16_t h2 = Low16Bits(w1); - const uint16_t h3 = High16Bits(w1); - movz(rd, h0, 0); - movk(rd, h1, 16); - movk(rd, h2, 32); - movk(rd, h3, 48); - } - - void AdrpAdd(Register rd, uint64_t from, uint64_t to) { - uint64_t from_PAGE = ALIGN(from, 0x1000); - uint64_t to_PAGE = ALIGN(to, 0x1000); - uint64_t to_PAGEOFF = (uint64_t)to % 0x1000; - - adrp(rd, to_PAGE - from_PAGE); - add(rd, rd, to_PAGEOFF); - } -}; - -} // namespace arm64 -} // namespace zz - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler-ia32.cc b/app/src/main/cpp/Dobby/source/core/assembler/assembler-ia32.cc deleted file mode 100644 index dd30472..0000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler-ia32.cc +++ /dev/null @@ -1,34 +0,0 @@ -#include "platform_macro.h" -#if TARGET_ARCH_IA32 - -#include "core/assembler/assembler-ia32.h" - -using namespace zz::x86; - -void Assembler::jmp(Immediate imm) { - buffer_->Emit8(0xE9); - buffer_->Emit32((int)imm.value()); -} - -addr32_t TurboAssembler::CurrentIP() { - return pc_offset() + (addr_t)realized_addr_; -} - -void AssemblerPseudoLabel::link_confused_instructions(CodeBufferBase *buffer) { - auto _buffer = (CodeBuffer *)buffer; - - for (auto &ref_label_inst : ref_label_insts_) { - int64_t new_offset = relocated_pos() - ref_label_inst.offset_; - - if (ref_label_inst.type_ == kDisp32_off_7) { - // why 7 ? - // use `call` and `pop` get the runtime ip register - // but the ip register not the real call next insn - // it need add two insn length == 7 - int disp32_fix_pos = ref_label_inst.offset_ - sizeof(int32_t); - _buffer->FixBindLabel(disp32_fix_pos, new_offset + 7); - } - } -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler-ia32.h b/app/src/main/cpp/Dobby/source/core/assembler/assembler-ia32.h deleted file mode 100644 index 5530a55..0000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler-ia32.h +++ /dev/null @@ -1,470 +0,0 @@ -#ifndef CORE_ASSEMBLER_X86_H -#define CORE_ASSEMBLER_X86_H - -#include "common_header.h" - -#include "core/arch/x86/registers-x86.h" -#include "core/assembler/assembler.h" - -#include "MemoryAllocator/CodeBuffer/code_buffer_x86.h" - -#define IsInt8(imm) (-128 <= imm && imm <= 127) - -enum ref_label_type_t { kDisp32_off_7 }; - - -namespace zz { -namespace x86 { - -constexpr Register VOLATILE_REGISTER = eax; - -#define ModRM_Mod(byte) ((byte & 0b11000000) >> 6) -#define ModRM_RegOpcode(byte) ((byte & 0b00111000) >> 3) -#define ModRM_RM(byte) (byte & 0b00000111) - -typedef union _ModRM { - byte_t ModRM; - struct { - byte_t RM : 3; - byte_t RegOpcode : 3; - byte_t Mod : 2; - }; -} ModRM; - -// --- - - -class Immediate { -public: - explicit Immediate(int32_t imm) : value_(imm), value_size_(32) { - if ((int32_t)(int8_t)imm == imm) { - value_size_ = 8; - } else if ((int32_t)(int16_t)imm == imm) { - value_size_ = 16; - } else { - value_size_ = 32; - } - } - - explicit Immediate(int32_t imm, int size) : value_(imm), value_size_(size) { - } - - int32_t value() const { - return value_; - } - - int size() const { - return value_size_; - } - -private: - const int32_t value_; - - int value_size_; -}; - -// --- - -class Operand { -public: - // [base] - Operand(Register base); - - // [base + disp/r] - Operand(Register base, int32_t disp); - - // [base + index*scale + disp/r] - Operand(Register base, Register index, ScaleFactor scale, int32_t disp); - - // [index*scale + disp/r] - Operand(Register index, ScaleFactor scale, int32_t disp); - -public: // Getter and Setter - uint8_t modrm() { - return (encoding_at(0)); - } - - uint8_t mod() const { - return (encoding_at(0) >> 6) & 3; - } - - Register rm() const { - return Register::from_code(encoding_at(0) & 7); - } - - ScaleFactor scale() const { - return static_cast((encoding_at(1) >> 6) & 3); - } - - Register index() const { - return Register::from_code((encoding_at(1) >> 3) & 7); - } - - Register base() const { - return Register::from_code(encoding_at(1) & 7); - } - - int8_t disp8() const { - ASSERT(length_ >= 2); - return static_cast(encoding_[length_ - 1]); - } - - int32_t disp32() const { - ASSERT(length_ >= 5); - return static_cast(encoding_[length_ - 4]); - } - -protected: - Operand() : length_(0) { - } - - void SetModRM(int mod, Register rm) { - ASSERT((mod & ~3) == 0); - encoding_[0] = (mod << 6) | rm.code(); - length_ = 1; - } - - void SetSIB(ScaleFactor scale, Register index, Register base) { - ASSERT(length_ == 1); - ASSERT((scale & ~3) == 0); - encoding_[1] = (scale << 6) | (index.code() << 3) | base.code(); - length_ = 2; - } - - void SetDisp8(int8_t disp) { - ASSERT(length_ == 1 || length_ == 2); - encoding_[length_++] = static_cast(disp); - } - - void SetDisp32(int32_t disp) { - ASSERT(length_ == 1 || length_ == 2); - *(int32_t *)&encoding_[length_] = disp; - length_ += sizeof(disp); - } - -private: - // explicit Operand(Register reg) : rex_(REX_NONE) { SetModRM(3, reg); } - - // Get the operand encoding byte at the given index. - uint8_t encoding_at(intptr_t index) const { - ASSERT(index >= 0 && index < length_); - return encoding_[index]; - } - -public: - uint8_t length_; - uint8_t encoding_[6]; -}; - -// --- - - -class Address : public Operand { -public: - Address(Register base, int32_t disp) { - int base_ = base.code(); - int ebp_ = ebp.code(); - int esp_ = esp.code(); - if ((disp == 0) && (base_ != ebp_)) { - SetModRM(0, base); - if (base_ == esp_) - SetSIB(TIMES_1, esp, base); - } else if (disp >= -128 && disp <= 127) { - SetModRM(1, base); - if (base_ == esp_) - SetSIB(TIMES_1, esp, base); - SetDisp8(disp); - } else { - SetModRM(2, base); - if (base_ == esp_) - SetSIB(TIMES_1, esp, base); - SetDisp32(disp); - } - } - - // This addressing mode does not exist. - Address(Register base, Register r); - - Address(Register index, ScaleFactor scale, int32_t disp) { - ASSERT(index.code() != rsp.code()); // Illegal addressing mode. - SetModRM(0, esp); - SetSIB(scale, index, ebp); - SetDisp32(disp); - } - - // This addressing mode does not exist. - Address(Register index, ScaleFactor scale, Register r); - - Address(Register base, Register index, ScaleFactor scale, int32_t disp) { - ASSERT(index.code() != rsp.code()); // Illegal addressing mode. - int rbp_ = ebp.code(); - if ((disp == 0) && ((base.code() & 7) != rbp_)) { - SetModRM(0, esp); - SetSIB(scale, index, base); - } else if (disp >= -128 && disp <= 127) { - SetModRM(1, esp); - SetSIB(scale, index, base); - SetDisp8(disp); - } else { - SetModRM(2, esp); - SetSIB(scale, index, base); - SetDisp32(disp); - } - } - - // This addressing mode does not exist. - Address(Register base, Register index, ScaleFactor scale, Register r); - -private: - Address(Register base, int32_t disp, bool fixed) { - ASSERT(fixed); - - SetModRM(2, base); - if (base.code() == esp.code()) { - SetSIB(TIMES_1, esp, base); - } - SetDisp32(disp); - } -}; - -// --- - - -class Assembler : public AssemblerBase { -public: - Assembler(void *address) : AssemblerBase(address) { - buffer_ = new CodeBuffer(); - } - ~Assembler() { - if (buffer_) - delete buffer_; - buffer_ = NULL; - } - -public: - void Emit1(byte_t val) { - buffer_->Emit8(val); - } - - void Emit(int32_t value) { - buffer_->Emit32(value); - } - - // --- - - - void EmitImmediate(Immediate imm, int imm_size) { - if (imm_size == 8) { - buffer_->Emit8((uint8_t)imm.value()); - } else if (imm_size == 32) { - buffer_->Emit32((uint32_t)imm.value()); - } else { - UNREACHABLE(); - } - } - - // --- - - - // ATTENTION: - // ModR/M == 8 registers and 24 addressing mode - - void Emit_OpEn_Register_MemOperand(Register dst, Address &operand) { - EmitModRM_Update_Register(operand.modrm(), dst); - buffer_->EmitBuffer(&operand.encoding_[1], operand.length_ - 1); - } - - void Emit_OpEn_Register_RegOperand(Register dst, Register src) { - EmitModRM_Register_Register(dst, src); - } - - void Emit_OpEn_MemOperand_Immediate(uint8_t extra_opcode, Address &operand, Immediate imm) { - EmitModRM_Update_ExtraOpcode(operand.modrm(), extra_opcode); - buffer_->EmitBuffer(&operand.encoding_[1], operand.length_ - 1); - EmitImmediate(imm, imm.size()); - } - - void Emit_OpEn_RegOperand_Immediate(uint8_t extra_opcode, Register reg, Immediate imm) { - EmitModRM_ExtraOpcode_Register(extra_opcode, reg); - EmitImmediate(imm, imm.size()); - } - - void Emit_OpEn_MemOperand(uint8_t extra_opcode, Address &operand) { - EmitModRM_Update_ExtraOpcode(operand.modrm(), extra_opcode); - buffer_->EmitBuffer(&operand.encoding_[1], operand.length_ - 1); - } - - void Emit_OpEn_RegOperand(uint8_t extra_opcode, Register reg) { - EmitModRM_ExtraOpcode_Register(extra_opcode, reg); - } - - // Encoding: OI - void Emit_OpEn_OpcodeRegister_Immediate(uint8_t opcode, Register dst, Immediate imm) { - EmitOpcode_Register(opcode, dst); - EmitImmediate(imm, imm.size()); - } - - // --- - - - inline void EmitModRM(uint8_t Mod, uint8_t RegOpcode, uint8_t RM) { - uint8_t ModRM = 0; - ModRM |= Mod << 6; - ModRM |= RegOpcode << 3; - ModRM |= RM; - Emit1(ModRM); - } - - void EmitModRM_ExtraOpcode_Register(uint8_t extra_opcode, Register reg) { - EmitModRM(0b11, extra_opcode, reg.code()); - } - - void EmitModRM_Register_Register(Register reg1, Register reg2) { - EmitModRM(0b11, reg1.code(), reg2.code()); - } - - // update operand's ModRM - void EmitModRM_Update_Register(uint8_t modRM, Register reg) { - EmitModRM(ModRM_Mod(modRM), reg.code(), ModRM_RM(modRM)); - } - - // update operand's ModRM - void EmitModRM_Update_ExtraOpcode(uint8_t modRM, uint8_t extra_opcode) { - EmitModRM(ModRM_Mod(modRM), extra_opcode, ModRM_RM(modRM)); - } - - // --- - - void EmitOpcode(uint8_t opcode) { - Emit1(opcode); - } - - void EmitOpcode_Register(uint8_t opcode, Register reg) { - EmitOpcode(opcode | reg.code()); - } - - // --- - - - void pushfq() { - Emit1(0x9C); - } - - void jmp(Immediate imm); - - void sub(Register dst, Immediate imm) { - DCHECK_EQ(dst.size(), 32); - - EmitOpcode(0x81); - - Emit_OpEn_RegOperand_Immediate(0x5, dst, imm); - } - - void add(Register dst, Immediate imm) { - DCHECK_EQ(dst.size(), 32); - - EmitOpcode(0x81); - - Emit_OpEn_RegOperand_Immediate(0x0, dst, imm); - } - - // MOV RAX, 0x320 - // 48 c7 c0 20 03 00 00 (MI encoding) - // 48 b8 20 03 00 00 00 00 00 00 (OI encoding) - void mov(Register dst, const Immediate imm) { - Emit_OpEn_OpcodeRegister_Immediate(0xb8, dst, imm); - } - - void mov(Address dst, const Immediate imm) { - EmitOpcode(0xc7); - - Emit_OpEn_MemOperand_Immediate(0x0, dst, imm); - } - - void mov(Register dst, Address src) { - EmitOpcode(0x8B); - - Emit_OpEn_Register_MemOperand(dst, src); - } - - void mov(Address dst, Register src) { - EmitOpcode(0x89); - - Emit_OpEn_Register_MemOperand(src, dst); - } - - void mov(Register dst, Register src) { - Emit1(0x8B); - - Emit_OpEn_Register_RegOperand(dst, src); - } - - void call(Address operand) { - EmitOpcode(0xFF); - - Emit_OpEn_MemOperand(0x2, operand); - } - - void call(Immediate imm) { - EmitOpcode(0xe8); - - EmitImmediate(imm, imm.size()); - } - - void call(Register reg) { - EmitOpcode(0xFF); - - Emit_OpEn_RegOperand(0x2, reg); - } - - void pop(Register reg) { - EmitOpcode_Register(0x58, reg); - } - - void push(Register reg) { - EmitOpcode_Register(0x50, reg); - } - - void ret() { - EmitOpcode(0xc3); - } - void nop() { - EmitOpcode(0x90); - } -}; - -// --- - - -class TurboAssembler : public Assembler { -public: - TurboAssembler(void *address) : Assembler(address) { - } - - ~TurboAssembler() { - } - - addr32_t CurrentIP(); - - void CallFunction(ExternalReference function) { - nop(); - MovRipToRegister(VOLATILE_REGISTER); - call(Address(VOLATILE_REGISTER, INT32_MAX)); - { - RelocLabel *addr_label = new RelocLabel(function.address()); - addr_label->link_to(kDisp32_off_7, 0, ip_offset()); - this->AppendRelocLabel(addr_label); - } - nop(); - } - - void MovRipToRegister(Register dst) { - call(Immediate(0, 32)); - pop(dst); - } -}; - -} // namespace x86 -} // namespace zz - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler-x64.cc b/app/src/main/cpp/Dobby/source/core/assembler/assembler-x64.cc deleted file mode 100644 index bb7910b..0000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler-x64.cc +++ /dev/null @@ -1,34 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_X64) - -#include "core/assembler/assembler-x64.h" - -using namespace zz::x64; - -void AssemblerPseudoLabel::link_confused_instructions(CodeBufferBase *buffer) { - CodeBuffer *_buffer = (CodeBuffer *)buffer; - - for (auto &ref_label_inst : ref_label_insts_) { - int64_t new_offset = relocated_pos() - ref_label_inst.offset_; - - if (ref_label_inst.type_ == kDisp32_off_9) { - // why 9 ? - // use `call` and `pop` get the runtime ip register - // but the ip register not the real call next insn - // it need add two insn length == 9 - int disp32_fix_pos = ref_label_inst.offset_ - sizeof(int32_t); - _buffer->FixBindLabel(disp32_fix_pos, new_offset + 9); - } - } -} - -void Assembler::jmp(Immediate imm) { - buffer_->Emit8(0xE9); - buffer_->Emit32((int)imm.value()); -} - -addr64_t TurboAssembler::CurrentIP() { - return pc_offset() + (addr_t)realized_addr_; -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler-x64.h b/app/src/main/cpp/Dobby/source/core/assembler/assembler-x64.h deleted file mode 100644 index 38b3513..0000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler-x64.h +++ /dev/null @@ -1,596 +0,0 @@ -#pragma once - -#include "common_header.h" - -#include "core/arch/x64/registers-x64.h" -#include "core/assembler/assembler.h" - -#include "MemoryAllocator/CodeBuffer/code_buffer_x64.h" - -#define IsInt8(imm) (-128 <= imm && imm <= 127) - -enum ref_label_type_t { kDisp32_off_9 }; - -namespace zz { -namespace x64 { - -constexpr Register VOLATILE_REGISTER = r11; - -#define ModRM_Mod(byte) ((byte & 0b11000000) >> 6) -#define ModRM_RegOpcode(byte) ((byte & 0b00111000) >> 3) -#define ModRM_RM(byte) (byte & 0b00000111) - -typedef union _ModRM { - byte_t ModRM; - struct { - byte_t RM : 3; - byte_t RegOpcode : 3; - byte_t Mod : 2; - }; -} ModRM; - -// --- - -class Immediate { -public: - explicit Immediate(int64_t imm) : value_(imm), value_size_(64) { - if ((int64_t)(int8_t)imm == imm) { - value_size_ = 8; - } else if ((int64_t)(int16_t)imm == imm) { - value_size_ = 8; - } else if ((int64_t)(int32_t)imm == imm) { - value_size_ = 32; - } else { - value_size_ = 64; - } - } - - explicit Immediate(int64_t imm, int size) : value_(imm), value_size_(size) { - } - - int64_t value() const { - return value_; - } - - int size() const { - return value_size_; - } - -private: - const int64_t value_; - - int value_size_; -}; - -// --- - -class Operand { -public: - // [base] - Operand(Register base); - - // [base + disp/r] - Operand(Register base, int32_t disp); - - // [base + index*scale + disp/r] - Operand(Register base, Register index, ScaleFactor scale, int32_t disp); - - // [index*scale + disp/r] - Operand(Register index, ScaleFactor scale, int32_t disp); - -public: // Getter and Setter - uint8_t rex() const { - return rex_; - } - - inline uint8_t rex_b() const { - return (rex_ & REX_B); - } - - inline uint8_t rex_x() const { - return (rex_ & REX_X); - } - - inline uint8_t rex_r() const { - return (rex_ & REX_R); - } - - inline uint8_t rex_w() const { - return (rex_ & REX_W); - } - - uint8_t modrm() { - return (encoding_at(0)); - } - - uint8_t mod() const { - return (encoding_at(0) >> 6) & 3; - } - - Register rm() const { - int rm_rex = rex_b() << 3; - return Register::from_code(rm_rex + (encoding_at(0) & 7)); - } - - ScaleFactor scale() const { - return static_cast((encoding_at(1) >> 6) & 3); - } - - Register index() const { - int index_rex = rex_x() << 2; - return Register::from_code(index_rex + ((encoding_at(1) >> 3) & 7)); - } - - Register base() const { - int base_rex = rex_b() << 3; - return Register::from_code(base_rex + (encoding_at(1) & 7)); - } - - int8_t disp8() const { - ASSERT(length_ >= 2); - return static_cast(encoding_[length_ - 1]); - } - - int32_t disp32() const { - ASSERT(length_ >= 5); - return static_cast(encoding_[length_ - 4]); - } - -protected: - Operand() : length_(0), rex_(REX_NONE) { - } // Needed by subclass Address. - - void SetModRM(int mod, Register rm) { - ASSERT((mod & ~3) == 0); - - if ((rm.code() > 7) && !((rm.Is(r12)) && (mod != 3))) { - rex_ |= REX_B; - } - encoding_[0] = (mod << 6) | (rm.code() & 7); - length_ = 1; - } - - void SetSIB(ScaleFactor scale, Register index, Register base) { - ASSERT(length_ == 1); - ASSERT((scale & ~3) == 0); - - if (base.code() > 7) { - ASSERT((rex_ & REX_B) == 0); // Must not have REX.B already set. - rex_ |= REX_B; - } - if (index.code() > 7) - rex_ |= REX_X; - - encoding_[1] = (scale << 6) | ((index.code() & 7) << 3) | (base.code() & 7); - length_ = 2; - } - - void SetDisp8(int8_t disp) { - ASSERT(length_ == 1 || length_ == 2); - - encoding_[length_++] = static_cast(disp); - } - - void SetDisp32(int32_t disp) { - ASSERT(length_ == 1 || length_ == 2); - - *(int32_t *)&encoding_[length_] = disp; - length_ += sizeof(disp); - } - -private: - // explicit Operand(Register reg) : rex_(REX_NONE) { SetModRM(3, reg); } - - // Get the operand encoding byte at the given index. - uint8_t encoding_at(intptr_t index) const { - ASSERT(index >= 0 && index < length_); - return encoding_[index]; - } - -public: - uint8_t length_; - uint8_t rex_; - uint8_t encoding_[6]; -}; - -// --- - -class Address : public Operand { -public: - Address(Register base, int32_t disp) { - int base_ = base.code(); - int rbp_ = rbp.code(); - int rsp_ = rsp.code(); - if ((disp == 0) && ((base_ & 7) != rbp_)) { - SetModRM(0, base); - if ((base_ & 7) == rsp_) { - SetSIB(TIMES_1, rsp, base); - } - } else if (IsInt8(disp)) { - SetModRM(1, base); - if ((base_ & 7) == rsp_) { - SetSIB(TIMES_1, rsp, base); - } - SetDisp8(disp); - } else { - SetModRM(2, base); - if ((base_ & 7) == rsp_) { - SetSIB(TIMES_1, rsp, base); - } - SetDisp32(disp); - } - } - - // This addressing mode does not exist. - Address(Register base, Register r); - - Address(Register index, ScaleFactor scale, int32_t disp) { - ASSERT(index.code() != rsp.code()); // Illegal addressing mode. - SetModRM(0, rsp); - SetSIB(scale, index, rbp); - SetDisp32(disp); - } - - // This addressing mode does not exist. - Address(Register index, ScaleFactor scale, Register r); - - Address(Register base, Register index, ScaleFactor scale, int32_t disp) { - ASSERT(index.code() != rsp.code()); // Illegal addressing mode. - int rbp_ = rbp.code(); - if ((disp == 0) && ((base.code() & 7) != rbp_)) { - SetModRM(0, rsp); - SetSIB(scale, index, base); - } else if (IsInt8(disp)) { - SetModRM(1, rsp); - SetSIB(scale, index, base); - SetDisp8(disp); - } else { - SetModRM(2, rsp); - SetSIB(scale, index, base); - SetDisp32(disp); - } - } - - // This addressing mode does not exist. - Address(Register base, Register index, ScaleFactor scale, Register r); - -private: - Address(Register base, int32_t disp, bool fixed) { - ASSERT(fixed); - - SetModRM(2, base); - if ((base.code() & 7) == rsp.code()) { - SetSIB(TIMES_1, rsp, base); - } - SetDisp32(disp); - } -}; - -// --- - -class Assembler : public AssemblerBase { -public: - Assembler(void *address) : AssemblerBase(address) { - buffer_ = new CodeBuffer(); - } - ~Assembler() { - if (buffer_) - delete buffer_; - buffer_ = NULL; - } - -public: - void Emit1(byte_t val) { - buffer_->Emit8(val); - } - - void Emit(int32_t value) { - buffer_->Emit32(value); - } - - void EmitInt64(int64_t value) { - buffer_->Emit64(value); - } - - // --- - - // refer android_art - uint8_t EmitOptionalRex(bool force, bool w, bool r, bool x, bool b) { - // REX.WRXB - // W - 64-bit operand - // R - MODRM.reg - // X - SIB.index - // B - MODRM.rm/SIB.base - - uint8_t rex = force ? 0x40 : 0; - if (w) { - rex |= 0x48; // REX.W000 - } - if (r) { - rex |= 0x44; // REX.0R00 - } - if (x) { - rex |= 0x42; // REX.00X0 - } - if (b) { - rex |= 0x41; // REX.000B - } - if (rex != 0) { - return rex; - } - return 0; - } - - void Emit_64REX(uint8_t extra) { - uint8_t rex = EmitOptionalRex(false, true, false, false, false); - rex |= extra; - if (rex) - Emit1(rex); - } - - void EmitREX_ExtraRegister(Register reg) { - uint8_t rex = EmitOptionalRex(false, reg.size() == 64, reg.code() > 7, false, reg.code() > 7); - if (rex) - Emit1(rex); - } - - void EmitREX_Register(Register reg) { - uint8_t rex = EmitOptionalRex(false, reg.size() == 64, reg.code() > 7, false, false); - if (rex) - Emit1(rex); - } - - void EmitREX_Register_Operand(Register reg, Operand &operand) { - if (reg.size() != 64) - UNIMPLEMENTED(); - uint8_t rex = operand.rex(); - rex |= EmitOptionalRex(true, reg.size() == 64, reg.code() > 7, false, false); - if (rex != 0) { - Emit1(rex); - } - } - - void EmitREX_Operand(Operand &operand) { - uint8_t rex = operand.rex(); - rex |= REX_PREFIX; - if (rex != 0) { - Emit1(rex); - } - } - - // --- - - void EmitImmediate(Immediate imm, int imm_size) { - if (imm_size == 8) { - buffer_->Emit8((uint8_t)imm.value()); - } else if (imm_size == 32) { - buffer_->Emit32((uint32_t)imm.value()); - } else if (imm_size == 64) { - buffer_->Emit64((uint64_t)imm.value()); - } else { - UNREACHABLE(); - } - } - - // --- - - // ATTENTION: - // ModR/M == 8 registers and 24 addressing mode - - void Emit_OpEn_Register_MemOperand(Register dst, Address &operand) { - EmitModRM_Update_Register(operand.modrm(), dst); - buffer_->EmitBuffer(&operand.encoding_[1], operand.length_ - 1); - } - - void Emit_OpEn_Register_RegOperand(Register dst, Register src) { - EmitModRM_Register_Register(dst, src); - } - - void Emit_OpEn_MemOperand_Immediate(uint8_t extra_opcode, Address &operand, Immediate imm) { - EmitModRM_Update_ExtraOpcode(operand.modrm(), extra_opcode); - buffer_->EmitBuffer(&operand.encoding_[1], operand.length_ - 1); - EmitImmediate(imm, imm.size()); - } - - void Emit_OpEn_RegOperand_Immediate(uint8_t extra_opcode, Register reg, Immediate imm) { - EmitModRM_ExtraOpcode_Register(extra_opcode, reg); - EmitImmediate(imm, imm.size()); - } - - void Emit_OpEn_MemOperand(uint8_t extra_opcode, Address &operand) { - EmitModRM_Update_ExtraOpcode(operand.modrm(), extra_opcode); - buffer_->EmitBuffer(&operand.encoding_[1], operand.length_ - 1); - } - - void Emit_OpEn_RegOperand(uint8_t extra_opcode, Register reg) { - EmitModRM_ExtraOpcode_Register(extra_opcode, reg); - } - - // Encoding: OI - void Emit_OpEn_OpcodeRegister_Immediate(uint8_t opcode, Register dst, Immediate imm) { - EmitOpcode_Register(opcode, dst); - EmitImmediate(imm, imm.size()); - } - - // --- - - inline void EmitModRM(uint8_t Mod, uint8_t RegOpcode, uint8_t RM) { - uint8_t ModRM = 0; - ModRM |= Mod << 6; - ModRM |= RegOpcode << 3; - ModRM |= RM; - Emit1(ModRM); - } - - void EmitModRM_ExtraOpcode_Register(uint8_t extra_opcode, Register reg) { - EmitModRM(0b11, extra_opcode, reg.code()); - } - - void EmitModRM_Register_Register(Register reg1, Register reg2) { - EmitModRM(0b11, reg1.code(), reg2.code()); - } - - // update operand's ModRM - void EmitModRM_Update_Register(uint8_t modRM, Register reg) { - EmitModRM(ModRM_Mod(modRM), reg.low_bits(), ModRM_RM(modRM)); - } - - // update operand's ModRM - void EmitModRM_Update_ExtraOpcode(uint8_t modRM, uint8_t extra_opcode) { - EmitModRM(ModRM_Mod(modRM), extra_opcode, ModRM_RM(modRM)); - } - - // --- - - void EmitOpcode(uint8_t opcode) { - Emit1(opcode); - } - - void EmitOpcode_Register(uint8_t opcode, Register reg) { - EmitOpcode(opcode | reg.low_bits()); - } - - // --- - - void pushfq() { - Emit1(0x9C); - } - - void jmp(Immediate imm); - - void sub(Register dst, Immediate imm) { - EmitREX_Register(dst); - - EmitOpcode(0x81); - - Emit_OpEn_RegOperand_Immediate(0x5, dst, imm); - } - - void add(Register dst, Immediate imm) { - EmitREX_Register(dst); - - EmitOpcode(0x81); - - Emit_OpEn_RegOperand_Immediate(0x0, dst, imm); - } - - // MOV RAX, 0x320 - // 48 c7 c0 20 03 00 00 (MI encoding) - // 48 b8 20 03 00 00 00 00 00 00 (OI encoding) - void mov(Register dst, const Immediate imm) { - EmitREX_Register(dst); - - Emit_OpEn_OpcodeRegister_Immediate(0xb8, dst, imm); - } - - void mov(Address dst, const Immediate imm) { - EmitREX_Operand(dst); - - EmitOpcode(0xc7); - - Emit_OpEn_MemOperand_Immediate(0x0, dst, imm); - } - - void mov(Register dst, Address src) { - EmitREX_Register(dst); - - EmitOpcode(0x8B); - - Emit_OpEn_Register_MemOperand(dst, src); - } - - void mov(Address dst, Register src) { - EmitREX_Register_Operand(src, dst); - - EmitOpcode(0x89); - - Emit_OpEn_Register_MemOperand(src, dst); - } - - void mov(Register dst, Register src) { - EmitREX_Register(dst); - - Emit1(0x8B); - - Emit_OpEn_Register_RegOperand(dst, src); - } - - void call(Address operand) { - EmitREX_Operand(operand); - - EmitOpcode(0xFF); - - Emit_OpEn_MemOperand(0x2, operand); - } - - void call(Immediate imm) { - EmitOpcode(0xe8); - - EmitImmediate(imm, imm.size()); - } - - void call(Register reg) { - EmitREX_Register(reg); - - EmitOpcode(0xFF); - - Emit_OpEn_RegOperand(0x2, reg); - } - - void pop(Register reg) { - EmitREX_ExtraRegister(reg); - - EmitOpcode_Register(0x58, reg); - } - - void push(Register reg) { - EmitREX_ExtraRegister(reg); - - EmitOpcode_Register(0x50, reg); - } - - void ret() { - EmitOpcode(0xc3); - } - void nop() { - EmitOpcode(0x90); - } -}; - -// --- - -class TurboAssembler : public Assembler { -public: - TurboAssembler(void *address) : Assembler(address) { - } - - ~TurboAssembler() { - } - - addr64_t CurrentIP(); - - void CallFunction(ExternalReference function) { -#if 0 - mov(r11, Immediate((int64_t)function.address(), 64)); - call(r11); -#endif - - nop(); - MovRipToRegister(VOLATILE_REGISTER); - call(Address(VOLATILE_REGISTER, INT32_MAX)); - { - RelocLabel *addr_label = new RelocLabel((uint64_t)function.address()); - addr_label->link_to(kDisp32_off_9, 0, ip_offset()); - this->AppendRelocLabel(addr_label); - } - nop(); - } - - void MovRipToRegister(Register dst) { - call(Immediate(0, 32)); - pop(dst); - } -}; - -} // namespace x64 -} // namespace zz diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler-x86-shared.cc b/app/src/main/cpp/Dobby/source/core/assembler/assembler-x86-shared.cc deleted file mode 100644 index 12968ac..0000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler-x86-shared.cc +++ /dev/null @@ -1,17 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_IA32) - -#include "core/assembler/assembler-x86-shared.h" - -using namespace zz::x86shared; - -void Assembler::jmp(Immediate imm) { - buffer_->Emit8(0xE9); - buffer_->Emit32((int)imm.value()); -} - -uint64_t TurboAssembler::CurrentIP() { - return pc_offset() + (addr_t)realized_addr_; -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler-x86-shared.h b/app/src/main/cpp/Dobby/source/core/assembler/assembler-x86-shared.h deleted file mode 100644 index d84af57..0000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler-x86-shared.h +++ /dev/null @@ -1,710 +0,0 @@ -#ifndef CORE_ASSEMBLER_X64_H -#define CORE_ASSEMBLER_X64_H - -#include "common_header.h" - -#include "core/arch/x64/registers-x64.h" -#include "core/assembler/assembler.h" - -#include "MemoryAllocator/CodeBuffer/code_buffer_x64.h" - -#include "xnucxx/LiteMutableArray.h" -#include "xnucxx/LiteIterator.h" - -#define IsInt8(imm) (-128 <= imm && imm <= 127) - -namespace zz { -namespace x86shared { - -using namespace x64; - -constexpr Register VOLATILE_REGISTER = r11; - -// ================================================================ -// AssemblerPseudoLabel - -class AssemblerPseudoLabel : public Label { -public: - enum PseudoLabelType { kDisp32_off_9 }; - - typedef struct _PseudoLabelInstruction { - int position_; - PseudoLabelType type_; - } PseudoLabelInstruction; - -public: - AssemblerPseudoLabel(void) { - instructions_.initWithCapacity(8); - } - ~AssemblerPseudoLabel(void) { - for (size_t i = 0; i < instructions_.getCount(); i++) { - PseudoLabelInstruction *item = (PseudoLabelInstruction *)instructions_.getObject(i); - delete item; - } - - instructions_.release(); - } - - bool has_confused_instructions() { - return instructions_.getCount() > 0; - } - - void link_confused_instructions(CodeBuffer *buffer = nullptr) { - if (!buffer) - UNREACHABLE(); - CodeBuffer *_buffer = buffer; - - for (size_t i = 0; i < instructions_.getCount(); i++) { - PseudoLabelInstruction *instruction = (PseudoLabelInstruction *)instructions_.getObject(i); - - int32_t offset = pos() - instruction->position_; - - switch (instruction->type_) { - case kDisp32_off_9: { - int disp32_fix_pos = instruction->position_ - sizeof(int32_t); - _buffer->FixBindLabel(disp32_fix_pos, offset + 9); - } break; - default: - UNREACHABLE(); - break; - } - } - }; - - void link_to(int pos, PseudoLabelType type) { - PseudoLabelInstruction *instruction = new PseudoLabelInstruction; - instruction->position_ = pos; - instruction->type_ = type; - instructions_.pushObject((LiteObject *)instruction); - } - -private: - LiteMutableArray instructions_; -}; - -class RelocLabel : public AssemblerPseudoLabel { -public: - explicit RelocLabel(uint64_t data) : data_size_(0) { - data_ = data; - } - - uint64_t data() { - return data_; - } - -private: - uint64_t data_; - - int data_size_; -}; - -#define ModRM_Mod(byte) ((byte & 0b11000000) >> 6) -#define ModRM_RegOpcode(byte) ((byte & 0b00111000) >> 3) -#define ModRM_RM(byte) (byte & 0b00000111) - -typedef union _ModRM { - byte_t ModRM; - struct { - byte_t RM : 3; - byte_t RegOpcode : 3; - byte_t Mod : 2; - }; -} ModRM; - -// ================================================================ -// Immediate - -class Immediate { -public: - explicit Immediate(int64_t imm) : value_(imm), value_size_(64) { - if ((int64_t)(int8_t)imm == imm) { - value_size_ = 8; - } else if ((int64_t)(int16_t)imm == imm) { - value_size_ = 8; - } else if ((int64_t)(int32_t)imm == imm) { - value_size_ = 32; - } else { - value_size_ = 64; - } - } - - explicit Immediate(int64_t imm, int size) : value_(imm), value_size_(size) { - } - - int64_t value() const { - return value_; - } - - int size() const { - return value_size_; - } - -private: - const int64_t value_; - - int value_size_; -}; - -// ================================================================ -// Operand - -class Operand { -public: - // [base] - Operand(Register base); - - // [base + disp/r] - Operand(Register base, int32_t disp); - - // [base + index*scale + disp/r] - Operand(Register base, Register index, ScaleFactor scale, int32_t disp); - - // [index*scale + disp/r] - Operand(Register index, ScaleFactor scale, int32_t disp); - -public: // Getter and Setter - uint8_t rex() const { - return rex_; - } - - inline uint8_t rex_b() const { - return (rex_ & REX_B); - } - - inline uint8_t rex_x() const { - return (rex_ & REX_X); - } - - inline uint8_t rex_r() const { - return (rex_ & REX_R); - } - - inline uint8_t rex_w() const { - return (rex_ & REX_W); - } - - uint8_t modrm() { - return (encoding_at(0)); - } - - uint8_t mod() const { - return (encoding_at(0) >> 6) & 3; - } - - Register rm() const { - int rm_rex = rex_b() << 3; - return Register::from_code(rm_rex + (encoding_at(0) & 7)); - } - - ScaleFactor scale() const { - return static_cast((encoding_at(1) >> 6) & 3); - } - - Register index() const { - int index_rex = rex_x() << 2; - return Register::from_code(index_rex + ((encoding_at(1) >> 3) & 7)); - } - - Register base() const { - int base_rex = rex_b() << 3; - return Register::from_code(base_rex + (encoding_at(1) & 7)); - } - - int8_t disp8() const { - ASSERT(length_ >= 2); - return static_cast(encoding_[length_ - 1]); - } - - int32_t disp32() const { - ASSERT(length_ >= 5); - return static_cast(encoding_[length_ - 4]); - } - -protected: - Operand() : length_(0), rex_(REX_NONE) { - } // Needed by subclass Address. - - void SetModRM(int mod, Register rm) { - ASSERT((mod & ~3) == 0); - - if ((rm.code() > 7) && !((rm.Is(r12)) && (mod != 3))) { - rex_ |= REX_B; - } - encoding_[0] = (mod << 6) | (rm.code() & 7); - length_ = 1; - } - - void SetSIB(ScaleFactor scale, Register index, Register base) { - ASSERT(length_ == 1); - ASSERT((scale & ~3) == 0); - - if (base.code() > 7) { - ASSERT((rex_ & REX_B) == 0); // Must not have REX.B already set. - rex_ |= REX_B; - } - if (index.code() > 7) - rex_ |= REX_X; - encoding_[1] = (scale << 6) | ((index.code() & 7) << 3) | (base.code() & 7); - length_ = 2; - } - - void SetDisp8(int8_t disp) { - ASSERT(length_ == 1 || length_ == 2); - - encoding_[length_++] = static_cast(disp); - } - - void SetDisp32(int32_t disp) { - ASSERT(length_ == 1 || length_ == 2); - - *(int32_t *)&encoding_[length_] = disp; - length_ += sizeof(disp); - } - -private: - // explicit Operand(Register reg) : rex_(REX_NONE) { SetModRM(3, reg); } - - // Get the operand encoding byte at the given index. - uint8_t encoding_at(intptr_t index) const { - ASSERT(index >= 0 && index < length_); - return encoding_[index]; - } - -public: - uint8_t length_; - uint8_t rex_; - uint8_t encoding_[6]; -}; - -// ================================================================ -// Address - -class Address : public Operand { -public: - Address(Register base, int32_t disp) { - int base_ = base.code(); - int rbp_ = rbp.code(); - int rsp_ = rsp.code(); - if ((disp == 0) && ((base_ & 7) != rbp_)) { - SetModRM(0, base); - if ((base_ & 7) == rsp_) { - SetSIB(TIMES_1, rsp, base); - } - } else if (IsInt8(disp)) { - SetModRM(1, base); - if ((base_ & 7) == rsp_) { - SetSIB(TIMES_1, rsp, base); - } - SetDisp8(disp); - } else { - SetModRM(2, base); - if ((base_ & 7) == rsp_) { - SetSIB(TIMES_1, rsp, base); - } - SetDisp32(disp); - } - } - - // This addressing mode does not exist. - Address(Register base, Register r); - - Address(Register index, ScaleFactor scale, int32_t disp) { - ASSERT(index.code() != rsp.code()); // Illegal addressing mode. - SetModRM(0, rsp); - SetSIB(scale, index, rbp); - SetDisp32(disp); - } - - // This addressing mode does not exist. - Address(Register index, ScaleFactor scale, Register r); - - Address(Register base, Register index, ScaleFactor scale, int32_t disp) { - ASSERT(index.code() != rsp.code()); // Illegal addressing mode. - int rbp_ = rbp.code(); - if ((disp == 0) && ((base.code() & 7) != rbp_)) { - SetModRM(0, rsp); - SetSIB(scale, index, base); - } else if (IsInt8(disp)) { - SetModRM(1, rsp); - SetSIB(scale, index, base); - SetDisp8(disp); - } else { - SetModRM(2, rsp); - SetSIB(scale, index, base); - SetDisp32(disp); - } - } - - // This addressing mode does not exist. - Address(Register base, Register index, ScaleFactor scale, Register r); - -private: - Address(Register base, int32_t disp, bool fixed) { - ASSERT(fixed); - SetModRM(2, base); - if ((base.code() & 7) == rsp.code()) { - SetSIB(TIMES_1, rsp, base); - } - SetDisp32(disp); - } -}; - -// ================================================================ -// Assembler - -class Assembler : public AssemblerBase { -public: - Assembler(void *address, int mode) : AssemblerBase(address) : mode_(mode) { - buffer_ = new CodeBuffer(); - } - ~Assembler() { - if (buffer_) - delete buffer_; - buffer_ = NULL - } - -public: - void Emit1(byte_t val) { - buffer_->Emit8(val); - } - - void Emit(int32_t value) { - buffer_->Emit32(value); - } - - void EmitInt64(int64_t value) { - buffer_->Emit64(value); - } - - void EmitAddr(uint64_t addr) { - if (mode == 64) { - EmitInt64(int64_t)addr); - } else { - EmitI((int32_t)addr); - } - } - - // ================================================================ - // REX - - // refer android_art - uint8_t EmitOptionalRex(bool force, bool w, bool r, bool x, bool b) { - // REX.WRXB - // W - 64-bit operand - // R - MODRM.reg - // X - SIB.index - // B - MODRM.rm/SIB.base - - uint8_t rex = force ? 0x40 : 0; - if (w) { - rex |= 0x48; // REX.W000 - } - if (r) { - rex |= 0x44; // REX.0R00 - } - if (x) { - rex |= 0x42; // REX.00X0 - } - if (b) { - rex |= 0x41; // REX.000B - } - if (rex != 0) { - return rex; - } - return 0; - } - - void Emit_64REX(uint8_t extra) { - uint8_t rex = EmitOptionalRex(false, true, false, false, false); - rex |= extra; - if (rex) - Emit1(rex); - } - - void EmitREX_ExtraRegister(Register reg) { - uint8_t rex = EmitOptionalRex(false, reg.size() == 64, reg.code() > 7, false, reg.code() > 7); - if (rex) - Emit1(rex); - } - - void EmitREX_Register(Register reg) { - uint8_t rex = EmitOptionalRex(false, reg.size() == 64, reg.code() > 7, false, false); - if (rex) - Emit1(rex); - } - - void EmitREX_Register_Operand(Register reg, Operand &operand) { - if (reg.size() != 64) - UNIMPLEMENTED(); - uint8_t rex = operand.rex(); - rex |= EmitOptionalRex(true, reg.size() == 64, reg.code() > 7, false, false); - if (rex != 0) { - Emit1(rex); - } - } - - void EmitREX_Operand(Operand &operand) { - uint8_t rex = operand.rex(); - rex |= REX_PREFIX; - if (rex != 0) { - Emit1(rex); - } - } - - // ================================================================ - // Immediate - - void EmitImmediate(Immediate imm, int imm_size) { - if (imm_size == 8) { - buffer_->Emit8((uint8_t)imm.value()); - } else if (imm_size == 32) { - buffer_->Emit32((uint32_t)imm.value()); - } else if (imm_size == 64) { - buffer_->Emit64((uint64_t)imm.value()); - } else { - UNREACHABLE(); - } - } - - // ================================================================ - // Operand Encoding - - // ATTENTION: - // ModR/M == 8 registers and 24 addressing mode - - // RM or MR - void Emit_OpEn_Register_MemOperand(Register dst, Address &operand) { - EmitModRM_Update_Register(operand.modrm(), dst); - buffer_->EmitBuffer(&operand.encoding_[1], operand.length_ - 1); - } - void Emit_OpEn_Register_RegOperand(Register dst, Register src) { - EmitModRM_Register_Register(dst, src); - } - - void Emit_OpEn_MemOperand_Immediate(uint8_t extra_opcode, Address &operand, Immediate imm) { - } - void Emit_OpEn_RegOperand_Immediate(uint8_t extra_opcode, Register reg, Immediate imm) { - EmitModRM_ExtraOpcode_Register(extra_opcode, reg); - EmitImmediate(imm, imm.size()); - } - - void Emit_OpEn_MemOperand(uint8_t extra_opcode, Address &operand) { - EmitModRM_Update_ExtraOpcode(operand.modrm(), extra_opcode); - buffer_->EmitBuffer(&operand.encoding_[1], operand.length_ - 1); - } - void Emit_OpEn_RegOperand(uint8_t extra_opcode, Register reg) { - EmitModRM_ExtraOpcode_Register(extra_opcode, reg); - } - - // Encoding: OI - void Emit_OpEn_OpcodeRegister_Immediate(uint8_t opcode, Register dst, Immediate imm) { - EmitOpcode_Register(opcode, dst); - EmitImmediate(imm, imm.size()); - } - - // ================================================================ - // ModRM - - inline void EmitModRM(uint8_t Mod, uint8_t RegOpcode, uint8_t RM) { - uint8_t ModRM = 0; - ModRM |= Mod << 6; - ModRM |= RegOpcode << 3; - ModRM |= RM; - Emit1(ModRM); - } - - void EmitModRM_ExtraOpcode_Register(uint8_t extra_opcode, Register reg) { - EmitModRM(0b11, extra_opcode, reg.code()); - } - - void EmitModRM_Register_Register(Register reg1, Register reg2) { - EmitModRM(0b11, reg1.code(), reg2.code()); - } - - // update operand's ModRM - void EmitModRM_Update_Register(uint8_t modRM, Register reg) { - EmitModRM(ModRM_Mod(modRM), reg.low_bits(), ModRM_RM(modRM)); - } - - // update operand's ModRM - void EmitModRM_Update_ExtraOpcode(uint8_t modRM, uint8_t extra_opcode) { - EmitModRM(ModRM_Mod(modRM), extra_opcode, ModRM_RM(modRM)); - } - - // ================================================================ - // Opcode - void EmitOpcode(uint8_t opcode) { - Emit1(opcode); - } - - void EmitOpcode_Register(uint8_t opcode, Register reg) { - EmitOpcode(opcode | reg.low_bits()); - } - - // ================================================================ - // Instruction - - void pushfq() { - Emit1(0x9C); - } - - void jmp(Immediate imm); - - void sub(Register dst, Immediate imm) { - EmitREX_Register(dst); - EmitOpcode(0x81); - Emit_OpEn_RegOperand_Immediate(0x5, dst, imm); - } - - void add(Register dst, Immediate imm) { - EmitREX_Register(dst); - EmitOpcode(0x81); - Emit_OpEn_RegOperand_Immediate(0x0, dst, imm); - } - - // MOV RAX, 0x320 - // 48 c7 c0 20 03 00 00 (MI encoding) - // 48 b8 20 03 00 00 00 00 00 00 (OI encoding) - void mov(Register dst, const Immediate imm) { - EmitREX_Register(dst); - - // OI encoding - Emit_OpEn_OpcodeRegister_Immediate(0xb8, dst, imm); - } - - void mov(Register dst, Address src) { - EmitREX_Register(dst); - - EmitOpcode(0x8B); - - Emit_OpEn_Register_MemOperand(dst, src); - } - - void mov(Address dst, Register src) { - EmitREX_Register_Operand(src, dst); - EmitOpcode(0x89); - Emit_OpEn_Register_MemOperand(src, dst); - } - - void mov(Register dst, Register src) { - EmitREX_Register(dst); - - Emit1(0x8B); - - Emit_OpEn_Register_RegOperand(dst, src); - } - - void call(Address operand) { - EmitREX_Operand(operand); - - EmitOpcode(0xFF); - - Emit_OpEn_MemOperand(0x2, operand); - } - - void call(Immediate imm) { - EmitOpcode(0xe8); - EmitImmediate(imm, imm.size()); - } - - void call(Register reg) { - EmitREX_Register(reg); - EmitOpcode(0xFF); - Emit_OpEn_RegOperand(0x2, reg); - } - - void pop(Register reg) { - EmitREX_ExtraRegister(reg); - EmitOpcode_Register(0x58, reg); - } - - void push(Register reg) { - EmitREX_ExtraRegister(reg); - EmitOpcode_Register(0x50, reg); - } - - void ret() { - EmitOpcode(0xc3); - } - void nop() { - EmitOpcode(0x90); - } - -private: - int mode_; -}; - -// ================================================================ -// TurboAssembler - -class TurboAssembler : public Assembler { -public: - TurboAssembler(void *address, int mode) : Assembler(address, mode) { - data_labels_ = NULL; - } - - addr64_t CurrentIP(); - - void CallFunction(ExternalReference function) { -#if 0 - mov(r11, Immediate((int64_t)function.address(), 64)); - call(r11); -#endif - - nop(); - MovRipToRegister(VOLATILE_REGISTER); - call(Address(VOLATILE_REGISTER, INT32_MAX)); - { - RelocLabel *addrLabel = new RelocLabel((uint64_t)function.address()); - addrLabel->link_to(ip_offset(), AssemblerPseudoLabel::kDisp32_off_9); - this->AppendRelocLabel(addrLabel); - } - nop(); - } - - void MovRipToRegister(Register dst) { - call(Immediate(0, 32)); - pop(dst); - } - - // ================================================================ - // RelocLabel - - void PseudoBind(AssemblerPseudoLabel *label) { - const addr_t bound_pc = buffer_->GetBufferSize(); - label->bind_to(bound_pc); - // If some instructions have been wrote, before the label bound, we need link these `confused` instructions - if (label->has_confused_instructions()) { - label->link_confused_instructions(reinterpret_cast(this->GetCodeBuffer())); - } - } - - void RelocBind() { - if (data_labels_ == NULL) - return; - for (size_t i = 0; i < data_labels_->getCount(); i++) { - RelocLabel *label = (RelocLabel *)data_labels_->getObject(i); - PseudoBind(label); - EmitAddr(label->data()); - } - } - - void AppendRelocLabel(RelocLabel *label) { - if (data_labels_ == NULL) { - data_labels_ = new LiteMutableArray(8); - } - data_labels_->pushObject((LiteObject *)label); - } - - LiteMutableArray *GetLabels() { - return data_labels_; - } - -private: - LiteMutableArray *data_labels_; -}; - -} // namespace x86shared -} // namespace zz - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler.cc b/app/src/main/cpp/Dobby/source/core/assembler/assembler.cc deleted file mode 100644 index 69c761f..0000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler.cc +++ /dev/null @@ -1,65 +0,0 @@ -#include "core/assembler/assembler.h" -#include "logging/logging.h" - -namespace zz { - -const void *ExternalReference::address() { - return address_; -} - -AssemblerBase::AssemblerBase(void *address) { - realized_addr_ = address; - buffer_ = nullptr; -} - -AssemblerBase::~AssemblerBase() { - buffer_ = nullptr; -} - -size_t AssemblerBase::ip_offset() const { - return reinterpret_cast(buffer_)->GetBufferSize(); -} - -size_t AssemblerBase::pc_offset() const { - return reinterpret_cast(buffer_)->GetBufferSize(); -} - -CodeBuffer *AssemblerBase::GetCodeBuffer() { - return buffer_; -} - -void AssemblerBase::PseudoBind(AssemblerPseudoLabel *label) { - off_t bound_offset = reinterpret_cast(buffer_)->GetBufferSize(); - label->bind_to(bound_offset); - // If some instructions had been written, before the label bound, we need link these `confused` instructions - if (label->has_confused_instructions()) { - label->link_confused_instructions(reinterpret_cast(buffer_)); - } -} - -void AssemblerBase::RelocBind() { - for (auto *data_label : data_labels_) { - PseudoBind(data_label); - reinterpret_cast(buffer_)->EmitBuffer(data_label->data_, data_label->data_size_); - } -} - -void AssemblerBase::AppendRelocLabel(RelocLabel *label) { - data_labels_.push_back(label); -} - -void AssemblerBase::SetRealizedAddress(void *address) { - realized_addr_ = address; -} - -void *AssemblerBase::GetRealizedAddress() { - return realized_addr_; -} - -void AssemblerBase::FlushICache(addr_t start, int size) { -} - -void AssemblerBase::FlushICache(addr_t start, addr_t end) { -} - -} // namespace zz diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler.h b/app/src/main/cpp/Dobby/source/core/assembler/assembler.h deleted file mode 100644 index 6e53f49..0000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler.h +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once - -#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" - -#include "AssemblerPseudoLabel.h" - -class CodeBuffer; - -namespace zz { - -class ExternalReference { -public: - explicit ExternalReference(void *address) : address_(address) { -#if defined(__APPLE__) && __arm64e__ -#if __has_feature(ptrauth_calls) - address_ = ptrauth_strip(address, ptrauth_key_asia); -#endif -#endif - } - - const void *address(); - -private: - const void *address_; -}; - -class AssemblerBase { -public: - explicit AssemblerBase(void *address); - - ~AssemblerBase(); - - size_t ip_offset() const; - - size_t pc_offset() const; - - CodeBuffer *GetCodeBuffer(); - - void PseudoBind(AssemblerPseudoLabel *label); - - void RelocBind(); - - void AppendRelocLabel(RelocLabel *label); - -protected: - std::vector data_labels_; - -public: - virtual void *GetRealizedAddress(); - - virtual void SetRealizedAddress(void *address); - - static void FlushICache(addr_t start, int size); - - static void FlushICache(addr_t start, addr_t end); - -protected: - CodeBuffer *buffer_; - - void *realized_addr_; -}; - -} // namespace zz - -#if 0 -#include "globals.h" -#if TARGET_ARCH_ARM -#include "core/assembler/assembler-arm.h" -#elif TARGET_ARCH_ARM64 -#include "core/assembler/assembler-arm64.h" -#elif TARGET_ARCH_X64 -#include "core/assembler/assembler-x64.h" -#else -#error "unsupported architecture" -#endif -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/codegen/codegen-arm.cc b/app/src/main/cpp/Dobby/source/core/codegen/codegen-arm.cc deleted file mode 100644 index 3d9922f..0000000 --- a/app/src/main/cpp/Dobby/source/core/codegen/codegen-arm.cc +++ /dev/null @@ -1,19 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_ARM) - -#include "core/codegen/codegen-arm.h" - -namespace zz { -namespace arm { - -void CodeGen::LiteralLdrBranch(uint32_t address) { - TurboAssembler *turbo_assembler_ = reinterpret_cast(this->assembler_); -#define _ turbo_assembler_-> - _ ldr(pc, MemOperand(pc, -4)); - turbo_assembler_->GetCodeBuffer()->Emit32((addr_t)address); -} - -} // namespace arm -} // namespace zz - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/codegen/codegen-arm.h b/app/src/main/cpp/Dobby/source/core/codegen/codegen-arm.h deleted file mode 100644 index 9f87202..0000000 --- a/app/src/main/cpp/Dobby/source/core/codegen/codegen-arm.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef CORE_CODEGEN_ARM_H -#define CORE_CODEGEN_ARM_H - -#include "core/codegen/codegen.h" -#include "core/assembler/assembler.h" -#include "core/assembler/assembler-arm.h" - -namespace zz { -namespace arm { - -class CodeGen : public CodeGenBase { -public: - CodeGen(TurboAssembler *turbo_assembler) : CodeGenBase(turbo_assembler) { - } - - void LiteralLdrBranch(uint32_t address); -}; - -} // namespace arm -} // namespace zz - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/codegen/codegen-arm64.cc b/app/src/main/cpp/Dobby/source/core/codegen/codegen-arm64.cc deleted file mode 100644 index 41e209e..0000000 --- a/app/src/main/cpp/Dobby/source/core/codegen/codegen-arm64.cc +++ /dev/null @@ -1,26 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_ARM64) - -#include "dobby_internal.h" -#include "core/codegen/codegen-arm64.h" - -namespace zz { -namespace arm64 { - -void CodeGen::LiteralLdrBranch(uint64_t address) { - auto turbo_assembler_ = reinterpret_cast(this->assembler_); -#define _ turbo_assembler_-> - - auto dst_label = new RelocLabel(address); - turbo_assembler_->AppendRelocLabel(dst_label); - - _ Ldr(TMP_REG_0, dst_label); - _ br(TMP_REG_0); - -#undef _ -} - -} // namespace arm64 -} // namespace zz - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/codegen/codegen-arm64.h b/app/src/main/cpp/Dobby/source/core/codegen/codegen-arm64.h deleted file mode 100644 index 99dafb3..0000000 --- a/app/src/main/cpp/Dobby/source/core/codegen/codegen-arm64.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef CORE_CODEGEN_ARM64_H -#define CORE_CODEGEN_ARM64_H - -#include "core/codegen/codegen.h" -#include "core/assembler/assembler.h" -#include "core/assembler/assembler-arm64.h" - -namespace zz { -namespace arm64 { - -class CodeGen : public CodeGenBase { -public: - CodeGen(TurboAssembler *turbo_assembler) : CodeGenBase(turbo_assembler) { - } - void LiteralLdrBranch(uint64_t address); -}; - -} // namespace arm64 -} // namespace zz - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/codegen/codegen-ia32.cc b/app/src/main/cpp/Dobby/source/core/codegen/codegen-ia32.cc deleted file mode 100644 index a5eba09..0000000 --- a/app/src/main/cpp/Dobby/source/core/codegen/codegen-ia32.cc +++ /dev/null @@ -1,23 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_IA32) - -#include "core/codegen/codegen-ia32.h" - -namespace zz { -namespace x86 { - -void CodeGen::JmpNear(uint32_t address) { - TurboAssembler *turbo_assembler_ = reinterpret_cast(this->assembler_); -#define _ turbo_assembler_-> -#define __ turbo_assembler_->GetCodeBuffer()-> - uint32_t currIP = turbo_assembler_->CurrentIP() + 5; - int32_t offset = (int32_t)(address - currIP); - - __ Emit8(0xe9); - __ Emit32(offset); -} - -} // namespace x86 -} // namespace zz - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/codegen/codegen-ia32.h b/app/src/main/cpp/Dobby/source/core/codegen/codegen-ia32.h deleted file mode 100644 index 5ad42bc..0000000 --- a/app/src/main/cpp/Dobby/source/core/codegen/codegen-ia32.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef CORE_CODEGEN_X86_H -#define CORE_CODEGEN_X86_H - -#include "core/codegen/codegen.h" -#include "core/assembler/assembler.h" -#include "core/assembler/assembler-ia32.h" - -namespace zz { -namespace x86 { - -class CodeGen : public CodeGenBase { -public: - CodeGen(TurboAssembler *turbo_assembler) : CodeGenBase(turbo_assembler) { - } - - void JmpNear(uint32_t address); -}; - -} // namespace x86 -} // namespace zz - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/codegen/codegen-x64.cc b/app/src/main/cpp/Dobby/source/core/codegen/codegen-x64.cc deleted file mode 100644 index 83c9777..0000000 --- a/app/src/main/cpp/Dobby/source/core/codegen/codegen-x64.cc +++ /dev/null @@ -1,25 +0,0 @@ -#include "platform_macro.h" -#if defined(TARGET_ARCH_X64) - -#include "core/codegen/codegen-x64.h" - -namespace zz { -namespace x64 { - -void CodeGen::JmpNearIndirect(addr_t forward_stub_addr) { - TurboAssembler *turbo_assembler_ = reinterpret_cast(this->assembler_); -#define _ turbo_assembler_-> -#define __ turbo_assembler_->GetCodeBuffer()-> - uint64_t currIP = turbo_assembler_->CurrentIP() + 6; - int32_t offset = (int32_t)(forward_stub_addr - currIP); - - // jmp *(rip + disp32) - __ Emit8(0xFF); - __ Emit8(0x25); // ModR/M: 00 100 101 - __ Emit32(offset); -} - -} // namespace x64 -} // namespace zz - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/codegen/codegen-x64.h b/app/src/main/cpp/Dobby/source/core/codegen/codegen-x64.h deleted file mode 100644 index 5fbbc1f..0000000 --- a/app/src/main/cpp/Dobby/source/core/codegen/codegen-x64.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef CORE_CODEGEN_X64_H -#define CORE_CODEGEN_X64_H - -#include "core/codegen/codegen.h" -#include "core/assembler/assembler.h" -#include "core/assembler/assembler-x64.h" - -namespace zz { -namespace x64 { - -class CodeGen : public CodeGenBase { -public: - CodeGen(TurboAssembler *turbo_assembler) : CodeGenBase(turbo_assembler) { - } - - void JmpNearIndirect(addr_t forward_stub_addr); -}; - -} // namespace x64 -} // namespace zz - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/codegen/codegen.h b/app/src/main/cpp/Dobby/source/core/codegen/codegen.h deleted file mode 100644 index e75d193..0000000 --- a/app/src/main/cpp/Dobby/source/core/codegen/codegen.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef CORE_CODEGEN_H -#define CORE_CODEGEN_H - -#include "core/assembler/assembler.h" - -using namespace zz; - -class CodeGenBase { -public: - CodeGenBase(AssemblerBase *assembler) : assembler_(assembler) { - } - -protected: - AssemblerBase *assembler_; -}; - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/emulator/dummy.cc b/app/src/main/cpp/Dobby/source/core/emulator/dummy.cc deleted file mode 100644 index e69de29..0000000 diff --git a/app/src/main/cpp/Dobby/source/dobby.cpp b/app/src/main/cpp/Dobby/source/dobby.cpp deleted file mode 100644 index 2026830..0000000 --- a/app/src/main/cpp/Dobby/source/dobby.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "dobby_internal.h" -#include "Interceptor.h" - -__attribute__((constructor)) static void ctor() { - DLOG(-1, "================================"); - DLOG(-1, "Dobby"); - DLOG(-1, "================================"); - - DLOG(-1, "dobby in debug log mode, disable with cmake flag \"-DDOBBY_DEBUG=OFF\""); -} - -PUBLIC const char *DobbyGetVersion() { - return __DOBBY_BUILD_VERSION__; -} - -PUBLIC int DobbyDestroy(void *address) { -#if defined(TARGET_ARCH_ARM) - if ((addr_t)address % 2) { - address = (void *)((addr_t)address - 1); - } -#endif - auto entry = Interceptor::SharedInstance()->find((addr_t)address); - if (entry) { - uint8_t *buffer = entry->origin_insns; - uint32_t buffer_size = entry->origin_insn_size; - DobbyCodePatch(address, buffer, buffer_size); - Interceptor::SharedInstance()->remove((addr_t)address); - return RT_SUCCESS; - } - - return RT_FAILED; -} diff --git a/app/src/main/cpp/Dobby/source/dobby_internal.h b/app/src/main/cpp/Dobby/source/dobby_internal.h deleted file mode 100644 index 0dc0c13..0000000 --- a/app/src/main/cpp/Dobby/source/dobby_internal.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "common_header.h" - -#include "dobby.h" - -#include "logging/logging.h" -#include "logging/check_logging.h" - -#include "UnifiedInterface/platform.h" - -#include "PlatformUnifiedInterface/MemoryAllocator.h" -#include "PlatformUnifiedInterface/ExecMemory/CodePatchTool.h" -#include "PlatformUnifiedInterface/ExecMemory/ClearCacheTool.h" - -#include "MemoryAllocator/AssemblyCodeBuilder.h" - -#include "InterceptRouting/InterceptRouting.h" diff --git a/app/src/main/cpp/Dobby/source/include/common_header.h b/app/src/main/cpp/Dobby/source/include/common_header.h deleted file mode 100644 index 324d144..0000000 --- a/app/src/main/cpp/Dobby/source/include/common_header.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "include/type_header.h" -#include "include/platform_header.h" -#include "include/platform_macro.h" -#include "include/utility_macro.h" - -#include "logging/logging.h" -#include "logging/check_logging.h" \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/include/kernel_mode_header.h b/app/src/main/cpp/Dobby/source/include/kernel_mode_header.h deleted file mode 100644 index 66d7a1a..0000000 --- a/app/src/main/cpp/Dobby/source/include/kernel_mode_header.h +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void *vm_map_entry_t; -extern vm_map_t kernel_map; - -typedef void *pmap_paddr_t; -struct pmap; -typedef struct pmap *pmap_t; -extern pmap_t kernel_pmap; - -extern task_t kernel_task; - -#ifdef __cplusplus -} -#endif - -// ----- pmap ----- - -typedef void *pmap_paddr_t; -struct pmap; -typedef struct pmap *pmap_t; - -typedef uint64_t vaddr_t; -typedef uint64_t paddr_t; - -struct pmap; -typedef struct pmap *pmap_t; - -#ifdef __cplusplus -extern "C" { -#endif - -extern pmap_t kernel_pmap; - -void pmap_kit_init(); - -paddr_t pmap_kit_kvtophys(pmap_t pmap, vaddr_t va); - -int pmap_kit_set_perm(pmap_t pmap, vaddr_t start, vaddr_t end, unsigned int prot); - -#define cppvPsnk 1 -#define cppvPsrc 2 -void pmap_kit_bcopy_phys(paddr_t src, paddr_t dst, size_t size, int flags); - -typedef uint64_t pt_entry_t; -pt_entry_t pmap_kit_kva_to_pte(pmap_t pmap, vaddr_t va); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/include/list_c.h b/app/src/main/cpp/Dobby/source/include/list_c.h deleted file mode 100644 index 2d179d2..0000000 --- a/app/src/main/cpp/Dobby/source/include/list_c.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -struct list_head { - struct list_head *next; - struct list_head *prev; -}; -#define container_of(ptr, type, member) \ - ({ \ - const __typeof(((type *)0)->member) *__mptr = (ptr); \ - (type *)((char *)__mptr - offsetof(type, member)); \ - }) - -#define INIT_LIST_HEAD(ptr) \ - do { \ - (ptr)->next = (ptr); \ - (ptr)->prev = (ptr); \ - } while (0) - -static inline int list_empty(struct list_head *head) { - return head->next == head; -} - -static void __list_add(struct list_head *new_node, struct list_head *prev, struct list_head *next) { - next->prev = new_node; - new_node->next = next; - new_node->prev = prev; - prev->next = new_node; -} - -static inline void list_add(struct list_head *new_node, struct list_head *head) { - __list_add(new_node, head, head->next); -} - -static inline void __list_del(struct list_head *prev, struct list_head *next) { - next->prev = prev; - prev->next = next; -} - -static inline void list_del(struct list_head *entry) { - __list_del(entry->prev, entry->next); - entry->next = NULL; - entry->prev = NULL; -} - -#define list_entry(ptr, type, member) container_of(ptr, type, member) - -#define list_first_entry(ptr, type, member) list_entry((ptr)->next, type, member) - -#define list_next_entry(pos, member) list_entry((pos)->member.next, typeof(*(pos)), member) - -#define list_for_each_entry(pos, head, member) \ - for (pos = list_first_entry(head, typeof(*pos), member); &pos->member != (head); pos = list_next_entry(pos, member)) \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/include/platform_header.h b/app/src/main/cpp/Dobby/source/include/platform_header.h deleted file mode 100644 index c9b8d7f..0000000 --- a/app/src/main/cpp/Dobby/source/include/platform_header.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#if defined(__APPLE__) && __arm64e__ -#if __has_feature(ptrauth_calls) -#include -#endif -#endif - -#if defined(BUILDING_KERNEL) -#include -#include -#include -#include -#include -#include -#include -#else -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(__linux__) || defined(__APPLE__) -#include -#include -#endif -#endif - -#if defined(BUILDING_KERNEL) -#include "kernel_mode_header.h" -#endif - -#if defined(BUILDING_KERNEL) -#define abs(a) ((a) < 0 ? -(a) : (a)) -#define llabs(a) (((long long)a) < 0 ? -((long long)a) : ((long long)a)) -#define min(a, b) (((a) < (b)) ? (a) : (b)) -#define max(a, b) (((a) > (b)) ? (a) : (b)) -#ifdef __cplusplus -#define abs(a) ((a) < 0 ? -(a) : (a)) -#endif -#else -#ifdef __cplusplus -#include -#include -#include -#include "TINYSTL/vector.h" -#include "TINYSTL/unordered_map.h" -#endif -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/include/platform_macro.h b/app/src/main/cpp/Dobby/source/include/platform_macro.h deleted file mode 100644 index 300c759..0000000 --- a/app/src/main/cpp/Dobby/source/include/platform_macro.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#if !defined(DISABLE_ARCH_DETECT) -#if defined(__arm__) -#define TARGET_ARCH_ARM 1 -#elif defined(__arm64__) || defined(__aarch64__) -#define TARGET_ARCH_ARM64 1 -#elif defined(_M_IX86) || defined(__i386__) -#define TARGET_ARCH_IA32 1 -#elif defined(_M_X64) || defined(__x86_64__) -#define TARGET_ARCH_X64 1 -#else -#error Target architecture was not detected as supported by Dobby -#endif -#endif diff --git a/app/src/main/cpp/Dobby/source/include/type_header.h b/app/src/main/cpp/Dobby/source/include/type_header.h deleted file mode 100644 index 9c3952c..0000000 --- a/app/src/main/cpp/Dobby/source/include/type_header.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "platform_header.h" - -typedef uintptr_t vmaddr_t; -typedef uintptr_t addr_t; -typedef uint32_t addr32_t; -typedef uint64_t addr64_t; -typedef unsigned char byte_t; -typedef unsigned int uint; - -#ifndef NULL -#define NULL 0 -#endif diff --git a/app/src/main/cpp/Dobby/source/include/utility_macro.h b/app/src/main/cpp/Dobby/source/include/utility_macro.h deleted file mode 100644 index a6c567c..0000000 --- a/app/src/main/cpp/Dobby/source/include/utility_macro.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -// offset of struct member -#define OFFSETOF(TYPE, ELEMENT) ((size_t) & (((TYPE *)0)->ELEMENT)) - -// assert -#define ASSERT(X) - -// left/right shift -#define LeftShift(a, b, c) ((a & ((1 << b) - 1)) << c) -#define RightShift(a, b, c) ((a >> c) & ((1 << b) - 1)) - -// align -#ifndef ALIGN -#define ALIGN ALIGN_FLOOR -#endif -#define ALIGN_FLOOR(address, range) ((uintptr_t)address & ~((uintptr_t)range - 1)) -#define ALIGN_CEIL(address, range) (((uintptr_t)address + (uintptr_t)range - 1) & ~((uintptr_t)range - 1)) - -// borrow from gdb, refer: binutils-gdb/gdb/arch/arm.h -#define submask(x) ((1L << ((x) + 1)) - 1) -#define bits(obj, st, fn) (((obj) >> (st)) & submask((fn) - (st))) -#define bit(obj, st) (((obj) >> (st)) & 1) -#define sbits(obj, st, fn) ((long)(bits(obj, st, fn) | ((long)bit(obj, fn) * ~submask(fn - st)))) - -// make it easy -#define set_bit(obj, st, bit) obj = (((~(1 << st)) & obj) | (bit << st)) -#define set_bits(obj, st, fn, bits) obj = (((~(submask(fn - st) << st)) & obj) | (bits << st)) - -// definition to expand macro then apply to pragma message -// #pragma message(VAR_NAME_VALUE(HOST_OS_IOS)) -#define VALUE_TO_STRING(x) #x -#define VALUE(x) VALUE_TO_STRING(x) -#define VAR_NAME_VALUE(var) #var "=" VALUE(var) - -// format print -#ifdef __LP64__ -#define __PRI_64_prefix "l" -#define __PRI_PTR_prefix "l" -#else -#define __PRI_64_prefix "ll" -#define __PRI_PTR_prefix -#endif -#define PRIxPTR __PRI_PTR_prefix "x" /* uintptr_t */ - -// deprecated declared -#if defined(__GNUC__) || defined(__clang__) -#define DEPRECATED __attribute__((deprecated)) -#elif defined(_MSC_VER) -#define DEPRECATED __declspec(deprecated) -#else -#pragma message("WARNING: You need to implement DEPRECATED for this compiler") -#define DEPRECATED -#endif - -// export method -#if defined(_WIN32) -#define PUBLIC -#else -#define PUBLIC __attribute__((visibility("default"))) -#define INTERNAL __attribute__((visibility("internal"))) -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/tests/CMakeLists.txt b/app/src/main/cpp/Dobby/tests/CMakeLists.txt deleted file mode 100644 index 8cb2454..0000000 --- a/app/src/main/cpp/Dobby/tests/CMakeLists.txt +++ /dev/null @@ -1,120 +0,0 @@ - -find_package(PkgConfig REQUIRED) -pkg_check_modules(CAPSTONE REQUIRED capstone) -message(STATUS "Capstone libraries: " ${CAPSTONE_LIBRARY_DIRS}) -message(STATUS "Capstone includes: " ${CAPSTONE_INCLUDE_DIRS}) - -pkg_check_modules(UNICORN REQUIRED unicorn) -message(STATUS "unicorn libraries: " ${UNICORN_LIBRARY_DIRS}) -message(STATUS "unicorn includes: " ${UNICORN_INCLUDE_DIRS}) - -get_property(DOBBY_SOURCE_FILE_LIST - TARGET dobby - PROPERTY SOURCES) - -set(DOBBY_SOURCES) -foreach (path ${DOBBY_SOURCE_FILE_LIST}) - if (NOT path MATCHES "^/") - list(APPEND DOBBY_SOURCES ${DOBBY_DIR}/${path}) - else () - list(APPEND DOBBY_SOURCES ${path}) - endif () -endforeach () - - -add_executable(test_insn_relo_arm64 - test_insn_relo_arm64.cpp - UniconEmulator.cpp - ${DOBBY_SOURCES} - ) - -target_compile_definitions(test_insn_relo_arm64 PUBLIC - LOGGING_DEBUG=1 - DISABLE_ARCH_DETECT=1 - TARGET_ARCH_ARM64=1 - TEST_WITH_UNICORN=1 - ) - -target_include_directories(test_insn_relo_arm64 PUBLIC - ${CAPSTONE_INCLUDE_DIRS} - ${UNICORN_INCLUDE_DIRS} - ) - -target_link_directories(test_insn_relo_arm64 PUBLIC - ${CAPSTONE_LIBRARY_DIRS} - ${UNICORN_LIBRARY_DIRS} - ) - -target_link_libraries(test_insn_relo_arm64 PUBLIC - ${CAPSTONE_LIBRARIES} - ${UNICORN_LIBRARIES} - ) - -# --- - -add_executable(test_insn_relo_arm - test_insn_relo_arm.cpp - UniconEmulator.cpp - ${DOBBY_SOURCES} - ) - -target_compile_definitions(test_insn_relo_arm PUBLIC - LOGGING_DEBUG=1 - DISABLE_ARCH_DETECT=1 - TARGET_ARCH_ARM=1 - TEST_WITH_UNICORN=1 - ) - -target_include_directories(test_insn_relo_arm PUBLIC - ${CAPSTONE_INCLUDE_DIRS} - ${UNICORN_INCLUDE_DIRS} - ) - -target_link_directories(test_insn_relo_arm PUBLIC - ${CAPSTONE_LIBRARY_DIRS} - ${UNICORN_LIBRARY_DIRS} - ) - -target_link_libraries(test_insn_relo_arm PUBLIC - ${CAPSTONE_LIBRARIES} - ${UNICORN_LIBRARIES} - ) - -# --- - -add_executable(test_insn_relo_x64 - test_insn_relo_x64.cpp - UniconEmulator.cpp - ${DOBBY_SOURCES} - ) - -target_compile_definitions(test_insn_relo_x64 PUBLIC - LOGGING_DEBUG=1 - DISABLE_ARCH_DETECT=1 - TARGET_ARCH_X64=1 - TEST_WITH_UNICORN=1 - # TARGET_ARCH_IA32=1 - ) - -target_include_directories(test_insn_relo_x64 PUBLIC - ${CAPSTONE_INCLUDE_DIRS} - ${UNICORN_INCLUDE_DIRS} - ) - -target_link_directories(test_insn_relo_x64 PUBLIC - ${CAPSTONE_LIBRARY_DIRS} - ${UNICORN_LIBRARY_DIRS} - ) - -target_link_libraries(test_insn_relo_x64 PUBLIC - ${CAPSTONE_LIBRARIES} - ${UNICORN_LIBRARIES} - ) - -# --- - -add_executable(test_native - test_native.cpp) - -target_link_libraries(test_native - dobby) \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/tests/UniconEmulator.cpp b/app/src/main/cpp/Dobby/tests/UniconEmulator.cpp deleted file mode 100644 index a0848ca..0000000 --- a/app/src/main/cpp/Dobby/tests/UniconEmulator.cpp +++ /dev/null @@ -1,219 +0,0 @@ -#include "UniconEmulator.h" -#include "PlatformUnifiedInterface/MemoryAllocator.h" -#include "InstructionRelocation/InstructionRelocation.h" - -// align -#ifndef ALIGN -#define ALIGN ALIGN_FLOOR -#endif -#define ALIGN_FLOOR(address, range) ((uintptr_t)address & ~((uintptr_t)range - 1)) -#define ALIGN_CEIL(address, range) (((uintptr_t)address + (uintptr_t)range - 1) & ~((uintptr_t)range - 1)) - -std::string g_arch = ""; - -void set_global_arch(std::string arch) { - g_arch = arch; -} - -std::unordered_map CapstoneDisassembler::instances_; - -CapstoneDisassembler *CapstoneDisassembler::Get(const std::string &arch) { - if (instances_.count(arch) == 0) { - cs_err err = CS_ERR_OK; - csh csh_; - if (arch == "arm") { - err = cs_open(CS_ARCH_ARM, CS_MODE_ARM, &csh_); - } else if (arch == "thumb") { - err = cs_open(CS_ARCH_ARM, CS_MODE_THUMB, &csh_); - } else if (arch == "arm64") { - err = cs_open(CS_ARCH_ARM64, CS_MODE_ARM, &csh_); - } else if (arch == "x86_64") { - err = cs_open(CS_ARCH_X86, CS_MODE_64, &csh_); - } else if (arch == "x86") { - err = cs_open(CS_ARCH_X86, CS_MODE_32, &csh_); - } - - auto instance = new CapstoneDisassembler(arch, csh_); - instances_[arch] = instance; - } - return instances_[arch]; -} - -CapstoneDisassembler::CapstoneDisassembler(const std::string &arch, csh csh_) : arch_(arch), csh_(csh_) { -} - -CapstoneDisassembler::~CapstoneDisassembler() { - cs_close((csh *)&csh_); -} - -void CapstoneDisassembler::disassemble(uintptr_t addr, char *buffer, size_t buffer_size) { - cs_insn *insns; - - size_t count = cs_disasm(csh_, (uint8_t *)buffer, buffer_size, addr, 0, &insns); - for (size_t i = 0; i < count; ++i) { - auto &insn = insns[i]; - if (arch_ == "thumb") { - printf("%s %p: %s %s // thumb-%d\n", "-", insn.address, insn.mnemonic, insn.op_str, insn.size / 2); - } else { - printf("%s %p: %s %s\n", "-", insn.address, insn.mnemonic, insn.op_str); - } - } - cs_free(insns, count); -} - -static void hook_trace_insn(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) { - auto emu = (UniconEmulator *)user_data; - - uc_err err; - char insn_bytes[16]; - err = uc_mem_read(uc, address, insn_bytes, size); - assert(err == UC_ERR_OK); - - if (address >= emu->end_) { - emu->stop(); - return; - } - - if ((emu->arch_ == "arm" || emu->arch_ == "thumb") && emu->isThumb()) { - CapstoneDisassembler::Get("thumb")->disassemble(address, (char *)insn_bytes, size); - } else { - CapstoneDisassembler::Get(g_arch)->disassemble(address, (char *)insn_bytes, size); - } -} - -static void hook_unmapped(uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, void *user_data) { - printf(">>> Unmapped memory access at %p, data size = %p, data value = %p\n", address, size, value); - auto emu = (UniconEmulator *)user_data; - emu->setUnmappedAddr(address); - emu->stop(); -} - -void dump_regions(uc_engine *uc) { - uc_mem_region *regions; - uint32_t region_count; - uc_mem_regions(uc, ®ions, ®ion_count); - for (int i = 0; i < region_count; ++i) { - auto ®ion = regions[i]; - printf("region: %p - %p\n", region.begin, region.end); - } -} - -UniconEmulator::UniconEmulator(const std::string &arch) { - uc_err err = UC_ERR_OK; - if (arch == "arm" || arch == "thumb") { - err = uc_open(UC_ARCH_ARM, UC_MODE_ARM, &uc_); - } else if (arch == "arm64") { - err = uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc_); - } else if (arch == "x86_64") { - err = uc_open(UC_ARCH_X86, UC_MODE_64, &uc_); - } else if (arch == "x86") { - err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc_); - } - assert(err == UC_ERR_OK); - - arch_ = arch; - - uc_hook hook_trace_insn_handle; - uc_hook_add(uc_, &hook_trace_insn_handle, UC_HOOK_CODE, (void *)hook_trace_insn, this, 1, 0); - - uc_hook hook_unmapped_handle; - uc_hook_add(uc_, &hook_unmapped_handle, UC_HOOK_MEM_UNMAPPED, (void *)hook_unmapped, this, 1, 0); -} - -void UniconEmulator::mapMemory(uintptr_t addr, char *buffer, size_t buffer_size) { - uc_err err = UC_ERR_OK; - uintptr_t map_addr = ALIGN_FLOOR(addr, 0x1000); - size_t map_size = ALIGN_CEIL(buffer_size, 0x1000); - err = uc_mem_map(uc_, map_addr, map_size, UC_PROT_ALL); - assert(err == UC_ERR_OK); - err = uc_mem_write(uc_, addr, buffer, buffer_size); - assert(err == UC_ERR_OK); -} - -void *UniconEmulator::readRegister(int regId) { - void *value = nullptr; - uc_reg_read(uc_, regId, &value); - return value; -} - -void UniconEmulator::writeRegister(int regNdx, void *value) { - uc_reg_write(uc_, regNdx, (void *)&value); -} - -void UniconEmulator::start(uintptr_t addr, uintptr_t end) { - uc_err err; - if (g_arch == "thumb") { - addr |= 1; - } - err = uc_emu_start(uc_, addr, end, 0, 0); - if (err == UC_ERR_FETCH_UNMAPPED || err == UC_ERR_READ_UNMAPPED || err == UC_ERR_WRITE_UNMAPPED) - err = UC_ERR_OK; - assert(err == UC_ERR_OK); -} - -void UniconEmulator::emulate(uintptr_t addr, uintptr_t end, char *buffer, size_t buffer_size) { - uc_err err; - mapMemory(addr, buffer, buffer_size); - writeRegister(UC_ARM_REG_PC, (void *)addr); - - if (end == 0) - end = addr + buffer_size; - - start_ = addr; - end_ = end; - - start(addr, end); -} - -void check_insn_relo(char *buffer, size_t buffer_size, bool check_fault_addr, int check_reg_id, - void (^callback)(UniconEmulator *orig, UniconEmulator *relo), uintptr_t relo_stop_size) { - auto *orig_ue = new UniconEmulator(g_arch); - auto *relo_ue = new UniconEmulator(g_arch); - - addr_t orig_addr = 0x100014000; - addr_t relocate_addr = 0x100024000; - - if (g_arch == "arm" || g_arch == "thumb") { - orig_addr = 0x10014000; - relocate_addr = 0x10024000; - } - - // auto dism = CapstoneDisassembler::Get("arm64"); - // dism->disassemble((uintptr_t)orig_addr, buffer, buffer_size); - // printf("\n"); - - auto origin = new CodeMemBlock(orig_addr, buffer_size); - auto relocated = new CodeMemBlock(relocate_addr, 0x1000); - if (g_arch == "thumb") { - origin->reset(origin->addr + 1, origin->size); - } - - GenRelocateCode(buffer, origin, relocated, false); - - if (g_arch == "thumb") { - orig_ue->writeRegister(UC_ARM_REG_CPSR, (void *)0x20); - relo_ue->writeRegister(UC_ARM_REG_CPSR, (void *)0x20); - } - orig_ue->emulate(orig_addr, 0, buffer, buffer_size); - if (g_arch == "thumb") { - relocated->addr -= 1; - } - if (relo_stop_size == 0) { - relo_stop_size = relocated->size; - } - relo_ue->emulate(relocate_addr, relocate_addr + relo_stop_size, (char *)relocated->addr, relocated->size); - - // dism->disassemble((uintptr_t)relocate_addr, (char *)relocated->addr, relocated->size); - // printf("\n"); - - if (check_fault_addr) { - assert(orig_ue->getFaultAddr() == relo_ue->getFaultAddr()); - } else if (check_reg_id != -1) { - assert(orig_ue->readRegister(check_reg_id) == relo_ue->readRegister(check_reg_id)); - } else if (callback) { - callback(orig_ue, relo_ue); - } - - delete orig_ue; - delete relo_ue; -} diff --git a/app/src/main/cpp/Dobby/tests/UniconEmulator.h b/app/src/main/cpp/Dobby/tests/UniconEmulator.h deleted file mode 100644 index 414618b..0000000 --- a/app/src/main/cpp/Dobby/tests/UniconEmulator.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include -#include - -#include -#include - -class CapstoneDisassembler { -public: - void disassemble(uintptr_t addr, char *buffer, size_t buffer_size); - - static CapstoneDisassembler *Get(const std::string &arch); - -private: - CapstoneDisassembler(const std::string &arch, csh csh_); - - ~CapstoneDisassembler(); - -private: - std::string arch_; - csh csh_; - - static std::unordered_map instances_; -}; - -class UniconEmulator { -public: - UniconEmulator(const std::string &arch); - - void mapMemory(uintptr_t addr, char *buffer, size_t buffer_size); - - void *readRegister(int regId); - - void writeRegister(int regId, void *value); - - void start(uintptr_t addr, uintptr_t end); - - void stop() { - uc_emu_stop(uc_); - } - - void emulate(uintptr_t addr, uintptr_t end, char *buffer, size_t buffer_size); - - void setUnmappedAddr(uintptr_t addr) { - unmapped_addr_ = addr; - } - - intptr_t getFaultAddr() { - return unmapped_addr_; - } - - bool isThumb() { - void *reg_value = readRegister(UC_ARM_REG_CPSR); - return (intptr_t)reg_value & 0x20; - } - - void reset(); - -public: - std::string arch_; - uintptr_t start_, end_; - -private: - uc_err err_; - uc_engine *uc_; - uintptr_t unmapped_addr_; -}; - -void set_global_arch(std::string arch); - -void check_insn_relo(char *buffer, size_t buffer_size, bool check_fault_addr, int check_reg_id, - void (^callback)(UniconEmulator *orig, UniconEmulator *relo), uintptr_t relo_stop_size = 0); \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/tests/test_insn_decoder_x86.cpp b/app/src/main/cpp/Dobby/tests/test_insn_decoder_x86.cpp deleted file mode 100644 index 20e0fb9..0000000 --- a/app/src/main/cpp/Dobby/tests/test_insn_decoder_x86.cpp +++ /dev/null @@ -1,267 +0,0 @@ -#include "InstructionRelocation/InstructionRelocation.h" -#include "InstructionRelocation/arm64/InstructionRelocationARM64.h" - -#include -#include - -#include - -class CapstoneDisassembler { -public: - void disassemble(uintptr_t addr, char *buffer, size_t buffer_szie); - - static CapstoneDisassembler *Get(const std::string &arch); - -private: - CapstoneDisassembler(const std::string &arch, csh csh_); - - ~CapstoneDisassembler(); - -private: - csh csh_; - - static CapstoneDisassembler *instance_; -}; - -CapstoneDisassembler *CapstoneDisassembler::instance_ = nullptr; - -CapstoneDisassembler *CapstoneDisassembler::Get(const std::string &arch) { - if (instance_ == nullptr) { - cs_err err = CS_ERR_OK; - csh csh_; - if (arch == "arm") { - err = cs_open(CS_ARCH_ARM, CS_MODE_ARM, &csh_); - } else if (arch == "arm64") { - err = cs_open(CS_ARCH_ARM64, CS_MODE_ARM, &csh_); - } else if (arch == "x86_64") { - err = cs_open(CS_ARCH_X86, CS_MODE_64, &csh_); - } else if (arch == "x86") { - err = cs_open(CS_ARCH_X86, CS_MODE_32, &csh_); - } - instance_ = new CapstoneDisassembler(arch, csh_); - } - return instance_; -} - -CapstoneDisassembler::CapstoneDisassembler(const std::string &arch, csh csh_) : csh_(csh_) { -} - -CapstoneDisassembler::~CapstoneDisassembler() { - cs_close((csh *)&csh_); -} - -void CapstoneDisassembler::disassemble(uintptr_t addr, char *buffer, size_t buffer_size) { - cs_insn *insns; - - size_t count = cs_disasm(csh_, (uint8_t *)buffer, buffer_size, addr, 0, &insns); - for (size_t i = 0; i < count; ++i) { - auto &insn = insns[i]; - printf("%s %p: %s %s\n", "-", insn.address, insn.mnemonic, insn.op_str); - } - cs_free(insns, count); -} - -class UniconEmulator { -public: - UniconEmulator(const std::string &arch); - - void mapMemory(uintptr_t addr, char *buffer, size_t buffer_size); - - void *readRegister(int regId); - - void writeRegister(int regId, void *value); - - void start(uintptr_t addr, uintptr_t end); - - void stop() { - uc_emu_stop(uc_); - } - - void emulate(uintptr_t addr, char *buffer, size_t buffer_size); - - void setUnmappedAddr(uintptr_t addr) { - unmapped_addr_ = addr; - } - - intptr_t getFaultAddr() { - return unmapped_addr_; - } - - void reset(); - -private: -private: - uc_err err_; - uc_engine *uc_; - uintptr_t unmapped_addr_; -}; - -static void hook_trace_insn(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) { - auto emu = (UniconEmulator *)user_data; - uc_err err; - char insn_bytes[16]; - err = uc_mem_read(uc, address, insn_bytes, size); - assert(err == UC_ERR_OK); - CapstoneDisassembler::Get("arm64")->disassemble(address, (char *)insn_bytes, size); -} - -static void hook_unmapped(uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, void *user_data) { - printf(">>> Unmapped memory access at %p, data size = %p, data value = %p\n", address, size, value); - auto emu = (UniconEmulator *)user_data; - emu->setUnmappedAddr(address); - emu->stop(); -} - -void dump_regions(uc_engine *uc) { - uc_mem_region *regions; - uint32_t region_count; - uc_mem_regions(uc, ®ions, ®ion_count); - for (int i = 0; i < region_count; ++i) { - auto ®ion = regions[i]; - printf("region: %p - %p\n", region.begin, region.end); - } -} - -UniconEmulator::UniconEmulator(const std::string &arch) { - uc_err err = UC_ERR_OK; - if (arch == "arm") { - err = uc_open(UC_ARCH_ARM, UC_MODE_ARM, &uc_); - } else if (arch == "arm64") { - err = uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc_); - } else if (arch == "x86_64") { - err = uc_open(UC_ARCH_X86, UC_MODE_64, &uc_); - } else if (arch == "x86") { - err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc_); - } - assert(err == UC_ERR_OK); - - uc_hook hook_trace_insn_handle; - uc_hook_add(uc_, &hook_trace_insn_handle, UC_HOOK_CODE, (void *)hook_trace_insn, this, 1, 0); - - uc_hook hook_unmapped_handle; - uc_hook_add(uc_, &hook_unmapped_handle, UC_HOOK_MEM_UNMAPPED, (void *)hook_unmapped, this, 1, 0); -} - -void UniconEmulator::mapMemory(uintptr_t addr, char *buffer, size_t buffer_size) { - uc_err err = UC_ERR_OK; - uintptr_t map_addr = ALIGN_FLOOR(addr, 0x1000); - size_t map_size = ALIGN_CEIL(buffer_size, 0x1000); - err = uc_mem_map(uc_, map_addr, map_size, UC_PROT_ALL); - assert(err == UC_ERR_OK); - err = uc_mem_write(uc_, addr, buffer, buffer_size); - assert(err == UC_ERR_OK); -} - -void *UniconEmulator::readRegister(int regId) { - void *value = nullptr; - uc_reg_read(uc_, regId, &value); - return value; -} - -void UniconEmulator::writeRegister(int regNdx, void *value) { - uc_reg_write(uc_, regNdx, (void *)&value); -} - -void UniconEmulator::start(uintptr_t addr, uintptr_t end) { - uc_err err; - err = uc_emu_start(uc_, addr, end, 0, 0); - if (err == UC_ERR_FETCH_UNMAPPED || err == UC_ERR_READ_UNMAPPED || err == UC_ERR_WRITE_UNMAPPED) - err = UC_ERR_OK; - assert(err == UC_ERR_OK); -} - -void UniconEmulator::emulate(uintptr_t addr, char *buffer, size_t buffer_size) { - uc_err err; - mapMemory(addr, buffer, buffer_size); - writeRegister(UC_ARM_REG_PC, (void *)addr); - start(addr, addr + buffer_size); -} - -void check_insn_relo(char *buffer, size_t buffer_size, bool check_fault_addr, int check_reg_id, - void (^callback)(UniconEmulator *orig, UniconEmulator *relo)) { - auto *orig_ue = new UniconEmulator("arm64"); - auto *relo_ue = new UniconEmulator("arm64"); - - addr_t orig_addr = 0x100004000; - addr_t relocate_addr = 0x200004000; - - // auto dism = CapstoneDisassembler::Get("arm64"); - // dism->disassemble((uintptr_t)orig_addr, buffer, buffer_size); - // printf("\n"); - - auto origin = new CodeMemBlock(orig_addr, buffer_size); - auto relocated = new CodeMemBlock(); - - GenRelocateCode(buffer, origin, relocated, false); - - orig_ue->emulate(orig_addr, buffer, buffer_size); - relo_ue->emulate(relocate_addr, (char *)relocated->addr, relocated->size); - - // dism->disassemble((uintptr_t)relocate_addr, (char *)relocated->addr, relocated->size); - // printf("\n"); - - if (check_fault_addr) { - assert(orig_ue->getFaultAddr() == relo_ue->getFaultAddr()); - } else if (check_reg_id != -1) { - assert(orig_ue->readRegister(check_reg_id) == relo_ue->readRegister(check_reg_id)); - } else if (callback) { - callback(orig_ue, relo_ue); - } - - delete orig_ue; - delete relo_ue; -} - -int main() { - // b #-0x4000 - check_insn_relo("\x00\xf0\xff\x17", 4, true, -1, nullptr); - // b #0x4000 - check_insn_relo("\x00\x10\x00\x14", 4, true, -1, nullptr); - - // bl #-0x4000 - check_insn_relo("\x00\xf0\xff\x97", 4, true, -1, nullptr); - // bl #0x4000 - check_insn_relo("\x00\x10\x00\x94", 4, true, -1, nullptr); - - // mov x0, #0 - // cbz x0, #-0x4000 - check_insn_relo("\x00\x00\x80\xd2\x00\x00\xfe\xb4", 8, true, -1, nullptr); - // mov x0, #0 - // cbz x0, #0x4000 - check_insn_relo("\x00\x00\x80\xd2\x00\x00\x02\xb4", 8, true, -1, nullptr); - - // ldr x0, #-0x4000 - check_insn_relo("\x00\x00\xfe\x58", 4, true, -1, nullptr); - // ldr x0, #0x4000 - check_insn_relo("\x00\x00\x02\x58", 4, true, -1, nullptr); - - // adr x0, #-0x4000 - check_insn_relo("\x00\x00\xfe\x10", 4, false, UC_ARM64_REG_X0, nullptr); - // adr x0, #0x4000 - check_insn_relo("\x00\x00\x02\x10", 4, false, UC_ARM64_REG_X0, nullptr); - - // adrp x0, #-0x4000 - check_insn_relo("\xe0\xff\xff\x90", 4, false, UC_ARM64_REG_X0, nullptr); - // adrp x0, #0x4000 - check_insn_relo("\x20\x00\x00\x90", 4, false, UC_ARM64_REG_X0, nullptr); - - // mov x0, #0 - // cmp x0, #0 - // b.eq #-0x4000 - check_insn_relo("\x00\x00\x80\xd2\x1f\x00\x00\xf1\x00\x00\xfe\x54", 12, true, -1, nullptr); - // mov x0, #0 - // cmp x0, #0 - // b.eq #0x4000 - check_insn_relo("\x00\x00\x80\xd2\x1f\x00\x00\xf1\x00\x00\x02\x54", 12, true, -1, nullptr); - - // mov x0, #0xb - // tbz w0, 2, #-0x4000 - check_insn_relo("\x60\x01\x80\xd2\x00\x00\x16\x36", 8, true, -1, nullptr); - // mov x0, #0xb - - // mov x0, #0xb - // tbz w0, 2, #0x4000 - check_insn_relo("\x60\x01\x80\xd2\x00\x00\x12\x36", 8, true, -1, nullptr); - - return 0; -} diff --git a/app/src/main/cpp/Dobby/tests/test_insn_relo_arm.cpp b/app/src/main/cpp/Dobby/tests/test_insn_relo_arm.cpp deleted file mode 100644 index 43dd16c..0000000 --- a/app/src/main/cpp/Dobby/tests/test_insn_relo_arm.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include "InstructionRelocation/InstructionRelocation.h" - -#include "UniconEmulator.h" - -void check_insn_relo_arm(char *buffer, size_t buffer_size, bool check_fault_addr, int check_reg_id, - void (^callback)(UniconEmulator *orig, UniconEmulator *relo)) { - __attribute__((aligned(4))) char code[64] = {0}; - memcpy(code, buffer, buffer_size); - check_insn_relo(code, buffer_size, check_fault_addr, check_reg_id, callback); -} - -void check_insn_relo_thumb(char *buffer, size_t buffer_size, bool check_fault_addr, int check_reg_id, - void (^callback)(UniconEmulator *orig, UniconEmulator *relo), uintptr_t relo_stop_size = 0) { - __attribute__((aligned(4))) char code[64] = {0}; - memcpy(code, buffer, buffer_size); - check_insn_relo(code, buffer_size, check_fault_addr, check_reg_id, callback, relo_stop_size); -} - -int main() { - log_set_level(0); - set_global_arch("arm"); - - // ldr r0, [pc, #-0x20] - __attribute__((aligned(4))) char *code_0 = "\x20\x00\x1f\xe5"; - check_insn_relo(code_0, 4, true, -1, nullptr); - - // ldr r0, [pc, #0x20] - __attribute__((aligned(4))) char *code_1 = "\x20\x00\x9f\xe5"; - check_insn_relo(code_1, 4, false, -1, ^(UniconEmulator *orig, UniconEmulator *relo) { - assert(relo->getFaultAddr() == 0x10014028); - }); - - // add r0, pc, #-0x4000 - check_insn_relo_arm("\x01\x09\x4f\xe2", 4, false, UC_ARM_REG_R0, nullptr); - // add r0, pc, #0x4000 - check_insn_relo_arm("\x01\x09\x8f\xe2", 4, false, UC_ARM_REG_R0, nullptr); - - // b #-0x4000 - check_insn_relo_arm("\xfe\xef\xff\xea", 4, true, -1, nullptr); - // b #0x4000 - check_insn_relo_arm("\xfe\x0f\x00\xea", 4, true, -1, nullptr); - - // bl #-0x4000 - check_insn_relo_arm("\xfe\xef\xff\xeb", 4, true, -1, nullptr); - // blx #0x4000 - check_insn_relo_arm("\xfe\x0f\x00\xfa", 4, true, -1, nullptr); - - set_global_arch("thumb"); - - // cmp r0, pc - check_insn_relo_thumb("\x78\x45", 2, false, -1, ^(UniconEmulator *orig, UniconEmulator *relo) { - assert(relo->readRegister(UC_ARM_REG_R12) == (void *)0x10014004); - }); - - // adr r0, #0x20 - check_insn_relo_thumb("\x08\xa0", 2, false, UC_ARM_REG_R0, nullptr, 8); - - // bx pc - check_insn_relo_thumb("\x78\x47", 2, false, UC_ARM_REG_PC, nullptr); - // blx pc - check_insn_relo_thumb("\xf8\x47", 2, false, UC_ARM_REG_PC, nullptr); - - // ldr r0, [pc, #8] - check_insn_relo_thumb("\x02\x48", 2, false, -1, ^(UniconEmulator *orig, UniconEmulator *relo) { - assert(relo->getFaultAddr() == 0x1001400c); - }); - - // b #-8 - check_insn_relo_thumb("\xfa\xe7", 2, true, -1, nullptr); - // b #8 - check_insn_relo_thumb("\x02\xe0", 2, false, -1, ^(UniconEmulator *orig, UniconEmulator *relo) { - assert(relo->getFaultAddr() == 0x10014008); - }); - - // mov r0, 0 - // cbz r0, #8 - check_insn_relo_thumb("\x4f\xf0\x00\x00" - "\x10\xb1", - 6, false, -1, ^(UniconEmulator *orig, UniconEmulator *relo) { - assert(relo->getFaultAddr() == 0x1001400c); - }); - - set_global_arch("thumb"); - - // cmp r0, r0 - // beq.w #-0x4000 - check_insn_relo_thumb("\x80\x42" - "\x3c\xf4\x00\xa8", - 6, true, -1, nullptr); - // cmp r0, r0 - // beq.w #0x4000 - check_insn_relo_thumb("\x80\x42" - "\x04\xf0\x00\x80", - 6, true, -1, nullptr); - - // bl #-0x4000 - check_insn_relo_thumb("\xfb\xf7\xfe\xff", 4, true, -1, nullptr); - // blx #0x4000 - check_insn_relo_thumb("\x03\xf0\xfe\xef", 4, true, -1, nullptr); - - // adr r0, #-0x512 - check_insn_relo_thumb("\xaf\xf2\x12\x50", 4, false, UC_ARM_REG_R0, nullptr); - // adr r0, #0x512 - check_insn_relo_thumb("\x0f\xf2\x12\x50", 4, false, UC_ARM_REG_R0, nullptr); - - // ldr r0, [pc, #-0x512] - check_insn_relo_thumb("\x5f\xf8\x12\x05", 4, true, -1, nullptr, 0xc); - // ldr r0, [pc, #0x512] - check_insn_relo_thumb( - "\xdf\xf8\x12\x05", 4, false, -1, - ^(UniconEmulator *orig, UniconEmulator *relo) { - assert(relo->getFaultAddr() == 0x10014000 + 0x512 + 4); - }, - 0xc); - return 0; -} diff --git a/app/src/main/cpp/Dobby/tests/test_insn_relo_arm64.cpp b/app/src/main/cpp/Dobby/tests/test_insn_relo_arm64.cpp deleted file mode 100644 index d76aee6..0000000 --- a/app/src/main/cpp/Dobby/tests/test_insn_relo_arm64.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - -test_b: -b #-0x4000 -b #0x4000 - -test_bl: -bl #-0x4000 -bl #0x4000 - -test_cbz: -cbz x0, #-0x4000 -cbz x0, #0x4000 - -test_ldr_liberal: -ldr x0, #-0x4000 -ldr x0, #0x4000 - -test_adr: -adr x0, #-0x4000 -adr x0, #0x4000 - -test_adrp: -adrp x0, #-0x4000 -adrp x0, #0x4000 - -test_b_cond: -b.eq #-0x4000 -b.eq #0x4000 - -test_tbz: -tbz x0, #0, #-0x4000 -tbz x0, #0, #0x4000 - -*/ - -// clang -arch arm64 code_arm64.asm -o code_arm64.o - -#include "InstructionRelocation/InstructionRelocation.h" - -#include "UniconEmulator.h" - -int main() { - set_global_arch("arm64"); - - // b #-0x4000 - check_insn_relo("\x00\xf0\xff\x17", 4, true, -1, nullptr); - // b #0x4000 - check_insn_relo("\x00\x10\x00\x14", 4, true, -1, nullptr); - - // bl #-0x4000 - check_insn_relo("\x00\xf0\xff\x97", 4, true, -1, nullptr); - // bl #0x4000 - check_insn_relo("\x00\x10\x00\x94", 4, true, -1, nullptr); - - // mov x0, #0 - // cbz x0, #-0x4000 - check_insn_relo("\x00\x00\x80\xd2\x00\x00\xfe\xb4", 8, true, -1, nullptr); - // mov x0, #0 - // cbz x0, #0x4000 - check_insn_relo("\x00\x00\x80\xd2\x00\x00\x02\xb4", 8, true, -1, nullptr); - - // ldr x0, #-0x4000 - check_insn_relo("\x00\x00\xfe\x58", 4, true, -1, nullptr); - // ldr x0, #0x4000 - check_insn_relo("\x00\x00\x02\x58", 4, true, -1, nullptr); - - // adr x0, #-0x4000 - check_insn_relo("\x00\x00\xfe\x10", 4, false, UC_ARM64_REG_X0, nullptr); - // adr x0, #0x4000 - check_insn_relo("\x00\x00\x02\x10", 4, false, UC_ARM64_REG_X0, nullptr); - - // adrp x0, #-0x4000 - check_insn_relo("\xe0\xff\xff\x90", 4, false, UC_ARM64_REG_X0, nullptr); - // adrp x0, #0x4000 - check_insn_relo("\x20\x00\x00\x90", 4, false, UC_ARM64_REG_X0, nullptr); - - // mov x0, #0 - // cmp x0, #0 - // b.eq #-0x4000 - check_insn_relo("\x00\x00\x80\xd2\x1f\x00\x00\xf1\x00\x00\xfe\x54", 12, true, -1, nullptr); - // mov x0, #0 - // cmp x0, #0 - // b.eq #0x4000 - check_insn_relo("\x00\x00\x80\xd2\x1f\x00\x00\xf1\x00\x00\x02\x54", 12, true, -1, nullptr); - - // mov x0, #0xb - // tbz w0, 2, #-0x4000 - check_insn_relo("\x60\x01\x80\xd2\x00\x00\x16\x36", 8, true, -1, nullptr); - // mov x0, #0xb - - // mov x0, #0xb - // tbz w0, 2, #0x4000 - check_insn_relo("\x60\x01\x80\xd2\x00\x00\x12\x36", 8, true, -1, nullptr); - - return 0; -} diff --git a/app/src/main/cpp/Dobby/tests/test_insn_relo_x64.cpp b/app/src/main/cpp/Dobby/tests/test_insn_relo_x64.cpp deleted file mode 100644 index f9db59d..0000000 --- a/app/src/main/cpp/Dobby/tests/test_insn_relo_x64.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "InstructionRelocation/InstructionRelocation.h" - -#include "UniconEmulator.h" - -int main() { - log_set_level(0); - set_global_arch("x86_64"); - - - // cmp eax, eax - // jz -0x20 - check_insn_relo("\x39\xc0\x74\xdc", 4, false, UC_X86_REG_IP, nullptr); - // cmp eax, eax - // jz 0x20 - check_insn_relo("\x39\xc0\x74\x1c", 4, false, UC_X86_REG_IP, nullptr); - - // jmp -0x20 - check_insn_relo("\xeb\xde", 2, false, UC_X86_REG_IP, nullptr); - // jmp 0x20 - check_insn_relo("\xeb\x1e", 2, false, UC_X86_REG_IP, nullptr); - - - // jmp -0x4000 - check_insn_relo("\xe9\xfb\xbf\xff\xff", 4, false, UC_X86_REG_IP, nullptr); - // jmp 0x4000 - check_insn_relo("\xe9\xfb\x3f\x00\x00", 4, false, UC_X86_REG_IP, nullptr); - - // lea rax, [rip] - check_insn_relo("\x48\x8d\x05\x00\x00\x00\x00", 7, false, UC_X86_REG_RAX, nullptr); - - // lea rax, [rip + 0x4000] - check_insn_relo("\x48\x8d\x05\x00\x40\x00\x00", 7, false, UC_X86_REG_RAX, nullptr); - - // mov rax, [rip + 0x4000] - check_insn_relo("\x48\x8b\x05\x00\x40\x00\x00", 7, true, -1, nullptr); - - return 0; -} diff --git a/app/src/main/cpp/Dobby/tests/test_native.cpp b/app/src/main/cpp/Dobby/tests/test_native.cpp deleted file mode 100644 index 21f84a9..0000000 --- a/app/src/main/cpp/Dobby/tests/test_native.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "dobby.h" - -#include -#include - -#define LOG(fmt, ...) printf("[test_native] " fmt, ##__VA_ARGS__) - -void test_execve() { - char *argv[] = {NULL}; - char *envp[] = {NULL}; - - LOG("test execve"); - - DobbyInstrument(DobbySymbolResolver(0, "_execve"), [](void *, DobbyRegisterContext *ctx) { - LOG("execve: %s", (char *)ctx->general.regs.rdi); - return; - }); - - execve("ls", argv, envp); - - return; -} - -int main(int argc, char *argv[]) { - log_set_level(0); - - test_execve(); - - return 0; -} diff --git a/app/src/main/cpp/libcxx b/app/src/main/cpp/libcxx deleted file mode 160000 index 12c8f4e..0000000 --- a/app/src/main/cpp/libcxx +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 12c8f4e93f196a700137e983dcceeac43cf807f2 diff --git a/app/src/main/cpp/libcxx/arm64-v8a/libcxx.a b/app/src/main/cpp/libcxx/arm64-v8a/libcxx.a new file mode 100644 index 0000000000000000000000000000000000000000..a923662c227ebb9e090076751908592660bb35ce GIT binary patch literal 2030488 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 aE=dPOS5^>~ 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 z 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

#$rh~ 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%0D~oo?8aqoWlP$D%`Q_GuorS>Msae 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ⅈEtE$YuQx_^r^5AhGO+mmSAGk|q>fpZ3M1N&xP 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
^}o&0Emg+f3j+F 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 literal 0 HcmV?d00001 diff --git a/app/src/main/cpp/libcxx/armeabi-v7a/libcxx.a b/app/src/main/cpp/libcxx/armeabi-v7a/libcxx.a new file mode 100644 index 0000000000000000000000000000000000000000..5e943711040e4685a0ead0a6da1ca74679378979 GIT binary patch literal 2360796 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 z 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%0DKG}{x(m091HqyuK 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 XUmQ3K2ETiNsug4d6+RBRFUj}6<-0?> literal 0 HcmV?d00001 diff --git a/app/src/main/cpp/libcxx/include/CMakeLists.txt b/app/src/main/cpp/libcxx/include/CMakeLists.txt new file mode 100644 index 0000000..a12aa1d --- /dev/null +++ b/app/src/main/cpp/libcxx/include/CMakeLists.txt @@ -0,0 +1,934 @@ +set(files + __algorithm/adjacent_find.h + __algorithm/all_of.h + __algorithm/any_of.h + __algorithm/binary_search.h + __algorithm/clamp.h + __algorithm/comp.h + __algorithm/comp_ref_type.h + __algorithm/copy.h + __algorithm/copy_backward.h + __algorithm/copy_if.h + __algorithm/copy_move_common.h + __algorithm/copy_n.h + __algorithm/count.h + __algorithm/count_if.h + __algorithm/equal.h + __algorithm/equal_range.h + __algorithm/fill.h + __algorithm/fill_n.h + __algorithm/find.h + __algorithm/find_end.h + __algorithm/find_first_of.h + __algorithm/find_if.h + __algorithm/find_if_not.h + __algorithm/for_each.h + __algorithm/for_each_n.h + __algorithm/generate.h + __algorithm/generate_n.h + __algorithm/half_positive.h + __algorithm/in_found_result.h + __algorithm/in_fun_result.h + __algorithm/in_in_out_result.h + __algorithm/in_in_result.h + __algorithm/in_out_out_result.h + __algorithm/in_out_result.h + __algorithm/includes.h + __algorithm/inplace_merge.h + __algorithm/is_heap.h + __algorithm/is_heap_until.h + __algorithm/is_partitioned.h + __algorithm/is_permutation.h + __algorithm/is_sorted.h + __algorithm/is_sorted_until.h + __algorithm/iter_swap.h + __algorithm/iterator_operations.h + __algorithm/lexicographical_compare.h + __algorithm/lower_bound.h + __algorithm/make_heap.h + __algorithm/make_projected.h + __algorithm/max.h + __algorithm/max_element.h + __algorithm/merge.h + __algorithm/min.h + __algorithm/min_element.h + __algorithm/min_max_result.h + __algorithm/minmax.h + __algorithm/minmax_element.h + __algorithm/mismatch.h + __algorithm/move.h + __algorithm/move_backward.h + __algorithm/next_permutation.h + __algorithm/none_of.h + __algorithm/nth_element.h + __algorithm/partial_sort.h + __algorithm/partial_sort_copy.h + __algorithm/partition.h + __algorithm/partition_copy.h + __algorithm/partition_point.h + __algorithm/pop_heap.h + __algorithm/prev_permutation.h + __algorithm/push_heap.h + __algorithm/ranges_adjacent_find.h + __algorithm/ranges_all_of.h + __algorithm/ranges_any_of.h + __algorithm/ranges_binary_search.h + __algorithm/ranges_clamp.h + __algorithm/ranges_copy.h + __algorithm/ranges_copy_backward.h + __algorithm/ranges_copy_if.h + __algorithm/ranges_copy_n.h + __algorithm/ranges_count.h + __algorithm/ranges_count_if.h + __algorithm/ranges_equal.h + __algorithm/ranges_equal_range.h + __algorithm/ranges_fill.h + __algorithm/ranges_fill_n.h + __algorithm/ranges_find.h + __algorithm/ranges_find_end.h + __algorithm/ranges_find_first_of.h + __algorithm/ranges_find_if.h + __algorithm/ranges_find_if_not.h + __algorithm/ranges_for_each.h + __algorithm/ranges_for_each_n.h + __algorithm/ranges_generate.h + __algorithm/ranges_generate_n.h + __algorithm/ranges_includes.h + __algorithm/ranges_inplace_merge.h + __algorithm/ranges_is_heap.h + __algorithm/ranges_is_heap_until.h + __algorithm/ranges_is_partitioned.h + __algorithm/ranges_is_permutation.h + __algorithm/ranges_is_sorted.h + __algorithm/ranges_is_sorted_until.h + __algorithm/ranges_iterator_concept.h + __algorithm/ranges_lexicographical_compare.h + __algorithm/ranges_lower_bound.h + __algorithm/ranges_make_heap.h + __algorithm/ranges_max.h + __algorithm/ranges_max_element.h + __algorithm/ranges_merge.h + __algorithm/ranges_min.h + __algorithm/ranges_min_element.h + __algorithm/ranges_minmax.h + __algorithm/ranges_minmax_element.h + __algorithm/ranges_mismatch.h + __algorithm/ranges_move.h + __algorithm/ranges_move_backward.h + __algorithm/ranges_next_permutation.h + __algorithm/ranges_none_of.h + __algorithm/ranges_nth_element.h + __algorithm/ranges_partial_sort.h + __algorithm/ranges_partial_sort_copy.h + __algorithm/ranges_partition.h + __algorithm/ranges_partition_copy.h + __algorithm/ranges_partition_point.h + __algorithm/ranges_pop_heap.h + __algorithm/ranges_prev_permutation.h + __algorithm/ranges_push_heap.h + __algorithm/ranges_remove.h + __algorithm/ranges_remove_copy.h + __algorithm/ranges_remove_copy_if.h + __algorithm/ranges_remove_if.h + __algorithm/ranges_replace.h + __algorithm/ranges_replace_copy.h + __algorithm/ranges_replace_copy_if.h + __algorithm/ranges_replace_if.h + __algorithm/ranges_reverse.h + __algorithm/ranges_reverse_copy.h + __algorithm/ranges_rotate.h + __algorithm/ranges_rotate_copy.h + __algorithm/ranges_sample.h + __algorithm/ranges_search.h + __algorithm/ranges_search_n.h + __algorithm/ranges_set_difference.h + __algorithm/ranges_set_intersection.h + __algorithm/ranges_set_symmetric_difference.h + __algorithm/ranges_set_union.h + __algorithm/ranges_shuffle.h + __algorithm/ranges_sort.h + __algorithm/ranges_sort_heap.h + __algorithm/ranges_stable_partition.h + __algorithm/ranges_stable_sort.h + __algorithm/ranges_swap_ranges.h + __algorithm/ranges_transform.h + __algorithm/ranges_unique.h + __algorithm/ranges_unique_copy.h + __algorithm/ranges_upper_bound.h + __algorithm/remove.h + __algorithm/remove_copy.h + __algorithm/remove_copy_if.h + __algorithm/remove_if.h + __algorithm/replace.h + __algorithm/replace_copy.h + __algorithm/replace_copy_if.h + __algorithm/replace_if.h + __algorithm/reverse.h + __algorithm/reverse_copy.h + __algorithm/rotate.h + __algorithm/rotate_copy.h + __algorithm/sample.h + __algorithm/search.h + __algorithm/search_n.h + __algorithm/set_difference.h + __algorithm/set_intersection.h + __algorithm/set_symmetric_difference.h + __algorithm/set_union.h + __algorithm/shift_left.h + __algorithm/shift_right.h + __algorithm/shuffle.h + __algorithm/sift_down.h + __algorithm/sort.h + __algorithm/sort_heap.h + __algorithm/stable_partition.h + __algorithm/stable_sort.h + __algorithm/swap_ranges.h + __algorithm/transform.h + __algorithm/uniform_random_bit_generator_adaptor.h + __algorithm/unique.h + __algorithm/unique_copy.h + __algorithm/unwrap_iter.h + __algorithm/unwrap_range.h + __algorithm/upper_bound.h + __assert + __availability + __bit/bit_cast.h + __bit/bit_ceil.h + __bit/bit_floor.h + __bit/bit_log2.h + __bit/bit_width.h + __bit/blsr.h + __bit/byteswap.h + __bit/countl.h + __bit/countr.h + __bit/endian.h + __bit/has_single_bit.h + __bit/popcount.h + __bit/rotate.h + __bit_reference + __bsd_locale_defaults.h + __bsd_locale_fallbacks.h + __charconv/chars_format.h + __charconv/from_chars_result.h + __charconv/tables.h + __charconv/to_chars_base_10.h + __charconv/to_chars_result.h + __chrono/calendar.h + __chrono/convert_to_timespec.h + __chrono/convert_to_tm.h + __chrono/day.h + __chrono/duration.h + __chrono/file_clock.h + __chrono/formatter.h + __chrono/hh_mm_ss.h + __chrono/high_resolution_clock.h + __chrono/literals.h + __chrono/month.h + __chrono/month_weekday.h + __chrono/monthday.h + __chrono/ostream.h + __chrono/parser_std_format_spec.h + __chrono/statically_widen.h + __chrono/steady_clock.h + __chrono/system_clock.h + __chrono/time_point.h + __chrono/weekday.h + __chrono/year.h + __chrono/year_month.h + __chrono/year_month_day.h + __chrono/year_month_weekday.h + __compare/common_comparison_category.h + __compare/compare_partial_order_fallback.h + __compare/compare_strong_order_fallback.h + __compare/compare_three_way.h + __compare/compare_three_way_result.h + __compare/compare_weak_order_fallback.h + __compare/is_eq.h + __compare/ordering.h + __compare/partial_order.h + __compare/strong_order.h + __compare/synth_three_way.h + __compare/three_way_comparable.h + __compare/weak_order.h + __concepts/arithmetic.h + __concepts/assignable.h + __concepts/boolean_testable.h + __concepts/class_or_enum.h + __concepts/common_reference_with.h + __concepts/common_with.h + __concepts/constructible.h + __concepts/convertible_to.h + __concepts/copyable.h + __concepts/derived_from.h + __concepts/destructible.h + __concepts/different_from.h + __concepts/equality_comparable.h + __concepts/invocable.h + __concepts/movable.h + __concepts/predicate.h + __concepts/regular.h + __concepts/relation.h + __concepts/same_as.h + __concepts/semiregular.h + __concepts/swappable.h + __concepts/totally_ordered.h + __config + __coroutine/coroutine_handle.h + __coroutine/coroutine_traits.h + __coroutine/noop_coroutine_handle.h + __coroutine/trivial_awaitables.h + __debug + __debug_utils/randomize_range.h + __errc + __expected/bad_expected_access.h + __expected/expected.h + __expected/unexpect.h + __expected/unexpected.h + __filesystem/copy_options.h + __filesystem/directory_entry.h + __filesystem/directory_iterator.h + __filesystem/directory_options.h + __filesystem/file_status.h + __filesystem/file_time_type.h + __filesystem/file_type.h + __filesystem/filesystem_error.h + __filesystem/operations.h + __filesystem/path.h + __filesystem/path_iterator.h + __filesystem/perm_options.h + __filesystem/perms.h + __filesystem/recursive_directory_iterator.h + __filesystem/space_info.h + __filesystem/u8path.h + __format/buffer.h + __format/concepts.h + __format/container_adaptor.h + __format/enable_insertable.h + __format/escaped_output_table.h + __format/extended_grapheme_cluster_table.h + __format/format_arg.h + __format/format_arg_store.h + __format/format_args.h + __format/format_context.h + __format/format_error.h + __format/format_functions.h + __format/format_fwd.h + __format/format_parse_context.h + __format/format_string.h + __format/format_to_n_result.h + __format/formatter.h + __format/formatter_bool.h + __format/formatter_char.h + __format/formatter_floating_point.h + __format/formatter_integer.h + __format/formatter_integral.h + __format/formatter_output.h + __format/formatter_pointer.h + __format/formatter_string.h + __format/formatter_tuple.h + __format/parser_std_format_spec.h + __format/range_default_formatter.h + __format/range_formatter.h + __format/unicode.h + __functional/binary_function.h + __functional/binary_negate.h + __functional/bind.h + __functional/bind_back.h + __functional/bind_front.h + __functional/binder1st.h + __functional/binder2nd.h + __functional/boyer_moore_searcher.h + __functional/compose.h + __functional/default_searcher.h + __functional/function.h + __functional/hash.h + __functional/identity.h + __functional/invoke.h + __functional/is_transparent.h + __functional/mem_fn.h + __functional/mem_fun_ref.h + __functional/not_fn.h + __functional/operations.h + __functional/perfect_forward.h + __functional/pointer_to_binary_function.h + __functional/pointer_to_unary_function.h + __functional/ranges_operations.h + __functional/reference_wrapper.h + __functional/unary_function.h + __functional/unary_negate.h + __functional/unwrap_ref.h + __functional/weak_result_type.h + __fwd/array.h + __fwd/get.h + __fwd/hash.h + __fwd/memory_resource.h + __fwd/pair.h + __fwd/span.h + __fwd/string.h + __fwd/string_view.h + __fwd/subrange.h + __fwd/tuple.h + __hash_table + __ios/fpos.h + __iterator/access.h + __iterator/advance.h + __iterator/back_insert_iterator.h + __iterator/bounded_iter.h + __iterator/common_iterator.h + __iterator/concepts.h + __iterator/counted_iterator.h + __iterator/data.h + __iterator/default_sentinel.h + __iterator/distance.h + __iterator/empty.h + __iterator/erase_if_container.h + __iterator/front_insert_iterator.h + __iterator/incrementable_traits.h + __iterator/indirectly_comparable.h + __iterator/insert_iterator.h + __iterator/istream_iterator.h + __iterator/istreambuf_iterator.h + __iterator/iter_move.h + __iterator/iter_swap.h + __iterator/iterator.h + __iterator/iterator_traits.h + __iterator/iterator_with_data.h + __iterator/mergeable.h + __iterator/move_iterator.h + __iterator/move_sentinel.h + __iterator/next.h + __iterator/ostream_iterator.h + __iterator/ostreambuf_iterator.h + __iterator/permutable.h + __iterator/prev.h + __iterator/projected.h + __iterator/readable_traits.h + __iterator/reverse_access.h + __iterator/reverse_iterator.h + __iterator/segmented_iterator.h + __iterator/size.h + __iterator/sortable.h + __iterator/unreachable_sentinel.h + __iterator/wrap_iter.h + __locale + __mbstate_t.h + __memory/addressof.h + __memory/align.h + __memory/allocate_at_least.h + __memory/allocation_guard.h + __memory/allocator.h + __memory/allocator_arg_t.h + __memory/allocator_destructor.h + __memory/allocator_traits.h + __memory/assume_aligned.h + __memory/auto_ptr.h + __memory/builtin_new_allocator.h + __memory/compressed_pair.h + __memory/concepts.h + __memory/construct_at.h + __memory/destruct_n.h + __memory/pointer_traits.h + __memory/ranges_construct_at.h + __memory/ranges_uninitialized_algorithms.h + __memory/raw_storage_iterator.h + __memory/shared_ptr.h + __memory/swap_allocator.h + __memory/temp_value.h + __memory/temporary_buffer.h + __memory/uninitialized_algorithms.h + __memory/unique_ptr.h + __memory/uses_allocator.h + __memory/uses_allocator_construction.h + __memory/voidify.h + __memory_resource/memory_resource.h + __memory_resource/monotonic_buffer_resource.h + __memory_resource/polymorphic_allocator.h + __memory_resource/pool_options.h + __memory_resource/synchronized_pool_resource.h + __memory_resource/unsynchronized_pool_resource.h + __mutex_base + __node_handle + __numeric/accumulate.h + __numeric/adjacent_difference.h + __numeric/exclusive_scan.h + __numeric/gcd_lcm.h + __numeric/inclusive_scan.h + __numeric/inner_product.h + __numeric/iota.h + __numeric/midpoint.h + __numeric/partial_sum.h + __numeric/reduce.h + __numeric/transform_exclusive_scan.h + __numeric/transform_inclusive_scan.h + __numeric/transform_reduce.h + __random/bernoulli_distribution.h + __random/binomial_distribution.h + __random/cauchy_distribution.h + __random/chi_squared_distribution.h + __random/clamp_to_integral.h + __random/default_random_engine.h + __random/discard_block_engine.h + __random/discrete_distribution.h + __random/exponential_distribution.h + __random/extreme_value_distribution.h + __random/fisher_f_distribution.h + __random/gamma_distribution.h + __random/generate_canonical.h + __random/geometric_distribution.h + __random/independent_bits_engine.h + __random/is_seed_sequence.h + __random/is_valid.h + __random/knuth_b.h + __random/linear_congruential_engine.h + __random/log2.h + __random/lognormal_distribution.h + __random/mersenne_twister_engine.h + __random/negative_binomial_distribution.h + __random/normal_distribution.h + __random/piecewise_constant_distribution.h + __random/piecewise_linear_distribution.h + __random/poisson_distribution.h + __random/random_device.h + __random/ranlux.h + __random/seed_seq.h + __random/shuffle_order_engine.h + __random/student_t_distribution.h + __random/subtract_with_carry_engine.h + __random/uniform_int_distribution.h + __random/uniform_random_bit_generator.h + __random/uniform_real_distribution.h + __random/weibull_distribution.h + __ranges/access.h + __ranges/all.h + __ranges/as_rvalue_view.h + __ranges/common_view.h + __ranges/concepts.h + __ranges/copyable_box.h + __ranges/counted.h + __ranges/dangling.h + __ranges/data.h + __ranges/drop_view.h + __ranges/drop_while_view.h + __ranges/elements_view.h + __ranges/empty.h + __ranges/empty_view.h + __ranges/enable_borrowed_range.h + __ranges/enable_view.h + __ranges/filter_view.h + __ranges/iota_view.h + __ranges/istream_view.h + __ranges/join_view.h + __ranges/lazy_split_view.h + __ranges/non_propagating_cache.h + __ranges/owning_view.h + __ranges/range_adaptor.h + __ranges/rbegin.h + __ranges/ref_view.h + __ranges/rend.h + __ranges/reverse_view.h + __ranges/single_view.h + __ranges/size.h + __ranges/split_view.h + __ranges/subrange.h + __ranges/take_view.h + __ranges/take_while_view.h + __ranges/transform_view.h + __ranges/view_interface.h + __ranges/views.h + __ranges/zip_view.h + __split_buffer + __std_stream + __string/char_traits.h + __string/extern_template_lists.h + __support/android/locale_bionic.h + __support/fuchsia/xlocale.h + __support/ibm/gettod_zos.h + __support/ibm/locale_mgmt_zos.h + __support/ibm/nanosleep.h + __support/ibm/xlocale.h + __support/musl/xlocale.h + __support/newlib/xlocale.h + __support/openbsd/xlocale.h + __support/solaris/floatingpoint.h + __support/solaris/wchar.h + __support/solaris/xlocale.h + __support/win32/locale_win32.h + __support/xlocale/__nop_locale_mgmt.h + __support/xlocale/__posix_l_fallback.h + __support/xlocale/__strtonum_fallback.h + __thread/poll_with_backoff.h + __thread/timed_backoff_policy.h + __threading_support + __tree + __tuple_dir/apply_cv.h + __tuple_dir/make_tuple_types.h + __tuple_dir/pair_like.h + __tuple_dir/sfinae_helpers.h + __tuple_dir/tuple_element.h + __tuple_dir/tuple_indices.h + __tuple_dir/tuple_like.h + __tuple_dir/tuple_like_ext.h + __tuple_dir/tuple_size.h + __tuple_dir/tuple_types.h + __type_traits/add_const.h + __type_traits/add_cv.h + __type_traits/add_lvalue_reference.h + __type_traits/add_pointer.h + __type_traits/add_rvalue_reference.h + __type_traits/add_volatile.h + __type_traits/aligned_storage.h + __type_traits/aligned_union.h + __type_traits/alignment_of.h + __type_traits/apply_cv.h + __type_traits/can_extract_key.h + __type_traits/common_reference.h + __type_traits/common_type.h + __type_traits/conditional.h + __type_traits/conjunction.h + __type_traits/copy_cv.h + __type_traits/copy_cvref.h + __type_traits/decay.h + __type_traits/dependent_type.h + __type_traits/disjunction.h + __type_traits/enable_if.h + __type_traits/extent.h + __type_traits/has_unique_object_representation.h + __type_traits/has_virtual_destructor.h + __type_traits/integral_constant.h + __type_traits/is_abstract.h + __type_traits/is_aggregate.h + __type_traits/is_allocator.h + __type_traits/is_always_bitcastable.h + __type_traits/is_arithmetic.h + __type_traits/is_array.h + __type_traits/is_assignable.h + __type_traits/is_base_of.h + __type_traits/is_bounded_array.h + __type_traits/is_callable.h + __type_traits/is_char_like_type.h + __type_traits/is_class.h + __type_traits/is_compound.h + __type_traits/is_const.h + __type_traits/is_constant_evaluated.h + __type_traits/is_constructible.h + __type_traits/is_convertible.h + __type_traits/is_copy_assignable.h + __type_traits/is_copy_constructible.h + __type_traits/is_core_convertible.h + __type_traits/is_default_constructible.h + __type_traits/is_destructible.h + __type_traits/is_empty.h + __type_traits/is_enum.h + __type_traits/is_final.h + __type_traits/is_floating_point.h + __type_traits/is_function.h + __type_traits/is_fundamental.h + __type_traits/is_implicitly_default_constructible.h + __type_traits/is_integral.h + __type_traits/is_literal_type.h + __type_traits/is_member_function_pointer.h + __type_traits/is_member_object_pointer.h + __type_traits/is_member_pointer.h + __type_traits/is_move_assignable.h + __type_traits/is_move_constructible.h + __type_traits/is_nothrow_assignable.h + __type_traits/is_nothrow_constructible.h + __type_traits/is_nothrow_convertible.h + __type_traits/is_nothrow_copy_assignable.h + __type_traits/is_nothrow_copy_constructible.h + __type_traits/is_nothrow_default_constructible.h + __type_traits/is_nothrow_destructible.h + __type_traits/is_nothrow_move_assignable.h + __type_traits/is_nothrow_move_constructible.h + __type_traits/is_null_pointer.h + __type_traits/is_object.h + __type_traits/is_pod.h + __type_traits/is_pointer.h + __type_traits/is_polymorphic.h + __type_traits/is_primary_template.h + __type_traits/is_reference.h + __type_traits/is_reference_wrapper.h + __type_traits/is_referenceable.h + __type_traits/is_same.h + __type_traits/is_scalar.h + __type_traits/is_scoped_enum.h + __type_traits/is_signed.h + __type_traits/is_signed_integer.h + __type_traits/is_specialization.h + __type_traits/is_standard_layout.h + __type_traits/is_swappable.h + __type_traits/is_trivial.h + __type_traits/is_trivially_assignable.h + __type_traits/is_trivially_constructible.h + __type_traits/is_trivially_copy_assignable.h + __type_traits/is_trivially_copy_constructible.h + __type_traits/is_trivially_copyable.h + __type_traits/is_trivially_default_constructible.h + __type_traits/is_trivially_destructible.h + __type_traits/is_trivially_move_assignable.h + __type_traits/is_trivially_move_constructible.h + __type_traits/is_unbounded_array.h + __type_traits/is_union.h + __type_traits/is_unsigned.h + __type_traits/is_unsigned_integer.h + __type_traits/is_valid_expansion.h + __type_traits/is_void.h + __type_traits/is_volatile.h + __type_traits/lazy.h + __type_traits/make_32_64_or_128_bit.h + __type_traits/make_const_lvalue_ref.h + __type_traits/make_signed.h + __type_traits/make_unsigned.h + __type_traits/maybe_const.h + __type_traits/nat.h + __type_traits/negation.h + __type_traits/noexcept_move_assign_container.h + __type_traits/promote.h + __type_traits/rank.h + __type_traits/remove_all_extents.h + __type_traits/remove_const.h + __type_traits/remove_const_ref.h + __type_traits/remove_cv.h + __type_traits/remove_cvref.h + __type_traits/remove_extent.h + __type_traits/remove_pointer.h + __type_traits/remove_reference.h + __type_traits/remove_volatile.h + __type_traits/result_of.h + __type_traits/strip_signature.h + __type_traits/type_identity.h + __type_traits/type_list.h + __type_traits/underlying_type.h + __type_traits/void_t.h + __undef_macros + __utility/as_const.h + __utility/auto_cast.h + __utility/cmp.h + __utility/convert_to_integral.h + __utility/declval.h + __utility/exception_guard.h + __utility/exchange.h + __utility/forward.h + __utility/forward_like.h + __utility/in_place.h + __utility/integer_sequence.h + __utility/move.h + __utility/pair.h + __utility/piecewise_construct.h + __utility/priority_tag.h + __utility/rel_ops.h + __utility/swap.h + __utility/to_underlying.h + __utility/unreachable.h + __variant/monostate.h + __verbose_abort + algorithm + any + array + atomic + barrier + bit + bitset + cassert + ccomplex + cctype + cerrno + cfenv + cfloat + charconv + chrono + cinttypes + ciso646 + climits + clocale + cmath + codecvt + compare + complex + complex.h + concepts + condition_variable + coroutine + csetjmp + csignal + cstdarg + cstdbool + cstddef + cstdint + cstdio + cstdlib + cstring + ctgmath + ctime + ctype.h + cuchar + cwchar + cwctype + deque + errno.h + exception + execution + expected + experimental/__config + experimental/__memory + experimental/algorithm + experimental/coroutine + experimental/deque + experimental/forward_list + experimental/functional + experimental/iterator + experimental/list + experimental/map + experimental/memory_resource + experimental/propagate_const + experimental/regex + experimental/set + experimental/simd + experimental/string + experimental/type_traits + experimental/unordered_map + experimental/unordered_set + experimental/utility + experimental/vector + ext/__hash + ext/hash_map + ext/hash_set + fenv.h + filesystem + float.h + format + forward_list + fstream + functional + future + initializer_list + inttypes.h + iomanip + ios + iosfwd + iostream + istream + iterator + latch + libcxx.imp + limits + limits.h + list + locale + locale.h + map + math.h + memory + memory_resource + mutex + new + numbers + numeric + optional + ostream + queue + random + ranges + ratio + regex + scoped_allocator + semaphore + set + setjmp.h + shared_mutex + source_location + span + sstream + stack + stdatomic.h + stdbool.h + stddef.h + stdexcept + stdint.h + stdio.h + stdlib.h + streambuf + string + string.h + string_view + strstream + system_error + tgmath.h + thread + tuple + type_traits + typeindex + typeinfo + uchar.h + unordered_map + unordered_set + utility + valarray + variant + vector + version + wchar.h + wctype.h + ) + +foreach(feature LIBCXX_ENABLE_FILESYSTEM LIBCXX_ENABLE_LOCALIZATION LIBCXX_ENABLE_FSTREAM LIBCXX_ENABLE_THREADS LIBCXX_ENABLE_WIDE_CHARACTERS) + if (NOT ${${feature}}) + set(requires_${feature} "requires LIBCXX_CONFIGURED_WITHOUT_SUPPORT_FOR_THIS_HEADER") + endif() +endforeach() + +configure_file("__config_site.in" "${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}/__config_site" @ONLY) +configure_file("module.modulemap.in" "${LIBCXX_GENERATED_INCLUDE_DIR}/module.modulemap" @ONLY) + +set(_all_includes "${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}/__config_site" + "${LIBCXX_GENERATED_INCLUDE_DIR}/module.modulemap") +foreach(f ${files}) + set(src "${CMAKE_CURRENT_SOURCE_DIR}/${f}") + set(dst "${LIBCXX_GENERATED_INCLUDE_DIR}/${f}") + add_custom_command(OUTPUT ${dst} + DEPENDS ${src} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst} + COMMENT "Copying CXX header ${f}") + list(APPEND _all_includes "${dst}") +endforeach() + +add_custom_target(generate-cxx-headers ALL DEPENDS ${_all_includes}) + +add_library(cxx-headers INTERFACE) +target_link_libraries(cxx-headers INTERFACE libcxx-abi-headers) +add_dependencies(cxx-headers generate-cxx-headers) +target_include_directories(cxx-headers INTERFACE ${LIBCXX_GENERATED_INCLUDE_DIR} + ${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}) + +if (LIBCXX_INSTALL_HEADERS) + foreach(file ${files}) + get_filename_component(dir ${file} DIRECTORY) + install(FILES ${file} + DESTINATION "${LIBCXX_INSTALL_INCLUDE_DIR}/${dir}" + COMPONENT cxx-headers + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ + ) + endforeach() + + # Install the generated __config_site file to the per-target include dir. + install(FILES "${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}/__config_site" + DESTINATION "${LIBCXX_INSTALL_INCLUDE_TARGET_DIR}" + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ + COMPONENT cxx-headers) + + # Install the generated modulemap file to the generic include dir. + install(FILES "${LIBCXX_GENERATED_INCLUDE_DIR}/module.modulemap" + DESTINATION "${LIBCXX_INSTALL_INCLUDE_DIR}" + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ + COMPONENT cxx-headers) + + if (NOT CMAKE_CONFIGURATION_TYPES) + add_custom_target(install-cxx-headers + DEPENDS cxx-headers + COMMAND "${CMAKE_COMMAND}" + -DCMAKE_INSTALL_COMPONENT=cxx-headers + -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") + # Stripping is a no-op for headers + add_custom_target(install-cxx-headers-stripped DEPENDS install-cxx-headers) + endif() +endif() diff --git a/app/src/main/cpp/libcxx/include/__algorithm/adjacent_find.h b/app/src/main/cpp/libcxx/include/__algorithm/adjacent_find.h new file mode 100644 index 0000000..30df4a9 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/adjacent_find.h @@ -0,0 +1,53 @@ +// -*- 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 _LIBCPP___ALGORITHM_ADJACENT_FIND_H +#define _LIBCPP___ALGORITHM_ADJACENT_FIND_H + +#include <__algorithm/comp.h> +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter +__adjacent_find(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) { + if (__first == __last) + return __first; + _Iter __i = __first; + while (++__i != __last) { + if (__pred(*__first, *__i)) + return __first; + __first = __i; + } + return __i; +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) { + return std::__adjacent_find(std::move(__first), std::move(__last), __pred); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +adjacent_find(_ForwardIterator __first, _ForwardIterator __last) { + return std::adjacent_find(std::move(__first), std::move(__last), __equal_to()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_ADJACENT_FIND_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/all_of.h b/app/src/main/cpp/libcxx/include/__algorithm/all_of.h new file mode 100644 index 0000000..284c34f --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/all_of.h @@ -0,0 +1,32 @@ +// -*- 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 _LIBCPP___ALGORITHM_ALL_OF_H +#define _LIBCPP___ALGORITHM_ALL_OF_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { + for (; __first != __last; ++__first) + if (!__pred(*__first)) + return false; + return true; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_ALL_OF_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/any_of.h b/app/src/main/cpp/libcxx/include/__algorithm/any_of.h new file mode 100644 index 0000000..fe08828 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/any_of.h @@ -0,0 +1,32 @@ +// -*- 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 _LIBCPP___ALGORITHM_ANY_OF_H +#define _LIBCPP___ALGORITHM_ANY_OF_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { + for (; __first != __last; ++__first) + if (__pred(*__first)) + return true; + return false; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_ANY_OF_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/binary_search.h b/app/src/main/cpp/libcxx/include/__algorithm/binary_search.h new file mode 100644 index 0000000..8f958c2 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/binary_search.h @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_BINARY_SEARCH_H +#define _LIBCPP___ALGORITHM_BINARY_SEARCH_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/lower_bound.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +bool +binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) +{ + __first = std::lower_bound<_ForwardIterator, _Tp, __comp_ref_type<_Compare> >(__first, __last, __value, __comp); + return __first != __last && !__comp(__value, *__first); +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +bool +binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) +{ + return std::binary_search(__first, __last, __value, + __less::value_type, _Tp>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_BINARY_SEARCH_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/clamp.h b/app/src/main/cpp/libcxx/include/__algorithm/clamp.h new file mode 100644 index 0000000..30ddbdc --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/clamp.h @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_CLAMP_H +#define _LIBCPP___ALGORITHM_CLAMP_H + +#include <__algorithm/comp.h> +#include <__assert> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY constexpr +const _Tp& +clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi, _Compare __comp) +{ + _LIBCPP_ASSERT(!__comp(__hi, __lo), "Bad bounds passed to std::clamp"); + return __comp(__v, __lo) ? __lo : __comp(__hi, __v) ? __hi : __v; + +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY constexpr +const _Tp& +clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi) +{ + return _VSTD::clamp(__v, __lo, __hi, __less<_Tp>()); +} +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_CLAMP_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/comp.h b/app/src/main/cpp/libcxx/include/__algorithm/comp.h new file mode 100644 index 0000000..af8eb7b --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/comp.h @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_COMP_H +#define _LIBCPP___ALGORITHM_COMP_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +struct __equal_to { + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _T1& __x, const _T2& __y) const { + return __x == __y; + } +}; + +template +struct __less +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 + bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 + bool operator()(const _T1& __x, const _T2& __y) const {return __x < __y;} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 + bool operator()(const _T2& __x, const _T1& __y) const {return __x < __y;} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 + bool operator()(const _T2& __x, const _T2& __y) const {return __x < __y;} +}; + +template +struct __less<_T1, _T1> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 + bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} +}; + +template +struct __less +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 + bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} +}; + +template +struct __less<_T1, const _T1> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 + bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_COMP_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/comp_ref_type.h b/app/src/main/cpp/libcxx/include/__algorithm/comp_ref_type.h new file mode 100644 index 0000000..f2338e1 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/comp_ref_type.h @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_COMP_REF_TYPE_H +#define _LIBCPP___ALGORITHM_COMP_REF_TYPE_H + +#include <__config> +#include <__debug> +#include <__utility/declval.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __debug_less +{ + _Compare &__comp_; + _LIBCPP_CONSTEXPR_SINCE_CXX14 + __debug_less(_Compare& __c) : __comp_(__c) {} + + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 + bool operator()(const _Tp& __x, const _Up& __y) + { + bool __r = __comp_(__x, __y); + if (__r) + __do_compare_assert(0, __y, __x); + return __r; + } + + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 + bool operator()(_Tp& __x, _Up& __y) + { + bool __r = __comp_(__x, __y); + if (__r) + __do_compare_assert(0, __y, __x); + return __r; + } + + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 + inline _LIBCPP_INLINE_VISIBILITY + decltype((void)std::declval<_Compare&>()( + std::declval<_LHS &>(), std::declval<_RHS &>())) + __do_compare_assert(int, _LHS & __l, _RHS & __r) { + _LIBCPP_DEBUG_ASSERT(!__comp_(__l, __r), + "Comparator does not induce a strict weak ordering"); + (void)__l; + (void)__r; + } + + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 + inline _LIBCPP_INLINE_VISIBILITY + void __do_compare_assert(long, _LHS &, _RHS &) {} +}; + +// Pass the comparator by lvalue reference. Or in debug mode, using a +// debugging wrapper that stores a reference. +#ifdef _LIBCPP_ENABLE_DEBUG_MODE +template +using __comp_ref_type = __debug_less<_Comp>; +#else +template +using __comp_ref_type = _Comp&; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_COMP_REF_TYPE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/copy.h b/app/src/main/cpp/libcxx/include/__algorithm/copy.h new file mode 100644 index 0000000..193a6df --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/copy.h @@ -0,0 +1,126 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_COPY_H +#define _LIBCPP___ALGORITHM_COPY_H + +#include <__algorithm/copy_move_common.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/min.h> +#include <__config> +#include <__iterator/segmented_iterator.h> +#include <__type_traits/common_type.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> __copy(_InIter, _Sent, _OutIter); + +template +struct __copy_loop { + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> + operator()(_InIter __first, _Sent __last, _OutIter __result) const { + while (__first != __last) { + *__result = *__first; + ++__first; + ++__result; + } + + return std::make_pair(std::move(__first), std::move(__result)); + } + + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> + operator()(_InIter __first, _InIter __last, _OutIter __result) const { + using _Traits = __segmented_iterator_traits<_InIter>; + auto __sfirst = _Traits::__segment(__first); + auto __slast = _Traits::__segment(__last); + if (__sfirst == __slast) { + auto __iters = std::__copy<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result)); + return std::make_pair(__last, std::move(__iters.second)); + } + + __result = std::__copy<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__sfirst), std::move(__result)).second; + ++__sfirst; + while (__sfirst != __slast) { + __result = + std::__copy<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__end(__sfirst), std::move(__result)).second; + ++__sfirst; + } + __result = + std::__copy<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__local(__last), std::move(__result)).second; + return std::make_pair(__last, std::move(__result)); + } + + template ::value && + !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value, + int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> + operator()(_InIter __first, _InIter __last, _OutIter __result) { + using _Traits = __segmented_iterator_traits<_OutIter>; + using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type; + + if (__first == __last) + return std::make_pair(std::move(__first), std::move(__result)); + + auto __local_first = _Traits::__local(__result); + auto __segment_iterator = _Traits::__segment(__result); + while (true) { + auto __local_last = _Traits::__end(__segment_iterator); + auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first); + auto __iters = std::__copy<_AlgPolicy>(__first, __first + __size, __local_first); + __first = std::move(__iters.first); + + if (__first == __last) + return std::make_pair(std::move(__first), _Traits::__compose(__segment_iterator, std::move(__iters.second))); + + __local_first = _Traits::__begin(++__segment_iterator); + } + } +}; + +struct __copy_trivial { + // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer. + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> + operator()(_In* __first, _In* __last, _Out* __result) const { + return std::__copy_trivial_impl(__first, __last, __result); + } +}; + +template +pair<_InIter, _OutIter> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +__copy(_InIter __first, _Sent __last, _OutIter __result) { + return std::__dispatch_copy_or_move<_AlgPolicy, __copy_loop<_AlgPolicy>, __copy_trivial>( + std::move(__first), std::move(__last), std::move(__result)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { + return std::__copy<_ClassicAlgPolicy>(__first, __last, __result).second; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_COPY_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/copy_backward.h b/app/src/main/cpp/libcxx/include/__algorithm/copy_backward.h new file mode 100644 index 0000000..bb2a432 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/copy_backward.h @@ -0,0 +1,143 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_COPY_BACKWARD_H +#define _LIBCPP___ALGORITHM_COPY_BACKWARD_H + +#include <__algorithm/copy_move_common.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/min.h> +#include <__config> +#include <__iterator/segmented_iterator.h> +#include <__type_traits/common_type.h> +#include <__type_traits/is_copy_constructible.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InIter, _OutIter> +__copy_backward(_InIter __first, _Sent __last, _OutIter __result); + +template +struct __copy_backward_loop { + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> + operator()(_InIter __first, _Sent __last, _OutIter __result) const { + auto __last_iter = _IterOps<_AlgPolicy>::next(__first, __last); + auto __original_last_iter = __last_iter; + + while (__first != __last_iter) { + *--__result = *--__last_iter; + } + + return std::make_pair(std::move(__original_last_iter), std::move(__result)); + } + + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> + operator()(_InIter __first, _InIter __last, _OutIter __result) const { + using _Traits = __segmented_iterator_traits<_InIter>; + auto __sfirst = _Traits::__segment(__first); + auto __slast = _Traits::__segment(__last); + if (__sfirst == __slast) { + auto __iters = + std::__copy_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result)); + return std::make_pair(__last, __iters.second); + } + + __result = + std::__copy_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__local(__last), std::move(__result)) + .second; + --__slast; + while (__sfirst != __slast) { + __result = + std::__copy_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__end(__slast), std::move(__result)) + .second; + --__slast; + } + __result = std::__copy_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__slast), std::move(__result)) + .second; + return std::make_pair(__last, std::move(__result)); + } + + template ::value && + !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value, + int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> + operator()(_InIter __first, _InIter __last, _OutIter __result) { + using _Traits = __segmented_iterator_traits<_OutIter>; + auto __orig_last = __last; + auto __segment_iterator = _Traits::__segment(__result); + + // When the range contains no elements, __result might not be a valid iterator + if (__first == __last) + return std::make_pair(__first, __result); + + auto __local_last = _Traits::__local(__result); + while (true) { + using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type; + + auto __local_first = _Traits::__begin(__segment_iterator); + auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first); + auto __iter = std::__copy_backward<_AlgPolicy>(__last - __size, __last, __local_last).second; + __last -= __size; + + if (__first == __last) + return std::make_pair(std::move(__orig_last), _Traits::__compose(__segment_iterator, std::move(__iter))); + --__segment_iterator; + __local_last = _Traits::__end(__segment_iterator); + } + } +}; + +struct __copy_backward_trivial { + // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer. + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> + operator()(_In* __first, _In* __last, _Out* __result) const { + return std::__copy_backward_trivial_impl(__first, __last, __result); + } +}; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator1, _BidirectionalIterator2> +__copy_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result) { + return std::__dispatch_copy_or_move<_AlgPolicy, __copy_backward_loop<_AlgPolicy>, __copy_backward_trivial>( + std::move(__first), std::move(__last), std::move(__result)); +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +_BidirectionalIterator2 +copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, + _BidirectionalIterator2 __result) +{ + static_assert(std::is_copy_constructible<_BidirectionalIterator1>::value && + std::is_copy_constructible<_BidirectionalIterator1>::value, "Iterators must be copy constructible."); + + return std::__copy_backward<_ClassicAlgPolicy>( + std::move(__first), std::move(__last), std::move(__result)).second; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_COPY_BACKWARD_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/copy_if.h b/app/src/main/cpp/libcxx/include/__algorithm/copy_if.h new file mode 100644 index 0000000..a5938b8 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/copy_if.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_COPY_IF_H +#define _LIBCPP___ALGORITHM_COPY_IF_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +_OutputIterator +copy_if(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Predicate __pred) +{ + for (; __first != __last; ++__first) + { + if (__pred(*__first)) + { + *__result = *__first; + ++__result; + } + } + return __result; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_COPY_IF_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/copy_move_common.h b/app/src/main/cpp/libcxx/include/__algorithm/copy_move_common.h new file mode 100644 index 0000000..b88c149 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/copy_move_common.h @@ -0,0 +1,163 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_COPY_MOVE_COMMON_H +#define _LIBCPP___ALGORITHM_COPY_MOVE_COMMON_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/unwrap_iter.h> +#include <__algorithm/unwrap_range.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__memory/pointer_traits.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_always_bitcastable.h> +#include <__type_traits/is_constant_evaluated.h> +#include <__type_traits/is_copy_constructible.h> +#include <__type_traits/is_trivially_assignable.h> +#include <__type_traits/is_trivially_copyable.h> +#include <__type_traits/is_volatile.h> +#include <__utility/move.h> +#include <__utility/pair.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Type traits. + +template +struct __can_lower_copy_assignment_to_memmove { + static const bool value = + // If the types are always bitcastable, it's valid to do a bitwise copy between them. + __is_always_bitcastable<_From, _To>::value && + // Reject conversions that wouldn't be performed by the regular built-in assignment (e.g. between arrays). + is_trivially_assignable<_To&, const _From&>::value && + // `memmove` doesn't accept `volatile` pointers, make sure the optimization SFINAEs away in that case. + !is_volatile<_From>::value && + !is_volatile<_To>::value; +}; + +template +struct __can_lower_move_assignment_to_memmove { + static const bool value = + __is_always_bitcastable<_From, _To>::value && + is_trivially_assignable<_To&, _From&&>::value && + !is_volatile<_From>::value && + !is_volatile<_To>::value; +}; + +// `memmove` algorithms implementation. + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> +__copy_trivial_impl(_In* __first, _In* __last, _Out* __result) { + const size_t __n = static_cast(__last - __first); + ::__builtin_memmove(__result, __first, __n * sizeof(_Out)); + + return std::make_pair(__last, __result + __n); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> +__copy_backward_trivial_impl(_In* __first, _In* __last, _Out* __result) { + const size_t __n = static_cast(__last - __first); + __result -= __n; + + ::__builtin_memmove(__result, __first, __n * sizeof(_Out)); + + return std::make_pair(__last, __result); +} + +// Iterator unwrapping and dispatching to the correct overload. + +template +struct __overload : _F1, _F2 { + using _F1::operator(); + using _F2::operator(); +}; + +template +struct __can_rewrap : false_type {}; + +template +struct __can_rewrap<_InIter, + _Sent, + _OutIter, + // Note that sentinels are always copy-constructible. + __enable_if_t< is_copy_constructible<_InIter>::value && + is_copy_constructible<_OutIter>::value > > : true_type {}; + +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter> +__unwrap_and_dispatch(_InIter __first, _Sent __last, _OutIter __out_first) { + auto __range = std::__unwrap_range(__first, std::move(__last)); + auto __result = _Algorithm()(std::move(__range.first), std::move(__range.second), std::__unwrap_iter(__out_first)); + return std::make_pair(std::__rewrap_range<_Sent>(std::move(__first), std::move(__result.first)), + std::__rewrap_iter(std::move(__out_first), std::move(__result.second))); +} + +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter> +__unwrap_and_dispatch(_InIter __first, _Sent __last, _OutIter __out_first) { + return _Algorithm()(std::move(__first), std::move(__last), std::move(__out_first)); +} + +template +struct __can_copy_without_conversion : false_type {}; + +template +struct __can_copy_without_conversion< + _IterOps, + _InValue, + _OutIter, + __enable_if_t >::value> > : true_type {}; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter> +__dispatch_copy_or_move(_InIter __first, _Sent __last, _OutIter __out_first) { +#ifdef _LIBCPP_COMPILER_GCC + // GCC doesn't support `__builtin_memmove` during constant evaluation. + if (__libcpp_is_constant_evaluated()) { + return std::__unwrap_and_dispatch<_NaiveAlgorithm>(std::move(__first), std::move(__last), std::move(__out_first)); + } +#else + // In Clang, `__builtin_memmove` only supports fully trivially copyable types (just having trivial copy assignment is + // insufficient). Also, conversions are not supported. + if (__libcpp_is_constant_evaluated()) { + using _InValue = typename _IterOps<_AlgPolicy>::template __value_type<_InIter>; + if (!is_trivially_copyable<_InValue>::value || + !__can_copy_without_conversion<_IterOps<_AlgPolicy>, _InValue, _OutIter>::value) { + return std::__unwrap_and_dispatch<_NaiveAlgorithm>(std::move(__first), std::move(__last), std::move(__out_first)); + } + } +#endif // _LIBCPP_COMPILER_GCC + + using _Algorithm = __overload<_NaiveAlgorithm, _OptimizedAlgorithm>; + return std::__unwrap_and_dispatch<_Algorithm>(std::move(__first), std::move(__last), std::move(__out_first)); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_COPY_MOVE_COMMON_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/copy_n.h b/app/src/main/cpp/libcxx/include/__algorithm/copy_n.h new file mode 100644 index 0000000..b08bbdf --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/copy_n.h @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_COPY_N_H +#define _LIBCPP___ALGORITHM_COPY_N_H + +#include <__algorithm/copy.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/convert_to_integral.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +typename enable_if +< + __is_cpp17_input_iterator<_InputIterator>::value && + !__is_cpp17_random_access_iterator<_InputIterator>::value, + _OutputIterator +>::type +copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) +{ + typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; + _IntegralSize __n = __orig_n; + if (__n > 0) + { + *__result = *__first; + ++__result; + for (--__n; __n > 0; --__n) + { + ++__first; + *__result = *__first; + ++__result; + } + } + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +typename enable_if +< + __is_cpp17_random_access_iterator<_InputIterator>::value, + _OutputIterator +>::type +copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) +{ + typedef typename iterator_traits<_InputIterator>::difference_type difference_type; + typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; + _IntegralSize __n = __orig_n; + return _VSTD::copy(__first, __first + difference_type(__n), __result); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_COPY_N_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/count.h b/app/src/main/cpp/libcxx/include/__algorithm/count.h new file mode 100644 index 0000000..6c8c7fd --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/count.h @@ -0,0 +1,35 @@ +// -*- 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 _LIBCPP___ALGORITHM_COUNT_H +#define _LIBCPP___ALGORITHM_COUNT_H + +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + typename iterator_traits<_InputIterator>::difference_type + count(_InputIterator __first, _InputIterator __last, const _Tp& __value) { + typename iterator_traits<_InputIterator>::difference_type __r(0); + for (; __first != __last; ++__first) + if (*__first == __value) + ++__r; + return __r; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_COUNT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/count_if.h b/app/src/main/cpp/libcxx/include/__algorithm/count_if.h new file mode 100644 index 0000000..b96521f --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/count_if.h @@ -0,0 +1,35 @@ +// -*- 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 _LIBCPP___ALGORITHM_COUNT_IF_H +#define _LIBCPP___ALGORITHM_COUNT_IF_H + +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + typename iterator_traits<_InputIterator>::difference_type + count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { + typename iterator_traits<_InputIterator>::difference_type __r(0); + for (; __first != __last; ++__first) + if (__pred(*__first)) + ++__r; + return __r; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_COUNT_IF_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/equal.h b/app/src/main/cpp/libcxx/include/__algorithm/equal.h new file mode 100644 index 0000000..cf37f46 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/equal.h @@ -0,0 +1,86 @@ +// -*- 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 _LIBCPP___ALGORITHM_EQUAL_H +#define _LIBCPP___ALGORITHM_EQUAL_H + +#include <__algorithm/comp.h> +#include <__config> +#include <__iterator/distance.h> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) { + for (; __first1 != __last1; ++__first1, (void)++__first2) + if (!__pred(*__first1, *__first2)) + return false; + return true; +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) { + return std::equal(__first1, __last1, __first2, __equal_to()); +} + +#if _LIBCPP_STD_VER > 11 +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +__equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, + _BinaryPredicate __pred, input_iterator_tag, input_iterator_tag) { + for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2) + if (!__pred(*__first1, *__first2)) + return false; + return __first1 == __last1 && __first2 == __last2; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +__equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag, + random_access_iterator_tag) { + if (_VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2)) + return false; + return _VSTD::equal<_RandomAccessIterator1, _RandomAccessIterator2, + _BinaryPredicate&>(__first1, __last1, __first2, __pred); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, + _BinaryPredicate __pred) { + return _VSTD::__equal<_BinaryPredicate&>( + __first1, __last1, __first2, __last2, __pred, typename iterator_traits<_InputIterator1>::iterator_category(), + typename iterator_traits<_InputIterator2>::iterator_category()); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { + return std::__equal( + __first1, + __last1, + __first2, + __last2, + __equal_to(), + typename iterator_traits<_InputIterator1>::iterator_category(), + typename iterator_traits<_InputIterator2>::iterator_category()); +} +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_EQUAL_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/equal_range.h b/app/src/main/cpp/libcxx/include/__algorithm/equal_range.h new file mode 100644 index 0000000..2075b03 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/equal_range.h @@ -0,0 +1,87 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_EQUAL_RANGE_H +#define _LIBCPP___ALGORITHM_EQUAL_RANGE_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/half_positive.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/lower_bound.h> +#include <__algorithm/upper_bound.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/advance.h> +#include <__iterator/distance.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__type_traits/is_callable.h> +#include <__type_traits/is_copy_constructible.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter, _Iter> +__equal_range(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp, _Proj&& __proj) { + auto __len = _IterOps<_AlgPolicy>::distance(__first, __last); + _Iter __end = _IterOps<_AlgPolicy>::next(__first, __last); + while (__len != 0) { + auto __half_len = std::__half_positive(__len); + _Iter __mid = _IterOps<_AlgPolicy>::next(__first, __half_len); + if (std::__invoke(__comp, std::__invoke(__proj, *__mid), __value)) { + __first = ++__mid; + __len -= __half_len + 1; + } else if (std::__invoke(__comp, __value, std::__invoke(__proj, *__mid))) { + __end = __mid; + __len = __half_len; + } else { + _Iter __mp1 = __mid; + return pair<_Iter, _Iter>( + std::__lower_bound_impl<_AlgPolicy>(__first, __mid, __value, __comp, __proj), + std::__upper_bound<_AlgPolicy>(++__mp1, __end, __value, __comp, __proj)); + } + } + return pair<_Iter, _Iter>(__first, __first); +} + +template +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> +equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { + static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, + "The comparator has to be callable"); + static_assert(is_copy_constructible<_ForwardIterator>::value, + "Iterator has to be copy constructible"); + return std::__equal_range<_ClassicAlgPolicy>( + std::move(__first), + std::move(__last), + __value, + static_cast<__comp_ref_type<_Compare> >(__comp), + std::__identity()); +} + +template +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> +equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + return std::equal_range( + std::move(__first), + std::move(__last), + __value, + __less::value_type, _Tp>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_EQUAL_RANGE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/fill.h b/app/src/main/cpp/libcxx/include/__algorithm/fill.h new file mode 100644 index 0000000..76cf4a1 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/fill.h @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_FILL_H +#define _LIBCPP___ALGORITHM_FILL_H + +#include <__algorithm/fill_n.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// fill isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset. + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +void +__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, forward_iterator_tag) +{ + for (; __first != __last; ++__first) + *__first = __value; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +void +__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value, random_access_iterator_tag) +{ + _VSTD::fill_n(__first, __last - __first, __value); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +void +fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) +{ + _VSTD::__fill(__first, __last, __value, typename iterator_traits<_ForwardIterator>::iterator_category()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_FILL_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/fill_n.h b/app/src/main/cpp/libcxx/include/__algorithm/fill_n.h new file mode 100644 index 0000000..fe58c8d --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/fill_n.h @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_FILL_N_H +#define _LIBCPP___ALGORITHM_FILL_N_H + +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/convert_to_integral.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// fill_n isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset. + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +_OutputIterator +__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) +{ + for (; __n > 0; ++__first, (void) --__n) + *__first = __value; + return __first; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +_OutputIterator +fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) +{ + return _VSTD::__fill_n(__first, _VSTD::__convert_to_integral(__n), __value); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_FILL_N_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/find.h b/app/src/main/cpp/libcxx/include/__algorithm/find.h new file mode 100644 index 0000000..e51dc9b --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/find.h @@ -0,0 +1,32 @@ +// -*- 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 _LIBCPP___ALGORITHM_FIND_H +#define _LIBCPP___ALGORITHM_FIND_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator +find(_InputIterator __first, _InputIterator __last, const _Tp& __value) { + for (; __first != __last; ++__first) + if (*__first == __value) + break; + return __first; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_FIND_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/find_end.h b/app/src/main/cpp/libcxx/include/__algorithm/find_end.h new file mode 100644 index 0000000..e2fee6b --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/find_end.h @@ -0,0 +1,227 @@ +// -*- 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 _LIBCPP___ALGORITHM_FIND_END_OF_H +#define _LIBCPP___ALGORITHM_FIND_END_OF_H + +#include <__algorithm/comp.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/search.h> +#include <__config> +#include <__functional/identity.h> +#include <__iterator/advance.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/reverse_iterator.h> +#include <__utility/pair.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template < + class _AlgPolicy, + class _Iter1, + class _Sent1, + class _Iter2, + class _Sent2, + class _Pred, + class _Proj1, + class _Proj2> +_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __find_end_impl( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2, + forward_iterator_tag, + forward_iterator_tag) { + // modeled after search algorithm + _Iter1 __match_first = _IterOps<_AlgPolicy>::next(__first1, __last1); // __last1 is the "default" answer + _Iter1 __match_last = __match_first; + if (__first2 == __last2) + return pair<_Iter1, _Iter1>(__match_last, __match_last); + while (true) { + while (true) { + if (__first1 == __last1) // if source exhausted return last correct answer (or __last1 if never found) + return pair<_Iter1, _Iter1>(__match_first, __match_last); + if (std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2))) + break; + ++__first1; + } + // *__first1 matches *__first2, now match elements after here + _Iter1 __m1 = __first1; + _Iter2 __m2 = __first2; + while (true) { + if (++__m2 == __last2) { // Pattern exhaused, record answer and search for another one + __match_first = __first1; + __match_last = ++__m1; + ++__first1; + break; + } + if (++__m1 == __last1) // Source exhausted, return last answer + return pair<_Iter1, _Iter1>(__match_first, __match_last); + // mismatch, restart with a new __first + if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2))) + { + ++__first1; + break; + } // else there is a match, check next elements + } + } +} + +template < + class _IterOps, + class _Pred, + class _Iter1, + class _Sent1, + class _Iter2, + class _Sent2, + class _Proj1, + class _Proj2> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter1 __find_end( + _Iter1 __first1, + _Sent1 __sent1, + _Iter2 __first2, + _Sent2 __sent2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2, + bidirectional_iterator_tag, + bidirectional_iterator_tag) { + auto __last1 = _IterOps::next(__first1, __sent1); + auto __last2 = _IterOps::next(__first2, __sent2); + // modeled after search algorithm (in reverse) + if (__first2 == __last2) + return __last1; // Everything matches an empty sequence + _Iter1 __l1 = __last1; + _Iter2 __l2 = __last2; + --__l2; + while (true) { + // Find last element in sequence 1 that matchs *(__last2-1), with a mininum of loop checks + while (true) { + if (__first1 == __l1) // return __last1 if no element matches *__first2 + return __last1; + if (std::__invoke(__pred, std::__invoke(__proj1, *--__l1), std::__invoke(__proj2, *__l2))) + break; + } + // *__l1 matches *__l2, now match elements before here + _Iter1 __m1 = __l1; + _Iter2 __m2 = __l2; + while (true) { + if (__m2 == __first2) // If pattern exhausted, __m1 is the answer (works for 1 element pattern) + return __m1; + if (__m1 == __first1) // Otherwise if source exhaused, pattern not found + return __last1; + + // if there is a mismatch, restart with a new __l1 + if (!std::__invoke(__pred, std::__invoke(__proj1, *--__m1), std::__invoke(__proj2, *--__m2))) + { + break; + } // else there is a match, check next elements + } + } +} + +template < + class _AlgPolicy, + class _Pred, + class _Iter1, + class _Sent1, + class _Iter2, + class _Sent2, + class _Proj1, + class _Proj2> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter1 __find_end( + _Iter1 __first1, + _Sent1 __sent1, + _Iter2 __first2, + _Sent2 __sent2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2, + random_access_iterator_tag, + random_access_iterator_tag) { + typedef typename iterator_traits<_Iter1>::difference_type _D1; + auto __last1 = _IterOps<_AlgPolicy>::next(__first1, __sent1); + auto __last2 = _IterOps<_AlgPolicy>::next(__first2, __sent2); + // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern + auto __len2 = __last2 - __first2; + if (__len2 == 0) + return __last1; + auto __len1 = __last1 - __first1; + if (__len1 < __len2) + return __last1; + const _Iter1 __s = __first1 + _D1(__len2 - 1); // End of pattern match can't go before here + _Iter1 __l1 = __last1; + _Iter2 __l2 = __last2; + --__l2; + while (true) { + while (true) { + if (__s == __l1) + return __last1; + if (std::__invoke(__pred, std::__invoke(__proj1, *--__l1), std::__invoke(__proj2, *__l2))) + break; + } + _Iter1 __m1 = __l1; + _Iter2 __m2 = __l2; + while (true) { + if (__m2 == __first2) + return __m1; + // no need to check range on __m1 because __s guarantees we have enough source + if (!std::__invoke(__pred, std::__invoke(__proj1, *--__m1), std::__invoke(*--__m2))) { + break; + } + } + } +} + +template +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +_ForwardIterator1 __find_end_classic(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate& __pred) { + auto __proj = __identity(); + return std::__find_end_impl<_ClassicAlgPolicy>( + __first1, + __last1, + __first2, + __last2, + __pred, + __proj, + __proj, + typename iterator_traits<_ForwardIterator1>::iterator_category(), + typename iterator_traits<_ForwardIterator2>::iterator_category()) + .first; +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +_ForwardIterator1 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __pred) { + return std::__find_end_classic(__first1, __last1, __first2, __last2, __pred); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +_ForwardIterator1 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2) { + return std::find_end(__first1, __last1, __first2, __last2, __equal_to()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_FIND_END_OF_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/find_first_of.h b/app/src/main/cpp/libcxx/include/__algorithm/find_first_of.h new file mode 100644 index 0000000..12f0109 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/find_first_of.h @@ -0,0 +1,52 @@ +// -*- 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 _LIBCPP___ALGORITHM_FIND_FIRST_OF_H +#define _LIBCPP___ALGORITHM_FIND_FIRST_OF_H + +#include <__algorithm/comp.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 __find_first_of_ce(_ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _BinaryPredicate&& __pred) { + for (; __first1 != __last1; ++__first1) + for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j) + if (__pred(*__first1, *__j)) + return __first1; + return __last1; +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 +find_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, + _ForwardIterator2 __last2, _BinaryPredicate __pred) { + return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __pred); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_first_of( + _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { + return std::__find_first_of_ce(__first1, __last1, __first2, __last2, __equal_to()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_FIND_FIRST_OF_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/find_if.h b/app/src/main/cpp/libcxx/include/__algorithm/find_if.h new file mode 100644 index 0000000..f4ef3ac --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/find_if.h @@ -0,0 +1,32 @@ +// -*- 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 _LIBCPP___ALGORITHM_FIND_IF_H +#define _LIBCPP___ALGORITHM_FIND_IF_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator +find_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { + for (; __first != __last; ++__first) + if (__pred(*__first)) + break; + return __first; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_FIND_IF_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/find_if_not.h b/app/src/main/cpp/libcxx/include/__algorithm/find_if_not.h new file mode 100644 index 0000000..96c159c --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/find_if_not.h @@ -0,0 +1,32 @@ +// -*- 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 _LIBCPP___ALGORITHM_FIND_IF_NOT_H +#define _LIBCPP___ALGORITHM_FIND_IF_NOT_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator +find_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred) { + for (; __first != __last; ++__first) + if (!__pred(*__first)) + break; + return __first; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_FIND_IF_NOT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/for_each.h b/app/src/main/cpp/libcxx/include/__algorithm/for_each.h new file mode 100644 index 0000000..6564f31 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/for_each.h @@ -0,0 +1,32 @@ +// -*- 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 _LIBCPP___ALGORITHM_FOR_EACH_H +#define _LIBCPP___ALGORITHM_FOR_EACH_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _Function for_each(_InputIterator __first, + _InputIterator __last, + _Function __f) { + for (; __first != __last; ++__first) + __f(*__first); + return __f; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_FOR_EACH_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/for_each_n.h b/app/src/main/cpp/libcxx/include/__algorithm/for_each_n.h new file mode 100644 index 0000000..38d204a --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/for_each_n.h @@ -0,0 +1,43 @@ +// -*- 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 _LIBCPP___ALGORITHM_FOR_EACH_N_H +#define _LIBCPP___ALGORITHM_FOR_EACH_N_H + +#include <__config> +#include <__utility/convert_to_integral.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator for_each_n(_InputIterator __first, + _Size __orig_n, + _Function __f) { + typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; + _IntegralSize __n = __orig_n; + while (__n > 0) { + __f(*__first); + ++__first; + --__n; + } + return __first; +} + +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_FOR_EACH_N_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/generate.h b/app/src/main/cpp/libcxx/include/__algorithm/generate.h new file mode 100644 index 0000000..48e21b5 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/generate.h @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_GENERATE_H +#define _LIBCPP___ALGORITHM_GENERATE_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +void +generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) +{ + for (; __first != __last; ++__first) + *__first = __gen(); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_GENERATE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/generate_n.h b/app/src/main/cpp/libcxx/include/__algorithm/generate_n.h new file mode 100644 index 0000000..4525998 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/generate_n.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_GENERATE_N_H +#define _LIBCPP___ALGORITHM_GENERATE_N_H + +#include <__config> +#include <__utility/convert_to_integral.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +_OutputIterator +generate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen) +{ + typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; + _IntegralSize __n = __orig_n; + for (; __n > 0; ++__first, (void) --__n) + *__first = __gen(); + return __first; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_GENERATE_N_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/half_positive.h b/app/src/main/cpp/libcxx/include/__algorithm/half_positive.h new file mode 100644 index 0000000..74aede2 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/half_positive.h @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_HALF_POSITIVE_H +#define _LIBCPP___ALGORITHM_HALF_POSITIVE_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Perform division by two quickly for positive integers (llvm.org/PR39129) + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + is_integral<_Integral>::value, + _Integral +>::type +__half_positive(_Integral __value) +{ + return static_cast<_Integral>(static_cast<__make_unsigned_t<_Integral> >(__value) / 2); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + !is_integral<_Tp>::value, + _Tp +>::type +__half_positive(_Tp __value) +{ + return __value / 2; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_HALF_POSITIVE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/in_found_result.h b/app/src/main/cpp/libcxx/include/__algorithm/in_found_result.h new file mode 100644 index 0000000..3134d6e --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/in_found_result.h @@ -0,0 +1,49 @@ +// -*- 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 _LIBCPP___ALGORITHM_IN_FOUND_RESULT_H +#define _LIBCPP___ALGORITHM_IN_FOUND_RESULT_H + +#include <__concepts/convertible_to.h> +#include <__config> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +template +struct in_found_result { + _LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in; + bool found; + + template + requires convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr operator in_found_result<_InIter2>() const & { + return {in, found}; + } + + template + requires convertible_to<_InIter1, _InIter2> + _LIBCPP_HIDE_FROM_ABI constexpr operator in_found_result<_InIter2>() && { + return {std::move(in), found}; + } +}; +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_IN_FOUND_RESULT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/in_fun_result.h b/app/src/main/cpp/libcxx/include/__algorithm/in_fun_result.h new file mode 100644 index 0000000..3cbb9e1 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/in_fun_result.h @@ -0,0 +1,49 @@ +// -*- 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 _LIBCPP___ALGORITHM_IN_FUN_RESULT_H +#define _LIBCPP___ALGORITHM_IN_FUN_RESULT_H + +#include <__concepts/convertible_to.h> +#include <__config> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace ranges { +template +struct in_fun_result { + _LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in; + _LIBCPP_NO_UNIQUE_ADDRESS _Func1 fun; + + template + requires convertible_to && convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr operator in_fun_result<_InIter2, _Func2>() const & { + return {in, fun}; + } + + template + requires convertible_to<_InIter1, _InIter2> && convertible_to<_Func1, _Func2> + _LIBCPP_HIDE_FROM_ABI constexpr operator in_fun_result<_InIter2, _Func2>() && { + return {std::move(in), std::move(fun)}; + } +}; +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IN_FUN_RESULT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/in_in_out_result.h b/app/src/main/cpp/libcxx/include/__algorithm/in_in_out_result.h new file mode 100644 index 0000000..3e747be --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/in_in_out_result.h @@ -0,0 +1,56 @@ +// -*- 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 _LIBCPP___ALGORITHM_IN_IN_OUT_RESULT_H +#define _LIBCPP___ALGORITHM_IN_IN_OUT_RESULT_H + +#include <__concepts/convertible_to.h> +#include <__config> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace ranges { + +template +struct in_in_out_result { + _LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in1; + _LIBCPP_NO_UNIQUE_ADDRESS _InIter2 in2; + _LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out; + + template + requires convertible_to + && convertible_to && convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr + operator in_in_out_result<_InIter3, _InIter4, _OutIter2>() const& { + return {in1, in2, out}; + } + + template + requires convertible_to<_InIter1, _InIter3> + && convertible_to<_InIter2, _InIter4> && convertible_to<_OutIter1, _OutIter2> + _LIBCPP_HIDE_FROM_ABI constexpr + operator in_in_out_result<_InIter3, _InIter4, _OutIter2>() && { + return {std::move(in1), std::move(in2), std::move(out)}; + } +}; + +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IN_IN_OUT_RESULT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/in_in_result.h b/app/src/main/cpp/libcxx/include/__algorithm/in_in_result.h new file mode 100644 index 0000000..2098c18 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/in_in_result.h @@ -0,0 +1,53 @@ +// -*- 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 _LIBCPP___ALGORITHM_IN_IN_RESULT_H +#define _LIBCPP___ALGORITHM_IN_IN_RESULT_H + +#include <__concepts/convertible_to.h> +#include <__config> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace ranges { + +template +struct in_in_result { + _LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in1; + _LIBCPP_NO_UNIQUE_ADDRESS _InIter2 in2; + + template + requires convertible_to && convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr + operator in_in_result<_InIter3, _InIter4>() const & { + return {in1, in2}; + } + + template + requires convertible_to<_InIter1, _InIter3> && convertible_to<_InIter2, _InIter4> + _LIBCPP_HIDE_FROM_ABI constexpr + operator in_in_result<_InIter3, _InIter4>() && { + return {std::move(in1), std::move(in2)}; + } +}; + +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IN_IN_RESULT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/in_out_out_result.h b/app/src/main/cpp/libcxx/include/__algorithm/in_out_out_result.h new file mode 100644 index 0000000..4046eee --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/in_out_out_result.h @@ -0,0 +1,54 @@ +// -*- 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 _LIBCPP___ALGORITHM_IN_OUT_OUT_RESULT_H +#define _LIBCPP___ALGORITHM_IN_OUT_OUT_RESULT_H + +#include <__concepts/convertible_to.h> +#include <__config> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace ranges { +template +struct in_out_out_result { + _LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in; + _LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out1; + _LIBCPP_NO_UNIQUE_ADDRESS _OutIter2 out2; + + template + requires convertible_to + && convertible_to && convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr + operator in_out_out_result<_InIter2, _OutIter3, _OutIter4>() const& { + return {in, out1, out2}; + } + + template + requires convertible_to<_InIter1, _InIter2> + && convertible_to<_OutIter1, _OutIter3> && convertible_to<_OutIter2, _OutIter4> + _LIBCPP_HIDE_FROM_ABI constexpr + operator in_out_out_result<_InIter2, _OutIter3, _OutIter4>() && { + return {std::move(in), std::move(out1), std::move(out2)}; + } +}; +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IN_OUT_OUT_RESULT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/in_out_result.h b/app/src/main/cpp/libcxx/include/__algorithm/in_out_result.h new file mode 100644 index 0000000..7f5a027 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/in_out_result.h @@ -0,0 +1,53 @@ +// -*- 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 _LIBCPP___ALGORITHM_IN_OUT_RESULT_H +#define _LIBCPP___ALGORITHM_IN_OUT_RESULT_H + +#include <__concepts/convertible_to.h> +#include <__config> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace ranges { + +template +struct in_out_result { + _LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in; + _LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out; + + template + requires convertible_to && convertible_to + _LIBCPP_HIDE_FROM_ABI + constexpr operator in_out_result<_InIter2, _OutIter2>() const & { + return {in, out}; + } + + template + requires convertible_to<_InIter1, _InIter2> && convertible_to<_OutIter1, _OutIter2> + _LIBCPP_HIDE_FROM_ABI + constexpr operator in_out_result<_InIter2, _OutIter2>() && { + return {std::move(in), std::move(out)}; + } +}; + +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IN_OUT_RESULT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/includes.h b/app/src/main/cpp/libcxx/include/__algorithm/includes.h new file mode 100644 index 0000000..cc39f27 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/includes.h @@ -0,0 +1,75 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_INCLUDES_H +#define _LIBCPP___ALGORITHM_INCLUDES_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/iterator_traits.h> +#include <__type_traits/is_callable.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +__includes(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, + _Comp&& __comp, _Proj1&& __proj1, _Proj2&& __proj2) { + for (; __first2 != __last2; ++__first1) { + if (__first1 == __last1 || std::__invoke( + __comp, std::__invoke(__proj2, *__first2), std::__invoke(__proj1, *__first1))) + return false; + if (!std::__invoke(__comp, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2))) + ++__first2; + } + return true; +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool includes( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _Compare __comp) { + static_assert(__is_callable<_Compare, decltype(*__first1), decltype(*__first2)>::value, + "Comparator has to be callable"); + + return std::__includes( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + static_cast<__comp_ref_type<_Compare> >(__comp), + __identity(), + __identity()); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { + return std::includes( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + __less::value_type, + typename iterator_traits<_InputIterator2>::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_INCLUDES_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/inplace_merge.h b/app/src/main/cpp/libcxx/include/__algorithm/inplace_merge.h new file mode 100644 index 0000000..5bbefc9 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/inplace_merge.h @@ -0,0 +1,257 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_INPLACE_MERGE_H +#define _LIBCPP___ALGORITHM_INPLACE_MERGE_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/lower_bound.h> +#include <__algorithm/min.h> +#include <__algorithm/move.h> +#include <__algorithm/rotate.h> +#include <__algorithm/upper_bound.h> +#include <__config> +#include <__functional/identity.h> +#include <__iterator/advance.h> +#include <__iterator/distance.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/reverse_iterator.h> +#include <__memory/destruct_n.h> +#include <__memory/temporary_buffer.h> +#include <__memory/unique_ptr.h> +#include <__utility/pair.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class __invert // invert the sense of a comparison +{ +private: + _Predicate __p_; +public: + _LIBCPP_INLINE_VISIBILITY __invert() {} + + _LIBCPP_INLINE_VISIBILITY + explicit __invert(_Predicate __p) : __p_(__p) {} + + template + _LIBCPP_INLINE_VISIBILITY + bool operator()(const _T1& __x) {return !__p_(__x);} + + template + _LIBCPP_INLINE_VISIBILITY + bool operator()(const _T1& __x, const _T2& __y) {return __p_(__y, __x);} +}; + +template +_LIBCPP_HIDE_FROM_ABI +void __half_inplace_merge(_InputIterator1 __first1, _Sent1 __last1, + _InputIterator2 __first2, _Sent2 __last2, + _OutputIterator __result, _Compare&& __comp) +{ + for (; __first1 != __last1; ++__result) + { + if (__first2 == __last2) + { + std::__move<_AlgPolicy>(__first1, __last1, __result); + return; + } + + if (__comp(*__first2, *__first1)) + { + *__result = _IterOps<_AlgPolicy>::__iter_move(__first2); + ++__first2; + } + else + { + *__result = _IterOps<_AlgPolicy>::__iter_move(__first1); + ++__first1; + } + } + // __first2 through __last2 are already in the right spot. +} + +template +_LIBCPP_HIDE_FROM_ABI +void __buffered_inplace_merge( + _BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Compare&& __comp, + typename iterator_traits<_BidirectionalIterator>::difference_type __len1, + typename iterator_traits<_BidirectionalIterator>::difference_type __len2, + typename iterator_traits<_BidirectionalIterator>::value_type* __buff) { + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + __destruct_n __d(0); + unique_ptr __h2(__buff, __d); + if (__len1 <= __len2) + { + value_type* __p = __buff; + for (_BidirectionalIterator __i = __first; __i != __middle; __d.template __incr(), (void) ++__i, (void) ++__p) + ::new ((void*)__p) value_type(_IterOps<_AlgPolicy>::__iter_move(__i)); + std::__half_inplace_merge<_AlgPolicy>(__buff, __p, __middle, __last, __first, __comp); + } + else + { + value_type* __p = __buff; + for (_BidirectionalIterator __i = __middle; __i != __last; __d.template __incr(), (void) ++__i, (void) ++__p) + ::new ((void*)__p) value_type(_IterOps<_AlgPolicy>::__iter_move(__i)); + typedef __unconstrained_reverse_iterator<_BidirectionalIterator> _RBi; + typedef __unconstrained_reverse_iterator _Rv; + typedef __invert<_Compare> _Inverted; + std::__half_inplace_merge<_AlgPolicy>(_Rv(__p), _Rv(__buff), + _RBi(__middle), _RBi(__first), + _RBi(__last), _Inverted(__comp)); + } +} + +template +void __inplace_merge( + _BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Compare&& __comp, + typename iterator_traits<_BidirectionalIterator>::difference_type __len1, + typename iterator_traits<_BidirectionalIterator>::difference_type __len2, + typename iterator_traits<_BidirectionalIterator>::value_type* __buff, + ptrdiff_t __buff_size) { + using _Ops = _IterOps<_AlgPolicy>; + + typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; + while (true) + { + // if __middle == __last, we're done + if (__len2 == 0) + return; + if (__len1 <= __buff_size || __len2 <= __buff_size) + return std::__buffered_inplace_merge<_AlgPolicy> + (__first, __middle, __last, __comp, __len1, __len2, __buff); + // shrink [__first, __middle) as much as possible (with no moves), returning if it shrinks to 0 + for (; true; ++__first, (void) --__len1) + { + if (__len1 == 0) + return; + if (__comp(*__middle, *__first)) + break; + } + // __first < __middle < __last + // *__first > *__middle + // partition [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) such that + // all elements in: + // [__first, __m1) <= [__middle, __m2) + // [__middle, __m2) < [__m1, __middle) + // [__m1, __middle) <= [__m2, __last) + // and __m1 or __m2 is in the middle of its range + _BidirectionalIterator __m1; // "median" of [__first, __middle) + _BidirectionalIterator __m2; // "median" of [__middle, __last) + difference_type __len11; // distance(__first, __m1) + difference_type __len21; // distance(__middle, __m2) + // binary search smaller range + if (__len1 < __len2) + { // __len >= 1, __len2 >= 2 + __len21 = __len2 / 2; + __m2 = __middle; + _Ops::advance(__m2, __len21); + __m1 = std::__upper_bound<_AlgPolicy>(__first, __middle, *__m2, __comp, std::__identity()); + __len11 = _Ops::distance(__first, __m1); + } + else + { + if (__len1 == 1) + { // __len1 >= __len2 && __len2 > 0, therefore __len2 == 1 + // It is known *__first > *__middle + _Ops::iter_swap(__first, __middle); + return; + } + // __len1 >= 2, __len2 >= 1 + __len11 = __len1 / 2; + __m1 = __first; + _Ops::advance(__m1, __len11); + __m2 = std::lower_bound(__middle, __last, *__m1, __comp); + __len21 = _Ops::distance(__middle, __m2); + } + difference_type __len12 = __len1 - __len11; // distance(__m1, __middle) + difference_type __len22 = __len2 - __len21; // distance(__m2, __last) + // [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) + // swap middle two partitions + __middle = std::__rotate<_AlgPolicy>(__m1, __middle, __m2).first; + // __len12 and __len21 now have swapped meanings + // merge smaller range with recursive call and larger with tail recursion elimination + if (__len11 + __len21 < __len12 + __len22) + { + std::__inplace_merge<_AlgPolicy>( + __first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size); + __first = __middle; + __middle = __m2; + __len1 = __len12; + __len2 = __len22; + } + else + { + std::__inplace_merge<_AlgPolicy>( + __middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size); + __last = __middle; + __middle = __m1; + __len1 = __len11; + __len2 = __len21; + } + } +} + +template +_LIBCPP_HIDE_FROM_ABI +void +__inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, + _Compare&& __comp) +{ + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; + difference_type __len1 = _IterOps<_AlgPolicy>::distance(__first, __middle); + difference_type __len2 = _IterOps<_AlgPolicy>::distance(__middle, __last); + difference_type __buf_size = _VSTD::min(__len1, __len2); +// TODO: Remove the use of std::get_temporary_buffer +_LIBCPP_SUPPRESS_DEPRECATED_PUSH + pair __buf = _VSTD::get_temporary_buffer(__buf_size); +_LIBCPP_SUPPRESS_DEPRECATED_POP + unique_ptr __h(__buf.first); + return std::__inplace_merge<_AlgPolicy>( + std::move(__first), std::move(__middle), std::move(__last), __comp, __len1, __len2, __buf.first, __buf.second); +} + +template +inline _LIBCPP_HIDE_FROM_ABI void inplace_merge( + _BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, _Compare __comp) { + std::__inplace_merge<_ClassicAlgPolicy>( + std::move(__first), std::move(__middle), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp)); +} + +template +inline _LIBCPP_HIDE_FROM_ABI +void +inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last) +{ + std::inplace_merge(std::move(__first), std::move(__middle), std::move(__last), + __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_INPLACE_MERGE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/is_heap.h b/app/src/main/cpp/libcxx/include/__algorithm/is_heap.h new file mode 100644 index 0000000..2dcb4a2 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/is_heap.h @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_IS_HEAP_H +#define _LIBCPP___ALGORITHM_IS_HEAP_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/is_heap_until.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +bool +is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ + return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp)) == __last; +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +bool +is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + return _VSTD::is_heap(__first, __last, __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IS_HEAP_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/is_heap_until.h b/app/src/main/cpp/libcxx/include/__algorithm/is_heap_until.h new file mode 100644 index 0000000..6ed4cb2 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/is_heap_until.h @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H +#define _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator +__is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) +{ + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + difference_type __len = __last - __first; + difference_type __p = 0; + difference_type __c = 1; + _RandomAccessIterator __pp = __first; + while (__c < __len) + { + _RandomAccessIterator __cp = __first + __c; + if (__comp(*__pp, *__cp)) + return __cp; + ++__c; + ++__cp; + if (__c == __len) + return __last; + if (__comp(*__pp, *__cp)) + return __cp; + ++__p; + ++__pp; + __c = 2 * __p + 1; + } + return __last; +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator +is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ + return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp)); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator +is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + return _VSTD::__is_heap_until(__first, __last, __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/is_partitioned.h b/app/src/main/cpp/libcxx/include/__algorithm/is_partitioned.h new file mode 100644 index 0000000..ab59d3c --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/is_partitioned.h @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_IS_PARTITIONED_H +#define _LIBCPP___ALGORITHM_IS_PARTITIONED_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred) +{ + for (; __first != __last; ++__first) + if (!__pred(*__first)) + break; + if ( __first == __last ) + return true; + ++__first; + for (; __first != __last; ++__first) + if (__pred(*__first)) + return false; + return true; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IS_PARTITIONED_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/is_permutation.h b/app/src/main/cpp/libcxx/include/__algorithm/is_permutation.h new file mode 100644 index 0000000..0054456 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/is_permutation.h @@ -0,0 +1,238 @@ +// -*- 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 _LIBCPP___ALGORITHM_IS_PERMUTATION_H +#define _LIBCPP___ALGORITHM_IS_PERMUTATION_H + +#include <__algorithm/comp.h> +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/distance.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _ConstTimeDistance : false_type {}; + +#if _LIBCPP_STD_VER > 17 + +template +struct _ConstTimeDistance<_Iter1, _Sent1, _Iter2, _Sent2, __enable_if_t< + sized_sentinel_for<_Sent1, _Iter1> && + sized_sentinel_for<_Sent2, _Iter2> +>> : true_type {}; + +#else + +template +struct _ConstTimeDistance<_Iter1, _Iter1, _Iter2, _Iter2, __enable_if_t< + is_same::iterator_category, random_access_iterator_tag>::value && + is_same::iterator_category, random_access_iterator_tag>::value +> > : true_type {}; + +#endif // _LIBCPP_STD_VER > 17 + +// Internal functions + +// For each element in [f1, l1) see if there are the same number of equal elements in [f2, l2) +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +__is_permutation_impl(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, + _Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2) { + using _D1 = __iter_diff_t<_Iter1>; + + for (auto __i = __first1; __i != __last1; ++__i) { + // Have we already counted the number of *__i in [f1, l1)? + auto __match = __first1; + for (; __match != __i; ++__match) { + if (std::__invoke(__pred, std::__invoke(__proj1, *__match), std::__invoke(__proj1, *__i))) + break; + } + + if (__match == __i) { + // Count number of *__i in [f2, l2) + _D1 __c2 = 0; + for (auto __j = __first2; __j != __last2; ++__j) { + if (std::__invoke(__pred, std::__invoke(__proj1, *__i), std::__invoke(__proj2, *__j))) + ++__c2; + } + if (__c2 == 0) + return false; + + // Count number of *__i in [__i, l1) (we can start with 1) + _D1 __c1 = 1; + for (auto __j = _IterOps<_AlgPolicy>::next(__i); __j != __last1; ++__j) { + if (std::__invoke(__pred, std::__invoke(__proj1, *__i), std::__invoke(__proj1, *__j))) + ++__c1; + } + if (__c1 != __c2) + return false; + } + } + + return true; +} + +// 2+1 iterators, predicate. Not used by range algorithms. +template +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +__is_permutation(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2, + _BinaryPredicate&& __pred) { + // Shorten sequences as much as possible by lopping of any equal prefix. + for (; __first1 != __last1; ++__first1, (void)++__first2) { + if (!__pred(*__first1, *__first2)) + break; + } + + if (__first1 == __last1) + return true; + + // __first1 != __last1 && *__first1 != *__first2 + using _D1 = __iter_diff_t<_ForwardIterator1>; + _D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1); + if (__l1 == _D1(1)) + return false; + auto __last2 = _IterOps<_AlgPolicy>::next(__first2, __l1); + + return std::__is_permutation_impl<_AlgPolicy>( + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), + __pred, __identity(), __identity()); +} + +// 2+2 iterators, predicate, non-constant time `distance`. +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +__is_permutation(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, + _Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2, + /*_ConstTimeDistance=*/false_type) { + // Shorten sequences as much as possible by lopping of any equal prefix. + while (__first1 != __last1 && __first2 != __last2) { + if (!std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2))) + break; + ++__first1; + ++__first2; + } + + if (__first1 == __last1) + return __first2 == __last2; + if (__first2 == __last2) // Second range is shorter + return false; + + using _D1 = __iter_diff_t<_Iter1>; + _D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1); + + using _D2 = __iter_diff_t<_Iter2>; + _D2 __l2 = _IterOps<_AlgPolicy>::distance(__first2, __last2); + if (__l1 != __l2) + return false; + + return std::__is_permutation_impl<_AlgPolicy>( + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), + __pred, __proj1, __proj2); +} + +// 2+2 iterators, predicate, specialization for constant-time `distance` call. +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +__is_permutation(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, + _Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2, + /*_ConstTimeDistance=*/true_type) { + if (std::distance(__first1, __last1) != std::distance(__first2, __last2)) + return false; + return std::__is_permutation<_AlgPolicy>( + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), + __pred, __proj1, __proj2, + /*_ConstTimeDistance=*/false_type()); +} + +// 2+2 iterators, predicate +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +__is_permutation(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, + _Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2) { + return std::__is_permutation<_AlgPolicy>( + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), + __pred, __proj1, __proj2, + _ConstTimeDistance<_Iter1, _Sent1, _Iter2, _Sent2>()); +} + +// Public interface + +// 2+1 iterators, predicate +template +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, + _BinaryPredicate __pred) { + static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value, + "The predicate has to be callable"); + + return std::__is_permutation<_ClassicAlgPolicy>( + std::move(__first1), std::move(__last1), std::move(__first2), __pred); +} + +// 2+1 iterators +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { + return std::is_permutation(__first1, __last1, __first2, __equal_to()); +} + +#if _LIBCPP_STD_VER > 11 + +// 2+2 iterators +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation( + _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { + return std::__is_permutation<_ClassicAlgPolicy>( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + __equal_to(), + __identity(), + __identity()); +} + +// 2+2 iterators, predicate +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, + _ForwardIterator2 __last2, _BinaryPredicate __pred) { + static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value, + "The predicate has to be callable"); + + return std::__is_permutation<_ClassicAlgPolicy>( + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), + __pred, __identity(), __identity()); +} + +#endif // _LIBCPP_STD_VER > 11 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IS_PERMUTATION_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/is_sorted.h b/app/src/main/cpp/libcxx/include/__algorithm/is_sorted.h new file mode 100644 index 0000000..bf44f45 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/is_sorted.h @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_IS_SORTED_H +#define _LIBCPP___ALGORITHM_IS_SORTED_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/is_sorted_until.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +bool +is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) +{ + return _VSTD::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp) == __last; +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +bool +is_sorted(_ForwardIterator __first, _ForwardIterator __last) +{ + return _VSTD::is_sorted(__first, __last, __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IS_SORTED_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/is_sorted_until.h b/app/src/main/cpp/libcxx/include/__algorithm/is_sorted_until.h new file mode 100644 index 0000000..b668300 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/is_sorted_until.h @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H +#define _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +__is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) +{ + if (__first != __last) + { + _ForwardIterator __i = __first; + while (++__i != __last) + { + if (__comp(*__i, *__first)) + return __i; + __first = __i; + } + } + return __last; +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) +{ + return _VSTD::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +is_sorted_until(_ForwardIterator __first, _ForwardIterator __last) +{ + return _VSTD::is_sorted_until(__first, __last, __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/iter_swap.h b/app/src/main/cpp/libcxx/include/__algorithm/iter_swap.h new file mode 100644 index 0000000..44422b5 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/iter_swap.h @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_ITER_SWAP_H +#define _LIBCPP___ALGORITHM_ITER_SWAP_H + +#include <__config> +#include <__utility/declval.h> +#include <__utility/swap.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void iter_swap(_ForwardIterator1 __a, + _ForwardIterator2 __b) + // _NOEXCEPT_(_NOEXCEPT_(swap(*__a, *__b))) + _NOEXCEPT_(_NOEXCEPT_(swap(*std::declval<_ForwardIterator1>(), *std::declval<_ForwardIterator2>()))) { + swap(*__a, *__b); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_ITER_SWAP_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/iterator_operations.h b/app/src/main/cpp/libcxx/include/__algorithm/iterator_operations.h new file mode 100644 index 0000000..bd3e6f1 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/iterator_operations.h @@ -0,0 +1,175 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H +#define _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H + +#include <__algorithm/iter_swap.h> +#include <__algorithm/ranges_iterator_concept.h> +#include <__config> +#include <__iterator/advance.h> +#include <__iterator/distance.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iter_move.h> +#include <__iterator/iter_swap.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/prev.h> +#include <__iterator/readable_traits.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_reference.h> +#include <__type_traits/is_same.h> +#include <__type_traits/remove_cvref.h> +#include <__utility/declval.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template struct _IterOps; + +#if _LIBCPP_STD_VER > 17 +struct _RangeAlgPolicy {}; + +template <> +struct _IterOps<_RangeAlgPolicy> { + + template + using __value_type = iter_value_t<_Iter>; + + template + using __iterator_category = ranges::__iterator_concept<_Iter>; + + template + using __difference_type = iter_difference_t<_Iter>; + + static constexpr auto advance = ranges::advance; + static constexpr auto distance = ranges::distance; + static constexpr auto __iter_move = ranges::iter_move; + static constexpr auto iter_swap = ranges::iter_swap; + static constexpr auto next = ranges::next; + static constexpr auto prev = ranges::prev; + static constexpr auto __advance_to = ranges::advance; +}; + +#endif + +struct _ClassicAlgPolicy {}; + +template <> +struct _IterOps<_ClassicAlgPolicy> { + + template + using __value_type = typename iterator_traits<_Iter>::value_type; + + template + using __iterator_category = typename iterator_traits<_Iter>::iterator_category; + + template + using __difference_type = typename iterator_traits<_Iter>::difference_type; + + // advance + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 + static void advance(_Iter& __iter, _Distance __count) { + std::advance(__iter, __count); + } + + // distance + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 + static typename iterator_traits<_Iter>::difference_type distance(_Iter __first, _Iter __last) { + return std::distance(__first, __last); + } + + template + using __deref_t = decltype(*std::declval<_Iter&>()); + + template + using __move_t = decltype(std::move(*std::declval<_Iter&>())); + + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 + static void __validate_iter_reference() { + static_assert(is_same<__deref_t<_Iter>, typename iterator_traits<__remove_cvref_t<_Iter> >::reference>::value, + "It looks like your iterator's `iterator_traits::reference` does not match the return type of " + "dereferencing the iterator, i.e., calling `*it`. This is undefined behavior according to [input.iterators] " + "and can lead to dangling reference issues at runtime, so we are flagging this."); + } + + // iter_move + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static + // If the result of dereferencing `_Iter` is a reference type, deduce the result of calling `std::move` on it. Note + // that the C++03 mode doesn't support `decltype(auto)` as the return type. + __enable_if_t< + is_reference<__deref_t<_Iter> >::value, + __move_t<_Iter> > + __iter_move(_Iter&& __i) { + __validate_iter_reference<_Iter>(); + + return std::move(*std::forward<_Iter>(__i)); + } + + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static + // If the result of dereferencing `_Iter` is a value type, deduce the return value of this function to also be a + // value -- otherwise, after `operator*` returns a temporary, this function would return a dangling reference to that + // temporary. Note that the C++03 mode doesn't support `auto` as the return type. + __enable_if_t< + !is_reference<__deref_t<_Iter> >::value, + __deref_t<_Iter> > + __iter_move(_Iter&& __i) { + __validate_iter_reference<_Iter>(); + + return *std::forward<_Iter>(__i); + } + + // iter_swap + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 + static void iter_swap(_Iter1&& __a, _Iter2&& __b) { + std::iter_swap(std::forward<_Iter1>(__a), std::forward<_Iter2>(__b)); + } + + // next + template + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 + _Iterator next(_Iterator, _Iterator __last) { + return __last; + } + + template + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 + __remove_cvref_t<_Iter> next(_Iter&& __it, + typename iterator_traits<__remove_cvref_t<_Iter> >::difference_type __n = 1) { + return std::next(std::forward<_Iter>(__it), __n); + } + + // prev + template + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 + __remove_cvref_t<_Iter> prev(_Iter&& __iter, + typename iterator_traits<__remove_cvref_t<_Iter> >::difference_type __n = 1) { + return std::prev(std::forward<_Iter>(__iter), __n); + } + + template + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 + void __advance_to(_Iter& __first, _Iter __last) { + __first = __last; + } +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/lexicographical_compare.h b/app/src/main/cpp/libcxx/include/__algorithm/lexicographical_compare.h new file mode 100644 index 0000000..0a13c5d --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/lexicographical_compare.h @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H +#define _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +__lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) +{ + for (; __first2 != __last2; ++__first1, (void) ++__first2) + { + if (__first1 == __last1 || __comp(*__first1, *__first2)) + return true; + if (__comp(*__first2, *__first1)) + return false; + } + return false; +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +bool +lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) +{ + return _VSTD::__lexicographical_compare<__comp_ref_type<_Compare> >(__first1, __last1, __first2, __last2, __comp); +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +bool +lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2) +{ + return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2, + __less::value_type, + typename iterator_traits<_InputIterator2>::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/lower_bound.h b/app/src/main/cpp/libcxx/include/__algorithm/lower_bound.h new file mode 100644 index 0000000..2648982 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/lower_bound.h @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_LOWER_BOUND_H +#define _LIBCPP___ALGORITHM_LOWER_BOUND_H + +#include <__algorithm/comp.h> +#include <__algorithm/half_positive.h> +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/advance.h> +#include <__iterator/distance.h> +#include <__iterator/iterator_traits.h> +#include <__type_traits/is_callable.h> +#include <__type_traits/remove_reference.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +_Iter __lower_bound_impl(_Iter __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) { + auto __len = _IterOps<_AlgPolicy>::distance(__first, __last); + + while (__len != 0) { + auto __l2 = std::__half_positive(__len); + _Iter __m = __first; + _IterOps<_AlgPolicy>::advance(__m, __l2); + if (std::__invoke(__comp, std::__invoke(__proj, *__m), __value)) { + __first = ++__m; + __len -= __l2 + 1; + } else { + __len = __l2; + } + } + return __first; +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +_ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { + static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, + "The comparator has to be callable"); + auto __proj = std::__identity(); + return std::__lower_bound_impl<_ClassicAlgPolicy>(__first, __last, __value, __comp, __proj); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +_ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + return std::lower_bound(__first, __last, __value, + __less::value_type, _Tp>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_LOWER_BOUND_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/make_heap.h b/app/src/main/cpp/libcxx/include/__algorithm/make_heap.h new file mode 100644 index 0000000..d66cfe2 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/make_heap.h @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_MAKE_HEAP_H +#define _LIBCPP___ALGORITHM_MAKE_HEAP_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/sift_down.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +void __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) { + __comp_ref_type<_Compare> __comp_ref = __comp; + + using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; + difference_type __n = __last - __first; + if (__n > 1) { + // start from the first parent, there is no need to consider children + for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start) { + std::__sift_down<_AlgPolicy>(__first, __comp_ref, __n, __first + __start); + } + } +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + std::__make_heap<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { + std::make_heap(std::move(__first), std::move(__last), + __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_MAKE_HEAP_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/make_projected.h b/app/src/main/cpp/libcxx/include/__algorithm/make_projected.h new file mode 100644 index 0000000..87d4d59 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/make_projected.h @@ -0,0 +1,126 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_MAKE_PROJECTED_H +#define _LIBCPP___ALGORITHM_MAKE_PROJECTED_H + +#include <__concepts/same_as.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__type_traits/decay.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_member_pointer.h> +#include <__type_traits/is_same.h> +#include <__utility/declval.h> +#include <__utility/forward.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _ProjectedPred { + _Pred& __pred; // Can be a unary or a binary predicate. + _Proj& __proj; + + _LIBCPP_CONSTEXPR _ProjectedPred(_Pred& __pred_arg, _Proj& __proj_arg) : __pred(__pred_arg), __proj(__proj_arg) {} + + template + typename __invoke_of<_Pred&, + decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_Tp>())) + >::type + _LIBCPP_CONSTEXPR operator()(_Tp&& __v) const { + return std::__invoke(__pred, std::__invoke(__proj, std::forward<_Tp>(__v))); + } + + template + typename __invoke_of<_Pred&, + decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T1>())), + decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T2>())) + >::type + _LIBCPP_CONSTEXPR operator()(_T1&& __lhs, _T2&& __rhs) const { + return std::__invoke(__pred, + std::__invoke(__proj, std::forward<_T1>(__lhs)), + std::__invoke(__proj, std::forward<_T2>(__rhs))); + } + +}; + +template +struct __can_use_pristine_comp : false_type {}; + +template +struct __can_use_pristine_comp<_Pred, _Proj, __enable_if_t< + !is_member_pointer::type>::value && ( +#if _LIBCPP_STD_VER > 17 + is_same::type, identity>::value || +#endif + is_same::type, __identity>::value + ) +> > : true_type {}; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static +__enable_if_t< + !__can_use_pristine_comp<_Pred, _Proj>::value, + _ProjectedPred<_Pred, _Proj> +> +__make_projected(_Pred& __pred, _Proj& __proj) { + return _ProjectedPred<_Pred, _Proj>(__pred, __proj); +} + +// Avoid creating the functor and just use the pristine comparator -- for certain algorithms, this would enable +// optimizations that rely on the type of the comparator. Additionally, this results in less layers of indirection in +// the call stack when the comparator is invoked, even in an unoptimized build. +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static +__enable_if_t< + __can_use_pristine_comp<_Pred, _Proj>::value, + _Pred& +> +__make_projected(_Pred& __pred, _Proj&) { + return __pred; +} + +_LIBCPP_END_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +_LIBCPP_HIDE_FROM_ABI constexpr static +decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __proj2) { + if constexpr (same_as, identity> && same_as, identity> && + !is_member_pointer_v>) { + // Avoid creating the lambda and just use the pristine comparator -- for certain algorithms, this would enable + // optimizations that rely on the type of the comparator. + return __comp; + + } else { + return [&](auto&& __lhs, auto&& __rhs) { + return std::invoke(__comp, + std::invoke(__proj1, std::forward(__lhs)), + std::invoke(__proj2, std::forward(__rhs))); + }; + } +} + +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_MAKE_PROJECTED_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/max.h b/app/src/main/cpp/libcxx/include/__algorithm/max.h new file mode 100644 index 0000000..a08a3fc --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/max.h @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_MAX_H +#define _LIBCPP___ALGORITHM_MAX_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/max_element.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +const _Tp& +max(const _Tp& __a, const _Tp& __b, _Compare __comp) +{ + return __comp(__a, __b) ? __b : __a; +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +const _Tp& +max(const _Tp& __a, const _Tp& __b) +{ + return _VSTD::max(__a, __b, __less<_Tp>()); +} + +#ifndef _LIBCPP_CXX03_LANG + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +_Tp +max(initializer_list<_Tp> __t, _Compare __comp) +{ + return *_VSTD::__max_element<__comp_ref_type<_Compare> >(__t.begin(), __t.end(), __comp); +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +_Tp +max(initializer_list<_Tp> __t) +{ + return *_VSTD::max_element(__t.begin(), __t.end(), __less<_Tp>()); +} + +#endif // _LIBCPP_CXX03_LANG + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_MAX_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/max_element.h b/app/src/main/cpp/libcxx/include/__algorithm/max_element.h new file mode 100644 index 0000000..6ac3106 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/max_element.h @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_MAX_ELEMENT_H +#define _LIBCPP___ALGORITHM_MAX_ELEMENT_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator +__max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) +{ + static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, + "std::max_element requires a ForwardIterator"); + if (__first != __last) + { + _ForwardIterator __i = __first; + while (++__i != __last) + if (__comp(*__first, *__i)) + __first = __i; + } + return __first; +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator +max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) +{ + return _VSTD::__max_element<__comp_ref_type<_Compare> >(__first, __last, __comp); +} + + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator +max_element(_ForwardIterator __first, _ForwardIterator __last) +{ + return _VSTD::max_element(__first, __last, + __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_MAX_ELEMENT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/merge.h b/app/src/main/cpp/libcxx/include/__algorithm/merge.h new file mode 100644 index 0000000..e54e430 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/merge.h @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_MERGE_H +#define _LIBCPP___ALGORITHM_MERGE_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/copy.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +_OutputIterator +__merge(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) +{ + for (; __first1 != __last1; ++__result) + { + if (__first2 == __last2) + return _VSTD::copy(__first1, __last1, __result); + if (__comp(*__first2, *__first1)) + { + *__result = *__first2; + ++__first2; + } + else + { + *__result = *__first1; + ++__first1; + } + } + return _VSTD::copy(__first2, __last2, __result); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +_OutputIterator +merge(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) +{ + return _VSTD::__merge<__comp_ref_type<_Compare> >(__first1, __last1, __first2, __last2, __result, __comp); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +_OutputIterator +merge(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) +{ + typedef typename iterator_traits<_InputIterator1>::value_type __v1; + typedef typename iterator_traits<_InputIterator2>::value_type __v2; + return _VSTD::merge(__first1, __last1, __first2, __last2, __result, __less<__v1, __v2>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_MERGE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/min.h b/app/src/main/cpp/libcxx/include/__algorithm/min.h new file mode 100644 index 0000000..2882485 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/min.h @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_MIN_H +#define _LIBCPP___ALGORITHM_MIN_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/min_element.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +const _Tp& +min(const _Tp& __a, const _Tp& __b, _Compare __comp) +{ + return __comp(__b, __a) ? __b : __a; +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +const _Tp& +min(const _Tp& __a, const _Tp& __b) +{ + return _VSTD::min(__a, __b, __less<_Tp>()); +} + +#ifndef _LIBCPP_CXX03_LANG + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +_Tp +min(initializer_list<_Tp> __t, _Compare __comp) +{ + return *_VSTD::__min_element<__comp_ref_type<_Compare> >(__t.begin(), __t.end(), __comp); +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +_Tp +min(initializer_list<_Tp> __t) +{ + return *_VSTD::min_element(__t.begin(), __t.end(), __less<_Tp>()); +} + +#endif // _LIBCPP_CXX03_LANG + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_MIN_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/min_element.h b/app/src/main/cpp/libcxx/include/__algorithm/min_element.h new file mode 100644 index 0000000..c0706fe --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/min_element.h @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_MIN_ELEMENT_H +#define _LIBCPP___ALGORITHM_MIN_ELEMENT_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/iterator_traits.h> +#include <__type_traits/is_callable.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +_Iter __min_element(_Iter __first, _Sent __last, _Comp __comp, _Proj& __proj) { + if (__first == __last) + return __first; + + _Iter __i = __first; + while (++__i != __last) + if (std::__invoke(__comp, std::__invoke(__proj, *__i), std::__invoke(__proj, *__first))) + __first = __i; + + return __first; +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +_Iter __min_element(_Iter __first, _Sent __last, _Comp __comp) { + auto __proj = __identity(); + return std::__min_element<_Comp>(std::move(__first), std::move(__last), __comp, __proj); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator +min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) +{ + static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, + "std::min_element requires a ForwardIterator"); + static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value, + "The comparator has to be callable"); + + return std::__min_element<__comp_ref_type<_Compare> >(std::move(__first), std::move(__last), __comp); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator +min_element(_ForwardIterator __first, _ForwardIterator __last) +{ + return _VSTD::min_element(__first, __last, + __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_MIN_ELEMENT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/min_max_result.h b/app/src/main/cpp/libcxx/include/__algorithm/min_max_result.h new file mode 100644 index 0000000..4be3999 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/min_max_result.h @@ -0,0 +1,56 @@ +// -*- 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 _LIBCPP___ALGORITHM_MIN_MAX_RESULT_H +#define _LIBCPP___ALGORITHM_MIN_MAX_RESULT_H + +#include <__concepts/convertible_to.h> +#include <__config> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace ranges { + +template +struct min_max_result { + _LIBCPP_NO_UNIQUE_ADDRESS _T1 min; + _LIBCPP_NO_UNIQUE_ADDRESS _T1 max; + + template + requires convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr operator min_max_result<_T2>() const & { + return {min, max}; + } + + template + requires convertible_to<_T1, _T2> + _LIBCPP_HIDE_FROM_ABI constexpr operator min_max_result<_T2>() && { + return {std::move(min), std::move(max)}; + } +}; + +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_MIN_MAX_RESULT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/minmax.h b/app/src/main/cpp/libcxx/include/__algorithm/minmax.h new file mode 100644 index 0000000..6ef0a77 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/minmax.h @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_MINMAX_H +#define _LIBCPP___ALGORITHM_MINMAX_H + +#include <__algorithm/comp.h> +#include <__algorithm/minmax_element.h> +#include <__config> +#include <__functional/identity.h> +#include <__type_traits/is_callable.h> +#include <__utility/pair.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair +minmax(const _Tp& __a, const _Tp& __b, _Compare __comp) +{ + return __comp(__b, __a) ? pair(__b, __a) : + pair(__a, __b); +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair +minmax(const _Tp& __a, const _Tp& __b) +{ + return std::minmax(__a, __b, __less<_Tp>()); +} + +#ifndef _LIBCPP_CXX03_LANG + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair<_Tp, _Tp> minmax(initializer_list<_Tp> __t, _Compare __comp) { + static_assert(__is_callable<_Compare, _Tp, _Tp>::value, "The comparator has to be callable"); + __identity __proj; + auto __ret = std::__minmax_element_impl(__t.begin(), __t.end(), __comp, __proj); + return pair<_Tp, _Tp>(*__ret.first, *__ret.second); +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair<_Tp, _Tp> +minmax(initializer_list<_Tp> __t) +{ + return std::minmax(__t, __less<_Tp>()); +} + +#endif // _LIBCPP_CXX03_LANG + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_MINMAX_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/minmax_element.h b/app/src/main/cpp/libcxx/include/__algorithm/minmax_element.h new file mode 100644 index 0000000..caa963e --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/minmax_element.h @@ -0,0 +1,101 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H +#define _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H + +#include <__algorithm/comp.h> +#include <__config> +#include <__functional/identity.h> +#include <__iterator/iterator_traits.h> +#include <__utility/pair.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _MinmaxElementLessFunc { + _Comp& __comp_; + _Proj& __proj_; + +public: + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR + _MinmaxElementLessFunc(_Comp& __comp, _Proj& __proj) : __comp_(__comp), __proj_(__proj) {} + + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 + bool operator()(_Iter& __it1, _Iter& __it2) { + return std::__invoke(__comp_, std::__invoke(__proj_, *__it1), std::__invoke(__proj_, *__it2)); + } +}; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair<_Iter, _Iter> __minmax_element_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __less = _MinmaxElementLessFunc<_Comp, _Proj>(__comp, __proj); + + pair<_Iter, _Iter> __result(__first, __first); + if (__first == __last || ++__first == __last) + return __result; + + if (__less(__first, __result.first)) + __result.first = __first; + else + __result.second = __first; + + while (++__first != __last) { + _Iter __i = __first; + if (++__first == __last) { + if (__less(__i, __result.first)) + __result.first = __i; + else if (!__less(__i, __result.second)) + __result.second = __i; + return __result; + } + + if (__less(__first, __i)) { + if (__less(__first, __result.first)) + __result.first = __first; + if (!__less(__i, __result.second)) + __result.second = __i; + } else { + if (__less(__i, __result.first)) + __result.first = __i; + if (!__less(__first, __result.second)) + __result.second = __first; + } + } + + return __result; +} + +template +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair<_ForwardIterator, _ForwardIterator> +minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, + "std::minmax_element requires a ForwardIterator"); + static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value, + "The comparator has to be callable"); + auto __proj = __identity(); + return std::__minmax_element_impl(__first, __last, __comp, __proj); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair<_ForwardIterator, _ForwardIterator> minmax_element(_ForwardIterator __first, _ForwardIterator __last) { + return std::minmax_element(__first, __last, __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/mismatch.h b/app/src/main/cpp/libcxx/include/__algorithm/mismatch.h new file mode 100644 index 0000000..600e2cd --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/mismatch.h @@ -0,0 +1,63 @@ +// -*- 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 _LIBCPP___ALGORITHM_MISMATCH_H +#define _LIBCPP___ALGORITHM_MISMATCH_H + +#include <__algorithm/comp.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> + mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) { + for (; __first1 != __last1; ++__first1, (void)++__first2) + if (!__pred(*__first1, *__first2)) + break; + return pair<_InputIterator1, _InputIterator2>(__first1, __first2); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> + mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) { + return std::mismatch(__first1, __last1, __first2, __equal_to()); +} + +#if _LIBCPP_STD_VER > 11 +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> + mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, + _BinaryPredicate __pred) { + for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2) + if (!__pred(*__first1, *__first2)) + break; + return pair<_InputIterator1, _InputIterator2>(__first1, __first2); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> + mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { + return std::mismatch(__first1, __last1, __first2, __last2, __equal_to()); +} +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_MISMATCH_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/move.h b/app/src/main/cpp/libcxx/include/__algorithm/move.h new file mode 100644 index 0000000..ac95bda --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/move.h @@ -0,0 +1,130 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_MOVE_H +#define _LIBCPP___ALGORITHM_MOVE_H + +#include <__algorithm/copy_move_common.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/min.h> +#include <__config> +#include <__iterator/segmented_iterator.h> +#include <__type_traits/common_type.h> +#include <__type_traits/is_copy_constructible.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> +__move(_InIter __first, _Sent __last, _OutIter __result); + +template +struct __move_loop { + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> + operator()(_InIter __first, _Sent __last, _OutIter __result) const { + while (__first != __last) { + *__result = _IterOps<_AlgPolicy>::__iter_move(__first); + ++__first; + ++__result; + } + return std::make_pair(std::move(__first), std::move(__result)); + } + + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> + operator()(_InIter __first, _InIter __last, _OutIter __result) const { + using _Traits = __segmented_iterator_traits<_InIter>; + auto __sfirst = _Traits::__segment(__first); + auto __slast = _Traits::__segment(__last); + if (__sfirst == __slast) { + auto __iters = std::__move<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result)); + return std::make_pair(__last, std::move(__iters.second)); + } + + __result = std::__move<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__sfirst), std::move(__result)).second; + ++__sfirst; + while (__sfirst != __slast) { + __result = + std::__move<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__end(__sfirst), std::move(__result)).second; + ++__sfirst; + } + __result = + std::__move<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__local(__last), std::move(__result)).second; + return std::make_pair(__last, std::move(__result)); + } + + template ::value && + !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value, + int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> + operator()(_InIter __first, _InIter __last, _OutIter __result) { + using _Traits = __segmented_iterator_traits<_OutIter>; + using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type; + + if (__first == __last) + return std::make_pair(std::move(__first), std::move(__result)); + + auto __local_first = _Traits::__local(__result); + auto __segment_iterator = _Traits::__segment(__result); + while (true) { + auto __local_last = _Traits::__end(__segment_iterator); + auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first); + auto __iters = std::__move<_AlgPolicy>(__first, __first + __size, __local_first); + __first = std::move(__iters.first); + + if (__first == __last) + return std::make_pair(std::move(__first), _Traits::__compose(__segment_iterator, std::move(__iters.second))); + + __local_first = _Traits::__begin(++__segment_iterator); + } + } +}; + +struct __move_trivial { + // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer. + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> + operator()(_In* __first, _In* __last, _Out* __result) const { + return std::__copy_trivial_impl(__first, __last, __result); + } +}; + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> +__move(_InIter __first, _Sent __last, _OutIter __result) { + return std::__dispatch_copy_or_move<_AlgPolicy, __move_loop<_AlgPolicy>, __move_trivial>( + std::move(__first), std::move(__last), std::move(__result)); +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +move(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { + static_assert(is_copy_constructible<_InputIterator>::value, "Iterators has to be copy constructible."); + static_assert(is_copy_constructible<_OutputIterator>::value, "The output iterator has to be copy constructible."); + + return std::__move<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)).second; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_MOVE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/move_backward.h b/app/src/main/cpp/libcxx/include/__algorithm/move_backward.h new file mode 100644 index 0000000..d4f013b --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/move_backward.h @@ -0,0 +1,139 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_MOVE_BACKWARD_H +#define _LIBCPP___ALGORITHM_MOVE_BACKWARD_H + +#include <__algorithm/copy_move_common.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/min.h> +#include <__config> +#include <__iterator/segmented_iterator.h> +#include <__type_traits/common_type.h> +#include <__type_traits/is_copy_constructible.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator1, _BidirectionalIterator2> +__move_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result); + +template +struct __move_backward_loop { + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> + operator()(_InIter __first, _Sent __last, _OutIter __result) const { + auto __last_iter = _IterOps<_AlgPolicy>::next(__first, __last); + auto __original_last_iter = __last_iter; + + while (__first != __last_iter) { + *--__result = _IterOps<_AlgPolicy>::__iter_move(--__last_iter); + } + + return std::make_pair(std::move(__original_last_iter), std::move(__result)); + } + + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> + operator()(_InIter __first, _InIter __last, _OutIter __result) const { + using _Traits = __segmented_iterator_traits<_InIter>; + auto __sfirst = _Traits::__segment(__first); + auto __slast = _Traits::__segment(__last); + if (__sfirst == __slast) { + auto __iters = + std::__move_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result)); + return std::make_pair(__last, __iters.second); + } + + __result = + std::__move_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__local(__last), std::move(__result)) + .second; + --__slast; + while (__sfirst != __slast) { + __result = + std::__move_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__end(__slast), std::move(__result)) + .second; + --__slast; + } + __result = std::__move_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__slast), std::move(__result)) + .second; + return std::make_pair(__last, std::move(__result)); + } + + template ::value && + !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value, + int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> + operator()(_InIter __first, _InIter __last, _OutIter __result) { + using _Traits = __segmented_iterator_traits<_OutIter>; + using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type; + + // When the range contains no elements, __result might not be a valid iterator + if (__first == __last) + return std::make_pair(__first, __result); + + auto __orig_last = __last; + + auto __local_last = _Traits::__local(__result); + auto __segment_iterator = _Traits::__segment(__result); + while (true) { + auto __local_first = _Traits::__begin(__segment_iterator); + auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first); + auto __iter = std::__move_backward<_AlgPolicy>(__last - __size, __last, __local_last).second; + __last -= __size; + + if (__first == __last) + return std::make_pair(std::move(__orig_last), _Traits::__compose(__segment_iterator, std::move(__iter))); + + __local_last = _Traits::__end(--__segment_iterator); + } + } +}; + +struct __move_backward_trivial { + // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer. + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> + operator()(_In* __first, _In* __last, _Out* __result) const { + return std::__copy_backward_trivial_impl(__first, __last, __result); + } +}; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator1, _BidirectionalIterator2> +__move_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result) { + static_assert(std::is_copy_constructible<_BidirectionalIterator1>::value && + std::is_copy_constructible<_BidirectionalIterator1>::value, "Iterators must be copy constructible."); + + return std::__dispatch_copy_or_move<_AlgPolicy, __move_backward_loop<_AlgPolicy>, __move_backward_trivial>( + std::move(__first), std::move(__last), std::move(__result)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _BidirectionalIterator2 +move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, _BidirectionalIterator2 __result) { + return std::__move_backward<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)).second; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_MOVE_BACKWARD_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/next_permutation.h b/app/src/main/cpp/libcxx/include/__algorithm/next_permutation.h new file mode 100644 index 0000000..73e8b99 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/next_permutation.h @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H +#define _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/reverse.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, bool> +__next_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp) +{ + using _Result = pair<_BidirectionalIterator, bool>; + + _BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last); + _BidirectionalIterator __i = __last_iter; + if (__first == __last || __first == --__i) + return _Result(std::move(__last_iter), false); + + while (true) + { + _BidirectionalIterator __ip1 = __i; + if (__comp(*--__i, *__ip1)) + { + _BidirectionalIterator __j = __last_iter; + while (!__comp(*__i, *--__j)) + ; + _IterOps<_AlgPolicy>::iter_swap(__i, __j); + std::__reverse<_AlgPolicy>(__ip1, __last_iter); + return _Result(std::move(__last_iter), true); + } + if (__i == __first) + { + std::__reverse<_AlgPolicy>(__first, __last_iter); + return _Result(std::move(__last_iter), false); + } + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +bool +next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) +{ + return std::__next_permutation<_ClassicAlgPolicy>( + std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp)).second; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +bool +next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) +{ + return _VSTD::next_permutation(__first, __last, + __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/none_of.h b/app/src/main/cpp/libcxx/include/__algorithm/none_of.h new file mode 100644 index 0000000..19357eb --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/none_of.h @@ -0,0 +1,32 @@ +// -*- 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 _LIBCPP___ALGORITHM_NONE_OF_H +#define _LIBCPP___ALGORITHM_NONE_OF_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { + for (; __first != __last; ++__first) + if (__pred(*__first)) + return false; + return true; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_NONE_OF_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/nth_element.h b/app/src/main/cpp/libcxx/include/__algorithm/nth_element.h new file mode 100644 index 0000000..9fdfb2c --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/nth_element.h @@ -0,0 +1,258 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_NTH_ELEMENT_H +#define _LIBCPP___ALGORITHM_NTH_ELEMENT_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/sort.h> +#include <__config> +#include <__debug> +#include <__debug_utils/randomize_range.h> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool +__nth_element_find_guard(_RandomAccessIterator& __i, _RandomAccessIterator& __j, + _RandomAccessIterator __m, _Compare __comp) +{ + // manually guard downward moving __j against __i + while (true) { + if (__i == --__j) { + return false; + } + if (__comp(*__j, *__m)) { + return true; // found guard for downward moving __j, now use unguarded partition + } + } +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void +__nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) +{ + using _Ops = _IterOps<_AlgPolicy>; + + // _Compare is known to be a reference type + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + const difference_type __limit = 7; + while (true) + { + if (__nth == __last) + return; + difference_type __len = __last - __first; + switch (__len) + { + case 0: + case 1: + return; + case 2: + if (__comp(*--__last, *__first)) + _Ops::iter_swap(__first, __last); + return; + case 3: + { + _RandomAccessIterator __m = __first; + std::__sort3<_AlgPolicy, _Compare>(__first, ++__m, --__last, __comp); + return; + } + } + if (__len <= __limit) + { + std::__selection_sort<_AlgPolicy, _Compare>(__first, __last, __comp); + return; + } + // __len > __limit >= 3 + _RandomAccessIterator __m = __first + __len/2; + _RandomAccessIterator __lm1 = __last; + unsigned __n_swaps = std::__sort3<_AlgPolicy, _Compare>(__first, __m, --__lm1, __comp); + // *__m is median + // partition [__first, __m) < *__m and *__m <= [__m, __last) + // (this inhibits tossing elements equivalent to __m around unnecessarily) + _RandomAccessIterator __i = __first; + _RandomAccessIterator __j = __lm1; + // j points beyond range to be tested, *__lm1 is known to be <= *__m + // The search going up is known to be guarded but the search coming down isn't. + // Prime the downward search with a guard. + if (!__comp(*__i, *__m)) // if *__first == *__m + { + // *__first == *__m, *__first doesn't go in first part + if (_VSTD::__nth_element_find_guard<_Compare>(__i, __j, __m, __comp)) { + _Ops::iter_swap(__i, __j); + ++__n_swaps; + } else { + // *__first == *__m, *__m <= all other elements + // Partition instead into [__first, __i) == *__first and *__first < [__i, __last) + ++__i; // __first + 1 + __j = __last; + if (!__comp(*__first, *--__j)) { // we need a guard if *__first == *(__last-1) + while (true) { + if (__i == __j) { + return; // [__first, __last) all equivalent elements + } else if (__comp(*__first, *__i)) { + _Ops::iter_swap(__i, __j); + ++__n_swaps; + ++__i; + break; + } + ++__i; + } + } + // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1 + if (__i == __j) { + return; + } + while (true) { + while (!__comp(*__first, *__i)) + ++__i; + while (__comp(*__first, *--__j)) + ; + if (__i >= __j) + break; + _Ops::iter_swap(__i, __j); + ++__n_swaps; + ++__i; + } + // [__first, __i) == *__first and *__first < [__i, __last) + // The first part is sorted, + if (__nth < __i) { + return; + } + // __nth_element the second part + // _VSTD::__nth_element<_Compare>(__i, __nth, __last, __comp); + __first = __i; + continue; + } + } + ++__i; + // j points beyond range to be tested, *__lm1 is known to be <= *__m + // if not yet partitioned... + if (__i < __j) + { + // known that *(__i - 1) < *__m + while (true) + { + // __m still guards upward moving __i + while (__comp(*__i, *__m)) + ++__i; + // It is now known that a guard exists for downward moving __j + while (!__comp(*--__j, *__m)) + ; + if (__i >= __j) + break; + _Ops::iter_swap(__i, __j); + ++__n_swaps; + // It is known that __m != __j + // If __m just moved, follow it + if (__m == __i) + __m = __j; + ++__i; + } + } + // [__first, __i) < *__m and *__m <= [__i, __last) + if (__i != __m && __comp(*__m, *__i)) + { + _Ops::iter_swap(__i, __m); + ++__n_swaps; + } + // [__first, __i) < *__i and *__i <= [__i+1, __last) + if (__nth == __i) + return; + if (__n_swaps == 0) + { + // We were given a perfectly partitioned sequence. Coincidence? + if (__nth < __i) + { + // Check for [__first, __i) already sorted + __j = __m = __first; + while (true) { + if (++__j == __i) { + // [__first, __i) sorted + return; + } + if (__comp(*__j, *__m)) { + // not yet sorted, so sort + break; + } + __m = __j; + } + } + else + { + // Check for [__i, __last) already sorted + __j = __m = __i; + while (true) { + if (++__j == __last) { + // [__i, __last) sorted + return; + } + if (__comp(*__j, *__m)) { + // not yet sorted, so sort + break; + } + __m = __j; + } + } + } + // __nth_element on range containing __nth + if (__nth < __i) + { + // _VSTD::__nth_element<_Compare>(__first, __nth, __i, __comp); + __last = __i; + } + else + { + // _VSTD::__nth_element<_Compare>(__i+1, __nth, __last, __comp); + __first = ++__i; + } + } +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void __nth_element_impl(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, + _Compare& __comp) { + if (__nth == __last) + return; + + std::__debug_randomize_range<_AlgPolicy>(__first, __last); + + std::__nth_element<_AlgPolicy, __comp_ref_type<_Compare> >(__first, __nth, __last, __comp); + + std::__debug_randomize_range<_AlgPolicy>(__first, __nth); + if (__nth != __last) { + std::__debug_randomize_range<_AlgPolicy>(++__nth, __last); + } +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, + _Compare __comp) { + std::__nth_element_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__nth), std::move(__last), __comp); +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last) { + std::nth_element(std::move(__first), std::move(__nth), std::move(__last), __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_NTH_ELEMENT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/partial_sort.h b/app/src/main/cpp/libcxx/include/__algorithm/partial_sort.h new file mode 100644 index 0000000..e0812af --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/partial_sort.h @@ -0,0 +1,96 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_PARTIAL_SORT_H +#define _LIBCPP___ALGORITHM_PARTIAL_SORT_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_heap.h> +#include <__algorithm/sift_down.h> +#include <__algorithm/sort_heap.h> +#include <__config> +#include <__debug> +#include <__debug_utils/randomize_range.h> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +_RandomAccessIterator __partial_sort_impl( + _RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, _Compare&& __comp) { + if (__first == __middle) { + return _IterOps<_AlgPolicy>::next(__middle, __last); + } + + std::__make_heap<_AlgPolicy>(__first, __middle, __comp); + + typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first; + _RandomAccessIterator __i = __middle; + for (; __i != __last; ++__i) + { + if (__comp(*__i, *__first)) + { + _IterOps<_AlgPolicy>::iter_swap(__i, __first); + std::__sift_down<_AlgPolicy>(__first, __comp, __len, __first); + } + } + std::__sort_heap<_AlgPolicy>(std::move(__first), std::move(__middle), __comp); + + return __i; +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +_RandomAccessIterator __partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, + _Compare& __comp) { + if (__first == __middle) + return _IterOps<_AlgPolicy>::next(__middle, __last); + + std::__debug_randomize_range<_AlgPolicy>(__first, __last); + + auto __last_iter = + std::__partial_sort_impl<_AlgPolicy>(__first, __middle, __last, static_cast<__comp_ref_type<_Compare> >(__comp)); + + std::__debug_randomize_range<_AlgPolicy>(__middle, __last); + + return __last_iter; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +void +partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, + _Compare __comp) +{ + static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible."); + static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable."); + + (void)std::__partial_sort<_ClassicAlgPolicy>(std::move(__first), std::move(__middle), std::move(__last), __comp); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +void +partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) +{ + _VSTD::partial_sort(__first, __middle, __last, + __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_PARTIAL_SORT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/partial_sort_copy.h b/app/src/main/cpp/libcxx/include/__algorithm/partial_sort_copy.h new file mode 100644 index 0000000..1aba071 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/partial_sort_copy.h @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H +#define _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_heap.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/sift_down.h> +#include <__algorithm/sort_heap.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/iterator_traits.h> +#include <__type_traits/is_callable.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator, _RandomAccessIterator> +__partial_sort_copy(_InputIterator __first, _Sentinel1 __last, + _RandomAccessIterator __result_first, _Sentinel2 __result_last, + _Compare&& __comp, _Proj1&& __proj1, _Proj2&& __proj2) +{ + _RandomAccessIterator __r = __result_first; + auto&& __projected_comp = std::__make_projected(__comp, __proj2); + + if (__r != __result_last) + { + for (; __first != __last && __r != __result_last; ++__first, (void) ++__r) + *__r = *__first; + std::__make_heap<_AlgPolicy>(__result_first, __r, __projected_comp); + typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first; + for (; __first != __last; ++__first) + if (std::__invoke(__comp, std::__invoke(__proj1, *__first), std::__invoke(__proj2, *__result_first))) { + *__result_first = *__first; + std::__sift_down<_AlgPolicy>(__result_first, __projected_comp, __len, __result_first); + } + std::__sort_heap<_AlgPolicy>(__result_first, __r, __projected_comp); + } + + return pair<_InputIterator, _RandomAccessIterator>( + _IterOps<_AlgPolicy>::next(std::move(__first), std::move(__last)), std::move(__r)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +_RandomAccessIterator +partial_sort_copy(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp) +{ + static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__result_first)>::value, + "Comparator has to be callable"); + + auto __result = std::__partial_sort_copy<_ClassicAlgPolicy>(__first, __last, __result_first, __result_last, + static_cast<__comp_ref_type<_Compare> >(__comp), __identity(), __identity()); + return __result.second; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +_RandomAccessIterator +partial_sort_copy(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __result_first, _RandomAccessIterator __result_last) +{ + return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last, + __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/partition.h b/app/src/main/cpp/libcxx/include/__algorithm/partition.h new file mode 100644 index 0000000..0e094bf --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/partition.h @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_PARTITION_H +#define _LIBCPP___ALGORITHM_PARTITION_H + +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> +#include <__utility/pair.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> +__partition_impl(_ForwardIterator __first, _Sentinel __last, _Predicate __pred, forward_iterator_tag) +{ + while (true) + { + if (__first == __last) + return std::make_pair(std::move(__first), std::move(__first)); + if (!__pred(*__first)) + break; + ++__first; + } + + _ForwardIterator __p = __first; + while (++__p != __last) + { + if (__pred(*__p)) + { + _IterOps<_AlgPolicy>::iter_swap(__first, __p); + ++__first; + } + } + return std::make_pair(std::move(__first), std::move(__p)); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, _BidirectionalIterator> +__partition_impl(_BidirectionalIterator __first, _Sentinel __sentinel, _Predicate __pred, + bidirectional_iterator_tag) +{ + _BidirectionalIterator __original_last = _IterOps<_AlgPolicy>::next(__first, __sentinel); + _BidirectionalIterator __last = __original_last; + + while (true) + { + while (true) + { + if (__first == __last) + return std::make_pair(std::move(__first), std::move(__original_last)); + if (!__pred(*__first)) + break; + ++__first; + } + do + { + if (__first == --__last) + return std::make_pair(std::move(__first), std::move(__original_last)); + } while (!__pred(*__last)); + _IterOps<_AlgPolicy>::iter_swap(__first, __last); + ++__first; + } +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +pair<_ForwardIterator, _ForwardIterator> __partition( + _ForwardIterator __first, _Sentinel __last, _Predicate&& __pred, _IterCategory __iter_category) { + return std::__partition_impl<__remove_cvref_t<_Predicate>&, _AlgPolicy>( + std::move(__first), std::move(__last), __pred, __iter_category); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +_ForwardIterator +partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) +{ + using _IterCategory = typename iterator_traits<_ForwardIterator>::iterator_category; + auto __result = std::__partition<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __pred, _IterCategory()); + return __result.first; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_PARTITION_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/partition_copy.h b/app/src/main/cpp/libcxx/include/__algorithm/partition_copy.h new file mode 100644 index 0000000..ff8826a --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/partition_copy.h @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_PARTITION_COPY_H +#define _LIBCPP___ALGORITHM_PARTITION_COPY_H + +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_OutputIterator1, _OutputIterator2> +partition_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator1 __out_true, _OutputIterator2 __out_false, + _Predicate __pred) +{ + for (; __first != __last; ++__first) + { + if (__pred(*__first)) + { + *__out_true = *__first; + ++__out_true; + } + else + { + *__out_false = *__first; + ++__out_false; + } + } + return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_PARTITION_COPY_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/partition_point.h b/app/src/main/cpp/libcxx/include/__algorithm/partition_point.h new file mode 100644 index 0000000..6ede71a --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/partition_point.h @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_PARTITION_POINT_H +#define _LIBCPP___ALGORITHM_PARTITION_POINT_H + +#include <__algorithm/half_positive.h> +#include <__config> +#include <__iterator/advance.h> +#include <__iterator/distance.h> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) +{ + typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; + difference_type __len = _VSTD::distance(__first, __last); + while (__len != 0) + { + difference_type __l2 = _VSTD::__half_positive(__len); + _ForwardIterator __m = __first; + _VSTD::advance(__m, __l2); + if (__pred(*__m)) + { + __first = ++__m; + __len -= __l2 + 1; + } + else + __len = __l2; + } + return __first; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_PARTITION_POINT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/pop_heap.h b/app/src/main/cpp/libcxx/include/__algorithm/pop_heap.h new file mode 100644 index 0000000..94d32a4 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/pop_heap.h @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_POP_HEAP_H +#define _LIBCPP___ALGORITHM_POP_HEAP_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/push_heap.h> +#include <__algorithm/sift_down.h> +#include <__assert> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len) { + _LIBCPP_ASSERT(__len > 0, "The heap given to pop_heap must be non-empty"); + + __comp_ref_type<_Compare> __comp_ref = __comp; + + using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; + if (__len > 1) { + value_type __top = _IterOps<_AlgPolicy>::__iter_move(__first); // create a hole at __first + _RandomAccessIterator __hole = std::__floyd_sift_down<_AlgPolicy>(__first, __comp_ref, __len); + --__last; + + if (__hole == __last) { + *__hole = std::move(__top); + } else { + *__hole = _IterOps<_AlgPolicy>::__iter_move(__last); + ++__hole; + *__last = std::move(__top); + std::__sift_up<_AlgPolicy>(__first, __hole, __comp_ref, __hole - __first); + } + } +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible."); + static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable."); + + typename iterator_traits<_RandomAccessIterator>::difference_type __len = __last - __first; + std::__pop_heap<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp, __len); +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { + std::pop_heap(std::move(__first), std::move(__last), + __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_POP_HEAP_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/prev_permutation.h b/app/src/main/cpp/libcxx/include/__algorithm/prev_permutation.h new file mode 100644 index 0000000..0b86ab7 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/prev_permutation.h @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_PREV_PERMUTATION_H +#define _LIBCPP___ALGORITHM_PREV_PERMUTATION_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/reverse.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +pair<_BidirectionalIterator, bool> +__prev_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp) +{ + using _Result = pair<_BidirectionalIterator, bool>; + + _BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last); + _BidirectionalIterator __i = __last_iter; + if (__first == __last || __first == --__i) + return _Result(std::move(__last_iter), false); + + while (true) + { + _BidirectionalIterator __ip1 = __i; + if (__comp(*__ip1, *--__i)) + { + _BidirectionalIterator __j = __last_iter; + while (!__comp(*--__j, *__i)) + ; + _IterOps<_AlgPolicy>::iter_swap(__i, __j); + std::__reverse<_AlgPolicy>(__ip1, __last_iter); + return _Result(std::move(__last_iter), true); + } + if (__i == __first) + { + std::__reverse<_AlgPolicy>(__first, __last_iter); + return _Result(std::move(__last_iter), false); + } + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +bool +prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) +{ + return std::__prev_permutation<_ClassicAlgPolicy>( + std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp)).second; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +bool +prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) +{ + return _VSTD::prev_permutation(__first, __last, + __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_PREV_PERMUTATION_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/push_heap.h b/app/src/main/cpp/libcxx/include/__algorithm/push_heap.h new file mode 100644 index 0000000..9068495 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/push_heap.h @@ -0,0 +1,77 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_PUSH_HEAP_H +#define _LIBCPP___ALGORITHM_PUSH_HEAP_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +void __sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len) { + using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; + + if (__len > 1) { + __len = (__len - 2) / 2; + _RandomAccessIterator __ptr = __first + __len; + + if (__comp(*__ptr, *--__last)) { + value_type __t(_IterOps<_AlgPolicy>::__iter_move(__last)); + do { + *__last = _IterOps<_AlgPolicy>::__iter_move(__ptr); + __last = __ptr; + if (__len == 0) + break; + __len = (__len - 1) / 2; + __ptr = __first + __len; + } while (__comp(*__ptr, __t)); + + *__last = std::move(__t); + } + } +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +void __push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) { + typename iterator_traits<_RandomAccessIterator>::difference_type __len = __last - __first; + std::__sift_up<_AlgPolicy, __comp_ref_type<_Compare> >(std::move(__first), std::move(__last), __comp, __len); +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible."); + static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable."); + + std::__push_heap<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { + std::push_heap(std::move(__first), std::move(__last), + __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_PUSH_HEAP_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_adjacent_find.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_adjacent_find.h new file mode 100644 index 0000000..d338d13 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_adjacent_find.h @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_ADJACENT_FIND_H +#define _LIBCPP___ALGORITHM_RANGES_ADJACENT_FIND_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __adjacent_find { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + _Iter __adjacent_find_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { + if (__first == __last) + return __first; + + auto __i = __first; + while (++__i != __last) { + if (std::invoke(__pred, std::invoke(__proj, *__first), std::invoke(__proj, *__i))) + return __first; + __first = __i; + } + return __i; + } + + template _Sent, + class _Proj = identity, + indirect_binary_predicate, projected<_Iter, _Proj>> _Pred = ranges::equal_to> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { + return __adjacent_find_impl(std::move(__first), std::move(__last), __pred, __proj); + } + + template , _Proj>, + projected, _Proj>> _Pred = ranges::equal_to> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __range, _Pred __pred = {}, _Proj __proj = {}) const { + return __adjacent_find_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); + } +}; +} // namespace __adjacent_find + +inline namespace __cpo { + inline constexpr auto adjacent_find = __adjacent_find::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_ADJACENT_FIND_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_all_of.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_all_of.h new file mode 100644 index 0000000..e45c4e5 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_all_of.h @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_ALL_OF_H +#define _LIBCPP___ALGORITHM_RANGES_ALL_OF_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __all_of { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + bool __all_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { + for (; __first != __last; ++__first) { + if (!std::invoke(__pred, std::invoke(__proj, *__first))) + return false; + } + return true; + } + + template _Sent, class _Proj = identity, + indirect_unary_predicate> _Pred> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { + return __all_of_impl(std::move(__first), std::move(__last), __pred, __proj); + } + + template , _Proj>> _Pred> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { + return __all_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); + } +}; +} // namespace __all_of + +inline namespace __cpo { + inline constexpr auto all_of = __all_of::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_ALL_OF_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_any_of.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_any_of.h new file mode 100644 index 0000000..e7d1e72 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_any_of.h @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_ANY_OF_H +#define _LIBCPP___ALGORITHM_RANGES_ANY_OF_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __any_of { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + bool __any_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { + for (; __first != __last; ++__first) { + if (std::invoke(__pred, std::invoke(__proj, *__first))) + return true; + } + return false; + } + + template _Sent, class _Proj = identity, + indirect_unary_predicate> _Pred> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { + return __any_of_impl(std::move(__first), std::move(__last), __pred, __proj); + } + + template , _Proj>> _Pred> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { + return __any_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); + } +}; +} // namespace __any_of + +inline namespace __cpo { + inline constexpr auto any_of = __any_of::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_ANY_OF_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_binary_search.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_binary_search.h new file mode 100644 index 0000000..b2a8977 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_binary_search.h @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_BINARY_SEARCH_H +#define _LIBCPP___ALGORITHM_RANGES_BINARY_SEARCH_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/lower_bound.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __binary_search { +struct __fn { + template _Sent, class _Type, class _Proj = identity, + indirect_strict_weak_order> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); + return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__first)); + } + + template , _Proj>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { + auto __first = ranges::begin(__r); + auto __last = ranges::end(__r); + auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); + return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__first)); + } +}; +} // namespace __binary_search + +inline namespace __cpo { + inline constexpr auto binary_search = __binary_search::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_BINARY_SEARCH_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_clamp.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_clamp.h new file mode 100644 index 0000000..09a97fc --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_clamp.h @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_CLAMP_H +#define _LIBCPP___ALGORITHM_RANGES_CLAMP_H + +#include <__assert> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__utility/forward.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __clamp { +struct __fn { + + template > _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + const _Type& operator()(const _Type& __value, + const _Type& __low, + const _Type& __high, + _Comp __comp = {}, + _Proj __proj = {}) const { + _LIBCPP_ASSERT(!bool(std::invoke(__comp, std::invoke(__proj, __high), std::invoke(__proj, __low))), + "Bad bounds passed to std::ranges::clamp"); + + if (std::invoke(__comp, std::invoke(__proj, __value), std::invoke(__proj, __low))) + return __low; + else if (std::invoke(__comp, std::invoke(__proj, __high), std::invoke(__proj, __value))) + return __high; + else + return __value; + } + +}; +} // namespace __clamp + +inline namespace __cpo { + inline constexpr auto clamp = __clamp::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_CLAMP_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_copy.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_copy.h new file mode 100644 index 0000000..bb02c84 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_copy.h @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_COPY_H +#define _LIBCPP___ALGORITHM_RANGES_COPY_H + +#include <__algorithm/copy.h> +#include <__algorithm/in_out_result.h> +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__functional/identity.h> +#include <__iterator/concepts.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using copy_result = in_out_result<_InIter, _OutIter>; + +namespace __copy { +struct __fn { + + template _Sent, weakly_incrementable _OutIter> + requires indirectly_copyable<_InIter, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + copy_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const { + auto __ret = std::__copy<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)); + return {std::move(__ret.first), std::move(__ret.second)}; + } + + template + requires indirectly_copyable, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + copy_result, _OutIter> operator()(_Range&& __r, _OutIter __result) const { + auto __ret = std::__copy<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), std::move(__result)); + return {std::move(__ret.first), std::move(__ret.second)}; + } +}; +} // namespace __copy + +inline namespace __cpo { + inline constexpr auto copy = __copy::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_COPY_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_copy_backward.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_copy_backward.h new file mode 100644 index 0000000..f41af66 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_copy_backward.h @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_COPY_BACKWARD_H +#define _LIBCPP___ALGORITHM_RANGES_COPY_BACKWARD_H + +#include <__algorithm/copy_backward.h> +#include <__algorithm/in_out_result.h> +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using copy_backward_result = in_out_result<_Ip, _Op>; + +namespace __copy_backward { +struct __fn { + + template _Sent1, bidirectional_iterator _InIter2> + requires indirectly_copyable<_InIter1, _InIter2> + _LIBCPP_HIDE_FROM_ABI constexpr + copy_backward_result<_InIter1, _InIter2> operator()(_InIter1 __first, _Sent1 __last, _InIter2 __result) const { + auto __ret = std::__copy_backward<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)); + return {std::move(__ret.first), std::move(__ret.second)}; + } + + template + requires indirectly_copyable, _Iter> + _LIBCPP_HIDE_FROM_ABI constexpr + copy_backward_result, _Iter> operator()(_Range&& __r, _Iter __result) const { + auto __ret = std::__copy_backward<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), std::move(__result)); + return {std::move(__ret.first), std::move(__ret.second)}; + } +}; +} // namespace __copy_backward + +inline namespace __cpo { + inline constexpr auto copy_backward = __copy_backward::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_COPY_BACKWARD_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_copy_if.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_copy_if.h new file mode 100644 index 0000000..dba41c3 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_copy_if.h @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_COPY_IF_H +#define _LIBCPP___ALGORITHM_RANGES_COPY_IF_H + +#include <__algorithm/in_out_result.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using copy_if_result = in_out_result<_Ip, _Op>; + +namespace __copy_if { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI static constexpr + copy_if_result <_InIter, _OutIter> + __copy_if_impl(_InIter __first, _Sent __last, _OutIter __result, _Pred& __pred, _Proj& __proj) { + for (; __first != __last; ++__first) { + if (std::invoke(__pred, std::invoke(__proj, *__first))) { + *__result = *__first; + ++__result; + } + } + return {std::move(__first), std::move(__result)}; + } + + template _Sent, weakly_incrementable _OutIter, class _Proj = identity, + indirect_unary_predicate> _Pred> + requires indirectly_copyable<_Iter, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + copy_if_result<_Iter, _OutIter> + operator()(_Iter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const { + return __copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj); + } + + template , _Proj>> _Pred> + requires indirectly_copyable, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + copy_if_result, _OutIter> + operator()(_Range&& __r, _OutIter __result, _Pred __pred, _Proj __proj = {}) const { + return __copy_if_impl(ranges::begin(__r), ranges::end(__r), std::move(__result), __pred, __proj); + } +}; +} // namespace __copy_if + +inline namespace __cpo { + inline constexpr auto copy_if = __copy_if::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_COPY_IF_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_copy_n.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_copy_n.h new file mode 100644 index 0000000..04bb80b --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_copy_n.h @@ -0,0 +1,77 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_COPY_N_H +#define _LIBCPP___ALGORITHM_RANGES_COPY_N_H + +#include <__algorithm/copy.h> +#include <__algorithm/in_out_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/ranges_copy.h> +#include <__config> +#include <__functional/identity.h> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/unreachable_sentinel.h> +#include <__iterator/wrap_iter.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace ranges { + +template +using copy_n_result = in_out_result<_Ip, _Op>; + +namespace __copy_n { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + copy_n_result<_InIter, _OutIter> __go(_InIter __first, _DiffType __n, _OutIter __result) { + while (__n != 0) { + *__result = *__first; + ++__first; + ++__result; + --__n; + } + return {std::move(__first), std::move(__result)}; + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + copy_n_result<_InIter, _OutIter> __go(_InIter __first, _DiffType __n, _OutIter __result) { + auto __ret = std::__copy<_RangeAlgPolicy>(__first, __first + __n, __result); + return {__ret.first, __ret.second}; + } + + template + requires indirectly_copyable<_Ip, _Op> + _LIBCPP_HIDE_FROM_ABI constexpr + copy_n_result<_Ip, _Op> operator()(_Ip __first, iter_difference_t<_Ip> __n, _Op __result) const { + return __go(std::move(__first), __n, std::move(__result)); + } +}; +} // namespace __copy_n + +inline namespace __cpo { + inline constexpr auto copy_n = __copy_n::__fn{}; +} // namespace __cpo +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_RANGES_COPY_N_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_count.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_count.h new file mode 100644 index 0000000..527dd06 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_count.h @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_COUNT_H +#define _LIBCPP___ALGORITHM_RANGES_COUNT_H + +#include <__algorithm/ranges_count_if.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __count { +struct __fn { + template _Sent, class _Type, class _Proj = identity> + requires indirect_binary_predicate, const _Type*> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + iter_difference_t<_Iter> operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const { + auto __pred = [&](auto&& __e) { return __e == __value; }; + return ranges::__count_if_impl(std::move(__first), std::move(__last), __pred, __proj); + } + + template + requires indirect_binary_predicate, _Proj>, const _Type*> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + range_difference_t<_Range> operator()(_Range&& __r, const _Type& __value, _Proj __proj = {}) const { + auto __pred = [&](auto&& __e) { return __e == __value; }; + return ranges::__count_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj); + } +}; +} // namespace __count + +inline namespace __cpo { + inline constexpr auto count = __count::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_COUNT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_count_if.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_count_if.h new file mode 100644 index 0000000..931618b --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_count_if.h @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_COUNT_IF_H +#define _LIBCPP___ALGORITHM_RANGES_COUNT_IF_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +template +_LIBCPP_HIDE_FROM_ABI constexpr +iter_difference_t<_Iter> __count_if_impl(_Iter __first, _Sent __last, + _Pred& __pred, _Proj& __proj) { + iter_difference_t<_Iter> __counter(0); + for (; __first != __last; ++__first) { + if (std::invoke(__pred, std::invoke(__proj, *__first))) + ++__counter; + } + return __counter; +} + +namespace __count_if { +struct __fn { + template _Sent, class _Proj = identity, + indirect_unary_predicate> _Predicate> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + iter_difference_t<_Iter> operator()(_Iter __first, _Sent __last, _Predicate __pred, _Proj __proj = {}) const { + return ranges::__count_if_impl(std::move(__first), std::move(__last), __pred, __proj); + } + + template , _Proj>> _Predicate> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + range_difference_t<_Range> operator()(_Range&& __r, _Predicate __pred, _Proj __proj = {}) const { + return ranges::__count_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj); + } +}; +} // namespace __count_if + +inline namespace __cpo { + inline constexpr auto count_if = __count_if::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_COUNT_IF_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_equal.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_equal.h new file mode 100644 index 0000000..3c417f0 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_equal.h @@ -0,0 +1,115 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_EQUAL_H +#define _LIBCPP___ALGORITHM_RANGES_EQUAL_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/distance.h> +#include <__iterator/indirectly_comparable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __equal { +struct __fn { +private: + template + _LIBCPP_HIDE_FROM_ABI constexpr static + bool __equal_impl(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2) { + while (__first1 != __last1 && __first2 != __last2) { + if (!std::invoke(__pred, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2))) + return false; + ++__first1; + ++__first2; + } + return __first1 == __last1 && __first2 == __last2; + } + +public: + + template _Sent1, + input_iterator _Iter2, sentinel_for<_Iter2> _Sent2, + class _Pred = ranges::equal_to, + class _Proj1 = identity, + class _Proj2 = identity> + requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Pred __pred = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + if constexpr (sized_sentinel_for<_Sent1, _Iter1> && sized_sentinel_for<_Sent2, _Iter2>) { + if (__last1 - __first1 != __last2 - __first2) + return false; + } + return __equal_impl(std::move(__first1), std::move(__last1), + std::move(__first2), std::move(__last2), + __pred, + __proj1, + __proj2); + } + + template + requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Range1&& __range1, + _Range2&& __range2, + _Pred __pred = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + if constexpr (sized_range<_Range1> && sized_range<_Range2>) { + if (ranges::distance(__range1) != ranges::distance(__range2)) + return false; + } + return __equal_impl(ranges::begin(__range1), ranges::end(__range1), + ranges::begin(__range2), ranges::end(__range2), + __pred, + __proj1, + __proj2); + return false; + } +}; +} // namespace __equal + +inline namespace __cpo { + inline constexpr auto equal = __equal::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_EQUAL_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_equal_range.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_equal_range.h new file mode 100644 index 0000000..94dc058 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_equal_range.h @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM __project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_EQUAL_RANGE_H +#define _LIBCPP___ALGORITHM_RANGES_EQUAL_RANGE_H + +#include <__algorithm/equal_range.h> +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__ranges/subrange.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __equal_range { + +struct __fn { + template < + forward_iterator _Iter, + sentinel_for<_Iter> _Sent, + class _Tp, + class _Proj = identity, + indirect_strict_weak_order> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> + operator()(_Iter __first, _Sent __last, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = std::__equal_range<_RangeAlgPolicy>( + std::move(__first), std::move(__last), __value, __comp, __proj); + return {std::move(__ret.first), std::move(__ret.second)}; + } + + template < + forward_range _Range, + class _Tp, + class _Proj = identity, + indirect_strict_weak_order, _Proj>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> + operator()(_Range&& __range, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = std::__equal_range<_RangeAlgPolicy>( + ranges::begin(__range), ranges::end(__range), __value, __comp, __proj); + return {std::move(__ret.first), std::move(__ret.second)}; + } +}; + +} // namespace __equal_range + +inline namespace __cpo { + inline constexpr auto equal_range = __equal_range::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_EQUAL_RANGE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_fill.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_fill.h new file mode 100644 index 0000000..6ebc2bd --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_fill.h @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_FILL_H +#define _LIBCPP___ALGORITHM_RANGES_FILL_H + +#include <__algorithm/ranges_fill_n.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __fill { +struct __fn { + template _Iter, sentinel_for<_Iter> _Sent> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, const _Type& __value) const { + if constexpr(random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>) { + return ranges::fill_n(__first, __last - __first, __value); + } else { + for (; __first != __last; ++__first) + *__first = __value; + return __first; + } + } + + template _Range> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __range, const _Type& __value) const { + return (*this)(ranges::begin(__range), ranges::end(__range), __value); + } +}; +} // namespace __fill + +inline namespace __cpo { + inline constexpr auto fill = __fill::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_FILL_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_fill_n.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_fill_n.h new file mode 100644 index 0000000..a2660e8 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_fill_n.h @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_FILL_N_H +#define _LIBCPP___ALGORITHM_RANGES_FILL_N_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __fill_n { +struct __fn { + template _Iter> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, iter_difference_t<_Iter> __n, const _Type& __value) const { + for (; __n != 0; --__n) { + *__first = __value; + ++__first; + } + return __first; + } +}; +} // namespace __fill_n + +inline namespace __cpo { + inline constexpr auto fill_n = __fill_n::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_FILL_N_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_find.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_find.h new file mode 100644 index 0000000..580c2a1 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_find.h @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_FIND_H +#define _LIBCPP___ALGORITHM_RANGES_FIND_H + +#include <__algorithm/ranges_find_if.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __find { +struct __fn { + template _Sp, class _Tp, class _Proj = identity> + requires indirect_binary_predicate, const _Tp*> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + _Ip operator()(_Ip __first, _Sp __last, const _Tp& __value, _Proj __proj = {}) const { + auto __pred = [&](auto&& __e) { return std::forward(__e) == __value; }; + return ranges::__find_if_impl(std::move(__first), std::move(__last), __pred, __proj); + } + + template + requires indirect_binary_predicate, _Proj>, const _Tp*> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Rp> operator()(_Rp&& __r, const _Tp& __value, _Proj __proj = {}) const { + auto __pred = [&](auto&& __e) { return std::forward(__e) == __value; }; + return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj); + } +}; +} // namespace __find + +inline namespace __cpo { + inline constexpr auto find = __find::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_FIND_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_find_end.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_find_end.h new file mode 100644 index 0000000..ea36f4d --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_find_end.h @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_FIND_END_H +#define _LIBCPP___ALGORITHM_RANGES_FIND_END_H + +#include <__algorithm/find_end.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/ranges_iterator_concept.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/indirectly_comparable.h> +#include <__iterator/iterator_traits.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/subrange.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __find_end { +struct __fn { + template _Sent1, + forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2, + class _Pred = ranges::equal_to, + class _Proj1 = identity, + class _Proj2 = identity> + requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + subrange<_Iter1> operator()(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Pred __pred = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + auto __ret = std::__find_end_impl<_RangeAlgPolicy>( + __first1, + __last1, + __first2, + __last2, + __pred, + __proj1, + __proj2, + __iterator_concept<_Iter1>(), + __iterator_concept<_Iter2>()); + return {__ret.first, __ret.second}; + } + + template + requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_subrange_t<_Range1> operator()(_Range1&& __range1, + _Range2&& __range2, + _Pred __pred = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + auto __ret = std::__find_end_impl<_RangeAlgPolicy>( + ranges::begin(__range1), + ranges::end(__range1), + ranges::begin(__range2), + ranges::end(__range2), + __pred, + __proj1, + __proj2, + __iterator_concept>(), + __iterator_concept>()); + return {__ret.first, __ret.second}; + } +}; +} // namespace __find_end + +inline namespace __cpo { + inline constexpr auto find_end = __find_end::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_FIND_END_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_find_first_of.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_find_first_of.h new file mode 100644 index 0000000..9d66e75 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_find_first_of.h @@ -0,0 +1,101 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_FIND_FIRST_OF_H +#define _LIBCPP___ALGORITHM_RANGES_FIND_FIRST_OF_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/indirectly_comparable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __find_first_of { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + _Iter1 __find_first_of_impl(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2) { + for (; __first1 != __last1; ++__first1) { + for (auto __j = __first2; __j != __last2; ++__j) { + if (std::invoke(__pred, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__j))) + return __first1; + } + } + return __first1; + } + + template _Sent1, + forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2, + class _Pred = ranges::equal_to, + class _Proj1 = identity, + class _Proj2 = identity> + requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + _Iter1 operator()(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Pred __pred = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + return __find_first_of_impl(std::move(__first1), std::move(__last1), + std::move(__first2), std::move(__last2), + __pred, + __proj1, + __proj2); + } + + template + requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range1> operator()(_Range1&& __range1, + _Range2&& __range2, + _Pred __pred = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + return __find_first_of_impl(ranges::begin(__range1), ranges::end(__range1), + ranges::begin(__range2), ranges::end(__range2), + __pred, + __proj1, + __proj2); + } + +}; +} // namespace __find_first_of + +inline namespace __cpo { + inline constexpr auto find_first_of = __find_first_of::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_FIND_FIRST_OF_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_find_if.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_find_if.h new file mode 100644 index 0000000..45ce6e4 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_find_if.h @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_FIND_IF_H +#define _LIBCPP___ALGORITHM_RANGES_FIND_IF_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +_LIBCPP_HIDE_FROM_ABI static constexpr +_Ip __find_if_impl(_Ip __first, _Sp __last, _Pred& __pred, _Proj& __proj) { + for (; __first != __last; ++__first) { + if (std::invoke(__pred, std::invoke(__proj, *__first))) + break; + } + return __first; +} + +namespace __find_if { +struct __fn { + + template _Sp, class _Proj = identity, + indirect_unary_predicate> _Pred> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + _Ip operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const { + return ranges::__find_if_impl(std::move(__first), std::move(__last), __pred, __proj); + } + + template , _Proj>> _Pred> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const { + return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj); + } +}; +} // namespace __find_if + +inline namespace __cpo { + inline constexpr auto find_if = __find_if::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_FIND_IF_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_find_if_not.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_find_if_not.h new file mode 100644 index 0000000..3dd1213 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_find_if_not.h @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_FIND_IF_NOT_H +#define _LIBCPP___ALGORITHM_RANGES_FIND_IF_NOT_H + +#include <__algorithm/ranges_find_if.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __find_if_not { +struct __fn { + template _Sp, class _Proj = identity, + indirect_unary_predicate> _Pred> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + _Ip operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const { + auto __pred2 = [&](auto&& __e) { return !std::invoke(__pred, std::forward(__e)); }; + return ranges::__find_if_impl(std::move(__first), std::move(__last), __pred2, __proj); + } + + template , _Proj>> _Pred> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const { + auto __pred2 = [&](auto&& __e) { return !std::invoke(__pred, std::forward(__e)); }; + return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred2, __proj); + } +}; +} // namespace __find_if_not + +inline namespace __cpo { + inline constexpr auto find_if_not = __find_if_not::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_FIND_IF_NOT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_for_each.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_for_each.h new file mode 100644 index 0000000..0c70c05 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_for_each.h @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_FOR_EACH_H +#define _LIBCPP___ALGORITHM_RANGES_FOR_EACH_H + +#include <__algorithm/in_fun_result.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using for_each_result = in_fun_result<_Iter, _Func>; + +namespace __for_each { +struct __fn { +private: + template + _LIBCPP_HIDE_FROM_ABI constexpr static + for_each_result<_Iter, _Func> __for_each_impl(_Iter __first, _Sent __last, _Func& __func, _Proj& __proj) { + for (; __first != __last; ++__first) + std::invoke(__func, std::invoke(__proj, *__first)); + return {std::move(__first), std::move(__func)}; + } + +public: + template _Sent, + class _Proj = identity, + indirectly_unary_invocable> _Func> + _LIBCPP_HIDE_FROM_ABI constexpr + for_each_result<_Iter, _Func> operator()(_Iter __first, _Sent __last, _Func __func, _Proj __proj = {}) const { + return __for_each_impl(std::move(__first), std::move(__last), __func, __proj); + } + + template , _Proj>> _Func> + _LIBCPP_HIDE_FROM_ABI constexpr + for_each_result, _Func> operator()(_Range&& __range, + _Func __func, + _Proj __proj = {}) const { + return __for_each_impl(ranges::begin(__range), ranges::end(__range), __func, __proj); + } + +}; +} // namespace __for_each + +inline namespace __cpo { + inline constexpr auto for_each = __for_each::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_FOR_EACH_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_for_each_n.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_for_each_n.h new file mode 100644 index 0000000..261816a --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_for_each_n.h @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_FOR_EACH_N_H +#define _LIBCPP___ALGORITHM_RANGES_FOR_EACH_N_H + +#include <__algorithm/in_fun_result.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/projected.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using for_each_n_result = in_fun_result<_Iter, _Func>; + +namespace __for_each_n { +struct __fn { + + template > _Func> + _LIBCPP_HIDE_FROM_ABI constexpr + for_each_n_result<_Iter, _Func> operator()(_Iter __first, + iter_difference_t<_Iter> __count, + _Func __func, + _Proj __proj = {}) const { + while (__count-- > 0) { + std::invoke(__func, std::invoke(__proj, *__first)); + ++__first; + } + return {std::move(__first), std::move(__func)}; + } + +}; +} // namespace __for_each_n + +inline namespace __cpo { + inline constexpr auto for_each_n = __for_each_n::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_FOR_EACH_N_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_generate.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_generate.h new file mode 100644 index 0000000..ae486ae --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_generate.h @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_GENERATE_H +#define _LIBCPP___ALGORITHM_RANGES_GENERATE_H + +#include <__concepts/constructible.h> +#include <__concepts/invocable.h> +#include <__config> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __generate { + +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr + static _OutIter __generate_fn_impl(_OutIter __first, _Sent __last, _Func& __gen) { + for (; __first != __last; ++__first) { + *__first = __gen(); + } + + return __first; + } + + template _Sent, copy_constructible _Func> + requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>> + _LIBCPP_HIDE_FROM_ABI constexpr + _OutIter operator()(_OutIter __first, _Sent __last, _Func __gen) const { + return __generate_fn_impl(std::move(__first), std::move(__last), __gen); + } + + template + requires invocable<_Func&> && output_range<_Range, invoke_result_t<_Func&>> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __range, _Func __gen) const { + return __generate_fn_impl(ranges::begin(__range), ranges::end(__range), __gen); + } + +}; + +} // namespace __generate + +inline namespace __cpo { + inline constexpr auto generate = __generate::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_GENERATE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_generate_n.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_generate_n.h new file mode 100644 index 0000000..e625e3a --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_generate_n.h @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_GENERATE_N_H +#define _LIBCPP___ALGORITHM_RANGES_GENERATE_N_H + +#include <__concepts/constructible.h> +#include <__concepts/invocable.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iterator_traits.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __generate_n { + +struct __fn { + + template + requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>> + _LIBCPP_HIDE_FROM_ABI constexpr + _OutIter operator()(_OutIter __first, iter_difference_t<_OutIter> __n, _Func __gen) const { + for (; __n > 0; --__n) { + *__first = __gen(); + ++__first; + } + + return __first; + } + +}; + +} // namespace __generate_n + +inline namespace __cpo { + inline constexpr auto generate_n = __generate_n::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_GENERATE_N_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_includes.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_includes.h new file mode 100644 index 0000000..8438117 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_includes.h @@ -0,0 +1,95 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_INCLUDES_H +#define _LIBCPP___ALGORITHM_RANGES_INCLUDES_H + +#include <__algorithm/includes.h> +#include <__algorithm/make_projected.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __includes { + +struct __fn { + template < + input_iterator _Iter1, + sentinel_for<_Iter1> _Sent1, + input_iterator _Iter2, + sentinel_for<_Iter2> _Sent2, + class _Proj1 = identity, + class _Proj2 = identity, + indirect_strict_weak_order, projected<_Iter2, _Proj2>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + return std::__includes( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__comp), + std::move(__proj1), + std::move(__proj2)); + } + + template < + input_range _Range1, + input_range _Range2, + class _Proj1 = identity, + class _Proj2 = identity, + indirect_strict_weak_order, _Proj1>, projected, _Proj2>> + _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + _Range1&& __range1, _Range2&& __range2, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + return std::__includes( + ranges::begin(__range1), + ranges::end(__range1), + ranges::begin(__range2), + ranges::end(__range2), + std::move(__comp), + std::move(__proj1), + std::move(__proj2)); + } +}; + +} // namespace __includes + +inline namespace __cpo { + inline constexpr auto includes = __includes::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_INCLUDES_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_inplace_merge.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_inplace_merge.h new file mode 100644 index 0000000..88171a6 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_inplace_merge.h @@ -0,0 +1,85 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_INPLACE_MERGE_H +#define _LIBCPP___ALGORITHM_RANGES_INPLACE_MERGE_H + +#include <__algorithm/inplace_merge.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/projected.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __inplace_merge { + + struct __fn { + template + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __inplace_merge_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp&& __comp, _Proj&& __proj) { + auto __last_iter = ranges::next(__middle, __last); + std::__inplace_merge<_RangeAlgPolicy>( + std::move(__first), std::move(__middle), __last_iter, std::__make_projected(__comp, __proj)); + return __last_iter; + } + + template < + bidirectional_iterator _Iter, + sentinel_for<_Iter> _Sent, + class _Comp = ranges::less, + class _Proj = identity> + requires sortable<_Iter, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI _Iter + operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return __inplace_merge_impl( + std::move(__first), std::move(__middle), std::move(__last), std::move(__comp), std::move(__proj)); + } + + template + requires sortable< + iterator_t<_Range>, + _Comp, + _Proj> _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_Range> + operator()(_Range&& __range, iterator_t<_Range> __middle, _Comp __comp = {}, _Proj __proj = {}) const { + return __inplace_merge_impl( + ranges::begin(__range), std::move(__middle), ranges::end(__range), std::move(__comp), std::move(__proj)); + } + }; + +} // namespace __inplace_merge + +inline namespace __cpo { + inline constexpr auto inplace_merge = __inplace_merge::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_INPLACE_MERGE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_is_heap.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_is_heap.h new file mode 100644 index 0000000..a16c075 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_is_heap.h @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_IS_HEAP_H +#define _LIBCPP___ALGORITHM_RANGES_IS_HEAP_H + +#include <__algorithm/is_heap_until.h> +#include <__algorithm/make_projected.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __is_heap { + +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr + static bool __is_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __last_iter = ranges::next(__first, __last); + auto&& __projected_comp = std::__make_projected(__comp, __proj); + + auto __result = std::__is_heap_until(std::move(__first), std::move(__last_iter), __projected_comp); + return __result == __last; + } + + template _Sent, class _Proj = identity, + indirect_strict_weak_order> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return __is_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj); + } + + template , _Proj>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { + return __is_heap_fn_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj); + } +}; + +} // namespace __is_heap + +inline namespace __cpo { + inline constexpr auto is_heap = __is_heap::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_IS_HEAP_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_is_heap_until.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_is_heap_until.h new file mode 100644 index 0000000..8c8dac5 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_is_heap_until.h @@ -0,0 +1,75 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_IS_HEAP_UNTIL_H +#define _LIBCPP___ALGORITHM_RANGES_IS_HEAP_UNTIL_H + +#include <__algorithm/is_heap_until.h> +#include <__algorithm/make_projected.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __is_heap_until { + +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr + static _Iter __is_heap_until_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __last_iter = ranges::next(__first, __last); + auto&& __projected_comp = std::__make_projected(__comp, __proj); + + return std::__is_heap_until(std::move(__first), std::move(__last_iter), __projected_comp); + } + + template _Sent, class _Proj = identity, + indirect_strict_weak_order> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return __is_heap_until_fn_impl(std::move(__first), std::move(__last), __comp, __proj); + } + + template , _Proj>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { + return __is_heap_until_fn_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj); + } + +}; + +} // namespace __is_heap_until + +inline namespace __cpo { + inline constexpr auto is_heap_until = __is_heap_until::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_IS_HEAP_UNTIL_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_is_partitioned.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_is_partitioned.h new file mode 100644 index 0000000..b903953 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_is_partitioned.h @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_IS_PARTITIONED_H +#define _LIBCPP___ALGORITHM_RANGES_IS_PARTITIONED_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/indirectly_comparable.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __is_partitioned { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + bool __is_parititioned_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { + for (; __first != __last; ++__first) { + if (!std::invoke(__pred, std::invoke(__proj, *__first))) + break; + } + + if (__first == __last) + return true; + ++__first; + + for (; __first != __last; ++__first) { + if (std::invoke(__pred, std::invoke(__proj, *__first))) + return false; + } + + return true; + } + + template _Sent, + class _Proj = identity, + indirect_unary_predicate> _Pred> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { + return __is_parititioned_impl(std::move(__first), std::move(__last), __pred, __proj); + } + + template , _Proj>> _Pred> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { + return __is_parititioned_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); + } +}; +} // namespace __is_partitioned + +inline namespace __cpo { + inline constexpr auto is_partitioned = __is_partitioned::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_IS_PARTITIONED_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_is_permutation.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_is_permutation.h new file mode 100644 index 0000000..b617500 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_is_permutation.h @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_IS_PERMUTATION_H +#define _LIBCPP___ALGORITHM_RANGES_IS_PERMUTATION_H + +#include <__algorithm/is_permutation.h> +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/distance.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __is_permutation { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + bool __is_permutation_func_impl(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, + _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) { + return std::__is_permutation<_RangeAlgPolicy>( + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), + __pred, __proj1, __proj2); + } + + template _Sent1, + forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2, + class _Proj1 = identity, + class _Proj2 = identity, + indirect_equivalence_relation, + projected<_Iter2, _Proj2>> _Pred = ranges::equal_to> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, + _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + return __is_permutation_func_impl( + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), + __pred, __proj1, __proj2); + } + + template , _Proj1>, projected, _Proj2>> _Pred = ranges::equal_to> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Range1&& __range1, _Range2&& __range2, + _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + if constexpr (sized_range<_Range1> && sized_range<_Range2>) { + if (ranges::distance(__range1) != ranges::distance(__range2)) + return false; + } + + return __is_permutation_func_impl( + ranges::begin(__range1), ranges::end(__range1), ranges::begin(__range2), ranges::end(__range2), + __pred, __proj1, __proj2); + } +}; +} // namespace __is_permutation + +inline namespace __cpo { + inline constexpr auto is_permutation = __is_permutation::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_IS_PERMUTATION_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_is_sorted.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_is_sorted.h new file mode 100644 index 0000000..ce3032f --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_is_sorted.h @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP__ALGORITHM_RANGES_IS_SORTED_H +#define _LIBCPP__ALGORITHM_RANGES_IS_SORTED_H + +#include <__algorithm/ranges_is_sorted_until.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __is_sorted { +struct __fn { + template _Sent, + class _Proj = identity, + indirect_strict_weak_order> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return ranges::__is_sorted_until_impl(std::move(__first), __last, __comp, __proj) == __last; + } + + template , _Proj>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { + auto __last = ranges::end(__range); + return ranges::__is_sorted_until_impl(ranges::begin(__range), __last, __comp, __proj) == __last; + } +}; +} // namespace __is_sorted + +inline namespace __cpo { + inline constexpr auto is_sorted = __is_sorted::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP__ALGORITHM_RANGES_IS_SORTED_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_is_sorted_until.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_is_sorted_until.h new file mode 100644 index 0000000..17fc42e --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_is_sorted_until.h @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP__ALGORITHM_RANGES_IS_SORTED_UNTIL_H +#define _LIBCPP__ALGORITHM_RANGES_IS_SORTED_UNTIL_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +_LIBCPP_HIDE_FROM_ABI constexpr +_Iter __is_sorted_until_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + if (__first == __last) + return __first; + auto __i = __first; + while (++__i != __last) { + if (std::invoke(__comp, std::invoke(__proj, *__i), std::invoke(__proj, *__first))) + return __i; + __first = __i; + } + return __i; +} + +namespace __is_sorted_until { +struct __fn { + template _Sent, + class _Proj = identity, + indirect_strict_weak_order> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return ranges::__is_sorted_until_impl(std::move(__first), std::move(__last), __comp, __proj); + } + + template , _Proj>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { + return ranges::__is_sorted_until_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj); + } +}; +} // namespace __is_sorted_until + +inline namespace __cpo { + inline constexpr auto is_sorted_until = __is_sorted_until::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP__ALGORITHM_RANGES_IS_SORTED_UNTIL_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_iterator_concept.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_iterator_concept.h new file mode 100644 index 0000000..3ac6b31 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_iterator_concept.h @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_ITERATOR_CONCEPT_H +#define _LIBCPP___ALGORITHM_RANGES_ITERATOR_CONCEPT_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__type_traits/remove_cvref.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +consteval auto __get_iterator_concept() { + using _Iter = __remove_cvref_t<_IterMaybeQualified>; + + if constexpr (contiguous_iterator<_Iter>) + return contiguous_iterator_tag(); + else if constexpr (random_access_iterator<_Iter>) + return random_access_iterator_tag(); + else if constexpr (bidirectional_iterator<_Iter>) + return bidirectional_iterator_tag(); + else if constexpr (forward_iterator<_Iter>) + return forward_iterator_tag(); + else if constexpr (input_iterator<_Iter>) + return input_iterator_tag(); +} + +template +using __iterator_concept = decltype(__get_iterator_concept<_Iter>()); + +} // namespace ranges +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_ITERATOR_CONCEPT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_lexicographical_compare.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_lexicographical_compare.h new file mode 100644 index 0000000..2972e32 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_lexicographical_compare.h @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_LEXICOGRAPHICAL_COMPARE_H +#define _LIBCPP___ALGORITHM_RANGES_LEXICOGRAPHICAL_COMPARE_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __lexicographical_compare { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + bool __lexicographical_compare_impl(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Comp& __comp, + _Proj1& __proj1, + _Proj2& __proj2) { + while (__first2 != __last2) { + if (__first1 == __last1 + || std::invoke(__comp, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2))) + return true; + if (std::invoke(__comp, std::invoke(__proj2, *__first2), std::invoke(__proj1, *__first1))) + return false; + ++__first1; + ++__first2; + } + return false; + } + + template _Sent1, + input_iterator _Iter2, sentinel_for<_Iter2> _Sent2, + class _Proj1 = identity, + class _Proj2 = identity, + indirect_strict_weak_order, projected<_Iter2, _Proj2>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + return __lexicographical_compare_impl(std::move(__first1), std::move(__last1), + std::move(__first2), std::move(__last2), + __comp, + __proj1, + __proj2); + } + + template , _Proj1>, + projected, _Proj2>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Range1&& __range1, _Range2&& __range2, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + return __lexicographical_compare_impl(ranges::begin(__range1), ranges::end(__range1), + ranges::begin(__range2), ranges::end(__range2), + __comp, + __proj1, + __proj2); + } + +}; +} // namespace __lexicographical_compare + +inline namespace __cpo { + inline constexpr auto lexicographical_compare = __lexicographical_compare::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_LEXICOGRAPHICAL_COMPARE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_lower_bound.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_lower_bound.h new file mode 100644 index 0000000..78cbb6d --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_lower_bound.h @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_LOWER_BOUND_H +#define _LIBCPP___ALGORITHM_RANGES_LOWER_BOUND_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/lower_bound.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/advance.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +namespace __lower_bound { +struct __fn { + template _Sent, class _Type, class _Proj = identity, + indirect_strict_weak_order> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { + return std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); + } + + template , _Proj>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __r, + const _Type& __value, + _Comp __comp = {}, + _Proj __proj = {}) const { + return std::__lower_bound_impl<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), __value, __comp, __proj); + } +}; +} // namespace __lower_bound + +inline namespace __cpo { + inline constexpr auto lower_bound = __lower_bound::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_LOWER_BOUND_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_make_heap.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_make_heap.h new file mode 100644 index 0000000..f25c7ab --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_make_heap.h @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_MAKE_HEAP_H +#define _LIBCPP___ALGORITHM_RANGES_MAKE_HEAP_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_heap.h> +#include <__algorithm/make_projected.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/projected.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __make_heap { + +struct __fn { + template + _LIBCPP_HIDE_FROM_ABI constexpr static + _Iter __make_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __last_iter = ranges::next(__first, __last); + + auto&& __projected_comp = std::__make_projected(__comp, __proj); + std::__make_heap<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp); + + return __last_iter; + } + + template _Sent, class _Comp = ranges::less, class _Proj = identity> + requires sortable<_Iter, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return __make_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj); + } + + template + requires sortable, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + return __make_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); + } +}; + +} // namespace __make_heap + +inline namespace __cpo { + inline constexpr auto make_heap = __make_heap::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_MAKE_HEAP_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_max.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_max.h new file mode 100644 index 0000000..55aef99 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_max.h @@ -0,0 +1,93 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_MAX_H +#define _LIBCPP___ALGORITHM_RANGES_MAX_H + +#include <__algorithm/ranges_min_element.h> +#include <__assert> +#include <__concepts/copyable.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __max { +struct __fn { + template > _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + const _Tp& operator()(const _Tp& __a, const _Tp& __b, _Comp __comp = {}, _Proj __proj = {}) const { + return std::invoke(__comp, std::invoke(__proj, __a), std::invoke(__proj, __b)) ? __b : __a; + } + + template > _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + _Tp operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_ASSERT(__il.begin() != __il.end(), "initializer_list must contain at least one element"); + + auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); }; + return *ranges::__min_element_impl(__il.begin(), __il.end(), __comp_lhs_rhs_swapped, __proj); + } + + template , _Proj>> _Comp = ranges::less> + requires indirectly_copyable_storable, range_value_t<_Rp>*> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + range_value_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + auto __first = ranges::begin(__r); + auto __last = ranges::end(__r); + + _LIBCPP_ASSERT(__first != __last, "range must contain at least one element"); + + if constexpr (forward_range<_Rp>) { + auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); }; + return *ranges::__min_element_impl(std::move(__first), std::move(__last), __comp_lhs_rhs_swapped, __proj); + } else { + range_value_t<_Rp> __result = *__first; + while (++__first != __last) { + if (std::invoke(__comp, std::invoke(__proj, __result), std::invoke(__proj, *__first))) + __result = *__first; + } + return __result; + } + } +}; +} // namespace __max + +inline namespace __cpo { + inline constexpr auto max = __max::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP_STD_VER > 17 && + +#endif // _LIBCPP___ALGORITHM_RANGES_MAX_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_max_element.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_max_element.h new file mode 100644 index 0000000..490f320 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_max_element.h @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_MAX_ELEMENT_H +#define _LIBCPP___ALGORITHM_RANGES_MAX_ELEMENT_H + +#include <__algorithm/ranges_min_element.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __max_element { +struct __fn { + template _Sp, class _Proj = identity, + indirect_strict_weak_order> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + _Ip operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { + auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); }; + return ranges::__min_element_impl(__first, __last, __comp_lhs_rhs_swapped, __proj); + } + + template , _Proj>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); }; + return ranges::__min_element_impl(ranges::begin(__r), ranges::end(__r), __comp_lhs_rhs_swapped, __proj); + } +}; +} // namespace __max_element + +inline namespace __cpo { + inline constexpr auto max_element = __max_element::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_MAX_ELEMENT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_merge.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_merge.h new file mode 100644 index 0000000..b36a05a --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_merge.h @@ -0,0 +1,142 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_MERGE_H +#define _LIBCPP___ALGORITHM_RANGES_MERGE_H + +#include <__algorithm/in_in_out_result.h> +#include <__algorithm/ranges_copy.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/mergeable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using merge_result = in_in_out_result<_InIter1, _InIter2, _OutIter>; + +namespace __merge { + +template < + class _InIter1, + class _Sent1, + class _InIter2, + class _Sent2, + class _OutIter, + class _Comp, + class _Proj1, + class _Proj2> +_LIBCPP_HIDE_FROM_ABI constexpr merge_result<__remove_cvref_t<_InIter1>, __remove_cvref_t<_InIter2>, __remove_cvref_t<_OutIter>> +__merge_impl( + _InIter1&& __first1, + _Sent1&& __last1, + _InIter2&& __first2, + _Sent2&& __last2, + _OutIter&& __result, + _Comp&& __comp, + _Proj1&& __proj1, + _Proj2&& __proj2) { + for (; __first1 != __last1 && __first2 != __last2; ++__result) { + if (std::invoke(__comp, std::invoke(__proj2, *__first2), std::invoke(__proj1, *__first1))) { + *__result = *__first2; + ++__first2; + } else { + *__result = *__first1; + ++__first1; + } + } + auto __ret1 = ranges::copy(std::move(__first1), std::move(__last1), std::move(__result)); + auto __ret2 = ranges::copy(std::move(__first2), std::move(__last2), std::move(__ret1.out)); + return {std::move(__ret1.in), std::move(__ret2.in), std::move(__ret2.out)}; +} + +struct __fn { + template < + input_iterator _InIter1, + sentinel_for<_InIter1> _Sent1, + input_iterator _InIter2, + sentinel_for<_InIter2> _Sent2, + weakly_incrementable _OutIter, + class _Comp = less, + class _Proj1 = identity, + class _Proj2 = identity> + requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2> + _LIBCPP_HIDE_FROM_ABI constexpr merge_result<_InIter1, _InIter2, _OutIter> operator()( + _InIter1 __first1, + _Sent1 __last1, + _InIter2 __first2, + _Sent2 __last2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + return __merge::__merge_impl(__first1, __last1, __first2, __last2, __result, __comp, __proj1, __proj2); + } + + template < + input_range _Range1, + input_range _Range2, + weakly_incrementable _OutIter, + class _Comp = less, + class _Proj1 = identity, + class _Proj2 = identity> + requires mergeable< + iterator_t<_Range1>, + iterator_t<_Range2>, + _OutIter, + _Comp, + _Proj1, + _Proj2> + _LIBCPP_HIDE_FROM_ABI constexpr merge_result, borrowed_iterator_t<_Range2>, _OutIter> + operator()( + _Range1&& __range1, + _Range2&& __range2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + return __merge::__merge_impl( + ranges::begin(__range1), + ranges::end(__range1), + ranges::begin(__range2), + ranges::end(__range2), + __result, + __comp, + __proj1, + __proj2); + } +}; + +} // namespace __merge + +inline namespace __cpo { + inline constexpr auto merge = __merge::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_MERGE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_min.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_min.h new file mode 100644 index 0000000..0e31f57 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_min.h @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_MIN_H +#define _LIBCPP___ALGORITHM_RANGES_MIN_H + +#include <__algorithm/ranges_min_element.h> +#include <__assert> +#include <__concepts/copyable.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __min { +struct __fn { + template > _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + const _Tp& operator()(const _Tp& __a, const _Tp& __b, _Comp __comp = {}, _Proj __proj = {}) const { + return std::invoke(__comp, std::invoke(__proj, __b), std::invoke(__proj, __a)) ? __b : __a; + } + + template > _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + _Tp operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_ASSERT(__il.begin() != __il.end(), "initializer_list must contain at least one element"); + return *ranges::__min_element_impl(__il.begin(), __il.end(), __comp, __proj); + } + + template , _Proj>> _Comp = ranges::less> + requires indirectly_copyable_storable, range_value_t<_Rp>*> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + range_value_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + auto __first = ranges::begin(__r); + auto __last = ranges::end(__r); + + _LIBCPP_ASSERT(__first != __last, "range must contain at least one element"); + + if constexpr (forward_range<_Rp>) { + return *ranges::__min_element_impl(__first, __last, __comp, __proj); + } else { + range_value_t<_Rp> __result = *__first; + while (++__first != __last) { + if (std::invoke(__comp, std::invoke(__proj, *__first), std::invoke(__proj, __result))) + __result = *__first; + } + return __result; + } + } +}; +} // namespace __min + +inline namespace __cpo { + inline constexpr auto min = __min::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP_STD_VER > 17 && + +#endif // _LIBCPP___ALGORITHM_RANGES_MIN_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_min_element.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_min_element.h new file mode 100644 index 0000000..1751874 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_min_element.h @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_MIN_ELEMENT_H +#define _LIBCPP___ALGORITHM_RANGES_MIN_ELEMENT_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +// TODO(ranges): `ranges::min_element` can now simply delegate to `std::__min_element`. +template +_LIBCPP_HIDE_FROM_ABI static constexpr +_Ip __min_element_impl(_Ip __first, _Sp __last, _Comp& __comp, _Proj& __proj) { + if (__first == __last) + return __first; + + _Ip __i = __first; + while (++__i != __last) + if (std::invoke(__comp, std::invoke(__proj, *__i), std::invoke(__proj, *__first))) + __first = __i; + return __first; +} + +namespace __min_element { +struct __fn { + template _Sp, class _Proj = identity, + indirect_strict_weak_order> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + _Ip operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { + return ranges::__min_element_impl(__first, __last, __comp, __proj); + } + + template , _Proj>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + return ranges::__min_element_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); + } +}; +} // namespace __min_element + +inline namespace __cpo { + inline constexpr auto min_element = __min_element::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_MIN_ELEMENT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_minmax.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_minmax.h new file mode 100644 index 0000000..f82e005 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_minmax.h @@ -0,0 +1,134 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_MINMAX_H +#define _LIBCPP___ALGORITHM_RANGES_MINMAX_H + +#include <__algorithm/min_max_result.h> +#include <__algorithm/minmax_element.h> +#include <__assert> +#include <__concepts/copyable.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/pair.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +template +using minmax_result = min_max_result<_T1>; + +namespace __minmax { +struct __fn { + template > _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result + operator()(const _Type& __a, const _Type& __b, _Comp __comp = {}, _Proj __proj = {}) const { + if (std::invoke(__comp, std::invoke(__proj, __b), std::invoke(__proj, __a))) + return {__b, __a}; + return {__a, __b}; + } + + template > _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + ranges::minmax_result<_Type> operator()(initializer_list<_Type> __il, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_ASSERT(__il.begin() != __il.end(), "initializer_list has to contain at least one element"); + auto __iters = std::__minmax_element_impl(__il.begin(), __il.end(), __comp, __proj); + return ranges::minmax_result<_Type> { *__iters.first, *__iters.second }; + } + + template , _Proj>> _Comp = ranges::less> + requires indirectly_copyable_storable, range_value_t<_Range>*> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + ranges::minmax_result> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + auto __first = ranges::begin(__r); + auto __last = ranges::end(__r); + using _ValueT = range_value_t<_Range>; + + _LIBCPP_ASSERT(__first != __last, "range has to contain at least one element"); + + if constexpr (forward_range<_Range>) { + auto __result = std::__minmax_element_impl(__first, __last, __comp, __proj); + return {*__result.first, *__result.second}; + } else { + // input_iterators can't be copied, so the implementation for input_iterators has to store + // the values instead of a pointer to the correct values + auto __less = [&](auto&& __a, auto&& __b) -> bool { + return std::invoke(__comp, std::invoke(__proj, std::forward(__a)), + std::invoke(__proj, std::forward(__b))); + }; + + ranges::minmax_result<_ValueT> __result = {*__first, __result.min}; + if (__first == __last || ++__first == __last) + return __result; + + if (__less(*__first, __result.min)) + __result.min = *__first; + else + __result.max = *__first; + + while (++__first != __last) { + _ValueT __i = *__first; + if (++__first == __last) { + if (__less(__i, __result.min)) + __result.min = __i; + else if (!__less(__i, __result.max)) + __result.max = __i; + return __result; + } + + if (__less(*__first, __i)) { + if (__less(*__first, __result.min)) + __result.min = *__first; + if (!__less(__i, __result.max)) + __result.max = std::move(__i); + } else { + if (__less(__i, __result.min)) + __result.min = std::move(__i); + if (!__less(*__first, __result.max)) + __result.max = *__first; + } + } + return __result; + } + } +}; +} // namespace __minmax + +inline namespace __cpo { + inline constexpr auto minmax = __minmax::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_MINMAX_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_minmax_element.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_minmax_element.h new file mode 100644 index 0000000..6699f96 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_minmax_element.h @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_MINMAX_ELEMENT_H +#define _LIBCPP___ALGORITHM_RANGES_MINMAX_ELEMENT_H + +#include <__algorithm/min_max_result.h> +#include <__algorithm/minmax_element.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/pair.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using minmax_element_result = min_max_result<_T1>; + +namespace __minmax_element { +struct __fn { + template _Sp, class _Proj = identity, + indirect_strict_weak_order> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + ranges::minmax_element_result<_Ip> operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = std::__minmax_element_impl(std::move(__first), std::move(__last), __comp, __proj); + return {__ret.first, __ret.second}; + } + + template , _Proj>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + ranges::minmax_element_result> + operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = std::__minmax_element_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); + return {__ret.first, __ret.second}; + } +}; +} // namespace __minmax_element + +inline namespace __cpo { + inline constexpr auto minmax_element = __minmax_element::__fn{}; +} // namespace __cpo + +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_MINMAX_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_mismatch.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_mismatch.h new file mode 100644 index 0000000..4fd0517 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_mismatch.h @@ -0,0 +1,85 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_MISMATCH_H +#define _LIBCPP___ALGORITHM_RANGES_MISMATCH_H + +#include <__algorithm/in_in_result.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/indirectly_comparable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace ranges { + +template +using mismatch_result = in_in_result<_I1, _I2>; + +namespace __mismatch { +struct __fn { + template + static _LIBCPP_HIDE_FROM_ABI constexpr + mismatch_result<_I1, _I2> + __go(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2, + _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) { + while (__first1 != __last1 && __first2 != __last2) { + if (!std::invoke(__pred, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2))) + break; + ++__first1; + ++__first2; + } + return {std::move(__first1), std::move(__first2)}; + } + + template _S1, + input_iterator _I2, sentinel_for<_I2> _S2, + class _Pred = ranges::equal_to, class _Proj1 = identity, class _Proj2 = identity> + requires indirectly_comparable<_I1, _I2, _Pred, _Proj1, _Proj2> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + mismatch_result<_I1, _I2> operator()(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2, + _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + return __go(std::move(__first1), __last1, std::move(__first2), __last2, __pred, __proj1, __proj2); + } + + template + requires indirectly_comparable, iterator_t<_R2>, _Pred, _Proj1, _Proj2> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + mismatch_result, borrowed_iterator_t<_R2>> + operator()(_R1&& __r1, _R2&& __r2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + return __go(ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2), + __pred, __proj1, __proj2); + } +}; +} // namespace __mismatch + +inline namespace __cpo { + constexpr inline auto mismatch = __mismatch::__fn{}; +} // namespace __cpo +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_RANGES_MISMATCH_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_move.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_move.h new file mode 100644 index 0000000..46a0970 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_move.h @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_MOVE_H +#define _LIBCPP___ALGORITHM_RANGES_MOVE_H + +#include <__algorithm/in_out_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/move.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using move_result = in_out_result<_InIter, _OutIter>; + +namespace __move { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + move_result<_InIter, _OutIter> __move_impl(_InIter __first, _Sent __last, _OutIter __result) { + auto __ret = std::__move<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)); + return {std::move(__ret.first), std::move(__ret.second)}; + } + + template _Sent, weakly_incrementable _OutIter> + requires indirectly_movable<_InIter, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + move_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const { + return __move_impl(std::move(__first), std::move(__last), std::move(__result)); + } + + template + requires indirectly_movable, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + move_result, _OutIter> operator()(_Range&& __range, _OutIter __result) const { + return __move_impl(ranges::begin(__range), ranges::end(__range), std::move(__result)); + } + +}; +} // namespace __move + +inline namespace __cpo { + inline constexpr auto move = __move::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_MOVE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_move_backward.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_move_backward.h new file mode 100644 index 0000000..d4e8eb1 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_move_backward.h @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_MOVE_BACKWARD_H +#define _LIBCPP___ALGORITHM_RANGES_MOVE_BACKWARD_H + +#include <__algorithm/in_out_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/move_backward.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/iter_move.h> +#include <__iterator/next.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using move_backward_result = in_out_result<_InIter, _OutIter>; + +namespace __move_backward { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + move_backward_result<_InIter, _OutIter> __move_backward_impl(_InIter __first, _Sent __last, _OutIter __result) { + auto __ret = std::__move_backward<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)); + return {std::move(__ret.first), std::move(__ret.second)}; + } + + template _Sent, bidirectional_iterator _OutIter> + requires indirectly_movable<_InIter, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + move_backward_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const { + return __move_backward_impl(std::move(__first), std::move(__last), std::move(__result)); + } + + template + requires indirectly_movable, _Iter> + _LIBCPP_HIDE_FROM_ABI constexpr + move_backward_result, _Iter> operator()(_Range&& __range, _Iter __result) const { + return __move_backward_impl(ranges::begin(__range), ranges::end(__range), std::move(__result)); + } + +}; +} // namespace __move_backward + +inline namespace __cpo { + inline constexpr auto move_backward = __move_backward::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_MOVE_BACKWARD_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_next_permutation.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_next_permutation.h new file mode 100644 index 0000000..6c8e8e1 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_next_permutation.h @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_NEXT_PERMUTATION_H +#define _LIBCPP___ALGORITHM_RANGES_NEXT_PERMUTATION_H + +#include <__algorithm/in_found_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/next_permutation.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using next_permutation_result = in_found_result<_InIter>; + +namespace __next_permutation { + +struct __fn { + template _Sent, class _Comp = ranges::less, class _Proj = identity> + requires sortable<_Iter, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr next_permutation_result<_Iter> + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + auto __result = std::__next_permutation<_RangeAlgPolicy>( + std::move(__first), std::move(__last), std::__make_projected(__comp, __proj)); + return {std::move(__result.first), std::move(__result.second)}; + } + + template + requires sortable, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr next_permutation_result> + operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { + auto __result = std::__next_permutation<_RangeAlgPolicy>( + ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj)); + return {std::move(__result.first), std::move(__result.second)}; + } +}; + +} // namespace __next_permutation + +inline namespace __cpo { +constexpr inline auto next_permutation = __next_permutation::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_NEXT_PERMUTATION_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_none_of.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_none_of.h new file mode 100644 index 0000000..b39e570 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_none_of.h @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_NONE_OF_H +#define _LIBCPP___ALGORITHM_RANGES_NONE_OF_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __none_of { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + bool __none_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { + for (; __first != __last; ++__first) { + if (std::invoke(__pred, std::invoke(__proj, *__first))) + return false; + } + return true; + } + + template _Sent, class _Proj = identity, + indirect_unary_predicate> _Pred> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { + return __none_of_impl(std::move(__first), std::move(__last), __pred, __proj); + } + + template , _Proj>> _Pred> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { + return __none_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); + } +}; +} // namespace __none_of + +inline namespace __cpo { + inline constexpr auto none_of = __none_of::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_NONE_OF_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_nth_element.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_nth_element.h new file mode 100644 index 0000000..d9ec4f1 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_nth_element.h @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_NTH_ELEMENT_H +#define _LIBCPP___ALGORITHM_RANGES_NTH_ELEMENT_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/nth_element.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/projected.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __nth_element { + +struct __fn { + template + _LIBCPP_HIDE_FROM_ABI constexpr static + _Iter __nth_element_fn_impl(_Iter __first, _Iter __nth, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __last_iter = ranges::next(__first, __last); + + auto&& __projected_comp = std::__make_projected(__comp, __proj); + std::__nth_element_impl<_RangeAlgPolicy>(std::move(__first), std::move(__nth), __last_iter, __projected_comp); + + return __last_iter; + } + + template _Sent, class _Comp = ranges::less, class _Proj = identity> + requires sortable<_Iter, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Iter __nth, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return __nth_element_fn_impl(std::move(__first), std::move(__nth), std::move(__last), __comp, __proj); + } + + template + requires sortable, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __r, iterator_t<_Range> __nth, _Comp __comp = {}, + _Proj __proj = {}) const { + return __nth_element_fn_impl(ranges::begin(__r), std::move(__nth), ranges::end(__r), __comp, __proj); + } +}; + +} // namespace __nth_element + +inline namespace __cpo { + inline constexpr auto nth_element = __nth_element::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_NTH_ELEMENT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_partial_sort.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_partial_sort.h new file mode 100644 index 0000000..3ea0a7f --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_partial_sort.h @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_H +#define _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/partial_sort.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/projected.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __partial_sort { + +struct __fn { + template + _LIBCPP_HIDE_FROM_ABI constexpr static + _Iter __partial_sort_fn_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto&& __projected_comp = std::__make_projected(__comp, __proj); + return std::__partial_sort<_RangeAlgPolicy>(std::move(__first), std::move(__middle), __last, __projected_comp); + } + + template _Sent, class _Comp = ranges::less, class _Proj = identity> + requires sortable<_Iter, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return __partial_sort_fn_impl(std::move(__first), std::move(__middle), std::move(__last), __comp, __proj); + } + + template + requires sortable, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __r, iterator_t<_Range> __middle, _Comp __comp = {}, + _Proj __proj = {}) const { + return __partial_sort_fn_impl(ranges::begin(__r), std::move(__middle), ranges::end(__r), __comp, __proj); + } +}; + +} // namespace __partial_sort + +inline namespace __cpo { + inline constexpr auto partial_sort = __partial_sort::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_partial_sort_copy.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_partial_sort_copy.h new file mode 100644 index 0000000..212db55 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_partial_sort_copy.h @@ -0,0 +1,92 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_COPY_H +#define _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_COPY_H + +#include <__algorithm/in_out_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/partial_sort_copy.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/projected.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using partial_sort_copy_result = in_out_result<_InIter, _OutIter>; + +namespace __partial_sort_copy { + +struct __fn { + + template _Sent1, + random_access_iterator _Iter2, sentinel_for<_Iter2> _Sent2, + class _Comp = ranges::less, class _Proj1 = identity, class _Proj2 = identity> + requires indirectly_copyable<_Iter1, _Iter2> && sortable<_Iter2, _Comp, _Proj2> && + indirect_strict_weak_order<_Comp, projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>> + _LIBCPP_HIDE_FROM_ABI constexpr + partial_sort_copy_result<_Iter1, _Iter2> + operator()(_Iter1 __first, _Sent1 __last, _Iter2 __result_first, _Sent2 __result_last, + _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + auto __result = std::__partial_sort_copy<_RangeAlgPolicy>( + std::move(__first), std::move(__last), std::move(__result_first), std::move(__result_last), + __comp, __proj1, __proj2 + ); + return {std::move(__result.first), std::move(__result.second)}; + } + + template + requires indirectly_copyable, iterator_t<_Range2>> && + sortable, _Comp, _Proj2> && + indirect_strict_weak_order<_Comp, projected, _Proj1>, + projected, _Proj2>> + _LIBCPP_HIDE_FROM_ABI constexpr + partial_sort_copy_result, borrowed_iterator_t<_Range2>> + operator()(_Range1&& __range, _Range2&& __result_range, _Comp __comp = {}, + _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + auto __result = std::__partial_sort_copy<_RangeAlgPolicy>( + ranges::begin(__range), ranges::end(__range), ranges::begin(__result_range), ranges::end(__result_range), + __comp, __proj1, __proj2 + ); + return {std::move(__result.first), std::move(__result.second)}; + } + +}; + +} // namespace __partial_sort_copy + +inline namespace __cpo { + inline constexpr auto partial_sort_copy = __partial_sort_copy::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_COPY_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_partition.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_partition.h new file mode 100644 index 0000000..8b3aae5 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_partition.h @@ -0,0 +1,83 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_PARTITION_H +#define _LIBCPP___ALGORITHM_RANGES_PARTITION_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/partition.h> +#include <__algorithm/ranges_iterator_concept.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/permutable.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/subrange.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/pair.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __partition { + +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI static constexpr + subrange<__remove_cvref_t<_Iter>> __partition_fn_impl(_Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) { + auto&& __projected_pred = std::__make_projected(__pred, __proj); + auto __result = std::__partition<_RangeAlgPolicy>( + std::move(__first), std::move(__last), __projected_pred, __iterator_concept<_Iter>()); + + return {std::move(__result.first), std::move(__result.second)}; + } + + template _Sent, class _Proj = identity, + indirect_unary_predicate> _Pred> + _LIBCPP_HIDE_FROM_ABI constexpr + subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { + return __partition_fn_impl(__first, __last, __pred, __proj); + } + + template , _Proj>> _Pred> + requires permutable> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_subrange_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { + return __partition_fn_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); + } + +}; + +} // namespace __partition + +inline namespace __cpo { + inline constexpr auto partition = __partition::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_partition_copy.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_partition_copy.h new file mode 100644 index 0000000..e7a9a34 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_partition_copy.h @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_PARTITION_COPY_H +#define _LIBCPP___ALGORITHM_RANGES_PARTITION_COPY_H + +#include <__algorithm/in_out_out_result.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using partition_copy_result = in_out_out_result<_InIter, _OutIter1, _OutIter2>; + +namespace __partition_copy { + +struct __fn { + + // TODO(ranges): delegate to the classic algorithm. + template + _LIBCPP_HIDE_FROM_ABI constexpr + static partition_copy_result< + __remove_cvref_t<_InIter>, __remove_cvref_t<_OutIter1>, __remove_cvref_t<_OutIter2> + > __partition_copy_fn_impl( _InIter&& __first, _Sent&& __last, _OutIter1&& __out_true, _OutIter2&& __out_false, + _Pred& __pred, _Proj& __proj) { + for (; __first != __last; ++__first) { + if (std::invoke(__pred, std::invoke(__proj, *__first))) { + *__out_true = *__first; + ++__out_true; + + } else { + *__out_false = *__first; + ++__out_false; + } + } + + return {std::move(__first), std::move(__out_true), std::move(__out_false)}; + } + + template _Sent, + weakly_incrementable _OutIter1, weakly_incrementable _OutIter2, + class _Proj = identity, indirect_unary_predicate> _Pred> + requires indirectly_copyable<_InIter, _OutIter1> && indirectly_copyable<_InIter, _OutIter2> + _LIBCPP_HIDE_FROM_ABI constexpr + partition_copy_result<_InIter, _OutIter1, _OutIter2> + operator()(_InIter __first, _Sent __last, _OutIter1 __out_true, _OutIter2 __out_false, + _Pred __pred, _Proj __proj = {}) const { + return __partition_copy_fn_impl( + std::move(__first), std::move(__last), std::move(__out_true), std::move(__out_false), __pred, __proj); + } + + template , _Proj>> _Pred> + requires indirectly_copyable, _OutIter1> && indirectly_copyable, _OutIter2> + _LIBCPP_HIDE_FROM_ABI constexpr + partition_copy_result, _OutIter1, _OutIter2> + operator()(_Range&& __range, _OutIter1 __out_true, _OutIter2 __out_false, _Pred __pred, _Proj __proj = {}) const { + return __partition_copy_fn_impl( + ranges::begin(__range), ranges::end(__range), std::move(__out_true), std::move(__out_false), __pred, __proj); + } + +}; + +} // namespace __partition_copy + +inline namespace __cpo { + inline constexpr auto partition_copy = __partition_copy::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_COPY_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_partition_point.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_partition_point.h new file mode 100644 index 0000000..2bd118d --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_partition_point.h @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_PARTITION_POINT_H +#define _LIBCPP___ALGORITHM_RANGES_PARTITION_POINT_H + +#include <__algorithm/half_positive.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/distance.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __partition_point { + +struct __fn { + + // TODO(ranges): delegate to the classic algorithm. + template + _LIBCPP_HIDE_FROM_ABI constexpr + static _Iter __partition_point_fn_impl(_Iter&& __first, _Sent&& __last, _Pred& __pred, _Proj& __proj) { + auto __len = ranges::distance(__first, __last); + + while (__len != 0) { + auto __half_len = std::__half_positive(__len); + auto __mid = ranges::next(__first, __half_len); + + if (std::invoke(__pred, std::invoke(__proj, *__mid))) { + __first = ++__mid; + __len -= __half_len + 1; + + } else { + __len = __half_len; + } + } + + return __first; + } + + template _Sent, class _Proj = identity, + indirect_unary_predicate> _Pred> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { + return __partition_point_fn_impl(std::move(__first), std::move(__last), __pred, __proj); + } + + template , _Proj>> _Pred> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { + return __partition_point_fn_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); + } + +}; + +} // namespace __partition_point + +inline namespace __cpo { + inline constexpr auto partition_point = __partition_point::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_POINT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_pop_heap.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_pop_heap.h new file mode 100644 index 0000000..65beec8 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_pop_heap.h @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_POP_HEAP_H +#define _LIBCPP___ALGORITHM_RANGES_POP_HEAP_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/pop_heap.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/projected.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __pop_heap { + +struct __fn { + template + _LIBCPP_HIDE_FROM_ABI constexpr static + _Iter __pop_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __last_iter = ranges::next(__first, __last); + auto __len = __last_iter - __first; + + auto&& __projected_comp = std::__make_projected(__comp, __proj); + std::__pop_heap<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp, __len); + + return __last_iter; + } + + template _Sent, class _Comp = ranges::less, class _Proj = identity> + requires sortable<_Iter, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return __pop_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj); + } + + template + requires sortable, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + return __pop_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); + } +}; + +} // namespace __pop_heap + +inline namespace __cpo { + inline constexpr auto pop_heap = __pop_heap::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_POP_HEAP_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_prev_permutation.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_prev_permutation.h new file mode 100644 index 0000000..6866d90 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_prev_permutation.h @@ -0,0 +1,77 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_PREV_PERMUTATION_H +#define _LIBCPP___ALGORITHM_RANGES_PREV_PERMUTATION_H + +#include <__algorithm/in_found_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/prev_permutation.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using prev_permutation_result = in_found_result<_InIter>; + +namespace __prev_permutation { + +struct __fn { + + template _Sent, + class _Comp = ranges::less, class _Proj = identity> + requires sortable<_Iter, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr prev_permutation_result<_Iter> + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + auto __result = std::__prev_permutation<_RangeAlgPolicy>( + std::move(__first), std::move(__last), std::__make_projected(__comp, __proj)); + return {std::move(__result.first), std::move(__result.second)}; + } + + template + requires sortable, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr prev_permutation_result> + operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { + auto __result = std::__prev_permutation<_RangeAlgPolicy>( + ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj)); + return {std::move(__result.first), std::move(__result.second)}; + } + +}; + +} // namespace __prev_permutation + +inline namespace __cpo { +constexpr inline auto prev_permutation = __prev_permutation::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_PREV_PERMUTATION_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_push_heap.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_push_heap.h new file mode 100644 index 0000000..a1f4347 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_push_heap.h @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_PUSH_HEAP_H +#define _LIBCPP___ALGORITHM_RANGES_PUSH_HEAP_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/push_heap.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/projected.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __push_heap { + +struct __fn { + template + _LIBCPP_HIDE_FROM_ABI constexpr static + _Iter __push_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __last_iter = ranges::next(__first, __last); + + auto&& __projected_comp = std::__make_projected(__comp, __proj); + std::__push_heap<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp); + + return __last_iter; + } + + template _Sent, class _Comp = ranges::less, class _Proj = identity> + requires sortable<_Iter, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return __push_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj); + } + + template + requires sortable, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + return __push_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); + } +}; + +} // namespace __push_heap + +inline namespace __cpo { + inline constexpr auto push_heap = __push_heap::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_PUSH_HEAP_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_remove.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_remove.h new file mode 100644 index 0000000..dd5c5fb --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_remove.h @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_REMOVE_H +#define _LIBCPP___ALGORITHM_RANGES_REMOVE_H +#include <__config> + +#include <__algorithm/ranges_remove_if.h> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/permutable.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/subrange.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __remove { +struct __fn { + + template _Sent, class _Type, class _Proj = identity> + requires indirect_binary_predicate, const _Type*> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + subrange<_Iter> operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const { + auto __pred = [&](auto&& __other) { return __value == __other; }; + return ranges::__remove_if_impl(std::move(__first), std::move(__last), __pred, __proj); + } + + template + requires permutable> + && indirect_binary_predicate, _Proj>, const _Type*> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_subrange_t<_Range> operator()(_Range&& __range, const _Type& __value, _Proj __proj = {}) const { + auto __pred = [&](auto&& __other) { return __value == __other; }; + return ranges::__remove_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); + } +}; +} // namespace __remove + +inline namespace __cpo { + inline constexpr auto remove = __remove::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_remove_copy.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_remove_copy.h new file mode 100644 index 0000000..2102228 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_remove_copy.h @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_H +#define _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_H + +#include <__algorithm/in_out_result.h> +#include <__algorithm/ranges_remove_copy_if.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using remove_copy_result = in_out_result<_InIter, _OutIter>; + +namespace __remove_copy { + + struct __fn { + template _Sent, + weakly_incrementable _OutIter, + class _Type, + class _Proj = identity> + requires indirectly_copyable<_InIter, _OutIter> && + indirect_binary_predicate, const _Type*> + _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_result<_InIter, _OutIter> + operator()(_InIter __first, _Sent __last, _OutIter __result, const _Type& __value, _Proj __proj = {}) const { + auto __pred = [&](auto&& __val) { return __value == __val; }; + return ranges::__remove_copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj); + } + + template + requires indirectly_copyable, _OutIter> && + indirect_binary_predicate, _Proj>, const _Type*> + _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_result, _OutIter> + operator()(_Range&& __range, _OutIter __result, const _Type& __value, _Proj __proj = {}) const { + auto __pred = [&](auto&& __val) { return __value == __val; }; + return ranges::__remove_copy_if_impl( + ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __proj); + } + }; + +} // namespace __remove_copy + +inline namespace __cpo { + inline constexpr auto remove_copy = __remove_copy::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_remove_copy_if.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_remove_copy_if.h new file mode 100644 index 0000000..4fc6745 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_remove_copy_if.h @@ -0,0 +1,90 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_IF_H +#define _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_IF_H + +#include <__algorithm/in_out_result.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/remove_copy_if.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using remove_copy_if_result = in_out_result<_InIter, _OutIter>; + +template +_LIBCPP_HIDE_FROM_ABI constexpr in_out_result<_InIter, _OutIter> +__remove_copy_if_impl(_InIter __first, _Sent __last, _OutIter __result, _Pred& __pred, _Proj& __proj) { + for (; __first != __last; ++__first) { + if (!std::invoke(__pred, std::invoke(__proj, *__first))) { + *__result = *__first; + ++__result; + } + } + return {std::move(__first), std::move(__result)}; +} + +namespace __remove_copy_if { + + struct __fn { + template _Sent, + weakly_incrementable _OutIter, + class _Proj = identity, + indirect_unary_predicate> _Pred> + requires indirectly_copyable<_InIter, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_if_result<_InIter, _OutIter> + operator()(_InIter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const { + return ranges::__remove_copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj); + } + + template , _Proj>> _Pred> + requires indirectly_copyable, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_if_result, _OutIter> + operator()(_Range&& __range, _OutIter __result, _Pred __pred, _Proj __proj = {}) const { + return ranges::__remove_copy_if_impl( + ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __proj); + } + }; + +} // namespace __remove_copy_if + +inline namespace __cpo { + inline constexpr auto remove_copy_if = __remove_copy_if::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_IF_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_remove_if.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_remove_if.h new file mode 100644 index 0000000..1f17467 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_remove_if.h @@ -0,0 +1,85 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_REMOVE_IF_H +#define _LIBCPP___ALGORITHM_RANGES_REMOVE_IF_H +#include <__config> + +#include <__algorithm/ranges_find_if.h> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iter_move.h> +#include <__iterator/permutable.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/subrange.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +_LIBCPP_HIDE_FROM_ABI constexpr +subrange<_Iter> __remove_if_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { + auto __new_end = ranges::__find_if_impl(__first, __last, __pred, __proj); + if (__new_end == __last) + return {__new_end, __new_end}; + + _Iter __i = __new_end; + while (++__i != __last) { + if (!std::invoke(__pred, std::invoke(__proj, *__i))) { + *__new_end = ranges::iter_move(__i); + ++__new_end; + } + } + return {__new_end, __i}; +} + +namespace __remove_if { +struct __fn { + + template _Sent, + class _Proj = identity, + indirect_unary_predicate> _Pred> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { + return ranges::__remove_if_impl(std::move(__first), std::move(__last), __pred, __proj); + } + + template , _Proj>> _Pred> + requires permutable> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_subrange_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { + return ranges::__remove_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); + } + +}; +} // namespace __remove_if + +inline namespace __cpo { + inline constexpr auto remove_if = __remove_if::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_IF_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_replace.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_replace.h new file mode 100644 index 0000000..8b12bea --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_replace.h @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_REPLACE_H +#define _LIBCPP___ALGORITHM_RANGES_REPLACE_H + +#include <__algorithm/ranges_replace_if.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __replace { +struct __fn { + + template _Sent, + class _Type1, + class _Type2, + class _Proj = identity> + requires indirectly_writable<_Iter, const _Type2&> + && indirect_binary_predicate, const _Type1*> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, + const _Type1& __old_value, + const _Type2& __new_value, + _Proj __proj = {}) const { + auto __pred = [&](const auto& __val) { return __val == __old_value; }; + return ranges::__replace_if_impl(std::move(__first), std::move(__last), __pred, __new_value, __proj); + } + + template + requires indirectly_writable, const _Type2&> + && indirect_binary_predicate, _Proj>, const _Type1*> + _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + operator()(_Range&& __range, const _Type1& __old_value, const _Type2& __new_value, _Proj __proj = {}) const { + auto __pred = [&](auto&& __val) { return __val == __old_value; }; + return ranges::__replace_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __new_value, __proj); + } + +}; +} // namespace __replace + +inline namespace __cpo { + inline constexpr auto replace = __replace::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_replace_copy.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_replace_copy.h new file mode 100644 index 0000000..f87a236 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_replace_copy.h @@ -0,0 +1,91 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_H +#define _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_H + +#include <__algorithm/in_out_result.h> +#include <__algorithm/ranges_replace_copy_if.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using replace_copy_result = in_out_result<_InIter, _OutIter>; + +namespace __replace_copy { + + struct __fn { + template _Sent, + class _OldType, + class _NewType, + output_iterator _OutIter, + class _Proj = identity> + requires indirectly_copyable<_InIter, _OutIter> && + indirect_binary_predicate, const _OldType*> + _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_result<_InIter, _OutIter> + operator()(_InIter __first, + _Sent __last, + _OutIter __result, + const _OldType& __old_value, + const _NewType& __new_value, + _Proj __proj = {}) const { + auto __pred = [&](const auto& __value) { return __value == __old_value; }; + return ranges::__replace_copy_if_impl( + std::move(__first), std::move(__last), std::move(__result), __pred, __new_value, __proj); + } + + template _OutIter, + class _Proj = identity> + requires indirectly_copyable, _OutIter> && + indirect_binary_predicate, _Proj>, const _OldType*> + _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_result, _OutIter> + operator()(_Range&& __range, + _OutIter __result, + const _OldType& __old_value, + const _NewType& __new_value, + _Proj __proj = {}) const { + auto __pred = [&](const auto& __value) { return __value == __old_value; }; + return ranges::__replace_copy_if_impl( + ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __new_value, __proj); + } + }; + +} // namespace __replace_copy + +inline namespace __cpo { + inline constexpr auto replace_copy = __replace_copy::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_replace_copy_if.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_replace_copy_if.h new file mode 100644 index 0000000..b8741ec --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_replace_copy_if.h @@ -0,0 +1,93 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_IF_H +#define _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_IF_H + +#include <__algorithm/in_out_result.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using replace_copy_if_result = in_out_result<_InIter, _OutIter>; + +template +_LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<_InIter, _OutIter> __replace_copy_if_impl( + _InIter __first, _Sent __last, _OutIter __result, _Pred& __pred, const _Type& __new_value, _Proj& __proj) { + while (__first != __last) { + if (std::invoke(__pred, std::invoke(__proj, *__first))) + *__result = __new_value; + else + *__result = *__first; + + ++__first; + ++__result; + } + + return {std::move(__first), std::move(__result)}; +} + +namespace __replace_copy_if { + + struct __fn { + template _Sent, + class _Type, + output_iterator _OutIter, + class _Proj = identity, + indirect_unary_predicate> _Pred> + requires indirectly_copyable<_InIter, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<_InIter, _OutIter> operator()( + _InIter __first, _Sent __last, _OutIter __result, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) + const { + return ranges::__replace_copy_if_impl( + std::move(__first), std::move(__last), std::move(__result), __pred, __new_value, __proj); + } + + template _OutIter, + class _Proj = identity, + indirect_unary_predicate, _Proj>> _Pred> + requires indirectly_copyable, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result, _OutIter> + operator()(_Range&& __range, _OutIter __result, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const { + return ranges::__replace_copy_if_impl( + ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __new_value, __proj); + } + }; + +} // namespace __replace_copy_if + +inline namespace __cpo { + inline constexpr auto replace_copy_if = __replace_copy_if::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_IF_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_replace_if.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_replace_if.h new file mode 100644 index 0000000..65be3c7 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_replace_if.h @@ -0,0 +1,77 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_REPLACE_IF_H +#define _LIBCPP___ALGORITHM_RANGES_REPLACE_IF_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +_LIBCPP_HIDE_FROM_ABI constexpr +_Iter __replace_if_impl(_Iter __first, _Sent __last, _Pred& __pred, const _Type& __new_value, _Proj& __proj) { + for (; __first != __last; ++__first) { + if (std::invoke(__pred, std::invoke(__proj, *__first))) + *__first = __new_value; + } + return __first; +} + +namespace __replace_if { +struct __fn { + + template _Sent, + class _Type, + class _Proj = identity, + indirect_unary_predicate> _Pred> + requires indirectly_writable<_Iter, const _Type&> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const { + return ranges::__replace_if_impl(std::move(__first), std::move(__last), __pred, __new_value, __proj); + } + + template , _Proj>> _Pred> + requires indirectly_writable, const _Type&> + _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + operator()(_Range&& __range, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const { + return ranges::__replace_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __new_value, __proj); + } + +}; +} // namespace __replace_if + +inline namespace __cpo { + inline constexpr auto replace_if = __replace_if::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_IF_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_reverse.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_reverse.h new file mode 100644 index 0000000..e2a5d9a --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_reverse.h @@ -0,0 +1,83 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_REVERSE_H +#define _LIBCPP___ALGORITHM_RANGES_REVERSE_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/iter_swap.h> +#include <__iterator/next.h> +#include <__iterator/permutable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __reverse { +struct __fn { + + template _Sent> + requires permutable<_Iter> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last) const { + if constexpr (random_access_iterator<_Iter>) { + if (__first == __last) + return __first; + + auto __end = ranges::next(__first, __last); + auto __ret = __end; + + while (__first < --__end) { + ranges::iter_swap(__first, __end); + ++__first; + } + return __ret; + } else { + auto __end = ranges::next(__first, __last); + auto __ret = __end; + + while (__first != __end) { + if (__first == --__end) + break; + + ranges::iter_swap(__first, __end); + ++__first; + } + return __ret; + } + } + + template + requires permutable> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __range) const { + return (*this)(ranges::begin(__range), ranges::end(__range)); + } + +}; +} // namespace __reverse + +inline namespace __cpo { + inline constexpr auto reverse = __reverse::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_REVERSE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_reverse_copy.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_reverse_copy.h new file mode 100644 index 0000000..a84b1ad --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_reverse_copy.h @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_REVERSE_COPY_H +#define _LIBCPP___ALGORITHM_RANGES_REVERSE_COPY_H + +#include <__algorithm/in_out_result.h> +#include <__algorithm/ranges_copy.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/next.h> +#include <__iterator/reverse_iterator.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__ranges/subrange.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using reverse_copy_result = in_out_result<_InIter, _OutIter>; + +namespace __reverse_copy { +struct __fn { + + template _Sent, weakly_incrementable _OutIter> + requires indirectly_copyable<_InIter, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + reverse_copy_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const { + return (*this)(subrange(std::move(__first), std::move(__last)), std::move(__result)); + } + + template + requires indirectly_copyable, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + reverse_copy_result, _OutIter> operator()(_Range&& __range, _OutIter __result) const { + auto __ret = ranges::copy(std::__reverse_range(__range), std::move(__result)); + return {ranges::next(ranges::begin(__range), ranges::end(__range)), std::move(__ret.out)}; + } + +}; +} // namespace __reverse_copy + +inline namespace __cpo { + inline constexpr auto reverse_copy = __reverse_copy::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_REVERSE_COPY_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_rotate.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_rotate.h new file mode 100644 index 0000000..91ed402 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_rotate.h @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_ROTATE_H +#define _LIBCPP___ALGORITHM_RANGES_ROTATE_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/ranges_iterator_concept.h> +#include <__algorithm/rotate.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/permutable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/subrange.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __rotate { + +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr + static subrange<_Iter> __rotate_fn_impl(_Iter __first, _Iter __middle, _Sent __last) { + auto __ret = std::__rotate<_RangeAlgPolicy>( + std::move(__first), std::move(__middle), std::move(__last)); + return {std::move(__ret.first), std::move(__ret.second)}; + } + + template _Sent> + _LIBCPP_HIDE_FROM_ABI constexpr + subrange<_Iter> operator()(_Iter __first, _Iter __middle, _Sent __last) const { + return __rotate_fn_impl(std::move(__first), std::move(__middle), std::move(__last)); + } + + template + requires permutable> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_subrange_t<_Range> operator()(_Range&& __range, iterator_t<_Range> __middle) const { + return __rotate_fn_impl(ranges::begin(__range), std::move(__middle), ranges::end(__range)); + } + +}; + +} // namespace __rotate + +inline namespace __cpo { + inline constexpr auto rotate = __rotate::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_ROTATE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_rotate_copy.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_rotate_copy.h new file mode 100644 index 0000000..52f403c --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_rotate_copy.h @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_ROTATE_COPY_H +#define _LIBCPP___ALGORITHM_RANGES_ROTATE_COPY_H + +#include <__algorithm/in_out_result.h> +#include <__algorithm/ranges_copy.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/reverse_iterator.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using rotate_copy_result = in_out_result<_InIter, _OutIter>; + +namespace __rotate_copy { +struct __fn { + + template _Sent, weakly_incrementable _OutIter> + requires indirectly_copyable<_InIter, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + rotate_copy_result<_InIter, _OutIter> + operator()(_InIter __first, _InIter __middle, _Sent __last, _OutIter __result) const { + auto __res1 = ranges::copy(__middle, __last, std::move(__result)); + auto __res2 = ranges::copy(__first, __middle, std::move(__res1.out)); + return {std::move(__res1.in), std::move(__res2.out)}; + } + + template + requires indirectly_copyable, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + rotate_copy_result, _OutIter> + operator()(_Range&& __range, iterator_t<_Range> __middle, _OutIter __result) const { + return (*this)(ranges::begin(__range), std::move(__middle), ranges::end(__range), std::move(__result)); + } + +}; +} // namespace __rotate_copy + +inline namespace __cpo { + inline constexpr auto rotate_copy = __rotate_copy::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_ROTATE_COPY_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_sample.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_sample.h new file mode 100644 index 0000000..a37cb64 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_sample.h @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_SAMPLE_H +#define _LIBCPP___ALGORITHM_RANGES_SAMPLE_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/sample.h> +#include <__algorithm/uniform_random_bit_generator_adaptor.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iterator_traits.h> +#include <__random/uniform_random_bit_generator.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __sample { + +struct __fn { + + template _Sent, weakly_incrementable _OutIter, class _Gen> + requires (forward_iterator<_Iter> || random_access_iterator<_OutIter>) && + indirectly_copyable<_Iter, _OutIter> && + uniform_random_bit_generator> + _LIBCPP_HIDE_FROM_ABI + _OutIter operator()(_Iter __first, _Sent __last, + _OutIter __out_first, iter_difference_t<_Iter> __n, _Gen&& __gen) const { + _ClassicGenAdaptor<_Gen> __adapted_gen(__gen); + return std::__sample<_RangeAlgPolicy>( + std::move(__first), std::move(__last), std::move(__out_first), __n, __adapted_gen); + } + + template + requires (forward_range<_Range> || random_access_iterator<_OutIter>) && + indirectly_copyable, _OutIter> && + uniform_random_bit_generator> + _LIBCPP_HIDE_FROM_ABI + _OutIter operator()(_Range&& __range, _OutIter __out_first, range_difference_t<_Range> __n, _Gen&& __gen) const { + return (*this)(ranges::begin(__range), ranges::end(__range), + std::move(__out_first), __n, std::forward<_Gen>(__gen)); + } + +}; + +} // namespace __sample + +inline namespace __cpo { + inline constexpr auto sample = __sample::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_SAMPLE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_search.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_search.h new file mode 100644 index 0000000..388d5af --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_search.h @@ -0,0 +1,135 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_SEARCH_H +#define _LIBCPP___ALGORITHM_RANGES_SEARCH_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/search.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/advance.h> +#include <__iterator/concepts.h> +#include <__iterator/distance.h> +#include <__iterator/indirectly_comparable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/size.h> +#include <__ranges/subrange.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __search { +struct __fn { + template + _LIBCPP_HIDE_FROM_ABI static constexpr subrange<_Iter1> __ranges_search_impl( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2) { + if constexpr (sized_sentinel_for<_Sent2, _Iter2>) { + auto __size2 = ranges::distance(__first2, __last2); + if (__size2 == 0) + return {__first1, __first1}; + + if constexpr (sized_sentinel_for<_Sent1, _Iter1>) { + auto __size1 = ranges::distance(__first1, __last1); + if (__size1 < __size2) { + ranges::advance(__first1, __last1); + return {__first1, __first1}; + } + + if constexpr (random_access_iterator<_Iter1> && random_access_iterator<_Iter2>) { + auto __ret = std::__search_random_access_impl<_RangeAlgPolicy>( + __first1, __last1, __first2, __last2, __pred, __proj1, __proj2, __size1, __size2); + return {__ret.first, __ret.second}; + } + } + } + + auto __ret = + std::__search_forward_impl<_RangeAlgPolicy>(__first1, __last1, __first2, __last2, __pred, __proj1, __proj2); + return {__ret.first, __ret.second}; + } + + template _Sent1, + forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2, + class _Pred = ranges::equal_to, + class _Proj1 = identity, + class _Proj2 = identity> + requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + subrange<_Iter1> operator()(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Pred __pred = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + return __ranges_search_impl(__first1, __last1, __first2, __last2, __pred, __proj1, __proj2); + } + + template + requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_subrange_t<_Range1> operator()(_Range1&& __range1, + _Range2&& __range2, + _Pred __pred = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + auto __first1 = ranges::begin(__range1); + if constexpr (sized_range<_Range2>) { + auto __size2 = ranges::size(__range2); + if (__size2 == 0) + return {__first1, __first1}; + if constexpr (sized_range<_Range1>) { + auto __size1 = ranges::size(__range1); + if (__size1 < __size2) { + ranges::advance(__first1, ranges::end(__range1)); + return {__first1, __first1}; + } + } + } + + return __ranges_search_impl( + ranges::begin(__range1), + ranges::end(__range1), + ranges::begin(__range2), + ranges::end(__range2), + __pred, + __proj1, + __proj2); + } + +}; +} // namespace __search + +inline namespace __cpo { + inline constexpr auto search = __search::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_SEARCH_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_search_n.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_search_n.h new file mode 100644 index 0000000..56ec8f3 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_search_n.h @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_SEARCH_N_H +#define _LIBCPP___ALGORITHM_RANGES_SEARCH_N_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/search_n.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/advance.h> +#include <__iterator/concepts.h> +#include <__iterator/distance.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/indirectly_comparable.h> +#include <__iterator/iterator_traits.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/size.h> +#include <__ranges/subrange.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __search_n { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI static constexpr subrange<_Iter1> __ranges_search_n_impl( + _Iter1 __first, _Sent1 __last, _SizeT __count, const _Type& __value, _Pred& __pred, _Proj& __proj) { + if (__count == 0) + return {__first, __first}; + + if constexpr (sized_sentinel_for<_Sent1, _Iter1>) { + auto __size = ranges::distance(__first, __last); + if (__size < __count) { + ranges::advance(__first, __last); + return {__first, __first}; + } + + if constexpr (random_access_iterator<_Iter1>) { + auto __ret = std::__search_n_random_access_impl<_RangeAlgPolicy>( + __first, __last, __count, __value, __pred, __proj, __size); + return {std::move(__ret.first), std::move(__ret.second)}; + } + } + + auto __ret = std::__search_n_forward_impl<_RangeAlgPolicy>(__first, __last, + __count, + __value, + __pred, + __proj); + return {std::move(__ret.first), std::move(__ret.second)}; + } + + template _Sent, + class _Type, + class _Pred = ranges::equal_to, + class _Proj = identity> + requires indirectly_comparable<_Iter, const _Type*, _Pred, _Proj> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + subrange<_Iter> operator()(_Iter __first, _Sent __last, + iter_difference_t<_Iter> __count, + const _Type& __value, + _Pred __pred = {}, + _Proj __proj = _Proj{}) const { + return __ranges_search_n_impl(__first, __last, __count, __value, __pred, __proj); + } + + template + requires indirectly_comparable, const _Type*, _Pred, _Proj> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_subrange_t<_Range> operator()(_Range&& __range, + range_difference_t<_Range> __count, + const _Type& __value, + _Pred __pred = {}, + _Proj __proj = {}) const { + auto __first = ranges::begin(__range); + if (__count <= 0) + return {__first, __first}; + if constexpr (sized_range<_Range>) { + auto __size1 = ranges::size(__range); + if (__size1 < static_cast>(__count)) { + ranges::advance(__first, ranges::end(__range)); + return {__first, __first}; + } + } + + return __ranges_search_n_impl(ranges::begin(__range), ranges::end(__range), __count, __value, __pred, __proj); + } +}; +} // namespace __search_n + +inline namespace __cpo { + inline constexpr auto search_n = __search_n::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_SEARCH_N_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_set_difference.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_set_difference.h new file mode 100644 index 0000000..607dd68 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_set_difference.h @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_SET_DIFFERENCE_H +#define _LIBCPP___ALGORITHM_RANGES_SET_DIFFERENCE_H + +#include <__algorithm/in_out_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/set_difference.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/mergeable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__type_traits/decay.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using set_difference_result = in_out_result<_InIter, _OutIter>; + +namespace __set_difference { + +struct __fn { + template < + input_iterator _InIter1, + sentinel_for<_InIter1> _Sent1, + input_iterator _InIter2, + sentinel_for<_InIter2> _Sent2, + weakly_incrementable _OutIter, + class _Comp = less, + class _Proj1 = identity, + class _Proj2 = identity> + requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2> + _LIBCPP_HIDE_FROM_ABI constexpr set_difference_result<_InIter1, _OutIter> operator()( + _InIter1 __first1, + _Sent1 __last1, + _InIter2 __first2, + _Sent2 __last2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + auto __ret = std::__set_difference<_RangeAlgPolicy>( + __first1, __last1, __first2, __last2, __result, ranges::__make_projected_comp(__comp, __proj1, __proj2)); + return {std::move(__ret.first), std::move(__ret.second)}; + } + + template < + input_range _Range1, + input_range _Range2, + weakly_incrementable _OutIter, + class _Comp = less, + class _Proj1 = identity, + class _Proj2 = identity> + requires mergeable, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2> + _LIBCPP_HIDE_FROM_ABI constexpr set_difference_result, _OutIter> + operator()( + _Range1&& __range1, + _Range2&& __range2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + auto __ret = std::__set_difference<_RangeAlgPolicy>( + ranges::begin(__range1), + ranges::end(__range1), + ranges::begin(__range2), + ranges::end(__range2), + __result, + ranges::__make_projected_comp(__comp, __proj1, __proj2)); + return {std::move(__ret.first), std::move(__ret.second)}; + } +}; + +} // namespace __set_difference + +inline namespace __cpo { + inline constexpr auto set_difference = __set_difference::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 +#endif // _LIBCPP___ALGORITHM_RANGES_SET_DIFFERENCE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_set_intersection.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_set_intersection.h new file mode 100644 index 0000000..aa9fd24 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_set_intersection.h @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_SET_INTERSECTION_H +#define _LIBCPP___ALGORITHM_RANGES_SET_INTERSECTION_H + +#include <__algorithm/in_in_out_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/set_intersection.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/mergeable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using set_intersection_result = in_in_out_result<_InIter1, _InIter2, _OutIter>; + +namespace __set_intersection { + +struct __fn { + template < + input_iterator _InIter1, + sentinel_for<_InIter1> _Sent1, + input_iterator _InIter2, + sentinel_for<_InIter2> _Sent2, + weakly_incrementable _OutIter, + class _Comp = less, + class _Proj1 = identity, + class _Proj2 = identity> + requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2> + _LIBCPP_HIDE_FROM_ABI constexpr set_intersection_result<_InIter1, _InIter2, _OutIter> operator()( + _InIter1 __first1, + _Sent1 __last1, + _InIter2 __first2, + _Sent2 __last2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + auto __ret = std::__set_intersection<_RangeAlgPolicy>( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + ranges::__make_projected_comp(__comp, __proj1, __proj2)); + return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)}; + } + + template < + input_range _Range1, + input_range _Range2, + weakly_incrementable _OutIter, + class _Comp = less, + class _Proj1 = identity, + class _Proj2 = identity> + requires mergeable< + iterator_t<_Range1>, + iterator_t<_Range2>, + _OutIter, + _Comp, + _Proj1, + _Proj2> + _LIBCPP_HIDE_FROM_ABI constexpr set_intersection_result, + borrowed_iterator_t<_Range2>, + _OutIter> + operator()( + _Range1&& __range1, + _Range2&& __range2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + auto __ret = std::__set_intersection<_RangeAlgPolicy>( + ranges::begin(__range1), + ranges::end(__range1), + ranges::begin(__range2), + ranges::end(__range2), + std::move(__result), + ranges::__make_projected_comp(__comp, __proj1, __proj2)); + return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)}; + } +}; + +} // namespace __set_intersection + +inline namespace __cpo { + inline constexpr auto set_intersection = __set_intersection::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 +#endif // _LIBCPP___ALGORITHM_RANGES_SET_INTERSECTION_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_set_symmetric_difference.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_set_symmetric_difference.h new file mode 100644 index 0000000..bc4a906 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_set_symmetric_difference.h @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_SET_SYMMETRIC_DIFFERENCE_H +#define _LIBCPP___ALGORITHM_RANGES_SET_SYMMETRIC_DIFFERENCE_H + +#include <__algorithm/in_in_out_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/set_symmetric_difference.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/mergeable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using set_symmetric_difference_result = in_in_out_result<_InIter1, _InIter2, _OutIter>; + +namespace __set_symmetric_difference { + +struct __fn { + template < + input_iterator _InIter1, + sentinel_for<_InIter1> _Sent1, + input_iterator _InIter2, + sentinel_for<_InIter2> _Sent2, + weakly_incrementable _OutIter, + class _Comp = ranges::less, + class _Proj1 = identity, + class _Proj2 = identity> + requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2> + _LIBCPP_HIDE_FROM_ABI constexpr set_symmetric_difference_result<_InIter1, _InIter2, _OutIter> operator()( + _InIter1 __first1, + _Sent1 __last1, + _InIter2 __first2, + _Sent2 __last2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + auto __ret = std::__set_symmetric_difference<_RangeAlgPolicy>( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + ranges::__make_projected_comp(__comp, __proj1, __proj2)); + return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)}; + } + + template < + input_range _Range1, + input_range _Range2, + weakly_incrementable _OutIter, + class _Comp = ranges::less, + class _Proj1 = identity, + class _Proj2 = identity> + requires mergeable< + iterator_t<_Range1>, + iterator_t<_Range2>, + _OutIter, + _Comp, + _Proj1, + _Proj2> + _LIBCPP_HIDE_FROM_ABI constexpr set_symmetric_difference_result, + borrowed_iterator_t<_Range2>, + _OutIter> + operator()( + _Range1&& __range1, + _Range2&& __range2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + auto __ret = std::__set_symmetric_difference<_RangeAlgPolicy>( + ranges::begin(__range1), + ranges::end(__range1), + ranges::begin(__range2), + ranges::end(__range2), + std::move(__result), + ranges::__make_projected_comp(__comp, __proj1, __proj2)); + return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)}; + } +}; + +} // namespace __set_symmetric_difference + +inline namespace __cpo { + inline constexpr auto set_symmetric_difference = __set_symmetric_difference::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 +#endif // _LIBCPP___ALGORITHM_RANGES_SET_SYMMETRIC_DIFFERENCE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_set_union.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_set_union.h new file mode 100644 index 0000000..f8cd45c --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_set_union.h @@ -0,0 +1,121 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_SET_UNION_H +#define _LIBCPP___ALGORITHM_RANGES_SET_UNION_H + +#include <__algorithm/in_in_out_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/set_union.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/mergeable.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using set_union_result = in_in_out_result<_InIter1, _InIter2, _OutIter>; + +namespace __set_union { + +struct __fn { + template < + input_iterator _InIter1, + sentinel_for<_InIter1> _Sent1, + input_iterator _InIter2, + sentinel_for<_InIter2> _Sent2, + weakly_incrementable _OutIter, + class _Comp = ranges::less, + class _Proj1 = identity, + class _Proj2 = identity> + requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2> + _LIBCPP_HIDE_FROM_ABI constexpr set_union_result<_InIter1, _InIter2, _OutIter> operator()( + _InIter1 __first1, + _Sent1 __last1, + _InIter2 __first2, + _Sent2 __last2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + auto __ret = std::__set_union<_RangeAlgPolicy>( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + ranges::__make_projected_comp(__comp, __proj1, __proj2)); + return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)}; + } + + template < + input_range _Range1, + input_range _Range2, + weakly_incrementable _OutIter, + class _Comp = ranges::less, + class _Proj1 = identity, + class _Proj2 = identity> + requires mergeable< + iterator_t<_Range1>, + iterator_t<_Range2>, + _OutIter, + _Comp, + _Proj1, + _Proj2> + _LIBCPP_HIDE_FROM_ABI constexpr set_union_result, + borrowed_iterator_t<_Range2>, + _OutIter> + operator()( + _Range1&& __range1, + _Range2&& __range2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + auto __ret = std::__set_union<_RangeAlgPolicy>( + ranges::begin(__range1), + ranges::end(__range1), + ranges::begin(__range2), + ranges::end(__range2), + std::move(__result), + ranges::__make_projected_comp(__comp, __proj1, __proj2)); + return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)}; + } +}; + +} // namespace __set_union + +inline namespace __cpo { + inline constexpr auto set_union = __set_union::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_SET_UNION_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_shuffle.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_shuffle.h new file mode 100644 index 0000000..a2f2c0e --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_shuffle.h @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_SHUFFLE_H +#define _LIBCPP___ALGORITHM_RANGES_SHUFFLE_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/shuffle.h> +#include <__algorithm/uniform_random_bit_generator_adaptor.h> +#include <__config> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/permutable.h> +#include <__random/uniform_random_bit_generator.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __shuffle { + +struct __fn { + + template _Sent, class _Gen> + requires permutable<_Iter> && uniform_random_bit_generator> + _LIBCPP_HIDE_FROM_ABI + _Iter operator()(_Iter __first, _Sent __last, _Gen&& __gen) const { + _ClassicGenAdaptor<_Gen> __adapted_gen(__gen); + return std::__shuffle<_RangeAlgPolicy>(std::move(__first), std::move(__last), __adapted_gen); + } + + template + requires permutable> && uniform_random_bit_generator> + _LIBCPP_HIDE_FROM_ABI + borrowed_iterator_t<_Range> operator()(_Range&& __range, _Gen&& __gen) const { + return (*this)(ranges::begin(__range), ranges::end(__range), std::forward<_Gen>(__gen)); + } + +}; + +} // namespace __shuffle + +inline namespace __cpo { + inline constexpr auto shuffle = __shuffle::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_SHUFFLE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_sort.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_sort.h new file mode 100644 index 0000000..32391df --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_sort.h @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_SORT_H +#define _LIBCPP___ALGORITHM_RANGES_SORT_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/sort.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/projected.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __sort { + +struct __fn { + template + _LIBCPP_HIDE_FROM_ABI constexpr static + _Iter __sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __last_iter = ranges::next(__first, __last); + + auto&& __projected_comp = std::__make_projected(__comp, __proj); + std::__sort_impl<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp); + + return __last_iter; + } + + template _Sent, class _Comp = ranges::less, class _Proj = identity> + requires sortable<_Iter, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return __sort_fn_impl(std::move(__first), std::move(__last), __comp, __proj); + } + + template + requires sortable, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + return __sort_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); + } +}; + +} // namespace __sort + +inline namespace __cpo { + inline constexpr auto sort = __sort::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_SORT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_sort_heap.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_sort_heap.h new file mode 100644 index 0000000..9feb0f6 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_sort_heap.h @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_SORT_HEAP_H +#define _LIBCPP___ALGORITHM_RANGES_SORT_HEAP_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/sort_heap.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/projected.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __sort_heap { + +struct __fn { + template + _LIBCPP_HIDE_FROM_ABI constexpr static + _Iter __sort_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __last_iter = ranges::next(__first, __last); + + auto&& __projected_comp = std::__make_projected(__comp, __proj); + std::__sort_heap<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp); + + return __last_iter; + } + + template _Sent, class _Comp = ranges::less, class _Proj = identity> + requires sortable<_Iter, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return __sort_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj); + } + + template + requires sortable, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + return __sort_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); + } +}; + +} // namespace __sort_heap + +inline namespace __cpo { + inline constexpr auto sort_heap = __sort_heap::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_SORT_HEAP_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_stable_partition.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_stable_partition.h new file mode 100644 index 0000000..c3469f1 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_stable_partition.h @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_STABLE_PARTITION_H +#define _LIBCPP___ALGORITHM_RANGES_STABLE_PARTITION_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/ranges_iterator_concept.h> +#include <__algorithm/stable_partition.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/permutable.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__ranges/subrange.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __stable_partition { + +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI static + subrange<__remove_cvref_t<_Iter>> __stable_partition_fn_impl( + _Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) { + auto __last_iter = ranges::next(__first, __last); + + auto&& __projected_pred = std::__make_projected(__pred, __proj); + auto __result = std::__stable_partition<_RangeAlgPolicy>( + std::move(__first), __last_iter, __projected_pred, __iterator_concept<_Iter>()); + + return {std::move(__result), std::move(__last_iter)}; + } + + template _Sent, class _Proj = identity, + indirect_unary_predicate> _Pred> + requires permutable<_Iter> + _LIBCPP_HIDE_FROM_ABI + subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { + return __stable_partition_fn_impl(__first, __last, __pred, __proj); + } + + template , _Proj>> _Pred> + requires permutable> + _LIBCPP_HIDE_FROM_ABI + borrowed_subrange_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { + return __stable_partition_fn_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); + } + +}; + +} // namespace __stable_partition + +inline namespace __cpo { + inline constexpr auto stable_partition = __stable_partition::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_STABLE_PARTITION_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_stable_sort.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_stable_sort.h new file mode 100644 index 0000000..d3c48dd --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_stable_sort.h @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_STABLE_SORT_H +#define _LIBCPP___ALGORITHM_RANGES_STABLE_SORT_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/stable_sort.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/projected.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __stable_sort { + +struct __fn { + template + _LIBCPP_HIDE_FROM_ABI + static _Iter __stable_sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __last_iter = ranges::next(__first, __last); + + auto&& __projected_comp = std::__make_projected(__comp, __proj); + std::__stable_sort_impl<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp); + + return __last_iter; + } + + template _Sent, class _Comp = ranges::less, class _Proj = identity> + requires sortable<_Iter, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI + _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return __stable_sort_fn_impl(std::move(__first), std::move(__last), __comp, __proj); + } + + template + requires sortable, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI + borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + return __stable_sort_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); + } +}; + +} // namespace __stable_sort + +inline namespace __cpo { + inline constexpr auto stable_sort = __stable_sort::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_STABLE_SORT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_swap_ranges.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_swap_ranges.h new file mode 100644 index 0000000..552fd55 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_swap_ranges.h @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_SWAP_RANGES_H +#define _LIBCPP___ALGORITHM_RANGES_SWAP_RANGES_H + +#include <__algorithm/in_in_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/swap_ranges.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/iter_swap.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using swap_ranges_result = in_in_result<_I1, _I2>; + +namespace __swap_ranges { +struct __fn { + template _S1, + input_iterator _I2, sentinel_for<_I2> _S2> + requires indirectly_swappable<_I1, _I2> + _LIBCPP_HIDE_FROM_ABI constexpr swap_ranges_result<_I1, _I2> + operator()(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2) const { + auto __ret = std::__swap_ranges<_RangeAlgPolicy>( + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2)); + return {std::move(__ret.first), std::move(__ret.second)}; + } + + template + requires indirectly_swappable, iterator_t<_R2>> + _LIBCPP_HIDE_FROM_ABI constexpr + swap_ranges_result, borrowed_iterator_t<_R2>> + operator()(_R1&& __r1, _R2&& __r2) const { + return operator()(ranges::begin(__r1), ranges::end(__r1), + ranges::begin(__r2), ranges::end(__r2)); + } +}; +} // namespace __swap_ranges + +inline namespace __cpo { + inline constexpr auto swap_ranges = __swap_ranges::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_SWAP_RANGES_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_transform.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_transform.h new file mode 100644 index 0000000..c0981a0 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_transform.h @@ -0,0 +1,170 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_TRANSFORM_H +#define _LIBCPP___ALGORITHM_RANGES_TRANSFORM_H + +#include <__algorithm/in_in_out_result.h> +#include <__algorithm/in_out_result.h> +#include <__concepts/constructible.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using unary_transform_result = in_out_result<_Ip, _Op>; + +template +using binary_transform_result = in_in_out_result<_I1, _I2, _O1>; + +namespace __transform { +struct __fn { +private: + template + _LIBCPP_HIDE_FROM_ABI static constexpr + unary_transform_result<_InIter, _OutIter> __unary(_InIter __first, _Sent __last, + _OutIter __result, + _Func& __operation, + _Proj& __projection) { + while (__first != __last) { + *__result = std::invoke(__operation, std::invoke(__projection, *__first)); + ++__first; + ++__result; + } + + return {std::move(__first), std::move(__result)}; + } + + template + _LIBCPP_HIDE_FROM_ABI static constexpr binary_transform_result<_InIter1, _InIter2, _OutIter> + __binary(_InIter1 __first1, _Sent1 __last1, + _InIter2 __first2, _Sent2 __last2, + _OutIter __result, + _Func& __binary_operation, + _Proj1& __projection1, + _Proj2& __projection2) { + while (__first1 != __last1 && __first2 != __last2) { + *__result = std::invoke(__binary_operation, std::invoke(__projection1, *__first1), + std::invoke(__projection2, *__first2)); + ++__first1; + ++__first2; + ++__result; + } + return {std::move(__first1), std::move(__first2), std::move(__result)}; + } +public: + template _Sent, + weakly_incrementable _OutIter, + copy_constructible _Func, + class _Proj = identity> + requires indirectly_writable<_OutIter, indirect_result_t<_Func&, projected<_InIter, _Proj>>> + _LIBCPP_HIDE_FROM_ABI constexpr + unary_transform_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, + _OutIter __result, + _Func __operation, + _Proj __proj = {}) const { + return __unary(std::move(__first), std::move(__last), std::move(__result), __operation, __proj); + } + + template + requires indirectly_writable<_OutIter, indirect_result_t<_Func, projected, _Proj>>> + _LIBCPP_HIDE_FROM_ABI constexpr + unary_transform_result, _OutIter> operator()(_Range&& __range, + _OutIter __result, + _Func __operation, + _Proj __projection = {}) const { + return __unary(ranges::begin(__range), ranges::end(__range), std::move(__result), __operation, __projection); + } + + template _Sent1, + input_iterator _InIter2, sentinel_for<_InIter2> _Sent2, + weakly_incrementable _OutIter, + copy_constructible _Func, + class _Proj1 = identity, + class _Proj2 = identity> + requires indirectly_writable<_OutIter, indirect_result_t<_Func&, projected<_InIter1, _Proj1>, + projected<_InIter2, _Proj2>>> + _LIBCPP_HIDE_FROM_ABI constexpr + binary_transform_result<_InIter1, _InIter2, _OutIter> operator()(_InIter1 __first1, _Sent1 __last1, + _InIter2 __first2, _Sent2 __last2, + _OutIter __result, + _Func __binary_operation, + _Proj1 __projection1 = {}, + _Proj2 __projection2 = {}) const { + return __binary(std::move(__first1), std::move(__last1), + std::move(__first2), std::move(__last2), + std::move(__result), + __binary_operation, + __projection1, + __projection2); + } + + template + requires indirectly_writable<_OutIter, indirect_result_t<_Func&, projected, _Proj1>, + projected, _Proj2>>> + _LIBCPP_HIDE_FROM_ABI constexpr + binary_transform_result, borrowed_iterator_t<_Range2>, _OutIter> + operator()(_Range1&& __range1, + _Range2&& __range2, + _OutIter __result, + _Func __binary_operation, + _Proj1 __projection1 = {}, + _Proj2 __projection2 = {}) const { + return __binary(ranges::begin(__range1), ranges::end(__range1), + ranges::begin(__range2), ranges::end(__range2), + std::move(__result), + __binary_operation, + __projection1, + __projection2); + } + +}; +} // namespace __transform + +inline namespace __cpo { + inline constexpr auto transform = __transform::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_TRANSFORM_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_unique.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_unique.h new file mode 100644 index 0000000..be427cc --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_unique.h @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_UNIQUE_H +#define _LIBCPP___ALGORITHM_RANGES_UNIQUE_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/unique.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/permutable.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__ranges/subrange.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __unique { + + struct __fn { + template < + permutable _Iter, + sentinel_for<_Iter> _Sent, + class _Proj = identity, + indirect_equivalence_relation> _Comp = ranges::equal_to> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = std::__unique<_RangeAlgPolicy>( + std::move(__first), std::move(__last), std::__make_projected(__comp, __proj)); + return {std::move(__ret.first), std::move(__ret.second)}; + } + + template < + forward_range _Range, + class _Proj = identity, + indirect_equivalence_relation, _Proj>> _Comp = ranges::equal_to> + requires permutable> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> + operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = std::__unique<_RangeAlgPolicy>( + ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj)); + return {std::move(__ret.first), std::move(__ret.second)}; + } + }; + +} // namespace __unique + +inline namespace __cpo { + inline constexpr auto unique = __unique::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_UNIQUE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_unique_copy.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_unique_copy.h new file mode 100644 index 0000000..3ad47b0 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_unique_copy.h @@ -0,0 +1,116 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_UNIQUE_COPY_H +#define _LIBCPP___ALGORITHM_RANGES_UNIQUE_COPY_H + +#include <__algorithm/in_out_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/unique_copy.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/projected.h> +#include <__iterator/readable_traits.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using unique_copy_result = in_out_result<_InIter, _OutIter>; + +namespace __unique_copy { + +template +concept __can_reread_from_output = (input_iterator<_OutIter> && same_as, iter_value_t<_OutIter>>); + +struct __fn { + template + static consteval auto __get_algo_tag() { + if constexpr (forward_iterator<_InIter>) { + return __unique_copy_tags::__reread_from_input_tag{}; + } else if constexpr (__can_reread_from_output<_InIter, _OutIter>) { + return __unique_copy_tags::__reread_from_output_tag{}; + } else if constexpr (indirectly_copyable_storable<_InIter, _OutIter>) { + return __unique_copy_tags::__read_from_tmp_value_tag{}; + } + } + + template + using __algo_tag_t = decltype(__get_algo_tag<_InIter, _OutIter>()); + + template _Sent, + weakly_incrementable _OutIter, + class _Proj = identity, + indirect_equivalence_relation> _Comp = ranges::equal_to> + requires indirectly_copyable<_InIter, _OutIter> && + (forward_iterator<_InIter> || + (input_iterator<_OutIter> && same_as, iter_value_t<_OutIter>>) || + indirectly_copyable_storable<_InIter, _OutIter>) + _LIBCPP_HIDE_FROM_ABI constexpr unique_copy_result<_InIter, _OutIter> + operator()(_InIter __first, _Sent __last, _OutIter __result, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = std::__unique_copy<_RangeAlgPolicy>( + std::move(__first), + std::move(__last), + std::move(__result), + std::__make_projected(__comp, __proj), + __algo_tag_t<_InIter, _OutIter>()); + return {std::move(__ret.first), std::move(__ret.second)}; + } + + template , _Proj>> _Comp = ranges::equal_to> + requires indirectly_copyable, _OutIter> && + (forward_iterator> || + (input_iterator<_OutIter> && same_as, iter_value_t<_OutIter>>) || + indirectly_copyable_storable, _OutIter>) + _LIBCPP_HIDE_FROM_ABI constexpr unique_copy_result, _OutIter> + operator()(_Range&& __range, _OutIter __result, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = std::__unique_copy<_RangeAlgPolicy>( + ranges::begin(__range), + ranges::end(__range), + std::move(__result), + std::__make_projected(__comp, __proj), + __algo_tag_t, _OutIter>()); + return {std::move(__ret.first), std::move(__ret.second)}; + } +}; + +} // namespace __unique_copy + +inline namespace __cpo { +inline constexpr auto unique_copy = __unique_copy::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_UNIQUE_COPY_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/ranges_upper_bound.h b/app/src/main/cpp/libcxx/include/__algorithm/ranges_upper_bound.h new file mode 100644 index 0000000..a134080 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/ranges_upper_bound.h @@ -0,0 +1,75 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_UPPER_BOUND_H +#define _LIBCPP___ALGORITHM_RANGES_UPPER_BOUND_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/lower_bound.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __upper_bound { +struct __fn { + template _Sent, class _Type, class _Proj = identity, + indirect_strict_weak_order> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { + auto __comp_lhs_rhs_swapped = [&](const auto& __lhs, const auto& __rhs) { + return !std::invoke(__comp, __rhs, __lhs); + }; + + return std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp_lhs_rhs_swapped, __proj); + } + + template , _Proj>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __r, + const _Type& __value, + _Comp __comp = {}, + _Proj __proj = {}) const { + auto __comp_lhs_rhs_swapped = [&](const auto& __lhs, const auto& __rhs) { + return !std::invoke(__comp, __rhs, __lhs); + }; + + return std::__lower_bound_impl<_RangeAlgPolicy>(ranges::begin(__r), + ranges::end(__r), + __value, + __comp_lhs_rhs_swapped, + __proj); + } +}; +} // namespace __upper_bound + +inline namespace __cpo { + inline constexpr auto upper_bound = __upper_bound::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_UPPER_BOUND_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/remove.h b/app/src/main/cpp/libcxx/include/__algorithm/remove.h new file mode 100644 index 0000000..533e41b --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/remove.h @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_REMOVE_H +#define _LIBCPP___ALGORITHM_REMOVE_H + +#include <__algorithm/find.h> +#include <__algorithm/find_if.h> +#include <__config> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) +{ + __first = _VSTD::find(__first, __last, __value); + if (__first != __last) + { + _ForwardIterator __i = __first; + while (++__i != __last) + { + if (!(*__i == __value)) + { + *__first = _VSTD::move(*__i); + ++__first; + } + } + } + return __first; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_REMOVE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/remove_copy.h b/app/src/main/cpp/libcxx/include/__algorithm/remove_copy.h new file mode 100644 index 0000000..ecba08a --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/remove_copy.h @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_REMOVE_COPY_H +#define _LIBCPP___ALGORITHM_REMOVE_COPY_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +_OutputIterator +remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value) +{ + for (; __first != __last; ++__first) + { + if (!(*__first == __value)) + { + *__result = *__first; + ++__result; + } + } + return __result; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_REMOVE_COPY_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/remove_copy_if.h b/app/src/main/cpp/libcxx/include/__algorithm/remove_copy_if.h new file mode 100644 index 0000000..2f235fd --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/remove_copy_if.h @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_REMOVE_COPY_IF_H +#define _LIBCPP___ALGORITHM_REMOVE_COPY_IF_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +_OutputIterator +remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) +{ + for (; __first != __last; ++__first) + { + if (!__pred(*__first)) + { + *__result = *__first; + ++__result; + } + } + return __result; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_REMOVE_COPY_IF_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/remove_if.h b/app/src/main/cpp/libcxx/include/__algorithm/remove_if.h new file mode 100644 index 0000000..2735072 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/remove_if.h @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_REMOVE_IF_H +#define _LIBCPP___ALGORITHM_REMOVE_IF_H + +#include <__algorithm/find_if.h> +#include <__config> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) +{ + __first = _VSTD::find_if<_ForwardIterator, _Predicate&>(__first, __last, __pred); + if (__first != __last) + { + _ForwardIterator __i = __first; + while (++__i != __last) + { + if (!__pred(*__i)) + { + *__first = _VSTD::move(*__i); + ++__first; + } + } + } + return __first; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_REMOVE_IF_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/replace.h b/app/src/main/cpp/libcxx/include/__algorithm/replace.h new file mode 100644 index 0000000..ce62150 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/replace.h @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_REPLACE_H +#define _LIBCPP___ALGORITHM_REPLACE_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +void +replace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value) +{ + for (; __first != __last; ++__first) + if (*__first == __old_value) + *__first = __new_value; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_REPLACE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/replace_copy.h b/app/src/main/cpp/libcxx/include/__algorithm/replace_copy.h new file mode 100644 index 0000000..bebb14c --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/replace_copy.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_REPLACE_COPY_H +#define _LIBCPP___ALGORITHM_REPLACE_COPY_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +_OutputIterator +replace_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, + const _Tp& __old_value, const _Tp& __new_value) +{ + for (; __first != __last; ++__first, (void) ++__result) + if (*__first == __old_value) + *__result = __new_value; + else + *__result = *__first; + return __result; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_REPLACE_COPY_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/replace_copy_if.h b/app/src/main/cpp/libcxx/include/__algorithm/replace_copy_if.h new file mode 100644 index 0000000..e1ddb52 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/replace_copy_if.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_REPLACE_COPY_IF_H +#define _LIBCPP___ALGORITHM_REPLACE_COPY_IF_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +_OutputIterator +replace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, + _Predicate __pred, const _Tp& __new_value) +{ + for (; __first != __last; ++__first, (void) ++__result) + if (__pred(*__first)) + *__result = __new_value; + else + *__result = *__first; + return __result; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_REPLACE_COPY_IF_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/replace_if.h b/app/src/main/cpp/libcxx/include/__algorithm/replace_if.h new file mode 100644 index 0000000..b3a3367 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/replace_if.h @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_REPLACE_IF_H +#define _LIBCPP___ALGORITHM_REPLACE_IF_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +void +replace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value) +{ + for (; __first != __last; ++__first) + if (__pred(*__first)) + *__first = __new_value; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_REPLACE_IF_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/reverse.h b/app/src/main/cpp/libcxx/include/__algorithm/reverse.h new file mode 100644 index 0000000..aa76951 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/reverse.h @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_REVERSE_H +#define _LIBCPP___ALGORITHM_REVERSE_H + +#include <__algorithm/iter_swap.h> +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +void +__reverse_impl(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag) +{ + while (__first != __last) + { + if (__first == --__last) + break; + _IterOps<_AlgPolicy>::iter_swap(__first, __last); + ++__first; + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +void +__reverse_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag) +{ + if (__first != __last) + for (; __first < --__last; ++__first) + _IterOps<_AlgPolicy>::iter_swap(__first, __last); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void __reverse(_BidirectionalIterator __first, _Sentinel __last) { + using _IterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_BidirectionalIterator>; + std::__reverse_impl<_AlgPolicy>(std::move(__first), std::move(__last), _IterCategory()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +void +reverse(_BidirectionalIterator __first, _BidirectionalIterator __last) +{ + std::__reverse<_ClassicAlgPolicy>(std::move(__first), std::move(__last)); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_REVERSE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/reverse_copy.h b/app/src/main/cpp/libcxx/include/__algorithm/reverse_copy.h new file mode 100644 index 0000000..f4a0e97 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/reverse_copy.h @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_REVERSE_COPY_H +#define _LIBCPP___ALGORITHM_REVERSE_COPY_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +_OutputIterator +reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) +{ + for (; __first != __last; ++__result) + *__result = *--__last; + return __result; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_REVERSE_COPY_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/rotate.h b/app/src/main/cpp/libcxx/include/__algorithm/rotate.h new file mode 100644 index 0000000..8934ce0 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/rotate.h @@ -0,0 +1,221 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_ROTATE_H +#define _LIBCPP___ALGORITHM_ROTATE_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/move.h> +#include <__algorithm/move_backward.h> +#include <__algorithm/swap_ranges.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> +#include <__utility/pair.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator +__rotate_left(_ForwardIterator __first, _ForwardIterator __last) +{ + typedef typename iterator_traits<_ForwardIterator>::value_type value_type; + using _Ops = _IterOps<_AlgPolicy>; + + value_type __tmp = _Ops::__iter_move(__first); + _ForwardIterator __lm1 = std::__move<_AlgPolicy>( + _Ops::next(__first), __last, __first).second; + *__lm1 = _VSTD::move(__tmp); + return __lm1; +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _BidirectionalIterator +__rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last) +{ + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + using _Ops = _IterOps<_AlgPolicy>; + + _BidirectionalIterator __lm1 = _Ops::prev(__last); + value_type __tmp = _Ops::__iter_move(__lm1); + _BidirectionalIterator __fp1 = std::__move_backward<_AlgPolicy>(__first, __lm1, std::move(__last)).second; + *__first = _VSTD::move(__tmp); + return __fp1; +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _ForwardIterator +__rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) +{ + _ForwardIterator __i = __middle; + while (true) + { + _IterOps<_AlgPolicy>::iter_swap(__first, __i); + ++__first; + if (++__i == __last) + break; + if (__first == __middle) + __middle = __i; + } + _ForwardIterator __r = __first; + if (__first != __middle) + { + __i = __middle; + while (true) + { + _IterOps<_AlgPolicy>::iter_swap(__first, __i); + ++__first; + if (++__i == __last) + { + if (__first == __middle) + break; + __i = __middle; + } + else if (__first == __middle) + __middle = __i; + } + } + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR_SINCE_CXX17 _Integral +__algo_gcd(_Integral __x, _Integral __y) +{ + do + { + _Integral __t = __x % __y; + __x = __y; + __y = __t; + } while (__y); + return __x; +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _RandomAccessIterator +__rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) +{ + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + using _Ops = _IterOps<_AlgPolicy>; + + const difference_type __m1 = __middle - __first; + const difference_type __m2 = _Ops::distance(__middle, __last); + if (__m1 == __m2) + { + std::__swap_ranges<_AlgPolicy>(__first, __middle, __middle, __last); + return __middle; + } + const difference_type __g = _VSTD::__algo_gcd(__m1, __m2); + for (_RandomAccessIterator __p = __first + __g; __p != __first;) + { + value_type __t(_Ops::__iter_move(--__p)); + _RandomAccessIterator __p1 = __p; + _RandomAccessIterator __p2 = __p1 + __m1; + do + { + *__p1 = _Ops::__iter_move(__p2); + __p1 = __p2; + const difference_type __d = _Ops::distance(__p2, __last); + if (__m1 < __d) + __p2 += __m1; + else + __p2 = __first + (__m1 - __d); + } while (__p2 != __p); + *__p1 = _VSTD::move(__t); + } + return __first + __m2; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator +__rotate_impl(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, + _VSTD::forward_iterator_tag) +{ + typedef typename iterator_traits<_ForwardIterator>::value_type value_type; + if (is_trivially_move_assignable::value) + { + if (_IterOps<_AlgPolicy>::next(__first) == __middle) + return std::__rotate_left<_AlgPolicy>(__first, __last); + } + return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR_SINCE_CXX14 _BidirectionalIterator +__rotate_impl(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, + bidirectional_iterator_tag) +{ + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + if (is_trivially_move_assignable::value) + { + if (_IterOps<_AlgPolicy>::next(__first) == __middle) + return std::__rotate_left<_AlgPolicy>(__first, __last); + if (_IterOps<_AlgPolicy>::next(__middle) == __last) + return std::__rotate_right<_AlgPolicy>(__first, __last); + } + return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator +__rotate_impl(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, + random_access_iterator_tag) +{ + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + if (is_trivially_move_assignable::value) + { + if (_IterOps<_AlgPolicy>::next(__first) == __middle) + return std::__rotate_left<_AlgPolicy>(__first, __last); + if (_IterOps<_AlgPolicy>::next(__middle) == __last) + return std::__rotate_right<_AlgPolicy>(__first, __last); + return std::__rotate_gcd<_AlgPolicy>(__first, __middle, __last); + } + return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair<_Iterator, _Iterator> +__rotate(_Iterator __first, _Iterator __middle, _Sentinel __last) { + using _Ret = pair<_Iterator, _Iterator>; + _Iterator __last_iter = _IterOps<_AlgPolicy>::next(__middle, __last); + + if (__first == __middle) + return _Ret(__last_iter, __last_iter); + if (__middle == __last) + return _Ret(std::move(__first), std::move(__last_iter)); + + using _IterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_Iterator>; + auto __result = std::__rotate_impl<_AlgPolicy>( + std::move(__first), std::move(__middle), __last_iter, _IterCategory()); + + return _Ret(std::move(__result), std::move(__last_iter)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) +{ + return std::__rotate<_ClassicAlgPolicy>( + std::move(__first), std::move(__middle), std::move(__last)).first; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_ROTATE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/rotate_copy.h b/app/src/main/cpp/libcxx/include/__algorithm/rotate_copy.h new file mode 100644 index 0000000..c154649 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/rotate_copy.h @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_ROTATE_COPY_H +#define _LIBCPP___ALGORITHM_ROTATE_COPY_H + +#include <__algorithm/copy.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +_OutputIterator +rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result) +{ + return _VSTD::copy(__first, __middle, _VSTD::copy(__middle, __last, __result)); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_ROTATE_COPY_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/sample.h b/app/src/main/cpp/libcxx/include/__algorithm/sample.h new file mode 100644 index 0000000..f403ba6 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/sample.h @@ -0,0 +1,112 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_SAMPLE_H +#define _LIBCPP___ALGORITHM_SAMPLE_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/min.h> +#include <__assert> +#include <__config> +#include <__iterator/distance.h> +#include <__iterator/iterator_traits.h> +#include <__random/uniform_int_distribution.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_INLINE_VISIBILITY +_SampleIterator __sample(_PopulationIterator __first, + _PopulationSentinel __last, _SampleIterator __output_iter, + _Distance __n, + _UniformRandomNumberGenerator& __g, + input_iterator_tag) { + + _Distance __k = 0; + for (; __first != __last && __k < __n; ++__first, (void) ++__k) + __output_iter[__k] = *__first; + _Distance __sz = __k; + for (; __first != __last; ++__first, (void) ++__k) { + _Distance __r = uniform_int_distribution<_Distance>(0, __k)(__g); + if (__r < __sz) + __output_iter[__r] = *__first; + } + return __output_iter + _VSTD::min(__n, __k); +} + +template +_LIBCPP_INLINE_VISIBILITY +_SampleIterator __sample(_PopulationIterator __first, + _PopulationSentinel __last, _SampleIterator __output_iter, + _Distance __n, + _UniformRandomNumberGenerator& __g, + forward_iterator_tag) { + _Distance __unsampled_sz = _IterOps<_AlgPolicy>::distance(__first, __last); + for (__n = _VSTD::min(__n, __unsampled_sz); __n != 0; ++__first) { + _Distance __r = uniform_int_distribution<_Distance>(0, --__unsampled_sz)(__g); + if (__r < __n) { + *__output_iter++ = *__first; + --__n; + } + } + return __output_iter; +} + +template +_LIBCPP_INLINE_VISIBILITY +_SampleIterator __sample(_PopulationIterator __first, + _PopulationSentinel __last, _SampleIterator __output_iter, + _Distance __n, _UniformRandomNumberGenerator& __g) { + _LIBCPP_ASSERT(__n >= 0, "N must be a positive number."); + + using _PopIterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_PopulationIterator>; + using _Difference = typename _IterOps<_AlgPolicy>::template __difference_type<_PopulationIterator>; + using _CommonType = typename common_type<_Distance, _Difference>::type; + + return std::__sample<_AlgPolicy>( + std::move(__first), std::move(__last), std::move(__output_iter), _CommonType(__n), + __g, _PopIterCategory()); +} + +#if _LIBCPP_STD_VER > 14 +template +inline _LIBCPP_INLINE_VISIBILITY +_SampleIterator sample(_PopulationIterator __first, + _PopulationIterator __last, _SampleIterator __output_iter, + _Distance __n, _UniformRandomNumberGenerator&& __g) { + static_assert(__is_cpp17_forward_iterator<_PopulationIterator>::value || + __is_cpp17_random_access_iterator<_SampleIterator>::value, + "SampleIterator must meet the requirements of RandomAccessIterator"); + + return std::__sample<_ClassicAlgPolicy>( + std::move(__first), std::move(__last), std::move(__output_iter), __n, __g); +} + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_SAMPLE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/search.h b/app/src/main/cpp/libcxx/include/__algorithm/search.h new file mode 100644 index 0000000..93771be --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/search.h @@ -0,0 +1,201 @@ +// -*- 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 _LIBCPP___ALGORITHM_SEARCH_H +#define _LIBCPP___ALGORITHM_SEARCH_H + +#include <__algorithm/comp.h> +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__functional/identity.h> +#include <__iterator/advance.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__type_traits/is_callable.h> +#include <__utility/pair.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair<_Iter1, _Iter1> __search_forward_impl(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2) { + if (__first2 == __last2) + return std::make_pair(__first1, __first1); // Everything matches an empty sequence + while (true) { + // Find first element in sequence 1 that matchs *__first2, with a mininum of loop checks + while (true) { + if (__first1 == __last1) { // return __last1 if no element matches *__first2 + _IterOps<_AlgPolicy>::__advance_to(__first1, __last1); + return std::make_pair(__first1, __first1); + } + if (std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2))) + break; + ++__first1; + } + // *__first1 matches *__first2, now match elements after here + _Iter1 __m1 = __first1; + _Iter2 __m2 = __first2; + while (true) { + if (++__m2 == __last2) // If pattern exhausted, __first1 is the answer (works for 1 element pattern) + return std::make_pair(__first1, ++__m1); + if (++__m1 == __last1) { // Otherwise if source exhaused, pattern not found + return std::make_pair(__m1, __m1); + } + + // if there is a mismatch, restart with a new __first1 + if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2))) + { + ++__first1; + break; + } // else there is a match, check next elements + } + } +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair<_Iter1, _Iter1> __search_random_access_impl(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2, + _DiffT1 __size1, + _DiffT2 __size2) { + const _Iter1 __s = __first1 + __size1 - _DiffT1(__size2 - 1); // Start of pattern match can't go beyond here + + while (true) { + while (true) { + if (__first1 == __s) { + _IterOps<_AlgPolicy>::__advance_to(__first1, __last1); + return std::make_pair(__first1, __first1); + } + if (std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2))) + break; + ++__first1; + } + + _Iter1 __m1 = __first1; + _Iter2 __m2 = __first2; + while (true) { + if (++__m2 == __last2) + return std::make_pair(__first1, __first1 + _DiffT1(__size2)); + ++__m1; // no need to check range on __m1 because __s guarantees we have enough source + if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2))) { + ++__first1; + break; + } + } + } +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair<_Iter1, _Iter1> __search_impl(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2, + __enable_if_t<__is_cpp17_random_access_iterator<_Iter1>::value + && __is_cpp17_random_access_iterator<_Iter2>::value>* = nullptr) { + + auto __size2 = __last2 - __first2; + if (__size2 == 0) + return std::make_pair(__first1, __first1); + + auto __size1 = __last1 - __first1; + if (__size1 < __size2) { + return std::make_pair(__last1, __last1); + } + + return std::__search_random_access_impl<_ClassicAlgPolicy>(__first1, __last1, + __first2, __last2, + __pred, + __proj1, + __proj2, + __size1, + __size2); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair<_Iter1, _Iter1> __search_impl(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2, + __enable_if_t<__is_cpp17_forward_iterator<_Iter1>::value + && __is_cpp17_forward_iterator<_Iter2>::value + && !(__is_cpp17_random_access_iterator<_Iter1>::value + && __is_cpp17_random_access_iterator<_Iter2>::value)>* = nullptr) { + return std::__search_forward_impl<_ClassicAlgPolicy>(__first1, __last1, + __first2, __last2, + __pred, + __proj1, + __proj2); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +_ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __pred) { + static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value, + "BinaryPredicate has to be callable"); + auto __proj = __identity(); + return std::__search_impl(__first1, __last1, __first2, __last2, __pred, __proj, __proj).first; +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +_ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2) { + return std::search(__first1, __last1, __first2, __last2, __equal_to()); +} + +#if _LIBCPP_STD_VER > 14 +template +_LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher& __s) { + return __s(__f, __l).first; +} + +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SEARCH_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/search_n.h b/app/src/main/cpp/libcxx/include/__algorithm/search_n.h new file mode 100644 index 0000000..60a0735 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/search_n.h @@ -0,0 +1,181 @@ +// -*- 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 _LIBCPP___ALGORITHM_SEARCH_N_H +#define _LIBCPP___ALGORITHM_SEARCH_N_H + +#include <__algorithm/comp.h> +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__functional/identity.h> +#include <__iterator/advance.h> +#include <__iterator/concepts.h> +#include <__iterator/distance.h> +#include <__iterator/iterator_traits.h> +#include <__ranges/concepts.h> +#include <__utility/convert_to_integral.h> +#include <__utility/pair.h> +#include // __convert_to_integral + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair<_Iter, _Iter> __search_n_forward_impl(_Iter __first, _Sent __last, + _SizeT __count, + const _Type& __value, + _Pred& __pred, + _Proj& __proj) { + if (__count <= 0) + return std::make_pair(__first, __first); + while (true) { + // Find first element in sequence that matchs __value, with a mininum of loop checks + while (true) { + if (__first == __last) { // return __last if no element matches __value + _IterOps<_AlgPolicy>::__advance_to(__first, __last); + return std::make_pair(__first, __first); + } + if (std::__invoke(__pred, std::__invoke(__proj, *__first), __value)) + break; + ++__first; + } + // *__first matches __value, now match elements after here + _Iter __m = __first; + _SizeT __c(0); + while (true) { + if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern) + return std::make_pair(__first, ++__m); + if (++__m == __last) { // Otherwise if source exhaused, pattern not found + _IterOps<_AlgPolicy>::__advance_to(__first, __last); + return std::make_pair(__first, __first); + } + + // if there is a mismatch, restart with a new __first + if (!std::__invoke(__pred, std::__invoke(__proj, *__m), __value)) + { + __first = __m; + ++__first; + break; + } // else there is a match, check next elements + } + } +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +std::pair<_Iter, _Iter> __search_n_random_access_impl(_Iter __first, _Sent __last, + _SizeT __count, + const _Type& __value, + _Pred& __pred, + _Proj& __proj, + _DiffT __size1) { + using difference_type = typename iterator_traits<_Iter>::difference_type; + if (__count == 0) + return std::make_pair(__first, __first); + if (__size1 < static_cast<_DiffT>(__count)) { + _IterOps<_AlgPolicy>::__advance_to(__first, __last); + return std::make_pair(__first, __first); + } + + const auto __s = __first + __size1 - difference_type(__count - 1); // Start of pattern match can't go beyond here + while (true) { + // Find first element in sequence that matchs __value, with a mininum of loop checks + while (true) { + if (__first >= __s) { // return __last if no element matches __value + _IterOps<_AlgPolicy>::__advance_to(__first, __last); + return std::make_pair(__first, __first); + } + if (std::__invoke(__pred, std::__invoke(__proj, *__first), __value)) + break; + ++__first; + } + // *__first matches __value_, now match elements after here + auto __m = __first; + _SizeT __c(0); + while (true) { + if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern) + return std::make_pair(__first, __first + _DiffT(__count)); + ++__m; // no need to check range on __m because __s guarantees we have enough source + + // if there is a mismatch, restart with a new __first + if (!std::__invoke(__pred, std::__invoke(__proj, *__m), __value)) + { + __first = __m; + ++__first; + break; + } // else there is a match, check next elements + } + } +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair<_Iter, _Iter> __search_n_impl(_Iter __first, _Sent __last, + _DiffT __count, + const _Type& __value, + _Pred& __pred, + _Proj& __proj, + __enable_if_t<__is_cpp17_random_access_iterator<_Iter>::value>* = nullptr) { + return std::__search_n_random_access_impl<_ClassicAlgPolicy>(__first, __last, + __count, + __value, + __pred, + __proj, + __last - __first); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair<_Iter1, _Iter1> __search_n_impl(_Iter1 __first, _Sent1 __last, + _DiffT __count, + const _Type& __value, + _Pred& __pred, + _Proj& __proj, + __enable_if_t<__is_cpp17_forward_iterator<_Iter1>::value + && !__is_cpp17_random_access_iterator<_Iter1>::value>* = nullptr) { + return std::__search_n_forward_impl<_ClassicAlgPolicy>(__first, __last, + __count, + __value, + __pred, + __proj); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +_ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last, + _Size __count, + const _Tp& __value, + _BinaryPredicate __pred) { + static_assert(__is_callable<_BinaryPredicate, decltype(*__first), const _Tp&>::value, + "BinaryPredicate has to be callable"); + auto __proj = __identity(); + return std::__search_n_impl(__first, __last, std::__convert_to_integral(__count), __value, __pred, __proj).first; +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +_ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value) { + return std::search_n(__first, __last, std::__convert_to_integral(__count), __value, __equal_to()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SEARCH_N_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/set_difference.h b/app/src/main/cpp/libcxx/include/__algorithm/set_difference.h new file mode 100644 index 0000000..cffdc8f --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/set_difference.h @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_SET_DIFFERENCE_H +#define _LIBCPP___ALGORITHM_SET_DIFFERENCE_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/copy.h> +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> +#include <__utility/pair.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<__remove_cvref_t<_InIter1>, __remove_cvref_t<_OutIter> > +__set_difference( + _InIter1&& __first1, _Sent1&& __last1, _InIter2&& __first2, _Sent2&& __last2, _OutIter&& __result, _Comp&& __comp) { + while (__first1 != __last1 && __first2 != __last2) { + if (__comp(*__first1, *__first2)) { + *__result = *__first1; + ++__first1; + ++__result; + } else if (__comp(*__first2, *__first1)) { + ++__first2; + } else { + ++__first1; + ++__first2; + } + } + return std::__copy<_AlgPolicy>(std::move(__first1), std::move(__last1), std::move(__result)); +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_difference( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result, + _Compare __comp) { + return std::__set_difference<_ClassicAlgPolicy, __comp_ref_type<_Compare> >( + __first1, __last1, __first2, __last2, __result, __comp) + .second; +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_difference( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result) { + return std::__set_difference<_ClassicAlgPolicy>( + __first1, + __last1, + __first2, + __last2, + __result, + __less::value_type, + typename iterator_traits<_InputIterator2>::value_type>()).second; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SET_DIFFERENCE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/set_intersection.h b/app/src/main/cpp/libcxx/include/__algorithm/set_intersection.h new file mode 100644 index 0000000..9fa7799 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/set_intersection.h @@ -0,0 +1,99 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_SET_INTERSECTION_H +#define _LIBCPP___ALGORITHM_SET_INTERSECTION_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __set_intersection_result { + _InIter1 __in1_; + _InIter2 __in2_; + _OutIter __out_; + + // need a constructor as C++03 aggregate init is hard + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 + __set_intersection_result(_InIter1&& __in_iter1, _InIter2&& __in_iter2, _OutIter&& __out_iter) + : __in1_(std::move(__in_iter1)), __in2_(std::move(__in_iter2)), __out_(std::move(__out_iter)) {} +}; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __set_intersection_result<_InIter1, _InIter2, _OutIter> +__set_intersection( + _InIter1 __first1, _Sent1 __last1, _InIter2 __first2, _Sent2 __last2, _OutIter __result, _Compare&& __comp) { + while (__first1 != __last1 && __first2 != __last2) { + if (__comp(*__first1, *__first2)) + ++__first1; + else { + if (!__comp(*__first2, *__first1)) { + *__result = *__first1; + ++__result; + ++__first1; + } + ++__first2; + } + } + + return __set_intersection_result<_InIter1, _InIter2, _OutIter>( + _IterOps<_AlgPolicy>::next(std::move(__first1), std::move(__last1)), + _IterOps<_AlgPolicy>::next(std::move(__first2), std::move(__last2)), + std::move(__result)); +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_intersection( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result, + _Compare __comp) { + return std::__set_intersection<_ClassicAlgPolicy, __comp_ref_type<_Compare> >( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + __comp) + .__out_; +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_intersection( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result) { + return std::__set_intersection<_ClassicAlgPolicy>( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + __less::value_type, + typename iterator_traits<_InputIterator2>::value_type>()) + .__out_; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SET_INTERSECTION_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/set_symmetric_difference.h b/app/src/main/cpp/libcxx/include/__algorithm/set_symmetric_difference.h new file mode 100644 index 0000000..bcb0958 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/set_symmetric_difference.h @@ -0,0 +1,105 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H +#define _LIBCPP___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/copy.h> +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __set_symmetric_difference_result { + _InIter1 __in1_; + _InIter2 __in2_; + _OutIter __out_; + + // need a constructor as C++03 aggregate init is hard + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 + __set_symmetric_difference_result(_InIter1&& __in_iter1, _InIter2&& __in_iter2, _OutIter&& __out_iter) + : __in1_(std::move(__in_iter1)), __in2_(std::move(__in_iter2)), __out_(std::move(__out_iter)) {} +}; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __set_symmetric_difference_result<_InIter1, _InIter2, _OutIter> +__set_symmetric_difference( + _InIter1 __first1, _Sent1 __last1, _InIter2 __first2, _Sent2 __last2, _OutIter __result, _Compare&& __comp) { + while (__first1 != __last1) { + if (__first2 == __last2) { + auto __ret1 = std::__copy<_AlgPolicy>(std::move(__first1), std::move(__last1), std::move(__result)); + return __set_symmetric_difference_result<_InIter1, _InIter2, _OutIter>( + std::move(__ret1.first), std::move(__first2), std::move((__ret1.second))); + } + if (__comp(*__first1, *__first2)) { + *__result = *__first1; + ++__result; + ++__first1; + } else { + if (__comp(*__first2, *__first1)) { + *__result = *__first2; + ++__result; + } else { + ++__first1; + } + ++__first2; + } + } + auto __ret2 = std::__copy<_AlgPolicy>(std::move(__first2), std::move(__last2), std::move(__result)); + return __set_symmetric_difference_result<_InIter1, _InIter2, _OutIter>( + std::move(__first1), std::move(__ret2.first), std::move((__ret2.second))); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_symmetric_difference( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result, + _Compare __comp) { + return std::__set_symmetric_difference<_ClassicAlgPolicy, __comp_ref_type<_Compare> >( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + __comp) + .__out_; +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_symmetric_difference( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result) { + return std::set_symmetric_difference( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + __less::value_type, + typename iterator_traits<_InputIterator2>::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/set_union.h b/app/src/main/cpp/libcxx/include/__algorithm/set_union.h new file mode 100644 index 0000000..4d154b8 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/set_union.h @@ -0,0 +1,101 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_SET_UNION_H +#define _LIBCPP___ALGORITHM_SET_UNION_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/copy.h> +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __set_union_result { + _InIter1 __in1_; + _InIter2 __in2_; + _OutIter __out_; + + // need a constructor as C++03 aggregate init is hard + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 + __set_union_result(_InIter1&& __in_iter1, _InIter2&& __in_iter2, _OutIter&& __out_iter) + : __in1_(std::move(__in_iter1)), __in2_(std::move(__in_iter2)), __out_(std::move(__out_iter)) {} +}; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __set_union_result<_InIter1, _InIter2, _OutIter> __set_union( + _InIter1 __first1, _Sent1 __last1, _InIter2 __first2, _Sent2 __last2, _OutIter __result, _Compare&& __comp) { + for (; __first1 != __last1; ++__result) { + if (__first2 == __last2) { + auto __ret1 = std::__copy<_AlgPolicy>(std::move(__first1), std::move(__last1), std::move(__result)); + return __set_union_result<_InIter1, _InIter2, _OutIter>( + std::move(__ret1.first), std::move(__first2), std::move((__ret1.second))); + } + if (__comp(*__first2, *__first1)) { + *__result = *__first2; + ++__first2; + } else { + if (!__comp(*__first1, *__first2)) { + ++__first2; + } + *__result = *__first1; + ++__first1; + } + } + auto __ret2 = std::__copy<_AlgPolicy>(std::move(__first2), std::move(__last2), std::move(__result)); + return __set_union_result<_InIter1, _InIter2, _OutIter>( + std::move(__first1), std::move(__ret2.first), std::move((__ret2.second))); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_union( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result, + _Compare __comp) { + return std::__set_union<_ClassicAlgPolicy, __comp_ref_type<_Compare> >( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + __comp) + .__out_; +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_union( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result) { + return std::set_union( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + __less::value_type, + typename iterator_traits<_InputIterator2>::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SET_UNION_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/shift_left.h b/app/src/main/cpp/libcxx/include/__algorithm/shift_left.h new file mode 100644 index 0000000..33f06d5 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/shift_left.h @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_SHIFT_LEFT_H +#define _LIBCPP___ALGORITHM_SHIFT_LEFT_H + +#include <__algorithm/move.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +inline _LIBCPP_INLINE_VISIBILITY constexpr +_ForwardIterator +shift_left(_ForwardIterator __first, _ForwardIterator __last, + typename iterator_traits<_ForwardIterator>::difference_type __n) +{ + if (__n == 0) { + return __last; + } + + _ForwardIterator __m = __first; + if constexpr (__is_cpp17_random_access_iterator<_ForwardIterator>::value) { + if (__n >= __last - __first) { + return __first; + } + __m += __n; + } else { + for (; __n > 0; --__n) { + if (__m == __last) { + return __first; + } + ++__m; + } + } + return _VSTD::move(__m, __last, __first); +} + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SHIFT_LEFT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/shift_right.h b/app/src/main/cpp/libcxx/include/__algorithm/shift_right.h new file mode 100644 index 0000000..14bc761 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/shift_right.h @@ -0,0 +1,102 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_SHIFT_RIGHT_H +#define _LIBCPP___ALGORITHM_SHIFT_RIGHT_H + +#include <__algorithm/move.h> +#include <__algorithm/move_backward.h> +#include <__algorithm/swap_ranges.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/swap.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +inline _LIBCPP_INLINE_VISIBILITY constexpr +_ForwardIterator +shift_right(_ForwardIterator __first, _ForwardIterator __last, + typename iterator_traits<_ForwardIterator>::difference_type __n) +{ + if (__n == 0) { + return __first; + } + + if constexpr (__is_cpp17_random_access_iterator<_ForwardIterator>::value) { + decltype(__n) __d = __last - __first; + if (__n >= __d) { + return __last; + } + _ForwardIterator __m = __first + (__d - __n); + return _VSTD::move_backward(__first, __m, __last); + } else if constexpr (__is_cpp17_bidirectional_iterator<_ForwardIterator>::value) { + _ForwardIterator __m = __last; + for (; __n > 0; --__n) { + if (__m == __first) { + return __last; + } + --__m; + } + return _VSTD::move_backward(__first, __m, __last); + } else { + _ForwardIterator __ret = __first; + for (; __n > 0; --__n) { + if (__ret == __last) { + return __last; + } + ++__ret; + } + + // We have an __n-element scratch space from __first to __ret. + // Slide an __n-element window [__trail, __lead) from left to right. + // We're essentially doing swap_ranges(__first, __ret, __trail, __lead) + // over and over; but once __lead reaches __last we needn't bother + // to save the values of elements [__trail, __last). + + auto __trail = __first; + auto __lead = __ret; + while (__trail != __ret) { + if (__lead == __last) { + _VSTD::move(__first, __trail, __ret); + return __ret; + } + ++__trail; + ++__lead; + } + + _ForwardIterator __mid = __first; + while (true) { + if (__lead == __last) { + __trail = _VSTD::move(__mid, __ret, __trail); + _VSTD::move(__first, __mid, __trail); + return __ret; + } + swap(*__mid, *__trail); + ++__mid; + ++__trail; + ++__lead; + if (__mid == __ret) { + __mid = __first; + } + } + } +} + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SHIFT_RIGHT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/shuffle.h b/app/src/main/cpp/libcxx/include/__algorithm/shuffle.h new file mode 100644 index 0000000..f7bce68 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/shuffle.h @@ -0,0 +1,175 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_SHUFFLE_H +#define _LIBCPP___ALGORITHM_SHUFFLE_H + +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__debug> +#include <__iterator/iterator_traits.h> +#include <__random/uniform_int_distribution.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/swap.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +class _LIBCPP_TYPE_VIS __libcpp_debug_randomizer { +public: + __libcpp_debug_randomizer() { + __state_ = __seed(); + __inc_ = __state_ + 0xda3e39cb94b95bdbULL; + __inc_ = (__inc_ << 1) | 1; + } + typedef uint_fast32_t result_type; + + static const result_type _Min = 0; + static const result_type _Max = 0xFFFFFFFF; + + _LIBCPP_HIDE_FROM_ABI result_type operator()() { + uint_fast64_t __oldstate = __state_; + __state_ = __oldstate * 6364136223846793005ULL + __inc_; + return __oldstate >> 32; + } + + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type min() { return _Min; } + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type max() { return _Max; } + +private: + uint_fast64_t __state_; + uint_fast64_t __inc_; + _LIBCPP_HIDE_FROM_ABI static uint_fast64_t __seed() { +#ifdef _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY_SEED + return _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY_SEED; +#else + static char __x; + return reinterpret_cast(&__x); +#endif + } +}; + +#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE) \ + || defined(_LIBCPP_BUILDING_LIBRARY) +class _LIBCPP_TYPE_VIS __rs_default; + +_LIBCPP_FUNC_VIS __rs_default __rs_get(); + +class _LIBCPP_TYPE_VIS __rs_default +{ + static unsigned __c_; + + __rs_default(); +public: + typedef uint_fast32_t result_type; + + static const result_type _Min = 0; + static const result_type _Max = 0xFFFFFFFF; + + __rs_default(const __rs_default&); + ~__rs_default(); + + result_type operator()(); + + static _LIBCPP_CONSTEXPR result_type min() {return _Min;} + static _LIBCPP_CONSTEXPR result_type max() {return _Max;} + + friend _LIBCPP_FUNC_VIS __rs_default __rs_get(); +}; + +_LIBCPP_FUNC_VIS __rs_default __rs_get(); + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX14 void +random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef uniform_int_distribution _Dp; + typedef typename _Dp::param_type _Pp; + difference_type __d = __last - __first; + if (__d > 1) + { + _Dp __uid; + __rs_default __g = __rs_get(); + for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d) + { + difference_type __i = __uid(__g, _Pp(0, __d)); + if (__i != difference_type(0)) + swap(*__first, *(__first + __i)); + } + } +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX14 void +random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, +#ifndef _LIBCPP_CXX03_LANG + _RandomNumberGenerator&& __rand) +#else + _RandomNumberGenerator& __rand) +#endif +{ + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + difference_type __d = __last - __first; + if (__d > 1) + { + for (--__last; __first < __last; ++__first, (void) --__d) + { + difference_type __i = __rand(__d); + if (__i != difference_type(0)) + swap(*__first, *(__first + __i)); + } + } +} +#endif + +template +_LIBCPP_HIDE_FROM_ABI _RandomAccessIterator __shuffle( + _RandomAccessIterator __first, _Sentinel __last_sentinel, _UniformRandomNumberGenerator&& __g) { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef uniform_int_distribution _Dp; + typedef typename _Dp::param_type _Pp; + + auto __original_last = _IterOps<_AlgPolicy>::next(__first, __last_sentinel); + auto __last = __original_last; + difference_type __d = __last - __first; + if (__d > 1) + { + _Dp __uid; + for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d) + { + difference_type __i = __uid(__g, _Pp(0, __d)); + if (__i != difference_type(0)) + _IterOps<_AlgPolicy>::iter_swap(__first, __first + __i); + } + } + + return __original_last; +} + +template +_LIBCPP_HIDE_FROM_ABI void +shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, _UniformRandomNumberGenerator&& __g) { + (void)std::__shuffle<_ClassicAlgPolicy>( + std::move(__first), std::move(__last), std::forward<_UniformRandomNumberGenerator>(__g)); +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_SHUFFLE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/sift_down.h b/app/src/main/cpp/libcxx/include/__algorithm/sift_down.h new file mode 100644 index 0000000..e3972fb --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/sift_down.h @@ -0,0 +1,114 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_SIFT_DOWN_H +#define _LIBCPP___ALGORITHM_SIFT_DOWN_H + +#include <__algorithm/iterator_operations.h> +#include <__assert> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void +__sift_down(_RandomAccessIterator __first, _Compare&& __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len, + _RandomAccessIterator __start) +{ + using _Ops = _IterOps<_AlgPolicy>; + + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + // left-child of __start is at 2 * __start + 1 + // right-child of __start is at 2 * __start + 2 + difference_type __child = __start - __first; + + if (__len < 2 || (__len - 2) / 2 < __child) + return; + + __child = 2 * __child + 1; + _RandomAccessIterator __child_i = __first + __child; + + if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) { + // right-child exists and is greater than left-child + ++__child_i; + ++__child; + } + + // check if we are in heap-order + if (__comp(*__child_i, *__start)) + // we are, __start is larger than its largest child + return; + + value_type __top(_Ops::__iter_move(__start)); + do + { + // we are not in heap-order, swap the parent with its largest child + *__start = _Ops::__iter_move(__child_i); + __start = __child_i; + + if ((__len - 2) / 2 < __child) + break; + + // recompute the child based off of the updated parent + __child = 2 * __child + 1; + __child_i = __first + __child; + + if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) { + // right-child exists and is greater than left-child + ++__child_i; + ++__child; + } + + // check if we are in heap-order + } while (!__comp(*__child_i, __top)); + *__start = _VSTD::move(__top); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator +__floyd_sift_down(_RandomAccessIterator __first, _Compare&& __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len) +{ + using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; + _LIBCPP_ASSERT(__len >= 2, "shouldn't be called unless __len >= 2"); + + _RandomAccessIterator __hole = __first; + _RandomAccessIterator __child_i = __first; + difference_type __child = 0; + + while (true) { + __child_i += difference_type(__child + 1); + __child = 2 * __child + 1; + + if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) { + // right-child exists and is greater than left-child + ++__child_i; + ++__child; + } + + // swap __hole with its largest child + *__hole = _IterOps<_AlgPolicy>::__iter_move(__child_i); + __hole = __child_i; + + // if __hole is now a leaf, we're done + if (__child > (__len - 2) / 2) + return __hole; + } +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SIFT_DOWN_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/sort.h b/app/src/main/cpp/libcxx/include/__algorithm/sort.h new file mode 100644 index 0000000..a7d2d55 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/sort.h @@ -0,0 +1,1001 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_SORT_H +#define _LIBCPP___ALGORITHM_SORT_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/iter_swap.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/min_element.h> +#include <__algorithm/partial_sort.h> +#include <__algorithm/unwrap_iter.h> +#include <__assert> +#include <__bit/blsr.h> +#include <__bit/countl.h> +#include <__bit/countr.h> +#include <__config> +#include <__debug> +#include <__debug_utils/randomize_range.h> +#include <__functional/operations.h> +#include <__functional/ranges_operations.h> +#include <__iterator/iterator_traits.h> +#include <__memory/destruct_n.h> +#include <__memory/unique_ptr.h> +#include <__type_traits/conditional.h> +#include <__type_traits/is_arithmetic.h> +#include <__utility/move.h> +#include <__utility/pair.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Wraps an algorithm policy tag and a comparator in a single struct, used to pass the policy tag around without +// changing the number of template arguments (to keep the ABI stable). This is only used for the "range" policy tag. +// +// To create an object of this type, use `_WrapAlgPolicy::type` -- see the specialization below for the rationale. +template +struct _WrapAlgPolicy { + using type = _WrapAlgPolicy; + + using _AlgPolicy = _PolicyT; + using _Comp = _CompT; + _Comp& __comp; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 + _WrapAlgPolicy(_Comp& __c) : __comp(__c) {} +}; + +// Specialization for the "classic" policy tag that avoids creating a struct and simply defines an alias for the +// comparator. When unwrapping, a pristine comparator is always considered to have the "classic" tag attached. Passing +// the pristine comparator where possible allows using template instantiations from the dylib. +template +struct _WrapAlgPolicy<_PolicyT, _CompT, __enable_if_t::value> > { + using type = _CompT; +}; + +// Unwraps a pristine functor (e.g. `std::less`) as if it were wrapped using `_WrapAlgPolicy`. The policy tag is always +// set to "classic". +template +struct _UnwrapAlgPolicy { + using _AlgPolicy = _ClassicAlgPolicy; + using _Comp = _CompT; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static + _Comp __get_comp(_Comp __comp) { return __comp; } +}; + +// Unwraps a `_WrapAlgPolicy` struct. +template +struct _UnwrapAlgPolicy<_WrapAlgPolicy<_Ts...> > { + using _Wrapped = _WrapAlgPolicy<_Ts...>; + using _AlgPolicy = typename _Wrapped::_AlgPolicy; + using _Comp = typename _Wrapped::_Comp; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static + _Comp __get_comp(_Wrapped& __w) { return __w.__comp; } +}; + +// stable, 2-3 compares, 0-2 swaps + +template +_LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_SINCE_CXX14 unsigned __sort3(_ForwardIterator __x, _ForwardIterator __y, _ForwardIterator __z, + _Compare __c) { + using _Ops = _IterOps<_AlgPolicy>; + + unsigned __r = 0; + if (!__c(*__y, *__x)) // if x <= y + { + if (!__c(*__z, *__y)) // if y <= z + return __r; // x <= y && y <= z + // x <= y && y > z + _Ops::iter_swap(__y, __z); // x <= z && y < z + __r = 1; + if (__c(*__y, *__x)) // if x > y + { + _Ops::iter_swap(__x, __y); // x < y && y <= z + __r = 2; + } + return __r; // x <= y && y < z + } + if (__c(*__z, *__y)) // x > y, if y > z + { + _Ops::iter_swap(__x, __z); // x < y && y < z + __r = 1; + return __r; + } + _Ops::iter_swap(__x, __y); // x > y && y <= z + __r = 1; // x < y && x <= z + if (__c(*__z, *__y)) // if y > z + { + _Ops::iter_swap(__y, __z); // x <= y && y < z + __r = 2; + } + return __r; +} // x <= y && y <= z + +// stable, 3-6 compares, 0-5 swaps + +template +_LIBCPP_HIDE_FROM_ABI +unsigned __sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, _ForwardIterator __x4, + _Compare __c) { + using _Ops = _IterOps<_AlgPolicy>; + unsigned __r = std::__sort3<_AlgPolicy, _Compare>(__x1, __x2, __x3, __c); + if (__c(*__x4, *__x3)) { + _Ops::iter_swap(__x3, __x4); + ++__r; + if (__c(*__x3, *__x2)) { + _Ops::iter_swap(__x2, __x3); + ++__r; + if (__c(*__x2, *__x1)) { + _Ops::iter_swap(__x1, __x2); + ++__r; + } + } + } + return __r; +} + +// stable, 4-10 compares, 0-9 swaps + +template +_LIBCPP_HIDDEN unsigned __sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, + _ForwardIterator __x4, _ForwardIterator __x5, _WrappedComp __wrapped_comp) { + using _Unwrap = _UnwrapAlgPolicy<_WrappedComp>; + using _AlgPolicy = typename _Unwrap::_AlgPolicy; + using _Ops = _IterOps<_AlgPolicy>; + + using _Compare = typename _Unwrap::_Comp; + _Compare __c = _Unwrap::__get_comp(__wrapped_comp); + + unsigned __r = std::__sort4<_AlgPolicy, _Compare>(__x1, __x2, __x3, __x4, __c); + if (__c(*__x5, *__x4)) { + _Ops::iter_swap(__x4, __x5); + ++__r; + if (__c(*__x4, *__x3)) { + _Ops::iter_swap(__x3, __x4); + ++__r; + if (__c(*__x3, *__x2)) { + _Ops::iter_swap(__x2, __x3); + ++__r; + if (__c(*__x2, *__x1)) { + _Ops::iter_swap(__x1, __x2); + ++__r; + } + } + } + } + return __r; +} + +template +_LIBCPP_HIDE_FROM_ABI unsigned __sort5_wrap_policy( + _ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, _ForwardIterator __x4, _ForwardIterator __x5, + _Compare __c) { + using _WrappedComp = typename _WrapAlgPolicy<_AlgPolicy, _Compare>::type; + _WrappedComp __wrapped_comp(__c); + return std::__sort5<_WrappedComp, _ForwardIterator>( + std::move(__x1), std::move(__x2), std::move(__x3), std::move(__x4), std::move(__x5), __wrapped_comp); +} + +// The comparator being simple is a prerequisite for using the branchless optimization. +template +struct __is_simple_comparator : false_type {}; +template +struct __is_simple_comparator<__less<_Tp>&> : true_type {}; +template +struct __is_simple_comparator&> : true_type {}; +template +struct __is_simple_comparator&> : true_type {}; +#if _LIBCPP_STD_VER > 17 +template <> +struct __is_simple_comparator : true_type {}; +template <> +struct __is_simple_comparator : true_type {}; +#endif + +template ::value_type> +using __use_branchless_sort = + integral_constant::value && sizeof(_Tp) <= sizeof(void*) && + is_arithmetic<_Tp>::value && __is_simple_comparator<_Compare>::value>; + +namespace __detail { + +// Size in bits for the bitset in use. +enum { __block_size = sizeof(uint64_t) * 8 }; + +} // namespace __detail + +// Ensures that __c(*__x, *__y) is true by swapping *__x and *__y if necessary. +template +inline _LIBCPP_HIDE_FROM_ABI void __cond_swap(_RandomAccessIterator __x, _RandomAccessIterator __y, _Compare __c) { + // Note: this function behaves correctly even with proxy iterators (because it relies on `value_type`). + using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; + bool __r = __c(*__x, *__y); + value_type __tmp = __r ? *__x : *__y; + *__y = __r ? *__y : *__x; + *__x = __tmp; +} + +// Ensures that *__x, *__y and *__z are ordered according to the comparator __c, +// under the assumption that *__y and *__z are already ordered. +template +inline _LIBCPP_HIDE_FROM_ABI void __partially_sorted_swap(_RandomAccessIterator __x, _RandomAccessIterator __y, + _RandomAccessIterator __z, _Compare __c) { + // Note: this function behaves correctly even with proxy iterators (because it relies on `value_type`). + using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; + bool __r = __c(*__z, *__x); + value_type __tmp = __r ? *__z : *__x; + *__z = __r ? *__x : *__z; + __r = __c(__tmp, *__y); + *__x = __r ? *__x : *__y; + *__y = __r ? *__y : __tmp; +} + +template +inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>::value, void> +__sort3_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, + _Compare __c) { + std::__cond_swap<_Compare>(__x2, __x3, __c); + std::__partially_sorted_swap<_Compare>(__x1, __x2, __x3, __c); +} + +template +inline _LIBCPP_HIDE_FROM_ABI __enable_if_t::value, void> +__sort3_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, + _Compare __c) { + std::__sort3<_AlgPolicy, _Compare>(__x1, __x2, __x3, __c); +} + +template +inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>::value, void> +__sort4_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, + _RandomAccessIterator __x4, _Compare __c) { + std::__cond_swap<_Compare>(__x1, __x3, __c); + std::__cond_swap<_Compare>(__x2, __x4, __c); + std::__cond_swap<_Compare>(__x1, __x2, __c); + std::__cond_swap<_Compare>(__x3, __x4, __c); + std::__cond_swap<_Compare>(__x2, __x3, __c); +} + +template +inline _LIBCPP_HIDE_FROM_ABI __enable_if_t::value, void> +__sort4_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, + _RandomAccessIterator __x4, _Compare __c) { + std::__sort4<_AlgPolicy, _Compare>(__x1, __x2, __x3, __x4, __c); +} + +template +inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>::value, void> +__sort5_maybe_branchless( + _RandomAccessIterator __x1, + _RandomAccessIterator __x2, + _RandomAccessIterator __x3, + _RandomAccessIterator __x4, + _RandomAccessIterator __x5, + _Compare __c) { + std::__cond_swap<_Compare>(__x1, __x2, __c); + std::__cond_swap<_Compare>(__x4, __x5, __c); + std::__partially_sorted_swap<_Compare>(__x3, __x4, __x5, __c); + std::__cond_swap<_Compare>(__x2, __x5, __c); + std::__partially_sorted_swap<_Compare>(__x1, __x3, __x4, __c); + std::__partially_sorted_swap<_Compare>(__x2, __x3, __x4, __c); +} + +template +inline _LIBCPP_HIDE_FROM_ABI __enable_if_t::value, void> +__sort5_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, + _RandomAccessIterator __x4, _RandomAccessIterator __x5, _Compare __c) { + std::__sort5_wrap_policy<_AlgPolicy, _Compare>(__x1, __x2, __x3, __x4, __x5, __c); +} + +// Assumes size > 0 +template +_LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_SINCE_CXX14 void __selection_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, + _Compare __comp) { + _BidirectionalIterator __lm1 = __last; + for (--__lm1; __first != __lm1; ++__first) { + _BidirectionalIterator __i = std::__min_element<_Compare>(__first, __last, __comp); + if (__i != __first) + _IterOps<_AlgPolicy>::iter_swap(__first, __i); + } +} + +// Sort the iterator range [__first, __last) using the comparator __comp using +// the insertion sort algorithm. +template +_LIBCPP_HIDE_FROM_ABI +void __insertion_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { + using _Ops = _IterOps<_AlgPolicy>; + + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + if (__first == __last) + return; + _BidirectionalIterator __i = __first; + for (++__i; __i != __last; ++__i) { + _BidirectionalIterator __j = __i; + --__j; + if (__comp(*__i, *__j)) { + value_type __t(_Ops::__iter_move(__i)); + _BidirectionalIterator __k = __j; + __j = __i; + do { + *__j = _Ops::__iter_move(__k); + __j = __k; + } while (__j != __first && __comp(__t, *--__k)); + *__j = std::move(__t); + } + } +} + +// Sort the iterator range [__first, __last) using the comparator __comp using +// the insertion sort algorithm. Insertion sort has two loops, outer and inner. +// The implementation below has not bounds check (unguarded) for the inner loop. +// Assumes that there is an element in the position (__first - 1) and that each +// element in the input range is greater or equal to the element at __first - 1. +template +_LIBCPP_HIDE_FROM_ABI void +__insertion_sort_unguarded(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + using _Ops = _IterOps<_AlgPolicy>; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + if (__first == __last) + return; + for (_RandomAccessIterator __i = __first + difference_type(1); __i != __last; ++__i) { + _RandomAccessIterator __j = __i - difference_type(1); + if (__comp(*__i, *__j)) { + value_type __t(_Ops::__iter_move(__i)); + _RandomAccessIterator __k = __j; + __j = __i; + do { + *__j = _Ops::__iter_move(__k); + __j = __k; + } while (__comp(__t, *--__k)); // No need for bounds check due to the assumption stated above. + *__j = std::move(__t); + } + } +} + +template +_LIBCPP_HIDDEN bool __insertion_sort_incomplete( + _RandomAccessIterator __first, _RandomAccessIterator __last, _WrappedComp __wrapped_comp) { + using _Unwrap = _UnwrapAlgPolicy<_WrappedComp>; + using _AlgPolicy = typename _Unwrap::_AlgPolicy; + using _Ops = _IterOps<_AlgPolicy>; + + using _Compare = typename _Unwrap::_Comp; + _Compare __comp = _Unwrap::__get_comp(__wrapped_comp); + + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + switch (__last - __first) { + case 0: + case 1: + return true; + case 2: + if (__comp(*--__last, *__first)) + _Ops::iter_swap(__first, __last); + return true; + case 3: + std::__sort3_maybe_branchless<_AlgPolicy, _Compare>(__first, __first + difference_type(1), --__last, __comp); + return true; + case 4: + std::__sort4_maybe_branchless<_AlgPolicy, _Compare>( + __first, __first + difference_type(1), __first + difference_type(2), --__last, __comp); + return true; + case 5: + std::__sort5_maybe_branchless<_AlgPolicy, _Compare>( + __first, __first + difference_type(1), __first + difference_type(2), __first + difference_type(3), + --__last, __comp); + return true; + } + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + _RandomAccessIterator __j = __first + difference_type(2); + std::__sort3_maybe_branchless<_AlgPolicy, _Compare>(__first, __first + difference_type(1), __j, __comp); + const unsigned __limit = 8; + unsigned __count = 0; + for (_RandomAccessIterator __i = __j + difference_type(1); __i != __last; ++__i) { + if (__comp(*__i, *__j)) { + value_type __t(_Ops::__iter_move(__i)); + _RandomAccessIterator __k = __j; + __j = __i; + do { + *__j = _Ops::__iter_move(__k); + __j = __k; + } while (__j != __first && __comp(__t, *--__k)); + *__j = std::move(__t); + if (++__count == __limit) + return ++__i == __last; + } + __j = __i; + } + return true; +} + +template +_LIBCPP_HIDE_FROM_ABI +void __insertion_sort_move(_BidirectionalIterator __first1, _BidirectionalIterator __last1, + typename iterator_traits<_BidirectionalIterator>::value_type* __first2, _Compare __comp) { + using _Ops = _IterOps<_AlgPolicy>; + + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + if (__first1 != __last1) { + __destruct_n __d(0); + unique_ptr __h(__first2, __d); + value_type* __last2 = __first2; + ::new ((void*)__last2) value_type(_Ops::__iter_move(__first1)); + __d.template __incr(); + for (++__last2; ++__first1 != __last1; ++__last2) { + value_type* __j2 = __last2; + value_type* __i2 = __j2; + if (__comp(*__first1, *--__i2)) { + ::new ((void*)__j2) value_type(std::move(*__i2)); + __d.template __incr(); + for (--__j2; __i2 != __first2 && __comp(*__first1, *--__i2); --__j2) + *__j2 = std::move(*__i2); + *__j2 = _Ops::__iter_move(__first1); + } else { + ::new ((void*)__j2) value_type(_Ops::__iter_move(__first1)); + __d.template __incr(); + } + } + __h.release(); + } +} + +template +inline _LIBCPP_HIDE_FROM_ABI void __swap_bitmap_pos( + _RandomAccessIterator __first, _RandomAccessIterator __last, uint64_t& __left_bitset, uint64_t& __right_bitset) { + using _Ops = _IterOps<_AlgPolicy>; + typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type; + // Swap one pair on each iteration as long as both bitsets have at least one + // element for swapping. + while (__left_bitset != 0 && __right_bitset != 0) { + difference_type tz_left = __libcpp_ctz(__left_bitset); + __left_bitset = __libcpp_blsr(__left_bitset); + difference_type tz_right = __libcpp_ctz(__right_bitset); + __right_bitset = __libcpp_blsr(__right_bitset); + _Ops::iter_swap(__first + tz_left, __last - tz_right); + } +} + +template ::value_type> +inline _LIBCPP_HIDE_FROM_ABI void +__populate_left_bitset(_RandomAccessIterator __first, _Compare __comp, _ValueType& __pivot, uint64_t& __left_bitset) { + // Possible vectorization. With a proper "-march" flag, the following loop + // will be compiled into a set of SIMD instructions. + _RandomAccessIterator __iter = __first; + for (int __j = 0; __j < __detail::__block_size;) { + bool __comp_result = !__comp(*__iter, __pivot); + __left_bitset |= (static_cast(__comp_result) << __j); + __j++; + ++__iter; + } +} + +template ::value_type> +inline _LIBCPP_HIDE_FROM_ABI void +__populate_right_bitset(_RandomAccessIterator __lm1, _Compare __comp, _ValueType& __pivot, uint64_t& __right_bitset) { + // Possible vectorization. With a proper "-march" flag, the following loop + // will be compiled into a set of SIMD instructions. + _RandomAccessIterator __iter = __lm1; + for (int __j = 0; __j < __detail::__block_size;) { + bool __comp_result = __comp(*__iter, __pivot); + __right_bitset |= (static_cast(__comp_result) << __j); + __j++; + --__iter; + } +} + +template ::value_type> +inline _LIBCPP_HIDE_FROM_ABI void __bitset_partition_partial_blocks( + _RandomAccessIterator& __first, + _RandomAccessIterator& __lm1, + _Compare __comp, + _ValueType& __pivot, + uint64_t& __left_bitset, + uint64_t& __right_bitset) { + typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type; + difference_type __remaining_len = __lm1 - __first + 1; + difference_type __l_size; + difference_type __r_size; + if (__left_bitset == 0 && __right_bitset == 0) { + __l_size = __remaining_len / 2; + __r_size = __remaining_len - __l_size; + } else if (__left_bitset == 0) { + // We know at least one side is a full block. + __l_size = __remaining_len - __detail::__block_size; + __r_size = __detail::__block_size; + } else { // if (__right_bitset == 0) + __l_size = __detail::__block_size; + __r_size = __remaining_len - __detail::__block_size; + } + // Record the comparison outcomes for the elements currently on the left side. + if (__left_bitset == 0) { + _RandomAccessIterator __iter = __first; + for (int j = 0; j < __l_size; j++) { + bool __comp_result = !__comp(*__iter, __pivot); + __left_bitset |= (static_cast(__comp_result) << j); + ++__iter; + } + } + // Record the comparison outcomes for the elements currently on the right + // side. + if (__right_bitset == 0) { + _RandomAccessIterator __iter = __lm1; + for (int j = 0; j < __r_size; j++) { + bool __comp_result = __comp(*__iter, __pivot); + __right_bitset |= (static_cast(__comp_result) << j); + --__iter; + } + } + std::__swap_bitmap_pos<_AlgPolicy, _RandomAccessIterator>(__first, __lm1, __left_bitset, __right_bitset); + __first += (__left_bitset == 0) ? __l_size : 0; + __lm1 -= (__right_bitset == 0) ? __r_size : 0; +} + +template +inline _LIBCPP_HIDE_FROM_ABI void __swap_bitmap_pos_within( + _RandomAccessIterator& __first, _RandomAccessIterator& __lm1, uint64_t& __left_bitset, uint64_t& __right_bitset) { + using _Ops = _IterOps<_AlgPolicy>; + typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type; + if (__left_bitset) { + // Swap within the left side. Need to find set positions in the reverse + // order. + while (__left_bitset != 0) { + difference_type __tz_left = __detail::__block_size - 1 - __libcpp_clz(__left_bitset); + __left_bitset &= (static_cast(1) << __tz_left) - 1; + _RandomAccessIterator it = __first + __tz_left; + if (it != __lm1) { + _Ops::iter_swap(it, __lm1); + } + --__lm1; + } + __first = __lm1 + difference_type(1); + } else if (__right_bitset) { + // Swap within the right side. Need to find set positions in the reverse + // order. + while (__right_bitset != 0) { + difference_type __tz_right = __detail::__block_size - 1 - __libcpp_clz(__right_bitset); + __right_bitset &= (static_cast(1) << __tz_right) - 1; + _RandomAccessIterator it = __lm1 - __tz_right; + if (it != __first) { + _Ops::iter_swap(it, __first); + } + ++__first; + } + } +} + +// Partition [__first, __last) using the comparator __comp. *__first has the +// chosen pivot. Elements that are equivalent are kept to the left of the +// pivot. Returns the iterator for the pivot and a bool value which is true if +// the provided range is already sorted, false otherwise. We assume that the +// length of the range is at least three elements. +// +// __bitset_partition uses bitsets for storing outcomes of the comparisons +// between the pivot and other elements. +template +_LIBCPP_HIDE_FROM_ABI std::pair<_RandomAccessIterator, bool> +__bitset_partition(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + using _Ops = _IterOps<_AlgPolicy>; + typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type; + typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type; + _LIBCPP_ASSERT(__last - __first >= difference_type(3), ""); + + _RandomAccessIterator __begin = __first; + value_type __pivot(_Ops::__iter_move(__first)); + // Find the first element greater than the pivot. + if (__comp(__pivot, *(__last - difference_type(1)))) { + // Not guarded since we know the last element is greater than the pivot. + while (!__comp(__pivot, *++__first)) { + } + } else { + while (++__first < __last && !__comp(__pivot, *__first)) { + } + } + // Find the last element less than or equal to the pivot. + if (__first < __last) { + // It will be always guarded because __introsort will do the median-of-three + // before calling this. + while (__comp(__pivot, *--__last)) { + } + } + // If the first element greater than the pivot is at or after the + // last element less than or equal to the pivot, then we have covered the + // entire range without swapping elements. This implies the range is already + // partitioned. + bool __already_partitioned = __first >= __last; + if (!__already_partitioned) { + _Ops::iter_swap(__first, __last); + ++__first; + } + + // In [__first, __last) __last is not inclusive. From now on, it uses last + // minus one to be inclusive on both sides. + _RandomAccessIterator __lm1 = __last - difference_type(1); + uint64_t __left_bitset = 0; + uint64_t __right_bitset = 0; + + // Reminder: length = __lm1 - __first + 1. + while (__lm1 - __first >= 2 * __detail::__block_size - 1) { + // Record the comparison outcomes for the elements currently on the left + // side. + if (__left_bitset == 0) + std::__populate_left_bitset<_Compare>(__first, __comp, __pivot, __left_bitset); + // Record the comparison outcomes for the elements currently on the right + // side. + if (__right_bitset == 0) + std::__populate_right_bitset<_Compare>(__lm1, __comp, __pivot, __right_bitset); + // Swap the elements recorded to be the candidates for swapping in the + // bitsets. + std::__swap_bitmap_pos<_AlgPolicy, _RandomAccessIterator>(__first, __lm1, __left_bitset, __right_bitset); + // Only advance the iterator if all the elements that need to be moved to + // other side were moved. + __first += (__left_bitset == 0) ? difference_type(__detail::__block_size) : difference_type(0); + __lm1 -= (__right_bitset == 0) ? difference_type(__detail::__block_size) : difference_type(0); + } + // Now, we have a less-than a block worth of elements on at least one of the + // sides. + std::__bitset_partition_partial_blocks<_AlgPolicy, _Compare>( + __first, __lm1, __comp, __pivot, __left_bitset, __right_bitset); + // At least one the bitsets would be empty. For the non-empty one, we need to + // properly partition the elements that appear within that bitset. + std::__swap_bitmap_pos_within<_AlgPolicy>(__first, __lm1, __left_bitset, __right_bitset); + + // Move the pivot to its correct position. + _RandomAccessIterator __pivot_pos = __first - difference_type(1); + if (__begin != __pivot_pos) { + *__begin = _Ops::__iter_move(__pivot_pos); + } + *__pivot_pos = std::move(__pivot); + return std::make_pair(__pivot_pos, __already_partitioned); +} + +// Partition [__first, __last) using the comparator __comp. *__first has the +// chosen pivot. Elements that are equivalent are kept to the right of the +// pivot. Returns the iterator for the pivot and a bool value which is true if +// the provided range is already sorted, false otherwise. We assume that the +// length of the range is at least three elements. +template +_LIBCPP_HIDE_FROM_ABI std::pair<_RandomAccessIterator, bool> +__partition_with_equals_on_right(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + using _Ops = _IterOps<_AlgPolicy>; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type; + _LIBCPP_ASSERT(__last - __first >= difference_type(3), ""); + _RandomAccessIterator __begin = __first; + value_type __pivot(_Ops::__iter_move(__first)); + // Find the first element greater or equal to the pivot. It will be always + // guarded because __introsort will do the median-of-three before calling + // this. + while (__comp(*++__first, __pivot)) + ; + + // Find the last element less than the pivot. + if (__begin == __first - difference_type(1)) { + while (__first < __last && !__comp(*--__last, __pivot)) + ; + } else { + // Guarded. + while (!__comp(*--__last, __pivot)) + ; + } + + // If the first element greater than or equal to the pivot is at or after the + // last element less than the pivot, then we have covered the entire range + // without swapping elements. This implies the range is already partitioned. + bool __already_partitioned = __first >= __last; + // Go through the remaining elements. Swap pairs of elements (one to the + // right of the pivot and the other to left of the pivot) that are not on the + // correct side of the pivot. + while (__first < __last) { + _Ops::iter_swap(__first, __last); + while (__comp(*++__first, __pivot)) + ; + while (!__comp(*--__last, __pivot)) + ; + } + // Move the pivot to its correct position. + _RandomAccessIterator __pivot_pos = __first - difference_type(1); + if (__begin != __pivot_pos) { + *__begin = _Ops::__iter_move(__pivot_pos); + } + *__pivot_pos = std::move(__pivot); + return std::make_pair(__pivot_pos, __already_partitioned); +} + +// Similar to the above function. Elements equivalent to the pivot are put to +// the left of the pivot. Returns the iterator to the pivot element. +template +_LIBCPP_HIDE_FROM_ABI _RandomAccessIterator +__partition_with_equals_on_left(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + using _Ops = _IterOps<_AlgPolicy>; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type; + _RandomAccessIterator __begin = __first; + value_type __pivot(_Ops::__iter_move(__first)); + if (__comp(__pivot, *(__last - difference_type(1)))) { + // Guarded. + while (!__comp(__pivot, *++__first)) { + } + } else { + while (++__first < __last && !__comp(__pivot, *__first)) { + } + } + + if (__first < __last) { + // It will be always guarded because __introsort will do the + // median-of-three before calling this. + while (__comp(__pivot, *--__last)) { + } + } + while (__first < __last) { + _Ops::iter_swap(__first, __last); + while (!__comp(__pivot, *++__first)) + ; + while (__comp(__pivot, *--__last)) + ; + } + _RandomAccessIterator __pivot_pos = __first - difference_type(1); + if (__begin != __pivot_pos) { + *__begin = _Ops::__iter_move(__pivot_pos); + } + *__pivot_pos = std::move(__pivot); + return __first; +} + +// The main sorting function. Implements introsort combined with other ideas: +// - option of using block quick sort for partitioning, +// - guarded and unguarded insertion sort for small lengths, +// - Tuckey's ninther technique for computing the pivot, +// - check on whether partition was not required. +// The implementation is partly based on Orson Peters' pattern-defeating +// quicksort, published at: . +template +void __introsort(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Compare __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __depth, + bool __leftmost = true) { + using _Ops = _IterOps<_AlgPolicy>; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + using _Comp_ref = __comp_ref_type<_Compare>; + // Upper bound for using insertion sort for sorting. + _LIBCPP_CONSTEXPR difference_type __limit = 24; + // Lower bound for using Tuckey's ninther technique for median computation. + _LIBCPP_CONSTEXPR difference_type __ninther_threshold = 128; + while (true) { + difference_type __len = __last - __first; + switch (__len) { + case 0: + case 1: + return; + case 2: + if (__comp(*--__last, *__first)) + _Ops::iter_swap(__first, __last); + return; + case 3: + std::__sort3_maybe_branchless<_AlgPolicy, _Compare>(__first, __first + difference_type(1), --__last, __comp); + return; + case 4: + std::__sort4_maybe_branchless<_AlgPolicy, _Compare>( + __first, __first + difference_type(1), __first + difference_type(2), --__last, __comp); + return; + case 5: + std::__sort5_maybe_branchless<_AlgPolicy, _Compare>( + __first, __first + difference_type(1), __first + difference_type(2), __first + difference_type(3), + --__last, __comp); + return; + } + // Use insertion sort if the length of the range is below the specified limit. + if (__len < __limit) { + if (__leftmost) { + std::__insertion_sort<_AlgPolicy, _Compare>(__first, __last, __comp); + } else { + std::__insertion_sort_unguarded<_AlgPolicy, _Compare>(__first, __last, __comp); + } + return; + } + if (__depth == 0) { + // Fallback to heap sort as Introsort suggests. + std::__partial_sort<_AlgPolicy, _Compare>(__first, __last, __last, __comp); + return; + } + --__depth; + { + difference_type __half_len = __len / 2; + // Use Tuckey's ninther technique or median of 3 for pivot selection + // depending on the length of the range being sorted. + if (__len > __ninther_threshold) { + std::__sort3<_AlgPolicy, _Compare>(__first, __first + __half_len, __last - difference_type(1), __comp); + std::__sort3<_AlgPolicy, _Compare>( + __first + difference_type(1), __first + (__half_len - 1), __last - difference_type(2), __comp); + std::__sort3<_AlgPolicy, _Compare>( + __first + difference_type(2), __first + (__half_len + 1), __last - difference_type(3), __comp); + std::__sort3<_AlgPolicy, _Compare>( + __first + (__half_len - 1), __first + __half_len, __first + (__half_len + 1), __comp); + _Ops::iter_swap(__first, __first + __half_len); + } else { + std::__sort3<_AlgPolicy, _Compare>(__first + __half_len, __first, __last - difference_type(1), __comp); + } + } + // The elements to the left of the current iterator range are already + // sorted. If the current iterator range to be sorted is not the + // leftmost part of the entire iterator range and the pivot is same as + // the highest element in the range to the left, then we know that all + // the elements in the range [first, pivot] would be equal to the pivot, + // assuming the equal elements are put on the left side when + // partitioned. This also means that we do not need to sort the left + // side of the partition. + if (!__leftmost && !__comp(*(__first - difference_type(1)), *__first)) { + __first = std::__partition_with_equals_on_left<_AlgPolicy, _RandomAccessIterator, _Comp_ref>( + __first, __last, _Comp_ref(__comp)); + continue; + } + // Use bitset partition only if asked for. + auto __ret = + _UseBitSetPartition + ? std::__bitset_partition<_AlgPolicy, _RandomAccessIterator, _Compare>(__first, __last, __comp) + : std::__partition_with_equals_on_right<_AlgPolicy, _RandomAccessIterator, _Compare>(__first, __last, __comp); + _RandomAccessIterator __i = __ret.first; + // [__first, __i) < *__i and *__i <= [__i+1, __last) + // If we were given a perfect partition, see if insertion sort is quick... + if (__ret.second) { + using _WrappedComp = typename _WrapAlgPolicy<_AlgPolicy, _Compare>::type; + _WrappedComp __wrapped_comp(__comp); + bool __fs = std::__insertion_sort_incomplete<_WrappedComp>(__first, __i, __wrapped_comp); + if (std::__insertion_sort_incomplete<_WrappedComp>(__i + difference_type(1), __last, __wrapped_comp)) { + if (__fs) + return; + __last = __i; + continue; + } else { + if (__fs) { + __first = ++__i; + continue; + } + } + } + // Sort the left partiton recursively and the right partition with tail recursion elimination. + std::__introsort<_AlgPolicy, _Compare, _RandomAccessIterator, _UseBitSetPartition>( + __first, __i, __comp, __depth, __leftmost); + __leftmost = false; + __first = ++__i; + } +} + +template +inline _LIBCPP_HIDE_FROM_ABI _Number __log2i(_Number __n) { + if (__n == 0) + return 0; + if (sizeof(__n) <= sizeof(unsigned)) + return sizeof(unsigned) * CHAR_BIT - 1 - __libcpp_clz(static_cast(__n)); + if (sizeof(__n) <= sizeof(unsigned long)) + return sizeof(unsigned long) * CHAR_BIT - 1 - __libcpp_clz(static_cast(__n)); + if (sizeof(__n) <= sizeof(unsigned long long)) + return sizeof(unsigned long long) * CHAR_BIT - 1 - __libcpp_clz(static_cast(__n)); + + _Number __log2 = 0; + while (__n > 1) { + __log2++; + __n >>= 1; + } + return __log2; +} + +template +_LIBCPP_HIDDEN void __sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _WrappedComp __wrapped_comp) { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + difference_type __depth_limit = 2 * std::__log2i(__last - __first); + + using _Unwrap = _UnwrapAlgPolicy<_WrappedComp>; + using _AlgPolicy = typename _Unwrap::_AlgPolicy; + using _Compare = typename _Unwrap::_Comp; + _Compare __comp = _Unwrap::__get_comp(__wrapped_comp); + // Only use bitset partitioning for arithmetic types. We should also check + // that the default comparator is in use so that we are sure that there are no + // branches in the comparator. + std::__introsort<_AlgPolicy, + _Compare, + _RandomAccessIterator, + __use_branchless_sort<_Compare, _RandomAccessIterator>::value>( + __first, __last, __comp, __depth_limit); +} + +template +inline _LIBCPP_INLINE_VISIBILITY void __sort(_Tp** __first, _Tp** __last, __less<_Tp*>&) { + __less __comp; + std::__sort<__less&, uintptr_t*>((uintptr_t*)__first, (uintptr_t*)__last, __comp); +} + +extern template _LIBCPP_FUNC_VIS void __sort<__less&, char*>(char*, char*, __less&); +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +extern template _LIBCPP_FUNC_VIS void __sort<__less&, wchar_t*>(wchar_t*, wchar_t*, __less&); +#endif +extern template _LIBCPP_FUNC_VIS void __sort<__less&, signed char*>(signed char*, signed char*, __less&); +extern template _LIBCPP_FUNC_VIS void __sort<__less&, unsigned char*>(unsigned char*, unsigned char*, __less&); +extern template _LIBCPP_FUNC_VIS void __sort<__less&, short*>(short*, short*, __less&); +extern template _LIBCPP_FUNC_VIS void __sort<__less&, unsigned short*>(unsigned short*, unsigned short*, __less&); +extern template _LIBCPP_FUNC_VIS void __sort<__less&, int*>(int*, int*, __less&); +extern template _LIBCPP_FUNC_VIS void __sort<__less&, unsigned*>(unsigned*, unsigned*, __less&); +extern template _LIBCPP_FUNC_VIS void __sort<__less&, long*>(long*, long*, __less&); +extern template _LIBCPP_FUNC_VIS void __sort<__less&, unsigned long*>(unsigned long*, unsigned long*, __less&); +extern template _LIBCPP_FUNC_VIS void __sort<__less&, long long*>(long long*, long long*, __less&); +extern template _LIBCPP_FUNC_VIS void __sort<__less&, unsigned long long*>(unsigned long long*, unsigned long long*, __less&); +extern template _LIBCPP_FUNC_VIS void __sort<__less&, float*>(float*, float*, __less&); +extern template _LIBCPP_FUNC_VIS void __sort<__less&, double*>(double*, double*, __less&); +extern template _LIBCPP_FUNC_VIS void __sort<__less&, long double*>(long double*, long double*, __less&); + +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, char*>(char*, char*, __less&); +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, wchar_t*>(wchar_t*, wchar_t*, __less&); +#endif +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, signed char*>(signed char*, signed char*, __less&); +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned char*>(unsigned char*, unsigned char*, __less&); +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, short*>(short*, short*, __less&); +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned short*>(unsigned short*, unsigned short*, __less&); +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, int*>(int*, int*, __less&); +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned*>(unsigned*, unsigned*, __less&); +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, long*>(long*, long*, __less&); +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned long*>(unsigned long*, unsigned long*, __less&); +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, long long*>(long long*, long long*, __less&); +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned long long*>(unsigned long long*, unsigned long long*, __less&); +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, float*>(float*, float*, __less&); +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, double*>(double*, double*, __less&); +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, long double*>(long double*, long double*, __less&); + +extern template _LIBCPP_FUNC_VIS unsigned __sort5<__less&, long double*>(long double*, long double*, long double*, long double*, long double*, __less&); + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void __sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) { + std::__debug_randomize_range<_AlgPolicy>(__first, __last); + + using _Comp_ref = __comp_ref_type<_Comp>; + if (__libcpp_is_constant_evaluated()) { + std::__partial_sort<_AlgPolicy>(__first, __last, __last, __comp); + + } else { + using _WrappedComp = typename _WrapAlgPolicy<_AlgPolicy, _Comp_ref>::type; + _Comp_ref __comp_ref(__comp); + _WrappedComp __wrapped_comp(__comp_ref); + std::__sort<_WrappedComp>(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __wrapped_comp); + } +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) { + std::__sort_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void sort(_RandomAccessIterator __first, _RandomAccessIterator __last) { + std::sort(__first, __last, __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SORT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/sort_heap.h b/app/src/main/cpp/libcxx/include/__algorithm/sort_heap.h new file mode 100644 index 0000000..8249407 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/sort_heap.h @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_SORT_HEAP_H +#define _LIBCPP___ALGORITHM_SORT_HEAP_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/pop_heap.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +void __sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) { + __comp_ref_type<_Compare> __comp_ref = __comp; + + using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; + for (difference_type __n = __last - __first; __n > 1; --__last, (void) --__n) + std::__pop_heap<_AlgPolicy>(__first, __last, __comp_ref, __n); +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible."); + static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable."); + + std::__sort_heap<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { + std::sort_heap(std::move(__first), std::move(__last), + __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SORT_HEAP_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/stable_partition.h b/app/src/main/cpp/libcxx/include/__algorithm/stable_partition.h new file mode 100644 index 0000000..a49de6d --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/stable_partition.h @@ -0,0 +1,329 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_STABLE_PARTITION_H +#define _LIBCPP___ALGORITHM_STABLE_PARTITION_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/rotate.h> +#include <__config> +#include <__iterator/advance.h> +#include <__iterator/distance.h> +#include <__iterator/iterator_traits.h> +#include <__memory/destruct_n.h> +#include <__memory/temporary_buffer.h> +#include <__memory/unique_ptr.h> +#include <__utility/move.h> +#include <__utility/pair.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _ForwardIterator +__stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, + _Distance __len, _Pair __p, forward_iterator_tag __fit) +{ + using _Ops = _IterOps<_AlgPolicy>; + + // *__first is known to be false + // __len >= 1 + if (__len == 1) + return __first; + if (__len == 2) + { + _ForwardIterator __m = __first; + if (__pred(*++__m)) + { + _Ops::iter_swap(__first, __m); + return __m; + } + return __first; + } + if (__len <= __p.second) + { // The buffer is big enough to use + typedef typename iterator_traits<_ForwardIterator>::value_type value_type; + __destruct_n __d(0); + unique_ptr __h(__p.first, __d); + // Move the falses into the temporary buffer, and the trues to the front of the line + // Update __first to always point to the end of the trues + value_type* __t = __p.first; + ::new ((void*)__t) value_type(_Ops::__iter_move(__first)); + __d.template __incr(); + ++__t; + _ForwardIterator __i = __first; + while (++__i != __last) + { + if (__pred(*__i)) + { + *__first = _Ops::__iter_move(__i); + ++__first; + } + else + { + ::new ((void*)__t) value_type(_Ops::__iter_move(__i)); + __d.template __incr(); + ++__t; + } + } + // All trues now at start of range, all falses in buffer + // Move falses back into range, but don't mess up __first which points to first false + __i = __first; + for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void) ++__i) + *__i = _Ops::__iter_move(__t2); + // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer + return __first; + } + // Else not enough buffer, do in place + // __len >= 3 + _ForwardIterator __m = __first; + _Distance __len2 = __len / 2; // __len2 >= 2 + _Ops::advance(__m, __len2); + // recurse on [__first, __m), *__first know to be false + // F????????????????? + // f m l + _ForwardIterator __first_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>( + __first, __m, __pred, __len2, __p, __fit); + // TTTFFFFF?????????? + // f ff m l + // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true + _ForwardIterator __m1 = __m; + _ForwardIterator __second_false = __last; + _Distance __len_half = __len - __len2; + while (__pred(*__m1)) + { + if (++__m1 == __last) + goto __second_half_done; + --__len_half; + } + // TTTFFFFFTTTF?????? + // f ff m m1 l + __second_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>( + __m1, __last, __pred, __len_half, __p, __fit); +__second_half_done: + // TTTFFFFFTTTTTFFFFF + // f ff m sf l + return std::__rotate<_AlgPolicy>(__first_false, __m, __second_false).first; + // TTTTTTTTFFFFFFFFFF + // | +} + +template +_LIBCPP_HIDE_FROM_ABI _ForwardIterator +__stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, + forward_iterator_tag) +{ + const unsigned __alloc_limit = 3; // might want to make this a function of trivial assignment + // Either prove all true and return __first or point to first false + while (true) + { + if (__first == __last) + return __first; + if (!__pred(*__first)) + break; + ++__first; + } + // We now have a reduced range [__first, __last) + // *__first is known to be false + typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; + typedef typename iterator_traits<_ForwardIterator>::value_type value_type; + difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last); + pair __p(0, 0); + unique_ptr __h; + if (__len >= __alloc_limit) + { +// TODO: Remove the use of std::get_temporary_buffer +_LIBCPP_SUPPRESS_DEPRECATED_PUSH + __p = _VSTD::get_temporary_buffer(__len); +_LIBCPP_SUPPRESS_DEPRECATED_POP + __h.reset(__p.first); + } + return std::__stable_partition_impl<_AlgPolicy, _Predicate&>( + std::move(__first), std::move(__last), __pred, __len, __p, forward_iterator_tag()); +} + +template +_BidirectionalIterator +__stable_partition_impl(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, + _Distance __len, _Pair __p, bidirectional_iterator_tag __bit) +{ + using _Ops = _IterOps<_AlgPolicy>; + + // *__first is known to be false + // *__last is known to be true + // __len >= 2 + if (__len == 2) + { + _Ops::iter_swap(__first, __last); + return __last; + } + if (__len == 3) + { + _BidirectionalIterator __m = __first; + if (__pred(*++__m)) + { + _Ops::iter_swap(__first, __m); + _Ops::iter_swap(__m, __last); + return __last; + } + _Ops::iter_swap(__m, __last); + _Ops::iter_swap(__first, __m); + return __m; + } + if (__len <= __p.second) + { // The buffer is big enough to use + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + __destruct_n __d(0); + unique_ptr __h(__p.first, __d); + // Move the falses into the temporary buffer, and the trues to the front of the line + // Update __first to always point to the end of the trues + value_type* __t = __p.first; + ::new ((void*)__t) value_type(_Ops::__iter_move(__first)); + __d.template __incr(); + ++__t; + _BidirectionalIterator __i = __first; + while (++__i != __last) + { + if (__pred(*__i)) + { + *__first = _Ops::__iter_move(__i); + ++__first; + } + else + { + ::new ((void*)__t) value_type(_Ops::__iter_move(__i)); + __d.template __incr(); + ++__t; + } + } + // move *__last, known to be true + *__first = _Ops::__iter_move(__i); + __i = ++__first; + // All trues now at start of range, all falses in buffer + // Move falses back into range, but don't mess up __first which points to first false + for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void) ++__i) + *__i = _Ops::__iter_move(__t2); + // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer + return __first; + } + // Else not enough buffer, do in place + // __len >= 4 + _BidirectionalIterator __m = __first; + _Distance __len2 = __len / 2; // __len2 >= 2 + _Ops::advance(__m, __len2); + // recurse on [__first, __m-1], except reduce __m-1 until *(__m-1) is true, *__first know to be false + // F????????????????T + // f m l + _BidirectionalIterator __m1 = __m; + _BidirectionalIterator __first_false = __first; + _Distance __len_half = __len2; + while (!__pred(*--__m1)) + { + if (__m1 == __first) + goto __first_half_done; + --__len_half; + } + // F???TFFF?????????T + // f m1 m l + __first_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>( + __first, __m1, __pred, __len_half, __p, __bit); +__first_half_done: + // TTTFFFFF?????????T + // f ff m l + // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true + __m1 = __m; + _BidirectionalIterator __second_false = __last; + ++__second_false; + __len_half = __len - __len2; + while (__pred(*__m1)) + { + if (++__m1 == __last) + goto __second_half_done; + --__len_half; + } + // TTTFFFFFTTTF?????T + // f ff m m1 l + __second_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>( + __m1, __last, __pred, __len_half, __p, __bit); +__second_half_done: + // TTTFFFFFTTTTTFFFFF + // f ff m sf l + return std::__rotate<_AlgPolicy>(__first_false, __m, __second_false).first; + // TTTTTTTTFFFFFFFFFF + // | +} + +template +_LIBCPP_HIDE_FROM_ABI _BidirectionalIterator +__stable_partition_impl(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, + bidirectional_iterator_tag) +{ + typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + const difference_type __alloc_limit = 4; // might want to make this a function of trivial assignment + // Either prove all true and return __first or point to first false + while (true) + { + if (__first == __last) + return __first; + if (!__pred(*__first)) + break; + ++__first; + } + // __first points to first false, everything prior to __first is already set. + // Either prove [__first, __last) is all false and return __first, or point __last to last true + do + { + if (__first == --__last) + return __first; + } while (!__pred(*__last)); + // We now have a reduced range [__first, __last] + // *__first is known to be false + // *__last is known to be true + // __len >= 2 + difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last) + 1; + pair __p(0, 0); + unique_ptr __h; + if (__len >= __alloc_limit) + { +// TODO: Remove the use of std::get_temporary_buffer +_LIBCPP_SUPPRESS_DEPRECATED_PUSH + __p = _VSTD::get_temporary_buffer(__len); +_LIBCPP_SUPPRESS_DEPRECATED_POP + __h.reset(__p.first); + } + return std::__stable_partition_impl<_AlgPolicy, _Predicate&>( + std::move(__first), std::move(__last), __pred, __len, __p, bidirectional_iterator_tag()); +} + +template +_LIBCPP_HIDE_FROM_ABI +_ForwardIterator __stable_partition( + _ForwardIterator __first, _ForwardIterator __last, _Predicate&& __pred, _IterCategory __iter_category) { + return std::__stable_partition_impl<_AlgPolicy, __remove_cvref_t<_Predicate>&>( + std::move(__first), std::move(__last), __pred, __iter_category); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator +stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) +{ + using _IterCategory = typename iterator_traits<_ForwardIterator>::iterator_category; + return std::__stable_partition<_ClassicAlgPolicy, _Predicate&>( + std::move(__first), std::move(__last), __pred, _IterCategory()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_STABLE_PARTITION_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/stable_sort.h b/app/src/main/cpp/libcxx/include/__algorithm/stable_sort.h new file mode 100644 index 0000000..8e70978 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/stable_sort.h @@ -0,0 +1,247 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_STABLE_SORT_H +#define _LIBCPP___ALGORITHM_STABLE_SORT_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/inplace_merge.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/sort.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__memory/destruct_n.h> +#include <__memory/temporary_buffer.h> +#include <__memory/unique_ptr.h> +#include <__utility/move.h> +#include <__utility/pair.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI void +__merge_move_construct(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + typename iterator_traits<_InputIterator1>::value_type* __result, _Compare __comp) +{ + using _Ops = _IterOps<_AlgPolicy>; + + typedef typename iterator_traits<_InputIterator1>::value_type value_type; + __destruct_n __d(0); + unique_ptr __h(__result, __d); + for (; true; ++__result) + { + if (__first1 == __last1) + { + for (; __first2 != __last2; ++__first2, (void) ++__result, __d.template __incr()) + ::new ((void*)__result) value_type(_Ops::__iter_move(__first2)); + __h.release(); + return; + } + if (__first2 == __last2) + { + for (; __first1 != __last1; ++__first1, (void) ++__result, __d.template __incr()) + ::new ((void*)__result) value_type(_Ops::__iter_move(__first1)); + __h.release(); + return; + } + if (__comp(*__first2, *__first1)) + { + ::new ((void*)__result) value_type(_Ops::__iter_move(__first2)); + __d.template __incr(); + ++__first2; + } + else + { + ::new ((void*)__result) value_type(_Ops::__iter_move(__first1)); + __d.template __incr(); + ++__first1; + } + } +} + +template +_LIBCPP_HIDE_FROM_ABI void +__merge_move_assign(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) +{ + using _Ops = _IterOps<_AlgPolicy>; + + for (; __first1 != __last1; ++__result) + { + if (__first2 == __last2) + { + for (; __first1 != __last1; ++__first1, (void) ++__result) + *__result = _Ops::__iter_move(__first1); + return; + } + if (__comp(*__first2, *__first1)) + { + *__result = _Ops::__iter_move(__first2); + ++__first2; + } + else + { + *__result = _Ops::__iter_move(__first1); + ++__first1; + } + } + for (; __first2 != __last2; ++__first2, (void) ++__result) + *__result = _Ops::__iter_move(__first2); +} + +template +void +__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len, + typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size); + +template +void +__stable_sort_move(_RandomAccessIterator __first1, _RandomAccessIterator __last1, _Compare __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len, + typename iterator_traits<_RandomAccessIterator>::value_type* __first2) +{ + using _Ops = _IterOps<_AlgPolicy>; + + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + switch (__len) + { + case 0: + return; + case 1: + ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1)); + return; + case 2: + __destruct_n __d(0); + unique_ptr __h2(__first2, __d); + if (__comp(*--__last1, *__first1)) + { + ::new ((void*)__first2) value_type(_Ops::__iter_move(__last1)); + __d.template __incr(); + ++__first2; + ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1)); + } + else + { + ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1)); + __d.template __incr(); + ++__first2; + ::new ((void*)__first2) value_type(_Ops::__iter_move(__last1)); + } + __h2.release(); + return; + } + if (__len <= 8) + { + std::__insertion_sort_move<_AlgPolicy, _Compare>(__first1, __last1, __first2, __comp); + return; + } + typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; + _RandomAccessIterator __m = __first1 + __l2; + std::__stable_sort<_AlgPolicy, _Compare>(__first1, __m, __comp, __l2, __first2, __l2); + std::__stable_sort<_AlgPolicy, _Compare>(__m, __last1, __comp, __len - __l2, __first2 + __l2, __len - __l2); + std::__merge_move_construct<_AlgPolicy, _Compare>(__first1, __m, __m, __last1, __first2, __comp); +} + +template +struct __stable_sort_switch +{ + static const unsigned value = 128*is_trivially_copy_assignable<_Tp>::value; +}; + +template +void +__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len, + typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size) +{ + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + switch (__len) + { + case 0: + case 1: + return; + case 2: + if (__comp(*--__last, *__first)) + _IterOps<_AlgPolicy>::iter_swap(__first, __last); + return; + } + if (__len <= static_cast(__stable_sort_switch::value)) + { + std::__insertion_sort<_AlgPolicy, _Compare>(__first, __last, __comp); + return; + } + typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; + _RandomAccessIterator __m = __first + __l2; + if (__len <= __buff_size) + { + __destruct_n __d(0); + unique_ptr __h2(__buff, __d); + std::__stable_sort_move<_AlgPolicy, _Compare>(__first, __m, __comp, __l2, __buff); + __d.__set(__l2, (value_type*)nullptr); + std::__stable_sort_move<_AlgPolicy, _Compare>(__m, __last, __comp, __len - __l2, __buff + __l2); + __d.__set(__len, (value_type*)nullptr); + std::__merge_move_assign<_AlgPolicy, _Compare>( + __buff, __buff + __l2, __buff + __l2, __buff + __len, __first, __comp); +// _VSTD::__merge<_Compare>(move_iterator(__buff), +// move_iterator(__buff + __l2), +// move_iterator<_RandomAccessIterator>(__buff + __l2), +// move_iterator<_RandomAccessIterator>(__buff + __len), +// __first, __comp); + return; + } + std::__stable_sort<_AlgPolicy, _Compare>(__first, __m, __comp, __l2, __buff, __buff_size); + std::__stable_sort<_AlgPolicy, _Compare>(__m, __last, __comp, __len - __l2, __buff, __buff_size); + std::__inplace_merge<_AlgPolicy>(__first, __m, __last, __comp, __l2, __len - __l2, __buff, __buff_size); +} + +template +inline _LIBCPP_HIDE_FROM_ABI +void __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) { + using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; + using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; + + difference_type __len = __last - __first; + pair __buf(0, 0); + unique_ptr __h; + if (__len > static_cast(__stable_sort_switch::value)) { +// TODO: Remove the use of std::get_temporary_buffer +_LIBCPP_SUPPRESS_DEPRECATED_PUSH + __buf = std::get_temporary_buffer(__len); +_LIBCPP_SUPPRESS_DEPRECATED_POP + __h.reset(__buf.first); + } + + std::__stable_sort<_AlgPolicy, __comp_ref_type<_Compare> >(__first, __last, __comp, __len, __buf.first, __buf.second); +} + +template +inline _LIBCPP_HIDE_FROM_ABI +void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + std::__stable_sort_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); +} + +template +inline _LIBCPP_HIDE_FROM_ABI +void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) { + std::stable_sort(__first, __last, __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_STABLE_SORT_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/swap_ranges.h b/app/src/main/cpp/libcxx/include/__algorithm/swap_ranges.h new file mode 100644 index 0000000..5ce5ed8 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/swap_ranges.h @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_SWAP_RANGES_H +#define _LIBCPP___ALGORITHM_SWAP_RANGES_H + +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// 2+2 iterators: the shorter size will be used. +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +pair<_ForwardIterator1, _ForwardIterator2> +__swap_ranges(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2, _Sentinel2 __last2) { + while (__first1 != __last1 && __first2 != __last2) { + _IterOps<_AlgPolicy>::iter_swap(__first1, __first2); + ++__first1; + ++__first2; + } + + return pair<_ForwardIterator1, _ForwardIterator2>(std::move(__first1), std::move(__first2)); +} + +// 2+1 iterators: size2 >= size1. +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +pair<_ForwardIterator1, _ForwardIterator2> +__swap_ranges(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2) { + while (__first1 != __last1) { + _IterOps<_AlgPolicy>::iter_swap(__first1, __first2); + ++__first1; + ++__first2; + } + + return pair<_ForwardIterator1, _ForwardIterator2>(std::move(__first1), std::move(__first2)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator2 +swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { + return std::__swap_ranges<_ClassicAlgPolicy>( + std::move(__first1), std::move(__last1), std::move(__first2)).second; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SWAP_RANGES_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/transform.h b/app/src/main/cpp/libcxx/include/__algorithm/transform.h new file mode 100644 index 0000000..4722c15 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/transform.h @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_TRANSFORM_H +#define _LIBCPP___ALGORITHM_TRANSFORM_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +_OutputIterator +transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op) +{ + for (; __first != __last; ++__first, (void) ++__result) + *__result = __op(*__first); + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +_OutputIterator +transform(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, + _OutputIterator __result, _BinaryOperation __binary_op) +{ + for (; __first1 != __last1; ++__first1, (void) ++__first2, ++__result) + *__result = __binary_op(*__first1, *__first2); + return __result; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_TRANSFORM_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/uniform_random_bit_generator_adaptor.h b/app/src/main/cpp/libcxx/include/__algorithm/uniform_random_bit_generator_adaptor.h new file mode 100644 index 0000000..1e86074 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/uniform_random_bit_generator_adaptor.h @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_UNIFORM_RANDOM_BIT_GENERATOR_ADAPTOR_H +#define _LIBCPP___ALGORITHM_RANGES_UNIFORM_RANDOM_BIT_GENERATOR_ADAPTOR_H + +#include <__config> +#include <__functional/invoke.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Range versions of random algorithms (e.g. `std::shuffle`) are less constrained than their classic counterparts. +// Range algorithms only require the given generator to satisfy the `std::uniform_random_bit_generator` concept. +// Classic algorithms require the given generator to meet the uniform random bit generator requirements; these +// requirements include satisfying `std::uniform_random_bit_generator` and add a requirement for the generator to +// provide a nested `result_type` typedef (see `[rand.req.urng]`). +// +// To be able to reuse classic implementations, make the given generator meet the classic requirements by wrapping +// it into an adaptor type that forwards all of its interface and adds the required typedef. +template +class _ClassicGenAdaptor { +private: + // The generator is not required to be copyable or movable, so it has to be stored as a reference. + _Gen& __gen_; + +public: + using result_type = invoke_result_t<_Gen&>; + + _LIBCPP_HIDE_FROM_ABI + static constexpr auto min() { return __remove_cvref_t<_Gen>::min(); } + _LIBCPP_HIDE_FROM_ABI + static constexpr auto max() { return __remove_cvref_t<_Gen>::max(); } + + _LIBCPP_HIDE_FROM_ABI + constexpr explicit _ClassicGenAdaptor(_Gen& __g) : __gen_(__g) {} + + _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()() const { return __gen_(); } +}; + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_UNIFORM_RANDOM_BIT_GENERATOR_ADAPTOR_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/unique.h b/app/src/main/cpp/libcxx/include/__algorithm/unique.h new file mode 100644 index 0000000..1717a00 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/unique.h @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_UNIQUE_H +#define _LIBCPP___ALGORITHM_UNIQUE_H + +#include <__algorithm/adjacent_find.h> +#include <__algorithm/comp.h> +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// unique + +template +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 std::pair<_Iter, _Iter> +__unique(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) { + __first = std::__adjacent_find(__first, __last, __pred); + if (__first != __last) { + // ... a a ? ... + // f i + _Iter __i = __first; + for (++__i; ++__i != __last;) + if (!__pred(*__first, *__i)) + *++__first = _IterOps<_AlgPolicy>::__iter_move(__i); + ++__first; + return std::pair<_Iter, _Iter>(std::move(__first), std::move(__i)); + } + return std::pair<_Iter, _Iter>(__first, __first); +} + +template +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) { + return std::__unique<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __pred).first; +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +unique(_ForwardIterator __first, _ForwardIterator __last) { + return std::unique(__first, __last, __equal_to()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_UNIQUE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/unique_copy.h b/app/src/main/cpp/libcxx/include/__algorithm/unique_copy.h new file mode 100644 index 0000000..81fcd50 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/unique_copy.h @@ -0,0 +1,122 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_UNIQUE_COPY_H +#define _LIBCPP___ALGORITHM_UNIQUE_COPY_H + +#include <__algorithm/comp.h> +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__type_traits/conditional.h> +#include <__type_traits/is_base_of.h> +#include <__type_traits/is_same.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace __unique_copy_tags { + +struct __reread_from_input_tag {}; +struct __reread_from_output_tag {}; +struct __read_from_tmp_value_tag {}; + +} // namespace __unique_copy_tags + +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _OutputIterator> +__unique_copy(_InputIterator __first, + _Sent __last, + _OutputIterator __result, + _BinaryPredicate&& __pred, + __unique_copy_tags::__read_from_tmp_value_tag) { + if (__first != __last) { + typename _IterOps<_AlgPolicy>::template __value_type<_InputIterator> __t(*__first); + *__result = __t; + ++__result; + while (++__first != __last) { + if (!__pred(__t, *__first)) { + __t = *__first; + *__result = __t; + ++__result; + } + } + } + return pair<_InputIterator, _OutputIterator>(std::move(__first), std::move(__result)); +} + +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pair<_ForwardIterator, _OutputIterator> +__unique_copy(_ForwardIterator __first, + _Sent __last, + _OutputIterator __result, + _BinaryPredicate&& __pred, + __unique_copy_tags::__reread_from_input_tag) { + if (__first != __last) { + _ForwardIterator __i = __first; + *__result = *__i; + ++__result; + while (++__first != __last) { + if (!__pred(*__i, *__first)) { + *__result = *__first; + ++__result; + __i = __first; + } + } + } + return pair<_ForwardIterator, _OutputIterator>(std::move(__first), std::move(__result)); +} + +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _InputAndOutputIterator> +__unique_copy(_InputIterator __first, + _Sent __last, + _InputAndOutputIterator __result, + _BinaryPredicate&& __pred, + __unique_copy_tags::__reread_from_output_tag) { + if (__first != __last) { + *__result = *__first; + while (++__first != __last) + if (!__pred(*__result, *__first)) + *++__result = *__first; + ++__result; + } + return pair<_InputIterator, _InputAndOutputIterator>(std::move(__first), std::move(__result)); +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred) { + using __algo_tag = __conditional_t< + is_base_of::iterator_category>::value, + __unique_copy_tags::__reread_from_input_tag, + __conditional_t< + is_base_of::iterator_category>::value && + is_same< typename iterator_traits<_InputIterator>::value_type, + typename iterator_traits<_OutputIterator>::value_type>::value, + __unique_copy_tags::__reread_from_output_tag, + __unique_copy_tags::__read_from_tmp_value_tag> >; + return std::__unique_copy<_ClassicAlgPolicy>( + std::move(__first), std::move(__last), std::move(__result), __pred, __algo_tag()) + .second; +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { + return std::unique_copy(std::move(__first), std::move(__last), std::move(__result), __equal_to()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_UNIQUE_COPY_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/unwrap_iter.h b/app/src/main/cpp/libcxx/include/__algorithm/unwrap_iter.h new file mode 100644 index 0000000..0f661e1 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/unwrap_iter.h @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_UNWRAP_ITER_H +#define _LIBCPP___ALGORITHM_UNWRAP_ITER_H + +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__memory/pointer_traits.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_copy_constructible.h> +#include <__utility/declval.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// TODO: Change the name of __unwrap_iter_impl to something more appropriate +// The job of __unwrap_iter is to remove iterator wrappers (like reverse_iterator or __wrap_iter), +// to reduce the number of template instantiations and to enable pointer-based optimizations e.g. in std::copy. +// In debug mode, we don't do this. +// +// Some algorithms (e.g. std::copy, but not std::sort) need to convert an +// "unwrapped" result back into the original iterator type. Doing that is the job of __rewrap_iter. + +// Default case - we can't unwrap anything +template ::value> +struct __unwrap_iter_impl { + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __rewrap(_Iter, _Iter __iter) { return __iter; } + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __unwrap(_Iter __i) _NOEXCEPT { return __i; } +}; + +#ifndef _LIBCPP_ENABLE_DEBUG_MODE + +// It's a contiguous iterator, so we can use a raw pointer instead +template +struct __unwrap_iter_impl<_Iter, true> { + using _ToAddressT = decltype(std::__to_address(std::declval<_Iter>())); + + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __rewrap(_Iter __orig_iter, _ToAddressT __unwrapped_iter) { + return __orig_iter + (__unwrapped_iter - std::__to_address(__orig_iter)); + } + + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToAddressT __unwrap(_Iter __i) _NOEXCEPT { + return std::__to_address(__i); + } +}; + +#endif // !_LIBCPP_ENABLE_DEBUG_MODE + +template, + __enable_if_t::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +decltype(_Impl::__unwrap(std::declval<_Iter>())) __unwrap_iter(_Iter __i) _NOEXCEPT { + return _Impl::__unwrap(__i); +} + +template > +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _OrigIter __rewrap_iter(_OrigIter __orig_iter, _Iter __iter) _NOEXCEPT { + return _Impl::__rewrap(std::move(__orig_iter), std::move(__iter)); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_UNWRAP_ITER_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/unwrap_range.h b/app/src/main/cpp/libcxx/include/__algorithm/unwrap_range.h new file mode 100644 index 0000000..2c5d23e --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/unwrap_range.h @@ -0,0 +1,97 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_UNWRAP_RANGE_H +#define _LIBCPP___ALGORITHM_UNWRAP_RANGE_H + +#include <__algorithm/unwrap_iter.h> +#include <__concepts/constructible.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/next.h> +#include <__utility/declval.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// __unwrap_range and __rewrap_range are used to unwrap ranges which may have different iterator and sentinel types. +// __unwrap_iter and __rewrap_iter don't work for this, because they assume that the iterator and sentinel have +// the same type. __unwrap_range tries to get two iterators and then forward to __unwrap_iter. + +#if _LIBCPP_STD_VER > 17 +template +struct __unwrap_range_impl { + _LIBCPP_HIDE_FROM_ABI static constexpr auto __unwrap(_Iter __first, _Sent __sent) + requires random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter> + { + auto __last = ranges::next(__first, __sent); + return pair{std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last))}; + } + + _LIBCPP_HIDE_FROM_ABI static constexpr auto __unwrap(_Iter __first, _Sent __last) { + return pair{std::move(__first), std::move(__last)}; + } + + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __rewrap(_Iter __orig_iter, decltype(std::__unwrap_iter(__orig_iter)) __iter) + requires random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter> + { + return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter)); + } + + _LIBCPP_HIDE_FROM_ABI static constexpr auto __rewrap(const _Iter&, _Iter __iter) + requires (!(random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>)) + { + return __iter; + } +}; + +template +struct __unwrap_range_impl<_Iter, _Iter> { + _LIBCPP_HIDE_FROM_ABI static constexpr auto __unwrap(_Iter __first, _Iter __last) { + return pair{std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last))}; + } + + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __rewrap(_Iter __orig_iter, decltype(std::__unwrap_iter(__orig_iter)) __iter) { + return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter)); + } +}; + +template +_LIBCPP_HIDE_FROM_ABI constexpr auto __unwrap_range(_Iter __first, _Sent __last) { + return __unwrap_range_impl<_Iter, _Sent>::__unwrap(std::move(__first), std::move(__last)); +} + +template < + class _Sent, + class _Iter, + class _Unwrapped = decltype(std::__unwrap_range(std::declval<_Iter>(), std::declval<_Sent>()))> +_LIBCPP_HIDE_FROM_ABI constexpr _Iter __rewrap_range(_Iter __orig_iter, _Unwrapped __iter) { + return __unwrap_range_impl<_Iter, _Sent>::__rewrap(std::move(__orig_iter), std::move(__iter)); +} +#else // _LIBCPP_STD_VER > 17 +template ()))> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR pair<_Unwrapped, _Unwrapped> __unwrap_range(_Iter __first, _Iter __last) { + return std::make_pair(std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last))); +} + +template ()))> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __rewrap_range(_Iter __orig_iter, _Unwrapped __iter) { + return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter)); +} +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_UNWRAP_RANGE_H diff --git a/app/src/main/cpp/libcxx/include/__algorithm/upper_bound.h b/app/src/main/cpp/libcxx/include/__algorithm/upper_bound.h new file mode 100644 index 0000000..96552ce --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__algorithm/upper_bound.h @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_UPPER_BOUND_H +#define _LIBCPP___ALGORITHM_UPPER_BOUND_H + +#include <__algorithm/comp.h> +#include <__algorithm/half_positive.h> +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/advance.h> +#include <__iterator/distance.h> +#include <__iterator/iterator_traits.h> +#include <__type_traits/is_copy_constructible.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter +__upper_bound(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp, _Proj&& __proj) { + auto __len = _IterOps<_AlgPolicy>::distance(__first, __last); + while (__len != 0) { + auto __half_len = std::__half_positive(__len); + auto __mid = _IterOps<_AlgPolicy>::next(__first, __half_len); + if (std::__invoke(__comp, __value, std::__invoke(__proj, *__mid))) + __len = __half_len; + else { + __first = ++__mid; + __len -= __half_len + 1; + } + } + return __first; +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { + static_assert(is_copy_constructible<_ForwardIterator>::value, + "Iterator has to be copy constructible"); + return std::__upper_bound<_ClassicAlgPolicy>( + std::move(__first), std::move(__last), __value, std::move(__comp), std::__identity()); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + return std::upper_bound( + std::move(__first), + std::move(__last), + __value, + __less<_Tp, typename iterator_traits<_ForwardIterator>::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_UPPER_BOUND_H diff --git a/app/src/main/cpp/libcxx/include/__assert b/app/src/main/cpp/libcxx/include/__assert new file mode 100644 index 0000000..9c0cd1b --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__assert @@ -0,0 +1,55 @@ +// -*- 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 _LIBCPP___ASSERT +#define _LIBCPP___ASSERT + +#include <__config> +#include <__verbose_abort> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +// TODO: Remove in LLVM 17. +#if defined(_LIBCPP_DEBUG) +# error "Defining _LIBCPP_DEBUG is not supported anymore. Please use _LIBCPP_ENABLE_DEBUG_MODE instead." +#endif + +// Automatically enable assertions when the debug mode is enabled. +#if defined(_LIBCPP_ENABLE_DEBUG_MODE) +# ifndef _LIBCPP_ENABLE_ASSERTIONS +# define _LIBCPP_ENABLE_ASSERTIONS 1 +# endif +#endif + +#ifndef _LIBCPP_ENABLE_ASSERTIONS +# define _LIBCPP_ENABLE_ASSERTIONS _LIBCPP_ENABLE_ASSERTIONS_DEFAULT +#endif + +#if _LIBCPP_ENABLE_ASSERTIONS != 0 && _LIBCPP_ENABLE_ASSERTIONS != 1 +# error "_LIBCPP_ENABLE_ASSERTIONS must be set to 0 or 1" +#endif + +#if _LIBCPP_ENABLE_ASSERTIONS +# define _LIBCPP_ASSERT(expression, message) \ + (__builtin_expect(static_cast(expression), 1) ? \ + (void)0 : \ + _LIBCPP_VERBOSE_ABORT("%s:%d: assertion %s failed: %s", __FILE__, __LINE__, #expression, message)) +#elif !defined(_LIBCPP_ASSERTIONS_DISABLE_ASSUME) && __has_builtin(__builtin_assume) +# define _LIBCPP_ASSERT(expression, message) \ + (_LIBCPP_DIAGNOSTIC_PUSH \ + _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wassume") \ + __builtin_assume(static_cast(expression)) \ + _LIBCPP_DIAGNOSTIC_POP) +#else +# define _LIBCPP_ASSERT(expression, message) ((void)0) +#endif + +#endif // _LIBCPP___ASSERT diff --git a/app/src/main/cpp/libcxx/include/__availability b/app/src/main/cpp/libcxx/include/__availability new file mode 100644 index 0000000..6dfca3f --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__availability @@ -0,0 +1,288 @@ +// -*- 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 _LIBCPP___AVAILABILITY +#define _LIBCPP___AVAILABILITY + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +// Libc++ is shipped by various vendors. In particular, it is used as a system +// library on macOS, iOS and other Apple platforms. In order for users to be +// able to compile a binary that is intended to be deployed to an older version +// of a platform, Clang provides availability attributes [1]. These attributes +// can be placed on declarations and are used to describe the life cycle of a +// symbol in the library. +// +// The main goal is to ensure a compile-time error if a symbol that hasn't been +// introduced in a previously released library is used in a program that targets +// that previously released library. Normally, this would be a load-time error +// when one tries to launch the program against the older library. +// +// For example, the filesystem library was introduced in the dylib in macOS 10.15. +// If a user compiles on a macOS 10.15 host but targets macOS 10.13 with their +// program, the compiler would normally not complain (because the required +// declarations are in the headers), but the dynamic loader would fail to find +// the symbols when actually trying to launch the program on macOS 10.13. To +// turn this into a compile-time issue instead, declarations are annotated with +// when they were introduced, and the compiler can produce a diagnostic if the +// program references something that isn't available on the deployment target. +// +// This mechanism is general in nature, and any vendor can add their markup to +// the library (see below). Whenever a new feature is added that requires support +// in the shared library, a macro should be added below to mark this feature +// as unavailable. When vendors decide to ship the feature as part of their +// shared library, they can update the markup appropriately. +// +// Furthermore, many features in the standard library have corresponding +// feature-test macros. When a feature is made unavailable on some deployment +// target, a macro should be defined to signal that it is unavailable. That +// macro can then be picked up when feature-test macros are generated (see +// generate_feature_test_macro_components.py) to make sure that feature-test +// macros don't announce a feature as being implemented if it has been marked +// as unavailable. +// +// Note that this mechanism is disabled by default in the "upstream" libc++. +// Availability annotations are only meaningful when shipping libc++ inside +// a platform (i.e. as a system library), and so vendors that want them should +// turn those annotations on at CMake configuration time. +// +// [1]: https://clang.llvm.org/docs/AttributeReference.html#availability + + +// For backwards compatibility, allow users to define _LIBCPP_DISABLE_AVAILABILITY +// for a while. +#if defined(_LIBCPP_DISABLE_AVAILABILITY) +# if !defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) +# define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS +# endif +#endif + +// Availability markup is disabled when building the library, or when the compiler +// doesn't support the proper attributes. +#if defined(_LIBCPP_BUILDING_LIBRARY) || \ + defined(_LIBCXXABI_BUILDING_LIBRARY) || \ + !__has_feature(attribute_availability_with_strict) || \ + !__has_feature(attribute_availability_in_templates) || \ + !__has_extension(pragma_clang_attribute_external_declaration) +# if !defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) +# define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS +# endif +#endif + +#if defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) + + // This controls the availability of std::shared_mutex and std::shared_timed_mutex, + // which were added to the dylib later. +# define _LIBCPP_AVAILABILITY_SHARED_MUTEX +// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex +// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex + + // These macros control the availability of std::bad_optional_access and + // other exception types. These were put in the shared library to prevent + // code bloat from every user program defining the vtable for these exception + // types. + // + // Note that when exceptions are disabled, the methods that normally throw + // these exceptions can be used even on older deployment targets, but those + // methods will abort instead of throwing. +# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS +# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST + + // This controls the availability of std::uncaught_exceptions(). +# define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS + + // This controls the availability of the sized version of ::operator delete, + // ::operator delete[], and their align_val_t variants, which were all added + // in C++17, and hence not present in early dylibs. +# define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE + + // This controls the availability of the std::future_error exception. + // + // Note that when exceptions are disabled, the methods that normally throw + // std::future_error can be used even on older deployment targets, but those + // methods will abort instead of throwing. +# define _LIBCPP_AVAILABILITY_FUTURE_ERROR + + // This controls the availability of std::type_info's vtable. + // I can't imagine how using std::type_info can work at all if + // this isn't supported. +# define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE + + // This controls the availability of std::locale::category members + // (e.g. std::locale::collate), which are defined in the dylib. +# define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY + + // This controls the availability of atomic operations on std::shared_ptr + // (e.g. `std::atomic_store(std::shared_ptr)`), which require a shared + // lock table located in the dylib. +# define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR + + // These macros control the availability of all parts of that + // depend on something in the dylib. +# define _LIBCPP_AVAILABILITY_FILESYSTEM +# define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH +# define _LIBCPP_AVAILABILITY_FILESYSTEM_POP +// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem + + // This controls the availability of floating-point std::to_chars functions. + // These overloads were added later than the integer overloads. +# define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT + + // This controls the availability of the C++20 synchronization library, + // which requires shared library support for various operations + // (see libcxx/src/atomic.cpp). This includes , , + // , and notification functions on std::atomic. +# define _LIBCPP_AVAILABILITY_SYNC +// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait +// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier +// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch +// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore + + // This controls the availability of the C++20 format library. + // The library is in development and not ABI stable yet. P2216 is + // retroactively accepted in C++20. This paper contains ABI breaking + // changes. +# define _LIBCPP_AVAILABILITY_FORMAT +// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format + + // This controls whether the library claims to provide a default verbose + // termination function, and consequently whether the headers will try + // to use it when the mechanism isn't overriden at compile-time. +// # define _LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY + +#elif defined(__APPLE__) + +# define _LIBCPP_AVAILABILITY_SHARED_MUTEX \ + __attribute__((availability(macos,strict,introduced=10.12))) \ + __attribute__((availability(ios,strict,introduced=10.0))) \ + __attribute__((availability(tvos,strict,introduced=10.0))) \ + __attribute__((availability(watchos,strict,introduced=3.0))) +# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200) || \ + (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \ + (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 100000) || \ + (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 30000) +# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex +# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex +# endif + + // Note: bad_optional_access & friends were not introduced in the matching + // macOS and iOS versions, so the version mismatch between macOS and others + // is intended. +# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS \ + __attribute__((availability(macos,strict,introduced=10.13))) \ + __attribute__((availability(ios,strict,introduced=12.0))) \ + __attribute__((availability(tvos,strict,introduced=12.0))) \ + __attribute__((availability(watchos,strict,introduced=5.0))) +# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS \ + _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST \ + _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS + +# define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS \ + __attribute__((availability(macos,strict,introduced=10.12))) \ + __attribute__((availability(ios,strict,introduced=10.0))) \ + __attribute__((availability(tvos,strict,introduced=10.0))) \ + __attribute__((availability(watchos,strict,introduced=3.0))) + +# define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE \ + __attribute__((availability(macos,strict,introduced=10.12))) \ + __attribute__((availability(ios,strict,introduced=10.0))) \ + __attribute__((availability(tvos,strict,introduced=10.0))) \ + __attribute__((availability(watchos,strict,introduced=3.0))) + +# define _LIBCPP_AVAILABILITY_FUTURE_ERROR \ + __attribute__((availability(ios,strict,introduced=6.0))) + +# define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE \ + __attribute__((availability(macos,strict,introduced=10.9))) \ + __attribute__((availability(ios,strict,introduced=7.0))) + +# define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY \ + __attribute__((availability(macos,strict,introduced=10.9))) \ + __attribute__((availability(ios,strict,introduced=7.0))) + +# define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR \ + __attribute__((availability(macos,strict,introduced=10.9))) \ + __attribute__((availability(ios,strict,introduced=7.0))) + +# define _LIBCPP_AVAILABILITY_FILESYSTEM \ + __attribute__((availability(macos,strict,introduced=10.15))) \ + __attribute__((availability(ios,strict,introduced=13.0))) \ + __attribute__((availability(tvos,strict,introduced=13.0))) \ + __attribute__((availability(watchos,strict,introduced=6.0))) +# define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH \ + _Pragma("clang attribute push(__attribute__((availability(macos,strict,introduced=10.15))), apply_to=any(function,record))") \ + _Pragma("clang attribute push(__attribute__((availability(ios,strict,introduced=13.0))), apply_to=any(function,record))") \ + _Pragma("clang attribute push(__attribute__((availability(tvos,strict,introduced=13.0))), apply_to=any(function,record))") \ + _Pragma("clang attribute push(__attribute__((availability(watchos,strict,introduced=6.0))), apply_to=any(function,record))") +# define _LIBCPP_AVAILABILITY_FILESYSTEM_POP \ + _Pragma("clang attribute pop") \ + _Pragma("clang attribute pop") \ + _Pragma("clang attribute pop") \ + _Pragma("clang attribute pop") +# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500) || \ + (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 130000) || \ + (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 130000) || \ + (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 60000) +# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem +# endif + +# define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT \ + __attribute__((unavailable)) + +# define _LIBCPP_AVAILABILITY_SYNC \ + __attribute__((availability(macos,strict,introduced=11.0))) \ + __attribute__((availability(ios,strict,introduced=14.0))) \ + __attribute__((availability(tvos,strict,introduced=14.0))) \ + __attribute__((availability(watchos,strict,introduced=7.0))) +# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 110000) || \ + (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 140000) || \ + (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 140000) || \ + (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 70000) +# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait +# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier +# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch +# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore +# endif + +# define _LIBCPP_AVAILABILITY_FORMAT \ + __attribute__((unavailable)) +# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format + +# define _LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY + +#else + +// ...New vendors can add availability markup here... + +# error "It looks like you're trying to enable vendor availability markup, but you haven't defined the corresponding macros yet!" + +#endif + +// Define availability attributes that depend on _LIBCPP_NO_EXCEPTIONS. +// Those are defined in terms of the availability attributes above, and +// should not be vendor-specific. +#if defined(_LIBCPP_NO_EXCEPTIONS) +# define _LIBCPP_AVAILABILITY_FUTURE +# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST +# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS +#else +# define _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_AVAILABILITY_FUTURE_ERROR +# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _LIBCPP_AVAILABILITY_BAD_ANY_CAST +# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS +#endif + +#endif // _LIBCPP___AVAILABILITY diff --git a/app/src/main/cpp/libcxx/include/__bit/bit_cast.h b/app/src/main/cpp/libcxx/include/__bit/bit_cast.h new file mode 100644 index 0000000..2ca4120 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__bit/bit_cast.h @@ -0,0 +1,36 @@ +// -*- 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 _LIBCPP___BIT_BIT_CAST_H +#define _LIBCPP___BIT_BIT_CAST_H + +#include <__config> +#include <__type_traits/is_trivially_copyable.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template + requires(sizeof(_ToType) == sizeof(_FromType) && + is_trivially_copyable_v<_ToType> && + is_trivially_copyable_v<_FromType>) +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _ToType bit_cast(const _FromType& __from) noexcept { + return __builtin_bit_cast(_ToType, __from); +} + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___BIT_BIT_CAST_H diff --git a/app/src/main/cpp/libcxx/include/__bit/bit_ceil.h b/app/src/main/cpp/libcxx/include/__bit/bit_ceil.h new file mode 100644 index 0000000..a558d61 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__bit/bit_ceil.h @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___BIT_BIT_CEIL_H +#define _LIBCPP___BIT_BIT_CEIL_H + +#include <__assert> +#include <__bit/countl.h> +#include <__concepts/arithmetic.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 20 + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_ceil(_Tp __t) noexcept { + if (__t < 2) + return 1; + const unsigned __n = numeric_limits<_Tp>::digits - std::countl_zero((_Tp)(__t - 1u)); + _LIBCPP_ASSERT(__n != numeric_limits<_Tp>::digits, "Bad input to bit_ceil"); + + if constexpr (sizeof(_Tp) >= sizeof(unsigned)) + return _Tp{1} << __n; + else { + const unsigned __extra = numeric_limits::digits - numeric_limits<_Tp>::digits; + const unsigned __retVal = 1u << (__n + __extra); + return (_Tp)(__retVal >> __extra); + } +} + +#endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___BIT_BIT_CEIL_H diff --git a/app/src/main/cpp/libcxx/include/__bit/bit_floor.h b/app/src/main/cpp/libcxx/include/__bit/bit_floor.h new file mode 100644 index 0000000..b2e3809 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__bit/bit_floor.h @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___BIT_BIT_FLOOR_H +#define _LIBCPP___BIT_BIT_FLOOR_H + +#include <__bit/bit_log2.h> +#include <__concepts/arithmetic.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 20 + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_floor(_Tp __t) noexcept { + return __t == 0 ? 0 : _Tp{1} << std::__bit_log2(__t); +} + +#endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___BIT_BIT_FLOOR_H diff --git a/app/src/main/cpp/libcxx/include/__bit/bit_log2.h b/app/src/main/cpp/libcxx/include/__bit/bit_log2.h new file mode 100644 index 0000000..62936f6 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__bit/bit_log2.h @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___BIT_BIT_LOG2_H +#define _LIBCPP___BIT_BIT_LOG2_H + +#include <__bit/countl.h> +#include <__concepts/arithmetic.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 20 + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr _Tp __bit_log2(_Tp __t) noexcept { + return numeric_limits<_Tp>::digits - 1 - std::countl_zero(__t); +} + +#endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___BIT_BIT_LOG2_H diff --git a/app/src/main/cpp/libcxx/include/__bit/bit_width.h b/app/src/main/cpp/libcxx/include/__bit/bit_width.h new file mode 100644 index 0000000..4381f22 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__bit/bit_width.h @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___BIT_BIT_WIDTH_H +#define _LIBCPP___BIT_BIT_WIDTH_H + +#include <__bit/bit_log2.h> +#include <__concepts/arithmetic.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER >= 20 + +_LIBCPP_BEGIN_NAMESPACE_STD + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr int bit_width(_Tp __t) noexcept { + return __t == 0 ? 0 : std::__bit_log2(__t) + 1; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 20 + +#endif // _LIBCPP___BIT_BIT_WIDTH_H diff --git a/app/src/main/cpp/libcxx/include/__bit/blsr.h b/app/src/main/cpp/libcxx/include/__bit/blsr.h new file mode 100644 index 0000000..de991e9 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__bit/blsr.h @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___BIT_BLSR_H +#define _LIBCPP___BIT_BLSR_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unsigned __libcpp_blsr(unsigned __x) _NOEXCEPT { + return __x ^ (__x & -__x); +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unsigned long __libcpp_blsr(unsigned long __x) _NOEXCEPT { + return __x ^ (__x & -__x); +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unsigned long long __libcpp_blsr(unsigned long long __x) _NOEXCEPT { + return __x ^ (__x & -__x); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___BIT_BLSR_H diff --git a/app/src/main/cpp/libcxx/include/__bit/byteswap.h b/app/src/main/cpp/libcxx/include/__bit/byteswap.h new file mode 100644 index 0000000..6fa8d48 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__bit/byteswap.h @@ -0,0 +1,55 @@ +// -*- 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 _LIBCPP___BIT_BYTESWAP_H +#define _LIBCPP___BIT_BYTESWAP_H + +#include <__concepts/arithmetic.h> +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 20 + +template +_LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept { + + if constexpr (sizeof(_Tp) == 1) { + return __val; + } else if constexpr (sizeof(_Tp) == 2) { + return __builtin_bswap16(__val); + } else if constexpr (sizeof(_Tp) == 4) { + return __builtin_bswap32(__val); + } else if constexpr (sizeof(_Tp) == 8) { + return __builtin_bswap64(__val); +#ifndef _LIBCPP_HAS_NO_INT128 + } else if constexpr (sizeof(_Tp) == 16) { +#if __has_builtin(__builtin_bswap128) + return __builtin_bswap128(__val); +#else + return static_cast<_Tp>(byteswap(static_cast(__val))) << 64 | + static_cast<_Tp>(byteswap(static_cast(__val >> 64))); +#endif // __has_builtin(__builtin_bswap128) +#endif // _LIBCPP_HAS_NO_INT128 + } else { + static_assert(sizeof(_Tp) == 0, "byteswap is unimplemented for integral types of this size"); + } +} + +#endif // _LIBCPP_STD_VER > 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___BIT_BYTESWAP_H diff --git a/app/src/main/cpp/libcxx/include/__bit/countl.h b/app/src/main/cpp/libcxx/include/__bit/countl.h new file mode 100644 index 0000000..86eaee0 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__bit/countl.h @@ -0,0 +1,104 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___BIT_COUNTL_H +#define _LIBCPP___BIT_COUNTL_H + +#include <__bit/rotate.h> +#include <__concepts/arithmetic.h> +#include <__config> +#include <__type_traits/is_unsigned_integer.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_clz(unsigned __x) _NOEXCEPT { return __builtin_clz(__x); } + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_clz(unsigned long __x) _NOEXCEPT { return __builtin_clzl(__x); } + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_clz(unsigned long long __x) _NOEXCEPT { return __builtin_clzll(__x); } + +# ifndef _LIBCPP_HAS_NO_INT128 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_clz(__uint128_t __x) _NOEXCEPT { + // The function is written in this form due to C++ constexpr limitations. + // The algorithm: + // - Test whether any bit in the high 64-bits is set + // - No bits set: + // - The high 64-bits contain 64 leading zeros, + // - Add the result of the low 64-bits. + // - Any bits set: + // - The number of leading zeros of the input is the number of leading + // zeros in the high 64-bits. + return ((__x >> 64) == 0) + ? (64 + __builtin_clzll(static_cast(__x))) + : __builtin_clzll(static_cast(__x >> 64)); +} +# endif // _LIBCPP_HAS_NO_INT128 + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +int __countl_zero(_Tp __t) _NOEXCEPT +{ + static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countl_zero requires an unsigned integer type"); + if (__t == 0) + return numeric_limits<_Tp>::digits; + + if (sizeof(_Tp) <= sizeof(unsigned int)) + return std::__libcpp_clz(static_cast(__t)) + - (numeric_limits::digits - numeric_limits<_Tp>::digits); + else if (sizeof(_Tp) <= sizeof(unsigned long)) + return std::__libcpp_clz(static_cast(__t)) + - (numeric_limits::digits - numeric_limits<_Tp>::digits); + else if (sizeof(_Tp) <= sizeof(unsigned long long)) + return std::__libcpp_clz(static_cast(__t)) + - (numeric_limits::digits - numeric_limits<_Tp>::digits); + else + { + int __ret = 0; + int __iter = 0; + const unsigned int __ulldigits = numeric_limits::digits; + while (true) { + __t = std::__rotr(__t, __ulldigits); + if ((__iter = std::__countl_zero(static_cast(__t))) != __ulldigits) + break; + __ret += __iter; + } + return __ret + __iter; + } +} + +#if _LIBCPP_STD_VER >= 20 + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr int countl_zero(_Tp __t) noexcept { + return std::__countl_zero(__t); +} + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept { + return __t != numeric_limits<_Tp>::max() ? std::countl_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits; +} + +#endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___BIT_COUNTL_H diff --git a/app/src/main/cpp/libcxx/include/__bit/countr.h b/app/src/main/cpp/libcxx/include/__bit/countr.h new file mode 100644 index 0000000..d3ca5b6 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__bit/countr.h @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___BIT_COUNTR_H +#define _LIBCPP___BIT_COUNTR_H + +#include <__bit/rotate.h> +#include <__concepts/arithmetic.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_ctz(unsigned __x) _NOEXCEPT { return __builtin_ctz(__x); } + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_ctz(unsigned long __x) _NOEXCEPT { return __builtin_ctzl(__x); } + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_ctz(unsigned long long __x) _NOEXCEPT { return __builtin_ctzll(__x); } + +#if _LIBCPP_STD_VER >= 20 + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept { + if (__t == 0) + return numeric_limits<_Tp>::digits; + + if (sizeof(_Tp) <= sizeof(unsigned int)) + return std::__libcpp_ctz(static_cast(__t)); + else if (sizeof(_Tp) <= sizeof(unsigned long)) + return std::__libcpp_ctz(static_cast(__t)); + else if (sizeof(_Tp) <= sizeof(unsigned long long)) + return std::__libcpp_ctz(static_cast(__t)); + else { + int __ret = 0; + const unsigned int __ulldigits = numeric_limits::digits; + while (static_cast(__t) == 0uLL) { + __ret += __ulldigits; + __t >>= __ulldigits; + } + return __ret + std::__libcpp_ctz(static_cast(__t)); + } +} + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept { + return __t != numeric_limits<_Tp>::max() ? std::countr_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits; +} + +#endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___BIT_COUNTR_H diff --git a/app/src/main/cpp/libcxx/include/__bit/endian.h b/app/src/main/cpp/libcxx/include/__bit/endian.h new file mode 100644 index 0000000..52635f2 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__bit/endian.h @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___BIT_ENDIAN_H +#define _LIBCPP___BIT_ENDIAN_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER >= 20 + +_LIBCPP_BEGIN_NAMESPACE_STD + +enum class endian { + little = 0xDEAD, + big = 0xFACE, +# if defined(_LIBCPP_LITTLE_ENDIAN) + native = little +# elif defined(_LIBCPP_BIG_ENDIAN) + native = big +# else + native = 0xCAFE +# endif +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 20 + +#endif // _LIBCPP___BIT_ENDIAN_H diff --git a/app/src/main/cpp/libcxx/include/__bit/has_single_bit.h b/app/src/main/cpp/libcxx/include/__bit/has_single_bit.h new file mode 100644 index 0000000..b89f599 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__bit/has_single_bit.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___BIT_HAS_SINGLE_BIT_H +#define _LIBCPP___BIT_HAS_SINGLE_BIT_H + +#include <__concepts/arithmetic.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +#if _LIBCPP_STD_VER >= 20 + +_LIBCPP_BEGIN_NAMESPACE_STD + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept { + return __t != 0 && (((__t & (__t - 1)) == 0)); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___BIT_HAS_SINGLE_BIT_H diff --git a/app/src/main/cpp/libcxx/include/__bit/popcount.h b/app/src/main/cpp/libcxx/include/__bit/popcount.h new file mode 100644 index 0000000..33b94cf --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__bit/popcount.h @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___BIT_POPCOUNT_H +#define _LIBCPP___BIT_POPCOUNT_H + +#include <__bit/rotate.h> +#include <__concepts/arithmetic.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_popcount(unsigned __x) _NOEXCEPT { return __builtin_popcount(__x); } + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_popcount(unsigned long __x) _NOEXCEPT { return __builtin_popcountl(__x); } + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_popcount(unsigned long long __x) _NOEXCEPT { return __builtin_popcountll(__x); } + +#if _LIBCPP_STD_VER >= 20 + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr int popcount(_Tp __t) noexcept { + if (sizeof(_Tp) <= sizeof(unsigned int)) + return std::__libcpp_popcount(static_cast(__t)); + else if (sizeof(_Tp) <= sizeof(unsigned long)) + return std::__libcpp_popcount(static_cast(__t)); + else if (sizeof(_Tp) <= sizeof(unsigned long long)) + return std::__libcpp_popcount(static_cast(__t)); + else { + int __ret = 0; + while (__t != 0) { + __ret += std::__libcpp_popcount(static_cast(__t)); + __t >>= numeric_limits::digits; + } + return __ret; + } +} + +#endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___BIT_POPCOUNT_H diff --git a/app/src/main/cpp/libcxx/include/__bit/rotate.h b/app/src/main/cpp/libcxx/include/__bit/rotate.h new file mode 100644 index 0000000..5aa7518 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__bit/rotate.h @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___BIT_ROTATE_H +#define _LIBCPP___BIT_ROTATE_H + +#include <__concepts/arithmetic.h> +#include <__config> +#include <__type_traits/is_unsigned_integer.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +_Tp __rotr(_Tp __t, unsigned int __cnt) _NOEXCEPT +{ + static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotr requires an unsigned integer type"); + const unsigned int __dig = numeric_limits<_Tp>::digits; + if ((__cnt % __dig) == 0) + return __t; + return (__t >> (__cnt % __dig)) | (__t << (__dig - (__cnt % __dig))); +} + +#if _LIBCPP_STD_VER >= 20 + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, unsigned int __cnt) noexcept { + const unsigned int __dig = numeric_limits<_Tp>::digits; + if ((__cnt % __dig) == 0) + return __t; + return (__t << (__cnt % __dig)) | (__t >> (__dig - (__cnt % __dig))); +} + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, unsigned int __cnt) noexcept { + return std::__rotr(__t, __cnt); +} + +#endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___BIT_ROTATE_H diff --git a/app/src/main/cpp/libcxx/include/__bit_reference b/app/src/main/cpp/libcxx/include/__bit_reference new file mode 100644 index 0000000..2665749 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__bit_reference @@ -0,0 +1,1360 @@ +// -*- 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 _LIBCPP___BIT_REFERENCE +#define _LIBCPP___BIT_REFERENCE + +#include <__algorithm/copy_n.h> +#include <__algorithm/fill_n.h> +#include <__algorithm/min.h> +#include <__bit/countr.h> +#include <__bit/popcount.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__memory/construct_at.h> +#include <__memory/pointer_traits.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + + +_LIBCPP_BEGIN_NAMESPACE_STD + +template class __bit_iterator; +template class __bit_const_reference; + +template +struct __has_storage_type +{ + static const bool value = false; +}; + +template ::value> +class __bit_reference +{ + typedef typename _Cp::__storage_type __storage_type; + typedef typename _Cp::__storage_pointer __storage_pointer; + + __storage_pointer __seg_; + __storage_type __mask_; + + friend typename _Cp::__self; + + friend class __bit_const_reference<_Cp>; + friend class __bit_iterator<_Cp, false>; +public: + using __container = typename _Cp::__self; + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + __bit_reference(const __bit_reference&) = default; + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 operator bool() const _NOEXCEPT + {return static_cast(*__seg_ & __mask_);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool operator ~() const _NOEXCEPT + {return !static_cast(*this);} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + __bit_reference& operator=(bool __x) _NOEXCEPT + { + if (__x) + *__seg_ |= __mask_; + else + *__seg_ &= ~__mask_; + return *this; + } + +#if _LIBCPP_STD_VER > 20 + _LIBCPP_HIDE_FROM_ABI constexpr const __bit_reference& operator=(bool __x) const noexcept { + if (__x) + *__seg_ |= __mask_; + else + *__seg_ &= ~__mask_; + return *this; + } +#endif + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + __bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT + {return operator=(static_cast(__x));} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void flip() _NOEXCEPT {*__seg_ ^= __mask_;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> operator&() const _NOEXCEPT + {return __bit_iterator<_Cp, false>(__seg_, static_cast(std::__libcpp_ctz(__mask_)));} +private: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + explicit __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT + : __seg_(__s), __mask_(__m) {} +}; + +template +class __bit_reference<_Cp, false> +{ +}; + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +void +swap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT +{ + bool __t = __x; + __x = __y; + __y = __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +void +swap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT +{ + bool __t = __x; + __x = __y; + __y = __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +void +swap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT +{ + bool __t = __x; + __x = __y; + __y = __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +void +swap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT +{ + bool __t = __x; + __x = __y; + __y = __t; +} + +template +class __bit_const_reference +{ + typedef typename _Cp::__storage_type __storage_type; + typedef typename _Cp::__const_storage_pointer __storage_pointer; + + __storage_pointer __seg_; + __storage_type __mask_; + + friend typename _Cp::__self; + friend class __bit_iterator<_Cp, true>; +public: + _LIBCPP_INLINE_VISIBILITY + __bit_const_reference(const __bit_const_reference&) = default; + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT + : __seg_(__x.__seg_), __mask_(__x.__mask_) {} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator bool() const _NOEXCEPT + {return static_cast(*__seg_ & __mask_);} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, true> operator&() const _NOEXCEPT + {return __bit_iterator<_Cp, true>(__seg_, static_cast(std::__libcpp_ctz(__mask_)));} +private: + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR + explicit __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT + : __seg_(__s), __mask_(__m) {} + + __bit_const_reference& operator=(const __bit_const_reference&) = delete; +}; + +// find + +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, _IsConst> +__find_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) +{ + typedef __bit_iterator<_Cp, _IsConst> _It; + typedef typename _It::__storage_type __storage_type; + const int __bits_per_word = _It::__bits_per_word; + // do first partial word + if (__first.__ctz_ != 0) + { + __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); + __storage_type __dn = _VSTD::min(__clz_f, __n); + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __storage_type __b = *__first.__seg_ & __m; + if (__b) + return _It(__first.__seg_, static_cast(_VSTD::__libcpp_ctz(__b))); + if (__n == __dn) + return __first + __n; + __n -= __dn; + ++__first.__seg_; + } + // do middle whole words + for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) + if (*__first.__seg_) + return _It(__first.__seg_, static_cast(_VSTD::__libcpp_ctz(*__first.__seg_))); + // do last partial word + if (__n > 0) + { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b = *__first.__seg_ & __m; + if (__b) + return _It(__first.__seg_, static_cast(_VSTD::__libcpp_ctz(__b))); + } + return _It(__first.__seg_, static_cast(__n)); +} + +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, _IsConst> +__find_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) +{ + typedef __bit_iterator<_Cp, _IsConst> _It; + typedef typename _It::__storage_type __storage_type; + const int __bits_per_word = _It::__bits_per_word; + // do first partial word + if (__first.__ctz_ != 0) + { + __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); + __storage_type __dn = _VSTD::min(__clz_f, __n); + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __storage_type __b = ~*__first.__seg_ & __m; + if (__b) + return _It(__first.__seg_, static_cast(_VSTD::__libcpp_ctz(__b))); + if (__n == __dn) + return __first + __n; + __n -= __dn; + ++__first.__seg_; + } + // do middle whole words + for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) + { + __storage_type __b = ~*__first.__seg_; + if (__b) + return _It(__first.__seg_, static_cast(_VSTD::__libcpp_ctz(__b))); + } + // do last partial word + if (__n > 0) + { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b = ~*__first.__seg_ & __m; + if (__b) + return _It(__first.__seg_, static_cast(_VSTD::__libcpp_ctz(__b))); + } + return _It(__first.__seg_, static_cast(__n)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +__bit_iterator<_Cp, _IsConst> +find(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value) +{ + if (static_cast(__value)) + return _VSTD::__find_bool_true(__first, static_cast(__last - __first)); + return _VSTD::__find_bool_false(__first, static_cast(__last - __first)); +} + +// count + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __bit_iterator<_Cp, _IsConst>::difference_type +__count_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) +{ + typedef __bit_iterator<_Cp, _IsConst> _It; + typedef typename _It::__storage_type __storage_type; + typedef typename _It::difference_type difference_type; + const int __bits_per_word = _It::__bits_per_word; + difference_type __r = 0; + // do first partial word + if (__first.__ctz_ != 0) + { + __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); + __storage_type __dn = _VSTD::min(__clz_f, __n); + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __r = _VSTD::__libcpp_popcount(*__first.__seg_ & __m); + __n -= __dn; + ++__first.__seg_; + } + // do middle whole words + for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) + __r += _VSTD::__libcpp_popcount(*__first.__seg_); + // do last partial word + if (__n > 0) + { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + __r += _VSTD::__libcpp_popcount(*__first.__seg_ & __m); + } + return __r; +} + +template +_LIBCPP_HIDE_FROM_ABI typename __bit_iterator<_Cp, _IsConst>::difference_type +__count_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) +{ + typedef __bit_iterator<_Cp, _IsConst> _It; + typedef typename _It::__storage_type __storage_type; + typedef typename _It::difference_type difference_type; + const int __bits_per_word = _It::__bits_per_word; + difference_type __r = 0; + // do first partial word + if (__first.__ctz_ != 0) + { + __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); + __storage_type __dn = _VSTD::min(__clz_f, __n); + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __r = _VSTD::__libcpp_popcount(~*__first.__seg_ & __m); + __n -= __dn; + ++__first.__seg_; + } + // do middle whole words + for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) + __r += _VSTD::__libcpp_popcount(~*__first.__seg_); + // do last partial word + if (__n > 0) + { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + __r += _VSTD::__libcpp_popcount(~*__first.__seg_ & __m); + } + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __bit_iterator<_Cp, _IsConst>::difference_type +count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value) +{ + if (static_cast(__value)) + return _VSTD::__count_bool_true(__first, static_cast(__last - __first)); + return _VSTD::__count_bool_false(__first, static_cast(__last - __first)); +} + +// fill_n + +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void +__fill_n_false(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) +{ + typedef __bit_iterator<_Cp, false> _It; + typedef typename _It::__storage_type __storage_type; + const int __bits_per_word = _It::__bits_per_word; + // do first partial word + if (__first.__ctz_ != 0) + { + __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); + __storage_type __dn = _VSTD::min(__clz_f, __n); + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + *__first.__seg_ &= ~__m; + __n -= __dn; + ++__first.__seg_; + } + // do middle whole words + __storage_type __nw = __n / __bits_per_word; + std::fill_n(std::__to_address(__first.__seg_), __nw, 0); + __n -= __nw * __bits_per_word; + // do last partial word + if (__n > 0) + { + __first.__seg_ += __nw; + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + *__first.__seg_ &= ~__m; + } +} + +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void +__fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) +{ + typedef __bit_iterator<_Cp, false> _It; + typedef typename _It::__storage_type __storage_type; + const int __bits_per_word = _It::__bits_per_word; + // do first partial word + if (__first.__ctz_ != 0) + { + __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); + __storage_type __dn = _VSTD::min(__clz_f, __n); + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + *__first.__seg_ |= __m; + __n -= __dn; + ++__first.__seg_; + } + // do middle whole words + __storage_type __nw = __n / __bits_per_word; + // __storage_type is always an unsigned type, so -1 sets all bits + std::fill_n(std::__to_address(__first.__seg_), __nw, static_cast<__storage_type>(-1)); + __n -= __nw * __bits_per_word; + // do last partial word + if (__n > 0) + { + __first.__seg_ += __nw; + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + *__first.__seg_ |= __m; + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +void +fill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __value) +{ + if (__n > 0) + { + if (__value) + _VSTD::__fill_n_true(__first, __n); + else + _VSTD::__fill_n_false(__first, __n); + } +} + +// fill + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +void +fill(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __last, bool __value) +{ + _VSTD::fill_n(__first, static_cast(__last - __first), __value); +} + +// copy + +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> +__copy_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, + __bit_iterator<_Cp, false> __result) +{ + typedef __bit_iterator<_Cp, _IsConst> _In; + typedef typename _In::difference_type difference_type; + typedef typename _In::__storage_type __storage_type; + const int __bits_per_word = _In::__bits_per_word; + difference_type __n = __last - __first; + if (__n > 0) + { + // do first word + if (__first.__ctz_ != 0) + { + unsigned __clz = __bits_per_word - __first.__ctz_; + difference_type __dn = _VSTD::min(static_cast(__clz), __n); + __n -= __dn; + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); + __storage_type __b = *__first.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b; + __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; + __result.__ctz_ = static_cast((__dn + __result.__ctz_) % __bits_per_word); + ++__first.__seg_; + // __first.__ctz_ = 0; + } + // __first.__ctz_ == 0; + // do middle words + __storage_type __nw = __n / __bits_per_word; + std::copy_n(std::__to_address(__first.__seg_), __nw, std::__to_address(__result.__seg_)); + __n -= __nw * __bits_per_word; + __result.__seg_ += __nw; + // do last word + if (__n > 0) + { + __first.__seg_ += __nw; + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b = *__first.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b; + __result.__ctz_ = static_cast(__n); + } + } + return __result; +} + +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> +__copy_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, + __bit_iterator<_Cp, false> __result) +{ + typedef __bit_iterator<_Cp, _IsConst> _In; + typedef typename _In::difference_type difference_type; + typedef typename _In::__storage_type __storage_type; + const int __bits_per_word = _In::__bits_per_word; + difference_type __n = __last - __first; + if (__n > 0) + { + // do first word + if (__first.__ctz_ != 0) + { + unsigned __clz_f = __bits_per_word - __first.__ctz_; + difference_type __dn = _VSTD::min(static_cast(__clz_f), __n); + __n -= __dn; + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __storage_type __b = *__first.__seg_ & __m; + unsigned __clz_r = __bits_per_word - __result.__ctz_; + __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r); + __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); + *__result.__seg_ &= ~__m; + if (__result.__ctz_ > __first.__ctz_) + *__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_); + else + *__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_); + __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word; + __result.__ctz_ = static_cast((__ddn + __result.__ctz_) % __bits_per_word); + __dn -= __ddn; + if (__dn > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __dn); + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b >> (__first.__ctz_ + __ddn); + __result.__ctz_ = static_cast(__dn); + } + ++__first.__seg_; + // __first.__ctz_ = 0; + } + // __first.__ctz_ == 0; + // do middle words + unsigned __clz_r = __bits_per_word - __result.__ctz_; + __storage_type __m = ~__storage_type(0) << __result.__ctz_; + for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) + { + __storage_type __b = *__first.__seg_; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b << __result.__ctz_; + ++__result.__seg_; + *__result.__seg_ &= __m; + *__result.__seg_ |= __b >> __clz_r; + } + // do last word + if (__n > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b = *__first.__seg_ & __m; + __storage_type __dn = _VSTD::min(__n, static_cast(__clz_r)); + __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b << __result.__ctz_; + __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; + __result.__ctz_ = static_cast((__dn + __result.__ctz_) % __bits_per_word); + __n -= __dn; + if (__n > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __n); + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b >> __dn; + __result.__ctz_ = static_cast(__n); + } + } + } + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +__bit_iterator<_Cp, false> +copy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) +{ + if (__first.__ctz_ == __result.__ctz_) + return _VSTD::__copy_aligned(__first, __last, __result); + return _VSTD::__copy_unaligned(__first, __last, __result); +} + +// copy_backward + +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> +__copy_backward_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, + __bit_iterator<_Cp, false> __result) +{ + typedef __bit_iterator<_Cp, _IsConst> _In; + typedef typename _In::difference_type difference_type; + typedef typename _In::__storage_type __storage_type; + const int __bits_per_word = _In::__bits_per_word; + difference_type __n = __last - __first; + if (__n > 0) + { + // do first word + if (__last.__ctz_ != 0) + { + difference_type __dn = _VSTD::min(static_cast(__last.__ctz_), __n); + __n -= __dn; + unsigned __clz = __bits_per_word - __last.__ctz_; + __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz); + __storage_type __b = *__last.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b; + __result.__ctz_ = static_cast(((-__dn & (__bits_per_word - 1)) + + __result.__ctz_) % __bits_per_word); + // __last.__ctz_ = 0 + } + // __last.__ctz_ == 0 || __n == 0 + // __result.__ctz_ == 0 || __n == 0 + // do middle words + __storage_type __nw = __n / __bits_per_word; + __result.__seg_ -= __nw; + __last.__seg_ -= __nw; + std::copy_n(std::__to_address(__last.__seg_), __nw, std::__to_address(__result.__seg_)); + __n -= __nw * __bits_per_word; + // do last word + if (__n > 0) + { + __storage_type __m = ~__storage_type(0) << (__bits_per_word - __n); + __storage_type __b = *--__last.__seg_ & __m; + *--__result.__seg_ &= ~__m; + *__result.__seg_ |= __b; + __result.__ctz_ = static_cast(-__n & (__bits_per_word - 1)); + } + } + return __result; +} + +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> +__copy_backward_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, + __bit_iterator<_Cp, false> __result) +{ + typedef __bit_iterator<_Cp, _IsConst> _In; + typedef typename _In::difference_type difference_type; + typedef typename _In::__storage_type __storage_type; + const int __bits_per_word = _In::__bits_per_word; + difference_type __n = __last - __first; + if (__n > 0) + { + // do first word + if (__last.__ctz_ != 0) + { + difference_type __dn = _VSTD::min(static_cast(__last.__ctz_), __n); + __n -= __dn; + unsigned __clz_l = __bits_per_word - __last.__ctz_; + __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_l); + __storage_type __b = *__last.__seg_ & __m; + unsigned __clz_r = __bits_per_word - __result.__ctz_; + __storage_type __ddn = _VSTD::min(__dn, static_cast(__result.__ctz_)); + if (__ddn > 0) + { + __m = (~__storage_type(0) << (__result.__ctz_ - __ddn)) & (~__storage_type(0) >> __clz_r); + *__result.__seg_ &= ~__m; + if (__result.__ctz_ > __last.__ctz_) + *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_); + else + *__result.__seg_ |= __b >> (__last.__ctz_ - __result.__ctz_); + __result.__ctz_ = static_cast(((-__ddn & (__bits_per_word - 1)) + + __result.__ctz_) % __bits_per_word); + __dn -= __ddn; + } + if (__dn > 0) + { + // __result.__ctz_ == 0 + --__result.__seg_; + __result.__ctz_ = static_cast(-__dn & (__bits_per_word - 1)); + __m = ~__storage_type(0) << __result.__ctz_; + *__result.__seg_ &= ~__m; + __last.__ctz_ -= __dn + __ddn; + *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_); + } + // __last.__ctz_ = 0 + } + // __last.__ctz_ == 0 || __n == 0 + // __result.__ctz_ != 0 || __n == 0 + // do middle words + unsigned __clz_r = __bits_per_word - __result.__ctz_; + __storage_type __m = ~__storage_type(0) >> __clz_r; + for (; __n >= __bits_per_word; __n -= __bits_per_word) + { + __storage_type __b = *--__last.__seg_; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b >> __clz_r; + *--__result.__seg_ &= __m; + *__result.__seg_ |= __b << __result.__ctz_; + } + // do last word + if (__n > 0) + { + __m = ~__storage_type(0) << (__bits_per_word - __n); + __storage_type __b = *--__last.__seg_ & __m; + __clz_r = __bits_per_word - __result.__ctz_; + __storage_type __dn = _VSTD::min(__n, static_cast(__result.__ctz_)); + __m = (~__storage_type(0) << (__result.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_r); + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b >> (__bits_per_word - __result.__ctz_); + __result.__ctz_ = static_cast(((-__dn & (__bits_per_word - 1)) + + __result.__ctz_) % __bits_per_word); + __n -= __dn; + if (__n > 0) + { + // __result.__ctz_ == 0 + --__result.__seg_; + __result.__ctz_ = static_cast(-__n & (__bits_per_word - 1)); + __m = ~__storage_type(0) << __result.__ctz_; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b << (__result.__ctz_ - (__bits_per_word - __n - __dn)); + } + } + } + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +__bit_iterator<_Cp, false> +copy_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) +{ + if (__last.__ctz_ == __result.__ctz_) + return _VSTD::__copy_backward_aligned(__first, __last, __result); + return _VSTD::__copy_backward_unaligned(__first, __last, __result); +} + +// move + +template +inline _LIBCPP_INLINE_VISIBILITY +__bit_iterator<_Cp, false> +move(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) +{ + return _VSTD::copy(__first, __last, __result); +} + +// move_backward + +template +inline _LIBCPP_INLINE_VISIBILITY +__bit_iterator<_Cp, false> +move_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) +{ + return _VSTD::copy_backward(__first, __last, __result); +} + +// swap_ranges + +template +_LIBCPP_HIDE_FROM_ABI __bit_iterator<__C2, false> +__swap_ranges_aligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last, + __bit_iterator<__C2, false> __result) +{ + typedef __bit_iterator<__C1, false> _I1; + typedef typename _I1::difference_type difference_type; + typedef typename _I1::__storage_type __storage_type; + const int __bits_per_word = _I1::__bits_per_word; + difference_type __n = __last - __first; + if (__n > 0) + { + // do first word + if (__first.__ctz_ != 0) + { + unsigned __clz = __bits_per_word - __first.__ctz_; + difference_type __dn = _VSTD::min(static_cast(__clz), __n); + __n -= __dn; + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); + __storage_type __b1 = *__first.__seg_ & __m; + *__first.__seg_ &= ~__m; + __storage_type __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b1; + *__first.__seg_ |= __b2; + __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; + __result.__ctz_ = static_cast((__dn + __result.__ctz_) % __bits_per_word); + ++__first.__seg_; + // __first.__ctz_ = 0; + } + // __first.__ctz_ == 0; + // do middle words + for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_, ++__result.__seg_) + swap(*__first.__seg_, *__result.__seg_); + // do last word + if (__n > 0) + { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b1 = *__first.__seg_ & __m; + *__first.__seg_ &= ~__m; + __storage_type __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b1; + *__first.__seg_ |= __b2; + __result.__ctz_ = static_cast(__n); + } + } + return __result; +} + +template +_LIBCPP_HIDE_FROM_ABI __bit_iterator<__C2, false> +__swap_ranges_unaligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last, + __bit_iterator<__C2, false> __result) +{ + typedef __bit_iterator<__C1, false> _I1; + typedef typename _I1::difference_type difference_type; + typedef typename _I1::__storage_type __storage_type; + const int __bits_per_word = _I1::__bits_per_word; + difference_type __n = __last - __first; + if (__n > 0) + { + // do first word + if (__first.__ctz_ != 0) + { + unsigned __clz_f = __bits_per_word - __first.__ctz_; + difference_type __dn = _VSTD::min(static_cast(__clz_f), __n); + __n -= __dn; + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __storage_type __b1 = *__first.__seg_ & __m; + *__first.__seg_ &= ~__m; + unsigned __clz_r = __bits_per_word - __result.__ctz_; + __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r); + __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); + __storage_type __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + if (__result.__ctz_ > __first.__ctz_) + { + unsigned __s = __result.__ctz_ - __first.__ctz_; + *__result.__seg_ |= __b1 << __s; + *__first.__seg_ |= __b2 >> __s; + } + else + { + unsigned __s = __first.__ctz_ - __result.__ctz_; + *__result.__seg_ |= __b1 >> __s; + *__first.__seg_ |= __b2 << __s; + } + __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word; + __result.__ctz_ = static_cast((__ddn + __result.__ctz_) % __bits_per_word); + __dn -= __ddn; + if (__dn > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __dn); + __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + unsigned __s = __first.__ctz_ + __ddn; + *__result.__seg_ |= __b1 >> __s; + *__first.__seg_ |= __b2 << __s; + __result.__ctz_ = static_cast(__dn); + } + ++__first.__seg_; + // __first.__ctz_ = 0; + } + // __first.__ctz_ == 0; + // do middle words + __storage_type __m = ~__storage_type(0) << __result.__ctz_; + unsigned __clz_r = __bits_per_word - __result.__ctz_; + for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) + { + __storage_type __b1 = *__first.__seg_; + __storage_type __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b1 << __result.__ctz_; + *__first.__seg_ = __b2 >> __result.__ctz_; + ++__result.__seg_; + __b2 = *__result.__seg_ & ~__m; + *__result.__seg_ &= __m; + *__result.__seg_ |= __b1 >> __clz_r; + *__first.__seg_ |= __b2 << __clz_r; + } + // do last word + if (__n > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b1 = *__first.__seg_ & __m; + *__first.__seg_ &= ~__m; + __storage_type __dn = _VSTD::min<__storage_type>(__n, __clz_r); + __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); + __storage_type __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b1 << __result.__ctz_; + *__first.__seg_ |= __b2 >> __result.__ctz_; + __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; + __result.__ctz_ = static_cast((__dn + __result.__ctz_) % __bits_per_word); + __n -= __dn; + if (__n > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __n); + __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b1 >> __dn; + *__first.__seg_ |= __b2 << __dn; + __result.__ctz_ = static_cast(__n); + } + } + } + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +__bit_iterator<__C2, false> +swap_ranges(__bit_iterator<__C1, false> __first1, __bit_iterator<__C1, false> __last1, + __bit_iterator<__C2, false> __first2) +{ + if (__first1.__ctz_ == __first2.__ctz_) + return _VSTD::__swap_ranges_aligned(__first1, __last1, __first2); + return _VSTD::__swap_ranges_unaligned(__first1, __last1, __first2); +} + +// rotate + +template +struct __bit_array +{ + typedef typename _Cp::difference_type difference_type; + typedef typename _Cp::__storage_type __storage_type; + typedef typename _Cp::__storage_pointer __storage_pointer; + typedef typename _Cp::iterator iterator; + static const unsigned __bits_per_word = _Cp::__bits_per_word; + static const unsigned _Np = 4; + + difference_type __size_; + __storage_type __word_[_Np]; + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 static difference_type capacity() + {return static_cast(_Np * __bits_per_word);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_array(difference_type __s) : __size_(__s) { + if (__libcpp_is_constant_evaluated()) { + for (size_t __i = 0; __i != __bit_array<_Cp>::_Np; ++__i) + std::__construct_at(__word_ + __i, 0); + } + } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator begin() + { + return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0); + } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator end() + { + return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word, + static_cast(__size_ % __bits_per_word)); + } +}; + +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> +rotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle, __bit_iterator<_Cp, false> __last) +{ + typedef __bit_iterator<_Cp, false> _I1; + typedef typename _I1::difference_type difference_type; + difference_type __d1 = __middle - __first; + difference_type __d2 = __last - __middle; + _I1 __r = __first + __d2; + while (__d1 != 0 && __d2 != 0) + { + if (__d1 <= __d2) + { + if (__d1 <= __bit_array<_Cp>::capacity()) + { + __bit_array<_Cp> __b(__d1); + _VSTD::copy(__first, __middle, __b.begin()); + _VSTD::copy(__b.begin(), __b.end(), _VSTD::copy(__middle, __last, __first)); + break; + } + else + { + __bit_iterator<_Cp, false> __mp = _VSTD::swap_ranges(__first, __middle, __middle); + __first = __middle; + __middle = __mp; + __d2 -= __d1; + } + } + else + { + if (__d2 <= __bit_array<_Cp>::capacity()) + { + __bit_array<_Cp> __b(__d2); + _VSTD::copy(__middle, __last, __b.begin()); + _VSTD::copy_backward(__b.begin(), __b.end(), _VSTD::copy_backward(__first, __middle, __last)); + break; + } + else + { + __bit_iterator<_Cp, false> __mp = __first + __d2; + _VSTD::swap_ranges(__first, __mp, __middle); + __first = __mp; + __d1 -= __d2; + } + } + } + return __r; +} + +// equal + +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool +__equal_unaligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, + __bit_iterator<_Cp, _IC2> __first2) +{ + typedef __bit_iterator<_Cp, _IC1> _It; + typedef typename _It::difference_type difference_type; + typedef typename _It::__storage_type __storage_type; + const int __bits_per_word = _It::__bits_per_word; + difference_type __n = __last1 - __first1; + if (__n > 0) + { + // do first word + if (__first1.__ctz_ != 0) + { + unsigned __clz_f = __bits_per_word - __first1.__ctz_; + difference_type __dn = _VSTD::min(static_cast(__clz_f), __n); + __n -= __dn; + __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __storage_type __b = *__first1.__seg_ & __m; + unsigned __clz_r = __bits_per_word - __first2.__ctz_; + __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r); + __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); + if (__first2.__ctz_ > __first1.__ctz_) + { + if ((*__first2.__seg_ & __m) != (__b << (__first2.__ctz_ - __first1.__ctz_))) + return false; + } + else + { + if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ - __first2.__ctz_))) + return false; + } + __first2.__seg_ += (__ddn + __first2.__ctz_) / __bits_per_word; + __first2.__ctz_ = static_cast((__ddn + __first2.__ctz_) % __bits_per_word); + __dn -= __ddn; + if (__dn > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __dn); + if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ + __ddn))) + return false; + __first2.__ctz_ = static_cast(__dn); + } + ++__first1.__seg_; + // __first1.__ctz_ = 0; + } + // __first1.__ctz_ == 0; + // do middle words + unsigned __clz_r = __bits_per_word - __first2.__ctz_; + __storage_type __m = ~__storage_type(0) << __first2.__ctz_; + for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_) + { + __storage_type __b = *__first1.__seg_; + if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_)) + return false; + ++__first2.__seg_; + if ((*__first2.__seg_ & ~__m) != (__b >> __clz_r)) + return false; + } + // do last word + if (__n > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b = *__first1.__seg_ & __m; + __storage_type __dn = _VSTD::min(__n, static_cast(__clz_r)); + __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); + if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_)) + return false; + __first2.__seg_ += (__dn + __first2.__ctz_) / __bits_per_word; + __first2.__ctz_ = static_cast((__dn + __first2.__ctz_) % __bits_per_word); + __n -= __dn; + if (__n > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __n); + if ((*__first2.__seg_ & __m) != (__b >> __dn)) + return false; + } + } + } + return true; +} + +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool +__equal_aligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, + __bit_iterator<_Cp, _IC2> __first2) +{ + typedef __bit_iterator<_Cp, _IC1> _It; + typedef typename _It::difference_type difference_type; + typedef typename _It::__storage_type __storage_type; + const int __bits_per_word = _It::__bits_per_word; + difference_type __n = __last1 - __first1; + if (__n > 0) + { + // do first word + if (__first1.__ctz_ != 0) + { + unsigned __clz = __bits_per_word - __first1.__ctz_; + difference_type __dn = _VSTD::min(static_cast(__clz), __n); + __n -= __dn; + __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); + if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m)) + return false; + ++__first2.__seg_; + ++__first1.__seg_; + // __first1.__ctz_ = 0; + // __first2.__ctz_ = 0; + } + // __first1.__ctz_ == 0; + // __first2.__ctz_ == 0; + // do middle words + for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_, ++__first2.__seg_) + if (*__first2.__seg_ != *__first1.__seg_) + return false; + // do last word + if (__n > 0) + { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m)) + return false; + } + } + return true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +bool +equal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) +{ + if (__first1.__ctz_ == __first2.__ctz_) + return _VSTD::__equal_aligned(__first1, __last1, __first2); + return _VSTD::__equal_unaligned(__first1, __last1, __first2); +} + +template +class __bit_iterator +{ +public: + typedef typename _Cp::difference_type difference_type; + typedef bool value_type; + typedef __bit_iterator pointer; +#ifndef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL + typedef __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> > reference; +#else + using reference = __conditional_t<_IsConst, bool, __bit_reference<_Cp> >; +#endif + typedef random_access_iterator_tag iterator_category; + +private: + typedef typename _Cp::__storage_type __storage_type; + typedef __conditional_t<_IsConst, typename _Cp::__const_storage_pointer, typename _Cp::__storage_pointer> + __storage_pointer; + static const unsigned __bits_per_word = _Cp::__bits_per_word; + + __storage_pointer __seg_; + unsigned __ctz_; + +public: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator() _NOEXCEPT +#if _LIBCPP_STD_VER > 11 + : __seg_(nullptr), __ctz_(0) +#endif + {} + + // When _IsConst=false, this is the copy constructor. + // It is non-trivial. Making it trivial would break ABI. + // When _IsConst=true, this is a converting constructor; + // the copy and move constructors are implicitly generated + // and trivial. + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT + : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {} + + // When _IsConst=false, we have a user-provided copy constructor, + // so we must also provide a copy assignment operator because + // the implicit generation of a defaulted one is deprecated. + // When _IsConst=true, the assignment operators are + // implicitly generated and trivial. + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + __bit_iterator& operator=(const _If<_IsConst, struct __private_nat, __bit_iterator>& __it) { + __seg_ = __it.__seg_; + __ctz_ = __it.__ctz_; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator*() const _NOEXCEPT { + return __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >( + __seg_, __storage_type(1) << __ctz_); + } + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator++() + { + if (__ctz_ != __bits_per_word-1) + ++__ctz_; + else + { + __ctz_ = 0; + ++__seg_; + } + return *this; + } + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator++(int) + { + __bit_iterator __tmp = *this; + ++(*this); + return __tmp; + } + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator--() + { + if (__ctz_ != 0) + --__ctz_; + else + { + __ctz_ = __bits_per_word - 1; + --__seg_; + } + return *this; + } + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator--(int) + { + __bit_iterator __tmp = *this; + --(*this); + return __tmp; + } + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator+=(difference_type __n) + { + if (__n >= 0) + __seg_ += (__n + __ctz_) / __bits_per_word; + else + __seg_ += static_cast(__n - __bits_per_word + __ctz_ + 1) + / static_cast(__bits_per_word); + __n &= (__bits_per_word - 1); + __ctz_ = static_cast((__n + __ctz_) % __bits_per_word); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator-=(difference_type __n) + { + return *this += -__n; + } + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator+(difference_type __n) const + { + __bit_iterator __t(*this); + __t += __n; + return __t; + } + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator-(difference_type __n) const + { + __bit_iterator __t(*this); + __t -= __n; + return __t; + } + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend __bit_iterator operator+(difference_type __n, const __bit_iterator& __it) {return __it + __n;} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend difference_type operator-(const __bit_iterator& __x, const __bit_iterator& __y) + {return (__x.__seg_ - __y.__seg_) * __bits_per_word + __x.__ctz_ - __y.__ctz_;} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](difference_type __n) const {return *(*this + __n);} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator==(const __bit_iterator& __x, const __bit_iterator& __y) + {return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_;} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator!=(const __bit_iterator& __x, const __bit_iterator& __y) + {return !(__x == __y);} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator<(const __bit_iterator& __x, const __bit_iterator& __y) + {return __x.__seg_ < __y.__seg_ || (__x.__seg_ == __y.__seg_ && __x.__ctz_ < __y.__ctz_);} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator>(const __bit_iterator& __x, const __bit_iterator& __y) + {return __y < __x;} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator<=(const __bit_iterator& __x, const __bit_iterator& __y) + {return !(__y < __x);} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator>=(const __bit_iterator& __x, const __bit_iterator& __y) + {return !(__x < __y);} + +private: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + explicit __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT + : __seg_(__s), __ctz_(__ctz) {} + + friend typename _Cp::__self; + + friend class __bit_reference<_Cp>; + friend class __bit_const_reference<_Cp>; + friend class __bit_iterator<_Cp, true>; + template friend struct __bit_array; + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend void __fill_n_false(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n); + + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend void __fill_n_true(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n); + + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend __bit_iterator<_Dp, false> __copy_aligned(__bit_iterator<_Dp, _IC> __first, + __bit_iterator<_Dp, _IC> __last, + __bit_iterator<_Dp, false> __result); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend __bit_iterator<_Dp, false> __copy_unaligned(__bit_iterator<_Dp, _IC> __first, + __bit_iterator<_Dp, _IC> __last, + __bit_iterator<_Dp, false> __result); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend __bit_iterator<_Dp, false> copy(__bit_iterator<_Dp, _IC> __first, + __bit_iterator<_Dp, _IC> __last, + __bit_iterator<_Dp, false> __result); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend __bit_iterator<_Dp, false> __copy_backward_aligned(__bit_iterator<_Dp, _IC> __first, + __bit_iterator<_Dp, _IC> __last, + __bit_iterator<_Dp, false> __result); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend __bit_iterator<_Dp, false> __copy_backward_unaligned(__bit_iterator<_Dp, _IC> __first, + __bit_iterator<_Dp, _IC> __last, + __bit_iterator<_Dp, false> __result); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend __bit_iterator<_Dp, false> copy_backward(__bit_iterator<_Dp, _IC> __first, + __bit_iterator<_Dp, _IC> __last, + __bit_iterator<_Dp, false> __result); + template friend __bit_iterator<__C2, false> __swap_ranges_aligned(__bit_iterator<__C1, false>, + __bit_iterator<__C1, false>, + __bit_iterator<__C2, false>); + template friend __bit_iterator<__C2, false> __swap_ranges_unaligned(__bit_iterator<__C1, false>, + __bit_iterator<__C1, false>, + __bit_iterator<__C2, false>); + template friend __bit_iterator<__C2, false> swap_ranges(__bit_iterator<__C1, false>, + __bit_iterator<__C1, false>, + __bit_iterator<__C2, false>); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend __bit_iterator<_Dp, false> rotate(__bit_iterator<_Dp, false>, + __bit_iterator<_Dp, false>, + __bit_iterator<_Dp, false>); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend bool __equal_aligned(__bit_iterator<_Dp, _IC1>, + __bit_iterator<_Dp, _IC1>, + __bit_iterator<_Dp, _IC2>); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend bool __equal_unaligned(__bit_iterator<_Dp, _IC1>, + __bit_iterator<_Dp, _IC1>, + __bit_iterator<_Dp, _IC2>); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend bool equal(__bit_iterator<_Dp, _IC1>, + __bit_iterator<_Dp, _IC1>, + __bit_iterator<_Dp, _IC2>); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend __bit_iterator<_Dp, _IC> __find_bool_true(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend __bit_iterator<_Dp, _IC> __find_bool_false(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); + template friend typename __bit_iterator<_Dp, _IC>::difference_type + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 + __count_bool_true(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); + template friend typename __bit_iterator<_Dp, _IC>::difference_type + __count_bool_false(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); +}; + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___BIT_REFERENCE diff --git a/app/src/main/cpp/libcxx/include/__bsd_locale_defaults.h b/app/src/main/cpp/libcxx/include/__bsd_locale_defaults.h new file mode 100644 index 0000000..4d99048 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__bsd_locale_defaults.h @@ -0,0 +1,36 @@ +// -*- 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 +// +//===----------------------------------------------------------------------===// +// The BSDs have lots of *_l functions. We don't want to define those symbols +// on other platforms though, for fear of conflicts with user code. So here, +// we will define the mapping from an internal macro to the real BSD symbol. +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___BSD_LOCALE_DEFAULTS_H +#define _LIBCPP___BSD_LOCALE_DEFAULTS_H + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#define __libcpp_mb_cur_max_l(loc) MB_CUR_MAX_L(loc) +#define __libcpp_btowc_l(ch, loc) btowc_l(ch, loc) +#define __libcpp_wctob_l(wch, loc) wctob_l(wch, loc) +#define __libcpp_wcsnrtombs_l(dst, src, nwc, len, ps, loc) wcsnrtombs_l(dst, src, nwc, len, ps, loc) +#define __libcpp_wcrtomb_l(src, wc, ps, loc) wcrtomb_l(src, wc, ps, loc) +#define __libcpp_mbsnrtowcs_l(dst, src, nms, len, ps, loc) mbsnrtowcs_l(dst, src, nms, len, ps, loc) +#define __libcpp_mbrtowc_l(pwc, s, n, ps, l) mbrtowc_l(pwc, s, n, ps, l) +#define __libcpp_mbtowc_l(pwc, pmb, max, l) mbtowc_l(pwc, pmb, max, l) +#define __libcpp_mbrlen_l(s, n, ps, l) mbrlen_l(s, n, ps, l) +#define __libcpp_localeconv_l(l) localeconv_l(l) +#define __libcpp_mbsrtowcs_l(dest, src, len, ps, l) mbsrtowcs_l(dest, src, len, ps, l) +#define __libcpp_snprintf_l(...) snprintf_l(__VA_ARGS__) +#define __libcpp_asprintf_l(...) asprintf_l(__VA_ARGS__) +#define __libcpp_sscanf_l(...) sscanf_l(__VA_ARGS__) + +#endif // _LIBCPP___BSD_LOCALE_DEFAULTS_H diff --git a/app/src/main/cpp/libcxx/include/__bsd_locale_fallbacks.h b/app/src/main/cpp/libcxx/include/__bsd_locale_fallbacks.h new file mode 100644 index 0000000..9abd7e7 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__bsd_locale_fallbacks.h @@ -0,0 +1,142 @@ +// -*- 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 +// +//===----------------------------------------------------------------------===// +// The BSDs have lots of *_l functions. This file provides reimplementations +// of those functions for non-BSD platforms. +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___BSD_LOCALE_FALLBACKS_H +#define _LIBCPP___BSD_LOCALE_FALLBACKS_H + +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +inline _LIBCPP_INLINE_VISIBILITY +decltype(MB_CUR_MAX) __libcpp_mb_cur_max_l(locale_t __l) +{ + __libcpp_locale_guard __current(__l); + return MB_CUR_MAX; +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +inline _LIBCPP_INLINE_VISIBILITY +wint_t __libcpp_btowc_l(int __c, locale_t __l) +{ + __libcpp_locale_guard __current(__l); + return btowc(__c); +} + +inline _LIBCPP_INLINE_VISIBILITY +int __libcpp_wctob_l(wint_t __c, locale_t __l) +{ + __libcpp_locale_guard __current(__l); + return wctob(__c); +} + +inline _LIBCPP_INLINE_VISIBILITY +size_t __libcpp_wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc, + size_t __len, mbstate_t *__ps, locale_t __l) +{ + __libcpp_locale_guard __current(__l); + return wcsnrtombs(__dest, __src, __nwc, __len, __ps); +} + +inline _LIBCPP_INLINE_VISIBILITY +size_t __libcpp_wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l) +{ + __libcpp_locale_guard __current(__l); + return wcrtomb(__s, __wc, __ps); +} + +inline _LIBCPP_INLINE_VISIBILITY +size_t __libcpp_mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms, + size_t __len, mbstate_t *__ps, locale_t __l) +{ + __libcpp_locale_guard __current(__l); + return mbsnrtowcs(__dest, __src, __nms, __len, __ps); +} + +inline _LIBCPP_INLINE_VISIBILITY +size_t __libcpp_mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n, + mbstate_t *__ps, locale_t __l) +{ + __libcpp_locale_guard __current(__l); + return mbrtowc(__pwc, __s, __n, __ps); +} + +inline _LIBCPP_INLINE_VISIBILITY +int __libcpp_mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l) +{ + __libcpp_locale_guard __current(__l); + return mbtowc(__pwc, __pmb, __max); +} + +inline _LIBCPP_INLINE_VISIBILITY +size_t __libcpp_mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l) +{ + __libcpp_locale_guard __current(__l); + return mbrlen(__s, __n, __ps); +} +#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS + +inline _LIBCPP_INLINE_VISIBILITY +lconv *__libcpp_localeconv_l(locale_t __l) +{ + __libcpp_locale_guard __current(__l); + return localeconv(); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +inline _LIBCPP_INLINE_VISIBILITY +size_t __libcpp_mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len, + mbstate_t *__ps, locale_t __l) +{ + __libcpp_locale_guard __current(__l); + return mbsrtowcs(__dest, __src, __len, __ps); +} +#endif + +inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 4, 5) +int __libcpp_snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) { + va_list __va; + va_start(__va, __format); + __libcpp_locale_guard __current(__l); + int __res = vsnprintf(__s, __n, __format, __va); + va_end(__va); + return __res; +} + +inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) +int __libcpp_asprintf_l(char **__s, locale_t __l, const char *__format, ...) { + va_list __va; + va_start(__va, __format); + __libcpp_locale_guard __current(__l); + int __res = vasprintf(__s, __format, __va); + va_end(__va); + return __res; +} + +inline _LIBCPP_ATTRIBUTE_FORMAT(__scanf__, 3, 4) +int __libcpp_sscanf_l(const char *__s, locale_t __l, const char *__format, ...) { + va_list __va; + va_start(__va, __format); + __libcpp_locale_guard __current(__l); + int __res = vsscanf(__s, __format, __va); + va_end(__va); + return __res; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___BSD_LOCALE_FALLBACKS_H diff --git a/app/src/main/cpp/libcxx/include/__charconv/chars_format.h b/app/src/main/cpp/libcxx/include/__charconv/chars_format.h new file mode 100644 index 0000000..695bd87 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__charconv/chars_format.h @@ -0,0 +1,77 @@ +// -*- 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 _LIBCPP___CHARCONV_CHARS_FORMAT_H +#define _LIBCPP___CHARCONV_CHARS_FORMAT_H + +#include <__config> +#include <__utility/to_underlying.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +enum class _LIBCPP_ENUM_VIS chars_format +{ + scientific = 0x1, + fixed = 0x2, + hex = 0x4, + general = fixed | scientific +}; + +inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format +operator~(chars_format __x) { + return chars_format(~_VSTD::__to_underlying(__x)); +} + +inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format +operator&(chars_format __x, chars_format __y) { + return chars_format(_VSTD::__to_underlying(__x) & + _VSTD::__to_underlying(__y)); +} + +inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format +operator|(chars_format __x, chars_format __y) { + return chars_format(_VSTD::__to_underlying(__x) | + _VSTD::__to_underlying(__y)); +} + +inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format +operator^(chars_format __x, chars_format __y) { + return chars_format(_VSTD::__to_underlying(__x) ^ + _VSTD::__to_underlying(__y)); +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format& +operator&=(chars_format& __x, chars_format __y) { + __x = __x & __y; + return __x; +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format& +operator|=(chars_format& __x, chars_format __y) { + __x = __x | __y; + return __x; +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format& +operator^=(chars_format& __x, chars_format __y) { + __x = __x ^ __y; + return __x; +} + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHARCONV_CHARS_FORMAT_H diff --git a/app/src/main/cpp/libcxx/include/__charconv/from_chars_result.h b/app/src/main/cpp/libcxx/include/__charconv/from_chars_result.h new file mode 100644 index 0000000..05ffe14 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__charconv/from_chars_result.h @@ -0,0 +1,37 @@ +// -*- 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 _LIBCPP___CHARCONV_FROM_CHARS_RESULT_H +#define _LIBCPP___CHARCONV_FROM_CHARS_RESULT_H + +#include <__config> +#include <__errc> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +struct _LIBCPP_TYPE_VIS from_chars_result +{ + const char* ptr; + errc ec; +# if _LIBCPP_STD_VER > 17 + _LIBCPP_HIDE_FROM_ABI friend bool operator==(const from_chars_result&, const from_chars_result&) = default; +# endif +}; + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHARCONV_FROM_CHARS_RESULT_H diff --git a/app/src/main/cpp/libcxx/include/__charconv/tables.h b/app/src/main/cpp/libcxx/include/__charconv/tables.h new file mode 100644 index 0000000..9b82440 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__charconv/tables.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 _LIBCPP___CHARCONV_TABLES +#define _LIBCPP___CHARCONV_TABLES + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +namespace __itoa { + +inline constexpr char __base_2_lut[64] = { + '0', '0', '0', '0', '0', '0', '0', '1', '0', '0', '1', '0', '0', '0', '1', '1', '0', '1', '0', '0', '0', '1', + '0', '1', '0', '1', '1', '0', '0', '1', '1', '1', '1', '0', '0', '0', '1', '0', '0', '1', '1', '0', '1', '0', + '1', '0', '1', '1', '1', '1', '0', '0', '1', '1', '0', '1', '1', '1', '1', '0', '1', '1', '1', '1'}; + +inline constexpr char __base_8_lut[128] = { + '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '1', '0', '1', '1', '1', '2', + '1', '3', '1', '4', '1', '5', '1', '6', '1', '7', '2', '0', '2', '1', '2', '2', '2', '3', '2', '4', '2', '5', + '2', '6', '2', '7', '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '4', '0', + '4', '1', '4', '2', '4', '3', '4', '4', '4', '5', '4', '6', '4', '7', '5', '0', '5', '1', '5', '2', '5', '3', + '5', '4', '5', '5', '5', '6', '5', '7', '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', + '6', '7', '7', '0', '7', '1', '7', '2', '7', '3', '7', '4', '7', '5', '7', '6', '7', '7'}; + +inline constexpr char __base_16_lut[512] = { + '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '0', '8', '0', '9', '0', 'a', '0', + 'b', '0', 'c', '0', 'd', '0', 'e', '0', 'f', '1', '0', '1', '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6', + '1', '7', '1', '8', '1', '9', '1', 'a', '1', 'b', '1', 'c', '1', 'd', '1', 'e', '1', 'f', '2', '0', '2', '1', '2', + '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9', '2', 'a', '2', 'b', '2', 'c', '2', 'd', + '2', 'e', '2', 'f', '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '3', '8', '3', + '9', '3', 'a', '3', 'b', '3', 'c', '3', 'd', '3', 'e', '3', 'f', '4', '0', '4', '1', '4', '2', '4', '3', '4', '4', + '4', '5', '4', '6', '4', '7', '4', '8', '4', '9', '4', 'a', '4', 'b', '4', 'c', '4', 'd', '4', 'e', '4', 'f', '5', + '0', '5', '1', '5', '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9', '5', 'a', '5', 'b', + '5', 'c', '5', 'd', '5', 'e', '5', 'f', '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6', + '7', '6', '8', '6', '9', '6', 'a', '6', 'b', '6', 'c', '6', 'd', '6', 'e', '6', 'f', '7', '0', '7', '1', '7', '2', + '7', '3', '7', '4', '7', '5', '7', '6', '7', '7', '7', '8', '7', '9', '7', 'a', '7', 'b', '7', 'c', '7', 'd', '7', + 'e', '7', 'f', '8', '0', '8', '1', '8', '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9', + '8', 'a', '8', 'b', '8', 'c', '8', 'd', '8', 'e', '8', 'f', '9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', + '5', '9', '6', '9', '7', '9', '8', '9', '9', '9', 'a', '9', 'b', '9', 'c', '9', 'd', '9', 'e', '9', 'f', 'a', '0', + 'a', '1', 'a', '2', 'a', '3', 'a', '4', 'a', '5', 'a', '6', 'a', '7', 'a', '8', 'a', '9', 'a', 'a', 'a', 'b', 'a', + 'c', 'a', 'd', 'a', 'e', 'a', 'f', 'b', '0', 'b', '1', 'b', '2', 'b', '3', 'b', '4', 'b', '5', 'b', '6', 'b', '7', + 'b', '8', 'b', '9', 'b', 'a', 'b', 'b', 'b', 'c', 'b', 'd', 'b', 'e', 'b', 'f', 'c', '0', 'c', '1', 'c', '2', 'c', + '3', 'c', '4', 'c', '5', 'c', '6', 'c', '7', 'c', '8', 'c', '9', 'c', 'a', 'c', 'b', 'c', 'c', 'c', 'd', 'c', 'e', + 'c', 'f', 'd', '0', 'd', '1', 'd', '2', 'd', '3', 'd', '4', 'd', '5', 'd', '6', 'd', '7', 'd', '8', 'd', '9', 'd', + 'a', 'd', 'b', 'd', 'c', 'd', 'd', 'd', 'e', 'd', 'f', 'e', '0', 'e', '1', 'e', '2', 'e', '3', 'e', '4', 'e', '5', + 'e', '6', 'e', '7', 'e', '8', 'e', '9', 'e', 'a', 'e', 'b', 'e', 'c', 'e', 'd', 'e', 'e', 'e', 'f', 'f', '0', 'f', + '1', 'f', '2', 'f', '3', 'f', '4', 'f', '5', 'f', '6', 'f', '7', 'f', '8', 'f', '9', 'f', 'a', 'f', 'b', 'f', 'c', + 'f', 'd', 'f', 'e', 'f', 'f'}; + +inline constexpr uint32_t __pow10_32[10] = { + UINT32_C(0), UINT32_C(10), UINT32_C(100), UINT32_C(1000), UINT32_C(10000), + UINT32_C(100000), UINT32_C(1000000), UINT32_C(10000000), UINT32_C(100000000), UINT32_C(1000000000)}; + +inline constexpr uint64_t __pow10_64[20] = {UINT64_C(0), + UINT64_C(10), + UINT64_C(100), + UINT64_C(1000), + UINT64_C(10000), + UINT64_C(100000), + UINT64_C(1000000), + UINT64_C(10000000), + UINT64_C(100000000), + UINT64_C(1000000000), + UINT64_C(10000000000), + UINT64_C(100000000000), + UINT64_C(1000000000000), + UINT64_C(10000000000000), + UINT64_C(100000000000000), + UINT64_C(1000000000000000), + UINT64_C(10000000000000000), + UINT64_C(100000000000000000), + UINT64_C(1000000000000000000), + UINT64_C(10000000000000000000)}; + +# ifndef _LIBCPP_HAS_NO_INT128 +inline constexpr int __pow10_128_offset = 0; +inline constexpr __uint128_t __pow10_128[40] = { + UINT64_C(0), + UINT64_C(10), + UINT64_C(100), + UINT64_C(1000), + UINT64_C(10000), + UINT64_C(100000), + UINT64_C(1000000), + UINT64_C(10000000), + UINT64_C(100000000), + UINT64_C(1000000000), + UINT64_C(10000000000), + UINT64_C(100000000000), + UINT64_C(1000000000000), + UINT64_C(10000000000000), + UINT64_C(100000000000000), + UINT64_C(1000000000000000), + UINT64_C(10000000000000000), + UINT64_C(100000000000000000), + UINT64_C(1000000000000000000), + UINT64_C(10000000000000000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(10), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(100), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(1000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(10000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(100000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(1000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(10000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(100000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(1000000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(10000000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(100000000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(1000000000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(10000000000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(100000000000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(1000000000000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(10000000000000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(100000000000000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(1000000000000000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(10000000000000000000), + (__uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(10000000000000000000)) * 10}; +# endif + +inline constexpr char __digits_base_10[200] = { + // clang-format off + '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '0', '8', '0', '9', + '1', '0', '1', '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6', '1', '7', '1', '8', '1', '9', + '2', '0', '2', '1', '2', '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9', + '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '3', '8', '3', '9', + '4', '0', '4', '1', '4', '2', '4', '3', '4', '4', '4', '5', '4', '6', '4', '7', '4', '8', '4', '9', + '5', '0', '5', '1', '5', '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9', + '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6', '7', '6', '8', '6', '9', + '7', '0', '7', '1', '7', '2', '7', '3', '7', '4', '7', '5', '7', '6', '7', '7', '7', '8', '7', '9', + '8', '0', '8', '1', '8', '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9', + '9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9', '7', '9', '8', '9', '9'}; +// clang-format on + +} // namespace __itoa + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHARCONV_TABLES diff --git a/app/src/main/cpp/libcxx/include/__charconv/to_chars_base_10.h b/app/src/main/cpp/libcxx/include/__charconv/to_chars_base_10.h new file mode 100644 index 0000000..fc7fb76 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__charconv/to_chars_base_10.h @@ -0,0 +1,185 @@ +// -*- 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 _LIBCPP___CHARCONV_TO_CHARS_BASE_10_H +#define _LIBCPP___CHARCONV_TO_CHARS_BASE_10_H + +#include <__algorithm/copy_n.h> +#include <__charconv/tables.h> +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +namespace __itoa { + +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append1(char* __first, uint32_t __value) noexcept { + *__first = '0' + static_cast(__value); + return __first + 1; +} + +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append2(char* __first, uint32_t __value) noexcept { + return std::copy_n(&__digits_base_10[__value * 2], 2, __first); +} + +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append3(char* __first, uint32_t __value) noexcept { + return __itoa::__append2(__itoa::__append1(__first, __value / 100), __value % 100); +} + +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append4(char* __first, uint32_t __value) noexcept { + return __itoa::__append2(__itoa::__append2(__first, __value / 100), __value % 100); +} + +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append5(char* __first, uint32_t __value) noexcept { + return __itoa::__append4(__itoa::__append1(__first, __value / 10000), __value % 10000); +} + +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append6(char* __first, uint32_t __value) noexcept { + return __itoa::__append4(__itoa::__append2(__first, __value / 10000), __value % 10000); +} + +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append7(char* __first, uint32_t __value) noexcept { + return __itoa::__append6(__itoa::__append1(__first, __value / 1000000), __value % 1000000); +} + +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append8(char* __first, uint32_t __value) noexcept { + return __itoa::__append6(__itoa::__append2(__first, __value / 1000000), __value % 1000000); +} + +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append9(char* __first, uint32_t __value) noexcept { + return __itoa::__append8(__itoa::__append1(__first, __value / 100000000), __value % 100000000); +} + +template +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __append10(char* __first, _Tp __value) noexcept { + return __itoa::__append8(__itoa::__append2(__first, static_cast(__value / 100000000)), + static_cast(__value % 100000000)); +} + +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u32(char* __first, uint32_t __value) noexcept { + if (__value < 1000000) { + if (__value < 10000) { + if (__value < 100) { + // 0 <= __value < 100 + if (__value < 10) + return __itoa::__append1(__first, __value); + return __itoa::__append2(__first, __value); + } + // 100 <= __value < 10'000 + if (__value < 1000) + return __itoa::__append3(__first, __value); + return __itoa::__append4(__first, __value); + } + + // 10'000 <= __value < 1'000'000 + if (__value < 100000) + return __itoa::__append5(__first, __value); + return __itoa::__append6(__first, __value); + } + + // __value => 1'000'000 + if (__value < 100000000) { + // 1'000'000 <= __value < 100'000'000 + if (__value < 10000000) + return __itoa::__append7(__first, __value); + return __itoa::__append8(__first, __value); + } + + // 100'000'000 <= __value < max + if (__value < 1000000000) + return __itoa::__append9(__first, __value); + return __itoa::__append10(__first, __value); +} + +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u64(char* __buffer, uint64_t __value) noexcept { + if (__value <= UINT32_MAX) + return __itoa::__base_10_u32(__buffer, static_cast(__value)); + + // Numbers in the range UINT32_MAX <= val < 10'000'000'000 always contain 10 + // digits and are outputted after this if statement. + if (__value >= 10000000000) { + // This function properly deterimines the first non-zero leading digit. + __buffer = __itoa::__base_10_u32(__buffer, static_cast(__value / 10000000000)); + __value %= 10000000000; + } + return __itoa::__append10(__buffer, __value); +} + +# ifndef _LIBCPP_HAS_NO_INT128 +/// \returns 10^\a exp +/// +/// \pre \a exp [19, 39] +/// +/// \note The lookup table contains a partial set of exponents limiting the +/// range that can be used. However the range is sufficient for +/// \ref __base_10_u128. +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline __uint128_t __pow_10(int __exp) noexcept { + _LIBCPP_ASSERT(__exp >= __pow10_128_offset, "Index out of bounds"); + return __pow10_128[__exp - __pow10_128_offset]; +} + +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u128(char* __buffer, __uint128_t __value) noexcept { + _LIBCPP_ASSERT( + __value > numeric_limits::max(), "The optimizations for this algorithm fail when this isn't true."); + + // Unlike the 64 to 32 bit case the 128 bit case the "upper half" can't be + // stored in the "lower half". Instead we first need to handle the top most + // digits separately. + // + // Maximum unsigned values + // 64 bit 18'446'744'073'709'551'615 (20 digits) + // 128 bit 340'282'366'920'938'463'463'374'607'431'768'211'455 (39 digits) + // step 1 ^ ([0-1] digits) + // step 2 ^^^^^^^^^^^^^^^^^^^^^^^^^ ([0-19] digits) + // step 3 ^^^^^^^^^^^^^^^^^^^^^^^^^ (19 digits) + if (__value >= __itoa::__pow_10(38)) { + // step 1 + __buffer = __itoa::__append1(__buffer, static_cast(__value / __itoa::__pow_10(38))); + __value %= __itoa::__pow_10(38); + + // step 2 always 19 digits. + // They are handled here since leading zeros need to be appended to the buffer, + __buffer = __itoa::__append9(__buffer, static_cast(__value / __itoa::__pow_10(29))); + __value %= __itoa::__pow_10(29); + __buffer = __itoa::__append10(__buffer, static_cast(__value / __itoa::__pow_10(19))); + __value %= __itoa::__pow_10(19); + } + else { + // step 2 + // This version needs to determine the position of the leading non-zero digit. + __buffer = __base_10_u64(__buffer, static_cast(__value / __itoa::__pow_10(19))); + __value %= __itoa::__pow_10(19); + } + + // Step 3 + __buffer = __itoa::__append9(__buffer, static_cast(__value / 10000000000)); + __buffer = __itoa::__append10(__buffer, static_cast(__value % 10000000000)); + + return __buffer; +} +# endif +} // namespace __itoa + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___CHARCONV_TO_CHARS_BASE_10_H diff --git a/app/src/main/cpp/libcxx/include/__charconv/to_chars_result.h b/app/src/main/cpp/libcxx/include/__charconv/to_chars_result.h new file mode 100644 index 0000000..2eb4098 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__charconv/to_chars_result.h @@ -0,0 +1,37 @@ +// -*- 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 _LIBCPP___CHARCONV_TO_CHARS_RESULT_H +#define _LIBCPP___CHARCONV_TO_CHARS_RESULT_H + +#include <__config> +#include <__errc> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +struct _LIBCPP_TYPE_VIS to_chars_result +{ + char* ptr; + errc ec; +# if _LIBCPP_STD_VER > 17 + _LIBCPP_HIDE_FROM_ABI friend bool operator==(const to_chars_result&, const to_chars_result&) = default; +# endif +}; + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHARCONV_TO_CHARS_RESULT_H diff --git a/app/src/main/cpp/libcxx/include/__chrono/calendar.h b/app/src/main/cpp/libcxx/include/__chrono/calendar.h new file mode 100644 index 0000000..d3762a6 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__chrono/calendar.h @@ -0,0 +1,44 @@ +// -*- 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 _LIBCPP___CHRONO_CALENDAR_H +#define _LIBCPP___CHRONO_CALENDAR_H + +#include <__chrono/duration.h> +#include <__chrono/time_point.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +struct local_t {}; +template +using local_time = time_point; +using local_seconds = local_time; +using local_days = local_time; + +struct last_spec { _LIBCPP_HIDE_FROM_ABI explicit last_spec() = default; }; +inline constexpr last_spec last{}; + + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___CHRONO_CALENDAR_H diff --git a/app/src/main/cpp/libcxx/include/__chrono/convert_to_timespec.h b/app/src/main/cpp/libcxx/include/__chrono/convert_to_timespec.h new file mode 100644 index 0000000..fab07f2 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__chrono/convert_to_timespec.h @@ -0,0 +1,56 @@ +// -*- 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 _LIBCPP___CHRONO_CONVERT_TO_TIMESPEC_H +#define _LIBCPP___CHRONO_CONVERT_TO_TIMESPEC_H + +#include <__chrono/duration.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Convert a nanoseconds duration to the given TimeSpec type, which must have +// the same properties as std::timespec. +template +_LIBCPP_HIDE_FROM_ABI inline +_TimeSpec __convert_to_timespec(const chrono::nanoseconds& __ns) +{ + using namespace chrono; + seconds __s = duration_cast(__ns); + _TimeSpec __ts; + typedef decltype(__ts.tv_sec) __ts_sec; + const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max(); + + if (__s.count() < __ts_sec_max) + { + __ts.tv_sec = static_cast<__ts_sec>(__s.count()); + __ts.tv_nsec = static_cast((__ns - __s).count()); + } + else + { + __ts.tv_sec = __ts_sec_max; + __ts.tv_nsec = 999999999; // (10^9 - 1) + } + + return __ts; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___CHRONO_CONVERT_TO_TIMESPEC_H diff --git a/app/src/main/cpp/libcxx/include/__chrono/convert_to_tm.h b/app/src/main/cpp/libcxx/include/__chrono/convert_to_tm.h new file mode 100644 index 0000000..36846b3 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__chrono/convert_to_tm.h @@ -0,0 +1,127 @@ +// -*- 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 _LIBCPP___CHRONO_CONVERT_TO_TM_H +#define _LIBCPP___CHRONO_CONVERT_TO_TM_H + +#include <__chrono/day.h> +#include <__chrono/duration.h> +#include <__chrono/hh_mm_ss.h> +#include <__chrono/month.h> +#include <__chrono/month_weekday.h> +#include <__chrono/monthday.h> +#include <__chrono/statically_widen.h> +#include <__chrono/system_clock.h> +#include <__chrono/time_point.h> +#include <__chrono/weekday.h> +#include <__chrono/year.h> +#include <__chrono/year_month.h> +#include <__chrono/year_month_day.h> +#include <__chrono/year_month_weekday.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__memory/addressof.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// Conerts a chrono date and weekday to a given _Tm type. +// +// This is an implementation detail for the function +// template +// _Tm __convert_to_tm(const _ChronoT& __value) +// +// This manually converts the two values to the proper type. It is possible to +// convert from sys_days to time_t and then to _Tm. But this leads to the Y2K +// bug when time_t is a 32-bit signed integer. Chrono considers years beyond +// the year 2038 valid, so instead do the transformation manually. +template + requires(same_as<_Date, chrono::year_month_day> || same_as<_Date, chrono::year_month_day_last>) +_LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _Date& __date, chrono::weekday __weekday) { + _Tm __result = {}; +# ifdef __GLIBC__ + __result.tm_zone = "UTC"; +# endif + __result.tm_year = static_cast(__date.year()) - 1900; + __result.tm_mon = static_cast(__date.month()) - 1; + __result.tm_mday = static_cast(__date.day()); + __result.tm_wday = static_cast(__weekday.c_encoding()); + __result.tm_yday = + (static_cast(__date) - + static_cast(chrono::year_month_day{__date.year(), chrono::January, chrono::day{1}})) + .count(); + + return __result; +} + +// Convert a chrono (calendar) time point, or dururation to the given _Tm type, +// which must have the same properties as std::tm. +template +_LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _ChronoT& __value) { + _Tm __result = {}; +# ifdef __GLIBC__ + __result.tm_zone = "UTC"; +# endif + + if constexpr (chrono::__is_duration<_ChronoT>::value) { + // [time.format]/6 + // ... However, if a flag refers to a "time of day" (e.g. %H, %I, %p, + // etc.), then a specialization of duration is interpreted as the time of + // day elapsed since midnight. + uint64_t __sec = chrono::duration_cast(__value).count(); + __sec %= 24 * 3600; + __result.tm_hour = __sec / 3600; + __sec %= 3600; + __result.tm_min = __sec / 60; + __result.tm_sec = __sec % 60; + } else if constexpr (same_as<_ChronoT, chrono::day>) + __result.tm_mday = static_cast(__value); + else if constexpr (same_as<_ChronoT, chrono::month>) + __result.tm_mon = static_cast(__value) - 1; + else if constexpr (same_as<_ChronoT, chrono::year>) + __result.tm_year = static_cast(__value) - 1900; + else if constexpr (same_as<_ChronoT, chrono::weekday>) + __result.tm_wday = __value.c_encoding(); + else if constexpr (same_as<_ChronoT, chrono::weekday_indexed> || same_as<_ChronoT, chrono::weekday_last>) + __result.tm_wday = __value.weekday().c_encoding(); + else if constexpr (same_as<_ChronoT, chrono::month_day>) { + __result.tm_mday = static_cast(__value.day()); + __result.tm_mon = static_cast(__value.month()) - 1; + } else if constexpr (same_as<_ChronoT, chrono::month_day_last>) { + __result.tm_mon = static_cast(__value.month()) - 1; + } else if constexpr (same_as<_ChronoT, chrono::month_weekday> || same_as<_ChronoT, chrono::month_weekday_last>) { + __result.tm_wday = __value.weekday_indexed().weekday().c_encoding(); + __result.tm_mon = static_cast(__value.month()) - 1; + } else if constexpr (same_as<_ChronoT, chrono::year_month>) { + __result.tm_year = static_cast(__value.year()) - 1900; + __result.tm_mon = static_cast(__value.month()) - 1; + } else if constexpr (same_as<_ChronoT, chrono::year_month_day> || same_as<_ChronoT, chrono::year_month_day_last>) { + return std::__convert_to_tm<_Tm>( + chrono::year_month_day{__value}, chrono::weekday{static_cast(__value)}); + } else if constexpr (same_as<_ChronoT, chrono::year_month_weekday> || + same_as<_ChronoT, chrono::year_month_weekday_last>) { + return std::__convert_to_tm<_Tm>(chrono::year_month_day{static_cast(__value)}, __value.weekday()); + } else + static_assert(sizeof(_ChronoT) == 0, "Add the missing type specialization"); + + return __result; +} + +#endif //if _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_CONVERT_TO_TM_H diff --git a/app/src/main/cpp/libcxx/include/__chrono/day.h b/app/src/main/cpp/libcxx/include/__chrono/day.h new file mode 100644 index 0000000..35ecfcf --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__chrono/day.h @@ -0,0 +1,84 @@ +// -*- 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 _LIBCPP___CHRONO_DAY_H +#define _LIBCPP___CHRONO_DAY_H + +#include <__chrono/duration.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +class day { +private: + unsigned char __d_; +public: + _LIBCPP_HIDE_FROM_ABI day() = default; + _LIBCPP_HIDE_FROM_ABI explicit inline constexpr day(unsigned __val) noexcept : __d_(static_cast(__val)) {} + _LIBCPP_HIDE_FROM_ABI inline constexpr day& operator++() noexcept { ++__d_; return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr day operator++(int) noexcept { day __tmp = *this; ++(*this); return __tmp; } + _LIBCPP_HIDE_FROM_ABI inline constexpr day& operator--() noexcept { --__d_; return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr day operator--(int) noexcept { day __tmp = *this; --(*this); return __tmp; } + _LIBCPP_HIDE_FROM_ABI constexpr day& operator+=(const days& __dd) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr day& operator-=(const days& __dd) noexcept; + _LIBCPP_HIDE_FROM_ABI explicit inline constexpr operator unsigned() const noexcept { return __d_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __d_ >= 1 && __d_ <= 31; } + }; + + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const day& __lhs, const day& __rhs) noexcept +{ return static_cast(__lhs) == static_cast(__rhs); } + +_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const day& __lhs, const day& __rhs) noexcept { + return static_cast(__lhs) <=> static_cast(__rhs); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +day operator+ (const day& __lhs, const days& __rhs) noexcept +{ return day(static_cast(__lhs) + __rhs.count()); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +day operator+ (const days& __lhs, const day& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +day operator- (const day& __lhs, const days& __rhs) noexcept +{ return __lhs + -__rhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +days operator-(const day& __lhs, const day& __rhs) noexcept +{ return days(static_cast(static_cast(__lhs)) - + static_cast(static_cast(__rhs))); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +day& day::operator+=(const days& __dd) noexcept +{ *this = *this + __dd; return *this; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +day& day::operator-=(const days& __dd) noexcept +{ *this = *this - __dd; return *this; } + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___CHRONO_DAY_H diff --git a/app/src/main/cpp/libcxx/include/__chrono/duration.h b/app/src/main/cpp/libcxx/include/__chrono/duration.h new file mode 100644 index 0000000..afcc38b --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__chrono/duration.h @@ -0,0 +1,622 @@ +// -*- 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 _LIBCPP___CHRONO_DURATION_H +#define _LIBCPP___CHRONO_DURATION_H + +#include <__config> +#include <__type_traits/common_type.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_convertible.h> +#include <__type_traits/is_floating_point.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +template > class _LIBCPP_TEMPLATE_VIS duration; + +template +struct __is_duration : false_type {}; + +template +struct __is_duration > : true_type {}; + +template +struct __is_duration > : true_type {}; + +template +struct __is_duration > : true_type {}; + +template +struct __is_duration > : true_type {}; + +} // namespace chrono + +template +struct _LIBCPP_TEMPLATE_VIS common_type, + chrono::duration<_Rep2, _Period2> > +{ + typedef chrono::duration::type, + typename __ratio_gcd<_Period1, _Period2>::type> type; +}; + +namespace chrono { + +// duration_cast + +template ::type, + bool = _Period::num == 1, + bool = _Period::den == 1> +struct __duration_cast; + +template +struct __duration_cast<_FromDuration, _ToDuration, _Period, true, true> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + _ToDuration operator()(const _FromDuration& __fd) const + { + return _ToDuration(static_cast(__fd.count())); + } +}; + +template +struct __duration_cast<_FromDuration, _ToDuration, _Period, true, false> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + _ToDuration operator()(const _FromDuration& __fd) const + { + typedef typename common_type::type _Ct; + return _ToDuration(static_cast( + static_cast<_Ct>(__fd.count()) / static_cast<_Ct>(_Period::den))); + } +}; + +template +struct __duration_cast<_FromDuration, _ToDuration, _Period, false, true> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + _ToDuration operator()(const _FromDuration& __fd) const + { + typedef typename common_type::type _Ct; + return _ToDuration(static_cast( + static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num))); + } +}; + +template +struct __duration_cast<_FromDuration, _ToDuration, _Period, false, false> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + _ToDuration operator()(const _FromDuration& __fd) const + { + typedef typename common_type::type _Ct; + return _ToDuration(static_cast( + static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num) + / static_cast<_Ct>(_Period::den))); + } +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + _ToDuration +>::type +duration_cast(const duration<_Rep, _Period>& __fd) +{ + return __duration_cast, _ToDuration>()(__fd); +} + +template +struct _LIBCPP_TEMPLATE_VIS treat_as_floating_point : is_floating_point<_Rep> {}; + +#if _LIBCPP_STD_VER > 14 +template +inline constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>::value; +#endif + +template +struct _LIBCPP_TEMPLATE_VIS duration_values +{ +public: + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep zero() _NOEXCEPT {return _Rep(0);} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep max() _NOEXCEPT {return numeric_limits<_Rep>::max();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep min() _NOEXCEPT {return numeric_limits<_Rep>::lowest();} +}; + +#if _LIBCPP_STD_VER > 14 +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + _ToDuration +>::type +floor(const duration<_Rep, _Period>& __d) +{ + _ToDuration __t = chrono::duration_cast<_ToDuration>(__d); + if (__t > __d) + __t = __t - _ToDuration{1}; + return __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + _ToDuration +>::type +ceil(const duration<_Rep, _Period>& __d) +{ + _ToDuration __t = chrono::duration_cast<_ToDuration>(__d); + if (__t < __d) + __t = __t + _ToDuration{1}; + return __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + _ToDuration +>::type +round(const duration<_Rep, _Period>& __d) +{ + _ToDuration __lower = chrono::floor<_ToDuration>(__d); + _ToDuration __upper = __lower + _ToDuration{1}; + auto __lowerDiff = __d - __lower; + auto __upperDiff = __upper - __d; + if (__lowerDiff < __upperDiff) + return __lower; + if (__lowerDiff > __upperDiff) + return __upper; + return __lower.count() & 1 ? __upper : __lower; +} +#endif + +// duration + +template +class _LIBCPP_TEMPLATE_VIS duration +{ + static_assert(!__is_duration<_Rep>::value, "A duration representation can not be a duration"); + static_assert(__is_ratio<_Period>::value, "Second template parameter of duration must be a std::ratio"); + static_assert(_Period::num > 0, "duration period must be positive"); + + template + struct __no_overflow + { + private: + static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value; + static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value; + static const intmax_t __n1 = _R1::num / __gcd_n1_n2; + static const intmax_t __d1 = _R1::den / __gcd_d1_d2; + static const intmax_t __n2 = _R2::num / __gcd_n1_n2; + static const intmax_t __d2 = _R2::den / __gcd_d1_d2; + static const intmax_t max = -((intmax_t(1) << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1); + + template + struct __mul // __overflow == false + { + static const intmax_t value = _Xp * _Yp; + }; + + template + struct __mul<_Xp, _Yp, true> + { + static const intmax_t value = 1; + }; + + public: + static const bool value = (__n1 <= max / __d2) && (__n2 <= max / __d1); + typedef ratio<__mul<__n1, __d2, !value>::value, + __mul<__n2, __d1, !value>::value> type; + }; + +public: + typedef _Rep rep; + typedef typename _Period::type period; +private: + rep __rep_; +public: + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +#ifndef _LIBCPP_CXX03_LANG + duration() = default; +#else + duration() {} +#endif + + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + explicit duration(const _Rep2& __r, + typename enable_if + < + is_convertible::value && + (treat_as_floating_point::value || + !treat_as_floating_point<_Rep2>::value) + >::type* = nullptr) + : __rep_(__r) {} + + // conversions + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + duration(const duration<_Rep2, _Period2>& __d, + typename enable_if + < + __no_overflow<_Period2, period>::value && ( + treat_as_floating_point::value || + (__no_overflow<_Period2, period>::type::den == 1 && + !treat_as_floating_point<_Rep2>::value)) + >::type* = nullptr) + : __rep_(chrono::duration_cast(__d).count()) {} + + // observer + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR rep count() const {return __rep_;} + + // arithmetic + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename common_type::type operator+() const {return typename common_type::type(*this);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename common_type::type operator-() const {return typename common_type::type(-__rep_);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator++() {++__rep_; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration operator++(int) {return duration(__rep_++);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator--() {--__rep_; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration operator--(int) {return duration(__rep_--);} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator+=(const duration& __d) {__rep_ += __d.count(); return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator-=(const duration& __d) {__rep_ -= __d.count(); return *this;} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator*=(const rep& __rhs) {__rep_ *= __rhs; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator/=(const rep& __rhs) {__rep_ /= __rhs; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator%=(const rep& __rhs) {__rep_ %= __rhs; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator%=(const duration& __rhs) {__rep_ %= __rhs.count(); return *this;} + + // special values + + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration zero() _NOEXCEPT {return duration(duration_values::zero());} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration min() _NOEXCEPT {return duration(duration_values::min());} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration max() _NOEXCEPT {return duration(duration_values::max());} +}; + +typedef duration nanoseconds; +typedef duration microseconds; +typedef duration milliseconds; +typedef duration seconds; +typedef duration< long, ratio< 60> > minutes; +typedef duration< long, ratio<3600> > hours; +#if _LIBCPP_STD_VER > 17 +typedef duration< int, ratio_multiply, hours::period>> days; +typedef duration< int, ratio_multiply, days::period>> weeks; +typedef duration< int, ratio_multiply, days::period>> years; +typedef duration< int, ratio_divide>> months; +#endif +// Duration == + +template +struct __duration_eq +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const + { + typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; + return _Ct(__lhs).count() == _Ct(__rhs).count(); + } +}; + +template +struct __duration_eq<_LhsDuration, _LhsDuration> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const + {return __lhs.count() == __rhs.count();} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return __duration_eq, duration<_Rep2, _Period2> >()(__lhs, __rhs); +} + +// Duration != + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return !(__lhs == __rhs); +} + +// Duration < + +template +struct __duration_lt +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const + { + typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; + return _Ct(__lhs).count() < _Ct(__rhs).count(); + } +}; + +template +struct __duration_lt<_LhsDuration, _LhsDuration> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const + {return __lhs.count() < __rhs.count();} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator< (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return __duration_lt, duration<_Rep2, _Period2> >()(__lhs, __rhs); +} + +// Duration > + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator> (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return __rhs < __lhs; +} + +// Duration <= + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator<=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return !(__rhs < __lhs); +} + +// Duration >= + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return !(__lhs < __rhs); +} + +// Duration + + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename common_type, duration<_Rep2, _Period2> >::type +operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef typename common_type, duration<_Rep2, _Period2> >::type _Cd; + return _Cd(_Cd(__lhs).count() + _Cd(__rhs).count()); +} + +// Duration - + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename common_type, duration<_Rep2, _Period2> >::type +operator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef typename common_type, duration<_Rep2, _Period2> >::type _Cd; + return _Cd(_Cd(__lhs).count() - _Cd(__rhs).count()); +} + +// Duration * + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, + duration::type, _Period> +>::type +operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s) +{ + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef duration<_Cr, _Period> _Cd; + return _Cd(_Cd(__d).count() * static_cast<_Cr>(__s)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + is_convertible<_Rep1, typename common_type<_Rep1, _Rep2>::type>::value, + duration::type, _Period> +>::type +operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d) +{ + return __d * __s; +} + +// Duration / + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + !__is_duration<_Rep2>::value && + is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, + duration::type, _Period> +>::type +operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s) +{ + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef duration<_Cr, _Period> _Cd; + return _Cd(_Cd(__d).count() / static_cast<_Cr>(__s)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename common_type<_Rep1, _Rep2>::type +operator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef typename common_type, duration<_Rep2, _Period2> >::type _Ct; + return _Ct(__lhs).count() / _Ct(__rhs).count(); +} + +// Duration % + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + !__is_duration<_Rep2>::value && + is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, + duration::type, _Period> +>::type +operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s) +{ + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef duration<_Cr, _Period> _Cd; + return _Cd(_Cd(__d).count() % static_cast<_Cr>(__s)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename common_type, duration<_Rep2, _Period2> >::type +operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef typename common_type, duration<_Rep2, _Period2> >::type _Cd; + return _Cd(static_cast<_Cr>(_Cd(__lhs).count()) % static_cast<_Cr>(_Cd(__rhs).count())); +} + +} // namespace chrono + +#if _LIBCPP_STD_VER > 11 +// Suffixes for duration literals [time.duration.literals] +inline namespace literals +{ + inline namespace chrono_literals + { + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::hours operator""h(unsigned long long __h) + { + return chrono::hours(static_cast(__h)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration> operator""h(long double __h) + { + return chrono::duration>(__h); + } + + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::minutes operator""min(unsigned long long __m) + { + return chrono::minutes(static_cast(__m)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration> operator""min(long double __m) + { + return chrono::duration> (__m); + } + + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::seconds operator""s(unsigned long long __s) + { + return chrono::seconds(static_cast(__s)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration operator""s(long double __s) + { + return chrono::duration (__s); + } + + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::milliseconds operator""ms(unsigned long long __ms) + { + return chrono::milliseconds(static_cast(__ms)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration operator""ms(long double __ms) + { + return chrono::duration(__ms); + } + + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::microseconds operator""us(unsigned long long __us) + { + return chrono::microseconds(static_cast(__us)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration operator""us(long double __us) + { + return chrono::duration (__us); + } + + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::nanoseconds operator""ns(unsigned long long __ns) + { + return chrono::nanoseconds(static_cast(__ns)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration operator""ns(long double __ns) + { + return chrono::duration (__ns); + } + +} // namespace chrono_literals +} // namespace literals + +namespace chrono { // hoist the literals into namespace std::chrono + using namespace literals::chrono_literals; +} // namespace chrono + +#endif // _LIBCPP_STD_VER > 11 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 +# include +#endif + +#endif // _LIBCPP___CHRONO_DURATION_H diff --git a/app/src/main/cpp/libcxx/include/__chrono/file_clock.h b/app/src/main/cpp/libcxx/include/__chrono/file_clock.h new file mode 100644 index 0000000..ef62b83 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__chrono/file_clock.h @@ -0,0 +1,85 @@ +// -*- 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 _LIBCPP___CHRONO_FILE_CLOCK_H +#define _LIBCPP___CHRONO_FILE_CLOCK_H + +#include <__availability> +#include <__chrono/duration.h> +#include <__chrono/system_clock.h> +#include <__chrono/time_point.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM +struct _FilesystemClock; +_LIBCPP_END_NAMESPACE_FILESYSTEM +#endif // !_LIBCPP_CXX03_LANG + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +// [time.clock.file], type file_clock +using file_clock = _VSTD_FS::_FilesystemClock; + +template +using file_time = time_point; + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#ifndef _LIBCPP_CXX03_LANG +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM +struct _FilesystemClock { +#if !defined(_LIBCPP_HAS_NO_INT128) + typedef __int128_t rep; + typedef nano period; +#else + typedef long long rep; + typedef nano period; +#endif + + typedef chrono::duration duration; + typedef chrono::time_point<_FilesystemClock> time_point; + + _LIBCPP_EXPORTED_FROM_ABI + static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = false; + + _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_FUNC_VIS static time_point now() noexcept; + +#if _LIBCPP_STD_VER > 17 + template + _LIBCPP_HIDE_FROM_ABI + static chrono::sys_time<_Duration> to_sys(const chrono::file_time<_Duration>& __t) { + return chrono::sys_time<_Duration>(__t.time_since_epoch()); + } + + template + _LIBCPP_HIDE_FROM_ABI + static chrono::file_time<_Duration> from_sys(const chrono::sys_time<_Duration>& __t) { + return chrono::file_time<_Duration>(__t.time_since_epoch()); + } +#endif // _LIBCPP_STD_VER > 17 +}; +_LIBCPP_END_NAMESPACE_FILESYSTEM +#endif // !_LIBCPP_CXX03_LANG + +#endif // _LIBCPP___CHRONO_FILE_CLOCK_H diff --git a/app/src/main/cpp/libcxx/include/__chrono/formatter.h b/app/src/main/cpp/libcxx/include/__chrono/formatter.h new file mode 100644 index 0000000..2015783 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__chrono/formatter.h @@ -0,0 +1,716 @@ +// -*- 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 _LIBCPP___CHRONO_FORMATTER_H +#define _LIBCPP___CHRONO_FORMATTER_H + +#include <__chrono/calendar.h> +#include <__chrono/convert_to_tm.h> +#include <__chrono/day.h> +#include <__chrono/duration.h> +#include <__chrono/hh_mm_ss.h> +#include <__chrono/month.h> +#include <__chrono/month_weekday.h> +#include <__chrono/monthday.h> +#include <__chrono/ostream.h> +#include <__chrono/parser_std_format_spec.h> +#include <__chrono/statically_widen.h> +#include <__chrono/time_point.h> +#include <__chrono/weekday.h> +#include <__chrono/year.h> +#include <__chrono/year_month.h> +#include <__chrono/year_month_day.h> +#include <__chrono/year_month_weekday.h> +#include <__concepts/arithmetic.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__format/concepts.h> +#include <__format/format_error.h> +#include <__format/format_functions.h> +#include <__format/format_parse_context.h> +#include <__format/formatter.h> +#include <__format/formatter_output.h> +#include <__format/parser_std_format_spec.h> +#include <__memory/addressof.h> +#include +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) + +namespace __formatter { + +/// Formats a time based on a tm struct. +/// +/// This formatter passes the formatting to time_put which uses strftime. When +/// the value is outside the valid range it's unspecified what strftime will +/// output. For example weekday 8 can print 1 when the day is processed modulo +/// 7 since that handles the Sunday for 0-based weekday. It can also print 8 if +/// 7 is handled as a special case. +/// +/// The Standard doesn't specify what to do in this case so the result depends +/// on the result of the underlying code. +/// +/// \pre When the (abbreviated) weekday or month name are used, the caller +/// validates whether the value is valid. So the caller handles that +/// requirement of Table 97: Meaning of conversion specifiers +/// [tab:time.format.spec]. +/// +/// When no chrono-specs are provided it uses the stream formatter. + +// For tiny ratios it's not possible to convert a duration to a hh_mm_ss. This +// fails compile-time due to the limited precision of the ratio (64-bit is too +// small). Therefore a duration uses its own conversion. +template + requires(chrono::__is_duration<_Tp>::value) +_LIBCPP_HIDE_FROM_ABI void __format_sub_seconds(const _Tp& __value, basic_stringstream<_CharT>& __sstr) { + __sstr << std::use_facet>(__sstr.getloc()).decimal_point(); + + auto __fraction = __value - chrono::duration_cast(__value); + if constexpr (chrono::treat_as_floating_point_v) + // When the floating-point value has digits itself they are ignored based + // on the wording in [tab:time.format.spec] + // If the precision of the input cannot be exactly represented with + // seconds, then the format is a decimal floating-point number with a + // fixed format and a precision matching that of the precision of the + // input (or to a microseconds precision if the conversion to + // floating-point decimal seconds cannot be made within 18 fractional + // digits). + // + // This matches the behaviour of MSVC STL, fmtlib interprets this + // differently and uses 3 decimals. + // https://godbolt.org/z/6dsbnW8ba + std::format_to(std::ostreambuf_iterator<_CharT>{__sstr}, + _LIBCPP_STATICALLY_WIDEN(_CharT, "{:0{}.0f}"), + __fraction.count(), + chrono::hh_mm_ss<_Tp>::fractional_width); + else + std::format_to(std::ostreambuf_iterator<_CharT>{__sstr}, + _LIBCPP_STATICALLY_WIDEN(_CharT, "{:0{}}"), + __fraction.count(), + chrono::hh_mm_ss<_Tp>::fractional_width); +} + +template +consteval bool __use_fraction() { + if constexpr (chrono::__is_duration<_Tp>::value) + return chrono::hh_mm_ss<_Tp>::fractional_width; + else + return false; +} + +template +_LIBCPP_HIDE_FROM_ABI void __format_year(int __year, basic_stringstream<_CharT>& __sstr) { + if (__year < 0) { + __sstr << _CharT('-'); + __year = -__year; + } + + // TODO FMT Write an issue + // If the result has less than four digits it is zero-padded with 0 to two digits. + // is less -> has less + // left-padded -> zero-padded, otherwise the proper value would be 000-0. + + // Note according to the wording it should be left padded, which is odd. + __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:04}"), __year); +} + +template +_LIBCPP_HIDE_FROM_ABI void __format_century(int __year, basic_stringstream<_CharT>& __sstr) { + // TODO FMT Write an issue + // [tab:time.format.spec] + // %C The year divided by 100 using floored division. If the result is a + // single decimal digit, it is prefixed with 0. + + bool __negative = __year < 0; + int __century = (__year - (99 * __negative)) / 100; // floored division + __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:02}"), __century); +} + +template +_LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs( + const _Tp& __value, basic_stringstream<_CharT>& __sstr, basic_string_view<_CharT> __chrono_specs) { + tm __t = std::__convert_to_tm(__value); + const auto& __facet = std::use_facet>(__sstr.getloc()); + for (auto __it = __chrono_specs.begin(); __it != __chrono_specs.end(); ++__it) { + if (*__it == _CharT('%')) { + auto __s = __it; + ++__it; + // We only handle the types that can't be directly handled by time_put. + // (as an optimization n, t, and % are also handled directly.) + switch (*__it) { + case _CharT('n'): + __sstr << _CharT('\n'); + break; + case _CharT('t'): + __sstr << _CharT('\t'); + break; + case _CharT('%'): + __sstr << *__it; + break; + + case _CharT('C'): { + // strftime's output is only defined in the range [00, 99]. + int __year = __t.tm_year + 1900; + if (__year < 1000 || __year > 9999) + __formatter::__format_century(__year, __sstr); + else + __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1); + } break; + + case _CharT('j'): + if constexpr (chrono::__is_duration<_Tp>::value) + // Converting a duration where the period has a small ratio to days + // may fail to compile. This due to loss of precision in the + // conversion. In order to avoid that issue convert to seconds as + // an intemediate step. + __sstr << chrono::duration_cast(chrono::duration_cast(__value)).count(); + else + __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1); + break; + + case _CharT('q'): + if constexpr (chrono::__is_duration<_Tp>::value) { + __sstr << chrono::__units_suffix<_CharT, typename _Tp::period>(); + break; + } + __builtin_unreachable(); + + case _CharT('Q'): + // TODO FMT Determine the proper ideas + // - Should it honour the precision? + // - Shoult it honour the locale setting for the separators? + // The wording for Q doesn't use the word locale and the effect of + // precision is unspecified. + // + // MSVC STL ignores precision but uses separator + // FMT honours precision and has a bug for separator + // https://godbolt.org/z/78b7sMxns + if constexpr (chrono::__is_duration<_Tp>::value) { + __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{}"), __value.count()); + break; + } + __builtin_unreachable(); + + case _CharT('S'): + case _CharT('T'): + __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1); + if constexpr (__use_fraction<_Tp>()) + __formatter::__format_sub_seconds(__value, __sstr); + break; + + // Unlike time_put and strftime the formatting library requires %Y + // + // [tab:time.format.spec] + // The year as a decimal number. If the result is less than four digits + // it is left-padded with 0 to four digits. + // + // This means years in the range (-1000, 1000) need manual formatting. + // It's unclear whether %EY needs the same treatment. For example the + // Japanese EY contains the era name and year. This is zero-padded to 2 + // digits in time_put (note that older glibc versions didn't do + // padding.) However most eras won't reach 100 years, let alone 1000. + // So padding to 4 digits seems unwanted for Japanese. + // + // The same applies to %Ex since that too depends on the era. + // + // %x the locale's date representation is currently doesn't handle the + // zero-padding too. + // + // The 4 digits can be implemented better at a later time. On POSIX + // systems the required information can be extracted by nl_langinfo + // https://man7.org/linux/man-pages/man3/nl_langinfo.3.html + // + // Note since year < -1000 is expected to be rare it uses the more + // expensive year routine. + // + // TODO FMT evaluate the comment above. + +# if defined(__GLIBC__) || defined(_AIX) + case _CharT('y'): + // Glibc fails for negative values, AIX for positive values too. + __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:02}"), (std::abs(__t.tm_year + 1900)) % 100); + break; +# endif // defined(__GLIBC__) || defined(_AIX) + + case _CharT('Y'): { + int __year = __t.tm_year + 1900; + if (__year < 1000) + __formatter::__format_year(__year, __sstr); + else + __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1); + } break; + + case _CharT('F'): { + int __year = __t.tm_year + 1900; + if (__year < 1000) { + __formatter::__format_year(__year, __sstr); + __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "-{:02}-{:02}"), __t.tm_mon + 1, __t.tm_mday); + } else + __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1); + } break; + + case _CharT('O'): + if constexpr (__use_fraction<_Tp>()) { + // Handle OS using the normal representation for the non-fractional + // part. There seems to be no locale information regarding how the + // fractional part should be formatted. + if (*(__it + 1) == 'S') { + ++__it; + __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1); + __formatter::__format_sub_seconds(__value, __sstr); + break; + } + } + [[fallthrough]]; + case _CharT('E'): + ++__it; + [[fallthrough]]; + default: + __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1); + break; + } + } else { + __sstr << *__it; + } + } +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_ok(const _Tp& __value) { + if constexpr (same_as<_Tp, chrono::day>) + return true; + else if constexpr (same_as<_Tp, chrono::month>) + return __value.ok(); + else if constexpr (same_as<_Tp, chrono::year>) + return true; + else if constexpr (same_as<_Tp, chrono::weekday>) + return true; + else if constexpr (same_as<_Tp, chrono::weekday_indexed>) + return true; + else if constexpr (same_as<_Tp, chrono::weekday_last>) + return true; + else if constexpr (same_as<_Tp, chrono::month_day>) + return true; + else if constexpr (same_as<_Tp, chrono::month_day_last>) + return true; + else if constexpr (same_as<_Tp, chrono::month_weekday>) + return true; + else if constexpr (same_as<_Tp, chrono::month_weekday_last>) + return true; + else if constexpr (same_as<_Tp, chrono::year_month>) + return true; + else if constexpr (same_as<_Tp, chrono::year_month_day>) + return __value.ok(); + else if constexpr (same_as<_Tp, chrono::year_month_day_last>) + return __value.ok(); + else if constexpr (same_as<_Tp, chrono::year_month_weekday>) + return __value.weekday().ok(); + else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>) + return __value.weekday().ok(); + else + static_assert(sizeof(_Tp) == 0, "Add the missing type specialization"); +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_name_ok(const _Tp& __value) { + if constexpr (same_as<_Tp, chrono::day>) + return true; + else if constexpr (same_as<_Tp, chrono::month>) + return __value.ok(); + else if constexpr (same_as<_Tp, chrono::year>) + return true; + else if constexpr (same_as<_Tp, chrono::weekday>) + return __value.ok(); + else if constexpr (same_as<_Tp, chrono::weekday_indexed>) + return __value.weekday().ok(); + else if constexpr (same_as<_Tp, chrono::weekday_last>) + return __value.weekday().ok(); + else if constexpr (same_as<_Tp, chrono::month_day>) + return true; + else if constexpr (same_as<_Tp, chrono::month_day_last>) + return true; + else if constexpr (same_as<_Tp, chrono::month_weekday>) + return __value.weekday_indexed().ok(); + else if constexpr (same_as<_Tp, chrono::month_weekday_last>) + return __value.weekday_indexed().ok(); + else if constexpr (same_as<_Tp, chrono::year_month>) + return true; + else if constexpr (same_as<_Tp, chrono::year_month_day>) + return __value.ok(); + else if constexpr (same_as<_Tp, chrono::year_month_day_last>) + return __value.ok(); + else if constexpr (same_as<_Tp, chrono::year_month_weekday>) + return __value.weekday().ok(); + else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>) + return __value.weekday().ok(); + else + static_assert(sizeof(_Tp) == 0, "Add the missing type specialization"); +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool __date_ok(const _Tp& __value) { + if constexpr (same_as<_Tp, chrono::day>) + return true; + else if constexpr (same_as<_Tp, chrono::month>) + return __value.ok(); + else if constexpr (same_as<_Tp, chrono::year>) + return true; + else if constexpr (same_as<_Tp, chrono::weekday>) + return true; + else if constexpr (same_as<_Tp, chrono::weekday_indexed>) + return true; + else if constexpr (same_as<_Tp, chrono::weekday_last>) + return true; + else if constexpr (same_as<_Tp, chrono::month_day>) + return true; + else if constexpr (same_as<_Tp, chrono::month_day_last>) + return true; + else if constexpr (same_as<_Tp, chrono::month_weekday>) + return true; + else if constexpr (same_as<_Tp, chrono::month_weekday_last>) + return true; + else if constexpr (same_as<_Tp, chrono::year_month>) + return true; + else if constexpr (same_as<_Tp, chrono::year_month_day>) + return __value.ok(); + else if constexpr (same_as<_Tp, chrono::year_month_day_last>) + return __value.ok(); + else if constexpr (same_as<_Tp, chrono::year_month_weekday>) + return __value.ok(); + else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>) + return __value.ok(); + else + static_assert(sizeof(_Tp) == 0, "Add the missing type specialization"); +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool __month_name_ok(const _Tp& __value) { + if constexpr (same_as<_Tp, chrono::day>) + return true; + else if constexpr (same_as<_Tp, chrono::month>) + return __value.ok(); + else if constexpr (same_as<_Tp, chrono::year>) + return true; + else if constexpr (same_as<_Tp, chrono::weekday>) + return true; + else if constexpr (same_as<_Tp, chrono::weekday_indexed>) + return true; + else if constexpr (same_as<_Tp, chrono::weekday_last>) + return true; + else if constexpr (same_as<_Tp, chrono::month_day>) + return __value.month().ok(); + else if constexpr (same_as<_Tp, chrono::month_day_last>) + return __value.month().ok(); + else if constexpr (same_as<_Tp, chrono::month_weekday>) + return __value.month().ok(); + else if constexpr (same_as<_Tp, chrono::month_weekday_last>) + return __value.month().ok(); + else if constexpr (same_as<_Tp, chrono::year_month>) + return __value.month().ok(); + else if constexpr (same_as<_Tp, chrono::year_month_day>) + return __value.month().ok(); + else if constexpr (same_as<_Tp, chrono::year_month_day_last>) + return __value.month().ok(); + else if constexpr (same_as<_Tp, chrono::year_month_weekday>) + return __value.month().ok(); + else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>) + return __value.month().ok(); + else + static_assert(sizeof(_Tp) == 0, "Add the missing type specialization"); +} + +template +_LIBCPP_HIDE_FROM_ABI auto +__format_chrono(const _Tp& __value, + auto& __ctx, + __format_spec::__parsed_specifications<_CharT> __specs, + basic_string_view<_CharT> __chrono_specs) -> decltype(__ctx.out()) { + basic_stringstream<_CharT> __sstr; + // [time.format]/2 + // 2.1 - the "C" locale if the L option is not present in chrono-format-spec, otherwise + // 2.2 - the locale passed to the formatting function if any, otherwise + // 2.3 - the global locale. + // Note that the __ctx's locale() call does 2.2 and 2.3. + if (__specs.__chrono_.__locale_specific_form_) + __sstr.imbue(__ctx.locale()); + else + __sstr.imbue(locale::classic()); + + if (__chrono_specs.empty()) + __sstr << __value; + else { + if constexpr (chrono::__is_duration<_Tp>::value) { + if (__value < __value.zero()) + __sstr << _CharT('-'); + __formatter::__format_chrono_using_chrono_specs(chrono::abs(__value), __sstr, __chrono_specs); + // TODO FMT When keeping the precision it will truncate the string. + // Note that the behaviour what the precision does isn't specified. + __specs.__precision_ = -1; + } else { + // Test __weekday_name_ before __weekday_ to give a better error. + if (__specs.__chrono_.__weekday_name_ && !__formatter::__weekday_name_ok(__value)) + std::__throw_format_error("formatting a weekday name needs a valid weekday"); + + if (__specs.__chrono_.__weekday_ && !__formatter::__weekday_ok(__value)) + std::__throw_format_error("formatting a weekday needs a valid weekday"); + + if (__specs.__chrono_.__day_of_year_ && !__formatter::__date_ok(__value)) + std::__throw_format_error("formatting a day of year needs a valid date"); + + if (__specs.__chrono_.__week_of_year_ && !__formatter::__date_ok(__value)) + std::__throw_format_error("formatting a week of year needs a valid date"); + + if (__specs.__chrono_.__month_name_ && !__formatter::__month_name_ok(__value)) + std::__throw_format_error("formatting a month name from an invalid month number"); + + __formatter::__format_chrono_using_chrono_specs(__value, __sstr, __chrono_specs); + } + } + + // TODO FMT Use the stringstream's view after P0408R7 has been implemented. + basic_string<_CharT> __str = __sstr.str(); + return __formatter::__write_string(basic_string_view<_CharT>{__str}, __ctx.out(), __specs); +} + +} // namespace __formatter + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_chrono { +public: + _LIBCPP_HIDE_FROM_ABI constexpr auto __parse( + basic_format_parse_context<_CharT>& __parse_ctx, __format_spec::__fields __fields, __format_spec::__flags __flags) + -> decltype(__parse_ctx.begin()) { + return __parser_.__parse(__parse_ctx, __fields, __flags); + } + + template + _LIBCPP_HIDE_FROM_ABI auto format(const _Tp& __value, auto& __ctx) const -> decltype(__ctx.out()) const { + return __formatter::__format_chrono( + __value, __ctx, __parser_.__parser_.__get_parsed_chrono_specifications(__ctx), __parser_.__chrono_specs_); + } + + __format_spec::__parser_chrono<_CharT> __parser_; +}; + +template +struct formatter, _CharT> : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + // [time.format]/1 + // Giving a precision specification in the chrono-format-spec is valid only + // for std::chrono::duration types where the representation type Rep is a + // floating-point type. For all other Rep types, an exception of type + // format_error is thrown if the chrono-format-spec contains a precision + // specification. + // + // Note this doesn't refer to chrono::treat_as_floating_point_v<_Rep>. + if constexpr (std::floating_point<_Rep>) + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono_fractional, __format_spec::__flags::__duration); + else + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__duration); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__day); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__year); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_day); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_weekday); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_weekday); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__year_month); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date); + } +}; + +#endif // if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_FORMATTER_H diff --git a/app/src/main/cpp/libcxx/include/__chrono/hh_mm_ss.h b/app/src/main/cpp/libcxx/include/__chrono/hh_mm_ss.h new file mode 100644 index 0000000..fd61cbe --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__chrono/hh_mm_ss.h @@ -0,0 +1,112 @@ +// -*- 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 _LIBCPP___CHRONO_HH_MM_SS_H +#define _LIBCPP___CHRONO_HH_MM_SS_H + +#include <__chrono/duration.h> +#include <__chrono/time_point.h> +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +template +class hh_mm_ss +{ +private: + static_assert(__is_duration<_Duration>::value, "template parameter of hh_mm_ss must be a std::chrono::duration"); + using __CommonType = common_type_t<_Duration, chrono::seconds>; + + _LIBCPP_HIDE_FROM_ABI static constexpr uint64_t __pow10(unsigned __exp) + { + uint64_t __ret = 1; + for (unsigned __i = 0; __i < __exp; ++__i) + __ret *= 10U; + return __ret; + } + + _LIBCPP_HIDE_FROM_ABI static constexpr unsigned __width(uint64_t __n, uint64_t __d = 10, unsigned __w = 0) + { + if (__n >= 2 && __d != 0 && __w < 19) + return 1 + __width(__n, __d % __n * 10, __w+1); + return 0; + } + +public: + _LIBCPP_HIDE_FROM_ABI static unsigned constexpr fractional_width = __width(__CommonType::period::den) < 19 ? + __width(__CommonType::period::den) : 6u; + using precision = duration>; + + _LIBCPP_HIDE_FROM_ABI constexpr hh_mm_ss() noexcept : hh_mm_ss{_Duration::zero()} {} + + _LIBCPP_HIDE_FROM_ABI constexpr explicit hh_mm_ss(_Duration __d) noexcept : + __is_neg_(__d < _Duration(0)), + __h_(chrono::duration_cast (chrono::abs(__d))), + __m_(chrono::duration_cast(chrono::abs(__d) - hours())), + __s_(chrono::duration_cast(chrono::abs(__d) - hours() - minutes())), + __f_(chrono::duration_cast (chrono::abs(__d) - hours() - minutes() - seconds())) + {} + + _LIBCPP_HIDE_FROM_ABI constexpr bool is_negative() const noexcept { return __is_neg_; } + _LIBCPP_HIDE_FROM_ABI constexpr chrono::hours hours() const noexcept { return __h_; } + _LIBCPP_HIDE_FROM_ABI constexpr chrono::minutes minutes() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI constexpr chrono::seconds seconds() const noexcept { return __s_; } + _LIBCPP_HIDE_FROM_ABI constexpr precision subseconds() const noexcept { return __f_; } + + _LIBCPP_HIDE_FROM_ABI constexpr precision to_duration() const noexcept + { + auto __dur = __h_ + __m_ + __s_ + __f_; + return __is_neg_ ? -__dur : __dur; + } + + _LIBCPP_HIDE_FROM_ABI constexpr explicit operator precision() const noexcept { return to_duration(); } + +private: + bool __is_neg_; + chrono::hours __h_; + chrono::minutes __m_; + chrono::seconds __s_; + precision __f_; +}; + +_LIBCPP_HIDE_FROM_ABI constexpr bool is_am(const hours& __h) noexcept { return __h >= hours( 0) && __h < hours(12); } +_LIBCPP_HIDE_FROM_ABI constexpr bool is_pm(const hours& __h) noexcept { return __h >= hours(12) && __h < hours(24); } + +_LIBCPP_HIDE_FROM_ABI constexpr hours make12(const hours& __h) noexcept +{ + if (__h == hours( 0)) return hours(12); + else if (__h <= hours(12)) return __h; + else return __h - hours(12); +} + +_LIBCPP_HIDE_FROM_ABI constexpr hours make24(const hours& __h, bool __is_pm) noexcept +{ + if (__is_pm) + return __h == hours(12) ? __h : __h + hours(12); + else + return __h == hours(12) ? hours(0) : __h; +} +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___CHRONO_HH_MM_SS_H diff --git a/app/src/main/cpp/libcxx/include/__chrono/high_resolution_clock.h b/app/src/main/cpp/libcxx/include/__chrono/high_resolution_clock.h new file mode 100644 index 0000000..778ff44 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__chrono/high_resolution_clock.h @@ -0,0 +1,36 @@ +// -*- 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 _LIBCPP___CHRONO_HIGH_RESOLUTION_CLOCK_H +#define _LIBCPP___CHRONO_HIGH_RESOLUTION_CLOCK_H + +#include <__chrono/steady_clock.h> +#include <__chrono/system_clock.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK +typedef steady_clock high_resolution_clock; +#else +typedef system_clock high_resolution_clock; +#endif + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_HIGH_RESOLUTION_CLOCK_H diff --git a/app/src/main/cpp/libcxx/include/__chrono/literals.h b/app/src/main/cpp/libcxx/include/__chrono/literals.h new file mode 100644 index 0000000..50529bd --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__chrono/literals.h @@ -0,0 +1,49 @@ +// -*- 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 _LIBCPP___CHRONO_LITERALS_H +#define _LIBCPP___CHRONO_LITERALS_H + +#include <__chrono/day.h> +#include <__chrono/year.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +inline namespace literals +{ + inline namespace chrono_literals + { + _LIBCPP_HIDE_FROM_ABI constexpr chrono::day operator ""d(unsigned long long __d) noexcept + { + return chrono::day(static_cast(__d)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::year operator ""y(unsigned long long __y) noexcept + { + return chrono::year(static_cast(__y)); + } +} // namespace chrono_literals +} // namespace literals + +namespace chrono { // hoist the literals into namespace std::chrono + using namespace literals::chrono_literals; +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___CHRONO_LITERALS_H diff --git a/app/src/main/cpp/libcxx/include/__chrono/month.h b/app/src/main/cpp/libcxx/include/__chrono/month.h new file mode 100644 index 0000000..e929f24 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__chrono/month.h @@ -0,0 +1,103 @@ +// -*- 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 _LIBCPP___CHRONO_MONTH_H +#define _LIBCPP___CHRONO_MONTH_H + +#include <__chrono/duration.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +class month { +private: + unsigned char __m_; +public: + _LIBCPP_HIDE_FROM_ABI month() = default; + _LIBCPP_HIDE_FROM_ABI explicit inline constexpr month(unsigned __val) noexcept : __m_(static_cast(__val)) {} + _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator++() noexcept { ++__m_; return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr month operator++(int) noexcept { month __tmp = *this; ++(*this); return __tmp; } + _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator--() noexcept { --__m_; return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr month operator--(int) noexcept { month __tmp = *this; --(*this); return __tmp; } + _LIBCPP_HIDE_FROM_ABI constexpr month& operator+=(const months& __m1) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr month& operator-=(const months& __m1) noexcept; + _LIBCPP_HIDE_FROM_ABI explicit inline constexpr operator unsigned() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m_ >= 1 && __m_ <= 12; } +}; + + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const month& __lhs, const month& __rhs) noexcept +{ return static_cast(__lhs) == static_cast(__rhs); } + +_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const month& __lhs, const month& __rhs) noexcept { + return static_cast(__lhs) <=> static_cast(__rhs); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month operator+ (const month& __lhs, const months& __rhs) noexcept +{ + auto const __mu = static_cast(static_cast(__lhs)) + (__rhs.count() - 1); + auto const __yr = (__mu >= 0 ? __mu : __mu - 11) / 12; + return month{static_cast(__mu - __yr * 12 + 1)}; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month operator+ (const months& __lhs, const month& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month operator- (const month& __lhs, const months& __rhs) noexcept +{ return __lhs + -__rhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +months operator-(const month& __lhs, const month& __rhs) noexcept +{ + auto const __dm = static_cast(__lhs) - static_cast(__rhs); + return months(__dm <= 11 ? __dm : __dm + 12); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month& month::operator+=(const months& __dm) noexcept +{ *this = *this + __dm; return *this; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month& month::operator-=(const months& __dm) noexcept +{ *this = *this - __dm; return *this; } + +inline constexpr month January{1}; +inline constexpr month February{2}; +inline constexpr month March{3}; +inline constexpr month April{4}; +inline constexpr month May{5}; +inline constexpr month June{6}; +inline constexpr month July{7}; +inline constexpr month August{8}; +inline constexpr month September{9}; +inline constexpr month October{10}; +inline constexpr month November{11}; +inline constexpr month December{12}; + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___CHRONO_MONTH_H diff --git a/app/src/main/cpp/libcxx/include/__chrono/month_weekday.h b/app/src/main/cpp/libcxx/include/__chrono/month_weekday.h new file mode 100644 index 0000000..01cdf76 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__chrono/month_weekday.h @@ -0,0 +1,106 @@ +// -*- 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 _LIBCPP___CHRONO_MONTH_WEEKDAY_H +#define _LIBCPP___CHRONO_MONTH_WEEKDAY_H + +#include <__chrono/month.h> +#include <__chrono/weekday.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +class month_weekday { +private: + chrono::month __m_; + chrono::weekday_indexed __wdi_; +public: + _LIBCPP_HIDE_FROM_ABI constexpr month_weekday(const chrono::month& __mval, const chrono::weekday_indexed& __wdival) noexcept + : __m_{__mval}, __wdi_{__wdival} {} + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m_.ok() && __wdi_.ok(); } +}; + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const month_weekday& __lhs, const month_weekday& __rhs) noexcept +{ return __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator!=(const month_weekday& __lhs, const month_weekday& __rhs) noexcept +{ return !(__lhs == __rhs); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_weekday operator/(const month& __lhs, const weekday_indexed& __rhs) noexcept +{ return month_weekday{__lhs, __rhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_weekday operator/(int __lhs, const weekday_indexed& __rhs) noexcept +{ return month_weekday{month(__lhs), __rhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_weekday operator/(const weekday_indexed& __lhs, const month& __rhs) noexcept +{ return month_weekday{__rhs, __lhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_weekday operator/(const weekday_indexed& __lhs, int __rhs) noexcept +{ return month_weekday{month(__rhs), __lhs}; } + + +class month_weekday_last { + chrono::month __m_; + chrono::weekday_last __wdl_; + public: + _LIBCPP_HIDE_FROM_ABI constexpr month_weekday_last(const chrono::month& __mval, const chrono::weekday_last& __wdlval) noexcept + : __m_{__mval}, __wdl_{__wdlval} {} + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m_.ok() && __wdl_.ok(); } +}; + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept +{ return __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator!=(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept +{ return !(__lhs == __rhs); } + + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_weekday_last operator/(const month& __lhs, const weekday_last& __rhs) noexcept +{ return month_weekday_last{__lhs, __rhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_weekday_last operator/(int __lhs, const weekday_last& __rhs) noexcept +{ return month_weekday_last{month(__lhs), __rhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_weekday_last operator/(const weekday_last& __lhs, const month& __rhs) noexcept +{ return month_weekday_last{__rhs, __lhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_weekday_last operator/(const weekday_last& __lhs, int __rhs) noexcept +{ return month_weekday_last{month(__rhs), __lhs}; } +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___CHRONO_MONTH_WEEKDAY_H diff --git a/app/src/main/cpp/libcxx/include/__chrono/monthday.h b/app/src/main/cpp/libcxx/include/__chrono/monthday.h new file mode 100644 index 0000000..c0ee3e4 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__chrono/monthday.h @@ -0,0 +1,129 @@ +// -*- 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 _LIBCPP___CHRONO_MONTHDAY_H +#define _LIBCPP___CHRONO_MONTHDAY_H + +#include <__chrono/calendar.h> +#include <__chrono/day.h> +#include <__chrono/month.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +class month_day { +private: + chrono::month __m_; + chrono::day __d_; +public: + _LIBCPP_HIDE_FROM_ABI month_day() = default; + _LIBCPP_HIDE_FROM_ABI constexpr month_day(const chrono::month& __mval, const chrono::day& __dval) noexcept + : __m_{__mval}, __d_{__dval} {} + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::day day() const noexcept { return __d_; } + _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept; +}; + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool month_day::ok() const noexcept +{ + if (!__m_.ok()) return false; + const unsigned __dval = static_cast(__d_); + if (__dval < 1 || __dval > 31) return false; + if (__dval <= 29) return true; +// Now we've got either 30 or 31 + const unsigned __mval = static_cast(__m_); + if (__mval == 2) return false; + if (__mval == 4 || __mval == 6 || __mval == 9 || __mval == 11) + return __dval == 30; + return true; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const month_day& __lhs, const month_day& __rhs) noexcept +{ return __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); } + +_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const month_day& __lhs, const month_day& __rhs) noexcept { + if (auto __c = __lhs.month() <=> __rhs.month(); __c != 0) + return __c; + return __lhs.day() <=> __rhs.day(); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_day operator/(const month& __lhs, const day& __rhs) noexcept +{ return month_day{__lhs, __rhs}; } + +_LIBCPP_HIDE_FROM_ABI constexpr +month_day operator/(const day& __lhs, const month& __rhs) noexcept +{ return __rhs / __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_day operator/(const month& __lhs, int __rhs) noexcept +{ return __lhs / day(__rhs); } + +_LIBCPP_HIDE_FROM_ABI constexpr +month_day operator/(int __lhs, const day& __rhs) noexcept +{ return month(__lhs) / __rhs; } + +_LIBCPP_HIDE_FROM_ABI constexpr +month_day operator/(const day& __lhs, int __rhs) noexcept +{ return month(__rhs) / __lhs; } + +class month_day_last { +private: + chrono::month __m_; +public: + _LIBCPP_HIDE_FROM_ABI explicit constexpr month_day_last(const chrono::month& __val) noexcept + : __m_{__val} {} + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m_.ok(); } +}; + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const month_day_last& __lhs, const month_day_last& __rhs) noexcept +{ return __lhs.month() == __rhs.month(); } + +_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering +operator<=>(const month_day_last& __lhs, const month_day_last& __rhs) noexcept { + return __lhs.month() <=> __rhs.month(); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_day_last operator/(const month& __lhs, last_spec) noexcept +{ return month_day_last{__lhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_day_last operator/(last_spec, const month& __rhs) noexcept +{ return month_day_last{__rhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_day_last operator/(int __lhs, last_spec) noexcept +{ return month_day_last{month(__lhs)}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_day_last operator/(last_spec, int __rhs) noexcept +{ return month_day_last{month(__rhs)}; } + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___CHRONO_MONTHDAY_H diff --git a/app/src/main/cpp/libcxx/include/__chrono/ostream.h b/app/src/main/cpp/libcxx/include/__chrono/ostream.h new file mode 100644 index 0000000..30a04bd --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__chrono/ostream.h @@ -0,0 +1,238 @@ +// -*- 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 _LIBCPP___CHRONO_OSTREAM_H +#define _LIBCPP___CHRONO_OSTREAM_H + +#include <__chrono/day.h> +#include <__chrono/duration.h> +#include <__chrono/month.h> +#include <__chrono/month_weekday.h> +#include <__chrono/monthday.h> +#include <__chrono/statically_widen.h> +#include <__chrono/weekday.h> +#include <__chrono/year.h> +#include <__chrono/year_month.h> +#include <__chrono/year_month_day.h> +#include <__chrono/year_month_weekday.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__format/format_functions.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) + +namespace chrono { + +// Depending on the type the return is a const _CharT* or a basic_string<_CharT> +template +_LIBCPP_HIDE_FROM_ABI auto __units_suffix() { + // TODO FMT LWG issue the suffixes are always char and not STATICALLY-WIDEN'ed. + if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "as"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "fs"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "ps"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "ns"); + else if constexpr (same_as) +# ifndef _LIBCPP_HAS_NO_UNICODE + return _LIBCPP_STATICALLY_WIDEN(_CharT, "\u00b5s"); +# else + return _LIBCPP_STATICALLY_WIDEN(_CharT, "us"); +# endif + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "ms"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "cs"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "ds"); + else if constexpr (same_as>) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "s"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "das"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "hs"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "ks"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "Ms"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "Gs"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "Ts"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "Ps"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "Es"); + else if constexpr (same_as>) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "min"); + else if constexpr (same_as>) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "h"); + else if constexpr (same_as>) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "d"); + else if constexpr (_Period::den == 1) + return std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "[{}]s"), _Period::num); + else + return std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "[{}/{}]s"), _Period::num, _Period::den); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const duration<_Rep, _Period>& __d) { + basic_ostringstream<_CharT, _Traits> __s; + __s.flags(__os.flags()); + __s.imbue(__os.getloc()); + __s.precision(__os.precision()); + __s << __d.count() << chrono::__units_suffix<_CharT, _Period>(); + return __os << __s.str(); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const day& __d) { + return __os + << (__d.ok() + ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%d}"), __d) + // Note this error differs from the wording of the Standard. The + // Standard wording doesn't work well on AIX or Windows. There + // the formatted day seems to be either modulo 100 or completely + // omitted. Judging by the wording this is valid. + // TODO FMT Write a paper of file an LWG issue. + : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:02} is not a valid day"), static_cast(__d))); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const month& __m) { + return __os << (__m.ok() ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%b}"), __m) + : std::format(__os.getloc(), + _LIBCPP_STATICALLY_WIDEN(_CharT, "{} is not a valid month"), + static_cast(__m))); // TODO FMT Standard mandated locale isn't used. +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const year& __y) { + return __os << (__y.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%Y}"), __y) + : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%Y} is not a valid year"), __y)); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday& __wd) { + return __os << (__wd.ok() ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%a}"), __wd) + : std::format(__os.getloc(), // TODO FMT Standard mandated locale isn't used. + _LIBCPP_STATICALLY_WIDEN(_CharT, "{} is not a valid weekday"), + static_cast(__wd.c_encoding()))); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_indexed& __wdi) { + auto __i = __wdi.index(); + return __os << (__i >= 1 && __i <= 5 + ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[{}]"), __wdi.weekday(), __i) + : std::format(__os.getloc(), + _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[{} is not a valid index]"), + __wdi.weekday(), + __i)); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_last& __wdl) { + return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[last]"), __wdl.weekday()); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day& __md) { + // TODO FMT The Standard allows 30th of February to be printed. + // It would be nice to show an error message instead. + return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{}"), __md.month(), __md.day()); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day_last& __mdl) { + return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/last"), __mdl.month()); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const month_weekday& __mwd) { + return __os << std::format( + __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{:L}"), __mwd.month(), __mwd.weekday_indexed()); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const month_weekday_last& __mwdl) { + return __os << std::format( + __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{:L}"), __mwdl.month(), __mwdl.weekday_last()); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month& __ym) { + return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}"), __ym.year(), __ym.month()); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_day& __ymd) { + return __os << (__ymd.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%F}"), __ymd) + : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%F} is not a valid date"), __ymd)); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_day_last& __ymdl) { + return __os << std::format( + __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}"), __ymdl.year(), __ymdl.month_day_last()); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday& __ymwd) { + return __os << std::format( + __os.getloc(), + _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}/{:L}"), + __ymwd.year(), + __ymwd.month(), + __ymwd.weekday_indexed()); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday_last& __ymwdl) { + return __os << std::format( + __os.getloc(), + _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}/{:L}"), + __ymwdl.year(), + __ymwdl.month(), + __ymwdl.weekday_last()); +} + +} // namespace chrono + +#endif //if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_OSTREAM_H diff --git a/app/src/main/cpp/libcxx/include/__chrono/parser_std_format_spec.h b/app/src/main/cpp/libcxx/include/__chrono/parser_std_format_spec.h new file mode 100644 index 0000000..dbcfe6d --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__chrono/parser_std_format_spec.h @@ -0,0 +1,410 @@ +// -*- 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 _LIBCPP___CHRONO_PARSER_STD_FORMAT_SPEC_H +#define _LIBCPP___CHRONO_PARSER_STD_FORMAT_SPEC_H + +#include <__config> +#include <__format/concepts.h> +#include <__format/format_error.h> +#include <__format/format_parse_context.h> +#include <__format/formatter_string.h> +#include <__format/parser_std_format_spec.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) + +namespace __format_spec { + +// By not placing this constant in the formatter class it's not duplicated for char and wchar_t +inline constexpr __fields __fields_chrono_fractional{ + .__precision_ = true, .__locale_specific_form_ = true, .__type_ = false}; +inline constexpr __fields __fields_chrono{.__locale_specific_form_ = true, .__type_ = false}; + +/// Flags available or required in a chrono type. +/// +/// The caller of the chrono formatter lists the types it has available and the +/// validation tests whether the requested type spec (e.g. %M) is available in +/// the formatter. +/// When the type in the chrono-format-spec isn't present in the data a +/// \ref format_error is thrown. +enum class __flags { + __second = 0x1, + __minute = 0x2, + __hour = 0x4, + __time = __hour | __minute | __second, + + __day = 0x8, + __month = 0x10, + __year = 0x20, + + __weekday = 0x40, + + __month_day = __day | __month, + __month_weekday = __weekday | __month, + __year_month = __month | __year, + __date = __day | __month | __year | __weekday, + + __date_time = __date | __time, + + __duration = 0x80 | __time, + + __time_zone = 0x100, + + __clock = __date_time | __time_zone +}; + +_LIBCPP_HIDE_FROM_ABI constexpr __flags operator&(__flags __lhs, __flags __rhs) { + return static_cast<__flags>(static_cast(__lhs) & static_cast(__rhs)); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_second(__flags __flags) { + if ((__flags & __flags::__second) != __flags::__second) + std::__throw_format_error("The supplied date time doesn't contain a second"); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_minute(__flags __flags) { + if ((__flags & __flags::__minute) != __flags::__minute) + std::__throw_format_error("The supplied date time doesn't contain a minute"); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_hour(__flags __flags) { + if ((__flags & __flags::__hour) != __flags::__hour) + std::__throw_format_error("The supplied date time doesn't contain an hour"); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_time(__flags __flags) { + if ((__flags & __flags::__time) != __flags::__time) + std::__throw_format_error("The supplied date time doesn't contain a time"); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_day(__flags __flags) { + if ((__flags & __flags::__day) != __flags::__day) + std::__throw_format_error("The supplied date time doesn't contain a day"); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_month(__flags __flags) { + if ((__flags & __flags::__month) != __flags::__month) + std::__throw_format_error("The supplied date time doesn't contain a month"); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_year(__flags __flags) { + if ((__flags & __flags::__year) != __flags::__year) + std::__throw_format_error("The supplied date time doesn't contain a year"); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_date(__flags __flags) { + if ((__flags & __flags::__date) != __flags::__date) + std::__throw_format_error("The supplied date time doesn't contain a date"); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_date_or_duration(__flags __flags) { + if (((__flags & __flags::__date) != __flags::__date) && ((__flags & __flags::__duration) != __flags::__duration)) + std::__throw_format_error("The supplied date time doesn't contain a date or duration"); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_date_time(__flags __flags) { + if ((__flags & __flags::__date_time) != __flags::__date_time) + std::__throw_format_error("The supplied date time doesn't contain a date and time"); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_weekday(__flags __flags) { + if ((__flags & __flags::__weekday) != __flags::__weekday) + std::__throw_format_error("The supplied date time doesn't contain a weekday"); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_duration(__flags __flags) { + if ((__flags & __flags::__duration) != __flags::__duration) + std::__throw_format_error("The supplied date time doesn't contain a duration"); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_time_zone(__flags __flags) { + if ((__flags & __flags::__time_zone) != __flags::__time_zone) + std::__throw_format_error("The supplied date time doesn't contain a time zone"); +} + +template +class _LIBCPP_TEMPLATE_VIS __parser_chrono { +public: + _LIBCPP_HIDE_FROM_ABI constexpr auto + __parse(basic_format_parse_context<_CharT>& __parse_ctx, __fields __fields, __flags __flags) + -> decltype(__parse_ctx.begin()) { + const _CharT* __begin = __parser_.__parse(__parse_ctx, __fields); + const _CharT* __end = __parse_ctx.end(); + if (__begin == __end) + return __begin; + + const _CharT* __last = __parse_chrono_specs(__begin, __end, __flags); + __chrono_specs_ = basic_string_view<_CharT>{__begin, __last}; + + return __last; + } + + __parser<_CharT> __parser_; + basic_string_view<_CharT> __chrono_specs_; + +private: + _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* + __parse_chrono_specs(const _CharT* __begin, const _CharT* __end, __flags __flags) { + _LIBCPP_ASSERT(__begin != __end, + "When called with an empty input the function will cause " + "undefined behavior by evaluating data not in the input"); + + if (*__begin != _CharT('%') && *__begin != _CharT('}')) + std::__throw_format_error("Expected '%' or '}' in the chrono format-string"); + + do { + switch (*__begin) { + case _CharT('{'): + std::__throw_format_error("The chrono-specs contains a '{'"); + + case _CharT('}'): + return __begin; + + case _CharT('%'): + __parse_conversion_spec(__begin, __end, __flags); + [[fallthrough]]; + + default: + // All other literals + ++__begin; + } + + } while (__begin != __end && *__begin != _CharT('}')); + + return __begin; + } + + /// \pre *__begin == '%' + /// \post __begin points at the end parsed conversion-spec + _LIBCPP_HIDE_FROM_ABI constexpr void + __parse_conversion_spec(const _CharT*& __begin, const _CharT* __end, __flags __flags) { + ++__begin; + if (__begin == __end) + std::__throw_format_error("End of input while parsing the modifier chrono conversion-spec"); + + switch (*__begin) { + case _CharT('n'): + case _CharT('t'): + case _CharT('%'): + break; + + case _CharT('S'): + __format_spec::__validate_second(__flags); + break; + + case _CharT('M'): + __format_spec::__validate_minute(__flags); + break; + + case _CharT('p'): // TODO FMT does the formater require an hour or a time? + case _CharT('H'): + case _CharT('I'): + __validate_hour(__flags); + break; + + case _CharT('r'): + case _CharT('R'): + case _CharT('T'): + case _CharT('X'): + __format_spec::__validate_time(__flags); + break; + + case _CharT('d'): + case _CharT('e'): + __format_spec::__validate_day(__flags); + break; + + case _CharT('b'): + case _CharT('h'): + case _CharT('B'): + __parser_.__month_name_ = true; + [[fallthrough]]; + case _CharT('m'): + __format_spec::__validate_month(__flags); + break; + + case _CharT('y'): + case _CharT('C'): + case _CharT('Y'): + __format_spec::__validate_year(__flags); + break; + + case _CharT('j'): + __parser_.__day_of_year_ = true; + __format_spec::__validate_date_or_duration(__flags); + break; + + case _CharT('g'): + case _CharT('G'): + case _CharT('U'): + case _CharT('V'): + case _CharT('W'): + __parser_.__week_of_year_ = true; + [[fallthrough]]; + case _CharT('x'): + case _CharT('D'): + case _CharT('F'): + __format_spec::__validate_date(__flags); + break; + + case _CharT('c'): + __format_spec::__validate_date_time(__flags); + break; + + case _CharT('a'): + case _CharT('A'): + __parser_.__weekday_name_ = true; + [[fallthrough]]; + case _CharT('u'): + case _CharT('w'): + __parser_.__weekday_ = true; + __validate_weekday(__flags); + __format_spec::__validate_weekday(__flags); + break; + + case _CharT('q'): + case _CharT('Q'): + __format_spec::__validate_duration(__flags); + break; + + case _CharT('E'): + __parse_modifier_E(__begin, __end, __flags); + break; + + case _CharT('O'): + __parse_modifier_O(__begin, __end, __flags); + break; + + case _CharT('z'): + case _CharT('Z'): + // Currently there's no time zone information. However some clocks have a + // hard-coded "time zone", for these clocks the information can be used. + // TODO FMT implement time zones. + __format_spec::__validate_time_zone(__flags); + break; + + default: // unknown type; + std::__throw_format_error("The date time type specifier is invalid"); + } + } + + /// \pre *__begin == 'E' + /// \post __begin is incremented by one. + _LIBCPP_HIDE_FROM_ABI constexpr void + __parse_modifier_E(const _CharT*& __begin, const _CharT* __end, __flags __flags) { + ++__begin; + if (__begin == __end) + std::__throw_format_error("End of input while parsing the modifier E"); + + switch (*__begin) { + case _CharT('X'): + __format_spec::__validate_time(__flags); + break; + + case _CharT('y'): + case _CharT('C'): + case _CharT('Y'): + __format_spec::__validate_year(__flags); + break; + + case _CharT('x'): + __format_spec::__validate_date(__flags); + break; + + case _CharT('c'): + __format_spec::__validate_date_time(__flags); + break; + + case _CharT('z'): + // Currently there's no time zone information. However some clocks have a + // hard-coded "time zone", for these clocks the information can be used. + // TODO FMT implement time zones. + __format_spec::__validate_time_zone(__flags); + break; + + default: + std::__throw_format_error("The date time type specifier for modifier E is invalid"); + } + } + + /// \pre *__begin == 'O' + /// \post __begin is incremented by one. + _LIBCPP_HIDE_FROM_ABI constexpr void + __parse_modifier_O(const _CharT*& __begin, const _CharT* __end, __flags __flags) { + ++__begin; + if (__begin == __end) + std::__throw_format_error("End of input while parsing the modifier O"); + + switch (*__begin) { + case _CharT('S'): + __format_spec::__validate_second(__flags); + break; + + case _CharT('M'): + __format_spec::__validate_minute(__flags); + break; + + case _CharT('I'): + case _CharT('H'): + __format_spec::__validate_hour(__flags); + break; + + case _CharT('d'): + case _CharT('e'): + __format_spec::__validate_day(__flags); + break; + + case _CharT('m'): + __format_spec::__validate_month(__flags); + break; + + case _CharT('y'): + __format_spec::__validate_year(__flags); + break; + + case _CharT('U'): + case _CharT('V'): + case _CharT('W'): + __parser_.__week_of_year_ = true; + __format_spec::__validate_date(__flags); + break; + + case _CharT('u'): + case _CharT('w'): + __parser_.__weekday_ = true; + __format_spec::__validate_weekday(__flags); + break; + + case _CharT('z'): + // Currently there's no time zone information. However some clocks have a + // hard-coded "time zone", for these clocks the information can be used. + // TODO FMT implement time zones. + __format_spec::__validate_time_zone(__flags); + break; + + default: + std::__throw_format_error("The date time type specifier for modifier O is invalid"); + } + } +}; + +} // namespace __format_spec + +#endif //_LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_PARSER_STD_FORMAT_SPEC_H diff --git a/app/src/main/cpp/libcxx/include/__chrono/statically_widen.h b/app/src/main/cpp/libcxx/include/__chrono/statically_widen.h new file mode 100644 index 0000000..360b6c2 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__chrono/statically_widen.h @@ -0,0 +1,52 @@ +// -*- 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 _LIBCPP___CHRONO_STATICALLY_WIDEN_H +#define _LIBCPP___CHRONO_STATICALLY_WIDEN_H + +// Implements the STATICALLY-WIDEN exposition-only function. ([time.general]/2) + +#include <__concepts/same_as.h> +#include <__config> +#include <__format/concepts.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template <__fmt_char_type _CharT> +_LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __statically_widen(const char* __str, const wchar_t* __wstr) { + if constexpr (same_as<_CharT, char>) + return __str; + else + return __wstr; +} +# define _LIBCPP_STATICALLY_WIDEN(_CharT, __str) ::std::__statically_widen<_CharT>(__str, L##__str) +# else // _LIBCPP_HAS_NO_WIDE_CHARACTERS + +// Without this indirection the unit test test/libcxx/modules_include.sh.cpp +// fails for the CI build "No wide characters". This seems like a bug. +// TODO FMT investigate why this is needed. +template <__fmt_char_type _CharT> +_LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __statically_widen(const char* __str) { + return __str; +} +# define _LIBCPP_STATICALLY_WIDEN(_CharT, __str) ::std::__statically_widen<_CharT>(__str) +# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_STATICALLY_WIDEN_H diff --git a/app/src/main/cpp/libcxx/include/__chrono/steady_clock.h b/app/src/main/cpp/libcxx/include/__chrono/steady_clock.h new file mode 100644 index 0000000..ba83351 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__chrono/steady_clock.h @@ -0,0 +1,44 @@ +// -*- 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 _LIBCPP___CHRONO_STEADY_CLOCK_H +#define _LIBCPP___CHRONO_STEADY_CLOCK_H + +#include <__chrono/duration.h> +#include <__chrono/time_point.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK +class _LIBCPP_TYPE_VIS steady_clock +{ +public: + typedef nanoseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point time_point; + static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = true; + + static time_point now() _NOEXCEPT; +}; +#endif + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_STEADY_CLOCK_H diff --git a/app/src/main/cpp/libcxx/include/__chrono/system_clock.h b/app/src/main/cpp/libcxx/include/__chrono/system_clock.h new file mode 100644 index 0000000..331db46 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__chrono/system_clock.h @@ -0,0 +1,54 @@ +// -*- 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 _LIBCPP___CHRONO_SYSTEM_CLOCK_H +#define _LIBCPP___CHRONO_SYSTEM_CLOCK_H + +#include <__chrono/duration.h> +#include <__chrono/time_point.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +class _LIBCPP_TYPE_VIS system_clock +{ +public: + typedef microseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point time_point; + static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = false; + + static time_point now() _NOEXCEPT; + static time_t to_time_t (const time_point& __t) _NOEXCEPT; + static time_point from_time_t(time_t __t) _NOEXCEPT; +}; + +#if _LIBCPP_STD_VER > 17 + +template +using sys_time = time_point; +using sys_seconds = sys_time; +using sys_days = sys_time; + +#endif + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_SYSTEM_CLOCK_H diff --git a/app/src/main/cpp/libcxx/include/__chrono/time_point.h b/app/src/main/cpp/libcxx/include/__chrono/time_point.h new file mode 100644 index 0000000..8a8fa21 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__chrono/time_point.h @@ -0,0 +1,251 @@ +// -*- 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 _LIBCPP___CHRONO_TIME_POINT_H +#define _LIBCPP___CHRONO_TIME_POINT_H + +#include <__chrono/duration.h> +#include <__config> +#include <__type_traits/common_type.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_convertible.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +template +class _LIBCPP_TEMPLATE_VIS time_point +{ + static_assert(__is_duration<_Duration>::value, + "Second template parameter of time_point must be a std::chrono::duration"); +public: + typedef _Clock clock; + typedef _Duration duration; + typedef typename duration::rep rep; + typedef typename duration::period period; +private: + duration __d_; + +public: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point() : __d_(duration::zero()) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit time_point(const duration& __d) : __d_(__d) {} + + // conversions + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 + time_point(const time_point& __t, + typename enable_if + < + is_convertible<_Duration2, duration>::value + >::type* = nullptr) + : __d_(__t.time_since_epoch()) {} + + // observer + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 duration time_since_epoch() const {return __d_;} + + // arithmetic + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 time_point& operator+=(const duration& __d) {__d_ += __d; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 time_point& operator-=(const duration& __d) {__d_ -= __d; return *this;} + + // special values + + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point min() _NOEXCEPT {return time_point(duration::min());} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point max() _NOEXCEPT {return time_point(duration::max());} +}; + +} // namespace chrono + +template +struct _LIBCPP_TEMPLATE_VIS common_type, + chrono::time_point<_Clock, _Duration2> > +{ + typedef chrono::time_point<_Clock, typename common_type<_Duration1, _Duration2>::type> type; +}; + +namespace chrono { + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +time_point<_Clock, _ToDuration> +time_point_cast(const time_point<_Clock, _Duration>& __t) +{ + return time_point<_Clock, _ToDuration>(chrono::duration_cast<_ToDuration>(__t.time_since_epoch())); +} + +#if _LIBCPP_STD_VER > 14 +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + time_point<_Clock, _ToDuration> +>::type +floor(const time_point<_Clock, _Duration>& __t) +{ + return time_point<_Clock, _ToDuration>{chrono::floor<_ToDuration>(__t.time_since_epoch())}; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + time_point<_Clock, _ToDuration> +>::type +ceil(const time_point<_Clock, _Duration>& __t) +{ + return time_point<_Clock, _ToDuration>{chrono::ceil<_ToDuration>(__t.time_since_epoch())}; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + time_point<_Clock, _ToDuration> +>::type +round(const time_point<_Clock, _Duration>& __t) +{ + return time_point<_Clock, _ToDuration>{chrono::round<_ToDuration>(__t.time_since_epoch())}; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + numeric_limits<_Rep>::is_signed, + duration<_Rep, _Period> +>::type +abs(duration<_Rep, _Period> __d) +{ + return __d >= __d.zero() ? +__d : -__d; +} +#endif // _LIBCPP_STD_VER > 14 + +// time_point == + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +bool +operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __lhs.time_since_epoch() == __rhs.time_since_epoch(); +} + +// time_point != + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +bool +operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return !(__lhs == __rhs); +} + +// time_point < + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +bool +operator<(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __lhs.time_since_epoch() < __rhs.time_since_epoch(); +} + +// time_point > + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +bool +operator>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __rhs < __lhs; +} + +// time_point <= + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +bool +operator<=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return !(__rhs < __lhs); +} + +// time_point >= + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +bool +operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return !(__lhs < __rhs); +} + +// time_point operator+(time_point x, duration y); + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> +operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr; + return _Tr (__lhs.time_since_epoch() + __rhs); +} + +// time_point operator+(duration x, time_point y); + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +time_point<_Clock, typename common_type, _Duration2>::type> +operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __rhs + __lhs; +} + +// time_point operator-(time_point x, duration y); + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> +operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Ret; + return _Ret(__lhs.time_since_epoch() -__rhs); +} + +// duration operator-(time_point x, time_point y); + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +typename common_type<_Duration1, _Duration2>::type +operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __lhs.time_since_epoch() - __rhs.time_since_epoch(); +} + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___CHRONO_TIME_POINT_H diff --git a/app/src/main/cpp/libcxx/include/__chrono/weekday.h b/app/src/main/cpp/libcxx/include/__chrono/weekday.h new file mode 100644 index 0000000..e0bc8a4 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__chrono/weekday.h @@ -0,0 +1,185 @@ +// -*- 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 _LIBCPP___CHRONO_WEEKDAY_H +#define _LIBCPP___CHRONO_WEEKDAY_H + +#include <__chrono/calendar.h> +#include <__chrono/duration.h> +#include <__chrono/system_clock.h> +#include <__chrono/time_point.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +class weekday_indexed; +class weekday_last; + +class weekday { +private: + unsigned char __wd_; + _LIBCPP_HIDE_FROM_ABI static constexpr unsigned char __weekday_from_days(int __days) noexcept; +public: + _LIBCPP_HIDE_FROM_ABI weekday() = default; + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr weekday(unsigned __val) noexcept : __wd_(static_cast(__val == 7 ? 0 : __val)) {} + _LIBCPP_HIDE_FROM_ABI inline constexpr weekday(const sys_days& __sysd) noexcept + : __wd_(__weekday_from_days(__sysd.time_since_epoch().count())) {} + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr weekday(const local_days& __locd) noexcept + : __wd_(__weekday_from_days(__locd.time_since_epoch().count())) {} + + _LIBCPP_HIDE_FROM_ABI inline constexpr weekday& operator++() noexcept { __wd_ = (__wd_ == 6 ? 0 : __wd_ + 1); return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator++(int) noexcept { weekday __tmp = *this; ++(*this); return __tmp; } + _LIBCPP_HIDE_FROM_ABI inline constexpr weekday& operator--() noexcept { __wd_ = (__wd_ == 0 ? 6 : __wd_ - 1); return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator--(int) noexcept { weekday __tmp = *this; --(*this); return __tmp; } + _LIBCPP_HIDE_FROM_ABI constexpr weekday& operator+=(const days& __dd) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr weekday& operator-=(const days& __dd) noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned c_encoding() const noexcept { return __wd_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned iso_encoding() const noexcept { return __wd_ == 0u ? 7 : __wd_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __wd_ <= 6; } + _LIBCPP_HIDE_FROM_ABI constexpr weekday_indexed operator[](unsigned __index) const noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr weekday_last operator[](last_spec) const noexcept; +}; + + +// https://howardhinnant.github.io/date_algorithms.html#weekday_from_days +_LIBCPP_HIDE_FROM_ABI inline constexpr +unsigned char weekday::__weekday_from_days(int __days) noexcept +{ + return static_cast( + static_cast(__days >= -4 ? (__days+4) % 7 : (__days+5) % 7 + 6) + ); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept +{ return __lhs.c_encoding() == __rhs.c_encoding(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator!=(const weekday& __lhs, const weekday& __rhs) noexcept +{ return !(__lhs == __rhs); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator< (const weekday& __lhs, const weekday& __rhs) noexcept +{ return __lhs.c_encoding() < __rhs.c_encoding(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator> (const weekday& __lhs, const weekday& __rhs) noexcept +{ return __rhs < __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator<=(const weekday& __lhs, const weekday& __rhs) noexcept +{ return !(__rhs < __lhs);} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator>=(const weekday& __lhs, const weekday& __rhs) noexcept +{ return !(__lhs < __rhs); } + +_LIBCPP_HIDE_FROM_ABI constexpr +weekday operator+(const weekday& __lhs, const days& __rhs) noexcept +{ + auto const __mu = static_cast(__lhs.c_encoding()) + __rhs.count(); + auto const __yr = (__mu >= 0 ? __mu : __mu - 6) / 7; + return weekday{static_cast(__mu - __yr * 7)}; +} + +_LIBCPP_HIDE_FROM_ABI constexpr +weekday operator+(const days& __lhs, const weekday& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI constexpr +weekday operator-(const weekday& __lhs, const days& __rhs) noexcept +{ return __lhs + -__rhs; } + +_LIBCPP_HIDE_FROM_ABI constexpr +days operator-(const weekday& __lhs, const weekday& __rhs) noexcept +{ + const int __wdu = __lhs.c_encoding() - __rhs.c_encoding(); + const int __wk = (__wdu >= 0 ? __wdu : __wdu-6) / 7; + return days{__wdu - __wk * 7}; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +weekday& weekday::operator+=(const days& __dd) noexcept +{ *this = *this + __dd; return *this; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +weekday& weekday::operator-=(const days& __dd) noexcept +{ *this = *this - __dd; return *this; } + +class weekday_indexed { +private: + chrono::weekday __wd_; + unsigned char __idx_; +public: + _LIBCPP_HIDE_FROM_ABI weekday_indexed() = default; + _LIBCPP_HIDE_FROM_ABI inline constexpr weekday_indexed(const chrono::weekday& __wdval, unsigned __idxval) noexcept + : __wd_{__wdval}, __idx_(__idxval) {} + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wd_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned index() const noexcept { return __idx_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __wd_.ok() && __idx_ >= 1 && __idx_ <= 5; } +}; + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept +{ return __lhs.weekday() == __rhs.weekday() && __lhs.index() == __rhs.index(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator!=(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept +{ return !(__lhs == __rhs); } + + +class weekday_last { +private: + chrono::weekday __wd_; +public: + _LIBCPP_HIDE_FROM_ABI explicit constexpr weekday_last(const chrono::weekday& __val) noexcept + : __wd_{__val} {} + _LIBCPP_HIDE_FROM_ABI constexpr chrono::weekday weekday() const noexcept { return __wd_; } + _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept { return __wd_.ok(); } +}; + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const weekday_last& __lhs, const weekday_last& __rhs) noexcept +{ return __lhs.weekday() == __rhs.weekday(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator!=(const weekday_last& __lhs, const weekday_last& __rhs) noexcept +{ return !(__lhs == __rhs); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +weekday_indexed weekday::operator[](unsigned __index) const noexcept { return weekday_indexed{*this, __index}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +weekday_last weekday::operator[](last_spec) const noexcept { return weekday_last{*this}; } + + +inline constexpr weekday Sunday{0}; +inline constexpr weekday Monday{1}; +inline constexpr weekday Tuesday{2}; +inline constexpr weekday Wednesday{3}; +inline constexpr weekday Thursday{4}; +inline constexpr weekday Friday{5}; +inline constexpr weekday Saturday{6}; + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___CHRONO_WEEKDAY_H diff --git a/app/src/main/cpp/libcxx/include/__chrono/year.h b/app/src/main/cpp/libcxx/include/__chrono/year.h new file mode 100644 index 0000000..79ee8a0 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__chrono/year.h @@ -0,0 +1,102 @@ +// -*- 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 _LIBCPP___CHRONO_YEAR_H +#define _LIBCPP___CHRONO_YEAR_H + +#include <__chrono/duration.h> +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +class year { +private: + short __y_; +public: + _LIBCPP_HIDE_FROM_ABI year() = default; + _LIBCPP_HIDE_FROM_ABI explicit inline constexpr year(int __val) noexcept : __y_(static_cast(__val)) {} + + _LIBCPP_HIDE_FROM_ABI inline constexpr year& operator++() noexcept { ++__y_; return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr year operator++(int) noexcept { year __tmp = *this; ++(*this); return __tmp; } + _LIBCPP_HIDE_FROM_ABI inline constexpr year& operator--() noexcept { --__y_; return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr year operator--(int) noexcept { year __tmp = *this; --(*this); return __tmp; } + _LIBCPP_HIDE_FROM_ABI constexpr year& operator+=(const years& __dy) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year& operator-=(const years& __dy) noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr year operator+() const noexcept { return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr year operator-() const noexcept { return year{-__y_}; } + + _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_leap() const noexcept { return __y_ % 4 == 0 && (__y_ % 100 != 0 || __y_ % 400 == 0); } + _LIBCPP_HIDE_FROM_ABI explicit inline constexpr operator int() const noexcept { return __y_; } + _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept; + _LIBCPP_HIDE_FROM_ABI static inline constexpr year min() noexcept { return year{-32767}; } + _LIBCPP_HIDE_FROM_ABI static inline constexpr year max() noexcept { return year{ 32767}; } +}; + + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const year& __lhs, const year& __rhs) noexcept +{ return static_cast(__lhs) == static_cast(__rhs); } + +_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const year& __lhs, const year& __rhs) noexcept { + return static_cast(__lhs) <=> static_cast(__rhs); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year operator+ (const year& __lhs, const years& __rhs) noexcept +{ return year(static_cast(__lhs) + __rhs.count()); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year operator+ (const years& __lhs, const year& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year operator- (const year& __lhs, const years& __rhs) noexcept +{ return __lhs + -__rhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +years operator-(const year& __lhs, const year& __rhs) noexcept +{ return years{static_cast(__lhs) - static_cast(__rhs)}; } + + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year& year::operator+=(const years& __dy) noexcept +{ *this = *this + __dy; return *this; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year& year::operator-=(const years& __dy) noexcept +{ *this = *this - __dy; return *this; } + +_LIBCPP_HIDE_FROM_ABI constexpr bool year::ok() const noexcept { + static_assert(static_cast(std::numeric_limits::max()) == static_cast(max())); + return static_cast(min()) <= __y_; +} + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___CHRONO_YEAR_H diff --git a/app/src/main/cpp/libcxx/include/__chrono/year_month.h b/app/src/main/cpp/libcxx/include/__chrono/year_month.h new file mode 100644 index 0000000..9f1e65c --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__chrono/year_month.h @@ -0,0 +1,101 @@ +// -*- 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 _LIBCPP___CHRONO_YEAR_MONTH_H +#define _LIBCPP___CHRONO_YEAR_MONTH_H + +#include <__chrono/duration.h> +#include <__chrono/month.h> +#include <__chrono/year.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +class year_month { + chrono::year __y_; + chrono::month __m_; +public: + _LIBCPP_HIDE_FROM_ABI year_month() = default; + _LIBCPP_HIDE_FROM_ABI constexpr year_month(const chrono::year& __yval, const chrono::month& __mval) noexcept + : __y_{__yval}, __m_{__mval} {} + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator+=(const months& __dm) noexcept { this->__m_ += __dm; return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator-=(const months& __dm) noexcept { this->__m_ -= __dm; return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator+=(const years& __dy) noexcept { this->__y_ += __dy; return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator-=(const years& __dy) noexcept { this->__y_ -= __dy; return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y_.ok() && __m_.ok(); } +}; + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month operator/(const year& __y, const month& __m) noexcept { return year_month{__y, __m}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month operator/(const year& __y, int __m) noexcept { return year_month{__y, month(__m)}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const year_month& __lhs, const year_month& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month(); } + +_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const year_month& __lhs, const year_month& __rhs) noexcept { + if (auto __c = __lhs.year() <=> __rhs.year(); __c != 0) + return __c; + return __lhs.month() <=> __rhs.month(); +} + +_LIBCPP_HIDE_FROM_ABI constexpr +year_month operator+(const year_month& __lhs, const months& __rhs) noexcept +{ + int __dmi = static_cast(static_cast(__lhs.month())) - 1 + __rhs.count(); + const int __dy = (__dmi >= 0 ? __dmi : __dmi-11) / 12; + __dmi = __dmi - __dy * 12 + 1; + return (__lhs.year() + years(__dy)) / month(static_cast(__dmi)); +} + +_LIBCPP_HIDE_FROM_ABI constexpr +year_month operator+(const months& __lhs, const year_month& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI constexpr +year_month operator+(const year_month& __lhs, const years& __rhs) noexcept +{ return (__lhs.year() + __rhs) / __lhs.month(); } + +_LIBCPP_HIDE_FROM_ABI constexpr +year_month operator+(const years& __lhs, const year_month& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI constexpr +months operator-(const year_month& __lhs, const year_month& __rhs) noexcept +{ return (__lhs.year() - __rhs.year()) + months(static_cast(__lhs.month()) - static_cast(__rhs.month())); } + +_LIBCPP_HIDE_FROM_ABI constexpr +year_month operator-(const year_month& __lhs, const months& __rhs) noexcept +{ return __lhs + -__rhs; } + +_LIBCPP_HIDE_FROM_ABI constexpr +year_month operator-(const year_month& __lhs, const years& __rhs) noexcept +{ return __lhs + -__rhs; } + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___CHRONO_YEAR_MONTH_H diff --git a/app/src/main/cpp/libcxx/include/__chrono/year_month_day.h b/app/src/main/cpp/libcxx/include/__chrono/year_month_day.h new file mode 100644 index 0000000..b749014 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__chrono/year_month_day.h @@ -0,0 +1,307 @@ +// -*- 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 _LIBCPP___CHRONO_YEAR_MONTH_DAY_H +#define _LIBCPP___CHRONO_YEAR_MONTH_DAY_H + +#include <__chrono/calendar.h> +#include <__chrono/day.h> +#include <__chrono/duration.h> +#include <__chrono/month.h> +#include <__chrono/monthday.h> +#include <__chrono/system_clock.h> +#include <__chrono/time_point.h> +#include <__chrono/year.h> +#include <__chrono/year_month.h> +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +class year_month_day_last; + +class year_month_day { +private: + chrono::year __y_; + chrono::month __m_; + chrono::day __d_; +public: + _LIBCPP_HIDE_FROM_ABI year_month_day() = default; + _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day( + const chrono::year& __yval, const chrono::month& __mval, const chrono::day& __dval) noexcept + : __y_{__yval}, __m_{__mval}, __d_{__dval} {} + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day(const year_month_day_last& __ymdl) noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day(const sys_days& __sysd) noexcept + : year_month_day(__from_days(__sysd.time_since_epoch())) {} + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr year_month_day(const local_days& __locd) noexcept + : year_month_day(__from_days(__locd.time_since_epoch())) {} + + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator+=(const months& __dm) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator-=(const months& __dm) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator+=(const years& __dy) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator-=(const years& __dy) noexcept; + + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::day day() const noexcept { return __d_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } + + _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept; + + _LIBCPP_HIDE_FROM_ABI static constexpr year_month_day __from_days(days __d) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept; +}; + + +// https://howardhinnant.github.io/date_algorithms.html#civil_from_days +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day year_month_day::__from_days(days __d) noexcept +{ + static_assert(numeric_limits::digits >= 18, ""); + static_assert(numeric_limits::digits >= 20 , ""); + const int __z = __d.count() + 719468; + const int __era = (__z >= 0 ? __z : __z - 146096) / 146097; + const unsigned __doe = static_cast(__z - __era * 146097); // [0, 146096] + const unsigned __yoe = (__doe - __doe/1460 + __doe/36524 - __doe/146096) / 365; // [0, 399] + const int __yr = static_cast(__yoe) + __era * 400; + const unsigned __doy = __doe - (365 * __yoe + __yoe/4 - __yoe/100); // [0, 365] + const unsigned __mp = (5 * __doy + 2)/153; // [0, 11] + const unsigned __dy = __doy - (153 * __mp + 2)/5 + 1; // [1, 31] + const unsigned __mth = __mp + (__mp < 10 ? 3 : -9); // [1, 12] + return year_month_day{chrono::year{__yr + (__mth <= 2)}, chrono::month{__mth}, chrono::day{__dy}}; +} + +// https://howardhinnant.github.io/date_algorithms.html#days_from_civil +_LIBCPP_HIDE_FROM_ABI inline constexpr +days year_month_day::__to_days() const noexcept +{ + static_assert(numeric_limits::digits >= 18, ""); + static_assert(numeric_limits::digits >= 20 , ""); + + const int __yr = static_cast(__y_) - (__m_ <= February); + const unsigned __mth = static_cast(__m_); + const unsigned __dy = static_cast(__d_); + + const int __era = (__yr >= 0 ? __yr : __yr - 399) / 400; + const unsigned __yoe = static_cast(__yr - __era * 400); // [0, 399] + const unsigned __doy = (153 * (__mth + (__mth > 2 ? -3 : 9)) + 2) / 5 + __dy-1; // [0, 365] + const unsigned __doe = __yoe * 365 + __yoe/4 - __yoe/100 + __doy; // [0, 146096] + return days{__era * 146097 + static_cast(__doe) - 719468}; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const year_month_day& __lhs, const year_month_day& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); } + +_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering +operator<=>(const year_month_day& __lhs, const year_month_day& __rhs) noexcept { + if (auto __c = __lhs.year() <=> __rhs.year(); __c != 0) + return __c; + if (auto __c = __lhs.month() <=> __rhs.month(); __c != 0) + return __c; + return __lhs.day() <=> __rhs.day(); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day operator/(const year_month& __lhs, const day& __rhs) noexcept +{ return year_month_day{__lhs.year(), __lhs.month(), __rhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day operator/(const year_month& __lhs, int __rhs) noexcept +{ return __lhs / day(__rhs); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day operator/(const year& __lhs, const month_day& __rhs) noexcept +{ return __lhs / __rhs.month() / __rhs.day(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day operator/(int __lhs, const month_day& __rhs) noexcept +{ return year(__lhs) / __rhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day operator/(const month_day& __lhs, const year& __rhs) noexcept +{ return __rhs / __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day operator/(const month_day& __lhs, int __rhs) noexcept +{ return year(__rhs) / __lhs; } + + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day operator+(const year_month_day& __lhs, const months& __rhs) noexcept +{ return (__lhs.year()/__lhs.month() + __rhs)/__lhs.day(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day operator+(const months& __lhs, const year_month_day& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day operator-(const year_month_day& __lhs, const months& __rhs) noexcept +{ return __lhs + -__rhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day operator+(const year_month_day& __lhs, const years& __rhs) noexcept +{ return (__lhs.year() + __rhs) / __lhs.month() / __lhs.day(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day operator+(const years& __lhs, const year_month_day& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day operator-(const year_month_day& __lhs, const years& __rhs) noexcept +{ return __lhs + -__rhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } + +class year_month_day_last { +private: + chrono::year __y_; + chrono::month_day_last __mdl_; +public: + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last(const year& __yval, const month_day_last& __mdlval) noexcept + : __y_{__yval}, __mdl_{__mdlval} {} + + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator+=(const months& __m) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator-=(const months& __m) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator+=(const years& __y) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator-=(const years& __y) noexcept; + + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __mdl_.month(); } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month_day_last month_day_last() const noexcept { return __mdl_; } + _LIBCPP_HIDE_FROM_ABI constexpr chrono::day day() const noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{year()/month()/day()}; } + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { return local_days{year()/month()/day()}; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y_.ok() && __mdl_.ok(); } +}; + +_LIBCPP_HIDE_FROM_ABI inline constexpr +chrono::day year_month_day_last::day() const noexcept +{ + constexpr chrono::day __d[] = + { + chrono::day(31), chrono::day(28), chrono::day(31), + chrono::day(30), chrono::day(31), chrono::day(30), + chrono::day(31), chrono::day(31), chrono::day(30), + chrono::day(31), chrono::day(30), chrono::day(31) + }; + return (month() != February || !__y_.is_leap()) && month().ok() ? + __d[static_cast(month()) - 1] : chrono::day{29}; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month_day_last() == __rhs.month_day_last(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator!=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return !(__lhs == __rhs); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator< (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ + if (__lhs.year() < __rhs.year()) return true; + if (__lhs.year() > __rhs.year()) return false; + return __lhs.month_day_last() < __rhs.month_day_last(); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator> (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return __rhs < __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator<=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return !(__rhs < __lhs);} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator>=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return !(__lhs < __rhs); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day_last operator/(const year_month& __lhs, last_spec) noexcept +{ return year_month_day_last{__lhs.year(), month_day_last{__lhs.month()}}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day_last operator/(const year& __lhs, const month_day_last& __rhs) noexcept +{ return year_month_day_last{__lhs, __rhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day_last operator/(int __lhs, const month_day_last& __rhs) noexcept +{ return year_month_day_last{year{__lhs}, __rhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last +operator/(const month_day_last& __lhs, const year& __rhs) noexcept +{ return __rhs / __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day_last operator/(const month_day_last& __lhs, int __rhs) noexcept +{ return year{__rhs} / __lhs; } + + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day_last operator+(const year_month_day_last& __lhs, const months& __rhs) noexcept +{ return (__lhs.year() / __lhs.month() + __rhs) / last; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day_last operator+(const months& __lhs, const year_month_day_last& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day_last operator-(const year_month_day_last& __lhs, const months& __rhs) noexcept +{ return __lhs + (-__rhs); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day_last operator+(const year_month_day_last& __lhs, const years& __rhs) noexcept +{ return year_month_day_last{__lhs.year() + __rhs, __lhs.month_day_last()}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day_last operator+(const years& __lhs, const year_month_day_last& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day_last operator-(const year_month_day_last& __lhs, const years& __rhs) noexcept +{ return __lhs + (-__rhs); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& year_month_day_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& year_month_day_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& year_month_day_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& year_month_day_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept + : __y_{__ymdl.year()}, __m_{__ymdl.month()}, __d_{__ymdl.day()} {} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool year_month_day::ok() const noexcept +{ + if (!__y_.ok() || !__m_.ok()) return false; + return chrono::day{1} <= __d_ && __d_ <= (__y_ / __m_ / last).day(); +} + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___CHRONO_YEAR_MONTH_DAY_H diff --git a/app/src/main/cpp/libcxx/include/__chrono/year_month_weekday.h b/app/src/main/cpp/libcxx/include/__chrono/year_month_weekday.h new file mode 100644 index 0000000..6604dea --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__chrono/year_month_weekday.h @@ -0,0 +1,255 @@ +// -*- 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 _LIBCPP___CHRONO_YEAR_MONTH_WEEKDAY_H +#define _LIBCPP___CHRONO_YEAR_MONTH_WEEKDAY_H + +#include <__chrono/calendar.h> +#include <__chrono/day.h> +#include <__chrono/duration.h> +#include <__chrono/month.h> +#include <__chrono/month_weekday.h> +#include <__chrono/system_clock.h> +#include <__chrono/time_point.h> +#include <__chrono/weekday.h> +#include <__chrono/year.h> +#include <__chrono/year_month.h> +#include <__chrono/year_month_day.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +class year_month_weekday { + chrono::year __y_; + chrono::month __m_; + chrono::weekday_indexed __wdi_; +public: + _LIBCPP_HIDE_FROM_ABI year_month_weekday() = default; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday(const chrono::year& __yval, const chrono::month& __mval, + const chrono::weekday_indexed& __wdival) noexcept + : __y_{__yval}, __m_{__mval}, __wdi_{__wdival} {} + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday(const sys_days& __sysd) noexcept + : year_month_weekday(__from_days(__sysd.time_since_epoch())) {} + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr year_month_weekday(const local_days& __locd) noexcept + : year_month_weekday(__from_days(__locd.time_since_epoch())) {} + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator+=(const months&) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator-=(const months&) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator+=(const years&) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator-=(const years&) noexcept; + + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wdi_.weekday(); } + _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned index() const noexcept { return __wdi_.index(); } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi_; } + + _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept + { + if (!__y_.ok() || !__m_.ok() || !__wdi_.ok()) return false; + if (__wdi_.index() <= 4) return true; + auto __nth_weekday_day = + __wdi_.weekday() - + chrono::weekday{static_cast(__y_ / __m_ / 1)} + + days{(__wdi_.index() - 1) * 7 + 1}; + return static_cast(__nth_weekday_day.count()) <= + static_cast((__y_ / __m_ / last).day()); + } + + _LIBCPP_HIDE_FROM_ABI static constexpr year_month_weekday __from_days(days __d) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept; +}; + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday year_month_weekday::__from_days(days __d) noexcept +{ + const sys_days __sysd{__d}; + const chrono::weekday __wd = chrono::weekday(__sysd); + const year_month_day __ymd = year_month_day(__sysd); + return year_month_weekday{__ymd.year(), __ymd.month(), + __wd[(static_cast(__ymd.day())-1)/7+1]}; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +days year_month_weekday::__to_days() const noexcept +{ + const sys_days __sysd = sys_days(__y_/__m_/1); + return (__sysd + (__wdi_.weekday() - chrono::weekday(__sysd) + days{(__wdi_.index()-1)*7})) + .time_since_epoch(); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator!=(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept +{ return !(__lhs == __rhs); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday operator/(const year_month& __lhs, const weekday_indexed& __rhs) noexcept +{ return year_month_weekday{__lhs.year(), __lhs.month(), __rhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday operator/(const year& __lhs, const month_weekday& __rhs) noexcept +{ return year_month_weekday{__lhs, __rhs.month(), __rhs.weekday_indexed()}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday operator/(int __lhs, const month_weekday& __rhs) noexcept +{ return year(__lhs) / __rhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday operator/(const month_weekday& __lhs, const year& __rhs) noexcept +{ return __rhs / __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday operator/(const month_weekday& __lhs, int __rhs) noexcept +{ return year(__rhs) / __lhs; } + + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday operator+(const year_month_weekday& __lhs, const months& __rhs) noexcept +{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_indexed(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday operator+(const months& __lhs, const year_month_weekday& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday operator-(const year_month_weekday& __lhs, const months& __rhs) noexcept +{ return __lhs + (-__rhs); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday operator+(const year_month_weekday& __lhs, const years& __rhs) noexcept +{ return year_month_weekday{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_indexed()}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday operator+(const years& __lhs, const year_month_weekday& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday operator-(const year_month_weekday& __lhs, const years& __rhs) noexcept +{ return __lhs + (-__rhs); } + + +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } + +class year_month_weekday_last { +private: + chrono::year __y_; + chrono::month __m_; + chrono::weekday_last __wdl_; +public: + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last(const chrono::year& __yval, const chrono::month& __mval, + const chrono::weekday_last& __wdlval) noexcept + : __y_{__yval}, __m_{__mval}, __wdl_{__wdlval} {} + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator+=(const months& __dm) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator-=(const months& __dm) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator+=(const years& __dy) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator-=(const years& __dy) noexcept; + + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wdl_.weekday(); } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y_.ok() && __m_.ok() && __wdl_.ok(); } + + _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept; + +}; + +_LIBCPP_HIDE_FROM_ABI inline constexpr +days year_month_weekday_last::__to_days() const noexcept +{ + const sys_days __last = sys_days{__y_/__m_/last}; + return (__last - (chrono::weekday{__last} - __wdl_.weekday())).time_since_epoch(); + +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator!=(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept +{ return !(__lhs == __rhs); } + + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday_last operator/(const year_month& __lhs, const weekday_last& __rhs) noexcept +{ return year_month_weekday_last{__lhs.year(), __lhs.month(), __rhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday_last operator/(const year& __lhs, const month_weekday_last& __rhs) noexcept +{ return year_month_weekday_last{__lhs, __rhs.month(), __rhs.weekday_last()}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday_last operator/(int __lhs, const month_weekday_last& __rhs) noexcept +{ return year(__lhs) / __rhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday_last operator/(const month_weekday_last& __lhs, const year& __rhs) noexcept +{ return __rhs / __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday_last operator/(const month_weekday_last& __lhs, int __rhs) noexcept +{ return year(__rhs) / __lhs; } + + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const months& __rhs) noexcept +{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_last(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday_last operator+(const months& __lhs, const year_month_weekday_last& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const months& __rhs) noexcept +{ return __lhs + (-__rhs); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const years& __rhs) noexcept +{ return year_month_weekday_last{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_last()}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday_last operator+(const years& __lhs, const year_month_weekday_last& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const years& __rhs) noexcept +{ return __lhs + (-__rhs); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___CHRONO_YEAR_MONTH_WEEKDAY_H diff --git a/app/src/main/cpp/libcxx/include/__compare/common_comparison_category.h b/app/src/main/cpp/libcxx/include/__compare/common_comparison_category.h new file mode 100644 index 0000000..06c4b28 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__compare/common_comparison_category.h @@ -0,0 +1,95 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___COMPARE_COMMON_COMPARISON_CATEGORY_H +#define _LIBCPP___COMPARE_COMMON_COMPARISON_CATEGORY_H + +#include <__compare/ordering.h> +#include <__config> +#include <__type_traits/is_same.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __comp_detail { + +enum _ClassifyCompCategory : unsigned { + _None, + _PartialOrd, + _WeakOrd, + _StrongOrd, + _CCC_Size +}; + +template +_LIBCPP_HIDE_FROM_ABI +constexpr _ClassifyCompCategory __type_to_enum() noexcept { + if (is_same_v<_Tp, partial_ordering>) + return _PartialOrd; + if (is_same_v<_Tp, weak_ordering>) + return _WeakOrd; + if (is_same_v<_Tp, strong_ordering>) + return _StrongOrd; + return _None; +} + +template +_LIBCPP_HIDE_FROM_ABI +constexpr _ClassifyCompCategory +__compute_comp_type(const _ClassifyCompCategory (&__types)[_Size]) { + int __seen[_CCC_Size] = {}; + for (auto __type : __types) + ++__seen[__type]; + if (__seen[_None]) + return _None; + if (__seen[_PartialOrd]) + return _PartialOrd; + if (__seen[_WeakOrd]) + return _WeakOrd; + return _StrongOrd; +} + +template +_LIBCPP_HIDE_FROM_ABI +constexpr auto __get_comp_type() { + using _CCC = _ClassifyCompCategory; + constexpr _CCC __type_kinds[] = {_StrongOrd, __type_to_enum<_Ts>()...}; + constexpr _CCC _Cat = __comp_detail::__compute_comp_type(__type_kinds); + if constexpr (_Cat == _None) + return void(); + else if constexpr (_Cat == _PartialOrd) + return partial_ordering::equivalent; + else if constexpr (_Cat == _WeakOrd) + return weak_ordering::equivalent; + else if constexpr (_Cat == _StrongOrd) + return strong_ordering::equivalent; + else + static_assert(_False, "unhandled case"); +} +} // namespace __comp_detail + +// [cmp.common], common comparison category type +template +struct _LIBCPP_TEMPLATE_VIS common_comparison_category { + using type = decltype(__comp_detail::__get_comp_type<_Ts...>()); +}; + +template +using common_comparison_category_t = typename common_comparison_category<_Ts...>::type; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_COMMON_COMPARISON_CATEGORY_H diff --git a/app/src/main/cpp/libcxx/include/__compare/compare_partial_order_fallback.h b/app/src/main/cpp/libcxx/include/__compare/compare_partial_order_fallback.h new file mode 100644 index 0000000..06f03fe --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__compare/compare_partial_order_fallback.h @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___COMPARE_COMPARE_PARTIAL_ORDER_FALLBACK +#define _LIBCPP___COMPARE_COMPARE_PARTIAL_ORDER_FALLBACK + +#include <__compare/ordering.h> +#include <__compare/partial_order.h> +#include <__config> +#include <__type_traits/decay.h> +#include <__type_traits/is_same.h> +#include <__utility/forward.h> +#include <__utility/priority_tag.h> + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [cmp.alg] +namespace __compare_partial_order_fallback { + struct __fn { + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) + noexcept(noexcept(_VSTD::partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + -> decltype( _VSTD::partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))) + { return _VSTD::partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) + noexcept(noexcept(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? partial_ordering::equivalent : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? partial_ordering::less : + _VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t) ? partial_ordering::greater : + partial_ordering::unordered)) + -> decltype( _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? partial_ordering::equivalent : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? partial_ordering::less : + _VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t) ? partial_ordering::greater : + partial_ordering::unordered) + { + return _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? partial_ordering::equivalent : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? partial_ordering::less : + _VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t) ? partial_ordering::greater : + partial_ordering::unordered; + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>()))) + -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>())) + { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>()); } + }; +} // namespace __compare_partial_order_fallback + +inline namespace __cpo { + inline constexpr auto compare_partial_order_fallback = __compare_partial_order_fallback::__fn{}; +} // namespace __cpo + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_COMPARE_PARTIAL_ORDER_FALLBACK diff --git a/app/src/main/cpp/libcxx/include/__compare/compare_strong_order_fallback.h b/app/src/main/cpp/libcxx/include/__compare/compare_strong_order_fallback.h new file mode 100644 index 0000000..8693868 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__compare/compare_strong_order_fallback.h @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___COMPARE_COMPARE_STRONG_ORDER_FALLBACK +#define _LIBCPP___COMPARE_COMPARE_STRONG_ORDER_FALLBACK + +#include <__compare/ordering.h> +#include <__compare/strong_order.h> +#include <__config> +#include <__type_traits/decay.h> +#include <__type_traits/is_same.h> +#include <__utility/forward.h> +#include <__utility/priority_tag.h> + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [cmp.alg] +namespace __compare_strong_order_fallback { + struct __fn { + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) + noexcept(noexcept(_VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + -> decltype( _VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))) + { return _VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) + noexcept(noexcept(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? strong_ordering::equal : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? strong_ordering::less : + strong_ordering::greater)) + -> decltype( _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? strong_ordering::equal : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? strong_ordering::less : + strong_ordering::greater) + { + return _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? strong_ordering::equal : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? strong_ordering::less : + strong_ordering::greater; + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>()))) + -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>())) + { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>()); } + }; +} // namespace __compare_strong_order_fallback + +inline namespace __cpo { + inline constexpr auto compare_strong_order_fallback = __compare_strong_order_fallback::__fn{}; +} // namespace __cpo + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_COMPARE_STRONG_ORDER_FALLBACK diff --git a/app/src/main/cpp/libcxx/include/__compare/compare_three_way.h b/app/src/main/cpp/libcxx/include/__compare/compare_three_way.h new file mode 100644 index 0000000..fdbba04 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__compare/compare_three_way.h @@ -0,0 +1,41 @@ +// -*- 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 _LIBCPP___COMPARE_COMPARE_THREE_WAY_H +#define _LIBCPP___COMPARE_COMPARE_THREE_WAY_H + +#include <__compare/three_way_comparable.h> +#include <__config> +#include <__utility/forward.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +struct _LIBCPP_TEMPLATE_VIS compare_three_way +{ + template + requires three_way_comparable_with<_T1, _T2> + constexpr _LIBCPP_HIDE_FROM_ABI + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) <=> _VSTD::forward<_T2>(__u))) + { return _VSTD::forward<_T1>(__t) <=> _VSTD::forward<_T2>(__u); } + + using is_transparent = void; +}; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_COMPARE_THREE_WAY_H diff --git a/app/src/main/cpp/libcxx/include/__compare/compare_three_way_result.h b/app/src/main/cpp/libcxx/include/__compare/compare_three_way_result.h new file mode 100644 index 0000000..8885d7e --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__compare/compare_three_way_result.h @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___COMPARE_COMPARE_THREE_WAY_RESULT_H +#define _LIBCPP___COMPARE_COMPARE_THREE_WAY_RESULT_H + +#include <__config> +#include <__type_traits/make_const_lvalue_ref.h> +#include <__utility/declval.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +struct _LIBCPP_HIDE_FROM_ABI __compare_three_way_result { }; + +template +struct _LIBCPP_HIDE_FROM_ABI __compare_three_way_result<_Tp, _Up, decltype( + std::declval<__make_const_lvalue_ref<_Tp>>() <=> std::declval<__make_const_lvalue_ref<_Up>>(), void() +)> { + using type = decltype(std::declval<__make_const_lvalue_ref<_Tp>>() <=> std::declval<__make_const_lvalue_ref<_Up>>()); +}; + +template +struct _LIBCPP_TEMPLATE_VIS compare_three_way_result : __compare_three_way_result<_Tp, _Up, void> { }; + +template +using compare_three_way_result_t = typename compare_three_way_result<_Tp, _Up>::type; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_COMPARE_THREE_WAY_RESULT_H diff --git a/app/src/main/cpp/libcxx/include/__compare/compare_weak_order_fallback.h b/app/src/main/cpp/libcxx/include/__compare/compare_weak_order_fallback.h new file mode 100644 index 0000000..f434dcb --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__compare/compare_weak_order_fallback.h @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___COMPARE_COMPARE_WEAK_ORDER_FALLBACK +#define _LIBCPP___COMPARE_COMPARE_WEAK_ORDER_FALLBACK + +#include <__compare/ordering.h> +#include <__compare/weak_order.h> +#include <__config> +#include <__type_traits/decay.h> +#include <__type_traits/is_same.h> +#include <__utility/forward.h> +#include <__utility/priority_tag.h> + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [cmp.alg] +namespace __compare_weak_order_fallback { + struct __fn { + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) + noexcept(noexcept(_VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + -> decltype( _VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))) + { return _VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) + noexcept(noexcept(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? weak_ordering::equivalent : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? weak_ordering::less : + weak_ordering::greater)) + -> decltype( _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? weak_ordering::equivalent : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? weak_ordering::less : + weak_ordering::greater) + { + return _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? weak_ordering::equivalent : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? weak_ordering::less : + weak_ordering::greater; + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>()))) + -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>())) + { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>()); } + }; +} // namespace __compare_weak_order_fallback + +inline namespace __cpo { + inline constexpr auto compare_weak_order_fallback = __compare_weak_order_fallback::__fn{}; +} // namespace __cpo + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_COMPARE_WEAK_ORDER_FALLBACK diff --git a/app/src/main/cpp/libcxx/include/__compare/is_eq.h b/app/src/main/cpp/libcxx/include/__compare/is_eq.h new file mode 100644 index 0000000..4964892 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__compare/is_eq.h @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___COMPARE_IS_EQ_H +#define _LIBCPP___COMPARE_IS_EQ_H + +#include <__compare/ordering.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_eq(partial_ordering __c) noexcept { return __c == 0; } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_neq(partial_ordering __c) noexcept { return __c != 0; } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lt(partial_ordering __c) noexcept { return __c < 0; } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lteq(partial_ordering __c) noexcept { return __c <= 0; } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gt(partial_ordering __c) noexcept { return __c > 0; } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gteq(partial_ordering __c) noexcept { return __c >= 0; } + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_IS_EQ_H diff --git a/app/src/main/cpp/libcxx/include/__compare/ordering.h b/app/src/main/cpp/libcxx/include/__compare/ordering.h new file mode 100644 index 0000000..ff148ab --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__compare/ordering.h @@ -0,0 +1,326 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___COMPARE_ORDERING_H +#define _LIBCPP___COMPARE_ORDERING_H + +#include <__config> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_same.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// exposition only +enum class _LIBCPP_ENUM_VIS _OrdResult : signed char { + __less = -1, + __equiv = 0, + __greater = 1 +}; + +enum class _LIBCPP_ENUM_VIS _NCmpResult : signed char { + __unordered = -127 +}; + +class partial_ordering; +class weak_ordering; +class strong_ordering; + +template +inline constexpr bool __one_of_v = (is_same_v<_Tp, _Args> || ...); + +struct _CmpUnspecifiedParam { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEVAL + _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {} + + template>> + _CmpUnspecifiedParam(_Tp) = delete; +}; + +class partial_ordering { + using _ValueT = signed char; + + _LIBCPP_HIDE_FROM_ABI + explicit constexpr partial_ordering(_OrdResult __v) noexcept + : __value_(_ValueT(__v)) {} + + _LIBCPP_HIDE_FROM_ABI + explicit constexpr partial_ordering(_NCmpResult __v) noexcept + : __value_(_ValueT(__v)) {} + + _LIBCPP_HIDE_FROM_ABI + constexpr bool __is_ordered() const noexcept { + return __value_ != _ValueT(_NCmpResult::__unordered); + } +public: + // valid values + static const partial_ordering less; + static const partial_ordering equivalent; + static const partial_ordering greater; + static const partial_ordering unordered; + + // comparisons + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default; + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__is_ordered() && __v.__value_ == 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__is_ordered() && __v.__value_ < 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__is_ordered() && __v.__value_ <= 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__is_ordered() && __v.__value_ > 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__is_ordered() && __v.__value_ >= 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept { + return __v.__is_ordered() && 0 < __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { + return __v.__is_ordered() && 0 <= __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept { + return __v.__is_ordered() && 0 > __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { + return __v.__is_ordered() && 0 >= __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept { + return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v); + } +private: + _ValueT __value_; +}; + +inline constexpr partial_ordering partial_ordering::less(_OrdResult::__less); +inline constexpr partial_ordering partial_ordering::equivalent(_OrdResult::__equiv); +inline constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater); +inline constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered); + +class weak_ordering { + using _ValueT = signed char; + + _LIBCPP_HIDE_FROM_ABI + explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} + +public: + static const weak_ordering less; + static const weak_ordering equivalent; + static const weak_ordering greater; + + _LIBCPP_HIDE_FROM_ABI + constexpr operator partial_ordering() const noexcept { + return __value_ == 0 ? partial_ordering::equivalent + : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); + } + + // comparisons + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default; + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ == 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ < 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ <= 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ > 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ >= 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept { + return 0 < __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { + return 0 <= __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept { + return 0 > __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { + return 0 >= __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept { + return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v); + } + +private: + _ValueT __value_; +}; + +inline constexpr weak_ordering weak_ordering::less(_OrdResult::__less); +inline constexpr weak_ordering weak_ordering::equivalent(_OrdResult::__equiv); +inline constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater); + +class strong_ordering { + using _ValueT = signed char; + + _LIBCPP_HIDE_FROM_ABI + explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} + +public: + static const strong_ordering less; + static const strong_ordering equal; + static const strong_ordering equivalent; + static const strong_ordering greater; + + // conversions + _LIBCPP_HIDE_FROM_ABI + constexpr operator partial_ordering() const noexcept { + return __value_ == 0 ? partial_ordering::equivalent + : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); + } + + _LIBCPP_HIDE_FROM_ABI + constexpr operator weak_ordering() const noexcept { + return __value_ == 0 ? weak_ordering::equivalent + : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater); + } + + // comparisons + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default; + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ == 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ < 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ <= 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ > 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ >= 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept { + return 0 < __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { + return 0 <= __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept { + return 0 > __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { + return 0 >= __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept { + return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v); + } + +private: + _ValueT __value_; +}; + +inline constexpr strong_ordering strong_ordering::less(_OrdResult::__less); +inline constexpr strong_ordering strong_ordering::equal(_OrdResult::__equiv); +inline constexpr strong_ordering strong_ordering::equivalent(_OrdResult::__equiv); +inline constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater); + +/// [cmp.categories.pre]/1 +/// The types partial_ordering, weak_ordering, and strong_ordering are +/// collectively termed the comparison category types. +template +concept __comparison_category = __one_of_v<_Tp, partial_ordering, weak_ordering, strong_ordering>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_ORDERING_H diff --git a/app/src/main/cpp/libcxx/include/__compare/partial_order.h b/app/src/main/cpp/libcxx/include/__compare/partial_order.h new file mode 100644 index 0000000..aee07eb --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__compare/partial_order.h @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___COMPARE_PARTIAL_ORDER +#define _LIBCPP___COMPARE_PARTIAL_ORDER + +#include <__compare/compare_three_way.h> +#include <__compare/ordering.h> +#include <__compare/weak_order.h> +#include <__config> +#include <__type_traits/decay.h> +#include <__type_traits/is_same.h> +#include <__utility/forward.h> +#include <__utility/priority_tag.h> + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [cmp.alg] +namespace __partial_order { + struct __fn { + // NOLINTBEGIN(libcpp-robust-against-adl) partial_order should use ADL, but only here + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<2>) + noexcept(noexcept(partial_ordering(partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( partial_ordering(partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return partial_ordering(partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + // NOLINTEND(libcpp-robust-against-adl) + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) + noexcept(noexcept(partial_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( partial_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return partial_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) + noexcept(noexcept(partial_ordering(_VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( partial_ordering(_VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return partial_ordering(_VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>()))) + -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>())) + { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>()); } + }; +} // namespace __partial_order + +inline namespace __cpo { + inline constexpr auto partial_order = __partial_order::__fn{}; +} // namespace __cpo + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_PARTIAL_ORDER diff --git a/app/src/main/cpp/libcxx/include/__compare/strong_order.h b/app/src/main/cpp/libcxx/include/__compare/strong_order.h new file mode 100644 index 0000000..05856c2 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__compare/strong_order.h @@ -0,0 +1,139 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___COMPARE_STRONG_ORDER +#define _LIBCPP___COMPARE_STRONG_ORDER + +#include <__bit/bit_cast.h> +#include <__compare/compare_three_way.h> +#include <__compare/ordering.h> +#include <__config> +#include <__type_traits/conditional.h> +#include <__type_traits/decay.h> +#include <__utility/forward.h> +#include <__utility/priority_tag.h> +#include +#include +#include + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [cmp.alg] +namespace __strong_order { + struct __fn { + // NOLINTBEGIN(libcpp-robust-against-adl) strong_order should use ADL, but only here + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<2>) + noexcept(noexcept(strong_ordering(strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( strong_ordering(strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return strong_ordering(strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + // NOLINTEND(libcpp-robust-against-adl) + + template> + requires is_same_v<_Dp, decay_t<_Up>> && is_floating_point_v<_Dp> + _LIBCPP_HIDE_FROM_ABI static constexpr strong_ordering + __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) noexcept + { + if constexpr (numeric_limits<_Dp>::is_iec559 && sizeof(_Dp) == sizeof(int32_t)) { + int32_t __rx = _VSTD::bit_cast(__t); + int32_t __ry = _VSTD::bit_cast(__u); + __rx = (__rx < 0) ? (numeric_limits::min() - __rx - 1) : __rx; + __ry = (__ry < 0) ? (numeric_limits::min() - __ry - 1) : __ry; + return (__rx <=> __ry); + } else if constexpr (numeric_limits<_Dp>::is_iec559 && sizeof(_Dp) == sizeof(int64_t)) { + int64_t __rx = _VSTD::bit_cast(__t); + int64_t __ry = _VSTD::bit_cast(__u); + __rx = (__rx < 0) ? (numeric_limits::min() - __rx - 1) : __rx; + __ry = (__ry < 0) ? (numeric_limits::min() - __ry - 1) : __ry; + return (__rx <=> __ry); + } else if (__t < __u) { + return strong_ordering::less; + } else if (__t > __u) { + return strong_ordering::greater; + } else if (__t == __u) { + if constexpr (numeric_limits<_Dp>::radix == 2) { + return _VSTD::signbit(__u) <=> _VSTD::signbit(__t); + } else { + // This is bullet 3 of the IEEE754 algorithm, relevant + // only for decimal floating-point; + // see https://stackoverflow.com/questions/69068075/ + if (__t == 0 || _VSTD::isinf(__t)) { + return _VSTD::signbit(__u) <=> _VSTD::signbit(__t); + } else { + int __texp, __uexp; + (void)_VSTD::frexp(__t, &__texp); + (void)_VSTD::frexp(__u, &__uexp); + return (__t < 0) ? (__texp <=> __uexp) : (__uexp <=> __texp); + } + } + } else { + // They're unordered, so one of them must be a NAN. + // The order is -QNAN, -SNAN, numbers, +SNAN, +QNAN. + bool __t_is_nan = _VSTD::isnan(__t); + bool __u_is_nan = _VSTD::isnan(__u); + bool __t_is_negative = _VSTD::signbit(__t); + bool __u_is_negative = _VSTD::signbit(__u); + using _IntType = conditional_t< + sizeof(__t) == sizeof(int32_t), int32_t, conditional_t< + sizeof(__t) == sizeof(int64_t), int64_t, void> + >; + if constexpr (is_same_v<_IntType, void>) { + static_assert(sizeof(_Dp) == 0, "std::strong_order is unimplemented for this floating-point type"); + } else if (__t_is_nan && __u_is_nan) { + // Order by sign bit, then by "payload bits" (we'll just use bit_cast). + if (__t_is_negative != __u_is_negative) { + return (__u_is_negative <=> __t_is_negative); + } else { + return _VSTD::bit_cast<_IntType>(__t) <=> _VSTD::bit_cast<_IntType>(__u); + } + } else if (__t_is_nan) { + return __t_is_negative ? strong_ordering::less : strong_ordering::greater; + } else { + return __u_is_negative ? strong_ordering::greater : strong_ordering::less; + } + } + } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) + noexcept(noexcept(strong_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( strong_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return strong_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>()))) + -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>())) + { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>()); } + }; +} // namespace __strong_order + +inline namespace __cpo { + inline constexpr auto strong_order = __strong_order::__fn{}; +} // namespace __cpo + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___COMPARE_STRONG_ORDER diff --git a/app/src/main/cpp/libcxx/include/__compare/synth_three_way.h b/app/src/main/cpp/libcxx/include/__compare/synth_three_way.h new file mode 100644 index 0000000..7d33898 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__compare/synth_three_way.h @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___COMPARE_SYNTH_THREE_WAY_H +#define _LIBCPP___COMPARE_SYNTH_THREE_WAY_H + +#include <__compare/ordering.h> +#include <__compare/three_way_comparable.h> +#include <__concepts/boolean_testable.h> +#include <__config> +#include <__utility/declval.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [expos.only.func] + +_LIBCPP_HIDE_FROM_ABI inline constexpr auto __synth_three_way = + [](const _Tp& __t, const _Up& __u) + requires requires { + { __t < __u } -> __boolean_testable; + { __u < __t } -> __boolean_testable; + } + { + if constexpr (three_way_comparable_with<_Tp, _Up>) { + return __t <=> __u; + } else { + if (__t < __u) return weak_ordering::less; + if (__u < __t) return weak_ordering::greater; + return weak_ordering::equivalent; + } + }; + +template +using __synth_three_way_result = decltype(std::__synth_three_way(std::declval<_Tp&>(), std::declval<_Up&>())); + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_SYNTH_THREE_WAY_H diff --git a/app/src/main/cpp/libcxx/include/__compare/three_way_comparable.h b/app/src/main/cpp/libcxx/include/__compare/three_way_comparable.h new file mode 100644 index 0000000..6c98916 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__compare/three_way_comparable.h @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___COMPARE_THREE_WAY_COMPARABLE_H +#define _LIBCPP___COMPARE_THREE_WAY_COMPARABLE_H + +#include <__compare/common_comparison_category.h> +#include <__compare/ordering.h> +#include <__concepts/common_reference_with.h> +#include <__concepts/equality_comparable.h> +#include <__concepts/same_as.h> +#include <__concepts/totally_ordered.h> +#include <__config> +#include <__type_traits/common_reference.h> +#include <__type_traits/make_const_lvalue_ref.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +concept __compares_as = + same_as, _Cat>; + +template +concept three_way_comparable = + __weakly_equality_comparable_with<_Tp, _Tp> && + __partially_ordered_with<_Tp, _Tp> && + requires(__make_const_lvalue_ref<_Tp> __a, __make_const_lvalue_ref<_Tp> __b) { + { __a <=> __b } -> __compares_as<_Cat>; + }; + +template +concept three_way_comparable_with = + three_way_comparable<_Tp, _Cat> && + three_way_comparable<_Up, _Cat> && + common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> && + three_way_comparable, __make_const_lvalue_ref<_Up>>, _Cat> && + __weakly_equality_comparable_with<_Tp, _Up> && + __partially_ordered_with<_Tp, _Up> && + requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { + { __t <=> __u } -> __compares_as<_Cat>; + { __u <=> __t } -> __compares_as<_Cat>; + }; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_THREE_WAY_COMPARABLE_H diff --git a/app/src/main/cpp/libcxx/include/__compare/weak_order.h b/app/src/main/cpp/libcxx/include/__compare/weak_order.h new file mode 100644 index 0000000..abb24e3 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__compare/weak_order.h @@ -0,0 +1,102 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___COMPARE_WEAK_ORDER +#define _LIBCPP___COMPARE_WEAK_ORDER + +#include <__compare/compare_three_way.h> +#include <__compare/ordering.h> +#include <__compare/strong_order.h> +#include <__config> +#include <__type_traits/decay.h> +#include <__utility/forward.h> +#include <__utility/priority_tag.h> +#include + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [cmp.alg] +namespace __weak_order { + struct __fn { + // NOLINTBEGIN(libcpp-robust-against-adl) weak_order should use ADL, but only here + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<3>) + noexcept(noexcept(weak_ordering(weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( weak_ordering(weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return weak_ordering(weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + // NOLINTEND(libcpp-robust-against-adl) + + template> + requires is_same_v<_Dp, decay_t<_Up>> && is_floating_point_v<_Dp> + _LIBCPP_HIDE_FROM_ABI static constexpr weak_ordering + __go(_Tp&& __t, _Up&& __u, __priority_tag<2>) noexcept + { + partial_ordering __po = (__t <=> __u); + if (__po == partial_ordering::less) { + return weak_ordering::less; + } else if (__po == partial_ordering::equivalent) { + return weak_ordering::equivalent; + } else if (__po == partial_ordering::greater) { + return weak_ordering::greater; + } else { + // Otherwise, at least one of them is a NaN. + bool __t_is_nan = _VSTD::isnan(__t); + bool __u_is_nan = _VSTD::isnan(__u); + bool __t_is_negative = _VSTD::signbit(__t); + bool __u_is_negative = _VSTD::signbit(__u); + if (__t_is_nan && __u_is_nan) { + return (__u_is_negative <=> __t_is_negative); + } else if (__t_is_nan) { + return __t_is_negative ? weak_ordering::less : weak_ordering::greater; + } else { + return __u_is_negative ? weak_ordering::greater : weak_ordering::less; + } + } + } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) + noexcept(noexcept(weak_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( weak_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return weak_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) + noexcept(noexcept(weak_ordering(_VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( weak_ordering(_VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return weak_ordering(_VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<3>()))) + -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<3>())) + { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<3>()); } + }; +} // namespace __weak_order + +inline namespace __cpo { + inline constexpr auto weak_order = __weak_order::__fn{}; +} // namespace __cpo + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_WEAK_ORDER diff --git a/app/src/main/cpp/libcxx/include/__concepts/arithmetic.h b/app/src/main/cpp/libcxx/include/__concepts/arithmetic.h new file mode 100644 index 0000000..215b52a --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__concepts/arithmetic.h @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_ARITHMETIC_H +#define _LIBCPP___CONCEPTS_ARITHMETIC_H + +#include <__config> +#include <__type_traits/is_floating_point.h> +#include <__type_traits/is_integral.h> +#include <__type_traits/is_signed.h> +#include <__type_traits/is_signed_integer.h> +#include <__type_traits/is_unsigned_integer.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concepts.arithmetic], arithmetic concepts + +template +concept integral = is_integral_v<_Tp>; + +template +concept signed_integral = integral<_Tp> && is_signed_v<_Tp>; + +template +concept unsigned_integral = integral<_Tp> && !signed_integral<_Tp>; + +template +concept floating_point = is_floating_point_v<_Tp>; + +// Concept helpers for the internal type traits for the fundamental types. + +template +concept __libcpp_unsigned_integer = __libcpp_is_unsigned_integer<_Tp>::value; +template +concept __libcpp_signed_integer = __libcpp_is_signed_integer<_Tp>::value; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_ARITHMETIC_H diff --git a/app/src/main/cpp/libcxx/include/__concepts/assignable.h b/app/src/main/cpp/libcxx/include/__concepts/assignable.h new file mode 100644 index 0000000..91edd40 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__concepts/assignable.h @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_ASSIGNABLE_H +#define _LIBCPP___CONCEPTS_ASSIGNABLE_H + +#include <__concepts/common_reference_with.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__type_traits/is_reference.h> +#include <__type_traits/make_const_lvalue_ref.h> +#include <__utility/forward.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.assignable] + +template +concept assignable_from = + is_lvalue_reference_v<_Lhs> && + common_reference_with<__make_const_lvalue_ref<_Lhs>, __make_const_lvalue_ref<_Rhs>> && + requires (_Lhs __lhs, _Rhs&& __rhs) { + { __lhs = _VSTD::forward<_Rhs>(__rhs) } -> same_as<_Lhs>; + }; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_ASSIGNABLE_H diff --git a/app/src/main/cpp/libcxx/include/__concepts/boolean_testable.h b/app/src/main/cpp/libcxx/include/__concepts/boolean_testable.h new file mode 100644 index 0000000..a96bde7 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__concepts/boolean_testable.h @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_BOOLEAN_TESTABLE_H +#define _LIBCPP___CONCEPTS_BOOLEAN_TESTABLE_H + +#include <__concepts/convertible_to.h> +#include <__config> +#include <__utility/forward.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concepts.booleantestable] + +template +concept __boolean_testable_impl = convertible_to<_Tp, bool>; + +template +concept __boolean_testable = __boolean_testable_impl<_Tp> && requires(_Tp&& __t) { + { !_VSTD::forward<_Tp>(__t) } -> __boolean_testable_impl; +}; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_BOOLEAN_TESTABLE_H diff --git a/app/src/main/cpp/libcxx/include/__concepts/class_or_enum.h b/app/src/main/cpp/libcxx/include/__concepts/class_or_enum.h new file mode 100644 index 0000000..c4d2f98 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__concepts/class_or_enum.h @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_CLASS_OR_ENUM_H +#define _LIBCPP___CONCEPTS_CLASS_OR_ENUM_H + +#include <__config> +#include <__type_traits/is_class.h> +#include <__type_traits/is_enum.h> +#include <__type_traits/is_union.h> +#include <__type_traits/remove_cvref.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// Whether a type is a class type or enumeration type according to the Core wording. + +template +concept __class_or_enum = is_class_v<_Tp> || is_union_v<_Tp> || is_enum_v<_Tp>; + +// Work around Clang bug https://llvm.org/PR52970 +// TODO: remove this workaround once libc++ no longer has to support Clang 13 (it was fixed in Clang 14). +template +concept __workaround_52970 = is_class_v<__remove_cvref_t<_Tp>> || is_union_v<__remove_cvref_t<_Tp>>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_CLASS_OR_ENUM_H diff --git a/app/src/main/cpp/libcxx/include/__concepts/common_reference_with.h b/app/src/main/cpp/libcxx/include/__concepts/common_reference_with.h new file mode 100644 index 0000000..cc92762 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__concepts/common_reference_with.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_COMMON_REFERENCE_WITH_H +#define _LIBCPP___CONCEPTS_COMMON_REFERENCE_WITH_H + +#include <__concepts/convertible_to.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__type_traits/common_reference.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.commonref] + +template +concept common_reference_with = + same_as, common_reference_t<_Up, _Tp>> && + convertible_to<_Tp, common_reference_t<_Tp, _Up>> && + convertible_to<_Up, common_reference_t<_Tp, _Up>>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_COMMON_REFERENCE_WITH_H diff --git a/app/src/main/cpp/libcxx/include/__concepts/common_with.h b/app/src/main/cpp/libcxx/include/__concepts/common_with.h new file mode 100644 index 0000000..569a0ee --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__concepts/common_with.h @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_COMMON_WITH_H +#define _LIBCPP___CONCEPTS_COMMON_WITH_H + +#include <__concepts/common_reference_with.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__type_traits/add_lvalue_reference.h> +#include <__type_traits/common_reference.h> +#include <__type_traits/common_type.h> +#include <__utility/declval.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.common] + +template +concept common_with = + same_as, common_type_t<_Up, _Tp>> && + requires { + static_cast>(std::declval<_Tp>()); + static_cast>(std::declval<_Up>()); + } && + common_reference_with< + add_lvalue_reference_t, + add_lvalue_reference_t> && + common_reference_with< + add_lvalue_reference_t>, + common_reference_t< + add_lvalue_reference_t, + add_lvalue_reference_t>>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_COMMON_WITH_H diff --git a/app/src/main/cpp/libcxx/include/__concepts/constructible.h b/app/src/main/cpp/libcxx/include/__concepts/constructible.h new file mode 100644 index 0000000..1d78eb5 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__concepts/constructible.h @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_CONSTRUCTIBLE_H +#define _LIBCPP___CONCEPTS_CONSTRUCTIBLE_H + +#include <__concepts/convertible_to.h> +#include <__concepts/destructible.h> +#include <__config> +#include <__type_traits/is_constructible.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.constructible] +template +concept constructible_from = + destructible<_Tp> && is_constructible_v<_Tp, _Args...>; + +// [concept.default.init] + +template +concept __default_initializable = requires { ::new _Tp; }; + +template +concept default_initializable = constructible_from<_Tp> && + requires { _Tp{}; } && __default_initializable<_Tp>; + +// [concept.moveconstructible] +template +concept move_constructible = + constructible_from<_Tp, _Tp> && convertible_to<_Tp, _Tp>; + +// [concept.copyconstructible] +template +concept copy_constructible = + move_constructible<_Tp> && + constructible_from<_Tp, _Tp&> && convertible_to<_Tp&, _Tp> && + constructible_from<_Tp, const _Tp&> && convertible_to && + constructible_from<_Tp, const _Tp> && convertible_to; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_CONSTRUCTIBLE_H diff --git a/app/src/main/cpp/libcxx/include/__concepts/convertible_to.h b/app/src/main/cpp/libcxx/include/__concepts/convertible_to.h new file mode 100644 index 0000000..2c1d267 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__concepts/convertible_to.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_CONVERTIBLE_TO_H +#define _LIBCPP___CONCEPTS_CONVERTIBLE_TO_H + +#include <__config> +#include <__type_traits/is_convertible.h> +#include <__utility/declval.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.convertible] + +template +concept convertible_to = + is_convertible_v<_From, _To> && + requires { + static_cast<_To>(std::declval<_From>()); + }; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_CONVERTIBLE_TO_H diff --git a/app/src/main/cpp/libcxx/include/__concepts/copyable.h b/app/src/main/cpp/libcxx/include/__concepts/copyable.h new file mode 100644 index 0000000..c5d8a80 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__concepts/copyable.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_COPYABLE_H +#define _LIBCPP___CONCEPTS_COPYABLE_H + +#include <__concepts/assignable.h> +#include <__concepts/constructible.h> +#include <__concepts/movable.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concepts.object] + +template +concept copyable = + copy_constructible<_Tp> && + movable<_Tp> && + assignable_from<_Tp&, _Tp&> && + assignable_from<_Tp&, const _Tp&> && + assignable_from<_Tp&, const _Tp>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_COPYABLE_H diff --git a/app/src/main/cpp/libcxx/include/__concepts/derived_from.h b/app/src/main/cpp/libcxx/include/__concepts/derived_from.h new file mode 100644 index 0000000..0d3462d --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__concepts/derived_from.h @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_DERIVED_FROM_H +#define _LIBCPP___CONCEPTS_DERIVED_FROM_H + +#include <__config> +#include <__type_traits/is_base_of.h> +#include <__type_traits/is_convertible.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.derived] + +template +concept derived_from = + is_base_of_v<_Bp, _Dp> && + is_convertible_v; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_DERIVED_FROM_H diff --git a/app/src/main/cpp/libcxx/include/__concepts/destructible.h b/app/src/main/cpp/libcxx/include/__concepts/destructible.h new file mode 100644 index 0000000..ad3819d --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__concepts/destructible.h @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_DESTRUCTIBLE_H +#define _LIBCPP___CONCEPTS_DESTRUCTIBLE_H + +#include <__config> +#include <__type_traits/is_nothrow_destructible.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.destructible] + +template +concept destructible = is_nothrow_destructible_v<_Tp>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_DESTRUCTIBLE_H diff --git a/app/src/main/cpp/libcxx/include/__concepts/different_from.h b/app/src/main/cpp/libcxx/include/__concepts/different_from.h new file mode 100644 index 0000000..15fd8f0 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__concepts/different_from.h @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_DIFFERENT_FROM_H +#define _LIBCPP___CONCEPTS_DIFFERENT_FROM_H + +#include <__concepts/same_as.h> +#include <__config> +#include <__type_traits/remove_cvref.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +concept __different_from = !same_as, remove_cvref_t<_Up>>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_DIFFERENT_FROM_H diff --git a/app/src/main/cpp/libcxx/include/__concepts/equality_comparable.h b/app/src/main/cpp/libcxx/include/__concepts/equality_comparable.h new file mode 100644 index 0000000..b865141 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__concepts/equality_comparable.h @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_EQUALITY_COMPARABLE_H +#define _LIBCPP___CONCEPTS_EQUALITY_COMPARABLE_H + +#include <__concepts/boolean_testable.h> +#include <__concepts/common_reference_with.h> +#include <__config> +#include <__type_traits/common_reference.h> +#include <__type_traits/make_const_lvalue_ref.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.equalitycomparable] + +template +concept __weakly_equality_comparable_with = + requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { + { __t == __u } -> __boolean_testable; + { __t != __u } -> __boolean_testable; + { __u == __t } -> __boolean_testable; + { __u != __t } -> __boolean_testable; + }; + +template +concept equality_comparable = __weakly_equality_comparable_with<_Tp, _Tp>; + +template +concept equality_comparable_with = + equality_comparable<_Tp> && equality_comparable<_Up> && + common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> && + equality_comparable< + common_reference_t< + __make_const_lvalue_ref<_Tp>, + __make_const_lvalue_ref<_Up>>> && + __weakly_equality_comparable_with<_Tp, _Up>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_EQUALITY_COMPARABLE_H diff --git a/app/src/main/cpp/libcxx/include/__concepts/invocable.h b/app/src/main/cpp/libcxx/include/__concepts/invocable.h new file mode 100644 index 0000000..ec39b7b --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__concepts/invocable.h @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_INVOCABLE_H +#define _LIBCPP___CONCEPTS_INVOCABLE_H + +#include <__config> +#include <__functional/invoke.h> +#include <__utility/forward.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.invocable] + +template +concept invocable = requires(_Fn&& __fn, _Args&&... __args) { + _VSTD::invoke(_VSTD::forward<_Fn>(__fn), _VSTD::forward<_Args>(__args)...); // not required to be equality preserving +}; + +// [concept.regular.invocable] + +template +concept regular_invocable = invocable<_Fn, _Args...>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_INVOCABLE_H diff --git a/app/src/main/cpp/libcxx/include/__concepts/movable.h b/app/src/main/cpp/libcxx/include/__concepts/movable.h new file mode 100644 index 0000000..749b78a --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__concepts/movable.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_MOVABLE_H +#define _LIBCPP___CONCEPTS_MOVABLE_H + +#include <__concepts/assignable.h> +#include <__concepts/constructible.h> +#include <__concepts/swappable.h> +#include <__config> +#include <__type_traits/is_object.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concepts.object] + +template +concept movable = + is_object_v<_Tp> && + move_constructible<_Tp> && + assignable_from<_Tp&, _Tp> && + swappable<_Tp>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_MOVABLE_H diff --git a/app/src/main/cpp/libcxx/include/__concepts/predicate.h b/app/src/main/cpp/libcxx/include/__concepts/predicate.h new file mode 100644 index 0000000..7ae9783 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__concepts/predicate.h @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_PREDICATE_H +#define _LIBCPP___CONCEPTS_PREDICATE_H + +#include <__concepts/boolean_testable.h> +#include <__concepts/invocable.h> +#include <__config> +#include <__functional/invoke.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.predicate] + +template +concept predicate = + regular_invocable<_Fn, _Args...> && __boolean_testable>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_PREDICATE_H diff --git a/app/src/main/cpp/libcxx/include/__concepts/regular.h b/app/src/main/cpp/libcxx/include/__concepts/regular.h new file mode 100644 index 0000000..d15728d --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__concepts/regular.h @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_REGULAR_H +#define _LIBCPP___CONCEPTS_REGULAR_H + +#include <__concepts/equality_comparable.h> +#include <__concepts/semiregular.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.object] + +template +concept regular = semiregular<_Tp> && equality_comparable<_Tp>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_REGULAR_H diff --git a/app/src/main/cpp/libcxx/include/__concepts/relation.h b/app/src/main/cpp/libcxx/include/__concepts/relation.h new file mode 100644 index 0000000..7d5141c --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__concepts/relation.h @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_RELATION_H +#define _LIBCPP___CONCEPTS_RELATION_H + +#include <__concepts/predicate.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.relation] + +template +concept relation = + predicate<_Rp, _Tp, _Tp> && predicate<_Rp, _Up, _Up> && + predicate<_Rp, _Tp, _Up> && predicate<_Rp, _Up, _Tp>; + +// [concept.equiv] + +template +concept equivalence_relation = relation<_Rp, _Tp, _Up>; + +// [concept.strictweakorder] + +template +concept strict_weak_order = relation<_Rp, _Tp, _Up>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_RELATION_H diff --git a/app/src/main/cpp/libcxx/include/__concepts/same_as.h b/app/src/main/cpp/libcxx/include/__concepts/same_as.h new file mode 100644 index 0000000..554ebc3 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__concepts/same_as.h @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_SAME_AS_H +#define _LIBCPP___CONCEPTS_SAME_AS_H + +#include <__config> +#include <__type_traits/is_same.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.same] + +template +concept __same_as_impl = _IsSame<_Tp, _Up>::value; + +template +concept same_as = __same_as_impl<_Tp, _Up> && __same_as_impl<_Up, _Tp>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_SAME_AS_H diff --git a/app/src/main/cpp/libcxx/include/__concepts/semiregular.h b/app/src/main/cpp/libcxx/include/__concepts/semiregular.h new file mode 100644 index 0000000..d15bb3b --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__concepts/semiregular.h @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_SEMIREGULAR_H +#define _LIBCPP___CONCEPTS_SEMIREGULAR_H + +#include <__concepts/constructible.h> +#include <__concepts/copyable.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.object] + +template +concept semiregular = copyable<_Tp> && default_initializable<_Tp>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_SEMIREGULAR_H diff --git a/app/src/main/cpp/libcxx/include/__concepts/swappable.h b/app/src/main/cpp/libcxx/include/__concepts/swappable.h new file mode 100644 index 0000000..d91a7a1 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__concepts/swappable.h @@ -0,0 +1,121 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_SWAPPABLE_H +#define _LIBCPP___CONCEPTS_SWAPPABLE_H + +#include <__concepts/assignable.h> +#include <__concepts/class_or_enum.h> +#include <__concepts/common_reference_with.h> +#include <__concepts/constructible.h> +#include <__config> +#include <__type_traits/extent.h> +#include <__type_traits/is_nothrow_move_assignable.h> +#include <__type_traits/is_nothrow_move_constructible.h> +#include <__type_traits/remove_cvref.h> +#include <__utility/exchange.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/swap.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.swappable] + +namespace ranges { +namespace __swap { + + template + void swap(_Tp&, _Tp&) = delete; + + template + concept __unqualified_swappable_with = + (__class_or_enum> || __class_or_enum>) && + requires(_Tp&& __t, _Up&& __u) { + swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); + }; + + struct __fn; + + template + concept __swappable_arrays = + !__unqualified_swappable_with<_Tp(&)[_Size], _Up(&)[_Size]> && + extent_v<_Tp> == extent_v<_Up> && + requires(_Tp(& __t)[_Size], _Up(& __u)[_Size], const __fn& __swap) { + __swap(__t[0], __u[0]); + }; + + template + concept __exchangeable = + !__unqualified_swappable_with<_Tp&, _Tp&> && + move_constructible<_Tp> && + assignable_from<_Tp&, _Tp>; + + struct __fn { + // 2.1 `S` is `(void)swap(E1, E2)`* if `E1` or `E2` has class or enumeration type and... + // *The name `swap` is used here unqualified. + template + requires __unqualified_swappable_with<_Tp, _Up> + constexpr void operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { + swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); + } + + // 2.2 Otherwise, if `E1` and `E2` are lvalues of array types with equal extent and... + template + requires __swappable_arrays<_Tp, _Up, _Size> + constexpr void operator()(_Tp(& __t)[_Size], _Up(& __u)[_Size]) const + noexcept(noexcept((*this)(*__t, *__u))) + { + // TODO(cjdb): replace with `ranges::swap_ranges`. + for (size_t __i = 0; __i < _Size; ++__i) { + (*this)(__t[__i], __u[__i]); + } + } + + // 2.3 Otherwise, if `E1` and `E2` are lvalues of the same type `T` that models... + template<__exchangeable _Tp> + constexpr void operator()(_Tp& __x, _Tp& __y) const + noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_assignable_v<_Tp>) + { + __y = _VSTD::exchange(__x, _VSTD::move(__y)); + } + }; +} // namespace __swap + +inline namespace __cpo { + inline constexpr auto swap = __swap::__fn{}; +} // namespace __cpo +} // namespace ranges + +template +concept swappable = requires(_Tp& __a, _Tp& __b) { ranges::swap(__a, __b); }; + +template +concept swappable_with = + common_reference_with<_Tp, _Up> && + requires(_Tp&& __t, _Up&& __u) { + ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Tp>(__t)); + ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Up>(__u)); + ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); + ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Tp>(__t)); + }; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_SWAPPABLE_H diff --git a/app/src/main/cpp/libcxx/include/__concepts/totally_ordered.h b/app/src/main/cpp/libcxx/include/__concepts/totally_ordered.h new file mode 100644 index 0000000..f12d26b --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__concepts/totally_ordered.h @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_TOTALLY_ORDERED_H +#define _LIBCPP___CONCEPTS_TOTALLY_ORDERED_H + +#include <__concepts/boolean_testable.h> +#include <__concepts/equality_comparable.h> +#include <__config> +#include <__type_traits/common_reference.h> +#include <__type_traits/make_const_lvalue_ref.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.totallyordered] + +template +concept __partially_ordered_with = + requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { + { __t < __u } -> __boolean_testable; + { __t > __u } -> __boolean_testable; + { __t <= __u } -> __boolean_testable; + { __t >= __u } -> __boolean_testable; + { __u < __t } -> __boolean_testable; + { __u > __t } -> __boolean_testable; + { __u <= __t } -> __boolean_testable; + { __u >= __t } -> __boolean_testable; + }; + +template +concept totally_ordered = equality_comparable<_Tp> && __partially_ordered_with<_Tp, _Tp>; + +template +concept totally_ordered_with = + totally_ordered<_Tp> && totally_ordered<_Up> && + equality_comparable_with<_Tp, _Up> && + totally_ordered< + common_reference_t< + __make_const_lvalue_ref<_Tp>, + __make_const_lvalue_ref<_Up>>> && + __partially_ordered_with<_Tp, _Up>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_TOTALLY_ORDERED_H diff --git a/app/src/main/cpp/libcxx/include/__config b/app/src/main/cpp/libcxx/include/__config new file mode 100644 index 0000000..40c9deb --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__config @@ -0,0 +1,1255 @@ +// -*- 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 _LIBCPP___CONFIG +#define _LIBCPP___CONFIG + +#include <__config_site> + +#if defined(_MSC_VER) && !defined(__clang__) +# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# define _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +# endif +#endif + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +# pragma GCC system_header +#endif + +#if defined(__apple_build_version__) +# define _LIBCPP_COMPILER_CLANG_BASED +# define _LIBCPP_APPLE_CLANG_VER (__apple_build_version__ / 10000) +#elif defined(__clang__) +# define _LIBCPP_COMPILER_CLANG_BASED +# define _LIBCPP_CLANG_VER (__clang_major__ * 100 + __clang_minor__) +#elif defined(__GNUC__) +# define _LIBCPP_COMPILER_GCC +#endif + +#ifdef __cplusplus + +// _LIBCPP_VERSION represents the version of libc++, which matches the version of LLVM. +// Given a LLVM release LLVM XX.YY.ZZ (e.g. LLVM 17.0.1 == 17.00.01), _LIBCPP_VERSION is +// defined to XXYYZZ. +# define _LIBCPP_VERSION 170000 + +# define _LIBCPP_CONCAT_IMPL(_X, _Y) _X##_Y +# define _LIBCPP_CONCAT(_X, _Y) _LIBCPP_CONCAT_IMPL(_X, _Y) + +// Valid C++ identifier that revs with every libc++ version. This can be used to +// generate identifiers that must be unique for every released libc++ version. +# define _LIBCPP_VERSIONED_IDENTIFIER _LIBCPP_CONCAT(v, _LIBCPP_VERSION) + +# if __STDC_HOSTED__ == 0 +# define _LIBCPP_FREESTANDING +# endif + +# ifndef _LIBCPP_STD_VER +# if __cplusplus <= 201103L +# define _LIBCPP_STD_VER 11 +# elif __cplusplus <= 201402L +# define _LIBCPP_STD_VER 14 +# elif __cplusplus <= 201703L +# define _LIBCPP_STD_VER 17 +# elif __cplusplus <= 202002L +# define _LIBCPP_STD_VER 20 +# else +// Expected release year of the next C++ standard +# define _LIBCPP_STD_VER 23 +# endif +# endif // _LIBCPP_STD_VER + +# if defined(__ELF__) +# define _LIBCPP_OBJECT_FORMAT_ELF 1 +# elif defined(__MACH__) +# define _LIBCPP_OBJECT_FORMAT_MACHO 1 +# elif defined(_WIN32) +# define _LIBCPP_OBJECT_FORMAT_COFF 1 +# elif defined(__wasm__) +# define _LIBCPP_OBJECT_FORMAT_WASM 1 +# elif defined(_AIX) +# define _LIBCPP_OBJECT_FORMAT_XCOFF 1 +# else +// ... add new file formats here ... +# endif + +# if _LIBCPP_ABI_VERSION >= 2 +// Change short string representation so that string data starts at offset 0, +// improving its alignment in some cases. +# define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT +// Fix deque iterator type in order to support incomplete types. +# define _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE +// Fix undefined behavior in how std::list stores its linked nodes. +# define _LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB +// Fix undefined behavior in how __tree stores its end and parent nodes. +# define _LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB +// Fix undefined behavior in how __hash_table stores its pointer types. +# define _LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB +# define _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB +# define _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE +// Define a key function for `bad_function_call` in the library, to centralize +// its vtable and typeinfo to libc++ rather than having all other libraries +// using that class define their own copies. +# define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION +// Override the default return value of exception::what() for +// bad_function_call::what() with a string that is specific to +// bad_function_call (see http://wg21.link/LWG2233). This is an ABI break +// because it changes the vtable layout of bad_function_call. +# define _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE +// Enable optimized version of __do_get_(un)signed which avoids redundant copies. +# define _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET +// Give reverse_iterator one data member of type T, not two. +// Also, in C++17 and later, don't derive iterator types from std::iterator. +# define _LIBCPP_ABI_NO_ITERATOR_BASES +// Use the smallest possible integer type to represent the index of the variant. +// Previously libc++ used "unsigned int" exclusively. +# define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION +// Unstable attempt to provide a more optimized std::function +# define _LIBCPP_ABI_OPTIMIZED_FUNCTION +// All the regex constants must be distinct and nonzero. +# define _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO +// Re-worked external template instantiations for std::string with a focus on +// performance and fast-path inlining. +# define _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION +// Enable clang::trivial_abi on std::unique_ptr. +# define _LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI +// Enable clang::trivial_abi on std::shared_ptr and std::weak_ptr +# define _LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI +// std::random_device holds some state when it uses an implementation that gets +// entropy from a file (see _LIBCPP_USING_DEV_RANDOM). When switching from this +// implementation to another one on a platform that has already shipped +// std::random_device, one needs to retain the same object layout to remain ABI +// compatible. This switch removes these workarounds for platforms that don't care +// about ABI compatibility. +# define _LIBCPP_ABI_NO_RANDOM_DEVICE_COMPATIBILITY_LAYOUT +// Don't export the legacy __basic_string_common class and its methods from the built library. +# define _LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON +// Don't export the legacy __vector_base_common class and its methods from the built library. +# define _LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON +// According to the Standard, `bitset::operator[] const` returns bool +# define _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL +// Remove the base 10 implementation of std::to_chars from the dylib. +// The implementation moved to the header, but we still export the symbols from +// the dylib for backwards compatibility. +# define _LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10 +# elif _LIBCPP_ABI_VERSION == 1 +# if !(defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF)) +// Enable compiling copies of now inline methods into the dylib to support +// applications compiled against older libraries. This is unnecessary with +// COFF dllexport semantics, since dllexport forces a non-inline definition +// of inline functions to be emitted anyway. Our own non-inline copy would +// conflict with the dllexport-emitted copy, so we disable it. For XCOFF, +// the linker will take issue with the symbols in the shared object if the +// weak inline methods get visibility (such as from -fvisibility-inlines-hidden), +// so disable it. +# define _LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS +# endif +// Feature macros for disabling pre ABI v1 features. All of these options +// are deprecated. +# if defined(__FreeBSD__) +# define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR +# endif +# endif + +# if defined(_LIBCPP_BUILDING_LIBRARY) || _LIBCPP_ABI_VERSION >= 2 +// Enable additional explicit instantiations of iostreams components. This +// reduces the number of weak definitions generated in programs that use +// iostreams by providing a single strong definition in the shared library. +# define _LIBCPP_ABI_ENABLE_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1 + +// Define a key function for `bad_function_call` in the library, to centralize +// its vtable and typeinfo to libc++ rather than having all other libraries +// using that class define their own copies. +# define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION +# endif + +# define _LIBCPP_TOSTRING2(x) #x +# define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x) + +# if __cplusplus < 201103L +# define _LIBCPP_CXX03_LANG +# endif + +# ifndef __has_attribute +# define __has_attribute(__x) 0 +# endif + +# ifndef __has_builtin +# define __has_builtin(__x) 0 +# endif + +# ifndef __has_extension +# define __has_extension(__x) 0 +# endif + +# ifndef __has_feature +# define __has_feature(__x) 0 +# endif + +# ifndef __has_cpp_attribute +# define __has_cpp_attribute(__x) 0 +# endif + +# ifndef __has_constexpr_builtin +# define __has_constexpr_builtin(x) 0 +# endif + +// '__is_identifier' returns '0' if '__x' is a reserved identifier provided by +// the compiler and '1' otherwise. +# ifndef __is_identifier +# define __is_identifier(__x) 1 +# endif + +# ifndef __has_declspec_attribute +# define __has_declspec_attribute(__x) 0 +# endif + +# define __has_keyword(__x) !(__is_identifier(__x)) + +# ifndef __has_include +# define __has_include(...) 0 +# endif + +# if !defined(_LIBCPP_COMPILER_CLANG_BASED) && __cplusplus < 201103L +# error "libc++ only supports C++03 with Clang-based compilers. Please enable C++11" +# endif + +// FIXME: ABI detection should be done via compiler builtin macros. This +// is just a placeholder until Clang implements such macros. For now assume +// that Windows compilers pretending to be MSVC++ target the Microsoft ABI, +// and allow the user to explicitly specify the ABI to handle cases where this +// heuristic falls short. +# if defined(_LIBCPP_ABI_FORCE_ITANIUM) && defined(_LIBCPP_ABI_FORCE_MICROSOFT) +# error "Only one of _LIBCPP_ABI_FORCE_ITANIUM and _LIBCPP_ABI_FORCE_MICROSOFT can be defined" +# elif defined(_LIBCPP_ABI_FORCE_ITANIUM) +# define _LIBCPP_ABI_ITANIUM +# elif defined(_LIBCPP_ABI_FORCE_MICROSOFT) +# define _LIBCPP_ABI_MICROSOFT +# else +# if defined(_WIN32) && defined(_MSC_VER) +# define _LIBCPP_ABI_MICROSOFT +# else +# define _LIBCPP_ABI_ITANIUM +# endif +# endif + +# if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_NO_VCRUNTIME) +# define _LIBCPP_ABI_VCRUNTIME +# endif + +# if __has_feature(experimental_library) +# ifndef _LIBCPP_ENABLE_EXPERIMENTAL +# define _LIBCPP_ENABLE_EXPERIMENTAL +# endif +# endif + +// Incomplete features get their own specific disabling flags. This makes it +// easier to grep for target specific flags once the feature is complete. +# if !defined(_LIBCPP_ENABLE_EXPERIMENTAL) && !defined(_LIBCPP_BUILDING_LIBRARY) +# define _LIBCPP_HAS_NO_INCOMPLETE_FORMAT +# endif + +// Need to detect which libc we're using if we're on Linux. +# if defined(__linux__) +# include +# if defined(__GLIBC_PREREQ) +# define _LIBCPP_GLIBC_PREREQ(a, b) __GLIBC_PREREQ(a, b) +# else +# define _LIBCPP_GLIBC_PREREQ(a, b) 0 +# endif // defined(__GLIBC_PREREQ) +# endif // defined(__linux__) + +# if defined(__MVS__) +# include // for __NATIVE_ASCII_F +# endif + +# ifdef __LITTLE_ENDIAN__ +# if __LITTLE_ENDIAN__ +# define _LIBCPP_LITTLE_ENDIAN +# endif // __LITTLE_ENDIAN__ +# endif // __LITTLE_ENDIAN__ + +# ifdef __BIG_ENDIAN__ +# if __BIG_ENDIAN__ +# define _LIBCPP_BIG_ENDIAN +# endif // __BIG_ENDIAN__ +# endif // __BIG_ENDIAN__ + +# ifdef __BYTE_ORDER__ +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define _LIBCPP_LITTLE_ENDIAN +# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define _LIBCPP_BIG_ENDIAN +# endif // __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# endif // __BYTE_ORDER__ + +# ifdef __FreeBSD__ +# include +# include +# if _BYTE_ORDER == _LITTLE_ENDIAN +# define _LIBCPP_LITTLE_ENDIAN +# else // _BYTE_ORDER == _LITTLE_ENDIAN +# define _LIBCPP_BIG_ENDIAN +# endif // _BYTE_ORDER == _LITTLE_ENDIAN +# endif // __FreeBSD__ + +# if defined(__NetBSD__) || defined(__OpenBSD__) +# include +# if _BYTE_ORDER == _LITTLE_ENDIAN +# define _LIBCPP_LITTLE_ENDIAN +# else // _BYTE_ORDER == _LITTLE_ENDIAN +# define _LIBCPP_BIG_ENDIAN +# endif // _BYTE_ORDER == _LITTLE_ENDIAN +# endif // defined(__NetBSD__) || defined(__OpenBSD__) + +# if defined(_WIN32) +# define _LIBCPP_WIN32API +# define _LIBCPP_LITTLE_ENDIAN +# define _LIBCPP_SHORT_WCHAR 1 +// Both MinGW and native MSVC provide a "MSVC"-like environment +# define _LIBCPP_MSVCRT_LIKE +// If mingw not explicitly detected, assume using MS C runtime only if +// a MS compatibility version is specified. +# if defined(_MSC_VER) && !defined(__MINGW32__) +# define _LIBCPP_MSVCRT // Using Microsoft's C Runtime library +# endif +# if (defined(_M_AMD64) || defined(__x86_64__)) || (defined(_M_ARM) || defined(__arm__)) +# define _LIBCPP_HAS_BITSCAN64 +# endif +# define _LIBCPP_HAS_OPEN_WITH_WCHAR +# endif // defined(_WIN32) + +# ifdef __sun__ +# include +# ifdef _LITTLE_ENDIAN +# define _LIBCPP_LITTLE_ENDIAN +# else +# define _LIBCPP_BIG_ENDIAN +# endif +# endif // __sun__ + +# if defined(_AIX) && !defined(__64BIT__) +// The size of wchar is 2 byte on 32-bit mode on AIX. +# define _LIBCPP_SHORT_WCHAR 1 +# endif + +// Libc++ supports various implementations of std::random_device. +// +// _LIBCPP_USING_DEV_RANDOM +// Read entropy from the given file, by default `/dev/urandom`. +// If a token is provided, it is assumed to be the path to a file +// to read entropy from. This is the default behavior if nothing +// else is specified. This implementation requires storing state +// inside `std::random_device`. +// +// _LIBCPP_USING_ARC4_RANDOM +// Use arc4random(). This allows obtaining random data even when +// using sandboxing mechanisms. On some platforms like Apple, this +// is the recommended source of entropy for user-space programs. +// When this option is used, the token passed to `std::random_device`'s +// constructor *must* be "/dev/urandom" -- anything else is an error. +// +// _LIBCPP_USING_GETENTROPY +// Use getentropy(). +// When this option is used, the token passed to `std::random_device`'s +// constructor *must* be "/dev/urandom" -- anything else is an error. +// +// _LIBCPP_USING_FUCHSIA_CPRNG +// Use Fuchsia's zx_cprng_draw() system call, which is specified to +// deliver high-quality entropy and cannot fail. +// When this option is used, the token passed to `std::random_device`'s +// constructor *must* be "/dev/urandom" -- anything else is an error. +// +// _LIBCPP_USING_NACL_RANDOM +// NaCl's sandbox (which PNaCl also runs in) doesn't allow filesystem access, +// including accesses to the special files under `/dev`. This implementation +// uses the NaCL syscall `nacl_secure_random_init()` to get entropy. +// When this option is used, the token passed to `std::random_device`'s +// constructor *must* be "/dev/urandom" -- anything else is an error. +// +// _LIBCPP_USING_WIN32_RANDOM +// Use rand_s(), for use on Windows. +// When this option is used, the token passed to `std::random_device`'s +// constructor *must* be "/dev/urandom" -- anything else is an error. +# if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ + defined(__DragonFly__) || defined(__sun__) +# define _LIBCPP_USING_ARC4_RANDOM +# elif defined(__wasi__) || defined(__EMSCRIPTEN__) +# define _LIBCPP_USING_GETENTROPY +# elif defined(__Fuchsia__) +# define _LIBCPP_USING_FUCHSIA_CPRNG +# elif defined(__native_client__) +# define _LIBCPP_USING_NACL_RANDOM +# elif defined(_LIBCPP_WIN32API) +# define _LIBCPP_USING_WIN32_RANDOM +# else +# define _LIBCPP_USING_DEV_RANDOM +# endif + +# if !defined(_LIBCPP_LITTLE_ENDIAN) && !defined(_LIBCPP_BIG_ENDIAN) +# include +# if __BYTE_ORDER == __LITTLE_ENDIAN +# define _LIBCPP_LITTLE_ENDIAN +# elif __BYTE_ORDER == __BIG_ENDIAN +# define _LIBCPP_BIG_ENDIAN +# else // __BYTE_ORDER == __BIG_ENDIAN +# error unable to determine endian +# endif +# endif // !defined(_LIBCPP_LITTLE_ENDIAN) && !defined(_LIBCPP_BIG_ENDIAN) + +# if __has_attribute(__no_sanitize__) && !defined(_LIBCPP_COMPILER_GCC) +# define _LIBCPP_NO_CFI __attribute__((__no_sanitize__("cfi"))) +# else +# define _LIBCPP_NO_CFI +# endif + +# ifndef _LIBCPP_CXX03_LANG + +# define _LIBCPP_ALIGNOF(_Tp) alignof(_Tp) +# define _ALIGNAS_TYPE(x) alignas(x) +# define _ALIGNAS(x) alignas(x) +# define _LIBCPP_NORETURN [[noreturn]] +# define _NOEXCEPT noexcept +# define _NOEXCEPT_(x) noexcept(x) +# define _LIBCPP_CONSTEXPR constexpr + +# else + +# define _LIBCPP_ALIGNOF(_Tp) _Alignof(_Tp) +# define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x)))) +# define _ALIGNAS(x) __attribute__((__aligned__(x))) +# define _LIBCPP_NORETURN __attribute__((__noreturn__)) +# define _LIBCPP_HAS_NO_NOEXCEPT +# define nullptr __nullptr +# define _NOEXCEPT throw() +# define _NOEXCEPT_(x) +# define static_assert(...) _Static_assert(__VA_ARGS__) +# define decltype(...) __decltype(__VA_ARGS__) +# define _LIBCPP_CONSTEXPR + +typedef __char16_t char16_t; +typedef __char32_t char32_t; + +# endif + +# if !defined(__cpp_exceptions) || __cpp_exceptions < 199711L +# define _LIBCPP_NO_EXCEPTIONS +# endif + +# define _LIBCPP_PREFERRED_ALIGNOF(_Tp) __alignof(_Tp) + +# if defined(_LIBCPP_COMPILER_CLANG_BASED) + +# if defined(__APPLE__) && !defined(__i386__) && !defined(__x86_64__) && (!defined(__arm__) || __ARM_ARCH_7K__ >= 2) +# define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT +# endif + +// Objective-C++ features (opt-in) +# if __has_feature(objc_arc) +# define _LIBCPP_HAS_OBJC_ARC +# endif + +# if __has_feature(objc_arc_weak) +# define _LIBCPP_HAS_OBJC_ARC_WEAK +# endif + +# if __has_extension(blocks) +# define _LIBCPP_HAS_EXTENSION_BLOCKS +# endif + +# if defined(_LIBCPP_HAS_EXTENSION_BLOCKS) && defined(__APPLE__) +# define _LIBCPP_HAS_BLOCKS_RUNTIME +# endif + +# if !__has_feature(address_sanitizer) +# define _LIBCPP_HAS_NO_ASAN +# endif + +// Allow for build-time disabling of unsigned integer sanitization +# if __has_attribute(no_sanitize) +# define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK __attribute__((__no_sanitize__("unsigned-integer-overflow"))) +# endif + +# define _LIBCPP_ALWAYS_INLINE __attribute__((__always_inline__)) + +# define _LIBCPP_DISABLE_EXTENSION_WARNING __extension__ + +# elif defined(_LIBCPP_COMPILER_GCC) + +# if !defined(__SANITIZE_ADDRESS__) +# define _LIBCPP_HAS_NO_ASAN +# endif + +# define _LIBCPP_ALWAYS_INLINE __attribute__((__always_inline__)) + +# define _LIBCPP_DISABLE_EXTENSION_WARNING __extension__ + +# endif // _LIBCPP_COMPILER_[CLANG|GCC] + +# if defined(_LIBCPP_OBJECT_FORMAT_COFF) + +# ifdef _DLL +# define _LIBCPP_CRT_FUNC __declspec(dllimport) +# else +# define _LIBCPP_CRT_FUNC +# endif + +# if defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) || (defined(__MINGW32__) && !defined(_LIBCPP_BUILDING_LIBRARY)) +# define _LIBCPP_DLL_VIS +# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS +# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS +# define _LIBCPP_OVERRIDABLE_FUNC_VIS +# define _LIBCPP_EXPORTED_FROM_ABI +# elif defined(_LIBCPP_BUILDING_LIBRARY) +# define _LIBCPP_DLL_VIS __declspec(dllexport) +# if defined(__MINGW32__) +# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_DLL_VIS +# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS +# else +# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS +# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS _LIBCPP_DLL_VIS +# endif +# define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_DLL_VIS +# define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllexport) +# else +# define _LIBCPP_DLL_VIS __declspec(dllimport) +# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_DLL_VIS +# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS +# define _LIBCPP_OVERRIDABLE_FUNC_VIS +# define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllimport) +# endif + +# define _LIBCPP_TYPE_VIS _LIBCPP_DLL_VIS +# define _LIBCPP_FUNC_VIS _LIBCPP_DLL_VIS +# define _LIBCPP_EXCEPTION_ABI _LIBCPP_DLL_VIS +# define _LIBCPP_HIDDEN +# define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS +# define _LIBCPP_TEMPLATE_VIS +# define _LIBCPP_TEMPLATE_DATA_VIS +# define _LIBCPP_ENUM_VIS + +# else + +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +# define _LIBCPP_VISIBILITY(vis) __attribute__((__visibility__(vis))) +# else +# define _LIBCPP_VISIBILITY(vis) +# endif + +# define _LIBCPP_HIDDEN _LIBCPP_VISIBILITY("hidden") +# define _LIBCPP_FUNC_VIS _LIBCPP_VISIBILITY("default") +# define _LIBCPP_TYPE_VIS _LIBCPP_VISIBILITY("default") +# define _LIBCPP_TEMPLATE_DATA_VIS _LIBCPP_VISIBILITY("default") +# define _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_VISIBILITY("default") +# define _LIBCPP_EXCEPTION_ABI _LIBCPP_VISIBILITY("default") +# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_VISIBILITY("default") +# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS + +// TODO: Make this a proper customization point or remove the option to override it. +# ifndef _LIBCPP_OVERRIDABLE_FUNC_VIS +# define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_VISIBILITY("default") +# endif + +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +// The inline should be removed once PR32114 is resolved +# define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS inline _LIBCPP_HIDDEN +# else +# define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS +# endif + +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +# if __has_attribute(__type_visibility__) +# define _LIBCPP_TEMPLATE_VIS __attribute__((__type_visibility__("default"))) +# else +# define _LIBCPP_TEMPLATE_VIS __attribute__((__visibility__("default"))) +# endif +# else +# define _LIBCPP_TEMPLATE_VIS +# endif + +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) && __has_attribute(__type_visibility__) +# define _LIBCPP_ENUM_VIS __attribute__((__type_visibility__("default"))) +# else +# define _LIBCPP_ENUM_VIS +# endif + +# endif // defined(_LIBCPP_OBJECT_FORMAT_COFF) + +# if __has_attribute(exclude_from_explicit_instantiation) +# define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__((__exclude_from_explicit_instantiation__)) +# else +// Try to approximate the effect of exclude_from_explicit_instantiation +// (which is that entities are not assumed to be provided by explicit +// template instantiations in the dylib) by always inlining those entities. +# define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION _LIBCPP_ALWAYS_INLINE +# endif + +// This macro marks a symbol as being hidden from libc++'s ABI. This is achieved +// on two levels: +// 1. The symbol is given hidden visibility, which ensures that users won't start exporting +// symbols from their dynamic library by means of using the libc++ headers. This ensures +// that those symbols stay private to the dynamic library in which it is defined. +// +// 2. The symbol is given an ABI tag that changes with each version of libc++. This ensures +// that no ODR violation can arise from mixing two TUs compiled with different versions +// of libc++ where we would have changed the definition of a symbol. If the symbols shared +// the same name, the ODR would require that their definitions be token-by-token equivalent, +// which basically prevents us from being able to make any change to any function in our +// headers. Using this ABI tag ensures that the symbol name is "bumped" artificially at +// each release, which lets us change the definition of these symbols at our leisure. +// Note that historically, this has been achieved in various ways, including force-inlining +// all functions or giving internal linkage to all functions. Both these (previous) solutions +// suffer from drawbacks that lead notably to code bloat. +// +// Note that we use _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION to ensure that we don't depend +// on _LIBCPP_HIDE_FROM_ABI methods of classes explicitly instantiated in the dynamic library. +// +// Also note that the _LIBCPP_HIDE_FROM_ABI_VIRTUAL macro should be used on virtual functions +// instead of _LIBCPP_HIDE_FROM_ABI. That macro does not use an ABI tag. Indeed, the mangled +// name of a virtual function is part of its ABI, since some architectures like arm64e can sign +// the virtual function pointer in the vtable based on the mangled name of the function. Since +// we use an ABI tag that changes with each released version, the mangled name of the virtual +// function would change, which is incorrect. Note that it doesn't make much sense to change +// the implementation of a virtual function in an ABI-incompatible way in the first place, +// since that would be an ABI break anyway. Hence, the lack of ABI tag should not be noticeable. +// +// TODO: We provide a escape hatch with _LIBCPP_NO_ABI_TAG for folks who want to avoid increasing +// the length of symbols with an ABI tag. In practice, we should remove the escape hatch and +// use compression mangling instead, see https://github.com/itanium-cxx-abi/cxx-abi/issues/70. +# ifndef _LIBCPP_NO_ABI_TAG +# define _LIBCPP_HIDE_FROM_ABI \ + _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION \ + __attribute__((__abi_tag__(_LIBCPP_TOSTRING(_LIBCPP_VERSIONED_IDENTIFIER)))) +# else +# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION +# endif +# define _LIBCPP_HIDE_FROM_ABI_VIRTUAL _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION + +// This macro provides a HIDE_FROM_ABI equivalent that can be applied to extern +// "C" function, as those lack mangling. +# define _LIBCPP_HIDE_FROM_ABI_C _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION + +# ifdef _LIBCPP_BUILDING_LIBRARY +# if _LIBCPP_ABI_VERSION > 1 +# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI +# else +# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 +# endif +# else +# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI +# endif + +// Just so we can migrate to the new macros gradually. +# define _LIBCPP_INLINE_VISIBILITY _LIBCPP_HIDE_FROM_ABI + +// Inline namespaces are available in Clang/GCC/MSVC regardless of C++ dialect. +// clang-format off +# define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { inline namespace _LIBCPP_ABI_NAMESPACE { +# define _LIBCPP_END_NAMESPACE_STD }} +# define _VSTD std + +_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD + +# if _LIBCPP_STD_VER > 14 +# define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \ + _LIBCPP_BEGIN_NAMESPACE_STD inline namespace __fs { namespace filesystem { +# else +# define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \ + _LIBCPP_BEGIN_NAMESPACE_STD namespace __fs { namespace filesystem { +# endif + +# define _LIBCPP_END_NAMESPACE_FILESYSTEM _LIBCPP_END_NAMESPACE_STD }} +// clang-format on + +# define _VSTD_FS std::__fs::filesystem + +# if __has_attribute(__enable_if__) +# define _LIBCPP_PREFERRED_OVERLOAD __attribute__((__enable_if__(true, ""))) +# endif + +# ifndef __SIZEOF_INT128__ +# define _LIBCPP_HAS_NO_INT128 +# endif + +# ifndef __cpp_consteval +# define _LIBCPP_CONSTEVAL _LIBCPP_CONSTEXPR +# else +# define _LIBCPP_CONSTEVAL consteval +# endif + +# if __has_attribute(__malloc__) +# define _LIBCPP_NOALIAS __attribute__((__malloc__)) +# else +# define _LIBCPP_NOALIAS +# endif + +# if __has_attribute(__using_if_exists__) +# define _LIBCPP_USING_IF_EXISTS __attribute__((__using_if_exists__)) +# else +# define _LIBCPP_USING_IF_EXISTS +# endif + +# ifdef _LIBCPP_CXX03_LANG +# define _LIBCPP_DECLARE_STRONG_ENUM(x) \ + struct _LIBCPP_TYPE_VIS x { \ + enum __lx +// clang-format off +# define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) \ + __lx __v_; \ + _LIBCPP_INLINE_VISIBILITY x(__lx __v) : __v_(__v) {} \ + _LIBCPP_INLINE_VISIBILITY explicit x(int __v) : __v_(static_cast<__lx>(__v)) {} \ + _LIBCPP_INLINE_VISIBILITY operator int() const { return __v_; } \ + }; +// clang-format on + +# else // _LIBCPP_CXX03_LANG +# define _LIBCPP_DECLARE_STRONG_ENUM(x) enum class _LIBCPP_ENUM_VIS x +# define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) +# endif // _LIBCPP_CXX03_LANG + +# if defined(__APPLE__) || defined(__FreeBSD__) || defined(_LIBCPP_MSVCRT_LIKE) || defined(__sun__) || \ + defined(__NetBSD__) +# define _LIBCPP_LOCALE__L_EXTENSIONS 1 +# endif + +# ifdef __FreeBSD__ +# define _DECLARE_C99_LDBL_MATH 1 +# endif + +// If we are getting operator new from the MSVC CRT, then allocation overloads +// for align_val_t were added in 19.12, aka VS 2017 version 15.3. +# if defined(_LIBCPP_MSVCRT) && defined(_MSC_VER) && _MSC_VER < 1912 +# define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION +# elif defined(_LIBCPP_ABI_VCRUNTIME) && !defined(__cpp_aligned_new) +// We're deferring to Microsoft's STL to provide aligned new et al. We don't +// have it unless the language feature test macro is defined. +# define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION +# elif defined(__MVS__) +# define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION +# endif + +# if defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) || (!defined(__cpp_aligned_new) || __cpp_aligned_new < 201606) +# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION +# endif + +// It is not yet possible to use aligned_alloc() on all Apple platforms since +// 10.15 was the first version to ship an implementation of aligned_alloc(). +# if defined(__APPLE__) +# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \ + __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500) +# define _LIBCPP_HAS_NO_C11_ALIGNED_ALLOC +# endif +# elif defined(__ANDROID__) && __ANDROID_API__ < 28 +// Android only provides aligned_alloc when targeting API 28 or higher. +# define _LIBCPP_HAS_NO_C11_ALIGNED_ALLOC +# endif + +# if defined(__APPLE__) || defined(__FreeBSD__) +# define _LIBCPP_HAS_DEFAULTRUNELOCALE +# endif + +# if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun__) +# define _LIBCPP_WCTYPE_IS_MASK +# endif + +# if _LIBCPP_STD_VER <= 17 || !defined(__cpp_char8_t) +# define _LIBCPP_HAS_NO_CHAR8_T +# endif + +// Deprecation macros. +// +// Deprecations warnings are always enabled, except when users explicitly opt-out +// by defining _LIBCPP_DISABLE_DEPRECATION_WARNINGS. +# if !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) +# if __has_attribute(deprecated) +# define _LIBCPP_DEPRECATED __attribute__((deprecated)) +# define _LIBCPP_DEPRECATED_(m) __attribute__((deprecated(m))) +# elif _LIBCPP_STD_VER > 11 +# define _LIBCPP_DEPRECATED [[deprecated]] +# define _LIBCPP_DEPRECATED_(m) [[deprecated(m)]] +# else +# define _LIBCPP_DEPRECATED +# define _LIBCPP_DEPRECATED_(m) +# endif +# else +# define _LIBCPP_DEPRECATED +# define _LIBCPP_DEPRECATED_(m) +# endif + +# if !defined(_LIBCPP_CXX03_LANG) +# define _LIBCPP_DEPRECATED_IN_CXX11 _LIBCPP_DEPRECATED +# else +# define _LIBCPP_DEPRECATED_IN_CXX11 +# endif + +# if _LIBCPP_STD_VER > 11 +# define _LIBCPP_DEPRECATED_IN_CXX14 _LIBCPP_DEPRECATED +# else +# define _LIBCPP_DEPRECATED_IN_CXX14 +# endif + +# if _LIBCPP_STD_VER > 14 +# define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED +# else +# define _LIBCPP_DEPRECATED_IN_CXX17 +# endif + +# if _LIBCPP_STD_VER > 17 +# define _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_DEPRECATED +# else +# define _LIBCPP_DEPRECATED_IN_CXX20 +# endif + +#if _LIBCPP_STD_VER >= 23 +# define _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_DEPRECATED +#else +# define _LIBCPP_DEPRECATED_IN_CXX23 +#endif + +# if !defined(_LIBCPP_HAS_NO_CHAR8_T) +# define _LIBCPP_DEPRECATED_WITH_CHAR8_T _LIBCPP_DEPRECATED +# else +# define _LIBCPP_DEPRECATED_WITH_CHAR8_T +# endif + +// Macros to enter and leave a state where deprecation warnings are suppressed. +# if defined(_LIBCPP_COMPILER_CLANG_BASED) || defined(_LIBCPP_COMPILER_GCC) +# define _LIBCPP_SUPPRESS_DEPRECATED_PUSH \ + _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wdeprecated\"") \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +# define _LIBCPP_SUPPRESS_DEPRECATED_POP _Pragma("GCC diagnostic pop") +# else +# define _LIBCPP_SUPPRESS_DEPRECATED_PUSH +# define _LIBCPP_SUPPRESS_DEPRECATED_POP +# endif + +# if _LIBCPP_STD_VER <= 11 +# define _LIBCPP_EXPLICIT_AFTER_CXX11 +# else +# define _LIBCPP_EXPLICIT_AFTER_CXX11 explicit +# endif + +# if _LIBCPP_STD_VER > 11 +# define _LIBCPP_CONSTEXPR_SINCE_CXX14 constexpr +# else +# define _LIBCPP_CONSTEXPR_SINCE_CXX14 +# endif + +# if _LIBCPP_STD_VER > 14 +# define _LIBCPP_CONSTEXPR_SINCE_CXX17 constexpr +# else +# define _LIBCPP_CONSTEXPR_SINCE_CXX17 +# endif + +# if _LIBCPP_STD_VER > 17 +# define _LIBCPP_CONSTEXPR_SINCE_CXX20 constexpr +# else +# define _LIBCPP_CONSTEXPR_SINCE_CXX20 +# endif + +# if _LIBCPP_STD_VER > 20 +# define _LIBCPP_CONSTEXPR_SINCE_CXX23 constexpr +# else +# define _LIBCPP_CONSTEXPR_SINCE_CXX23 +# endif + +# if __has_cpp_attribute(nodiscard) +# define _LIBCPP_NODISCARD [[nodiscard]] +# else +// We can't use GCC's [[gnu::warn_unused_result]] and +// __attribute__((warn_unused_result)), because GCC does not silence them via +// (void) cast. +# define _LIBCPP_NODISCARD +# endif + +// _LIBCPP_NODISCARD_EXT may be used to apply [[nodiscard]] to entities not +// specified as such as an extension. +# if !defined(_LIBCPP_DISABLE_NODISCARD_EXT) +# define _LIBCPP_NODISCARD_EXT _LIBCPP_NODISCARD +# else +# define _LIBCPP_NODISCARD_EXT +# endif + +# if _LIBCPP_STD_VER > 17 || !defined(_LIBCPP_DISABLE_NODISCARD_EXT) +# define _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_NODISCARD +# else +# define _LIBCPP_NODISCARD_AFTER_CXX17 +# endif + +# if __has_attribute(__no_destroy__) +# define _LIBCPP_NO_DESTROY __attribute__((__no_destroy__)) +# else +# define _LIBCPP_NO_DESTROY +# endif + +# ifndef _LIBCPP_HAS_NO_ASAN + extern "C" _LIBCPP_FUNC_VIS void + __sanitizer_annotate_contiguous_container(const void*, const void*, const void*, const void*); +# endif + +// Try to find out if RTTI is disabled. +# if !defined(__cpp_rtti) || __cpp_rtti < 199711L +# define _LIBCPP_NO_RTTI +# endif + +# ifndef _LIBCPP_WEAK +# define _LIBCPP_WEAK __attribute__((__weak__)) +# endif + +// Thread API +// clang-format off +# if !defined(_LIBCPP_HAS_NO_THREADS) && \ + !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && \ + !defined(_LIBCPP_HAS_THREAD_API_WIN32) && \ + !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) + +# if defined(__FreeBSD__) || \ + defined(__wasi__) || \ + defined(__NetBSD__) || \ + defined(__OpenBSD__) || \ + defined(__NuttX__) || \ + defined(__linux__) || \ + defined(__GNU__) || \ + defined(__APPLE__) || \ + defined(__sun__) || \ + defined(__MVS__) || \ + defined(_AIX) || \ + defined(__EMSCRIPTEN__) +// clang-format on +# define _LIBCPP_HAS_THREAD_API_PTHREAD +# elif defined(__Fuchsia__) +// TODO(44575): Switch to C11 thread API when possible. +# define _LIBCPP_HAS_THREAD_API_PTHREAD +# elif defined(_LIBCPP_WIN32API) +# define _LIBCPP_HAS_THREAD_API_WIN32 +# else +# error "No thread API" +# endif // _LIBCPP_HAS_THREAD_API +# endif // _LIBCPP_HAS_NO_THREADS + +# if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) +# if defined(__ANDROID__) && __ANDROID_API__ >= 30 +# define _LIBCPP_HAS_COND_CLOCKWAIT +# elif defined(_LIBCPP_GLIBC_PREREQ) +# if _LIBCPP_GLIBC_PREREQ(2, 30) +# define _LIBCPP_HAS_COND_CLOCKWAIT +# endif +# endif +# endif + +# if defined(_LIBCPP_HAS_NO_THREADS) && defined(_LIBCPP_HAS_THREAD_API_PTHREAD) +# error _LIBCPP_HAS_THREAD_API_PTHREAD may only be defined when \ + _LIBCPP_HAS_NO_THREADS is not defined. +# endif + +# if defined(_LIBCPP_HAS_NO_THREADS) && defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) +# error _LIBCPP_HAS_THREAD_API_EXTERNAL may not be defined when \ + _LIBCPP_HAS_NO_THREADS is defined. +# endif + +# if defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) && !defined(_LIBCPP_HAS_NO_THREADS) +# error _LIBCPP_HAS_NO_MONOTONIC_CLOCK may only be defined when \ + _LIBCPP_HAS_NO_THREADS is defined. +# endif + +# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(__STDCPP_THREADS__) +# define __STDCPP_THREADS__ 1 +# endif + +// The glibc and Bionic implementation of pthreads implements +// pthread_mutex_destroy as nop for regular mutexes. Additionally, Win32 +// mutexes have no destroy mechanism. +// +// This optimization can't be performed on Apple platforms, where +// pthread_mutex_destroy can allow the kernel to release resources. +// See https://llvm.org/D64298 for details. +// +// TODO(EricWF): Enable this optimization on Bionic after speaking to their +// respective stakeholders. +// clang-format off +# if (defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && defined(__GLIBC__)) || \ + (defined(_LIBCPP_HAS_THREAD_API_C11) && defined(__Fuchsia__)) || \ + defined(_LIBCPP_HAS_THREAD_API_WIN32) +// clang-format on +# define _LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION +# endif + +// Destroying a condvar is a nop on Windows. +// +// This optimization can't be performed on Apple platforms, where +// pthread_cond_destroy can allow the kernel to release resources. +// See https://llvm.org/D64298 for details. +// +// TODO(EricWF): This is potentially true for some pthread implementations +// as well. +# if (defined(_LIBCPP_HAS_THREAD_API_C11) && defined(__Fuchsia__)) || defined(_LIBCPP_HAS_THREAD_API_WIN32) +# define _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION +# endif + +// Some systems do not provide gets() in their C library, for security reasons. +# if defined(_LIBCPP_MSVCRT) || (defined(__FreeBSD_version) && __FreeBSD_version >= 1300043) || defined(__OpenBSD__) +# define _LIBCPP_C_HAS_NO_GETS +# endif + +# if defined(__BIONIC__) || defined(__NuttX__) || defined(__Fuchsia__) || defined(__wasi__) || \ + defined(_LIBCPP_HAS_MUSL_LIBC) || defined(__OpenBSD__) +# define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE +# endif + +# if __has_feature(cxx_atomic) || __has_extension(c_atomic) || __has_keyword(_Atomic) +# define _LIBCPP_HAS_C_ATOMIC_IMP +# elif defined(_LIBCPP_COMPILER_GCC) +# define _LIBCPP_HAS_GCC_ATOMIC_IMP +# endif + +# if !defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) && \ + !defined(_LIBCPP_HAS_EXTERNAL_ATOMIC_IMP) +# define _LIBCPP_HAS_NO_ATOMIC_HEADER +# else +# ifndef _LIBCPP_ATOMIC_FLAG_TYPE +# define _LIBCPP_ATOMIC_FLAG_TYPE bool +# endif +# ifdef _LIBCPP_FREESTANDING +# define _LIBCPP_ATOMIC_ONLY_USE_BUILTINS +# endif +# endif + +# ifndef _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK +# define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK +# endif + +# if defined(_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS) +# if defined(__clang__) && __has_attribute(acquire_capability) +// Work around the attribute handling in clang. When both __declspec and +// __attribute__ are present, the processing goes awry preventing the definition +// of the types. In MinGW mode, __declspec evaluates to __attribute__, and thus +// combining the two does work. +# if !defined(_MSC_VER) +# define _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS +# endif +# endif +# endif + +# ifdef _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS +# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) __attribute__((x)) +# else +# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) +# endif + +# if _LIBCPP_STD_VER > 17 +# define _LIBCPP_CONSTINIT constinit +# elif __has_attribute(__require_constant_initialization__) +# define _LIBCPP_CONSTINIT __attribute__((__require_constant_initialization__)) +# else +# define _LIBCPP_CONSTINIT +# endif + +# if __has_attribute(__diagnose_if__) && !defined(_LIBCPP_DISABLE_ADDITIONAL_DIAGNOSTICS) +# define _LIBCPP_DIAGNOSE_WARNING(...) __attribute__((__diagnose_if__(__VA_ARGS__, "warning"))) +# else +# define _LIBCPP_DIAGNOSE_WARNING(...) +# endif + +// Use a function like macro to imply that it must be followed by a semicolon +# if __has_cpp_attribute(fallthrough) +# define _LIBCPP_FALLTHROUGH() [[fallthrough]] +# elif __has_attribute(__fallthrough__) +# define _LIBCPP_FALLTHROUGH() __attribute__((__fallthrough__)) +# else +# define _LIBCPP_FALLTHROUGH() ((void)0) +# endif + +# if __has_cpp_attribute(_Clang::__lifetimebound__) +# define _LIBCPP_LIFETIMEBOUND [[_Clang::__lifetimebound__]] +# else +# define _LIBCPP_LIFETIMEBOUND +# endif + +# if __has_attribute(__nodebug__) +# define _LIBCPP_NODEBUG __attribute__((__nodebug__)) +# else +# define _LIBCPP_NODEBUG +# endif + +# if __has_attribute(__standalone_debug__) +# define _LIBCPP_STANDALONE_DEBUG __attribute__((__standalone_debug__)) +# else +# define _LIBCPP_STANDALONE_DEBUG +# endif + +# if __has_attribute(__preferred_name__) +# define _LIBCPP_PREFERRED_NAME(x) __attribute__((__preferred_name__(x))) +# else +# define _LIBCPP_PREFERRED_NAME(x) +# endif + +// We often repeat things just for handling wide characters in the library. +// When wide characters are disabled, it can be useful to have a quick way of +// disabling it without having to resort to #if-#endif, which has a larger +// impact on readability. +# if defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS) +# define _LIBCPP_IF_WIDE_CHARACTERS(...) +# else +# define _LIBCPP_IF_WIDE_CHARACTERS(...) __VA_ARGS__ +# endif + +# if defined(_LIBCPP_ABI_MICROSOFT) && __has_declspec_attribute(empty_bases) +# define _LIBCPP_DECLSPEC_EMPTY_BASES __declspec(empty_bases) +# else +# define _LIBCPP_DECLSPEC_EMPTY_BASES +# endif + +# if defined(_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES) +# define _LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR +# define _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS +# define _LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE +# define _LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS +# define _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION +# endif // _LIBCPP_ENABLE_CXX17_REMOVED_FEATURES + +# if defined(_LIBCPP_ENABLE_CXX20_REMOVED_FEATURES) +# define _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS +# define _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION +# define _LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS +# define _LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS +# define _LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR +# define _LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS +# endif // _LIBCPP_ENABLE_CXX20_REMOVED_FEATURES + +# define _LIBCPP_PUSH_MACROS _Pragma("push_macro(\"min\")") _Pragma("push_macro(\"max\")") +# define _LIBCPP_POP_MACROS _Pragma("pop_macro(\"min\")") _Pragma("pop_macro(\"max\")") + +# ifndef _LIBCPP_NO_AUTO_LINK +# if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY) +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +# pragma comment(lib, "c++.lib") +# else +# pragma comment(lib, "libc++.lib") +# endif +# endif // defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY) +# endif // _LIBCPP_NO_AUTO_LINK + +// Configures the fopen close-on-exec mode character, if any. This string will +// be appended to any mode string used by fstream for fopen/fdopen. +// +// Not all platforms support this, but it helps avoid fd-leaks on platforms that +// do. +# if defined(__BIONIC__) +# define _LIBCPP_FOPEN_CLOEXEC_MODE "e" +# else +# define _LIBCPP_FOPEN_CLOEXEC_MODE +# endif + +// Support for _FILE_OFFSET_BITS=64 landed gradually in Android, so the full set +// of functions used in cstdio may not be available for low API levels when +// using 64-bit file offsets on LP32. +# if defined(__BIONIC__) && defined(__USE_FILE_OFFSET64) && __ANDROID_API__ < 24 +# define _LIBCPP_HAS_NO_FGETPOS_FSETPOS +# endif + +# if __has_attribute(__init_priority__) +# define _LIBCPP_INIT_PRIORITY_MAX __attribute__((__init_priority__(100))) +# else +# define _LIBCPP_INIT_PRIORITY_MAX +# endif + +# if __has_attribute(__format__) +// The attribute uses 1-based indices for ordinary and static member functions. +// The attribute uses 2-based indices for non-static member functions. +# define _LIBCPP_ATTRIBUTE_FORMAT(archetype, format_string_index, first_format_arg_index) \ + __attribute__((__format__(archetype, format_string_index, first_format_arg_index))) +# else +# define _LIBCPP_ATTRIBUTE_FORMAT(archetype, format_string_index, first_format_arg_index) /* nothing */ +# endif + +# if __has_cpp_attribute(msvc::no_unique_address) +// MSVC implements [[no_unique_address]] as a silent no-op currently. +// (If/when MSVC breaks its C++ ABI, it will be changed to work as intended.) +// However, MSVC implements [[msvc::no_unique_address]] which does what +// [[no_unique_address]] is supposed to do, in general. + +// Clang-cl does not yet (14.0) implement either [[no_unique_address]] or +// [[msvc::no_unique_address]] though. If/when it does implement +// [[msvc::no_unique_address]], this should be preferred though. +# define _LIBCPP_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]] +# elif __has_cpp_attribute(no_unique_address) +# define _LIBCPP_NO_UNIQUE_ADDRESS [[no_unique_address]] +# else +# define _LIBCPP_NO_UNIQUE_ADDRESS /* nothing */ +// Note that this can be replaced by #error as soon as clang-cl +// implements msvc::no_unique_address, since there should be no C++20 +// compiler that doesn't support one of the two attributes at that point. +// We generally don't want to use this macro outside of C++20-only code, +// because using it conditionally in one language version only would make +// the ABI inconsistent. +# endif + +# ifdef _LIBCPP_COMPILER_CLANG_BASED +# define _LIBCPP_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push") +# define _LIBCPP_DIAGNOSTIC_POP _Pragma("clang diagnostic pop") +# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str) _Pragma(_LIBCPP_TOSTRING(clang diagnostic ignored str)) +# define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str) +# elif defined(_LIBCPP_COMPILER_GCC) +# define _LIBCPP_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push") +# define _LIBCPP_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop") +# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str) +# define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str) _Pragma(_LIBCPP_TOSTRING(GCC diagnostic ignored str)) +# else +# define _LIBCPP_DIAGNOSTIC_PUSH +# define _LIBCPP_DIAGNOSTIC_POP +# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str) +# define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str) +# endif + +# if defined(_AIX) && !defined(_LIBCPP_COMPILER_GCC) +# define _LIBCPP_PACKED_BYTE_FOR_AIX _Pragma("pack(1)") +# define _LIBCPP_PACKED_BYTE_FOR_AIX_END _Pragma("pack(pop)") +# else +# define _LIBCPP_PACKED_BYTE_FOR_AIX /* empty */ +# define _LIBCPP_PACKED_BYTE_FOR_AIX_END /* empty */ +# endif + +# if __has_attribute(__packed__) +# define _LIBCPP_PACKED __attribute__((__packed__)) +# else +# define _LIBCPP_PACKED +# endif + +// c8rtomb() and mbrtoc8() were added in C++20 and C23. Support for these +// functions is gradually being added to existing C libraries. The conditions +// below check for known C library versions and conditions under which these +// functions are declared by the C library. +# define _LIBCPP_HAS_NO_C8RTOMB_MBRTOC8 +// GNU libc 2.36 and newer declare c8rtomb() and mbrtoc8() in C++ modes if +// __cpp_char8_t is defined or if C2X extensions are enabled. Unfortunately, +// determining the latter depends on internal GNU libc details. If the +// __cpp_char8_t feature test macro is not defined, then a char8_t typedef +// will be declared as well. +# if defined(_LIBCPP_GLIBC_PREREQ) && defined(__GLIBC_USE) +# if _LIBCPP_GLIBC_PREREQ(2, 36) && (defined(__cpp_char8_t) || __GLIBC_USE(ISOC2X)) +# undef _LIBCPP_HAS_NO_C8RTOMB_MBRTOC8 +# endif +# endif + +// There are a handful of public standard library types that are intended to +// support CTAD but don't need any explicit deduction guides to do so. This +// macro is used to mark them as such, which suppresses the +// '-Wctad-maybe-unsupported' compiler warning when CTAD is used in user code +// with these classes. +#if _LIBCPP_STD_VER >= 17 +# define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) \ + template \ + _ClassName(typename _Tag::__allow_ctad...) -> _ClassName<_Tag...> +#else +# define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) static_assert(true, "") +#endif + +#endif // __cplusplus + +#endif // _LIBCPP___CONFIG diff --git a/app/src/main/cpp/libcxx/include/__config_site b/app/src/main/cpp/libcxx/include/__config_site new file mode 100644 index 0000000..76d809b --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__config_site @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONFIG_SITE +#define _LIBCPP___CONFIG_SITE + +/* #undef _LIBCPP_ABI_VERSION */ +/* #undef _LIBCPP_ABI_NAMESPACE */ +/* #undef _LIBCPP_ABI_FORCE_ITANIUM */ +/* #undef _LIBCPP_ABI_FORCE_MICROSOFT */ +/* #undef _LIBCPP_HAS_NO_THREADS */ +/* #undef _LIBCPP_HAS_NO_MONOTONIC_CLOCK */ +/* #undef _LIBCPP_HAS_MUSL_LIBC */ +/* #undef _LIBCPP_HAS_THREAD_API_PTHREAD */ +/* #undef _LIBCPP_HAS_THREAD_API_EXTERNAL */ +/* #undef _LIBCPP_HAS_THREAD_API_WIN32 */ +/* #undef _LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL */ +/* #undef _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS */ +#define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS +/* #undef _LIBCPP_NO_VCRUNTIME */ +/* #undef _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION */ +/* #undef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY */ +/* #undef _LIBCPP_HAS_PARALLEL_ALGORITHMS */ +/* #undef _LIBCPP_HAS_NO_RANDOM_DEVICE */ +/* #undef _LIBCPP_HAS_NO_LOCALIZATION */ +/* #undef _LIBCPP_HAS_NO_FSTREAM */ +/* #undef _LIBCPP_HAS_NO_WIDE_CHARACTERS */ +/* #undef _LIBCPP_ENABLE_ASSERTIONS_DEFAULT */ +/* #undef _LIBCPP_ENABLE_DEBUG_MODE */ + + + + +#endif // _LIBCPP___CONFIG_SITE diff --git a/app/src/main/cpp/libcxx/include/__config_site.in b/app/src/main/cpp/libcxx/include/__config_site.in new file mode 100644 index 0000000..2ff6725 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__config_site.in @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONFIG_SITE +#define _LIBCPP___CONFIG_SITE + +#cmakedefine _LIBCPP_ABI_VERSION @_LIBCPP_ABI_VERSION@ +#cmakedefine _LIBCPP_ABI_NAMESPACE @_LIBCPP_ABI_NAMESPACE@ +#cmakedefine _LIBCPP_ABI_FORCE_ITANIUM +#cmakedefine _LIBCPP_ABI_FORCE_MICROSOFT +#cmakedefine _LIBCPP_HAS_NO_THREADS +#cmakedefine _LIBCPP_HAS_NO_MONOTONIC_CLOCK +#cmakedefine _LIBCPP_HAS_MUSL_LIBC +#cmakedefine _LIBCPP_HAS_THREAD_API_PTHREAD +#cmakedefine _LIBCPP_HAS_THREAD_API_EXTERNAL +#cmakedefine _LIBCPP_HAS_THREAD_API_WIN32 +#cmakedefine _LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL +#cmakedefine _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS +#cmakedefine _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS +#cmakedefine _LIBCPP_NO_VCRUNTIME +#cmakedefine _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION @_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION@ +#cmakedefine _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +#cmakedefine _LIBCPP_HAS_PARALLEL_ALGORITHMS +#cmakedefine _LIBCPP_HAS_NO_RANDOM_DEVICE +#cmakedefine _LIBCPP_HAS_NO_LOCALIZATION +#cmakedefine _LIBCPP_HAS_NO_FSTREAM +#cmakedefine _LIBCPP_HAS_NO_WIDE_CHARACTERS +#cmakedefine01 _LIBCPP_ENABLE_ASSERTIONS_DEFAULT +#cmakedefine _LIBCPP_ENABLE_DEBUG_MODE + +// __USE_MINGW_ANSI_STDIO gets redefined on MinGW +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmacro-redefined" +#endif + +@_LIBCPP_ABI_DEFINES@ +@_LIBCPP_EXTRA_SITE_DEFINES@ + +#ifdef __clang__ +# pragma clang diagnostic pop +#endif + +#endif // _LIBCPP___CONFIG_SITE diff --git a/app/src/main/cpp/libcxx/include/__coroutine/coroutine_handle.h b/app/src/main/cpp/libcxx/include/__coroutine/coroutine_handle.h new file mode 100644 index 0000000..0a6cc1c --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__coroutine/coroutine_handle.h @@ -0,0 +1,203 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___COROUTINE_COROUTINE_HANDLE_H +#define _LIBCPP___COROUTINE_COROUTINE_HANDLE_H + +#include <__assert> +#include <__config> +#include <__functional/hash.h> +#include <__memory/addressof.h> +#include <__type_traits/remove_cv.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +// [coroutine.handle] +template +struct _LIBCPP_TEMPLATE_VIS coroutine_handle; + +template <> +struct _LIBCPP_TEMPLATE_VIS coroutine_handle { +public: + // [coroutine.handle.con], construct/reset + _LIBCPP_HIDE_FROM_ABI + constexpr coroutine_handle() noexcept = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr coroutine_handle(nullptr_t) noexcept {} + + _LIBCPP_HIDE_FROM_ABI + coroutine_handle& operator=(nullptr_t) noexcept { + __handle_ = nullptr; + return *this; + } + + // [coroutine.handle.export.import], export/import + _LIBCPP_HIDE_FROM_ABI + constexpr void* address() const noexcept { return __handle_; } + + _LIBCPP_HIDE_FROM_ABI + static constexpr coroutine_handle from_address(void* __addr) noexcept { + coroutine_handle __tmp; + __tmp.__handle_ = __addr; + return __tmp; + } + + // [coroutine.handle.observers], observers + _LIBCPP_HIDE_FROM_ABI + constexpr explicit operator bool() const noexcept { + return __handle_ != nullptr; + } + + _LIBCPP_HIDE_FROM_ABI + bool done() const { + _LIBCPP_ASSERT(__is_suspended(), "done() can be called only on suspended coroutines"); + return __builtin_coro_done(__handle_); + } + + // [coroutine.handle.resumption], resumption + _LIBCPP_HIDE_FROM_ABI + void operator()() const { resume(); } + + _LIBCPP_HIDE_FROM_ABI + void resume() const { + _LIBCPP_ASSERT(__is_suspended(), "resume() can be called only on suspended coroutines"); + _LIBCPP_ASSERT(!done(), "resume() has undefined behavior when the coroutine is done"); + __builtin_coro_resume(__handle_); + } + + _LIBCPP_HIDE_FROM_ABI + void destroy() const { + _LIBCPP_ASSERT(__is_suspended(), "destroy() can be called only on suspended coroutines"); + __builtin_coro_destroy(__handle_); + } + +private: + bool __is_suspended() const { + // FIXME actually implement a check for if the coro is suspended. + return __handle_ != nullptr; + } + + void* __handle_ = nullptr; +}; + +// [coroutine.handle.compare] +inline _LIBCPP_HIDE_FROM_ABI +constexpr bool operator==(coroutine_handle<> __x, coroutine_handle<> __y) noexcept { + return __x.address() == __y.address(); +} +inline _LIBCPP_HIDE_FROM_ABI +constexpr strong_ordering operator<=>(coroutine_handle<> __x, coroutine_handle<> __y) noexcept { + return compare_three_way()(__x.address(), __y.address()); +} + +template +struct _LIBCPP_TEMPLATE_VIS coroutine_handle { +public: + // [coroutine.handle.con], construct/reset + _LIBCPP_HIDE_FROM_ABI + constexpr coroutine_handle() noexcept = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr coroutine_handle(nullptr_t) noexcept {} + + _LIBCPP_HIDE_FROM_ABI + static coroutine_handle from_promise(_Promise& __promise) { + using _RawPromise = __remove_cv_t<_Promise>; + coroutine_handle __tmp; + __tmp.__handle_ = + __builtin_coro_promise(_VSTD::addressof(const_cast<_RawPromise&>(__promise)), alignof(_Promise), true); + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI + coroutine_handle& operator=(nullptr_t) noexcept { + __handle_ = nullptr; + return *this; + } + + // [coroutine.handle.export.import], export/import + _LIBCPP_HIDE_FROM_ABI + constexpr void* address() const noexcept { return __handle_; } + + _LIBCPP_HIDE_FROM_ABI + static constexpr coroutine_handle from_address(void* __addr) noexcept { + coroutine_handle __tmp; + __tmp.__handle_ = __addr; + return __tmp; + } + + // [coroutine.handle.conv], conversion + _LIBCPP_HIDE_FROM_ABI + constexpr operator coroutine_handle<>() const noexcept { + return coroutine_handle<>::from_address(address()); + } + + // [coroutine.handle.observers], observers + _LIBCPP_HIDE_FROM_ABI + constexpr explicit operator bool() const noexcept { + return __handle_ != nullptr; + } + + _LIBCPP_HIDE_FROM_ABI + bool done() const { + _LIBCPP_ASSERT(__is_suspended(), "done() can be called only on suspended coroutines"); + return __builtin_coro_done(__handle_); + } + + // [coroutine.handle.resumption], resumption + _LIBCPP_HIDE_FROM_ABI + void operator()() const { resume(); } + + _LIBCPP_HIDE_FROM_ABI + void resume() const { + _LIBCPP_ASSERT(__is_suspended(), "resume() can be called only on suspended coroutines"); + _LIBCPP_ASSERT(!done(), "resume() has undefined behavior when the coroutine is done"); + __builtin_coro_resume(__handle_); + } + + _LIBCPP_HIDE_FROM_ABI + void destroy() const { + _LIBCPP_ASSERT(__is_suspended(), "destroy() can be called only on suspended coroutines"); + __builtin_coro_destroy(__handle_); + } + + // [coroutine.handle.promise], promise access + _LIBCPP_HIDE_FROM_ABI + _Promise& promise() const { + return *static_cast<_Promise*>(__builtin_coro_promise(this->__handle_, alignof(_Promise), false)); + } + +private: + bool __is_suspended() const { + // FIXME actually implement a check for if the coro is suspended. + return __handle_ != nullptr; + } + void* __handle_ = nullptr; +}; + +// [coroutine.handle.hash] +template +struct hash> { + _LIBCPP_HIDE_FROM_ABI + size_t operator()(const coroutine_handle<_Tp>& __v) const noexcept { return hash()(__v.address()); } +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // __LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___COROUTINE_COROUTINE_HANDLE_H diff --git a/app/src/main/cpp/libcxx/include/__coroutine/coroutine_traits.h b/app/src/main/cpp/libcxx/include/__coroutine/coroutine_traits.h new file mode 100644 index 0000000..d513075 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__coroutine/coroutine_traits.h @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___COROUTINE_COROUTINE_TRAITS_H +#define _LIBCPP___COROUTINE_COROUTINE_TRAITS_H + +#include <__config> +#include <__type_traits/void_t.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +// [coroutine.traits] +// [coroutine.traits.primary] +// The header defined the primary template coroutine_traits such that +// if ArgTypes is a parameter pack of types and if the qualified-id R::promise_type +// is valid and denotes a type ([temp.deduct]), then coroutine_traits +// has the following publicly accessible memebr: +// +// using promise_type = typename R::promise_type; +// +// Otherwise, coroutine_traits has no members. +template +struct __coroutine_traits_sfinae {}; + +template +struct __coroutine_traits_sfinae< + _Tp, __void_t > +{ + using promise_type = typename _Tp::promise_type; +}; + +template +struct coroutine_traits + : public __coroutine_traits_sfinae<_Ret> +{ +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // __LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___COROUTINE_COROUTINE_TRAITS_H diff --git a/app/src/main/cpp/libcxx/include/__coroutine/noop_coroutine_handle.h b/app/src/main/cpp/libcxx/include/__coroutine/noop_coroutine_handle.h new file mode 100644 index 0000000..2993047 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__coroutine/noop_coroutine_handle.h @@ -0,0 +1,112 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___COROUTINE_NOOP_COROUTINE_HANDLE_H +#define _LIBCPP___COROUTINE_NOOP_COROUTINE_HANDLE_H + +#include <__config> +#include <__coroutine/coroutine_handle.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC) + +// [coroutine.noop] +// [coroutine.promise.noop] +struct noop_coroutine_promise {}; + +// [coroutine.handle.noop] +template <> +struct _LIBCPP_TEMPLATE_VIS coroutine_handle { +public: + // [coroutine.handle.noop.conv], conversion + _LIBCPP_HIDE_FROM_ABI + constexpr operator coroutine_handle<>() const noexcept { + return coroutine_handle<>::from_address(address()); + } + + // [coroutine.handle.noop.observers], observers + _LIBCPP_HIDE_FROM_ABI + constexpr explicit operator bool() const noexcept { return true; } + _LIBCPP_HIDE_FROM_ABI + constexpr bool done() const noexcept { return false; } + + // [coroutine.handle.noop.resumption], resumption + _LIBCPP_HIDE_FROM_ABI + constexpr void operator()() const noexcept {} + _LIBCPP_HIDE_FROM_ABI + constexpr void resume() const noexcept {} + _LIBCPP_HIDE_FROM_ABI + constexpr void destroy() const noexcept {} + + // [coroutine.handle.noop.promise], promise access + _LIBCPP_HIDE_FROM_ABI + noop_coroutine_promise& promise() const noexcept { + return *static_cast( + __builtin_coro_promise(this->__handle_, alignof(noop_coroutine_promise), false)); + } + + // [coroutine.handle.noop.address], address + _LIBCPP_HIDE_FROM_ABI + constexpr void* address() const noexcept { return __handle_; } + +private: + _LIBCPP_HIDE_FROM_ABI + friend coroutine_handle noop_coroutine() noexcept; + +#if __has_builtin(__builtin_coro_noop) + _LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept { + this->__handle_ = __builtin_coro_noop(); + } + + void* __handle_ = nullptr; + +#elif defined(_LIBCPP_COMPILER_GCC) + // GCC doesn't implement __builtin_coro_noop(). + // Construct the coroutine frame manually instead. + struct __noop_coroutine_frame_ty_ { + static void __dummy_resume_destroy_func() { } + + void (*__resume_)() = __dummy_resume_destroy_func; + void (*__destroy_)() = __dummy_resume_destroy_func; + struct noop_coroutine_promise __promise_; + }; + + static __noop_coroutine_frame_ty_ __noop_coroutine_frame_; + + void* __handle_ = &__noop_coroutine_frame_; + + _LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept = default; + +#endif // __has_builtin(__builtin_coro_noop) +}; + +using noop_coroutine_handle = coroutine_handle; + +#if defined(_LIBCPP_COMPILER_GCC) +inline noop_coroutine_handle::__noop_coroutine_frame_ty_ + noop_coroutine_handle::__noop_coroutine_frame_{}; +#endif + +// [coroutine.noop.coroutine] +inline _LIBCPP_HIDE_FROM_ABI +noop_coroutine_handle noop_coroutine() noexcept { return noop_coroutine_handle(); } + +#endif // __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC) + +_LIBCPP_END_NAMESPACE_STD + +#endif // __LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___COROUTINE_NOOP_COROUTINE_HANDLE_H diff --git a/app/src/main/cpp/libcxx/include/__coroutine/trivial_awaitables.h b/app/src/main/cpp/libcxx/include/__coroutine/trivial_awaitables.h new file mode 100644 index 0000000..bbbae7a --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__coroutine/trivial_awaitables.h @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef __LIBCPP___COROUTINE_TRIVIAL_AWAITABLES_H +#define __LIBCPP___COROUTINE_TRIVIAL_AWAITABLES_H + +#include <__config> +#include <__coroutine/coroutine_handle.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +// [coroutine.trivial.awaitables] +struct suspend_never { + _LIBCPP_HIDE_FROM_ABI + constexpr bool await_ready() const noexcept { return true; } + _LIBCPP_HIDE_FROM_ABI + constexpr void await_suspend(coroutine_handle<>) const noexcept {} + _LIBCPP_HIDE_FROM_ABI + constexpr void await_resume() const noexcept {} +}; + +struct suspend_always { + _LIBCPP_HIDE_FROM_ABI + constexpr bool await_ready() const noexcept { return false; } + _LIBCPP_HIDE_FROM_ABI + constexpr void await_suspend(coroutine_handle<>) const noexcept {} + _LIBCPP_HIDE_FROM_ABI + constexpr void await_resume() const noexcept {} +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // __LIBCPP_STD_VER > 17 + +#endif // __LIBCPP___COROUTINE_TRIVIAL_AWAITABLES_H diff --git a/app/src/main/cpp/libcxx/include/__debug b/app/src/main/cpp/libcxx/include/__debug new file mode 100644 index 0000000..140cc91 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__debug @@ -0,0 +1,266 @@ +// -*- 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 _LIBCPP___DEBUG +#define _LIBCPP___DEBUG + +#include <__assert> +#include <__config> +#include <__type_traits/is_constant_evaluated.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if defined(_LIBCPP_ENABLE_DEBUG_MODE) && !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY) +# define _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY +#endif + +#if defined(_LIBCPP_ENABLE_DEBUG_MODE) && !defined(_LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING) +# define _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING +#endif + +#ifdef _LIBCPP_ENABLE_DEBUG_MODE +# define _LIBCPP_DEBUG_ASSERT(x, m) _LIBCPP_ASSERT(::std::__libcpp_is_constant_evaluated() || (x), m) +#else +# define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0) +#endif + +#if defined(_LIBCPP_ENABLE_DEBUG_MODE) || defined(_LIBCPP_BUILDING_LIBRARY) + +_LIBCPP_BEGIN_NAMESPACE_STD + +struct _LIBCPP_TYPE_VIS __c_node; + +struct _LIBCPP_TYPE_VIS __i_node +{ + void* __i_; + __i_node* __next_; + __c_node* __c_; + + __i_node(const __i_node&) = delete; + __i_node& operator=(const __i_node&) = delete; + + _LIBCPP_INLINE_VISIBILITY + __i_node(void* __i, __i_node* __next, __c_node* __c) + : __i_(__i), __next_(__next), __c_(__c) {} + ~__i_node(); +}; + +struct _LIBCPP_TYPE_VIS __c_node +{ + void* __c_; + __c_node* __next_; + __i_node** beg_; + __i_node** end_; + __i_node** cap_; + + __c_node(const __c_node&) = delete; + __c_node& operator=(const __c_node&) = delete; + + _LIBCPP_INLINE_VISIBILITY + explicit __c_node(void* __c, __c_node* __next) + : __c_(__c), __next_(__next), beg_(nullptr), end_(nullptr), cap_(nullptr) {} + virtual ~__c_node(); + + virtual bool __dereferenceable(const void*) const = 0; + virtual bool __decrementable(const void*) const = 0; + virtual bool __addable(const void*, ptrdiff_t) const = 0; + virtual bool __subscriptable(const void*, ptrdiff_t) const = 0; + + void __add(__i_node* __i); + _LIBCPP_HIDDEN void __remove(__i_node* __i); +}; + +template +struct _C_node + : public __c_node +{ + explicit _C_node(void* __c, __c_node* __n) + : __c_node(__c, __n) {} + + bool __dereferenceable(const void*) const override; + bool __decrementable(const void*) const override; + bool __addable(const void*, ptrdiff_t) const override; + bool __subscriptable(const void*, ptrdiff_t) const override; +}; + +template +inline bool +_C_node<_Cont>::__dereferenceable(const void* __i) const +{ + typedef typename _Cont::const_iterator iterator; + const iterator* __j = static_cast(__i); + _Cont* _Cp = static_cast<_Cont*>(__c_); + return _Cp->__dereferenceable(__j); +} + +template +inline bool +_C_node<_Cont>::__decrementable(const void* __i) const +{ + typedef typename _Cont::const_iterator iterator; + const iterator* __j = static_cast(__i); + _Cont* _Cp = static_cast<_Cont*>(__c_); + return _Cp->__decrementable(__j); +} + +template +inline bool +_C_node<_Cont>::__addable(const void* __i, ptrdiff_t __n) const +{ + typedef typename _Cont::const_iterator iterator; + const iterator* __j = static_cast(__i); + _Cont* _Cp = static_cast<_Cont*>(__c_); + return _Cp->__addable(__j, __n); +} + +template +inline bool +_C_node<_Cont>::__subscriptable(const void* __i, ptrdiff_t __n) const +{ + typedef typename _Cont::const_iterator iterator; + const iterator* __j = static_cast(__i); + _Cont* _Cp = static_cast<_Cont*>(__c_); + return _Cp->__subscriptable(__j, __n); +} + +class _LIBCPP_TYPE_VIS __libcpp_db +{ + __c_node** __cbeg_; + __c_node** __cend_; + size_t __csz_; + __i_node** __ibeg_; + __i_node** __iend_; + size_t __isz_; + + explicit __libcpp_db(); +public: + __libcpp_db(const __libcpp_db&) = delete; + __libcpp_db& operator=(const __libcpp_db&) = delete; + + ~__libcpp_db(); + + class __db_c_iterator; + class __db_c_const_iterator; + class __db_i_iterator; + class __db_i_const_iterator; + + __db_c_const_iterator __c_end() const; + __db_i_const_iterator __i_end() const; + + typedef __c_node*(_InsertConstruct)(void*, void*, __c_node*); + + template + _LIBCPP_INLINE_VISIBILITY static __c_node* __create_C_node(void *__mem, void *__c, __c_node *__next) { + return ::new (__mem) _C_node<_Cont>(__c, __next); + } + + template + _LIBCPP_INLINE_VISIBILITY + void __insert_c(_Cont* __c) + { + __insert_c(static_cast(__c), &__create_C_node<_Cont>); + } + + void __insert_i(void* __i); + void __insert_c(void* __c, _InsertConstruct* __fn); + void __erase_c(void* __c); + + void __insert_ic(void* __i, const void* __c); + void __iterator_copy(void* __i, const void* __i0); + void __erase_i(void* __i); + + void* __find_c_from_i(void* __i) const; + void __invalidate_all(void* __c); + __c_node* __find_c_and_lock(void* __c) const; + __c_node* __find_c(void* __c) const; + void unlock() const; + + void swap(void* __c1, void* __c2); + + + bool __dereferenceable(const void* __i) const; + bool __decrementable(const void* __i) const; + bool __addable(const void* __i, ptrdiff_t __n) const; + bool __subscriptable(const void* __i, ptrdiff_t __n) const; + bool __less_than_comparable(const void* __i, const void* __j) const; +private: + _LIBCPP_HIDDEN + __i_node* __insert_iterator(void* __i); + _LIBCPP_HIDDEN + __i_node* __find_iterator(const void* __i) const; + + friend _LIBCPP_FUNC_VIS __libcpp_db* __get_db(); +}; + +_LIBCPP_FUNC_VIS __libcpp_db* __get_db(); +_LIBCPP_FUNC_VIS const __libcpp_db* __get_const_db(); + +_LIBCPP_END_NAMESPACE_STD + +#endif // defined(_LIBCPP_ENABLE_DEBUG_MODE) || defined(_LIBCPP_BUILDING_LIBRARY) + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_insert_c(_Tp* __c) { +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + if (!__libcpp_is_constant_evaluated()) + __get_db()->__insert_c(__c); +#else + (void)(__c); +#endif +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_insert_i(_Tp* __i) { +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + if (!__libcpp_is_constant_evaluated()) + __get_db()->__insert_i(__i); +#else + (void)(__i); +#endif +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_erase_c(_Tp* __c) { +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + if (!__libcpp_is_constant_evaluated()) + __get_db()->__erase_c(__c); +#else + (void)(__c); +#endif +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_swap(_Tp* __lhs, _Tp* __rhs) { +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + if (!__libcpp_is_constant_evaluated()) + __get_db()->swap(__lhs, __rhs); +#else + (void)(__lhs); + (void)(__rhs); +#endif +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_invalidate_all(_Tp* __c) { +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + if (!__libcpp_is_constant_evaluated()) + __get_db()->__invalidate_all(__c); +#else + (void)(__c); +#endif +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___DEBUG diff --git a/app/src/main/cpp/libcxx/include/__debug_utils/randomize_range.h b/app/src/main/cpp/libcxx/include/__debug_utils/randomize_range.h new file mode 100644 index 0000000..dce6192 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__debug_utils/randomize_range.h @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___LIBCXX_DEBUG_RANDOMIZE_RANGE_H +#define _LIBCPP___LIBCXX_DEBUG_RANDOMIZE_RANGE_H + +#include <__config> + +#ifdef _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY +# include <__algorithm/shuffle.h> +# include <__type_traits/is_constant_evaluated.h> +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +void __debug_randomize_range(_Iterator __first, _Sentinel __last) { +#ifdef _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY +# ifdef _LIBCPP_CXX03_LANG +# error Support for unspecified stability is only for C++11 and higher +# endif + + if (!__libcpp_is_constant_evaluated()) + std::__shuffle<_AlgPolicy>(__first, __last, __libcpp_debug_randomizer()); +#else + (void)__first; + (void)__last; +#endif +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___LIBCXX_DEBUG_RANDOMIZE_RANGE_H diff --git a/app/src/main/cpp/libcxx/include/__errc b/app/src/main/cpp/libcxx/include/__errc new file mode 100644 index 0000000..17bbe0e --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__errc @@ -0,0 +1,217 @@ +// -*- 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 _LIBCPP___ERRC +#define _LIBCPP___ERRC + +/* + system_error synopsis + +namespace std +{ + +enum class errc +{ + address_family_not_supported, // EAFNOSUPPORT + address_in_use, // EADDRINUSE + address_not_available, // EADDRNOTAVAIL + already_connected, // EISCONN + argument_list_too_long, // E2BIG + argument_out_of_domain, // EDOM + bad_address, // EFAULT + bad_file_descriptor, // EBADF + bad_message, // EBADMSG + broken_pipe, // EPIPE + connection_aborted, // ECONNABORTED + connection_already_in_progress, // EALREADY + connection_refused, // ECONNREFUSED + connection_reset, // ECONNRESET + cross_device_link, // EXDEV + destination_address_required, // EDESTADDRREQ + device_or_resource_busy, // EBUSY + directory_not_empty, // ENOTEMPTY + executable_format_error, // ENOEXEC + file_exists, // EEXIST + file_too_large, // EFBIG + filename_too_long, // ENAMETOOLONG + function_not_supported, // ENOSYS + host_unreachable, // EHOSTUNREACH + identifier_removed, // EIDRM + illegal_byte_sequence, // EILSEQ + inappropriate_io_control_operation, // ENOTTY + interrupted, // EINTR + invalid_argument, // EINVAL + invalid_seek, // ESPIPE + io_error, // EIO + is_a_directory, // EISDIR + message_size, // EMSGSIZE + network_down, // ENETDOWN + network_reset, // ENETRESET + network_unreachable, // ENETUNREACH + no_buffer_space, // ENOBUFS + no_child_process, // ECHILD + no_link, // ENOLINK + no_lock_available, // ENOLCK + no_message_available, // ENODATA + no_message, // ENOMSG + no_protocol_option, // ENOPROTOOPT + no_space_on_device, // ENOSPC + no_stream_resources, // ENOSR + no_such_device_or_address, // ENXIO + no_such_device, // ENODEV + no_such_file_or_directory, // ENOENT + no_such_process, // ESRCH + not_a_directory, // ENOTDIR + not_a_socket, // ENOTSOCK + not_a_stream, // ENOSTR + not_connected, // ENOTCONN + not_enough_memory, // ENOMEM + not_supported, // ENOTSUP + operation_canceled, // ECANCELED + operation_in_progress, // EINPROGRESS + operation_not_permitted, // EPERM + operation_not_supported, // EOPNOTSUPP + operation_would_block, // EWOULDBLOCK + owner_dead, // EOWNERDEAD + permission_denied, // EACCES + protocol_error, // EPROTO + protocol_not_supported, // EPROTONOSUPPORT + read_only_file_system, // EROFS + resource_deadlock_would_occur, // EDEADLK + resource_unavailable_try_again, // EAGAIN + result_out_of_range, // ERANGE + state_not_recoverable, // ENOTRECOVERABLE + stream_timeout, // ETIME + text_file_busy, // ETXTBSY + timed_out, // ETIMEDOUT + too_many_files_open_in_system, // ENFILE + too_many_files_open, // EMFILE + too_many_links, // EMLINK + too_many_symbolic_link_levels, // ELOOP + value_too_large, // EOVERFLOW + wrong_protocol_type // EPROTOTYPE +}; + +*/ + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Some error codes are not present on all platforms, so we provide equivalents +// for them: + +//enum class errc +_LIBCPP_DECLARE_STRONG_ENUM(errc) +{ + address_family_not_supported = EAFNOSUPPORT, + address_in_use = EADDRINUSE, + address_not_available = EADDRNOTAVAIL, + already_connected = EISCONN, + argument_list_too_long = E2BIG, + argument_out_of_domain = EDOM, + bad_address = EFAULT, + bad_file_descriptor = EBADF, + bad_message = EBADMSG, + broken_pipe = EPIPE, + connection_aborted = ECONNABORTED, + connection_already_in_progress = EALREADY, + connection_refused = ECONNREFUSED, + connection_reset = ECONNRESET, + cross_device_link = EXDEV, + destination_address_required = EDESTADDRREQ, + device_or_resource_busy = EBUSY, + directory_not_empty = ENOTEMPTY, + executable_format_error = ENOEXEC, + file_exists = EEXIST, + file_too_large = EFBIG, + filename_too_long = ENAMETOOLONG, + function_not_supported = ENOSYS, + host_unreachable = EHOSTUNREACH, + identifier_removed = EIDRM, + illegal_byte_sequence = EILSEQ, + inappropriate_io_control_operation = ENOTTY, + interrupted = EINTR, + invalid_argument = EINVAL, + invalid_seek = ESPIPE, + io_error = EIO, + is_a_directory = EISDIR, + message_size = EMSGSIZE, + network_down = ENETDOWN, + network_reset = ENETRESET, + network_unreachable = ENETUNREACH, + no_buffer_space = ENOBUFS, + no_child_process = ECHILD, + no_link = ENOLINK, + no_lock_available = ENOLCK, +#ifdef ENODATA + no_message_available = ENODATA, +#else + no_message_available = ENOMSG, +#endif + no_message = ENOMSG, + no_protocol_option = ENOPROTOOPT, + no_space_on_device = ENOSPC, +#ifdef ENOSR + no_stream_resources = ENOSR, +#else + no_stream_resources = ENOMEM, +#endif + no_such_device_or_address = ENXIO, + no_such_device = ENODEV, + no_such_file_or_directory = ENOENT, + no_such_process = ESRCH, + not_a_directory = ENOTDIR, + not_a_socket = ENOTSOCK, +#ifdef ENOSTR + not_a_stream = ENOSTR, +#else + not_a_stream = EINVAL, +#endif + not_connected = ENOTCONN, + not_enough_memory = ENOMEM, + not_supported = ENOTSUP, + operation_canceled = ECANCELED, + operation_in_progress = EINPROGRESS, + operation_not_permitted = EPERM, + operation_not_supported = EOPNOTSUPP, + operation_would_block = EWOULDBLOCK, + owner_dead = EOWNERDEAD, + permission_denied = EACCES, + protocol_error = EPROTO, + protocol_not_supported = EPROTONOSUPPORT, + read_only_file_system = EROFS, + resource_deadlock_would_occur = EDEADLK, + resource_unavailable_try_again = EAGAIN, + result_out_of_range = ERANGE, + state_not_recoverable = ENOTRECOVERABLE, +#ifdef ETIME + stream_timeout = ETIME, +#else + stream_timeout = ETIMEDOUT, +#endif + text_file_busy = ETXTBSY, + timed_out = ETIMEDOUT, + too_many_files_open_in_system = ENFILE, + too_many_files_open = EMFILE, + too_many_links = EMLINK, + too_many_symbolic_link_levels = ELOOP, + value_too_large = EOVERFLOW, + wrong_protocol_type = EPROTOTYPE +}; +_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(errc) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ERRC diff --git a/app/src/main/cpp/libcxx/include/__expected/bad_expected_access.h b/app/src/main/cpp/libcxx/include/__expected/bad_expected_access.h new file mode 100644 index 0000000..361eab4 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__expected/bad_expected_access.h @@ -0,0 +1,64 @@ +// -*- 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 _LIBCPP___EXPECTED_BAD_EXPECTED_ACCESS_H +#define _LIBCPP___EXPECTED_BAD_EXPECTED_ACCESS_H + +#include <__config> +#include <__utility/move.h> + +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER >= 23 + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class bad_expected_access; + +template <> +class bad_expected_access : public exception { +protected: + _LIBCPP_HIDE_FROM_ABI bad_expected_access() noexcept = default; + _LIBCPP_HIDE_FROM_ABI bad_expected_access(const bad_expected_access&) = default; + _LIBCPP_HIDE_FROM_ABI bad_expected_access(bad_expected_access&&) = default; + _LIBCPP_HIDE_FROM_ABI bad_expected_access& operator=(const bad_expected_access&) = default; + _LIBCPP_HIDE_FROM_ABI bad_expected_access& operator=(bad_expected_access&&) = default; + ~bad_expected_access() override = default; + +public: + // The way this has been designed (by using a class template below) means that we'll already + // have a profusion of these vtables in TUs, and the dynamic linker will already have a bunch + // of work to do. So it is not worth hiding the specialization in the dylib, given that + // it adds deployment target restrictions. + const char* what() const noexcept override { return "bad access to std::expected"; } +}; + +template +class bad_expected_access : public bad_expected_access { +public: + _LIBCPP_HIDE_FROM_ABI explicit bad_expected_access(_Err __e) : __unex_(std::move(__e)) {} + + _LIBCPP_HIDE_FROM_ABI _Err& error() & noexcept { return __unex_; } + _LIBCPP_HIDE_FROM_ABI const _Err& error() const& noexcept { return __unex_; } + _LIBCPP_HIDE_FROM_ABI _Err&& error() && noexcept { return std::move(__unex_); } + _LIBCPP_HIDE_FROM_ABI const _Err&& error() const&& noexcept { return std::move(__unex_); } + +private: + _Err __unex_; +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 23 + +#endif // _LIBCPP___EXPECTED_BAD_EXPECTED_ACCESS_H diff --git a/app/src/main/cpp/libcxx/include/__expected/expected.h b/app/src/main/cpp/libcxx/include/__expected/expected.h new file mode 100644 index 0000000..e1f590c --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__expected/expected.h @@ -0,0 +1,973 @@ +// -*- 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 _LIBCPP___EXPECTED_EXPECTED_H +#define _LIBCPP___EXPECTED_EXPECTED_H + +#include <__assert> +#include <__config> +#include <__expected/bad_expected_access.h> +#include <__expected/unexpect.h> +#include <__expected/unexpected.h> +#include <__memory/addressof.h> +#include <__memory/construct_at.h> +#include <__type_traits/conjunction.h> +#include <__type_traits/disjunction.h> +#include <__type_traits/is_assignable.h> +#include <__type_traits/is_constructible.h> +#include <__type_traits/is_convertible.h> +#include <__type_traits/is_copy_assignable.h> +#include <__type_traits/is_copy_constructible.h> +#include <__type_traits/is_default_constructible.h> +#include <__type_traits/is_function.h> +#include <__type_traits/is_move_assignable.h> +#include <__type_traits/is_move_constructible.h> +#include <__type_traits/is_nothrow_constructible.h> +#include <__type_traits/is_nothrow_copy_assignable.h> +#include <__type_traits/is_nothrow_copy_constructible.h> +#include <__type_traits/is_nothrow_default_constructible.h> +#include <__type_traits/is_nothrow_move_assignable.h> +#include <__type_traits/is_nothrow_move_constructible.h> +#include <__type_traits/is_reference.h> +#include <__type_traits/is_same.h> +#include <__type_traits/is_swappable.h> +#include <__type_traits/is_trivially_copy_constructible.h> +#include <__type_traits/is_trivially_destructible.h> +#include <__type_traits/is_trivially_move_constructible.h> +#include <__type_traits/is_void.h> +#include <__type_traits/lazy.h> +#include <__type_traits/negation.h> +#include <__type_traits/remove_cv.h> +#include <__type_traits/remove_cvref.h> +#include <__utility/exception_guard.h> +#include <__utility/forward.h> +#include <__utility/in_place.h> +#include <__utility/move.h> +#include <__utility/swap.h> +#include // for std::abort +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER >= 23 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace __expected { + +template +_LIBCPP_HIDE_FROM_ABI void __throw_bad_expected_access(_Arg&& __arg) { +# ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_expected_access<_Err>(std::forward<_Arg>(__arg)); +# else + (void)__arg; + std::abort(); +# endif +} + +} // namespace __expected + +template +class expected { + static_assert( + !is_reference_v<_Tp> && + !is_function_v<_Tp> && + !is_same_v, in_place_t> && + !is_same_v, unexpect_t> && + !__is_std_unexpected>::value && + __valid_std_unexpected<_Err>::value + , + "[expected.object.general] A program that instantiates the definition of template expected for a " + "reference type, a function type, or for possibly cv-qualified types in_place_t, unexpect_t, or a " + "specialization of unexpected for the T parameter is ill-formed. A program that instantiates the " + "definition of the template expected with a type for the E parameter that is not a valid " + "template argument for unexpected is ill-formed."); + + template + friend class expected; + +public: + using value_type = _Tp; + using error_type = _Err; + using unexpected_type = unexpected<_Err>; + + template + using rebind = expected<_Up, error_type>; + + // [expected.object.ctor], constructors + _LIBCPP_HIDE_FROM_ABI constexpr expected() + noexcept(is_nothrow_default_constructible_v<_Tp>) // strengthened + requires is_default_constructible_v<_Tp> + : __has_val_(true) { + std::construct_at(std::addressof(__union_.__val_)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) = delete; + + _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) + requires(is_copy_constructible_v<_Tp> && + is_copy_constructible_v<_Err> && + is_trivially_copy_constructible_v<_Tp> && + is_trivially_copy_constructible_v<_Err>) + = default; + + _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __other) + noexcept(is_nothrow_copy_constructible_v<_Tp> && is_nothrow_copy_constructible_v<_Err>) // strengthened + requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> && + !(is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_constructible_v<_Err>)) + : __has_val_(__other.__has_val_) { + if (__has_val_) { + std::construct_at(std::addressof(__union_.__val_), __other.__union_.__val_); + } else { + std::construct_at(std::addressof(__union_.__unex_), __other.__union_.__unex_); + } + } + + + _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&&) + requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> + && is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>) + = default; + + _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __other) + noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_constructible_v<_Err>) + requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> && + !(is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>)) + : __has_val_(__other.__has_val_) { + if (__has_val_) { + std::construct_at(std::addressof(__union_.__val_), std::move(__other.__union_.__val_)); + } else { + std::construct_at(std::addressof(__union_.__unex_), std::move(__other.__union_.__unex_)); + } + } + +private: + template + using __can_convert = + _And< is_constructible<_Tp, _UfQual>, + is_constructible<_Err, _OtherErrQual>, + _Not&>>, + _Not>>, + _Not&>>, + _Not>>, + _Not&, _Tp>>, + _Not&&, _Tp>>, + _Not&, _Tp>>, + _Not&&, _Tp>>, + _Not, expected<_Up, _OtherErr>&>>, + _Not, expected<_Up, _OtherErr>>>, + _Not, const expected<_Up, _OtherErr>&>>, + _Not, const expected<_Up, _OtherErr>>> >; + + +public: + template + requires __can_convert<_Up, _OtherErr, const _Up&, const _OtherErr&>::value + _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v || + !is_convertible_v) + expected(const expected<_Up, _OtherErr>& __other) + noexcept(is_nothrow_constructible_v<_Tp, const _Up&> && + is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened + : __has_val_(__other.__has_val_) { + if (__has_val_) { + std::construct_at(std::addressof(__union_.__val_), __other.__union_.__val_); + } else { + std::construct_at(std::addressof(__union_.__unex_), __other.__union_.__unex_); + } + } + + template + requires __can_convert<_Up, _OtherErr, _Up, _OtherErr>::value + _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp> || !is_convertible_v<_OtherErr, _Err>) + expected(expected<_Up, _OtherErr>&& __other) + noexcept(is_nothrow_constructible_v<_Tp, _Up> && is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened + : __has_val_(__other.__has_val_) { + if (__has_val_) { + std::construct_at(std::addressof(__union_.__val_), std::move(__other.__union_.__val_)); + } else { + std::construct_at(std::addressof(__union_.__unex_), std::move(__other.__union_.__unex_)); + } + } + + template + requires(!is_same_v, in_place_t> && !is_same_v> && + !__is_std_unexpected>::value && is_constructible_v<_Tp, _Up>) + _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp>) + expected(_Up&& __u) + noexcept(is_nothrow_constructible_v<_Tp, _Up>) // strengthened + : __has_val_(true) { + std::construct_at(std::addressof(__union_.__val_), std::forward<_Up>(__u)); + } + + + template + requires is_constructible_v<_Err, const _OtherErr&> + _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v) + expected(const unexpected<_OtherErr>& __unex) + noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened + : __has_val_(false) { + std::construct_at(std::addressof(__union_.__unex_), __unex.error()); + } + + template + requires is_constructible_v<_Err, _OtherErr> + _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>) + expected(unexpected<_OtherErr>&& __unex) + noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened + : __has_val_(false) { + std::construct_at(std::addressof(__union_.__unex_), std::move(__unex.error())); + } + + template + requires is_constructible_v<_Tp, _Args...> + _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t, _Args&&... __args) + noexcept(is_nothrow_constructible_v<_Tp, _Args...>) // strengthened + : __has_val_(true) { + std::construct_at(std::addressof(__union_.__val_), std::forward<_Args>(__args)...); + } + + template + requires is_constructible_v< _Tp, initializer_list<_Up>&, _Args... > + _LIBCPP_HIDE_FROM_ABI constexpr explicit + expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args) + noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>) // strengthened + : __has_val_(true) { + std::construct_at(std::addressof(__union_.__val_), __il, std::forward<_Args>(__args)...); + } + + template + requires is_constructible_v<_Err, _Args...> + _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args) + noexcept(is_nothrow_constructible_v<_Err, _Args...>) // strengthened + : __has_val_(false) { + std::construct_at(std::addressof(__union_.__unex_), std::forward<_Args>(__args)...); + } + + template + requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... > + _LIBCPP_HIDE_FROM_ABI constexpr explicit + expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args) + noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened + : __has_val_(false) { + std::construct_at(std::addressof(__union_.__unex_), __il, std::forward<_Args>(__args)...); + } + + // [expected.object.dtor], destructor + + _LIBCPP_HIDE_FROM_ABI constexpr ~expected() + requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>) + = default; + + _LIBCPP_HIDE_FROM_ABI constexpr ~expected() + requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>) + { + if (__has_val_) { + std::destroy_at(std::addressof(__union_.__val_)); + } else { + std::destroy_at(std::addressof(__union_.__unex_)); + } + } + +private: + template + _LIBCPP_HIDE_FROM_ABI static constexpr void __reinit_expected(_T1& __newval, _T2& __oldval, _Args&&... __args) { + if constexpr (is_nothrow_constructible_v<_T1, _Args...>) { + std::destroy_at(std::addressof(__oldval)); + std::construct_at(std::addressof(__newval), std::forward<_Args>(__args)...); + } else if constexpr (is_nothrow_move_constructible_v<_T1>) { + _T1 __tmp(std::forward<_Args>(__args)...); + std::destroy_at(std::addressof(__oldval)); + std::construct_at(std::addressof(__newval), std::move(__tmp)); + } else { + static_assert( + is_nothrow_move_constructible_v<_T2>, + "To provide strong exception guarantee, T2 has to satisfy `is_nothrow_move_constructible_v` so that it can " + "be reverted to the previous state in case an exception is thrown during the assignment."); + _T2 __tmp(std::move(__oldval)); + std::destroy_at(std::addressof(__oldval)); + __exception_guard __trans([&] { std::construct_at(std::addressof(__oldval), std::move(__tmp)); }); + std::construct_at(std::addressof(__newval), std::forward<_Args>(__args)...); + __trans.__complete(); + } + } + +public: + // [expected.object.assign], assignment + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected&) = delete; + + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs) + noexcept(is_nothrow_copy_assignable_v<_Tp> && + is_nothrow_copy_constructible_v<_Tp> && + is_nothrow_copy_assignable_v<_Err> && + is_nothrow_copy_constructible_v<_Err>) // strengthened + requires(is_copy_assignable_v<_Tp> && + is_copy_constructible_v<_Tp> && + is_copy_assignable_v<_Err> && + is_copy_constructible_v<_Err> && + (is_nothrow_move_constructible_v<_Tp> || + is_nothrow_move_constructible_v<_Err>)) + { + if (__has_val_ && __rhs.__has_val_) { + __union_.__val_ = __rhs.__union_.__val_; + } else if (__has_val_) { + __reinit_expected(__union_.__unex_, __union_.__val_, __rhs.__union_.__unex_); + } else if (__rhs.__has_val_) { + __reinit_expected(__union_.__val_, __union_.__unex_, __rhs.__union_.__val_); + } else { + __union_.__unex_ = __rhs.__union_.__unex_; + } + // note: only reached if no exception+rollback was done inside __reinit_expected + __has_val_ = __rhs.__has_val_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&& __rhs) + noexcept(is_nothrow_move_assignable_v<_Tp> && + is_nothrow_move_constructible_v<_Tp> && + is_nothrow_move_assignable_v<_Err> && + is_nothrow_move_constructible_v<_Err>) + requires(is_move_constructible_v<_Tp> && + is_move_assignable_v<_Tp> && + is_move_constructible_v<_Err> && + is_move_assignable_v<_Err> && + (is_nothrow_move_constructible_v<_Tp> || + is_nothrow_move_constructible_v<_Err>)) + { + if (__has_val_ && __rhs.__has_val_) { + __union_.__val_ = std::move(__rhs.__union_.__val_); + } else if (__has_val_) { + __reinit_expected(__union_.__unex_, __union_.__val_, std::move(__rhs.__union_.__unex_)); + } else if (__rhs.__has_val_) { + __reinit_expected(__union_.__val_, __union_.__unex_, std::move(__rhs.__union_.__val_)); + } else { + __union_.__unex_ = std::move(__rhs.__union_.__unex_); + } + // note: only reached if no exception+rollback was done inside __reinit_expected + __has_val_ = __rhs.__has_val_; + return *this; + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(_Up&& __v) + requires(!is_same_v> && + !__is_std_unexpected>::value && + is_constructible_v<_Tp, _Up> && + is_assignable_v<_Tp&, _Up> && + (is_nothrow_constructible_v<_Tp, _Up> || + is_nothrow_move_constructible_v<_Tp> || + is_nothrow_move_constructible_v<_Err>)) + { + if (__has_val_) { + __union_.__val_ = std::forward<_Up>(__v); + } else { + __reinit_expected(__union_.__val_, __union_.__unex_, std::forward<_Up>(__v)); + __has_val_ = true; + } + return *this; + } + +private: + template + static constexpr bool __can_assign_from_unexpected = + _And< is_constructible<_Err, _OtherErrQual>, + is_assignable<_Err&, _OtherErrQual>, + _Lazy<_Or, + is_nothrow_constructible<_Err, _OtherErrQual>, + is_nothrow_move_constructible<_Tp>, + is_nothrow_move_constructible<_Err>> >::value; + +public: + template + requires(__can_assign_from_unexpected) + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const unexpected<_OtherErr>& __un) { + if (__has_val_) { + __reinit_expected(__union_.__unex_, __union_.__val_, __un.error()); + __has_val_ = false; + } else { + __union_.__unex_ = __un.error(); + } + return *this; + } + + template + requires(__can_assign_from_unexpected<_OtherErr>) + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(unexpected<_OtherErr>&& __un) { + if (__has_val_) { + __reinit_expected(__union_.__unex_, __union_.__val_, std::move(__un.error())); + __has_val_ = false; + } else { + __union_.__unex_ = std::move(__un.error()); + } + return *this; + } + + template + requires is_nothrow_constructible_v<_Tp, _Args...> + _LIBCPP_HIDE_FROM_ABI constexpr _Tp& emplace(_Args&&... __args) noexcept { + if (__has_val_) { + std::destroy_at(std::addressof(__union_.__val_)); + } else { + std::destroy_at(std::addressof(__union_.__unex_)); + __has_val_ = true; + } + return *std::construct_at(std::addressof(__union_.__val_), std::forward<_Args>(__args)...); + } + + template + requires is_nothrow_constructible_v< _Tp, initializer_list<_Up>&, _Args... > + _LIBCPP_HIDE_FROM_ABI constexpr _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) noexcept { + if (__has_val_) { + std::destroy_at(std::addressof(__union_.__val_)); + } else { + std::destroy_at(std::addressof(__union_.__unex_)); + __has_val_ = true; + } + return *std::construct_at(std::addressof(__union_.__val_), __il, std::forward<_Args>(__args)...); + } + + +public: + // [expected.object.swap], swap + _LIBCPP_HIDE_FROM_ABI constexpr void swap(expected& __rhs) + noexcept(is_nothrow_move_constructible_v<_Tp> && + is_nothrow_swappable_v<_Tp> && + is_nothrow_move_constructible_v<_Err> && + is_nothrow_swappable_v<_Err>) + requires(is_swappable_v<_Tp> && + is_swappable_v<_Err> && + is_move_constructible_v<_Tp> && + is_move_constructible_v<_Err> && + (is_nothrow_move_constructible_v<_Tp> || + is_nothrow_move_constructible_v<_Err>)) + { + auto __swap_val_unex_impl = [&](expected& __with_val, expected& __with_err) { + if constexpr (is_nothrow_move_constructible_v<_Err>) { + _Err __tmp(std::move(__with_err.__union_.__unex_)); + std::destroy_at(std::addressof(__with_err.__union_.__unex_)); + __exception_guard __trans([&] { + std::construct_at(std::addressof(__with_err.__union_.__unex_), std::move(__tmp)); + }); + std::construct_at(std::addressof(__with_err.__union_.__val_), std::move(__with_val.__union_.__val_)); + __trans.__complete(); + std::destroy_at(std::addressof(__with_val.__union_.__val_)); + std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__tmp)); + } else { + static_assert(is_nothrow_move_constructible_v<_Tp>, + "To provide strong exception guarantee, Tp has to satisfy `is_nothrow_move_constructible_v` so " + "that it can be reverted to the previous state in case an exception is thrown during swap."); + _Tp __tmp(std::move(__with_val.__union_.__val_)); + std::destroy_at(std::addressof(__with_val.__union_.__val_)); + __exception_guard __trans([&] { + std::construct_at(std::addressof(__with_val.__union_.__val_), std::move(__tmp)); + }); + std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__with_err.__union_.__unex_)); + __trans.__complete(); + std::destroy_at(std::addressof(__with_err.__union_.__unex_)); + std::construct_at(std::addressof(__with_err.__union_.__val_), std::move(__tmp)); + } + __with_val.__has_val_ = false; + __with_err.__has_val_ = true; + }; + + if (__has_val_) { + if (__rhs.__has_val_) { + using std::swap; + swap(__union_.__val_, __rhs.__union_.__val_); + } else { + __swap_val_unex_impl(*this, __rhs); + } + } else { + if (__rhs.__has_val_) { + __swap_val_unex_impl(__rhs, *this); + } else { + using std::swap; + swap(__union_.__unex_, __rhs.__union_.__unex_); + } + } + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y) + noexcept(noexcept(__x.swap(__y))) + requires requires { __x.swap(__y); } + { + __x.swap(__y); + } + + // [expected.object.obs], observers + _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept { + _LIBCPP_ASSERT(__has_val_, "expected::operator-> requires the expected to contain a value"); + return std::addressof(__union_.__val_); + } + + _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept { + _LIBCPP_ASSERT(__has_val_, "expected::operator-> requires the expected to contain a value"); + return std::addressof(__union_.__val_); + } + + _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const& noexcept { + _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); + return __union_.__val_; + } + + _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() & noexcept { + _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); + return __union_.__val_; + } + + _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& operator*() const&& noexcept { + _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); + return std::move(__union_.__val_); + } + + _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator*() && noexcept { + _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); + return std::move(__union_.__val_); + } + + _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __has_val_; } + + _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __has_val_; } + + _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& value() const& { + if (!__has_val_) { + __expected::__throw_bad_expected_access<_Err>(__union_.__unex_); + } + return __union_.__val_; + } + + _LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() & { + if (!__has_val_) { + __expected::__throw_bad_expected_access<_Err>(__union_.__unex_); + } + return __union_.__val_; + } + + _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& value() const&& { + if (!__has_val_) { + __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_)); + } + return std::move(__union_.__val_); + } + + _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& value() && { + if (!__has_val_) { + __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_)); + } + return std::move(__union_.__val_); + } + + _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept { + _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); + return __union_.__unex_; + } + + _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept { + _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); + return __union_.__unex_; + } + + _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept { + _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); + return std::move(__union_.__unex_); + } + + _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept { + _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); + return std::move(__union_.__unex_); + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) const& { + static_assert(is_copy_constructible_v<_Tp>, "value_type has to be copy constructible"); + static_assert(is_convertible_v<_Up, _Tp>, "argument has to be convertible to value_type"); + return __has_val_ ? __union_.__val_ : static_cast<_Tp>(std::forward<_Up>(__v)); + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) && { + static_assert(is_move_constructible_v<_Tp>, "value_type has to be move constructible"); + static_assert(is_convertible_v<_Up, _Tp>, "argument has to be convertible to value_type"); + return __has_val_ ? std::move(__union_.__val_) : static_cast<_Tp>(std::forward<_Up>(__v)); + } + + // [expected.object.eq], equality operators + template + requires(!is_void_v<_T2>) + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const expected<_T2, _E2>& __y) { + if (__x.__has_val_ != __y.__has_val_) { + return false; + } else { + if (__x.__has_val_) { + return __x.__union_.__val_ == __y.__union_.__val_; + } else { + return __x.__union_.__unex_ == __y.__union_.__unex_; + } + } + } + + template + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const _T2& __v) { + return __x.__has_val_ && static_cast(__x.__union_.__val_ == __v); + } + + template + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const unexpected<_E2>& __e) { + return !__x.__has_val_ && static_cast(__x.__union_.__unex_ == __e.error()); + } + +private: + struct __empty_t {}; + // use named union because [[no_unique_address]] cannot be applied to an unnamed union + _LIBCPP_NO_UNIQUE_ADDRESS union __union_t { + _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {} + + _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() + requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>) + = default; + + // the expected's destructor handles this + _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() + requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>) + {} + + _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_; + _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_; + _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_; + } __union_; + + bool __has_val_; +}; + +template + requires is_void_v<_Tp> +class expected<_Tp, _Err> { + static_assert(__valid_std_unexpected<_Err>::value, + "[expected.void.general] A program that instantiates expected with a E that is not a " + "valid argument for unexpected is ill-formed"); + + template + friend class expected; + + template + using __can_convert = + _And< is_void<_Up>, + is_constructible<_Err, _OtherErrQual>, + _Not, expected<_Up, _OtherErr>&>>, + _Not, expected<_Up, _OtherErr>>>, + _Not, const expected<_Up, _OtherErr>&>>, + _Not, const expected<_Up, _OtherErr>>>>; + +public: + using value_type = _Tp; + using error_type = _Err; + using unexpected_type = unexpected<_Err>; + + template + using rebind = expected<_Up, error_type>; + + // [expected.void.ctor], constructors + _LIBCPP_HIDE_FROM_ABI constexpr expected() noexcept : __has_val_(true) {} + + _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) = delete; + + _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) + requires(is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Err>) + = default; + + _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __rhs) + noexcept(is_nothrow_copy_constructible_v<_Err>) // strengthened + requires(is_copy_constructible_v<_Err> && !is_trivially_copy_constructible_v<_Err>) + : __has_val_(__rhs.__has_val_) { + if (!__rhs.__has_val_) { + std::construct_at(std::addressof(__union_.__unex_), __rhs.__union_.__unex_); + } + } + + _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&&) + requires(is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Err>) + = default; + + _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __rhs) + noexcept(is_nothrow_move_constructible_v<_Err>) + requires(is_move_constructible_v<_Err> && !is_trivially_move_constructible_v<_Err>) + : __has_val_(__rhs.__has_val_) { + if (!__rhs.__has_val_) { + std::construct_at(std::addressof(__union_.__unex_), std::move(__rhs.__union_.__unex_)); + } + } + + template + requires __can_convert<_Up, _OtherErr, const _OtherErr&>::value + _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v) + expected(const expected<_Up, _OtherErr>& __rhs) + noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened + : __has_val_(__rhs.__has_val_) { + if (!__rhs.__has_val_) { + std::construct_at(std::addressof(__union_.__unex_), __rhs.__union_.__unex_); + } + } + + template + requires __can_convert<_Up, _OtherErr, _OtherErr>::value + _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>) + expected(expected<_Up, _OtherErr>&& __rhs) + noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened + : __has_val_(__rhs.__has_val_) { + if (!__rhs.__has_val_) { + std::construct_at(std::addressof(__union_.__unex_), std::move(__rhs.__union_.__unex_)); + } + } + + template + requires is_constructible_v<_Err, const _OtherErr&> + _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v) + expected(const unexpected<_OtherErr>& __unex) + noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened + : __has_val_(false) { + std::construct_at(std::addressof(__union_.__unex_), __unex.error()); + } + + template + requires is_constructible_v<_Err, _OtherErr> + _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>) + expected(unexpected<_OtherErr>&& __unex) + noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened + : __has_val_(false) { + std::construct_at(std::addressof(__union_.__unex_), std::move(__unex.error())); + } + + _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t) noexcept : __has_val_(true) {} + + template + requires is_constructible_v<_Err, _Args...> + _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args) + noexcept(is_nothrow_constructible_v<_Err, _Args...>) // strengthened + : __has_val_(false) { + std::construct_at(std::addressof(__union_.__unex_), std::forward<_Args>(__args)...); + } + + template + requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... > + _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args) + noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened + : __has_val_(false) { + std::construct_at(std::addressof(__union_.__unex_), __il, std::forward<_Args>(__args)...); + } + + // [expected.void.dtor], destructor + + _LIBCPP_HIDE_FROM_ABI constexpr ~expected() + requires is_trivially_destructible_v<_Err> + = default; + + _LIBCPP_HIDE_FROM_ABI constexpr ~expected() + requires(!is_trivially_destructible_v<_Err>) + { + if (!__has_val_) { + std::destroy_at(std::addressof(__union_.__unex_)); + } + } + + // [expected.void.assign], assignment + + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected&) = delete; + + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs) + noexcept(is_nothrow_copy_assignable_v<_Err> && is_nothrow_copy_constructible_v<_Err>) // strengthened + requires(is_copy_assignable_v<_Err> && is_copy_constructible_v<_Err>) + { + if (__has_val_) { + if (!__rhs.__has_val_) { + std::construct_at(std::addressof(__union_.__unex_), __rhs.__union_.__unex_); + __has_val_ = false; + } + } else { + if (__rhs.__has_val_) { + std::destroy_at(std::addressof(__union_.__unex_)); + __has_val_ = true; + } else { + __union_.__unex_ = __rhs.__union_.__unex_; + } + } + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&&) = delete; + + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&& __rhs) + noexcept(is_nothrow_move_assignable_v<_Err> && + is_nothrow_move_constructible_v<_Err>) + requires(is_move_assignable_v<_Err> && + is_move_constructible_v<_Err>) + { + if (__has_val_) { + if (!__rhs.__has_val_) { + std::construct_at(std::addressof(__union_.__unex_), std::move(__rhs.__union_.__unex_)); + __has_val_ = false; + } + } else { + if (__rhs.__has_val_) { + std::destroy_at(std::addressof(__union_.__unex_)); + __has_val_ = true; + } else { + __union_.__unex_ = std::move(__rhs.__union_.__unex_); + } + } + return *this; + } + + template + requires(is_constructible_v<_Err, const _OtherErr&> && is_assignable_v<_Err&, const _OtherErr&>) + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const unexpected<_OtherErr>& __un) { + if (__has_val_) { + std::construct_at(std::addressof(__union_.__unex_), __un.error()); + __has_val_ = false; + } else { + __union_.__unex_ = __un.error(); + } + return *this; + } + + template + requires(is_constructible_v<_Err, _OtherErr> && is_assignable_v<_Err&, _OtherErr>) + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(unexpected<_OtherErr>&& __un) { + if (__has_val_) { + std::construct_at(std::addressof(__union_.__unex_), std::move(__un.error())); + __has_val_ = false; + } else { + __union_.__unex_ = std::move(__un.error()); + } + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr void emplace() noexcept { + if (!__has_val_) { + std::destroy_at(std::addressof(__union_.__unex_)); + __has_val_ = true; + } + } + + // [expected.void.swap], swap + _LIBCPP_HIDE_FROM_ABI constexpr void swap(expected& __rhs) + noexcept(is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>) + requires(is_swappable_v<_Err> && is_move_constructible_v<_Err>) + { + auto __swap_val_unex_impl = [&](expected& __with_val, expected& __with_err) { + std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__with_err.__union_.__unex_)); + std::destroy_at(std::addressof(__with_err.__union_.__unex_)); + __with_val.__has_val_ = false; + __with_err.__has_val_ = true; + }; + + if (__has_val_) { + if (!__rhs.__has_val_) { + __swap_val_unex_impl(*this, __rhs); + } + } else { + if (__rhs.__has_val_) { + __swap_val_unex_impl(__rhs, *this); + } else { + using std::swap; + swap(__union_.__unex_, __rhs.__union_.__unex_); + } + } + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y) + noexcept(noexcept(__x.swap(__y))) + requires requires { __x.swap(__y); } + { + __x.swap(__y); + } + + // [expected.void.obs], observers + _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __has_val_; } + + _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __has_val_; } + + _LIBCPP_HIDE_FROM_ABI constexpr void operator*() const noexcept { + _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); + } + + _LIBCPP_HIDE_FROM_ABI constexpr void value() const& { + if (!__has_val_) { + __expected::__throw_bad_expected_access<_Err>(__union_.__unex_); + } + } + + _LIBCPP_HIDE_FROM_ABI constexpr void value() && { + if (!__has_val_) { + __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_)); + } + } + + _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept { + _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); + return __union_.__unex_; + } + + _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept { + _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); + return __union_.__unex_; + } + + _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept { + _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); + return std::move(__union_.__unex_); + } + + _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept { + _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); + return std::move(__union_.__unex_); + } + + // [expected.void.eq], equality operators + template + requires is_void_v<_T2> + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const expected<_T2, _E2>& __y) { + if (__x.__has_val_ != __y.__has_val_) { + return false; + } else { + return __x.__has_val_ || static_cast(__x.__union_.__unex_ == __y.__union_.__unex_); + } + } + + template + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const unexpected<_E2>& __y) { + return !__x.__has_val_ && static_cast(__x.__union_.__unex_ == __y.error()); + } + +private: + struct __empty_t {}; + // use named union because [[no_unique_address]] cannot be applied to an unnamed union + _LIBCPP_NO_UNIQUE_ADDRESS union __union_t { + _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {} + + _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() + requires(is_trivially_destructible_v<_Err>) + = default; + + // the expected's destructor handles this + _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() + requires(!is_trivially_destructible_v<_Err>) + {} + + _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_; + _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_; + } __union_; + + bool __has_val_; +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 23 + +#endif // _LIBCPP___EXPECTED_EXPECTED_H diff --git a/app/src/main/cpp/libcxx/include/__expected/unexpect.h b/app/src/main/cpp/libcxx/include/__expected/unexpect.h new file mode 100644 index 0000000..20bafc1 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__expected/unexpect.h @@ -0,0 +1,32 @@ +// -*- 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 _LIBCPP___EXPECTED_UNEXPECT_H +#define _LIBCPP___EXPECTED_UNEXPECT_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER >= 23 + +_LIBCPP_BEGIN_NAMESPACE_STD + +struct unexpect_t { + _LIBCPP_HIDE_FROM_ABI explicit unexpect_t() = default; +}; + +inline constexpr unexpect_t unexpect{}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 23 + +#endif // _LIBCPP___EXPECTED_UNEXPECT_H diff --git a/app/src/main/cpp/libcxx/include/__expected/unexpected.h b/app/src/main/cpp/libcxx/include/__expected/unexpected.h new file mode 100644 index 0000000..075963a --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__expected/unexpected.h @@ -0,0 +1,122 @@ +// -*- 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 _LIBCPP___EXPECTED_UNEXPECTED_H +#define _LIBCPP___EXPECTED_UNEXPECTED_H + +#include <__config> +#include <__type_traits/conjunction.h> +#include <__type_traits/is_array.h> +#include <__type_traits/is_const.h> +#include <__type_traits/is_constructible.h> +#include <__type_traits/is_nothrow_constructible.h> +#include <__type_traits/is_object.h> +#include <__type_traits/is_same.h> +#include <__type_traits/is_swappable.h> +#include <__type_traits/is_volatile.h> +#include <__type_traits/negation.h> +#include <__type_traits/remove_cvref.h> +#include <__utility/forward.h> +#include <__utility/in_place.h> +#include <__utility/move.h> +#include <__utility/swap.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER >= 23 + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class unexpected; + +template +struct __is_std_unexpected : false_type {}; + +template +struct __is_std_unexpected> : true_type {}; + +template +using __valid_std_unexpected = _BoolConstant< // + is_object_v<_Tp> && // + !is_array_v<_Tp> && // + !__is_std_unexpected<_Tp>::value && // + !is_const_v<_Tp> && // + !is_volatile_v<_Tp> // + >; + +template +class unexpected { + static_assert(__valid_std_unexpected<_Err>::value, + "[expected.un.general] states a program that instantiates std::unexpected for a non-object type, an " + "array type, a specialization of unexpected, or a cv-qualified type is ill-formed."); + +public: + _LIBCPP_HIDE_FROM_ABI constexpr unexpected(const unexpected&) = default; + _LIBCPP_HIDE_FROM_ABI constexpr unexpected(unexpected&&) = default; + + template + requires(!is_same_v, unexpected> && // + !is_same_v, in_place_t> && // + is_constructible_v<_Err, _Error>) + _LIBCPP_HIDE_FROM_ABI constexpr explicit unexpected(_Error&& __error) // + noexcept(is_nothrow_constructible_v<_Err, _Error>) // strengthened + : __unex_(std::forward<_Error>(__error)) {} + + template + requires is_constructible_v<_Err, _Args...> + _LIBCPP_HIDE_FROM_ABI constexpr explicit unexpected(in_place_t, _Args&&... __args) // + noexcept(is_nothrow_constructible_v<_Err, _Args...>) // strengthened + : __unex_(std::forward<_Args>(__args)...) {} + + template + requires is_constructible_v<_Err, initializer_list<_Up>&, _Args...> + _LIBCPP_HIDE_FROM_ABI constexpr explicit unexpected(in_place_t, initializer_list<_Up> __il, _Args&&... __args) // + noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened + : __unex_(__il, std::forward<_Args>(__args)...) {} + + _LIBCPP_HIDE_FROM_ABI constexpr unexpected& operator=(const unexpected&) = default; + _LIBCPP_HIDE_FROM_ABI constexpr unexpected& operator=(unexpected&&) = default; + + _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept { return __unex_; } + _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept { return __unex_; } + _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept { return std::move(__unex_); } + _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept { return std::move(__unex_); } + + _LIBCPP_HIDE_FROM_ABI constexpr void swap(unexpected& __other) noexcept(is_nothrow_swappable_v<_Err>) { + static_assert(is_swappable_v<_Err>, "unexpected::swap requires is_swappable_v to be true"); + using std::swap; + swap(__unex_, __other.__unex_); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(unexpected& __x, unexpected& __y) noexcept(noexcept(__x.swap(__y))) + requires is_swappable_v<_Err> + { + __x.swap(__y); + } + + template + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const unexpected& __x, const unexpected<_Err2>& __y) { + return __x.__unex_ == __y.__unex_; + } + +private: + _Err __unex_; +}; + +template +unexpected(_Err) -> unexpected<_Err>; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 23 + +#endif // _LIBCPP___EXPECTED_UNEXPECTED_H diff --git a/app/src/main/cpp/libcxx/include/__filesystem/copy_options.h b/app/src/main/cpp/libcxx/include/__filesystem/copy_options.h new file mode 100644 index 0000000..96c7535 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__filesystem/copy_options.h @@ -0,0 +1,84 @@ +// -*- 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 _LIBCPP___FILESYSTEM_COPY_OPTIONS_H +#define _LIBCPP___FILESYSTEM_COPY_OPTIONS_H + +#include <__availability> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +enum class _LIBCPP_ENUM_VIS copy_options : unsigned short { + none = 0, + skip_existing = 1, + overwrite_existing = 2, + update_existing = 4, + recursive = 8, + copy_symlinks = 16, + skip_symlinks = 32, + directories_only = 64, + create_symlinks = 128, + create_hard_links = 256, + __in_recursive_copy = 512, +}; + +_LIBCPP_INLINE_VISIBILITY +inline constexpr copy_options operator&(copy_options __lhs, copy_options __rhs) { + return static_cast(static_cast(__lhs) & + static_cast(__rhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr copy_options operator|(copy_options __lhs, copy_options __rhs) { + return static_cast(static_cast(__lhs) | + static_cast(__rhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr copy_options operator^(copy_options __lhs, copy_options __rhs) { + return static_cast(static_cast(__lhs) ^ + static_cast(__rhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr copy_options operator~(copy_options __lhs) { + return static_cast(~static_cast(__lhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline copy_options& operator&=(copy_options& __lhs, copy_options __rhs) { + return __lhs = __lhs & __rhs; +} + +_LIBCPP_INLINE_VISIBILITY +inline copy_options& operator|=(copy_options& __lhs, copy_options __rhs) { + return __lhs = __lhs | __rhs; +} + +_LIBCPP_INLINE_VISIBILITY +inline copy_options& operator^=(copy_options& __lhs, copy_options __rhs) { + return __lhs = __lhs ^ __rhs; +} + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_COPY_OPTIONS_H diff --git a/app/src/main/cpp/libcxx/include/__filesystem/directory_entry.h b/app/src/main/cpp/libcxx/include/__filesystem/directory_entry.h new file mode 100644 index 0000000..b17eaaa --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__filesystem/directory_entry.h @@ -0,0 +1,527 @@ +// -*- 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 _LIBCPP___FILESYSTEM_DIRECTORY_ENTRY_H +#define _LIBCPP___FILESYSTEM_DIRECTORY_ENTRY_H + +#include <__availability> +#include <__chrono/time_point.h> +#include <__config> +#include <__errc> +#include <__filesystem/file_status.h> +#include <__filesystem/file_time_type.h> +#include <__filesystem/file_type.h> +#include <__filesystem/filesystem_error.h> +#include <__filesystem/operations.h> +#include <__filesystem/path.h> +#include <__filesystem/perms.h> +#include <__utility/unreachable.h> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + + +class directory_entry { + typedef _VSTD_FS::path _Path; + +public: + // constructors and destructors + directory_entry() noexcept = default; + directory_entry(directory_entry const&) = default; + directory_entry(directory_entry&&) noexcept = default; + + _LIBCPP_INLINE_VISIBILITY + explicit directory_entry(_Path const& __p) : __p_(__p) { + error_code __ec; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + directory_entry(_Path const& __p, error_code& __ec) : __p_(__p) { + __refresh(&__ec); + } + + ~directory_entry() {} + + directory_entry& operator=(directory_entry const&) = default; + directory_entry& operator=(directory_entry&&) noexcept = default; + + _LIBCPP_INLINE_VISIBILITY + void assign(_Path const& __p) { + __p_ = __p; + error_code __ec; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + void assign(_Path const& __p, error_code& __ec) { + __p_ = __p; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + void replace_filename(_Path const& __p) { + __p_.replace_filename(__p); + error_code __ec; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + void replace_filename(_Path const& __p, error_code& __ec) { + __p_ = __p_.parent_path() / __p; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + void refresh() { __refresh(); } + + _LIBCPP_INLINE_VISIBILITY + void refresh(error_code& __ec) noexcept { __refresh(&__ec); } + + _LIBCPP_INLINE_VISIBILITY + _Path const& path() const noexcept { return __p_; } + + _LIBCPP_INLINE_VISIBILITY + operator const _Path&() const noexcept { return __p_; } + + _LIBCPP_INLINE_VISIBILITY + bool exists() const { return _VSTD_FS::exists(file_status{__get_ft()}); } + + _LIBCPP_INLINE_VISIBILITY + bool exists(error_code& __ec) const noexcept { + return _VSTD_FS::exists(file_status{__get_ft(&__ec)}); + } + + _LIBCPP_INLINE_VISIBILITY + bool is_block_file() const { return __get_ft() == file_type::block; } + + _LIBCPP_INLINE_VISIBILITY + bool is_block_file(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::block; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_character_file() const { return __get_ft() == file_type::character; } + + _LIBCPP_INLINE_VISIBILITY + bool is_character_file(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::character; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_directory() const { return __get_ft() == file_type::directory; } + + _LIBCPP_INLINE_VISIBILITY + bool is_directory(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::directory; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_fifo() const { return __get_ft() == file_type::fifo; } + + _LIBCPP_INLINE_VISIBILITY + bool is_fifo(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::fifo; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_other() const { return _VSTD_FS::is_other(file_status{__get_ft()}); } + + _LIBCPP_INLINE_VISIBILITY + bool is_other(error_code& __ec) const noexcept { + return _VSTD_FS::is_other(file_status{__get_ft(&__ec)}); + } + + _LIBCPP_INLINE_VISIBILITY + bool is_regular_file() const { return __get_ft() == file_type::regular; } + + _LIBCPP_INLINE_VISIBILITY + bool is_regular_file(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::regular; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_socket() const { return __get_ft() == file_type::socket; } + + _LIBCPP_INLINE_VISIBILITY + bool is_socket(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::socket; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_symlink() const { return __get_sym_ft() == file_type::symlink; } + + _LIBCPP_INLINE_VISIBILITY + bool is_symlink(error_code& __ec) const noexcept { + return __get_sym_ft(&__ec) == file_type::symlink; + } + _LIBCPP_INLINE_VISIBILITY + uintmax_t file_size() const { return __get_size(); } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t file_size(error_code& __ec) const noexcept { + return __get_size(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t hard_link_count() const { return __get_nlink(); } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t hard_link_count(error_code& __ec) const noexcept { + return __get_nlink(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + file_time_type last_write_time() const { return __get_write_time(); } + + _LIBCPP_INLINE_VISIBILITY + file_time_type last_write_time(error_code& __ec) const noexcept { + return __get_write_time(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + file_status status() const { return __get_status(); } + + _LIBCPP_INLINE_VISIBILITY + file_status status(error_code& __ec) const noexcept { + return __get_status(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + file_status symlink_status() const { return __get_symlink_status(); } + + _LIBCPP_INLINE_VISIBILITY + file_status symlink_status(error_code& __ec) const noexcept { + return __get_symlink_status(&__ec); + } + + + _LIBCPP_INLINE_VISIBILITY + bool operator==(directory_entry const& __rhs) const noexcept { + return __p_ == __rhs.__p_; + } + +#if _LIBCPP_STD_VER <= 17 + _LIBCPP_INLINE_VISIBILITY + bool operator!=(directory_entry const& __rhs) const noexcept { + return __p_ != __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator<(directory_entry const& __rhs) const noexcept { + return __p_ < __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator<=(directory_entry const& __rhs) const noexcept { + return __p_ <= __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator>(directory_entry const& __rhs) const noexcept { + return __p_ > __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator>=(directory_entry const& __rhs) const noexcept { + return __p_ >= __rhs.__p_; + } + +#else // _LIBCPP_STD_VER <= 17 + + _LIBCPP_HIDE_FROM_ABI + strong_ordering operator<=>(const directory_entry& __rhs) const noexcept { + return __p_ <=> __rhs.__p_; + } + +#endif // _LIBCPP_STD_VER <= 17 + + template + _LIBCPP_INLINE_VISIBILITY + friend basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const directory_entry& __d) { + return __os << __d.path(); + } + +private: + friend class directory_iterator; + friend class recursive_directory_iterator; + friend class _LIBCPP_HIDDEN __dir_stream; + + enum _CacheType : unsigned char { + _Empty, + _IterSymlink, + _IterNonSymlink, + _RefreshSymlink, + _RefreshSymlinkUnresolved, + _RefreshNonSymlink + }; + + struct __cached_data { + uintmax_t __size_; + uintmax_t __nlink_; + file_time_type __write_time_; + perms __sym_perms_; + perms __non_sym_perms_; + file_type __type_; + _CacheType __cache_type_; + + _LIBCPP_INLINE_VISIBILITY + __cached_data() noexcept { __reset(); } + + _LIBCPP_INLINE_VISIBILITY + void __reset() { + __cache_type_ = _Empty; + __type_ = file_type::none; + __sym_perms_ = __non_sym_perms_ = perms::unknown; + __size_ = __nlink_ = uintmax_t(-1); + __write_time_ = file_time_type::min(); + } + }; + + _LIBCPP_INLINE_VISIBILITY + static __cached_data __create_iter_result(file_type __ft) { + __cached_data __data; + __data.__type_ = __ft; + __data.__cache_type_ = [&]() { + switch (__ft) { + case file_type::none: + return _Empty; + case file_type::symlink: + return _IterSymlink; + default: + return _IterNonSymlink; + } + }(); + return __data; + } + + _LIBCPP_INLINE_VISIBILITY + void __assign_iter_entry(_Path&& __p, __cached_data __dt) { + __p_ = _VSTD::move(__p); + __data_ = __dt; + } + + _LIBCPP_FUNC_VIS + error_code __do_refresh() noexcept; + + _LIBCPP_INLINE_VISIBILITY + static bool __is_dne_error(error_code const& __ec) { + if (!__ec) + return true; + switch (static_cast(__ec.value())) { + case errc::no_such_file_or_directory: + case errc::not_a_directory: + return true; + default: + return false; + } + } + + _LIBCPP_INLINE_VISIBILITY + void __handle_error(const char* __msg, error_code* __dest_ec, + error_code const& __ec, bool __allow_dne = false) const { + if (__dest_ec) { + *__dest_ec = __ec; + return; + } + if (__ec && (!__allow_dne || !__is_dne_error(__ec))) + __throw_filesystem_error(__msg, __p_, __ec); + } + + _LIBCPP_INLINE_VISIBILITY + void __refresh(error_code* __ec = nullptr) { + __handle_error("in directory_entry::refresh", __ec, __do_refresh(), + /*allow_dne*/ true); + } + + _LIBCPP_INLINE_VISIBILITY + file_type __get_sym_ft(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + return __symlink_status(__p_, __ec).type(); + case _IterSymlink: + case _RefreshSymlink: + case _RefreshSymlinkUnresolved: + if (__ec) + __ec->clear(); + return file_type::symlink; + case _IterNonSymlink: + case _RefreshNonSymlink: + file_status __st(__data_.__type_); + if (__ec && !_VSTD_FS::exists(__st)) + *__ec = make_error_code(errc::no_such_file_or_directory); + else if (__ec) + __ec->clear(); + return __data_.__type_; + } + __libcpp_unreachable(); + } + + _LIBCPP_INLINE_VISIBILITY + file_type __get_ft(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return __status(__p_, __ec).type(); + case _IterNonSymlink: + case _RefreshNonSymlink: + case _RefreshSymlink: { + file_status __st(__data_.__type_); + if (__ec && !_VSTD_FS::exists(__st)) + *__ec = make_error_code(errc::no_such_file_or_directory); + else if (__ec) + __ec->clear(); + return __data_.__type_; + } + } + __libcpp_unreachable(); + } + + _LIBCPP_INLINE_VISIBILITY + file_status __get_status(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return __status(__p_, __ec); + case _RefreshNonSymlink: + case _RefreshSymlink: + return file_status(__get_ft(__ec), __data_.__non_sym_perms_); + } + __libcpp_unreachable(); + } + + _LIBCPP_INLINE_VISIBILITY + file_status __get_symlink_status(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + return __symlink_status(__p_, __ec); + case _RefreshNonSymlink: + return file_status(__get_sym_ft(__ec), __data_.__non_sym_perms_); + case _RefreshSymlink: + case _RefreshSymlinkUnresolved: + return file_status(__get_sym_ft(__ec), __data_.__sym_perms_); + } + __libcpp_unreachable(); + } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t __get_size(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return _VSTD_FS::__file_size(__p_, __ec); + case _RefreshSymlink: + case _RefreshNonSymlink: { + error_code __m_ec; + file_status __st(__get_ft(&__m_ec)); + __handle_error("in directory_entry::file_size", __ec, __m_ec); + if (_VSTD_FS::exists(__st) && !_VSTD_FS::is_regular_file(__st)) { + errc __err_kind = _VSTD_FS::is_directory(__st) ? errc::is_a_directory + : errc::not_supported; + __handle_error("in directory_entry::file_size", __ec, + make_error_code(__err_kind)); + } + return __data_.__size_; + } + } + __libcpp_unreachable(); + } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t __get_nlink(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return _VSTD_FS::__hard_link_count(__p_, __ec); + case _RefreshSymlink: + case _RefreshNonSymlink: { + error_code __m_ec; + (void)__get_ft(&__m_ec); + __handle_error("in directory_entry::hard_link_count", __ec, __m_ec); + return __data_.__nlink_; + } + } + __libcpp_unreachable(); + } + + _LIBCPP_INLINE_VISIBILITY + file_time_type __get_write_time(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return _VSTD_FS::__last_write_time(__p_, __ec); + case _RefreshSymlink: + case _RefreshNonSymlink: { + error_code __m_ec; + file_status __st(__get_ft(&__m_ec)); + __handle_error("in directory_entry::last_write_time", __ec, __m_ec); + if (_VSTD_FS::exists(__st) && + __data_.__write_time_ == file_time_type::min()) + __handle_error("in directory_entry::last_write_time", __ec, + make_error_code(errc::value_too_large)); + return __data_.__write_time_; + } + } + __libcpp_unreachable(); + } + +private: + _Path __p_; + __cached_data __data_; +}; + +class __dir_element_proxy { +public: + inline _LIBCPP_INLINE_VISIBILITY directory_entry operator*() { + return _VSTD::move(__elem_); + } + +private: + friend class directory_iterator; + friend class recursive_directory_iterator; + explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {} + __dir_element_proxy(__dir_element_proxy&& __o) + : __elem_(_VSTD::move(__o.__elem_)) {} + directory_entry __elem_; +}; + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___FILESYSTEM_DIRECTORY_ENTRY_H diff --git a/app/src/main/cpp/libcxx/include/__filesystem/directory_iterator.h b/app/src/main/cpp/libcxx/include/__filesystem/directory_iterator.h new file mode 100644 index 0000000..5ff2f01 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__filesystem/directory_iterator.h @@ -0,0 +1,165 @@ +// -*- 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 _LIBCPP___FILESYSTEM_DIRECTORY_ITERATOR_H +#define _LIBCPP___FILESYSTEM_DIRECTORY_ITERATOR_H + +#include <__assert> +#include <__availability> +#include <__config> +#include <__filesystem/directory_entry.h> +#include <__filesystem/directory_options.h> +#include <__filesystem/path.h> +#include <__iterator/iterator_traits.h> +#include <__memory/shared_ptr.h> +#include <__ranges/enable_borrowed_range.h> +#include <__ranges/enable_view.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +class _LIBCPP_HIDDEN __dir_stream; +class directory_iterator { +public: + typedef directory_entry value_type; + typedef ptrdiff_t difference_type; + typedef value_type const* pointer; + typedef value_type const& reference; + typedef input_iterator_tag iterator_category; + +public: + //ctor & dtor + _LIBCPP_HIDE_FROM_ABI + directory_iterator() noexcept {} + + _LIBCPP_HIDE_FROM_ABI + explicit directory_iterator(const path& __p) + : directory_iterator(__p, nullptr) {} + + _LIBCPP_HIDE_FROM_ABI + directory_iterator(const path& __p, directory_options __opts) + : directory_iterator(__p, nullptr, __opts) {} + + _LIBCPP_HIDE_FROM_ABI + directory_iterator(const path& __p, error_code& __ec) + : directory_iterator(__p, &__ec) {} + + _LIBCPP_HIDE_FROM_ABI + directory_iterator(const path& __p, directory_options __opts, + error_code& __ec) + : directory_iterator(__p, &__ec, __opts) {} + + _LIBCPP_HIDE_FROM_ABI directory_iterator(const directory_iterator&) = default; + _LIBCPP_HIDE_FROM_ABI directory_iterator(directory_iterator&&) = default; + _LIBCPP_HIDE_FROM_ABI directory_iterator& operator=(const directory_iterator&) = default; + + _LIBCPP_HIDE_FROM_ABI + directory_iterator& operator=(directory_iterator&& __o) noexcept { + // non-default implementation provided to support self-move assign. + if (this != &__o) { + __imp_ = _VSTD::move(__o.__imp_); + } + return *this; + } + + _LIBCPP_HIDE_FROM_ABI ~directory_iterator() = default; + + _LIBCPP_HIDE_FROM_ABI + const directory_entry& operator*() const { + _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced"); + return __dereference(); + } + + _LIBCPP_HIDE_FROM_ABI + const directory_entry* operator->() const { return &**this; } + + _LIBCPP_HIDE_FROM_ABI + directory_iterator& operator++() { return __increment(); } + + _LIBCPP_HIDE_FROM_ABI + __dir_element_proxy operator++(int) { + __dir_element_proxy __p(**this); + __increment(); + return __p; + } + + _LIBCPP_HIDE_FROM_ABI + directory_iterator& increment(error_code& __ec) { return __increment(&__ec); } + +private: + inline _LIBCPP_HIDE_FROM_ABI friend bool + operator==(const directory_iterator& __lhs, + const directory_iterator& __rhs) noexcept; + + // construct the dir_stream + _LIBCPP_FUNC_VIS + directory_iterator(const path&, error_code*, + directory_options = directory_options::none); + + _LIBCPP_FUNC_VIS + directory_iterator& __increment(error_code* __ec = nullptr); + + _LIBCPP_FUNC_VIS + const directory_entry& __dereference() const; + +private: + shared_ptr<__dir_stream> __imp_; +}; + +inline _LIBCPP_HIDE_FROM_ABI bool +operator==(const directory_iterator& __lhs, + const directory_iterator& __rhs) noexcept { + return __lhs.__imp_ == __rhs.__imp_; +} + +inline _LIBCPP_HIDE_FROM_ABI bool +operator!=(const directory_iterator& __lhs, + const directory_iterator& __rhs) noexcept { + return !(__lhs == __rhs); +} + +// enable directory_iterator range-based for statements +inline _LIBCPP_HIDE_FROM_ABI directory_iterator +begin(directory_iterator __iter) noexcept { + return __iter; +} + +inline _LIBCPP_HIDE_FROM_ABI directory_iterator +end(directory_iterator) noexcept { + return directory_iterator(); +} + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#if _LIBCPP_STD_VER > 17 + +template <> +_LIBCPP_AVAILABILITY_FILESYSTEM +inline constexpr bool _VSTD::ranges::enable_borrowed_range<_VSTD_FS::directory_iterator> = true; + +template <> +_LIBCPP_AVAILABILITY_FILESYSTEM +inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::directory_iterator> = true; + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_DIRECTORY_ITERATOR_H diff --git a/app/src/main/cpp/libcxx/include/__filesystem/directory_options.h b/app/src/main/cpp/libcxx/include/__filesystem/directory_options.h new file mode 100644 index 0000000..c5c031a --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__filesystem/directory_options.h @@ -0,0 +1,82 @@ +// -*- 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 _LIBCPP___FILESYSTEM_DIRECTORY_OPTIONS_H +#define _LIBCPP___FILESYSTEM_DIRECTORY_OPTIONS_H + +#include <__availability> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +enum class _LIBCPP_ENUM_VIS directory_options : unsigned char { + none = 0, + follow_directory_symlink = 1, + skip_permission_denied = 2 +}; + +_LIBCPP_INLINE_VISIBILITY +inline constexpr directory_options operator&(directory_options __lhs, + directory_options __rhs) { + return static_cast(static_cast(__lhs) & + static_cast(__rhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr directory_options operator|(directory_options __lhs, + directory_options __rhs) { + return static_cast(static_cast(__lhs) | + static_cast(__rhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr directory_options operator^(directory_options __lhs, + directory_options __rhs) { + return static_cast(static_cast(__lhs) ^ + static_cast(__rhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr directory_options operator~(directory_options __lhs) { + return static_cast(~static_cast(__lhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline directory_options& operator&=(directory_options& __lhs, + directory_options __rhs) { + return __lhs = __lhs & __rhs; +} + +_LIBCPP_INLINE_VISIBILITY +inline directory_options& operator|=(directory_options& __lhs, + directory_options __rhs) { + return __lhs = __lhs | __rhs; +} + +_LIBCPP_INLINE_VISIBILITY +inline directory_options& operator^=(directory_options& __lhs, + directory_options __rhs) { + return __lhs = __lhs ^ __rhs; +} + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_DIRECTORY_OPTIONS_H diff --git a/app/src/main/cpp/libcxx/include/__filesystem/file_status.h b/app/src/main/cpp/libcxx/include/__filesystem/file_status.h new file mode 100644 index 0000000..ac3f6cb --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__filesystem/file_status.h @@ -0,0 +1,72 @@ +// -*- 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 _LIBCPP___FILESYSTEM_FILE_STATUS_H +#define _LIBCPP___FILESYSTEM_FILE_STATUS_H + +#include <__availability> +#include <__config> +#include <__filesystem/file_type.h> +#include <__filesystem/perms.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +class _LIBCPP_TYPE_VIS file_status { +public: + // constructors + _LIBCPP_INLINE_VISIBILITY + file_status() noexcept : file_status(file_type::none) {} + _LIBCPP_INLINE_VISIBILITY + explicit file_status(file_type __ft, perms __prms = perms::unknown) noexcept + : __ft_(__ft), + __prms_(__prms) {} + + file_status(const file_status&) noexcept = default; + file_status(file_status&&) noexcept = default; + + _LIBCPP_INLINE_VISIBILITY + ~file_status() {} + + file_status& operator=(const file_status&) noexcept = default; + file_status& operator=(file_status&&) noexcept = default; + + // observers + _LIBCPP_INLINE_VISIBILITY + file_type type() const noexcept { return __ft_; } + + _LIBCPP_INLINE_VISIBILITY + perms permissions() const noexcept { return __prms_; } + + // modifiers + _LIBCPP_INLINE_VISIBILITY + void type(file_type __ft) noexcept { __ft_ = __ft; } + + _LIBCPP_INLINE_VISIBILITY + void permissions(perms __p) noexcept { __prms_ = __p; } + +private: + file_type __ft_; + perms __prms_; +}; + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_FILE_STATUS_H diff --git a/app/src/main/cpp/libcxx/include/__filesystem/file_time_type.h b/app/src/main/cpp/libcxx/include/__filesystem/file_time_type.h new file mode 100644 index 0000000..7c4932e --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__filesystem/file_time_type.h @@ -0,0 +1,32 @@ +// -*- 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 _LIBCPP___FILESYSTEM_FILE_TIME_TYPE_H +#define _LIBCPP___FILESYSTEM_FILE_TIME_TYPE_H + +#include <__availability> +#include <__chrono/file_clock.h> +#include <__chrono/time_point.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +typedef chrono::time_point<_FilesystemClock> file_time_type; + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_FILE_TIME_TYPE_H diff --git a/app/src/main/cpp/libcxx/include/__filesystem/file_type.h b/app/src/main/cpp/libcxx/include/__filesystem/file_type.h new file mode 100644 index 0000000..c756a05 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__filesystem/file_type.h @@ -0,0 +1,43 @@ +// -*- 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 _LIBCPP___FILESYSTEM_FILE_TYPE_H +#define _LIBCPP___FILESYSTEM_FILE_TYPE_H + +#include <__availability> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +// On Windows, the library never identifies files as block, character, fifo +// or socket. +enum class _LIBCPP_ENUM_VIS file_type : signed char { + none = 0, + not_found = -1, + regular = 1, + directory = 2, + symlink = 3, + block = 4, + character = 5, + fifo = 6, + socket = 7, + unknown = 8 +}; + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_FILE_TYPE_H diff --git a/app/src/main/cpp/libcxx/include/__filesystem/filesystem_error.h b/app/src/main/cpp/libcxx/include/__filesystem/filesystem_error.h new file mode 100644 index 0000000..effe699 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__filesystem/filesystem_error.h @@ -0,0 +1,104 @@ +// -*- 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 _LIBCPP___FILESYSTEM_FILESYSTEM_ERROR_H +#define _LIBCPP___FILESYSTEM_FILESYSTEM_ERROR_H + +#include <__availability> +#include <__config> +#include <__filesystem/path.h> +#include <__memory/shared_ptr.h> +#include <__utility/forward.h> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +class _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error { +public: + _LIBCPP_INLINE_VISIBILITY + filesystem_error(const string& __what, error_code __ec) + : system_error(__ec, __what), + __storage_(make_shared<_Storage>(path(), path())) { + __create_what(0); + } + + _LIBCPP_INLINE_VISIBILITY + filesystem_error(const string& __what, const path& __p1, error_code __ec) + : system_error(__ec, __what), + __storage_(make_shared<_Storage>(__p1, path())) { + __create_what(1); + } + + _LIBCPP_INLINE_VISIBILITY + filesystem_error(const string& __what, const path& __p1, const path& __p2, + error_code __ec) + : system_error(__ec, __what), + __storage_(make_shared<_Storage>(__p1, __p2)) { + __create_what(2); + } + + _LIBCPP_INLINE_VISIBILITY + const path& path1() const noexcept { return __storage_->__p1_; } + + _LIBCPP_INLINE_VISIBILITY + const path& path2() const noexcept { return __storage_->__p2_; } + + filesystem_error(const filesystem_error&) = default; + ~filesystem_error() override; // key function + + _LIBCPP_HIDE_FROM_ABI_VIRTUAL + const char* what() const noexcept override { + return __storage_->__what_.c_str(); + } + + void __create_what(int __num_paths); + +private: + struct _LIBCPP_HIDDEN _Storage { + _LIBCPP_INLINE_VISIBILITY + _Storage(const path& __p1, const path& __p2) : __p1_(__p1), __p2_(__p2) {} + + path __p1_; + path __p2_; + string __what_; + }; + shared_ptr<_Storage> __storage_; +}; + +// TODO(ldionne): We need to pop the pragma and push it again after +// filesystem_error to work around PR41078. +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +template +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY +#ifndef _LIBCPP_NO_EXCEPTIONS +void __throw_filesystem_error(_Args&&... __args) { + throw filesystem_error(_VSTD::forward<_Args>(__args)...); +} +#else +void __throw_filesystem_error(_Args&&...) { + _VSTD::abort(); +} +#endif +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_FILESYSTEM_ERROR_H diff --git a/app/src/main/cpp/libcxx/include/__filesystem/operations.h b/app/src/main/cpp/libcxx/include/__filesystem/operations.h new file mode 100644 index 0000000..f48d301 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__filesystem/operations.h @@ -0,0 +1,201 @@ +// -*- 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 _LIBCPP___FILESYSTEM_OPERATIONS_H +#define _LIBCPP___FILESYSTEM_OPERATIONS_H + +#include <__availability> +#include <__chrono/time_point.h> +#include <__config> +#include <__filesystem/copy_options.h> +#include <__filesystem/file_status.h> +#include <__filesystem/file_time_type.h> +#include <__filesystem/file_type.h> +#include <__filesystem/path.h> +#include <__filesystem/perm_options.h> +#include <__filesystem/perms.h> +#include <__filesystem/space_info.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +_LIBCPP_FUNC_VIS path __absolute(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS path __canonical(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS bool __copy_file(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __copy_symlink(const path& __existing_symlink, const path& __new_symlink, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __copy(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS bool __create_directories(const path&, error_code* = nullptr); +_LIBCPP_FUNC_VIS void __create_directory_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS bool __create_directory(const path&, error_code* = nullptr); +_LIBCPP_FUNC_VIS bool __create_directory(const path&, const path& __attributes, error_code* = nullptr); +_LIBCPP_FUNC_VIS void __create_hard_link(const path& __to, const path& __new_hard_link, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __create_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS path __current_path(error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __current_path(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS bool __equivalent(const path&, const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS file_status __status(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS uintmax_t __file_size(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS file_status __symlink_status(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS file_time_type __last_write_time(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __last_write_time(const path&, file_time_type __new_time, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS path __weakly_canonical(path const& __p, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS path __read_symlink(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS uintmax_t __remove_all(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS bool __remove(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __rename(const path& __from, const path& __to, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __resize_file(const path&, uintmax_t __size, error_code* = nullptr); +_LIBCPP_FUNC_VIS path __temp_directory_path(error_code* __ec = nullptr); + +inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p) { return __absolute(__p); } +inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p, error_code& __ec) { return __absolute(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI path canonical(const path& __p) { return __canonical(__p); } +inline _LIBCPP_HIDE_FROM_ABI path canonical(const path& __p, error_code& __ec) { return __canonical(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to) { return __copy_file(__from, __to, copy_options::none); } +inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to, error_code& __ec) { return __copy_file(__from, __to, copy_options::none, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to, copy_options __opt) { return __copy_file(__from, __to, __opt); } +inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to, copy_options __opt, error_code& __ec) { return __copy_file(__from, __to, __opt, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void copy_symlink(const path& __from, const path& __to) { __copy_symlink(__from, __to); } +inline _LIBCPP_HIDE_FROM_ABI void copy_symlink(const path& __from, const path& __to, error_code& __ec) noexcept { __copy_symlink(__from, __to, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to) { __copy(__from, __to, copy_options::none); } +inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to, error_code& __ec) { __copy(__from, __to, copy_options::none, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to, copy_options __opt) { __copy(__from, __to, __opt); } +inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to, copy_options __opt, error_code& __ec) { __copy(__from, __to, __opt, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool create_directories(const path& __p) { return __create_directories(__p); } +inline _LIBCPP_HIDE_FROM_ABI bool create_directories(const path& __p, error_code& __ec) { return __create_directories(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void create_directory_symlink(const path& __target, const path& __link) { __create_directory_symlink(__target, __link); } +inline _LIBCPP_HIDE_FROM_ABI void create_directory_symlink(const path& __target, const path& __link, error_code& __ec) noexcept { __create_directory_symlink(__target, __link, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p) { return __create_directory(__p); } +inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p, error_code& __ec) noexcept { return __create_directory(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p, const path& __attrs) { return __create_directory(__p, __attrs); } +inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p, const path& __attrs, error_code& __ec) noexcept { return __create_directory(__p, __attrs, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void create_hard_link(const path& __target, const path& __link) { __create_hard_link(__target, __link); } +inline _LIBCPP_HIDE_FROM_ABI void create_hard_link(const path& __target, const path& __link, error_code& __ec) noexcept { __create_hard_link(__target, __link, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void create_symlink(const path& __target, const path& __link) { __create_symlink(__target, __link); } +inline _LIBCPP_HIDE_FROM_ABI void create_symlink(const path& __target, const path& __link, error_code& __ec) noexcept { return __create_symlink(__target, __link, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI path current_path() { return __current_path(); } +inline _LIBCPP_HIDE_FROM_ABI path current_path(error_code& __ec) { return __current_path(&__ec); } +inline _LIBCPP_HIDE_FROM_ABI void current_path(const path& __p) { __current_path(__p); } +inline _LIBCPP_HIDE_FROM_ABI void current_path(const path& __p, error_code& __ec) noexcept { __current_path(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool equivalent(const path& __p1, const path& __p2) { return __equivalent(__p1, __p2); } +inline _LIBCPP_HIDE_FROM_ABI bool equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept { return __equivalent(__p1, __p2, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool status_known(file_status __s) noexcept { return __s.type() != file_type::none; } +inline _LIBCPP_HIDE_FROM_ABI bool exists(file_status __s) noexcept { return status_known(__s) && __s.type() != file_type::not_found; } +inline _LIBCPP_HIDE_FROM_ABI bool exists(const path& __p) { return exists(__status(__p)); } + +inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p, error_code& __ec) noexcept { + auto __s = __status(__p, &__ec); + if (status_known(__s)) + __ec.clear(); + return exists(__s); +} + +inline _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(const path& __p) { return __file_size(__p); } +inline _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(const path& __p, error_code& __ec) noexcept { return __file_size(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(const path& __p) { return __hard_link_count(__p); } +inline _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(const path& __p, error_code& __ec) noexcept { return __hard_link_count(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(file_status __s) noexcept { return __s.type() == file_type::block; } +inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(const path& __p) { return is_block_file(__status(__p)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(const path& __p, error_code& __ec) noexcept { return is_block_file(__status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(file_status __s) noexcept { return __s.type() == file_type::character; } +inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(const path& __p) { return is_character_file(__status(__p)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(const path& __p, error_code& __ec) noexcept { return is_character_file(__status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_directory(file_status __s) noexcept { return __s.type() == file_type::directory; } +inline _LIBCPP_HIDE_FROM_ABI bool is_directory(const path& __p) { return is_directory(__status(__p)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_directory(const path& __p, error_code& __ec) noexcept { return is_directory(__status(__p, &__ec)); } +_LIBCPP_FUNC_VIS bool __fs_is_empty(const path& __p, error_code* __ec = nullptr); +inline _LIBCPP_HIDE_FROM_ABI bool is_empty(const path& __p) { return __fs_is_empty(__p); } +inline _LIBCPP_HIDE_FROM_ABI bool is_empty(const path& __p, error_code& __ec) { return __fs_is_empty(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(file_status __s) noexcept { return __s.type() == file_type::fifo; } +inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(const path& __p) { return is_fifo(__status(__p)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(const path& __p, error_code& __ec) noexcept { return is_fifo(__status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_regular_file(file_status __s) noexcept { return __s.type() == file_type::regular; } +inline _LIBCPP_HIDE_FROM_ABI bool is_regular_file(const path& __p) { return is_regular_file(__status(__p)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_regular_file(const path& __p, error_code& __ec) noexcept { return is_regular_file(__status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_symlink(file_status __s) noexcept { return __s.type() == file_type::symlink; } +inline _LIBCPP_HIDE_FROM_ABI bool is_symlink(const path& __p) { return is_symlink(__symlink_status(__p)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_symlink(const path& __p, error_code& __ec) noexcept { return is_symlink(__symlink_status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_other(file_status __s) noexcept { return exists(__s) && !is_regular_file(__s) && !is_directory(__s) && !is_symlink(__s); } +inline _LIBCPP_HIDE_FROM_ABI bool is_other(const path& __p) { return is_other(__status(__p)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_other(const path& __p, error_code& __ec) noexcept { return is_other(__status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_socket(file_status __s) noexcept { return __s.type() == file_type::socket; } +inline _LIBCPP_HIDE_FROM_ABI bool is_socket(const path& __p) { return is_socket(__status(__p)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_socket(const path& __p, error_code& __ec) noexcept { return is_socket(__status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(const path& __p) { return __last_write_time(__p); } +inline _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(const path& __p, error_code& __ec) noexcept { return __last_write_time(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void last_write_time(const path& __p, file_time_type __t) { __last_write_time(__p, __t); } +inline _LIBCPP_HIDE_FROM_ABI void last_write_time(const path& __p, file_time_type __t, error_code& __ec) noexcept { __last_write_time(__p, __t, &__ec); } +_LIBCPP_FUNC_VIS void __permissions(const path&, perms, perm_options, error_code* = nullptr); +inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, perm_options __opts = perm_options::replace) { __permissions(__p, __prms, __opts); } +inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, error_code& __ec) noexcept { __permissions(__p, __prms, perm_options::replace, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, perm_options __opts, error_code& __ec) { __permissions(__p, __prms, __opts, &__ec); } + +inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, const path& __base, error_code& __ec) { + path __tmp = __weakly_canonical(__p, &__ec); + if (__ec) + return {}; + path __tmp_base = __weakly_canonical(__base, &__ec); + if (__ec) + return {}; + return __tmp.lexically_proximate(__tmp_base); +} + +inline _LIBCPP_HIDE_FROM_ABI path proximate(const path& __p, error_code& __ec) { return proximate(__p, current_path(), __ec); } +inline _LIBCPP_HIDE_FROM_ABI path proximate(const path& __p, const path& __base = current_path()) { return __weakly_canonical(__p).lexically_proximate(__weakly_canonical(__base)); } +inline _LIBCPP_HIDE_FROM_ABI path read_symlink(const path& __p) { return __read_symlink(__p); } +inline _LIBCPP_HIDE_FROM_ABI path read_symlink(const path& __p, error_code& __ec) { return __read_symlink(__p, &__ec); } + +inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, const path& __base, error_code& __ec) { + path __tmp = __weakly_canonical(__p, &__ec); + if (__ec) + return path(); + path __tmpbase = __weakly_canonical(__base, &__ec); + if (__ec) + return path(); + return __tmp.lexically_relative(__tmpbase); +} + +inline _LIBCPP_HIDE_FROM_ABI path relative(const path& __p, error_code& __ec) { return relative(__p, current_path(), __ec); } +inline _LIBCPP_HIDE_FROM_ABI path relative(const path& __p, const path& __base = current_path()) { return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base)); } +inline _LIBCPP_HIDE_FROM_ABI uintmax_t remove_all(const path& __p) { return __remove_all(__p); } +inline _LIBCPP_HIDE_FROM_ABI uintmax_t remove_all(const path& __p, error_code& __ec) { return __remove_all(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool remove(const path& __p) { return __remove(__p); } +inline _LIBCPP_HIDE_FROM_ABI bool remove(const path& __p, error_code& __ec) noexcept { return __remove(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void rename(const path& __from, const path& __to) { return __rename(__from, __to); } +inline _LIBCPP_HIDE_FROM_ABI void rename(const path& __from, const path& __to, error_code& __ec) noexcept { return __rename(__from, __to, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void resize_file(const path& __p, uintmax_t __ns) { return __resize_file(__p, __ns); } +inline _LIBCPP_HIDE_FROM_ABI void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept { return __resize_file(__p, __ns, &__ec); } +_LIBCPP_FUNC_VIS space_info __space(const path&, error_code* __ec = nullptr); +inline _LIBCPP_HIDE_FROM_ABI space_info space(const path& __p) { return __space(__p); } +inline _LIBCPP_HIDE_FROM_ABI space_info space(const path& __p, error_code& __ec) noexcept { return __space(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI file_status status(const path& __p) { return __status(__p); } +inline _LIBCPP_HIDE_FROM_ABI file_status status(const path& __p, error_code& __ec) noexcept { return __status(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI file_status symlink_status(const path& __p) { return __symlink_status(__p); } +inline _LIBCPP_HIDE_FROM_ABI file_status symlink_status(const path& __p, error_code& __ec) noexcept { return __symlink_status(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI path temp_directory_path() { return __temp_directory_path(); } +inline _LIBCPP_HIDE_FROM_ABI path temp_directory_path(error_code& __ec) { return __temp_directory_path(&__ec); } +inline _LIBCPP_HIDE_FROM_ABI path weakly_canonical(path const& __p) { return __weakly_canonical(__p); } +inline _LIBCPP_HIDE_FROM_ABI path weakly_canonical(path const& __p, error_code& __ec) { return __weakly_canonical(__p, &__ec); } + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_OPERATIONS_H diff --git a/app/src/main/cpp/libcxx/include/__filesystem/path.h b/app/src/main/cpp/libcxx/include/__filesystem/path.h new file mode 100644 index 0000000..4e6912f --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__filesystem/path.h @@ -0,0 +1,1091 @@ +// -*- 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 _LIBCPP___FILESYSTEM_PATH_H +#define _LIBCPP___FILESYSTEM_PATH_H + +#include <__algorithm/replace.h> +#include <__algorithm/replace_copy.h> +#include <__availability> +#include <__config> +#include <__iterator/back_insert_iterator.h> +#include <__iterator/iterator_traits.h> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) +# include // for quoted +# include +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +template +struct __can_convert_char { + static const bool value = false; +}; +template +struct __can_convert_char : public __can_convert_char<_Tp> {}; +template <> +struct __can_convert_char { + static const bool value = true; + using __char_type = char; +}; +template <> +struct __can_convert_char { + static const bool value = true; + using __char_type = wchar_t; +}; +#ifndef _LIBCPP_HAS_NO_CHAR8_T +template <> +struct __can_convert_char { + static const bool value = true; + using __char_type = char8_t; +}; +#endif +template <> +struct __can_convert_char { + static const bool value = true; + using __char_type = char16_t; +}; +template <> +struct __can_convert_char { + static const bool value = true; + using __char_type = char32_t; +}; + +template +_LIBCPP_HIDE_FROM_ABI +typename enable_if<__can_convert_char<_ECharT>::value, bool>::type +__is_separator(_ECharT __e) { +#if defined(_LIBCPP_WIN32API) + return __e == _ECharT('/') || __e == _ECharT('\\'); +#else + return __e == _ECharT('/'); +#endif +} + +#ifndef _LIBCPP_HAS_NO_CHAR8_T +typedef u8string __u8_string; +#else +typedef string __u8_string; +#endif + +struct _NullSentinel {}; + +template +using _Void = void; + +template +struct __is_pathable_string : public false_type {}; + +template +struct __is_pathable_string< + basic_string<_ECharT, _Traits, _Alloc>, + _Void::__char_type> > + : public __can_convert_char<_ECharT> { + using _Str = basic_string<_ECharT, _Traits, _Alloc>; + using _Base = __can_convert_char<_ECharT>; + + _LIBCPP_HIDE_FROM_ABI + static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } + + _LIBCPP_HIDE_FROM_ABI + static _ECharT const* __range_end(_Str const& __s) { + return __s.data() + __s.length(); + } + + _LIBCPP_HIDE_FROM_ABI + static _ECharT __first_or_null(_Str const& __s) { + return __s.empty() ? _ECharT{} : __s[0]; + } +}; + +template +struct __is_pathable_string< + basic_string_view<_ECharT, _Traits>, + _Void::__char_type> > + : public __can_convert_char<_ECharT> { + using _Str = basic_string_view<_ECharT, _Traits>; + using _Base = __can_convert_char<_ECharT>; + + _LIBCPP_HIDE_FROM_ABI + static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } + + _LIBCPP_HIDE_FROM_ABI + static _ECharT const* __range_end(_Str const& __s) { + return __s.data() + __s.length(); + } + + _LIBCPP_HIDE_FROM_ABI + static _ECharT __first_or_null(_Str const& __s) { + return __s.empty() ? _ECharT{} : __s[0]; + } +}; + +template ::type, + class _UnqualPtrType = + __remove_const_t<__remove_pointer_t<_DS> >, + bool _IsCharPtr = is_pointer<_DS>::value&& + __can_convert_char<_UnqualPtrType>::value> +struct __is_pathable_char_array : false_type {}; + +template +struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true> + : __can_convert_char<__remove_const_t<_ECharT> > { + using _Base = __can_convert_char<__remove_const_t<_ECharT> >; + + _LIBCPP_HIDE_FROM_ABI + static _ECharT const* __range_begin(const _ECharT* __b) { return __b; } + + _LIBCPP_HIDE_FROM_ABI + static _ECharT const* __range_end(const _ECharT* __b) { + using _Iter = const _ECharT*; + const _ECharT __sentinel = _ECharT{}; + _Iter __e = __b; + for (; *__e != __sentinel; ++__e) + ; + return __e; + } + + _LIBCPP_HIDE_FROM_ABI + static _ECharT __first_or_null(const _ECharT* __b) { return *__b; } +}; + +template ::value, + class = void> +struct __is_pathable_iter : false_type {}; + +template +struct __is_pathable_iter< + _Iter, true, + _Void::value_type>::__char_type> > + : __can_convert_char::value_type> { + using _ECharT = typename iterator_traits<_Iter>::value_type; + using _Base = __can_convert_char<_ECharT>; + + _LIBCPP_HIDE_FROM_ABI + static _Iter __range_begin(_Iter __b) { return __b; } + + _LIBCPP_HIDE_FROM_ABI + static _NullSentinel __range_end(_Iter) { return _NullSentinel{}; } + + _LIBCPP_HIDE_FROM_ABI + static _ECharT __first_or_null(_Iter __b) { return *__b; } +}; + +template ::value, + bool _IsCharIterT = __is_pathable_char_array<_Tp>::value, + bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value> +struct __is_pathable : false_type { + static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false"); +}; + +template +struct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {}; + +template +struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> { +}; + +template +struct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {}; + +#if defined(_LIBCPP_WIN32API) +typedef wstring __path_string; +typedef wchar_t __path_value; +#else +typedef string __path_string; +typedef char __path_value; +#endif + +#if defined(_LIBCPP_WIN32API) +_LIBCPP_FUNC_VIS +size_t __wide_to_char(const wstring&, char*, size_t); +_LIBCPP_FUNC_VIS +size_t __char_to_wide(const string&, wchar_t*, size_t); +#endif + +template +struct _PathCVT; + +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) +template +struct _PathCVT { + static_assert(__can_convert_char<_ECharT>::value, + "Char type not convertible"); + + typedef __narrow_to_utf8 _Narrower; +#if defined(_LIBCPP_WIN32API) + typedef __widen_from_utf8 _Widener; +#endif + + _LIBCPP_HIDE_FROM_ABI + static void __append_range(__path_string& __dest, _ECharT const* __b, + _ECharT const* __e) { +#if defined(_LIBCPP_WIN32API) + string __utf8; + _Narrower()(back_inserter(__utf8), __b, __e); + _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); +#else + _Narrower()(back_inserter(__dest), __b, __e); +#endif + } + + template + _LIBCPP_HIDE_FROM_ABI + static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) { + static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); + if (__b == __e) + return; + basic_string<_ECharT> __tmp(__b, __e); +#if defined(_LIBCPP_WIN32API) + string __utf8; + _Narrower()(back_inserter(__utf8), __tmp.data(), + __tmp.data() + __tmp.length()); + _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); +#else + _Narrower()(back_inserter(__dest), __tmp.data(), + __tmp.data() + __tmp.length()); +#endif + } + + template + _LIBCPP_HIDE_FROM_ABI + static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { + static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); + const _ECharT __sentinel = _ECharT{}; + if (*__b == __sentinel) + return; + basic_string<_ECharT> __tmp; + for (; *__b != __sentinel; ++__b) + __tmp.push_back(*__b); +#if defined(_LIBCPP_WIN32API) + string __utf8; + _Narrower()(back_inserter(__utf8), __tmp.data(), + __tmp.data() + __tmp.length()); + _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); +#else + _Narrower()(back_inserter(__dest), __tmp.data(), + __tmp.data() + __tmp.length()); +#endif + } + + template + _LIBCPP_HIDE_FROM_ABI + static void __append_source(__path_string& __dest, _Source const& __s) { + using _Traits = __is_pathable<_Source>; + __append_range(__dest, _Traits::__range_begin(__s), + _Traits::__range_end(__s)); + } +}; +#endif // !_LIBCPP_HAS_NO_LOCALIZATION + +template <> +struct _PathCVT<__path_value> { + + template + _LIBCPP_HIDE_FROM_ABI + static typename enable_if<__is_exactly_cpp17_input_iterator<_Iter>::value>::type + __append_range(__path_string& __dest, _Iter __b, _Iter __e) { + for (; __b != __e; ++__b) + __dest.push_back(*__b); + } + + template + _LIBCPP_HIDE_FROM_ABI + static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type + __append_range(__path_string& __dest, _Iter __b, _Iter __e) { + __dest.append(__b, __e); + } + + template + _LIBCPP_HIDE_FROM_ABI + static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { + const char __sentinel = char{}; + for (; *__b != __sentinel; ++__b) + __dest.push_back(*__b); + } + + template + _LIBCPP_HIDE_FROM_ABI + static void __append_source(__path_string& __dest, _Source const& __s) { + using _Traits = __is_pathable<_Source>; + __append_range(__dest, _Traits::__range_begin(__s), + _Traits::__range_end(__s)); + } +}; + +#if defined(_LIBCPP_WIN32API) +template <> +struct _PathCVT { + + _LIBCPP_HIDE_FROM_ABI + static void + __append_string(__path_string& __dest, const basic_string &__str) { + size_t __size = __char_to_wide(__str, nullptr, 0); + size_t __pos = __dest.size(); + __dest.resize(__pos + __size); + __char_to_wide(__str, const_cast<__path_value*>(__dest.data()) + __pos, __size); + } + + template + _LIBCPP_HIDE_FROM_ABI + static typename enable_if<__is_exactly_cpp17_input_iterator<_Iter>::value>::type + __append_range(__path_string& __dest, _Iter __b, _Iter __e) { + basic_string __tmp(__b, __e); + __append_string(__dest, __tmp); + } + + template + _LIBCPP_HIDE_FROM_ABI + static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type + __append_range(__path_string& __dest, _Iter __b, _Iter __e) { + basic_string __tmp(__b, __e); + __append_string(__dest, __tmp); + } + + template + _LIBCPP_HIDE_FROM_ABI + static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { + const char __sentinel = char{}; + basic_string __tmp; + for (; *__b != __sentinel; ++__b) + __tmp.push_back(*__b); + __append_string(__dest, __tmp); + } + + template + _LIBCPP_HIDE_FROM_ABI + static void __append_source(__path_string& __dest, _Source const& __s) { + using _Traits = __is_pathable<_Source>; + __append_range(__dest, _Traits::__range_begin(__s), + _Traits::__range_end(__s)); + } +}; + +template +struct _PathExport { + typedef __narrow_to_utf8 _Narrower; + typedef __widen_from_utf8 _Widener; + + template + _LIBCPP_HIDE_FROM_ABI + static void __append(_Str& __dest, const __path_string& __src) { + string __utf8; + _Narrower()(back_inserter(__utf8), __src.data(), __src.data() + __src.size()); + _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); + } +}; + +template <> +struct _PathExport { + template + _LIBCPP_HIDE_FROM_ABI + static void __append(_Str& __dest, const __path_string& __src) { + size_t __size = __wide_to_char(__src, nullptr, 0); + size_t __pos = __dest.size(); + __dest.resize(__size); + __wide_to_char(__src, const_cast(__dest.data()) + __pos, __size); + } +}; + +template <> +struct _PathExport { + template + _LIBCPP_HIDE_FROM_ABI + static void __append(_Str& __dest, const __path_string& __src) { + __dest.append(__src.begin(), __src.end()); + } +}; + +template <> +struct _PathExport { + template + _LIBCPP_HIDE_FROM_ABI + static void __append(_Str& __dest, const __path_string& __src) { + __dest.append(__src.begin(), __src.end()); + } +}; + +#ifndef _LIBCPP_HAS_NO_CHAR8_T +template <> +struct _PathExport { + typedef __narrow_to_utf8 _Narrower; + + template + _LIBCPP_HIDE_FROM_ABI + static void __append(_Str& __dest, const __path_string& __src) { + _Narrower()(back_inserter(__dest), __src.data(), __src.data() + __src.size()); + } +}; +#endif /* !_LIBCPP_HAS_NO_CHAR8_T */ +#endif /* _LIBCPP_WIN32API */ + +class _LIBCPP_TYPE_VIS path { + template + using _EnableIfPathable = + typename enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type; + + template + using _SourceChar = typename __is_pathable<_Tp>::__char_type; + + template + using _SourceCVT = _PathCVT<_SourceChar<_Tp> >; + +public: +#if defined(_LIBCPP_WIN32API) + typedef wchar_t value_type; + static constexpr value_type preferred_separator = L'\\'; +#else + typedef char value_type; + static constexpr value_type preferred_separator = '/'; +#endif + typedef basic_string string_type; + typedef basic_string_view __string_view; + + enum _LIBCPP_ENUM_VIS format : unsigned char { + auto_format, + native_format, + generic_format + }; + + // constructors and destructor + _LIBCPP_HIDE_FROM_ABI path() noexcept {} + _LIBCPP_HIDE_FROM_ABI path(const path& __p) : __pn_(__p.__pn_) {} + _LIBCPP_HIDE_FROM_ABI path(path&& __p) noexcept + : __pn_(_VSTD::move(__p.__pn_)) {} + + _LIBCPP_HIDE_FROM_ABI + path(string_type&& __s, format = format::auto_format) noexcept + : __pn_(_VSTD::move(__s)) {} + + template > + _LIBCPP_HIDE_FROM_ABI + path(const _Source& __src, format = format::auto_format) { + _SourceCVT<_Source>::__append_source(__pn_, __src); + } + + template + _LIBCPP_HIDE_FROM_ABI + path(_InputIt __first, _InputIt __last, format = format::auto_format) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); + } + +/* +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + // TODO Implement locale conversions. + template > + path(const _Source& __src, const locale& __loc, format = format::auto_format); + template + path(_InputIt __first, _InputIt _last, const locale& __loc, + format = format::auto_format); +#endif +*/ + + _LIBCPP_HIDE_FROM_ABI + ~path() = default; + + // assignments + _LIBCPP_HIDE_FROM_ABI + path& operator=(const path& __p) { + __pn_ = __p.__pn_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + path& operator=(path&& __p) noexcept { + __pn_ = _VSTD::move(__p.__pn_); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + path& operator=(string_type&& __s) noexcept { + __pn_ = _VSTD::move(__s); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + path& assign(string_type&& __s) noexcept { + __pn_ = _VSTD::move(__s); + return *this; + } + + template + _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> + operator=(const _Source& __src) { + return this->assign(__src); + } + + template + _LIBCPP_HIDE_FROM_ABI + _EnableIfPathable<_Source> assign(const _Source& __src) { + __pn_.clear(); + _SourceCVT<_Source>::__append_source(__pn_, __src); + return *this; + } + + template + _LIBCPP_HIDE_FROM_ABI + path& assign(_InputIt __first, _InputIt __last) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + __pn_.clear(); + _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); + return *this; + } + +public: + // appends +#if defined(_LIBCPP_WIN32API) + _LIBCPP_HIDE_FROM_ABI + path& operator/=(const path& __p) { + auto __p_root_name = __p.__root_name(); + auto __p_root_name_size = __p_root_name.size(); + if (__p.is_absolute() || + (!__p_root_name.empty() && __p_root_name != __string_view(root_name().__pn_))) { + __pn_ = __p.__pn_; + return *this; + } + if (__p.has_root_directory()) { + path __root_name_str = root_name(); + __pn_ = __root_name_str.native(); + __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size); + return *this; + } + if (has_filename() || (!has_root_directory() && is_absolute())) + __pn_ += preferred_separator; + __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size); + return *this; + } + template + _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source> + operator/=(const _Source& __src) { + return operator/=(path(__src)); + } + + template + _LIBCPP_HIDE_FROM_ABI + _EnableIfPathable<_Source> append(const _Source& __src) { + return operator/=(path(__src)); + } + + template + _LIBCPP_HIDE_FROM_ABI + path& append(_InputIt __first, _InputIt __last) { + return operator/=(path(__first, __last)); + } +#else + _LIBCPP_HIDE_FROM_ABI + path& operator/=(const path& __p) { + if (__p.is_absolute()) { + __pn_ = __p.__pn_; + return *this; + } + if (has_filename()) + __pn_ += preferred_separator; + __pn_ += __p.native(); + return *this; + } + + // FIXME: Use _LIBCPP_DIAGNOSE_WARNING to produce a diagnostic when __src + // is known at compile time to be "/' since the user almost certainly intended + // to append a separator instead of overwriting the path with "/" + template + _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> + operator/=(const _Source& __src) { + return this->append(__src); + } + + template + _LIBCPP_HIDE_FROM_ABI + _EnableIfPathable<_Source> append(const _Source& __src) { + using _Traits = __is_pathable<_Source>; + using _CVT = _PathCVT<_SourceChar<_Source> >; + bool __source_is_absolute = _VSTD_FS::__is_separator(_Traits::__first_or_null(__src)); + if (__source_is_absolute) + __pn_.clear(); + else if (has_filename()) + __pn_ += preferred_separator; + _CVT::__append_source(__pn_, __src); + return *this; + } + + template + _LIBCPP_HIDE_FROM_ABI + path& append(_InputIt __first, _InputIt __last) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + static_assert(__can_convert_char<_ItVal>::value, "Must convertible"); + using _CVT = _PathCVT<_ItVal>; + if (__first != __last && _VSTD_FS::__is_separator(*__first)) + __pn_.clear(); + else if (has_filename()) + __pn_ += preferred_separator; + _CVT::__append_range(__pn_, __first, __last); + return *this; + } +#endif + + // concatenation + _LIBCPP_HIDE_FROM_ABI + path& operator+=(const path& __x) { + __pn_ += __x.__pn_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + path& operator+=(const string_type& __x) { + __pn_ += __x; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + path& operator+=(__string_view __x) { + __pn_ += __x; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + path& operator+=(const value_type* __x) { + __pn_ += __x; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + path& operator+=(value_type __x) { + __pn_ += __x; + return *this; + } + + template + _LIBCPP_HIDE_FROM_ABI + typename enable_if<__can_convert_char<_ECharT>::value, path&>::type + operator+=(_ECharT __x) { + _PathCVT<_ECharT>::__append_source(__pn_, + basic_string_view<_ECharT>(&__x, 1)); + return *this; + } + + template + _LIBCPP_HIDE_FROM_ABI + _EnableIfPathable<_Source> operator+=(const _Source& __x) { + return this->concat(__x); + } + + template + _LIBCPP_HIDE_FROM_ABI + _EnableIfPathable<_Source> concat(const _Source& __x) { + _SourceCVT<_Source>::__append_source(__pn_, __x); + return *this; + } + + template + _LIBCPP_HIDE_FROM_ABI + path& concat(_InputIt __first, _InputIt __last) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); + return *this; + } + + // modifiers + _LIBCPP_HIDE_FROM_ABI + void clear() noexcept { __pn_.clear(); } + + _LIBCPP_HIDE_FROM_ABI + path& make_preferred() { +#if defined(_LIBCPP_WIN32API) + _VSTD::replace(__pn_.begin(), __pn_.end(), L'/', L'\\'); +#endif + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + path& remove_filename() { + auto __fname = __filename(); + if (!__fname.empty()) + __pn_.erase(__fname.data() - __pn_.data()); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + path& replace_filename(const path& __replacement) { + remove_filename(); + return (*this /= __replacement); + } + + path& replace_extension(const path& __replacement = path()); + + friend _LIBCPP_HIDE_FROM_ABI bool operator==(const path& __lhs, const path& __rhs) noexcept { + return __lhs.__compare(__rhs.__pn_) == 0; + } +# if _LIBCPP_STD_VER <= 17 + friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const path& __lhs, const path& __rhs) noexcept { + return __lhs.__compare(__rhs.__pn_) != 0; + } + friend _LIBCPP_HIDE_FROM_ABI bool operator<(const path& __lhs, const path& __rhs) noexcept { + return __lhs.__compare(__rhs.__pn_) < 0; + } + friend _LIBCPP_HIDE_FROM_ABI bool operator<=(const path& __lhs, const path& __rhs) noexcept { + return __lhs.__compare(__rhs.__pn_) <= 0; + } + friend _LIBCPP_HIDE_FROM_ABI bool operator>(const path& __lhs, const path& __rhs) noexcept { + return __lhs.__compare(__rhs.__pn_) > 0; + } + friend _LIBCPP_HIDE_FROM_ABI bool operator>=(const path& __lhs, const path& __rhs) noexcept { + return __lhs.__compare(__rhs.__pn_) >= 0; + } +# else // _LIBCPP_STD_VER <= 17 + friend _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(const path& __lhs, const path& __rhs) noexcept { + return __lhs.__compare(__rhs.__pn_) <=> 0; + } +# endif // _LIBCPP_STD_VER <= 17 + + friend _LIBCPP_HIDE_FROM_ABI path operator/(const path& __lhs, const path& __rhs) { + path __result(__lhs); + __result /= __rhs; + return __result; + } + + _LIBCPP_HIDE_FROM_ABI + void swap(path& __rhs) noexcept { __pn_.swap(__rhs.__pn_); } + + // private helper to allow reserving memory in the path + _LIBCPP_HIDE_FROM_ABI + void __reserve(size_t __s) { __pn_.reserve(__s); } + + // native format observers + _LIBCPP_HIDE_FROM_ABI + const string_type& native() const noexcept { return __pn_; } + + _LIBCPP_HIDE_FROM_ABI + const value_type* c_str() const noexcept { return __pn_.c_str(); } + + _LIBCPP_HIDE_FROM_ABI operator string_type() const { return __pn_; } + +#if defined(_LIBCPP_WIN32API) + _LIBCPP_HIDE_FROM_ABI _VSTD::wstring wstring() const { return __pn_; } + + _LIBCPP_HIDE_FROM_ABI + _VSTD::wstring generic_wstring() const { + _VSTD::wstring __s; + __s.resize(__pn_.size()); + _VSTD::replace_copy(__pn_.begin(), __pn_.end(), __s.begin(), '\\', '/'); + return __s; + } + +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + template , + class _Allocator = allocator<_ECharT> > + _LIBCPP_HIDE_FROM_ABI + basic_string<_ECharT, _Traits, _Allocator> + string(const _Allocator& __a = _Allocator()) const { + using _Str = basic_string<_ECharT, _Traits, _Allocator>; + _Str __s(__a); + __s.reserve(__pn_.size()); + _PathExport<_ECharT>::__append(__s, __pn_); + return __s; + } + + _LIBCPP_HIDE_FROM_ABI _VSTD::string string() const { + return string(); + } + _LIBCPP_HIDE_FROM_ABI __u8_string u8string() const { + using _CVT = __narrow_to_utf8; + __u8_string __s; + __s.reserve(__pn_.size()); + _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size()); + return __s; + } + + _LIBCPP_HIDE_FROM_ABI _VSTD::u16string u16string() const { + return string(); + } + _LIBCPP_HIDE_FROM_ABI _VSTD::u32string u32string() const { + return string(); + } + + // generic format observers + template , + class _Allocator = allocator<_ECharT> > + _LIBCPP_HIDE_FROM_ABI + basic_string<_ECharT, _Traits, _Allocator> + generic_string(const _Allocator& __a = _Allocator()) const { + using _Str = basic_string<_ECharT, _Traits, _Allocator>; + _Str __s = string<_ECharT, _Traits, _Allocator>(__a); + // Note: This (and generic_u8string below) is slightly suboptimal as + // it iterates twice over the string; once to convert it to the right + // character type, and once to replace path delimiters. + _VSTD::replace(__s.begin(), __s.end(), + static_cast<_ECharT>('\\'), static_cast<_ECharT>('/')); + return __s; + } + + _LIBCPP_HIDE_FROM_ABI _VSTD::string generic_string() const { return generic_string(); } + _LIBCPP_HIDE_FROM_ABI _VSTD::u16string generic_u16string() const { return generic_string(); } + _LIBCPP_HIDE_FROM_ABI _VSTD::u32string generic_u32string() const { return generic_string(); } + _LIBCPP_HIDE_FROM_ABI + __u8_string generic_u8string() const { + __u8_string __s = u8string(); + _VSTD::replace(__s.begin(), __s.end(), '\\', '/'); + return __s; + } +#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ +#else /* _LIBCPP_WIN32API */ + + _LIBCPP_HIDE_FROM_ABI _VSTD::string string() const { return __pn_; } +#ifndef _LIBCPP_HAS_NO_CHAR8_T + _LIBCPP_HIDE_FROM_ABI _VSTD::u8string u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); } +#else + _LIBCPP_HIDE_FROM_ABI _VSTD::string u8string() const { return __pn_; } +#endif + +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + template , + class _Allocator = allocator<_ECharT> > + _LIBCPP_HIDE_FROM_ABI + basic_string<_ECharT, _Traits, _Allocator> + string(const _Allocator& __a = _Allocator()) const { + using _CVT = __widen_from_utf8; + using _Str = basic_string<_ECharT, _Traits, _Allocator>; + _Str __s(__a); + __s.reserve(__pn_.size()); + _CVT()(std::back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size()); + return __s; + } + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS + _LIBCPP_HIDE_FROM_ABI _VSTD::wstring wstring() const { + return string(); + } +#endif + _LIBCPP_HIDE_FROM_ABI _VSTD::u16string u16string() const { + return string(); + } + _LIBCPP_HIDE_FROM_ABI _VSTD::u32string u32string() const { + return string(); + } +#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ + + // generic format observers + _LIBCPP_HIDE_FROM_ABI _VSTD::string generic_string() const { return __pn_; } +#ifndef _LIBCPP_HAS_NO_CHAR8_T + _LIBCPP_HIDE_FROM_ABI _VSTD::u8string generic_u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); } +#else + _LIBCPP_HIDE_FROM_ABI _VSTD::string generic_u8string() const { return __pn_; } +#endif + +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + template , + class _Allocator = allocator<_ECharT> > + _LIBCPP_HIDE_FROM_ABI + basic_string<_ECharT, _Traits, _Allocator> + generic_string(const _Allocator& __a = _Allocator()) const { + return string<_ECharT, _Traits, _Allocator>(__a); + } + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS + _LIBCPP_HIDE_FROM_ABI _VSTD::wstring generic_wstring() const { return string(); } +#endif + _LIBCPP_HIDE_FROM_ABI _VSTD::u16string generic_u16string() const { return string(); } + _LIBCPP_HIDE_FROM_ABI _VSTD::u32string generic_u32string() const { return string(); } +#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ +#endif /* !_LIBCPP_WIN32API */ + +private: + int __compare(__string_view) const; + __string_view __root_name() const; + __string_view __root_directory() const; + __string_view __root_path_raw() const; + __string_view __relative_path() const; + __string_view __parent_path() const; + __string_view __filename() const; + __string_view __stem() const; + __string_view __extension() const; + +public: + // compare + _LIBCPP_HIDE_FROM_ABI int compare(const path& __p) const noexcept { + return __compare(__p.__pn_); + } + _LIBCPP_HIDE_FROM_ABI int compare(const string_type& __s) const { + return __compare(__s); + } + _LIBCPP_HIDE_FROM_ABI int compare(__string_view __s) const { + return __compare(__s); + } + _LIBCPP_HIDE_FROM_ABI int compare(const value_type* __s) const { + return __compare(__s); + } + + // decomposition + _LIBCPP_HIDE_FROM_ABI path root_name() const { + return string_type(__root_name()); + } + _LIBCPP_HIDE_FROM_ABI path root_directory() const { + return string_type(__root_directory()); + } + _LIBCPP_HIDE_FROM_ABI path root_path() const { +#if defined(_LIBCPP_WIN32API) + return string_type(__root_path_raw()); +#else + return root_name().append(string_type(__root_directory())); +#endif + } + _LIBCPP_HIDE_FROM_ABI path relative_path() const { + return string_type(__relative_path()); + } + _LIBCPP_HIDE_FROM_ABI path parent_path() const { + return string_type(__parent_path()); + } + _LIBCPP_HIDE_FROM_ABI path filename() const { + return string_type(__filename()); + } + _LIBCPP_HIDE_FROM_ABI path stem() const { return string_type(__stem()); } + _LIBCPP_HIDE_FROM_ABI path extension() const { + return string_type(__extension()); + } + + // query + _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool + empty() const noexcept { + return __pn_.empty(); + } + + _LIBCPP_HIDE_FROM_ABI bool has_root_name() const { + return !__root_name().empty(); + } + _LIBCPP_HIDE_FROM_ABI bool has_root_directory() const { + return !__root_directory().empty(); + } + _LIBCPP_HIDE_FROM_ABI bool has_root_path() const { + return !__root_path_raw().empty(); + } + _LIBCPP_HIDE_FROM_ABI bool has_relative_path() const { + return !__relative_path().empty(); + } + _LIBCPP_HIDE_FROM_ABI bool has_parent_path() const { + return !__parent_path().empty(); + } + _LIBCPP_HIDE_FROM_ABI bool has_filename() const { + return !__filename().empty(); + } + _LIBCPP_HIDE_FROM_ABI bool has_stem() const { return !__stem().empty(); } + _LIBCPP_HIDE_FROM_ABI bool has_extension() const { + return !__extension().empty(); + } + + _LIBCPP_HIDE_FROM_ABI bool is_absolute() const { +#if defined(_LIBCPP_WIN32API) + __string_view __root_name_str = __root_name(); + __string_view __root_dir = __root_directory(); + if (__root_name_str.size() == 2 && __root_name_str[1] == ':') { + // A drive letter with no root directory is relative, e.g. x:example. + return !__root_dir.empty(); + } + // If no root name, it's relative, e.g. \example is relative to the current drive + if (__root_name_str.empty()) + return false; + if (__root_name_str.size() < 3) + return false; + // A server root name, like \\server, is always absolute + if (__root_name_str[0] != '/' && __root_name_str[0] != '\\') + return false; + if (__root_name_str[1] != '/' && __root_name_str[1] != '\\') + return false; + // Seems to be a server root name + return true; +#else + return has_root_directory(); +#endif + } + _LIBCPP_HIDE_FROM_ABI bool is_relative() const { return !is_absolute(); } + + // relative paths + path lexically_normal() const; + path lexically_relative(const path& __base) const; + + _LIBCPP_HIDE_FROM_ABI path lexically_proximate(const path& __base) const { + path __result = this->lexically_relative(__base); + if (__result.native().empty()) + return *this; + return __result; + } + + // iterators + class _LIBCPP_TYPE_VIS iterator; + typedef iterator const_iterator; + + iterator begin() const; + iterator end() const; + +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + template + _LIBCPP_HIDE_FROM_ABI friend + typename enable_if::value && + is_same<_Traits, char_traits >::value, + basic_ostream<_CharT, _Traits>&>::type + operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { + __os << _VSTD::__quoted(__p.native()); + return __os; + } + + template + _LIBCPP_HIDE_FROM_ABI friend + typename enable_if::value || + !is_same<_Traits, char_traits >::value, + basic_ostream<_CharT, _Traits>&>::type + operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { + __os << _VSTD::__quoted(__p.string<_CharT, _Traits>()); + return __os; + } + + template + _LIBCPP_HIDE_FROM_ABI friend basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) { + basic_string<_CharT, _Traits> __tmp; + __is >> _VSTD::__quoted(__tmp); + __p = __tmp; + return __is; + } +#endif // !_LIBCPP_HAS_NO_LOCALIZATION + +private: + inline _LIBCPP_HIDE_FROM_ABI path& + __assign_view(__string_view const& __s) noexcept { + __pn_ = string_type(__s); + return *this; + } + string_type __pn_; +}; + +inline _LIBCPP_HIDE_FROM_ABI void swap(path& __lhs, path& __rhs) noexcept { + __lhs.swap(__rhs); +} + +_LIBCPP_FUNC_VIS +size_t hash_value(const path& __p) noexcept; + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_PATH_H diff --git a/app/src/main/cpp/libcxx/include/__filesystem/path_iterator.h b/app/src/main/cpp/libcxx/include/__filesystem/path_iterator.h new file mode 100644 index 0000000..6f2baf8 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__filesystem/path_iterator.h @@ -0,0 +1,134 @@ +// -*- 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 _LIBCPP___FILESYSTEM_PATH_ITERATOR_H +#define _LIBCPP___FILESYSTEM_PATH_ITERATOR_H + +#include <__assert> +#include <__availability> +#include <__config> +#include <__filesystem/path.h> +#include <__iterator/iterator_traits.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +class _LIBCPP_TYPE_VIS path::iterator { +public: + enum _ParserState : unsigned char { + _Singular, + _BeforeBegin, + _InRootName, + _InRootDir, + _InFilenames, + _InTrailingSep, + _AtEnd + }; + +public: + typedef input_iterator_tag iterator_category; + typedef bidirectional_iterator_tag iterator_concept; + + typedef path value_type; + typedef ptrdiff_t difference_type; + typedef const path* pointer; + typedef path reference; + +public: + _LIBCPP_INLINE_VISIBILITY + iterator() + : __stashed_elem_(), __path_ptr_(nullptr), __entry_(), + __state_(_Singular) {} + + iterator(const iterator&) = default; + ~iterator() = default; + + iterator& operator=(const iterator&) = default; + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const { return __stashed_elem_; } + + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const { return &__stashed_elem_; } + + _LIBCPP_INLINE_VISIBILITY + iterator& operator++() { + _LIBCPP_ASSERT(__state_ != _Singular, + "attempting to increment a singular iterator"); + _LIBCPP_ASSERT(__state_ != _AtEnd, + "attempting to increment the end iterator"); + return __increment(); + } + + _LIBCPP_INLINE_VISIBILITY + iterator operator++(int) { + iterator __it(*this); + this->operator++(); + return __it; + } + + _LIBCPP_INLINE_VISIBILITY + iterator& operator--() { + _LIBCPP_ASSERT(__state_ != _Singular, + "attempting to decrement a singular iterator"); + _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(), + "attempting to decrement the begin iterator"); + return __decrement(); + } + + _LIBCPP_INLINE_VISIBILITY + iterator operator--(int) { + iterator __it(*this); + this->operator--(); + return __it; + } + +private: + friend class path; + + inline _LIBCPP_INLINE_VISIBILITY friend bool operator==(const iterator&, + const iterator&); + + iterator& __increment(); + iterator& __decrement(); + + path __stashed_elem_; + const path* __path_ptr_; + path::__string_view __entry_; + _ParserState __state_; +}; + +inline _LIBCPP_INLINE_VISIBILITY bool operator==(const path::iterator& __lhs, + const path::iterator& __rhs) { + return __lhs.__path_ptr_ == __rhs.__path_ptr_ && + __lhs.__entry_.data() == __rhs.__entry_.data(); +} + +inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path::iterator& __lhs, + const path::iterator& __rhs) { + return !(__lhs == __rhs); +} + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_PATH_ITERATOR_H diff --git a/app/src/main/cpp/libcxx/include/__filesystem/perm_options.h b/app/src/main/cpp/libcxx/include/__filesystem/perm_options.h new file mode 100644 index 0000000..4aba302 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__filesystem/perm_options.h @@ -0,0 +1,77 @@ +// -*- 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 _LIBCPP___FILESYSTEM_PERM_OPTIONS_H +#define _LIBCPP___FILESYSTEM_PERM_OPTIONS_H + +#include <__availability> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +enum class _LIBCPP_ENUM_VIS perm_options : unsigned char { + replace = 1, + add = 2, + remove = 4, + nofollow = 8 +}; + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perm_options operator&(perm_options __lhs, perm_options __rhs) { + return static_cast(static_cast(__lhs) & + static_cast(__rhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perm_options operator|(perm_options __lhs, perm_options __rhs) { + return static_cast(static_cast(__lhs) | + static_cast(__rhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perm_options operator^(perm_options __lhs, perm_options __rhs) { + return static_cast(static_cast(__lhs) ^ + static_cast(__rhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perm_options operator~(perm_options __lhs) { + return static_cast(~static_cast(__lhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline perm_options& operator&=(perm_options& __lhs, perm_options __rhs) { + return __lhs = __lhs & __rhs; +} + +_LIBCPP_INLINE_VISIBILITY +inline perm_options& operator|=(perm_options& __lhs, perm_options __rhs) { + return __lhs = __lhs | __rhs; +} + +_LIBCPP_INLINE_VISIBILITY +inline perm_options& operator^=(perm_options& __lhs, perm_options __rhs) { + return __lhs = __lhs ^ __rhs; +} + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_PERM_OPTIONS_H diff --git a/app/src/main/cpp/libcxx/include/__filesystem/perms.h b/app/src/main/cpp/libcxx/include/__filesystem/perms.h new file mode 100644 index 0000000..df45900 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__filesystem/perms.h @@ -0,0 +1,95 @@ +// -*- 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 _LIBCPP___FILESYSTEM_PERMS_H +#define _LIBCPP___FILESYSTEM_PERMS_H + +#include <__availability> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +// On Windows, these permission bits map to one single readonly flag per +// file, and the executable bit is always returned as set. When setting +// permissions, as long as the write bit is set for either owner, group or +// others, the readonly flag is cleared. +enum class _LIBCPP_ENUM_VIS perms : unsigned { + none = 0, + + owner_read = 0400, + owner_write = 0200, + owner_exec = 0100, + owner_all = 0700, + + group_read = 040, + group_write = 020, + group_exec = 010, + group_all = 070, + + others_read = 04, + others_write = 02, + others_exec = 01, + others_all = 07, + + all = 0777, + + set_uid = 04000, + set_gid = 02000, + sticky_bit = 01000, + mask = 07777, + unknown = 0xFFFF, +}; + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perms operator&(perms __lhs, perms __rhs) { + return static_cast(static_cast(__lhs) & + static_cast(__rhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perms operator|(perms __lhs, perms __rhs) { + return static_cast(static_cast(__lhs) | + static_cast(__rhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perms operator^(perms __lhs, perms __rhs) { + return static_cast(static_cast(__lhs) ^ + static_cast(__rhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perms operator~(perms __lhs) { + return static_cast(~static_cast(__lhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline perms& operator&=(perms& __lhs, perms __rhs) { return __lhs = __lhs & __rhs; } + +_LIBCPP_INLINE_VISIBILITY +inline perms& operator|=(perms& __lhs, perms __rhs) { return __lhs = __lhs | __rhs; } + +_LIBCPP_INLINE_VISIBILITY +inline perms& operator^=(perms& __lhs, perms __rhs) { return __lhs = __lhs ^ __rhs; } + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_PERMS_H diff --git a/app/src/main/cpp/libcxx/include/__filesystem/recursive_directory_iterator.h b/app/src/main/cpp/libcxx/include/__filesystem/recursive_directory_iterator.h new file mode 100644 index 0000000..b20d201 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__filesystem/recursive_directory_iterator.h @@ -0,0 +1,185 @@ +// -*- 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 _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H +#define _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H + +#include <__availability> +#include <__config> +#include <__filesystem/directory_entry.h> +#include <__filesystem/directory_options.h> +#include <__filesystem/path.h> +#include <__iterator/iterator_traits.h> +#include <__memory/shared_ptr.h> +#include <__ranges/enable_borrowed_range.h> +#include <__ranges/enable_view.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +class recursive_directory_iterator { +public: + using value_type = directory_entry; + using difference_type = ptrdiff_t; + using pointer = directory_entry const*; + using reference = directory_entry const&; + using iterator_category = input_iterator_tag; + +public: + // constructors and destructor + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator() noexcept : __rec_(false) {} + + _LIBCPP_INLINE_VISIBILITY + explicit recursive_directory_iterator( + const path& __p, directory_options __xoptions = directory_options::none) + : recursive_directory_iterator(__p, __xoptions, nullptr) {} + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator(const path& __p, directory_options __xoptions, + error_code& __ec) + : recursive_directory_iterator(__p, __xoptions, &__ec) {} + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator(const path& __p, error_code& __ec) + : recursive_directory_iterator(__p, directory_options::none, &__ec) {} + + recursive_directory_iterator(const recursive_directory_iterator&) = default; + recursive_directory_iterator(recursive_directory_iterator&&) = default; + + recursive_directory_iterator& + operator=(const recursive_directory_iterator&) = default; + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator& + operator=(recursive_directory_iterator&& __o) noexcept { + // non-default implementation provided to support self-move assign. + if (this != &__o) { + __imp_ = _VSTD::move(__o.__imp_); + __rec_ = __o.__rec_; + } + return *this; + } + + ~recursive_directory_iterator() = default; + + _LIBCPP_INLINE_VISIBILITY + const directory_entry& operator*() const { return __dereference(); } + + _LIBCPP_INLINE_VISIBILITY + const directory_entry* operator->() const { return &__dereference(); } + + recursive_directory_iterator& operator++() { return __increment(); } + + _LIBCPP_INLINE_VISIBILITY + __dir_element_proxy operator++(int) { + __dir_element_proxy __p(**this); + __increment(); + return __p; + } + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator& increment(error_code& __ec) { + return __increment(&__ec); + } + + _LIBCPP_FUNC_VIS directory_options options() const; + _LIBCPP_FUNC_VIS int depth() const; + + _LIBCPP_INLINE_VISIBILITY + void pop() { __pop(); } + + _LIBCPP_INLINE_VISIBILITY + void pop(error_code& __ec) { __pop(&__ec); } + + _LIBCPP_INLINE_VISIBILITY + bool recursion_pending() const { return __rec_; } + + _LIBCPP_INLINE_VISIBILITY + void disable_recursion_pending() { __rec_ = false; } + +private: + _LIBCPP_FUNC_VIS + recursive_directory_iterator(const path& __p, directory_options __opt, + error_code* __ec); + + _LIBCPP_FUNC_VIS + const directory_entry& __dereference() const; + + _LIBCPP_FUNC_VIS + bool __try_recursion(error_code* __ec); + + _LIBCPP_FUNC_VIS + void __advance(error_code* __ec = nullptr); + + _LIBCPP_FUNC_VIS + recursive_directory_iterator& __increment(error_code* __ec = nullptr); + + _LIBCPP_FUNC_VIS + void __pop(error_code* __ec = nullptr); + + inline _LIBCPP_INLINE_VISIBILITY friend bool + operator==(const recursive_directory_iterator&, + const recursive_directory_iterator&) noexcept; + + struct _LIBCPP_HIDDEN __shared_imp; + shared_ptr<__shared_imp> __imp_; + bool __rec_; +}; // class recursive_directory_iterator + +inline _LIBCPP_INLINE_VISIBILITY bool +operator==(const recursive_directory_iterator& __lhs, + const recursive_directory_iterator& __rhs) noexcept { + return __lhs.__imp_ == __rhs.__imp_; +} + +_LIBCPP_INLINE_VISIBILITY +inline bool operator!=(const recursive_directory_iterator& __lhs, + const recursive_directory_iterator& __rhs) noexcept { + return !(__lhs == __rhs); +} +// enable recursive_directory_iterator range-based for statements +inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator +begin(recursive_directory_iterator __iter) noexcept { + return __iter; +} + +inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator +end(recursive_directory_iterator) noexcept { + return recursive_directory_iterator(); +} + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#if _LIBCPP_STD_VER > 17 + +template <> +_LIBCPP_AVAILABILITY_FILESYSTEM +inline constexpr bool _VSTD::ranges::enable_borrowed_range<_VSTD_FS::recursive_directory_iterator> = true; + +template <> +_LIBCPP_AVAILABILITY_FILESYSTEM +inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::recursive_directory_iterator> = true; + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H diff --git a/app/src/main/cpp/libcxx/include/__filesystem/space_info.h b/app/src/main/cpp/libcxx/include/__filesystem/space_info.h new file mode 100644 index 0000000..d0747e3 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__filesystem/space_info.h @@ -0,0 +1,43 @@ +// -*- 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 _LIBCPP___FILESYSTEM_SPACE_INFO_H +#define _LIBCPP___FILESYSTEM_SPACE_INFO_H + +#include <__availability> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +struct _LIBCPP_TYPE_VIS space_info { + uintmax_t capacity; + uintmax_t free; + uintmax_t available; + +# if _LIBCPP_STD_VER > 17 + friend _LIBCPP_HIDE_FROM_ABI bool operator==(const space_info&, const space_info&) = default; +# endif +}; + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_SPACE_INFO_H diff --git a/app/src/main/cpp/libcxx/include/__filesystem/u8path.h b/app/src/main/cpp/libcxx/include/__filesystem/u8path.h new file mode 100644 index 0000000..d35faa1 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__filesystem/u8path.h @@ -0,0 +1,108 @@ +// -*- 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 _LIBCPP___FILESYSTEM_U8PATH_H +#define _LIBCPP___FILESYSTEM_U8PATH_H + +#include <__algorithm/unwrap_iter.h> +#include <__availability> +#include <__config> +#include <__filesystem/path.h> +#include +#include + +// Only required on Windows for __widen_from_utf8, and included conservatively +// because it requires support for localization. +#if defined(_LIBCPP_WIN32API) +# include +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T + typename enable_if<__is_pathable<_InputIt>::value, path>::type + u8path(_InputIt __f, _InputIt __l) { + static_assert( +#ifndef _LIBCPP_HAS_NO_CHAR8_T + is_same::__char_type, char8_t>::value || +#endif + is_same::__char_type, char>::value, + "u8path(Iter, Iter) requires Iter have a value_type of type 'char'" + " or 'char8_t'"); +#if defined(_LIBCPP_WIN32API) + string __tmp(__f, __l); + using _CVT = __widen_from_utf8; + _VSTD::wstring __w; + __w.reserve(__tmp.size()); + _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size()); + return path(__w); +#else + return path(__f, __l); +#endif /* !_LIBCPP_WIN32API */ +} + +#if defined(_LIBCPP_WIN32API) +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T + typename enable_if<__is_pathable<_InputIt>::value, path>::type + u8path(_InputIt __f, _NullSentinel) { + static_assert( +#ifndef _LIBCPP_HAS_NO_CHAR8_T + is_same::__char_type, char8_t>::value || +#endif + is_same::__char_type, char>::value, + "u8path(Iter, Iter) requires Iter have a value_type of type 'char'" + " or 'char8_t'"); + string __tmp; + const char __sentinel = char{}; + for (; *__f != __sentinel; ++__f) + __tmp.push_back(*__f); + using _CVT = __widen_from_utf8; + _VSTD::wstring __w; + __w.reserve(__tmp.size()); + _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size()); + return path(__w); +} +#endif /* _LIBCPP_WIN32API */ + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T + typename enable_if<__is_pathable<_Source>::value, path>::type + u8path(const _Source& __s) { + static_assert( +#ifndef _LIBCPP_HAS_NO_CHAR8_T + is_same::__char_type, char8_t>::value || +#endif + is_same::__char_type, char>::value, + "u8path(Source const&) requires Source have a character type of type " + "'char' or 'char8_t'"); +#if defined(_LIBCPP_WIN32API) + using _Traits = __is_pathable<_Source>; + return u8path(_VSTD::__unwrap_iter(_Traits::__range_begin(__s)), _VSTD::__unwrap_iter(_Traits::__range_end(__s))); +#else + return path(__s); +#endif +} + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_U8PATH_H diff --git a/app/src/main/cpp/libcxx/include/__format/buffer.h b/app/src/main/cpp/libcxx/include/__format/buffer.h new file mode 100644 index 0000000..ddfe767 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/buffer.h @@ -0,0 +1,573 @@ +// -*- 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 _LIBCPP___FORMAT_BUFFER_H +#define _LIBCPP___FORMAT_BUFFER_H + +#include <__algorithm/copy_n.h> +#include <__algorithm/fill_n.h> +#include <__algorithm/max.h> +#include <__algorithm/min.h> +#include <__algorithm/ranges_copy_n.h> +#include <__algorithm/transform.h> +#include <__algorithm/unwrap_iter.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__format/concepts.h> +#include <__format/enable_insertable.h> +#include <__format/format_to_n_result.h> +#include <__iterator/back_insert_iterator.h> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/wrap_iter.h> +#include <__utility/move.h> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __format { + +/// A "buffer" that handles writing to the proper iterator. +/// +/// This helper is used together with the @ref back_insert_iterator to offer +/// type-erasure for the formatting functions. This reduces the number to +/// template instantiations. +template <__fmt_char_type _CharT> +class _LIBCPP_TEMPLATE_VIS __output_buffer { +public: + using value_type = _CharT; + + template + _LIBCPP_HIDE_FROM_ABI explicit __output_buffer(_CharT* __ptr, size_t __capacity, _Tp* __obj) + : __ptr_(__ptr), + __capacity_(__capacity), + __flush_([](_CharT* __p, size_t __n, void* __o) { static_cast<_Tp*>(__o)->__flush(__p, __n); }), + __obj_(__obj) {} + + _LIBCPP_HIDE_FROM_ABI void __reset(_CharT* __ptr, size_t __capacity) { + __ptr_ = __ptr; + __capacity_ = __capacity; + } + + _LIBCPP_HIDE_FROM_ABI auto __make_output_iterator() { return std::back_insert_iterator{*this}; } + + // Used in std::back_insert_iterator. + _LIBCPP_HIDE_FROM_ABI void push_back(_CharT __c) { + __ptr_[__size_++] = __c; + + // Profiling showed flushing after adding is more efficient than flushing + // when entering the function. + if (__size_ == __capacity_) + __flush(); + } + + /// Copies the input __str to the buffer. + /// + /// Since some of the input is generated by std::to_chars, there needs to be a + /// conversion when _CharT is wchar_t. + template <__fmt_char_type _InCharT> + _LIBCPP_HIDE_FROM_ABI void __copy(basic_string_view<_InCharT> __str) { + // When the underlying iterator is a simple iterator the __capacity_ is + // infinite. For a string or container back_inserter it isn't. This means + // adding a large string the the buffer can cause some overhead. In that + // case a better approach could be: + // - flush the buffer + // - container.append(__str.begin(), __str.end()); + // The same holds true for the fill. + // For transform it might be slightly harder, however the use case for + // transform is slightly less common; it converts hexadecimal values to + // upper case. For integral these strings are short. + // TODO FMT Look at the improvements above. + size_t __n = __str.size(); + + __flush_on_overflow(__n); + if (__n <= __capacity_) { + _VSTD::copy_n(__str.data(), __n, _VSTD::addressof(__ptr_[__size_])); + __size_ += __n; + return; + } + + // The output doesn't fit in the internal buffer. + // Copy the data in "__capacity_" sized chunks. + _LIBCPP_ASSERT(__size_ == 0, "the buffer should be flushed by __flush_on_overflow"); + const _InCharT* __first = __str.data(); + do { + size_t __chunk = _VSTD::min(__n, __capacity_); + _VSTD::copy_n(__first, __chunk, _VSTD::addressof(__ptr_[__size_])); + __size_ = __chunk; + __first += __chunk; + __n -= __chunk; + __flush(); + } while (__n); + } + + /// A std::transform wrapper. + /// + /// Like @ref __copy it may need to do type conversion. + template <__fmt_char_type _InCharT, class _UnaryOperation> + _LIBCPP_HIDE_FROM_ABI void __transform(const _InCharT* __first, const _InCharT* __last, _UnaryOperation __operation) { + _LIBCPP_ASSERT(__first <= __last, "not a valid range"); + + size_t __n = static_cast(__last - __first); + __flush_on_overflow(__n); + if (__n <= __capacity_) { + _VSTD::transform(__first, __last, _VSTD::addressof(__ptr_[__size_]), _VSTD::move(__operation)); + __size_ += __n; + return; + } + + // The output doesn't fit in the internal buffer. + // Transform the data in "__capacity_" sized chunks. + _LIBCPP_ASSERT(__size_ == 0, "the buffer should be flushed by __flush_on_overflow"); + do { + size_t __chunk = _VSTD::min(__n, __capacity_); + _VSTD::transform(__first, __first + __chunk, _VSTD::addressof(__ptr_[__size_]), __operation); + __size_ = __chunk; + __first += __chunk; + __n -= __chunk; + __flush(); + } while (__n); + } + + /// A \c fill_n wrapper. + _LIBCPP_HIDE_FROM_ABI void __fill(size_t __n, _CharT __value) { + __flush_on_overflow(__n); + if (__n <= __capacity_) { + _VSTD::fill_n(_VSTD::addressof(__ptr_[__size_]), __n, __value); + __size_ += __n; + return; + } + + // The output doesn't fit in the internal buffer. + // Fill the buffer in "__capacity_" sized chunks. + _LIBCPP_ASSERT(__size_ == 0, "the buffer should be flushed by __flush_on_overflow"); + do { + size_t __chunk = _VSTD::min(__n, __capacity_); + _VSTD::fill_n(_VSTD::addressof(__ptr_[__size_]), __chunk, __value); + __size_ = __chunk; + __n -= __chunk; + __flush(); + } while (__n); + } + + _LIBCPP_HIDE_FROM_ABI void __flush() { + __flush_(__ptr_, __size_, __obj_); + __size_ = 0; + } + +private: + _CharT* __ptr_; + size_t __capacity_; + size_t __size_{0}; + void (*__flush_)(_CharT*, size_t, void*); + void* __obj_; + + /// Flushes the buffer when the output operation would overflow the buffer. + /// + /// A simple approach for the overflow detection would be something along the + /// lines: + /// \code + /// // The internal buffer is large enough. + /// if (__n <= __capacity_) { + /// // Flush when we really would overflow. + /// if (__size_ + __n >= __capacity_) + /// __flush(); + /// ... + /// } + /// \endcode + /// + /// This approach works for all cases but one: + /// A __format_to_n_buffer_base where \ref __enable_direct_output is true. + /// In that case the \ref __capacity_ of the buffer changes during the first + /// \ref __flush. During that operation the output buffer switches from its + /// __writer_ to its __storage_. The \ref __capacity_ of the former depends + /// on the value of n, of the latter is a fixed size. For example: + /// - a format_to_n call with a 10'000 char buffer, + /// - the buffer is filled with 9'500 chars, + /// - adding 1'000 elements would overflow the buffer so the buffer gets + /// changed and the \ref __capacity_ decreases from 10'000 to + /// __buffer_size (256 at the time of writing). + /// + /// This means that the \ref __flush for this class may need to copy a part of + /// the internal buffer to the proper output. In this example there will be + /// 500 characters that need this copy operation. + /// + /// Note it would be more efficient to write 500 chars directly and then swap + /// the buffers. This would make the code more complex and \ref format_to_n is + /// not the most common use case. Therefore the optimization isn't done. + _LIBCPP_HIDE_FROM_ABI void __flush_on_overflow(size_t __n) { + if (__size_ + __n >= __capacity_) + __flush(); + } +}; + +/// A storage using an internal buffer. +/// +/// This storage is used when writing a single element to the output iterator +/// is expensive. +template <__fmt_char_type _CharT> +class _LIBCPP_TEMPLATE_VIS __internal_storage { +public: + _LIBCPP_HIDE_FROM_ABI _CharT* __begin() { return __buffer_; } + + static constexpr size_t __buffer_size = 256 / sizeof(_CharT); + +private: + _CharT __buffer_[__buffer_size]; +}; + +/// A storage writing directly to the storage. +/// +/// This requires the storage to be a contiguous buffer of \a _CharT. +/// Since the output is directly written to the underlying storage this class +/// is just an empty class. +template <__fmt_char_type _CharT> +class _LIBCPP_TEMPLATE_VIS __direct_storage {}; + +template +concept __enable_direct_output = __fmt_char_type<_CharT> && + (same_as<_OutIt, _CharT*> +#ifndef _LIBCPP_ENABLE_DEBUG_MODE + || same_as<_OutIt, __wrap_iter<_CharT*>> +#endif + ); + +/// Write policy for directly writing to the underlying output. +template +class _LIBCPP_TEMPLATE_VIS __writer_direct { +public: + _LIBCPP_HIDE_FROM_ABI explicit __writer_direct(_OutIt __out_it) + : __out_it_(__out_it) {} + + _LIBCPP_HIDE_FROM_ABI _OutIt __out_it() { return __out_it_; } + + _LIBCPP_HIDE_FROM_ABI void __flush(_CharT*, size_t __n) { + // _OutIt can be a __wrap_iter. Therefore the original iterator + // is adjusted. + __out_it_ += __n; + } + +private: + _OutIt __out_it_; +}; + +/// Write policy for copying the buffer to the output. +template +class _LIBCPP_TEMPLATE_VIS __writer_iterator { +public: + _LIBCPP_HIDE_FROM_ABI explicit __writer_iterator(_OutIt __out_it) + : __out_it_{_VSTD::move(__out_it)} {} + + _LIBCPP_HIDE_FROM_ABI _OutIt __out_it() && { return std::move(__out_it_); } + + _LIBCPP_HIDE_FROM_ABI void __flush(_CharT* __ptr, size_t __n) { + __out_it_ = std::ranges::copy_n(__ptr, __n, std::move(__out_it_)).out; + } + +private: + _OutIt __out_it_; +}; + +/// Concept to see whether a \a _Container is insertable. +/// +/// The concept is used to validate whether multiple calls to a +/// \ref back_insert_iterator can be replace by a call to \c _Container::insert. +/// +/// \note a \a _Container needs to opt-in to the concept by specializing +/// \ref __enable_insertable. +template +concept __insertable = + __enable_insertable<_Container> && __fmt_char_type && + requires(_Container& __t, add_pointer_t __first, + add_pointer_t __last) { __t.insert(__t.end(), __first, __last); }; + +/// Extract the container type of a \ref back_insert_iterator. +template +struct _LIBCPP_TEMPLATE_VIS __back_insert_iterator_container { + using type = void; +}; + +template <__insertable _Container> +struct _LIBCPP_TEMPLATE_VIS __back_insert_iterator_container> { + using type = _Container; +}; + +/// Write policy for inserting the buffer in a container. +template +class _LIBCPP_TEMPLATE_VIS __writer_container { +public: + using _CharT = typename _Container::value_type; + + _LIBCPP_HIDE_FROM_ABI explicit __writer_container(back_insert_iterator<_Container> __out_it) + : __container_{__out_it.__get_container()} {} + + _LIBCPP_HIDE_FROM_ABI auto __out_it() { return std::back_inserter(*__container_); } + + _LIBCPP_HIDE_FROM_ABI void __flush(_CharT* __ptr, size_t __n) { + __container_->insert(__container_->end(), __ptr, __ptr + __n); + } + +private: + _Container* __container_; +}; + +/// Selects the type of the writer used for the output iterator. +template +class _LIBCPP_TEMPLATE_VIS __writer_selector { + using _Container = typename __back_insert_iterator_container<_OutIt>::type; + +public: + using type = conditional_t, __writer_container<_Container>, + conditional_t<__enable_direct_output<_OutIt, _CharT>, __writer_direct<_OutIt, _CharT>, + __writer_iterator<_OutIt, _CharT>>>; +}; + +/// The generic formatting buffer. +template +requires(output_iterator<_OutIt, const _CharT&>) class _LIBCPP_TEMPLATE_VIS + __format_buffer { + using _Storage = + conditional_t<__enable_direct_output<_OutIt, _CharT>, + __direct_storage<_CharT>, __internal_storage<_CharT>>; + +public: + _LIBCPP_HIDE_FROM_ABI explicit __format_buffer(_OutIt __out_it) + requires(same_as<_Storage, __internal_storage<_CharT>>) + : __output_(__storage_.__begin(), __storage_.__buffer_size, this), __writer_(_VSTD::move(__out_it)) {} + + _LIBCPP_HIDE_FROM_ABI explicit __format_buffer(_OutIt __out_it) requires( + same_as<_Storage, __direct_storage<_CharT>>) + : __output_(_VSTD::__unwrap_iter(__out_it), size_t(-1), this), + __writer_(_VSTD::move(__out_it)) {} + + _LIBCPP_HIDE_FROM_ABI auto __make_output_iterator() { return __output_.__make_output_iterator(); } + + _LIBCPP_HIDE_FROM_ABI void __flush(_CharT* __ptr, size_t __n) { __writer_.__flush(__ptr, __n); } + + _LIBCPP_HIDE_FROM_ABI _OutIt __out_it() && { + __output_.__flush(); + return _VSTD::move(__writer_).__out_it(); + } + +private: + _LIBCPP_NO_UNIQUE_ADDRESS _Storage __storage_; + __output_buffer<_CharT> __output_; + typename __writer_selector<_OutIt, _CharT>::type __writer_; +}; + +/// A buffer that counts the number of insertions. +/// +/// Since \ref formatted_size only needs to know the size, the output itself is +/// discarded. +template <__fmt_char_type _CharT> +class _LIBCPP_TEMPLATE_VIS __formatted_size_buffer { +public: + _LIBCPP_HIDE_FROM_ABI auto __make_output_iterator() { return __output_.__make_output_iterator(); } + + _LIBCPP_HIDE_FROM_ABI void __flush(const _CharT*, size_t __n) { __size_ += __n; } + + _LIBCPP_HIDE_FROM_ABI size_t __result() && { + __output_.__flush(); + return __size_; + } + +private: + __internal_storage<_CharT> __storage_; + __output_buffer<_CharT> __output_{__storage_.__begin(), __storage_.__buffer_size, this}; + size_t __size_{0}; +}; + +/// The base of a buffer that counts and limits the number of insertions. +template + requires(output_iterator<_OutIt, const _CharT&>) +struct _LIBCPP_TEMPLATE_VIS __format_to_n_buffer_base { + using _Size = iter_difference_t<_OutIt>; + +public: + _LIBCPP_HIDE_FROM_ABI explicit __format_to_n_buffer_base(_OutIt __out_it, _Size __max_size) + : __writer_(_VSTD::move(__out_it)), __max_size_(_VSTD::max(_Size(0), __max_size)) {} + + _LIBCPP_HIDE_FROM_ABI void __flush(_CharT* __ptr, size_t __n) { + if (_Size(__size_) <= __max_size_) + __writer_.__flush(__ptr, _VSTD::min(_Size(__n), __max_size_ - __size_)); + __size_ += __n; + } + +protected: + __internal_storage<_CharT> __storage_; + __output_buffer<_CharT> __output_{__storage_.__begin(), __storage_.__buffer_size, this}; + typename __writer_selector<_OutIt, _CharT>::type __writer_; + + _Size __max_size_; + _Size __size_{0}; +}; + +/// The base of a buffer that counts and limits the number of insertions. +/// +/// This version is used when \c __enable_direct_output<_OutIt, _CharT> == true. +/// +/// This class limits the size available to the direct writer so it will not +/// exceed the maximum number of code units. +template + requires(output_iterator<_OutIt, const _CharT&>) +class _LIBCPP_TEMPLATE_VIS __format_to_n_buffer_base<_OutIt, _CharT, true> { + using _Size = iter_difference_t<_OutIt>; + +public: + _LIBCPP_HIDE_FROM_ABI explicit __format_to_n_buffer_base(_OutIt __out_it, _Size __max_size) + : __output_(_VSTD::__unwrap_iter(__out_it), __max_size, this), + __writer_(_VSTD::move(__out_it)), + __max_size_(__max_size) { + if (__max_size <= 0) [[unlikely]] + __output_.__reset(__storage_.__begin(), __storage_.__buffer_size); + } + + _LIBCPP_HIDE_FROM_ABI void __flush(_CharT* __ptr, size_t __n) { + // A __flush to the direct writer happens in the following occasions: + // - The format function has written the maximum number of allowed code + // units. At this point it's no longer valid to write to this writer. So + // switch to the internal storage. This internal storage doesn't need to + // be written anywhere so the __flush for that storage writes no output. + // - Like above, but the next "mass write" operation would overflow the + // buffer. In that case the buffer is pre-emptively switched. The still + // valid code units will be written separately. + // - The format_to_n function is finished. In this case there's no need to + // switch the buffer, but for simplicity the buffers are still switched. + // When the __max_size <= 0 the constructor already switched the buffers. + if (__size_ == 0 && __ptr != __storage_.__begin()) { + __writer_.__flush(__ptr, __n); + __output_.__reset(__storage_.__begin(), __storage_.__buffer_size); + } else if (__size_ < __max_size_) { + // Copies a part of the internal buffer to the output up to n characters. + // See __output_buffer<_CharT>::__flush_on_overflow for more information. + _Size __s = _VSTD::min(_Size(__n), __max_size_ - __size_); + std::copy_n(__ptr, __s, __writer_.__out_it()); + __writer_.__flush(__ptr, __s); + } + + __size_ += __n; + } + +protected: + __internal_storage<_CharT> __storage_; + __output_buffer<_CharT> __output_; + __writer_direct<_OutIt, _CharT> __writer_; + + _Size __max_size_; + _Size __size_{0}; +}; + +/// The buffer that counts and limits the number of insertions. +template + requires(output_iterator<_OutIt, const _CharT&>) +struct _LIBCPP_TEMPLATE_VIS __format_to_n_buffer final + : public __format_to_n_buffer_base< _OutIt, _CharT, __enable_direct_output<_OutIt, _CharT>> { + using _Base = __format_to_n_buffer_base<_OutIt, _CharT, __enable_direct_output<_OutIt, _CharT>>; + using _Size = iter_difference_t<_OutIt>; + +public: + _LIBCPP_HIDE_FROM_ABI explicit __format_to_n_buffer(_OutIt __out_it, _Size __max_size) + : _Base(_VSTD::move(__out_it), __max_size) {} + _LIBCPP_HIDE_FROM_ABI auto __make_output_iterator() { return this->__output_.__make_output_iterator(); } + + _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __result() && { + this->__output_.__flush(); + return {_VSTD::move(this->__writer_).__out_it(), this->__size_}; + } +}; + +// A dynamically growing buffer intended to be used for retargeting a context. +// +// P2286 Formatting ranges adds range formatting support. It allows the user to +// specify the minimum width for the entire formatted range. The width of the +// range is not known until the range is formatted. Formatting is done to an +// output_iterator so there's no guarantee it would be possible to add the fill +// to the front of the output. Instead the range is formatted to a temporary +// buffer and that buffer is formatted as a string. +// +// There is an issue with that approach, the format context used in +// std::formatter::format contains the output iterator used as part of its +// type. So using this output iterator means there needs to be a new format +// context and the format arguments need to be retargeted to the new context. +// This retargeting is done by a basic_format_context specialized for the +// __iterator of this container. +template <__fmt_char_type _CharT> +class _LIBCPP_TEMPLATE_VIS __retarget_buffer { +public: + using value_type = _CharT; + + struct __iterator { + using difference_type = ptrdiff_t; + + _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(__retarget_buffer& __buffer) + : __buffer_(std::addressof(__buffer)) {} + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator=(const _CharT& __c) { + __buffer_->push_back(__c); + return *this; + } + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator=(_CharT&& __c) { + __buffer_->push_back(__c); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator*() { return *this; } + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() { return *this; } + _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) { return *this; } + __retarget_buffer* __buffer_; + }; + + _LIBCPP_HIDE_FROM_ABI explicit __retarget_buffer(size_t __size_hint) { __buffer_.reserve(__size_hint); } + + _LIBCPP_HIDE_FROM_ABI __iterator __make_output_iterator() { return __iterator{*this}; } + + _LIBCPP_HIDE_FROM_ABI void push_back(_CharT __c) { __buffer_.push_back(__c); } + + template <__fmt_char_type _InCharT> + _LIBCPP_HIDE_FROM_ABI void __copy(basic_string_view<_InCharT> __str) { + __buffer_.insert(__buffer_.end(), __str.begin(), __str.end()); + } + + template <__fmt_char_type _InCharT, class _UnaryOperation> + _LIBCPP_HIDE_FROM_ABI void __transform(const _InCharT* __first, const _InCharT* __last, _UnaryOperation __operation) { + _LIBCPP_ASSERT(__first <= __last, "not a valid range"); + std::transform(__first, __last, std::back_inserter(__buffer_), std::move(__operation)); + } + + _LIBCPP_HIDE_FROM_ABI void __fill(size_t __n, _CharT __value) { __buffer_.insert(__buffer_.end(), __n, __value); } + + _LIBCPP_HIDE_FROM_ABI basic_string_view<_CharT> __view() { return {__buffer_.data(), __buffer_.size()}; } + +private: + // Use vector instead of string to avoid adding zeros after every append + // operation. The buffer is exposed as a string_view and not as a c-string. + vector<_CharT> __buffer_; +}; + +} // namespace __format + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___FORMAT_BUFFER_H diff --git a/app/src/main/cpp/libcxx/include/__format/concepts.h b/app/src/main/cpp/libcxx/include/__format/concepts.h new file mode 100644 index 0000000..fe4a7b9 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/concepts.h @@ -0,0 +1,78 @@ +// -*- 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 _LIBCPP___FORMAT_CONCEPTS_H +#define _LIBCPP___FORMAT_CONCEPTS_H + +#include <__concepts/same_as.h> +#include <__concepts/semiregular.h> +#include <__config> +#include <__format/format_fwd.h> +#include <__format/format_parse_context.h> +#include <__type_traits/is_specialization.h> +#include <__utility/pair.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +/// The character type specializations of \ref formatter. +template +concept __fmt_char_type = + same_as<_CharT, char> +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS + || same_as<_CharT, wchar_t> +# endif + ; + +// The output iterator isn't specified. A formatter should accept any +// output_iterator. This iterator is a minimal iterator to test the concept. +// (Note testing for (w)format_context would be a valid choice, but requires +// selecting the proper one depending on the type of _CharT.) +template +using __fmt_iter_for = _CharT*; + +template +concept __formattable = + (semiregular, _CharT>>) && + requires(formatter, _CharT> __f, + const formatter, _CharT> __cf, + _Tp __t, + basic_format_context<__fmt_iter_for<_CharT>, _CharT> __fc, + basic_format_parse_context<_CharT> __pc) { + { __f.parse(__pc) } -> same_as::iterator>; + { __cf.format(__t, __fc) } -> same_as<__fmt_iter_for<_CharT>>; + }; + +# if _LIBCPP_STD_VER > 20 +template +concept formattable = __formattable<_Tp, _CharT>; + +// [tuple.like] defines a tuple-like exposition only concept. This concept is +// not related to that. Therefore it uses a different name for the concept. +// +// TODO FMT Add a test to validate we fail when using that concept after P2165 +// has been implemented. +template +concept __fmt_pair_like = __is_specialization_v<_Tp, pair> || + // Use a requires since tuple_size_v may fail to instantiate, + (__is_specialization_v<_Tp, tuple> && requires { tuple_size_v<_Tp> == 2; }); + +# endif //_LIBCPP_STD_VER > 20 +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_CONCEPTS_H diff --git a/app/src/main/cpp/libcxx/include/__format/container_adaptor.h b/app/src/main/cpp/libcxx/include/__format/container_adaptor.h new file mode 100644 index 0000000..62b6981 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/container_adaptor.h @@ -0,0 +1,70 @@ +// -*- 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 _LIBCPP___FORMAT_CONTAINER_ADAPTOR_H +#define _LIBCPP___FORMAT_CONTAINER_ADAPTOR_H + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#include <__availability> +#include <__config> +#include <__format/concepts.h> +#include <__format/formatter.h> +#include <__format/range_default_formatter.h> +#include +#include + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 20 + +// [container.adaptors.format] only specifies the library should provide the +// formatter specializations, not which header should provide them. +// Since includes a lot of headers, add these headers here instead of +// adding more dependencies like, locale, optinal, string, tuple, etc. to the +// adaptor headers. To use the format functions users already include . + +template +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_container_adaptor { +private: + using __maybe_const_adaptor = __fmt_maybe_const<_Adaptor, _CharT>; + formatter __underlying_; + +public: + template + _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { + return __underlying_.parse(__ctx); + } + + template + _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator + format(__maybe_const_adaptor& __adaptor, _FormatContext& __ctx) const { + return __underlying_.format(__adaptor.__get_container(), __ctx); + } +}; + +template _Container> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter, _CharT> + : public __formatter_container_adaptor, _CharT> {}; + +template +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter, _CharT> + : public __formatter_container_adaptor, _CharT> {}; + +template _Container> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter, _CharT> + : public __formatter_container_adaptor, _CharT> {}; + +#endif //_LIBCPP_STD_VER > 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_CONTAINER_ADAPTOR_H diff --git a/app/src/main/cpp/libcxx/include/__format/enable_insertable.h b/app/src/main/cpp/libcxx/include/__format/enable_insertable.h new file mode 100644 index 0000000..71b4252 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/enable_insertable.h @@ -0,0 +1,35 @@ +// -*- 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 _LIBCPP___FORMAT_ENABLE_INSERTABLE_H +#define _LIBCPP___FORMAT_ENABLE_INSERTABLE_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __format { + +/// Opt-in to enable \ref __insertable for a \a _Container. +template +inline constexpr bool __enable_insertable = false; + +} // namespace __format + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_ENABLE_INSERTABLE_H diff --git a/app/src/main/cpp/libcxx/include/__format/escaped_output_table.h b/app/src/main/cpp/libcxx/include/__format/escaped_output_table.h new file mode 100644 index 0000000..bd2994b --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/escaped_output_table.h @@ -0,0 +1,1038 @@ +// -*- 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 +// +//===----------------------------------------------------------------------===// + +// WARNING, this entire header is generated by +// utils/generate_escaped_output_table.py +// DO NOT MODIFY! + +// UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE +// +// See Terms of Use +// for definitions of Unicode Inc.'s Data Files and Software. +// +// NOTICE TO USER: Carefully read the following legal agreement. +// BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S +// DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), +// YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE +// TERMS AND CONDITIONS OF THIS AGREEMENT. +// IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE +// THE DATA FILES OR SOFTWARE. +// +// COPYRIGHT AND PERMISSION NOTICE +// +// Copyright (c) 1991-2022 Unicode, Inc. All rights reserved. +// Distributed under the Terms of Use in https://www.unicode.org/copyright.html. +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of the Unicode data files and any associated documentation +// (the "Data Files") or Unicode software and any associated documentation +// (the "Software") to deal in the Data Files or Software +// without restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, and/or sell copies of +// the Data Files or Software, and to permit persons to whom the Data Files +// or Software are furnished to do so, provided that either +// (a) this copyright and permission notice appear with all copies +// of the Data Files or Software, or +// (b) this copyright and permission notice appear in associated +// Documentation. +// +// THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. +// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS +// NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL +// DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THE DATA FILES OR SOFTWARE. +// +// Except as contained in this notice, the name of a copyright holder +// shall not be used in advertising or otherwise to promote the sale, +// use or other dealings in these Data Files or Software without prior +// written authorization of the copyright holder. + +#ifndef _LIBCPP___FORMAT_ESCAPED_OUTPUT_TABLE_H +#define _LIBCPP___FORMAT_ESCAPED_OUTPUT_TABLE_H + +#include <__algorithm/ranges_upper_bound.h> +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 20 + +namespace __escaped_output_table { + +/// The entries of the characters to escape in format's debug string. +/// +/// Contains the entries for [format.string.escaped]/2.2.1.2.1 +/// CE is a Unicode encoding and C corresponds to either a UCS scalar value +/// whose Unicode property General_Category has a value in the groups +/// Separator (Z) or Other (C) or to a UCS scalar value which has the Unicode +/// property Grapheme_Extend=Yes, as described by table 12 of UAX #44 +/// +/// Separator (Z) consists of General_Category +/// - Space_Separator, +/// - Line_Separator, +/// - Paragraph_Separator. +/// +/// Other (C) consists of General_Category +/// - Control, +/// - Format, +/// - Surrogate, +/// - Private_Use, +/// - Unassigned. +/// +/// The data is generated from +/// - https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt +/// - https://www.unicode.org/Public/UCD/latest/ucd/extracted/DerivedGeneralCategory.txt +/// +/// The table is similar to the table +/// __extended_grapheme_custer_property_boundary::__entries +/// which explains the details of these classes. The only difference is this +/// table lacks a property, thus having more bits available for the size. +/// +/// The data has 2 values: +/// - bits [0, 10] The size of the range, allowing 2048 elements. +/// - bits [11, 31] The lower bound code point of the range. The upper bound of +/// the range is lower bound + size. +inline constexpr uint32_t __entries[893] = { + 0x00000020, + 0x0003f821, + 0x00056800, + 0x0018006f, + 0x001bc001, + 0x001c0003, + 0x001c5800, + 0x001c6800, + 0x001d1000, + 0x00241806, + 0x00298000, + 0x002ab801, + 0x002c5801, + 0x002c802d, + 0x002df800, + 0x002e0801, + 0x002e2001, + 0x002e3808, + 0x002f5803, + 0x002fa810, + 0x0030800a, + 0x0030e000, + 0x00325814, + 0x00338000, + 0x0036b007, + 0x0036f805, + 0x00373801, + 0x00375003, + 0x00387001, + 0x00388800, + 0x0039801c, + 0x003d300a, + 0x003d900d, + 0x003f5808, + 0x003fd802, + 0x0040b003, + 0x0040d808, + 0x00412802, + 0x00414806, + 0x0041f800, + 0x0042c804, + 0x0042f800, + 0x00435804, + 0x00447810, + 0x00465038, + 0x0049d000, + 0x0049e000, + 0x004a0807, + 0x004a6800, + 0x004a8806, + 0x004b1001, + 0x004c0800, + 0x004c2000, + 0x004c6801, + 0x004c8801, + 0x004d4800, + 0x004d8800, + 0x004d9802, + 0x004dd002, + 0x004df000, + 0x004e0805, + 0x004e4801, + 0x004e6800, + 0x004e780c, + 0x004ef000, + 0x004f1003, + 0x004ff004, + 0x00502000, + 0x00505803, + 0x00508801, + 0x00514800, + 0x00518800, + 0x0051a000, + 0x0051b800, + 0x0051d003, + 0x00520817, + 0x0052e800, + 0x0052f806, + 0x00538001, + 0x0053a800, + 0x0053b80b, + 0x00542000, + 0x00547000, + 0x00549000, + 0x00554800, + 0x00558800, + 0x0055a000, + 0x0055d002, + 0x00560807, + 0x00565000, + 0x00566802, + 0x0056880e, + 0x00571003, + 0x00579006, + 0x0057d007, + 0x00582000, + 0x00586801, + 0x00588801, + 0x00594800, + 0x00598800, + 0x0059a000, + 0x0059d002, + 0x0059f001, + 0x005a0805, + 0x005a4801, + 0x005a680e, + 0x005af000, + 0x005b1003, + 0x005bc00a, + 0x005c2000, + 0x005c5802, + 0x005c8800, + 0x005cb002, + 0x005cd800, + 0x005ce800, + 0x005d0002, + 0x005d2802, + 0x005d5802, + 0x005dd004, + 0x005e0000, + 0x005e1802, + 0x005e4800, + 0x005e6802, + 0x005e8814, + 0x005fd805, + 0x00602000, + 0x00606800, + 0x00608800, + 0x00614800, + 0x0061d002, + 0x0061f002, + 0x00622812, + 0x0062d801, + 0x0062f001, + 0x00631003, + 0x00638006, + 0x00640800, + 0x00646800, + 0x00648800, + 0x00654800, + 0x0065a000, + 0x0065d002, + 0x0065f800, + 0x00661000, + 0x00662801, + 0x00664800, + 0x00666010, + 0x0066f800, + 0x00671003, + 0x00678000, + 0x0067a00d, + 0x00686800, + 0x00688800, + 0x0069d801, + 0x0069f000, + 0x006a0804, + 0x006a4800, + 0x006a6800, + 0x006a8003, + 0x006ab800, + 0x006b1003, + 0x006c0001, + 0x006c2000, + 0x006cb802, + 0x006d9000, + 0x006de000, + 0x006df001, + 0x006e3808, + 0x006e9005, + 0x006ef806, + 0x006f8001, + 0x006fa80b, + 0x00718800, + 0x0071a00a, + 0x00723807, + 0x0072e024, + 0x00741800, + 0x00742800, + 0x00745800, + 0x00752000, + 0x00753000, + 0x00758800, + 0x0075a008, + 0x0075f001, + 0x00762800, + 0x00763808, + 0x0076d001, + 0x0077001f, + 0x0078c001, + 0x0079a800, + 0x0079b800, + 0x0079c800, + 0x007a4000, + 0x007b6811, + 0x007c0004, + 0x007c3001, + 0x007c6830, + 0x007e3000, + 0x007e6800, + 0x007ed824, + 0x00816803, + 0x00819005, + 0x0081c801, + 0x0081e801, + 0x0082c001, + 0x0082f002, + 0x00838803, + 0x00841000, + 0x00842801, + 0x00846800, + 0x0084e800, + 0x00863000, + 0x00864004, + 0x00867001, + 0x00924800, + 0x00927001, + 0x0092b800, + 0x0092c800, + 0x0092f001, + 0x00944800, + 0x00947001, + 0x00958800, + 0x0095b001, + 0x0095f800, + 0x00960800, + 0x00963001, + 0x0096b800, + 0x00988800, + 0x0098b001, + 0x009ad804, + 0x009be802, + 0x009cd005, + 0x009fb001, + 0x009ff001, + 0x00b40000, + 0x00b4e802, + 0x00b7c806, + 0x00b89002, + 0x00b8b008, + 0x00b99001, + 0x00b9b808, + 0x00ba900d, + 0x00bb6800, + 0x00bb880e, + 0x00bda001, + 0x00bdb806, + 0x00be3000, + 0x00be480a, + 0x00bee802, + 0x00bf5005, + 0x00bfd005, + 0x00c05804, + 0x00c0d005, + 0x00c3c806, + 0x00c42801, + 0x00c54800, + 0x00c55804, + 0x00c7b009, + 0x00c8f803, + 0x00c93801, + 0x00c96003, + 0x00c99000, + 0x00c9c806, + 0x00ca0802, + 0x00cb7001, + 0x00cba80a, + 0x00cd6003, + 0x00ce5005, + 0x00ced802, + 0x00d0b801, + 0x00d0d802, + 0x00d2b000, + 0x00d2c008, + 0x00d31000, + 0x00d32807, + 0x00d3980c, + 0x00d45005, + 0x00d4d005, + 0x00d57055, + 0x00d9a006, + 0x00d9e000, + 0x00da1000, + 0x00da6802, + 0x00db5808, + 0x00dbf802, + 0x00dd1003, + 0x00dd4001, + 0x00dd5802, + 0x00df3000, + 0x00df4001, + 0x00df6800, + 0x00df7802, + 0x00dfa007, + 0x00e16007, + 0x00e1b004, + 0x00e25002, + 0x00e44806, + 0x00e5d801, + 0x00e6400a, + 0x00e6a00c, + 0x00e71006, + 0x00e76800, + 0x00e7a000, + 0x00e7c001, + 0x00e7d804, + 0x00ee003f, + 0x00f8b001, + 0x00f8f001, + 0x00fa3001, + 0x00fa7001, + 0x00fac000, + 0x00fad000, + 0x00fae000, + 0x00faf000, + 0x00fbf001, + 0x00fda800, + 0x00fe2800, + 0x00fea001, + 0x00fee000, + 0x00ff8001, + 0x00ffa800, + 0x00fff810, + 0x01014007, + 0x0102f810, + 0x01039001, + 0x01047800, + 0x0104e802, + 0x0106083e, + 0x010c6003, + 0x01213818, + 0x01225814, + 0x015ba001, + 0x015cb000, + 0x01677802, + 0x0167a004, + 0x01693000, + 0x01694004, + 0x01697001, + 0x016b4006, + 0x016b880e, + 0x016cb808, + 0x016d3800, + 0x016d7800, + 0x016db800, + 0x016df800, + 0x016e3800, + 0x016e7800, + 0x016eb800, + 0x016ef820, + 0x0172f021, + 0x0174d000, + 0x0177a00b, + 0x017eb019, + 0x017fe004, + 0x01815005, + 0x01820000, + 0x0184b803, + 0x01880004, + 0x01898000, + 0x018c7800, + 0x018f200b, + 0x0190f800, + 0x05246802, + 0x05263808, + 0x05316013, + 0x05337803, + 0x0533a009, + 0x0534f001, + 0x05378001, + 0x0537c007, + 0x053e5804, + 0x053e9000, + 0x053ea000, + 0x053ed017, + 0x05401000, + 0x05403000, + 0x05405800, + 0x05412801, + 0x05416003, + 0x0541d005, + 0x0543c007, + 0x05462009, + 0x0546d017, + 0x0547f800, + 0x05493007, + 0x054a380a, + 0x054aa00a, + 0x054be805, + 0x054d9800, + 0x054db003, + 0x054de001, + 0x054e7000, + 0x054ed003, + 0x054f2800, + 0x054ff800, + 0x05514805, + 0x05518801, + 0x0551a80a, + 0x05521800, + 0x05526000, + 0x05527001, + 0x0552d001, + 0x0553e000, + 0x05558000, + 0x05559002, + 0x0555b801, + 0x0555f001, + 0x05560800, + 0x05561817, + 0x05576001, + 0x0557b00a, + 0x05583801, + 0x05587801, + 0x0558b808, + 0x05593800, + 0x05597800, + 0x055b6003, + 0x055f2800, + 0x055f4000, + 0x055f6802, + 0x055fd005, + 0x06bd200b, + 0x06be3803, + 0x06bfe7ff, + 0x06ffe7ff, + 0x073fe7ff, + 0x077fe7ff, + 0x07bfe103, + 0x07d37001, + 0x07d6d025, + 0x07d8380b, + 0x07d8c004, + 0x07d8f000, + 0x07d9b800, + 0x07d9e800, + 0x07d9f800, + 0x07da1000, + 0x07da2800, + 0x07de180f, + 0x07ec8001, + 0x07ee4006, + 0x07ee801f, + 0x07f0000f, + 0x07f0d015, + 0x07f29800, + 0x07f33800, + 0x07f36003, + 0x07f3a800, + 0x07f7e803, + 0x07fcf001, + 0x07fdf802, + 0x07fe4001, + 0x07fe8001, + 0x07fec001, + 0x07fee802, + 0x07ff3800, + 0x07ff780c, + 0x07fff001, + 0x08006000, + 0x08013800, + 0x0801d800, + 0x0801f000, + 0x08027001, + 0x0802f021, + 0x0807d804, + 0x08081803, + 0x0809a002, + 0x080c7800, + 0x080ce802, + 0x080d082e, + 0x080fe882, + 0x0814e802, + 0x0816880f, + 0x0817e003, + 0x08192008, + 0x081a5804, + 0x081bb009, + 0x081cf000, + 0x081e2003, + 0x081eb029, + 0x0824f001, + 0x08255005, + 0x0826a003, + 0x0827e003, + 0x08294007, + 0x082b200a, + 0x082bd800, + 0x082c5800, + 0x082c9800, + 0x082cb000, + 0x082d1000, + 0x082d9000, + 0x082dd000, + 0x082de842, + 0x0839b808, + 0x083ab009, + 0x083b4017, + 0x083c3000, + 0x083d8800, + 0x083dd844, + 0x08403001, + 0x08404800, + 0x0841b000, + 0x0841c802, + 0x0841e801, + 0x0842b000, + 0x0844f807, + 0x0845802f, + 0x08479800, + 0x0847b004, + 0x0848e002, + 0x0849d004, + 0x084a003f, + 0x084dc003, + 0x084e8001, + 0x0850080e, + 0x0850a000, + 0x0850c000, + 0x0851b009, + 0x08524806, + 0x0852c806, + 0x0855001f, + 0x08572805, + 0x0857b808, + 0x0859b002, + 0x085ab001, + 0x085b9804, + 0x085c9006, + 0x085ce80b, + 0x085d804f, + 0x08624836, + 0x0865980c, + 0x08679806, + 0x0869200b, + 0x0869d125, + 0x0873f800, + 0x08755002, + 0x08757001, + 0x0875904d, + 0x08794007, + 0x087a300a, + 0x087ad015, + 0x087c1003, + 0x087c5025, + 0x087e6013, + 0x087fb808, + 0x08800800, + 0x0881c00e, + 0x08827003, + 0x08838000, + 0x08839801, + 0x0883b00b, + 0x08859803, + 0x0885c801, + 0x0885e800, + 0x0886100d, + 0x08874806, + 0x0887d008, + 0x08893804, + 0x08896808, + 0x088a4007, + 0x088b9800, + 0x088bb80a, + 0x088db008, + 0x088e4803, + 0x088e7800, + 0x088f0000, + 0x088fa80a, + 0x08909000, + 0x08917802, + 0x0891a000, + 0x0891b001, + 0x0891f000, + 0x0892083e, + 0x08943800, + 0x08944800, + 0x08947000, + 0x0894f000, + 0x08955005, + 0x0896f800, + 0x0897180c, + 0x0897d007, + 0x08982000, + 0x08986801, + 0x08988801, + 0x08994800, + 0x08998800, + 0x0899a000, + 0x0899d002, + 0x0899f000, + 0x089a0000, + 0x089a2801, + 0x089a4801, + 0x089a7001, + 0x089a880b, + 0x089b209b, + 0x08a1c007, + 0x08a21002, + 0x08a23000, + 0x08a2e000, + 0x08a2f000, + 0x08a3101d, + 0x08a58000, + 0x08a59805, + 0x08a5d000, + 0x08a5e800, + 0x08a5f801, + 0x08a61001, + 0x08a64007, + 0x08a6d0a5, + 0x08ad7800, + 0x08ad9005, + 0x08ade001, + 0x08adf801, + 0x08aee023, + 0x08b19807, + 0x08b1e800, + 0x08b1f801, + 0x08b2280a, + 0x08b2d005, + 0x08b36812, + 0x08b55800, + 0x08b56800, + 0x08b58005, + 0x08b5b800, + 0x08b5d005, + 0x08b65035, + 0x08b8d804, + 0x08b91003, + 0x08b93808, + 0x08ba38b8, + 0x08c17808, + 0x08c1c801, + 0x08c1e063, + 0x08c7980b, + 0x08c83801, + 0x08c85001, + 0x08c8a000, + 0x08c8b800, + 0x08c98000, + 0x08c9b000, + 0x08c9c803, + 0x08c9f000, + 0x08ca1800, + 0x08ca3808, + 0x08cad045, + 0x08cd4001, + 0x08cea007, + 0x08cf0000, + 0x08cf281a, + 0x08d00809, + 0x08d19805, + 0x08d1d803, + 0x08d23808, + 0x08d28805, + 0x08d2c802, + 0x08d4500c, + 0x08d4c001, + 0x08d5180c, + 0x08d7c806, + 0x08d850f5, + 0x08e04800, + 0x08e1800d, + 0x08e1f800, + 0x08e23009, + 0x08e36802, + 0x08e48018, + 0x08e55006, + 0x08e59001, + 0x08e5a84a, + 0x08e83800, + 0x08e85000, + 0x08e98814, + 0x08ea3808, + 0x08ead005, + 0x08eb3000, + 0x08eb4800, + 0x08ec7803, + 0x08eca800, + 0x08ecb800, + 0x08ecc806, + 0x08ed5135, + 0x08f79801, + 0x08f7c808, + 0x08f88800, + 0x08f9b007, + 0x08fa0000, + 0x08fa1000, + 0x08fad055, + 0x08fd880e, + 0x08ff900c, + 0x091cd065, + 0x09237800, + 0x0923a80a, + 0x092a27ff, + 0x096a224b, + 0x097f980c, + 0x09a18010, + 0x09a23fff, + 0x09e23fb8, + 0x0a323fff, + 0x0a723fff, + 0x0ab23fff, + 0x0af23fff, + 0x0b3239b8, + 0x0b51c806, + 0x0b52f800, + 0x0b535003, + 0x0b55f800, + 0x0b565005, + 0x0b577006, + 0x0b57b009, + 0x0b598006, + 0x0b5a3009, + 0x0b5ad000, + 0x0b5b1000, + 0x0b5bc004, + 0x0b5c82af, + 0x0b74d864, + 0x0b7a5804, + 0x0b7c400a, + 0x0b7d003f, + 0x0b7f200b, + 0x0b7f900d, + 0x0c3fc007, + 0x0c66b029, + 0x0c684fff, + 0x0ca84fff, + 0x0ce84fff, + 0x0d284fff, + 0x0d684ae6, + 0x0d7fa000, + 0x0d7fe000, + 0x0d7ff800, + 0x0d89180e, + 0x0d89981c, + 0x0d8a9801, + 0x0d8ab00d, + 0x0d8b4007, + 0x0d97e7ff, + 0x0dd7e103, + 0x0de35804, + 0x0de3e802, + 0x0de44806, + 0x0de4d001, + 0x0de4e801, + 0x0de507ff, + 0x0e2507ff, + 0x0e6502af, + 0x0e7e203b, + 0x0e87b009, + 0x0e893801, + 0x0e8b2800, + 0x0e8b3802, + 0x0e8b7014, + 0x0e8c2806, + 0x0e8d5003, + 0x0e8f5814, + 0x0e921002, + 0x0e923079, + 0x0e96a00b, + 0x0e97a00b, + 0x0e9ab808, + 0x0e9bc886, + 0x0ea2a800, + 0x0ea4e800, + 0x0ea50001, + 0x0ea51801, + 0x0ea53801, + 0x0ea56800, + 0x0ea5d000, + 0x0ea5e000, + 0x0ea62000, + 0x0ea83000, + 0x0ea85801, + 0x0ea8a800, + 0x0ea8e800, + 0x0ea9d000, + 0x0ea9f800, + 0x0eaa2800, + 0x0eaa3802, + 0x0eaa8800, + 0x0eb53001, + 0x0ebe6001, + 0x0ed00036, + 0x0ed1d831, + 0x0ed3a800, + 0x0ed42000, + 0x0ed46473, + 0x0ef8f805, + 0x0ef95904, + 0x0f037091, + 0x0f096809, + 0x0f09f001, + 0x0f0a5003, + 0x0f0a813f, + 0x0f157011, + 0x0f176003, + 0x0f17d004, + 0x0f1801cf, + 0x0f276003, + 0x0f27d2e5, + 0x0f3f3800, + 0x0f3f6000, + 0x0f3f7800, + 0x0f3ff800, + 0x0f462801, + 0x0f46802f, + 0x0f4a2006, + 0x0f4a6003, + 0x0f4ad003, + 0x0f4b0310, + 0x0f65a84b, + 0x0f69f0c1, + 0x0f702000, + 0x0f710000, + 0x0f711800, + 0x0f712801, + 0x0f714000, + 0x0f719800, + 0x0f71c000, + 0x0f71d000, + 0x0f71e005, + 0x0f721803, + 0x0f724000, + 0x0f725000, + 0x0f726000, + 0x0f728000, + 0x0f729800, + 0x0f72a801, + 0x0f72c000, + 0x0f72d000, + 0x0f72e000, + 0x0f72f000, + 0x0f730000, + 0x0f731800, + 0x0f732801, + 0x0f735800, + 0x0f739800, + 0x0f73c000, + 0x0f73e800, + 0x0f73f800, + 0x0f745000, + 0x0f74e004, + 0x0f752000, + 0x0f755000, + 0x0f75e033, + 0x0f77910d, + 0x0f816003, + 0x0f84a00b, + 0x0f857801, + 0x0f860000, + 0x0f868000, + 0x0f87b009, + 0x0f8d7037, + 0x0f90180c, + 0x0f91e003, + 0x0f924806, + 0x0f92900d, + 0x0f933099, + 0x0fb6c003, + 0x0fb76802, + 0x0fb7e802, + 0x0fbbb803, + 0x0fbed005, + 0x0fbf6003, + 0x0fbf880e, + 0x0fc06003, + 0x0fc24007, + 0x0fc2d005, + 0x0fc44007, + 0x0fc57001, + 0x0fc5904d, + 0x0fd2a00b, + 0x0fd37001, + 0x0fd3e802, + 0x0fd44806, + 0x0fd5f000, + 0x0fd63007, + 0x0fd6e003, + 0x0fd74806, + 0x0fd7c806, + 0x0fdc9800, + 0x0fde5824, + 0x0fdfd405, + 0x1537001f, + 0x15b9d005, + 0x15c0f001, + 0x1675100d, + 0x175f0fff, + 0x179f0c1e, + 0x17d0f5e1, + 0x189a5804}; + +/// At the end of the valid Unicode code points space a lot of code points are +/// either reserved or a noncharacter. Adding all these entries to the +/// lookup table would add 446 entries to the table (in Unicode 14). +/// Instead the only the start of the region is stored, every code point in +/// this region needs to be escaped. +inline constexpr uint32_t __unallocated_region_lower_bound = 0x000323b0; + +/// Returns whether the code unit needs to be escaped. +/// +/// \pre The code point is a valid Unicode code point. +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool __needs_escape(const char32_t __code_point) noexcept { + // Since __unallocated_region_lower_bound contains the unshifted range do the + // comparison without shifting. + if (__code_point >= __unallocated_region_lower_bound) + return true; + + ptrdiff_t __i = std::ranges::upper_bound(__entries, (__code_point << 11) | 0x7ffu) - __entries; + if (__i == 0) + return false; + + --__i; + uint32_t __upper_bound = (__entries[__i] >> 11) + (__entries[__i] & 0x7ffu); + return __code_point <= __upper_bound; +} + +} // namespace __escaped_output_table + +#endif //_LIBCPP_STD_VER > 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_ESCAPED_OUTPUT_TABLE_H diff --git a/app/src/main/cpp/libcxx/include/__format/extended_grapheme_cluster_table.h b/app/src/main/cpp/libcxx/include/__format/extended_grapheme_cluster_table.h new file mode 100644 index 0000000..1ffcfeb --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/extended_grapheme_cluster_table.h @@ -0,0 +1,1661 @@ +// -*- 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 +// +//===----------------------------------------------------------------------===// + +// WARNING, this entire header is generated by +// utils/generate_extended_grapheme_cluster_table.py +// DO NOT MODIFY! + +// UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE +// +// See Terms of Use +// for definitions of Unicode Inc.'s Data Files and Software. +// +// NOTICE TO USER: Carefully read the following legal agreement. +// BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S +// DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), +// YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE +// TERMS AND CONDITIONS OF THIS AGREEMENT. +// IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE +// THE DATA FILES OR SOFTWARE. +// +// COPYRIGHT AND PERMISSION NOTICE +// +// Copyright (c) 1991-2022 Unicode, Inc. All rights reserved. +// Distributed under the Terms of Use in https://www.unicode.org/copyright.html. +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of the Unicode data files and any associated documentation +// (the "Data Files") or Unicode software and any associated documentation +// (the "Software") to deal in the Data Files or Software +// without restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, and/or sell copies of +// the Data Files or Software, and to permit persons to whom the Data Files +// or Software are furnished to do so, provided that either +// (a) this copyright and permission notice appear with all copies +// of the Data Files or Software, or +// (b) this copyright and permission notice appear in associated +// Documentation. +// +// THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. +// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS +// NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL +// DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THE DATA FILES OR SOFTWARE. +// +// Except as contained in this notice, the name of a copyright holder +// shall not be used in advertising or otherwise to promote the sale, +// use or other dealings in these Data Files or Software without prior +// written authorization of the copyright holder. + +#ifndef _LIBCPP___FORMAT_EXTENDED_GRAPHEME_CLUSTER_TABLE_H +#define _LIBCPP___FORMAT_EXTENDED_GRAPHEME_CLUSTER_TABLE_H + +#include <__algorithm/ranges_upper_bound.h> +#include <__config> +#include <__iterator/access.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __extended_grapheme_custer_property_boundary { + +enum class __property : uint8_t { + // Values generated from the data files. + __CR, + __Control, + __Extend, + __Extended_Pictographic, + __L, + __LF, + __LV, + __LVT, + __Prepend, + __Regional_Indicator, + __SpacingMark, + __T, + __V, + __ZWJ, + + // The properies below aren't stored in the "database". + + // Text position properties. + __sot, + __eot, + + // The code unit has none of above properties. + __none +}; + +/// The entries of the extended grapheme cluster bondary property table. +/// +/// The data is generated from +/// - https://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakProperty.txt +/// - https://www.unicode.org/Public/UCD/latest/ucd/emoji/emoji-data.txt +/// +/// The data has 3 values +/// - bits [0, 3] The property. One of the values generated from the datafiles +/// of \ref __property +/// - bits [4, 10] The size of the range. +/// - bits [11, 31] The lower bound code point of the range. The upper bound of +/// the range is lower bound + size. +/// +/// The 7 bits for the size allow a maximum range of 128 elements. Some ranges +/// in the Unicode tables are larger. They are stored in multiple consecutive +/// ranges in the data table. An alternative would be to store the sizes in a +/// separate 16-bit value. The original MSVC STL code had such an approach, but +/// this approach uses less space for the data and is about 4% faster in the +/// following benchmark. +/// libcxx/benchmarks/std_format_spec_string_unicode.bench.cpp +inline constexpr uint32_t __entries[1496] = { + 0x00000091, + 0x00005005, + 0x00005811, + 0x00006800, + 0x00007111, + 0x0003fa01, + 0x00054803, + 0x00056801, + 0x00057003, + 0x001806f2, + 0x00241862, + 0x002c8ac2, + 0x002df802, + 0x002e0812, + 0x002e2012, + 0x002e3802, + 0x00300058, + 0x003080a2, + 0x0030e001, + 0x00325942, + 0x00338002, + 0x0036b062, + 0x0036e808, + 0x0036f852, + 0x00373812, + 0x00375032, + 0x00387808, + 0x00388802, + 0x003981a2, + 0x003d30a2, + 0x003f5882, + 0x003fe802, + 0x0040b032, + 0x0040d882, + 0x00412822, + 0x00414842, + 0x0042c822, + 0x00448018, + 0x0044c072, + 0x00465172, + 0x00471008, + 0x004719f2, + 0x0048180a, + 0x0049d002, + 0x0049d80a, + 0x0049e002, + 0x0049f02a, + 0x004a0872, + 0x004a483a, + 0x004a6802, + 0x004a701a, + 0x004a8862, + 0x004b1012, + 0x004c0802, + 0x004c101a, + 0x004de002, + 0x004df002, + 0x004df81a, + 0x004e0832, + 0x004e381a, + 0x004e581a, + 0x004e6802, + 0x004eb802, + 0x004f1012, + 0x004ff002, + 0x00500812, + 0x0050180a, + 0x0051e002, + 0x0051f02a, + 0x00520812, + 0x00523812, + 0x00525822, + 0x00528802, + 0x00538012, + 0x0053a802, + 0x00540812, + 0x0054180a, + 0x0055e002, + 0x0055f02a, + 0x00560842, + 0x00563812, + 0x0056480a, + 0x0056581a, + 0x00566802, + 0x00571012, + 0x0057d052, + 0x00580802, + 0x0058101a, + 0x0059e002, + 0x0059f012, + 0x005a000a, + 0x005a0832, + 0x005a381a, + 0x005a581a, + 0x005a6802, + 0x005aa822, + 0x005b1012, + 0x005c1002, + 0x005df002, + 0x005df80a, + 0x005e0002, + 0x005e081a, + 0x005e302a, + 0x005e502a, + 0x005e6802, + 0x005eb802, + 0x00600002, + 0x0060082a, + 0x00602002, + 0x0061e002, + 0x0061f022, + 0x0062083a, + 0x00623022, + 0x00625032, + 0x0062a812, + 0x00631012, + 0x00640802, + 0x0064101a, + 0x0065e002, + 0x0065f00a, + 0x0065f802, + 0x0066001a, + 0x00661002, + 0x0066181a, + 0x00663002, + 0x0066381a, + 0x0066501a, + 0x00666012, + 0x0066a812, + 0x00671012, + 0x0067980a, + 0x00680012, + 0x0068101a, + 0x0069d812, + 0x0069f002, + 0x0069f81a, + 0x006a0832, + 0x006a302a, + 0x006a502a, + 0x006a6802, + 0x006a7008, + 0x006ab802, + 0x006b1012, + 0x006c0802, + 0x006c101a, + 0x006e5002, + 0x006e7802, + 0x006e801a, + 0x006e9022, + 0x006eb002, + 0x006ec06a, + 0x006ef802, + 0x006f901a, + 0x00718802, + 0x0071980a, + 0x0071a062, + 0x00723872, + 0x00758802, + 0x0075980a, + 0x0075a082, + 0x00764062, + 0x0078c012, + 0x0079a802, + 0x0079b802, + 0x0079c802, + 0x0079f01a, + 0x007b88d2, + 0x007bf80a, + 0x007c0042, + 0x007c3012, + 0x007c68a2, + 0x007cca32, + 0x007e3002, + 0x00816832, + 0x0081880a, + 0x00819052, + 0x0081c812, + 0x0081d81a, + 0x0081e812, + 0x0082b01a, + 0x0082c012, + 0x0082f022, + 0x00838832, + 0x00841002, + 0x0084200a, + 0x00842812, + 0x00846802, + 0x0084e802, + 0x008805f4, + 0x008b047c, + 0x008d457b, + 0x009ae822, + 0x00b89022, + 0x00b8a80a, + 0x00b99012, + 0x00b9a00a, + 0x00ba9012, + 0x00bb9012, + 0x00bda012, + 0x00bdb00a, + 0x00bdb862, + 0x00bdf07a, + 0x00be3002, + 0x00be381a, + 0x00be48a2, + 0x00bee802, + 0x00c05822, + 0x00c07001, + 0x00c07802, + 0x00c42812, + 0x00c54802, + 0x00c90022, + 0x00c9183a, + 0x00c93812, + 0x00c9482a, + 0x00c9801a, + 0x00c99002, + 0x00c9985a, + 0x00c9c822, + 0x00d0b812, + 0x00d0c81a, + 0x00d0d802, + 0x00d2a80a, + 0x00d2b002, + 0x00d2b80a, + 0x00d2c062, + 0x00d30002, + 0x00d31002, + 0x00d32872, + 0x00d3685a, + 0x00d39892, + 0x00d3f802, + 0x00d581e2, + 0x00d80032, + 0x00d8200a, + 0x00d9a062, + 0x00d9d80a, + 0x00d9e002, + 0x00d9e84a, + 0x00da1002, + 0x00da181a, + 0x00db5882, + 0x00dc0012, + 0x00dc100a, + 0x00dd080a, + 0x00dd1032, + 0x00dd301a, + 0x00dd4012, + 0x00dd500a, + 0x00dd5822, + 0x00df3002, + 0x00df380a, + 0x00df4012, + 0x00df502a, + 0x00df6802, + 0x00df700a, + 0x00df7822, + 0x00df901a, + 0x00e1207a, + 0x00e16072, + 0x00e1a01a, + 0x00e1b012, + 0x00e68022, + 0x00e6a0c2, + 0x00e7080a, + 0x00e71062, + 0x00e76802, + 0x00e7a002, + 0x00e7b80a, + 0x00e7c012, + 0x00ee03f2, + 0x01005801, + 0x01006002, + 0x0100680d, + 0x01007011, + 0x01014061, + 0x0101e003, + 0x01024803, + 0x010300f1, + 0x01068202, + 0x01091003, + 0x0109c803, + 0x010ca053, + 0x010d4813, + 0x0118d013, + 0x01194003, + 0x011c4003, + 0x011e7803, + 0x011f48a3, + 0x011fc023, + 0x01261003, + 0x012d5013, + 0x012db003, + 0x012e0003, + 0x012fd833, + 0x01300053, + 0x013038b3, + 0x0130a713, + 0x01348753, + 0x013840a3, + 0x0138a003, + 0x0138b003, + 0x0138e803, + 0x01390803, + 0x01394003, + 0x01399813, + 0x013a2003, + 0x013a3803, + 0x013a6003, + 0x013a7003, + 0x013a9823, + 0x013ab803, + 0x013b1843, + 0x013ca823, + 0x013d0803, + 0x013d8003, + 0x013df803, + 0x0149a013, + 0x01582823, + 0x0158d813, + 0x015a8003, + 0x015aa803, + 0x01677822, + 0x016bf802, + 0x016f01f2, + 0x01815052, + 0x01818003, + 0x0181e803, + 0x0184c812, + 0x0194b803, + 0x0194c803, + 0x05337832, + 0x0533a092, + 0x0534f012, + 0x05378012, + 0x05401002, + 0x05403002, + 0x05405802, + 0x0541181a, + 0x05412812, + 0x0541380a, + 0x05416002, + 0x0544001a, + 0x0545a0fa, + 0x05462012, + 0x05470112, + 0x0547f802, + 0x05493072, + 0x054a38a2, + 0x054a901a, + 0x054b01c4, + 0x054c0022, + 0x054c180a, + 0x054d9802, + 0x054da01a, + 0x054db032, + 0x054dd01a, + 0x054de012, + 0x054df02a, + 0x054f2802, + 0x05514852, + 0x0551781a, + 0x05518812, + 0x0551981a, + 0x0551a812, + 0x05521802, + 0x05526002, + 0x0552680a, + 0x0553e002, + 0x05558002, + 0x05559022, + 0x0555b812, + 0x0555f012, + 0x05560802, + 0x0557580a, + 0x05576012, + 0x0557701a, + 0x0557a80a, + 0x0557b002, + 0x055f181a, + 0x055f2802, + 0x055f301a, + 0x055f4002, + 0x055f481a, + 0x055f600a, + 0x055f6802, + 0x05600006, + 0x056009a7, + 0x0560e006, + 0x0560e9a7, + 0x0561c006, + 0x0561c9a7, + 0x0562a006, + 0x0562a9a7, + 0x05638006, + 0x056389a7, + 0x05646006, + 0x056469a7, + 0x05654006, + 0x056549a7, + 0x05662006, + 0x056629a7, + 0x05670006, + 0x056709a7, + 0x0567e006, + 0x0567e9a7, + 0x0568c006, + 0x0568c9a7, + 0x0569a006, + 0x0569a9a7, + 0x056a8006, + 0x056a89a7, + 0x056b6006, + 0x056b69a7, + 0x056c4006, + 0x056c49a7, + 0x056d2006, + 0x056d29a7, + 0x056e0006, + 0x056e09a7, + 0x056ee006, + 0x056ee9a7, + 0x056fc006, + 0x056fc9a7, + 0x0570a006, + 0x0570a9a7, + 0x05718006, + 0x057189a7, + 0x05726006, + 0x057269a7, + 0x05734006, + 0x057349a7, + 0x05742006, + 0x057429a7, + 0x05750006, + 0x057509a7, + 0x0575e006, + 0x0575e9a7, + 0x0576c006, + 0x0576c9a7, + 0x0577a006, + 0x0577a9a7, + 0x05788006, + 0x057889a7, + 0x05796006, + 0x057969a7, + 0x057a4006, + 0x057a49a7, + 0x057b2006, + 0x057b29a7, + 0x057c0006, + 0x057c09a7, + 0x057ce006, + 0x057ce9a7, + 0x057dc006, + 0x057dc9a7, + 0x057ea006, + 0x057ea9a7, + 0x057f8006, + 0x057f89a7, + 0x05806006, + 0x058069a7, + 0x05814006, + 0x058149a7, + 0x05822006, + 0x058229a7, + 0x05830006, + 0x058309a7, + 0x0583e006, + 0x0583e9a7, + 0x0584c006, + 0x0584c9a7, + 0x0585a006, + 0x0585a9a7, + 0x05868006, + 0x058689a7, + 0x05876006, + 0x058769a7, + 0x05884006, + 0x058849a7, + 0x05892006, + 0x058929a7, + 0x058a0006, + 0x058a09a7, + 0x058ae006, + 0x058ae9a7, + 0x058bc006, + 0x058bc9a7, + 0x058ca006, + 0x058ca9a7, + 0x058d8006, + 0x058d89a7, + 0x058e6006, + 0x058e69a7, + 0x058f4006, + 0x058f49a7, + 0x05902006, + 0x059029a7, + 0x05910006, + 0x059109a7, + 0x0591e006, + 0x0591e9a7, + 0x0592c006, + 0x0592c9a7, + 0x0593a006, + 0x0593a9a7, + 0x05948006, + 0x059489a7, + 0x05956006, + 0x059569a7, + 0x05964006, + 0x059649a7, + 0x05972006, + 0x059729a7, + 0x05980006, + 0x059809a7, + 0x0598e006, + 0x0598e9a7, + 0x0599c006, + 0x0599c9a7, + 0x059aa006, + 0x059aa9a7, + 0x059b8006, + 0x059b89a7, + 0x059c6006, + 0x059c69a7, + 0x059d4006, + 0x059d49a7, + 0x059e2006, + 0x059e29a7, + 0x059f0006, + 0x059f09a7, + 0x059fe006, + 0x059fe9a7, + 0x05a0c006, + 0x05a0c9a7, + 0x05a1a006, + 0x05a1a9a7, + 0x05a28006, + 0x05a289a7, + 0x05a36006, + 0x05a369a7, + 0x05a44006, + 0x05a449a7, + 0x05a52006, + 0x05a529a7, + 0x05a60006, + 0x05a609a7, + 0x05a6e006, + 0x05a6e9a7, + 0x05a7c006, + 0x05a7c9a7, + 0x05a8a006, + 0x05a8a9a7, + 0x05a98006, + 0x05a989a7, + 0x05aa6006, + 0x05aa69a7, + 0x05ab4006, + 0x05ab49a7, + 0x05ac2006, + 0x05ac29a7, + 0x05ad0006, + 0x05ad09a7, + 0x05ade006, + 0x05ade9a7, + 0x05aec006, + 0x05aec9a7, + 0x05afa006, + 0x05afa9a7, + 0x05b08006, + 0x05b089a7, + 0x05b16006, + 0x05b169a7, + 0x05b24006, + 0x05b249a7, + 0x05b32006, + 0x05b329a7, + 0x05b40006, + 0x05b409a7, + 0x05b4e006, + 0x05b4e9a7, + 0x05b5c006, + 0x05b5c9a7, + 0x05b6a006, + 0x05b6a9a7, + 0x05b78006, + 0x05b789a7, + 0x05b86006, + 0x05b869a7, + 0x05b94006, + 0x05b949a7, + 0x05ba2006, + 0x05ba29a7, + 0x05bb0006, + 0x05bb09a7, + 0x05bbe006, + 0x05bbe9a7, + 0x05bcc006, + 0x05bcc9a7, + 0x05bda006, + 0x05bda9a7, + 0x05be8006, + 0x05be89a7, + 0x05bf6006, + 0x05bf69a7, + 0x05c04006, + 0x05c049a7, + 0x05c12006, + 0x05c129a7, + 0x05c20006, + 0x05c209a7, + 0x05c2e006, + 0x05c2e9a7, + 0x05c3c006, + 0x05c3c9a7, + 0x05c4a006, + 0x05c4a9a7, + 0x05c58006, + 0x05c589a7, + 0x05c66006, + 0x05c669a7, + 0x05c74006, + 0x05c749a7, + 0x05c82006, + 0x05c829a7, + 0x05c90006, + 0x05c909a7, + 0x05c9e006, + 0x05c9e9a7, + 0x05cac006, + 0x05cac9a7, + 0x05cba006, + 0x05cba9a7, + 0x05cc8006, + 0x05cc89a7, + 0x05cd6006, + 0x05cd69a7, + 0x05ce4006, + 0x05ce49a7, + 0x05cf2006, + 0x05cf29a7, + 0x05d00006, + 0x05d009a7, + 0x05d0e006, + 0x05d0e9a7, + 0x05d1c006, + 0x05d1c9a7, + 0x05d2a006, + 0x05d2a9a7, + 0x05d38006, + 0x05d389a7, + 0x05d46006, + 0x05d469a7, + 0x05d54006, + 0x05d549a7, + 0x05d62006, + 0x05d629a7, + 0x05d70006, + 0x05d709a7, + 0x05d7e006, + 0x05d7e9a7, + 0x05d8c006, + 0x05d8c9a7, + 0x05d9a006, + 0x05d9a9a7, + 0x05da8006, + 0x05da89a7, + 0x05db6006, + 0x05db69a7, + 0x05dc4006, + 0x05dc49a7, + 0x05dd2006, + 0x05dd29a7, + 0x05de0006, + 0x05de09a7, + 0x05dee006, + 0x05dee9a7, + 0x05dfc006, + 0x05dfc9a7, + 0x05e0a006, + 0x05e0a9a7, + 0x05e18006, + 0x05e189a7, + 0x05e26006, + 0x05e269a7, + 0x05e34006, + 0x05e349a7, + 0x05e42006, + 0x05e429a7, + 0x05e50006, + 0x05e509a7, + 0x05e5e006, + 0x05e5e9a7, + 0x05e6c006, + 0x05e6c9a7, + 0x05e7a006, + 0x05e7a9a7, + 0x05e88006, + 0x05e889a7, + 0x05e96006, + 0x05e969a7, + 0x05ea4006, + 0x05ea49a7, + 0x05eb2006, + 0x05eb29a7, + 0x05ec0006, + 0x05ec09a7, + 0x05ece006, + 0x05ece9a7, + 0x05edc006, + 0x05edc9a7, + 0x05eea006, + 0x05eea9a7, + 0x05ef8006, + 0x05ef89a7, + 0x05f06006, + 0x05f069a7, + 0x05f14006, + 0x05f149a7, + 0x05f22006, + 0x05f229a7, + 0x05f30006, + 0x05f309a7, + 0x05f3e006, + 0x05f3e9a7, + 0x05f4c006, + 0x05f4c9a7, + 0x05f5a006, + 0x05f5a9a7, + 0x05f68006, + 0x05f689a7, + 0x05f76006, + 0x05f769a7, + 0x05f84006, + 0x05f849a7, + 0x05f92006, + 0x05f929a7, + 0x05fa0006, + 0x05fa09a7, + 0x05fae006, + 0x05fae9a7, + 0x05fbc006, + 0x05fbc9a7, + 0x05fca006, + 0x05fca9a7, + 0x05fd8006, + 0x05fd89a7, + 0x05fe6006, + 0x05fe69a7, + 0x05ff4006, + 0x05ff49a7, + 0x06002006, + 0x060029a7, + 0x06010006, + 0x060109a7, + 0x0601e006, + 0x0601e9a7, + 0x0602c006, + 0x0602c9a7, + 0x0603a006, + 0x0603a9a7, + 0x06048006, + 0x060489a7, + 0x06056006, + 0x060569a7, + 0x06064006, + 0x060649a7, + 0x06072006, + 0x060729a7, + 0x06080006, + 0x060809a7, + 0x0608e006, + 0x0608e9a7, + 0x0609c006, + 0x0609c9a7, + 0x060aa006, + 0x060aa9a7, + 0x060b8006, + 0x060b89a7, + 0x060c6006, + 0x060c69a7, + 0x060d4006, + 0x060d49a7, + 0x060e2006, + 0x060e29a7, + 0x060f0006, + 0x060f09a7, + 0x060fe006, + 0x060fe9a7, + 0x0610c006, + 0x0610c9a7, + 0x0611a006, + 0x0611a9a7, + 0x06128006, + 0x061289a7, + 0x06136006, + 0x061369a7, + 0x06144006, + 0x061449a7, + 0x06152006, + 0x061529a7, + 0x06160006, + 0x061609a7, + 0x0616e006, + 0x0616e9a7, + 0x0617c006, + 0x0617c9a7, + 0x0618a006, + 0x0618a9a7, + 0x06198006, + 0x061989a7, + 0x061a6006, + 0x061a69a7, + 0x061b4006, + 0x061b49a7, + 0x061c2006, + 0x061c29a7, + 0x061d0006, + 0x061d09a7, + 0x061de006, + 0x061de9a7, + 0x061ec006, + 0x061ec9a7, + 0x061fa006, + 0x061fa9a7, + 0x06208006, + 0x062089a7, + 0x06216006, + 0x062169a7, + 0x06224006, + 0x062249a7, + 0x06232006, + 0x062329a7, + 0x06240006, + 0x062409a7, + 0x0624e006, + 0x0624e9a7, + 0x0625c006, + 0x0625c9a7, + 0x0626a006, + 0x0626a9a7, + 0x06278006, + 0x062789a7, + 0x06286006, + 0x062869a7, + 0x06294006, + 0x062949a7, + 0x062a2006, + 0x062a29a7, + 0x062b0006, + 0x062b09a7, + 0x062be006, + 0x062be9a7, + 0x062cc006, + 0x062cc9a7, + 0x062da006, + 0x062da9a7, + 0x062e8006, + 0x062e89a7, + 0x062f6006, + 0x062f69a7, + 0x06304006, + 0x063049a7, + 0x06312006, + 0x063129a7, + 0x06320006, + 0x063209a7, + 0x0632e006, + 0x0632e9a7, + 0x0633c006, + 0x0633c9a7, + 0x0634a006, + 0x0634a9a7, + 0x06358006, + 0x063589a7, + 0x06366006, + 0x063669a7, + 0x06374006, + 0x063749a7, + 0x06382006, + 0x063829a7, + 0x06390006, + 0x063909a7, + 0x0639e006, + 0x0639e9a7, + 0x063ac006, + 0x063ac9a7, + 0x063ba006, + 0x063ba9a7, + 0x063c8006, + 0x063c89a7, + 0x063d6006, + 0x063d69a7, + 0x063e4006, + 0x063e49a7, + 0x063f2006, + 0x063f29a7, + 0x06400006, + 0x064009a7, + 0x0640e006, + 0x0640e9a7, + 0x0641c006, + 0x0641c9a7, + 0x0642a006, + 0x0642a9a7, + 0x06438006, + 0x064389a7, + 0x06446006, + 0x064469a7, + 0x06454006, + 0x064549a7, + 0x06462006, + 0x064629a7, + 0x06470006, + 0x064709a7, + 0x0647e006, + 0x0647e9a7, + 0x0648c006, + 0x0648c9a7, + 0x0649a006, + 0x0649a9a7, + 0x064a8006, + 0x064a89a7, + 0x064b6006, + 0x064b69a7, + 0x064c4006, + 0x064c49a7, + 0x064d2006, + 0x064d29a7, + 0x064e0006, + 0x064e09a7, + 0x064ee006, + 0x064ee9a7, + 0x064fc006, + 0x064fc9a7, + 0x0650a006, + 0x0650a9a7, + 0x06518006, + 0x065189a7, + 0x06526006, + 0x065269a7, + 0x06534006, + 0x065349a7, + 0x06542006, + 0x065429a7, + 0x06550006, + 0x065509a7, + 0x0655e006, + 0x0655e9a7, + 0x0656c006, + 0x0656c9a7, + 0x0657a006, + 0x0657a9a7, + 0x06588006, + 0x065889a7, + 0x06596006, + 0x065969a7, + 0x065a4006, + 0x065a49a7, + 0x065b2006, + 0x065b29a7, + 0x065c0006, + 0x065c09a7, + 0x065ce006, + 0x065ce9a7, + 0x065dc006, + 0x065dc9a7, + 0x065ea006, + 0x065ea9a7, + 0x065f8006, + 0x065f89a7, + 0x06606006, + 0x066069a7, + 0x06614006, + 0x066149a7, + 0x06622006, + 0x066229a7, + 0x06630006, + 0x066309a7, + 0x0663e006, + 0x0663e9a7, + 0x0664c006, + 0x0664c9a7, + 0x0665a006, + 0x0665a9a7, + 0x06668006, + 0x066689a7, + 0x06676006, + 0x066769a7, + 0x06684006, + 0x066849a7, + 0x06692006, + 0x066929a7, + 0x066a0006, + 0x066a09a7, + 0x066ae006, + 0x066ae9a7, + 0x066bc006, + 0x066bc9a7, + 0x066ca006, + 0x066ca9a7, + 0x066d8006, + 0x066d89a7, + 0x066e6006, + 0x066e69a7, + 0x066f4006, + 0x066f49a7, + 0x06702006, + 0x067029a7, + 0x06710006, + 0x067109a7, + 0x0671e006, + 0x0671e9a7, + 0x0672c006, + 0x0672c9a7, + 0x0673a006, + 0x0673a9a7, + 0x06748006, + 0x067489a7, + 0x06756006, + 0x067569a7, + 0x06764006, + 0x067649a7, + 0x06772006, + 0x067729a7, + 0x06780006, + 0x067809a7, + 0x0678e006, + 0x0678e9a7, + 0x0679c006, + 0x0679c9a7, + 0x067aa006, + 0x067aa9a7, + 0x067b8006, + 0x067b89a7, + 0x067c6006, + 0x067c69a7, + 0x067d4006, + 0x067d49a7, + 0x067e2006, + 0x067e29a7, + 0x067f0006, + 0x067f09a7, + 0x067fe006, + 0x067fe9a7, + 0x0680c006, + 0x0680c9a7, + 0x0681a006, + 0x0681a9a7, + 0x06828006, + 0x068289a7, + 0x06836006, + 0x068369a7, + 0x06844006, + 0x068449a7, + 0x06852006, + 0x068529a7, + 0x06860006, + 0x068609a7, + 0x0686e006, + 0x0686e9a7, + 0x0687c006, + 0x0687c9a7, + 0x0688a006, + 0x0688a9a7, + 0x06898006, + 0x068989a7, + 0x068a6006, + 0x068a69a7, + 0x068b4006, + 0x068b49a7, + 0x068c2006, + 0x068c29a7, + 0x068d0006, + 0x068d09a7, + 0x068de006, + 0x068de9a7, + 0x068ec006, + 0x068ec9a7, + 0x068fa006, + 0x068fa9a7, + 0x06908006, + 0x069089a7, + 0x06916006, + 0x069169a7, + 0x06924006, + 0x069249a7, + 0x06932006, + 0x069329a7, + 0x06940006, + 0x069409a7, + 0x0694e006, + 0x0694e9a7, + 0x0695c006, + 0x0695c9a7, + 0x0696a006, + 0x0696a9a7, + 0x06978006, + 0x069789a7, + 0x06986006, + 0x069869a7, + 0x06994006, + 0x069949a7, + 0x069a2006, + 0x069a29a7, + 0x069b0006, + 0x069b09a7, + 0x069be006, + 0x069be9a7, + 0x069cc006, + 0x069cc9a7, + 0x069da006, + 0x069da9a7, + 0x069e8006, + 0x069e89a7, + 0x069f6006, + 0x069f69a7, + 0x06a04006, + 0x06a049a7, + 0x06a12006, + 0x06a129a7, + 0x06a20006, + 0x06a209a7, + 0x06a2e006, + 0x06a2e9a7, + 0x06a3c006, + 0x06a3c9a7, + 0x06a4a006, + 0x06a4a9a7, + 0x06a58006, + 0x06a589a7, + 0x06a66006, + 0x06a669a7, + 0x06a74006, + 0x06a749a7, + 0x06a82006, + 0x06a829a7, + 0x06a90006, + 0x06a909a7, + 0x06a9e006, + 0x06a9e9a7, + 0x06aac006, + 0x06aac9a7, + 0x06aba006, + 0x06aba9a7, + 0x06ac8006, + 0x06ac89a7, + 0x06ad6006, + 0x06ad69a7, + 0x06ae4006, + 0x06ae49a7, + 0x06af2006, + 0x06af29a7, + 0x06b00006, + 0x06b009a7, + 0x06b0e006, + 0x06b0e9a7, + 0x06b1c006, + 0x06b1c9a7, + 0x06b2a006, + 0x06b2a9a7, + 0x06b38006, + 0x06b389a7, + 0x06b46006, + 0x06b469a7, + 0x06b54006, + 0x06b549a7, + 0x06b62006, + 0x06b629a7, + 0x06b70006, + 0x06b709a7, + 0x06b7e006, + 0x06b7e9a7, + 0x06b8c006, + 0x06b8c9a7, + 0x06b9a006, + 0x06b9a9a7, + 0x06ba8006, + 0x06ba89a7, + 0x06bb6006, + 0x06bb69a7, + 0x06bc4006, + 0x06bc49a7, + 0x06bd816c, + 0x06be5b0b, + 0x07d8f002, + 0x07f000f2, + 0x07f100f2, + 0x07f7f801, + 0x07fcf012, + 0x07ff80b1, + 0x080fe802, + 0x08170002, + 0x081bb042, + 0x08500822, + 0x08502812, + 0x08506032, + 0x0851c022, + 0x0851f802, + 0x08572812, + 0x08692032, + 0x08755812, + 0x0877e822, + 0x087a30a2, + 0x087c1032, + 0x0880000a, + 0x08800802, + 0x0880100a, + 0x0881c0e2, + 0x08838002, + 0x08839812, + 0x0883f822, + 0x0884100a, + 0x0885802a, + 0x08859832, + 0x0885b81a, + 0x0885c812, + 0x0885e808, + 0x08861002, + 0x08866808, + 0x08880022, + 0x08893842, + 0x0889600a, + 0x08896872, + 0x088a281a, + 0x088b9802, + 0x088c0012, + 0x088c100a, + 0x088d982a, + 0x088db082, + 0x088df81a, + 0x088e1018, + 0x088e4832, + 0x088e700a, + 0x088e7802, + 0x0891602a, + 0x08917822, + 0x0891901a, + 0x0891a002, + 0x0891a80a, + 0x0891b012, + 0x0891f002, + 0x08920802, + 0x0896f802, + 0x0897002a, + 0x08971872, + 0x08980012, + 0x0898101a, + 0x0899d812, + 0x0899f002, + 0x0899f80a, + 0x089a0002, + 0x089a083a, + 0x089a381a, + 0x089a582a, + 0x089ab802, + 0x089b101a, + 0x089b3062, + 0x089b8042, + 0x08a1a82a, + 0x08a1c072, + 0x08a2001a, + 0x08a21022, + 0x08a2280a, + 0x08a23002, + 0x08a2f002, + 0x08a58002, + 0x08a5881a, + 0x08a59852, + 0x08a5c80a, + 0x08a5d002, + 0x08a5d81a, + 0x08a5e802, + 0x08a5f00a, + 0x08a5f812, + 0x08a6080a, + 0x08a61012, + 0x08ad7802, + 0x08ad801a, + 0x08ad9032, + 0x08adc03a, + 0x08ade012, + 0x08adf00a, + 0x08adf812, + 0x08aee012, + 0x08b1802a, + 0x08b19872, + 0x08b1d81a, + 0x08b1e802, + 0x08b1f00a, + 0x08b1f812, + 0x08b55802, + 0x08b5600a, + 0x08b56802, + 0x08b5701a, + 0x08b58052, + 0x08b5b00a, + 0x08b5b802, + 0x08b8e822, + 0x08b91032, + 0x08b9300a, + 0x08b93842, + 0x08c1602a, + 0x08c17882, + 0x08c1c00a, + 0x08c1c812, + 0x08c98002, + 0x08c9884a, + 0x08c9b81a, + 0x08c9d812, + 0x08c9e80a, + 0x08c9f002, + 0x08c9f808, + 0x08ca000a, + 0x08ca0808, + 0x08ca100a, + 0x08ca1802, + 0x08ce882a, + 0x08cea032, + 0x08ced012, + 0x08cee03a, + 0x08cf0002, + 0x08cf200a, + 0x08d00892, + 0x08d19852, + 0x08d1c80a, + 0x08d1d008, + 0x08d1d832, + 0x08d23802, + 0x08d28852, + 0x08d2b81a, + 0x08d2c822, + 0x08d42058, + 0x08d450c2, + 0x08d4b80a, + 0x08d4c012, + 0x08e1780a, + 0x08e18062, + 0x08e1c052, + 0x08e1f00a, + 0x08e1f802, + 0x08e49152, + 0x08e5480a, + 0x08e55062, + 0x08e5880a, + 0x08e59012, + 0x08e5a00a, + 0x08e5a812, + 0x08e98852, + 0x08e9d002, + 0x08e9e012, + 0x08e9f862, + 0x08ea3008, + 0x08ea3802, + 0x08ec504a, + 0x08ec8012, + 0x08ec981a, + 0x08eca802, + 0x08ecb00a, + 0x08ecb802, + 0x08f79812, + 0x08f7a81a, + 0x08f80012, + 0x08f81008, + 0x08f8180a, + 0x08f9a01a, + 0x08f9b042, + 0x08f9f01a, + 0x08fa0002, + 0x08fa080a, + 0x08fa1002, + 0x09a180f1, + 0x09a20002, + 0x09a238e2, + 0x0b578042, + 0x0b598062, + 0x0b7a7802, + 0x0b7a8b6a, + 0x0b7c7832, + 0x0b7f2002, + 0x0b7f801a, + 0x0de4e812, + 0x0de50031, + 0x0e7802d2, + 0x0e798162, + 0x0e8b2802, + 0x0e8b300a, + 0x0e8b3822, + 0x0e8b680a, + 0x0e8b7042, + 0x0e8b9871, + 0x0e8bd872, + 0x0e8c2862, + 0x0e8d5032, + 0x0e921022, + 0x0ed00362, + 0x0ed1db12, + 0x0ed3a802, + 0x0ed42002, + 0x0ed4d842, + 0x0ed508e2, + 0x0f000062, + 0x0f004102, + 0x0f00d862, + 0x0f011812, + 0x0f013042, + 0x0f047802, + 0x0f098062, + 0x0f157002, + 0x0f176032, + 0x0f276032, + 0x0f468062, + 0x0f4a2062, + 0x0f8007f3, + 0x0f8407f3, + 0x0f886823, + 0x0f897803, + 0x0f8b6053, + 0x0f8bf013, + 0x0f8c7003, + 0x0f8c8893, + 0x0f8d6b83, + 0x0f8f3199, + 0x0f9008e3, + 0x0f90d003, + 0x0f917803, + 0x0f919083, + 0x0f91e033, + 0x0f924ff3, + 0x0f964ff3, + 0x0f9a4ff3, + 0x0f9e4b13, + 0x0f9fd842, + 0x0fa007f3, + 0x0fa407f3, + 0x0fa803d3, + 0x0faa37f3, + 0x0fae37f3, + 0x0fb23093, + 0x0fb407f3, + 0x0fbba0b3, + 0x0fbeaaa3, + 0x0fc06033, + 0x0fc24073, + 0x0fc2d053, + 0x0fc44073, + 0x0fc57513, + 0x0fc862e3, + 0x0fc9e093, + 0x0fca3ff3, + 0x0fce3ff3, + 0x0fd23ff3, + 0x0fd63b83, + 0x0fe007f3, + 0x0fe407f3, + 0x0fe807f3, + 0x0fec07f3, + 0x0ff007f3, + 0x0ff407f3, + 0x0ff807f3, + 0x0ffc07d3, + 0x700001f1, + 0x700105f2, + 0x700407f1, + 0x700807f2, + 0x700c06f2, + 0x700f87f1, + 0x701387f1, + 0x701787f1, + 0x701b87f1, + 0x701f87f1, + 0x702387f1, + 0x702787f1, + 0x702b87f1, + 0x702f87f1, + 0x703387f1, + 0x703787f1, + 0x703b87f1, + 0x703f87f1, + 0x704387f1, + 0x704787f1, + 0x704b87f1, + 0x704f87f1, + 0x705387f1, + 0x705787f1, + 0x705b87f1, + 0x705f87f1, + 0x706387f1, + 0x706787f1, + 0x706b87f1, + 0x706f87f1, + 0x707387f1, + 0x707787f1, + 0x707b87f1, + 0x707f80f1}; + +/// Returns the extended grapheme cluster bondary property of a code point. +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __property __get_property(const char32_t __code_point) noexcept { + // The algorithm searches for the upper bound of the range and, when found, + // steps back one entry. This algorithm is used since the code point can be + // anywhere in the range. After a lower bound is found the next step is to + // compare whether the code unit is indeed in the range. + // + // Since the entry contains a code unit, size, and property the code point + // being sought needs to be adjusted. Just shifting the code point to the + // proper position doesn't work; suppose an entry has property 0, size 1, + // and lower bound 3. This results in the entry 0x1810. + // When searching for code point 3 it will search for 0x1800, find 0x1810 + // and moves to the previous entry. Thus the lower bound value will never + // be found. + // The simple solution is to set the bits belonging to the property and + // size. Then the upper bound for code point 3 will return the entry after + // 0x1810. After moving to the previous entry the algorithm arrives at the + // correct entry. + ptrdiff_t __i = std::ranges::upper_bound(__entries, (__code_point << 11) | 0x7ffu) - __entries; + if (__i == 0) + return __property::__none; + + --__i; + uint32_t __upper_bound = (__entries[__i] >> 11) + ((__entries[__i] >> 4) & 0x7f); + if (__code_point <= __upper_bound) + return static_cast<__property>(__entries[__i] & 0xf); + + return __property::__none; +} + +} // namespace __extended_grapheme_custer_property_boundary + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_EXTENDED_GRAPHEME_CLUSTER_TABLE_H diff --git a/app/src/main/cpp/libcxx/include/__format/format_arg.h b/app/src/main/cpp/libcxx/include/__format/format_arg.h new file mode 100644 index 0000000..771a03f --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/format_arg.h @@ -0,0 +1,302 @@ +// -*- 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 _LIBCPP___FORMAT_FORMAT_ARG_H +#define _LIBCPP___FORMAT_FORMAT_ARG_H + +#include <__assert> +#include <__concepts/arithmetic.h> +#include <__config> +#include <__format/format_error.h> +#include <__format/format_fwd.h> +#include <__format/format_parse_context.h> +#include <__functional/invoke.h> +#include <__memory/addressof.h> +#include <__utility/forward.h> +#include <__utility/unreachable.h> +#include <__variant/monostate.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __format { +/// The type stored in @ref basic_format_arg. +/// +/// @note The 128-bit types are unconditionally in the list to avoid the values +/// of the enums to depend on the availability of 128-bit integers. +/// +/// @note The value is stored as a 5-bit value in the __packed_arg_t_bits. This +/// limits the maximum number of elements to 32. +/// When modifying update the test +/// test/libcxx/utilities/format/format.arguments/format.arg/arg_t.compile.pass.cpp +/// It could be packed in 4-bits but that means a new type directly becomes an +/// ABI break. The packed type is 64-bit so this reduces the maximum number of +/// packed elements from 16 to 12. +/// +/// @note Some members of this enum are an extension. These extensions need +/// special behaviour in visit_format_arg. There they need to be wrapped in a +/// handle to satisfy the user observable behaviour. The internal function +/// __visit_format_arg doesn't do this wrapping. So in the format functions +/// this function is used to avoid unneeded overhead. +enum class _LIBCPP_ENUM_VIS __arg_t : uint8_t { + __none, + __boolean, + __char_type, + __int, + __long_long, + __i128, // extension + __unsigned, + __unsigned_long_long, + __u128, // extension + __float, + __double, + __long_double, + __const_char_type_ptr, + __string_view, + __ptr, + __handle +}; + +inline constexpr unsigned __packed_arg_t_bits = 5; +inline constexpr uint8_t __packed_arg_t_mask = 0x1f; + +inline constexpr unsigned __packed_types_storage_bits = 64; +inline constexpr unsigned __packed_types_max = __packed_types_storage_bits / __packed_arg_t_bits; + +_LIBCPP_HIDE_FROM_ABI +constexpr bool __use_packed_format_arg_store(size_t __size) { return __size <= __packed_types_max; } + +_LIBCPP_HIDE_FROM_ABI +constexpr __arg_t __get_packed_type(uint64_t __types, size_t __id) { + _LIBCPP_ASSERT(__id <= __packed_types_max, ""); + + if (__id > 0) + __types >>= __id * __packed_arg_t_bits; + + return static_cast<__format::__arg_t>(__types & __packed_arg_t_mask); +} + +} // namespace __format + +// This function is not user obervable, so it can directly use the non-standard +// types of the "variant". See __arg_t for more details. +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT decltype(auto) +__visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) { + switch (__arg.__type_) { + case __format::__arg_t::__none: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__monostate_); + case __format::__arg_t::__boolean: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__boolean_); + case __format::__arg_t::__char_type: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__char_type_); + case __format::__arg_t::__int: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__int_); + case __format::__arg_t::__long_long: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__long_long_); + case __format::__arg_t::__i128: +# ifndef _LIBCPP_HAS_NO_INT128 + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__i128_); +# else + __libcpp_unreachable(); +# endif + case __format::__arg_t::__unsigned: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__unsigned_); + case __format::__arg_t::__unsigned_long_long: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__unsigned_long_long_); + case __format::__arg_t::__u128: +# ifndef _LIBCPP_HAS_NO_INT128 + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__u128_); +# else + __libcpp_unreachable(); +# endif + case __format::__arg_t::__float: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__float_); + case __format::__arg_t::__double: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__double_); + case __format::__arg_t::__long_double: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__long_double_); + case __format::__arg_t::__const_char_type_ptr: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__const_char_type_ptr_); + case __format::__arg_t::__string_view: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__string_view_); + case __format::__arg_t::__ptr: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__ptr_); + case __format::__arg_t::__handle: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), + typename basic_format_arg<_Context>::handle{__arg.__value_.__handle_}); + } + + __libcpp_unreachable(); +} + +/// Contains the values used in basic_format_arg. +/// +/// This is a separate type so it's possible to store the values and types in +/// separate arrays. +template +class __basic_format_arg_value { + using _CharT = typename _Context::char_type; + +public: + /// Contains the implementation for basic_format_arg::handle. + struct __handle { + template + _LIBCPP_HIDE_FROM_ABI explicit __handle(_Tp&& __v) noexcept + : __ptr_(_VSTD::addressof(__v)), + __format_([](basic_format_parse_context<_CharT>& __parse_ctx, _Context& __ctx, const void* __ptr) { + using _Dp = remove_cvref_t<_Tp>; + using _Formatter = typename _Context::template formatter_type<_Dp>; + constexpr bool __const_formattable = + requires { _Formatter().format(std::declval(), std::declval<_Context&>()); }; + using _Qp = conditional_t<__const_formattable, const _Dp, _Dp>; + + static_assert(__const_formattable || !is_const_v>, "Mandated by [format.arg]/18"); + + _Formatter __f; + __parse_ctx.advance_to(__f.parse(__parse_ctx)); + __ctx.advance_to(__f.format(*const_cast<_Qp*>(static_cast(__ptr)), __ctx)); + }) {} + + const void* __ptr_; + void (*__format_)(basic_format_parse_context<_CharT>&, _Context&, const void*); + }; + + union { + monostate __monostate_; + bool __boolean_; + _CharT __char_type_; + int __int_; + unsigned __unsigned_; + long long __long_long_; + unsigned long long __unsigned_long_long_; +# ifndef _LIBCPP_HAS_NO_INT128 + __int128_t __i128_; + __uint128_t __u128_; +# endif + float __float_; + double __double_; + long double __long_double_; + const _CharT* __const_char_type_ptr_; + basic_string_view<_CharT> __string_view_; + const void* __ptr_; + __handle __handle_; + }; + + // These constructors contain the exact storage type used. If adjustments are + // required, these will be done in __create_format_arg. + + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value() noexcept : __monostate_() {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(bool __value) noexcept : __boolean_(__value) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(_CharT __value) noexcept : __char_type_(__value) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(int __value) noexcept : __int_(__value) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(unsigned __value) noexcept : __unsigned_(__value) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(long long __value) noexcept : __long_long_(__value) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(unsigned long long __value) noexcept + : __unsigned_long_long_(__value) {} +# ifndef _LIBCPP_HAS_NO_INT128 + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__int128_t __value) noexcept : __i128_(__value) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__uint128_t __value) noexcept : __u128_(__value) {} +# endif + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(float __value) noexcept : __float_(__value) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(double __value) noexcept : __double_(__value) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(long double __value) noexcept : __long_double_(__value) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(const _CharT* __value) noexcept : __const_char_type_ptr_(__value) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(basic_string_view<_CharT> __value) noexcept + : __string_view_(__value) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(const void* __value) noexcept : __ptr_(__value) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__handle __value) noexcept + // TODO FMT Investigate why it doesn't work without the forward. + : __handle_(std::forward<__handle>(__value)) {} +}; + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_arg { +public: + class _LIBCPP_TEMPLATE_VIS handle; + + _LIBCPP_HIDE_FROM_ABI basic_format_arg() noexcept + : __type_{__format::__arg_t::__none} {} + + _LIBCPP_HIDE_FROM_ABI explicit operator bool() const noexcept { + return __type_ != __format::__arg_t::__none; + } + +private: + using char_type = typename _Context::char_type; + + // TODO FMT Implement constrain [format.arg]/4 + // Constraints: The template specialization + // typename Context::template formatter_type + // meets the Formatter requirements ([formatter.requirements]). The extent + // to which an implementation determines that the specialization meets the + // Formatter requirements is unspecified, except that as a minimum the + // expression + // typename Context::template formatter_type() + // .format(declval(), declval()) + // shall be well-formed when treated as an unevaluated operand. + +public: + __basic_format_arg_value<_Context> __value_; + __format::__arg_t __type_; + + _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(__format::__arg_t __type, + __basic_format_arg_value<_Context> __value) noexcept + : __value_(__value), __type_(__type) {} +}; + +template +class _LIBCPP_TEMPLATE_VIS basic_format_arg<_Context>::handle { +public: + _LIBCPP_HIDE_FROM_ABI + void format(basic_format_parse_context& __parse_ctx, _Context& __ctx) const { + __handle_.__format_(__parse_ctx, __ctx, __handle_.__ptr_); + } + + _LIBCPP_HIDE_FROM_ABI explicit handle(typename __basic_format_arg_value<_Context>::__handle& __handle) noexcept + : __handle_(__handle) {} + +private: + typename __basic_format_arg_value<_Context>::__handle& __handle_; +}; + +// This function is user facing, so it must wrap the non-standard types of +// the "variant" in a handle to stay conforming. See __arg_t for more details. +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT decltype(auto) +visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) { + switch (__arg.__type_) { +# ifndef _LIBCPP_HAS_NO_INT128 + case __format::__arg_t::__i128: { + typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_.__i128_}; + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h}); + } + + case __format::__arg_t::__u128: { + typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_.__u128_}; + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h}); + } +# endif + default: + return _VSTD::__visit_format_arg(_VSTD::forward<_Visitor>(__vis), __arg); + } +} + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMAT_ARG_H diff --git a/app/src/main/cpp/libcxx/include/__format/format_arg_store.h b/app/src/main/cpp/libcxx/include/__format/format_arg_store.h new file mode 100644 index 0000000..6f4f4c3 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/format_arg_store.h @@ -0,0 +1,254 @@ +// -*- 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 _LIBCPP___FORMAT_FORMAT_ARG_STORE_H +#define _LIBCPP___FORMAT_FORMAT_ARG_STORE_H + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#include <__concepts/arithmetic.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__format/concepts.h> +#include <__format/format_arg.h> +#include <__utility/forward.h> +#include +#include +#include +#include + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __format { + +/// \returns The @c __arg_t based on the type of the formatting argument. +/// +/// \pre \c __formattable<_Tp, typename _Context::char_type> +template +consteval __arg_t __determine_arg_t(); + +// Boolean +template _Tp> +consteval __arg_t __determine_arg_t() { + return __arg_t::__boolean; +} + +// Char +template _Tp> +consteval __arg_t __determine_arg_t() { + return __arg_t::__char_type; +} +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template + requires(same_as && same_as<_CharT, char>) +consteval __arg_t __determine_arg_t() { + return __arg_t::__char_type; +} +# endif + +// Signed integers +template +consteval __arg_t __determine_arg_t() { + if constexpr (sizeof(_Tp) <= sizeof(int)) + return __arg_t::__int; + else if constexpr (sizeof(_Tp) <= sizeof(long long)) + return __arg_t::__long_long; +# ifndef _LIBCPP_HAS_NO_INT128 + else if constexpr (sizeof(_Tp) == sizeof(__int128_t)) + return __arg_t::__i128; +# endif + else + static_assert(sizeof(_Tp) == 0, "an unsupported signed integer was used"); +} + +// Unsigned integers +template +consteval __arg_t __determine_arg_t() { + if constexpr (sizeof(_Tp) <= sizeof(unsigned)) + return __arg_t::__unsigned; + else if constexpr (sizeof(_Tp) <= sizeof(unsigned long long)) + return __arg_t::__unsigned_long_long; +# ifndef _LIBCPP_HAS_NO_INT128 + else if constexpr (sizeof(_Tp) == sizeof(__uint128_t)) + return __arg_t::__u128; +# endif + else + static_assert(sizeof(_Tp) == 0, "an unsupported unsigned integer was used"); +} + +// Floating-point +template _Tp> +consteval __arg_t __determine_arg_t() { + return __arg_t::__float; +} +template _Tp> +consteval __arg_t __determine_arg_t() { + return __arg_t::__double; +} +template _Tp> +consteval __arg_t __determine_arg_t() { + return __arg_t::__long_double; +} + +// Char pointer +template + requires(same_as || same_as) +consteval __arg_t __determine_arg_t() { + return __arg_t::__const_char_type_ptr; +} + +// Char array +template + requires(is_array_v<_Tp> && same_as<_Tp, typename _Context::char_type[extent_v<_Tp>]>) +consteval __arg_t __determine_arg_t() { + return __arg_t::__string_view; +} + +// String view +template + requires(same_as && + same_as<_Tp, basic_string_view>) +consteval __arg_t __determine_arg_t() { + return __arg_t::__string_view; +} + +// String +template + requires( + same_as && + same_as<_Tp, basic_string>) +consteval __arg_t __determine_arg_t() { + return __arg_t::__string_view; +} + +// Pointers +template + requires(same_as<_Ptr, void*> || same_as<_Ptr, const void*> || same_as<_Ptr, nullptr_t>) +consteval __arg_t __determine_arg_t() { + return __arg_t::__ptr; +} + +// Handle +// +// Note this version can't be constrained avoiding ambiguous overloads. +// That means it can be instantiated by disabled formatters. To solve this, a +// constrained version for not formattable formatters is added. That overload +// is marked as deleted to fail creating a storage type for disabled formatters. +template +consteval __arg_t __determine_arg_t() { + return __arg_t::__handle; +} + +template + requires(!__formattable<_Tp, typename _Context::char_type>) +consteval __arg_t __determine_arg_t() = delete; + +template +_LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> __create_format_arg(_Tp&& __value) noexcept { + constexpr __arg_t __arg = __determine_arg_t<_Context, remove_cvref_t<_Tp>>(); + static_assert(__arg != __arg_t::__none); + + // Not all types can be used to directly initialize the + // __basic_format_arg_value. First handle all types needing adjustment, the + // final else requires no adjustment. + if constexpr (__arg == __arg_t::__char_type) + // On some platforms initializing a wchar_t from a char is a narrowing + // conversion. + return basic_format_arg<_Context>{__arg, static_cast(__value)}; + else if constexpr (__arg == __arg_t::__int) + return basic_format_arg<_Context>{__arg, static_cast(__value)}; + else if constexpr (__arg == __arg_t::__long_long) + return basic_format_arg<_Context>{__arg, static_cast(__value)}; + else if constexpr (__arg == __arg_t::__unsigned) + return basic_format_arg<_Context>{__arg, static_cast(__value)}; + else if constexpr (__arg == __arg_t::__unsigned_long_long) + return basic_format_arg<_Context>{__arg, static_cast(__value)}; + else if constexpr (__arg == __arg_t::__string_view) + // Using std::size on a character array will add the NUL-terminator to the size. + if constexpr (is_array_v>) + return basic_format_arg<_Context>{ + __arg, basic_string_view{__value, extent_v> - 1}}; + else + // When the _Traits or _Allocator are different an implicit conversion will + // fail. + return basic_format_arg<_Context>{ + __arg, basic_string_view{__value.data(), __value.size()}}; + else if constexpr (__arg == __arg_t::__ptr) + return basic_format_arg<_Context>{__arg, static_cast(__value)}; + else if constexpr (__arg == __arg_t::__handle) + return basic_format_arg<_Context>{ + __arg, typename __basic_format_arg_value<_Context>::__handle{_VSTD::forward<_Tp>(__value)}}; + else + return basic_format_arg<_Context>{__arg, __value}; +} + +template +_LIBCPP_HIDE_FROM_ABI void __create_packed_storage(uint64_t& __types, __basic_format_arg_value<_Context>* __values, + _Args&&... __args) noexcept { + int __shift = 0; + ( + [&] { + basic_format_arg<_Context> __arg = __format::__create_format_arg<_Context>(__args); + if (__shift != 0) + __types |= static_cast(__arg.__type_) << __shift; + else + // Assigns the initial value. + __types = static_cast(__arg.__type_); + __shift += __packed_arg_t_bits; + *__values++ = __arg.__value_; + }(), + ...); +} + +template +_LIBCPP_HIDE_FROM_ABI void __store_basic_format_arg(basic_format_arg<_Context>* __data, _Args&&... __args) noexcept { + ([&] { *__data++ = __format::__create_format_arg<_Context>(__args); }(), ...); +} + +template +struct __packed_format_arg_store { + __basic_format_arg_value<_Context> __values_[N]; + uint64_t __types_; +}; + +template +struct __unpacked_format_arg_store { + basic_format_arg<_Context> __args_[N]; +}; + +} // namespace __format + +template +struct _LIBCPP_TEMPLATE_VIS __format_arg_store { + _LIBCPP_HIDE_FROM_ABI + __format_arg_store(_Args&... __args) noexcept { + if constexpr (sizeof...(_Args) != 0) { + if constexpr (__format::__use_packed_format_arg_store(sizeof...(_Args))) + __format::__create_packed_storage(__storage.__types_, __storage.__values_, __args...); + else + __format::__store_basic_format_arg<_Context>(__storage.__args_, __args...); + } + } + + using _Storage = conditional_t<__format::__use_packed_format_arg_store(sizeof...(_Args)), + __format::__packed_format_arg_store<_Context, sizeof...(_Args)>, + __format::__unpacked_format_arg_store<_Context, sizeof...(_Args)>>; + + _Storage __storage; +}; + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMAT_ARG_STORE_H diff --git a/app/src/main/cpp/libcxx/include/__format/format_args.h b/app/src/main/cpp/libcxx/include/__format/format_args.h new file mode 100644 index 0000000..8b8fbde --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/format_args.h @@ -0,0 +1,80 @@ +// -*- 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 _LIBCPP___FORMAT_FORMAT_ARGS_H +#define _LIBCPP___FORMAT_FORMAT_ARGS_H + +#include <__availability> +#include <__config> +#include <__format/format_arg.h> +#include <__format/format_arg_store.h> +#include <__format/format_fwd.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_args { +public: + _LIBCPP_HIDE_FROM_ABI basic_format_args() noexcept = default; + + template + _LIBCPP_HIDE_FROM_ABI basic_format_args(const __format_arg_store<_Context, _Args...>& __store) noexcept + : __size_(sizeof...(_Args)) { + if constexpr (sizeof...(_Args) != 0) { + if constexpr (__format::__use_packed_format_arg_store(sizeof...(_Args))) { + __values_ = __store.__storage.__values_; + __types_ = __store.__storage.__types_; + } else + __args_ = __store.__storage.__args_; + } + } + + _LIBCPP_HIDE_FROM_ABI + basic_format_arg<_Context> get(size_t __id) const noexcept { + if (__id >= __size_) + return basic_format_arg<_Context>{}; + + if (__format::__use_packed_format_arg_store(__size_)) + return basic_format_arg<_Context>{__format::__get_packed_type(__types_, __id), __values_[__id]}; + + return __args_[__id]; + } + + _LIBCPP_HIDE_FROM_ABI size_t __size() const noexcept { return __size_; } + +private: + size_t __size_{0}; + // [format.args]/5 + // [Note 1: Implementations are encouraged to optimize the representation of + // basic_format_args for small number of formatting arguments by storing + // indices of type alternatives separately from values and packing the + // former. - end note] + union { + struct { + const __basic_format_arg_value<_Context>* __values_; + uint64_t __types_; + }; + const basic_format_arg<_Context>* __args_; + }; +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_args); + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMAT_ARGS_H diff --git a/app/src/main/cpp/libcxx/include/__format/format_context.h b/app/src/main/cpp/libcxx/include/__format/format_context.h new file mode 100644 index 0000000..85e00eb --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/format_context.h @@ -0,0 +1,223 @@ +// -*- 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 _LIBCPP___FORMAT_FORMAT_CONTEXT_H +#define _LIBCPP___FORMAT_FORMAT_CONTEXT_H + +#include <__availability> +#include <__concepts/same_as.h> +#include <__config> +#include <__format/buffer.h> +#include <__format/format_arg.h> +#include <__format/format_arg_store.h> +#include <__format/format_args.h> +#include <__format/format_error.h> +#include <__format/format_fwd.h> +#include <__iterator/back_insert_iterator.h> +#include <__iterator/concepts.h> +#include <__memory/addressof.h> +#include <__utility/move.h> +#include <__variant/monostate.h> +#include + +#ifndef _LIBCPP_HAS_NO_LOCALIZATION +#include +#include +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +requires output_iterator<_OutIt, const _CharT&> +class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_context; + +#ifndef _LIBCPP_HAS_NO_LOCALIZATION +/** + * Helper to create a basic_format_context. + * + * This is needed since the constructor is private. + */ +template +_LIBCPP_HIDE_FROM_ABI basic_format_context<_OutIt, _CharT> +__format_context_create( + _OutIt __out_it, + basic_format_args> __args, + optional<_VSTD::locale>&& __loc = nullopt) { + return _VSTD::basic_format_context(_VSTD::move(__out_it), __args, _VSTD::move(__loc)); +} +#else +template +_LIBCPP_HIDE_FROM_ABI basic_format_context<_OutIt, _CharT> +__format_context_create( + _OutIt __out_it, + basic_format_args> __args) { + return _VSTD::basic_format_context(_VSTD::move(__out_it), __args); +} +#endif + +using format_context = + basic_format_context>, + char>; +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +using wformat_context = basic_format_context< + back_insert_iterator<__format::__output_buffer>, wchar_t>; +#endif + +template +requires output_iterator<_OutIt, const _CharT&> +class + // clang-format off + _LIBCPP_TEMPLATE_VIS + _LIBCPP_AVAILABILITY_FORMAT + _LIBCPP_PREFERRED_NAME(format_context) + _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wformat_context)) + // clang-format on + basic_format_context { +public: + using iterator = _OutIt; + using char_type = _CharT; + template + using formatter_type = formatter<_Tp, _CharT>; + + _LIBCPP_HIDE_FROM_ABI basic_format_arg + arg(size_t __id) const noexcept { + return __args_.get(__id); + } +#ifndef _LIBCPP_HAS_NO_LOCALIZATION + _LIBCPP_HIDE_FROM_ABI _VSTD::locale locale() { + if (!__loc_) + __loc_ = _VSTD::locale{}; + return *__loc_; + } +#endif + _LIBCPP_HIDE_FROM_ABI iterator out() { return std::move(__out_it_); } + _LIBCPP_HIDE_FROM_ABI void advance_to(iterator __it) { __out_it_ = std::move(__it); } + +private: + iterator __out_it_; + basic_format_args __args_; +#ifndef _LIBCPP_HAS_NO_LOCALIZATION + + // The Standard doesn't specify how the locale is stored. + // [format.context]/6 + // std::locale locale(); + // Returns: The locale passed to the formatting function if the latter + // takes one, and std::locale() otherwise. + // This is done by storing the locale of the constructor in this optional. If + // locale() is called and the optional has no value the value will be created. + // This allows the implementation to lazily create the locale. + // TODO FMT Validate whether lazy creation is the best solution. + optional<_VSTD::locale> __loc_; + + template + friend _LIBCPP_HIDE_FROM_ABI basic_format_context<__OutIt, __CharT> + __format_context_create(__OutIt, basic_format_args>, + optional<_VSTD::locale>&&); + + // Note: the Standard doesn't specify the required constructors. + _LIBCPP_HIDE_FROM_ABI + explicit basic_format_context(_OutIt __out_it, + basic_format_args __args, + optional<_VSTD::locale>&& __loc) + : __out_it_(_VSTD::move(__out_it)), __args_(__args), + __loc_(_VSTD::move(__loc)) {} +#else + template + friend _LIBCPP_HIDE_FROM_ABI basic_format_context<__OutIt, __CharT> + __format_context_create(__OutIt, basic_format_args>); + + _LIBCPP_HIDE_FROM_ABI + explicit basic_format_context(_OutIt __out_it, + basic_format_args __args) + : __out_it_(_VSTD::move(__out_it)), __args_(__args) {} +#endif +}; + +// A specialization for __retarget_buffer +// +// See __retarget_buffer for the motivation for this specialization. +// +// This context holds a reference to the instance of the basic_format_context +// that is retargeted. It converts a formatting argument when it is requested +// during formatting. It is expected that the usage of the arguments is rare so +// the lookups are not expected to be used often. An alternative would be to +// convert all elements during construction. +// +// The elements of the retargets context are only used when an underlying +// formatter uses a locale specific formatting or an formatting argument is +// part for the format spec. For example +// format("{:256:{}}", input, 8); +// Here the width of an element in input is determined dynamically. +// Note when the top-level element has no width the retargeting is not needed. +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT + basic_format_context::__iterator, _CharT> { +public: + using iterator = typename __format::__retarget_buffer<_CharT>::__iterator; + using char_type = _CharT; + template + using formatter_type = formatter<_Tp, _CharT>; + + template + _LIBCPP_HIDE_FROM_ABI explicit basic_format_context(iterator __out_it, _Context& __ctx) + : __out_it_(std::move(__out_it)), +# ifndef _LIBCPP_HAS_NO_LOCALIZATION + __loc_([](void* __c) { return static_cast<_Context*>(__c)->locale(); }), +# endif + __ctx_(std::addressof(__ctx)), + __arg_([](void* __c, size_t __id) { + return std::visit_format_arg( + [&](auto __arg) -> basic_format_arg { + if constexpr (same_as) + return {}; + else if constexpr (same_as::handle>) + // At the moment it's not possible for formatting to use a re-targeted handle. + // TODO FMT add this when support is needed. + std::__throw_format_error("Re-targeting handle not supported"); + else + return basic_format_arg{ + __format::__determine_arg_t(), + __basic_format_arg_value(__arg)}; + }, + static_cast<_Context*>(__c)->arg(__id)); + }) { + } + + _LIBCPP_HIDE_FROM_ABI basic_format_arg arg(size_t __id) const noexcept { + return __arg_(__ctx_, __id); + } +# ifndef _LIBCPP_HAS_NO_LOCALIZATION + _LIBCPP_HIDE_FROM_ABI _VSTD::locale locale() { return __loc_(__ctx_); } +# endif + _LIBCPP_HIDE_FROM_ABI iterator out() { return std::move(__out_it_); } + _LIBCPP_HIDE_FROM_ABI void advance_to(iterator __it) { __out_it_ = std::move(__it); } + +private: + iterator __out_it_; + +# ifndef _LIBCPP_HAS_NO_LOCALIZATION + std::locale (*__loc_)(void* __ctx); +# endif + + void* __ctx_; + basic_format_arg (*__arg_)(void* __ctx, size_t __id); +}; + +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_context); +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMAT_CONTEXT_H diff --git a/app/src/main/cpp/libcxx/include/__format/format_error.h b/app/src/main/cpp/libcxx/include/__format/format_error.h new file mode 100644 index 0000000..002d1a4 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/format_error.h @@ -0,0 +1,55 @@ +// -*- 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 _LIBCPP___FORMAT_FORMAT_ERROR_H +#define _LIBCPP___FORMAT_FORMAT_ERROR_H + +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +class _LIBCPP_EXCEPTION_ABI format_error : public runtime_error { +public: + _LIBCPP_HIDE_FROM_ABI explicit format_error(const string& __s) + : runtime_error(__s) {} + _LIBCPP_HIDE_FROM_ABI explicit format_error(const char* __s) + : runtime_error(__s) {} + // TODO FMT Remove when format is no longer experimental. + // Avoids linker errors when building the Clang-cl Windows DLL which doesn't + // support the experimental library. +# ifndef _LIBCPP_INLINE_FORMAT_ERROR_DTOR + ~format_error() noexcept override; +# else + ~format_error() noexcept override {} +# endif +}; + +_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void +__throw_format_error(const char* __s) { +#ifndef _LIBCPP_NO_EXCEPTIONS + throw format_error(__s); +#else + (void)__s; + _VSTD::abort(); +#endif +} + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMAT_ERROR_H diff --git a/app/src/main/cpp/libcxx/include/__format/format_functions.h b/app/src/main/cpp/libcxx/include/__format/format_functions.h new file mode 100644 index 0000000..185148c --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/format_functions.h @@ -0,0 +1,661 @@ +// -*- 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 _LIBCPP___FORMAT_FORMAT_FUNCTIONS +#define _LIBCPP___FORMAT_FORMAT_FUNCTIONS + +// TODO FMT This is added to fix Apple back-deployment. +#include +#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) + +#include <__algorithm/clamp.h> +#include <__availability> +#include <__concepts/convertible_to.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__debug> +#include <__format/buffer.h> +#include <__format/format_arg.h> +#include <__format/format_arg_store.h> +#include <__format/format_args.h> +#include <__format/format_context.h> +#include <__format/format_error.h> +#include <__format/format_parse_context.h> +#include <__format/format_string.h> +#include <__format/format_to_n_result.h> +#include <__format/formatter.h> +#include <__format/formatter_bool.h> +#include <__format/formatter_char.h> +#include <__format/formatter_floating_point.h> +#include <__format/formatter_integer.h> +#include <__format/formatter_pointer.h> +#include <__format/formatter_string.h> +#include <__format/parser_std_format_spec.h> +#include <__iterator/back_insert_iterator.h> +#include <__iterator/incrementable_traits.h> +#include <__variant/monostate.h> +#include +#include +#include + +#ifndef _LIBCPP_HAS_NO_LOCALIZATION +#include +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// TODO FMT Evaluate which templates should be external templates. This +// improves the efficiency of the header. However since the header is still +// under heavy development and not all classes are stable it makes no sense +// to do this optimization now. + +using format_args = basic_format_args; +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +using wformat_args = basic_format_args; +#endif + +template +_LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> make_format_args(_Args&&... __args) { + return _VSTD::__format_arg_store<_Context, _Args...>(__args...); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template +_LIBCPP_HIDE_FROM_ABI __format_arg_store make_wformat_args(_Args&&... __args) { + return _VSTD::__format_arg_store(__args...); +} +#endif + +namespace __format { + +/// Helper class parse and handle argument. +/// +/// When parsing a handle which is not enabled the code is ill-formed. +/// This helper uses the parser of the appropriate formatter for the stored type. +template +class _LIBCPP_TEMPLATE_VIS __compile_time_handle { +public: + _LIBCPP_HIDE_FROM_ABI + constexpr void __parse(basic_format_parse_context<_CharT>& __parse_ctx) const { __parse_(__parse_ctx); } + + template + _LIBCPP_HIDE_FROM_ABI constexpr void __enable() { + __parse_ = [](basic_format_parse_context<_CharT>& __parse_ctx) { + formatter<_Tp, _CharT> __f; + __parse_ctx.advance_to(__f.parse(__parse_ctx)); + }; + } + + // Before calling __parse the proper handler needs to be set with __enable. + // The default handler isn't a core constant expression. + _LIBCPP_HIDE_FROM_ABI constexpr __compile_time_handle() + : __parse_([](basic_format_parse_context<_CharT>&) { std::__throw_format_error("Not a handle"); }) {} + +private: + void (*__parse_)(basic_format_parse_context<_CharT>&); +}; + +// Dummy format_context only providing the parts used during constant +// validation of the basic_format_string. +template +struct _LIBCPP_TEMPLATE_VIS __compile_time_basic_format_context { +public: + using char_type = _CharT; + + _LIBCPP_HIDE_FROM_ABI constexpr explicit __compile_time_basic_format_context( + const __arg_t* __args, const __compile_time_handle<_CharT>* __handles, size_t __size) + : __args_(__args), __handles_(__handles), __size_(__size) {} + + // During the compile-time validation nothing needs to be written. + // Therefore all operations of this iterator are a NOP. + struct iterator { + _LIBCPP_HIDE_FROM_ABI constexpr iterator& operator=(_CharT) { return *this; } + _LIBCPP_HIDE_FROM_ABI constexpr iterator& operator*() { return *this; } + _LIBCPP_HIDE_FROM_ABI constexpr iterator operator++(int) { return *this; } + }; + + _LIBCPP_HIDE_FROM_ABI constexpr __arg_t arg(size_t __id) const { + if (__id >= __size_) + std::__throw_format_error("Argument index out of bounds"); + return __args_[__id]; + } + + _LIBCPP_HIDE_FROM_ABI constexpr const __compile_time_handle<_CharT>& __handle(size_t __id) const { + if (__id >= __size_) + std::__throw_format_error("Argument index out of bounds"); + return __handles_[__id]; + } + + _LIBCPP_HIDE_FROM_ABI constexpr iterator out() { return {}; } + _LIBCPP_HIDE_FROM_ABI constexpr void advance_to(iterator) {} + +private: + const __arg_t* __args_; + const __compile_time_handle<_CharT>* __handles_; + size_t __size_; +}; + +_LIBCPP_HIDE_FROM_ABI +constexpr void __compile_time_validate_integral(__arg_t __type) { + switch (__type) { + case __arg_t::__int: + case __arg_t::__long_long: + case __arg_t::__i128: + case __arg_t::__unsigned: + case __arg_t::__unsigned_long_long: + case __arg_t::__u128: + return; + + default: + std::__throw_format_error("Argument isn't an integral type"); + } +} + +// _HasPrecision does the formatter have a precision? +template +_LIBCPP_HIDE_FROM_ABI constexpr void +__compile_time_validate_argument(basic_format_parse_context<_CharT>& __parse_ctx, + __compile_time_basic_format_context<_CharT>& __ctx) { + formatter<_Tp, _CharT> __formatter; + __parse_ctx.advance_to(__formatter.parse(__parse_ctx)); + // [format.string.std]/7 + // ... If the corresponding formatting argument is not of integral type, or + // its value is negative for precision or non-positive for width, an + // exception of type format_error is thrown. + // + // Validate whether the arguments are integrals. + if (__formatter.__parser_.__width_as_arg_) + __format::__compile_time_validate_integral(__ctx.arg(__formatter.__parser_.__width_)); + + if constexpr (_HasPrecision) + if (__formatter.__parser_.__precision_as_arg_) + __format::__compile_time_validate_integral(__ctx.arg(__formatter.__parser_.__precision_)); +} + +// This function is not user facing, so it can directly use the non-standard types of the "variant". +template +_LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_visit_format_arg(basic_format_parse_context<_CharT>& __parse_ctx, + __compile_time_basic_format_context<_CharT>& __ctx, + __arg_t __type) { + switch (__type) { + case __arg_t::__none: + std::__throw_format_error("Invalid argument"); + case __arg_t::__boolean: + return __format::__compile_time_validate_argument<_CharT, bool>(__parse_ctx, __ctx); + case __arg_t::__char_type: + return __format::__compile_time_validate_argument<_CharT, _CharT>(__parse_ctx, __ctx); + case __arg_t::__int: + return __format::__compile_time_validate_argument<_CharT, int>(__parse_ctx, __ctx); + case __arg_t::__long_long: + return __format::__compile_time_validate_argument<_CharT, long long>(__parse_ctx, __ctx); + case __arg_t::__i128: +# ifndef _LIBCPP_HAS_NO_INT128 + return __format::__compile_time_validate_argument<_CharT, __int128_t>(__parse_ctx, __ctx); +# else + std::__throw_format_error("Invalid argument"); +# endif + return; + case __arg_t::__unsigned: + return __format::__compile_time_validate_argument<_CharT, unsigned>(__parse_ctx, __ctx); + case __arg_t::__unsigned_long_long: + return __format::__compile_time_validate_argument<_CharT, unsigned long long>(__parse_ctx, __ctx); + case __arg_t::__u128: +# ifndef _LIBCPP_HAS_NO_INT128 + return __format::__compile_time_validate_argument<_CharT, __uint128_t>(__parse_ctx, __ctx); +# else + std::__throw_format_error("Invalid argument"); +# endif + return; + case __arg_t::__float: + return __format::__compile_time_validate_argument<_CharT, float, true>(__parse_ctx, __ctx); + case __arg_t::__double: + return __format::__compile_time_validate_argument<_CharT, double, true>(__parse_ctx, __ctx); + case __arg_t::__long_double: + return __format::__compile_time_validate_argument<_CharT, long double, true>(__parse_ctx, __ctx); + case __arg_t::__const_char_type_ptr: + return __format::__compile_time_validate_argument<_CharT, const _CharT*, true>(__parse_ctx, __ctx); + case __arg_t::__string_view: + return __format::__compile_time_validate_argument<_CharT, basic_string_view<_CharT>, true>(__parse_ctx, __ctx); + case __arg_t::__ptr: + return __format::__compile_time_validate_argument<_CharT, const void*>(__parse_ctx, __ctx); + case __arg_t::__handle: + std::__throw_format_error("Handle should use __compile_time_validate_handle_argument"); + } + std::__throw_format_error("Invalid argument"); +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr const _CharT* +__handle_replacement_field(const _CharT* __begin, const _CharT* __end, + _ParseCtx& __parse_ctx, _Ctx& __ctx) { + __format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __parse_ctx); + + bool __parse = *__r.__ptr == _CharT(':'); + switch (*__r.__ptr) { + case _CharT(':'): + // The arg-id has a format-specifier, advance the input to the format-spec. + __parse_ctx.advance_to(__r.__ptr + 1); + break; + case _CharT('}'): + // The arg-id has no format-specifier. + __parse_ctx.advance_to(__r.__ptr); + break; + default: + std::__throw_format_error("The replacement field arg-id should terminate at a ':' or '}'"); + } + + if constexpr (same_as<_Ctx, __compile_time_basic_format_context<_CharT>>) { + __arg_t __type = __ctx.arg(__r.__value); + if (__type == __arg_t::__handle) + __ctx.__handle(__r.__value).__parse(__parse_ctx); + else + __format::__compile_time_visit_format_arg(__parse_ctx, __ctx, __type); + } else + _VSTD::__visit_format_arg( + [&](auto __arg) { + if constexpr (same_as) + std::__throw_format_error("Argument index out of bounds"); + else if constexpr (same_as::handle>) + __arg.format(__parse_ctx, __ctx); + else { + formatter __formatter; + if (__parse) + __parse_ctx.advance_to(__formatter.parse(__parse_ctx)); + __ctx.advance_to(__formatter.format(__arg, __ctx)); + } + }, + __ctx.arg(__r.__value)); + + __begin = __parse_ctx.begin(); + if (__begin == __end || *__begin != _CharT('}')) + std::__throw_format_error("The replacement field misses a terminating '}'"); + + return ++__begin; +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr typename _Ctx::iterator +__vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) { + using _CharT = typename _ParseCtx::char_type; + static_assert(same_as); + + const _CharT* __begin = __parse_ctx.begin(); + const _CharT* __end = __parse_ctx.end(); + typename _Ctx::iterator __out_it = __ctx.out(); + while (__begin != __end) { + switch (*__begin) { + case _CharT('{'): + ++__begin; + if (__begin == __end) + std::__throw_format_error("The format string terminates at a '{'"); + + if (*__begin != _CharT('{')) [[likely]] { + __ctx.advance_to(_VSTD::move(__out_it)); + __begin = + __format::__handle_replacement_field(__begin, __end, __parse_ctx, __ctx); + __out_it = __ctx.out(); + + // The output is written and __begin points to the next character. So + // start the next iteration. + continue; + } + // The string is an escape character. + break; + + case _CharT('}'): + ++__begin; + if (__begin == __end || *__begin != _CharT('}')) + std::__throw_format_error("The format string contains an invalid escape sequence"); + + break; + } + + // Copy the character to the output verbatim. + *__out_it++ = *__begin++; + } + return __out_it; +} + +} // namespace __format + +template +struct _LIBCPP_TEMPLATE_VIS basic_format_string { + template + requires convertible_to> + consteval basic_format_string(const _Tp& __str) : __str_{__str} { + __format::__vformat_to(basic_format_parse_context<_CharT>{__str_, sizeof...(_Args)}, + _Context{__types_.data(), __handles_.data(), sizeof...(_Args)}); + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT constexpr basic_string_view<_CharT> get() const noexcept { + return __str_; + } + +private: + basic_string_view<_CharT> __str_; + + using _Context = __format::__compile_time_basic_format_context<_CharT>; + + static constexpr array<__format::__arg_t, sizeof...(_Args)> __types_{ + __format::__determine_arg_t<_Context, remove_cvref_t<_Args>>()...}; + + // TODO FMT remove this work-around when the AIX ICE has been resolved. +# if defined(_AIX) && defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 1400 + template + static constexpr __format::__compile_time_handle<_CharT> __get_handle() { + __format::__compile_time_handle<_CharT> __handle; + if (__format::__determine_arg_t<_Context, _Tp>() == __format::__arg_t::__handle) + __handle.template __enable<_Tp>(); + + return __handle; + } + + static constexpr array<__format::__compile_time_handle<_CharT>, sizeof...(_Args)> __handles_{ + __get_handle<_Args>()...}; +# else + static constexpr array<__format::__compile_time_handle<_CharT>, sizeof...(_Args)> __handles_{[] { + using _Tp = remove_cvref_t<_Args>; + __format::__compile_time_handle<_CharT> __handle; + if (__format::__determine_arg_t<_Context, _Tp>() == __format::__arg_t::__handle) + __handle.template __enable<_Tp>(); + + return __handle; + }()...}; +# endif +}; + +template +using format_string = basic_format_string...>; + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template +using wformat_string = basic_format_string...>; +#endif + +template +requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt + __vformat_to( + _OutIt __out_it, basic_string_view<_CharT> __fmt, + basic_format_args> __args) { + if constexpr (same_as<_OutIt, _FormatOutIt>) + return _VSTD::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(_VSTD::move(__out_it), __args)); + else { + __format::__format_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it)}; + _VSTD::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args)); + return _VSTD::move(__buffer).__out_it(); + } +} + +// The function is _LIBCPP_ALWAYS_INLINE since the compiler is bad at inlining +// https://reviews.llvm.org/D110499#inline-1180704 +// TODO FMT Evaluate whether we want to file a Clang bug report regarding this. +template _OutIt> +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt +vformat_to(_OutIt __out_it, string_view __fmt, format_args __args) { + return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template _OutIt> +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt +vformat_to(_OutIt __out_it, wstring_view __fmt, wformat_args __args) { + return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args); +} +#endif + +template _OutIt, class... _Args> +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt +format_to(_OutIt __out_it, format_string<_Args...> __fmt, _Args&&... __args) { + return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt.get(), + _VSTD::make_format_args(__args...)); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template _OutIt, class... _Args> +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt +format_to(_OutIt __out_it, wformat_string<_Args...> __fmt, _Args&&... __args) { + return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt.get(), + _VSTD::make_wformat_args(__args...)); +} +#endif + +_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string +vformat(string_view __fmt, format_args __args) { + string __res; + _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args); + return __res; +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring +vformat(wstring_view __fmt, wformat_args __args) { + wstring __res; + _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args); + return __res; +} +#endif + +template +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string format(format_string<_Args...> __fmt, + _Args&&... __args) { + return _VSTD::vformat(__fmt.get(), _VSTD::make_format_args(__args...)); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring +format(wformat_string<_Args...> __fmt, _Args&&... __args) { + return _VSTD::vformat(__fmt.get(), _VSTD::make_wformat_args(__args...)); +} +#endif + +template +_LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, + basic_string_view<_CharT> __fmt, + basic_format_args<_Context> __args) { + __format::__format_to_n_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it), __n}; + _VSTD::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args)); + return _VSTD::move(__buffer).__result(); +} + +template _OutIt, class... _Args> +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> +format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, format_string<_Args...> __fmt, _Args&&... __args) { + return _VSTD::__vformat_to_n(_VSTD::move(__out_it), __n, __fmt.get(), _VSTD::make_format_args(__args...)); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template _OutIt, class... _Args> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> +format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, wformat_string<_Args...> __fmt, + _Args&&... __args) { + return _VSTD::__vformat_to_n(_VSTD::move(__out_it), __n, __fmt.get(), _VSTD::make_wformat_args(__args...)); +} +#endif + +template +_LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(basic_string_view<_CharT> __fmt, auto __args) { + __format::__formatted_size_buffer<_CharT> __buffer; + _VSTD::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args)); + return _VSTD::move(__buffer).__result(); +} + +template +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t +formatted_size(format_string<_Args...> __fmt, _Args&&... __args) { + return _VSTD::__vformatted_size(__fmt.get(), basic_format_args{_VSTD::make_format_args(__args...)}); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t +formatted_size(wformat_string<_Args...> __fmt, _Args&&... __args) { + return _VSTD::__vformatted_size(__fmt.get(), basic_format_args{_VSTD::make_wformat_args(__args...)}); +} +#endif + +#ifndef _LIBCPP_HAS_NO_LOCALIZATION + +template +requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt + __vformat_to( + _OutIt __out_it, locale __loc, basic_string_view<_CharT> __fmt, + basic_format_args> __args) { + if constexpr (same_as<_OutIt, _FormatOutIt>) + return _VSTD::__format::__vformat_to( + basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(_VSTD::move(__out_it), __args, _VSTD::move(__loc))); + else { + __format::__format_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it)}; + _VSTD::__format::__vformat_to( + basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args, _VSTD::move(__loc))); + return _VSTD::move(__buffer).__out_it(); + } +} + +template _OutIt> +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to( + _OutIt __out_it, locale __loc, string_view __fmt, format_args __args) { + return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, + __args); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template _OutIt> +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to( + _OutIt __out_it, locale __loc, wstring_view __fmt, wformat_args __args) { + return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, + __args); +} +#endif + +template _OutIt, class... _Args> +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt +format_to(_OutIt __out_it, locale __loc, format_string<_Args...> __fmt, _Args&&... __args) { + return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt.get(), + _VSTD::make_format_args(__args...)); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template _OutIt, class... _Args> +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt +format_to(_OutIt __out_it, locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) { + return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt.get(), + _VSTD::make_wformat_args(__args...)); +} +#endif + +_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string +vformat(locale __loc, string_view __fmt, format_args __args) { + string __res; + _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt, + __args); + return __res; +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring +vformat(locale __loc, wstring_view __fmt, wformat_args __args) { + wstring __res; + _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt, + __args); + return __res; +} +#endif + +template +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string format(locale __loc, + format_string<_Args...> __fmt, + _Args&&... __args) { + return _VSTD::vformat(_VSTD::move(__loc), __fmt.get(), + _VSTD::make_format_args(__args...)); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring +format(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) { + return _VSTD::vformat(_VSTD::move(__loc), __fmt.get(), + _VSTD::make_wformat_args(__args...)); +} +#endif + +template +_LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, + locale __loc, basic_string_view<_CharT> __fmt, + basic_format_args<_Context> __args) { + __format::__format_to_n_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it), __n}; + _VSTD::__format::__vformat_to( + basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args, _VSTD::move(__loc))); + return _VSTD::move(__buffer).__result(); +} + +template _OutIt, class... _Args> +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> +format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, format_string<_Args...> __fmt, + _Args&&... __args) { + return _VSTD::__vformat_to_n(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt.get(), + _VSTD::make_format_args(__args...)); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template _OutIt, class... _Args> +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> +format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, wformat_string<_Args...> __fmt, + _Args&&... __args) { + return _VSTD::__vformat_to_n(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt.get(), + _VSTD::make_wformat_args(__args...)); +} +#endif + +template +_LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(locale __loc, basic_string_view<_CharT> __fmt, auto __args) { + __format::__formatted_size_buffer<_CharT> __buffer; + _VSTD::__format::__vformat_to( + basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args, _VSTD::move(__loc))); + return _VSTD::move(__buffer).__result(); +} + +template +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t +formatted_size(locale __loc, format_string<_Args...> __fmt, _Args&&... __args) { + return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt.get(), basic_format_args{_VSTD::make_format_args(__args...)}); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t +formatted_size(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) { + return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt.get(), basic_format_args{_VSTD::make_wformat_args(__args...)}); +} +#endif + +#endif // _LIBCPP_HAS_NO_LOCALIZATION + + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) + +#endif // _LIBCPP___FORMAT_FORMAT_FUNCTIONS diff --git a/app/src/main/cpp/libcxx/include/__format/format_fwd.h b/app/src/main/cpp/libcxx/include/__format/format_fwd.h new file mode 100644 index 0000000..f7c72e2 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/format_fwd.h @@ -0,0 +1,39 @@ +// -*- 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 _LIBCPP___FORMAT_FORMAT_FWD_H +#define _LIBCPP___FORMAT_FORMAT_FWD_H + +#include <__availability> +#include <__config> +#include <__iterator/concepts.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_arg; + +template + requires output_iterator<_OutIt, const _CharT&> +class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_context; + +template +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter; + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMAT_FWD_H diff --git a/app/src/main/cpp/libcxx/include/__format/format_parse_context.h b/app/src/main/cpp/libcxx/include/__format/format_parse_context.h new file mode 100644 index 0000000..30e3a7d --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/format_parse_context.h @@ -0,0 +1,100 @@ +// -*- 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 _LIBCPP___FORMAT_FORMAT_PARSE_CONTEXT_H +#define _LIBCPP___FORMAT_FORMAT_PARSE_CONTEXT_H + +#include <__config> +#include <__format/format_error.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_parse_context { +public: + using char_type = _CharT; + using const_iterator = typename basic_string_view<_CharT>::const_iterator; + using iterator = const_iterator; + + _LIBCPP_HIDE_FROM_ABI + constexpr explicit basic_format_parse_context(basic_string_view<_CharT> __fmt, + size_t __num_args = 0) noexcept + : __begin_(__fmt.begin()), + __end_(__fmt.end()), + __indexing_(__unknown), + __next_arg_id_(0), + __num_args_(__num_args) {} + + basic_format_parse_context(const basic_format_parse_context&) = delete; + basic_format_parse_context& + operator=(const basic_format_parse_context&) = delete; + + _LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const noexcept { + return __begin_; + } + _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const noexcept { + return __end_; + } + _LIBCPP_HIDE_FROM_ABI constexpr void advance_to(const_iterator __it) { + __begin_ = __it; + } + + _LIBCPP_HIDE_FROM_ABI constexpr size_t next_arg_id() { + if (__indexing_ == __manual) + std::__throw_format_error("Using automatic argument numbering in manual argument numbering mode"); + + if (__indexing_ == __unknown) + __indexing_ = __automatic; + return __next_arg_id_++; + } + _LIBCPP_HIDE_FROM_ABI constexpr void check_arg_id(size_t __id) { + if (__indexing_ == __automatic) + std::__throw_format_error("Using manual argument numbering in automatic argument numbering mode"); + + if (__indexing_ == __unknown) + __indexing_ = __manual; + + // Throws an exception to make the expression a non core constant + // expression as required by: + // [format.parse.ctx]/11 + // Remarks: Call expressions where id >= num_args_ are not core constant + // expressions ([expr.const]). + // Note: the Throws clause [format.parse.ctx]/10 doesn't specify the + // behavior when id >= num_args_. + if (is_constant_evaluated() && __id >= __num_args_) + std::__throw_format_error("Argument index outside the valid range"); + } + +private: + iterator __begin_; + iterator __end_; + enum _Indexing { __unknown, __manual, __automatic }; + _Indexing __indexing_; + size_t __next_arg_id_; + size_t __num_args_; +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_parse_context); + +using format_parse_context = basic_format_parse_context; +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +using wformat_parse_context = basic_format_parse_context; +#endif + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMAT_PARSE_CONTEXT_H diff --git a/app/src/main/cpp/libcxx/include/__format/format_string.h b/app/src/main/cpp/libcxx/include/__format/format_string.h new file mode 100644 index 0000000..d9caf86 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/format_string.h @@ -0,0 +1,163 @@ +// -*- 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 _LIBCPP___FORMAT_FORMAT_STRING_H +#define _LIBCPP___FORMAT_FORMAT_STRING_H + +#include <__assert> +#include <__config> +#include <__format/format_error.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __format { + +template +struct _LIBCPP_TEMPLATE_VIS __parse_number_result { + const _CharT* __ptr; + uint32_t __value; +}; + +template +__parse_number_result(const _CharT*, uint32_t) -> __parse_number_result<_CharT>; + +template +_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> +__parse_number(const _CharT* __begin, const _CharT* __end); + +/** + * The maximum value of a numeric argument. + * + * This is used for: + * * arg-id + * * width as value or arg-id. + * * precision as value or arg-id. + * + * The value is compatible with the maximum formatting width and precision + * using the `%*` syntax on a 32-bit system. + */ +inline constexpr uint32_t __number_max = INT32_MAX; + +namespace __detail { +template +_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> +__parse_zero(const _CharT* __begin, const _CharT*, auto& __parse_ctx) { + __parse_ctx.check_arg_id(0); + return {++__begin, 0}; // can never be larger than the maximum. +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> +__parse_automatic(const _CharT* __begin, const _CharT*, auto& __parse_ctx) { + size_t __value = __parse_ctx.next_arg_id(); + _LIBCPP_ASSERT(__value <= __number_max, + "Compilers don't support this number of arguments"); + + return {__begin, uint32_t(__value)}; +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> +__parse_manual(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) { + __parse_number_result<_CharT> __r = __format::__parse_number(__begin, __end); + __parse_ctx.check_arg_id(__r.__value); + return __r; +} + +} // namespace __detail + +/** + * Parses a number. + * + * The number is used for the 31-bit values @em width and @em precision. This + * allows a maximum value of 2147483647. + */ +template +_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> +__parse_number(const _CharT* __begin, const _CharT* __end_input) { + static_assert(__format::__number_max == INT32_MAX, + "The algorithm is implemented based on this value."); + /* + * Limit the input to 9 digits, otherwise we need two checks during every + * iteration: + * - Are we at the end of the input? + * - Does the value exceed width of an uint32_t? (Switching to uint64_t would + * have the same issue, but with a higher maximum.) + */ + const _CharT* __end = __end_input - __begin > 9 ? __begin + 9 : __end_input; + uint32_t __value = *__begin - _CharT('0'); + while (++__begin != __end) { + if (*__begin < _CharT('0') || *__begin > _CharT('9')) + return {__begin, __value}; + + __value = __value * 10 + *__begin - _CharT('0'); + } + + if (__begin != __end_input && *__begin >= _CharT('0') && + *__begin <= _CharT('9')) { + + /* + * There are more than 9 digits, do additional validations: + * - Does the 10th digit exceed the maximum allowed value? + * - Are there more than 10 digits? + * (More than 10 digits always overflows the maximum.) + */ + uint64_t __v = uint64_t(__value) * 10 + *__begin++ - _CharT('0'); + if (__v > __number_max || + (__begin != __end_input && *__begin >= _CharT('0') && + *__begin <= _CharT('9'))) + std::__throw_format_error("The numeric value of the format-spec is too large"); + + __value = __v; + } + + return {__begin, __value}; +} + +/** + * Multiplexer for all parse functions. + * + * The parser will return a pointer beyond the last consumed character. This + * should be the closing '}' of the arg-id. + */ +template +_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> +__parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) { + switch (*__begin) { + case _CharT('0'): + return __detail::__parse_zero(__begin, __end, __parse_ctx); + + case _CharT(':'): + // This case is conditionally valid. It's allowed in an arg-id in the + // replacement-field, but not in the std-format-spec. The caller can + // provide a better diagnostic, so accept it here unconditionally. + case _CharT('}'): + return __detail::__parse_automatic(__begin, __end, __parse_ctx); + } + if (*__begin < _CharT('0') || *__begin > _CharT('9')) + std::__throw_format_error("The arg-id of the format-spec starts with an invalid character"); + + return __detail::__parse_manual(__begin, __end, __parse_ctx); +} + +} // namespace __format + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMAT_STRING_H diff --git a/app/src/main/cpp/libcxx/include/__format/format_to_n_result.h b/app/src/main/cpp/libcxx/include/__format/format_to_n_result.h new file mode 100644 index 0000000..f1ed9a0 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/format_to_n_result.h @@ -0,0 +1,35 @@ +// -*- 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 _LIBCPP___FORMAT_FORMAT_TO_N_RESULT_H +#define _LIBCPP___FORMAT_FORMAT_TO_N_RESULT_H + +#include <__config> +#include <__iterator/incrementable_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +struct _LIBCPP_TEMPLATE_VIS format_to_n_result { + _OutIt out; + iter_difference_t<_OutIt> size; +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(format_to_n_result); + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMAT_TO_N_RESULT_H diff --git a/app/src/main/cpp/libcxx/include/__format/formatter.h b/app/src/main/cpp/libcxx/include/__format/formatter.h new file mode 100644 index 0000000..900a09a --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/formatter.h @@ -0,0 +1,54 @@ +// -*- 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 _LIBCPP___FORMAT_FORMATTER_H +#define _LIBCPP___FORMAT_FORMATTER_H + +#include <__availability> +#include <__config> +#include <__format/format_fwd.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +/// The default formatter template. +/// +/// [format.formatter.spec]/5 +/// If F is a disabled specialization of formatter, these values are false: +/// - is_default_constructible_v, +/// - is_copy_constructible_v, +/// - is_move_constructible_v, +/// - is_copy_assignable, and +/// - is_move_assignable. +template +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter { + formatter() = delete; + formatter(const formatter&) = delete; + formatter& operator=(const formatter&) = delete; +}; + +# if _LIBCPP_STD_VER > 20 + +template +_LIBCPP_HIDE_FROM_ABI constexpr void __set_debug_format(_Tp& __formatter) { + if constexpr (requires { __formatter.set_debug_format(); }) + __formatter.set_debug_format(); +} + +# endif // _LIBCPP_STD_VER > 20 +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMATTER_H diff --git a/app/src/main/cpp/libcxx/include/__format/formatter_bool.h b/app/src/main/cpp/libcxx/include/__format/formatter_bool.h new file mode 100644 index 0000000..0d005a1 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/formatter_bool.h @@ -0,0 +1,78 @@ +// -*- 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 _LIBCPP___FORMAT_FORMATTER_BOOL_H +#define _LIBCPP___FORMAT_FORMATTER_BOOL_H + +#include <__algorithm/copy.h> +#include <__availability> +#include <__config> +#include <__debug> +#include <__format/concepts.h> +#include <__format/format_error.h> +#include <__format/format_parse_context.h> +#include <__format/formatter.h> +#include <__format/formatter_integral.h> +#include <__format/parser_std_format_spec.h> +#include <__utility/unreachable.h> +#include + +#ifndef _LIBCPP_HAS_NO_LOCALIZATION +# include +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter { +public: + _LIBCPP_HIDE_FROM_ABI constexpr auto + parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) { + auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_integral); + __format_spec::__process_parsed_bool(__parser_); + return __result; + } + + _LIBCPP_HIDE_FROM_ABI auto format(bool __value, auto& __ctx) const -> decltype(__ctx.out()) { + switch (__parser_.__type_) { + case __format_spec::__type::__default: + case __format_spec::__type::__string: + return __formatter::__format_bool(__value, __ctx, __parser_.__get_parsed_std_specifications(__ctx)); + + case __format_spec::__type::__binary_lower_case: + case __format_spec::__type::__binary_upper_case: + case __format_spec::__type::__octal: + case __format_spec::__type::__decimal: + case __format_spec::__type::__hexadecimal_lower_case: + case __format_spec::__type::__hexadecimal_upper_case: + // Promotes bool to an integral type. This reduces the number of + // instantiations of __format_integer reducing code size. + return __formatter::__format_integer( + static_cast(__value), __ctx, __parser_.__get_parsed_std_specifications(__ctx)); + + default: + _LIBCPP_ASSERT(false, "The parse function should have validated the type"); + __libcpp_unreachable(); + } + } + + __format_spec::__parser<_CharT> __parser_; +}; + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMATTER_BOOL_H diff --git a/app/src/main/cpp/libcxx/include/__format/formatter_char.h b/app/src/main/cpp/libcxx/include/__format/formatter_char.h new file mode 100644 index 0000000..8a92e74 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/formatter_char.h @@ -0,0 +1,93 @@ +// -*- 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 _LIBCPP___FORMAT_FORMATTER_CHAR_H +#define _LIBCPP___FORMAT_FORMATTER_CHAR_H + +#include <__availability> +#include <__concepts/same_as.h> +#include <__config> +#include <__format/concepts.h> +#include <__format/format_parse_context.h> +#include <__format/formatter.h> +#include <__format/formatter_integral.h> +#include <__format/formatter_output.h> +#include <__format/parser_std_format_spec.h> +#include <__type_traits/conditional.h> +#include <__type_traits/is_signed.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_char { +public: + _LIBCPP_HIDE_FROM_ABI constexpr auto + parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) { + auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_integral); + __format_spec::__process_parsed_char(__parser_); + return __result; + } + + _LIBCPP_HIDE_FROM_ABI auto format(_CharT __value, auto& __ctx) const -> decltype(__ctx.out()) { + if (__parser_.__type_ == __format_spec::__type::__default || __parser_.__type_ == __format_spec::__type::__char) + return __formatter::__format_char(__value, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx)); + +# if _LIBCPP_STD_VER > 20 + if (__parser_.__type_ == __format_spec::__type::__debug) + return __formatter::__format_escaped_char(__value, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx)); +# endif + + if constexpr (sizeof(_CharT) <= sizeof(int)) + // Promotes _CharT to an integral type. This reduces the number of + // instantiations of __format_integer reducing code size. + return __formatter::__format_integer( + static_cast, int, unsigned>>(__value), + __ctx, + __parser_.__get_parsed_std_specifications(__ctx)); + else + return __formatter::__format_integer(__value, __ctx, __parser_.__get_parsed_std_specifications(__ctx)); + } + + _LIBCPP_HIDE_FROM_ABI auto format(char __value, auto& __ctx) const -> decltype(__ctx.out()) + requires(same_as<_CharT, wchar_t>) + { + return format(static_cast(__value), __ctx); + } + +# if _LIBCPP_STD_VER > 20 + _LIBCPP_HIDE_FROM_ABI constexpr void set_debug_format() { __parser_.__type_ = __format_spec::__type::__debug; } +# endif + + __format_spec::__parser<_CharT> __parser_; +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter : public __formatter_char {}; + +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template <> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter : public __formatter_char {}; + +template <> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter : public __formatter_char { +}; + +# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMATTER_CHAR_H diff --git a/app/src/main/cpp/libcxx/include/__format/formatter_floating_point.h b/app/src/main/cpp/libcxx/include/__format/formatter_floating_point.h new file mode 100644 index 0000000..a544b53 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/formatter_floating_point.h @@ -0,0 +1,757 @@ +// -*- 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 _LIBCPP___FORMAT_FORMATTER_FLOATING_POINT_H +#define _LIBCPP___FORMAT_FORMATTER_FLOATING_POINT_H + +#include <__algorithm/copy_n.h> +#include <__algorithm/find.h> +#include <__algorithm/max.h> +#include <__algorithm/min.h> +#include <__algorithm/rotate.h> +#include <__algorithm/transform.h> +#include <__concepts/arithmetic.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__format/concepts.h> +#include <__format/format_parse_context.h> +#include <__format/formatter.h> +#include <__format/formatter_integral.h> +#include <__format/formatter_output.h> +#include <__format/parser_std_format_spec.h> +#include <__memory/allocator.h> +#include <__utility/move.h> +#include <__utility/unreachable.h> +#include + +#ifndef _LIBCPP_HAS_NO_LOCALIZATION +# include +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __formatter { + +template +_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value) { + to_chars_result __r = _VSTD::to_chars(__first, __last, __value); + _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); + return __r.ptr; +} + +template +_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, chars_format __fmt) { + to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __fmt); + _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); + return __r.ptr; +} + +template +_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, chars_format __fmt, int __precision) { + to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __fmt, __precision); + _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); + return __r.ptr; +} + +// https://en.cppreference.com/w/cpp/language/types#cite_note-1 +// float min subnormal: +/-0x1p-149 max: +/- 3.402,823,4 10^38 +// double min subnormal: +/-0x1p-1074 max +/- 1.797,693,134,862,315,7 10^308 +// long double (x86) min subnormal: +/-0x1p-16446 max: +/- 1.189,731,495,357,231,765,021 10^4932 +// +// The maximum number of digits required for the integral part is based on the +// maximum's value power of 10. Every power of 10 requires one additional +// decimal digit. +// The maximum number of digits required for the fractional part is based on +// the minimal subnormal hexadecimal output's power of 10. Every division of a +// fraction's binary 1 by 2, requires one additional decimal digit. +// +// The maximum size of a formatted value depends on the selected output format. +// Ignoring the fact the format string can request a precision larger than the +// values maximum required, these values are: +// +// sign 1 code unit +// __max_integral +// radix point 1 code unit +// __max_fractional +// exponent character 1 code unit +// sign 1 code unit +// __max_fractional_value +// ----------------------------------- +// total 4 code units extra required. +// +// TODO FMT Optimize the storage to avoid storing digits that are known to be zero. +// https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/ + +// TODO FMT Add long double specialization when to_chars has proper long double support. +template +struct __traits; + +template +_LIBCPP_HIDE_FROM_ABI constexpr size_t __float_buffer_size(int __precision) { + using _Traits = __traits<_Fp>; + return 4 + _Traits::__max_integral + __precision + _Traits::__max_fractional_value; +} + +template <> +struct __traits { + static constexpr int __max_integral = 38; + static constexpr int __max_fractional = 149; + static constexpr int __max_fractional_value = 3; + static constexpr size_t __stack_buffer_size = 256; + + static constexpr int __hex_precision_digits = 3; +}; + +template <> +struct __traits { + static constexpr int __max_integral = 308; + static constexpr int __max_fractional = 1074; + static constexpr int __max_fractional_value = 4; + static constexpr size_t __stack_buffer_size = 1024; + + static constexpr int __hex_precision_digits = 4; +}; + +/// Helper class to store the conversion buffer. +/// +/// Depending on the maxium size required for a value, the buffer is allocated +/// on the stack or the heap. +template +class _LIBCPP_TEMPLATE_VIS __float_buffer { + using _Traits = __traits<_Fp>; + +public: + // TODO FMT Improve this constructor to do a better estimate. + // When using a scientific formatting with a precision of 6 a stack buffer + // will always suffice. At the moment that isn't important since floats and + // doubles use a stack buffer, unless the precision used in the format string + // is large. + // When supporting long doubles the __max_integral part becomes 4932 which + // may be too much for some platforms. For these cases a better estimate is + // required. + explicit _LIBCPP_HIDE_FROM_ABI __float_buffer(int __precision) + : __precision_(__precision != -1 ? __precision : _Traits::__max_fractional) { + + // When the precision is larger than _Traits::__max_fractional the digits in + // the range (_Traits::__max_fractional, precision] will contain the value + // zero. There's no need to request to_chars to write these zeros: + // - When the value is large a temporary heap buffer needs to be allocated. + // - When to_chars writes the values they need to be "copied" to the output: + // - char: std::fill on the output iterator is faster than std::copy. + // - wchar_t: same argument as char, but additional std::copy won't work. + // The input is always a char buffer, so every char in the buffer needs + // to be converted from a char to a wchar_t. + if (__precision_ > _Traits::__max_fractional) { + __num_trailing_zeros_ = __precision_ - _Traits::__max_fractional; + __precision_ = _Traits::__max_fractional; + } + + __size_ = __formatter::__float_buffer_size<_Fp>(__precision_); + if (__size_ > _Traits::__stack_buffer_size) + // The allocated buffer's contents don't need initialization. + __begin_ = allocator{}.allocate(__size_); + else + __begin_ = __buffer_; + } + + _LIBCPP_HIDE_FROM_ABI ~__float_buffer() { + if (__size_ > _Traits::__stack_buffer_size) + allocator{}.deallocate(__begin_, __size_); + } + _LIBCPP_HIDE_FROM_ABI __float_buffer(const __float_buffer&) = delete; + _LIBCPP_HIDE_FROM_ABI __float_buffer& operator=(const __float_buffer&) = delete; + + _LIBCPP_HIDE_FROM_ABI char* begin() const { return __begin_; } + _LIBCPP_HIDE_FROM_ABI char* end() const { return __begin_ + __size_; } + + _LIBCPP_HIDE_FROM_ABI int __precision() const { return __precision_; } + _LIBCPP_HIDE_FROM_ABI int __num_trailing_zeros() const { return __num_trailing_zeros_; } + _LIBCPP_HIDE_FROM_ABI void __remove_trailing_zeros() { __num_trailing_zeros_ = 0; } + _LIBCPP_HIDE_FROM_ABI void __add_trailing_zeros(int __zeros) { __num_trailing_zeros_ += __zeros; } + +private: + int __precision_; + int __num_trailing_zeros_{0}; + size_t __size_; + char* __begin_; + char __buffer_[_Traits::__stack_buffer_size]; +}; + +struct __float_result { + /// Points at the beginning of the integral part in the buffer. + /// + /// When there's no sign character this points at the start of the buffer. + char* __integral; + + /// Points at the radix point, when not present it's the same as \ref __last. + char* __radix_point; + + /// Points at the exponent character, when not present it's the same as \ref __last. + char* __exponent; + + /// Points beyond the last written element in the buffer. + char* __last; +}; + +/// Finds the position of the exponent character 'e' at the end of the buffer. +/// +/// Assuming there is an exponent the input will terminate with +/// eSdd and eSdddd (S = sign, d = digit) +/// +/// \returns a pointer to the exponent or __last when not found. +constexpr inline _LIBCPP_HIDE_FROM_ABI char* __find_exponent(char* __first, char* __last) { + ptrdiff_t __size = __last - __first; + if (__size >= 4) { + __first = __last - _VSTD::min(__size, ptrdiff_t(6)); + for (; __first != __last - 3; ++__first) { + if (*__first == 'e') + return __first; + } + } + return __last; +} + +template +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_default(const __float_buffer<_Fp>& __buffer, _Tp __value, + char* __integral) { + __float_result __result; + __result.__integral = __integral; + __result.__last = __formatter::__to_buffer(__integral, __buffer.end(), __value); + + __result.__exponent = __formatter::__find_exponent(__result.__integral, __result.__last); + + // Constrains: + // - There's at least one decimal digit before the radix point. + // - The radix point, when present, is placed before the exponent. + __result.__radix_point = _VSTD::find(__result.__integral + 1, __result.__exponent, '.'); + + // When the radix point isn't found its position is the exponent instead of + // __result.__last. + if (__result.__radix_point == __result.__exponent) + __result.__radix_point = __result.__last; + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent == __result.__last || *__result.__exponent == 'e'), + "Post-condition failure."); + // clang-format on + + return __result; +} + +template +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_lower_case(const __float_buffer<_Fp>& __buffer, + _Tp __value, int __precision, + char* __integral) { + __float_result __result; + __result.__integral = __integral; + if (__precision == -1) + __result.__last = __formatter::__to_buffer(__integral, __buffer.end(), __value, chars_format::hex); + else + __result.__last = __formatter::__to_buffer(__integral, __buffer.end(), __value, chars_format::hex, __precision); + + // H = one or more hex-digits + // S = sign + // D = one or more decimal-digits + // When the fractional part is zero and no precision the output is 0p+0 + // else the output is 0.HpSD + // So testing the second position can differentiate between these two cases. + char* __first = __integral + 1; + if (*__first == '.') { + __result.__radix_point = __first; + // One digit is the minimum + // 0.hpSd + // ^-- last + // ^---- integral = end of search + // ^-------- start of search + // 0123456 + // + // Four digits is the maximum + // 0.hpSdddd + // ^-- last + // ^---- integral = end of search + // ^-------- start of search + // 0123456789 + static_assert(__traits<_Fp>::__hex_precision_digits <= 4, "Guard against possible underflow."); + + char* __last = __result.__last - 2; + __first = __last - __traits<_Fp>::__hex_precision_digits; + __result.__exponent = _VSTD::find(__first, __last, 'p'); + } else { + __result.__radix_point = __result.__last; + __result.__exponent = __first; + } + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent != __result.__last && *__result.__exponent == 'p'), + "Post-condition failure."); + // clang-format on + + return __result; +} + +template +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_upper_case(const __float_buffer<_Fp>& __buffer, + _Tp __value, int __precision, + char* __integral) { + __float_result __result = + __formatter::__format_buffer_hexadecimal_lower_case(__buffer, __value, __precision, __integral); + _VSTD::transform(__result.__integral, __result.__exponent, __result.__integral, __hex_to_upper); + *__result.__exponent = 'P'; + return __result; +} + +template +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_lower_case(const __float_buffer<_Fp>& __buffer, + _Tp __value, int __precision, + char* __integral) { + __float_result __result; + __result.__integral = __integral; + __result.__last = + __formatter::__to_buffer(__integral, __buffer.end(), __value, chars_format::scientific, __precision); + + char* __first = __integral + 1; + _LIBCPP_ASSERT(__first != __result.__last, "No exponent present"); + if (*__first == '.') { + __result.__radix_point = __first; + __result.__exponent = __formatter::__find_exponent(__first + 1, __result.__last); + } else { + __result.__radix_point = __result.__last; + __result.__exponent = __first; + } + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent != __result.__last && *__result.__exponent == 'e'), + "Post-condition failure."); + // clang-format on + return __result; +} + +template +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_upper_case(const __float_buffer<_Fp>& __buffer, + _Tp __value, int __precision, + char* __integral) { + __float_result __result = + __formatter::__format_buffer_scientific_lower_case(__buffer, __value, __precision, __integral); + *__result.__exponent = 'E'; + return __result; +} + +template +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_fixed(const __float_buffer<_Fp>& __buffer, _Tp __value, + int __precision, char* __integral) { + __float_result __result; + __result.__integral = __integral; + __result.__last = __formatter::__to_buffer(__integral, __buffer.end(), __value, chars_format::fixed, __precision); + + // When there's no precision there's no radix point. + // Else the radix point is placed at __precision + 1 from the end. + // By converting __precision to a bool the subtraction can be done + // unconditionally. + __result.__radix_point = __result.__last - (__precision + bool(__precision)); + __result.__exponent = __result.__last; + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent == __result.__last), + "Post-condition failure."); + // clang-format on + return __result; +} + +template +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_lower_case(__float_buffer<_Fp>& __buffer, _Tp __value, + int __precision, char* __integral) { + + __buffer.__remove_trailing_zeros(); + + __float_result __result; + __result.__integral = __integral; + __result.__last = __formatter::__to_buffer(__integral, __buffer.end(), __value, chars_format::general, __precision); + + char* __first = __integral + 1; + if (__first == __result.__last) { + __result.__radix_point = __result.__last; + __result.__exponent = __result.__last; + } else { + __result.__exponent = __formatter::__find_exponent(__first, __result.__last); + if (__result.__exponent != __result.__last) + // In scientific mode if there's a radix point it will always be after + // the first digit. (This is the position __first points at). + __result.__radix_point = *__first == '.' ? __first : __result.__last; + else { + // In fixed mode the algorithm truncates trailing spaces and possibly the + // radix point. There's no good guess for the position of the radix point + // therefore scan the output after the first digit. + + __result.__radix_point = _VSTD::find(__first, __result.__last, '.'); + } + } + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent == __result.__last || *__result.__exponent == 'e'), + "Post-condition failure."); + // clang-format on + + return __result; +} + +template +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_upper_case(__float_buffer<_Fp>& __buffer, _Tp __value, + int __precision, char* __integral) { + __float_result __result = __formatter::__format_buffer_general_lower_case(__buffer, __value, __precision, __integral); + if (__result.__exponent != __result.__last) + *__result.__exponent = 'E'; + return __result; +} + +/// Fills the buffer with the data based on the requested formatting. +/// +/// This function, when needed, turns the characters to upper case and +/// determines the "interesting" locations which are returned to the caller. +/// +/// This means the caller never has to convert the contents of the buffer to +/// upper case or search for radix points and the location of the exponent. +/// This gives a bit of overhead. The original code didn't do that, but due +/// to the number of possible additional work needed to turn this number to +/// the proper output the code was littered with tests for upper cases and +/// searches for radix points and exponents. +/// - When a precision larger than the type's precision is selected +/// additional zero characters need to be written before the exponent. +/// - alternate form needs to add a radix point when not present. +/// - localization needs to do grouping in the integral part. +template +// TODO FMT _Fp should just be _Tp when to_chars has proper long double support. +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer( + __float_buffer<_Fp>& __buffer, + _Tp __value, + bool __negative, + bool __has_precision, + __format_spec::__sign __sign, + __format_spec::__type __type) { + char* __first = __formatter::__insert_sign(__buffer.begin(), __negative, __sign); + switch (__type) { + case __format_spec::__type::__default: + if (__has_precision) + return __formatter::__format_buffer_general_lower_case(__buffer, __value, __buffer.__precision(), __first); + else + return __formatter::__format_buffer_default(__buffer, __value, __first); + + case __format_spec::__type::__hexfloat_lower_case: + return __formatter::__format_buffer_hexadecimal_lower_case( + __buffer, __value, __has_precision ? __buffer.__precision() : -1, __first); + + case __format_spec::__type::__hexfloat_upper_case: + return __formatter::__format_buffer_hexadecimal_upper_case( + __buffer, __value, __has_precision ? __buffer.__precision() : -1, __first); + + case __format_spec::__type::__scientific_lower_case: + return __formatter::__format_buffer_scientific_lower_case(__buffer, __value, __buffer.__precision(), __first); + + case __format_spec::__type::__scientific_upper_case: + return __formatter::__format_buffer_scientific_upper_case(__buffer, __value, __buffer.__precision(), __first); + + case __format_spec::__type::__fixed_lower_case: + case __format_spec::__type::__fixed_upper_case: + return __formatter::__format_buffer_fixed(__buffer, __value, __buffer.__precision(), __first); + + case __format_spec::__type::__general_lower_case: + return __formatter::__format_buffer_general_lower_case(__buffer, __value, __buffer.__precision(), __first); + + case __format_spec::__type::__general_upper_case: + return __formatter::__format_buffer_general_upper_case(__buffer, __value, __buffer.__precision(), __first); + + default: + _LIBCPP_ASSERT(false, "The parser should have validated the type"); + __libcpp_unreachable(); + } +} + +# ifndef _LIBCPP_HAS_NO_LOCALIZATION +template +_LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form( + _OutIt __out_it, + const __float_buffer<_Fp>& __buffer, + const __float_result& __result, + _VSTD::locale __loc, + __format_spec::__parsed_specifications<_CharT> __specs) { + const auto& __np = std::use_facet>(__loc); + string __grouping = __np.grouping(); + char* __first = __result.__integral; + // When no radix point or exponent are present __last will be __result.__last. + char* __last = _VSTD::min(__result.__radix_point, __result.__exponent); + + ptrdiff_t __digits = __last - __first; + if (!__grouping.empty()) { + if (__digits <= __grouping[0]) + __grouping.clear(); + else + __grouping = __formatter::__determine_grouping(__digits, __grouping); + } + + ptrdiff_t __size = + __result.__last - __buffer.begin() + // Formatted string + __buffer.__num_trailing_zeros() + // Not yet rendered zeros + __grouping.size() - // Grouping contains one + !__grouping.empty(); // additional character + + __formatter::__padding_size_result __padding = {0, 0}; + bool __zero_padding = __specs.__alignment_ == __format_spec::__alignment::__zero_padding; + if (__size < __specs.__width_) { + if (__zero_padding) { + __specs.__alignment_ = __format_spec::__alignment::__right; + __specs.__fill_ = _CharT('0'); + } + + __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__alignment_); + } + + // sign and (zero padding or alignment) + if (__zero_padding && __first != __buffer.begin()) + *__out_it++ = *__buffer.begin(); + __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_); + if (!__zero_padding && __first != __buffer.begin()) + *__out_it++ = *__buffer.begin(); + + // integral part + if (__grouping.empty()) { + __out_it = __formatter::__copy(__first, __digits, _VSTD::move(__out_it)); + } else { + auto __r = __grouping.rbegin(); + auto __e = __grouping.rend() - 1; + _CharT __sep = __np.thousands_sep(); + // The output is divided in small groups of numbers to write: + // - A group before the first separator. + // - A separator and a group, repeated for the number of separators. + // - A group after the last separator. + // This loop achieves that process by testing the termination condition + // midway in the loop. + while (true) { + __out_it = __formatter::__copy(__first, *__r, _VSTD::move(__out_it)); + __first += *__r; + + if (__r == __e) + break; + + ++__r; + *__out_it++ = __sep; + } + } + + // fractional part + if (__result.__radix_point != __result.__last) { + *__out_it++ = __np.decimal_point(); + __out_it = __formatter::__copy(__result.__radix_point + 1, __result.__exponent, _VSTD::move(__out_it)); + __out_it = __formatter::__fill(_VSTD::move(__out_it), __buffer.__num_trailing_zeros(), _CharT('0')); + } + + // exponent + if (__result.__exponent != __result.__last) + __out_it = __formatter::__copy(__result.__exponent, __result.__last, _VSTD::move(__out_it)); + + // alignment + return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_); +} +# endif // _LIBCPP_HAS_NO_LOCALIZATION + +template +_LIBCPP_HIDE_FROM_ABI _OutIt __format_floating_point_non_finite( + _OutIt __out_it, __format_spec::__parsed_specifications<_CharT> __specs, bool __negative, bool __isnan) { + char __buffer[4]; + char* __last = __formatter::__insert_sign(__buffer, __negative, __specs.__std_.__sign_); + + // to_chars can return inf, infinity, nan, and nan(n-char-sequence). + // The format library requires inf and nan. + // All in one expression to avoid dangling references. + bool __upper_case = + __specs.__std_.__type_ == __format_spec::__type::__hexfloat_upper_case || + __specs.__std_.__type_ == __format_spec::__type::__scientific_upper_case || + __specs.__std_.__type_ == __format_spec::__type::__fixed_upper_case || + __specs.__std_.__type_ == __format_spec::__type::__general_upper_case; + __last = _VSTD::copy_n(&("infnanINFNAN"[6 * __upper_case + 3 * __isnan]), 3, __last); + + // [format.string.std]/13 + // A zero (0) character preceding the width field pads the field with + // leading zeros (following any indication of sign or base) to the field + // width, except when applied to an infinity or NaN. + if (__specs.__alignment_ == __format_spec::__alignment::__zero_padding) + __specs.__alignment_ = __format_spec::__alignment::__right; + + return __formatter::__write(__buffer, __last, _VSTD::move(__out_it), __specs); +} + +template +_LIBCPP_HIDE_FROM_ABI auto +__format_floating_point(_Tp __value, auto& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) + -> decltype(__ctx.out()) { + bool __negative = _VSTD::signbit(__value); + + if (!_VSTD::isfinite(__value)) [[unlikely]] + return __formatter::__format_floating_point_non_finite(__ctx.out(), __specs, __negative, _VSTD::isnan(__value)); + + // Depending on the std-format-spec string the sign and the value + // might not be outputted together: + // - zero-padding may insert additional '0' characters. + // Therefore the value is processed as a non negative value. + // The function @ref __insert_sign will insert a '-' when the value was + // negative. + + if (__negative) + __value = -__value; + + // TODO FMT _Fp should just be _Tp when to_chars has proper long double support. + using _Fp = conditional_t, double, _Tp>; + // Force the type of the precision to avoid -1 to become an unsigned value. + __float_buffer<_Fp> __buffer(__specs.__precision_); + __float_result __result = __formatter::__format_buffer( + __buffer, __value, __negative, (__specs.__has_precision()), __specs.__std_.__sign_, __specs.__std_.__type_); + + if (__specs.__std_.__alternate_form_) { + if (__result.__radix_point == __result.__last) { + *__result.__last++ = '.'; + + // When there is an exponent the point needs to be moved before the + // exponent. When there's no exponent the rotate does nothing. Since + // rotate tests whether the operation is a nop, call it unconditionally. + _VSTD::rotate(__result.__exponent, __result.__last - 1, __result.__last); + __result.__radix_point = __result.__exponent; + + // The radix point is always placed before the exponent. + // - No exponent needs to point to the new last. + // - An exponent needs to move one position to the right. + // So it's safe to increment the value unconditionally. + ++__result.__exponent; + } + + // [format.string.std]/6 + // In addition, for g and G conversions, trailing zeros are not removed + // from the result. + // + // If the type option for a floating-point type is none it may use the + // general formatting, but it's not a g or G conversion. So in that case + // the formatting should not append trailing zeros. + bool __is_general = __specs.__std_.__type_ == __format_spec::__type::__general_lower_case || + __specs.__std_.__type_ == __format_spec::__type::__general_upper_case; + + if (__is_general) { + // https://en.cppreference.com/w/c/io/fprintf + // Let P equal the precision if nonzero, 6 if the precision is not + // specified, or 1 if the precision is 0. Then, if a conversion with + // style E would have an exponent of X: + int __p = _VSTD::max(1, (__specs.__has_precision() ? __specs.__precision_ : 6)); + if (__result.__exponent == __result.__last) + // if P > X >= -4, the conversion is with style f or F and precision P - 1 - X. + // By including the radix point it calculates P - (1 + X) + __p -= __result.__radix_point - __buffer.begin(); + else + // otherwise, the conversion is with style e or E and precision P - 1. + --__p; + + ptrdiff_t __precision = (__result.__exponent - __result.__radix_point) - 1; + if (__precision < __p) + __buffer.__add_trailing_zeros(__p - __precision); + } + } + +# ifndef _LIBCPP_HAS_NO_LOCALIZATION + if (__specs.__std_.__locale_specific_form_) + return __formatter::__format_locale_specific_form(__ctx.out(), __buffer, __result, __ctx.locale(), __specs); +# endif + + ptrdiff_t __size = __result.__last - __buffer.begin(); + int __num_trailing_zeros = __buffer.__num_trailing_zeros(); + if (__size + __num_trailing_zeros >= __specs.__width_) { + if (__num_trailing_zeros && __result.__exponent != __result.__last) + // Insert trailing zeros before exponent character. + return __formatter::__copy( + __result.__exponent, + __result.__last, + __formatter::__fill(__formatter::__copy(__buffer.begin(), __result.__exponent, __ctx.out()), + __num_trailing_zeros, + _CharT('0'))); + + return __formatter::__fill( + __formatter::__copy(__buffer.begin(), __result.__last, __ctx.out()), __num_trailing_zeros, _CharT('0')); + } + + auto __out_it = __ctx.out(); + char* __first = __buffer.begin(); + if (__specs.__alignment_ == __format_spec::__alignment ::__zero_padding) { + // When there is a sign output it before the padding. Note the __size + // doesn't need any adjustment, regardless whether the sign is written + // here or in __formatter::__write. + if (__first != __result.__integral) + *__out_it++ = *__first++; + // After the sign is written, zero padding is the same a right alignment + // with '0'. + __specs.__alignment_ = __format_spec::__alignment::__right; + __specs.__fill_ = _CharT('0'); + } + + if (__num_trailing_zeros) + return __formatter::__write_using_trailing_zeros( + __first, __result.__last, _VSTD::move(__out_it), __specs, __size, __result.__exponent, __num_trailing_zeros); + + return __formatter::__write(__first, __result.__last, _VSTD::move(__out_it), __specs, __size); +} + +} // namespace __formatter + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS __formatter_floating_point { +public: + _LIBCPP_HIDE_FROM_ABI constexpr auto + parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) { + auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_floating_point); + __format_spec::__process_parsed_floating_point(__parser_); + return __result; + } + + template + _LIBCPP_HIDE_FROM_ABI auto format(_Tp __value, auto& __ctx) const -> decltype(__ctx.out()) { + return __formatter::__format_floating_point(__value, __ctx, __parser_.__get_parsed_std_specifications(__ctx)); + } + + __format_spec::__parser<_CharT> __parser_; +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_floating_point<_CharT> {}; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_floating_point<_CharT> {}; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_floating_point<_CharT> {}; + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___FORMAT_FORMATTER_FLOATING_POINT_H diff --git a/app/src/main/cpp/libcxx/include/__format/formatter_integer.h b/app/src/main/cpp/libcxx/include/__format/formatter_integer.h new file mode 100644 index 0000000..b4be9f9 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/formatter_integer.h @@ -0,0 +1,107 @@ +// -*- 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 _LIBCPP___FORMAT_FORMATTER_INTEGER_H +#define _LIBCPP___FORMAT_FORMATTER_INTEGER_H + +#include <__availability> +#include <__concepts/arithmetic.h> +#include <__config> +#include <__format/concepts.h> +#include <__format/format_parse_context.h> +#include <__format/formatter.h> +#include <__format/formatter_integral.h> +#include <__format/formatter_output.h> +#include <__format/parser_std_format_spec.h> +#include <__type_traits/make_32_64_or_128_bit.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + + _LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + + template <__fmt_char_type _CharT> + struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_integer { + +public: + _LIBCPP_HIDE_FROM_ABI constexpr auto + parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) { + auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_integral); + __format_spec::__process_parsed_integer(__parser_); + return __result; + } + + template + _LIBCPP_HIDE_FROM_ABI auto format(_Tp __value, auto& __ctx) const -> decltype(__ctx.out()) { + __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx); + + if (__specs.__std_.__type_ == __format_spec::__type::__char) + return __formatter::__format_char(__value, __ctx.out(), __specs); + + using _Type = __make_32_64_or_128_bit_t<_Tp>; + static_assert(!is_same<_Type, void>::value, "unsupported integral type used in __formatter_integer::__format"); + + // Reduce the number of instantiation of the integer formatter + return __formatter::__format_integer(static_cast<_Type>(__value), __ctx, __specs); + } + + __format_spec::__parser<_CharT> __parser_; +}; + +// Signed integral types. +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_integer<_CharT> {}; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter : public __formatter_integer<_CharT> { +}; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter : public __formatter_integer<_CharT> {}; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter : public __formatter_integer<_CharT> {}; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_integer<_CharT> {}; +# ifndef _LIBCPP_HAS_NO_INT128 +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<__int128_t, _CharT> + : public __formatter_integer<_CharT> {}; +# endif + +// Unsigned integral types. +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_integer<_CharT> {}; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_integer<_CharT> {}; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_integer<_CharT> {}; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_integer<_CharT> {}; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_integer<_CharT> {}; +# ifndef _LIBCPP_HAS_NO_INT128 +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<__uint128_t, _CharT> + : public __formatter_integer<_CharT> {}; +# endif + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMATTER_INTEGER_H diff --git a/app/src/main/cpp/libcxx/include/__format/formatter_integral.h b/app/src/main/cpp/libcxx/include/__format/formatter_integral.h new file mode 100644 index 0000000..fe3a063 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/formatter_integral.h @@ -0,0 +1,363 @@ +// -*- 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 _LIBCPP___FORMAT_FORMATTER_INTEGRAL_H +#define _LIBCPP___FORMAT_FORMATTER_INTEGRAL_H + +#include <__concepts/arithmetic.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__format/concepts.h> +#include <__format/format_error.h> +#include <__format/formatter_output.h> +#include <__format/parser_std_format_spec.h> +#include <__utility/unreachable.h> +#include +#include +#include +#include + +#ifndef _LIBCPP_HAS_NO_LOCALIZATION +# include +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __formatter { + +// +// Generic +// + +_LIBCPP_HIDE_FROM_ABI inline char* __insert_sign(char* __buf, bool __negative, __format_spec::__sign __sign) { + if (__negative) + *__buf++ = '-'; + else + switch (__sign) { + case __format_spec::__sign::__default: + case __format_spec::__sign::__minus: + // No sign added. + break; + case __format_spec::__sign::__plus: + *__buf++ = '+'; + break; + case __format_spec::__sign::__space: + *__buf++ = ' '; + break; + } + + return __buf; +} + +/** + * Determines the required grouping based on the size of the input. + * + * The grouping's last element will be repeated. For simplicity this repeating + * is unwrapped based on the length of the input. (When the input is short some + * groups are not processed.) + * + * @returns The size of the groups to write. This means the number of + * separator characters written is size() - 1. + * + * @note Since zero-sized groups cause issues they are silently ignored. + * + * @note The grouping field of the locale is always a @c std::string, + * regardless whether the @c std::numpunct's type is @c char or @c wchar_t. + */ +_LIBCPP_HIDE_FROM_ABI inline string __determine_grouping(ptrdiff_t __size, const string& __grouping) { + _LIBCPP_ASSERT(!__grouping.empty() && __size > __grouping[0], + "The slow grouping formatting is used while there will be no " + "separators written"); + string __r; + auto __end = __grouping.end() - 1; + auto __ptr = __grouping.begin(); + + while (true) { + __size -= *__ptr; + if (__size > 0) + __r.push_back(*__ptr); + else { + // __size <= 0 so the value pushed will be <= *__ptr. + __r.push_back(*__ptr + __size); + return __r; + } + + // Proceed to the next group. + if (__ptr != __end) { + do { + ++__ptr; + // Skip grouping with a width of 0. + } while (*__ptr == 0 && __ptr != __end); + } + } + + __libcpp_unreachable(); +} + +// +// Char +// + +template <__fmt_char_type _CharT> +_LIBCPP_HIDE_FROM_ABI auto __format_char( + integral auto __value, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { + using _Tp = decltype(__value); + if constexpr (!same_as<_CharT, _Tp>) { + // cmp_less and cmp_greater can't be used for character types. + if constexpr (signed_integral<_CharT> == signed_integral<_Tp>) { + if (__value < numeric_limits<_CharT>::min() || __value > numeric_limits<_CharT>::max()) + std::__throw_format_error("Integral value outside the range of the char type"); + } else if constexpr (signed_integral<_CharT>) { + // _CharT is signed _Tp is unsigned + if (__value > static_cast>(numeric_limits<_CharT>::max())) + std::__throw_format_error("Integral value outside the range of the char type"); + } else { + // _CharT is unsigned _Tp is signed + if (__value < 0 || static_cast>(__value) > numeric_limits<_CharT>::max()) + std::__throw_format_error("Integral value outside the range of the char type"); + } + } + + const auto __c = static_cast<_CharT>(__value); + return __formatter::__write(_VSTD::addressof(__c), _VSTD::addressof(__c) + 1, _VSTD::move(__out_it), __specs); +} + +// +// Integer +// + +/** Wrapper around @ref to_chars, returning the output pointer. */ +template +_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, int __base) { + // TODO FMT Evaluate code overhead due to not calling the internal function + // directly. (Should be zero overhead.) + to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __base); + _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); + return __r.ptr; +} + +/** + * Helper to determine the buffer size to output a integer in Base @em x. + * + * There are several overloads for the supported bases. The function uses the + * base as template argument so it can be used in a constant expression. + */ +template +consteval size_t __buffer_size() noexcept + requires(_Base == 2) +{ + return numeric_limits<_Tp>::digits // The number of binary digits. + + 2 // Reserve space for the '0[Bb]' prefix. + + 1; // Reserve space for the sign. +} + +template +consteval size_t __buffer_size() noexcept + requires(_Base == 8) +{ + return numeric_limits<_Tp>::digits // The number of binary digits. + / 3 // Adjust to octal. + + 1 // Turn floor to ceil. + + 1 // Reserve space for the '0' prefix. + + 1; // Reserve space for the sign. +} + +template +consteval size_t __buffer_size() noexcept + requires(_Base == 10) +{ + return numeric_limits<_Tp>::digits10 // The floored value. + + 1 // Turn floor to ceil. + + 1; // Reserve space for the sign. +} + +template +consteval size_t __buffer_size() noexcept + requires(_Base == 16) +{ + return numeric_limits<_Tp>::digits // The number of binary digits. + / 4 // Adjust to hexadecimal. + + 2 // Reserve space for the '0[Xx]' prefix. + + 1; // Reserve space for the sign. +} + +template +_LIBCPP_HIDE_FROM_ABI auto __format_integer( + _Tp __value, + auto& __ctx, + __format_spec::__parsed_specifications<_CharT> __specs, + bool __negative, + char* __begin, + char* __end, + const char* __prefix, + int __base) -> decltype(__ctx.out()) { + char* __first = __formatter::__insert_sign(__begin, __negative, __specs.__std_.__sign_); + if (__specs.__std_.__alternate_form_ && __prefix) + while (*__prefix) + *__first++ = *__prefix++; + + char* __last = __formatter::__to_buffer(__first, __end, __value, __base); + +# ifndef _LIBCPP_HAS_NO_LOCALIZATION + if (__specs.__std_.__locale_specific_form_) { + const auto& __np = std::use_facet>(__ctx.locale()); + string __grouping = __np.grouping(); + ptrdiff_t __size = __last - __first; + // Writing the grouped form has more overhead than the normal output + // routines. If there will be no separators written the locale-specific + // form is identical to the normal routine. Test whether to grouped form + // is required. + if (!__grouping.empty() && __size > __grouping[0]) + return __formatter::__write_using_decimal_separators( + __ctx.out(), + __begin, + __first, + __last, + __formatter::__determine_grouping(__size, __grouping), + __np.thousands_sep(), + __specs); + } +# endif + auto __out_it = __ctx.out(); + if (__specs.__alignment_ != __format_spec::__alignment::__zero_padding) + __first = __begin; + else { + // __buf contains [sign][prefix]data + // ^ location of __first + // The zero padding is done like: + // - Write [sign][prefix] + // - Write data right aligned with '0' as fill character. + __out_it = __formatter::__copy(__begin, __first, _VSTD::move(__out_it)); + __specs.__alignment_ = __format_spec::__alignment::__right; + __specs.__fill_ = _CharT('0'); + int32_t __size = __first - __begin; + + __specs.__width_ -= _VSTD::min(__size, __specs.__width_); + } + + if (__specs.__std_.__type_ != __format_spec::__type::__hexadecimal_upper_case) [[likely]] + return __formatter::__write(__first, __last, __ctx.out(), __specs); + + return __formatter::__write_transformed(__first, __last, __ctx.out(), __specs, __formatter::__hex_to_upper); +} + +template +_LIBCPP_HIDE_FROM_ABI auto __format_integer( + _Tp __value, auto& __ctx, __format_spec::__parsed_specifications<_CharT> __specs, bool __negative = false) + -> decltype(__ctx.out()) { + switch (__specs.__std_.__type_) { + case __format_spec::__type::__binary_lower_case: { + array()> __array; + return __formatter::__format_integer(__value, __ctx, __specs, __negative, __array.begin(), __array.end(), "0b", 2); + } + case __format_spec::__type::__binary_upper_case: { + array()> __array; + return __formatter::__format_integer(__value, __ctx, __specs, __negative, __array.begin(), __array.end(), "0B", 2); + } + case __format_spec::__type::__octal: { + // Octal is special; if __value == 0 there's no prefix. + array()> __array; + return __formatter::__format_integer( + __value, __ctx, __specs, __negative, __array.begin(), __array.end(), __value != 0 ? "0" : nullptr, 8); + } + case __format_spec::__type::__default: + case __format_spec::__type::__decimal: { + array()> __array; + return __formatter::__format_integer( + __value, __ctx, __specs, __negative, __array.begin(), __array.end(), nullptr, 10); + } + case __format_spec::__type::__hexadecimal_lower_case: { + array()> __array; + return __formatter::__format_integer(__value, __ctx, __specs, __negative, __array.begin(), __array.end(), "0x", 16); + } + case __format_spec::__type::__hexadecimal_upper_case: { + array()> __array; + return __formatter::__format_integer(__value, __ctx, __specs, __negative, __array.begin(), __array.end(), "0X", 16); + } + default: + _LIBCPP_ASSERT(false, "The parse function should have validated the type"); + __libcpp_unreachable(); + } +} + +template +_LIBCPP_HIDE_FROM_ABI auto +__format_integer(_Tp __value, auto& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) + -> decltype(__ctx.out()) { + // Depending on the std-format-spec string the sign and the value + // might not be outputted together: + // - alternate form may insert a prefix string. + // - zero-padding may insert additional '0' characters. + // Therefore the value is processed as a positive unsigned value. + // The function @ref __insert_sign will a '-' when the value was negative. + auto __r = std::__to_unsigned_like(__value); + bool __negative = __value < 0; + if (__negative) + __r = std::__complement(__r); + + return __formatter::__format_integer(__r, __ctx, __specs, __negative); +} + +// +// Formatter arithmetic (bool) +// + +template +struct _LIBCPP_TEMPLATE_VIS __bool_strings; + +template <> +struct _LIBCPP_TEMPLATE_VIS __bool_strings { + static constexpr string_view __true{"true"}; + static constexpr string_view __false{"false"}; +}; + +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template <> +struct _LIBCPP_TEMPLATE_VIS __bool_strings { + static constexpr wstring_view __true{L"true"}; + static constexpr wstring_view __false{L"false"}; +}; +# endif + +template +_LIBCPP_HIDE_FROM_ABI auto +__format_bool(bool __value, auto& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) + -> decltype(__ctx.out()) { +# ifndef _LIBCPP_HAS_NO_LOCALIZATION + if (__specs.__std_.__locale_specific_form_) { + const auto& __np = std::use_facet>(__ctx.locale()); + basic_string<_CharT> __str = __value ? __np.truename() : __np.falsename(); + return __formatter::__write_string_no_precision(basic_string_view<_CharT>{__str}, __ctx.out(), __specs); + } +# endif + basic_string_view<_CharT> __str = + __value ? __formatter::__bool_strings<_CharT>::__true : __formatter::__bool_strings<_CharT>::__false; + return __formatter::__write(__str.begin(), __str.end(), __ctx.out(), __specs); +} + +} // namespace __formatter + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___FORMAT_FORMATTER_INTEGRAL_H diff --git a/app/src/main/cpp/libcxx/include/__format/formatter_output.h b/app/src/main/cpp/libcxx/include/__format/formatter_output.h new file mode 100644 index 0000000..4676925 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/formatter_output.h @@ -0,0 +1,570 @@ +// -*- 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 _LIBCPP___FORMAT_FORMATTER_OUTPUT_H +#define _LIBCPP___FORMAT_FORMATTER_OUTPUT_H + +#include <__algorithm/ranges_copy.h> +#include <__algorithm/ranges_fill_n.h> +#include <__algorithm/ranges_transform.h> +#include <__chrono/statically_widen.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__format/buffer.h> +#include <__format/concepts.h> +#include <__format/escaped_output_table.h> +#include <__format/formatter.h> +#include <__format/parser_std_format_spec.h> +#include <__format/unicode.h> +#include <__iterator/back_insert_iterator.h> +#include <__type_traits/make_unsigned.h> +#include <__utility/move.h> +#include <__utility/unreachable.h> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __formatter { + +_LIBCPP_HIDE_FROM_ABI constexpr char __hex_to_upper(char __c) { + switch (__c) { + case 'a': + return 'A'; + case 'b': + return 'B'; + case 'c': + return 'C'; + case 'd': + return 'D'; + case 'e': + return 'E'; + case 'f': + return 'F'; + } + return __c; +} + +struct _LIBCPP_TYPE_VIS __padding_size_result { + size_t __before_; + size_t __after_; +}; + +_LIBCPP_HIDE_FROM_ABI constexpr __padding_size_result +__padding_size(size_t __size, size_t __width, __format_spec::__alignment __align) { + _LIBCPP_ASSERT(__width > __size, "don't call this function when no padding is required"); + _LIBCPP_ASSERT( + __align != __format_spec::__alignment::__zero_padding, "the caller should have handled the zero-padding"); + + size_t __fill = __width - __size; + switch (__align) { + case __format_spec::__alignment::__zero_padding: + __libcpp_unreachable(); + + case __format_spec::__alignment::__left: + return {0, __fill}; + + case __format_spec::__alignment::__center: { + // The extra padding is divided per [format.string.std]/3 + // __before = floor(__fill, 2); + // __after = ceil(__fill, 2); + size_t __before = __fill / 2; + size_t __after = __fill - __before; + return {__before, __after}; + } + case __format_spec::__alignment::__default: + case __format_spec::__alignment::__right: + return {__fill, 0}; + } + __libcpp_unreachable(); +} + +/// Copy wrapper. +/// +/// This uses a "mass output function" of __format::__output_buffer when possible. +template <__fmt_char_type _CharT, __fmt_char_type _OutCharT = _CharT> +_LIBCPP_HIDE_FROM_ABI auto __copy(basic_string_view<_CharT> __str, output_iterator auto __out_it) + -> decltype(__out_it) { + if constexpr (_VSTD::same_as>>) { + __out_it.__get_container()->__copy(__str); + return __out_it; + } else if constexpr (_VSTD::same_as::__iterator>) { + __out_it.__buffer_->__copy(__str); + return __out_it; + } else { + return std::ranges::copy(__str, _VSTD::move(__out_it)).out; + } +} + +template <__fmt_char_type _CharT, __fmt_char_type _OutCharT = _CharT> +_LIBCPP_HIDE_FROM_ABI auto +__copy(const _CharT* __first, const _CharT* __last, output_iterator auto __out_it) + -> decltype(__out_it) { + return __formatter::__copy(basic_string_view{__first, __last}, _VSTD::move(__out_it)); +} + +template <__fmt_char_type _CharT, __fmt_char_type _OutCharT = _CharT> +_LIBCPP_HIDE_FROM_ABI auto __copy(const _CharT* __first, size_t __n, output_iterator auto __out_it) + -> decltype(__out_it) { + return __formatter::__copy(basic_string_view{__first, __n}, _VSTD::move(__out_it)); +} + +/// Transform wrapper. +/// +/// This uses a "mass output function" of __format::__output_buffer when possible. +template <__fmt_char_type _CharT, __fmt_char_type _OutCharT = _CharT, class _UnaryOperation> +_LIBCPP_HIDE_FROM_ABI auto +__transform(const _CharT* __first, + const _CharT* __last, + output_iterator auto __out_it, + _UnaryOperation __operation) -> decltype(__out_it) { + if constexpr (_VSTD::same_as>>) { + __out_it.__get_container()->__transform(__first, __last, _VSTD::move(__operation)); + return __out_it; + } else if constexpr (_VSTD::same_as::__iterator>) { + __out_it.__buffer_->__transform(__first, __last, _VSTD::move(__operation)); + return __out_it; + } else { + return std::ranges::transform(__first, __last, _VSTD::move(__out_it), __operation).out; + } +} + +/// Fill wrapper. +/// +/// This uses a "mass output function" of __format::__output_buffer when possible. +template <__fmt_char_type _CharT, output_iterator _OutIt> +_LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, _CharT __value) { + if constexpr (_VSTD::same_as>>) { + __out_it.__get_container()->__fill(__n, __value); + return __out_it; + } else if constexpr (_VSTD::same_as::__iterator>) { + __out_it.__buffer_->__fill(__n, __value); + return __out_it; + } else { + return std::ranges::fill_n(_VSTD::move(__out_it), __n, __value); + } +} + +template +_LIBCPP_HIDE_FROM_ABI _OutIt __write_using_decimal_separators(_OutIt __out_it, const char* __begin, const char* __first, + const char* __last, string&& __grouping, _CharT __sep, + __format_spec::__parsed_specifications<_CharT> __specs) { + int __size = (__first - __begin) + // [sign][prefix] + (__last - __first) + // data + (__grouping.size() - 1); // number of separator characters + + __padding_size_result __padding = {0, 0}; + if (__specs.__alignment_ == __format_spec::__alignment::__zero_padding) { + // Write [sign][prefix]. + __out_it = __formatter::__copy(__begin, __first, _VSTD::move(__out_it)); + + if (__specs.__width_ > __size) { + // Write zero padding. + __padding.__before_ = __specs.__width_ - __size; + __out_it = __formatter::__fill(_VSTD::move(__out_it), __specs.__width_ - __size, _CharT('0')); + } + } else { + if (__specs.__width_ > __size) { + // Determine padding and write padding. + __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__alignment_); + + __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_); + } + // Write [sign][prefix]. + __out_it = __formatter::__copy(__begin, __first, _VSTD::move(__out_it)); + } + + auto __r = __grouping.rbegin(); + auto __e = __grouping.rend() - 1; + _LIBCPP_ASSERT(__r != __e, "The slow grouping formatting is used while " + "there will be no separators written."); + // The output is divided in small groups of numbers to write: + // - A group before the first separator. + // - A separator and a group, repeated for the number of separators. + // - A group after the last separator. + // This loop achieves that process by testing the termination condition + // midway in the loop. + // + // TODO FMT This loop evaluates the loop invariant `__parser.__type != + // _Flags::_Type::__hexadecimal_upper_case` for every iteration. (This test + // happens in the __write call.) Benchmark whether making two loops and + // hoisting the invariant is worth the effort. + while (true) { + if (__specs.__std_.__type_ == __format_spec::__type::__hexadecimal_upper_case) { + __last = __first + *__r; + __out_it = __formatter::__transform(__first, __last, _VSTD::move(__out_it), __hex_to_upper); + __first = __last; + } else { + __out_it = __formatter::__copy(__first, *__r, _VSTD::move(__out_it)); + __first += *__r; + } + + if (__r == __e) + break; + + ++__r; + *__out_it++ = __sep; + } + + return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_); +} + +/// Writes the input to the output with the required padding. +/// +/// Since the output column width is specified the function can be used for +/// ASCII and Unicode output. +/// +/// \pre \a __size <= \a __width. Using this function when this pre-condition +/// doesn't hold incurs an unwanted overhead. +/// +/// \param __str The string to write. +/// \param __out_it The output iterator to write to. +/// \param __specs The parsed formatting specifications. +/// \param __size The (estimated) output column width. When the elements +/// to be written are ASCII the following condition holds +/// \a __size == \a __last - \a __first. +/// +/// \returns An iterator pointing beyond the last element written. +/// +/// \note The type of the elements in range [\a __first, \a __last) can differ +/// from the type of \a __specs. Integer output uses \c std::to_chars for its +/// conversion, which means the [\a __first, \a __last) always contains elements +/// of the type \c char. +template +_LIBCPP_HIDE_FROM_ABI auto +__write(basic_string_view<_CharT> __str, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_ParserCharT> __specs, + ptrdiff_t __size) -> decltype(__out_it) { + if (__size >= __specs.__width_) + return __formatter::__copy(__str, _VSTD::move(__out_it)); + + __padding_size_result __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__std_.__alignment_); + __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_); + __out_it = __formatter::__copy(__str, _VSTD::move(__out_it)); + return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_); +} + +template +_LIBCPP_HIDE_FROM_ABI auto +__write(const _CharT* __first, + const _CharT* __last, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_ParserCharT> __specs, + ptrdiff_t __size) -> decltype(__out_it) { + _LIBCPP_ASSERT(__first <= __last, "Not a valid range"); + return __formatter::__write(basic_string_view{__first, __last}, _VSTD::move(__out_it), __specs, __size); +} + +/// \overload +/// +/// Calls the function above where \a __size = \a __last - \a __first. +template +_LIBCPP_HIDE_FROM_ABI auto +__write(const _CharT* __first, + const _CharT* __last, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_ParserCharT> __specs) -> decltype(__out_it) { + _LIBCPP_ASSERT(__first <= __last, "Not a valid range"); + return __formatter::__write(__first, __last, _VSTD::move(__out_it), __specs, __last - __first); +} + +template +_LIBCPP_HIDE_FROM_ABI auto __write_transformed(const _CharT* __first, const _CharT* __last, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_ParserCharT> __specs, + _UnaryOperation __op) -> decltype(__out_it) { + _LIBCPP_ASSERT(__first <= __last, "Not a valid range"); + + ptrdiff_t __size = __last - __first; + if (__size >= __specs.__width_) + return __formatter::__transform(__first, __last, _VSTD::move(__out_it), __op); + + __padding_size_result __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__alignment_); + __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_); + __out_it = __formatter::__transform(__first, __last, _VSTD::move(__out_it), __op); + return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_); +} + +/// Writes additional zero's for the precision before the exponent. +/// This is used when the precision requested in the format string is larger +/// than the maximum precision of the floating-point type. These precision +/// digits are always 0. +/// +/// \param __exponent The location of the exponent character. +/// \param __num_trailing_zeros The number of 0's to write before the exponent +/// character. +template +_LIBCPP_HIDE_FROM_ABI auto __write_using_trailing_zeros( + const _CharT* __first, + const _CharT* __last, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_ParserCharT> __specs, + size_t __size, + const _CharT* __exponent, + size_t __num_trailing_zeros) -> decltype(__out_it) { + _LIBCPP_ASSERT(__first <= __last, "Not a valid range"); + _LIBCPP_ASSERT(__num_trailing_zeros > 0, "The overload not writing trailing zeros should have been used"); + + __padding_size_result __padding = + __formatter::__padding_size(__size + __num_trailing_zeros, __specs.__width_, __specs.__alignment_); + __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_); + __out_it = __formatter::__copy(__first, __exponent, _VSTD::move(__out_it)); + __out_it = __formatter::__fill(_VSTD::move(__out_it), __num_trailing_zeros, _CharT('0')); + __out_it = __formatter::__copy(__exponent, __last, _VSTD::move(__out_it)); + return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_); +} + +/// Writes a string using format's width estimation algorithm. +/// +/// \pre !__specs.__has_precision() +/// +/// \note When \c _LIBCPP_HAS_NO_UNICODE is defined the function assumes the +/// input is ASCII. +template +_LIBCPP_HIDE_FROM_ABI auto __write_string_no_precision( + basic_string_view<_CharT> __str, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { + _LIBCPP_ASSERT(!__specs.__has_precision(), "use __write_string"); + + // No padding -> copy the string + if (!__specs.__has_width()) + return __formatter::__copy(__str, _VSTD::move(__out_it)); + + // Note when the estimated width is larger than size there's no padding. So + // there's no reason to get the real size when the estimate is larger than or + // equal to the minimum field width. + size_t __size = + __format_spec::__estimate_column_width(__str, __specs.__width_, __format_spec::__column_width_rounding::__up) + .__width_; + return __formatter::__write(__str, _VSTD::move(__out_it), __specs, __size); +} + +template +_LIBCPP_HIDE_FROM_ABI int __truncate(basic_string_view<_CharT>& __str, int __precision) { + __format_spec::__column_width_result<_CharT> __result = + __format_spec::__estimate_column_width(__str, __precision, __format_spec::__column_width_rounding::__down); + __str = basic_string_view<_CharT>{__str.begin(), __result.__last_}; + return __result.__width_; +} + +/// Writes a string using format's width estimation algorithm. +/// +/// \note When \c _LIBCPP_HAS_NO_UNICODE is defined the function assumes the +/// input is ASCII. +template +_LIBCPP_HIDE_FROM_ABI auto __write_string( + basic_string_view<_CharT> __str, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { + if (!__specs.__has_precision()) + return __formatter::__write_string_no_precision(__str, _VSTD::move(__out_it), __specs); + + int __size = __formatter::__truncate(__str, __specs.__precision_); + + return __formatter::__write(__str.begin(), __str.end(), _VSTD::move(__out_it), __specs, __size); +} + +# if _LIBCPP_STD_VER > 20 + +struct __nul_terminator {}; + +template +_LIBCPP_HIDE_FROM_ABI bool operator==(const _CharT* __cstr, __nul_terminator) { + return *__cstr == _CharT('\0'); +} + +template +_LIBCPP_HIDE_FROM_ABI void +__write_escaped_code_unit(basic_string<_CharT>& __str, char32_t __value, const _CharT* __prefix) { + back_insert_iterator __out_it{__str}; + std::ranges::copy(__prefix, __nul_terminator{}, __out_it); + + char __buffer[8]; + to_chars_result __r = std::to_chars(std::begin(__buffer), std::end(__buffer), __value, 16); + _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); + std::ranges::copy(std::begin(__buffer), __r.ptr, __out_it); + + __str += _CharT('}'); +} + +// [format.string.escaped]/2.2.1.2 +// ... +// then the sequence \u{hex-digit-sequence} is appended to E, where +// hex-digit-sequence is the shortest hexadecimal representation of C using +// lower-case hexadecimal digits. +template +_LIBCPP_HIDE_FROM_ABI void __write_well_formed_escaped_code_unit(basic_string<_CharT>& __str, char32_t __value) { + __formatter::__write_escaped_code_unit(__str, __value, _LIBCPP_STATICALLY_WIDEN(_CharT, "\\u{")); +} + +// [format.string.escaped]/2.2.3 +// Otherwise (X is a sequence of ill-formed code units), each code unit U is +// appended to E in order as the sequence \x{hex-digit-sequence}, where +// hex-digit-sequence is the shortest hexadecimal representation of U using +// lower-case hexadecimal digits. +template +_LIBCPP_HIDE_FROM_ABI void __write_escape_ill_formed_code_unit(basic_string<_CharT>& __str, char32_t __value) { + __formatter::__write_escaped_code_unit(__str, __value, _LIBCPP_STATICALLY_WIDEN(_CharT, "\\x{")); +} + +template +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool __is_escaped_sequence_written(basic_string<_CharT>& __str, char32_t __value) { +# ifdef _LIBCPP_HAS_NO_UNICODE + // For ASCII assume everything above 127 is printable. + if (__value > 127) + return false; +# endif + + if (!__escaped_output_table::__needs_escape(__value)) + return false; + + __formatter::__write_well_formed_escaped_code_unit(__str, __value); + return true; +} + +template +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr char32_t __to_char32(_CharT __value) { + return static_cast>(__value); +} + +enum class _LIBCPP_ENUM_VIS __escape_quotation_mark { __apostrophe, __double_quote }; + +// [format.string.escaped]/2 +template +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool +__is_escaped_sequence_written(basic_string<_CharT>& __str, char32_t __value, __escape_quotation_mark __mark) { + // 2.2.1.1 - Mapped character in [tab:format.escape.sequences] + switch (__value) { + case _CharT('\t'): + __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\t"); + return true; + case _CharT('\n'): + __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\n"); + return true; + case _CharT('\r'): + __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\r"); + return true; + case _CharT('\''): + if (__mark == __escape_quotation_mark::__apostrophe) + __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\')"); + else + __str += __value; + return true; + case _CharT('"'): + if (__mark == __escape_quotation_mark::__double_quote) + __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\")"); + else + __str += __value; + return true; + case _CharT('\\'): + __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\\)"); + return true; + + // 2.2.1.2 - Space + case _CharT(' '): + __str += __value; + return true; + } + + // 2.2.2 + // Otherwise, if X is a shift sequence, the effect on E and further + // decoding of S is unspecified. + // For now shift sequences are ignored and treated as Unicode. Other parts + // of the format library do the same. It's unknown how ostream treats them. + // TODO FMT determine what to do with shift sequences. + + // 2.2.1.2.1 and 2.2.1.2.2 - Escape + return __formatter::__is_escaped_sequence_written(__str, __formatter::__to_char32(__value)); +} + +template +_LIBCPP_HIDE_FROM_ABI void +__escape(basic_string<_CharT>& __str, basic_string_view<_CharT> __values, __escape_quotation_mark __mark) { + __unicode::__code_point_view<_CharT> __view{__values.begin(), __values.end()}; + + while (!__view.__at_end()) { + const _CharT* __first = __view.__position(); + typename __unicode::__consume_p2286_result __result = __view.__consume_p2286(); + if (__result.__ill_formed_size == 0) { + if (!__formatter::__is_escaped_sequence_written(__str, __result.__value, __mark)) + // 2.2.1.3 - Add the character + ranges::copy(__first, __view.__position(), std::back_insert_iterator(__str)); + + } else { + // 2.2.3 sequence of ill-formed code units + // The number of code-units in __result.__value depends on the character type being used. + if constexpr (sizeof(_CharT) == 1) { + _LIBCPP_ASSERT(__result.__ill_formed_size == 1 || __result.__ill_formed_size == 4, + "illegal number of invalid code units."); + if (__result.__ill_formed_size == 1) // ill-formed, one code unit + __formatter::__write_escape_ill_formed_code_unit(__str, __result.__value & 0xff); + else { // out of valid range, four code units + // The code point was properly encoded, decode the value. + __formatter::__write_escape_ill_formed_code_unit(__str, __result.__value >> 18 | 0xf0); + __formatter::__write_escape_ill_formed_code_unit(__str, (__result.__value >> 12 & 0x3f) | 0x80); + __formatter::__write_escape_ill_formed_code_unit(__str, (__result.__value >> 6 & 0x3f) | 0x80); + __formatter::__write_escape_ill_formed_code_unit(__str, (__result.__value & 0x3f) | 0x80); + } + } else if constexpr (sizeof(_CharT) == 2) { + _LIBCPP_ASSERT(__result.__ill_formed_size == 1, "for UTF-16 at most one invalid code unit"); + __formatter::__write_escape_ill_formed_code_unit(__str, __result.__value & 0xffff); + } else { + static_assert(sizeof(_CharT) == 4, "unsupported character width"); + _LIBCPP_ASSERT(__result.__ill_formed_size == 1, "for UTF-32 one code unit is one code point"); + __formatter::__write_escape_ill_formed_code_unit(__str, __result.__value); + } + } + } +} + +template +_LIBCPP_HIDE_FROM_ABI auto +__format_escaped_char(_CharT __value, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { + basic_string<_CharT> __str; + __str += _CharT('\''); + __formatter::__escape(__str, basic_string_view{std::addressof(__value), 1}, __escape_quotation_mark::__apostrophe); + __str += _CharT('\''); + return __formatter::__write(__str.data(), __str.data() + __str.size(), _VSTD::move(__out_it), __specs, __str.size()); +} + +template +_LIBCPP_HIDE_FROM_ABI auto +__format_escaped_string(basic_string_view<_CharT> __values, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { + basic_string<_CharT> __str; + __str += _CharT('"'); + __formatter::__escape(__str, __values, __escape_quotation_mark::__double_quote); + __str += _CharT('"'); + return __formatter::__write_string(basic_string_view{__str}, _VSTD::move(__out_it), __specs); +} + +# endif // _LIBCPP_STD_VER > 20 + +} // namespace __formatter + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMATTER_OUTPUT_H diff --git a/app/src/main/cpp/libcxx/include/__format/formatter_pointer.h b/app/src/main/cpp/libcxx/include/__format/formatter_pointer.h new file mode 100644 index 0000000..31b49e1 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/formatter_pointer.h @@ -0,0 +1,73 @@ +// -*- 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 _LIBCPP___FORMAT_FORMATTER_POINTER_H +#define _LIBCPP___FORMAT_FORMATTER_POINTER_H + +#include <__availability> +#include <__config> +#include <__format/concepts.h> +#include <__format/format_parse_context.h> +#include <__format/formatter.h> +#include <__format/formatter_integral.h> +#include <__format/formatter_output.h> +#include <__format/parser_std_format_spec.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS __formatter_pointer { +public: + constexpr __formatter_pointer() { __parser_.__alignment_ = __format_spec::__alignment::__right; } + + _LIBCPP_HIDE_FROM_ABI constexpr auto + parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) { + auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_pointer); + __format_spec::__process_display_type_pointer(__parser_.__type_); + return __result; + } + + _LIBCPP_HIDE_FROM_ABI auto format(const void* __ptr, auto& __ctx) const -> decltype(__ctx.out()) { + __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx); + __specs.__std_.__alternate_form_ = true; + __specs.__std_.__type_ = __format_spec::__type::__hexadecimal_lower_case; + return __formatter::__format_integer(reinterpret_cast(__ptr), __ctx, __specs); + } + + __format_spec::__parser<_CharT> __parser_; +}; + +// [format.formatter.spec]/2.4 +// For each charT, the pointer type specializations template<> +// - struct formatter; +// - template<> struct formatter; +// - template<> struct formatter; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_pointer<_CharT> {}; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter : public __formatter_pointer<_CharT> { +}; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_pointer<_CharT> {}; + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMATTER_POINTER_H diff --git a/app/src/main/cpp/libcxx/include/__format/formatter_string.h b/app/src/main/cpp/libcxx/include/__format/formatter_string.h new file mode 100644 index 0000000..606fb79 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/formatter_string.h @@ -0,0 +1,159 @@ +// -*- 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 _LIBCPP___FORMAT_FORMATTER_STRING_H +#define _LIBCPP___FORMAT_FORMATTER_STRING_H + +#include <__availability> +#include <__config> +#include <__format/concepts.h> +#include <__format/format_parse_context.h> +#include <__format/formatter.h> +#include <__format/formatter_output.h> +#include <__format/parser_std_format_spec.h> +#include <__utility/move.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS __formatter_string { +public: + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_string); + __format_spec::__process_display_type_string(__parser_.__type_); + return __result; + } + + _LIBCPP_HIDE_FROM_ABI auto format(basic_string_view<_CharT> __str, auto& __ctx) const -> decltype(__ctx.out()) { +# if _LIBCPP_STD_VER > 20 + if (__parser_.__type_ == __format_spec::__type::__debug) + return __formatter::__format_escaped_string(__str, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx)); +# endif + + return __formatter::__write_string(__str, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx)); + } + +# if _LIBCPP_STD_VER > 20 + _LIBCPP_HIDE_FROM_ABI constexpr void set_debug_format() { __parser_.__type_ = __format_spec::__type::__debug; } +# endif + + __format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__left}; +}; + +// Formatter const char*. +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_string<_CharT> { + using _Base = __formatter_string<_CharT>; + + _LIBCPP_HIDE_FROM_ABI auto format(const _CharT* __str, auto& __ctx) const -> decltype(__ctx.out()) { + _LIBCPP_ASSERT(__str, "The basic_format_arg constructor should have " + "prevented an invalid pointer."); + + __format_spec::__parsed_specifications<_CharT> __specs = _Base::__parser_.__get_parsed_std_specifications(__ctx); +# if _LIBCPP_STD_VER > 20 + if (_Base::__parser_.__type_ == __format_spec::__type::__debug) + return __formatter::__format_escaped_string(basic_string_view<_CharT>{__str}, __ctx.out(), __specs); +# endif + + // When using a center or right alignment and the width option the length + // of __str must be known to add the padding upfront. This case is handled + // by the base class by converting the argument to a basic_string_view. + // + // When using left alignment and the width option the padding is added + // after outputting __str so the length can be determined while outputting + // __str. The same holds true for the precision, during outputting __str it + // can be validated whether the precision threshold has been reached. For + // now these optimizations aren't implemented. Instead the base class + // handles these options. + // TODO FMT Implement these improvements. + if (__specs.__has_width() || __specs.__has_precision()) + return __formatter::__write_string(basic_string_view<_CharT>{__str}, __ctx.out(), __specs); + + // No formatting required, copy the string to the output. + auto __out_it = __ctx.out(); + while (*__str) + *__out_it++ = *__str++; + return __out_it; + } +}; + +// Formatter char*. +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_CharT*, _CharT> + : public formatter { + using _Base = formatter; + + _LIBCPP_HIDE_FROM_ABI auto format(_CharT* __str, auto& __ctx) const -> decltype(__ctx.out()) { + return _Base::format(__str, __ctx); + } +}; + +// Formatter char[]. +template <__fmt_char_type _CharT, size_t _Size> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_CharT[_Size], _CharT> + : public __formatter_string<_CharT> { + using _Base = __formatter_string<_CharT>; + + _LIBCPP_HIDE_FROM_ABI auto format(_CharT __str[_Size], auto& __ctx) const -> decltype(__ctx.out()) { + return _Base::format(basic_string_view<_CharT>(__str, _Size), __ctx); + } +}; + +// Formatter const char[]. +template <__fmt_char_type _CharT, size_t _Size> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_string<_CharT> { + using _Base = __formatter_string<_CharT>; + + _LIBCPP_HIDE_FROM_ABI auto format(const _CharT __str[_Size], auto& __ctx) const -> decltype(__ctx.out()) { + return _Base::format(basic_string_view<_CharT>(__str, _Size), __ctx); + } +}; + +// Formatter std::string. +template <__fmt_char_type _CharT, class _Traits, class _Allocator> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter, _CharT> + : public __formatter_string<_CharT> { + using _Base = __formatter_string<_CharT>; + + _LIBCPP_HIDE_FROM_ABI auto format(const basic_string<_CharT, _Traits, _Allocator>& __str, auto& __ctx) const + -> decltype(__ctx.out()) { + // Drop _Traits and _Allocator to have one std::basic_string formatter. + return _Base::format(basic_string_view<_CharT>(__str.data(), __str.size()), __ctx); + } +}; + +// Formatter std::string_view. +template <__fmt_char_type _CharT, class _Traits> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter, _CharT> + : public __formatter_string<_CharT> { + using _Base = __formatter_string<_CharT>; + + _LIBCPP_HIDE_FROM_ABI auto format(basic_string_view<_CharT, _Traits> __str, auto& __ctx) const + -> decltype(__ctx.out()) { + // Drop _Traits to have one std::basic_string_view formatter. + return _Base::format(basic_string_view<_CharT>(__str.data(), __str.size()), __ctx); + } +}; + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMATTER_STRING_H diff --git a/app/src/main/cpp/libcxx/include/__format/formatter_tuple.h b/app/src/main/cpp/libcxx/include/__format/formatter_tuple.h new file mode 100644 index 0000000..82f5ada --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/formatter_tuple.h @@ -0,0 +1,178 @@ +// -*- 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 _LIBCPP___FORMAT_FORMATTER_TUPLE_H +#define _LIBCPP___FORMAT_FORMATTER_TUPLE_H + +#include <__algorithm/ranges_copy.h> +#include <__availability> +#include <__chrono/statically_widen.h> +#include <__config> +#include <__format/concepts.h> +#include <__format/format_args.h> +#include <__format/format_context.h> +#include <__format/format_error.h> +#include <__format/format_parse_context.h> +#include <__format/formatter.h> +#include <__format/formatter_output.h> +#include <__format/parser_std_format_spec.h> +#include <__iterator/back_insert_iterator.h> +#include <__type_traits/remove_cvref.h> +#include <__utility/integer_sequence.h> +#include <__utility/pair.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 20 + +template <__fmt_char_type _CharT, class _Tuple, formattable<_CharT>... _Args> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_tuple { + _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) { + __separator_ = __separator; + } + _LIBCPP_HIDE_FROM_ABI constexpr void + set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) { + __opening_bracket_ = __opening_bracket; + __closing_bracket_ = __closing_bracket; + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __parse_ctx) { + const _CharT* __begin = __parser_.__parse(__parse_ctx, __format_spec::__fields_tuple); + + // [format.tuple]/7 + // ... For each element e in underlying_, if e.set_debug_format() + // is a valid expression, calls e.set_debug_format(). + // TODO FMT this can be removed when P2733 is accepted. + std::__for_each_index_sequence(make_index_sequence(), [&] { + std::__set_debug_format(std::get<_Index>(__underlying_)); + }); + + const _CharT* __end = __parse_ctx.end(); + if (__begin == __end) + return __begin; + + if (*__begin == _CharT('m')) { + if constexpr (sizeof...(_Args) == 2) { + set_separator(_LIBCPP_STATICALLY_WIDEN(_CharT, ": ")); + set_brackets({}, {}); + ++__begin; + } else + std::__throw_format_error("The format specifier m requires a pair or a two-element tuple"); + } else if (*__begin == _CharT('n')) { + set_brackets({}, {}); + ++__begin; + } + + if (__begin != __end && *__begin != _CharT('}')) + std::__throw_format_error("The format-spec should consume the input or end with a '}'"); + + return __begin; + } + + template + typename _FormatContext::iterator _LIBCPP_HIDE_FROM_ABI + format(conditional_t<(formattable && ...), const _Tuple&, _Tuple&> __tuple, + _FormatContext& __ctx) const { + __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx); + + if (!__specs.__has_width()) + return __format_tuple(__tuple, __ctx); + + basic_string<_CharT> __str; + + // Since the output is written to a different iterator a new context is + // created. Since the underlying formatter uses the default formatting it + // doesn't need a locale or the formatting arguments. So creating a new + // context works. + // + // This solution works for this formatter, but it will not work for the + // range_formatter. In that patch a generic solution is work in progress. + // Once that is finished it can be used here. (The range_formatter will use + // these features so it's easier to add it there and then port it.) + // + // TODO FMT Use formatting wrapping used in the range_formatter. + basic_format_context __c = std::__format_context_create( + back_insert_iterator{__str}, + basic_format_args>, _CharT>>{}); + + __format_tuple(__tuple, __c); + + return __formatter::__write_string_no_precision(basic_string_view{__str}, __ctx.out(), __specs); + } + + template + _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator __format_tuple(auto&& __tuple, _FormatContext& __ctx) const { + __ctx.advance_to(std::ranges::copy(__opening_bracket_, __ctx.out()).out); + + std::__for_each_index_sequence(make_index_sequence(), [&] { + if constexpr (_Index) + __ctx.advance_to(std::ranges::copy(__separator_, __ctx.out()).out); + + // During review Victor suggested to make the exposition only + // __underlying_ member a local variable. Currently the Standard + // requires nested debug-enabled formatter specializations not to + // output escaped output. P2733 fixes that bug, once accepted the + // code below can be used. + // (Note when a paper allows parsing a tuple-underlying-spec the + // exposition only member needs to be a class member. Earlier + // revisions of P2286 proposed that, but this was not pursued, + // due to time constrains and complexity of the matter.) + // TODO FMT This can be updated after P2733 is accepted. +# if 0 + // P2286 uses an exposition only member in the formatter + // tuple, _CharT>...> __underlying_; + // This was used in earlier versions of the paper since + // __underlying_.parse(...) was called. This is no longer the case + // so we can reduce the scope of the formatter. + // + // It does require the underlying's parse effect to be moved here too. + using _Arg = tuple_element<_Index, decltype(__tuple)>; + formatter, _CharT> __underlying; + + // [format.tuple]/7 + // ... For each element e in underlying_, if e.set_debug_format() + // is a valid expression, calls e.set_debug_format(). + std::__set_debug_format(__underlying); +# else + __ctx.advance_to(std::get<_Index>(__underlying_).format(std::get<_Index>(__tuple), __ctx)); +# endif + }); + + return std::ranges::copy(__closing_bracket_, __ctx.out()).out; + } + + __format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__left}; + +private: + tuple, _CharT>...> __underlying_; + basic_string_view<_CharT> __separator_ = _LIBCPP_STATICALLY_WIDEN(_CharT, ", "); + basic_string_view<_CharT> __opening_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, "("); + basic_string_view<_CharT> __closing_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, ")"); +}; + +template <__fmt_char_type _CharT, formattable<_CharT>... _Args> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter, _CharT> + : public __formatter_tuple<_CharT, pair<_Args...>, _Args...> {}; + +template <__fmt_char_type _CharT, formattable<_CharT>... _Args> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter, _CharT> + : public __formatter_tuple<_CharT, tuple<_Args...>, _Args...> {}; + +#endif //_LIBCPP_STD_VER > 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMATTER_TUPLE_H diff --git a/app/src/main/cpp/libcxx/include/__format/parser_std_format_spec.h b/app/src/main/cpp/libcxx/include/__format/parser_std_format_spec.h new file mode 100644 index 0000000..c03cec9 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/parser_std_format_spec.h @@ -0,0 +1,954 @@ +// -*- 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 _LIBCPP___FORMAT_PARSER_STD_FORMAT_SPEC_H +#define _LIBCPP___FORMAT_PARSER_STD_FORMAT_SPEC_H + +/// \file Contains the std-format-spec parser. +/// +/// Most of the code can be reused in the chrono-format-spec. +/// This header has some support for the chrono-format-spec since it doesn't +/// affect the std-format-spec. + +#include <__algorithm/find_if.h> +#include <__algorithm/min.h> +#include <__assert> +#include <__concepts/arithmetic.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__debug> +#include <__format/format_arg.h> +#include <__format/format_error.h> +#include <__format/format_parse_context.h> +#include <__format/format_string.h> +#include <__format/unicode.h> +#include <__variant/monostate.h> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __format_spec { + +template +_LIBCPP_HIDE_FROM_ABI constexpr __format::__parse_number_result< _CharT> +__parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) { + // This function is a wrapper to call the real parser. But it does the + // validation for the pre-conditions and post-conditions. + if (__begin == __end) + std::__throw_format_error("End of input while parsing format-spec arg-id"); + + __format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __parse_ctx); + + if (__r.__ptr == __end || *__r.__ptr != _CharT('}')) + std::__throw_format_error("Invalid arg-id"); + + ++__r.__ptr; + return __r; +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr uint32_t +__substitute_arg_id(basic_format_arg<_Context> __format_arg) { + // [format.string.std]/8 + // If the corresponding formatting argument is not of integral type... + // This wording allows char and bool too. LWG-3720 changes the wording to + // If the corresponding formatting argument is not of standard signed or + // unsigned integer type, + // This means the 128-bit will not be valid anymore. + // TODO FMT Verify this resolution is accepted and add a test to verify + // 128-bit integrals fail and switch to visit_format_arg. + return _VSTD::__visit_format_arg( + [](auto __arg) -> uint32_t { + using _Type = decltype(__arg); + if constexpr (integral<_Type>) { + if constexpr (signed_integral<_Type>) { + if (__arg < 0) + std::__throw_format_error("A format-spec arg-id replacement shouldn't have a negative value"); + } + + using _CT = common_type_t<_Type, decltype(__format::__number_max)>; + if (static_cast<_CT>(__arg) > + static_cast<_CT>(__format::__number_max)) + std::__throw_format_error("A format-spec arg-id replacement exceeds the maximum supported value"); + + return __arg; + } else if constexpr (same_as<_Type, monostate>) + std::__throw_format_error("Argument index out of bounds"); + else + std::__throw_format_error("A format-spec arg-id replacement argument isn't an integral type"); + }, + __format_arg); +} + +/// These fields are a filter for which elements to parse. +/// +/// They default to false so when a new field is added it needs to be opted in +/// explicitly. +// TODO FMT Use an ABI tag for this struct. +struct __fields { + uint8_t __sign_ : 1 {false}; + uint8_t __alternate_form_ : 1 {false}; + uint8_t __zero_padding_ : 1 {false}; + uint8_t __precision_ : 1 {false}; + uint8_t __locale_specific_form_ : 1 {false}; + uint8_t __type_ : 1 {false}; + // Determines the valid values for fill. + // + // Originally the fill could be any character except { and }. Range-based + // formatters use the colon to mark the beginning of the + // underlying-format-spec. To avoid parsing ambiguities these formatter + // specializations prohibit the use of the colon as a fill character. + uint8_t __allow_colon_in_fill_ : 1 {false}; +}; + +// By not placing this constant in the formatter class it's not duplicated for +// char and wchar_t. +inline constexpr __fields __fields_integral{ + .__sign_ = true, + .__alternate_form_ = true, + .__zero_padding_ = true, + .__locale_specific_form_ = true, + .__type_ = true}; +inline constexpr __fields __fields_floating_point{ + .__sign_ = true, + .__alternate_form_ = true, + .__zero_padding_ = true, + .__precision_ = true, + .__locale_specific_form_ = true, + .__type_ = true}; +inline constexpr __fields __fields_string{.__precision_ = true, .__type_ = true}; +inline constexpr __fields __fields_pointer{.__type_ = true}; + +# if _LIBCPP_STD_VER > 20 +inline constexpr __fields __fields_tuple{.__type_ = false, .__allow_colon_in_fill_ = true}; +inline constexpr __fields __fields_range{.__type_ = false, .__allow_colon_in_fill_ = true}; +# endif + +enum class _LIBCPP_ENUM_VIS __alignment : uint8_t { + /// No alignment is set in the format string. + __default, + __left, + __center, + __right, + __zero_padding +}; + +enum class _LIBCPP_ENUM_VIS __sign : uint8_t { + /// No sign is set in the format string. + /// + /// The sign isn't allowed for certain format-types. By using this value + /// it's possible to detect whether or not the user explicitly set the sign + /// flag. For formatting purposes it behaves the same as \ref __minus. + __default, + __minus, + __plus, + __space +}; + +enum class _LIBCPP_ENUM_VIS __type : uint8_t { + __default, + __string, + __binary_lower_case, + __binary_upper_case, + __octal, + __decimal, + __hexadecimal_lower_case, + __hexadecimal_upper_case, + __pointer, + __char, + __hexfloat_lower_case, + __hexfloat_upper_case, + __scientific_lower_case, + __scientific_upper_case, + __fixed_lower_case, + __fixed_upper_case, + __general_lower_case, + __general_upper_case, + __debug +}; + +struct __std { + __alignment __alignment_ : 3; + __sign __sign_ : 2; + bool __alternate_form_ : 1; + bool __locale_specific_form_ : 1; + __type __type_; +}; + +struct __chrono { + __alignment __alignment_ : 3; + bool __locale_specific_form_ : 1; + bool __weekday_name_ : 1; + bool __weekday_ : 1; + bool __day_of_year_ : 1; + bool __week_of_year_ : 1; + bool __month_name_ : 1; +}; + +/// Contains the parsed formatting specifications. +/// +/// This contains information for both the std-format-spec and the +/// chrono-format-spec. This results in some unused members for both +/// specifications. However these unused members don't increase the size +/// of the structure. +/// +/// This struct doesn't cross ABI boundaries so its layout doesn't need to be +/// kept stable. +template +struct __parsed_specifications { + union { + // The field __alignment_ is the first element in __std_ and __chrono_. + // This allows the code to always inspect this value regards which member + // of the union is the active member [class.union.general]/2. + // + // This is needed since the generic output routines handle the alignment of + // the output. + __alignment __alignment_ : 3; + __std __std_; + __chrono __chrono_; + }; + + /// The requested width. + /// + /// When the format-spec used an arg-id for this field it has already been + /// replaced with the value of that arg-id. + int32_t __width_; + + /// The requested precision. + /// + /// When the format-spec used an arg-id for this field it has already been + /// replaced with the value of that arg-id. + int32_t __precision_; + + _CharT __fill_; + + _LIBCPP_HIDE_FROM_ABI constexpr bool __has_width() const { return __width_ > 0; } + + _LIBCPP_HIDE_FROM_ABI constexpr bool __has_precision() const { return __precision_ >= 0; } +}; + +// Validate the struct is small and cheap to copy since the struct is passed by +// value in formatting functions. +static_assert(sizeof(__parsed_specifications) == 16); +static_assert(is_trivially_copyable_v<__parsed_specifications>); +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +static_assert(sizeof(__parsed_specifications) == 16); +static_assert(is_trivially_copyable_v<__parsed_specifications>); +# endif + +/// The parser for the std-format-spec. +/// +/// Note this class is a member of std::formatter specializations. It's +/// expected developers will create their own formatter specializations that +/// inherit from the std::formatter specializations. This means this class +/// must be ABI stable. To aid the stability the unused bits in the class are +/// set to zero. That way they can be repurposed if a future revision of the +/// Standards adds new fields to std-format-spec. +template +class _LIBCPP_TEMPLATE_VIS __parser { +public: + _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(basic_format_parse_context<_CharT>& __parse_ctx, __fields __fields) + -> decltype(__parse_ctx.begin()) { + + const _CharT* __begin = __parse_ctx.begin(); + const _CharT* __end = __parse_ctx.end(); + if (__begin == __end) + return __begin; + + if (__parse_fill_align(__begin, __end, __fields.__allow_colon_in_fill_) && __begin == __end) + return __begin; + + if (__fields.__sign_ && __parse_sign(__begin) && __begin == __end) + return __begin; + + if (__fields.__alternate_form_ && __parse_alternate_form(__begin) && __begin == __end) + return __begin; + + if (__fields.__zero_padding_ && __parse_zero_padding(__begin) && __begin == __end) + return __begin; + + if (__parse_width(__begin, __end, __parse_ctx) && __begin == __end) + return __begin; + + if (__fields.__precision_ && __parse_precision(__begin, __end, __parse_ctx) && __begin == __end) + return __begin; + + if (__fields.__locale_specific_form_ && __parse_locale_specific_form(__begin) && __begin == __end) + return __begin; + + if (__fields.__type_) { + __parse_type(__begin); + + // When __type_ is false the calling parser is expected to do additional + // parsing. In that case that parser should do the end of format string + // validation. + if (__begin != __end && *__begin != _CharT('}')) + std::__throw_format_error("The format-spec should consume the input or end with a '}'"); + } + + return __begin; + } + + /// \returns the `__parsed_specifications` with the resolved dynamic sizes.. + _LIBCPP_HIDE_FROM_ABI + __parsed_specifications<_CharT> __get_parsed_std_specifications(auto& __ctx) const { + return __parsed_specifications<_CharT>{ + .__std_ = __std{.__alignment_ = __alignment_, + .__sign_ = __sign_, + .__alternate_form_ = __alternate_form_, + .__locale_specific_form_ = __locale_specific_form_, + .__type_ = __type_}, + .__width_{__get_width(__ctx)}, + .__precision_{__get_precision(__ctx)}, + .__fill_{__fill_}}; + } + + _LIBCPP_HIDE_FROM_ABI __parsed_specifications<_CharT> __get_parsed_chrono_specifications(auto& __ctx) const { + return __parsed_specifications<_CharT>{ + .__chrono_ = + __chrono{.__alignment_ = __alignment_, + .__locale_specific_form_ = __locale_specific_form_, + .__weekday_name_ = __weekday_name_, + .__weekday_ = __weekday_, + .__day_of_year_ = __day_of_year_, + .__week_of_year_ = __week_of_year_, + .__month_name_ = __month_name_}, + .__width_{__get_width(__ctx)}, + .__precision_{__get_precision(__ctx)}, + .__fill_{__fill_}}; + } + + __alignment __alignment_ : 3 {__alignment::__default}; + __sign __sign_ : 2 {__sign::__default}; + bool __alternate_form_ : 1 {false}; + bool __locale_specific_form_ : 1 {false}; + bool __reserved_0_ : 1 {false}; + __type __type_{__type::__default}; + + // These flags are only used for formatting chrono. Since the struct has + // padding space left it's added to this structure. + bool __weekday_name_ : 1 {false}; + bool __weekday_ : 1 {false}; + + bool __day_of_year_ : 1 {false}; + bool __week_of_year_ : 1 {false}; + + bool __month_name_ : 1 {false}; + + uint8_t __reserved_1_ : 3 {0}; + uint8_t __reserved_2_ : 6 {0}; + // These two flags are only used internally and not part of the + // __parsed_specifications. Therefore put them at the end. + bool __width_as_arg_ : 1 {false}; + bool __precision_as_arg_ : 1 {false}; + + /// The requested width, either the value or the arg-id. + int32_t __width_{0}; + + /// The requested precision, either the value or the arg-id. + int32_t __precision_{-1}; + + // LWG 3576 will probably change this to always accept a Unicode code point + // To avoid changing the size with that change align the field so when it + // becomes 32-bit its alignment will remain the same. That also means the + // size will remain the same. (D2572 addresses the solution for LWG 3576.) + _CharT __fill_{_CharT(' ')}; + +private: + _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_alignment(_CharT __c) { + switch (__c) { + case _CharT('<'): + __alignment_ = __alignment::__left; + return true; + + case _CharT('^'): + __alignment_ = __alignment::__center; + return true; + + case _CharT('>'): + __alignment_ = __alignment::__right; + return true; + } + return false; + } + + // range-fill and tuple-fill are identical + _LIBCPP_HIDE_FROM_ABI constexpr bool + __parse_fill_align(const _CharT*& __begin, const _CharT* __end, bool __use_range_fill) { + _LIBCPP_ASSERT(__begin != __end, "when called with an empty input the function will cause " + "undefined behavior by evaluating data not in the input"); + if (__begin + 1 != __end) { + if (__parse_alignment(*(__begin + 1))) { + if (__use_range_fill && (*__begin == _CharT('{') || *__begin == _CharT('}') || *__begin == _CharT(':'))) + std::__throw_format_error("The format-spec range-fill field contains an invalid character"); + else if (*__begin == _CharT('{') || *__begin == _CharT('}')) + std::__throw_format_error("The format-spec fill field contains an invalid character"); + + __fill_ = *__begin; + __begin += 2; + return true; + } + } + + if (!__parse_alignment(*__begin)) + return false; + + ++__begin; + return true; + } + + _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_sign(const _CharT*& __begin) { + switch (*__begin) { + case _CharT('-'): + __sign_ = __sign::__minus; + break; + case _CharT('+'): + __sign_ = __sign::__plus; + break; + case _CharT(' '): + __sign_ = __sign::__space; + break; + default: + return false; + } + ++__begin; + return true; + } + + _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_alternate_form(const _CharT*& __begin) { + if (*__begin != _CharT('#')) + return false; + + __alternate_form_ = true; + ++__begin; + return true; + } + + _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_zero_padding(const _CharT*& __begin) { + if (*__begin != _CharT('0')) + return false; + + if (__alignment_ == __alignment::__default) + __alignment_ = __alignment::__zero_padding; + ++__begin; + return true; + } + + _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_width(const _CharT*& __begin, const _CharT* __end, auto& __parse_ctx) { + if (*__begin == _CharT('0')) + std::__throw_format_error("A format-spec width field shouldn't have a leading zero"); + + if (*__begin == _CharT('{')) { + __format::__parse_number_result __r = __format_spec::__parse_arg_id(++__begin, __end, __parse_ctx); + __width_as_arg_ = true; + __width_ = __r.__value; + __begin = __r.__ptr; + return true; + } + + if (*__begin < _CharT('0') || *__begin > _CharT('9')) + return false; + + __format::__parse_number_result __r = __format::__parse_number(__begin, __end); + __width_ = __r.__value; + _LIBCPP_ASSERT(__width_ != 0, "A zero value isn't allowed and should be impossible, " + "due to validations in this function"); + __begin = __r.__ptr; + return true; + } + + _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_precision(const _CharT*& __begin, const _CharT* __end, + auto& __parse_ctx) { + if (*__begin != _CharT('.')) + return false; + + ++__begin; + if (__begin == __end) + std::__throw_format_error("End of input while parsing format-spec precision"); + + if (*__begin == _CharT('{')) { + __format::__parse_number_result __arg_id = __format_spec::__parse_arg_id(++__begin, __end, __parse_ctx); + __precision_as_arg_ = true; + __precision_ = __arg_id.__value; + __begin = __arg_id.__ptr; + return true; + } + + if (*__begin < _CharT('0') || *__begin > _CharT('9')) + std::__throw_format_error("The format-spec precision field doesn't contain a value or arg-id"); + + __format::__parse_number_result __r = __format::__parse_number(__begin, __end); + __precision_ = __r.__value; + __precision_as_arg_ = false; + __begin = __r.__ptr; + return true; + } + + _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_locale_specific_form(const _CharT*& __begin) { + if (*__begin != _CharT('L')) + return false; + + __locale_specific_form_ = true; + ++__begin; + return true; + } + + _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(const _CharT*& __begin) { + // Determines the type. It does not validate whether the selected type is + // valid. Most formatters have optional fields that are only allowed for + // certain types. These parsers need to do validation after the type has + // been parsed. So its easier to implement the validation for all types in + // the specific parse function. + switch (*__begin) { + case 'A': + __type_ = __type::__hexfloat_upper_case; + break; + case 'B': + __type_ = __type::__binary_upper_case; + break; + case 'E': + __type_ = __type::__scientific_upper_case; + break; + case 'F': + __type_ = __type::__fixed_upper_case; + break; + case 'G': + __type_ = __type::__general_upper_case; + break; + case 'X': + __type_ = __type::__hexadecimal_upper_case; + break; + case 'a': + __type_ = __type::__hexfloat_lower_case; + break; + case 'b': + __type_ = __type::__binary_lower_case; + break; + case 'c': + __type_ = __type::__char; + break; + case 'd': + __type_ = __type::__decimal; + break; + case 'e': + __type_ = __type::__scientific_lower_case; + break; + case 'f': + __type_ = __type::__fixed_lower_case; + break; + case 'g': + __type_ = __type::__general_lower_case; + break; + case 'o': + __type_ = __type::__octal; + break; + case 'p': + __type_ = __type::__pointer; + break; + case 's': + __type_ = __type::__string; + break; + case 'x': + __type_ = __type::__hexadecimal_lower_case; + break; +# if _LIBCPP_STD_VER > 20 + case '?': + __type_ = __type::__debug; + break; +# endif + default: + return; + } + ++__begin; + } + + _LIBCPP_HIDE_FROM_ABI + int32_t __get_width(auto& __ctx) const { + if (!__width_as_arg_) + return __width_; + + return __format_spec::__substitute_arg_id(__ctx.arg(__width_)); + } + + _LIBCPP_HIDE_FROM_ABI + int32_t __get_precision(auto& __ctx) const { + if (!__precision_as_arg_) + return __precision_; + + return __format_spec::__substitute_arg_id(__ctx.arg(__precision_)); + } +}; + +// Validates whether the reserved bitfields don't change the size. +static_assert(sizeof(__parser) == 16); +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +static_assert(sizeof(__parser) == 16); +# endif + +_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_string(__format_spec::__type __type) { + switch (__type) { + case __format_spec::__type::__default: + case __format_spec::__type::__string: + case __format_spec::__type::__debug: + break; + + default: + std::__throw_format_error("The format-spec type has a type not supported for a string argument"); + } +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_bool_string(__parser<_CharT>& __parser) { + if (__parser.__sign_ != __sign::__default) + std::__throw_format_error("A sign field isn't allowed in this format-spec"); + + if (__parser.__alternate_form_) + std::__throw_format_error("An alternate form field isn't allowed in this format-spec"); + + if (__parser.__alignment_ == __alignment::__zero_padding) + std::__throw_format_error("A zero-padding field isn't allowed in this format-spec"); + + if (__parser.__alignment_ == __alignment::__default) + __parser.__alignment_ = __alignment::__left; +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_char(__parser<_CharT>& __parser) { + __format_spec::__process_display_type_bool_string(__parser); +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_bool(__parser<_CharT>& __parser) { + switch (__parser.__type_) { + case __format_spec::__type::__default: + case __format_spec::__type::__string: + __format_spec::__process_display_type_bool_string(__parser); + break; + + case __format_spec::__type::__binary_lower_case: + case __format_spec::__type::__binary_upper_case: + case __format_spec::__type::__octal: + case __format_spec::__type::__decimal: + case __format_spec::__type::__hexadecimal_lower_case: + case __format_spec::__type::__hexadecimal_upper_case: + break; + + default: + std::__throw_format_error("The format-spec type has a type not supported for a bool argument"); + } +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_char(__parser<_CharT>& __parser) { + switch (__parser.__type_) { + case __format_spec::__type::__default: + case __format_spec::__type::__char: + case __format_spec::__type::__debug: + __format_spec::__process_display_type_char(__parser); + break; + + case __format_spec::__type::__binary_lower_case: + case __format_spec::__type::__binary_upper_case: + case __format_spec::__type::__octal: + case __format_spec::__type::__decimal: + case __format_spec::__type::__hexadecimal_lower_case: + case __format_spec::__type::__hexadecimal_upper_case: + break; + + default: + std::__throw_format_error("The format-spec type has a type not supported for a char argument"); + } +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_integer(__parser<_CharT>& __parser) { + switch (__parser.__type_) { + case __format_spec::__type::__default: + case __format_spec::__type::__binary_lower_case: + case __format_spec::__type::__binary_upper_case: + case __format_spec::__type::__octal: + case __format_spec::__type::__decimal: + case __format_spec::__type::__hexadecimal_lower_case: + case __format_spec::__type::__hexadecimal_upper_case: + break; + + case __format_spec::__type::__char: + __format_spec::__process_display_type_char(__parser); + break; + + default: + std::__throw_format_error("The format-spec type has a type not supported for an integer argument"); + } +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_floating_point(__parser<_CharT>& __parser) { + switch (__parser.__type_) { + case __format_spec::__type::__default: + case __format_spec::__type::__hexfloat_lower_case: + case __format_spec::__type::__hexfloat_upper_case: + // Precision specific behavior will be handled later. + break; + case __format_spec::__type::__scientific_lower_case: + case __format_spec::__type::__scientific_upper_case: + case __format_spec::__type::__fixed_lower_case: + case __format_spec::__type::__fixed_upper_case: + case __format_spec::__type::__general_lower_case: + case __format_spec::__type::__general_upper_case: + if (!__parser.__precision_as_arg_ && __parser.__precision_ == -1) + // Set the default precision for the call to to_chars. + __parser.__precision_ = 6; + break; + + default: + std::__throw_format_error("The format-spec type has a type not supported for a floating-point argument"); + } +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_pointer(__format_spec::__type __type) { + switch (__type) { + case __format_spec::__type::__default: + case __format_spec::__type::__pointer: + break; + + default: + std::__throw_format_error("The format-spec type has a type not supported for a pointer argument"); + } +} + +template +struct __column_width_result { + /// The number of output columns. + size_t __width_; + /// One beyond the last code unit used in the estimation. + /// + /// This limits the original output to fit in the wanted number of columns. + const _CharT* __last_; +}; + +template +__column_width_result(size_t, const _CharT*) -> __column_width_result<_CharT>; + +/// Since a column width can be two it's possible that the requested column +/// width can't be achieved. Depending on the intended usage the policy can be +/// selected. +/// - When used as precision the maximum width may not be exceeded and the +/// result should be "rounded down" to the previous boundary. +/// - When used as a width we're done once the minimum is reached, but +/// exceeding is not an issue. Rounding down is an issue since that will +/// result in writing fill characters. Therefore the result needs to be +/// "rounded up". +enum class __column_width_rounding { __down, __up }; + +# ifndef _LIBCPP_HAS_NO_UNICODE + +namespace __detail { + +/// Converts a code point to the column width. +/// +/// The estimations are conforming to [format.string.general]/11 +/// +/// This version expects a value less than 0x1'0000, which is a 3-byte UTF-8 +/// character. +_LIBCPP_HIDE_FROM_ABI constexpr int __column_width_3(uint32_t __c) noexcept { + _LIBCPP_ASSERT(__c < 0x10000, "Use __column_width_4 or __column_width for larger values"); + + // clang-format off + return 1 + (__c >= 0x1100 && (__c <= 0x115f || + (__c >= 0x2329 && (__c <= 0x232a || + (__c >= 0x2e80 && (__c <= 0x303e || + (__c >= 0x3040 && (__c <= 0xa4cf || + (__c >= 0xac00 && (__c <= 0xd7a3 || + (__c >= 0xf900 && (__c <= 0xfaff || + (__c >= 0xfe10 && (__c <= 0xfe19 || + (__c >= 0xfe30 && (__c <= 0xfe6f || + (__c >= 0xff00 && (__c <= 0xff60 || + (__c >= 0xffe0 && (__c <= 0xffe6 + )))))))))))))))))))); + // clang-format on +} + +/// @overload +/// +/// This version expects a value greater than or equal to 0x1'0000, which is a +/// 4-byte UTF-8 character. +_LIBCPP_HIDE_FROM_ABI constexpr int __column_width_4(uint32_t __c) noexcept { + _LIBCPP_ASSERT(__c >= 0x10000, "Use __column_width_3 or __column_width for smaller values"); + + // clang-format off + return 1 + (__c >= 0x1'f300 && (__c <= 0x1'f64f || + (__c >= 0x1'f900 && (__c <= 0x1'f9ff || + (__c >= 0x2'0000 && (__c <= 0x2'fffd || + (__c >= 0x3'0000 && (__c <= 0x3'fffd + )))))))); + // clang-format on +} + +/// @overload +/// +/// The general case, accepting all values. +_LIBCPP_HIDE_FROM_ABI constexpr int __column_width(uint32_t __c) noexcept { + if (__c < 0x10000) + return __detail::__column_width_3(__c); + + return __detail::__column_width_4(__c); +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> __estimate_column_width_grapheme_clustering( + const _CharT* __first, const _CharT* __last, size_t __maximum, __column_width_rounding __rounding) noexcept { + __unicode::__extended_grapheme_cluster_view<_CharT> __view{__first, __last}; + + __column_width_result<_CharT> __result{0, __first}; + while (__result.__last_ != __last && __result.__width_ <= __maximum) { + typename __unicode::__extended_grapheme_cluster_view<_CharT>::__cluster __cluster = __view.__consume(); + int __width = __detail::__column_width(__cluster.__code_point_); + + // When the next entry would exceed the maximum width the previous width + // might be returned. For example when a width of 100 is requested the + // returned width might be 99, since the next code point has an estimated + // column width of 2. This depends on the rounding flag. + // When the maximum is exceeded the loop will abort the next iteration. + if (__rounding == __column_width_rounding::__down && __result.__width_ + __width > __maximum) + return __result; + + __result.__width_ += __width; + __result.__last_ = __cluster.__last_; + } + + return __result; +} + +} // namespace __detail + +// Unicode can be stored in several formats: UTF-8, UTF-16, and UTF-32. +// Depending on format the relation between the number of code units stored and +// the number of output columns differs. The first relation is the number of +// code units forming a code point. (The text assumes the code units are +// unsigned.) +// - UTF-8 The number of code units is between one and four. The first 127 +// Unicode code points match the ASCII character set. When the highest bit is +// set it means the code point has more than one code unit. +// - UTF-16: The number of code units is between 1 and 2. When the first +// code unit is in the range [0xd800,0xdfff) it means the code point uses two +// code units. +// - UTF-32: The number of code units is always one. +// +// The code point to the number of columns is specified in +// [format.string.std]/11. This list might change in the future. +// +// Another thing to be taken into account is Grapheme clustering. This means +// that in some cases multiple code points are combined one element in the +// output. For example: +// - an ASCII character with a combined diacritical mark +// - an emoji with a skin tone modifier +// - a group of combined people emoji to create a family +// - a combination of flag emoji +// +// See also: +// - [format.string.general]/11 +// - https://en.wikipedia.org/wiki/UTF-8#Encoding +// - https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF + +_LIBCPP_HIDE_FROM_ABI constexpr bool __is_ascii(char32_t __c) { return __c < 0x80; } + +/// Determines the number of output columns needed to render the input. +/// +/// \note When the scanner encounters malformed Unicode it acts as-if every +/// code unit is a one column code point. Typically a terminal uses the same +/// strategy and replaces every malformed code unit with a one column +/// replacement character. +/// +/// \param __first Points to the first element of the input range. +/// \param __last Points beyond the last element of the input range. +/// \param __maximum The maximum number of output columns. The returned number +/// of estimated output columns will not exceed this value. +/// \param __rounding Selects the rounding method. +/// \c __down result.__width_ <= __maximum +/// \c __up result.__width_ <= __maximum + 1 +template +_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> __estimate_column_width( + basic_string_view<_CharT> __str, size_t __maximum, __column_width_rounding __rounding) noexcept { + // The width estimation is done in two steps: + // - Quickly process for the ASCII part. ASCII has the following properties + // - One code unit is one code point + // - Every code point has an estimated width of one + // - When needed it will a Unicode Grapheme clustering algorithm to find + // the proper place for truncation. + + if (__str.empty() || __maximum == 0) + return {0, __str.begin()}; + + // ASCII has one caveat; when an ASCII character is followed by a non-ASCII + // character they might be part of an extended grapheme cluster. For example: + // an ASCII letter and a COMBINING ACUTE ACCENT + // The truncate should happen after the COMBINING ACUTE ACCENT. Therefore we + // need to scan one code unit beyond the requested precision. When this code + // unit is non-ASCII we omit the current code unit and let the Grapheme + // clustering algorithm do its work. + const _CharT* __it = __str.begin(); + if (__format_spec::__is_ascii(*__it)) { + do { + --__maximum; + ++__it; + if (__it == __str.end()) + return {__str.size(), __str.end()}; + + if (__maximum == 0) { + if (__format_spec::__is_ascii(*__it)) + return {static_cast(__it - __str.begin()), __it}; + + break; + } + } while (__format_spec::__is_ascii(*__it)); + --__it; + ++__maximum; + } + + ptrdiff_t __ascii_size = __it - __str.begin(); + __column_width_result __result = + __detail::__estimate_column_width_grapheme_clustering(__it, __str.end(), __maximum, __rounding); + + __result.__width_ += __ascii_size; + return __result; +} +# else // !defined(_LIBCPP_HAS_NO_UNICODE) +template +_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> +__estimate_column_width(basic_string_view<_CharT> __str, size_t __maximum, __column_width_rounding) noexcept { + // When Unicode isn't supported assume ASCII and every code unit is one code + // point. In ASCII the estimated column width is always one. Thus there's no + // need for rounding. + size_t __width_ = _VSTD::min(__str.size(), __maximum); + return {__width_, __str.begin() + __width_}; +} + +# endif // !defined(_LIBCPP_HAS_NO_UNICODE) + +} // namespace __format_spec + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___FORMAT_PARSER_STD_FORMAT_SPEC_H diff --git a/app/src/main/cpp/libcxx/include/__format/range_default_formatter.h b/app/src/main/cpp/libcxx/include/__format/range_default_formatter.h new file mode 100644 index 0000000..774887b --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/range_default_formatter.h @@ -0,0 +1,201 @@ +// -*- 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 _LIBCPP___FORMAT_RANGE_DEFAULT_FORMATTER_H +#define _LIBCPP___FORMAT_RANGE_DEFAULT_FORMATTER_H + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#include <__availability> +#include <__chrono/statically_widen.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__format/concepts.h> +#include <__format/formatter.h> +#include <__format/range_formatter.h> +#include <__ranges/concepts.h> +#include <__type_traits/remove_cvref.h> +#include <__utility/pair.h> +#include +#include + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 20 + +template +concept __const_formattable_range = + ranges::input_range && formattable, _CharT>; + +template +using __fmt_maybe_const = conditional_t<__const_formattable_range<_Rp, _CharT>, const _Rp, _Rp>; + +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wshadow") +_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshadow") +// This shadows map, set, and string. +enum class range_format { disabled, map, set, sequence, string, debug_string }; +_LIBCPP_DIAGNOSTIC_POP + +// There is no definition of this struct, it's purely intended to be used to +// generate diagnostics. +template +struct _LIBCPP_TEMPLATE_VIS __instantiated_the_primary_template_of_format_kind; + +template +constexpr range_format format_kind = [] { + // [format.range.fmtkind]/1 + // A program that instantiates the primary template of format_kind is ill-formed. + static_assert(sizeof(_Rp) != sizeof(_Rp), "create a template specialization of format_kind for your type"); + return range_format::disabled; +}(); + +template + requires same_as<_Rp, remove_cvref_t<_Rp>> +inline constexpr range_format format_kind<_Rp> = [] { + // [format.range.fmtkind]/2 + + // 2.1 If same_as>, R> is true, + // Otherwise format_kind is range_format::disabled. + if constexpr (same_as>, _Rp>) + return range_format::disabled; + // 2.2 Otherwise, if the qualified-id R::key_type is valid and denotes a type: + else if constexpr (requires { typename _Rp::key_type; }) { + // 2.2.1 If the qualified-id R::mapped_type is valid and denotes a type ... + if constexpr (requires { typename _Rp::mapped_type; } && + // 2.2.1 ... If either U is a specialization of pair or U is a specialization + // of tuple and tuple_size_v == 2 + __fmt_pair_like>>) + return range_format::map; + else + // 2.2.2 Otherwise format_kind is range_format::set. + return range_format::set; + } else + // 2.3 Otherwise, format_kind is range_format::sequence. + return range_format::sequence; +}(); + +// This is a non-standard work-around to fix instantiation of +// formatter +// const _CharT[N] satisfies the ranges::input_range concept. +// remove_cvref_t is _CharT[N] so it does not satisfy the +// requirement of the above specialization. Instead it will instantiate the +// primary template, which is ill-formed. +// +// An alternative solution is to remove the offending formatter. +// +// https://godbolt.org/z/bqjhhaexx +// +// The removal is proposed in LWG3833, but use the work-around until the issue +// has been adopted. +// TODO FMT Implement LWG3833. +template +inline constexpr range_format format_kind = range_format::disabled; + +template +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter; + +// Required specializations + +template +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter { +private: + using __maybe_const_r = __fmt_maybe_const<_Rp, _CharT>; + range_formatter>, _CharT> __underlying_; + +public: + _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) { + __underlying_.set_separator(__separator); + } + _LIBCPP_HIDE_FROM_ABI constexpr void + set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) { + __underlying_.set_brackets(__opening_bracket, __closing_bracket); + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { + return __underlying_.parse(__ctx); + } + + template + _LIBCPP_HIDE_FROM_ABI typename FormatContext::iterator format(__maybe_const_r& __range, FormatContext& __ctx) const { + return __underlying_.format(__range, __ctx); + } +}; + +template +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter { +private: + using __maybe_const_map = __fmt_maybe_const<_Rp, _CharT>; + using __element_type = remove_cvref_t>; + range_formatter<__element_type, _CharT> __underlying_; + +public: + _LIBCPP_HIDE_FROM_ABI constexpr __range_default_formatter() + requires(__fmt_pair_like<__element_type>) + { + __underlying_.set_brackets(_LIBCPP_STATICALLY_WIDEN(_CharT, "{"), _LIBCPP_STATICALLY_WIDEN(_CharT, "}")); + __underlying_.underlying().set_brackets({}, {}); + __underlying_.underlying().set_separator(_LIBCPP_STATICALLY_WIDEN(_CharT, ": ")); + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { + return __underlying_.parse(__ctx); + } + + template + _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator + format(__maybe_const_map& __range, _FormatContext& __ctx) const { + return __underlying_.format(__range, __ctx); + } +}; + +template +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter { +private: + using __maybe_const_set = __fmt_maybe_const<_Rp, _CharT>; + using __element_type = remove_cvref_t>; + range_formatter<__element_type, _CharT> __underlying_; + +public: + _LIBCPP_HIDE_FROM_ABI constexpr __range_default_formatter() { + __underlying_.set_brackets(_LIBCPP_STATICALLY_WIDEN(_CharT, "{"), _LIBCPP_STATICALLY_WIDEN(_CharT, "}")); + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { + return __underlying_.parse(__ctx); + } + + template + _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator + format(__maybe_const_set& __range, _FormatContext& __ctx) const { + return __underlying_.format(__range, __ctx); + } +}; + +template + requires(_Kp == range_format::string || _Kp == range_format::debug_string) +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<_Kp, _Rp, _CharT> { + __range_default_formatter() = delete; // TODO FMT Implement +}; + +template + requires(format_kind<_Rp> != range_format::disabled && formattable, _CharT>) +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_Rp, _CharT> + : __range_default_formatter, _Rp, _CharT> {}; + +#endif //_LIBCPP_STD_VER > 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_RANGE_DEFAULT_FORMATTER_H diff --git a/app/src/main/cpp/libcxx/include/__format/range_formatter.h b/app/src/main/cpp/libcxx/include/__format/range_formatter.h new file mode 100644 index 0000000..9ea61a7 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/range_formatter.h @@ -0,0 +1,255 @@ +// -*- 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 _LIBCPP___FORMAT_RANGE_FORMATTER_H +#define _LIBCPP___FORMAT_RANGE_FORMATTER_H + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#include <__algorithm/ranges_copy.h> +#include <__availability> +#include <__chrono/statically_widen.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__format/buffer.h> +#include <__format/concepts.h> +#include <__format/format_args.h> +#include <__format/format_context.h> +#include <__format/format_error.h> +#include <__format/formatter.h> +#include <__format/formatter_output.h> +#include <__format/parser_std_format_spec.h> +#include <__iterator/back_insert_iterator.h> +#include <__ranges/concepts.h> +#include <__ranges/data.h> +#include <__ranges/size.h> +#include <__type_traits/remove_cvref.h> +#include + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 20 + +template + requires same_as, _Tp> && formattable<_Tp, _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT range_formatter { + _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) { + __separator_ = __separator; + } + _LIBCPP_HIDE_FROM_ABI constexpr void + set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) { + __opening_bracket_ = __opening_bracket; + __closing_bracket_ = __closing_bracket; + } + + _LIBCPP_HIDE_FROM_ABI constexpr formatter<_Tp, _CharT>& underlying() { return __underlying_; } + _LIBCPP_HIDE_FROM_ABI constexpr const formatter<_Tp, _CharT>& underlying() const { return __underlying_; } + + template + _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __parse_ctx) { + const _CharT* __begin = __parser_.__parse(__parse_ctx, __format_spec::__fields_range); + const _CharT* __end = __parse_ctx.end(); + if (__begin == __end) + return __begin; + + // The n field overrides a possible m type, therefore delay applying the + // effect of n until the type has been procesed. + bool __clear_brackets = (*__begin == _CharT('n')); + if (__clear_brackets) { + ++__begin; + if (__begin == __end) { + // Since there is no more data, clear the brackets before returning. + set_brackets({}, {}); + return __begin; + } + } + + __parse_type(__begin, __end); + if (__clear_brackets) + set_brackets({}, {}); + if (__begin == __end) + return __begin; + + bool __has_range_underlying_spec = *__begin == _CharT(':'); + if (__parser_.__type_ != __format_spec::__type::__default) { + // [format.range.formatter]/6 + // If the range-type is s or ?s, then there shall be no n option and no + // range-underlying-spec. + if (__clear_brackets) { + if (__parser_.__type_ == __format_spec::__type::__string) + std::__throw_format_error("The n option and type s can't be used together"); + std::__throw_format_error("The n option and type ?s can't be used together"); + } + if (__has_range_underlying_spec) { + if (__parser_.__type_ == __format_spec::__type::__string) + std::__throw_format_error("Type s and an underlying format specification can't be used together"); + std::__throw_format_error("Type ?s and an underlying format specification can't be used together"); + } + } else if (!__has_range_underlying_spec) + std::__set_debug_format(__underlying_); + + if (__has_range_underlying_spec) { + // range-underlying-spec: + // : format-spec + ++__begin; + if (__begin == __end) + return __begin; + + __parse_ctx.advance_to(__begin); + __begin = __underlying_.parse(__parse_ctx); + } + + if (__begin != __end && *__begin != _CharT('}')) + std::__throw_format_error("The format-spec should consume the input or end with a '}'"); + + return __begin; + } + + template + requires formattable, _CharT> && + same_as>, _Tp> + _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(_Rp&& __range, _FormatContext& __ctx) const { + __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx); + + if (!__specs.__has_width()) + return __format_range(__range, __ctx, __specs); + + // The size of the buffer needed is: + // - open bracket characters + // - close bracket character + // - n elements where every element may have a different size + // - (n -1) separators + // The size of the element is hard to predict, knowing the type helps but + // it depends on the format-spec. As an initial estimate we guess 6 + // characters. + // Typically both brackets are 1 character and the separator is 2 + // characters. Which means there will be + // (n - 1) * 2 + 1 + 1 = n * 2 character + // So estimate 8 times the range size as buffer. + std::size_t __capacity_hint = 0; + if constexpr (std::ranges::sized_range<_Rp>) + __capacity_hint = 8 * ranges::size(__range); + __format::__retarget_buffer<_CharT> __buffer{__capacity_hint}; + basic_format_context::__iterator, _CharT> __c{ + __buffer.__make_output_iterator(), __ctx}; + + __format_range(__range, __c, __specs); + + return __formatter::__write_string_no_precision(__buffer.__view(), __ctx.out(), __specs); + } + + template + typename _FormatContext::iterator _LIBCPP_HIDE_FROM_ABI + __format_range(_Rp&& __range, _FormatContext& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) const { + if constexpr (same_as<_Tp, _CharT>) { + switch (__specs.__std_.__type_) { + case __format_spec::__type::__string: + case __format_spec::__type::__debug: + return __format_as_string(__range, __ctx, __specs.__std_.__type_ == __format_spec::__type::__debug); + default: + return __format_as_sequence(__range, __ctx); + } + } else + return __format_as_sequence(__range, __ctx); + } + + template + _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator + __format_as_string(_Rp&& __range, _FormatContext& __ctx, bool __debug_format) const { + // When the range is contiguous use a basic_string_view instead to avoid a + // copy of the underlying data. The basic_string_view formatter + // specialization is the "basic" string formatter in libc++. + if constexpr (ranges::contiguous_range<_Rp> && std::ranges::sized_range<_Rp>) { + std::formatter, _CharT> __formatter; + if (__debug_format) + __formatter.set_debug_format(); + return __formatter.format( + basic_string_view<_CharT>{ + ranges::data(__range), + ranges::size(__range), + }, + __ctx); + } else { + std::formatter, _CharT> __formatter; + if (__debug_format) + __formatter.set_debug_format(); + // P2106's from_range has not been implemented yet. Instead use a simple + // copy operation. + // TODO FMT use basic_string's "from_range" constructor. + // return std::formatter, _CharT>{}.format(basic_string<_CharT>{from_range, __range}, __ctx); + basic_string<_CharT> __str; + ranges::copy(__range, back_insert_iterator{__str}); + return __formatter.format(__str, __ctx); + } + } + + template + _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator + __format_as_sequence(_Rp&& __range, _FormatContext& __ctx) const { + __ctx.advance_to(ranges::copy(__opening_bracket_, __ctx.out()).out); + bool __use_separator = false; + for (auto&& __e : __range) { + if (__use_separator) + __ctx.advance_to(ranges::copy(__separator_, __ctx.out()).out); + else + __use_separator = true; + + __ctx.advance_to(__underlying_.format(__e, __ctx)); + } + + return ranges::copy(__closing_bracket_, __ctx.out()).out; + } + + __format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__left}; + +private: + _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(const _CharT*& __begin, const _CharT* __end) { + switch (*__begin) { + case _CharT('m'): + if constexpr (__fmt_pair_like<_Tp>) { + set_brackets(_LIBCPP_STATICALLY_WIDEN(_CharT, "{"), _LIBCPP_STATICALLY_WIDEN(_CharT, "}")); + set_separator(_LIBCPP_STATICALLY_WIDEN(_CharT, ", ")); + ++__begin; + } else + std::__throw_format_error("The range-format-spec type m requires two elements for a pair or tuple"); + break; + + case _CharT('s'): + if constexpr (same_as<_Tp, _CharT>) { + __parser_.__type_ = __format_spec::__type::__string; + ++__begin; + } else + std::__throw_format_error("The range-format-spec type s requires formatting a character type"); + break; + + case _CharT('?'): + ++__begin; + if (__begin == __end || *__begin != _CharT('s')) + std::__throw_format_error("The format-spec should consume the input or end with a '}'"); + if constexpr (same_as<_Tp, _CharT>) { + __parser_.__type_ = __format_spec::__type::__debug; + ++__begin; + } else + std::__throw_format_error("The range-format-spec type ?s requires formatting a character type"); + } + } + + formatter<_Tp, _CharT> __underlying_; + basic_string_view<_CharT> __separator_ = _LIBCPP_STATICALLY_WIDEN(_CharT, ", "); + basic_string_view<_CharT> __opening_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, "["); + basic_string_view<_CharT> __closing_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, "]"); +}; + +#endif //_LIBCPP_STD_VER > 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_RANGE_FORMATTER_H diff --git a/app/src/main/cpp/libcxx/include/__format/unicode.h b/app/src/main/cpp/libcxx/include/__format/unicode.h new file mode 100644 index 0000000..4327258 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__format/unicode.h @@ -0,0 +1,489 @@ +// -*- 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 _LIBCPP___FORMAT_UNICODE_H +#define _LIBCPP___FORMAT_UNICODE_H + +#include <__assert> +#include <__config> +#include <__format/extended_grapheme_cluster_table.h> +#include <__type_traits/make_unsigned.h> +#include <__utility/unreachable.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __unicode { + +# if _LIBCPP_STD_VER > 20 + +/// The result of consuming a code point using P2286' semantics +/// +/// TODO FMT Combine __consume and __consume_p2286 in one function. +struct __consume_p2286_result { + // A size of 0 means well formed. This to differenciate between + // a valid code point and a code unit that's invalid like 0b11111xxx. + int __ill_formed_size; + + // If well formed the consumed code point. + // Otherwise the ill-formed code units as unsigned 8-bit values. They are + // stored in reverse order, to make it easier to extract the values. + char32_t __value; +}; + +# endif // _LIBCPP_STD_VER > 20 + +# ifndef _LIBCPP_HAS_NO_UNICODE + +/// Implements the grapheme cluster boundary rules +/// +/// These rules are used to implement format's width estimation as stated in +/// [format.string.std]/11 +/// +/// The Standard refers to UAX \#29 for Unicode 12.0.0 +/// https://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundary_Rules +/// +/// The data tables used are +/// https://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakProperty.txt +/// https://www.unicode.org/Public/UCD/latest/ucd/emoji/emoji-data.txt +/// https://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakTest.txt (for testing only) + +inline constexpr char32_t __replacement_character = U'\ufffd'; + +_LIBCPP_HIDE_FROM_ABI constexpr bool __is_continuation(const char* __char, int __count) { + do { + if ((*__char & 0b1000'0000) != 0b1000'0000) + return false; + --__count; + ++__char; + } while (__count); + return true; +} + +/// Helper class to extract a code unit from a Unicode character range. +/// +/// The stored range is a view. There are multiple specialization for different +/// character types. +template +class __code_point_view; + +/// UTF-8 specialization. +template <> +class __code_point_view { +public: + _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(const char* __first, const char* __last) + : __first_(__first), __last_(__last) {} + + _LIBCPP_HIDE_FROM_ABI constexpr bool __at_end() const noexcept { return __first_ == __last_; } + _LIBCPP_HIDE_FROM_ABI constexpr const char* __position() const noexcept { return __first_; } + + _LIBCPP_HIDE_FROM_ABI constexpr char32_t __consume() noexcept { + _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input"); + + // Based on the number of leading 1 bits the number of code units in the + // code point can be determined. See + // https://en.wikipedia.org/wiki/UTF-8#Encoding + switch (_VSTD::countl_one(static_cast(*__first_))) { + case 0: + return *__first_++; + + case 2: + if (__last_ - __first_ < 2 || !__unicode::__is_continuation(__first_ + 1, 1)) [[unlikely]] + break; + else { + char32_t __value = static_cast(*__first_++) & 0x1f; + __value <<= 6; + __value |= static_cast(*__first_++) & 0x3f; + return __value; + } + + case 3: + if (__last_ - __first_ < 3 || !__unicode::__is_continuation(__first_ + 1, 2)) [[unlikely]] + break; + else { + char32_t __value = static_cast(*__first_++) & 0x0f; + __value <<= 6; + __value |= static_cast(*__first_++) & 0x3f; + __value <<= 6; + __value |= static_cast(*__first_++) & 0x3f; + return __value; + } + + case 4: + if (__last_ - __first_ < 4 || !__unicode::__is_continuation(__first_ + 1, 3)) [[unlikely]] + break; + else { + char32_t __value = static_cast(*__first_++) & 0x07; + __value <<= 6; + __value |= static_cast(*__first_++) & 0x3f; + __value <<= 6; + __value |= static_cast(*__first_++) & 0x3f; + __value <<= 6; + __value |= static_cast(*__first_++) & 0x3f; + return __value; + } + } + // An invalid number of leading ones can be garbage or a code unit in the + // middle of a code point. By consuming one code unit the parser may get + // "in sync" after a few code units. + ++__first_; + return __replacement_character; + } + +# if _LIBCPP_STD_VER > 20 + _LIBCPP_HIDE_FROM_ABI constexpr __consume_p2286_result __consume_p2286() noexcept { + _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input"); + + // Based on the number of leading 1 bits the number of code units in the + // code point can be determined. See + // https://en.wikipedia.org/wiki/UTF-8#Encoding + switch (std::countl_one(static_cast(*__first_))) { + case 0: + return {0, static_cast(*__first_++)}; + + case 2: + if (__last_ - __first_ < 2) [[unlikely]] + break; + + if (__unicode::__is_continuation(__first_ + 1, 1)) { + char32_t __value = static_cast(*__first_++) & 0x1f; + __value <<= 6; + __value |= static_cast(*__first_++) & 0x3f; + return {0, __value}; + } + break; + + case 3: + if (__last_ - __first_ < 3) [[unlikely]] + break; + + if (__unicode::__is_continuation(__first_ + 1, 2)) { + char32_t __value = static_cast(*__first_++) & 0x0f; + __value <<= 6; + __value |= static_cast(*__first_++) & 0x3f; + __value <<= 6; + __value |= static_cast(*__first_++) & 0x3f; + return {0, __value}; + } + break; + + case 4: + if (__last_ - __first_ < 4) [[unlikely]] + break; + + if (__unicode::__is_continuation(__first_ + 1, 3)) { + char32_t __value = static_cast(*__first_++) & 0x07; + __value <<= 6; + __value |= static_cast(*__first_++) & 0x3f; + __value <<= 6; + __value |= static_cast(*__first_++) & 0x3f; + __value <<= 6; + __value |= static_cast(*__first_++) & 0x3f; + + if (__value > 0x10FFFF) // Outside the valid Unicode range? + return {4, __value}; + + return {0, __value}; + } + break; + } + // An invalid number of leading ones can be garbage or a code unit in the + // middle of a code point. By consuming one code unit the parser may get + // "in sync" after a few code units. + return {1, static_cast(*__first_++)}; + } +# endif // _LIBCPP_STD_VER > 20 + +private: + const char* __first_; + const char* __last_; +}; + +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +_LIBCPP_HIDE_FROM_ABI constexpr bool __is_surrogate_pair_high(wchar_t __value) { + return __value >= 0xd800 && __value <= 0xdbff; +} + +_LIBCPP_HIDE_FROM_ABI constexpr bool __is_surrogate_pair_low(wchar_t __value) { + return __value >= 0xdc00 && __value <= 0xdfff; +} + +/// This specialization depends on the size of wchar_t +/// - 2 UTF-16 (for example Windows and AIX) +/// - 4 UTF-32 (for example Linux) +template <> +class __code_point_view { +public: + static_assert(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4, "sizeof(wchar_t) has a not implemented value"); + + _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(const wchar_t* __first, const wchar_t* __last) + : __first_(__first), __last_(__last) {} + + _LIBCPP_HIDE_FROM_ABI constexpr const wchar_t* __position() const noexcept { return __first_; } + _LIBCPP_HIDE_FROM_ABI constexpr bool __at_end() const noexcept { return __first_ == __last_; } + + _LIBCPP_HIDE_FROM_ABI constexpr char32_t __consume() noexcept { + _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input"); + + if constexpr (sizeof(wchar_t) == 2) { + char32_t __result = *__first_++; + // Is the code unit part of a surrogate pair? See + // https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF + if (__result >= 0xd800 && __result <= 0xDfff) { + // Malformed Unicode. + if (__first_ == __last_) [[unlikely]] + return __replacement_character; + + __result -= 0xd800; + __result <<= 10; + __result += *__first_++ - 0xdc00; + __result += 0x10000; + } + return __result; + + } else if constexpr (sizeof(wchar_t) == 4) { + char32_t __result = *__first_++; + if (__result > 0x10FFFF) [[unlikely]] + return __replacement_character; + return __result; + } else { + __libcpp_unreachable(); + } + } + +# if _LIBCPP_STD_VER > 20 + _LIBCPP_HIDE_FROM_ABI constexpr __consume_p2286_result __consume_p2286() noexcept { + _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input"); + + char32_t __result = *__first_++; + if constexpr (sizeof(wchar_t) == 2) { + // https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF + if (__is_surrogate_pair_high(__result)) { + // Malformed Unicode. + if (__first_ == __last_ || !__is_surrogate_pair_low(*(__first_ + 1))) [[unlikely]] + return {1, __result}; + + __result -= 0xd800; + __result <<= 10; + __result += *__first_++ - 0xdc00; + __result += 0x10000; + } else if (__is_surrogate_pair_low(__result)) + // A code point shouldn't start with the low surrogate pair + return {1, __result}; + } else { + if (__result > 0x10FFFF) [[unlikely]] + return {1, __result}; + } + + return {0, __result}; + } +# endif // _LIBCPP_STD_VER > 20 + +private: + const wchar_t* __first_; + const wchar_t* __last_; +}; +# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS + +_LIBCPP_HIDE_FROM_ABI constexpr bool __at_extended_grapheme_cluster_break( + bool& __ri_break_allowed, + bool __has_extened_pictographic, + __extended_grapheme_custer_property_boundary::__property __prev, + __extended_grapheme_custer_property_boundary::__property __next) { + using __extended_grapheme_custer_property_boundary::__property; + + __has_extened_pictographic |= __prev == __property::__Extended_Pictographic; + + // https://www.unicode.org/reports/tr29/tr29-39.html#Grapheme_Cluster_Boundary_Rules + + // *** Break at the start and end of text, unless the text is empty. *** + + _LIBCPP_ASSERT(__prev != __property::__sot, "should be handled in the constructor"); // GB1 + _LIBCPP_ASSERT(__prev != __property::__eot, "should be handled by our caller"); // GB2 + + // *** Do not break between a CR and LF. Otherwise, break before and after controls. *** + if (__prev == __property::__CR && __next == __property::__LF) // GB3 + return false; + + if (__prev == __property::__Control || __prev == __property::__CR || __prev == __property::__LF) // GB4 + return true; + + if (__next == __property::__Control || __next == __property::__CR || __next == __property::__LF) // GB5 + return true; + + // *** Do not break Hangul syllable sequences. *** + if (__prev == __property::__L && + (__next == __property::__L || __next == __property::__V || __next == __property::__LV || + __next == __property::__LVT)) // GB6 + return false; + + if ((__prev == __property::__LV || __prev == __property::__V) && + (__next == __property::__V || __next == __property::__T)) // GB7 + return false; + + if ((__prev == __property::__LVT || __prev == __property::__T) && __next == __property::__T) // GB8 + return false; + + // *** Do not break before extending characters or ZWJ. *** + if (__next == __property::__Extend || __next == __property::__ZWJ) + return false; // GB9 + + // *** Do not break before SpacingMarks, or after Prepend characters. *** + if (__next == __property::__SpacingMark) // GB9a + return false; + + if (__prev == __property::__Prepend) // GB9b + return false; + + // *** Do not break within emoji modifier sequences or emoji zwj sequences. *** + + // GB11 \p{Extended_Pictographic} Extend* ZWJ x \p{Extended_Pictographic} + // + // Note that several parts of this rule are matched by GB9: Any x (Extend | ZWJ) + // - \p{Extended_Pictographic} x Extend + // - Extend x Extend + // - \p{Extended_Pictographic} x ZWJ + // - Extend x ZWJ + // + // So the only case left to test is + // - \p{Extended_Pictographic}' x ZWJ x \p{Extended_Pictographic} + // where \p{Extended_Pictographic}' is stored in __has_extened_pictographic + if (__has_extened_pictographic && __prev == __property::__ZWJ && __next == __property::__Extended_Pictographic) + return false; + + // *** Do not break within emoji flag sequences *** + + // That is, do not break between regional indicator (RI) symbols if there + // is an odd number of RI characters before the break point. + + if (__prev == __property::__Regional_Indicator && __next == __property::__Regional_Indicator) { // GB12 + GB13 + __ri_break_allowed = !__ri_break_allowed; + return __ri_break_allowed; + } + + // *** Otherwise, break everywhere. *** + return true; // GB999 +} + +/// Helper class to extract an extended grapheme cluster from a Unicode character range. +/// +/// This function is used to determine the column width of an extended grapheme +/// cluster. In order to do that only the first code point is evaluated. +/// Therefore only this code point is extracted. +template +class __extended_grapheme_cluster_view { +public: + _LIBCPP_HIDE_FROM_ABI constexpr explicit __extended_grapheme_cluster_view(const _CharT* __first, const _CharT* __last) + : __code_point_view_(__first, __last), + __next_code_point_(__code_point_view_.__consume()), + __next_prop_(__extended_grapheme_custer_property_boundary::__get_property(__next_code_point_)) {} + + struct __cluster { + /// The first code point of the extended grapheme cluster. + /// + /// The first code point is used to estimate the width of the extended + /// grapheme cluster. + char32_t __code_point_; + + /// Points one beyond the last code unit in the extended grapheme cluster. + /// + /// It's expected the caller has the start position and thus can determine + /// the code unit range of the extended grapheme cluster. + const _CharT* __last_; + }; + + _LIBCPP_HIDE_FROM_ABI constexpr __cluster __consume() { + _LIBCPP_ASSERT( + __next_prop_ != __extended_grapheme_custer_property_boundary::__property::__eot, + "can't move beyond the end of input"); + char32_t __code_point = __next_code_point_; + if (!__code_point_view_.__at_end()) + return {__code_point, __get_break()}; + + __next_prop_ = __extended_grapheme_custer_property_boundary::__property::__eot; + return {__code_point, __code_point_view_.__position()}; + } + +private: + __code_point_view<_CharT> __code_point_view_; + + char32_t __next_code_point_; + __extended_grapheme_custer_property_boundary::__property __next_prop_; + + _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __get_break() { + bool __ri_break_allowed = true; + bool __has_extened_pictographic = false; + while (true) { + const _CharT* __result = __code_point_view_.__position(); + __extended_grapheme_custer_property_boundary::__property __prev = __next_prop_; + if (__code_point_view_.__at_end()) { + __next_prop_ = __extended_grapheme_custer_property_boundary::__property::__eot; + return __result; + } + __next_code_point_ = __code_point_view_.__consume(); + __next_prop_ = __extended_grapheme_custer_property_boundary::__get_property(__next_code_point_); + + __has_extened_pictographic |= + __prev == __extended_grapheme_custer_property_boundary::__property::__Extended_Pictographic; + + if (__at_extended_grapheme_cluster_break(__ri_break_allowed, __has_extened_pictographic, __prev, __next_prop_)) + return __result; + } + } +}; + +template +__extended_grapheme_cluster_view(const _CharT*, const _CharT*) -> __extended_grapheme_cluster_view<_CharT>; + +# else // _LIBCPP_HAS_NO_UNICODE + +// For ASCII every character is a "code point". +// This makes it easier to write code agnostic of the _LIBCPP_HAS_NO_UNICODE define. +template +class __code_point_view { +public: + _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(const _CharT* __first, const _CharT* __last) + : __first_(__first), __last_(__last) {} + + _LIBCPP_HIDE_FROM_ABI constexpr bool __at_end() const noexcept { return __first_ == __last_; } + _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __position() const noexcept { return __first_; } + + _LIBCPP_HIDE_FROM_ABI constexpr char32_t __consume() noexcept { + _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input"); + return *__first_++; + } + +# if _LIBCPP_STD_VER > 20 + _LIBCPP_HIDE_FROM_ABI constexpr __consume_p2286_result __consume_p2286() noexcept { + _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input"); + + return {0, std::make_unsigned_t<_CharT>(*__first_++)}; + } +# endif // _LIBCPP_STD_VER > 20 + +private: + const _CharT* __first_; + const _CharT* __last_; +}; + +# endif // _LIBCPP_HAS_NO_UNICODE + +} // namespace __unicode + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_UNICODE_H diff --git a/app/src/main/cpp/libcxx/include/__functional/binary_function.h b/app/src/main/cpp/libcxx/include/__functional/binary_function.h new file mode 100644 index 0000000..fdedb8b --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/binary_function.h @@ -0,0 +1,54 @@ +// -*- 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 _LIBCPP___FUNCTIONAL_BINARY_FUNCTION_H +#define _LIBCPP___FUNCTIONAL_BINARY_FUNCTION_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION) + +template +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binary_function +{ + typedef _Arg1 first_argument_type; + typedef _Arg2 second_argument_type; + typedef _Result result_type; +}; + +#endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION) + +template struct __binary_function_keep_layout_base { +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using first_argument_type _LIBCPP_DEPRECATED_IN_CXX17 = _Arg1; + using second_argument_type _LIBCPP_DEPRECATED_IN_CXX17 = _Arg2; + using result_type _LIBCPP_DEPRECATED_IN_CXX17 = _Result; +#endif +}; + +#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION) +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-declarations") +template +using __binary_function = binary_function<_Arg1, _Arg2, _Result>; +_LIBCPP_DIAGNOSTIC_POP +#else +template +using __binary_function = __binary_function_keep_layout_base<_Arg1, _Arg2, _Result>; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_BINARY_FUNCTION_H diff --git a/app/src/main/cpp/libcxx/include/__functional/binary_negate.h b/app/src/main/cpp/libcxx/include/__functional/binary_negate.h new file mode 100644 index 0000000..73ecea9 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/binary_negate.h @@ -0,0 +1,50 @@ +// -*- 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 _LIBCPP___FUNCTIONAL_BINARY_NEGATE_H +#define _LIBCPP___FUNCTIONAL_BINARY_NEGATE_H + +#include <__config> +#include <__functional/binary_function.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS) + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 binary_negate + : public __binary_function +{ + _Predicate __pred_; +public: + _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR_SINCE_CXX14 + binary_negate(const _Predicate& __pred) : __pred_(__pred) {} + + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + bool operator()(const typename _Predicate::first_argument_type& __x, + const typename _Predicate::second_argument_type& __y) const + {return !__pred_(__x, __y);} +}; + +template +_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY +binary_negate<_Predicate> +not2(const _Predicate& __pred) {return binary_negate<_Predicate>(__pred);} + +#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_BINARY_NEGATE_H diff --git a/app/src/main/cpp/libcxx/include/__functional/bind.h b/app/src/main/cpp/libcxx/include/__functional/bind.h new file mode 100644 index 0000000..297e4e5 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/bind.h @@ -0,0 +1,389 @@ +// -*- 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 _LIBCPP___FUNCTIONAL_BIND_H +#define _LIBCPP___FUNCTIONAL_BIND_H + +#include <__config> +#include <__functional/invoke.h> +#include <__functional/weak_result_type.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct is_bind_expression : _If< + _IsSame<_Tp, __remove_cvref_t<_Tp> >::value, + false_type, + is_bind_expression<__remove_cvref_t<_Tp> > +> {}; + +#if _LIBCPP_STD_VER > 14 +template +inline constexpr size_t is_bind_expression_v = is_bind_expression<_Tp>::value; +#endif + +template +struct is_placeholder : _If< + _IsSame<_Tp, __remove_cvref_t<_Tp> >::value, + integral_constant, + is_placeholder<__remove_cvref_t<_Tp> > +> {}; + +#if _LIBCPP_STD_VER > 14 +template +inline constexpr size_t is_placeholder_v = is_placeholder<_Tp>::value; +#endif + +namespace placeholders +{ + +template struct __ph {}; + +#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) +_LIBCPP_FUNC_VIS extern const __ph<1> _1; +_LIBCPP_FUNC_VIS extern const __ph<2> _2; +_LIBCPP_FUNC_VIS extern const __ph<3> _3; +_LIBCPP_FUNC_VIS extern const __ph<4> _4; +_LIBCPP_FUNC_VIS extern const __ph<5> _5; +_LIBCPP_FUNC_VIS extern const __ph<6> _6; +_LIBCPP_FUNC_VIS extern const __ph<7> _7; +_LIBCPP_FUNC_VIS extern const __ph<8> _8; +_LIBCPP_FUNC_VIS extern const __ph<9> _9; +_LIBCPP_FUNC_VIS extern const __ph<10> _10; +#else +/* inline */ constexpr __ph<1> _1{}; +/* inline */ constexpr __ph<2> _2{}; +/* inline */ constexpr __ph<3> _3{}; +/* inline */ constexpr __ph<4> _4{}; +/* inline */ constexpr __ph<5> _5{}; +/* inline */ constexpr __ph<6> _6{}; +/* inline */ constexpr __ph<7> _7{}; +/* inline */ constexpr __ph<8> _8{}; +/* inline */ constexpr __ph<9> _9{}; +/* inline */ constexpr __ph<10> _10{}; +#endif // defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) + +} // namespace placeholders + +template +struct is_placeholder > + : public integral_constant {}; + + +#ifndef _LIBCPP_CXX03_LANG + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp& +__mu(reference_wrapper<_Tp> __t, _Uj&) +{ + return __t.get(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __invoke_of<_Ti&, _Uj...>::type +__mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>) +{ + return __ti(_VSTD::forward<_Uj>(_VSTD::get<_Indx>(__uj))...); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_if_t +< + is_bind_expression<_Ti>::value, + __invoke_of<_Ti&, _Uj...> +>::type +__mu(_Ti& __ti, tuple<_Uj...>& __uj) +{ + typedef typename __make_tuple_indices::type __indices; + return _VSTD::__mu_expand(__ti, __uj, __indices()); +} + +template +struct __mu_return2 {}; + +template +struct __mu_return2 +{ + typedef typename tuple_element::value - 1, _Uj>::type type; +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + 0 < is_placeholder<_Ti>::value, + typename __mu_return2<0 < is_placeholder<_Ti>::value, _Ti, _Uj>::type +>::type +__mu(_Ti&, _Uj& __uj) +{ + const size_t _Indx = is_placeholder<_Ti>::value - 1; + return _VSTD::forward::type>(_VSTD::get<_Indx>(__uj)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + !is_bind_expression<_Ti>::value && + is_placeholder<_Ti>::value == 0 && + !__is_reference_wrapper<_Ti>::value, + _Ti& +>::type +__mu(_Ti& __ti, _Uj&) +{ + return __ti; +} + +template +struct __mu_return_impl; + +template +struct __mu_return_invokable // false +{ + typedef __nat type; +}; + +template +struct __mu_return_invokable +{ + typedef typename __invoke_of<_Ti&, _Uj...>::type type; +}; + +template +struct __mu_return_impl<_Ti, false, true, false, tuple<_Uj...> > + : public __mu_return_invokable<__invokable<_Ti&, _Uj...>::value, _Ti, _Uj...> +{ +}; + +template +struct __mu_return_impl<_Ti, false, false, true, _TupleUj> +{ + typedef typename tuple_element::value - 1, + _TupleUj>::type&& type; +}; + +template +struct __mu_return_impl<_Ti, true, false, false, _TupleUj> +{ + typedef typename _Ti::type& type; +}; + +template +struct __mu_return_impl<_Ti, false, false, false, _TupleUj> +{ + typedef _Ti& type; +}; + +template +struct __mu_return + : public __mu_return_impl<_Ti, + __is_reference_wrapper<_Ti>::value, + is_bind_expression<_Ti>::value, + 0 < is_placeholder<_Ti>::value && + is_placeholder<_Ti>::value <= tuple_size<_TupleUj>::value, + _TupleUj> +{ +}; + +template +struct __is_valid_bind_return +{ + static const bool value = false; +}; + +template +struct __is_valid_bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj> +{ + static const bool value = __invokable<_Fp, + typename __mu_return<_BoundArgs, _TupleUj>::type...>::value; +}; + +template +struct __is_valid_bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj> +{ + static const bool value = __invokable<_Fp, + typename __mu_return::type...>::value; +}; + +template ::value> +struct __bind_return; + +template +struct __bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj, true> +{ + typedef typename __invoke_of + < + _Fp&, + typename __mu_return + < + _BoundArgs, + _TupleUj + >::type... + >::type type; +}; + +template +struct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj, true> +{ + typedef typename __invoke_of + < + _Fp&, + typename __mu_return + < + const _BoundArgs, + _TupleUj + >::type... + >::type type; +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __bind_return<_Fp, _BoundArgs, _Args>::type +__apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>, + _Args&& __args) +{ + return _VSTD::__invoke(__f, _VSTD::__mu(_VSTD::get<_Indx>(__bound_args), __args)...); +} + +template +class __bind : public __weak_result_type::type> +{ +protected: + typedef typename decay<_Fp>::type _Fd; + typedef tuple::type...> _Td; +private: + _Fd __f_; + _Td __bound_args_; + + typedef typename __make_tuple_indices::type __indices; +public: + template ::value && + !is_same<__libcpp_remove_reference_t<_Gp>, + __bind>::value + >::type> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + explicit __bind(_Gp&& __f, _BA&& ...__bound_args) + : __f_(_VSTD::forward<_Gp>(__f)), + __bound_args_(_VSTD::forward<_BA>(__bound_args)...) {} + + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type + operator()(_Args&& ...__args) + { + return _VSTD::__apply_functor(__f_, __bound_args_, __indices(), + tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...)); + } + + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + typename __bind_return >::type + operator()(_Args&& ...__args) const + { + return _VSTD::__apply_functor(__f_, __bound_args_, __indices(), + tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...)); + } +}; + +template +struct is_bind_expression<__bind<_Fp, _BoundArgs...> > : public true_type {}; + +template +class __bind_r + : public __bind<_Fp, _BoundArgs...> +{ + typedef __bind<_Fp, _BoundArgs...> base; + typedef typename base::_Fd _Fd; + typedef typename base::_Td _Td; +public: + typedef _Rp result_type; + + + template ::value && + !is_same<__libcpp_remove_reference_t<_Gp>, + __bind_r>::value + >::type> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + explicit __bind_r(_Gp&& __f, _BA&& ...__bound_args) + : base(_VSTD::forward<_Gp>(__f), + _VSTD::forward<_BA>(__bound_args)...) {} + + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + typename enable_if + < + is_convertible >::type, + result_type>::value || is_void<_Rp>::value, + result_type + >::type + operator()(_Args&& ...__args) + { + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(static_cast(*this), _VSTD::forward<_Args>(__args)...); + } + + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + typename enable_if + < + is_convertible >::type, + result_type>::value || is_void<_Rp>::value, + result_type + >::type + operator()(_Args&& ...__args) const + { + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(static_cast(*this), _VSTD::forward<_Args>(__args)...); + } +}; + +template +struct is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {}; + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +__bind<_Fp, _BoundArgs...> +bind(_Fp&& __f, _BoundArgs&&... __bound_args) +{ + typedef __bind<_Fp, _BoundArgs...> type; + return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +__bind_r<_Rp, _Fp, _BoundArgs...> +bind(_Fp&& __f, _BoundArgs&&... __bound_args) +{ + typedef __bind_r<_Rp, _Fp, _BoundArgs...> type; + return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...); +} + +#endif // _LIBCPP_CXX03_LANG + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_BIND_H diff --git a/app/src/main/cpp/libcxx/include/__functional/bind_back.h b/app/src/main/cpp/libcxx/include/__functional/bind_back.h new file mode 100644 index 0000000..f0a6e49 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/bind_back.h @@ -0,0 +1,64 @@ +// -*- 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 _LIBCPP___FUNCTIONAL_BIND_BACK_H +#define _LIBCPP___FUNCTIONAL_BIND_BACK_H + +#include <__config> +#include <__functional/invoke.h> +#include <__functional/perfect_forward.h> +#include <__utility/forward.h> +#include <__utility/integer_sequence.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template > +struct __bind_back_op; + +template +struct __bind_back_op<_NBound, index_sequence<_Ip...>> { + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Fn&& __f, _BoundArgs&& __bound_args, _Args&&... __args) const + noexcept(noexcept(_VSTD::invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)..., _VSTD::get<_Ip>(_VSTD::forward<_BoundArgs>(__bound_args))...))) + -> decltype( _VSTD::invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)..., _VSTD::get<_Ip>(_VSTD::forward<_BoundArgs>(__bound_args))...)) + { return _VSTD::invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)..., _VSTD::get<_Ip>(_VSTD::forward<_BoundArgs>(__bound_args))...); } +}; + +template +struct __bind_back_t : __perfect_forward<__bind_back_op>, _Fn, _BoundArgs> { + using __perfect_forward<__bind_back_op>, _Fn, _BoundArgs>::__perfect_forward; +}; + +template , _Fn>, + is_move_constructible>, + is_constructible, _Args>..., + is_move_constructible>... + >::value +>> +_LIBCPP_HIDE_FROM_ABI +constexpr auto __bind_back(_Fn&& __f, _Args&&... __args) + noexcept(noexcept(__bind_back_t, tuple...>>(_VSTD::forward<_Fn>(__f), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)))) + -> decltype( __bind_back_t, tuple...>>(_VSTD::forward<_Fn>(__f), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...))) + { return __bind_back_t, tuple...>>(_VSTD::forward<_Fn>(__f), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); } + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_BIND_BACK_H diff --git a/app/src/main/cpp/libcxx/include/__functional/bind_front.h b/app/src/main/cpp/libcxx/include/__functional/bind_front.h new file mode 100644 index 0000000..22fb3a6 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/bind_front.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 _LIBCPP___FUNCTIONAL_BIND_FRONT_H +#define _LIBCPP___FUNCTIONAL_BIND_FRONT_H + +#include <__config> +#include <__functional/invoke.h> +#include <__functional/perfect_forward.h> +#include <__utility/forward.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +struct __bind_front_op { + template + _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Args&& ...__args) const + noexcept(noexcept(_VSTD::invoke(_VSTD::forward<_Args>(__args)...))) + -> decltype( _VSTD::invoke(_VSTD::forward<_Args>(__args)...)) + { return _VSTD::invoke(_VSTD::forward<_Args>(__args)...); } +}; + +template +struct __bind_front_t : __perfect_forward<__bind_front_op, _Fn, _BoundArgs...> { + using __perfect_forward<__bind_front_op, _Fn, _BoundArgs...>::__perfect_forward; +}; + +template , _Fn>, + is_move_constructible>, + is_constructible, _Args>..., + is_move_constructible>... + >::value +>> +_LIBCPP_HIDE_FROM_ABI +constexpr auto bind_front(_Fn&& __f, _Args&&... __args) { + return __bind_front_t, decay_t<_Args>...>(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...); +} + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_BIND_FRONT_H diff --git a/app/src/main/cpp/libcxx/include/__functional/binder1st.h b/app/src/main/cpp/libcxx/include/__functional/binder1st.h new file mode 100644 index 0000000..dea22c7 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/binder1st.h @@ -0,0 +1,53 @@ +// -*- 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 _LIBCPP___FUNCTIONAL_BINDER1ST_H +#define _LIBCPP___FUNCTIONAL_BINDER1ST_H + +#include <__config> +#include <__functional/unary_function.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder1st + : public __unary_function +{ +protected: + __Operation op; + typename __Operation::first_argument_type value; +public: + _LIBCPP_INLINE_VISIBILITY binder1st(const __Operation& __x, + const typename __Operation::first_argument_type __y) + : op(__x), value(__y) {} + _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator() + (typename __Operation::second_argument_type& __x) const + {return op(value, __x);} + _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator() + (const typename __Operation::second_argument_type& __x) const + {return op(value, __x);} +}; + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY +binder1st<__Operation> +bind1st(const __Operation& __op, const _Tp& __x) + {return binder1st<__Operation>(__op, __x);} + +#endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_BINDER1ST_H diff --git a/app/src/main/cpp/libcxx/include/__functional/binder2nd.h b/app/src/main/cpp/libcxx/include/__functional/binder2nd.h new file mode 100644 index 0000000..c98a146 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/binder2nd.h @@ -0,0 +1,53 @@ +// -*- 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 _LIBCPP___FUNCTIONAL_BINDER2ND_H +#define _LIBCPP___FUNCTIONAL_BINDER2ND_H + +#include <__config> +#include <__functional/unary_function.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder2nd + : public __unary_function +{ +protected: + __Operation op; + typename __Operation::second_argument_type value; +public: + _LIBCPP_INLINE_VISIBILITY + binder2nd(const __Operation& __x, const typename __Operation::second_argument_type __y) + : op(__x), value(__y) {} + _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator() + ( typename __Operation::first_argument_type& __x) const + {return op(__x, value);} + _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator() + (const typename __Operation::first_argument_type& __x) const + {return op(__x, value);} +}; + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY +binder2nd<__Operation> +bind2nd(const __Operation& __op, const _Tp& __x) + {return binder2nd<__Operation>(__op, __x);} + +#endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_BINDER2ND_H diff --git a/app/src/main/cpp/libcxx/include/__functional/boyer_moore_searcher.h b/app/src/main/cpp/libcxx/include/__functional/boyer_moore_searcher.h new file mode 100644 index 0000000..a675089 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/boyer_moore_searcher.h @@ -0,0 +1,315 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___FUNCTIONAL_BOYER_MOORE_SEARCHER_H +#define _LIBCPP___FUNCTIONAL_BOYER_MOORE_SEARCHER_H + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#include <__algorithm/fill_n.h> +#include <__config> +#include <__functional/hash.h> +#include <__functional/operations.h> +#include <__iterator/distance.h> +#include <__iterator/iterator_traits.h> +#include <__memory/shared_ptr.h> +#include <__utility/pair.h> +#include +#include +#include + +#if _LIBCPP_STD_VER > 14 + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _BMSkipTable; + +// General case for BM data searching; use a map +template +class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, false> { +private: + using value_type = _Value; + using key_type = _Key; + + const value_type __default_value_; + unordered_map<_Key, _Value, _Hash, _BinaryPredicate> __table_; + +public: + _LIBCPP_HIDE_FROM_ABI + explicit _BMSkipTable(size_t __sz, value_type __default_value, _Hash __hash, _BinaryPredicate __pred) + : __default_value_(__default_value), + __table_(__sz, __hash, __pred) {} + + _LIBCPP_HIDE_FROM_ABI void insert(const key_type& __key, value_type __val) { + __table_[__key] = __val; + } + + _LIBCPP_HIDE_FROM_ABI value_type operator[](const key_type& __key) const { + auto __it = __table_.find(__key); + return __it == __table_.end() ? __default_value_ : __it->second; + } +}; + +// Special case small numeric values; use an array +template +class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, true> { +private: + using value_type = _Value; + using key_type = _Key; + + using unsigned_key_type = make_unsigned_t; + std::array __table_; + static_assert(numeric_limits::max() < 256); + +public: + _LIBCPP_HIDE_FROM_ABI explicit _BMSkipTable(size_t, value_type __default_value, _Hash, _BinaryPredicate) { + std::fill_n(__table_.data(), __table_.size(), __default_value); + } + + _LIBCPP_HIDE_FROM_ABI void insert(key_type __key, value_type __val) { + __table_[static_cast(__key)] = __val; + } + + _LIBCPP_HIDE_FROM_ABI value_type operator[](key_type __key) const { + return __table_[static_cast(__key)]; + } +}; + +template ::value_type>, + class _BinaryPredicate = equal_to<>> +class _LIBCPP_TEMPLATE_VIS boyer_moore_searcher { +private: + using difference_type = typename std::iterator_traits<_RandomAccessIterator1>::difference_type; + using value_type = typename std::iterator_traits<_RandomAccessIterator1>::value_type; + using __skip_table_type = _BMSkipTable + && sizeof(value_type) == 1 + && is_same_v<_Hash, hash> + && is_same_v<_BinaryPredicate, equal_to<>>>; + +public: + boyer_moore_searcher(_RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _Hash __hash = _Hash(), + _BinaryPredicate __pred = _BinaryPredicate()) + : __first_(__first), + __last_(__last), + __pred_(__pred), + __pattern_length_(__last - __first), + __skip_table_(std::make_shared<__skip_table_type>(__pattern_length_, -1, __hash, __pred_)), + __suffix_(std::__allocate_shared_unbounded_array( + allocator(), __pattern_length_ + 1)) { + difference_type __i = 0; + while (__first != __last) { + __skip_table_->insert(*__first, __i); + ++__first; + ++__i; + } + __build_suffix_table(__first_, __last_, __pred_); + } + + template + pair<_RandomAccessIterator2, _RandomAccessIterator2> + operator()(_RandomAccessIterator2 __first, _RandomAccessIterator2 __last) const { + static_assert(__is_same_uncvref::value_type, + typename iterator_traits<_RandomAccessIterator2>::value_type>::value, + "Corpus and Pattern iterators must point to the same type"); + if (__first == __last) + return std::make_pair(__last, __last); + if (__first_ == __last_) + return std::make_pair(__first, __first); + + if (__pattern_length_ > (__last - __first)) + return std::make_pair(__last, __last); + return __search(__first, __last); + } + +private: + _RandomAccessIterator1 __first_; + _RandomAccessIterator1 __last_; + _BinaryPredicate __pred_; + difference_type __pattern_length_; + shared_ptr<__skip_table_type> __skip_table_; + shared_ptr __suffix_; + + template + pair<_RandomAccessIterator2, _RandomAccessIterator2> + __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const { + _RandomAccessIterator2 __current = __f; + const _RandomAccessIterator2 __last = __l - __pattern_length_; + const __skip_table_type& __skip_table = *__skip_table_; + + while (__current <= __last) { + difference_type __j = __pattern_length_; + while (__pred_(__first_[__j - 1], __current[__j - 1])) { + --__j; + if (__j == 0) + return std::make_pair(__current, __current + __pattern_length_); + } + + difference_type __k = __skip_table[__current[__j - 1]]; + difference_type __m = __j - __k - 1; + if (__k < __j && __m > __suffix_[__j]) + __current += __m; + else + __current += __suffix_[__j]; + } + return std::make_pair(__l, __l); + } + + template + void __compute_bm_prefix(_Iterator __first, _Iterator __last, _BinaryPredicate __pred, _Container& __prefix) { + const size_t __count = __last - __first; + + __prefix[0] = 0; + size_t __k = 0; + + for (size_t __i = 1; __i != __count; ++__i) { + while (__k > 0 && !__pred(__first[__k], __first[__i])) + __k = __prefix[__k - 1]; + + if (__pred(__first[__k], __first[__i])) + ++__k; + __prefix[__i] = __k; + } + } + + void __build_suffix_table(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _BinaryPredicate __pred) { + const size_t __count = __last - __first; + + if (__count == 0) + return; + + vector __scratch(__count); + + __compute_bm_prefix(__first, __last, __pred, __scratch); + for (size_t __i = 0; __i <= __count; ++__i) + __suffix_[__i] = __count - __scratch[__count - 1]; + + using _ReverseIter = reverse_iterator<_RandomAccessIterator1>; + __compute_bm_prefix(_ReverseIter(__last), _ReverseIter(__first), __pred, __scratch); + + for (size_t __i = 0; __i != __count; ++__i) { + const size_t __j = __count - __scratch[__i]; + const difference_type __k = __i - __scratch[__i] + 1; + + if (__suffix_[__j] > __k) + __suffix_[__j] = __k; + } + } +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(boyer_moore_searcher); + +template ::value_type>, + class _BinaryPredicate = equal_to<>> +class _LIBCPP_TEMPLATE_VIS boyer_moore_horspool_searcher { +private: + using difference_type = typename iterator_traits<_RandomAccessIterator1>::difference_type; + using value_type = typename iterator_traits<_RandomAccessIterator1>::value_type; + using __skip_table_type = _BMSkipTable + && sizeof(value_type) == 1 + && is_same_v<_Hash, hash> + && is_same_v<_BinaryPredicate, equal_to<>>>; +public: + boyer_moore_horspool_searcher(_RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _Hash __hash = _Hash(), + _BinaryPredicate __pred = _BinaryPredicate()) + : __first_(__first), + __last_(__last), + __pred_(__pred), + __pattern_length_(__last - __first), + __skip_table_(std::make_shared<__skip_table_type>(__pattern_length_, __pattern_length_, __hash, __pred_)) { + if (__first == __last) + return; + --__last; + difference_type __i = 0; + while (__first != __last) { + __skip_table_->insert(*__first, __pattern_length_ - 1 - __i); + ++__first; + ++__i; + } + } + + template + pair<_RandomAccessIterator2, _RandomAccessIterator2> + operator()(_RandomAccessIterator2 __first, _RandomAccessIterator2 __last) const { + static_assert(__is_same_uncvref::value_type, + typename std::iterator_traits<_RandomAccessIterator2>::value_type>::value, + "Corpus and Pattern iterators must point to the same type"); + if (__first == __last) + return std::make_pair(__last, __last); + if (__first_ == __last_) + return std::make_pair(__first, __first); + + if (__pattern_length_ > __last - __first) + return std::make_pair(__last, __last); + + return __search(__first, __last); + } + +private: + _RandomAccessIterator1 __first_; + _RandomAccessIterator1 __last_; + _BinaryPredicate __pred_; + difference_type __pattern_length_; + shared_ptr<__skip_table_type> __skip_table_; + + template + pair<_RandomAccessIterator2, _RandomAccessIterator2> + __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const { + _RandomAccessIterator2 __current = __f; + const _RandomAccessIterator2 __last = __l - __pattern_length_; + const __skip_table_type& __skip_table = *__skip_table_; + + while (__current <= __last) { + difference_type __j = __pattern_length_; + while (__pred_(__first_[__j - 1], __current[__j - 1])) { + --__j; + if (__j == 0) + return std::make_pair(__current, __current + __pattern_length_); + } + __current += __skip_table[__current[__pattern_length_ - 1]]; + } + return std::make_pair(__l, __l); + } +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(boyer_moore_horspool_searcher); + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP_STD_VER > 14 + +#endif // _LIBCPP___FUNCTIONAL_BOYER_MOORE_SEARCHER_H diff --git a/app/src/main/cpp/libcxx/include/__functional/compose.h b/app/src/main/cpp/libcxx/include/__functional/compose.h new file mode 100644 index 0000000..25213f2 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/compose.h @@ -0,0 +1,52 @@ +// -*- 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 _LIBCPP___FUNCTIONAL_COMPOSE_H +#define _LIBCPP___FUNCTIONAL_COMPOSE_H + +#include <__config> +#include <__functional/invoke.h> +#include <__functional/perfect_forward.h> +#include <__utility/forward.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +struct __compose_op { + template + _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Fn1&& __f1, _Fn2&& __f2, _Args&&... __args) const + noexcept(noexcept(_VSTD::invoke(_VSTD::forward<_Fn1>(__f1), _VSTD::invoke(_VSTD::forward<_Fn2>(__f2), _VSTD::forward<_Args>(__args)...)))) + -> decltype( _VSTD::invoke(_VSTD::forward<_Fn1>(__f1), _VSTD::invoke(_VSTD::forward<_Fn2>(__f2), _VSTD::forward<_Args>(__args)...))) + { return _VSTD::invoke(_VSTD::forward<_Fn1>(__f1), _VSTD::invoke(_VSTD::forward<_Fn2>(__f2), _VSTD::forward<_Args>(__args)...)); } +}; + +template +struct __compose_t : __perfect_forward<__compose_op, _Fn1, _Fn2> { + using __perfect_forward<__compose_op, _Fn1, _Fn2>::__perfect_forward; +}; + +template +_LIBCPP_HIDE_FROM_ABI +constexpr auto __compose(_Fn1&& __f1, _Fn2&& __f2) + noexcept(noexcept(__compose_t, decay_t<_Fn2>>(_VSTD::forward<_Fn1>(__f1), _VSTD::forward<_Fn2>(__f2)))) + -> decltype( __compose_t, decay_t<_Fn2>>(_VSTD::forward<_Fn1>(__f1), _VSTD::forward<_Fn2>(__f2))) + { return __compose_t, decay_t<_Fn2>>(_VSTD::forward<_Fn1>(__f1), _VSTD::forward<_Fn2>(__f2)); } + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_COMPOSE_H diff --git a/app/src/main/cpp/libcxx/include/__functional/default_searcher.h b/app/src/main/cpp/libcxx/include/__functional/default_searcher.h new file mode 100644 index 0000000..e4151e5 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/default_searcher.h @@ -0,0 +1,57 @@ +// -*- 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 _LIBCPP___FUNCTIONAL_DEFAULT_SEARCHER_H +#define _LIBCPP___FUNCTIONAL_DEFAULT_SEARCHER_H + +#include <__algorithm/search.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/operations.h> +#include <__iterator/iterator_traits.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +// default searcher +template> +class _LIBCPP_TEMPLATE_VIS default_searcher { +public: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + default_searcher(_ForwardIterator __f, _ForwardIterator __l, + _BinaryPredicate __p = _BinaryPredicate()) + : __first_(__f), __last_(__l), __pred_(__p) {} + + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + pair<_ForwardIterator2, _ForwardIterator2> + operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const + { + auto __proj = __identity(); + return std::__search_impl(__f, __l, __first_, __last_, __pred_, __proj, __proj); + } + +private: + _ForwardIterator __first_; + _ForwardIterator __last_; + _BinaryPredicate __pred_; +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(default_searcher); + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_DEFAULT_SEARCHER_H diff --git a/app/src/main/cpp/libcxx/include/__functional/function.h b/app/src/main/cpp/libcxx/include/__functional/function.h new file mode 100644 index 0000000..ca79d33 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/function.h @@ -0,0 +1,1216 @@ +// -*- 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 _LIBCPP___FUNCTIONAL_FUNCTION_H +#define _LIBCPP___FUNCTIONAL_FUNCTION_H + +#include <__assert> +#include <__config> +#include <__functional/binary_function.h> +#include <__functional/invoke.h> +#include <__functional/unary_function.h> +#include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> +#include <__memory/allocator.h> +#include <__memory/allocator_destructor.h> +#include <__memory/allocator_traits.h> +#include <__memory/builtin_new_allocator.h> +#include <__memory/compressed_pair.h> +#include <__memory/unique_ptr.h> +#include <__type_traits/strip_signature.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/piecewise_construct.h> +#include <__utility/swap.h> +#include +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_STD + +// bad_function_call + +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables") +class _LIBCPP_EXCEPTION_ABI bad_function_call + : public exception +{ +public: +// Note that when a key function is not used, every translation unit that uses +// bad_function_call will end up containing a weak definition of the vtable and +// typeinfo. +#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION + ~bad_function_call() _NOEXCEPT override; +#else + ~bad_function_call() _NOEXCEPT override {} +#endif + +#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE + const char* what() const _NOEXCEPT override; +#endif +}; +_LIBCPP_DIAGNOSTIC_POP + +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY +void __throw_bad_function_call() +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_function_call(); +#else + _VSTD::abort(); +#endif +} + +template class _LIBCPP_TEMPLATE_VIS function; // undefined + +namespace __function +{ + +template +struct __maybe_derive_from_unary_function +{ +}; + +template +struct __maybe_derive_from_unary_function<_Rp(_A1)> + : public __unary_function<_A1, _Rp> +{ +}; + +template +struct __maybe_derive_from_binary_function +{ +}; + +template +struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)> + : public __binary_function<_A1, _A2, _Rp> +{ +}; + +template +_LIBCPP_INLINE_VISIBILITY +bool __not_null(_Fp const&) { return true; } + +template +_LIBCPP_INLINE_VISIBILITY +bool __not_null(_Fp* __ptr) { return __ptr; } + +template +_LIBCPP_INLINE_VISIBILITY +bool __not_null(_Ret _Class::*__ptr) { return __ptr; } + +template +_LIBCPP_INLINE_VISIBILITY +bool __not_null(function<_Fp> const& __f) { return !!__f; } + +#ifdef _LIBCPP_HAS_EXTENSION_BLOCKS +template +_LIBCPP_INLINE_VISIBILITY +bool __not_null(_Rp (^__p)(_Args...)) { return __p; } +#endif + +} // namespace __function + +namespace __function { + +// __alloc_func holds a functor and an allocator. + +template class __alloc_func; +template +class __default_alloc_func; + +template +class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)> +{ + __compressed_pair<_Fp, _Ap> __f_; + + public: + typedef _LIBCPP_NODEBUG _Fp _Target; + typedef _LIBCPP_NODEBUG _Ap _Alloc; + + _LIBCPP_INLINE_VISIBILITY + const _Target& __target() const { return __f_.first(); } + + // WIN32 APIs may define __allocator, so use __get_allocator instead. + _LIBCPP_INLINE_VISIBILITY + const _Alloc& __get_allocator() const { return __f_.second(); } + + _LIBCPP_INLINE_VISIBILITY + explicit __alloc_func(_Target&& __f) + : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)), + _VSTD::forward_as_tuple()) + { + } + + _LIBCPP_INLINE_VISIBILITY + explicit __alloc_func(const _Target& __f, const _Alloc& __a) + : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f), + _VSTD::forward_as_tuple(__a)) + { + } + + _LIBCPP_INLINE_VISIBILITY + explicit __alloc_func(const _Target& __f, _Alloc&& __a) + : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f), + _VSTD::forward_as_tuple(_VSTD::move(__a))) + { + } + + _LIBCPP_INLINE_VISIBILITY + explicit __alloc_func(_Target&& __f, _Alloc&& __a) + : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)), + _VSTD::forward_as_tuple(_VSTD::move(__a))) + { + } + + _LIBCPP_INLINE_VISIBILITY + _Rp operator()(_ArgTypes&&... __arg) + { + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(__f_.first(), + _VSTD::forward<_ArgTypes>(__arg)...); + } + + _LIBCPP_INLINE_VISIBILITY + __alloc_func* __clone() const + { + typedef allocator_traits<_Alloc> __alloc_traits; + typedef __rebind_alloc<__alloc_traits, __alloc_func> _AA; + _AA __a(__f_.second()); + typedef __allocator_destructor<_AA> _Dp; + unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a)); + return __hold.release(); + } + + _LIBCPP_INLINE_VISIBILITY + void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); } + + static void __destroy_and_delete(__alloc_func* __f) { + typedef allocator_traits<_Alloc> __alloc_traits; + typedef __rebind_alloc<__alloc_traits, __alloc_func> _FunAlloc; + _FunAlloc __a(__f->__get_allocator()); + __f->destroy(); + __a.deallocate(__f, 1); + } +}; + +template +class __default_alloc_func<_Fp, _Rp(_ArgTypes...)> { + _Fp __f_; + +public: + typedef _LIBCPP_NODEBUG _Fp _Target; + + _LIBCPP_INLINE_VISIBILITY + const _Target& __target() const { return __f_; } + + _LIBCPP_INLINE_VISIBILITY + explicit __default_alloc_func(_Target&& __f) : __f_(_VSTD::move(__f)) {} + + _LIBCPP_INLINE_VISIBILITY + explicit __default_alloc_func(const _Target& __f) : __f_(__f) {} + + _LIBCPP_INLINE_VISIBILITY + _Rp operator()(_ArgTypes&&... __arg) { + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(__f_, _VSTD::forward<_ArgTypes>(__arg)...); + } + + _LIBCPP_INLINE_VISIBILITY + __default_alloc_func* __clone() const { + __builtin_new_allocator::__holder_t __hold = + __builtin_new_allocator::__allocate_type<__default_alloc_func>(1); + __default_alloc_func* __res = + ::new ((void*)__hold.get()) __default_alloc_func(__f_); + (void)__hold.release(); + return __res; + } + + _LIBCPP_INLINE_VISIBILITY + void destroy() _NOEXCEPT { __f_.~_Target(); } + + static void __destroy_and_delete(__default_alloc_func* __f) { + __f->destroy(); + __builtin_new_allocator::__deallocate_type<__default_alloc_func>(__f, 1); + } +}; + +// __base provides an abstract interface for copyable functors. + +template class _LIBCPP_TEMPLATE_VIS __base; + +template +class __base<_Rp(_ArgTypes...)> +{ + __base(const __base&); + __base& operator=(const __base&); +public: + _LIBCPP_INLINE_VISIBILITY __base() {} + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~__base() {} + virtual __base* __clone() const = 0; + virtual void __clone(__base*) const = 0; + virtual void destroy() _NOEXCEPT = 0; + virtual void destroy_deallocate() _NOEXCEPT = 0; + virtual _Rp operator()(_ArgTypes&& ...) = 0; +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(const type_info&) const _NOEXCEPT = 0; + virtual const std::type_info& target_type() const _NOEXCEPT = 0; +#endif // _LIBCPP_NO_RTTI +}; + +// __func implements __base for a given functor type. + +template class __func; + +template +class __func<_Fp, _Alloc, _Rp(_ArgTypes...)> + : public __base<_Rp(_ArgTypes...)> +{ + __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_; +public: + _LIBCPP_INLINE_VISIBILITY + explicit __func(_Fp&& __f) + : __f_(_VSTD::move(__f)) {} + + _LIBCPP_INLINE_VISIBILITY + explicit __func(const _Fp& __f, const _Alloc& __a) + : __f_(__f, __a) {} + + _LIBCPP_INLINE_VISIBILITY + explicit __func(const _Fp& __f, _Alloc&& __a) + : __f_(__f, _VSTD::move(__a)) {} + + _LIBCPP_INLINE_VISIBILITY + explicit __func(_Fp&& __f, _Alloc&& __a) + : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} + + virtual __base<_Rp(_ArgTypes...)>* __clone() const; + virtual void __clone(__base<_Rp(_ArgTypes...)>*) const; + virtual void destroy() _NOEXCEPT; + virtual void destroy_deallocate() _NOEXCEPT; + virtual _Rp operator()(_ArgTypes&&... __arg); +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(const type_info&) const _NOEXCEPT; + virtual const std::type_info& target_type() const _NOEXCEPT; +#endif // _LIBCPP_NO_RTTI +}; + +template +__base<_Rp(_ArgTypes...)>* +__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const +{ + typedef allocator_traits<_Alloc> __alloc_traits; + typedef __rebind_alloc<__alloc_traits, __func> _Ap; + _Ap __a(__f_.__get_allocator()); + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a)); + return __hold.release(); +} + +template +void +__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const +{ + ::new ((void*)__p) __func(__f_.__target(), __f_.__get_allocator()); +} + +template +void +__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT +{ + __f_.destroy(); +} + +template +void +__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT +{ + typedef allocator_traits<_Alloc> __alloc_traits; + typedef __rebind_alloc<__alloc_traits, __func> _Ap; + _Ap __a(__f_.__get_allocator()); + __f_.destroy(); + __a.deallocate(this, 1); +} + +template +_Rp +__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg) +{ + return __f_(_VSTD::forward<_ArgTypes>(__arg)...); +} + +#ifndef _LIBCPP_NO_RTTI + +template +const void* +__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT +{ + if (__ti == typeid(_Fp)) + return _VSTD::addressof(__f_.__target()); + return nullptr; +} + +template +const std::type_info& +__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT +{ + return typeid(_Fp); +} + +#endif // _LIBCPP_NO_RTTI + +// __value_func creates a value-type from a __func. + +template class __value_func; + +template class __value_func<_Rp(_ArgTypes...)> +{ + _LIBCPP_SUPPRESS_DEPRECATED_PUSH + typename aligned_storage<3 * sizeof(void*)>::type __buf_; + _LIBCPP_SUPPRESS_DEPRECATED_POP + + typedef __base<_Rp(_ArgTypes...)> __func; + __func* __f_; + + _LIBCPP_NO_CFI static __func* __as_base(void* __p) + { + return reinterpret_cast<__func*>(__p); + } + + public: + _LIBCPP_INLINE_VISIBILITY + __value_func() _NOEXCEPT : __f_(nullptr) {} + + template + _LIBCPP_INLINE_VISIBILITY __value_func(_Fp&& __f, const _Alloc& __a) + : __f_(nullptr) + { + typedef allocator_traits<_Alloc> __alloc_traits; + typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; + typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc; + + if (__function::__not_null(__f)) + { + _FunAlloc __af(__a); + if (sizeof(_Fun) <= sizeof(__buf_) && + is_nothrow_copy_constructible<_Fp>::value && + is_nothrow_copy_constructible<_FunAlloc>::value) + { + __f_ = + ::new ((void*)&__buf_) _Fun(_VSTD::move(__f), _Alloc(__af)); + } + else + { + typedef __allocator_destructor<_FunAlloc> _Dp; + unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); + ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f), _Alloc(__a)); + __f_ = __hold.release(); + } + } + } + + template ::type, __value_func>::value>::type> + _LIBCPP_INLINE_VISIBILITY explicit __value_func(_Fp&& __f) + : __value_func(_VSTD::forward<_Fp>(__f), allocator<_Fp>()) {} + + _LIBCPP_INLINE_VISIBILITY + __value_func(const __value_func& __f) + { + if (__f.__f_ == nullptr) + __f_ = nullptr; + else if ((void*)__f.__f_ == &__f.__buf_) + { + __f_ = __as_base(&__buf_); + __f.__f_->__clone(__f_); + } + else + __f_ = __f.__f_->__clone(); + } + + _LIBCPP_INLINE_VISIBILITY + __value_func(__value_func&& __f) _NOEXCEPT + { + if (__f.__f_ == nullptr) + __f_ = nullptr; + else if ((void*)__f.__f_ == &__f.__buf_) + { + __f_ = __as_base(&__buf_); + __f.__f_->__clone(__f_); + } + else + { + __f_ = __f.__f_; + __f.__f_ = nullptr; + } + } + + _LIBCPP_INLINE_VISIBILITY + ~__value_func() + { + if ((void*)__f_ == &__buf_) + __f_->destroy(); + else if (__f_) + __f_->destroy_deallocate(); + } + + _LIBCPP_INLINE_VISIBILITY + __value_func& operator=(__value_func&& __f) + { + *this = nullptr; + if (__f.__f_ == nullptr) + __f_ = nullptr; + else if ((void*)__f.__f_ == &__f.__buf_) + { + __f_ = __as_base(&__buf_); + __f.__f_->__clone(__f_); + } + else + { + __f_ = __f.__f_; + __f.__f_ = nullptr; + } + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __value_func& operator=(nullptr_t) + { + __func* __f = __f_; + __f_ = nullptr; + if ((void*)__f == &__buf_) + __f->destroy(); + else if (__f) + __f->destroy_deallocate(); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + _Rp operator()(_ArgTypes&&... __args) const + { + if (__f_ == nullptr) + __throw_bad_function_call(); + return (*__f_)(_VSTD::forward<_ArgTypes>(__args)...); + } + + _LIBCPP_INLINE_VISIBILITY + void swap(__value_func& __f) _NOEXCEPT + { + if (&__f == this) + return; + if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_) + { + _LIBCPP_SUPPRESS_DEPRECATED_PUSH + typename aligned_storage::type __tempbuf; + _LIBCPP_SUPPRESS_DEPRECATED_POP + __func* __t = __as_base(&__tempbuf); + __f_->__clone(__t); + __f_->destroy(); + __f_ = nullptr; + __f.__f_->__clone(__as_base(&__buf_)); + __f.__f_->destroy(); + __f.__f_ = nullptr; + __f_ = __as_base(&__buf_); + __t->__clone(__as_base(&__f.__buf_)); + __t->destroy(); + __f.__f_ = __as_base(&__f.__buf_); + } + else if ((void*)__f_ == &__buf_) + { + __f_->__clone(__as_base(&__f.__buf_)); + __f_->destroy(); + __f_ = __f.__f_; + __f.__f_ = __as_base(&__f.__buf_); + } + else if ((void*)__f.__f_ == &__f.__buf_) + { + __f.__f_->__clone(__as_base(&__buf_)); + __f.__f_->destroy(); + __f.__f_ = __f_; + __f_ = __as_base(&__buf_); + } + else + _VSTD::swap(__f_, __f.__f_); + } + + _LIBCPP_INLINE_VISIBILITY + explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; } + +#ifndef _LIBCPP_NO_RTTI + _LIBCPP_INLINE_VISIBILITY + const std::type_info& target_type() const _NOEXCEPT + { + if (__f_ == nullptr) + return typeid(void); + return __f_->target_type(); + } + + template + _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT + { + if (__f_ == nullptr) + return nullptr; + return (const _Tp*)__f_->target(typeid(_Tp)); + } +#endif // _LIBCPP_NO_RTTI +}; + +// Storage for a functor object, to be used with __policy to manage copy and +// destruction. +union __policy_storage +{ + mutable char __small[sizeof(void*) * 2]; + void* __large; +}; + +// True if _Fun can safely be held in __policy_storage.__small. +template +struct __use_small_storage + : public integral_constant< + bool, sizeof(_Fun) <= sizeof(__policy_storage) && + _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) && + is_trivially_copy_constructible<_Fun>::value && + is_trivially_destructible<_Fun>::value> {}; + +// Policy contains information about how to copy, destroy, and move the +// underlying functor. You can think of it as a vtable of sorts. +struct __policy +{ + // Used to copy or destroy __large values. null for trivial objects. + void* (*const __clone)(const void*); + void (*const __destroy)(void*); + + // True if this is the null policy (no value). + const bool __is_null; + + // The target type. May be null if RTTI is disabled. + const std::type_info* const __type_info; + + // Returns a pointer to a static policy object suitable for the functor + // type. + template + _LIBCPP_INLINE_VISIBILITY static const __policy* __create() + { + return __choose_policy<_Fun>(__use_small_storage<_Fun>()); + } + + _LIBCPP_INLINE_VISIBILITY + static const __policy* __create_empty() + { + static const _LIBCPP_CONSTEXPR __policy __policy_ = {nullptr, nullptr, + true, +#ifndef _LIBCPP_NO_RTTI + &typeid(void) +#else + nullptr +#endif + }; + return &__policy_; + } + + private: + template static void* __large_clone(const void* __s) + { + const _Fun* __f = static_cast(__s); + return __f->__clone(); + } + + template + static void __large_destroy(void* __s) { + _Fun::__destroy_and_delete(static_cast<_Fun*>(__s)); + } + + template + _LIBCPP_INLINE_VISIBILITY static const __policy* + __choose_policy(/* is_small = */ false_type) { + static const _LIBCPP_CONSTEXPR __policy __policy_ = { + &__large_clone<_Fun>, &__large_destroy<_Fun>, false, +#ifndef _LIBCPP_NO_RTTI + &typeid(typename _Fun::_Target) +#else + nullptr +#endif + }; + return &__policy_; + } + + template + _LIBCPP_INLINE_VISIBILITY static const __policy* + __choose_policy(/* is_small = */ true_type) + { + static const _LIBCPP_CONSTEXPR __policy __policy_ = { + nullptr, nullptr, false, +#ifndef _LIBCPP_NO_RTTI + &typeid(typename _Fun::_Target) +#else + nullptr +#endif + }; + return &__policy_; + } +}; + +// Used to choose between perfect forwarding or pass-by-value. Pass-by-value is +// faster for types that can be passed in registers. +template +using __fast_forward = __conditional_t::value, _Tp, _Tp&&>; + +// __policy_invoker calls an instance of __alloc_func held in __policy_storage. + +template struct __policy_invoker; + +template +struct __policy_invoker<_Rp(_ArgTypes...)> +{ + typedef _Rp (*__Call)(const __policy_storage*, + __fast_forward<_ArgTypes>...); + + __Call __call_; + + // Creates an invoker that throws bad_function_call. + _LIBCPP_INLINE_VISIBILITY + __policy_invoker() : __call_(&__call_empty) {} + + // Creates an invoker that calls the given instance of __func. + template + _LIBCPP_INLINE_VISIBILITY static __policy_invoker __create() + { + return __policy_invoker(&__call_impl<_Fun>); + } + + private: + _LIBCPP_INLINE_VISIBILITY + explicit __policy_invoker(__Call __c) : __call_(__c) {} + + static _Rp __call_empty(const __policy_storage*, + __fast_forward<_ArgTypes>...) + { + __throw_bad_function_call(); + } + + template + static _Rp __call_impl(const __policy_storage* __buf, + __fast_forward<_ArgTypes>... __args) + { + _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value + ? &__buf->__small + : __buf->__large); + return (*__f)(_VSTD::forward<_ArgTypes>(__args)...); + } +}; + +// __policy_func uses a __policy and __policy_invoker to create a type-erased, +// copyable functor. + +template class __policy_func; + +template class __policy_func<_Rp(_ArgTypes...)> +{ + // Inline storage for small objects. + __policy_storage __buf_; + + // Calls the value stored in __buf_. This could technically be part of + // policy, but storing it here eliminates a level of indirection inside + // operator(). + typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker; + __invoker __invoker_; + + // The policy that describes how to move / copy / destroy __buf_. Never + // null, even if the function is empty. + const __policy* __policy_; + + public: + _LIBCPP_INLINE_VISIBILITY + __policy_func() : __policy_(__policy::__create_empty()) {} + + template + _LIBCPP_INLINE_VISIBILITY __policy_func(_Fp&& __f, const _Alloc& __a) + : __policy_(__policy::__create_empty()) + { + typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; + typedef allocator_traits<_Alloc> __alloc_traits; + typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc; + + if (__function::__not_null(__f)) + { + __invoker_ = __invoker::template __create<_Fun>(); + __policy_ = __policy::__create<_Fun>(); + + _FunAlloc __af(__a); + if (__use_small_storage<_Fun>()) + { + ::new ((void*)&__buf_.__small) + _Fun(_VSTD::move(__f), _Alloc(__af)); + } + else + { + typedef __allocator_destructor<_FunAlloc> _Dp; + unique_ptr<_Fun, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); + ::new ((void*)__hold.get()) + _Fun(_VSTD::move(__f), _Alloc(__af)); + __buf_.__large = __hold.release(); + } + } + } + + template ::type, __policy_func>::value>::type> + _LIBCPP_INLINE_VISIBILITY explicit __policy_func(_Fp&& __f) + : __policy_(__policy::__create_empty()) { + typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun; + + if (__function::__not_null(__f)) { + __invoker_ = __invoker::template __create<_Fun>(); + __policy_ = __policy::__create<_Fun>(); + if (__use_small_storage<_Fun>()) { + ::new ((void*)&__buf_.__small) _Fun(_VSTD::move(__f)); + } else { + __builtin_new_allocator::__holder_t __hold = + __builtin_new_allocator::__allocate_type<_Fun>(1); + __buf_.__large = ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f)); + (void)__hold.release(); + } + } + } + + _LIBCPP_INLINE_VISIBILITY + __policy_func(const __policy_func& __f) + : __buf_(__f.__buf_), __invoker_(__f.__invoker_), + __policy_(__f.__policy_) + { + if (__policy_->__clone) + __buf_.__large = __policy_->__clone(__f.__buf_.__large); + } + + _LIBCPP_INLINE_VISIBILITY + __policy_func(__policy_func&& __f) + : __buf_(__f.__buf_), __invoker_(__f.__invoker_), + __policy_(__f.__policy_) + { + if (__policy_->__destroy) + { + __f.__policy_ = __policy::__create_empty(); + __f.__invoker_ = __invoker(); + } + } + + _LIBCPP_INLINE_VISIBILITY + ~__policy_func() + { + if (__policy_->__destroy) + __policy_->__destroy(__buf_.__large); + } + + _LIBCPP_INLINE_VISIBILITY + __policy_func& operator=(__policy_func&& __f) + { + *this = nullptr; + __buf_ = __f.__buf_; + __invoker_ = __f.__invoker_; + __policy_ = __f.__policy_; + __f.__policy_ = __policy::__create_empty(); + __f.__invoker_ = __invoker(); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __policy_func& operator=(nullptr_t) + { + const __policy* __p = __policy_; + __policy_ = __policy::__create_empty(); + __invoker_ = __invoker(); + if (__p->__destroy) + __p->__destroy(__buf_.__large); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + _Rp operator()(_ArgTypes&&... __args) const + { + return __invoker_.__call_(_VSTD::addressof(__buf_), + _VSTD::forward<_ArgTypes>(__args)...); + } + + _LIBCPP_INLINE_VISIBILITY + void swap(__policy_func& __f) + { + _VSTD::swap(__invoker_, __f.__invoker_); + _VSTD::swap(__policy_, __f.__policy_); + _VSTD::swap(__buf_, __f.__buf_); + } + + _LIBCPP_INLINE_VISIBILITY + explicit operator bool() const _NOEXCEPT + { + return !__policy_->__is_null; + } + +#ifndef _LIBCPP_NO_RTTI + _LIBCPP_INLINE_VISIBILITY + const std::type_info& target_type() const _NOEXCEPT + { + return *__policy_->__type_info; + } + + template + _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT + { + if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info) + return nullptr; + if (__policy_->__clone) // Out of line storage. + return reinterpret_cast(__buf_.__large); + else + return reinterpret_cast(&__buf_.__small); + } +#endif // _LIBCPP_NO_RTTI +}; + +#if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) + +extern "C" void *_Block_copy(const void *); +extern "C" void _Block_release(const void *); + +template +class __func<_Rp1(^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)> + : public __base<_Rp(_ArgTypes...)> +{ + typedef _Rp1(^__block_type)(_ArgTypes1...); + __block_type __f_; + +public: + _LIBCPP_INLINE_VISIBILITY + explicit __func(__block_type const& __f) +#ifdef _LIBCPP_HAS_OBJC_ARC + : __f_(__f) +#else + : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) +#endif + { } + + // [TODO] add && to save on a retain + + _LIBCPP_INLINE_VISIBILITY + explicit __func(__block_type __f, const _Alloc& /* unused */) +#ifdef _LIBCPP_HAS_OBJC_ARC + : __f_(__f) +#else + : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) +#endif + { } + + virtual __base<_Rp(_ArgTypes...)>* __clone() const { + _LIBCPP_ASSERT(false, + "Block pointers are just pointers, so they should always fit into " + "std::function's small buffer optimization. This function should " + "never be invoked."); + return nullptr; + } + + virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const { + ::new ((void*)__p) __func(__f_); + } + + virtual void destroy() _NOEXCEPT { +#ifndef _LIBCPP_HAS_OBJC_ARC + if (__f_) + _Block_release(__f_); +#endif + __f_ = 0; + } + + virtual void destroy_deallocate() _NOEXCEPT { + _LIBCPP_ASSERT(false, + "Block pointers are just pointers, so they should always fit into " + "std::function's small buffer optimization. This function should " + "never be invoked."); + } + + virtual _Rp operator()(_ArgTypes&& ... __arg) { + return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__arg)...); + } + +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(type_info const& __ti) const _NOEXCEPT { + if (__ti == typeid(__func::__block_type)) + return &__f_; + return (const void*)nullptr; + } + + virtual const std::type_info& target_type() const _NOEXCEPT { + return typeid(__func::__block_type); + } +#endif // _LIBCPP_NO_RTTI +}; + +#endif // _LIBCPP_HAS_EXTENSION_BLOCKS + +} // namespace __function + +template +class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)> + : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>, + public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)> +{ +#ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION + typedef __function::__value_func<_Rp(_ArgTypes...)> __func; +#else + typedef __function::__policy_func<_Rp(_ArgTypes...)> __func; +#endif + + __func __f_; + + template , function>, + __invokable<_Fp, _ArgTypes...> + >::value> + struct __callable; + template + struct __callable<_Fp, true> + { + static const bool value = is_void<_Rp>::value || + __is_core_convertible::type, + _Rp>::value; + }; + template + struct __callable<_Fp, false> + { + static const bool value = false; + }; + + template + using _EnableIfLValueCallable = typename enable_if<__callable<_Fp&>::value>::type; +public: + typedef _Rp result_type; + + // construct/copy/destroy: + _LIBCPP_INLINE_VISIBILITY + function() _NOEXCEPT { } + _LIBCPP_INLINE_VISIBILITY + function(nullptr_t) _NOEXCEPT {} + function(const function&); + function(function&&) _NOEXCEPT; + template> + function(_Fp); + +#if _LIBCPP_STD_VER <= 14 + template + _LIBCPP_INLINE_VISIBILITY + function(allocator_arg_t, const _Alloc&) _NOEXCEPT {} + template + _LIBCPP_INLINE_VISIBILITY + function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {} + template + function(allocator_arg_t, const _Alloc&, const function&); + template + function(allocator_arg_t, const _Alloc&, function&&); + template> + function(allocator_arg_t, const _Alloc& __a, _Fp __f); +#endif + + function& operator=(const function&); + function& operator=(function&&) _NOEXCEPT; + function& operator=(nullptr_t) _NOEXCEPT; + template::type>> + function& operator=(_Fp&&); + + ~function(); + + // function modifiers: + void swap(function&) _NOEXCEPT; + +#if _LIBCPP_STD_VER <= 14 + template + _LIBCPP_INLINE_VISIBILITY + void assign(_Fp&& __f, const _Alloc& __a) + {function(allocator_arg, __a, _VSTD::forward<_Fp>(__f)).swap(*this);} +#endif + + // function capacity: + _LIBCPP_INLINE_VISIBILITY + explicit operator bool() const _NOEXCEPT { + return static_cast(__f_); + } + + // deleted overloads close possible hole in the type system + template + bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete; + template + bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete; +public: + // function invocation: + _Rp operator()(_ArgTypes...) const; + +#ifndef _LIBCPP_NO_RTTI + // function target access: + const std::type_info& target_type() const _NOEXCEPT; + template _Tp* target() _NOEXCEPT; + template const _Tp* target() const _NOEXCEPT; +#endif // _LIBCPP_NO_RTTI +}; + +#if _LIBCPP_STD_VER >= 17 +template +function(_Rp(*)(_Ap...)) -> function<_Rp(_Ap...)>; + +template::type> +function(_Fp) -> function<_Stripped>; +#endif // _LIBCPP_STD_VER >= 17 + +template +function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {} + +#if _LIBCPP_STD_VER <= 14 +template +template +function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, + const function& __f) : __f_(__f.__f_) {} +#endif + +template +function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT + : __f_(_VSTD::move(__f.__f_)) {} + +#if _LIBCPP_STD_VER <= 14 +template +template +function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, + function&& __f) + : __f_(_VSTD::move(__f.__f_)) {} +#endif + +template +template +function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(_VSTD::move(__f)) {} + +#if _LIBCPP_STD_VER <= 14 +template +template +function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a, + _Fp __f) + : __f_(_VSTD::move(__f), __a) {} +#endif + +template +function<_Rp(_ArgTypes...)>& +function<_Rp(_ArgTypes...)>::operator=(const function& __f) +{ + function(__f).swap(*this); + return *this; +} + +template +function<_Rp(_ArgTypes...)>& +function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT +{ + __f_ = _VSTD::move(__f.__f_); + return *this; +} + +template +function<_Rp(_ArgTypes...)>& +function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT +{ + __f_ = nullptr; + return *this; +} + +template +template +function<_Rp(_ArgTypes...)>& +function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) +{ + function(_VSTD::forward<_Fp>(__f)).swap(*this); + return *this; +} + +template +function<_Rp(_ArgTypes...)>::~function() {} + +template +void +function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT +{ + __f_.swap(__f.__f_); +} + +template +_Rp +function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const +{ + return __f_(_VSTD::forward<_ArgTypes>(__arg)...); +} + +#ifndef _LIBCPP_NO_RTTI + +template +const std::type_info& +function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT +{ + return __f_.target_type(); +} + +template +template +_Tp* +function<_Rp(_ArgTypes...)>::target() _NOEXCEPT +{ + return (_Tp*)(__f_.template target<_Tp>()); +} + +template +template +const _Tp* +function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT +{ + return __f_.template target<_Tp>(); +} + +#endif // _LIBCPP_NO_RTTI + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return !__f;} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return !__f;} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return (bool)__f;} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return (bool)__f;} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT +{return __x.swap(__y);} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FUNCTIONAL_FUNCTION_H diff --git a/app/src/main/cpp/libcxx/include/__functional/hash.h b/app/src/main/cpp/libcxx/include/__functional/hash.h new file mode 100644 index 0000000..dfd8ea2 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/hash.h @@ -0,0 +1,693 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___FUNCTIONAL_HASH_H +#define _LIBCPP___FUNCTIONAL_HASH_H + +#include <__config> +#include <__functional/invoke.h> +#include <__functional/unary_function.h> +#include <__fwd/hash.h> +#include <__tuple_dir/sfinae_helpers.h> +#include <__type_traits/is_copy_constructible.h> +#include <__type_traits/is_default_constructible.h> +#include <__type_traits/is_enum.h> +#include <__type_traits/is_move_constructible.h> +#include <__type_traits/underlying_type.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/pair.h> +#include <__utility/swap.h> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY +_Size +__loadword(const void* __p) +{ + _Size __r; + _VSTD::memcpy(&__r, __p, sizeof(__r)); + return __r; +} + +// We use murmur2 when size_t is 32 bits, and cityhash64 when size_t +// is 64 bits. This is because cityhash64 uses 64bit x 64bit +// multiplication, which can be very slow on 32-bit systems. +template +struct __murmur2_or_cityhash; + +template +struct __murmur2_or_cityhash<_Size, 32> +{ + inline _Size operator()(const void* __key, _Size __len) + _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK; +}; + +// murmur2 +template +_Size +__murmur2_or_cityhash<_Size, 32>::operator()(const void* __key, _Size __len) +{ + const _Size __m = 0x5bd1e995; + const _Size __r = 24; + _Size __h = __len; + const unsigned char* __data = static_cast(__key); + for (; __len >= 4; __data += 4, __len -= 4) + { + _Size __k = std::__loadword<_Size>(__data); + __k *= __m; + __k ^= __k >> __r; + __k *= __m; + __h *= __m; + __h ^= __k; + } + switch (__len) + { + case 3: + __h ^= static_cast<_Size>(__data[2] << 16); + _LIBCPP_FALLTHROUGH(); + case 2: + __h ^= static_cast<_Size>(__data[1] << 8); + _LIBCPP_FALLTHROUGH(); + case 1: + __h ^= __data[0]; + __h *= __m; + } + __h ^= __h >> 13; + __h *= __m; + __h ^= __h >> 15; + return __h; +} + +template +struct __murmur2_or_cityhash<_Size, 64> +{ + inline _Size operator()(const void* __key, _Size __len) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK; + + private: + // Some primes between 2^63 and 2^64. + static const _Size __k0 = 0xc3a5c85c97cb3127ULL; + static const _Size __k1 = 0xb492b66fbe98f273ULL; + static const _Size __k2 = 0x9ae16a3b2f90404fULL; + static const _Size __k3 = 0xc949d7c7509e6557ULL; + + static _Size __rotate(_Size __val, int __shift) { + return __shift == 0 ? __val : ((__val >> __shift) | (__val << (64 - __shift))); + } + + static _Size __rotate_by_at_least_1(_Size __val, int __shift) { + return (__val >> __shift) | (__val << (64 - __shift)); + } + + static _Size __shift_mix(_Size __val) { + return __val ^ (__val >> 47); + } + + static _Size __hash_len_16(_Size __u, _Size __v) + _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK + { + const _Size __mul = 0x9ddfea08eb382d69ULL; + _Size __a = (__u ^ __v) * __mul; + __a ^= (__a >> 47); + _Size __b = (__v ^ __a) * __mul; + __b ^= (__b >> 47); + __b *= __mul; + return __b; + } + + static _Size __hash_len_0_to_16(const char* __s, _Size __len) + _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK + { + if (__len > 8) { + const _Size __a = std::__loadword<_Size>(__s); + const _Size __b = std::__loadword<_Size>(__s + __len - 8); + return __hash_len_16(__a, __rotate_by_at_least_1(__b + __len, __len)) ^ __b; + } + if (__len >= 4) { + const uint32_t __a = std::__loadword(__s); + const uint32_t __b = std::__loadword(__s + __len - 4); + return __hash_len_16(__len + (static_cast<_Size>(__a) << 3), __b); + } + if (__len > 0) { + const unsigned char __a = static_cast(__s[0]); + const unsigned char __b = static_cast(__s[__len >> 1]); + const unsigned char __c = static_cast(__s[__len - 1]); + const uint32_t __y = static_cast(__a) + + (static_cast(__b) << 8); + const uint32_t __z = __len + (static_cast(__c) << 2); + return __shift_mix(__y * __k2 ^ __z * __k3) * __k2; + } + return __k2; + } + + static _Size __hash_len_17_to_32(const char *__s, _Size __len) + _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK + { + const _Size __a = std::__loadword<_Size>(__s) * __k1; + const _Size __b = std::__loadword<_Size>(__s + 8); + const _Size __c = std::__loadword<_Size>(__s + __len - 8) * __k2; + const _Size __d = std::__loadword<_Size>(__s + __len - 16) * __k0; + return __hash_len_16(__rotate(__a - __b, 43) + __rotate(__c, 30) + __d, + __a + __rotate(__b ^ __k3, 20) - __c + __len); + } + + // Return a 16-byte hash for 48 bytes. Quick and dirty. + // Callers do best to use "random-looking" values for a and b. + static pair<_Size, _Size> __weak_hash_len_32_with_seeds( + _Size __w, _Size __x, _Size __y, _Size __z, _Size __a, _Size __b) + _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK + { + __a += __w; + __b = __rotate(__b + __a + __z, 21); + const _Size __c = __a; + __a += __x; + __a += __y; + __b += __rotate(__a, 44); + return pair<_Size, _Size>(__a + __z, __b + __c); + } + + // Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty. + static pair<_Size, _Size> __weak_hash_len_32_with_seeds( + const char* __s, _Size __a, _Size __b) + _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK + { + return __weak_hash_len_32_with_seeds(std::__loadword<_Size>(__s), + std::__loadword<_Size>(__s + 8), + std::__loadword<_Size>(__s + 16), + std::__loadword<_Size>(__s + 24), + __a, + __b); + } + + // Return an 8-byte hash for 33 to 64 bytes. + static _Size __hash_len_33_to_64(const char *__s, size_t __len) + _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK + { + _Size __z = std::__loadword<_Size>(__s + 24); + _Size __a = std::__loadword<_Size>(__s) + + (__len + std::__loadword<_Size>(__s + __len - 16)) * __k0; + _Size __b = __rotate(__a + __z, 52); + _Size __c = __rotate(__a, 37); + __a += std::__loadword<_Size>(__s + 8); + __c += __rotate(__a, 7); + __a += std::__loadword<_Size>(__s + 16); + _Size __vf = __a + __z; + _Size __vs = __b + __rotate(__a, 31) + __c; + __a = std::__loadword<_Size>(__s + 16) + std::__loadword<_Size>(__s + __len - 32); + __z += std::__loadword<_Size>(__s + __len - 8); + __b = __rotate(__a + __z, 52); + __c = __rotate(__a, 37); + __a += std::__loadword<_Size>(__s + __len - 24); + __c += __rotate(__a, 7); + __a += std::__loadword<_Size>(__s + __len - 16); + _Size __wf = __a + __z; + _Size __ws = __b + __rotate(__a, 31) + __c; + _Size __r = __shift_mix((__vf + __ws) * __k2 + (__wf + __vs) * __k0); + return __shift_mix(__r * __k0 + __vs) * __k2; + } +}; + +// cityhash64 +template +_Size +__murmur2_or_cityhash<_Size, 64>::operator()(const void* __key, _Size __len) +{ + const char* __s = static_cast(__key); + if (__len <= 32) { + if (__len <= 16) { + return __hash_len_0_to_16(__s, __len); + } else { + return __hash_len_17_to_32(__s, __len); + } + } else if (__len <= 64) { + return __hash_len_33_to_64(__s, __len); + } + + // For strings over 64 bytes we hash the end first, and then as we + // loop we keep 56 bytes of state: v, w, x, y, and z. + _Size __x = std::__loadword<_Size>(__s + __len - 40); + _Size __y = std::__loadword<_Size>(__s + __len - 16) + + std::__loadword<_Size>(__s + __len - 56); + _Size __z = __hash_len_16(std::__loadword<_Size>(__s + __len - 48) + __len, + std::__loadword<_Size>(__s + __len - 24)); + pair<_Size, _Size> __v = __weak_hash_len_32_with_seeds(__s + __len - 64, __len, __z); + pair<_Size, _Size> __w = __weak_hash_len_32_with_seeds(__s + __len - 32, __y + __k1, __x); + __x = __x * __k1 + std::__loadword<_Size>(__s); + + // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks. + __len = (__len - 1) & ~static_cast<_Size>(63); + do { + __x = __rotate(__x + __y + __v.first + std::__loadword<_Size>(__s + 8), 37) * __k1; + __y = __rotate(__y + __v.second + std::__loadword<_Size>(__s + 48), 42) * __k1; + __x ^= __w.second; + __y += __v.first + std::__loadword<_Size>(__s + 40); + __z = __rotate(__z + __w.first, 33) * __k1; + __v = __weak_hash_len_32_with_seeds(__s, __v.second * __k1, __x + __w.first); + __w = __weak_hash_len_32_with_seeds(__s + 32, __z + __w.second, + __y + std::__loadword<_Size>(__s + 16)); + _VSTD::swap(__z, __x); + __s += 64; + __len -= 64; + } while (__len != 0); + return __hash_len_16( + __hash_len_16(__v.first, __w.first) + __shift_mix(__y) * __k1 + __z, + __hash_len_16(__v.second, __w.second) + __x); +} + +template +struct __scalar_hash; + +template +struct __scalar_hash<_Tp, 0> + : public __unary_function<_Tp, size_t> +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(_Tp __v) const _NOEXCEPT + { + union + { + _Tp __t; + size_t __a; + } __u; + __u.__a = 0; + __u.__t = __v; + return __u.__a; + } +}; + +template +struct __scalar_hash<_Tp, 1> + : public __unary_function<_Tp, size_t> +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(_Tp __v) const _NOEXCEPT + { + union + { + _Tp __t; + size_t __a; + } __u; + __u.__t = __v; + return __u.__a; + } +}; + +template +struct __scalar_hash<_Tp, 2> + : public __unary_function<_Tp, size_t> +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(_Tp __v) const _NOEXCEPT + { + union + { + _Tp __t; + struct + { + size_t __a; + size_t __b; + } __s; + } __u; + __u.__t = __v; + return __murmur2_or_cityhash()(&__u, sizeof(__u)); + } +}; + +template +struct __scalar_hash<_Tp, 3> + : public __unary_function<_Tp, size_t> +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(_Tp __v) const _NOEXCEPT + { + union + { + _Tp __t; + struct + { + size_t __a; + size_t __b; + size_t __c; + } __s; + } __u; + __u.__t = __v; + return __murmur2_or_cityhash()(&__u, sizeof(__u)); + } +}; + +template +struct __scalar_hash<_Tp, 4> + : public __unary_function<_Tp, size_t> +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(_Tp __v) const _NOEXCEPT + { + union + { + _Tp __t; + struct + { + size_t __a; + size_t __b; + size_t __c; + size_t __d; + } __s; + } __u; + __u.__t = __v; + return __murmur2_or_cityhash()(&__u, sizeof(__u)); + } +}; + +struct _PairT { + size_t first; + size_t second; +}; + +_LIBCPP_INLINE_VISIBILITY +inline size_t __hash_combine(size_t __lhs, size_t __rhs) _NOEXCEPT { + typedef __scalar_hash<_PairT> _HashT; + const _PairT __p = {__lhs, __rhs}; + return _HashT()(__p); +} + +template +struct _LIBCPP_TEMPLATE_VIS hash<_Tp*> + : public __unary_function<_Tp*, size_t> +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(_Tp* __v) const _NOEXCEPT + { + union + { + _Tp* __t; + size_t __a; + } __u; + __u.__t = __v; + return __murmur2_or_cityhash()(&__u, sizeof(__u)); + } +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(bool __v) const _NOEXCEPT {return static_cast(__v);} +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(char __v) const _NOEXCEPT {return static_cast(__v);} +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(signed char __v) const _NOEXCEPT {return static_cast(__v);} +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(unsigned char __v) const _NOEXCEPT {return static_cast(__v);} +}; + +#ifndef _LIBCPP_HAS_NO_CHAR8_T +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(char8_t __v) const _NOEXCEPT {return static_cast(__v);} +}; +#endif // !_LIBCPP_HAS_NO_CHAR8_T + +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(char16_t __v) const _NOEXCEPT {return static_cast(__v);} +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(char32_t __v) const _NOEXCEPT {return static_cast(__v);} +}; + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(wchar_t __v) const _NOEXCEPT {return static_cast(__v);} +}; +#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS + +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(short __v) const _NOEXCEPT {return static_cast(__v);} +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(unsigned short __v) const _NOEXCEPT {return static_cast(__v);} +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(int __v) const _NOEXCEPT {return static_cast(__v);} +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(unsigned int __v) const _NOEXCEPT {return static_cast(__v);} +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(long __v) const _NOEXCEPT {return static_cast(__v);} +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(unsigned long __v) const _NOEXCEPT {return static_cast(__v);} +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __scalar_hash +{ +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __scalar_hash +{ +}; + +#ifndef _LIBCPP_HAS_NO_INT128 + +template <> +struct _LIBCPP_TEMPLATE_VIS hash<__int128_t> + : public __scalar_hash<__int128_t> +{ +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS hash<__uint128_t> + : public __scalar_hash<__uint128_t> +{ +}; + +#endif + +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __scalar_hash +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(float __v) const _NOEXCEPT + { + // -0.0 and 0.0 should return same hash + if (__v == 0.0f) + return 0; + return __scalar_hash::operator()(__v); + } +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __scalar_hash +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(double __v) const _NOEXCEPT + { + // -0.0 and 0.0 should return same hash + if (__v == 0.0) + return 0; + return __scalar_hash::operator()(__v); + } +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __scalar_hash +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(long double __v) const _NOEXCEPT + { + // -0.0 and 0.0 should return same hash + if (__v == 0.0L) + return 0; +#if defined(__i386__) || (defined(__x86_64__) && defined(__ILP32__)) + // Zero out padding bits + union + { + long double __t; + struct + { + size_t __a; + size_t __b; + size_t __c; + size_t __d; + } __s; + } __u; + __u.__s.__a = 0; + __u.__s.__b = 0; + __u.__s.__c = 0; + __u.__s.__d = 0; + __u.__t = __v; + return __u.__s.__a ^ __u.__s.__b ^ __u.__s.__c ^ __u.__s.__d; +#elif defined(__x86_64__) + // Zero out padding bits + union + { + long double __t; + struct + { + size_t __a; + size_t __b; + } __s; + } __u; + __u.__s.__a = 0; + __u.__s.__b = 0; + __u.__t = __v; + return __u.__s.__a ^ __u.__s.__b; +#else + return __scalar_hash::operator()(__v); +#endif + } +}; + +template ::value> +struct _LIBCPP_TEMPLATE_VIS __enum_hash + : public __unary_function<_Tp, size_t> +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(_Tp __v) const _NOEXCEPT + { + typedef typename underlying_type<_Tp>::type type; + return hash()(static_cast(__v)); + } +}; +template +struct _LIBCPP_TEMPLATE_VIS __enum_hash<_Tp, false> { + __enum_hash() = delete; + __enum_hash(__enum_hash const&) = delete; + __enum_hash& operator=(__enum_hash const&) = delete; +}; + +template +struct _LIBCPP_TEMPLATE_VIS hash : public __enum_hash<_Tp> +{ +}; + +#if _LIBCPP_STD_VER > 14 + +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(nullptr_t) const _NOEXCEPT { + return 662607004ull; + } +}; +#endif + +#ifndef _LIBCPP_CXX03_LANG +template +using __check_hash_requirements _LIBCPP_NODEBUG = integral_constant::value && + is_move_constructible<_Hash>::value && + __invokable_r::value +>; + +template > +using __has_enabled_hash _LIBCPP_NODEBUG = integral_constant::value && + is_default_constructible<_Hash>::value +>; + +#if _LIBCPP_STD_VER > 14 +template +using __enable_hash_helper_imp _LIBCPP_NODEBUG = _Type; + +template +using __enable_hash_helper _LIBCPP_NODEBUG = __enable_hash_helper_imp<_Type, + typename enable_if<__all<__has_enabled_hash<_Keys>::value...>::value>::type +>; +#else +template +using __enable_hash_helper _LIBCPP_NODEBUG = _Type; +#endif + +#endif // !_LIBCPP_CXX03_LANG + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_HASH_H diff --git a/app/src/main/cpp/libcxx/include/__functional/identity.h b/app/src/main/cpp/libcxx/include/__functional/identity.h new file mode 100644 index 0000000..2fe3acc --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/identity.h @@ -0,0 +1,46 @@ +// -*- 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 _LIBCPP___FUNCTIONAL_IDENTITY_H +#define _LIBCPP___FUNCTIONAL_IDENTITY_H + +#include <__config> +#include <__utility/forward.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +struct __identity { + template + _LIBCPP_NODISCARD _LIBCPP_CONSTEXPR _Tp&& operator()(_Tp&& __t) const _NOEXCEPT { + return std::forward<_Tp>(__t); + } + + using is_transparent = void; +}; + +#if _LIBCPP_STD_VER > 17 + +struct identity { + template + _LIBCPP_NODISCARD_EXT constexpr _Tp&& operator()(_Tp&& __t) const noexcept + { + return _VSTD::forward<_Tp>(__t); + } + + using is_transparent = void; +}; +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_IDENTITY_H diff --git a/app/src/main/cpp/libcxx/include/__functional/invoke.h b/app/src/main/cpp/libcxx/include/__functional/invoke.h new file mode 100644 index 0000000..48e6eac --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/invoke.h @@ -0,0 +1,546 @@ +// -*- 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 _LIBCPP___FUNCTIONAL_INVOKE_H +#define _LIBCPP___FUNCTIONAL_INVOKE_H + +#include <__config> +#include <__type_traits/add_lvalue_reference.h> +#include <__type_traits/apply_cv.h> +#include <__type_traits/conditional.h> +#include <__type_traits/decay.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_base_of.h> +#include <__type_traits/is_core_convertible.h> +#include <__type_traits/is_member_function_pointer.h> +#include <__type_traits/is_member_object_pointer.h> +#include <__type_traits/is_reference_wrapper.h> +#include <__type_traits/is_same.h> +#include <__type_traits/is_void.h> +#include <__type_traits/nat.h> +#include <__type_traits/remove_cv.h> +#include <__utility/declval.h> +#include <__utility/forward.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +// TODO: Disentangle the type traits and std::invoke properly + +_LIBCPP_BEGIN_NAMESPACE_STD + +struct __any +{ + __any(...); +}; + +template +struct __member_pointer_traits_imp +{ +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...), true, false> +{ + typedef _Class _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...), true, false> +{ + typedef _Class _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const, true, false> +{ + typedef _Class const _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const, true, false> +{ + typedef _Class const _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile, true, false> +{ + typedef _Class volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile, true, false> +{ + typedef _Class volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile, true, false> +{ + typedef _Class const volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile, true, false> +{ + typedef _Class const volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &, true, false> +{ + typedef _Class& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &, true, false> +{ + typedef _Class& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&, true, false> +{ + typedef _Class const& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&, true, false> +{ + typedef _Class const& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&, true, false> +{ + typedef _Class volatile& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&, true, false> +{ + typedef _Class volatile& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&, true, false> +{ + typedef _Class const volatile& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&, true, false> +{ + typedef _Class const volatile& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &&, true, false> +{ + typedef _Class&& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &&, true, false> +{ + typedef _Class&& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&&, true, false> +{ + typedef _Class const&& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&&, true, false> +{ + typedef _Class const&& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&&, true, false> +{ + typedef _Class volatile&& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&&, true, false> +{ + typedef _Class volatile&& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&&, true, false> +{ + typedef _Class const volatile&& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&&, true, false> +{ + typedef _Class const volatile&& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); +}; + +template +struct __member_pointer_traits_imp<_Rp _Class::*, false, true> +{ + typedef _Class _ClassType; + typedef _Rp _ReturnType; +}; + +template +struct __member_pointer_traits + : public __member_pointer_traits_imp<__remove_cv_t<_MP>, + is_member_function_pointer<_MP>::value, + is_member_object_pointer<_MP>::value> +{ +// typedef ... _ClassType; +// typedef ... _ReturnType; +// typedef ... _FnType; +}; + +template +struct __member_pointer_class_type {}; + +template +struct __member_pointer_class_type<_Ret _ClassType::*> { + typedef _ClassType type; +}; + +template ::type, + class _DecayA0 = typename decay<_A0>::type, + class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> +using __enable_if_bullet1 = typename enable_if + < + is_member_function_pointer<_DecayFp>::value + && is_base_of<_ClassT, _DecayA0>::value + >::type; + +template ::type, + class _DecayA0 = typename decay<_A0>::type> +using __enable_if_bullet2 = typename enable_if + < + is_member_function_pointer<_DecayFp>::value + && __is_reference_wrapper<_DecayA0>::value + >::type; + +template ::type, + class _DecayA0 = typename decay<_A0>::type, + class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> +using __enable_if_bullet3 = typename enable_if + < + is_member_function_pointer<_DecayFp>::value + && !is_base_of<_ClassT, _DecayA0>::value + && !__is_reference_wrapper<_DecayA0>::value + >::type; + +template ::type, + class _DecayA0 = typename decay<_A0>::type, + class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> +using __enable_if_bullet4 = typename enable_if + < + is_member_object_pointer<_DecayFp>::value + && is_base_of<_ClassT, _DecayA0>::value + >::type; + +template ::type, + class _DecayA0 = typename decay<_A0>::type> +using __enable_if_bullet5 = typename enable_if + < + is_member_object_pointer<_DecayFp>::value + && __is_reference_wrapper<_DecayA0>::value + >::type; + +template ::type, + class _DecayA0 = typename decay<_A0>::type, + class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> +using __enable_if_bullet6 = typename enable_if + < + is_member_object_pointer<_DecayFp>::value + && !is_base_of<_ClassT, _DecayA0>::value + && !__is_reference_wrapper<_DecayA0>::value + >::type; + +// __invoke forward declarations + +// fall back - none of the bullets + +template +__nat __invoke(__any, _Args&& ...__args); + +// bullets 1, 2 and 3 + +template > +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR decltype((std::declval<_A0>().*std::declval<_Fp>())(std::declval<_Args>()...)) +__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) + _NOEXCEPT_(noexcept((static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...))) + { return (static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...); } + +template > +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR decltype((std::declval<_A0>().get().*std::declval<_Fp>())(std::declval<_Args>()...)) +__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) + _NOEXCEPT_(noexcept((__a0.get().*__f)(static_cast<_Args&&>(__args)...))) + { return (__a0.get().*__f)(static_cast<_Args&&>(__args)...); } + +template > +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR decltype(((*std::declval<_A0>()).*std::declval<_Fp>())(std::declval<_Args>()...)) +__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) + _NOEXCEPT_(noexcept(((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...))) + { return ((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...); } + +// bullets 4, 5 and 6 + +template > +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR decltype(std::declval<_A0>().*std::declval<_Fp>()) +__invoke(_Fp&& __f, _A0&& __a0) + _NOEXCEPT_(noexcept(static_cast<_A0&&>(__a0).*__f)) + { return static_cast<_A0&&>(__a0).*__f; } + +template > +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR decltype(std::declval<_A0>().get().*std::declval<_Fp>()) +__invoke(_Fp&& __f, _A0&& __a0) + _NOEXCEPT_(noexcept(__a0.get().*__f)) + { return __a0.get().*__f; } + +template > +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR decltype((*std::declval<_A0>()).*std::declval<_Fp>()) +__invoke(_Fp&& __f, _A0&& __a0) + _NOEXCEPT_(noexcept((*static_cast<_A0&&>(__a0)).*__f)) + { return (*static_cast<_A0&&>(__a0)).*__f; } + +// bullet 7 + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR decltype(std::declval<_Fp>()(std::declval<_Args>()...)) +__invoke(_Fp&& __f, _Args&& ...__args) + _NOEXCEPT_(noexcept(static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...))) + { return static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...); } + +// __invokable +template +struct __invokable_r +{ + template + static decltype(std::__invoke(std::declval<_XFp>(), std::declval<_XArgs>()...)) __try_call(int); + template + static __nat __try_call(...); + + // FIXME: Check that _Ret, _Fp, and _Args... are all complete types, cv void, + // or incomplete array types as required by the standard. + using _Result = decltype(__try_call<_Fp, _Args...>(0)); + + using type = __conditional_t< + _IsNotSame<_Result, __nat>::value, + __conditional_t::value, true_type, __is_core_convertible<_Result, _Ret> >, + false_type>; + static const bool value = type::value; +}; +template +using __invokable = __invokable_r; + +template +struct __nothrow_invokable_r_imp { + static const bool value = false; +}; + +template +struct __nothrow_invokable_r_imp +{ + typedef __nothrow_invokable_r_imp _ThisT; + + template + static void __test_noexcept(_Tp) _NOEXCEPT; + +#ifdef _LIBCPP_CXX03_LANG + static const bool value = false; +#else + static const bool value = noexcept(_ThisT::__test_noexcept<_Ret>( + _VSTD::__invoke(std::declval<_Fp>(), std::declval<_Args>()...))); +#endif +}; + +template +struct __nothrow_invokable_r_imp +{ +#ifdef _LIBCPP_CXX03_LANG + static const bool value = false; +#else + static const bool value = noexcept( + _VSTD::__invoke(std::declval<_Fp>(), std::declval<_Args>()...)); +#endif +}; + +template +using __nothrow_invokable_r = + __nothrow_invokable_r_imp< + __invokable_r<_Ret, _Fp, _Args...>::value, + is_void<_Ret>::value, + _Ret, _Fp, _Args... + >; + +template +using __nothrow_invokable = + __nothrow_invokable_r_imp< + __invokable<_Fp, _Args...>::value, + true, void, _Fp, _Args... + >; + +template +struct __invoke_of + : public enable_if< + __invokable<_Fp, _Args...>::value, + typename __invokable_r::_Result> +{ +}; + +template ::value> +struct __invoke_void_return_wrapper +{ + template + static _Ret __call(_Args&&... __args) { + return std::__invoke(std::forward<_Args>(__args)...); + } +}; + +template +struct __invoke_void_return_wrapper<_Ret, true> +{ + template + static void __call(_Args&&... __args) { + std::__invoke(std::forward<_Args>(__args)...); + } +}; + +#if _LIBCPP_STD_VER > 14 + +// is_invocable + +template +struct _LIBCPP_TEMPLATE_VIS is_invocable + : integral_constant::value> {}; + +template +struct _LIBCPP_TEMPLATE_VIS is_invocable_r + : integral_constant::value> {}; + +template +inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value; + +template +inline constexpr bool is_invocable_r_v = is_invocable_r<_Ret, _Fn, _Args...>::value; + +// is_nothrow_invocable + +template +struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable + : integral_constant::value> {}; + +template +struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable_r + : integral_constant::value> {}; + +template +inline constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<_Fn, _Args...>::value; + +template +inline constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value; + +template +struct _LIBCPP_TEMPLATE_VIS invoke_result + : __invoke_of<_Fn, _Args...> +{ +}; + +template +using invoke_result_t = typename invoke_result<_Fn, _Args...>::type; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 invoke_result_t<_Fn, _Args...> +invoke(_Fn&& __f, _Args&&... __args) + noexcept(is_nothrow_invocable_v<_Fn, _Args...>) +{ + return _VSTD::__invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...); +} + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_INVOKE_H diff --git a/app/src/main/cpp/libcxx/include/__functional/is_transparent.h b/app/src/main/cpp/libcxx/include/__functional/is_transparent.h new file mode 100644 index 0000000..c7a0ee9 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/is_transparent.h @@ -0,0 +1,35 @@ +// -*- 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 _LIBCPP___FUNCTIONAL_IS_TRANSPARENT +#define _LIBCPP___FUNCTIONAL_IS_TRANSPARENT + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 11 + +template +struct __is_transparent : false_type {}; + +template +struct __is_transparent<_Tp, _Up, __void_t > + : true_type {}; + +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_IS_TRANSPARENT diff --git a/app/src/main/cpp/libcxx/include/__functional/mem_fn.h b/app/src/main/cpp/libcxx/include/__functional/mem_fn.h new file mode 100644 index 0000000..8b51627 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/mem_fn.h @@ -0,0 +1,59 @@ +// -*- 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 _LIBCPP___FUNCTIONAL_MEM_FN_H +#define _LIBCPP___FUNCTIONAL_MEM_FN_H + +#include <__config> +#include <__functional/binary_function.h> +#include <__functional/invoke.h> +#include <__functional/weak_result_type.h> +#include <__utility/forward.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class __mem_fn : public __weak_result_type<_Tp> +{ +public: + // types + typedef _Tp type; +private: + type __f_; + +public: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + __mem_fn(type __f) _NOEXCEPT : __f_(__f) {} + + // invoke + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + + typename __invoke_return::type + operator() (_ArgTypes&&... __args) const { + return std::__invoke(__f_, std::forward<_ArgTypes>(__args)...); + } +}; + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +__mem_fn<_Rp _Tp::*> +mem_fn(_Rp _Tp::* __pm) _NOEXCEPT +{ + return __mem_fn<_Rp _Tp::*>(__pm); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_MEM_FN_H diff --git a/app/src/main/cpp/libcxx/include/__functional/mem_fun_ref.h b/app/src/main/cpp/libcxx/include/__functional/mem_fun_ref.h new file mode 100644 index 0000000..65aab06 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/mem_fun_ref.h @@ -0,0 +1,173 @@ +// -*- 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 _LIBCPP___FUNCTIONAL_MEM_FUN_REF_H +#define _LIBCPP___FUNCTIONAL_MEM_FUN_REF_H + +#include <__config> +#include <__functional/binary_function.h> +#include <__functional/unary_function.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_t + : public __unary_function<_Tp*, _Sp> +{ + _Sp (_Tp::*__p_)(); +public: + _LIBCPP_INLINE_VISIBILITY explicit mem_fun_t(_Sp (_Tp::*__p)()) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp* __p) const + {return (__p->*__p_)();} +}; + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_t + : public __binary_function<_Tp*, _Ap, _Sp> +{ + _Sp (_Tp::*__p_)(_Ap); +public: + _LIBCPP_INLINE_VISIBILITY explicit mem_fun1_t(_Sp (_Tp::*__p)(_Ap)) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp* __p, _Ap __x) const + {return (__p->*__p_)(__x);} +}; + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY +mem_fun_t<_Sp,_Tp> +mem_fun(_Sp (_Tp::*__f)()) + {return mem_fun_t<_Sp,_Tp>(__f);} + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY +mem_fun1_t<_Sp,_Tp,_Ap> +mem_fun(_Sp (_Tp::*__f)(_Ap)) + {return mem_fun1_t<_Sp,_Tp,_Ap>(__f);} + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_ref_t + : public __unary_function<_Tp, _Sp> +{ + _Sp (_Tp::*__p_)(); +public: + _LIBCPP_INLINE_VISIBILITY explicit mem_fun_ref_t(_Sp (_Tp::*__p)()) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp& __p) const + {return (__p.*__p_)();} +}; + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_ref_t + : public __binary_function<_Tp, _Ap, _Sp> +{ + _Sp (_Tp::*__p_)(_Ap); +public: + _LIBCPP_INLINE_VISIBILITY explicit mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap)) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp& __p, _Ap __x) const + {return (__p.*__p_)(__x);} +}; + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY +mem_fun_ref_t<_Sp,_Tp> +mem_fun_ref(_Sp (_Tp::*__f)()) + {return mem_fun_ref_t<_Sp,_Tp>(__f);} + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY +mem_fun1_ref_t<_Sp,_Tp,_Ap> +mem_fun_ref(_Sp (_Tp::*__f)(_Ap)) + {return mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);} + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_t + : public __unary_function +{ + _Sp (_Tp::*__p_)() const; +public: + _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun_t(_Sp (_Tp::*__p)() const) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp* __p) const + {return (__p->*__p_)();} +}; + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_t + : public __binary_function +{ + _Sp (_Tp::*__p_)(_Ap) const; +public: + _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun1_t(_Sp (_Tp::*__p)(_Ap) const) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp* __p, _Ap __x) const + {return (__p->*__p_)(__x);} +}; + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY +const_mem_fun_t<_Sp,_Tp> +mem_fun(_Sp (_Tp::*__f)() const) + {return const_mem_fun_t<_Sp,_Tp>(__f);} + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY +const_mem_fun1_t<_Sp,_Tp,_Ap> +mem_fun(_Sp (_Tp::*__f)(_Ap) const) + {return const_mem_fun1_t<_Sp,_Tp,_Ap>(__f);} + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_ref_t + : public __unary_function<_Tp, _Sp> +{ + _Sp (_Tp::*__p_)() const; +public: + _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun_ref_t(_Sp (_Tp::*__p)() const) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp& __p) const + {return (__p.*__p_)();} +}; + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_ref_t + : public __binary_function<_Tp, _Ap, _Sp> +{ + _Sp (_Tp::*__p_)(_Ap) const; +public: + _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap) const) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp& __p, _Ap __x) const + {return (__p.*__p_)(__x);} +}; + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY +const_mem_fun_ref_t<_Sp,_Tp> +mem_fun_ref(_Sp (_Tp::*__f)() const) + {return const_mem_fun_ref_t<_Sp,_Tp>(__f);} + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY +const_mem_fun1_ref_t<_Sp,_Tp,_Ap> +mem_fun_ref(_Sp (_Tp::*__f)(_Ap) const) + {return const_mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);} + +#endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_MEM_FUN_REF_H diff --git a/app/src/main/cpp/libcxx/include/__functional/not_fn.h b/app/src/main/cpp/libcxx/include/__functional/not_fn.h new file mode 100644 index 0000000..79d9a87 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/not_fn.h @@ -0,0 +1,54 @@ +// -*- 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 _LIBCPP___FUNCTIONAL_NOT_FN_H +#define _LIBCPP___FUNCTIONAL_NOT_FN_H + +#include <__config> +#include <__functional/invoke.h> +#include <__functional/perfect_forward.h> +#include <__utility/forward.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +struct __not_fn_op { + template + _LIBCPP_HIDE_FROM_ABI + _LIBCPP_CONSTEXPR_SINCE_CXX20 auto operator()(_Args&&... __args) const + noexcept(noexcept(!_VSTD::invoke(_VSTD::forward<_Args>(__args)...))) + -> decltype( !_VSTD::invoke(_VSTD::forward<_Args>(__args)...)) + { return !_VSTD::invoke(_VSTD::forward<_Args>(__args)...); } +}; + +template +struct __not_fn_t : __perfect_forward<__not_fn_op, _Fn> { + using __perfect_forward<__not_fn_op, _Fn>::__perfect_forward; +}; + +template , _Fn> && + is_move_constructible_v> +>> +_LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_SINCE_CXX20 auto not_fn(_Fn&& __f) { + return __not_fn_t>(_VSTD::forward<_Fn>(__f)); +} + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_NOT_FN_H diff --git a/app/src/main/cpp/libcxx/include/__functional/operations.h b/app/src/main/cpp/libcxx/include/__functional/operations.h new file mode 100644 index 0000000..8a781ef --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/operations.h @@ -0,0 +1,580 @@ +// -*- 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 _LIBCPP___FUNCTIONAL_OPERATIONS_H +#define _LIBCPP___FUNCTIONAL_OPERATIONS_H + +#include <__config> +#include <__functional/binary_function.h> +#include <__functional/unary_function.h> +#include <__utility/forward.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Arithmetic operations + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS plus + : __binary_function<_Tp, _Tp, _Tp> +{ + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x, const _Tp& __y) const + {return __x + __y;} +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(plus); + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS plus +{ + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS minus + : __binary_function<_Tp, _Tp, _Tp> +{ + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x, const _Tp& __y) const + {return __x - __y;} +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(minus); + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS minus +{ + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS multiplies + : __binary_function<_Tp, _Tp, _Tp> +{ + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x, const _Tp& __y) const + {return __x * __y;} +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(multiplies); + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS multiplies +{ + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS divides + : __binary_function<_Tp, _Tp, _Tp> +{ + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x, const _Tp& __y) const + {return __x / __y;} +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(divides); + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS divides +{ + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS modulus + : __binary_function<_Tp, _Tp, _Tp> +{ + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x, const _Tp& __y) const + {return __x % __y;} +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(modulus); + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS modulus +{ + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS negate + : __unary_function<_Tp, _Tp> +{ + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x) const + {return -__x;} +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(negate); + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS negate +{ + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + auto operator()(_Tp&& __x) const + noexcept(noexcept(- _VSTD::forward<_Tp>(__x))) + -> decltype( - _VSTD::forward<_Tp>(__x)) + { return - _VSTD::forward<_Tp>(__x); } + typedef void is_transparent; +}; +#endif + +// Bitwise operations + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS bit_and + : __binary_function<_Tp, _Tp, _Tp> +{ + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x, const _Tp& __y) const + {return __x & __y;} +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_and); + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS bit_and +{ + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +#if _LIBCPP_STD_VER > 11 +template +struct _LIBCPP_TEMPLATE_VIS bit_not + : __unary_function<_Tp, _Tp> +{ + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x) const + {return ~__x;} +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_not); + +template <> +struct _LIBCPP_TEMPLATE_VIS bit_not +{ + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + auto operator()(_Tp&& __x) const + noexcept(noexcept(~_VSTD::forward<_Tp>(__x))) + -> decltype( ~_VSTD::forward<_Tp>(__x)) + { return ~_VSTD::forward<_Tp>(__x); } + typedef void is_transparent; +}; +#endif + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS bit_or + : __binary_function<_Tp, _Tp, _Tp> +{ + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x, const _Tp& __y) const + {return __x | __y;} +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_or); + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS bit_or +{ + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS bit_xor + : __binary_function<_Tp, _Tp, _Tp> +{ + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x, const _Tp& __y) const + {return __x ^ __y;} +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_xor); + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS bit_xor +{ + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +// Comparison operations + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS equal_to + : __binary_function<_Tp, _Tp, bool> +{ + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Tp& __x, const _Tp& __y) const + {return __x == __y;} +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(equal_to); + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS equal_to +{ + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS not_equal_to + : __binary_function<_Tp, _Tp, bool> +{ + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Tp& __x, const _Tp& __y) const + {return __x != __y;} +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(not_equal_to); + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS not_equal_to +{ + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS less + : __binary_function<_Tp, _Tp, bool> +{ + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Tp& __x, const _Tp& __y) const + {return __x < __y;} +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less); + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS less +{ + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS less_equal + : __binary_function<_Tp, _Tp, bool> +{ + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Tp& __x, const _Tp& __y) const + {return __x <= __y;} +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less_equal); + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS less_equal +{ + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS greater_equal + : __binary_function<_Tp, _Tp, bool> +{ + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Tp& __x, const _Tp& __y) const + {return __x >= __y;} +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater_equal); + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS greater_equal +{ + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS greater + : __binary_function<_Tp, _Tp, bool> +{ + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Tp& __x, const _Tp& __y) const + {return __x > __y;} +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater); + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS greater +{ + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +// Logical operations + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS logical_and + : __binary_function<_Tp, _Tp, bool> +{ + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Tp& __x, const _Tp& __y) const + {return __x && __y;} +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_and); + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS logical_and +{ + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS logical_not + : __unary_function<_Tp, bool> +{ + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Tp& __x) const + {return !__x;} +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_not); + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS logical_not +{ + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + auto operator()(_Tp&& __x) const + noexcept(noexcept(!_VSTD::forward<_Tp>(__x))) + -> decltype( !_VSTD::forward<_Tp>(__x)) + { return !_VSTD::forward<_Tp>(__x); } + typedef void is_transparent; +}; +#endif + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS logical_or + : __binary_function<_Tp, _Tp, bool> +{ + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Tp& __x, const _Tp& __y) const + {return __x || __y;} +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_or); + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS logical_or +{ + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_OPERATIONS_H diff --git a/app/src/main/cpp/libcxx/include/__functional/perfect_forward.h b/app/src/main/cpp/libcxx/include/__functional/perfect_forward.h new file mode 100644 index 0000000..9ffea1a --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/perfect_forward.h @@ -0,0 +1,94 @@ +// -*- 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 _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H +#define _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H + +#include <__config> +#include <__utility/declval.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +template +struct __perfect_forward_impl; + +template +struct __perfect_forward_impl<_Op, index_sequence<_Idx...>, _BoundArgs...> { +private: + tuple<_BoundArgs...> __bound_args_; + +public: + template , _Args&&...> + >> + explicit constexpr __perfect_forward_impl(_Args&&... __bound_args) + : __bound_args_(_VSTD::forward<_Args>(__bound_args)...) {} + + __perfect_forward_impl(__perfect_forward_impl const&) = default; + __perfect_forward_impl(__perfect_forward_impl&&) = default; + + __perfect_forward_impl& operator=(__perfect_forward_impl const&) = default; + __perfect_forward_impl& operator=(__perfect_forward_impl&&) = default; + + template >> + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) & + noexcept(noexcept(_Op()(_VSTD::get<_Idx>(__bound_args_)..., _VSTD::forward<_Args>(__args)...))) + -> decltype( _Op()(_VSTD::get<_Idx>(__bound_args_)..., _VSTD::forward<_Args>(__args)...)) + { return _Op()(_VSTD::get<_Idx>(__bound_args_)..., _VSTD::forward<_Args>(__args)...); } + + template >> + auto operator()(_Args&&...) & = delete; + + template >> + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) const& + noexcept(noexcept(_Op()(_VSTD::get<_Idx>(__bound_args_)..., _VSTD::forward<_Args>(__args)...))) + -> decltype( _Op()(_VSTD::get<_Idx>(__bound_args_)..., _VSTD::forward<_Args>(__args)...)) + { return _Op()(_VSTD::get<_Idx>(__bound_args_)..., _VSTD::forward<_Args>(__args)...); } + + template >> + auto operator()(_Args&&...) const& = delete; + + template >> + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) && + noexcept(noexcept(_Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_args_))..., _VSTD::forward<_Args>(__args)...))) + -> decltype( _Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_args_))..., _VSTD::forward<_Args>(__args)...)) + { return _Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_args_))..., _VSTD::forward<_Args>(__args)...); } + + template >> + auto operator()(_Args&&...) && = delete; + + template >> + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) const&& + noexcept(noexcept(_Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_args_))..., _VSTD::forward<_Args>(__args)...))) + -> decltype( _Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_args_))..., _VSTD::forward<_Args>(__args)...)) + { return _Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_args_))..., _VSTD::forward<_Args>(__args)...); } + + template >> + auto operator()(_Args&&...) const&& = delete; +}; + +// __perfect_forward implements a perfect-forwarding call wrapper as explained in [func.require]. +template +using __perfect_forward = __perfect_forward_impl<_Op, index_sequence_for<_Args...>, _Args...>; + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H diff --git a/app/src/main/cpp/libcxx/include/__functional/pointer_to_binary_function.h b/app/src/main/cpp/libcxx/include/__functional/pointer_to_binary_function.h new file mode 100644 index 0000000..b2676c5 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/pointer_to_binary_function.h @@ -0,0 +1,46 @@ +// -*- 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 _LIBCPP___FUNCTIONAL_POINTER_TO_BINARY_FUNCTION_H +#define _LIBCPP___FUNCTIONAL_POINTER_TO_BINARY_FUNCTION_H + +#include <__config> +#include <__functional/binary_function.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_binary_function + : public __binary_function<_Arg1, _Arg2, _Result> +{ + _Result (*__f_)(_Arg1, _Arg2); +public: + _LIBCPP_INLINE_VISIBILITY explicit pointer_to_binary_function(_Result (*__f)(_Arg1, _Arg2)) + : __f_(__f) {} + _LIBCPP_INLINE_VISIBILITY _Result operator()(_Arg1 __x, _Arg2 __y) const + {return __f_(__x, __y);} +}; + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY +pointer_to_binary_function<_Arg1,_Arg2,_Result> +ptr_fun(_Result (*__f)(_Arg1,_Arg2)) + {return pointer_to_binary_function<_Arg1,_Arg2,_Result>(__f);} + +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_POINTER_TO_BINARY_FUNCTION_H diff --git a/app/src/main/cpp/libcxx/include/__functional/pointer_to_unary_function.h b/app/src/main/cpp/libcxx/include/__functional/pointer_to_unary_function.h new file mode 100644 index 0000000..77d07ad --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/pointer_to_unary_function.h @@ -0,0 +1,46 @@ +// -*- 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 _LIBCPP___FUNCTIONAL_POINTER_TO_UNARY_FUNCTION_H +#define _LIBCPP___FUNCTIONAL_POINTER_TO_UNARY_FUNCTION_H + +#include <__config> +#include <__functional/unary_function.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_unary_function + : public __unary_function<_Arg, _Result> +{ + _Result (*__f_)(_Arg); +public: + _LIBCPP_INLINE_VISIBILITY explicit pointer_to_unary_function(_Result (*__f)(_Arg)) + : __f_(__f) {} + _LIBCPP_INLINE_VISIBILITY _Result operator()(_Arg __x) const + {return __f_(__x);} +}; + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY +pointer_to_unary_function<_Arg,_Result> +ptr_fun(_Result (*__f)(_Arg)) + {return pointer_to_unary_function<_Arg,_Result>(__f);} + +#endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_POINTER_TO_UNARY_FUNCTION_H diff --git a/app/src/main/cpp/libcxx/include/__functional/ranges_operations.h b/app/src/main/cpp/libcxx/include/__functional/ranges_operations.h new file mode 100644 index 0000000..87081dd --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/ranges_operations.h @@ -0,0 +1,100 @@ +// -*- 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 _LIBCPP___FUNCTIONAL_RANGES_OPERATIONS_H +#define _LIBCPP___FUNCTIONAL_RANGES_OPERATIONS_H + +#include <__concepts/equality_comparable.h> +#include <__concepts/totally_ordered.h> +#include <__config> +#include <__utility/forward.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace ranges { + +struct equal_to { + template + requires equality_comparable_with<_Tp, _Up> + [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const + noexcept(noexcept(bool(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u)))) { + return _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u); + } + + using is_transparent = void; +}; + +struct not_equal_to { + template + requires equality_comparable_with<_Tp, _Up> + [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const + noexcept(noexcept(bool(!(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u))))) { + return !(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u)); + } + + using is_transparent = void; +}; + +struct less { + template + requires totally_ordered_with<_Tp, _Up> + [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const + noexcept(noexcept(bool(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u)))) { + return _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u); + } + + using is_transparent = void; +}; + +struct less_equal { + template + requires totally_ordered_with<_Tp, _Up> + [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const + noexcept(noexcept(bool(!(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t))))) { + return !(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t)); + } + + using is_transparent = void; +}; + +struct greater { + template + requires totally_ordered_with<_Tp, _Up> + [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const + noexcept(noexcept(bool(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t)))) { + return _VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t); + } + + using is_transparent = void; +}; + +struct greater_equal { + template + requires totally_ordered_with<_Tp, _Up> + [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const + noexcept(noexcept(bool(!(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u))))) { + return !(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u)); + } + + using is_transparent = void; +}; + +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_RANGES_OPERATIONS_H diff --git a/app/src/main/cpp/libcxx/include/__functional/reference_wrapper.h b/app/src/main/cpp/libcxx/include/__functional/reference_wrapper.h new file mode 100644 index 0000000..c377b64 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/reference_wrapper.h @@ -0,0 +1,105 @@ +// -*- 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 _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H +#define _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H + +#include <__config> +#include <__functional/invoke.h> +#include <__functional/weak_result_type.h> +#include <__memory/addressof.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/remove_cvref.h> +#include <__utility/declval.h> +#include <__utility/forward.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS reference_wrapper : public __weak_result_type<_Tp> +{ +public: + // types + typedef _Tp type; +private: + type* __f_; + + static void __fun(_Tp&) _NOEXCEPT; + static void __fun(_Tp&&) = delete; + +public: + template ::value, decltype(__fun(std::declval<_Up>())) > > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + reference_wrapper(_Up&& __u) _NOEXCEPT_(noexcept(__fun(std::declval<_Up>()))) { + type& __f = static_cast<_Up&&>(__u); + __f_ = _VSTD::addressof(__f); + } + + // access + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + operator type&() const _NOEXCEPT {return *__f_;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + type& get() const _NOEXCEPT {return *__f_;} + + // invoke + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + typename __invoke_of::type + operator() (_ArgTypes&&... __args) const { + return std::__invoke(get(), std::forward<_ArgTypes>(__args)...); + } +}; + +#if _LIBCPP_STD_VER > 14 +template +reference_wrapper(_Tp&) -> reference_wrapper<_Tp>; +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +reference_wrapper<_Tp> +ref(_Tp& __t) _NOEXCEPT +{ + return reference_wrapper<_Tp>(__t); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +reference_wrapper<_Tp> +ref(reference_wrapper<_Tp> __t) _NOEXCEPT +{ + return __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +reference_wrapper +cref(const _Tp& __t) _NOEXCEPT +{ + return reference_wrapper(__t); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +reference_wrapper +cref(reference_wrapper<_Tp> __t) _NOEXCEPT +{ + return __t; +} + +template void ref(const _Tp&&) = delete; +template void cref(const _Tp&&) = delete; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H diff --git a/app/src/main/cpp/libcxx/include/__functional/unary_function.h b/app/src/main/cpp/libcxx/include/__functional/unary_function.h new file mode 100644 index 0000000..f07cac1 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/unary_function.h @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___FUNCTIONAL_UNARY_FUNCTION_H +#define _LIBCPP___FUNCTIONAL_UNARY_FUNCTION_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION) + +template +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 unary_function +{ + typedef _Arg argument_type; + typedef _Result result_type; +}; + +#endif // _LIBCPP_STD_VER <= 14 + +template struct __unary_function_keep_layout_base { +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using argument_type _LIBCPP_DEPRECATED_IN_CXX17 = _Arg; + using result_type _LIBCPP_DEPRECATED_IN_CXX17 = _Result; +#endif +}; + +#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION) +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-declarations") +template +using __unary_function = unary_function<_Arg, _Result>; +_LIBCPP_DIAGNOSTIC_POP +#else +template +using __unary_function = __unary_function_keep_layout_base<_Arg, _Result>; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_UNARY_FUNCTION_H diff --git a/app/src/main/cpp/libcxx/include/__functional/unary_negate.h b/app/src/main/cpp/libcxx/include/__functional/unary_negate.h new file mode 100644 index 0000000..ab87e86 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/unary_negate.h @@ -0,0 +1,47 @@ +// -*- 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 _LIBCPP___FUNCTIONAL_UNARY_NEGATE_H +#define _LIBCPP___FUNCTIONAL_UNARY_NEGATE_H + +#include <__config> +#include <__functional/unary_function.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS) + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 unary_negate + : public __unary_function +{ + _Predicate __pred_; +public: + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + explicit unary_negate(const _Predicate& __pred) + : __pred_(__pred) {} + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY + bool operator()(const typename _Predicate::argument_type& __x) const + {return !__pred_(__x);} +}; + +template +_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY +unary_negate<_Predicate> +not1(const _Predicate& __pred) {return unary_negate<_Predicate>(__pred);} + +#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_UNARY_NEGATE_H diff --git a/app/src/main/cpp/libcxx/include/__functional/unwrap_ref.h b/app/src/main/cpp/libcxx/include/__functional/unwrap_ref.h new file mode 100644 index 0000000..da000d8 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/unwrap_ref.h @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___FUNCTIONAL_UNWRAP_REF_H +#define _LIBCPP___FUNCTIONAL_UNWRAP_REF_H + +#include <__config> +#include <__type_traits/decay.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __unwrap_reference { typedef _LIBCPP_NODEBUG _Tp type; }; + +template +class reference_wrapper; + +template +struct __unwrap_reference > { typedef _LIBCPP_NODEBUG _Tp& type; }; + +template +struct decay; + +#if _LIBCPP_STD_VER > 17 +template +struct unwrap_reference : __unwrap_reference<_Tp> { }; + +template +using unwrap_reference_t = typename unwrap_reference<_Tp>::type; + +template +struct unwrap_ref_decay : unwrap_reference::type> { }; + +template +using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type; +#endif // > C++17 + +template +struct __unwrap_ref_decay +#if _LIBCPP_STD_VER > 17 + : unwrap_ref_decay<_Tp> +#else + : __unwrap_reference::type> +#endif +{ }; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_UNWRAP_REF_H diff --git a/app/src/main/cpp/libcxx/include/__functional/weak_result_type.h b/app/src/main/cpp/libcxx/include/__functional/weak_result_type.h new file mode 100644 index 0000000..18d1bf7 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__functional/weak_result_type.h @@ -0,0 +1,294 @@ +// -*- 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 _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H +#define _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H + +#include <__config> +#include <__functional/binary_function.h> +#include <__functional/invoke.h> +#include <__functional/unary_function.h> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_same.h> +#include <__utility/declval.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __has_result_type +{ +private: + template static false_type __test(...); + template static true_type __test(typename _Up::result_type* = 0); +public: + static const bool value = decltype(__test<_Tp>(0))::value; +}; + +// __weak_result_type + +template +struct __derives_from_unary_function +{ +private: + struct __two {char __lx; char __lxx;}; + static __two __test(...); + template + static __unary_function<_Ap, _Rp> + __test(const volatile __unary_function<_Ap, _Rp>*); + +public: + static const bool value = !is_same::value; + typedef decltype(__test((_Tp*)0)) type; +}; + +template +struct __derives_from_binary_function +{ +private: + struct __two {char __lx; char __lxx;}; + static __two __test(...); + template + static __binary_function<_A1, _A2, _Rp> + __test(const volatile __binary_function<_A1, _A2, _Rp>*); + +public: + static const bool value = !is_same::value; + typedef decltype(__test((_Tp*)0)) type; +}; + +template ::value> +struct __maybe_derive_from_unary_function // bool is true + : public __derives_from_unary_function<_Tp>::type +{ +}; + +template +struct __maybe_derive_from_unary_function<_Tp, false> +{ +}; + +template ::value> +struct __maybe_derive_from_binary_function // bool is true + : public __derives_from_binary_function<_Tp>::type +{ +}; + +template +struct __maybe_derive_from_binary_function<_Tp, false> +{ +}; + +template ::value> +struct __weak_result_type_imp // bool is true + : public __maybe_derive_from_unary_function<_Tp>, + public __maybe_derive_from_binary_function<_Tp> +{ +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = typename _Tp::result_type; +#endif +}; + +template +struct __weak_result_type_imp<_Tp, false> + : public __maybe_derive_from_unary_function<_Tp>, + public __maybe_derive_from_binary_function<_Tp> +{ +}; + +template +struct __weak_result_type + : public __weak_result_type_imp<_Tp> +{ +}; + +// 0 argument case + +template +struct __weak_result_type<_Rp ()> +{ +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; +#endif +}; + +template +struct __weak_result_type<_Rp (&)()> +{ +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; +#endif +}; + +template +struct __weak_result_type<_Rp (*)()> +{ +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; +#endif +}; + +// 1 argument case + +template +struct __weak_result_type<_Rp (_A1)> + : public __unary_function<_A1, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (&)(_A1)> + : public __unary_function<_A1, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (*)(_A1)> + : public __unary_function<_A1, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)()> + : public __unary_function<_Cp*, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)() const> + : public __unary_function +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)() volatile> + : public __unary_function +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)() const volatile> + : public __unary_function +{ +}; + +// 2 argument case + +template +struct __weak_result_type<_Rp (_A1, _A2)> + : public __binary_function<_A1, _A2, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (*)(_A1, _A2)> + : public __binary_function<_A1, _A2, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (&)(_A1, _A2)> + : public __binary_function<_A1, _A2, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1)> + : public __binary_function<_Cp*, _A1, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1) const> + : public __binary_function +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile> + : public __binary_function +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile> + : public __binary_function +{ +}; + +// 3 or more arguments + +template +struct __weak_result_type<_Rp (_A1, _A2, _A3, _A4...)> +{ +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; +#endif +}; + +template +struct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)> +{ +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; +#endif +}; + +template +struct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)> +{ +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; +#endif +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)> +{ +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; +#endif +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const> +{ +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; +#endif +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile> +{ +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; +#endif +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile> +{ +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; +#endif +}; + +template +struct __invoke_return +{ + typedef decltype(_VSTD::__invoke(std::declval<_Tp>(), std::declval<_Args>()...)) type; +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H diff --git a/app/src/main/cpp/libcxx/include/__fwd/array.h b/app/src/main/cpp/libcxx/include/__fwd/array.h new file mode 100644 index 0000000..9a79eff --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__fwd/array.h @@ -0,0 +1,26 @@ +//===---------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +#ifndef _LIBCPP___FWD_ARRAY_H +#define _LIBCPP___FWD_ARRAY_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_TEMPLATE_VIS array; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FWD_ARRAY_H diff --git a/app/src/main/cpp/libcxx/include/__fwd/get.h b/app/src/main/cpp/libcxx/include/__fwd/get.h new file mode 100644 index 0000000..ec1fab4 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__fwd/get.h @@ -0,0 +1,115 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___FWD_GET_H +#define _LIBCPP___FWD_GET_H + +#include <__concepts/copyable.h> +#include <__config> +#include <__fwd/array.h> +#include <__fwd/pair.h> +#include <__fwd/subrange.h> +#include <__fwd/tuple.h> +#include <__tuple_dir/tuple_element.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#ifndef _LIBCPP_CXX03_LANG + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +typename tuple_element<_Ip, tuple<_Tp...> >::type& +get(tuple<_Tp...>&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +const typename tuple_element<_Ip, tuple<_Tp...> >::type& +get(const tuple<_Tp...>&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +typename tuple_element<_Ip, tuple<_Tp...> >::type&& +get(tuple<_Tp...>&&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +const typename tuple_element<_Ip, tuple<_Tp...> >::type&& +get(const tuple<_Tp...>&&) _NOEXCEPT; + +#endif //_LIBCPP_CXX03_LANG + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +typename tuple_element<_Ip, pair<_T1, _T2> >::type& +get(pair<_T1, _T2>&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +const typename tuple_element<_Ip, pair<_T1, _T2> >::type& +get(const pair<_T1, _T2>&) _NOEXCEPT; + +#ifndef _LIBCPP_CXX03_LANG +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +typename tuple_element<_Ip, pair<_T1, _T2> >::type&& +get(pair<_T1, _T2>&&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +const typename tuple_element<_Ip, pair<_T1, _T2> >::type&& +get(const pair<_T1, _T2>&&) _NOEXCEPT; +#endif + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +_Tp& +get(array<_Tp, _Size>&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +const _Tp& +get(const array<_Tp, _Size>&) _NOEXCEPT; + +#ifndef _LIBCPP_CXX03_LANG +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +_Tp&& +get(array<_Tp, _Size>&&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +const _Tp&& +get(const array<_Tp, _Size>&&) _NOEXCEPT; +#endif + +#if _LIBCPP_STD_VER >= 20 + +namespace ranges { + +template + requires((_Index == 0 && copyable<_Iter>) || _Index == 1) +_LIBCPP_HIDE_FROM_ABI constexpr auto get(const subrange<_Iter, _Sent, _Kind>& __subrange); + +template + requires(_Index < 2) +_LIBCPP_HIDE_FROM_ABI constexpr auto get(subrange<_Iter, _Sent, _Kind>&& __subrange); + +} // namespace ranges + +using ranges::get; + +#endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FWD_GET_H diff --git a/app/src/main/cpp/libcxx/include/__fwd/hash.h b/app/src/main/cpp/libcxx/include/__fwd/hash.h new file mode 100644 index 0000000..af9eca8 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__fwd/hash.h @@ -0,0 +1,25 @@ +//===---------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +#ifndef _LIBCPP___FWD_HASH_H +#define _LIBCPP___FWD_HASH_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_TEMPLATE_VIS hash; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FWD_HASH_H diff --git a/app/src/main/cpp/libcxx/include/__fwd/memory_resource.h b/app/src/main/cpp/libcxx/include/__fwd/memory_resource.h new file mode 100644 index 0000000..718a907 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__fwd/memory_resource.h @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___FWD_MEMORY_RESOURCE_H +#define _LIBCPP___FWD_MEMORY_RESOURCE_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace pmr { +template +class _LIBCPP_TEMPLATE_VIS polymorphic_allocator; +} // namespace pmr + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FWD_MEMORY_RESOURCE_H diff --git a/app/src/main/cpp/libcxx/include/__fwd/pair.h b/app/src/main/cpp/libcxx/include/__fwd/pair.h new file mode 100644 index 0000000..3844014 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__fwd/pair.h @@ -0,0 +1,25 @@ +//===---------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +#ifndef _LIBCPP___FWD_PAIR_H +#define _LIBCPP___FWD_PAIR_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_TEMPLATE_VIS pair; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FWD_PAIR_H diff --git a/app/src/main/cpp/libcxx/include/__fwd/span.h b/app/src/main/cpp/libcxx/include/__fwd/span.h new file mode 100644 index 0000000..943cb13 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__fwd/span.h @@ -0,0 +1,37 @@ +// -*- 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 _LIBCPP___FWD_SPAN_H +#define _LIBCPP___FWD_SPAN_H + +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +inline constexpr size_t dynamic_extent = numeric_limits::max(); +template class span; + +#endif + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___FWD_SPAN_H diff --git a/app/src/main/cpp/libcxx/include/__fwd/string.h b/app/src/main/cpp/libcxx/include/__fwd/string.h new file mode 100644 index 0000000..7ab5561 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__fwd/string.h @@ -0,0 +1,110 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___FWD_STRING_H +#define _LIBCPP___FWD_STRING_H + +#include <__config> +#include <__fwd/memory_resource.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_TEMPLATE_VIS char_traits; +template <> +struct char_traits; + +#ifndef _LIBCPP_HAS_NO_CHAR8_T +template <> +struct char_traits; +#endif + +template <> +struct char_traits; +template <> +struct char_traits; + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template <> +struct char_traits; +#endif + +template +class _LIBCPP_TEMPLATE_VIS allocator; + +template , class _Allocator = allocator<_CharT> > +class _LIBCPP_TEMPLATE_VIS basic_string; + +using string = basic_string; + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +using wstring = basic_string; +#endif + +#ifndef _LIBCPP_HAS_NO_CHAR8_T +using u8string = basic_string; +#endif + +using u16string = basic_string; +using u32string = basic_string; + +#if _LIBCPP_STD_VER >= 17 + +namespace pmr { +template > +using basic_string = std::basic_string<_CharT, _Traits, polymorphic_allocator<_CharT>>; + +using string = basic_string; + +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +using wstring = basic_string; +# endif + +# ifndef _LIBCPP_HAS_NO_CHAR8_T +using u8string = basic_string; +# endif + +using u16string = basic_string; +using u32string = basic_string; + +} // namespace pmr + +#endif // _LIBCPP_STD_VER >= 17 + +// clang-format off +template +class _LIBCPP_PREFERRED_NAME(string) +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS + _LIBCPP_PREFERRED_NAME(wstring) +#endif +#ifndef _LIBCPP_HAS_NO_CHAR8_T + _LIBCPP_PREFERRED_NAME(u8string) +#endif + _LIBCPP_PREFERRED_NAME(u16string) + _LIBCPP_PREFERRED_NAME(u32string) +#if _LIBCPP_STD_VER >= 17 + _LIBCPP_PREFERRED_NAME(pmr::string) +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS + _LIBCPP_PREFERRED_NAME(pmr::wstring) +# endif +# ifndef _LIBCPP_HAS_NO_CHAR8_T + _LIBCPP_PREFERRED_NAME(pmr::u8string) +# endif + _LIBCPP_PREFERRED_NAME(pmr::u16string) + _LIBCPP_PREFERRED_NAME(pmr::u32string) +#endif + basic_string; +// clang-format on + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FWD_STRING_H diff --git a/app/src/main/cpp/libcxx/include/__fwd/string_view.h b/app/src/main/cpp/libcxx/include/__fwd/string_view.h new file mode 100644 index 0000000..4818990 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__fwd/string_view.h @@ -0,0 +1,50 @@ +// -*- 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 _LIBCPP___FWD_STRING_VIEW_H +#define _LIBCPP___FWD_STRING_VIEW_H + +#include <__config> +#include // char_traits + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template > +class _LIBCPP_TEMPLATE_VIS basic_string_view; + +typedef basic_string_view string_view; +#ifndef _LIBCPP_HAS_NO_CHAR8_T +typedef basic_string_view u8string_view; +#endif +typedef basic_string_view u16string_view; +typedef basic_string_view u32string_view; +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +typedef basic_string_view wstring_view; +#endif + +// clang-format off +template +class _LIBCPP_PREFERRED_NAME(string_view) +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS + _LIBCPP_PREFERRED_NAME(wstring_view) +#endif +#ifndef _LIBCPP_HAS_NO_CHAR8_T + _LIBCPP_PREFERRED_NAME(u8string_view) +#endif + _LIBCPP_PREFERRED_NAME(u16string_view) + _LIBCPP_PREFERRED_NAME(u32string_view) + basic_string_view; +// clang-format on +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FWD_STRING_VIEW_H diff --git a/app/src/main/cpp/libcxx/include/__fwd/subrange.h b/app/src/main/cpp/libcxx/include/__fwd/subrange.h new file mode 100644 index 0000000..8f72392 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__fwd/subrange.h @@ -0,0 +1,38 @@ +//===---------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +#ifndef _LIBCPP___FWD_SUBRANGE_H +#define _LIBCPP___FWD_SUBRANGE_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER >= 20 + +#include <__iterator/concepts.h> + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +enum class _LIBCPP_ENUM_VIS subrange_kind : bool { unsized, sized }; + +template _Sent, subrange_kind _Kind> + requires(_Kind == subrange_kind::sized || !sized_sentinel_for<_Sent, _Iter>) +class _LIBCPP_TEMPLATE_VIS subrange; + +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 20 + +#endif // _LIBCPP___FWD_SUBRANGE_H diff --git a/app/src/main/cpp/libcxx/include/__fwd/tuple.h b/app/src/main/cpp/libcxx/include/__fwd/tuple.h new file mode 100644 index 0000000..16b3fab --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__fwd/tuple.h @@ -0,0 +1,29 @@ +//===---------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +#ifndef _LIBCPP___FWD_TUPLE_H +#define _LIBCPP___FWD_TUPLE_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#ifndef _LIBCPP_CXX03_LANG + +template +class _LIBCPP_TEMPLATE_VIS tuple; + +#endif // _LIBCPP_CXX03_LANG + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FWD_TUPLE_H diff --git a/app/src/main/cpp/libcxx/include/__hash_table b/app/src/main/cpp/libcxx/include/__hash_table new file mode 100644 index 0000000..f8896c8 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__hash_table @@ -0,0 +1,2715 @@ +// -*- 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 _LIBCPP___HASH_TABLE +#define _LIBCPP___HASH_TABLE + +#include <__algorithm/max.h> +#include <__algorithm/min.h> +#include <__assert> +#include <__bit/countl.h> +#include <__config> +#include <__debug> +#include <__functional/hash.h> +#include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> +#include <__memory/allocator_traits.h> +#include <__memory/compressed_pair.h> +#include <__memory/pointer_traits.h> +#include <__memory/swap_allocator.h> +#include <__memory/unique_ptr.h> +#include <__type_traits/can_extract_key.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/pair.h> +#include <__utility/swap.h> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __hash_value_type; + +template +struct __is_hash_value_type_imp : false_type {}; + +template +struct __is_hash_value_type_imp<__hash_value_type<_Key, _Value> > : true_type {}; + +template +struct __is_hash_value_type : false_type {}; + +template +struct __is_hash_value_type<_One> : __is_hash_value_type_imp<__remove_cvref_t<_One> > {}; + +_LIBCPP_FUNC_VIS +size_t __next_prime(size_t __n); + +template +struct __hash_node_base +{ + typedef typename pointer_traits<_NodePtr>::element_type __node_type; + typedef __hash_node_base __first_node; + typedef __rebind_pointer_t<_NodePtr, __first_node> __node_base_pointer; + typedef _NodePtr __node_pointer; + +#if defined(_LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB) + typedef __node_base_pointer __next_pointer; +#else + typedef __conditional_t::value, __node_base_pointer, __node_pointer> __next_pointer; +#endif + + __next_pointer __next_; + + _LIBCPP_INLINE_VISIBILITY + __next_pointer __ptr() _NOEXCEPT { + return static_cast<__next_pointer>( + pointer_traits<__node_base_pointer>::pointer_to(*this)); + } + + _LIBCPP_INLINE_VISIBILITY + __node_pointer __upcast() _NOEXCEPT { + return static_cast<__node_pointer>( + pointer_traits<__node_base_pointer>::pointer_to(*this)); + } + + _LIBCPP_INLINE_VISIBILITY + size_t __hash() const _NOEXCEPT { + return static_cast<__node_type const&>(*this).__hash_; + } + + _LIBCPP_INLINE_VISIBILITY __hash_node_base() _NOEXCEPT : __next_(nullptr) {} +}; + +template +struct _LIBCPP_STANDALONE_DEBUG __hash_node + : public __hash_node_base + < + __rebind_pointer_t<_VoidPtr, __hash_node<_Tp, _VoidPtr> > + > +{ + typedef _Tp __node_value_type; + + size_t __hash_; + __node_value_type __value_; +}; + +inline _LIBCPP_INLINE_VISIBILITY +bool +__is_hash_power2(size_t __bc) +{ + return __bc > 2 && !(__bc & (__bc - 1)); +} + +inline _LIBCPP_INLINE_VISIBILITY +size_t +__constrain_hash(size_t __h, size_t __bc) +{ + return !(__bc & (__bc - 1)) ? __h & (__bc - 1) : + (__h < __bc ? __h : __h % __bc); +} + +inline _LIBCPP_INLINE_VISIBILITY +size_t +__next_hash_pow2(size_t __n) +{ + return __n < 2 ? __n : (size_t(1) << (numeric_limits::digits - __libcpp_clz(__n-1))); +} + + +template class __hash_table; + +template class _LIBCPP_TEMPLATE_VIS __hash_iterator; +template class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; +template class _LIBCPP_TEMPLATE_VIS __hash_local_iterator; +template class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; +template class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; +template class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; + +template +struct __hash_key_value_types { + static_assert(!is_reference<_Tp>::value && !is_const<_Tp>::value, ""); + typedef _Tp key_type; + typedef _Tp __node_value_type; + typedef _Tp __container_value_type; + static const bool __is_map = false; + + _LIBCPP_INLINE_VISIBILITY + static key_type const& __get_key(_Tp const& __v) { + return __v; + } + _LIBCPP_INLINE_VISIBILITY + static __container_value_type const& __get_value(__node_value_type const& __v) { + return __v; + } + _LIBCPP_INLINE_VISIBILITY + static __container_value_type* __get_ptr(__node_value_type& __n) { + return _VSTD::addressof(__n); + } + _LIBCPP_INLINE_VISIBILITY + static __container_value_type&& __move(__node_value_type& __v) { + return _VSTD::move(__v); + } +}; + +template +struct __hash_key_value_types<__hash_value_type<_Key, _Tp> > { + typedef _Key key_type; + typedef _Tp mapped_type; + typedef __hash_value_type<_Key, _Tp> __node_value_type; + typedef pair __container_value_type; + typedef __container_value_type __map_value_type; + static const bool __is_map = true; + + _LIBCPP_INLINE_VISIBILITY + static key_type const& __get_key(__container_value_type const& __v) { + return __v.first; + } + + template + _LIBCPP_INLINE_VISIBILITY + static __enable_if_t<__is_same_uncvref<_Up, __node_value_type>::value, __container_value_type const&> + __get_value(_Up& __t) { + return __t.__get_value(); + } + + template + _LIBCPP_INLINE_VISIBILITY + static __enable_if_t<__is_same_uncvref<_Up, __container_value_type>::value, __container_value_type const&> + __get_value(_Up& __t) { + return __t; + } + + _LIBCPP_INLINE_VISIBILITY + static __container_value_type* __get_ptr(__node_value_type& __n) { + return _VSTD::addressof(__n.__get_value()); + } + _LIBCPP_INLINE_VISIBILITY + static pair __move(__node_value_type& __v) { + return __v.__move(); + } +}; + +template , + bool = _KVTypes::__is_map> +struct __hash_map_pointer_types {}; + +template +struct __hash_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> { + typedef typename _KVTypes::__map_value_type _Mv; + typedef __rebind_pointer_t<_AllocPtr, _Mv> + __map_value_type_pointer; + typedef __rebind_pointer_t<_AllocPtr, const _Mv> + __const_map_value_type_pointer; +}; + +template ::element_type> +struct __hash_node_types; + +template +struct __hash_node_types<_NodePtr, __hash_node<_Tp, _VoidPtr> > + : public __hash_key_value_types<_Tp>, __hash_map_pointer_types<_Tp, _VoidPtr> + +{ + typedef __hash_key_value_types<_Tp> __base; + +public: + typedef ptrdiff_t difference_type; + typedef size_t size_type; + + typedef __rebind_pointer_t<_NodePtr, void> __void_pointer; + + typedef typename pointer_traits<_NodePtr>::element_type __node_type; + typedef _NodePtr __node_pointer; + + typedef __hash_node_base<__node_pointer> __node_base_type; + typedef __rebind_pointer_t<_NodePtr, __node_base_type> + __node_base_pointer; + + typedef typename __node_base_type::__next_pointer __next_pointer; + + typedef _Tp __node_value_type; + typedef __rebind_pointer_t<_VoidPtr, __node_value_type> + __node_value_type_pointer; + typedef __rebind_pointer_t<_VoidPtr, const __node_value_type> + __const_node_value_type_pointer; + +private: + static_assert(!is_const<__node_type>::value, + "_NodePtr should never be a pointer to const"); + static_assert((is_same::element_type, void>::value), + "_VoidPtr does not point to unqualified void type"); + static_assert((is_same<__rebind_pointer_t<_VoidPtr, __node_type>, + _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr."); +}; + +template +struct __hash_node_types_from_iterator; +template +struct __hash_node_types_from_iterator<__hash_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; +template +struct __hash_node_types_from_iterator<__hash_const_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; +template +struct __hash_node_types_from_iterator<__hash_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; +template +struct __hash_node_types_from_iterator<__hash_const_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; + + +template +struct __make_hash_node_types { + typedef __hash_node<_NodeValueTp, _VoidPtr> _NodeTp; + typedef __rebind_pointer_t<_VoidPtr, _NodeTp> _NodePtr; + typedef __hash_node_types<_NodePtr> type; +}; + +template +class _LIBCPP_TEMPLATE_VIS __hash_iterator +{ + typedef __hash_node_types<_NodePtr> _NodeTypes; + typedef _NodePtr __node_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; + + __next_pointer __node_; + +public: + typedef forward_iterator_tag iterator_category; + typedef typename _NodeTypes::__node_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; + typedef value_type& reference; + typedef typename _NodeTypes::__node_value_type_pointer pointer; + + _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT : __node_(nullptr) { + _VSTD::__debug_db_insert_i(this); + } + +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + _LIBCPP_INLINE_VISIBILITY + __hash_iterator(const __hash_iterator& __i) + : __node_(__i.__node_) + { + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); + } + + _LIBCPP_INLINE_VISIBILITY + ~__hash_iterator() + { + __get_db()->__erase_i(this); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_iterator& operator=(const __hash_iterator& __i) + { + if (this != _VSTD::addressof(__i)) + { + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); + __node_ = __i.__node_; + } + return *this; + } +#endif // _LIBCPP_ENABLE_DEBUG_MODE + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container iterator"); + return __node_->__upcast()->__value_; + } + + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container iterator"); + return pointer_traits::pointer_to(__node_->__upcast()->__value_); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_iterator& operator++() { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment a non-incrementable unordered container iterator"); + __node_ = __node_->__next_; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __hash_iterator operator++(int) + { + __hash_iterator __t(*this); + ++(*this); + return __t; + } + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __hash_iterator& __x, const __hash_iterator& __y) + { + return __x.__node_ == __y.__node_; + } + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __hash_iterator& __x, const __hash_iterator& __y) + {return !(__x == __y);} + +private: + _LIBCPP_INLINE_VISIBILITY + explicit __hash_iterator(__next_pointer __node, const void* __c) _NOEXCEPT + : __node_(__node) + { + (void)__c; +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + __get_db()->__insert_ic(this, __c); +#endif + } + template friend class __hash_table; + template friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; + template friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; + template friend class _LIBCPP_TEMPLATE_VIS unordered_map; + template friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; +}; + +template +class _LIBCPP_TEMPLATE_VIS __hash_const_iterator +{ + static_assert(!is_const::element_type>::value, ""); + typedef __hash_node_types<_NodePtr> _NodeTypes; + typedef _NodePtr __node_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; + + __next_pointer __node_; + +public: + typedef __hash_iterator<_NodePtr> __non_const_iterator; + + typedef forward_iterator_tag iterator_category; + typedef typename _NodeTypes::__node_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; + typedef const value_type& reference; + typedef typename _NodeTypes::__const_node_value_type_pointer pointer; + + + _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT : __node_(nullptr) { + _VSTD::__debug_db_insert_i(this); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT + : __node_(__x.__node_) + { +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); +#endif + } + +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + _LIBCPP_INLINE_VISIBILITY + __hash_const_iterator(const __hash_const_iterator& __i) + : __node_(__i.__node_) + { + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); + } + + _LIBCPP_INLINE_VISIBILITY + ~__hash_const_iterator() + { + __get_db()->__erase_i(this); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_const_iterator& operator=(const __hash_const_iterator& __i) + { + if (this != _VSTD::addressof(__i)) + { + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); + __node_ = __i.__node_; + } + return *this; + } +#endif // _LIBCPP_ENABLE_DEBUG_MODE + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container const_iterator"); + return __node_->__upcast()->__value_; + } + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container const_iterator"); + return pointer_traits::pointer_to(__node_->__upcast()->__value_); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_const_iterator& operator++() { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment a non-incrementable unordered container const_iterator"); + __node_ = __node_->__next_; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __hash_const_iterator operator++(int) + { + __hash_const_iterator __t(*this); + ++(*this); + return __t; + } + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __hash_const_iterator& __x, const __hash_const_iterator& __y) + { + return __x.__node_ == __y.__node_; + } + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __hash_const_iterator& __x, const __hash_const_iterator& __y) + {return !(__x == __y);} + +private: + _LIBCPP_INLINE_VISIBILITY + explicit __hash_const_iterator(__next_pointer __node, const void* __c) _NOEXCEPT + : __node_(__node) + { + (void)__c; +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + __get_db()->__insert_ic(this, __c); +#endif + } + template friend class __hash_table; + template friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; + template friend class _LIBCPP_TEMPLATE_VIS unordered_map; + template friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; +}; + +template +class _LIBCPP_TEMPLATE_VIS __hash_local_iterator +{ + typedef __hash_node_types<_NodePtr> _NodeTypes; + typedef _NodePtr __node_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; + + __next_pointer __node_; + size_t __bucket_; + size_t __bucket_count_; + +public: + typedef forward_iterator_tag iterator_category; + typedef typename _NodeTypes::__node_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; + typedef value_type& reference; + typedef typename _NodeTypes::__node_value_type_pointer pointer; + + _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT : __node_(nullptr) { + _VSTD::__debug_db_insert_i(this); + } + +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + _LIBCPP_INLINE_VISIBILITY + __hash_local_iterator(const __hash_local_iterator& __i) + : __node_(__i.__node_), + __bucket_(__i.__bucket_), + __bucket_count_(__i.__bucket_count_) + { + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); + } + + _LIBCPP_INLINE_VISIBILITY + ~__hash_local_iterator() + { + __get_db()->__erase_i(this); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_local_iterator& operator=(const __hash_local_iterator& __i) + { + if (this != _VSTD::addressof(__i)) + { + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); + __node_ = __i.__node_; + __bucket_ = __i.__bucket_; + __bucket_count_ = __i.__bucket_count_; + } + return *this; + } +#endif // _LIBCPP_ENABLE_DEBUG_MODE + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container local_iterator"); + return __node_->__upcast()->__value_; + } + + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container local_iterator"); + return pointer_traits::pointer_to(__node_->__upcast()->__value_); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_local_iterator& operator++() { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment a non-incrementable unordered container local_iterator"); + __node_ = __node_->__next_; + if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) + __node_ = nullptr; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __hash_local_iterator operator++(int) + { + __hash_local_iterator __t(*this); + ++(*this); + return __t; + } + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __hash_local_iterator& __x, const __hash_local_iterator& __y) + { + return __x.__node_ == __y.__node_; + } + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __hash_local_iterator& __x, const __hash_local_iterator& __y) + {return !(__x == __y);} + +private: + _LIBCPP_INLINE_VISIBILITY + explicit __hash_local_iterator(__next_pointer __node, size_t __bucket, + size_t __bucket_count, const void* __c) _NOEXCEPT + : __node_(__node), + __bucket_(__bucket), + __bucket_count_(__bucket_count) + { + (void)__c; +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + __get_db()->__insert_ic(this, __c); +#endif + if (__node_ != nullptr) + __node_ = __node_->__next_; + } + template friend class __hash_table; + template friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; + template friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; +}; + +template +class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator +{ + typedef __hash_node_types<_ConstNodePtr> _NodeTypes; + typedef _ConstNodePtr __node_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; + + __next_pointer __node_; + size_t __bucket_; + size_t __bucket_count_; + + typedef pointer_traits<__node_pointer> __pointer_traits; + typedef typename __pointer_traits::element_type __node; + typedef __remove_const_t<__node> __non_const_node; + typedef __rebind_pointer_t<__node_pointer, __non_const_node> + __non_const_node_pointer; +public: + typedef __hash_local_iterator<__non_const_node_pointer> + __non_const_iterator; + + typedef forward_iterator_tag iterator_category; + typedef typename _NodeTypes::__node_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; + typedef const value_type& reference; + typedef typename _NodeTypes::__const_node_value_type_pointer pointer; + + + _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT : __node_(nullptr) { + _VSTD::__debug_db_insert_i(this); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_const_local_iterator(const __non_const_iterator& __x) _NOEXCEPT + : __node_(__x.__node_), + __bucket_(__x.__bucket_), + __bucket_count_(__x.__bucket_count_) + { +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); +#endif + } + +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + _LIBCPP_INLINE_VISIBILITY + __hash_const_local_iterator(const __hash_const_local_iterator& __i) + : __node_(__i.__node_), + __bucket_(__i.__bucket_), + __bucket_count_(__i.__bucket_count_) + { + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); + } + + _LIBCPP_INLINE_VISIBILITY + ~__hash_const_local_iterator() + { + __get_db()->__erase_i(this); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_const_local_iterator& operator=(const __hash_const_local_iterator& __i) + { + if (this != _VSTD::addressof(__i)) + { + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); + __node_ = __i.__node_; + __bucket_ = __i.__bucket_; + __bucket_count_ = __i.__bucket_count_; + } + return *this; + } +#endif // _LIBCPP_ENABLE_DEBUG_MODE + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container const_local_iterator"); + return __node_->__upcast()->__value_; + } + + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container const_local_iterator"); + return pointer_traits::pointer_to(__node_->__upcast()->__value_); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_const_local_iterator& operator++() { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment a non-incrementable unordered container const_local_iterator"); + __node_ = __node_->__next_; + if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) + __node_ = nullptr; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __hash_const_local_iterator operator++(int) + { + __hash_const_local_iterator __t(*this); + ++(*this); + return __t; + } + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y) + { + return __x.__node_ == __y.__node_; + } + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y) + {return !(__x == __y);} + +private: + _LIBCPP_INLINE_VISIBILITY + explicit __hash_const_local_iterator(__next_pointer __node_ptr, size_t __bucket, + size_t __bucket_count, const void* __c) _NOEXCEPT + : __node_(__node_ptr), + __bucket_(__bucket), + __bucket_count_(__bucket_count) + { + (void)__c; +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + __get_db()->__insert_ic(this, __c); +#endif + if (__node_ != nullptr) + __node_ = __node_->__next_; + } + template friend class __hash_table; + template friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; +}; + +template +class __bucket_list_deallocator +{ + typedef _Alloc allocator_type; + typedef allocator_traits __alloc_traits; + typedef typename __alloc_traits::size_type size_type; + + __compressed_pair __data_; +public: + typedef typename __alloc_traits::pointer pointer; + + _LIBCPP_INLINE_VISIBILITY + __bucket_list_deallocator() + _NOEXCEPT_(is_nothrow_default_constructible::value) + : __data_(0, __default_init_tag()) {} + + _LIBCPP_INLINE_VISIBILITY + __bucket_list_deallocator(const allocator_type& __a, size_type __size) + _NOEXCEPT_(is_nothrow_copy_constructible::value) + : __data_(__size, __a) {} + + _LIBCPP_INLINE_VISIBILITY + __bucket_list_deallocator(__bucket_list_deallocator&& __x) + _NOEXCEPT_(is_nothrow_move_constructible::value) + : __data_(_VSTD::move(__x.__data_)) + { + __x.size() = 0; + } + + _LIBCPP_INLINE_VISIBILITY + size_type& size() _NOEXCEPT {return __data_.first();} + _LIBCPP_INLINE_VISIBILITY + size_type size() const _NOEXCEPT {return __data_.first();} + + _LIBCPP_INLINE_VISIBILITY + allocator_type& __alloc() _NOEXCEPT {return __data_.second();} + _LIBCPP_INLINE_VISIBILITY + const allocator_type& __alloc() const _NOEXCEPT {return __data_.second();} + + _LIBCPP_INLINE_VISIBILITY + void operator()(pointer __p) _NOEXCEPT + { + __alloc_traits::deallocate(__alloc(), __p, size()); + } +}; + +template class __hash_map_node_destructor; + +template +class __hash_node_destructor +{ + typedef _Alloc allocator_type; + typedef allocator_traits __alloc_traits; + +public: + typedef typename __alloc_traits::pointer pointer; +private: + typedef __hash_node_types _NodeTypes; + + allocator_type& __na_; + +public: + bool __value_constructed; + + __hash_node_destructor(__hash_node_destructor const&) = default; + __hash_node_destructor& operator=(const __hash_node_destructor&) = delete; + + + _LIBCPP_INLINE_VISIBILITY + explicit __hash_node_destructor(allocator_type& __na, + bool __constructed = false) _NOEXCEPT + : __na_(__na), + __value_constructed(__constructed) + {} + + _LIBCPP_INLINE_VISIBILITY + void operator()(pointer __p) _NOEXCEPT + { + if (__value_constructed) + __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_)); + if (__p) + __alloc_traits::deallocate(__na_, __p, 1); + } + + template friend class __hash_map_node_destructor; +}; + +#if _LIBCPP_STD_VER > 14 +template +struct __generic_container_node_destructor; + +template +struct __generic_container_node_destructor<__hash_node<_Tp, _VoidPtr>, _Alloc> + : __hash_node_destructor<_Alloc> +{ + using __hash_node_destructor<_Alloc>::__hash_node_destructor; +}; +#endif + +template +struct __enforce_unordered_container_requirements { +#ifndef _LIBCPP_CXX03_LANG + static_assert(__check_hash_requirements<_Key, _Hash>::value, + "the specified hash does not meet the Hash requirements"); + static_assert(is_copy_constructible<_Equal>::value, + "the specified comparator is required to be copy constructible"); +#endif + typedef int type; +}; + +template +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Equal const&, _Key const&, _Key const&>::value, + "the specified comparator type does not provide a viable const call operator") + _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Hash const&, _Key const&>::value, + "the specified hash functor does not provide a viable const call operator") +#endif +typename __enforce_unordered_container_requirements<_Key, _Hash, _Equal>::type +__diagnose_unordered_container_requirements(int); + +// This dummy overload is used so that the compiler won't emit a spurious +// "no matching function for call to __diagnose_unordered_xxx" diagnostic +// when the overload above causes a hard error. +template +int __diagnose_unordered_container_requirements(void*); + +template +class __hash_table +{ +public: + typedef _Tp value_type; + typedef _Hash hasher; + typedef _Equal key_equal; + typedef _Alloc allocator_type; + +private: + typedef allocator_traits __alloc_traits; + typedef typename + __make_hash_node_types::type + _NodeTypes; +public: + + typedef typename _NodeTypes::__node_value_type __node_value_type; + typedef typename _NodeTypes::__container_value_type __container_value_type; + typedef typename _NodeTypes::key_type key_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename __alloc_traits::pointer pointer; + typedef typename __alloc_traits::const_pointer const_pointer; +#ifndef _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE + typedef typename __alloc_traits::size_type size_type; +#else + typedef typename _NodeTypes::size_type size_type; +#endif + typedef typename _NodeTypes::difference_type difference_type; +public: + // Create __node + + typedef typename _NodeTypes::__node_type __node; + typedef __rebind_alloc<__alloc_traits, __node> __node_allocator; + typedef allocator_traits<__node_allocator> __node_traits; + typedef typename _NodeTypes::__void_pointer __void_pointer; + typedef typename _NodeTypes::__node_pointer __node_pointer; + typedef typename _NodeTypes::__node_pointer __node_const_pointer; + typedef typename _NodeTypes::__node_base_type __first_node; + typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; + +private: + // check for sane allocator pointer rebinding semantics. Rebinding the + // allocator for a new pointer type should be exactly the same as rebinding + // the pointer using 'pointer_traits'. + static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value), + "Allocator does not rebind pointers in a sane manner."); + typedef __rebind_alloc<__node_traits, __first_node> __node_base_allocator; + typedef allocator_traits<__node_base_allocator> __node_base_traits; + static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value), + "Allocator does not rebind pointers in a sane manner."); + +private: + + typedef __rebind_alloc<__node_traits, __next_pointer> __pointer_allocator; + typedef __bucket_list_deallocator<__pointer_allocator> __bucket_list_deleter; + typedef unique_ptr<__next_pointer[], __bucket_list_deleter> __bucket_list; + typedef allocator_traits<__pointer_allocator> __pointer_alloc_traits; + typedef typename __bucket_list_deleter::pointer __node_pointer_pointer; + + // --- Member data begin --- + __bucket_list __bucket_list_; + __compressed_pair<__first_node, __node_allocator> __p1_; + __compressed_pair __p2_; + __compressed_pair __p3_; + // --- Member data end --- + + _LIBCPP_INLINE_VISIBILITY + size_type& size() _NOEXCEPT {return __p2_.first();} +public: + _LIBCPP_INLINE_VISIBILITY + size_type size() const _NOEXCEPT {return __p2_.first();} + + _LIBCPP_INLINE_VISIBILITY + hasher& hash_function() _NOEXCEPT {return __p2_.second();} + _LIBCPP_INLINE_VISIBILITY + const hasher& hash_function() const _NOEXCEPT {return __p2_.second();} + + _LIBCPP_INLINE_VISIBILITY + float& max_load_factor() _NOEXCEPT {return __p3_.first();} + _LIBCPP_INLINE_VISIBILITY + float max_load_factor() const _NOEXCEPT {return __p3_.first();} + + _LIBCPP_INLINE_VISIBILITY + key_equal& key_eq() _NOEXCEPT {return __p3_.second();} + _LIBCPP_INLINE_VISIBILITY + const key_equal& key_eq() const _NOEXCEPT {return __p3_.second();} + + _LIBCPP_INLINE_VISIBILITY + __node_allocator& __node_alloc() _NOEXCEPT {return __p1_.second();} + _LIBCPP_INLINE_VISIBILITY + const __node_allocator& __node_alloc() const _NOEXCEPT + {return __p1_.second();} + +public: + typedef __hash_iterator<__node_pointer> iterator; + typedef __hash_const_iterator<__node_pointer> const_iterator; + typedef __hash_local_iterator<__node_pointer> local_iterator; + typedef __hash_const_local_iterator<__node_pointer> const_local_iterator; + + _LIBCPP_INLINE_VISIBILITY + __hash_table() + _NOEXCEPT_( + is_nothrow_default_constructible<__bucket_list>::value && + is_nothrow_default_constructible<__first_node>::value && + is_nothrow_default_constructible<__node_allocator>::value && + is_nothrow_default_constructible::value && + is_nothrow_default_constructible::value); + _LIBCPP_INLINE_VISIBILITY + __hash_table(const hasher& __hf, const key_equal& __eql); + __hash_table(const hasher& __hf, const key_equal& __eql, + const allocator_type& __a); + explicit __hash_table(const allocator_type& __a); + __hash_table(const __hash_table& __u); + __hash_table(const __hash_table& __u, const allocator_type& __a); + __hash_table(__hash_table&& __u) + _NOEXCEPT_( + is_nothrow_move_constructible<__bucket_list>::value && + is_nothrow_move_constructible<__first_node>::value && + is_nothrow_move_constructible<__node_allocator>::value && + is_nothrow_move_constructible::value && + is_nothrow_move_constructible::value); + __hash_table(__hash_table&& __u, const allocator_type& __a); + ~__hash_table(); + + __hash_table& operator=(const __hash_table& __u); + _LIBCPP_INLINE_VISIBILITY + __hash_table& operator=(__hash_table&& __u) + _NOEXCEPT_( + __node_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable<__node_allocator>::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable::value); + template + void __assign_unique(_InputIterator __first, _InputIterator __last); + template + void __assign_multi(_InputIterator __first, _InputIterator __last); + + _LIBCPP_INLINE_VISIBILITY + size_type max_size() const _NOEXCEPT + { + return _VSTD::min( + __node_traits::max_size(__node_alloc()), + numeric_limits::max() + ); + } + +private: + _LIBCPP_INLINE_VISIBILITY + __next_pointer __node_insert_multi_prepare(size_t __cp_hash, + value_type& __cp_val); + _LIBCPP_INLINE_VISIBILITY + void __node_insert_multi_perform(__node_pointer __cp, + __next_pointer __pn) _NOEXCEPT; + + _LIBCPP_INLINE_VISIBILITY + __next_pointer __node_insert_unique_prepare(size_t __nd_hash, + value_type& __nd_val); + _LIBCPP_INLINE_VISIBILITY + void __node_insert_unique_perform(__node_pointer __ptr) _NOEXCEPT; + +public: + _LIBCPP_INLINE_VISIBILITY + pair __node_insert_unique(__node_pointer __nd); + _LIBCPP_INLINE_VISIBILITY + iterator __node_insert_multi(__node_pointer __nd); + _LIBCPP_INLINE_VISIBILITY + iterator __node_insert_multi(const_iterator __p, + __node_pointer __nd); + + template + _LIBCPP_INLINE_VISIBILITY + pair __emplace_unique_key_args(_Key const& __k, _Args&&... __args); + + template + _LIBCPP_INLINE_VISIBILITY + pair __emplace_unique_impl(_Args&&... __args); + + template + _LIBCPP_INLINE_VISIBILITY + pair __emplace_unique(_Pp&& __x) { + return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x), + __can_extract_key<_Pp, key_type>()); + } + + template + _LIBCPP_INLINE_VISIBILITY + __enable_if_t<__can_extract_map_key<_First, key_type, __container_value_type>::value, pair > + __emplace_unique(_First&& __f, _Second&& __s) { + return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f), + _VSTD::forward<_Second>(__s)); + } + + template + _LIBCPP_INLINE_VISIBILITY + pair __emplace_unique(_Args&&... __args) { + return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...); + } + + template + _LIBCPP_INLINE_VISIBILITY + pair + __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) { + return __emplace_unique_impl(_VSTD::forward<_Pp>(__x)); + } + template + _LIBCPP_INLINE_VISIBILITY + pair + __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) { + return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x)); + } + template + _LIBCPP_INLINE_VISIBILITY + pair + __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) { + return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x)); + } + + template + _LIBCPP_INLINE_VISIBILITY + iterator __emplace_multi(_Args&&... __args); + template + _LIBCPP_INLINE_VISIBILITY + iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); + + + _LIBCPP_INLINE_VISIBILITY + pair + __insert_unique(__container_value_type&& __x) { + return __emplace_unique_key_args(_NodeTypes::__get_key(__x), _VSTD::move(__x)); + } + + template ::value> > + _LIBCPP_INLINE_VISIBILITY + pair __insert_unique(_Pp&& __x) { + return __emplace_unique(_VSTD::forward<_Pp>(__x)); + } + + template + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(_Pp&& __x) { + return __emplace_multi(_VSTD::forward<_Pp>(__x)); + } + + template + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(const_iterator __p, _Pp&& __x) { + return __emplace_hint_multi(__p, _VSTD::forward<_Pp>(__x)); + } + + _LIBCPP_INLINE_VISIBILITY + pair __insert_unique(const __container_value_type& __x) { + return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x); + } + +#if _LIBCPP_STD_VER > 14 + template + _LIBCPP_INLINE_VISIBILITY + _InsertReturnType __node_handle_insert_unique(_NodeHandle&& __nh); + template + _LIBCPP_INLINE_VISIBILITY + iterator __node_handle_insert_unique(const_iterator __hint, + _NodeHandle&& __nh); + template + _LIBCPP_INLINE_VISIBILITY + void __node_handle_merge_unique(_Table& __source); + + template + _LIBCPP_INLINE_VISIBILITY + iterator __node_handle_insert_multi(_NodeHandle&& __nh); + template + _LIBCPP_INLINE_VISIBILITY + iterator __node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh); + template + _LIBCPP_INLINE_VISIBILITY + void __node_handle_merge_multi(_Table& __source); + + template + _LIBCPP_INLINE_VISIBILITY + _NodeHandle __node_handle_extract(key_type const& __key); + template + _LIBCPP_INLINE_VISIBILITY + _NodeHandle __node_handle_extract(const_iterator __it); +#endif + + void clear() _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY void __rehash_unique(size_type __n) { __rehash(__n); } + _LIBCPP_INLINE_VISIBILITY void __rehash_multi(size_type __n) { __rehash(__n); } + _LIBCPP_INLINE_VISIBILITY void __reserve_unique(size_type __n) + { + __rehash_unique(static_cast(std::ceil(__n / max_load_factor()))); + } + _LIBCPP_INLINE_VISIBILITY void __reserve_multi(size_type __n) + { + __rehash_multi(static_cast(std::ceil(__n / max_load_factor()))); + } + + _LIBCPP_INLINE_VISIBILITY + size_type bucket_count() const _NOEXCEPT + { + return __bucket_list_.get_deleter().size(); + } + + _LIBCPP_INLINE_VISIBILITY + iterator begin() _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + iterator end() _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + const_iterator begin() const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + const_iterator end() const _NOEXCEPT; + + template + _LIBCPP_INLINE_VISIBILITY + size_type bucket(const _Key& __k) const + { + _LIBCPP_ASSERT(bucket_count() > 0, + "unordered container::bucket(key) called when bucket_count() == 0"); + return std::__constrain_hash(hash_function()(__k), bucket_count()); + } + + template + iterator find(const _Key& __x); + template + const_iterator find(const _Key& __x) const; + + typedef __hash_node_destructor<__node_allocator> _Dp; + typedef unique_ptr<__node, _Dp> __node_holder; + + iterator erase(const_iterator __p); + iterator erase(const_iterator __first, const_iterator __last); + template + size_type __erase_unique(const _Key& __k); + template + size_type __erase_multi(const _Key& __k); + __node_holder remove(const_iterator __p) _NOEXCEPT; + + template + _LIBCPP_INLINE_VISIBILITY + size_type __count_unique(const _Key& __k) const; + template + size_type __count_multi(const _Key& __k) const; + + template + pair + __equal_range_unique(const _Key& __k); + template + pair + __equal_range_unique(const _Key& __k) const; + + template + pair + __equal_range_multi(const _Key& __k); + template + pair + __equal_range_multi(const _Key& __k) const; + + void swap(__hash_table& __u) +#if _LIBCPP_STD_VER <= 11 + _NOEXCEPT_( + __is_nothrow_swappable::value && __is_nothrow_swappable::value + && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value + || __is_nothrow_swappable<__pointer_allocator>::value) + && (!__node_traits::propagate_on_container_swap::value + || __is_nothrow_swappable<__node_allocator>::value) + ); +#else + _NOEXCEPT_(__is_nothrow_swappable::value && __is_nothrow_swappable::value); +#endif + + _LIBCPP_INLINE_VISIBILITY + size_type max_bucket_count() const _NOEXCEPT + {return max_size(); } + size_type bucket_size(size_type __n) const; + _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT + { + size_type __bc = bucket_count(); + return __bc != 0 ? (float)size() / __bc : 0.f; + } + _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) _NOEXCEPT + { + _LIBCPP_ASSERT(__mlf > 0, + "unordered container::max_load_factor(lf) called with lf <= 0"); + max_load_factor() = _VSTD::max(__mlf, load_factor()); + } + + _LIBCPP_INLINE_VISIBILITY + local_iterator + begin(size_type __n) + { + _LIBCPP_ASSERT(__n < bucket_count(), + "unordered container::begin(n) called with n >= bucket_count()"); + return local_iterator(__bucket_list_[__n], __n, bucket_count(), this); + } + + _LIBCPP_INLINE_VISIBILITY + local_iterator + end(size_type __n) + { + _LIBCPP_ASSERT(__n < bucket_count(), + "unordered container::end(n) called with n >= bucket_count()"); + return local_iterator(nullptr, __n, bucket_count(), this); + } + + _LIBCPP_INLINE_VISIBILITY + const_local_iterator + cbegin(size_type __n) const + { + _LIBCPP_ASSERT(__n < bucket_count(), + "unordered container::cbegin(n) called with n >= bucket_count()"); + return const_local_iterator(__bucket_list_[__n], __n, bucket_count(), this); + } + + _LIBCPP_INLINE_VISIBILITY + const_local_iterator + cend(size_type __n) const + { + _LIBCPP_ASSERT(__n < bucket_count(), + "unordered container::cend(n) called with n >= bucket_count()"); + return const_local_iterator(nullptr, __n, bucket_count(), this); + } + +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + + bool __dereferenceable(const const_iterator* __i) const; + bool __decrementable(const const_iterator* __i) const; + bool __addable(const const_iterator* __i, ptrdiff_t __n) const; + bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const; + +#endif // _LIBCPP_ENABLE_DEBUG_MODE + +private: + template void __rehash(size_type __n); + template void __do_rehash(size_type __n); + + template + __node_holder __construct_node(_Args&& ...__args); + + template + __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest); + + + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const __hash_table& __u) + {__copy_assign_alloc(__u, integral_constant());} + void __copy_assign_alloc(const __hash_table& __u, true_type); + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const __hash_table&, false_type) {} + + void __move_assign(__hash_table& __u, false_type); + void __move_assign(__hash_table& __u, true_type) + _NOEXCEPT_( + is_nothrow_move_assignable<__node_allocator>::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable::value); + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__hash_table& __u) + _NOEXCEPT_( + !__node_traits::propagate_on_container_move_assignment::value || + (is_nothrow_move_assignable<__pointer_allocator>::value && + is_nothrow_move_assignable<__node_allocator>::value)) + {__move_assign_alloc(__u, integral_constant());} + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__hash_table& __u, true_type) + _NOEXCEPT_( + is_nothrow_move_assignable<__pointer_allocator>::value && + is_nothrow_move_assignable<__node_allocator>::value) + { + __bucket_list_.get_deleter().__alloc() = + _VSTD::move(__u.__bucket_list_.get_deleter().__alloc()); + __node_alloc() = _VSTD::move(__u.__node_alloc()); + } + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {} + + void __deallocate_node(__next_pointer __np) _NOEXCEPT; + __next_pointer __detach() _NOEXCEPT; + + template friend class _LIBCPP_TEMPLATE_VIS unordered_map; + template friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; +}; + +template +inline +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table() + _NOEXCEPT_( + is_nothrow_default_constructible<__bucket_list>::value && + is_nothrow_default_constructible<__first_node>::value && + is_nothrow_default_constructible<__node_allocator>::value && + is_nothrow_default_constructible::value && + is_nothrow_default_constructible::value) + : __p2_(0, __default_init_tag()), + __p3_(1.0f, __default_init_tag()) +{ +} + +template +inline +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf, + const key_equal& __eql) + : __bucket_list_(nullptr, __bucket_list_deleter()), + __p1_(), + __p2_(0, __hf), + __p3_(1.0f, __eql) +{ +} + +template +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf, + const key_equal& __eql, + const allocator_type& __a) + : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), + __p1_(__default_init_tag(), __node_allocator(__a)), + __p2_(0, __hf), + __p3_(1.0f, __eql) +{ +} + +template +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const allocator_type& __a) + : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), + __p1_(__default_init_tag(), __node_allocator(__a)), + __p2_(0, __default_init_tag()), + __p3_(1.0f, __default_init_tag()) +{ +} + +template +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u) + : __bucket_list_(nullptr, + __bucket_list_deleter(allocator_traits<__pointer_allocator>:: + select_on_container_copy_construction( + __u.__bucket_list_.get_deleter().__alloc()), 0)), + __p1_(__default_init_tag(), allocator_traits<__node_allocator>:: + select_on_container_copy_construction(__u.__node_alloc())), + __p2_(0, __u.hash_function()), + __p3_(__u.__p3_) +{ +} + +template +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u, + const allocator_type& __a) + : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), + __p1_(__default_init_tag(), __node_allocator(__a)), + __p2_(0, __u.hash_function()), + __p3_(__u.__p3_) +{ +} + +template +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u) + _NOEXCEPT_( + is_nothrow_move_constructible<__bucket_list>::value && + is_nothrow_move_constructible<__first_node>::value && + is_nothrow_move_constructible<__node_allocator>::value && + is_nothrow_move_constructible::value && + is_nothrow_move_constructible::value) + : __bucket_list_(_VSTD::move(__u.__bucket_list_)), + __p1_(_VSTD::move(__u.__p1_)), + __p2_(_VSTD::move(__u.__p2_)), + __p3_(_VSTD::move(__u.__p3_)) +{ + if (size() > 0) + { + __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = + __p1_.first().__ptr(); + __u.__p1_.first().__next_ = nullptr; + __u.size() = 0; + } +} + +template +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u, + const allocator_type& __a) + : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), + __p1_(__default_init_tag(), __node_allocator(__a)), + __p2_(0, _VSTD::move(__u.hash_function())), + __p3_(_VSTD::move(__u.__p3_)) +{ + if (__a == allocator_type(__u.__node_alloc())) + { + __bucket_list_.reset(__u.__bucket_list_.release()); + __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size(); + __u.__bucket_list_.get_deleter().size() = 0; + if (__u.size() > 0) + { + __p1_.first().__next_ = __u.__p1_.first().__next_; + __u.__p1_.first().__next_ = nullptr; + __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = + __p1_.first().__ptr(); + size() = __u.size(); + __u.size() = 0; + } + } +} + +template +__hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table() +{ +#if defined(_LIBCPP_CXX03_LANG) + static_assert((is_copy_constructible::value), + "Predicate must be copy-constructible."); + static_assert((is_copy_constructible::value), + "Hasher must be copy-constructible."); +#endif + + __deallocate_node(__p1_.first().__next_); + std::__debug_db_erase_c(this); +} + +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__copy_assign_alloc( + const __hash_table& __u, true_type) +{ + if (__node_alloc() != __u.__node_alloc()) + { + clear(); + __bucket_list_.reset(); + __bucket_list_.get_deleter().size() = 0; + } + __bucket_list_.get_deleter().__alloc() = __u.__bucket_list_.get_deleter().__alloc(); + __node_alloc() = __u.__node_alloc(); +} + +template +__hash_table<_Tp, _Hash, _Equal, _Alloc>& +__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __u) +{ + if (this != _VSTD::addressof(__u)) + { + __copy_assign_alloc(__u); + hash_function() = __u.hash_function(); + key_eq() = __u.key_eq(); + max_load_factor() = __u.max_load_factor(); + __assign_multi(__u.begin(), __u.end()); + } + return *this; +} + +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer __np) + _NOEXCEPT +{ + __node_allocator& __na = __node_alloc(); + while (__np != nullptr) + { + __next_pointer __next = __np->__next_; +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + __c_node* __c = __get_db()->__find_c_and_lock(this); + for (__i_node** __p = __c->end_; __p != __c->beg_; ) + { + --__p; + iterator* __i = static_cast((*__p)->__i_); + if (__i->__node_ == __np) + { + (*__p)->__c_ = nullptr; + if (--__c->end_ != __p) + _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + } + } + __get_db()->unlock(); +#endif + __node_pointer __real_np = __np->__upcast(); + __node_traits::destroy(__na, _NodeTypes::__get_ptr(__real_np->__value_)); + __node_traits::deallocate(__na, __real_np, 1); + __np = __next; + } +} + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT +{ + size_type __bc = bucket_count(); + for (size_type __i = 0; __i < __bc; ++__i) + __bucket_list_[__i] = nullptr; + size() = 0; + __next_pointer __cache = __p1_.first().__next_; + __p1_.first().__next_ = nullptr; + return __cache; +} + +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( + __hash_table& __u, true_type) + _NOEXCEPT_( + is_nothrow_move_assignable<__node_allocator>::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable::value) +{ + clear(); + __bucket_list_.reset(__u.__bucket_list_.release()); + __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size(); + __u.__bucket_list_.get_deleter().size() = 0; + __move_assign_alloc(__u); + size() = __u.size(); + hash_function() = _VSTD::move(__u.hash_function()); + max_load_factor() = __u.max_load_factor(); + key_eq() = _VSTD::move(__u.key_eq()); + __p1_.first().__next_ = __u.__p1_.first().__next_; + if (size() > 0) + { + __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = + __p1_.first().__ptr(); + __u.__p1_.first().__next_ = nullptr; + __u.size() = 0; + } + std::__debug_db_swap(this, std::addressof(__u)); +} + +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( + __hash_table& __u, false_type) +{ + if (__node_alloc() == __u.__node_alloc()) + __move_assign(__u, true_type()); + else + { + hash_function() = _VSTD::move(__u.hash_function()); + key_eq() = _VSTD::move(__u.key_eq()); + max_load_factor() = __u.max_load_factor(); + if (bucket_count() != 0) + { + __next_pointer __cache = __detach(); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + const_iterator __i = __u.begin(); + while (__cache != nullptr && __u.size() != 0) + { + __cache->__upcast()->__value_ = + _VSTD::move(__u.remove(__i++)->__value_); + __next_pointer __next = __cache->__next_; + __node_insert_multi(__cache->__upcast()); + __cache = __next; + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __deallocate_node(__cache); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + __deallocate_node(__cache); + } + const_iterator __i = __u.begin(); + while (__u.size() != 0) + { + __node_holder __h = __construct_node(_NodeTypes::__move(__u.remove(__i++)->__value_)); + __node_insert_multi(__h.get()); + __h.release(); + } + } +} + +template +inline +__hash_table<_Tp, _Hash, _Equal, _Alloc>& +__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u) + _NOEXCEPT_( + __node_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable<__node_allocator>::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable::value) +{ + __move_assign(__u, integral_constant()); + return *this; +} + +template +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first, + _InputIterator __last) +{ + typedef iterator_traits<_InputIterator> _ITraits; + typedef typename _ITraits::value_type _ItValueType; + static_assert((is_same<_ItValueType, __container_value_type>::value), + "__assign_unique may only be called with the containers value type"); + + if (bucket_count() != 0) + { + __next_pointer __cache = __detach(); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + for (; __cache != nullptr && __first != __last; ++__first) + { + __cache->__upcast()->__value_ = *__first; + __next_pointer __next = __cache->__next_; + __node_insert_unique(__cache->__upcast()); + __cache = __next; + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __deallocate_node(__cache); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + __deallocate_node(__cache); + } + for (; __first != __last; ++__first) + __insert_unique(*__first); +} + +template +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first, + _InputIterator __last) +{ + typedef iterator_traits<_InputIterator> _ITraits; + typedef typename _ITraits::value_type _ItValueType; + static_assert((is_same<_ItValueType, __container_value_type>::value || + is_same<_ItValueType, __node_value_type>::value), + "__assign_multi may only be called with the containers value type" + " or the nodes value type"); + if (bucket_count() != 0) + { + __next_pointer __cache = __detach(); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + for (; __cache != nullptr && __first != __last; ++__first) + { + __cache->__upcast()->__value_ = *__first; + __next_pointer __next = __cache->__next_; + __node_insert_multi(__cache->__upcast()); + __cache = __next; + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __deallocate_node(__cache); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + __deallocate_node(__cache); + } + for (; __first != __last; ++__first) + __insert_multi(_NodeTypes::__get_value(*__first)); +} + +template +inline +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT +{ + return iterator(__p1_.first().__next_, this); +} + +template +inline +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT +{ + return iterator(nullptr, this); +} + +template +inline +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT +{ + return const_iterator(__p1_.first().__next_, this); +} + +template +inline +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT +{ + return const_iterator(nullptr, this); +} + +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT +{ + if (size() > 0) + { + __deallocate_node(__p1_.first().__next_); + __p1_.first().__next_ = nullptr; + size_type __bc = bucket_count(); + for (size_type __i = 0; __i < __bc; ++__i) + __bucket_list_[__i] = nullptr; + size() = 0; + } +} + + +// Prepare the container for an insertion of the value __value with the hash +// __hash. This does a lookup into the container to see if __value is already +// present, and performs a rehash if necessary. Returns a pointer to the +// existing element if it exists, otherwise nullptr. +// +// Note that this function does forward exceptions if key_eq() throws, and never +// mutates __value or actually inserts into the map. +template +_LIBCPP_INLINE_VISIBILITY +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare( + size_t __hash, value_type& __value) +{ + size_type __bc = bucket_count(); + + if (__bc != 0) + { + size_t __chash = std::__constrain_hash(__hash, __bc); + __next_pointer __ndptr = __bucket_list_[__chash]; + if (__ndptr != nullptr) + { + for (__ndptr = __ndptr->__next_; __ndptr != nullptr && + std::__constrain_hash(__ndptr->__hash(), __bc) == __chash; + __ndptr = __ndptr->__next_) + { + if (key_eq()(__ndptr->__upcast()->__value_, __value)) + return __ndptr; + } + } + } + if (size()+1 > __bc * max_load_factor() || __bc == 0) + { + __rehash_unique(_VSTD::max(2 * __bc + !std::__is_hash_power2(__bc), + size_type(std::ceil(float(size() + 1) / max_load_factor())))); + } + return nullptr; +} + +// Insert the node __nd into the container by pushing it into the right bucket, +// and updating size(). Assumes that __nd->__hash is up-to-date, and that +// rehashing has already occurred and that no element with the same key exists +// in the map. +template +_LIBCPP_INLINE_VISIBILITY +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_perform( + __node_pointer __nd) _NOEXCEPT +{ + size_type __bc = bucket_count(); + size_t __chash = std::__constrain_hash(__nd->__hash(), __bc); + // insert_after __bucket_list_[__chash], or __first_node if bucket is null + __next_pointer __pn = __bucket_list_[__chash]; + if (__pn == nullptr) + { + __pn =__p1_.first().__ptr(); + __nd->__next_ = __pn->__next_; + __pn->__next_ = __nd->__ptr(); + // fix up __bucket_list_ + __bucket_list_[__chash] = __pn; + if (__nd->__next_ != nullptr) + __bucket_list_[std::__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr(); + } + else + { + __nd->__next_ = __pn->__next_; + __pn->__next_ = __nd->__ptr(); + } + ++size(); +} + +template +pair::iterator, bool> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __nd) +{ + __nd->__hash_ = hash_function()(__nd->__value_); + __next_pointer __existing_node = + __node_insert_unique_prepare(__nd->__hash(), __nd->__value_); + + // Insert the node, unless it already exists in the container. + bool __inserted = false; + if (__existing_node == nullptr) + { + __node_insert_unique_perform(__nd); + __existing_node = __nd->__ptr(); + __inserted = true; + } + return pair(iterator(__existing_node, this), __inserted); +} + +// Prepare the container for an insertion of the value __cp_val with the hash +// __cp_hash. This does a lookup into the container to see if __cp_value is +// already present, and performs a rehash if necessary. Returns a pointer to the +// last occurrence of __cp_val in the map. +// +// Note that this function does forward exceptions if key_eq() throws, and never +// mutates __value or actually inserts into the map. +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_prepare( + size_t __cp_hash, value_type& __cp_val) +{ + size_type __bc = bucket_count(); + if (size()+1 > __bc * max_load_factor() || __bc == 0) + { + __rehash_multi(_VSTD::max(2 * __bc + !std::__is_hash_power2(__bc), + size_type(std::ceil(float(size() + 1) / max_load_factor())))); + __bc = bucket_count(); + } + size_t __chash = std::__constrain_hash(__cp_hash, __bc); + __next_pointer __pn = __bucket_list_[__chash]; + if (__pn != nullptr) + { + for (bool __found = false; __pn->__next_ != nullptr && + std::__constrain_hash(__pn->__next_->__hash(), __bc) == __chash; + __pn = __pn->__next_) + { + // __found key_eq() action + // false false loop + // true true loop + // false true set __found to true + // true false break + if (__found != (__pn->__next_->__hash() == __cp_hash && + key_eq()(__pn->__next_->__upcast()->__value_, __cp_val))) + { + if (!__found) + __found = true; + else + break; + } + } + } + return __pn; +} + +// Insert the node __cp into the container after __pn (which is the last node in +// the bucket that compares equal to __cp). Rehashing, and checking for +// uniqueness has already been performed (in __node_insert_multi_prepare), so +// all we need to do is update the bucket and size(). Assumes that __cp->__hash +// is up-to-date. +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_perform( + __node_pointer __cp, __next_pointer __pn) _NOEXCEPT +{ + size_type __bc = bucket_count(); + size_t __chash = std::__constrain_hash(__cp->__hash_, __bc); + if (__pn == nullptr) + { + __pn =__p1_.first().__ptr(); + __cp->__next_ = __pn->__next_; + __pn->__next_ = __cp->__ptr(); + // fix up __bucket_list_ + __bucket_list_[__chash] = __pn; + if (__cp->__next_ != nullptr) + __bucket_list_[std::__constrain_hash(__cp->__next_->__hash(), __bc)] + = __cp->__ptr(); + } + else + { + __cp->__next_ = __pn->__next_; + __pn->__next_ = __cp->__ptr(); + if (__cp->__next_ != nullptr) + { + size_t __nhash = std::__constrain_hash(__cp->__next_->__hash(), __bc); + if (__nhash != __chash) + __bucket_list_[__nhash] = __cp->__ptr(); + } + } + ++size(); +} + + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp) +{ + __cp->__hash_ = hash_function()(__cp->__value_); + __next_pointer __pn = __node_insert_multi_prepare(__cp->__hash(), __cp->__value_); + __node_insert_multi_perform(__cp, __pn); + + return iterator(__cp->__ptr(), this); +} + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi( + const_iterator __p, __node_pointer __cp) +{ + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" + " referring to this unordered container"); + if (__p != end() && key_eq()(*__p, __cp->__value_)) + { + __next_pointer __np = __p.__node_; + __cp->__hash_ = __np->__hash(); + size_type __bc = bucket_count(); + if (size()+1 > __bc * max_load_factor() || __bc == 0) + { + __rehash_multi(_VSTD::max(2 * __bc + !std::__is_hash_power2(__bc), + size_type(std::ceil(float(size() + 1) / max_load_factor())))); + __bc = bucket_count(); + } + size_t __chash = std::__constrain_hash(__cp->__hash_, __bc); + __next_pointer __pp = __bucket_list_[__chash]; + while (__pp->__next_ != __np) + __pp = __pp->__next_; + __cp->__next_ = __np; + __pp->__next_ = static_cast<__next_pointer>(__cp); + ++size(); + return iterator(static_cast<__next_pointer>(__cp), this); + } + return __node_insert_multi(__cp); +} + + + +template +template +pair::iterator, bool> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args) +{ + + size_t __hash = hash_function()(__k); + size_type __bc = bucket_count(); + bool __inserted = false; + __next_pointer __nd; + size_t __chash; + if (__bc != 0) + { + __chash = std::__constrain_hash(__hash, __bc); + __nd = __bucket_list_[__chash]; + if (__nd != nullptr) + { + for (__nd = __nd->__next_; __nd != nullptr && + (__nd->__hash() == __hash || std::__constrain_hash(__nd->__hash(), __bc) == __chash); + __nd = __nd->__next_) + { + if (key_eq()(__nd->__upcast()->__value_, __k)) + goto __done; + } + } + } + { + __node_holder __h = __construct_node_hash(__hash, _VSTD::forward<_Args>(__args)...); + if (size()+1 > __bc * max_load_factor() || __bc == 0) + { + __rehash_unique(_VSTD::max(2 * __bc + !std::__is_hash_power2(__bc), + size_type(std::ceil(float(size() + 1) / max_load_factor())))); + __bc = bucket_count(); + __chash = std::__constrain_hash(__hash, __bc); + } + // insert_after __bucket_list_[__chash], or __first_node if bucket is null + __next_pointer __pn = __bucket_list_[__chash]; + if (__pn == nullptr) + { + __pn = __p1_.first().__ptr(); + __h->__next_ = __pn->__next_; + __pn->__next_ = __h.get()->__ptr(); + // fix up __bucket_list_ + __bucket_list_[__chash] = __pn; + if (__h->__next_ != nullptr) + __bucket_list_[std::__constrain_hash(__h->__next_->__hash(), __bc)] + = __h.get()->__ptr(); + } + else + { + __h->__next_ = __pn->__next_; + __pn->__next_ = static_cast<__next_pointer>(__h.get()); + } + __nd = static_cast<__next_pointer>(__h.release()); + // increment size + ++size(); + __inserted = true; + } +__done: + return pair(iterator(__nd, this), __inserted); +} + +template +template +pair::iterator, bool> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_impl(_Args&&... __args) +{ + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); + pair __r = __node_insert_unique(__h.get()); + if (__r.second) + __h.release(); + return __r; +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_multi(_Args&&... __args) +{ + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); + iterator __r = __node_insert_multi(__h.get()); + __h.release(); + return __r; +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi( + const_iterator __p, _Args&&... __args) +{ + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" + " referring to this unordered container"); + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); + iterator __r = __node_insert_multi(__p, __h.get()); + __h.release(); + return __r; +} + +#if _LIBCPP_STD_VER > 14 +template +template +_LIBCPP_INLINE_VISIBILITY +_InsertReturnType +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique( + _NodeHandle&& __nh) +{ + if (__nh.empty()) + return _InsertReturnType{end(), false, _NodeHandle()}; + pair __result = __node_insert_unique(__nh.__ptr_); + if (__result.second) + __nh.__release_ptr(); + return _InsertReturnType{__result.first, __result.second, _VSTD::move(__nh)}; +} + +template +template +_LIBCPP_INLINE_VISIBILITY +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique( + const_iterator, _NodeHandle&& __nh) +{ + if (__nh.empty()) + return end(); + pair __result = __node_insert_unique(__nh.__ptr_); + if (__result.second) + __nh.__release_ptr(); + return __result.first; +} + +template +template +_LIBCPP_INLINE_VISIBILITY +_NodeHandle +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract( + key_type const& __key) +{ + iterator __i = find(__key); + if (__i == end()) + return _NodeHandle(); + return __node_handle_extract<_NodeHandle>(__i); +} + +template +template +_LIBCPP_INLINE_VISIBILITY +_NodeHandle +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract( + const_iterator __p) +{ + allocator_type __alloc(__node_alloc()); + return _NodeHandle(remove(__p).release(), __alloc); +} + +template +template +_LIBCPP_INLINE_VISIBILITY +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_unique( + _Table& __source) +{ + static_assert(is_same<__node, typename _Table::__node>::value, ""); + + for (typename _Table::iterator __it = __source.begin(); + __it != __source.end();) + { + __node_pointer __src_ptr = __it.__node_->__upcast(); + size_t __hash = hash_function()(__src_ptr->__value_); + __next_pointer __existing_node = + __node_insert_unique_prepare(__hash, __src_ptr->__value_); + auto __prev_iter = __it++; + if (__existing_node == nullptr) + { + (void)__source.remove(__prev_iter).release(); + __src_ptr->__hash_ = __hash; + __node_insert_unique_perform(__src_ptr); + } + } +} + +template +template +_LIBCPP_INLINE_VISIBILITY +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi( + _NodeHandle&& __nh) +{ + if (__nh.empty()) + return end(); + iterator __result = __node_insert_multi(__nh.__ptr_); + __nh.__release_ptr(); + return __result; +} + +template +template +_LIBCPP_INLINE_VISIBILITY +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi( + const_iterator __hint, _NodeHandle&& __nh) +{ + if (__nh.empty()) + return end(); + iterator __result = __node_insert_multi(__hint, __nh.__ptr_); + __nh.__release_ptr(); + return __result; +} + +template +template +_LIBCPP_INLINE_VISIBILITY +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi( + _Table& __source) +{ + static_assert(is_same::value, ""); + + for (typename _Table::iterator __it = __source.begin(); + __it != __source.end();) + { + __node_pointer __src_ptr = __it.__node_->__upcast(); + size_t __src_hash = hash_function()(__src_ptr->__value_); + __next_pointer __pn = + __node_insert_multi_prepare(__src_hash, __src_ptr->__value_); + (void)__source.remove(__it++).release(); + __src_ptr->__hash_ = __src_hash; + __node_insert_multi_perform(__src_ptr, __pn); + } +} +#endif // _LIBCPP_STD_VER > 14 + +template +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __n) +_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK +{ + if (__n == 1) + __n = 2; + else if (__n & (__n - 1)) + __n = std::__next_prime(__n); + size_type __bc = bucket_count(); + if (__n > __bc) + __do_rehash<_UniqueKeys>(__n); + else if (__n < __bc) + { + __n = _VSTD::max + ( + __n, + std::__is_hash_power2(__bc) ? std::__next_hash_pow2(size_t(std::ceil(float(size()) / max_load_factor()))) : + std::__next_prime(size_t(std::ceil(float(size()) / max_load_factor()))) + ); + if (__n < __bc) + __do_rehash<_UniqueKeys>(__n); + } +} + +template +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__do_rehash(size_type __nbc) +{ + std::__debug_db_invalidate_all(this); + __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc(); + __bucket_list_.reset(__nbc > 0 ? + __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr); + __bucket_list_.get_deleter().size() = __nbc; + if (__nbc > 0) + { + for (size_type __i = 0; __i < __nbc; ++__i) + __bucket_list_[__i] = nullptr; + __next_pointer __pp = __p1_.first().__ptr(); + __next_pointer __cp = __pp->__next_; + if (__cp != nullptr) + { + size_type __chash = std::__constrain_hash(__cp->__hash(), __nbc); + __bucket_list_[__chash] = __pp; + size_type __phash = __chash; + for (__pp = __cp, void(), __cp = __cp->__next_; __cp != nullptr; + __cp = __pp->__next_) + { + __chash = std::__constrain_hash(__cp->__hash(), __nbc); + if (__chash == __phash) + __pp = __cp; + else + { + if (__bucket_list_[__chash] == nullptr) + { + __bucket_list_[__chash] = __pp; + __pp = __cp; + __phash = __chash; + } + else + { + __next_pointer __np = __cp; + if _LIBCPP_CONSTEXPR_SINCE_CXX17 (!_UniqueKeys) + { + for (; __np->__next_ != nullptr && + key_eq()(__cp->__upcast()->__value_, + __np->__next_->__upcast()->__value_); + __np = __np->__next_) + ; + } + __pp->__next_ = __np->__next_; + __np->__next_ = __bucket_list_[__chash]->__next_; + __bucket_list_[__chash]->__next_ = __cp; + + } + } + } + } + } +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) +{ + size_t __hash = hash_function()(__k); + size_type __bc = bucket_count(); + if (__bc != 0) + { + size_t __chash = std::__constrain_hash(__hash, __bc); + __next_pointer __nd = __bucket_list_[__chash]; + if (__nd != nullptr) + { + for (__nd = __nd->__next_; __nd != nullptr && + (__nd->__hash() == __hash + || std::__constrain_hash(__nd->__hash(), __bc) == __chash); + __nd = __nd->__next_) + { + if ((__nd->__hash() == __hash) + && key_eq()(__nd->__upcast()->__value_, __k)) + return iterator(__nd, this); + } + } + } + return end(); +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const +{ + size_t __hash = hash_function()(__k); + size_type __bc = bucket_count(); + if (__bc != 0) + { + size_t __chash = std::__constrain_hash(__hash, __bc); + __next_pointer __nd = __bucket_list_[__chash]; + if (__nd != nullptr) + { + for (__nd = __nd->__next_; __nd != nullptr && + (__hash == __nd->__hash() + || std::__constrain_hash(__nd->__hash(), __bc) == __chash); + __nd = __nd->__next_) + { + if ((__nd->__hash() == __hash) + && key_eq()(__nd->__upcast()->__value_, __k)) + return const_iterator(__nd, this); + } + } + + } + return end(); +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&& ...__args) +{ + static_assert(!__is_hash_value_type<_Args...>::value, + "Construct cannot be called with a hash value type"); + __node_allocator& __na = __node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...); + __h.get_deleter().__value_constructed = true; + __h->__hash_ = hash_function()(__h->__value_); + __h->__next_ = nullptr; + return __h; +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash( + size_t __hash, _First&& __f, _Rest&& ...__rest) +{ + static_assert(!__is_hash_value_type<_First, _Rest...>::value, + "Construct cannot be called with a hash value type"); + __node_allocator& __na = __node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), + _VSTD::forward<_First>(__f), + _VSTD::forward<_Rest>(__rest)...); + __h.get_deleter().__value_constructed = true; + __h->__hash_ = __hash; + __h->__next_ = nullptr; + return __h; +} + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p) +{ + __next_pointer __np = __p.__node_; + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "unordered container erase(iterator) called with an iterator not" + " referring to this container"); + _LIBCPP_ASSERT(__p != end(), + "unordered container erase(iterator) called with a non-dereferenceable iterator"); + iterator __r(__np, this); + ++__r; + remove(__p); + return __r; +} + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first, + const_iterator __last) +{ + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__first)) == this, + "unordered container::erase(iterator, iterator) called with an iterator not" + " referring to this container"); + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__last)) == this, + "unordered container::erase(iterator, iterator) called with an iterator not" + " referring to this container"); + for (const_iterator __p = __first; __first != __last; __p = __first) + { + ++__first; + erase(__p); + } + __next_pointer __np = __last.__node_; + return iterator (__np, this); +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_unique(const _Key& __k) +{ + iterator __i = find(__k); + if (__i == end()) + return 0; + erase(__i); + return 1; +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_multi(const _Key& __k) +{ + size_type __r = 0; + iterator __i = find(__k); + if (__i != end()) + { + iterator __e = end(); + do + { + erase(__i++); + ++__r; + } while (__i != __e && key_eq()(*__i, __k)); + } + return __r; +} + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder +__hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT +{ + // current node + __next_pointer __cn = __p.__node_; + size_type __bc = bucket_count(); + size_t __chash = std::__constrain_hash(__cn->__hash(), __bc); + // find previous node + __next_pointer __pn = __bucket_list_[__chash]; + for (; __pn->__next_ != __cn; __pn = __pn->__next_) + ; + // Fix up __bucket_list_ + // if __pn is not in same bucket (before begin is not in same bucket) && + // if __cn->__next_ is not in same bucket (nullptr is not in same bucket) + if (__pn == __p1_.first().__ptr() + || std::__constrain_hash(__pn->__hash(), __bc) != __chash) + { + if (__cn->__next_ == nullptr + || std::__constrain_hash(__cn->__next_->__hash(), __bc) != __chash) + __bucket_list_[__chash] = nullptr; + } + // if __cn->__next_ is not in same bucket (nullptr is in same bucket) + if (__cn->__next_ != nullptr) + { + size_t __nhash = std::__constrain_hash(__cn->__next_->__hash(), __bc); + if (__nhash != __chash) + __bucket_list_[__nhash] = __pn; + } + // remove __cn + __pn->__next_ = __cn->__next_; + __cn->__next_ = nullptr; + --size(); +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + __c_node* __c = __get_db()->__find_c_and_lock(this); + for (__i_node** __dp = __c->end_; __dp != __c->beg_; ) + { + --__dp; + iterator* __i = static_cast((*__dp)->__i_); + if (__i->__node_ == __cn) + { + (*__dp)->__c_ = nullptr; + if (--__c->end_ != __dp) + _VSTD::memmove(__dp, __dp+1, (__c->end_ - __dp)*sizeof(__i_node*)); + } + } + __get_db()->unlock(); +#endif + return __node_holder(__cn->__upcast(), _Dp(__node_alloc(), true)); +} + +template +template +inline +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_unique(const _Key& __k) const +{ + return static_cast(find(__k) != end()); +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_multi(const _Key& __k) const +{ + size_type __r = 0; + const_iterator __i = find(__k); + if (__i != end()) + { + const_iterator __e = end(); + do + { + ++__i; + ++__r; + } while (__i != __e && key_eq()(*__i, __k)); + } + return __r; +} + +template +template +pair::iterator, + typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique( + const _Key& __k) +{ + iterator __i = find(__k); + iterator __j = __i; + if (__i != end()) + ++__j; + return pair(__i, __j); +} + +template +template +pair::const_iterator, + typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique( + const _Key& __k) const +{ + const_iterator __i = find(__k); + const_iterator __j = __i; + if (__i != end()) + ++__j; + return pair(__i, __j); +} + +template +template +pair::iterator, + typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi( + const _Key& __k) +{ + iterator __i = find(__k); + iterator __j = __i; + if (__i != end()) + { + iterator __e = end(); + do + { + ++__j; + } while (__j != __e && key_eq()(*__j, __k)); + } + return pair(__i, __j); +} + +template +template +pair::const_iterator, + typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi( + const _Key& __k) const +{ + const_iterator __i = find(__k); + const_iterator __j = __i; + if (__i != end()) + { + const_iterator __e = end(); + do + { + ++__j; + } while (__j != __e && key_eq()(*__j, __k)); + } + return pair(__i, __j); +} + +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u) +#if _LIBCPP_STD_VER <= 11 + _NOEXCEPT_( + __is_nothrow_swappable::value && __is_nothrow_swappable::value + && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value + || __is_nothrow_swappable<__pointer_allocator>::value) + && (!__node_traits::propagate_on_container_swap::value + || __is_nothrow_swappable<__node_allocator>::value) + ) +#else + _NOEXCEPT_(__is_nothrow_swappable::value && __is_nothrow_swappable::value) +#endif +{ + _LIBCPP_ASSERT(__node_traits::propagate_on_container_swap::value || + this->__node_alloc() == __u.__node_alloc(), + "list::swap: Either propagate_on_container_swap must be true" + " or the allocators must compare equal"); + { + __node_pointer_pointer __npp = __bucket_list_.release(); + __bucket_list_.reset(__u.__bucket_list_.release()); + __u.__bucket_list_.reset(__npp); + } + _VSTD::swap(__bucket_list_.get_deleter().size(), __u.__bucket_list_.get_deleter().size()); + _VSTD::__swap_allocator(__bucket_list_.get_deleter().__alloc(), + __u.__bucket_list_.get_deleter().__alloc()); + _VSTD::__swap_allocator(__node_alloc(), __u.__node_alloc()); + _VSTD::swap(__p1_.first().__next_, __u.__p1_.first().__next_); + __p2_.swap(__u.__p2_); + __p3_.swap(__u.__p3_); + if (size() > 0) + __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = + __p1_.first().__ptr(); + if (__u.size() > 0) + __u.__bucket_list_[std::__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] = + __u.__p1_.first().__ptr(); + std::__debug_db_swap(this, std::addressof(__u)); +} + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type +__hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const +{ + _LIBCPP_ASSERT(__n < bucket_count(), + "unordered container::bucket_size(n) called with n >= bucket_count()"); + __next_pointer __np = __bucket_list_[__n]; + size_type __bc = bucket_count(); + size_type __r = 0; + if (__np != nullptr) + { + for (__np = __np->__next_; __np != nullptr && + std::__constrain_hash(__np->__hash(), __bc) == __n; + __np = __np->__next_, (void) ++__r) + ; + } + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x, + __hash_table<_Tp, _Hash, _Equal, _Alloc>& __y) + _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) +{ + __x.swap(__y); +} + +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + +template +bool +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__dereferenceable(const const_iterator* __i) const +{ + return __i->__node_ != nullptr; +} + +template +bool +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__decrementable(const const_iterator*) const +{ + return false; +} + +template +bool +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__addable(const const_iterator*, ptrdiff_t) const +{ + return false; +} + +template +bool +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const +{ + return false; +} + +#endif // _LIBCPP_ENABLE_DEBUG_MODE + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___HASH_TABLE diff --git a/app/src/main/cpp/libcxx/include/__ios/fpos.h b/app/src/main/cpp/libcxx/include/__ios/fpos.h new file mode 100644 index 0000000..87f0135 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__ios/fpos.h @@ -0,0 +1,79 @@ +// -*- 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 _LIBCPP___IOS_FPOS_H +#define _LIBCPP___IOS_FPOS_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS fpos { +private: + _StateT __st_; + streamoff __off_; + +public: + _LIBCPP_HIDE_FROM_ABI fpos(streamoff __off = streamoff()) : __st_(), __off_(__off) {} + + _LIBCPP_HIDE_FROM_ABI operator streamoff() const { return __off_; } + + _LIBCPP_HIDE_FROM_ABI _StateT state() const { return __st_; } + _LIBCPP_HIDE_FROM_ABI void state(_StateT __st) { __st_ = __st; } + + _LIBCPP_HIDE_FROM_ABI fpos& operator+=(streamoff __off) { + __off_ += __off; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI fpos operator+(streamoff __off) const { + fpos __t(*this); + __t += __off; + return __t; + } + + _LIBCPP_HIDE_FROM_ABI fpos& operator-=(streamoff __off) { + __off_ -= __off; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI fpos operator-(streamoff __off) const { + fpos __t(*this); + __t -= __off; + return __t; + } +}; + +template +inline _LIBCPP_HIDE_FROM_ABI +streamoff operator-(const fpos<_StateT>& __x, const fpos<_StateT>& __y) { + return streamoff(__x) - streamoff(__y); +} + +template +inline _LIBCPP_HIDE_FROM_ABI +bool operator==(const fpos<_StateT>& __x, const fpos<_StateT>& __y) { + return streamoff(__x) == streamoff(__y); +} + +template +inline _LIBCPP_HIDE_FROM_ABI +bool operator!=(const fpos<_StateT>& __x, const fpos<_StateT>& __y) { + return streamoff(__x) != streamoff(__y); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___IOS_FPOS_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/access.h b/app/src/main/cpp/libcxx/include/__iterator/access.h new file mode 100644 index 0000000..0b8d523 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/access.h @@ -0,0 +1,129 @@ +// -*- 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 _LIBCPP___ITERATOR_ACCESS_H +#define _LIBCPP___ITERATOR_ACCESS_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +_Tp* +begin(_Tp (&__array)[_Np]) +{ + return __array; +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +_Tp* +end(_Tp (&__array)[_Np]) +{ + return __array + _Np; +} + +#if !defined(_LIBCPP_CXX03_LANG) + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +auto +begin(_Cp& __c) -> decltype(__c.begin()) +{ + return __c.begin(); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +auto +begin(const _Cp& __c) -> decltype(__c.begin()) +{ + return __c.begin(); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +auto +end(_Cp& __c) -> decltype(__c.end()) +{ + return __c.end(); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +auto +end(const _Cp& __c) -> decltype(__c.end()) +{ + return __c.end(); +} + +#if _LIBCPP_STD_VER > 11 + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +auto cbegin(const _Cp& __c) -> decltype(_VSTD::begin(__c)) +{ + return _VSTD::begin(__c); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +auto cend(const _Cp& __c) -> decltype(_VSTD::end(__c)) +{ + return _VSTD::end(__c); +} + +#endif + + +#else // defined(_LIBCPP_CXX03_LANG) + +template +_LIBCPP_INLINE_VISIBILITY +typename _Cp::iterator +begin(_Cp& __c) +{ + return __c.begin(); +} + +template +_LIBCPP_INLINE_VISIBILITY +typename _Cp::const_iterator +begin(const _Cp& __c) +{ + return __c.begin(); +} + +template +_LIBCPP_INLINE_VISIBILITY +typename _Cp::iterator +end(_Cp& __c) +{ + return __c.end(); +} + +template +_LIBCPP_INLINE_VISIBILITY +typename _Cp::const_iterator +end(const _Cp& __c) +{ + return __c.end(); +} + +#endif // !defined(_LIBCPP_CXX03_LANG) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_ACCESS_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/advance.h b/app/src/main/cpp/libcxx/include/__iterator/advance.h new file mode 100644 index 0000000..154c273 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/advance.h @@ -0,0 +1,203 @@ +// -*- 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 _LIBCPP___ITERATOR_ADVANCE_H +#define _LIBCPP___ITERATOR_ADVANCE_H + +#include <__assert> +#include <__concepts/assignable.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iterator_traits.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_integral.h> +#include <__utility/convert_to_integral.h> +#include <__utility/declval.h> +#include <__utility/move.h> +#include <__utility/unreachable.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 +void __advance(_InputIter& __i, typename iterator_traits<_InputIter>::difference_type __n, input_iterator_tag) { + for (; __n > 0; --__n) + ++__i; +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 +void __advance(_BiDirIter& __i, typename iterator_traits<_BiDirIter>::difference_type __n, bidirectional_iterator_tag) { + if (__n >= 0) + for (; __n > 0; --__n) + ++__i; + else + for (; __n < 0; ++__n) + --__i; +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 +void __advance(_RandIter& __i, typename iterator_traits<_RandIter>::difference_type __n, random_access_iterator_tag) { + __i += __n; +} + +template < + class _InputIter, class _Distance, + class _IntegralDistance = decltype(_VSTD::__convert_to_integral(std::declval<_Distance>())), + class = __enable_if_t::value> > +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 +void advance(_InputIter& __i, _Distance __orig_n) { + typedef typename iterator_traits<_InputIter>::difference_type _Difference; + _Difference __n = static_cast<_Difference>(_VSTD::__convert_to_integral(__orig_n)); + _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, + "Attempt to advance(it, n) with negative n on a non-bidirectional iterator"); + _VSTD::__advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category()); +} + +#if _LIBCPP_STD_VER > 17 + +// [range.iter.op.advance] + +namespace ranges { +namespace __advance { + +struct __fn { +private: + template + _LIBCPP_HIDE_FROM_ABI + static constexpr void __advance_forward(_Ip& __i, iter_difference_t<_Ip> __n) { + while (__n > 0) { + --__n; + ++__i; + } + } + + template + _LIBCPP_HIDE_FROM_ABI + static constexpr void __advance_backward(_Ip& __i, iter_difference_t<_Ip> __n) { + while (__n < 0) { + ++__n; + --__i; + } + } + +public: + // Preconditions: If `I` does not model `bidirectional_iterator`, `n` is not negative. + template + _LIBCPP_HIDE_FROM_ABI + constexpr void operator()(_Ip& __i, iter_difference_t<_Ip> __n) const { + _LIBCPP_ASSERT(__n >= 0 || bidirectional_iterator<_Ip>, + "If `n < 0`, then `bidirectional_iterator` must be true."); + + // If `I` models `random_access_iterator`, equivalent to `i += n`. + if constexpr (random_access_iterator<_Ip>) { + __i += __n; + return; + } else if constexpr (bidirectional_iterator<_Ip>) { + // Otherwise, if `n` is non-negative, increments `i` by `n`. + __advance_forward(__i, __n); + // Otherwise, decrements `i` by `-n`. + __advance_backward(__i, __n); + return; + } else { + // Otherwise, if `n` is non-negative, increments `i` by `n`. + __advance_forward(__i, __n); + return; + } + } + + // Preconditions: Either `assignable_from || sized_sentinel_for` is modeled, or [i, bound_sentinel) denotes a range. + template _Sp> + _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Ip& __i, _Sp __bound_sentinel) const { + // If `I` and `S` model `assignable_from`, equivalent to `i = std::move(bound_sentinel)`. + if constexpr (assignable_from<_Ip&, _Sp>) { + __i = _VSTD::move(__bound_sentinel); + } + // Otherwise, if `S` and `I` model `sized_sentinel_for`, equivalent to `ranges::advance(i, bound_sentinel - i)`. + else if constexpr (sized_sentinel_for<_Sp, _Ip>) { + (*this)(__i, __bound_sentinel - __i); + } + // Otherwise, while `bool(i != bound_sentinel)` is true, increments `i`. + else { + while (__i != __bound_sentinel) { + ++__i; + } + } + } + + // Preconditions: + // * If `n > 0`, [i, bound_sentinel) denotes a range. + // * If `n == 0`, [i, bound_sentinel) or [bound_sentinel, i) denotes a range. + // * If `n < 0`, [bound_sentinel, i) denotes a range, `I` models `bidirectional_iterator`, and `I` and `S` model `same_as`. + // Returns: `n - M`, where `M` is the difference between the ending and starting position. + template _Sp> + _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Ip> operator()(_Ip& __i, iter_difference_t<_Ip> __n, + _Sp __bound_sentinel) const { + _LIBCPP_ASSERT((__n >= 0) || (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>), + "If `n < 0`, then `bidirectional_iterator && same_as` must be true."); + // If `S` and `I` model `sized_sentinel_for`: + if constexpr (sized_sentinel_for<_Sp, _Ip>) { + // If |n| >= |bound_sentinel - i|, equivalent to `ranges::advance(i, bound_sentinel)`. + // __magnitude_geq(a, b) returns |a| >= |b|, assuming they have the same sign. + auto __magnitude_geq = [](auto __a, auto __b) { + return __a == 0 ? __b == 0 : + __a > 0 ? __a >= __b : + __a <= __b; + }; + if (const auto __M = __bound_sentinel - __i; __magnitude_geq(__n, __M)) { + (*this)(__i, __bound_sentinel); + return __n - __M; + } + + // Otherwise, equivalent to `ranges::advance(i, n)`. + (*this)(__i, __n); + return 0; + } else { + // Otherwise, if `n` is non-negative, while `bool(i != bound_sentinel)` is true, increments `i` but at + // most `n` times. + while (__i != __bound_sentinel && __n > 0) { + ++__i; + --__n; + } + + // Otherwise, while `bool(i != bound_sentinel)` is true, decrements `i` but at most `-n` times. + if constexpr (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>) { + while (__i != __bound_sentinel && __n < 0) { + --__i; + ++__n; + } + } + return __n; + } + + __libcpp_unreachable(); + } +}; + +} // namespace __advance + +inline namespace __cpo { + inline constexpr auto advance = __advance::__fn{}; +} // namespace __cpo +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_ADVANCE_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/back_insert_iterator.h b/app/src/main/cpp/libcxx/include/__iterator/back_insert_iterator.h new file mode 100644 index 0000000..4c00a7e --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/back_insert_iterator.h @@ -0,0 +1,73 @@ +// -*- 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 _LIBCPP___ITERATOR_BACK_INSERT_ITERATOR_H +#define _LIBCPP___ITERATOR_BACK_INSERT_ITERATOR_H + +#include <__config> +#include <__iterator/iterator.h> +#include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template +class _LIBCPP_TEMPLATE_VIS back_insert_iterator +#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES) + : public iterator +#endif +{ +_LIBCPP_SUPPRESS_DEPRECATED_POP +protected: + _Container* container; +public: + typedef output_iterator_tag iterator_category; + typedef void value_type; +#if _LIBCPP_STD_VER > 17 + typedef ptrdiff_t difference_type; +#else + typedef void difference_type; +#endif + typedef void pointer; + typedef void reference; + typedef _Container container_type; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& operator=(const typename _Container::value_type& __value) + {container->push_back(__value); return *this;} +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& operator=(typename _Container::value_type&& __value) + {container->push_back(_VSTD::move(__value)); return *this;} +#endif // _LIBCPP_CXX03_LANG + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& operator*() {return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& operator++() {return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator operator++(int) {return *this;} + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Container* __get_container() const { return container; } +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(back_insert_iterator); + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +back_insert_iterator<_Container> +back_inserter(_Container& __x) +{ + return back_insert_iterator<_Container>(__x); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_BACK_INSERT_ITERATOR_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/bounded_iter.h b/app/src/main/cpp/libcxx/include/__iterator/bounded_iter.h new file mode 100644 index 0000000..2682f2a --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/bounded_iter.h @@ -0,0 +1,231 @@ +// -*- 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 _LIBCPP___ITERATOR_BOUNDED_ITER_H +#define _LIBCPP___ITERATOR_BOUNDED_ITER_H + +#include <__assert> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__memory/pointer_traits.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_convertible.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Iterator wrapper that carries the valid range it is allowed to access. +// +// This is a simple iterator wrapper for contiguous iterators that points +// within a [begin, end) range and carries these bounds with it. The iterator +// ensures that it is pointing within that [begin, end) range when it is +// dereferenced. +// +// Arithmetic operations are allowed and the bounds of the resulting iterator +// are not checked. Hence, it is possible to create an iterator pointing outside +// its range, but it is not possible to dereference it. +template ::value > > +struct __bounded_iter { + using value_type = typename iterator_traits<_Iterator>::value_type; + using difference_type = typename iterator_traits<_Iterator>::difference_type; + using pointer = typename iterator_traits<_Iterator>::pointer; + using reference = typename iterator_traits<_Iterator>::reference; + using iterator_category = typename iterator_traits<_Iterator>::iterator_category; +#if _LIBCPP_STD_VER > 17 + using iterator_concept = contiguous_iterator_tag; +#endif + + // Create a singular iterator. + // + // Such an iterator does not point to any object and is conceptually out of bounds, so it is + // not dereferenceable. Observing operations like comparison and assignment are valid. + _LIBCPP_HIDE_FROM_ABI __bounded_iter() = default; + + _LIBCPP_HIDE_FROM_ABI __bounded_iter(__bounded_iter const&) = default; + _LIBCPP_HIDE_FROM_ABI __bounded_iter(__bounded_iter&&) = default; + + template ::value > > + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bounded_iter(__bounded_iter<_OtherIterator> const& __other) _NOEXCEPT + : __current_(__other.__current_), + __begin_(__other.__begin_), + __end_(__other.__end_) {} + + // Assign a bounded iterator to another one, rebinding the bounds of the iterator as well. + _LIBCPP_HIDE_FROM_ABI __bounded_iter& operator=(__bounded_iter const&) = default; + _LIBCPP_HIDE_FROM_ABI __bounded_iter& operator=(__bounded_iter&&) = default; + +private: + // Create an iterator wrapping the given iterator, and whose bounds are described + // by the provided [begin, end) range. + // + // This constructor does not check whether the resulting iterator is within its bounds. + // However, it does check that the provided [begin, end) range is a valid range (that + // is, begin <= end). + // + // Since it is non-standard for iterators to have this constructor, __bounded_iter must + // be created via `std::__make_bounded_iter`. + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __bounded_iter( + _Iterator __current, _Iterator __begin, _Iterator __end) + : __current_(__current), __begin_(__begin), __end_(__end) { + _LIBCPP_ASSERT(__begin <= __end, "__bounded_iter(current, begin, end): [begin, end) is not a valid range"); + } + + template + friend _LIBCPP_CONSTEXPR __bounded_iter<_It> __make_bounded_iter(_It, _It, _It); + +public: + // Dereference and indexing operations. + // + // These operations check that the iterator is dereferenceable, that is within [begin, end). + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator*() const _NOEXCEPT { + _LIBCPP_ASSERT( + __in_bounds(__current_), "__bounded_iter::operator*: Attempt to dereference an out-of-range iterator"); + return *__current_; + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pointer operator->() const _NOEXCEPT { + _LIBCPP_ASSERT( + __in_bounds(__current_), "__bounded_iter::operator->: Attempt to dereference an out-of-range iterator"); + return std::__to_address(__current_); + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator[](difference_type __n) const _NOEXCEPT { + _LIBCPP_ASSERT( + __in_bounds(__current_ + __n), "__bounded_iter::operator[]: Attempt to index an iterator out-of-range"); + return __current_[__n]; + } + + // Arithmetic operations. + // + // These operations do not check that the resulting iterator is within the bounds, since that + // would make it impossible to create a past-the-end iterator. + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter& operator++() _NOEXCEPT { + ++__current_; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter operator++(int) _NOEXCEPT { + __bounded_iter __tmp(*this); + ++*this; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter& operator--() _NOEXCEPT { + --__current_; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter operator--(int) _NOEXCEPT { + __bounded_iter __tmp(*this); + --*this; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter& operator+=(difference_type __n) _NOEXCEPT { + __current_ += __n; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend __bounded_iter + operator+(__bounded_iter const& __self, difference_type __n) _NOEXCEPT { + __bounded_iter __tmp(__self); + __tmp += __n; + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend __bounded_iter + operator+(difference_type __n, __bounded_iter const& __self) _NOEXCEPT { + __bounded_iter __tmp(__self); + __tmp += __n; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter& operator-=(difference_type __n) _NOEXCEPT { + __current_ -= __n; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend __bounded_iter + operator-(__bounded_iter const& __self, difference_type __n) _NOEXCEPT { + __bounded_iter __tmp(__self); + __tmp -= __n; + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend difference_type + operator-(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT { + return __x.__current_ - __y.__current_; + } + + // Comparison operations. + // + // These operations do not check whether the iterators are within their bounds. + // The valid range for each iterator is also not considered as part of the comparison, + // i.e. two iterators pointing to the same location will be considered equal even + // if they have different validity ranges. + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool + operator==(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT { + return __x.__current_ == __y.__current_; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool + operator!=(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT { + return __x.__current_ != __y.__current_; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool + operator<(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT { + return __x.__current_ < __y.__current_; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool + operator>(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT { + return __x.__current_ > __y.__current_; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool + operator<=(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT { + return __x.__current_ <= __y.__current_; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool + operator>=(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT { + return __x.__current_ >= __y.__current_; + } + +private: + // Return whether the given iterator is in the bounds of this __bounded_iter. + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Iterator const& __iter) const { + return __iter >= __begin_ && __iter < __end_; + } + + template + friend struct pointer_traits; + _Iterator __current_; // current iterator + _Iterator __begin_, __end_; // valid range represented as [begin, end) +}; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bounded_iter<_It> __make_bounded_iter(_It __it, _It __begin, _It __end) { + return __bounded_iter<_It>(std::move(__it), std::move(__begin), std::move(__end)); +} + +#if _LIBCPP_STD_VER <= 17 +template +struct __is_cpp17_contiguous_iterator<__bounded_iter<_Iterator> > : true_type {}; +#endif + +template +struct pointer_traits<__bounded_iter<_Iterator> > { + using pointer = __bounded_iter<_Iterator>; + using element_type = typename pointer_traits<_Iterator>::element_type; + using difference_type = typename pointer_traits<_Iterator>::difference_type; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static element_type* to_address(pointer __it) _NOEXCEPT { + return std::__to_address(__it.__current_); + } +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_BOUNDED_ITER_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/common_iterator.h b/app/src/main/cpp/libcxx/include/__iterator/common_iterator.h new file mode 100644 index 0000000..f7883e2 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/common_iterator.h @@ -0,0 +1,281 @@ +// -*- 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 _LIBCPP___ITERATOR_COMMON_ITERATOR_H +#define _LIBCPP___ITERATOR_COMMON_ITERATOR_H + +#include <__assert> +#include <__concepts/assignable.h> +#include <__concepts/constructible.h> +#include <__concepts/convertible_to.h> +#include <__concepts/copyable.h> +#include <__concepts/derived_from.h> +#include <__concepts/equality_comparable.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iter_move.h> +#include <__iterator/iter_swap.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/readable_traits.h> +#include <__type_traits/is_pointer.h> +#include <__utility/declval.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +concept __can_use_postfix_proxy = + constructible_from, iter_reference_t<_Iter>> && + move_constructible>; + +template _Sent> + requires (!same_as<_Iter, _Sent> && copyable<_Iter>) +class common_iterator { + struct __proxy { + constexpr const iter_value_t<_Iter>* operator->() const noexcept { + return _VSTD::addressof(__value_); + } + iter_value_t<_Iter> __value_; + }; + + struct __postfix_proxy { + constexpr const iter_value_t<_Iter>& operator*() const noexcept { + return __value_; + } + iter_value_t<_Iter> __value_; + }; + +public: + variant<_Iter, _Sent> __hold_; + + common_iterator() requires default_initializable<_Iter> = default; + + constexpr common_iterator(_Iter __i) : __hold_(in_place_type<_Iter>, _VSTD::move(__i)) {} + constexpr common_iterator(_Sent __s) : __hold_(in_place_type<_Sent>, _VSTD::move(__s)) {} + + template + requires convertible_to && convertible_to + constexpr common_iterator(const common_iterator<_I2, _S2>& __other) + : __hold_([&]() -> variant<_Iter, _Sent> { + _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Attempted to construct from a valueless common_iterator"); + if (__other.__hold_.index() == 0) + return variant<_Iter, _Sent>{in_place_index<0>, _VSTD::__unchecked_get<0>(__other.__hold_)}; + return variant<_Iter, _Sent>{in_place_index<1>, _VSTD::__unchecked_get<1>(__other.__hold_)}; + }()) {} + + template + requires convertible_to && convertible_to && + assignable_from<_Iter&, const _I2&> && assignable_from<_Sent&, const _S2&> + common_iterator& operator=(const common_iterator<_I2, _S2>& __other) { + _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Attempted to assign from a valueless common_iterator"); + + auto __idx = __hold_.index(); + auto __other_idx = __other.__hold_.index(); + + // If they're the same index, just assign. + if (__idx == 0 && __other_idx == 0) + _VSTD::__unchecked_get<0>(__hold_) = _VSTD::__unchecked_get<0>(__other.__hold_); + else if (__idx == 1 && __other_idx == 1) + _VSTD::__unchecked_get<1>(__hold_) = _VSTD::__unchecked_get<1>(__other.__hold_); + + // Otherwise replace with the oposite element. + else if (__other_idx == 1) + __hold_.template emplace<1>(_VSTD::__unchecked_get<1>(__other.__hold_)); + else if (__other_idx == 0) + __hold_.template emplace<0>(_VSTD::__unchecked_get<0>(__other.__hold_)); + + return *this; + } + + constexpr decltype(auto) operator*() + { + _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); + return *_VSTD::__unchecked_get<_Iter>(__hold_); + } + + constexpr decltype(auto) operator*() const + requires __dereferenceable + { + _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); + return *_VSTD::__unchecked_get<_Iter>(__hold_); + } + + template + decltype(auto) operator->() const + requires indirectly_readable && + (requires(const _I2& __i) { __i.operator->(); } || + is_reference_v> || + constructible_from, iter_reference_t<_I2>>) + { + _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); + if constexpr (is_pointer_v<_Iter> || requires(const _Iter& __i) { __i.operator->(); }) { + return _VSTD::__unchecked_get<_Iter>(__hold_); + } else if constexpr (is_reference_v>) { + auto&& __tmp = *_VSTD::__unchecked_get<_Iter>(__hold_); + return _VSTD::addressof(__tmp); + } else { + return __proxy{*_VSTD::__unchecked_get<_Iter>(__hold_)}; + } + } + + common_iterator& operator++() { + _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator"); + ++_VSTD::__unchecked_get<_Iter>(__hold_); return *this; + } + + decltype(auto) operator++(int) { + _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator"); + if constexpr (forward_iterator<_Iter>) { + auto __tmp = *this; + ++*this; + return __tmp; + } else if constexpr (requires (_Iter& __i) { { *__i++ } -> __can_reference; } || + !__can_use_postfix_proxy<_Iter>) { + return _VSTD::__unchecked_get<_Iter>(__hold_)++; + } else { + auto __p = __postfix_proxy{**this}; + ++*this; + return __p; + } + } + + template _S2> + requires sentinel_for<_Sent, _I2> + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { + _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); + _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); + + auto __x_index = __x.__hold_.index(); + auto __y_index = __y.__hold_.index(); + + if (__x_index == __y_index) + return true; + + if (__x_index == 0) + return _VSTD::__unchecked_get<_Iter>(__x.__hold_) == _VSTD::__unchecked_get<_S2>(__y.__hold_); + + return _VSTD::__unchecked_get<_Sent>(__x.__hold_) == _VSTD::__unchecked_get<_I2>(__y.__hold_); + } + + template _S2> + requires sentinel_for<_Sent, _I2> && equality_comparable_with<_Iter, _I2> + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { + _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); + _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); + + auto __x_index = __x.__hold_.index(); + auto __y_index = __y.__hold_.index(); + + if (__x_index == 1 && __y_index == 1) + return true; + + if (__x_index == 0 && __y_index == 0) + return _VSTD::__unchecked_get<_Iter>(__x.__hold_) == _VSTD::__unchecked_get<_I2>(__y.__hold_); + + if (__x_index == 0) + return _VSTD::__unchecked_get<_Iter>(__x.__hold_) == _VSTD::__unchecked_get<_S2>(__y.__hold_); + + return _VSTD::__unchecked_get<_Sent>(__x.__hold_) == _VSTD::__unchecked_get<_I2>(__y.__hold_); + } + + template _I2, sized_sentinel_for<_Iter> _S2> + requires sized_sentinel_for<_Sent, _I2> + _LIBCPP_HIDE_FROM_ABI + friend constexpr iter_difference_t<_I2> operator-(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { + _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to subtract from a valueless common_iterator"); + _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to subtract a valueless common_iterator"); + + auto __x_index = __x.__hold_.index(); + auto __y_index = __y.__hold_.index(); + + if (__x_index == 1 && __y_index == 1) + return 0; + + if (__x_index == 0 && __y_index == 0) + return _VSTD::__unchecked_get<_Iter>(__x.__hold_) - _VSTD::__unchecked_get<_I2>(__y.__hold_); + + if (__x_index == 0) + return _VSTD::__unchecked_get<_Iter>(__x.__hold_) - _VSTD::__unchecked_get<_S2>(__y.__hold_); + + return _VSTD::__unchecked_get<_Sent>(__x.__hold_) - _VSTD::__unchecked_get<_I2>(__y.__hold_); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr iter_rvalue_reference_t<_Iter> iter_move(const common_iterator& __i) + noexcept(noexcept(ranges::iter_move(std::declval()))) + requires input_iterator<_Iter> + { + _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__i.__hold_), "Attempted to iter_move a non-dereferenceable common_iterator"); + return ranges::iter_move( _VSTD::__unchecked_get<_Iter>(__i.__hold_)); + } + + template _I2, class _S2> + _LIBCPP_HIDE_FROM_ABI friend constexpr void iter_swap(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) + noexcept(noexcept(ranges::iter_swap(std::declval(), std::declval()))) + { + _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__x.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator"); + _LIBCPP_ASSERT(std::holds_alternative<_I2>(__y.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator"); + return ranges::iter_swap(_VSTD::__unchecked_get<_Iter>(__x.__hold_), _VSTD::__unchecked_get<_I2>(__y.__hold_)); + } +}; + +template +struct incrementable_traits> { + using difference_type = iter_difference_t<_Iter>; +}; + +template +concept __denotes_forward_iter = + requires { typename iterator_traits<_Iter>::iterator_category; } && + derived_from::iterator_category, forward_iterator_tag>; + +template +concept __common_iter_has_ptr_op = requires(const common_iterator<_Iter, _Sent>& __a) { + __a.operator->(); +}; + +template +struct __arrow_type_or_void { + using type = void; +}; + +template + requires __common_iter_has_ptr_op<_Iter, _Sent> +struct __arrow_type_or_void<_Iter, _Sent> { + using type = decltype(std::declval&>().operator->()); +}; + +template +struct iterator_traits> { + using iterator_concept = _If, + forward_iterator_tag, + input_iterator_tag>; + using iterator_category = _If<__denotes_forward_iter<_Iter>, + forward_iterator_tag, + input_iterator_tag>; + using pointer = typename __arrow_type_or_void<_Iter, _Sent>::type; + using value_type = iter_value_t<_Iter>; + using difference_type = iter_difference_t<_Iter>; + using reference = iter_reference_t<_Iter>; +}; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_COMMON_ITERATOR_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/concepts.h b/app/src/main/cpp/libcxx/include/__iterator/concepts.h new file mode 100644 index 0000000..d9d40a4 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/concepts.h @@ -0,0 +1,300 @@ +// -*- 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 _LIBCPP___ITERATOR_CONCEPTS_H +#define _LIBCPP___ITERATOR_CONCEPTS_H + +#include <__concepts/arithmetic.h> +#include <__concepts/assignable.h> +#include <__concepts/common_reference_with.h> +#include <__concepts/constructible.h> +#include <__concepts/copyable.h> +#include <__concepts/derived_from.h> +#include <__concepts/equality_comparable.h> +#include <__concepts/invocable.h> +#include <__concepts/movable.h> +#include <__concepts/predicate.h> +#include <__concepts/regular.h> +#include <__concepts/relation.h> +#include <__concepts/same_as.h> +#include <__concepts/semiregular.h> +#include <__concepts/totally_ordered.h> +#include <__config> +#include <__functional/invoke.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iter_move.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/readable_traits.h> +#include <__memory/pointer_traits.h> +#include <__type_traits/add_pointer.h> +#include <__type_traits/common_reference.h> +#include <__type_traits/is_pointer.h> +#include <__type_traits/is_reference.h> +#include <__type_traits/remove_cv.h> +#include <__type_traits/remove_cvref.h> +#include <__utility/forward.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [iterator.concept.readable] +template +concept __indirectly_readable_impl = + requires(const _In __i) { + typename iter_value_t<_In>; + typename iter_reference_t<_In>; + typename iter_rvalue_reference_t<_In>; + { *__i } -> same_as>; + { ranges::iter_move(__i) } -> same_as>; + } && + common_reference_with&&, iter_value_t<_In>&> && + common_reference_with&&, iter_rvalue_reference_t<_In>&&> && + common_reference_with&&, const iter_value_t<_In>&>; + +template +concept indirectly_readable = __indirectly_readable_impl>; + +template +using iter_common_reference_t = common_reference_t, iter_value_t<_Tp>&>; + +// [iterator.concept.writable] +template +concept indirectly_writable = + requires(_Out&& __o, _Tp&& __t) { + *__o = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving + *_VSTD::forward<_Out>(__o) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving + const_cast&&>(*__o) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving + const_cast&&>(*_VSTD::forward<_Out>(__o)) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving + }; + +// [iterator.concept.winc] +template +concept __integer_like = integral<_Tp> && !same_as<_Tp, bool>; + +template +concept __signed_integer_like = signed_integral<_Tp>; + +template +concept weakly_incrementable = + // TODO: remove this once the clang bug is fixed (bugs.llvm.org/PR48173). + !same_as<_Ip, bool> && // Currently, clang does not handle bool correctly. + movable<_Ip> && + requires(_Ip __i) { + typename iter_difference_t<_Ip>; + requires __signed_integer_like>; + { ++__i } -> same_as<_Ip&>; // not required to be equality-preserving + __i++; // not required to be equality-preserving + }; + +// [iterator.concept.inc] +template +concept incrementable = + regular<_Ip> && + weakly_incrementable<_Ip> && + requires(_Ip __i) { + { __i++ } -> same_as<_Ip>; + }; + +// [iterator.concept.iterator] +template +concept input_or_output_iterator = + requires(_Ip __i) { + { *__i } -> __can_reference; + } && + weakly_incrementable<_Ip>; + +// [iterator.concept.sentinel] +template +concept sentinel_for = + semiregular<_Sp> && + input_or_output_iterator<_Ip> && + __weakly_equality_comparable_with<_Sp, _Ip>; + +template +inline constexpr bool disable_sized_sentinel_for = false; + +template +concept sized_sentinel_for = + sentinel_for<_Sp, _Ip> && + !disable_sized_sentinel_for, remove_cv_t<_Ip>> && + requires(const _Ip& __i, const _Sp& __s) { + { __s - __i } -> same_as>; + { __i - __s } -> same_as>; + }; + +// [iterator.concept.input] +template +concept input_iterator = + input_or_output_iterator<_Ip> && + indirectly_readable<_Ip> && + requires { typename _ITER_CONCEPT<_Ip>; } && + derived_from<_ITER_CONCEPT<_Ip>, input_iterator_tag>; + +// [iterator.concept.output] +template +concept output_iterator = + input_or_output_iterator<_Ip> && + indirectly_writable<_Ip, _Tp> && + requires (_Ip __it, _Tp&& __t) { + *__it++ = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving + }; + +// [iterator.concept.forward] +template +concept forward_iterator = + input_iterator<_Ip> && + derived_from<_ITER_CONCEPT<_Ip>, forward_iterator_tag> && + incrementable<_Ip> && + sentinel_for<_Ip, _Ip>; + +// [iterator.concept.bidir] +template +concept bidirectional_iterator = + forward_iterator<_Ip> && + derived_from<_ITER_CONCEPT<_Ip>, bidirectional_iterator_tag> && + requires(_Ip __i) { + { --__i } -> same_as<_Ip&>; + { __i-- } -> same_as<_Ip>; + }; + +template +concept random_access_iterator = + bidirectional_iterator<_Ip> && + derived_from<_ITER_CONCEPT<_Ip>, random_access_iterator_tag> && + totally_ordered<_Ip> && + sized_sentinel_for<_Ip, _Ip> && + requires(_Ip __i, const _Ip __j, const iter_difference_t<_Ip> __n) { + { __i += __n } -> same_as<_Ip&>; + { __j + __n } -> same_as<_Ip>; + { __n + __j } -> same_as<_Ip>; + { __i -= __n } -> same_as<_Ip&>; + { __j - __n } -> same_as<_Ip>; + { __j[__n] } -> same_as>; + }; + +template +concept contiguous_iterator = + random_access_iterator<_Ip> && + derived_from<_ITER_CONCEPT<_Ip>, contiguous_iterator_tag> && + is_lvalue_reference_v> && + same_as, remove_cvref_t>> && + requires(const _Ip& __i) { + { _VSTD::to_address(__i) } -> same_as>>; + }; + +template +concept __has_arrow = input_iterator<_Ip> && (is_pointer_v<_Ip> || requires(_Ip __i) { __i.operator->(); }); + +// [indirectcallable.indirectinvocable] +template +concept indirectly_unary_invocable = + indirectly_readable<_It> && + copy_constructible<_Fp> && + invocable<_Fp&, iter_value_t<_It>&> && + invocable<_Fp&, iter_reference_t<_It>> && + invocable<_Fp&, iter_common_reference_t<_It>> && + common_reference_with< + invoke_result_t<_Fp&, iter_value_t<_It>&>, + invoke_result_t<_Fp&, iter_reference_t<_It>>>; + +template +concept indirectly_regular_unary_invocable = + indirectly_readable<_It> && + copy_constructible<_Fp> && + regular_invocable<_Fp&, iter_value_t<_It>&> && + regular_invocable<_Fp&, iter_reference_t<_It>> && + regular_invocable<_Fp&, iter_common_reference_t<_It>> && + common_reference_with< + invoke_result_t<_Fp&, iter_value_t<_It>&>, + invoke_result_t<_Fp&, iter_reference_t<_It>>>; + +template +concept indirect_unary_predicate = + indirectly_readable<_It> && + copy_constructible<_Fp> && + predicate<_Fp&, iter_value_t<_It>&> && + predicate<_Fp&, iter_reference_t<_It>> && + predicate<_Fp&, iter_common_reference_t<_It>>; + +template +concept indirect_binary_predicate = + indirectly_readable<_It1> && indirectly_readable<_It2> && + copy_constructible<_Fp> && + predicate<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> && + predicate<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> && + predicate<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> && + predicate<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> && + predicate<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>; + +template +concept indirect_equivalence_relation = + indirectly_readable<_It1> && indirectly_readable<_It2> && + copy_constructible<_Fp> && + equivalence_relation<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> && + equivalence_relation<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> && + equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> && + equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> && + equivalence_relation<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>; + +template +concept indirect_strict_weak_order = + indirectly_readable<_It1> && indirectly_readable<_It2> && + copy_constructible<_Fp> && + strict_weak_order<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> && + strict_weak_order<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> && + strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> && + strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> && + strict_weak_order<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>; + +template + requires (indirectly_readable<_Its> && ...) && invocable<_Fp, iter_reference_t<_Its>...> +using indirect_result_t = invoke_result_t<_Fp, iter_reference_t<_Its>...>; + +template +concept indirectly_movable = + indirectly_readable<_In> && + indirectly_writable<_Out, iter_rvalue_reference_t<_In>>; + +template +concept indirectly_movable_storable = + indirectly_movable<_In, _Out> && + indirectly_writable<_Out, iter_value_t<_In>> && + movable> && + constructible_from, iter_rvalue_reference_t<_In>> && + assignable_from&, iter_rvalue_reference_t<_In>>; + +template +concept indirectly_copyable = + indirectly_readable<_In> && + indirectly_writable<_Out, iter_reference_t<_In>>; + +template +concept indirectly_copyable_storable = + indirectly_copyable<_In, _Out> && + indirectly_writable<_Out, iter_value_t<_In>&> && + indirectly_writable<_Out, const iter_value_t<_In>&> && + indirectly_writable<_Out, iter_value_t<_In>&&> && + indirectly_writable<_Out, const iter_value_t<_In>&&> && + copyable> && + constructible_from, iter_reference_t<_In>> && + assignable_from&, iter_reference_t<_In>>; + +// Note: indirectly_swappable is located in iter_swap.h to prevent a dependency cycle +// (both iter_swap and indirectly_swappable require indirectly_readable). + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_CONCEPTS_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/counted_iterator.h b/app/src/main/cpp/libcxx/include/__iterator/counted_iterator.h new file mode 100644 index 0000000..5fdbff4 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/counted_iterator.h @@ -0,0 +1,310 @@ +// -*- 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 _LIBCPP___ITERATOR_COUNTED_ITERATOR_H +#define _LIBCPP___ITERATOR_COUNTED_ITERATOR_H + +#include <__assert> +#include <__concepts/assignable.h> +#include <__concepts/common_with.h> +#include <__concepts/constructible.h> +#include <__concepts/convertible_to.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/default_sentinel.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iter_move.h> +#include <__iterator/iter_swap.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/readable_traits.h> +#include <__memory/pointer_traits.h> +#include <__type_traits/add_pointer.h> +#include <__type_traits/conditional.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +struct __counted_iterator_concept {}; + +template + requires requires { typename _Iter::iterator_concept; } +struct __counted_iterator_concept<_Iter> { + using iterator_concept = typename _Iter::iterator_concept; +}; + +template +struct __counted_iterator_category {}; + +template + requires requires { typename _Iter::iterator_category; } +struct __counted_iterator_category<_Iter> { + using iterator_category = typename _Iter::iterator_category; +}; + +template +struct __counted_iterator_value_type {}; + +template +struct __counted_iterator_value_type<_Iter> { + using value_type = iter_value_t<_Iter>; +}; + +template +class counted_iterator + : public __counted_iterator_concept<_Iter> + , public __counted_iterator_category<_Iter> + , public __counted_iterator_value_type<_Iter> +{ +public: + _LIBCPP_NO_UNIQUE_ADDRESS _Iter __current_ = _Iter(); + iter_difference_t<_Iter> __count_ = 0; + + using iterator_type = _Iter; + using difference_type = iter_difference_t<_Iter>; + + _LIBCPP_HIDE_FROM_ABI + constexpr counted_iterator() requires default_initializable<_Iter> = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr counted_iterator(_Iter __iter, iter_difference_t<_Iter> __n) + : __current_(_VSTD::move(__iter)), __count_(__n) { + _LIBCPP_ASSERT(__n >= 0, "__n must not be negative."); + } + + template + requires convertible_to + _LIBCPP_HIDE_FROM_ABI + constexpr counted_iterator(const counted_iterator<_I2>& __other) + : __current_(__other.__current_), __count_(__other.__count_) {} + + template + requires assignable_from<_Iter&, const _I2&> + _LIBCPP_HIDE_FROM_ABI + constexpr counted_iterator& operator=(const counted_iterator<_I2>& __other) { + __current_ = __other.__current_; + __count_ = __other.__count_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr const _Iter& base() const& noexcept { return __current_; } + + _LIBCPP_HIDE_FROM_ABI + constexpr _Iter base() && { return _VSTD::move(__current_); } + + _LIBCPP_HIDE_FROM_ABI + constexpr iter_difference_t<_Iter> count() const noexcept { return __count_; } + + _LIBCPP_HIDE_FROM_ABI + constexpr decltype(auto) operator*() { + _LIBCPP_ASSERT(__count_ > 0, "Iterator is equal to or past end."); + return *__current_; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr decltype(auto) operator*() const + requires __dereferenceable + { + _LIBCPP_ASSERT(__count_ > 0, "Iterator is equal to or past end."); + return *__current_; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto operator->() const noexcept + requires contiguous_iterator<_Iter> + { + return _VSTD::to_address(__current_); + } + + _LIBCPP_HIDE_FROM_ABI + constexpr counted_iterator& operator++() { + _LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end."); + ++__current_; + --__count_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + decltype(auto) operator++(int) { + _LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end."); + --__count_; +#ifndef _LIBCPP_NO_EXCEPTIONS + try { return __current_++; } + catch(...) { ++__count_; throw; } +#else + return __current_++; +#endif // _LIBCPP_NO_EXCEPTIONS + } + + _LIBCPP_HIDE_FROM_ABI + constexpr counted_iterator operator++(int) + requires forward_iterator<_Iter> + { + _LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end."); + counted_iterator __tmp = *this; + ++*this; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr counted_iterator& operator--() + requires bidirectional_iterator<_Iter> + { + --__current_; + ++__count_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr counted_iterator operator--(int) + requires bidirectional_iterator<_Iter> + { + counted_iterator __tmp = *this; + --*this; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr counted_iterator operator+(iter_difference_t<_Iter> __n) const + requires random_access_iterator<_Iter> + { + return counted_iterator(__current_ + __n, __count_ - __n); + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr counted_iterator operator+( + iter_difference_t<_Iter> __n, const counted_iterator& __x) + requires random_access_iterator<_Iter> + { + return __x + __n; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr counted_iterator& operator+=(iter_difference_t<_Iter> __n) + requires random_access_iterator<_Iter> + { + _LIBCPP_ASSERT(__n <= __count_, "Cannot advance iterator past end."); + __current_ += __n; + __count_ -= __n; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr counted_iterator operator-(iter_difference_t<_Iter> __n) const + requires random_access_iterator<_Iter> + { + return counted_iterator(__current_ - __n, __count_ + __n); + } + + template _I2> + _LIBCPP_HIDE_FROM_ABI + friend constexpr iter_difference_t<_I2> operator-( + const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs) + { + return __rhs.__count_ - __lhs.__count_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr iter_difference_t<_Iter> operator-( + const counted_iterator& __lhs, default_sentinel_t) + { + return -__lhs.__count_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr iter_difference_t<_Iter> operator-( + default_sentinel_t, const counted_iterator& __rhs) + { + return __rhs.__count_; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr counted_iterator& operator-=(iter_difference_t<_Iter> __n) + requires random_access_iterator<_Iter> + { + _LIBCPP_ASSERT(-__n <= __count_, "Attempt to subtract too large of a size: " + "counted_iterator would be decremented before the " + "first element of its range."); + __current_ -= __n; + __count_ += __n; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr decltype(auto) operator[](iter_difference_t<_Iter> __n) const + requires random_access_iterator<_Iter> + { + _LIBCPP_ASSERT(__n < __count_, "Subscript argument must be less than size."); + return __current_[__n]; + } + + template _I2> + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==( + const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs) + { + return __lhs.__count_ == __rhs.__count_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==( + const counted_iterator& __lhs, default_sentinel_t) + { + return __lhs.__count_ == 0; + } + + template _I2> + _LIBCPP_HIDE_FROM_ABI friend constexpr strong_ordering operator<=>( + const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs) + { + return __rhs.__count_ <=> __lhs.__count_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr iter_rvalue_reference_t<_Iter> iter_move(const counted_iterator& __i) + noexcept(noexcept(ranges::iter_move(__i.__current_))) + requires input_iterator<_Iter> + { + _LIBCPP_ASSERT(__i.__count_ > 0, "Iterator must not be past end of range."); + return ranges::iter_move(__i.__current_); + } + + template _I2> + _LIBCPP_HIDE_FROM_ABI + friend constexpr void iter_swap(const counted_iterator& __x, const counted_iterator<_I2>& __y) + noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) + { + _LIBCPP_ASSERT(__x.__count_ > 0 && __y.__count_ > 0, + "Iterators must not be past end of range."); + return ranges::iter_swap(__x.__current_, __y.__current_); + } +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(counted_iterator); + +template + requires same_as<_ITER_TRAITS<_Iter>, iterator_traits<_Iter>> +struct iterator_traits> : iterator_traits<_Iter> { + using pointer = conditional_t, + add_pointer_t>, void>; +}; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_COUNTED_ITERATOR_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/data.h b/app/src/main/cpp/libcxx/include/__iterator/data.h new file mode 100644 index 0000000..88eb752 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/data.h @@ -0,0 +1,51 @@ +// -*- 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 _LIBCPP___ITERATOR_DATA_H +#define _LIBCPP___ITERATOR_DATA_H + +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +template constexpr +_LIBCPP_INLINE_VISIBILITY +auto data(_Cont& __c) +_NOEXCEPT_(noexcept(__c.data())) +-> decltype (__c.data()) +{ return __c.data(); } + +template constexpr +_LIBCPP_INLINE_VISIBILITY +auto data(const _Cont& __c) +_NOEXCEPT_(noexcept(__c.data())) +-> decltype (__c.data()) +{ return __c.data(); } + +template +_LIBCPP_INLINE_VISIBILITY +constexpr _Tp* data(_Tp (&__array)[_Sz]) noexcept { return __array; } + +template +_LIBCPP_INLINE_VISIBILITY +constexpr const _Ep* data(initializer_list<_Ep> __il) noexcept { return __il.begin(); } + +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_DATA_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/default_sentinel.h b/app/src/main/cpp/libcxx/include/__iterator/default_sentinel.h new file mode 100644 index 0000000..669032a --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/default_sentinel.h @@ -0,0 +1,30 @@ +// -*- 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 _LIBCPP___ITERATOR_DEFAULT_SENTINEL_H +#define _LIBCPP___ITERATOR_DEFAULT_SENTINEL_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +struct default_sentinel_t { }; +inline constexpr default_sentinel_t default_sentinel{}; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_DEFAULT_SENTINEL_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/distance.h b/app/src/main/cpp/libcxx/include/__iterator/distance.h new file mode 100644 index 0000000..681e20d --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/distance.h @@ -0,0 +1,108 @@ +// -*- 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 _LIBCPP___ITERATOR_DISTANCE_H +#define _LIBCPP___ITERATOR_DISTANCE_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iterator_traits.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/size.h> +#include <__type_traits/decay.h> +#include <__type_traits/remove_cvref.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +typename iterator_traits<_InputIter>::difference_type +__distance(_InputIter __first, _InputIter __last, input_iterator_tag) +{ + typename iterator_traits<_InputIter>::difference_type __r(0); + for (; __first != __last; ++__first) + ++__r; + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +typename iterator_traits<_RandIter>::difference_type +__distance(_RandIter __first, _RandIter __last, random_access_iterator_tag) +{ + return __last - __first; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +typename iterator_traits<_InputIter>::difference_type +distance(_InputIter __first, _InputIter __last) +{ + return _VSTD::__distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category()); +} + +#if _LIBCPP_STD_VER > 17 + +// [range.iter.op.distance] + +namespace ranges { +namespace __distance { + +struct __fn { + template _Sp> + requires (!sized_sentinel_for<_Sp, _Ip>) + _LIBCPP_HIDE_FROM_ABI + constexpr iter_difference_t<_Ip> operator()(_Ip __first, _Sp __last) const { + iter_difference_t<_Ip> __n = 0; + while (__first != __last) { + ++__first; + ++__n; + } + return __n; + } + + template> _Sp> + _LIBCPP_HIDE_FROM_ABI + constexpr iter_difference_t<_Ip> operator()(_Ip&& __first, _Sp __last) const { + if constexpr (sized_sentinel_for<_Sp, __remove_cvref_t<_Ip>>) { + return __last - __first; + } else { + return __last - decay_t<_Ip>(__first); + } + } + + template + _LIBCPP_HIDE_FROM_ABI + constexpr range_difference_t<_Rp> operator()(_Rp&& __r) const { + if constexpr (sized_range<_Rp>) { + return static_cast>(ranges::size(__r)); + } else { + return operator()(ranges::begin(__r), ranges::end(__r)); + } + } +}; + +} // namespace __distance + +inline namespace __cpo { + inline constexpr auto distance = __distance::__fn{}; +} // namespace __cpo +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_DISTANCE_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/empty.h b/app/src/main/cpp/libcxx/include/__iterator/empty.h new file mode 100644 index 0000000..748ca9e --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/empty.h @@ -0,0 +1,44 @@ +// -*- 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 _LIBCPP___ITERATOR_EMPTY_H +#define _LIBCPP___ITERATOR_EMPTY_H + +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +template +_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY +constexpr auto empty(const _Cont& __c) +_NOEXCEPT_(noexcept(__c.empty())) +-> decltype (__c.empty()) +{ return __c.empty(); } + +template +_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY +constexpr bool empty(const _Tp (&)[_Sz]) noexcept { return false; } + +template +_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY +constexpr bool empty(initializer_list<_Ep> __il) noexcept { return __il.size() == 0; } + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_EMPTY_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/erase_if_container.h b/app/src/main/cpp/libcxx/include/__iterator/erase_if_container.h new file mode 100644 index 0000000..d7c71a9 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/erase_if_container.h @@ -0,0 +1,40 @@ +// -*- 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 _LIBCPP___ITERATOR_ERASE_IF_CONTAINER_H +#define _LIBCPP___ITERATOR_ERASE_IF_CONTAINER_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI +typename _Container::size_type +__libcpp_erase_if_container(_Container& __c, _Predicate& __pred) { + typename _Container::size_type __old_size = __c.size(); + + const typename _Container::iterator __last = __c.end(); + for (typename _Container::iterator __iter = __c.begin(); __iter != __last;) { + if (__pred(*__iter)) + __iter = __c.erase(__iter); + else + ++__iter; + } + + return __old_size - __c.size(); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_ERASE_IF_CONTAINER_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/front_insert_iterator.h b/app/src/main/cpp/libcxx/include/__iterator/front_insert_iterator.h new file mode 100644 index 0000000..e278359 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/front_insert_iterator.h @@ -0,0 +1,71 @@ +// -*- 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 _LIBCPP___ITERATOR_FRONT_INSERT_ITERATOR_H +#define _LIBCPP___ITERATOR_FRONT_INSERT_ITERATOR_H + +#include <__config> +#include <__iterator/iterator.h> +#include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template +class _LIBCPP_TEMPLATE_VIS front_insert_iterator +#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES) + : public iterator +#endif +{ +_LIBCPP_SUPPRESS_DEPRECATED_POP +protected: + _Container* container; +public: + typedef output_iterator_tag iterator_category; + typedef void value_type; +#if _LIBCPP_STD_VER > 17 + typedef ptrdiff_t difference_type; +#else + typedef void difference_type; +#endif + typedef void pointer; + typedef void reference; + typedef _Container container_type; + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit front_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator=(const typename _Container::value_type& __value) + {container->push_front(__value); return *this;} +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator=(typename _Container::value_type&& __value) + {container->push_front(_VSTD::move(__value)); return *this;} +#endif // _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator*() {return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator++() {return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator operator++(int) {return *this;} +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(front_insert_iterator); + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +front_insert_iterator<_Container> +front_inserter(_Container& __x) +{ + return front_insert_iterator<_Container>(__x); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_FRONT_INSERT_ITERATOR_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/incrementable_traits.h b/app/src/main/cpp/libcxx/include/__iterator/incrementable_traits.h new file mode 100644 index 0000000..3d06dc0 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/incrementable_traits.h @@ -0,0 +1,78 @@ +// -*- 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 _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H +#define _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H + +#include <__concepts/arithmetic.h> +#include <__config> +#include <__type_traits/conditional.h> +#include <__type_traits/is_object.h> +#include <__type_traits/is_primary_template.h> +#include <__type_traits/make_signed.h> +#include <__type_traits/remove_cvref.h> +#include <__utility/declval.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [incrementable.traits] +template struct incrementable_traits {}; + +template +requires is_object_v<_Tp> +struct incrementable_traits<_Tp*> { + using difference_type = ptrdiff_t; +}; + +template +struct incrementable_traits : incrementable_traits<_Ip> {}; + +template +concept __has_member_difference_type = requires { typename _Tp::difference_type; }; + +template<__has_member_difference_type _Tp> +struct incrementable_traits<_Tp> { + using difference_type = typename _Tp::difference_type; +}; + +template +concept __has_integral_minus = + requires(const _Tp& __x, const _Tp& __y) { + { __x - __y } -> integral; + }; + +template<__has_integral_minus _Tp> +requires (!__has_member_difference_type<_Tp>) +struct incrementable_traits<_Tp> { + using difference_type = make_signed_t() - std::declval<_Tp>())>; +}; + +template +struct iterator_traits; + +// Let `RI` be `remove_cvref_t`. The type `iter_difference_t` denotes +// `incrementable_traits::difference_type` if `iterator_traits` names a specialization +// generated from the primary template, and `iterator_traits::difference_type` otherwise. +template +using iter_difference_t = typename conditional_t<__is_primary_template > >::value, + incrementable_traits >, + iterator_traits > >::difference_type; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/indirectly_comparable.h b/app/src/main/cpp/libcxx/include/__iterator/indirectly_comparable.h new file mode 100644 index 0000000..868190f --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/indirectly_comparable.h @@ -0,0 +1,34 @@ +// -*- 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 _LIBCPP___ITERATOR_INDIRECTLY_COMPARABLE_H +#define _LIBCPP___ITERATOR_INDIRECTLY_COMPARABLE_H + +#include <__config> +#include <__functional/identity.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +concept indirectly_comparable = + indirect_binary_predicate<_Rp, projected<_I1, _P1>, projected<_I2, _P2>>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_INDIRECTLY_COMPARABLE_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/insert_iterator.h b/app/src/main/cpp/libcxx/include/__iterator/insert_iterator.h new file mode 100644 index 0000000..ecaea61 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/insert_iterator.h @@ -0,0 +1,81 @@ +// -*- 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 _LIBCPP___ITERATOR_INSERT_ITERATOR_H +#define _LIBCPP___ITERATOR_INSERT_ITERATOR_H + +#include <__config> +#include <__iterator/iterator.h> +#include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> +#include <__ranges/access.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 +template +using __insert_iterator_iter_t = ranges::iterator_t<_Container>; +#else +template +using __insert_iterator_iter_t = typename _Container::iterator; +#endif + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template +class _LIBCPP_TEMPLATE_VIS insert_iterator +#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES) + : public iterator +#endif +{ +_LIBCPP_SUPPRESS_DEPRECATED_POP +protected: + _Container* container; + __insert_iterator_iter_t<_Container> iter; +public: + typedef output_iterator_tag iterator_category; + typedef void value_type; +#if _LIBCPP_STD_VER > 17 + typedef ptrdiff_t difference_type; +#else + typedef void difference_type; +#endif + typedef void pointer; + typedef void reference; + typedef _Container container_type; + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator(_Container& __x, __insert_iterator_iter_t<_Container> __i) + : container(_VSTD::addressof(__x)), iter(__i) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator=(const typename _Container::value_type& __value) + {iter = container->insert(iter, __value); ++iter; return *this;} +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator=(typename _Container::value_type&& __value) + {iter = container->insert(iter, _VSTD::move(__value)); ++iter; return *this;} +#endif // _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator*() {return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator++() {return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator++(int) {return *this;} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +insert_iterator<_Container> +inserter(_Container& __x, __insert_iterator_iter_t<_Container> __i) +{ + return insert_iterator<_Container>(__x, __i); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_INSERT_ITERATOR_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/istream_iterator.h b/app/src/main/cpp/libcxx/include/__iterator/istream_iterator.h new file mode 100644 index 0000000..a056961 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/istream_iterator.h @@ -0,0 +1,105 @@ +// -*- 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 _LIBCPP___ITERATOR_ISTREAM_ITERATOR_H +#define _LIBCPP___ITERATOR_ISTREAM_ITERATOR_H + +#include <__config> +#include <__iterator/default_sentinel.h> +#include <__iterator/iterator.h> +#include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> +#include +#include // for forward declarations of char_traits and basic_istream + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template , class _Distance = ptrdiff_t> +class _LIBCPP_TEMPLATE_VIS istream_iterator +#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES) + : public iterator +#endif +{ +_LIBCPP_SUPPRESS_DEPRECATED_POP +public: + typedef input_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_istream<_CharT,_Traits> istream_type; +private: + istream_type* __in_stream_; + _Tp __value_; +public: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(nullptr), __value_() {} +#if _LIBCPP_STD_VER > 17 + _LIBCPP_HIDE_FROM_ABI constexpr istream_iterator(default_sentinel_t) : istream_iterator() {} +#endif // _LIBCPP_STD_VER > 17 + _LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(_VSTD::addressof(__s)) + { + if (!(*__in_stream_ >> __value_)) + __in_stream_ = nullptr; + } + + _LIBCPP_INLINE_VISIBILITY const _Tp& operator*() const {return __value_;} + _LIBCPP_INLINE_VISIBILITY const _Tp* operator->() const {return _VSTD::addressof((operator*()));} + _LIBCPP_INLINE_VISIBILITY istream_iterator& operator++() + { + if (!(*__in_stream_ >> __value_)) + __in_stream_ = nullptr; + return *this; + } + _LIBCPP_INLINE_VISIBILITY istream_iterator operator++(int) + {istream_iterator __t(*this); ++(*this); return __t;} + + template + friend _LIBCPP_INLINE_VISIBILITY + bool + operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x, + const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y); + +#if _LIBCPP_STD_VER > 17 + friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istream_iterator& __i, default_sentinel_t) { + return __i.__in_stream_ == nullptr; + } +#endif // _LIBCPP_STD_VER > 17 +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x, + const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y) +{ + return __x.__in_stream_ == __y.__in_stream_; +} + +#if _LIBCPP_STD_VER <= 17 +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x, + const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y) +{ + return !(__x == __y); +} +#endif // _LIBCPP_STD_VER <= 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_ISTREAM_ITERATOR_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/istreambuf_iterator.h b/app/src/main/cpp/libcxx/include/__iterator/istreambuf_iterator.h new file mode 100644 index 0000000..bc53a6a --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/istreambuf_iterator.h @@ -0,0 +1,119 @@ +// -*- 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 _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H +#define _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H + +#include <__config> +#include <__iterator/default_sentinel.h> +#include <__iterator/iterator.h> +#include <__iterator/iterator_traits.h> +#include // for forward declaration of basic_streambuf + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template +class _LIBCPP_TEMPLATE_VIS istreambuf_iterator +#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES) + : public iterator +#endif +{ +_LIBCPP_SUPPRESS_DEPRECATED_POP +public: + typedef input_iterator_tag iterator_category; + typedef _CharT value_type; + typedef typename _Traits::off_type difference_type; + typedef _CharT* pointer; + typedef _CharT reference; + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename _Traits::int_type int_type; + typedef basic_streambuf<_CharT,_Traits> streambuf_type; + typedef basic_istream<_CharT,_Traits> istream_type; +private: + mutable streambuf_type* __sbuf_; + + class __proxy + { + char_type __keep_; + streambuf_type* __sbuf_; + _LIBCPP_INLINE_VISIBILITY + explicit __proxy(char_type __c, streambuf_type* __s) + : __keep_(__c), __sbuf_(__s) {} + friend class istreambuf_iterator; + public: + _LIBCPP_INLINE_VISIBILITY char_type operator*() const {return __keep_;} + }; + + _LIBCPP_INLINE_VISIBILITY + bool __test_for_eof() const + { + if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sgetc(), traits_type::eof())) + __sbuf_ = nullptr; + return __sbuf_ == nullptr; + } +public: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(nullptr) {} +#if _LIBCPP_STD_VER > 17 + _LIBCPP_INLINE_VISIBILITY constexpr istreambuf_iterator(default_sentinel_t) noexcept + : istreambuf_iterator() {} +#endif // _LIBCPP_STD_VER > 17 + _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(istream_type& __s) _NOEXCEPT + : __sbuf_(__s.rdbuf()) {} + _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(streambuf_type* __s) _NOEXCEPT + : __sbuf_(__s) {} + _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(const __proxy& __p) _NOEXCEPT + : __sbuf_(__p.__sbuf_) {} + + _LIBCPP_INLINE_VISIBILITY char_type operator*() const + {return static_cast(__sbuf_->sgetc());} + _LIBCPP_INLINE_VISIBILITY istreambuf_iterator& operator++() + { + __sbuf_->sbumpc(); + return *this; + } + _LIBCPP_INLINE_VISIBILITY __proxy operator++(int) + { + return __proxy(__sbuf_->sbumpc(), __sbuf_); + } + + _LIBCPP_INLINE_VISIBILITY bool equal(const istreambuf_iterator& __b) const + {return __test_for_eof() == __b.__test_for_eof();} + +#if _LIBCPP_STD_VER > 17 + friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istreambuf_iterator& __i, default_sentinel_t) { + return __i.__test_for_eof(); + } +#endif // _LIBCPP_STD_VER > 17 +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +bool operator==(const istreambuf_iterator<_CharT,_Traits>& __a, + const istreambuf_iterator<_CharT,_Traits>& __b) + {return __a.equal(__b);} + +#if _LIBCPP_STD_VER <= 17 +template +inline _LIBCPP_INLINE_VISIBILITY +bool operator!=(const istreambuf_iterator<_CharT,_Traits>& __a, + const istreambuf_iterator<_CharT,_Traits>& __b) + {return !__a.equal(__b);} +#endif // _LIBCPP_STD_VER <= 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/iter_move.h b/app/src/main/cpp/libcxx/include/__iterator/iter_move.h new file mode 100644 index 0000000..a7d9413 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/iter_move.h @@ -0,0 +1,104 @@ +// -*- 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 _LIBCPP___ITERATOR_ITER_MOVE_H +#define _LIBCPP___ITERATOR_ITER_MOVE_H + +#include <__concepts/class_or_enum.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__type_traits/is_reference.h> +#include <__type_traits/remove_cvref.h> +#include <__utility/declval.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [iterator.cust.move] + +namespace ranges { +namespace __iter_move { + +void iter_move(); + +template +concept __unqualified_iter_move = + __class_or_enum> && + requires (_Tp&& __t) { + // NOLINTNEXTLINE(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap + iter_move(std::forward<_Tp>(__t)); + }; + +template +concept __move_deref = + !__unqualified_iter_move<_Tp> && + requires (_Tp&& __t) { + *__t; + requires is_lvalue_reference_v; + }; + +template +concept __just_deref = + !__unqualified_iter_move<_Tp> && + !__move_deref<_Tp> && + requires (_Tp&& __t) { + *__t; + requires (!is_lvalue_reference_v); + }; + +// [iterator.cust.move] + +struct __fn { + // NOLINTBEGIN(libcpp-robust-against-adl) iter_move ADL calls should only be made through ranges::iter_move + template + requires __unqualified_iter_move<_Ip> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Ip&& __i) const + noexcept(noexcept(iter_move(std::forward<_Ip>(__i)))) + { + return iter_move(std::forward<_Ip>(__i)); + } + // NOLINTEND(libcpp-robust-against-adl) + + template + requires __move_deref<_Ip> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Ip&& __i) const + noexcept(noexcept(std::move(*std::forward<_Ip>(__i)))) + -> decltype( std::move(*std::forward<_Ip>(__i))) + { return std::move(*std::forward<_Ip>(__i)); } + + template + requires __just_deref<_Ip> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Ip&& __i) const + noexcept(noexcept(*std::forward<_Ip>(__i))) + -> decltype( *std::forward<_Ip>(__i)) + { return *std::forward<_Ip>(__i); } +}; +} // namespace __iter_move + +inline namespace __cpo { + inline constexpr auto iter_move = __iter_move::__fn{}; +} // namespace __cpo +} // namespace ranges + +template<__dereferenceable _Tp> + requires requires(_Tp& __t) { { ranges::iter_move(__t) } -> __can_reference; } +using iter_rvalue_reference_t = decltype(ranges::iter_move(std::declval<_Tp&>())); + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_ITER_MOVE_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/iter_swap.h b/app/src/main/cpp/libcxx/include/__iterator/iter_swap.h new file mode 100644 index 0000000..d4c0dca --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/iter_swap.h @@ -0,0 +1,113 @@ +// -*- 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 _LIBCPP___ITERATOR_ITER_SWAP_H +#define _LIBCPP___ITERATOR_ITER_SWAP_H + +#include <__concepts/class_or_enum.h> +#include <__concepts/swappable.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/iter_move.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/readable_traits.h> +#include <__type_traits/remove_cvref.h> +#include <__utility/declval.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [iter.cust.swap] + +namespace ranges { +namespace __iter_swap { + template + void iter_swap(_I1, _I2) = delete; + + template + concept __unqualified_iter_swap = + (__class_or_enum> || __class_or_enum>) && + requires (_T1&& __x, _T2&& __y) { + // NOLINTNEXTLINE(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap + iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y)); + }; + + template + concept __readable_swappable = + indirectly_readable<_T1> && indirectly_readable<_T2> && + swappable_with, iter_reference_t<_T2>>; + + + struct __fn { + // NOLINTBEGIN(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap + template + requires __unqualified_iter_swap<_T1, _T2> + _LIBCPP_HIDE_FROM_ABI + constexpr void operator()(_T1&& __x, _T2&& __y) const + noexcept(noexcept(iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y)))) + { + (void)iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y)); + } + // NOLINTEND(libcpp-robust-against-adl) + + template + requires (!__unqualified_iter_swap<_T1, _T2>) && + __readable_swappable<_T1, _T2> + _LIBCPP_HIDE_FROM_ABI + constexpr void operator()(_T1&& __x, _T2&& __y) const + noexcept(noexcept(ranges::swap(*_VSTD::forward<_T1>(__x), *_VSTD::forward<_T2>(__y)))) + { + ranges::swap(*_VSTD::forward<_T1>(__x), *_VSTD::forward<_T2>(__y)); + } + + template + requires (!__unqualified_iter_swap<_T1, _T2> && + !__readable_swappable<_T1, _T2>) && + indirectly_movable_storable<_T1, _T2> && + indirectly_movable_storable<_T2, _T1> + _LIBCPP_HIDE_FROM_ABI + constexpr void operator()(_T1&& __x, _T2&& __y) const + noexcept(noexcept(iter_value_t<_T2>(ranges::iter_move(__y))) && + noexcept(*__y = ranges::iter_move(__x)) && + noexcept(*_VSTD::forward<_T1>(__x) = std::declval>())) + { + iter_value_t<_T2> __old(ranges::iter_move(__y)); + *__y = ranges::iter_move(__x); + *_VSTD::forward<_T1>(__x) = _VSTD::move(__old); + } + }; +} // namespace __iter_swap + +inline namespace __cpo { + inline constexpr auto iter_swap = __iter_swap::__fn{}; +} // namespace __cpo +} // namespace ranges + +template +concept indirectly_swappable = + indirectly_readable<_I1> && indirectly_readable<_I2> && + requires(const _I1 __i1, const _I2 __i2) { + ranges::iter_swap(__i1, __i1); + ranges::iter_swap(__i2, __i2); + ranges::iter_swap(__i1, __i2); + ranges::iter_swap(__i2, __i1); + }; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_ITER_SWAP_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/iterator.h b/app/src/main/cpp/libcxx/include/__iterator/iterator.h new file mode 100644 index 0000000..b417eea --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/iterator.h @@ -0,0 +1,35 @@ +// -*- 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 _LIBCPP___ITERATOR_ITERATOR_H +#define _LIBCPP___ITERATOR_ITERATOR_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 iterator +{ + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Pointer pointer; + typedef _Reference reference; + typedef _Category iterator_category; +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_ITERATOR_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/iterator_traits.h b/app/src/main/cpp/libcxx/include/__iterator/iterator_traits.h new file mode 100644 index 0000000..c9d8944 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/iterator_traits.h @@ -0,0 +1,539 @@ +// -*- 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 _LIBCPP___ITERATOR_ITERATOR_TRAITS_H +#define _LIBCPP___ITERATOR_ITERATOR_TRAITS_H + +#include <__concepts/arithmetic.h> +#include <__concepts/constructible.h> +#include <__concepts/convertible_to.h> +#include <__concepts/copyable.h> +#include <__concepts/equality_comparable.h> +#include <__concepts/same_as.h> +#include <__concepts/totally_ordered.h> +#include <__config> +#include <__fwd/pair.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/readable_traits.h> +#include <__type_traits/add_const.h> +#include <__type_traits/common_reference.h> +#include <__type_traits/conditional.h> +#include <__type_traits/disjunction.h> +#include <__type_traits/is_convertible.h> +#include <__type_traits/is_object.h> +#include <__type_traits/is_primary_template.h> +#include <__type_traits/is_reference.h> +#include <__type_traits/is_valid_expansion.h> +#include <__type_traits/remove_const.h> +#include <__type_traits/remove_cv.h> +#include <__type_traits/remove_cvref.h> +#include <__type_traits/void_t.h> +#include <__utility/declval.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +using __with_reference = _Tp&; + +template +concept __can_reference = requires { + typename __with_reference<_Tp>; +}; + +template +concept __dereferenceable = requires(_Tp& __t) { + { *__t } -> __can_reference; // not required to be equality-preserving +}; + +// [iterator.traits] +template<__dereferenceable _Tp> +using iter_reference_t = decltype(*std::declval<_Tp&>()); + +#endif // _LIBCPP_STD_VER > 17 + +template +struct _LIBCPP_TEMPLATE_VIS iterator_traits; + +struct _LIBCPP_TEMPLATE_VIS input_iterator_tag {}; +struct _LIBCPP_TEMPLATE_VIS output_iterator_tag {}; +struct _LIBCPP_TEMPLATE_VIS forward_iterator_tag : public input_iterator_tag {}; +struct _LIBCPP_TEMPLATE_VIS bidirectional_iterator_tag : public forward_iterator_tag {}; +struct _LIBCPP_TEMPLATE_VIS random_access_iterator_tag : public bidirectional_iterator_tag {}; +#if _LIBCPP_STD_VER > 17 +struct _LIBCPP_TEMPLATE_VIS contiguous_iterator_tag : public random_access_iterator_tag {}; +#endif + +template +struct __iter_traits_cache { + using type = _If< + __is_primary_template >::value, + _Iter, + iterator_traits<_Iter> + >; +}; +template +using _ITER_TRAITS = typename __iter_traits_cache<_Iter>::type; + +struct __iter_concept_concept_test { + template + using _Apply = typename _ITER_TRAITS<_Iter>::iterator_concept; +}; +struct __iter_concept_category_test { + template + using _Apply = typename _ITER_TRAITS<_Iter>::iterator_category; +}; +struct __iter_concept_random_fallback { + template + using _Apply = __enable_if_t< + __is_primary_template >::value, + random_access_iterator_tag + >; +}; + +template struct __test_iter_concept + : _IsValidExpansion<_Tester::template _Apply, _Iter>, + _Tester +{ +}; + +template +struct __iter_concept_cache { + using type = _Or< + __test_iter_concept<_Iter, __iter_concept_concept_test>, + __test_iter_concept<_Iter, __iter_concept_category_test>, + __test_iter_concept<_Iter, __iter_concept_random_fallback> + >; +}; + +template +using _ITER_CONCEPT = typename __iter_concept_cache<_Iter>::type::template _Apply<_Iter>; + + +template +struct __has_iterator_typedefs +{ +private: + template static false_type __test(...); + template static true_type __test(__void_t* = nullptr, + __void_t* = nullptr, + __void_t* = nullptr, + __void_t* = nullptr, + __void_t* = nullptr); +public: + static const bool value = decltype(__test<_Tp>(0,0,0,0,0))::value; +}; + + +template +struct __has_iterator_category +{ +private: + template static false_type __test(...); + template static true_type __test(typename _Up::iterator_category* = nullptr); +public: + static const bool value = decltype(__test<_Tp>(nullptr))::value; +}; + +template +struct __has_iterator_concept +{ +private: + template static false_type __test(...); + template static true_type __test(typename _Up::iterator_concept* = nullptr); +public: + static const bool value = decltype(__test<_Tp>(nullptr))::value; +}; + +#if _LIBCPP_STD_VER > 17 + +// The `cpp17-*-iterator` exposition-only concepts have very similar names to the `Cpp17*Iterator` named requirements +// from `[iterator.cpp17]`. To avoid confusion between the two, the exposition-only concepts have been banished to +// a "detail" namespace indicating they have a niche use-case. +namespace __iterator_traits_detail { +template +concept __cpp17_iterator = + requires(_Ip __i) { + { *__i } -> __can_reference; + { ++__i } -> same_as<_Ip&>; + { *__i++ } -> __can_reference; + } && + copyable<_Ip>; + +template +concept __cpp17_input_iterator = + __cpp17_iterator<_Ip> && + equality_comparable<_Ip> && + requires(_Ip __i) { + typename incrementable_traits<_Ip>::difference_type; + typename indirectly_readable_traits<_Ip>::value_type; + typename common_reference_t&&, + typename indirectly_readable_traits<_Ip>::value_type&>; + typename common_reference_t::value_type&>; + requires signed_integral::difference_type>; + }; + +template +concept __cpp17_forward_iterator = + __cpp17_input_iterator<_Ip> && + constructible_from<_Ip> && + is_lvalue_reference_v> && + same_as>, + typename indirectly_readable_traits<_Ip>::value_type> && + requires(_Ip __i) { + { __i++ } -> convertible_to<_Ip const&>; + { *__i++ } -> same_as>; + }; + +template +concept __cpp17_bidirectional_iterator = + __cpp17_forward_iterator<_Ip> && + requires(_Ip __i) { + { --__i } -> same_as<_Ip&>; + { __i-- } -> convertible_to<_Ip const&>; + { *__i-- } -> same_as>; + }; + +template +concept __cpp17_random_access_iterator = + __cpp17_bidirectional_iterator<_Ip> && + totally_ordered<_Ip> && + requires(_Ip __i, typename incrementable_traits<_Ip>::difference_type __n) { + { __i += __n } -> same_as<_Ip&>; + { __i -= __n } -> same_as<_Ip&>; + { __i + __n } -> same_as<_Ip>; + { __n + __i } -> same_as<_Ip>; + { __i - __n } -> same_as<_Ip>; + { __i - __i } -> same_as; // NOLINT(misc-redundant-expression) ; This is llvm.org/PR54114 + { __i[__n] } -> convertible_to>; + }; +} // namespace __iterator_traits_detail + +template +concept __has_member_reference = requires { typename _Ip::reference; }; + +template +concept __has_member_pointer = requires { typename _Ip::pointer; }; + +template +concept __has_member_iterator_category = requires { typename _Ip::iterator_category; }; + +template +concept __specifies_members = requires { + typename _Ip::value_type; + typename _Ip::difference_type; + requires __has_member_reference<_Ip>; + requires __has_member_iterator_category<_Ip>; + }; + +template +struct __iterator_traits_member_pointer_or_void { + using type = void; +}; + +template<__has_member_pointer _Tp> +struct __iterator_traits_member_pointer_or_void<_Tp> { + using type = typename _Tp::pointer; +}; + +template +concept __cpp17_iterator_missing_members = + !__specifies_members<_Tp> && + __iterator_traits_detail::__cpp17_iterator<_Tp>; + +template +concept __cpp17_input_iterator_missing_members = + __cpp17_iterator_missing_members<_Tp> && + __iterator_traits_detail::__cpp17_input_iterator<_Tp>; + +// Otherwise, `pointer` names `void`. +template +struct __iterator_traits_member_pointer_or_arrow_or_void { using type = void; }; + +// [iterator.traits]/3.2.1 +// If the qualified-id `I::pointer` is valid and denotes a type, `pointer` names that type. +template<__has_member_pointer _Ip> +struct __iterator_traits_member_pointer_or_arrow_or_void<_Ip> { using type = typename _Ip::pointer; }; + +// Otherwise, if `decltype(declval().operator->())` is well-formed, then `pointer` names that +// type. +template + requires requires(_Ip& __i) { __i.operator->(); } && (!__has_member_pointer<_Ip>) +struct __iterator_traits_member_pointer_or_arrow_or_void<_Ip> { + using type = decltype(std::declval<_Ip&>().operator->()); +}; + +// Otherwise, `reference` names `iter-reference-t`. +template +struct __iterator_traits_member_reference { using type = iter_reference_t<_Ip>; }; + +// [iterator.traits]/3.2.2 +// If the qualified-id `I::reference` is valid and denotes a type, `reference` names that type. +template<__has_member_reference _Ip> +struct __iterator_traits_member_reference<_Ip> { using type = typename _Ip::reference; }; + +// [iterator.traits]/3.2.3.4 +// input_iterator_tag +template +struct __deduce_iterator_category { + using type = input_iterator_tag; +}; + +// [iterator.traits]/3.2.3.1 +// `random_access_iterator_tag` if `I` satisfies `cpp17-random-access-iterator`, or otherwise +template<__iterator_traits_detail::__cpp17_random_access_iterator _Ip> +struct __deduce_iterator_category<_Ip> { + using type = random_access_iterator_tag; +}; + +// [iterator.traits]/3.2.3.2 +// `bidirectional_iterator_tag` if `I` satisfies `cpp17-bidirectional-iterator`, or otherwise +template<__iterator_traits_detail::__cpp17_bidirectional_iterator _Ip> +struct __deduce_iterator_category<_Ip> { + using type = bidirectional_iterator_tag; +}; + +// [iterator.traits]/3.2.3.3 +// `forward_iterator_tag` if `I` satisfies `cpp17-forward-iterator`, or otherwise +template<__iterator_traits_detail::__cpp17_forward_iterator _Ip> +struct __deduce_iterator_category<_Ip> { + using type = forward_iterator_tag; +}; + +template +struct __iterator_traits_iterator_category : __deduce_iterator_category<_Ip> {}; + +// [iterator.traits]/3.2.3 +// If the qualified-id `I::iterator-category` is valid and denotes a type, `iterator-category` names +// that type. +template<__has_member_iterator_category _Ip> +struct __iterator_traits_iterator_category<_Ip> { + using type = typename _Ip::iterator_category; +}; + +// otherwise, it names void. +template +struct __iterator_traits_difference_type { using type = void; }; + +// If the qualified-id `incrementable_traits::difference_type` is valid and denotes a type, then +// `difference_type` names that type; +template +requires requires { typename incrementable_traits<_Ip>::difference_type; } +struct __iterator_traits_difference_type<_Ip> { + using type = typename incrementable_traits<_Ip>::difference_type; +}; + +// [iterator.traits]/3.4 +// Otherwise, `iterator_traits` has no members by any of the above names. +template +struct __iterator_traits {}; + +// [iterator.traits]/3.1 +// If `I` has valid ([temp.deduct]) member types `difference-type`, `value-type`, `reference`, and +// `iterator-category`, then `iterator-traits` has the following publicly accessible members: +template<__specifies_members _Ip> +struct __iterator_traits<_Ip> { + using iterator_category = typename _Ip::iterator_category; + using value_type = typename _Ip::value_type; + using difference_type = typename _Ip::difference_type; + using pointer = typename __iterator_traits_member_pointer_or_void<_Ip>::type; + using reference = typename _Ip::reference; +}; + +// [iterator.traits]/3.2 +// Otherwise, if `I` satisfies the exposition-only concept `cpp17-input-iterator`, +// `iterator-traits` has the following publicly accessible members: +template<__cpp17_input_iterator_missing_members _Ip> +struct __iterator_traits<_Ip> { + using iterator_category = typename __iterator_traits_iterator_category<_Ip>::type; + using value_type = typename indirectly_readable_traits<_Ip>::value_type; + using difference_type = typename incrementable_traits<_Ip>::difference_type; + using pointer = typename __iterator_traits_member_pointer_or_arrow_or_void<_Ip>::type; + using reference = typename __iterator_traits_member_reference<_Ip>::type; +}; + +// Otherwise, if `I` satisfies the exposition-only concept `cpp17-iterator`, then +// `iterator_traits` has the following publicly accessible members: +template<__cpp17_iterator_missing_members _Ip> +struct __iterator_traits<_Ip> { + using iterator_category = output_iterator_tag; + using value_type = void; + using difference_type = typename __iterator_traits_difference_type<_Ip>::type; + using pointer = void; + using reference = void; +}; + +template +struct iterator_traits : __iterator_traits<_Ip> { + using __primary_template = iterator_traits; +}; + +#else // _LIBCPP_STD_VER > 17 + +template struct __iterator_traits {}; + +template struct __iterator_traits_impl {}; + +template +struct __iterator_traits_impl<_Iter, true> +{ + typedef typename _Iter::difference_type difference_type; + typedef typename _Iter::value_type value_type; + typedef typename _Iter::pointer pointer; + typedef typename _Iter::reference reference; + typedef typename _Iter::iterator_category iterator_category; +}; + +template +struct __iterator_traits<_Iter, true> + : __iterator_traits_impl + < + _Iter, + is_convertible::value || + is_convertible::value + > +{}; + +// iterator_traits will only have the nested types if Iterator::iterator_category +// exists. Else iterator_traits will be an empty class. This is a +// conforming extension which allows some programs to compile and behave as +// the client expects instead of failing at compile time. + +template +struct _LIBCPP_TEMPLATE_VIS iterator_traits + : __iterator_traits<_Iter, __has_iterator_typedefs<_Iter>::value> { + + using __primary_template = iterator_traits; +}; +#endif // _LIBCPP_STD_VER > 17 + +template +#if _LIBCPP_STD_VER > 17 +requires is_object_v<_Tp> +#endif +struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*> +{ + typedef ptrdiff_t difference_type; + typedef __remove_cv_t<_Tp> value_type; + typedef _Tp* pointer; + typedef _Tp& reference; + typedef random_access_iterator_tag iterator_category; +#if _LIBCPP_STD_VER > 17 + typedef contiguous_iterator_tag iterator_concept; +#endif +}; + +template >::value> +struct __has_iterator_category_convertible_to + : is_convertible::iterator_category, _Up> +{}; + +template +struct __has_iterator_category_convertible_to<_Tp, _Up, false> : false_type {}; + +template ::value> +struct __has_iterator_concept_convertible_to + : is_convertible +{}; + +template +struct __has_iterator_concept_convertible_to<_Tp, _Up, false> : false_type {}; + +template +struct __is_cpp17_input_iterator : public __has_iterator_category_convertible_to<_Tp, input_iterator_tag> {}; + +template +struct __is_cpp17_forward_iterator : public __has_iterator_category_convertible_to<_Tp, forward_iterator_tag> {}; + +template +struct __is_cpp17_bidirectional_iterator : public __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag> {}; + +template +struct __is_cpp17_random_access_iterator : public __has_iterator_category_convertible_to<_Tp, random_access_iterator_tag> {}; + +// __is_cpp17_contiguous_iterator determines if an iterator is known by +// libc++ to be contiguous, either because it advertises itself as such +// (in C++20) or because it is a pointer type or a known trivial wrapper +// around a (possibly fancy) pointer type, such as __wrap_iter. +// Such iterators receive special "contiguous" optimizations in +// std::copy and std::sort. +// +#if _LIBCPP_STD_VER > 17 +template +struct __is_cpp17_contiguous_iterator : _Or< + __has_iterator_category_convertible_to<_Tp, contiguous_iterator_tag>, + __has_iterator_concept_convertible_to<_Tp, contiguous_iterator_tag> +> {}; +#else +template +struct __is_cpp17_contiguous_iterator : false_type {}; +#endif + +// Any native pointer which is an iterator is also a contiguous iterator. +template +struct __is_cpp17_contiguous_iterator<_Up*> : true_type {}; + + +template +class __wrap_iter; + +template +struct __is_exactly_cpp17_input_iterator + : public integral_constant::value && + !__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value> {}; + +template +struct __is_exactly_cpp17_forward_iterator + : public integral_constant::value && + !__has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value> {}; + +template +struct __is_exactly_cpp17_bidirectional_iterator + : public integral_constant::value && + !__has_iterator_category_convertible_to<_Tp, random_access_iterator_tag>::value> {}; + +template +using __iter_value_type = typename iterator_traits<_InputIterator>::value_type; + +template +using __iter_key_type = __remove_const_t::value_type::first_type>; + +template +using __iter_mapped_type = typename iterator_traits<_InputIterator>::value_type::second_type; + +template +using __iter_to_alloc_type = pair< + typename add_const::value_type::first_type>::type, + typename iterator_traits<_InputIterator>::value_type::second_type>; + +template +using __iterator_category_type = typename iterator_traits<_Iter>::iterator_category; + +template +using __iterator_pointer_type = typename iterator_traits<_Iter>::pointer; + +template +using __iter_diff_t = typename iterator_traits<_Iter>::difference_type; + +template +using __iter_value_type = typename iterator_traits<_InputIterator>::value_type; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_ITERATOR_TRAITS_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/iterator_with_data.h b/app/src/main/cpp/libcxx/include/__iterator/iterator_with_data.h new file mode 100644 index 0000000..06c2fa6 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/iterator_with_data.h @@ -0,0 +1,100 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ITERATOR_ITERATOR_WITH_DATA_H +#define _LIBCPP___ITERATOR_ITERATOR_WITH_DATA_H + +#include <__compare/compare_three_way_result.h> +#include <__compare/three_way_comparable.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iter_move.h> +#include <__iterator/iter_swap.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/readable_traits.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER >= 20 + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class __iterator_with_data { + _Iterator __iter_{}; + _Data __data_{}; + +public: + using value_type = iter_value_t<_Iterator>; + using difference_type = iter_difference_t<_Iterator>; + + _LIBCPP_HIDE_FROM_ABI __iterator_with_data() = default; + + constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data(_Iterator __iter, _Data __data) + : __iter_(std::move(__iter)), __data_(std::move(__data)) {} + + constexpr _LIBCPP_HIDE_FROM_ABI _Iterator __get_iter() const { return __iter_; } + + constexpr _LIBCPP_HIDE_FROM_ABI _Data __get_data() && { return std::move(__data_); } + + friend constexpr _LIBCPP_HIDE_FROM_ABI bool + operator==(const __iterator_with_data& __lhs, const __iterator_with_data& __rhs) { + return __lhs.__iter_ == __rhs.__iter_; + } + + constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data& operator++() { + ++__iter_; + return *this; + } + + constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data operator++(int) { + auto __tmp = *this; + __iter_++; + return __tmp; + } + + constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data& operator--() + requires bidirectional_iterator<_Iterator> + { + --__iter_; + return *this; + } + + constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data operator--(int) + requires bidirectional_iterator<_Iterator> + { + auto __tmp = *this; + --__iter_; + return __tmp; + } + + constexpr _LIBCPP_HIDE_FROM_ABI iter_reference_t<_Iterator> operator*() const { return *__iter_; } + + _LIBCPP_HIDE_FROM_ABI friend constexpr iter_rvalue_reference_t<_Iterator> + iter_move(const __iterator_with_data& __iter) noexcept(noexcept(ranges::iter_move(__iter.__iter_))) { + return ranges::iter_move(__iter.__iter_); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr void + iter_swap(const __iterator_with_data& __lhs, + const __iterator_with_data& __rhs) noexcept(noexcept(ranges::iter_swap(__lhs.__iter_, __rhs.__iter_))) + requires indirectly_swappable<_Iterator> + { + return ranges::iter_swap(__lhs.__data_, __rhs.__iter_); + } +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 20 + +#endif // _LIBCPP___ITERATOR_ITERATOR_WITH_DATA_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/mergeable.h b/app/src/main/cpp/libcxx/include/__iterator/mergeable.h new file mode 100644 index 0000000..b9f2d08 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/mergeable.h @@ -0,0 +1,41 @@ +// -*- 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 _LIBCPP___ITERATOR_MERGEABLE_H +#define _LIBCPP___ITERATOR_MERGEABLE_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +concept mergeable = + input_iterator<_Input1> && + input_iterator<_Input2> && + weakly_incrementable<_Output> && + indirectly_copyable<_Input1, _Output> && + indirectly_copyable<_Input2, _Output> && + indirect_strict_weak_order<_Comp, projected<_Input1, _Proj1>, projected<_Input2, _Proj2>>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_MERGEABLE_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/move_iterator.h b/app/src/main/cpp/libcxx/include/__iterator/move_iterator.h new file mode 100644 index 0000000..fa806db --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/move_iterator.h @@ -0,0 +1,335 @@ +// -*- 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 _LIBCPP___ITERATOR_MOVE_ITERATOR_H +#define _LIBCPP___ITERATOR_MOVE_ITERATOR_H + +#include <__compare/compare_three_way_result.h> +#include <__compare/three_way_comparable.h> +#include <__concepts/assignable.h> +#include <__concepts/convertible_to.h> +#include <__concepts/derived_from.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iter_move.h> +#include <__iterator/iter_swap.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/move_sentinel.h> +#include <__iterator/readable_traits.h> +#include <__type_traits/conditional.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_assignable.h> +#include <__type_traits/is_constructible.h> +#include <__type_traits/is_convertible.h> +#include <__type_traits/is_reference.h> +#include <__type_traits/is_same.h> +#include <__type_traits/remove_reference.h> +#include <__utility/declval.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 +template +struct __move_iter_category_base {}; + +template + requires requires { typename iterator_traits<_Iter>::iterator_category; } +struct __move_iter_category_base<_Iter> { + using iterator_category = _If< + derived_from::iterator_category, random_access_iterator_tag>, + random_access_iterator_tag, + typename iterator_traits<_Iter>::iterator_category + >; +}; + +template +concept __move_iter_comparable = requires { + { std::declval() == std::declval<_Sent>() } -> convertible_to; +}; +#endif // _LIBCPP_STD_VER > 17 + +template +class _LIBCPP_TEMPLATE_VIS move_iterator +#if _LIBCPP_STD_VER > 17 + : public __move_iter_category_base<_Iter> +#endif +{ +public: +#if _LIBCPP_STD_VER > 17 + using iterator_type = _Iter; + using iterator_concept = input_iterator_tag; + // iterator_category is inherited and not always present + using value_type = iter_value_t<_Iter>; + using difference_type = iter_difference_t<_Iter>; + using pointer = _Iter; + using reference = iter_rvalue_reference_t<_Iter>; +#else + typedef _Iter iterator_type; + typedef _If< + __is_cpp17_random_access_iterator<_Iter>::value, + random_access_iterator_tag, + typename iterator_traits<_Iter>::iterator_category + > iterator_category; + typedef typename iterator_traits::value_type value_type; + typedef typename iterator_traits::difference_type difference_type; + typedef iterator_type pointer; + + typedef typename iterator_traits::reference __reference; + typedef typename conditional< + is_reference<__reference>::value, + __libcpp_remove_reference_t<__reference>&&, + __reference + >::type reference; +#endif // _LIBCPP_STD_VER > 17 + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + explicit move_iterator(_Iter __i) : __current_(std::move(__i)) {} + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + move_iterator& operator++() { ++__current_; return *this; } + + _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + pointer operator->() const { return __current_; } + +#if _LIBCPP_STD_VER > 17 + _LIBCPP_HIDE_FROM_ABI constexpr + move_iterator() requires is_constructible_v<_Iter> : __current_() {} + + template + requires (!_IsSame<_Up, _Iter>::value) && convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr + move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {} + + template + requires (!_IsSame<_Up, _Iter>::value) && + convertible_to && + assignable_from<_Iter&, const _Up&> + _LIBCPP_HIDE_FROM_ABI constexpr + move_iterator& operator=(const move_iterator<_Up>& __u) { + __current_ = __u.base(); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr const _Iter& base() const & noexcept { return __current_; } + _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() && { return std::move(__current_); } + + _LIBCPP_HIDE_FROM_ABI constexpr + reference operator*() const { return ranges::iter_move(__current_); } + _LIBCPP_HIDE_FROM_ABI constexpr + reference operator[](difference_type __n) const { return ranges::iter_move(__current_ + __n); } + + _LIBCPP_HIDE_FROM_ABI constexpr + auto operator++(int) + requires forward_iterator<_Iter> + { + move_iterator __tmp(*this); ++__current_; return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI constexpr + void operator++(int) { ++__current_; } +#else + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + move_iterator() : __current_() {} + + template ::value && is_convertible::value + > > + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {} + + template ::value && + is_convertible::value && + is_assignable<_Iter&, const _Up&>::value + > > + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + move_iterator& operator=(const move_iterator<_Up>& __u) { + __current_ = __u.base(); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + _Iter base() const { return __current_; } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + reference operator*() const { return static_cast(*__current_); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + reference operator[](difference_type __n) const { return static_cast(__current_[__n]); } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + move_iterator operator++(int) { move_iterator __tmp(*this); ++__current_; return __tmp; } +#endif // _LIBCPP_STD_VER > 17 + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + move_iterator& operator--() { --__current_; return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + move_iterator operator--(int) { move_iterator __tmp(*this); --__current_; return __tmp; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + move_iterator operator+(difference_type __n) const { return move_iterator(__current_ + __n); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + move_iterator& operator+=(difference_type __n) { __current_ += __n; return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + move_iterator operator-(difference_type __n) const { return move_iterator(__current_ - __n); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + move_iterator& operator-=(difference_type __n) { __current_ -= __n; return *this; } + +#if _LIBCPP_STD_VER > 17 + template _Sent> + friend _LIBCPP_HIDE_FROM_ABI constexpr + bool operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y) + requires __move_iter_comparable<_Iter, _Sent> + { + return __x.base() == __y.base(); + } + + template _Sent> + friend _LIBCPP_HIDE_FROM_ABI constexpr + iter_difference_t<_Iter> operator-(const move_sentinel<_Sent>& __x, const move_iterator& __y) + { + return __x.base() - __y.base(); + } + + template _Sent> + friend _LIBCPP_HIDE_FROM_ABI constexpr + iter_difference_t<_Iter> operator-(const move_iterator& __x, const move_sentinel<_Sent>& __y) + { + return __x.base() - __y.base(); + } + + friend _LIBCPP_HIDE_FROM_ABI constexpr + iter_rvalue_reference_t<_Iter> iter_move(const move_iterator& __i) + noexcept(noexcept(ranges::iter_move(__i.__current_))) + { + return ranges::iter_move(__i.__current_); + } + + template _It2> + friend _LIBCPP_HIDE_FROM_ABI constexpr + void iter_swap(const move_iterator& __x, const move_iterator<_It2>& __y) + noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) + { + return ranges::iter_swap(__x.__current_, __y.__current_); + } +#endif // _LIBCPP_STD_VER > 17 + +private: + template friend class move_iterator; + + _Iter __current_; +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_iterator); + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 +bool operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +{ + return __x.base() == __y.base(); +} + +#if _LIBCPP_STD_VER <= 17 +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 +bool operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +{ + return __x.base() != __y.base(); +} +#endif // _LIBCPP_STD_VER <= 17 + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 +bool operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +{ + return __x.base() < __y.base(); +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 +bool operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +{ + return __x.base() > __y.base(); +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 +bool operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +{ + return __x.base() <= __y.base(); +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 +bool operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +{ + return __x.base() >= __y.base(); +} + +#if _LIBCPP_STD_VER > 17 +template _Iter2> +inline _LIBCPP_HIDE_FROM_ABI constexpr +auto operator<=>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) + -> compare_three_way_result_t<_Iter1, _Iter2> +{ + return __x.base() <=> __y.base(); +} +#endif // _LIBCPP_STD_VER > 17 + +#ifndef _LIBCPP_CXX03_LANG +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 +auto operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) + -> decltype(__x.base() - __y.base()) +{ + return __x.base() - __y.base(); +} +#else +template +inline _LIBCPP_HIDE_FROM_ABI +typename move_iterator<_Iter1>::difference_type +operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +{ + return __x.base() - __y.base(); +} +#endif // !_LIBCPP_CXX03_LANG + +#if _LIBCPP_STD_VER > 17 +template +inline _LIBCPP_HIDE_FROM_ABI constexpr +move_iterator<_Iter> operator+(iter_difference_t<_Iter> __n, const move_iterator<_Iter>& __x) + requires requires { { __x.base() + __n } -> same_as<_Iter>; } +{ + return __x + __n; +} +#else +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 +move_iterator<_Iter> +operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x) +{ + return move_iterator<_Iter>(__x.base() + __n); +} +#endif // _LIBCPP_STD_VER > 17 + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 +move_iterator<_Iter> +make_move_iterator(_Iter __i) +{ + return move_iterator<_Iter>(std::move(__i)); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_MOVE_ITERATOR_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/move_sentinel.h b/app/src/main/cpp/libcxx/include/__iterator/move_sentinel.h new file mode 100644 index 0000000..0d7336a --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/move_sentinel.h @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ITERATOR_MOVE_SENTINEL_H +#define _LIBCPP___ITERATOR_MOVE_SENTINEL_H + +#include <__concepts/assignable.h> +#include <__concepts/convertible_to.h> +#include <__concepts/semiregular.h> +#include <__config> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +class _LIBCPP_TEMPLATE_VIS move_sentinel +{ +public: + _LIBCPP_HIDE_FROM_ABI + move_sentinel() = default; + + _LIBCPP_HIDE_FROM_ABI constexpr + explicit move_sentinel(_Sent __s) : __last_(std::move(__s)) {} + + template + requires convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr + move_sentinel(const move_sentinel<_S2>& __s) : __last_(__s.base()) {} + + template + requires assignable_from<_Sent&, const _S2&> + _LIBCPP_HIDE_FROM_ABI constexpr + move_sentinel& operator=(const move_sentinel<_S2>& __s) + { __last_ = __s.base(); return *this; } + + constexpr _Sent base() const { return __last_; } + +private: + _Sent __last_ = _Sent(); +}; + +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_sentinel); + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_MOVE_SENTINEL_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/next.h b/app/src/main/cpp/libcxx/include/__iterator/next.h new file mode 100644 index 0000000..49970ae --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/next.h @@ -0,0 +1,84 @@ +// -*- 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 _LIBCPP___ITERATOR_NEXT_H +#define _LIBCPP___ITERATOR_NEXT_H + +#include <__assert> +#include <__config> +#include <__iterator/advance.h> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iterator_traits.h> +#include <__type_traits/enable_if.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + typename enable_if<__is_cpp17_input_iterator<_InputIter>::value, _InputIter>::type + next(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) { + _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, + "Attempt to next(it, n) with negative n on a non-bidirectional iterator"); + + _VSTD::advance(__x, __n); + return __x; +} + +#if _LIBCPP_STD_VER > 17 + +// [range.iter.op.next] + +namespace ranges { +namespace __next { + +struct __fn { + template + _LIBCPP_HIDE_FROM_ABI + constexpr _Ip operator()(_Ip __x) const { + ++__x; + return __x; + } + + template + _LIBCPP_HIDE_FROM_ABI + constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n) const { + ranges::advance(__x, __n); + return __x; + } + + template _Sp> + _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x, _Sp __bound_sentinel) const { + ranges::advance(__x, __bound_sentinel); + return __x; + } + + template _Sp> + _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n, _Sp __bound_sentinel) const { + ranges::advance(__x, __n, __bound_sentinel); + return __x; + } +}; + +} // namespace __next + +inline namespace __cpo { + inline constexpr auto next = __next::__fn{}; +} // namespace __cpo +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_NEXT_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/ostream_iterator.h b/app/src/main/cpp/libcxx/include/__iterator/ostream_iterator.h new file mode 100644 index 0000000..d16f5a2 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/ostream_iterator.h @@ -0,0 +1,71 @@ +// -*- 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 _LIBCPP___ITERATOR_OSTREAM_ITERATOR_H +#define _LIBCPP___ITERATOR_OSTREAM_ITERATOR_H + +#include <__config> +#include <__iterator/iterator.h> +#include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> +#include +#include // for forward declarations of char_traits and basic_ostream + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template > +class _LIBCPP_TEMPLATE_VIS ostream_iterator +#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES) + : public iterator +#endif +{ +_LIBCPP_SUPPRESS_DEPRECATED_POP +public: + typedef output_iterator_tag iterator_category; + typedef void value_type; +#if _LIBCPP_STD_VER > 17 + typedef ptrdiff_t difference_type; +#else + typedef void difference_type; +#endif + typedef void pointer; + typedef void reference; + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_ostream<_CharT, _Traits> ostream_type; + +private: + ostream_type* __out_stream_; + const char_type* __delim_; +public: + _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s) _NOEXCEPT + : __out_stream_(_VSTD::addressof(__s)), __delim_(nullptr) {} + _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s, const _CharT* __delimiter) _NOEXCEPT + : __out_stream_(_VSTD::addressof(__s)), __delim_(__delimiter) {} + _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator=(const _Tp& __value) + { + *__out_stream_ << __value; + if (__delim_) + *__out_stream_ << __delim_; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator*() {return *this;} + _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++() {return *this;} + _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++(int) {return *this;} +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_OSTREAM_ITERATOR_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/ostreambuf_iterator.h b/app/src/main/cpp/libcxx/include/__iterator/ostreambuf_iterator.h new file mode 100644 index 0000000..b75f7b6 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/ostreambuf_iterator.h @@ -0,0 +1,77 @@ +// -*- 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 _LIBCPP___ITERATOR_OSTREAMBUF_ITERATOR_H +#define _LIBCPP___ITERATOR_OSTREAMBUF_ITERATOR_H + +#include <__config> +#include <__iterator/iterator.h> +#include <__iterator/iterator_traits.h> +#include +#include // for forward declaration of basic_streambuf + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template +class _LIBCPP_TEMPLATE_VIS ostreambuf_iterator +#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES) + : public iterator +#endif +{ +_LIBCPP_SUPPRESS_DEPRECATED_POP +public: + typedef output_iterator_tag iterator_category; + typedef void value_type; +#if _LIBCPP_STD_VER > 17 + typedef ptrdiff_t difference_type; +#else + typedef void difference_type; +#endif + typedef void pointer; + typedef void reference; + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_streambuf<_CharT, _Traits> streambuf_type; + typedef basic_ostream<_CharT, _Traits> ostream_type; + +private: + streambuf_type* __sbuf_; +public: + _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(ostream_type& __s) _NOEXCEPT + : __sbuf_(__s.rdbuf()) {} + _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(streambuf_type* __s) _NOEXCEPT + : __sbuf_(__s) {} + _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator=(_CharT __c) + { + if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sputc(__c), traits_type::eof())) + __sbuf_ = nullptr; + return *this; + } + _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator*() {return *this;} + _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++() {return *this;} + _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++(int) {return *this;} + _LIBCPP_INLINE_VISIBILITY bool failed() const _NOEXCEPT {return __sbuf_ == nullptr;} + + template + friend + _LIBCPP_HIDE_FROM_ABI + ostreambuf_iterator<_Ch, _Tr> + __pad_and_output(ostreambuf_iterator<_Ch, _Tr> __s, + const _Ch* __ob, const _Ch* __op, const _Ch* __oe, + ios_base& __iob, _Ch __fl); +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_OSTREAMBUF_ITERATOR_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/permutable.h b/app/src/main/cpp/libcxx/include/__iterator/permutable.h new file mode 100644 index 0000000..28d193e --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/permutable.h @@ -0,0 +1,35 @@ +// -*- 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 _LIBCPP___ITERATOR_PERMUTABLE_H +#define _LIBCPP___ITERATOR_PERMUTABLE_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/iter_swap.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +concept permutable = + forward_iterator<_Iterator> && + indirectly_movable_storable<_Iterator, _Iterator> && + indirectly_swappable<_Iterator, _Iterator>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_PERMUTABLE_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/prev.h b/app/src/main/cpp/libcxx/include/__iterator/prev.h new file mode 100644 index 0000000..af1e1ba --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/prev.h @@ -0,0 +1,77 @@ +// -*- 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 _LIBCPP___ITERATOR_PREV_H +#define _LIBCPP___ITERATOR_PREV_H + +#include <__assert> +#include <__config> +#include <__iterator/advance.h> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iterator_traits.h> +#include <__type_traits/enable_if.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + typename enable_if<__is_cpp17_input_iterator<_InputIter>::value, _InputIter>::type + prev(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) { + _LIBCPP_ASSERT(__n <= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, + "Attempt to prev(it, n) with a positive n on a non-bidirectional iterator"); + _VSTD::advance(__x, -__n); + return __x; +} + +#if _LIBCPP_STD_VER > 17 + +// [range.iter.op.prev] + +namespace ranges { +namespace __prev { + +struct __fn { + template + _LIBCPP_HIDE_FROM_ABI + constexpr _Ip operator()(_Ip __x) const { + --__x; + return __x; + } + + template + _LIBCPP_HIDE_FROM_ABI + constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n) const { + ranges::advance(__x, -__n); + return __x; + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n, _Ip __bound_iter) const { + ranges::advance(__x, -__n, __bound_iter); + return __x; + } +}; + +} // namespace __prev + +inline namespace __cpo { + inline constexpr auto prev = __prev::__fn{}; +} // namespace __cpo +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_PREV_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/projected.h b/app/src/main/cpp/libcxx/include/__iterator/projected.h new file mode 100644 index 0000000..19c076b --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/projected.h @@ -0,0 +1,41 @@ +// -*- 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 _LIBCPP___ITERATOR_PROJECTED_H +#define _LIBCPP___ITERATOR_PROJECTED_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__type_traits/remove_cvref.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template _Proj> +struct projected { + using value_type = remove_cvref_t>; + indirect_result_t<_Proj&, _It> operator*() const; // not defined +}; + +template +struct incrementable_traits> { + using difference_type = iter_difference_t<_It>; +}; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_PROJECTED_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/readable_traits.h b/app/src/main/cpp/libcxx/include/__iterator/readable_traits.h new file mode 100644 index 0000000..8f17757 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/readable_traits.h @@ -0,0 +1,92 @@ +// -*- 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 _LIBCPP___ITERATOR_READABLE_TRAITS_H +#define _LIBCPP___ITERATOR_READABLE_TRAITS_H + +#include <__concepts/same_as.h> +#include <__config> +#include <__type_traits/conditional.h> +#include <__type_traits/is_array.h> +#include <__type_traits/is_object.h> +#include <__type_traits/is_primary_template.h> +#include <__type_traits/remove_cv.h> +#include <__type_traits/remove_cvref.h> +#include <__type_traits/remove_extent.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [readable.traits] +template struct __cond_value_type {}; + +template +requires is_object_v<_Tp> +struct __cond_value_type<_Tp> { using value_type = remove_cv_t<_Tp>; }; + +template +concept __has_member_value_type = requires { typename _Tp::value_type; }; + +template +concept __has_member_element_type = requires { typename _Tp::element_type; }; + +template struct indirectly_readable_traits {}; + +template +requires is_array_v<_Ip> +struct indirectly_readable_traits<_Ip> { + using value_type = remove_cv_t>; +}; + +template +struct indirectly_readable_traits : indirectly_readable_traits<_Ip> {}; + +template +struct indirectly_readable_traits<_Tp*> : __cond_value_type<_Tp> {}; + +template<__has_member_value_type _Tp> +struct indirectly_readable_traits<_Tp> + : __cond_value_type {}; + +template<__has_member_element_type _Tp> +struct indirectly_readable_traits<_Tp> + : __cond_value_type {}; + +template<__has_member_value_type _Tp> + requires __has_member_element_type<_Tp> +struct indirectly_readable_traits<_Tp> {}; + +template<__has_member_value_type _Tp> + requires __has_member_element_type<_Tp> && + same_as, + remove_cv_t> +struct indirectly_readable_traits<_Tp> + : __cond_value_type {}; + +template +struct iterator_traits; + +// Let `RI` be `remove_cvref_t`. The type `iter_value_t` denotes +// `indirectly_readable_traits::value_type` if `iterator_traits` names a specialization +// generated from the primary template, and `iterator_traits::value_type` otherwise. +template +using iter_value_t = typename conditional_t<__is_primary_template > >::value, + indirectly_readable_traits >, + iterator_traits > >::value_type; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_READABLE_TRAITS_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/reverse_access.h b/app/src/main/cpp/libcxx/include/__iterator/reverse_access.h new file mode 100644 index 0000000..79b599c --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/reverse_access.h @@ -0,0 +1,100 @@ +// -*- 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 _LIBCPP___ITERATOR_REVERSE_ACCESS_H +#define _LIBCPP___ITERATOR_REVERSE_ACCESS_H + +#include <__config> +#include <__iterator/reverse_iterator.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 11 + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +reverse_iterator<_Tp*> rbegin(_Tp (&__array)[_Np]) +{ + return reverse_iterator<_Tp*>(__array + _Np); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +reverse_iterator<_Tp*> rend(_Tp (&__array)[_Np]) +{ + return reverse_iterator<_Tp*>(__array); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +reverse_iterator rbegin(initializer_list<_Ep> __il) +{ + return reverse_iterator(__il.end()); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +reverse_iterator rend(initializer_list<_Ep> __il) +{ + return reverse_iterator(__il.begin()); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +auto rbegin(_Cp& __c) -> decltype(__c.rbegin()) +{ + return __c.rbegin(); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +auto rbegin(const _Cp& __c) -> decltype(__c.rbegin()) +{ + return __c.rbegin(); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +auto rend(_Cp& __c) -> decltype(__c.rend()) +{ + return __c.rend(); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +auto rend(const _Cp& __c) -> decltype(__c.rend()) +{ + return __c.rend(); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +auto crbegin(const _Cp& __c) -> decltype(_VSTD::rbegin(__c)) +{ + return _VSTD::rbegin(__c); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +auto crend(const _Cp& __c) -> decltype(_VSTD::rend(__c)) +{ + return _VSTD::rend(__c); +} + +#endif // _LIBCPP_STD_VER > 11 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_REVERSE_ACCESS_H diff --git a/app/src/main/cpp/libcxx/include/__iterator/reverse_iterator.h b/app/src/main/cpp/libcxx/include/__iterator/reverse_iterator.h new file mode 100644 index 0000000..f272e03 --- /dev/null +++ b/app/src/main/cpp/libcxx/include/__iterator/reverse_iterator.h @@ -0,0 +1,533 @@ +// -*- 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 _LIBCPP___ITERATOR_REVERSE_ITERATOR_H +#define _LIBCPP___ITERATOR_REVERSE_ITERATOR_H + +#include <__algorithm/unwrap_iter.h> +#include <__compare/compare_three_way_result.h> +#include <__compare/three_way_comparable.h> +#include <__concepts/convertible_to.h> +#include <__config> +#include <__iterator/advance.h> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iter_move.h> +#include <__iterator/iter_swap.h> +#include <__iterator/iterator.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/prev.h> +#include <__iterator/readable_traits.h> +#include <__iterator/segmented_iterator.h> +#include <__memory/addressof.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/subrange.h> +#include <__type_traits/conditional.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_assignable.h> +#include <__type_traits/is_convertible.h> +#include <__type_traits/is_nothrow_copy_constructible.h> +#include <__type_traits/is_pointer.h> +#include <__type_traits/is_same.h> +#include <__utility/declval.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template +class _LIBCPP_TEMPLATE_VIS reverse_iterator +#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES) + : public iterator::iterator_category, + typename iterator_traits<_Iter>::value_type, + typename iterator_traits<_Iter>::difference_type, + typename iterator_traits<_Iter>::pointer, + typename iterator_traits<_Iter>::reference> +#endif +{ +_LIBCPP_SUPPRESS_DEPRECATED_POP +private: +#ifndef _LIBCPP_ABI_NO_ITERATOR_BASES + _Iter __t_; // no longer used as of LWG #2360, not removed due to ABI break +#endif + +#if _LIBCPP_STD_VER > 17 + static_assert(__is_cpp17_bidirectional_iterator<_Iter>::value || bidirectional_iterator<_Iter>, + "reverse_iterator requires It to be a bidirectional iterator."); +#endif // _LIBCPP_STD_VER > 17 + +protected: + _Iter current; +public: + using iterator_type = _Iter; + + using iterator_category = _If<__is_cpp17_random_access_iterator<_Iter>::value, + random_access_iterator_tag, + typename iterator_traits<_Iter>::iterator_category>; + using pointer = typename iterator_traits<_Iter>::pointer; +#if _LIBCPP_STD_VER > 17 + using iterator_concept = _If, random_access_iterator_tag, bidirectional_iterator_tag>; + using value_type = iter_value_t<_Iter>; + using difference_type = iter_difference_t<_Iter>; + using reference = iter_reference_t<_Iter>; +#else + using value_type = typename iterator_traits<_Iter>::value_type; + using difference_type = typename iterator_traits<_Iter>::difference_type; + using reference = typename iterator_traits<_Iter>::reference; +#endif + +#ifndef _LIBCPP_ABI_NO_ITERATOR_BASES + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + reverse_iterator() : __t_(), current() {} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + explicit reverse_iterator(_Iter __x) : __t_(__x), current(__x) {} + + template ::value && is_convertible<_Up const&, _Iter>::value + > > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + reverse_iterator(const reverse_iterator<_Up>& __u) + : __t_(__u.base()), current(__u.base()) + { } + + template ::value && + is_convertible<_Up const&, _Iter>::value && + is_assignable<_Iter&, _Up const&>::value + > > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { + __t_ = current = __u.base(); + return *this; + } +#else + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + reverse_iterator() : current() {} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + explicit reverse_iterator(_Iter __x) : current(__x) {} + + template ::value && is_convertible<_Up const&, _Iter>::value + > > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + reverse_iterator(const reverse_iterator<_Up>& __u) + : current(__u.base()) + { } + + template ::value && + is_convertible<_Up const&, _Iter>::value && + is_assignable<_Iter&, _Up const&>::value + > > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { + current = __u.base(); + return *this; + } +#endif + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + _Iter base() const {return current;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + reference operator*() const {_Iter __tmp = current; return *--__tmp;} + +#if _LIBCPP_STD_VER > 17 + _LIBCPP_INLINE_VISIBILITY + constexpr pointer operator->() const + requires is_pointer_v<_Iter> || requires(const _Iter __i) { __i.operator->(); } + { + if constexpr (is_pointer_v<_Iter>) { + return std::prev(current); + } else { + return std::prev(current).operator->(); + } + } +#else + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + pointer operator->() const { + return std::addressof(operator*()); + } +#endif // _LIBCPP_STD_VER > 17 + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + reverse_iterator& operator++() {--current; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + reverse_iterator operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + reverse_iterator& operator--() {++current; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + reverse_iterator operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + reverse_iterator operator+(difference_type __n) const {return reverse_iterator(current - __n);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + reverse_iterator& operator+=(difference_type __n) {current -= __n; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + reverse_iterator operator-(difference_type __n) const {return reverse_iterator(current + __n);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + reverse_iterator& operator-=(difference_type __n) {current += __n; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + reference operator[](difference_type __n) const {return *(*this + __n);} + +#if _LIBCPP_STD_VER > 17 + _LIBCPP_HIDE_FROM_ABI friend constexpr + iter_rvalue_reference_t<_Iter> iter_move(const reverse_iterator& __i) + noexcept(is_nothrow_copy_constructible_v<_Iter> && + noexcept(ranges::iter_move(--std::declval<_Iter&>()))) { + auto __tmp = __i.base(); + return ranges::iter_move(--__tmp); + } + + template _Iter2> + _LIBCPP_HIDE_FROM_ABI friend constexpr + void iter_swap(const reverse_iterator& __x, const reverse_iterator<_Iter2>& __y) + noexcept(is_nothrow_copy_constructible_v<_Iter> && + is_nothrow_copy_constructible_v<_Iter2> && + noexcept(ranges::iter_swap(--std::declval<_Iter&>(), --std::declval<_Iter2&>()))) { + auto __xtmp = __x.base(); + auto __ytmp = __y.base(); + ranges::iter_swap(--__xtmp, --__ytmp); + } +#endif // _LIBCPP_STD_VER > 17 +}; + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +bool +operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +#if _LIBCPP_STD_VER > 17 + requires requires { + { __x.base() == __y.base() } -> convertible_to; + } +#endif // _LIBCPP_STD_VER > 17 +{ + return __x.base() == __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +bool +operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +#if _LIBCPP_STD_VER > 17 + requires requires { + { __x.base() > __y.base() } -> convertible_to; + } +#endif // _LIBCPP_STD_VER > 17 +{ + return __x.base() > __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +bool +operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +#if _LIBCPP_STD_VER > 17 + requires requires { + { __x.base() != __y.base() } -> convertible_to; + } +#endif // _LIBCPP_STD_VER > 17 +{ + return __x.base() != __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +bool +operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +#if _LIBCPP_STD_VER > 17 + requires requires { + { __x.base() < __y.base() } -> convertible_to; + } +#endif // _LIBCPP_STD_VER > 17 +{ + return __x.base() < __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +bool +operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +#if _LIBCPP_STD_VER > 17 + requires requires { + { __x.base() <= __y.base() } -> convertible_to; + } +#endif // _LIBCPP_STD_VER > 17 +{ + return __x.base() <= __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +bool +operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +#if _LIBCPP_STD_VER > 17 + requires requires { + { __x.base() >= __y.base() } -> convertible_to; + } +#endif // _LIBCPP_STD_VER > 17 +{ + return __x.base() >= __y.base(); +} + +#if _LIBCPP_STD_VER > 17 +template _Iter2> +_LIBCPP_HIDE_FROM_ABI constexpr +compare_three_way_result_t<_Iter1, _Iter2> +operator<=>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +{ + return __y.base() <=> __x.base(); +} +#endif // _LIBCPP_STD_VER > 17 + +#ifndef _LIBCPP_CXX03_LANG +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +auto +operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +-> decltype(__y.base() - __x.base()) +{ + return __y.base() - __x.base(); +} +#else +template +inline _LIBCPP_INLINE_VISIBILITY +typename reverse_iterator<_Iter1>::difference_type +operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +{ + return __y.base() - __x.base(); +} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +reverse_iterator<_Iter> +operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x) +{ + return reverse_iterator<_Iter>(__x.base() - __n); +} + +#if _LIBCPP_STD_VER > 17 +template + requires (!sized_sentinel_for<_Iter1, _Iter2>) +inline constexpr bool disable_sized_sentinel_for, reverse_iterator<_Iter2>> = true; +#endif // _LIBCPP_STD_VER > 17 + +#if _LIBCPP_STD_VER > 11 +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 +reverse_iterator<_Iter> make_reverse_iterator(_Iter __i) +{ + return reverse_iterator<_Iter>(__i); +} +#endif + +#if _LIBCPP_STD_VER <= 17 +template +using __unconstrained_reverse_iterator = reverse_iterator<_Iter>; +#else + +// __unconstrained_reverse_iterator allows us to use reverse iterators in the implementation of algorithms by working +// around a language issue in C++20. +// In C++20, when a reverse iterator wraps certain C++20-hostile iterators, calling comparison operators on it will +// result in a compilation error. However, calling comparison operators on the pristine hostile iterator is not +// an error. Thus, we cannot use reverse_iterators in the implementation of an algorithm that accepts a +// C++20-hostile iterator. This class is an internal workaround -- it is a copy of reverse_iterator with +// tweaks to make it support hostile iterators. +// +// A C++20-hostile iterator is one that defines a comparison operator where one of the arguments is an exact match +// and the other requires an implicit conversion, for example: +// friend bool operator==(const BaseIter&, const DerivedIter&); +// +// C++20 rules for rewriting equality operators create another overload of this function with parameters reversed: +// friend bool operator==(const DerivedIter&, const BaseIter&); +// +// This creates an ambiguity in overload resolution. +// +// Clang treats this ambiguity differently in different contexts. When operator== is actually called in the function +// body, the code is accepted with a warning. When a concept requires operator== to be a valid expression, however, +// it evaluates to false. Thus, the implementation of reverse_iterator::operator== can actually call operator== on its +// base iterators, but the constraints on reverse_iterator::operator== prevent it from being considered during overload +// resolution. This class simply removes the problematic constraints from comparison functions. +template +class __unconstrained_reverse_iterator { + _Iter __iter_; + +public: + static_assert(__is_cpp17_bidirectional_iterator<_Iter>::value || bidirectional_iterator<_Iter>); + + using iterator_type = _Iter; + using iterator_category = + _If<__is_cpp17_random_access_iterator<_Iter>::value, random_access_iterator_tag, __iterator_category_type<_Iter>>; + using pointer = __iterator_pointer_type<_Iter>; + using value_type = iter_value_t<_Iter>; + using difference_type = iter_difference_t<_Iter>; + using reference = iter_reference_t<_Iter>; + + _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator() = default; + _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator(const __unconstrained_reverse_iterator&) = default; + _LIBCPP_HIDE_FROM_ABI constexpr explicit __unconstrained_reverse_iterator(_Iter __iter) : __iter_(__iter) {} + + _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() const { return __iter_; } + _LIBCPP_HIDE_FROM_ABI constexpr reference operator*() const { + auto __tmp = __iter_; + return *--__tmp; + } + + _LIBCPP_HIDE_FROM_ABI constexpr pointer operator->() const { + if constexpr (is_pointer_v<_Iter>) { + return std::prev(__iter_); + } else { + return std::prev(__iter_).operator->(); + } + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr + iter_rvalue_reference_t<_Iter> iter_move(const __unconstrained_reverse_iterator& __i) + noexcept(is_nothrow_copy_constructible_v<_Iter> && + noexcept(ranges::iter_move(--std::declval<_Iter&>()))) { + auto __tmp = __i.base(); + return ranges::iter_move(--__tmp); + } + + _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator++() { + --__iter_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator++(int) { + auto __tmp = *this; + --__iter_; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator--() { + ++__iter_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator--(int) { + auto __tmp = *this; + ++__iter_; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator+=(difference_type __n) { + __iter_ -= __n; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator-=(difference_type __n) { + __iter_ += __n; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator+(difference_type __n) const { + return __unconstrained_reverse_iterator(__iter_ - __n); + } + + _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator-(difference_type __n) const { + return __unconstrained_reverse_iterator(__iter_ + __n); + } + + _LIBCPP_HIDE_FROM_ABI constexpr difference_type operator-(const __unconstrained_reverse_iterator& __other) const { + return __other.__iter_ - __iter_; + } + + _LIBCPP_HIDE_FROM_ABI constexpr auto operator[](difference_type __n) const { return *(*this + __n); } + + // Deliberately unconstrained unlike the comparison functions in `reverse_iterator` -- see the class comment for the + // rationale. + _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator==(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { + return __lhs.base() == __rhs.base(); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator!=(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { + return __lhs.base() != __rhs.base(); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator<(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { + return __lhs.base() > __rhs.base(); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator>(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { + return __lhs.base() < __rhs.base(); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator<=(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { + return __lhs.base() >= __rhs.base(); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator>=(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { + return __lhs.base() <= __rhs.base(); + } +}; + +#endif // _LIBCPP_STD_VER <= 17 + +template