diff options
author | AlexSm <alex@ydb.tech> | 2023-12-27 23:31:58 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-27 23:31:58 +0100 |
commit | d67bfb4b4b7549081543e87a31bc6cb5c46ac973 (patch) | |
tree | 8674f2f1570877cb653e7ddcff37ba00288de15a | |
parent | 1f6bef05ed441c3aa2d565ac792b26cded704ac7 (diff) | |
download | ydb-d67bfb4b4b7549081543e87a31bc6cb5c46ac973.tar.gz |
Import libs 4 (#758)
400 files changed, 17112 insertions, 26399 deletions
diff --git a/build/conf/go.conf b/build/conf/go.conf index 18d3430584..44fdb693e3 100644 --- a/build/conf/go.conf +++ b/build/conf/go.conf @@ -989,7 +989,7 @@ macro GO_MOCKGEN_FROM(Path) { # tag:go-specific macro GO_MOCKGEN_CONTRIB_FROM(Path) { - SET(MOCKGEN_FROM ${GO_CONTRIB_PROJECT_PREFIX}/${Path}) + SET(MOCKGEN_FROM ${GO_CONTRIB_PROJECT_PREFIX}${Path}) SET(MOCKGEN_MODULE ${Path}) } diff --git a/build/conf/java.conf b/build/conf/java.conf index 2933045098..1422fe9c6b 100644 --- a/build/conf/java.conf +++ b/build/conf/java.conf @@ -673,9 +673,6 @@ macro _PACK_JAR_HELPER(Out) { macro _JAVAC_RUN_HELPER(JAVAC_CMD_WITH_ARGS...) { .CMD=${cwd:ARCADIA_BUILD_ROOT} ${env:"LC_ALL=en_US.UTF-8"} $YMAKE_PYTHON ${input:"build/scripts/with_pathsep_resolve.py"} $YMAKE_PYTHON ${input:"build/scripts/setup_java_tmpdir.py"} $YMAKE_PYTHON ${input:"build/scripts/run_javac.py"} --sources-list ${BINDIR}/all-java.srclst ${JAVAC_CMD_WITH_ARGS} @${BINDIR}/all-java.srclst -classpath ${ARCADIA_BUILD_ROOT}/bfg.jar -Xpkginfo:always ${JAVAC_OPTS} $_JAR_ANN_PROC_OPTS($_JAR_ANN_PROCESSORS) -d ${BINDIR}/cls -g -encoding UTF-8 } -macro _ADD_HIDDEN_INPUTS(Inputs...) { - .CMD=${input;hide:Inputs} -} # tag:java-specific ERROR_PRONE_JDK16_ADD_OPENS=-J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED diff --git a/build/conf/sysincl.conf b/build/conf/sysincl.conf index 933bcc3d73..6b2e9e97a8 100644 --- a/build/conf/sysincl.conf +++ b/build/conf/sysincl.conf @@ -78,3 +78,7 @@ when ($ARCH_RISCV32) { SYSINCL+=build/sysincl/newlib.yml SYSINCL+=build/sysincl/esp-idf.yml } + +when ($USE_ARCADIA_COMPILER_RUNTIME == "no") { + SYSINCL+=build/sysincl/local-compiler-runtime.yml +} diff --git a/build/mapping.conf.json b/build/mapping.conf.json index 9d47061c24..60e3cef573 100644 --- a/build/mapping.conf.json +++ b/build/mapping.conf.json @@ -87,6 +87,7 @@ "5530948376": "https://devtools-registry.s3.yandex.net/5530948376", "5545691160": "https://devtools-registry.s3.yandex.net/5545691160", "5559524010": "https://devtools-registry.s3.yandex.net/5559524010", + "5572005924": "https://devtools-registry.s3.yandex.net/5572005924", "5486731632": "https://devtools-registry.s3.yandex.net/5486731632", "5514350352": "https://devtools-registry.s3.yandex.net/5514350352", "5514360398": "https://devtools-registry.s3.yandex.net/5514360398", @@ -98,6 +99,8 @@ "5545709989": "https://devtools-registry.s3.yandex.net/5545709989", "5559537477": "https://devtools-registry.s3.yandex.net/5559537477", "5559549864": "https://devtools-registry.s3.yandex.net/5559549864", + "5571992960": "https://devtools-registry.s3.yandex.net/5571992960", + "5572031172": "https://devtools-registry.s3.yandex.net/5572031172", "4307890075": "https://devtools-registry.s3.yandex.net/4307890075", "5517245192": "https://devtools-registry.s3.yandex.net/5517245192", "4307901240": "https://devtools-registry.s3.yandex.net/4307901240", @@ -234,6 +237,7 @@ "5530948376": "devtools/ya/test/programs/test_tool/bin/test_tool for linux", "5545691160": "devtools/ya/test/programs/test_tool/bin/test_tool for linux", "5559524010": "devtools/ya/test/programs/test_tool/bin/test_tool for linux", + "5572005924": "devtools/ya/test/programs/test_tool/bin/test_tool for linux", "5486731632": "devtools/ya/test/programs/test_tool/bin3/test_tool3 for linux", "5514350352": "devtools/ya/test/programs/test_tool/bin3/test_tool3 for linux", "5514360398": "devtools/ya/test/programs/test_tool/bin3/test_tool3 for linux", @@ -245,6 +249,8 @@ "5545709989": "devtools/ya/test/programs/test_tool/bin3/test_tool3 for linux", "5559537477": "devtools/ya/test/programs/test_tool/bin3/test_tool3 for linux", "5559549864": "devtools/ya/test/programs/test_tool/bin3/test_tool3 for linux", + "5571992960": "devtools/ya/test/programs/test_tool/bin3/test_tool3 for linux", + "5572031172": "devtools/ya/test/programs/test_tool/bin3/test_tool3 for linux", "4307890075": "flake8_linter for linux", "5517245192": "flake8_linter for linux", "4307901240": "flake8_linter for linux-aarch64", diff --git a/build/platform/test_tool/host.ya.make.inc b/build/platform/test_tool/host.ya.make.inc index 410298c40c..5f1cb27489 100644 --- a/build/platform/test_tool/host.ya.make.inc +++ b/build/platform/test_tool/host.ya.make.inc @@ -1,17 +1,17 @@ IF (HOST_OS_DARWIN AND HOST_ARCH_X86_64) - DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5559522450) - DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5559535346) + DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5572004205) + DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5571990421) ELSEIF (HOST_OS_DARWIN AND HOST_ARCH_ARM64) - DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5559521542) - DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5559534336) + DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5572003616) + DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5571989359) ELSEIF (HOST_OS_LINUX AND HOST_ARCH_X86_64) - DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5559524010) - DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5559537477) + DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5572005924) + DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5571992960) ELSEIF (HOST_OS_LINUX AND HOST_ARCH_AARCH64) - DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5559520978) - DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5559533477) + DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5572002846) + DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5571988789) ELSEIF (HOST_OS_WINDOWS AND HOST_ARCH_X86_64) - DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5559523230) - DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5559536195) + DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5572004883) + DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5571991734) ENDIF() diff --git a/build/platform/test_tool/host_os.ya.make.inc b/build/platform/test_tool/host_os.ya.make.inc index 6041feb963..8c560d2926 100644 --- a/build/platform/test_tool/host_os.ya.make.inc +++ b/build/platform/test_tool/host_os.ya.make.inc @@ -1,17 +1,17 @@ IF (HOST_OS_DARWIN AND HOST_ARCH_X86_64) - DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5559548658) - DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5559548658) + DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5572030275) + DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5572030275) ELSEIF (HOST_OS_DARWIN AND HOST_ARCH_ARM64) - DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5559548099) - DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5559548099) + DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5572029953) + DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5572029953) ELSEIF (HOST_OS_LINUX AND HOST_ARCH_X86_64) - DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5559549864) - DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5559549864) + DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5572031172) + DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5572031172) ELSEIF (HOST_OS_LINUX AND HOST_ARCH_AARCH64) - DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5559547357) - DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5559547357) + DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5572029455) + DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5572029455) ELSEIF (HOST_OS_WINDOWS AND HOST_ARCH_X86_64) - DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5559549352) - DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5559549352) + DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5572030696) + DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5572030696) ENDIF() diff --git a/build/sysincl/local-compiler-runtime.yml b/build/sysincl/local-compiler-runtime.yml new file mode 100644 index 0000000000..999e050586 --- /dev/null +++ b/build/sysincl/local-compiler-runtime.yml @@ -0,0 +1,7 @@ +- includes: + - sanitizer/asan_interface.h + - sanitizer/common_interface_defs.h + - sanitizer/hwasan_interface.h + - sanitizer/lsan_interface.h + - sanitizer/msan_interface.h + - sanitizer/tsan_interface.h diff --git a/build/sysincl/stl-to-libcxx.yml b/build/sysincl/stl-to-libcxx.yml index 17f30acda6..d51bd0ee2d 100644 --- a/build/sysincl/stl-to-libcxx.yml +++ b/build/sysincl/stl-to-libcxx.yml @@ -271,6 +271,7 @@ - __algorithm/ranges_fill.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_fill.h - __algorithm/ranges_fill_n.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_fill_n.h - __algorithm/ranges_find.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_find.h + - __algorithm/ranges_find_end.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_find_end.h - __algorithm/ranges_find_first_of.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_find_first_of.h - __algorithm/ranges_find_if.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_find_if.h - __algorithm/ranges_find_if_not.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_find_if_not.h @@ -285,6 +286,7 @@ - __algorithm/ranges_is_partitioned.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_is_partitioned.h - __algorithm/ranges_is_sorted.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_is_sorted.h - __algorithm/ranges_is_sorted_until.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_is_sorted_until.h + - __algorithm/ranges_iterator_concept.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_iterator_concept.h - __algorithm/ranges_lexicographical_compare.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_lexicographical_compare.h - __algorithm/ranges_lower_bound.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_lower_bound.h - __algorithm/ranges_make_heap.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_make_heap.h @@ -300,6 +302,7 @@ - __algorithm/ranges_move_backward.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_move_backward.h - __algorithm/ranges_none_of.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_none_of.h - __algorithm/ranges_nth_element.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_nth_element.h + - __algorithm/ranges_partial_sort.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_partial_sort.h - __algorithm/ranges_partial_sort_copy.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_partial_sort_copy.h - __algorithm/ranges_partition.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_partition.h - __algorithm/ranges_partition_copy.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_partition_copy.h @@ -317,8 +320,11 @@ - __algorithm/ranges_reverse.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_reverse.h - __algorithm/ranges_reverse_copy.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_reverse_copy.h - __algorithm/ranges_rotate_copy.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_rotate_copy.h + - __algorithm/ranges_search.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_search.h + - __algorithm/ranges_search_n.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_search_n.h - __algorithm/ranges_set_difference.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_difference.h - __algorithm/ranges_set_intersection.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_intersection.h + - __algorithm/ranges_set_symmetric_difference.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_symmetric_difference.h - __algorithm/ranges_set_union.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_union.h - __algorithm/ranges_shuffle.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_shuffle.h - __algorithm/ranges_sort.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_sort.h @@ -448,6 +454,7 @@ - __format/buffer.h: contrib/libs/cxxsupp/libcxx/include/__format/buffer.h - __format/concepts.h: contrib/libs/cxxsupp/libcxx/include/__format/concepts.h - __format/enable_insertable.h: contrib/libs/cxxsupp/libcxx/include/__format/enable_insertable.h + - __format/extended_grapheme_cluster_table.h: contrib/libs/cxxsupp/libcxx/include/__format/extended_grapheme_cluster_table.h - __format/format_arg.h: contrib/libs/cxxsupp/libcxx/include/__format/format_arg.h - __format/format_arg_store.h: contrib/libs/cxxsupp/libcxx/include/__format/format_arg_store.h - __format/format_args.h: contrib/libs/cxxsupp/libcxx/include/__format/format_args.h @@ -467,6 +474,7 @@ - __format/formatter_pointer.h: contrib/libs/cxxsupp/libcxx/include/__format/formatter_pointer.h - __format/formatter_string.h: contrib/libs/cxxsupp/libcxx/include/__format/formatter_string.h - __format/parser_std_format_spec.h: contrib/libs/cxxsupp/libcxx/include/__format/parser_std_format_spec.h + - __format/unicode.h: contrib/libs/cxxsupp/libcxx/include/__format/unicode.h - __functional/binary_function.h: contrib/libs/cxxsupp/libcxx/include/__functional/binary_function.h - __functional/binary_negate.h: contrib/libs/cxxsupp/libcxx/include/__functional/binary_negate.h - __functional/bind.h: contrib/libs/cxxsupp/libcxx/include/__functional/bind.h @@ -645,10 +653,8 @@ - __support/android/locale_bionic.h: contrib/libs/cxxsupp/libcxx/include/__support/android/locale_bionic.h - __support/fuchsia/xlocale.h: contrib/libs/cxxsupp/libcxx/include/__support/fuchsia/xlocale.h - __support/ibm/gettod_zos.h: contrib/libs/cxxsupp/libcxx/include/__support/ibm/gettod_zos.h - - __support/ibm/limits.h: contrib/libs/cxxsupp/libcxx/include/__support/ibm/limits.h - __support/ibm/locale_mgmt_zos.h: contrib/libs/cxxsupp/libcxx/include/__support/ibm/locale_mgmt_zos.h - __support/ibm/nanosleep.h: contrib/libs/cxxsupp/libcxx/include/__support/ibm/nanosleep.h - - __support/ibm/support.h: contrib/libs/cxxsupp/libcxx/include/__support/ibm/support.h - __support/ibm/xlocale.h: contrib/libs/cxxsupp/libcxx/include/__support/ibm/xlocale.h - __support/musl/xlocale.h: contrib/libs/cxxsupp/libcxx/include/__support/musl/xlocale.h - __support/newlib/xlocale.h: contrib/libs/cxxsupp/libcxx/include/__support/newlib/xlocale.h diff --git a/build/ya.conf.json b/build/ya.conf.json index bfcc4b1c9e..38ec090d58 100644 --- a/build/ya.conf.json +++ b/build/ya.conf.json @@ -1177,8 +1177,8 @@ } }, "toolchain_aliases": { - "clang-win-i686": "clang14-win-i686", - "clang-win-x86_64": "clang14-win-x86_64", + "clang-win-i686": "default-win-i686", + "clang-win-x86_64": "default-win-x86_64", "gcc-linux-x86_64": "gcc82-linux-x86_64", "msvc-win-x86_64": "msvc2019-win-x86_64" }, diff --git a/build/ymake.core.conf b/build/ymake.core.conf index 3a236876bc..c1314fc8e9 100644 --- a/build/ymake.core.conf +++ b/build/ymake.core.conf @@ -9,7 +9,7 @@ FAKEID=628318530716 SANDBOX_FAKEID=${FAKEID}.7600000 -CPP_FAKEID=2023-12-05 +CPP_FAKEID=2023-12-06 GO_FAKEID=11100371 ANDROID_FAKEID=2023-05-17 CLANG_TIDY_FAKEID=2023-06-06 @@ -50,6 +50,11 @@ when ($CLANG16 == "yes") { CLANG_VER=16 } +USE_ARCADIA_COMPILER_RUNTIME=yes + +when ($LOCAL && $XCODE) { + USE_ARCADIA_COMPILER_RUNTIME=no +} @import "${CONF_ROOT}/conf/settings.conf" @import "${CONF_ROOT}/conf/opensource.conf" @@ -236,7 +241,7 @@ EXTRA_OUTPUT= when ($CLANG == "yes" || $GCC == "yes") { when ($BUILD_TYPE == "COVERAGE" || $GCOV_COVERAGE) { COVERAGE_FLAGS=-fprofile-arcs -ftest-coverage - EXTRA_OUTPUT=${output;noauto;hide;suf=${COMPILE_OUT_SUFFIX}${_CROSS_SUFFIX}.gcno:SRC} + EXTRA_OUTPUT=${output;noauto;hide;suf=${COMPILE_OUT_SUFFIX}${OBJ_SUF}${_CROSS_SUFFIX}.gcno:SRC} } } @@ -294,7 +299,9 @@ otherwise { # line when `ya make ...` is invoked. when ($NORUNTIME != "yes") { SYSINCL+=build/sysincl/stl-to-libcxx.yml - SYSINCL+=build/sysincl/stl-to-libcxxmsvc.yml + when ($MSVC == "yes" && $CLANG_CL != "yes") { + SYSINCL+=build/sysincl/stl-to-libcxxmsvc.yml + } when ($MUSL == "yes") { SYSINCL+=build/sysincl/libc-musl-libcxx.yml } @@ -774,6 +781,8 @@ module _BASE_UNIT: _BARE_UNIT { when ($TIDY_ENABLED == "yes") { PEERDIR+=build/platform/clang/clang-tidy } + + ENABLE(USE_YASM_ASSEMBLER) } _LINKER_ID= @@ -2393,6 +2402,12 @@ module UNION: _BASE_UNIT { } # tag:internal +### @usage: _ADD_HIDDEN_INPUTS(inputs...) # internal +macro _ADD_HIDDEN_INPUTS(Inputs...) { + .CMD=${input;hide:Inputs} +} + +# tag:internal ### @usage: _SET_FIRST_VALUE(name args...) # internal ### ### This macro sets the value of `name` variable to the value of next argument @@ -4795,9 +4810,12 @@ macro _SRC_nasm(SRC, PREINCLUDES[], SRCFLAGS...) { when ($USE_NASM_ASSEMBLER == "yes") { _SRC_ASM_CMDLINE=$_SRC_nasm($SRC $SRCFLAGS) } -otherwise { +elsewhen ($USE_YASM_ASSEMBLER == "yes") { _SRC_ASM_CMDLINE=$_SRC_yasm($SRC $SRCFLAGS) } +otherwise { + _SRC_ASM_CMDLINE= +} # tag:src-processing macro _SRC_ASM(SRC, SRCFLAGS...) { diff --git a/build/ymake_conf.py b/build/ymake_conf.py index fd6b6f01f9..0db0575d74 100755 --- a/build/ymake_conf.py +++ b/build/ymake_conf.py @@ -1044,7 +1044,14 @@ class GnuToolchainOptions(ToolchainOptions): self.sys_lib = self.target.find_in_dict(self.sys_lib, []) self.os_sdk = preset('OS_SDK') or self._default_os_sdk() - self.os_sdk_local = self.os_sdk == 'local' + + self.os_sdk_local = False + + if build.target.is_apple and to_bool(preset('APPLE_SDK_LOCAL'), default=False): + self.os_sdk_local = True + + if self.os_sdk == 'local': + self.os_sdk_local = True def _default_os_sdk(self): if self.target.is_linux: @@ -1265,15 +1272,10 @@ class GnuToolchain(Toolchain): if target.is_ios: self.c_flags_platform.append('-D__IOS__=1') - if self.tc.is_from_arcadia or self.tc.is_system_cxx: - if target.is_apple: - if target.is_ios: - self.setup_xcode_sdk(project='build/platform/ios_sdk', var='${IOS_SDK_ROOT_RESOURCE_GLOBAL}') - self.platform_projects.append('build/internal/platform/macos_system_stl') - if target.is_macos: - self.setup_xcode_sdk(project='build/internal/platform/macos_sdk', var='${MACOS_SDK_RESOURCE_GLOBAL}') - self.platform_projects.append('build/internal/platform/macos_system_stl') + if target.is_apple: + self.setup_apple_sdk(target) + if self.tc.is_from_arcadia or self.tc.is_system_cxx: if target.is_linux: if not tc.os_sdk_local: self.setup_sdk(project='build/platform/linux_sdk', var='$OS_SDK_ROOT_RESOURCE_GLOBAL') @@ -1290,22 +1292,42 @@ class GnuToolchain(Toolchain): if target.is_yocto: self.setup_sdk(project='build/platform/yocto_sdk/yocto_sdk', var='${YOCTO_SDK_ROOT_RESOURCE_GLOBAL}') - elif self.tc.params.get('local'): - if target.is_apple: - if not tc.os_sdk_local: - if target.is_ios: - self.setup_xcode_sdk(project='build/platform/ios_sdk', var='${IOS_SDK_ROOT_RESOURCE_GLOBAL}') - self.platform_projects.append('build/internal/platform/macos_system_stl') - if target.is_macos: - self.setup_xcode_sdk(project='build/internal/platform/macos_sdk', var='${MACOS_SDK_RESOURCE_GLOBAL}') - self.platform_projects.append('build/internal/platform/macos_system_stl') - else: - if target.is_iossim: - self.env.setdefault('SDKROOT', subprocess.check_output(['xcrun', '-sdk', 'iphonesimulator', '--show-sdk-path']).strip()) - elif target.is_ios: - self.env.setdefault('SDKROOT', subprocess.check_output(['xcrun', '-sdk', 'iphoneos', '--show-sdk-path']).strip()) - elif target.is_macos: - self.env.setdefault('SDKROOT', subprocess.check_output(['xcrun', '-sdk', 'macosx', '--show-sdk-path']).strip()) + + def setup_apple_sdk(self, target): + if not self.tc.os_sdk_local: + self.setup_apple_arcadia_sdk(target) + else: + self.setup_apple_local_sdk(target) + + def setup_apple_arcadia_sdk(self, target): + if target.is_ios: + self.setup_xcode_sdk(project='build/platform/ios_sdk', var='${IOS_SDK_ROOT_RESOURCE_GLOBAL}') + self.platform_projects.append('build/internal/platform/macos_system_stl') + if target.is_macos: + self.setup_xcode_sdk(project='build/internal/platform/macos_sdk', var='${MACOS_SDK_RESOURCE_GLOBAL}') + self.platform_projects.append('build/internal/platform/macos_system_stl') + + def setup_apple_local_sdk(self, target): + def get_output(*args): + return six.ensure_str(subprocess.check_output(tuple(args))).strip() + + def get_sdk_root(sdk): + root = self.env.get('SDKROOT') + if root not in (None, '', ['']): + return root + + root = os.environ.get('SDKROOT') + if root: + return root + + return get_output('xcrun', '-sdk', sdk, '--show-sdk-path') + + if target.is_iossim: + self.env['SDKROOT'] = get_sdk_root('iphonesimulator') + elif target.is_ios: + self.env['SDKROOT'] = get_sdk_root('iphoneos') + elif target.is_macos: + self.env['SDKROOT'] = get_sdk_root('macosx') def setup_sdk(self, project, var): self.platform_projects.append(project) diff --git a/contrib/clickhouse/src/Formats/registerFormats.cpp b/contrib/clickhouse/src/Formats/registerFormats.cpp index 5e91f433fe..fc2d54ba7c 100644 --- a/contrib/clickhouse/src/Formats/registerFormats.cpp +++ b/contrib/clickhouse/src/Formats/registerFormats.cpp @@ -14,7 +14,6 @@ void registerFileSegmentationEngineJSONEachRow(FormatFactory & factory); void registerFileSegmentationEngineRegexp(FormatFactory & factory); void registerFileSegmentationEngineJSONAsString(FormatFactory & factory); void registerFileSegmentationEngineJSONAsObject(FormatFactory & factory); -void registerFileSegmentationEngineJSONCompactEachRow(FormatFactory & factory); #if USE_HIVE void registerFileSegmentationEngineHiveText(FormatFactory & factory); #endif @@ -157,7 +156,6 @@ void registerFormats() registerFileSegmentationEngineJSONEachRow(factory); registerFileSegmentationEngineJSONAsString(factory); registerFileSegmentationEngineJSONAsObject(factory); - registerFileSegmentationEngineJSONCompactEachRow(factory); #if USE_HIVE registerFileSegmentationEngineHiveText(factory); #endif @@ -286,4 +284,3 @@ void registerFormats() } } - diff --git a/contrib/clickhouse/src/Interpreters/InterpreterCreateFunctionQuery.cpp b/contrib/clickhouse/src/Interpreters/InterpreterCreateFunctionQuery.cpp index b155476fd7..ea59115b07 100644 --- a/contrib/clickhouse/src/Interpreters/InterpreterCreateFunctionQuery.cpp +++ b/contrib/clickhouse/src/Interpreters/InterpreterCreateFunctionQuery.cpp @@ -6,6 +6,7 @@ #include <Interpreters/Context.h> #include <Interpreters/executeDDLQueryOnCluster.h> #include <Interpreters/removeOnClusterClauseIfNeeded.h> +#include <Interpreters/FunctionNameNormalizer.h> #include <Parsers/ASTCreateFunctionQuery.h> @@ -19,6 +20,7 @@ namespace ErrorCodes BlockIO InterpreterCreateFunctionQuery::execute() { + FunctionNameNormalizer().visit(query_ptr.get()); const auto updated_query_ptr = removeOnClusterClauseIfNeeded(query_ptr, getContext()); ASTCreateFunctionQuery & create_function_query = updated_query_ptr->as<ASTCreateFunctionQuery &>(); diff --git a/contrib/clickhouse/src/Interpreters/InterpreterCreateIndexQuery.cpp b/contrib/clickhouse/src/Interpreters/InterpreterCreateIndexQuery.cpp index 3b47a002e5..ed29c82a0f 100644 --- a/contrib/clickhouse/src/Interpreters/InterpreterCreateIndexQuery.cpp +++ b/contrib/clickhouse/src/Interpreters/InterpreterCreateIndexQuery.cpp @@ -4,6 +4,7 @@ #include <Databases/DatabaseReplicated.h> #include <Interpreters/Context.h> #include <Interpreters/executeDDLQueryOnCluster.h> +#include <Interpreters/FunctionNameNormalizer.h> #include <Parsers/ASTCreateIndexQuery.h> #include <Parsers/ASTIdentifier.h> #include <Parsers/ASTIndexDeclaration.h> @@ -22,6 +23,7 @@ namespace ErrorCodes BlockIO InterpreterCreateIndexQuery::execute() { + FunctionNameNormalizer().visit(query_ptr.get()); auto current_context = getContext(); const auto & create_index = query_ptr->as<ASTCreateIndexQuery &>(); diff --git a/contrib/clickhouse/src/Processors/Formats/Impl/JSONCompactEachRowRowInputFormat.cpp b/contrib/clickhouse/src/Processors/Formats/Impl/JSONCompactEachRowRowInputFormat.cpp index 1a8dddab83..efd90e05cd 100644 --- a/contrib/clickhouse/src/Processors/Formats/Impl/JSONCompactEachRowRowInputFormat.cpp +++ b/contrib/clickhouse/src/Processors/Formats/Impl/JSONCompactEachRowRowInputFormat.cpp @@ -279,23 +279,4 @@ void registerJSONCompactEachRowSchemaReader(FormatFactory & factory) } } -void registerFileSegmentationEngineJSONCompactEachRow(FormatFactory & factory) -{ - auto register_func = [&](const String & format_name, bool with_names, bool with_types) - { - /// In case when we have names and/or types in the first two/one rows, - /// we need to read at least one more row of actual data. So, set - /// the minimum of rows for segmentation engine according to - /// parameters with_names and with_types. - size_t min_rows = 1 + int(with_names) + int(with_types); - factory.registerFileSegmentationEngine(format_name, [min_rows](ReadBuffer & in, DB::Memory<> & memory, size_t min_bytes, size_t max_rows) - { - return JSONUtils::fileSegmentationEngineJSONCompactEachRow(in, memory, min_bytes, min_rows, max_rows); - }); - }; - - registerWithNamesAndTypes("JSONCompactEachRow", register_func); - registerWithNamesAndTypes("JSONCompactStringsEachRow", register_func); -} - } diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/equal_range.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/equal_range.h index cbfcd3c1ec..f30f55be64 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/equal_range.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/equal_range.h @@ -55,7 +55,7 @@ __equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __va _ForwardIterator __mp1 = __m; return pair<_ForwardIterator, _ForwardIterator> ( - _VSTD::__lower_bound_impl<_StdIterOps>(__first, __m, __value, __comp, __proj), + _VSTD::__lower_bound_impl<_ClassicAlgPolicy>(__first, __m, __value, __comp, __proj), _VSTD::__upper_bound<_Compare>(++__mp1, __last, __value, __comp) ); } diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/find_end.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/find_end.h index 0220c09397..65e9f29b1c 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/find_end.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/find_end.h @@ -11,8 +11,16 @@ #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 <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -20,35 +28,52 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2> -_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, - _BinaryPredicate __pred, forward_iterator_tag, - forward_iterator_tag) { +template < + class _AlgPolicy, + class _Iter1, + class _Sent1, + class _Iter2, + class _Sent2, + class _Pred, + class _Proj1, + class _Proj2> +_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_AFTER_CXX11 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 - _ForwardIterator1 __r = __last1; // __last1 is the "default" answer + _Iter1 __match_first = _IterOps<_AlgPolicy>::next(__first1, __last1); // __last1 is the "default" answer + _Iter1 __match_last = __match_first; if (__first2 == __last2) - return __r; + return pair<_Iter1, _Iter1>(__match_last, __match_last); while (true) { while (true) { - if (__first1 == __last1) // if source exhausted return last correct answer - return __r; // (or __last1 if never found) - if (__pred(*__first1, *__first2)) + 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 - _ForwardIterator1 __m1 = __first1; - _ForwardIterator2 __m2 = __first2; + _Iter1 __m1 = __first1; + _Iter2 __m2 = __first2; while (true) { if (++__m2 == __last2) { // Pattern exhaused, record answer and search for another one - __r = __first1; + __match_first = __first1; + __match_last = ++__m1; ++__first1; break; } if (++__m1 == __last1) // Source exhausted, return last answer - return __r; - if (!__pred(*__m1, *__m2)) // mismatch, restart with a new __first + 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; @@ -57,33 +82,52 @@ _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 __find_end(_ForwardIterator1 __f } } -template <class _BinaryPredicate, class _BidirectionalIterator1, class _BidirectionalIterator2> -_LIBCPP_CONSTEXPR_AFTER_CXX17 _BidirectionalIterator1 __find_end( - _BidirectionalIterator1 __first1, _BidirectionalIterator1 __last1, _BidirectionalIterator2 __first2, - _BidirectionalIterator2 __last2, _BinaryPredicate __pred, bidirectional_iterator_tag, bidirectional_iterator_tag) { +template < + class _IterOps, + class _Pred, + class _Iter1, + class _Sent1, + class _Iter2, + class _Sent2, + class _Proj1, + class _Proj2> +_LIBCPP_CONSTEXPR_AFTER_CXX17 _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 - _BidirectionalIterator1 __l1 = __last1; - _BidirectionalIterator2 __l2 = __last2; + _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 (__pred(*--__l1, *__l2)) + if (std::__invoke(__pred, std::__invoke(__proj1, *--__l1), std::__invoke(__proj2, *__l2))) break; } // *__l1 matches *__l2, now match elements before here - _BidirectionalIterator1 __m1 = __l1; - _BidirectionalIterator2 __m2 = __l2; + _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 (!__pred(*--__m1, *--__m2)) // if there is a mismatch, restart with a new __l1 + + // 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 @@ -91,37 +135,53 @@ _LIBCPP_CONSTEXPR_AFTER_CXX17 _BidirectionalIterator1 __find_end( } } -template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2> -_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1 __find_end( - _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, - _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag, random_access_iterator_tag) { - typedef typename iterator_traits<_RandomAccessIterator1>::difference_type _D1; - typedef typename iterator_traits<_RandomAccessIterator2>::difference_type _D2; +template < + class _AlgPolicy, + class _Pred, + class _Iter1, + class _Sent1, + class _Iter2, + class _Sent2, + class _Proj1, + class _Proj2> +_LIBCPP_CONSTEXPR_AFTER_CXX11 _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 - _D2 __len2 = __last2 - __first2; + auto __len2 = __last2 - __first2; if (__len2 == 0) return __last1; - _D1 __len1 = __last1 - __first1; + auto __len1 = __last1 - __first1; if (__len1 < __len2) return __last1; - const _RandomAccessIterator1 __s = __first1 + _D1(__len2 - 1); // End of pattern match can't go before here - _RandomAccessIterator1 __l1 = __last1; - _RandomAccessIterator2 __l2 = __last2; + 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 (__pred(*--__l1, *__l2)) + if (std::__invoke(__pred, std::__invoke(__proj1, *--__l1), std::__invoke(__proj2, *__l2))) break; } - _RandomAccessIterator1 __m1 = __l1; - _RandomAccessIterator2 __m2 = __l2; + _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 (!__pred(*--__m1, *--__m2)) { + if (!std::__invoke(__pred, std::__invoke(__proj1, *--__m1), std::__invoke(*--__m2))) { break; } } @@ -129,20 +189,39 @@ _LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1 __find_end( } template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 -find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, - _BinaryPredicate __pred) { - return _VSTD::__find_end<_BinaryPredicate&>( - __first1, __last1, __first2, __last2, __pred, typename iterator_traits<_ForwardIterator1>::iterator_category(), - typename iterator_traits<_ForwardIterator2>::iterator_category()); +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +_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 <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 +_ForwardIterator1 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __pred) { + return std::__find_end_classic(__first1, __last1, __first2, __last2, __pred); } template <class _ForwardIterator1, class _ForwardIterator2> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 -find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { - typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; - typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; - return _VSTD::find_end(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 +_ForwardIterator1 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2) { + using __v1 = typename iterator_traits<_ForwardIterator1>::value_type; + using __v2 = typename iterator_traits<_ForwardIterator2>::value_type; + return std::find_end(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/inplace_merge.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/inplace_merge.h index 58919ddbae..7369786eeb 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/inplace_merge.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/inplace_merge.h @@ -11,6 +11,7 @@ #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> @@ -21,7 +22,6 @@ #include <__iterator/distance.h> #include <__iterator/iterator_traits.h> #include <__iterator/reverse_iterator.h> -#include <__utility/swap.h> #include <memory> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -53,7 +53,7 @@ public: bool operator()(const _T1& __x, const _T2& __y) {return __p_(__y, __x);} }; -template <class _Compare, class _InputIterator1, class _InputIterator2, +template <class _AlgPolicy, class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> void __half_inplace_merge(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, @@ -63,25 +63,26 @@ void __half_inplace_merge(_InputIterator1 __first1, _InputIterator1 __last1, { if (__first2 == __last2) { + // TODO(alg-policy): pass `_AlgPolicy` once it's supported by `move`. _VSTD::move(__first1, __last1, __result); return; } if (__comp(*__first2, *__first1)) { - *__result = _VSTD::move(*__first2); + *__result = _IterOps<_AlgPolicy>::__iter_move(__first2); ++__first2; } else { - *__result = _VSTD::move(*__first1); + *__result = _IterOps<_AlgPolicy>::__iter_move(__first1); ++__first1; } } // __first2 through __last2 are already in the right spot. } -template <class _Compare, class _BidirectionalIterator> +template <class _AlgPolicy, class _Compare, class _BidirectionalIterator> void __buffered_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1, @@ -95,30 +96,32 @@ __buffered_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator { value_type* __p = __buff; for (_BidirectionalIterator __i = __first; __i != __middle; __d.template __incr<value_type>(), (void) ++__i, (void) ++__p) - ::new ((void*)__p) value_type(_VSTD::move(*__i)); - _VSTD::__half_inplace_merge<_Compare>(__buff, __p, __middle, __last, __first, __comp); + ::new ((void*)__p) value_type(_IterOps<_AlgPolicy>::__iter_move(__i)); + std::__half_inplace_merge<_AlgPolicy, _Compare>(__buff, __p, __middle, __last, __first, __comp); } else { value_type* __p = __buff; for (_BidirectionalIterator __i = __middle; __i != __last; __d.template __incr<value_type>(), (void) ++__i, (void) ++__p) - ::new ((void*)__p) value_type(_VSTD::move(*__i)); + ::new ((void*)__p) value_type(_IterOps<_AlgPolicy>::__iter_move(__i)); typedef reverse_iterator<_BidirectionalIterator> _RBi; typedef reverse_iterator<value_type*> _Rv; typedef __invert<_Compare> _Inverted; - _VSTD::__half_inplace_merge<_Inverted>(_Rv(__p), _Rv(__buff), + std::__half_inplace_merge<_AlgPolicy, _Inverted>(_Rv(__p), _Rv(__buff), _RBi(__middle), _RBi(__first), _RBi(__last), _Inverted(__comp)); } } -template <class _Compare, class _BidirectionalIterator> +template <class _AlgPolicy, class _Compare, class _BidirectionalIterator> 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) { @@ -126,7 +129,7 @@ __inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, if (__len2 == 0) return; if (__len1 <= __buff_size || __len2 <= __buff_size) - return _VSTD::__buffered_inplace_merge<_Compare> + return std::__buffered_inplace_merge<_AlgPolicy, _Compare> (__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) @@ -153,35 +156,37 @@ __inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, { // __len >= 1, __len2 >= 2 __len21 = __len2 / 2; __m2 = __middle; - _VSTD::advance(__m2, __len21); + _Ops::advance(__m2, __len21); __m1 = _VSTD::__upper_bound<_Compare>(__first, __middle, *__m2, __comp); - __len11 = _VSTD::distance(__first, __m1); + __len11 = _Ops::distance(__first, __m1); } else { if (__len1 == 1) { // __len1 >= __len2 && __len2 > 0, therefore __len2 == 1 // It is known *__first > *__middle - swap(*__first, *__middle); + _Ops::iter_swap(__first, __middle); return; } // __len1 >= 2, __len2 >= 1 __len11 = __len1 / 2; __m1 = __first; - _VSTD::advance(__m1, __len11); + _Ops::advance(__m1, __len11); __m2 = std::lower_bound(__middle, __last, *__m1, __comp); - __len21 = _VSTD::distance(__middle, __m2); + __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 + // TODO(alg-policy): pass `_AlgPolicy` once it's supported by `rotate`. __middle = _VSTD::rotate(__m1, __middle, __m2); // __len12 and __len21 now have swapped meanings // merge smaller range with recursive call and larger with tail recursion elimination if (__len11 + __len21 < __len12 + __len22) { - _VSTD::__inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size); + std::__inplace_merge<_AlgPolicy, _Compare>( + __first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size); // _VSTD::__inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size); __first = __middle; __middle = __m2; @@ -190,7 +195,8 @@ __inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, } else { - _VSTD::__inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size); + std::__inplace_merge<_AlgPolicy, _Compare>( + __middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size); // _VSTD::__inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size); __last = __middle; __middle = __m1; @@ -217,7 +223,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_PUSH _LIBCPP_SUPPRESS_DEPRECATED_POP unique_ptr<value_type, __return_temporary_buffer> __h(__buf.first); typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - return _VSTD::__inplace_merge<_Comp_ref>(__first, __middle, __last, __comp, __len1, __len2, + return _VSTD::__inplace_merge<_ClassicAlgPolicy, _Comp_ref>(__first, __middle, __last, __comp, __len1, __len2, __buf.first, __buf.second); } diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/iterator_operations.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/iterator_operations.h index 3d86f35f59..b27217d5d8 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/iterator_operations.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/iterator_operations.h @@ -6,14 +6,20 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORIHTM_ITERATOR_OPERATIONS_H -#define _LIBCPP___ALGORIHTM_ITERATOR_OPERATIONS_H +#ifndef _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H +#define _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H +#include <__algorithm/iter_swap.h> #include <__config> #include <__iterator/advance.h> #include <__iterator/distance.h> +#include <__iterator/iter_move.h> +#include <__iterator/iter_swap.h> #include <__iterator/iterator_traits.h> #include <__iterator/next.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -21,35 +27,91 @@ _LIBCPP_BEGIN_NAMESPACE_STD +template <class _AlgPolicy> struct _IterOps; + #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) -struct _RangesIterOps { +struct _RangeAlgPolicy {}; + +template <> +struct _IterOps<_RangeAlgPolicy> { 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 __advance_to = ranges::advance; }; + #endif -struct _StdIterOps { +struct _ClassicAlgPolicy {}; - template <class _Iterator, class _Distance> - _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_AFTER_CXX11 void advance(_Iterator& __iter, _Distance __count) { - return std::advance(__iter, __count); +template <> +struct _IterOps<_ClassicAlgPolicy> { + + // advance + template <class _Iter, class _Distance> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 + static void advance(_Iter& __iter, _Distance __count) { + std::advance(__iter, __count); } - template <class _Iterator> - _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_AFTER_CXX11 - typename iterator_traits<_Iterator>::difference_type distance(_Iterator __first, _Iterator __last) { + // distance + template <class _Iter> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 + static typename iterator_traits<_Iter>::difference_type distance(_Iter __first, _Iter __last) { return std::distance(__first, __last); } + // iter_move + template <class _Iter> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 + // Declaring the return type is necessary for C++03, so we basically mirror what `decltype(auto)` would deduce. + static __enable_if_t< + is_reference<typename iterator_traits<__uncvref_t<_Iter> >::reference>::value, + typename remove_reference< typename iterator_traits<__uncvref_t<_Iter> >::reference >::type&&> + __iter_move(_Iter&& __i) { + return std::move(*std::forward<_Iter>(__i)); + } + + template <class _Iter> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 + // Declaring the return type is necessary for C++03, so we basically mirror what `decltype(auto)` would deduce. + static __enable_if_t< + !is_reference<typename iterator_traits<__uncvref_t<_Iter> >::reference>::value, + typename iterator_traits<__uncvref_t<_Iter> >::reference> + __iter_move(_Iter&& __i) { + return *std::forward<_Iter>(__i); + } + + // iter_swap + template <class _Iter1, class _Iter2> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 + static void iter_swap(_Iter1&& __a, _Iter2&& __b) { + std::iter_swap(std::forward<_Iter1>(__a), std::forward<_Iter2>(__b)); + } + + // next template <class _Iterator> _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_AFTER_CXX11 _Iterator next(_Iterator, _Iterator __last) { return __last; } + template <class _Iter> + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_AFTER_CXX11 + __uncvref_t<_Iter> next(_Iter&& __it, + typename iterator_traits<__uncvref_t<_Iter> >::difference_type __n = 1){ + return std::next(std::forward<_Iter>(__it), __n); + } + + template <class _Iter> + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_AFTER_CXX11 + void __advance_to(_Iter& __first, _Iter __last) { + __first = __last; + } }; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORIHTM_ITERATOR_OPERATIONS_H +#endif // _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/lower_bound.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/lower_bound.h index 431ac92a64..2c92f71526 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/lower_bound.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/lower_bound.h @@ -19,6 +19,7 @@ #include <__iterator/distance.h> #include <__iterator/iterator_traits.h> #include <__type_traits/is_callable.h> +#include <__type_traits/remove_reference.h> #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -27,15 +28,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _IterOps, class _Iter, class _Sent, class _Type, class _Proj, class _Comp> +template <class _AlgPolicy, class _Iter, class _Sent, class _Type, class _Proj, class _Comp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _Iter __lower_bound_impl(_Iter __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) { - auto __len = _IterOps::distance(__first, __last); + auto __len = _IterOps<_AlgPolicy>::distance(__first, __last); while (__len != 0) { auto __l2 = std::__half_positive(__len); _Iter __m = __first; - _IterOps::advance(__m, __l2); + _IterOps<_AlgPolicy>::advance(__m, __l2); if (std::__invoke(__comp, std::__invoke(__proj, *__m), __value)) { __first = ++__m; __len -= __l2 + 1; @@ -52,7 +53,7 @@ _ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, 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<_StdIterOps>(__first, __last, __value, __comp, __proj); + return std::__lower_bound_impl<_ClassicAlgPolicy>(__first, __last, __value, __comp, __proj); } template <class _ForwardIterator, class _Tp> diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/make_heap.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/make_heap.h index bc39d82bf9..bf9dd96756 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/make_heap.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/make_heap.h @@ -11,6 +11,7 @@ #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> @@ -22,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Compare, class _RandomAccessIterator> +template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 void __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) { using _CompRef = typename __comp_ref_type<_Compare>::type; @@ -33,7 +34,7 @@ void __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _C 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<_CompRef>(__first, __comp_ref, __n, __first + __start); + std::__sift_down<_AlgPolicy, _CompRef>(__first, __comp_ref, __n, __first + __start); } } } @@ -41,7 +42,7 @@ void __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _C template <class _RandomAccessIterator, class _Compare> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { - std::__make_heap(std::move(__first), std::move(__last), __comp); + std::__make_heap<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); } template <class _RandomAccessIterator> diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/make_projected.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/make_projected.h index 6d8ebfd3d9..64fc3dfb6a 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/make_projected.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/make_projected.h @@ -27,6 +27,21 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { +template <class _Pred, class _Proj> +_LIBCPP_HIDE_FROM_ABI constexpr static +decltype(auto) __make_projected_pred(_Pred& __pred, _Proj& __proj) { + if constexpr (same_as<decay_t<_Proj>, identity> && !is_member_pointer_v<decay_t<_Pred>>) { + // Avoid creating the lambda and just use the pristine predicate -- for certain algorithms, this would enable + // optimizations that rely on the type of the predicate. + return __pred; + + } else { + return [&](auto&& __x) { + return std::invoke(__pred, std::invoke(__proj, std::forward<decltype(__x)>(__x))); + }; + } +} + template <class _Comp, class _Proj> _LIBCPP_HIDE_FROM_ABI constexpr static decltype(auto) __make_projected_comp(_Comp& __comp, _Proj& __proj) { diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/min_element.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/min_element.h index 129833d42b..17b242c341 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/min_element.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/min_element.h @@ -12,7 +12,11 @@ #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 @@ -20,28 +24,38 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Compare, class _ForwardIterator> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator -__min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) -{ - static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, - "std::min_element requires a ForwardIterator"); - if (__first != __last) - { - _ForwardIterator __i = __first; - while (++__i != __last) - if (__comp(*__i, *__first)) - __first = __i; - } +template <class _Comp, class _Iter, class _Sent, class _Proj> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +_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 <class _Comp, class _Iter, class _Sent> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +_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 <class _ForwardIterator, class _Compare> _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - return _VSTD::__min_element<_Comp_ref>(__first, __last, __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"); + + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + return std::__min_element<_Comp_ref>(std::move(__first), std::move(__last), __comp); } template <class _ForwardIterator> diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/nth_element.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/nth_element.h index c7cdef5be8..688398dee8 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/nth_element.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/nth_element.h @@ -11,13 +11,13 @@ #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> -#include <__utility/swap.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -41,10 +41,12 @@ __nth_element_find_guard(_RandomAccessIterator& __i, _RandomAccessIterator& __j, } } -template <class _Compare, class _RandomAccessIterator> +template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> _LIBCPP_CONSTEXPR_AFTER_CXX11 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; @@ -60,24 +62,24 @@ __nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _Rando return; case 2: if (__comp(*--__last, *__first)) - swap(*__first, *__last); + _Ops::iter_swap(__first, __last); return; case 3: { _RandomAccessIterator __m = __first; - _VSTD::__sort3<_Compare>(__first, ++__m, --__last, __comp); + std::__sort3<_AlgPolicy, _Compare>(__first, ++__m, --__last, __comp); return; } } if (__len <= __limit) { - _VSTD::__selection_sort<_Compare>(__first, __last, __comp); + std::__selection_sort<_AlgPolicy, _Compare>(__first, __last, __comp); return; } // __len > __limit >= 3 _RandomAccessIterator __m = __first + __len/2; _RandomAccessIterator __lm1 = __last; - unsigned __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, --__lm1, __comp); + 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) @@ -90,7 +92,7 @@ __nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _Rando { // *__first == *__m, *__first doesn't go in first part if (_VSTD::__nth_element_find_guard<_Compare>(__i, __j, __m, __comp)) { - swap(*__i, *__j); + _Ops::iter_swap(__i, __j); ++__n_swaps; } else { // *__first == *__m, *__m <= all other elements @@ -102,7 +104,7 @@ __nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _Rando if (__i == __j) { return; // [__first, __last) all equivalent elements } else if (__comp(*__first, *__i)) { - swap(*__i, *__j); + _Ops::iter_swap(__i, __j); ++__n_swaps; ++__i; break; @@ -121,7 +123,7 @@ __nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _Rando ; if (__i >= __j) break; - swap(*__i, *__j); + _Ops::iter_swap(__i, __j); ++__n_swaps; ++__i; } @@ -152,7 +154,7 @@ __nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _Rando ; if (__i >= __j) break; - swap(*__i, *__j); + _Ops::iter_swap(__i, __j); ++__n_swaps; // It is known that __m != __j // If __m just moved, follow it @@ -164,7 +166,7 @@ __nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _Rando // [__first, __i) < *__m and *__m <= [__i, __last) if (__i != __m && __comp(*__m, *__i)) { - swap(*__i, *__m); + _Ops::iter_swap(__i, __m); ++__n_swaps; } // [__first, __i) < *__i and *__i <= [__i+1, __last) @@ -220,21 +222,21 @@ __nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _Rando } } -template <class _RandomAccessIterator, class _Compare> +template <class _AlgPolicy, class _RandomAccessIterator, class _Compare> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __nth_element_impl(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare& __comp) { if (__nth == __last) return; - std::__debug_randomize_range(__first, __last); + std::__debug_randomize_range<_AlgPolicy>(__first, __last); using _Comp_ref = typename __comp_ref_type<_Compare>::type; - std::__nth_element<_Comp_ref>(__first, __nth, __last, __comp); + std::__nth_element<_AlgPolicy, _Comp_ref>(__first, __nth, __last, __comp); - std::__debug_randomize_range(__first, __nth); + std::__debug_randomize_range<_AlgPolicy>(__first, __nth); if (__nth != __last) { - std::__debug_randomize_range(++__nth, __last); + std::__debug_randomize_range<_AlgPolicy>(++__nth, __last); } } @@ -242,7 +244,7 @@ template <class _RandomAccessIterator, class _Compare> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) { - std::__nth_element_impl(std::move(__first), std::move(__nth), std::move(__last), __comp); + std::__nth_element_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__nth), std::move(__last), __comp); } template <class _RandomAccessIterator> diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/partial_sort.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/partial_sort.h index e008c0c996..cb6887e39b 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/partial_sort.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/partial_sort.h @@ -11,6 +11,7 @@ #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> @@ -18,7 +19,8 @@ #include <__debug> #include <__debug_utils/randomize_range.h> #include <__iterator/iterator_traits.h> -#include <__utility/swap.h> +#include <__utility/move.h> +#include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -26,24 +28,55 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Compare, class _RandomAccessIterator> -_LIBCPP_CONSTEXPR_AFTER_CXX17 void -__partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, - _Compare __comp) -{ - if (__first == __middle) - return; - _VSTD::__make_heap<_Compare>(__first, __middle, __comp); - typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first; - for (_RandomAccessIterator __i = __middle; __i != __last; ++__i) - { - if (__comp(*__i, *__first)) - { - swap(*__i, *__first); - _VSTD::__sift_down<_Compare>(__first, __comp, __len, __first); - } - } - _VSTD::__sort_heap<_Compare>(__first, __middle, __comp); +template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, class _Sentinel> +_LIBCPP_CONSTEXPR_AFTER_CXX17 +_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, _Compare>(__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, _Compare>(__first, __comp, __len, __first); + } + + } + std::__sort_heap<_AlgPolicy, _Compare>(std::move(__first), std::move(__middle), __comp); + + return __i; +} + +// TODO(ranges): once `ranges::shuffle` is implemented, remove this helper and make `__debug_randomize_range` support +// sentinels. +template <class _AlgPolicy, class _RandomAccessIterator, class _Sentinel> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 +void __maybe_randomize(_RandomAccessIterator __first, _Sentinel __last) { + std::__debug_randomize_range<_AlgPolicy>(__first, _IterOps<_AlgPolicy>::next(__first, __last)); +} + +template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, class _Sentinel> +_LIBCPP_CONSTEXPR_AFTER_CXX17 +_RandomAccessIterator __partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, + _Compare& __comp) { + if (__first == __middle) + return _IterOps<_AlgPolicy>::next(__middle, __last); + + std::__maybe_randomize<_AlgPolicy>(__first, __last); + + using _Comp_ref = typename __comp_ref_type<_Compare>::type; + auto __last_iter = std::__partial_sort_impl<_AlgPolicy, _Comp_ref>(__first, __middle, __last, __comp); + + std::__maybe_randomize<_AlgPolicy>(__middle, __last); + + return __last_iter; } template <class _RandomAccessIterator, class _Compare> @@ -52,10 +85,10 @@ void partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, _Compare __comp) { - std::__debug_randomize_range(__first, __last); - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - _VSTD::__partial_sort<_Comp_ref>(__first, __middle, __last, __comp); - std::__debug_randomize_range(__middle, __last); + 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 <class _RandomAccessIterator> diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/partial_sort_copy.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/partial_sort_copy.h index 7ed1e538e9..3556764e65 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/partial_sort_copy.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/partial_sort_copy.h @@ -11,6 +11,7 @@ #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> @@ -23,7 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Compare, class _InputIterator, class _RandomAccessIterator> +template <class _AlgPolicy, class _Compare, class _InputIterator, class _RandomAccessIterator> _LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator __partial_sort_copy(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp) @@ -33,15 +34,15 @@ __partial_sort_copy(_InputIterator __first, _InputIterator __last, { for (; __first != __last && __r != __result_last; ++__first, (void) ++__r) *__r = *__first; - _VSTD::__make_heap<_Compare>(__result_first, __r, __comp); + std::__make_heap<_AlgPolicy, _Compare>(__result_first, __r, __comp); typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first; for (; __first != __last; ++__first) if (__comp(*__first, *__result_first)) { *__result_first = *__first; - _VSTD::__sift_down<_Compare>(__result_first, __comp, __len, __result_first); + std::__sift_down<_AlgPolicy, _Compare>(__result_first, __comp, __len, __result_first); } - _VSTD::__sort_heap<_Compare>(__result_first, __r, __comp); + std::__sort_heap<_AlgPolicy, _Compare>(__result_first, __r, __comp); } return __r; } @@ -53,7 +54,8 @@ partial_sort_copy(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp) { typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - return _VSTD::__partial_sort_copy<_Comp_ref>(__first, __last, __result_first, __result_last, __comp); + return std::__partial_sort_copy<_ClassicAlgPolicy, _Comp_ref>( + __first, __last, __result_first, __result_last, __comp); } template <class _InputIterator, class _RandomAccessIterator> diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/partition.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/partition.h index 73d94831ed..60b4e290eb 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/partition.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/partition.h @@ -9,9 +9,12 @@ #ifndef _LIBCPP___ALGORITHM_PARTITION_H #define _LIBCPP___ALGORITHM_PARTITION_H +#include <__algorithm/iterator_operations.h> #include <__config> #include <__iterator/iterator_traits.h> -#include <__utility/swap.h> +#include <__utility/move.h> +#include <__utility/pair.h> +#include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -19,40 +22,45 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Predicate, class _ForwardIterator> -_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator -__partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, forward_iterator_tag) +template <class _Predicate, class _AlgPolicy, class _ForwardIterator, class _Sentinel> +_LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_ForwardIterator, _ForwardIterator> +__partition_impl(_ForwardIterator __first, _Sentinel __last, _Predicate __pred, forward_iterator_tag) { while (true) { if (__first == __last) - return __first; + return std::make_pair(std::move(__first), std::move(__first)); if (!__pred(*__first)) break; ++__first; } - for (_ForwardIterator __p = __first; ++__p != __last;) + + _ForwardIterator __p = __first; + while (++__p != __last) { if (__pred(*__p)) { - swap(*__first, *__p); + _IterOps<_AlgPolicy>::iter_swap(__first, __p); ++__first; } } - return __first; + return std::make_pair(std::move(__first), std::move(__p)); } -template <class _Predicate, class _BidirectionalIterator> -_LIBCPP_CONSTEXPR_AFTER_CXX17 _BidirectionalIterator -__partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, +template <class _Predicate, class _AlgPolicy, class _BidirectionalIterator, class _Sentinel> +_LIBCPP_CONSTEXPR_AFTER_CXX17 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 __first; + return std::make_pair(std::move(__first), std::move(__original_last)); if (!__pred(*__first)) break; ++__first; @@ -60,20 +68,29 @@ __partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Pred do { if (__first == --__last) - return __first; + return std::make_pair(std::move(__first), std::move(__original_last)); } while (!__pred(*__last)); - swap(*__first, *__last); + _IterOps<_AlgPolicy>::iter_swap(__first, __last); ++__first; } } +template <class _AlgPolicy, class _ForwardIterator, class _Sentinel, class _Predicate, class _IterCategory> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 +pair<_ForwardIterator, _ForwardIterator> __partition( + _ForwardIterator __first, _Sentinel __last, _Predicate&& __pred, _IterCategory __iter_category) { + return std::__partition_impl<__uncvref_t<_Predicate>&, _AlgPolicy>( + std::move(__first), std::move(__last), __pred, __iter_category); +} + template <class _ForwardIterator, class _Predicate> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { - return _VSTD::__partition<_Predicate&>( - __first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category()); + 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 diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/pop_heap.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/pop_heap.h index cadda81f6c..870af50c13 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/pop_heap.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/pop_heap.h @@ -11,12 +11,14 @@ #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 <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -24,7 +26,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Compare, class _RandomAccessIterator> +template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp, typename iterator_traits<_RandomAccessIterator>::difference_type __len) { @@ -35,17 +37,17 @@ void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Co using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; if (__len > 1) { - value_type __top = std::move(*__first); // create a hole at __first - _RandomAccessIterator __hole = std::__floyd_sift_down<_CompRef>(__first, __comp_ref, __len); + value_type __top = _IterOps<_AlgPolicy>::__iter_move(__first); // create a hole at __first + _RandomAccessIterator __hole = std::__floyd_sift_down<_AlgPolicy, _CompRef>(__first, __comp_ref, __len); --__last; if (__hole == __last) { *__hole = std::move(__top); } else { - *__hole = std::move(*__last); + *__hole = _IterOps<_AlgPolicy>::__iter_move(__last); ++__hole; *__last = std::move(__top); - std::__sift_up<_CompRef>(__first, __hole, __comp_ref, __hole - __first); + std::__sift_up<_AlgPolicy, _CompRef>(__first, __hole, __comp_ref, __hole - __first); } } } @@ -53,8 +55,11 @@ void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Co template <class _RandomAccessIterator, class _Compare> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 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(std::move(__first), std::move(__last), __comp, __len); + std::__pop_heap<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp, __len); } template <class _RandomAccessIterator> diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/push_heap.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/push_heap.h index 1e3eec373d..716670b767 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/push_heap.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/push_heap.h @@ -11,9 +11,11 @@ #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 <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -21,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Compare, class _RandomAccessIterator> +template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 void __sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, typename iterator_traits<_RandomAccessIterator>::difference_type __len) { @@ -32,9 +34,9 @@ void __sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com _RandomAccessIterator __ptr = __first + __len; if (__comp(*__ptr, *--__last)) { - value_type __t(std::move(*__last)); + value_type __t(_IterOps<_AlgPolicy>::__iter_move(__last)); do { - *__last = std::move(*__ptr); + *__last = _IterOps<_AlgPolicy>::__iter_move(__ptr); __last = __ptr; if (__len == 0) break; @@ -47,18 +49,21 @@ void __sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com } } -template <class _RandomAccessIterator, class _Compare> +template <class _AlgPolicy, class _RandomAccessIterator, class _Compare> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 void __push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) { using _CompRef = typename __comp_ref_type<_Compare>::type; typename iterator_traits<_RandomAccessIterator>::difference_type __len = __last - __first; - std::__sift_up<_CompRef>(std::move(__first), std::move(__last), __comp, __len); + std::__sift_up<_AlgPolicy, _CompRef>(std::move(__first), std::move(__last), __comp, __len); } template <class _RandomAccessIterator, class _Compare> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { - std::__push_heap(std::move(__first), std::move(__last), __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 <class _RandomAccessIterator> diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_binary_search.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_binary_search.h index 68359fb138..6da68834aa 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_binary_search.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_binary_search.h @@ -35,7 +35,7 @@ struct __fn { indirect_strict_weak_order<const _Type*, projected<_Iter, _Proj>> _Comp = ranges::less> _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<_RangesIterOps>(__first, __last, __value, __comp, __proj); + auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__first)); } @@ -45,7 +45,7 @@ struct __fn { 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<_RangesIterOps>(__first, __last, __value, __comp, __proj); + auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__first)); } }; diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_fill.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_fill.h index 846e318851..7ce4a76ba9 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_fill.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_fill.h @@ -30,7 +30,7 @@ struct __fn { template <class _Type, output_iterator<const _Type&> _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>) { + if constexpr(random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>) { return ranges::fill_n(__first, __last - __first, __value); } else { for (; __first != __last; ++__first) diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_find_end.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_find_end.h new file mode 100644 index 0000000000..270b006498 --- /dev/null +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_find_end.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_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> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __find_end { +struct __fn { + template <forward_iterator _Iter1, sentinel_for<_Iter1> _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_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 <forward_range _Range1, + forward_range _Range2, + class _Pred = ranges::equal_to, + class _Proj1 = identity, + class _Proj2 = identity> + requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> + _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_t<_Range1>>(), + __iterator_concept<iterator_t<_Range2>>()); + 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 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +#endif // _LIBCPP___ALGORITHM_RANGES_FIND_END_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_for_each_n.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_for_each_n.h index ddf8b047cd..013afbd193 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_for_each_n.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_for_each_n.h @@ -18,7 +18,6 @@ #include <__iterator/iterator_traits.h> #include <__iterator/projected.h> #include <__ranges/concepts.h> -#include <__ranges/dangling.h> #include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_iterator_concept.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_iterator_concept.h new file mode 100644 index 0000000000..3323119317 --- /dev/null +++ b/contrib/libs/cxxsupp/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> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template <class _IterMaybeQualified> +consteval auto __get_iterator_concept() { + using _Iter = __uncvref_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 <class _Iter> +using __iterator_concept = decltype(__get_iterator_concept<_Iter>()); + +} // namespace ranges +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +#endif // _LIBCPP___ALGORITHM_RANGES_ITERATOR_CONCEPT_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_lower_bound.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_lower_bound.h index a73470465c..1a9ae204a1 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_lower_bound.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_lower_bound.h @@ -39,7 +39,7 @@ struct __fn { indirect_strict_weak_order<const _Type*, projected<_Iter, _Proj>> _Comp = ranges::less> _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { - return std::__lower_bound_impl<_RangesIterOps>(__first, __last, __value, __comp, __proj); + return std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); } template <forward_range _Range, class _Type, class _Proj = identity, @@ -49,7 +49,7 @@ struct __fn { const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { - return std::__lower_bound_impl<_RangesIterOps>(ranges::begin(__r), ranges::end(__r), __value, __comp, __proj); + return std::__lower_bound_impl<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), __value, __comp, __proj); } }; } // namespace __lower_bound diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_make_heap.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_make_heap.h index fd488dc11a..8eabdd12cd 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_make_heap.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_make_heap.h @@ -9,6 +9,7 @@ #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> @@ -45,7 +46,7 @@ struct __fn { auto __last_iter = ranges::next(__first, __last); auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj); - std::__make_heap(std::move(__first), __last_iter, __projected_comp); + std::__make_heap<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp); return __last_iter; } diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_min_element.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_min_element.h index ae82dceb9a..26f95fe3a6 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_min_element.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_min_element.h @@ -30,6 +30,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { +// TODO(ranges): `ranges::min_element` can now simply delegate to `std::__min_element`. template <class _Ip, class _Sp, class _Proj, class _Comp> _LIBCPP_HIDE_FROM_ABI static constexpr _Ip __min_element_impl(_Ip __first, _Sp __last, _Comp& __comp, _Proj& __proj) { diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_nth_element.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_nth_element.h index 2a929eacb8..b15eb816b9 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_nth_element.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_nth_element.h @@ -9,6 +9,7 @@ #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> @@ -44,7 +45,7 @@ struct __fn { auto __last_iter = ranges::next(__first, __last); auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj); - std::__nth_element_impl(std::move(__first), std::move(__nth), __last_iter, __projected_comp); + std::__nth_element_impl<_RangeAlgPolicy>(std::move(__first), std::move(__nth), __last_iter, __projected_comp); return __last_iter; } diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_partial_sort.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_partial_sort.h new file mode 100644 index 0000000000..5e82bc6fcc --- /dev/null +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_partial_sort.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_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> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __partial_sort { + +struct __fn { + template <class _Iter, class _Sent, class _Comp, class _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr static + _Iter __partial_sort_fn_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj); + return std::__partial_sort<_RangeAlgPolicy>(std::move(__first), std::move(__middle), __last, __projected_comp); + } + + template <random_access_iterator _Iter, sentinel_for<_Iter> _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 <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity> + requires sortable<iterator_t<_Range>, _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 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +#endif // _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_partition.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_partition.h new file mode 100644 index 0000000000..60bee699d9 --- /dev/null +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_partition.h @@ -0,0 +1,82 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.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 <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __partition { + +struct __fn { + + template <class _Iter, class _Sent, class _Proj, class _Pred> + _LIBCPP_HIDE_FROM_ABI static constexpr + subrange<__uncvref_t<_Iter>> __partition_fn_impl(_Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) { + auto&& __projected_pred = ranges::__make_projected_pred(__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 <permutable _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity, + indirect_unary_predicate<projected<_Iter, _Proj>> _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 <forward_range _Range, class _Proj = identity, + indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred> + requires permutable<iterator_t<_Range>> + _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 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +#endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_partition_copy.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_partition_copy.h new file mode 100644 index 0000000000..7201a8cbfe --- /dev/null +++ b/contrib/libs/cxxsupp/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 <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template <class _InIter, class _OutIter1, class _OutIter2> +using partition_copy_result = in_out_out_result<_InIter, _OutIter1, _OutIter2>; + +namespace __partition_copy { + +struct __fn { + + // TODO(ranges): delegate to the classic algorithm. + template <class _InIter, class _Sent, class _OutIter1, class _OutIter2, class _Proj, class _Pred> + _LIBCPP_HIDE_FROM_ABI constexpr + static partition_copy_result< + __uncvref_t<_InIter>, __uncvref_t<_OutIter1>, __uncvref_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 <input_iterator _InIter, sentinel_for<_InIter> _Sent, + weakly_incrementable _OutIter1, weakly_incrementable _OutIter2, + class _Proj = identity, indirect_unary_predicate<projected<_InIter, _Proj>> _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 <input_range _Range, weakly_incrementable _OutIter1, weakly_incrementable _OutIter2, + class _Proj = identity, indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred> + requires indirectly_copyable<iterator_t<_Range>, _OutIter1> && indirectly_copyable<iterator_t<_Range>, _OutIter2> + _LIBCPP_HIDE_FROM_ABI constexpr + partition_copy_result<borrowed_iterator_t<_Range>, _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 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +#endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_COPY_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_partition_point.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_partition_point.h new file mode 100644 index 0000000000..6614a0bb50 --- /dev/null +++ b/contrib/libs/cxxsupp/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 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __partition_point { + +struct __fn { + + // TODO(ranges): delegate to the classic algorithm. + template <class _Iter, class _Sent, class _Proj, class _Pred> + _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 <forward_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity, + indirect_unary_predicate<projected<_Iter, _Proj>> _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 <forward_range _Range, class _Proj = identity, + indirect_unary_predicate<projected<iterator_t<_Range>, _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 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +#endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_POINT_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_pop_heap.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_pop_heap.h index d0b8314e5b..92df6119d3 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_pop_heap.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_pop_heap.h @@ -9,6 +9,7 @@ #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> @@ -46,7 +47,7 @@ struct __fn { auto __len = __last_iter - __first; auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj); - std::__pop_heap(std::move(__first), __last_iter, __projected_comp, __len); + std::__pop_heap<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp, __len); return __last_iter; } diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_push_heap.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_push_heap.h index e46ad19cfe..4c41b00128 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_push_heap.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_push_heap.h @@ -9,6 +9,7 @@ #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> @@ -45,7 +46,7 @@ struct __fn { auto __last_iter = ranges::next(__first, __last); auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj); - std::__push_heap(std::move(__first), __last_iter, __projected_comp); + std::__push_heap<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp); return __last_iter; } diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_search.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_search.h new file mode 100644 index 0000000000..0564bbe1f8 --- /dev/null +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_search.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_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> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __search { +struct __fn { + template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2> + _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 <forward_iterator _Iter1, sentinel_for<_Iter1> _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_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 <forward_range _Range1, + forward_range _Range2, + class _Pred = ranges::equal_to, + class _Proj1 = identity, + class _Proj2 = identity> + requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> + _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 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +#endif // _LIBCPP___ALGORITHM_RANGES_SEARCH_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_search_n.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_search_n.h new file mode 100644 index 0000000000..29fdbfb1c7 --- /dev/null +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_search_n.h @@ -0,0 +1,120 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.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> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __search_n { +struct __fn { + + template <class _Iter1, class _Sent1, class _SizeT, class _Type, class _Pred, class _Proj> + _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 = __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 <forward_iterator _Iter, sentinel_for<_Iter> _Sent, + class _Type, + class _Pred = ranges::equal_to, + class _Proj = identity> + requires indirectly_comparable<_Iter, const _Type*, _Pred, _Proj> + _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 <forward_range _Range, class _Type, class _Pred = ranges::equal_to, class _Proj = identity> + requires indirectly_comparable<iterator_t<_Range>, const _Type*, _Pred, _Proj> + _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<range_size_t<_Range>>(__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 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +#endif // _LIBCPP___ALGORITHM_RANGES_SEARCH_N_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_intersection.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_intersection.h index feb0fe4222..331ff061d3 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_intersection.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_intersection.h @@ -59,14 +59,14 @@ struct __fn { _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { - auto __ret = std::__set_intersection<_RangesIterOps>( + 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)}; + return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)}; } template < @@ -93,14 +93,14 @@ struct __fn { _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { - auto __ret = std::__set_intersection<_RangesIterOps>( + 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)}; + return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)}; } }; diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_symmetric_difference.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_symmetric_difference.h new file mode 100644 index 0000000000..f45c5dca6e --- /dev/null +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_symmetric_difference.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_SET_SYMMETRIC_DIFFERENCE_H +#define _LIBCPP___ALGORITHM_RANGES_SET_SYMMETRIC_DIFFERENCE_H + +#include <__algorithm/in_in_out_result.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 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template <class _InIter1, class _InIter2, class _OutIter> +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( + 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<_Range1>, + 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( + 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 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) +#endif // _LIBCPP___ALGORITHM_RANGES_SET_SYMMETRIC_DIFFERENCE_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_union.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_union.h new file mode 100644 index 0000000000..e4f28bb86a --- /dev/null +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_union.h @@ -0,0 +1,120 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.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/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 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template <class _InIter1, class _InIter2, class _OutIter> +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( + 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<_Range1>, + borrowed_iterator_t<_Range2>, + _OutIter> + operator()( + _Range1&& __range1, + _Range2&& __range2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + auto __ret = std::__set_union( + 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 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +#endif // _LIBCPP___ALGORITHM_RANGES_SET_UNION_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_sort.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_sort.h index 8297940df2..ef14db6429 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_sort.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_sort.h @@ -9,6 +9,7 @@ #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> @@ -44,7 +45,7 @@ struct __fn { auto __last_iter = ranges::next(__first, __last); auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj); - std::__sort_impl(std::move(__first), __last_iter, __projected_comp); + std::__sort_impl<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp); return __last_iter; } diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_sort_heap.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_sort_heap.h index c753e20c44..eb6a30dcd3 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_sort_heap.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_sort_heap.h @@ -9,6 +9,7 @@ #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> @@ -45,7 +46,7 @@ struct __fn { auto __last_iter = ranges::next(__first, __last); auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj); - std::__sort_heap(std::move(__first), __last_iter, __projected_comp); + std::__sort_heap<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp); return __last_iter; } diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_stable_partition.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_stable_partition.h new file mode 100644 index 0000000000..27957db882 --- /dev/null +++ b/contrib/libs/cxxsupp/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 <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __stable_partition { + +struct __fn { + + template <class _Iter, class _Sent, class _Proj, class _Pred> + _LIBCPP_HIDE_FROM_ABI static + subrange<__uncvref_t<_Iter>> __stable_partition_fn_impl( + _Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) { + auto __last_iter = ranges::next(__first, __last); + + auto&& __projected_pred = ranges::__make_projected_pred(__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 <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity, + indirect_unary_predicate<projected<_Iter, _Proj>> _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 <bidirectional_range _Range, class _Proj = identity, + indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred> + requires permutable<iterator_t<_Range>> + _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 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +#endif // _LIBCPP___ALGORITHM_RANGES_STABLE_PARTITION_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_stable_sort.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_stable_sort.h index 20e8404264..de48416a41 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_stable_sort.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_stable_sort.h @@ -9,6 +9,7 @@ #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> @@ -44,7 +45,7 @@ struct __fn { auto __last_iter = ranges::next(__first, __last); auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj); - std::__stable_sort_impl(std::move(__first), __last_iter, __projected_comp); + std::__stable_sort_impl<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp); return __last_iter; } diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_upper_bound.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_upper_bound.h index 94b5269c86..3c63249248 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_upper_bound.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_upper_bound.h @@ -40,7 +40,7 @@ struct __fn { return !std::invoke(__comp, __rhs, __lhs); }; - return std::__lower_bound_impl<_RangesIterOps>(__first, __last, __value, __comp_lhs_rhs_swapped, __proj); + return std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp_lhs_rhs_swapped, __proj); } template <forward_range _Range, class _Type, class _Proj = identity, @@ -54,7 +54,7 @@ struct __fn { return !std::invoke(__comp, __rhs, __lhs); }; - return std::__lower_bound_impl<_RangesIterOps>(ranges::begin(__r), + return std::__lower_bound_impl<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), __value, __comp_lhs_rhs_swapped, diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/rotate.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/rotate.h index c9ea5bad4c..fcf8444a65 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/rotate.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/rotate.h @@ -9,6 +9,7 @@ #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> @@ -26,37 +27,40 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _ForwardIterator> +template <class _AlgPolicy, class _ForwardIterator> _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator __rotate_left(_ForwardIterator __first, _ForwardIterator __last) { typedef typename iterator_traits<_ForwardIterator>::value_type value_type; - value_type __tmp = _VSTD::move(*__first); + value_type __tmp = _IterOps<_AlgPolicy>::__iter_move(__first); + // TODO(ranges): pass `_AlgPolicy` to `move`. _ForwardIterator __lm1 = _VSTD::move(_VSTD::next(__first), __last, __first); *__lm1 = _VSTD::move(__tmp); return __lm1; } -template <class _BidirectionalIterator> +template <class _AlgPolicy, class _BidirectionalIterator> _LIBCPP_CONSTEXPR_AFTER_CXX11 _BidirectionalIterator __rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last) { typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + // TODO(ranges): pass `_AlgPolicy` to `prev`. _BidirectionalIterator __lm1 = _VSTD::prev(__last); - value_type __tmp = _VSTD::move(*__lm1); + value_type __tmp = _IterOps<_AlgPolicy>::__iter_move(__lm1); + // TODO(ranges): pass `_AlgPolicy` to `move_backward`. _BidirectionalIterator __fp1 = _VSTD::move_backward(__first, __lm1, __last); *__first = _VSTD::move(__tmp); return __fp1; } -template <class _ForwardIterator> +template <class _AlgPolicy, class _ForwardIterator> _LIBCPP_CONSTEXPR_AFTER_CXX14 _ForwardIterator __rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) { _ForwardIterator __i = __middle; while (true) { - swap(*__first, *__i); + _IterOps<_AlgPolicy>::iter_swap(__first, __i); ++__first; if (++__i == __last) break; @@ -69,7 +73,7 @@ __rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIt __i = __middle; while (true) { - swap(*__first, *__i); + _IterOps<_AlgPolicy>::iter_swap(__first, __i); ++__first; if (++__i == __last) { @@ -98,7 +102,7 @@ __algo_gcd(_Integral __x, _Integral __y) return __x; } -template<typename _RandomAccessIterator> +template <class _AlgPolicy, typename _RandomAccessIterator> _LIBCPP_CONSTEXPR_AFTER_CXX14 _RandomAccessIterator __rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) { @@ -109,18 +113,19 @@ __rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Ran const difference_type __m2 = __last - __middle; if (__m1 == __m2) { + // TODO(ranges): pass `_AlgPolicy` to `swap_ranges`. _VSTD::swap_ranges(__first, __middle, __middle); return __middle; } const difference_type __g = _VSTD::__algo_gcd(__m1, __m2); for (_RandomAccessIterator __p = __first + __g; __p != __first;) { - value_type __t(_VSTD::move(*--__p)); + value_type __t(_IterOps<_AlgPolicy>::__iter_move(--__p)); _RandomAccessIterator __p1 = __p; _RandomAccessIterator __p2 = __p1 + __m1; do { - *__p1 = _VSTD::move(*__p2); + *__p1 = _IterOps<_AlgPolicy>::__iter_move(__p2); __p1 = __p2; const difference_type __d = __last - __p2; if (__m1 < __d) @@ -133,54 +138,66 @@ __rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Ran return __first + __m2; } -template <class _ForwardIterator> +template <class _AlgPolicy, class _ForwardIterator> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator -__rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, +__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_type>::value) { - if (_VSTD::next(__first) == __middle) - return _VSTD::__rotate_left(__first, __last); + if (_IterOps<_AlgPolicy>::next(__first) == __middle) + return std::__rotate_left<_AlgPolicy>(__first, __last); } - return _VSTD::__rotate_forward(__first, __middle, __last); + return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last); } -template <class _BidirectionalIterator> +template <class _AlgPolicy, class _BidirectionalIterator> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _BidirectionalIterator -__rotate(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, +__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_type>::value) { - if (_VSTD::next(__first) == __middle) - return _VSTD::__rotate_left(__first, __last); - if (_VSTD::next(__middle) == __last) - return _VSTD::__rotate_right(__first, __last); + 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 _VSTD::__rotate_forward(__first, __middle, __last); + return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last); } -template <class _RandomAccessIterator> +template <class _AlgPolicy, class _RandomAccessIterator> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator -__rotate(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, +__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_type>::value) { - if (_VSTD::next(__first) == __middle) - return _VSTD::__rotate_left(__first, __last); - if (_VSTD::next(__middle) == __last) - return _VSTD::__rotate_right(__first, __last); - return _VSTD::__rotate_gcd(__first, __middle, __last); + 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 _VSTD::__rotate_forward(__first, __middle, __last); + return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last); +} + +template <class _AlgPolicy, class _RandomAccessIterator, class _IterCategory> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +_RandomAccessIterator __rotate(_RandomAccessIterator __first, _RandomAccessIterator __middle, + _RandomAccessIterator __last, _IterCategory __iter_category) { + if (__first == __middle) + return __last; + if (__middle == __last) + return __first; + + return std::__rotate_impl<_AlgPolicy>(std::move(__first), std::move(__middle), std::move(__last), __iter_category); } template <class _ForwardIterator> @@ -188,12 +205,8 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) { - if (__first == __middle) - return __last; - if (__middle == __last) - return __first; - return _VSTD::__rotate(__first, __middle, __last, - typename iterator_traits<_ForwardIterator>::iterator_category()); + return std::__rotate<_ClassicAlgPolicy>(__first, __middle, __last, + typename iterator_traits<_ForwardIterator>::iterator_category()); } _LIBCPP_END_NAMESPACE_STD diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/search.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/search.h index d89ec2b1c5..4ead6cac82 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/search.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/search.h @@ -11,9 +11,15 @@ #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 <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -21,31 +27,43 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2> -pair<_ForwardIterator1, _ForwardIterator1> - _LIBCPP_CONSTEXPR_AFTER_CXX11 __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, - _BinaryPredicate __pred, forward_iterator_tag, forward_iterator_tag) { +template <class _AlgPolicy, + class _Iter1, class _Sent1, + class _Iter2, class _Sent2, + class _Pred, + class _Proj1, + class _Proj2> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +pair<_Iter1, _Iter1> __search_forward_impl(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2) { if (__first2 == __last2) - return _VSTD::make_pair(__first1, __first1); // Everything matches an empty sequence + 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 - return _VSTD::make_pair(__last1, __last1); - if (__pred(*__first1, *__first2)) + 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 - _ForwardIterator1 __m1 = __first1; - _ForwardIterator2 __m2 = __first2; + _Iter1 __m1 = __first1; + _Iter2 __m2 = __first2; while (true) { if (++__m2 == __last2) // If pattern exhausted, __first1 is the answer (works for 1 element pattern) - return _VSTD::make_pair(__first1, __m1); - if (++__m1 == __last1) // Otherwise if source exhaused, pattern not found - return _VSTD::make_pair(__last1, __last1); - if (!__pred(*__m1, *__m2)) // if there is a mismatch, restart with a new __first1 + 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; @@ -54,38 +72,42 @@ pair<_ForwardIterator1, _ForwardIterator1> } } -template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2> -_LIBCPP_CONSTEXPR_AFTER_CXX11 pair<_RandomAccessIterator1, _RandomAccessIterator1> -__search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, - _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag, - random_access_iterator_tag) { - typedef typename iterator_traits<_RandomAccessIterator1>::difference_type _D1; - typedef typename iterator_traits<_RandomAccessIterator2>::difference_type _D2; - // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern - const _D2 __len2 = __last2 - __first2; - if (__len2 == 0) - return _VSTD::make_pair(__first1, __first1); - const _D1 __len1 = __last1 - __first1; - if (__len1 < __len2) - return _VSTD::make_pair(__last1, __last1); - const _RandomAccessIterator1 __s = __last1 - _D1(__len2 - 1); // Start of pattern match can't go beyond here +template <class _AlgPolicy, + class _Iter1, class _Sent1, + class _Iter2, class _Sent2, + class _Pred, + class _Proj1, + class _Proj2, + class _DiffT1, + class _DiffT2> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +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) - return _VSTD::make_pair(__last1, __last1); - if (__pred(*__first1, *__first2)) + 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; } - _RandomAccessIterator1 __m1 = __first1; - _RandomAccessIterator2 __m2 = __first2; + _Iter1 __m1 = __first1; + _Iter2 __m2 = __first2; while (true) { if (++__m2 == __last2) - return _VSTD::make_pair(__first1, __first1 + _D1(__len2)); + return std::make_pair(__first1, __first1 + _DiffT1(__size2)); ++__m1; // no need to check range on __m1 because __s guarantees we have enough source - if (!__pred(*__m1, *__m2)) { + if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2))) { ++__first1; break; } @@ -93,22 +115,78 @@ __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _Rando } } +template <class _Iter1, class _Sent1, + class _Iter2, class _Sent2, + class _Pred, + class _Proj1, + class _Proj2> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +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 <class _Iter1, class _Sent1, + class _Iter2, class _Sent2, + class _Pred, + class _Proj1, + class _Proj2> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +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 <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 -search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, - _BinaryPredicate __pred) { - return _VSTD::__search<_BinaryPredicate&>( - __first1, __last1, __first2, __last2, __pred, - typename iterator_traits<_ForwardIterator1>::iterator_category(), - typename iterator_traits<_ForwardIterator2>::iterator_category()).first; +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_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 <class _ForwardIterator1, class _ForwardIterator2> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 -search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { - typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; - typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; - return _VSTD::search(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2) { + using __v1 = typename iterator_traits<_ForwardIterator1>::value_type; + using __v2 = typename iterator_traits<_ForwardIterator2>::value_type; + return std::search(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); } #if _LIBCPP_STD_VER > 14 diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/search_n.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/search_n.h index c51701415b..ccb8e845f5 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/search_n.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/search_n.h @@ -11,8 +11,15 @@ #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/pair.h> #include <type_traits> // __convert_to_integral #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -21,30 +28,39 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _BinaryPredicate, class _ForwardIterator, class _Size, class _Tp> -_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator __search_n(_ForwardIterator __first, _ForwardIterator __last, - _Size __count, const _Tp& __value, _BinaryPredicate __pred, - forward_iterator_tag) { +template <class _AlgPolicy, class _Pred, class _Iter, class _Sent, class _SizeT, class _Type, class _Proj> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +pair<_Iter, _Iter> __search_n_forward_impl(_Iter __first, _Sent __last, + _SizeT __count, + const _Type& __value, + _Pred& __pred, + _Proj& __proj) { if (__count <= 0) - return __first; + return std::make_pair(__first, __first); while (true) { - // Find first element in sequence that matchs __value_, with a mininum of loop checks + // 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_ - return __last; - if (__pred(*__first, __value)) + 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 - _ForwardIterator __m = __first; - _Size __c(0); + // *__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 __first; - if (++__m == __last) // Otherwise if source exhaused, pattern not found - return __last; - if (!__pred(*__m, __value)) // if there is a mismatch, restart with a new __first + 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; @@ -54,35 +70,44 @@ _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator __search_n(_ForwardIterator __fir } } -template <class _BinaryPredicate, class _RandomAccessIterator, class _Size, class _Tp> -_LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator __search_n(_RandomAccessIterator __first, - _RandomAccessIterator __last, _Size __count, - const _Tp& __value, _BinaryPredicate __pred, - random_access_iterator_tag) { - typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; - if (__count <= 0) - return __first; - _Size __len = static_cast<_Size>(__last - __first); - if (__len < __count) - return __last; - const _RandomAccessIterator __s = __last - difference_type(__count - 1); // Start of pattern match can't go beyond here +template <class _AlgPolicy, class _Pred, class _Iter, class _Sent, class _SizeT, class _Type, class _Proj, class _DiffT> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +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 + // 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_ - return __last; - if (__pred(*__first, __value)) + 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 - _RandomAccessIterator __m = __first; - _Size __c(0); + auto __m = __first; + _SizeT __c(0); while (true) { if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern) - return __first; - ++__m; // no need to check range on __m because __s guarantees we have enough source - if (!__pred(*__m, __value)) // if there is a mismatch, restart with a new __first + 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; @@ -92,19 +117,63 @@ _LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator __search_n(_RandomAccessIter } } +template <class _Iter, class _Sent, + class _DiffT, + class _Type, + class _Pred, + class _Proj> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +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 <class _Iter1, class _Sent1, + class _DiffT, + class _Type, + class _Pred, + class _Proj> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +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 <class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator search_n( - _ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value, _BinaryPredicate __pred) { - return _VSTD::__search_n<_BinaryPredicate&>( - __first, __last, _VSTD::__convert_to_integral(__count), __value, __pred, - typename iterator_traits<_ForwardIterator>::iterator_category()); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 +_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 <class _ForwardIterator, class _Size, class _Tp> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator -search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value) { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 +_ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value) { typedef typename iterator_traits<_ForwardIterator>::value_type __v; - return _VSTD::search_n(__first, __last, _VSTD::__convert_to_integral(__count), __value, __equal_to<__v, _Tp>()); + return std::search_n(__first, __last, std::__convert_to_integral(__count), __value, __equal_to<__v, _Tp>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/set_intersection.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/set_intersection.h index 837f9af01d..77cc83738d 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/set_intersection.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/set_intersection.h @@ -14,6 +14,7 @@ #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) @@ -24,17 +25,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class _InIter1, class _InIter2, class _OutIter> struct __set_intersection_result { - _InIter1 in1; - _InIter2 in2; - _OutIter out; + _InIter1 __in1_; + _InIter2 __in2_; + _OutIter __out_; // need a constructor as C++03 aggregate init is hard _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 __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)) {} + : __in1_(std::move(__in_iter1)), __in2_(std::move(__in_iter2)), __out_(std::move(__out_iter)) {} }; -template < class _IterOper, class _Compare, class _InIter1, class _Sent1, class _InIter2, class _Sent2, class _OutIter> +template <class _AlgPolicy, class _Compare, class _InIter1, class _Sent1, class _InIter2, class _Sent2, class _OutIter> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 __set_intersection_result<_InIter1, _InIter2, _OutIter> __set_intersection( _InIter1 __first1, _Sent1 __last1, _InIter2 __first2, _Sent2 __last2, _OutIter __result, _Compare&& __comp) { @@ -52,8 +53,8 @@ __set_intersection( } return __set_intersection_result<_InIter1, _InIter2, _OutIter>( - _IterOper::next(std::move(__first1), std::move(__last1)), - _IterOper::next(std::move(__first2), std::move(__last2)), + _IterOps<_AlgPolicy>::next(std::move(__first1), std::move(__last1)), + _IterOps<_AlgPolicy>::next(std::move(__first2), std::move(__last2)), std::move(__result)); } @@ -66,14 +67,14 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator set_i _OutputIterator __result, _Compare __comp) { typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - return std::__set_intersection<_StdIterOps, _Comp_ref>( + return std::__set_intersection<_ClassicAlgPolicy, _Comp_ref>( std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::move(__result), __comp) - .out; + .__out_; } template <class _InputIterator1, class _InputIterator2, class _OutputIterator> @@ -83,7 +84,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator set_i _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) { - return std::__set_intersection<_StdIterOps>( + return std::__set_intersection<_ClassicAlgPolicy>( std::move(__first1), std::move(__last1), std::move(__first2), @@ -91,7 +92,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator set_i std::move(__result), __less<typename iterator_traits<_InputIterator1>::value_type, typename iterator_traits<_InputIterator2>::value_type>()) - .out; + .__out_; } _LIBCPP_END_NAMESPACE_STD diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/set_symmetric_difference.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/set_symmetric_difference.h index 2dbfb35d7b..cd532ab580 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/set_symmetric_difference.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/set_symmetric_difference.h @@ -14,6 +14,7 @@ #include <__algorithm/copy.h> #include <__config> #include <__iterator/iterator_traits.h> +#include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -21,55 +22,81 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> -_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator -__set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) -{ - while (__first1 != __last1) - { - if (__first2 == __last2) - return _VSTD::copy(__first1, __last1, __result); - if (__comp(*__first1, *__first2)) - { - *__result = *__first1; - ++__result; - ++__first1; - } - else - { - if (__comp(*__first2, *__first1)) - { - *__result = *__first2; - ++__result; - } - else - ++__first1; - ++__first2; - } +template <class _InIter1, class _InIter2, class _OutIter> +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_AFTER_CXX17 + __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 <class _Compare, class _InIter1, class _Sent1, class _InIter2, class _Sent2, class _OutIter> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 __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_impl(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; } - return _VSTD::copy(__first2, __last2, __result); + } + auto __ret2 = std::__copy_impl(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 <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) -{ - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - return _VSTD::__set_symmetric_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator set_symmetric_difference( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result, + _Compare __comp) { + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + return std::__set_symmetric_difference<_Comp_ref>( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + __comp) + .__out_; } template <class _InputIterator1, class _InputIterator2, class _OutputIterator> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) -{ - return _VSTD::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, - __less<typename iterator_traits<_InputIterator1>::value_type, - typename iterator_traits<_InputIterator2>::value_type>()); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _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<typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/set_union.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/set_union.h index 0ec6b09380..3bd4379801 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/set_union.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/set_union.h @@ -14,6 +14,7 @@ #include <__algorithm/copy.h> #include <__config> #include <__iterator/iterator_traits.h> +#include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -21,50 +22,77 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> -_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator -__set_union(_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 - { - if (!__comp(*__first1, *__first2)) - ++__first2; - *__result = *__first1; - ++__first1; - } +template <class _InIter1, class _InIter2, class _OutIter> +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_AFTER_CXX17 + __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 <class _Compare, class _InIter1, class _Sent1, class _InIter2, class _Sent2, class _OutIter> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 __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_impl(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; } - return _VSTD::copy(__first2, __last2, __result); + } + auto __ret2 = std::__copy_impl(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 <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -set_union(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) -{ - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - return _VSTD::__set_union<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator set_union( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result, + _Compare __comp) { + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + return std::__set_union<_Comp_ref>( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + __comp) + .__out_; } template <class _InputIterator1, class _InputIterator2, class _OutputIterator> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -set_union(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) -{ - return _VSTD::set_union(__first1, __last1, __first2, __last2, __result, - __less<typename iterator_traits<_InputIterator1>::value_type, - typename iterator_traits<_InputIterator2>::value_type>()); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _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<typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/shuffle.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/shuffle.h index 6c6ff5675d..0778815621 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/shuffle.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/shuffle.h @@ -9,11 +9,13 @@ #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/swap.h> +#include <__utility/forward.h> +#include <__utility/move.h> #include <cstddef> #include <cstdint> @@ -134,10 +136,8 @@ random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, } #endif -template<class _RandomAccessIterator, class _UniformRandomNumberGenerator> - void shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, - _UniformRandomNumberGenerator&& __g) -{ +template <class _AlgPolicy, class _RandomAccessIterator, class _UniformRandomNumberGenerator> +void __shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, _UniformRandomNumberGenerator&& __g) { typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; typedef uniform_int_distribution<ptrdiff_t> _Dp; typedef typename _Dp::param_type _Pp; @@ -149,11 +149,18 @@ template<class _RandomAccessIterator, class _UniformRandomNumberGenerator> { difference_type __i = __uid(__g, _Pp(0, __d)); if (__i != difference_type(0)) - swap(*__first, *(__first + __i)); + _IterOps<_AlgPolicy>::iter_swap(__first, __first + __i); } } } +template <class _RandomAccessIterator, class _UniformRandomNumberGenerator> +void shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, + _UniformRandomNumberGenerator&& __g) { + std::__shuffle<_ClassicAlgPolicy>( + std::move(__first), std::move(__last), std::forward<_UniformRandomNumberGenerator>(__g)); +} + _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/sift_down.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/sift_down.h index 0351a1c578..be2eb29dd5 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/sift_down.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/sift_down.h @@ -9,6 +9,7 @@ #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> @@ -20,12 +21,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Compare, class _RandomAccessIterator> +template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> _LIBCPP_CONSTEXPR_AFTER_CXX11 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 @@ -49,11 +52,11 @@ __sift_down(_RandomAccessIterator __first, _Compare __comp, // we are, __start is larger than its largest child return; - value_type __top(_VSTD::move(*__start)); + value_type __top(_Ops::__iter_move(__start)); do { // we are not in heap-order, swap the parent with its largest child - *__start = _VSTD::move(*__child_i); + *__start = _Ops::__iter_move(__child_i); __start = __child_i; if ((__len - 2) / 2 < __child) @@ -74,7 +77,7 @@ __sift_down(_RandomAccessIterator __first, _Compare __comp, *__start = _VSTD::move(__top); } -template <class _Compare, class _RandomAccessIterator> +template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> _LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator __floyd_sift_down(_RandomAccessIterator __first, _Compare __comp, typename iterator_traits<_RandomAccessIterator>::difference_type __len) @@ -97,7 +100,7 @@ __floyd_sift_down(_RandomAccessIterator __first, _Compare __comp, } // swap __hole with its largest child - *__hole = std::move(*__child_i); + *__hole = _IterOps<_AlgPolicy>::__iter_move(__child_i); __hole = __child_i; // if __hole is now a leaf, we're done diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/sort.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/sort.h index 76a1821573..1ca2f1b817 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/sort.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/sort.h @@ -11,6 +11,7 @@ #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__algorithm/iterator_operations.h> #include <__algorithm/min_element.h> #include <__algorithm/partial_sort.h> #include <__algorithm/unwrap_iter.h> @@ -21,7 +22,6 @@ #include <__functional/operations.h> #include <__functional/ranges_operations.h> #include <__iterator/iterator_traits.h> -#include <__utility/swap.h> #include <climits> #include <memory> @@ -31,37 +31,85 @@ _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<T, C>::type` -- see the specialization below for the rationale. +template <class _PolicyT, class _CompT, class = void> +struct _WrapAlgPolicy { + using type = _WrapAlgPolicy; + + using _AlgPolicy = _PolicyT; + using _Comp = _CompT; + _Comp& __comp; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 + _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 <class _PolicyT, class _CompT> +struct _WrapAlgPolicy<_PolicyT, _CompT, __enable_if_t<std::is_same<_PolicyT, _ClassicAlgPolicy>::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 <class _CompT> +struct _UnwrapAlgPolicy { + using _AlgPolicy = _ClassicAlgPolicy; + using _Comp = _CompT; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 static + _Comp __get_comp(_Comp __comp) { return __comp; } +}; + +// Unwraps a `_WrapAlgPolicy` struct. +template <class... _Ts> +struct _UnwrapAlgPolicy<_WrapAlgPolicy<_Ts...> > { + using _Wrapped = _WrapAlgPolicy<_Ts...>; + using _AlgPolicy = typename _Wrapped::_AlgPolicy; + using _Comp = typename _Wrapped::_Comp; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 static + _Comp __get_comp(_Wrapped& __w) { return __w.__comp; } +}; + // stable, 2-3 compares, 0-2 swaps -template <class _Compare, class _ForwardIterator> +template <class _AlgPolicy, class _Compare, class _ForwardIterator> _LIBCPP_CONSTEXPR_AFTER_CXX11 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 - swap(*__y, *__z); // x <= z && y < z + _Ops::iter_swap(__y, __z); // x <= z && y < z __r = 1; if (__c(*__y, *__x)) // if x > y { - swap(*__x, *__y); // x < y && y <= z + _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 { - swap(*__x, *__z); // x < y && y < z + _Ops::iter_swap(__x, __z); // x < y && y < z __r = 1; return __r; } - swap(*__x, *__y); // x > y && y <= z + _Ops::iter_swap(__x, __y); // x > y && y <= z __r = 1; // x < y && x <= z if (__c(*__z, *__y)) // if y > z { - swap(*__y, *__z); // x <= y && y < z + _Ops::iter_swap(__y, __z); // x <= y && y < z __r = 2; } return __r; @@ -69,18 +117,20 @@ _LIBCPP_CONSTEXPR_AFTER_CXX11 unsigned __sort3(_ForwardIterator __x, _ForwardIte // stable, 3-6 compares, 0-5 swaps -template <class _Compare, class _ForwardIterator> +template <class _AlgPolicy, class _Compare, class _ForwardIterator> unsigned __sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, _ForwardIterator __x4, _Compare __c) { - unsigned __r = _VSTD::__sort3<_Compare>(__x1, __x2, __x3, __c); + using _Ops = _IterOps<_AlgPolicy>; + + unsigned __r = std::__sort3<_AlgPolicy, _Compare>(__x1, __x2, __x3, __c); if (__c(*__x4, *__x3)) { - swap(*__x3, *__x4); + _Ops::iter_swap(__x3, __x4); ++__r; if (__c(*__x3, *__x2)) { - swap(*__x2, *__x3); + _Ops::iter_swap(__x2, __x3); ++__r; if (__c(*__x2, *__x1)) { - swap(*__x1, *__x2); + _Ops::iter_swap(__x1, __x2); ++__r; } } @@ -90,21 +140,28 @@ unsigned __sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator // stable, 4-10 compares, 0-9 swaps -template <class _Compare, class _ForwardIterator> +template <class _WrappedComp, class _ForwardIterator> _LIBCPP_HIDDEN unsigned __sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, - _ForwardIterator __x4, _ForwardIterator __x5, _Compare __c) { - unsigned __r = _VSTD::__sort4<_Compare>(__x1, __x2, __x3, __x4, __c); + _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)) { - swap(*__x4, *__x5); + _Ops::iter_swap(__x4, __x5); ++__r; if (__c(*__x4, *__x3)) { - swap(*__x3, *__x4); + _Ops::iter_swap(__x3, __x4); ++__r; if (__c(*__x3, *__x2)) { - swap(*__x2, *__x3); + _Ops::iter_swap(__x2, __x3); ++__r; if (__c(*__x2, *__x1)) { - swap(*__x1, *__x2); + _Ops::iter_swap(__x1, __x2); ++__r; } } @@ -113,6 +170,16 @@ _LIBCPP_HIDDEN unsigned __sort5(_ForwardIterator __x1, _ForwardIterator __x2, _F return __r; } +template <class _AlgPolicy, class _Compare, class _ForwardIterator> +_LIBCPP_HIDDEN 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>( + 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 <class _Tp> struct __is_simple_comparator : false_type {}; @@ -137,6 +204,7 @@ using __use_branchless_sort = // Ensures that __c(*__x, *__y) is true by swapping *__x and *__y if necessary. template <class _Compare, class _RandomAccessIterator> 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; @@ -149,6 +217,7 @@ inline _LIBCPP_HIDE_FROM_ABI void __cond_swap(_RandomAccessIterator __x, _Random template <class _Compare, class _RandomAccessIterator> 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; @@ -158,7 +227,7 @@ inline _LIBCPP_HIDE_FROM_ABI void __partially_sorted_swap(_RandomAccessIterator *__y = __r ? *__y : __tmp; } -template <class _Compare, class _RandomAccessIterator> +template <class, class _Compare, class _RandomAccessIterator> 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) { @@ -166,14 +235,14 @@ __sort3_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _VSTD::__partially_sorted_swap<_Compare>(__x1, __x2, __x3, __c); } -template <class _Compare, class _RandomAccessIterator> +template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> 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) { - _VSTD::__sort3<_Compare>(__x1, __x2, __x3, __c); + std::__sort3<_AlgPolicy, _Compare>(__x1, __x2, __x3, __c); } -template <class _Compare, class _RandomAccessIterator> +template <class, class _Compare, class _RandomAccessIterator> 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) { @@ -184,14 +253,14 @@ __sort4_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _VSTD::__cond_swap<_Compare>(__x2, __x3, __c); } -template <class _Compare, class _RandomAccessIterator> +template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> 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) { - _VSTD::__sort4<_Compare>(__x1, __x2, __x3, __x4, __c); + std::__sort4<_AlgPolicy, _Compare>(__x1, __x2, __x3, __x4, __c); } -template <class _Compare, class _RandomAccessIterator> +template <class, class _Compare, class _RandomAccessIterator> 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) { @@ -203,53 +272,57 @@ __sort5_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _VSTD::__partially_sorted_swap<_Compare>(__x2, __x3, __x4, __c); } -template <class _Compare, class _RandomAccessIterator> +template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> 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) { - _VSTD::__sort5<_Compare>(__x1, __x2, __x3, __x4, __x5, __c); + std::__sort5_wrap_policy<_AlgPolicy, _Compare>(__x1, __x2, __x3, __x4, __x5, __c); } // Assumes size > 0 -template <class _Compare, class _BidirectionalIterator> +template <class _AlgPolicy, class _Compare, class _BidirectionalIterator> _LIBCPP_CONSTEXPR_AFTER_CXX11 void __selection_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { _BidirectionalIterator __lm1 = __last; for (--__lm1; __first != __lm1; ++__first) { - _BidirectionalIterator __i = _VSTD::min_element(__first, __last, __comp); + _BidirectionalIterator __i = std::__min_element<_Compare>(__first, __last, __comp); if (__i != __first) - swap(*__first, *__i); + _IterOps<_AlgPolicy>::iter_swap(__first, __i); } } -template <class _Compare, class _BidirectionalIterator> +template <class _AlgPolicy, class _Compare, class _BidirectionalIterator> 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) { _BidirectionalIterator __i = __first; for (++__i; __i != __last; ++__i) { _BidirectionalIterator __j = __i; - value_type __t(_VSTD::move(*__j)); + value_type __t(_Ops::__iter_move(__j)); for (_BidirectionalIterator __k = __i; __k != __first && __comp(__t, *--__k); --__j) - *__j = _VSTD::move(*__k); + *__j = _Ops::__iter_move(__k); *__j = _VSTD::move(__t); } } } -template <class _Compare, class _RandomAccessIterator> +template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> void __insertion_sort_3(_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; _RandomAccessIterator __j = __first + difference_type(2); - _VSTD::__sort3_maybe_branchless<_Compare>(__first, __first + difference_type(1), __j, __comp); + std::__sort3_maybe_branchless<_AlgPolicy, _Compare>(__first, __first + difference_type(1), __j, __comp); for (_RandomAccessIterator __i = __j + difference_type(1); __i != __last; ++__i) { if (__comp(*__i, *__j)) { - value_type __t(_VSTD::move(*__i)); + value_type __t(_Ops::__iter_move(__i)); _RandomAccessIterator __k = __j; __j = __i; do { - *__j = _VSTD::move(*__k); + *__j = _Ops::__iter_move(__k); __j = __k; } while (__j != __first && __comp(__t, *--__k)); *__j = _VSTD::move(__t); @@ -258,8 +331,16 @@ void __insertion_sort_3(_RandomAccessIterator __first, _RandomAccessIterator __l } } -template <class _Compare, class _RandomAccessIterator> -bool __insertion_sort_incomplete(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { +template <class _WrappedComp, class _RandomAccessIterator> +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: @@ -267,32 +348,33 @@ bool __insertion_sort_incomplete(_RandomAccessIterator __first, _RandomAccessIte return true; case 2: if (__comp(*--__last, *__first)) - swap(*__first, *__last); + _IterOps<_AlgPolicy>::iter_swap(__first, __last); return true; case 3: - _VSTD::__sort3_maybe_branchless<_Compare>(__first, __first + difference_type(1), --__last, __comp); + std::__sort3_maybe_branchless<_AlgPolicy, _Compare>(__first, __first + difference_type(1), --__last, __comp); return true; case 4: - _VSTD::__sort4_maybe_branchless<_Compare>(__first, __first + difference_type(1), __first + difference_type(2), - --__last, __comp); + std::__sort4_maybe_branchless<_AlgPolicy, _Compare>( + __first, __first + difference_type(1), __first + difference_type(2), --__last, __comp); return true; case 5: - _VSTD::__sort5_maybe_branchless<_Compare>(__first, __first + difference_type(1), __first + difference_type(2), - __first + difference_type(3), --__last, __comp); + 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); - _VSTD::__sort3_maybe_branchless<_Compare>(__first, __first + difference_type(1), __j, __comp); + 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(_VSTD::move(*__i)); + value_type __t(_Ops::__iter_move(__i)); _RandomAccessIterator __k = __j; __j = __i; do { - *__j = _VSTD::move(*__k); + *__j = _Ops::__iter_move(__k); __j = __k; } while (__j != __first && __comp(__t, *--__k)); *__j = _VSTD::move(__t); @@ -304,27 +386,29 @@ bool __insertion_sort_incomplete(_RandomAccessIterator __first, _RandomAccessIte return true; } -template <class _Compare, class _BidirectionalIterator> +template <class _AlgPolicy, class _Compare, class _BidirectionalIterator> 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<value_type, __destruct_n&> __h(__first2, __d); value_type* __last2 = __first2; - ::new ((void*)__last2) value_type(_VSTD::move(*__first1)); + ::new ((void*)__last2) value_type(_Ops::__iter_move(__first1)); __d.template __incr<value_type>(); for (++__last2; ++__first1 != __last1; ++__last2) { value_type* __j2 = __last2; value_type* __i2 = __j2; if (__comp(*__first1, *--__i2)) { - ::new ((void*)__j2) value_type(_VSTD::move(*__i2)); + ::new ((void*)__j2) value_type(std::move(*__i2)); __d.template __incr<value_type>(); for (--__j2; __i2 != __first2 && __comp(*__first1, *--__i2); --__j2) - *__j2 = _VSTD::move(*__i2); - *__j2 = _VSTD::move(*__first1); + *__j2 = std::move(*__i2); + *__j2 = _Ops::__iter_move(__first1); } else { - ::new ((void*)__j2) value_type(_VSTD::move(*__first1)); + ::new ((void*)__j2) value_type(_Ops::__iter_move(__first1)); __d.template __incr<value_type>(); } } @@ -332,9 +416,11 @@ void __insertion_sort_move(_BidirectionalIterator __first1, _BidirectionalIterat } } -template <class _Compare, class _RandomAccessIterator> +template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> void __introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, typename iterator_traits<_RandomAccessIterator>::difference_type __depth) { + using _Ops = _IterOps<_AlgPolicy>; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; const difference_type __limit = @@ -348,28 +434,29 @@ void __introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _C return; case 2: if (__comp(*--__last, *__first)) - swap(*__first, *__last); + _IterOps<_AlgPolicy>::iter_swap(__first, __last); return; case 3: - _VSTD::__sort3_maybe_branchless<_Compare>(__first, __first + difference_type(1), --__last, __comp); + std::__sort3_maybe_branchless<_AlgPolicy, _Compare>(__first, __first + difference_type(1), --__last, __comp); return; case 4: - _VSTD::__sort4_maybe_branchless<_Compare>(__first, __first + difference_type(1), __first + difference_type(2), - --__last, __comp); + std::__sort4_maybe_branchless<_AlgPolicy, _Compare>( + __first, __first + difference_type(1), __first + difference_type(2), --__last, __comp); return; case 5: - _VSTD::__sort5_maybe_branchless<_Compare>(__first, __first + difference_type(1), __first + difference_type(2), - __first + difference_type(3), --__last, __comp); + std::__sort5_maybe_branchless<_AlgPolicy, _Compare>( + __first, __first + difference_type(1), __first + difference_type(2), __first + difference_type(3), + --__last, __comp); return; } if (__len <= __limit) { - _VSTD::__insertion_sort_3<_Compare>(__first, __last, __comp); + std::__insertion_sort_3<_AlgPolicy, _Compare>(__first, __last, __comp); return; } // __len > 5 if (__depth == 0) { // Fallback to heap sort as Introsort suggests. - _VSTD::__partial_sort<_Compare>(__first, __last, __last, __comp); + std::__partial_sort<_AlgPolicy, _Compare>(__first, __last, __last, __comp); return; } --__depth; @@ -383,11 +470,12 @@ void __introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _C __delta = __len / 2; __m += __delta; __delta /= 2; - __n_swaps = _VSTD::__sort5<_Compare>(__first, __first + __delta, __m, __m + __delta, __lm1, __comp); + __n_swaps = std::__sort5_wrap_policy<_AlgPolicy, _Compare>( + __first, __first + __delta, __m, __m + __delta, __lm1, __comp); } else { __delta = __len / 2; __m += __delta; - __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, __lm1, __comp); + __n_swaps = std::__sort3<_AlgPolicy, _Compare>(__first, __m, __lm1, __comp); } } // *__m is median @@ -414,7 +502,7 @@ void __introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _C if (__i == __j) return; // [__first, __last) all equivalent elements if (__comp(*__first, *__i)) { - swap(*__i, *__j); + _Ops::iter_swap(__i, __j); ++__n_swaps; ++__i; break; @@ -432,7 +520,7 @@ void __introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _C ; if (__i >= __j) break; - swap(*__i, *__j); + _Ops::iter_swap(__i, __j); ++__n_swaps; ++__i; } @@ -443,7 +531,7 @@ void __introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _C goto __restart; } if (__comp(*__j, *__m)) { - swap(*__i, *__j); + _Ops::iter_swap(__i, __j); ++__n_swaps; break; // found guard for downward moving __j, now use unguarded partition } @@ -465,7 +553,7 @@ void __introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _C ; if (__i > __j) break; - swap(*__i, *__j); + _Ops::iter_swap(__i, __j); ++__n_swaps; // It is known that __m != __j // If __m just moved, follow it @@ -476,14 +564,16 @@ void __introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _C } // [__first, __i) < *__m and *__m <= [__i, __last) if (__i != __m && __comp(*__m, *__i)) { - swap(*__i, *__m); + _Ops::iter_swap(__i, __m); ++__n_swaps; } // [__first, __i) < *__i and *__i <= [__i+1, __last) // If we were given a perfect partition, see if insertion sort is quick... if (__n_swaps == 0) { - bool __fs = _VSTD::__insertion_sort_incomplete<_Compare>(__first, __i, __comp); - if (_VSTD::__insertion_sort_incomplete<_Compare>(__i + difference_type(1), __last, __comp)) { + 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; @@ -497,10 +587,10 @@ void __introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _C } // sort smaller range with recursive call and larger with tail recursion elimination if (__i - __first < __last - __i) { - _VSTD::__introsort<_Compare>(__first, __i, __comp, __depth); + std::__introsort<_AlgPolicy, _Compare>(__first, __i, __comp, __depth); __first = ++__i; } else { - _VSTD::__introsort<_Compare>(__i + difference_type(1), __last, __comp, __depth); + std::__introsort<_AlgPolicy, _Compare>(__i + difference_type(1), __last, __comp, __depth); __last = __i; } } @@ -525,17 +615,22 @@ inline _LIBCPP_HIDE_FROM_ABI _Number __log2i(_Number __n) { return __log2; } -template <class _Compare, class _RandomAccessIterator> -void __sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { +template <class _WrappedComp, class _RandomAccessIterator> +void __sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _WrappedComp __wrapped_comp) { typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; difference_type __depth_limit = 2 * __log2i(__last - __first); - _VSTD::__introsort<_Compare>(__first, __last, __comp, __depth_limit); + + using _Unwrap = _UnwrapAlgPolicy<_WrappedComp>; + using _AlgPolicy = typename _Unwrap::_AlgPolicy; + using _Compare = typename _Unwrap::_Comp; + _Compare __comp = _Unwrap::__get_comp(__wrapped_comp); + std::__introsort<_AlgPolicy, _Compare>(__first, __last, __comp, __depth_limit); } template <class _Compare, class _Tp> inline _LIBCPP_INLINE_VISIBILITY void __sort(_Tp** __first, _Tp** __last, __less<_Tp*>&) { __less<uintptr_t> __comp; - _VSTD::__sort<__less<uintptr_t>&, uintptr_t*>((uintptr_t*)__first, (uintptr_t*)__last, __comp); + std::__sort<__less<uintptr_t>&, uintptr_t*>((uintptr_t*)__first, (uintptr_t*)__last, __comp); } extern template _LIBCPP_FUNC_VIS void __sort<__less<char>&, char*>(char*, char*, __less<char>&); @@ -576,22 +671,27 @@ extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long do extern template _LIBCPP_FUNC_VIS unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&); -template <class _RandomAccessIterator, class _Comp> +template <class _AlgPolicy, class _RandomAccessIterator, class _Comp> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) { - std::__debug_randomize_range(__first, __last); + std::__debug_randomize_range<_AlgPolicy>(__first, __last); + using _Comp_ref = typename __comp_ref_type<_Comp>::type; if (__libcpp_is_constant_evaluated()) { - std::__partial_sort<_Comp_ref>(__first, __last, __last, _Comp_ref(__comp)); + std::__partial_sort<_AlgPolicy>(__first, __last, __last, __comp); + } else { - std::__sort<_Comp_ref>(std::__unwrap_iter(__first), std::__unwrap_iter(__last), _Comp_ref(__comp)); + 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 <class _RandomAccessIterator, class _Comp> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) { - std::__sort_impl(std::move(__first), std::move(__last), __comp); + std::__sort_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); } template <class _RandomAccessIterator> diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/sort_heap.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/sort_heap.h index 261adedd0e..b9f0b2c969 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/sort_heap.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/sort_heap.h @@ -11,11 +11,12 @@ #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 <type_traits> // swap +#include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -23,7 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Compare, class _RandomAccessIterator> +template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 void __sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) { using _CompRef = typename __comp_ref_type<_Compare>::type; @@ -31,13 +32,16 @@ void __sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _C using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; for (difference_type __n = __last - __first; __n > 1; --__last, (void) --__n) - std::__pop_heap<_CompRef>(__first, __last, __comp_ref, __n); + std::__pop_heap<_AlgPolicy, _CompRef>(__first, __last, __comp_ref, __n); } template <class _RandomAccessIterator, class _Compare> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { - std::__sort_heap(std::move(__first), std::move(__last), __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 <class _RandomAccessIterator> diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/stable_partition.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/stable_partition.h index 969ac7a617..e5ad48b2ed 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/stable_partition.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/stable_partition.h @@ -9,13 +9,14 @@ #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 <__utility/swap.h> #include <memory> +#include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -23,11 +24,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Predicate, class _ForwardIterator, class _Distance, class _Pair> +template <class _AlgPolicy, class _Predicate, class _ForwardIterator, class _Distance, class _Pair> _ForwardIterator -__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, +__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) @@ -37,7 +40,7 @@ __stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate _ForwardIterator __m = __first; if (__pred(*++__m)) { - swap(*__first, *__m); + _Ops::iter_swap(__first, __m); return __m; } return __first; @@ -50,7 +53,7 @@ __stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate // 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(_VSTD::move(*__first)); + ::new ((void*)__t) value_type(_Ops::__iter_move(__first)); __d.template __incr<value_type>(); ++__t; _ForwardIterator __i = __first; @@ -58,12 +61,12 @@ __stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate { if (__pred(*__i)) { - *__first = _VSTD::move(*__i); + *__first = _Ops::__iter_move(__i); ++__first; } else { - ::new ((void*)__t) value_type(_VSTD::move(*__i)); + ::new ((void*)__t) value_type(_Ops::__iter_move(__i)); __d.template __incr<value_type>(); ++__t; } @@ -72,7 +75,7 @@ __stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate // 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 = _VSTD::move(*__t2); + *__i = _Ops::__iter_move(__t2); // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer return __first; } @@ -80,11 +83,12 @@ __stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate // __len >= 3 _ForwardIterator __m = __first; _Distance __len2 = __len / 2; // __len2 >= 2 - _VSTD::advance(__m, __len2); + _Ops::advance(__m, __len2); // recurse on [__first, __m), *__first know to be false // F????????????????? // f m l - _ForwardIterator __first_false = _VSTD::__stable_partition<_Predicate&>(__first, __m, __pred, __len2, __p, __fit); + _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 @@ -99,18 +103,19 @@ __stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate } // TTTFFFFFTTTF?????? // f ff m m1 l - __second_false = _VSTD::__stable_partition<_Predicate&>(__m1, __last, __pred, __len_half, __p, __fit); + __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 _VSTD::rotate(__first_false, __m, __second_false); + return std::__rotate<_AlgPolicy>(__first_false, __m, __second_false, __fit); // TTTTTTTTFFFFFFFFFF // | } -template <class _Predicate, class _ForwardIterator> +template <class _AlgPolicy, class _Predicate, class _ForwardIterator> _ForwardIterator -__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, +__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 @@ -127,7 +132,7 @@ __stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate // *__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 = _VSTD::distance(__first, __last); + difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last); pair<value_type*, ptrdiff_t> __p(0, 0); unique_ptr<value_type, __return_temporary_buffer> __h; if (__len >= __alloc_limit) @@ -138,20 +143,23 @@ _LIBCPP_SUPPRESS_DEPRECATED_PUSH _LIBCPP_SUPPRESS_DEPRECATED_POP __h.reset(__p.first); } - return _VSTD::__stable_partition<_Predicate&>(__first, __last, __pred, __len, __p, forward_iterator_tag()); + return std::__stable_partition_impl<_AlgPolicy, _Predicate&>( + std::move(__first), std::move(__last), __pred, __len, __p, forward_iterator_tag()); } -template <class _Predicate, class _BidirectionalIterator, class _Distance, class _Pair> +template <class _AlgPolicy, class _Predicate, class _BidirectionalIterator, class _Distance, class _Pair> _BidirectionalIterator -__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, +__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) { - swap(*__first, *__last); + _Ops::iter_swap(__first, __last); return __last; } if (__len == 3) @@ -159,12 +167,12 @@ __stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last _BidirectionalIterator __m = __first; if (__pred(*++__m)) { - swap(*__first, *__m); - swap(*__m, *__last); + _Ops::iter_swap(__first, __m); + _Ops::iter_swap(__m, __last); return __last; } - swap(*__m, *__last); - swap(*__first, *__m); + _Ops::iter_swap(__m, __last); + _Ops::iter_swap(__first, __m); return __m; } if (__len <= __p.second) @@ -175,7 +183,7 @@ __stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last // 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(_VSTD::move(*__first)); + ::new ((void*)__t) value_type(_Ops::__iter_move(__first)); __d.template __incr<value_type>(); ++__t; _BidirectionalIterator __i = __first; @@ -183,23 +191,23 @@ __stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last { if (__pred(*__i)) { - *__first = _VSTD::move(*__i); + *__first = _Ops::__iter_move(__i); ++__first; } else { - ::new ((void*)__t) value_type(_VSTD::move(*__i)); + ::new ((void*)__t) value_type(_Ops::__iter_move(__i)); __d.template __incr<value_type>(); ++__t; } } // move *__last, known to be true - *__first = _VSTD::move(*__i); + *__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 = _VSTD::move(*__t2); + *__i = _Ops::__iter_move(__t2); // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer return __first; } @@ -207,7 +215,7 @@ __stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last // __len >= 4 _BidirectionalIterator __m = __first; _Distance __len2 = __len / 2; // __len2 >= 2 - _VSTD::advance(__m, __len2); + _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 @@ -222,7 +230,8 @@ __stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last } // F???TFFF?????????T // f m1 m l - __first_false = _VSTD::__stable_partition<_Predicate&>(__first, __m1, __pred, __len_half, __p, __bit); + __first_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>( + __first, __m1, __pred, __len_half, __p, __bit); __first_half_done: // TTTFFFFF?????????T // f ff m l @@ -239,18 +248,19 @@ __first_half_done: } // TTTFFFFFTTTF?????T // f ff m m1 l - __second_false = _VSTD::__stable_partition<_Predicate&>(__m1, __last, __pred, __len_half, __p, __bit); + __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 _VSTD::rotate(__first_false, __m, __second_false); + return std::__rotate<_AlgPolicy>(__first_false, __m, __second_false, __bit); // TTTTTTTTFFFFFFFFFF // | } -template <class _Predicate, class _BidirectionalIterator> +template <class _AlgPolicy, class _Predicate, class _BidirectionalIterator> _BidirectionalIterator -__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, +__stable_partition_impl(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, bidirectional_iterator_tag) { typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; @@ -276,7 +286,7 @@ __stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last // *__first is known to be false // *__last is known to be true // __len >= 2 - difference_type __len = _VSTD::distance(__first, __last) + 1; + difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last) + 1; pair<value_type*, ptrdiff_t> __p(0, 0); unique_ptr<value_type, __return_temporary_buffer> __h; if (__len >= __alloc_limit) @@ -287,7 +297,16 @@ _LIBCPP_SUPPRESS_DEPRECATED_PUSH _LIBCPP_SUPPRESS_DEPRECATED_POP __h.reset(__p.first); } - return _VSTD::__stable_partition<_Predicate&>(__first, __last, __pred, __len, __p, bidirectional_iterator_tag()); + return std::__stable_partition_impl<_AlgPolicy, _Predicate&>( + std::move(__first), std::move(__last), __pred, __len, __p, bidirectional_iterator_tag()); +} + +template <class _AlgPolicy, class _Predicate, class _ForwardIterator, class _IterCategory> +_LIBCPP_HIDE_FROM_ABI +_ForwardIterator __stable_partition( + _ForwardIterator __first, _ForwardIterator __last, _Predicate&& __pred, _IterCategory __iter_category) { + return std::__stable_partition_impl<_AlgPolicy, __uncvref_t<_Predicate>&>( + std::move(__first), std::move(__last), __pred, __iter_category); } template <class _ForwardIterator, class _Predicate> @@ -295,7 +314,9 @@ inline _LIBCPP_INLINE_VISIBILITY _ForwardIterator stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { - return _VSTD::__stable_partition<_Predicate&>(__first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category()); + 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 diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/stable_sort.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/stable_sort.h index e3479aad62..6122758bde 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/stable_sort.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/stable_sort.h @@ -12,11 +12,11 @@ #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 <__utility/move.h> -#include <__utility/swap.h> #include <memory> #include <type_traits> @@ -26,12 +26,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Compare, class _InputIterator1, class _InputIterator2> +template <class _AlgPolicy, class _Compare, class _InputIterator1, class _InputIterator2> 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<value_type, __destruct_n&> __h(__result, __d); @@ -40,111 +42,115 @@ __merge_move_construct(_InputIterator1 __first1, _InputIterator1 __last1, if (__first1 == __last1) { for (; __first2 != __last2; ++__first2, (void) ++__result, __d.template __incr<value_type>()) - ::new ((void*)__result) value_type(_VSTD::move(*__first2)); + ::new ((void*)__result) value_type(_Ops::__iter_move(__first2)); __h.release(); return; } if (__first2 == __last2) { for (; __first1 != __last1; ++__first1, (void) ++__result, __d.template __incr<value_type>()) - ::new ((void*)__result) value_type(_VSTD::move(*__first1)); + ::new ((void*)__result) value_type(_Ops::__iter_move(__first1)); __h.release(); return; } if (__comp(*__first2, *__first1)) { - ::new ((void*)__result) value_type(_VSTD::move(*__first2)); + ::new ((void*)__result) value_type(_Ops::__iter_move(__first2)); __d.template __incr<value_type>(); ++__first2; } else { - ::new ((void*)__result) value_type(_VSTD::move(*__first1)); + ::new ((void*)__result) value_type(_Ops::__iter_move(__first1)); __d.template __incr<value_type>(); ++__first1; } } } -template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> +template <class _AlgPolicy, class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> 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 = _VSTD::move(*__first1); + *__result = _Ops::__iter_move(__first1); return; } if (__comp(*__first2, *__first1)) { - *__result = _VSTD::move(*__first2); + *__result = _Ops::__iter_move(__first2); ++__first2; } else { - *__result = _VSTD::move(*__first1); + *__result = _Ops::__iter_move(__first1); ++__first1; } } for (; __first2 != __last2; ++__first2, (void) ++__result) - *__result = _VSTD::move(*__first2); + *__result = _Ops::__iter_move(__first2); } -template <class _Compare, class _RandomAccessIterator> +template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> 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 <class _Compare, class _RandomAccessIterator> +template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> 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(_VSTD::move(*__first1)); + ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1)); return; case 2: __destruct_n __d(0); unique_ptr<value_type, __destruct_n&> __h2(__first2, __d); if (__comp(*--__last1, *__first1)) { - ::new ((void*)__first2) value_type(_VSTD::move(*__last1)); + ::new ((void*)__first2) value_type(_Ops::__iter_move(__last1)); __d.template __incr<value_type>(); ++__first2; - ::new ((void*)__first2) value_type(_VSTD::move(*__first1)); + ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1)); } else { - ::new ((void*)__first2) value_type(_VSTD::move(*__first1)); + ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1)); __d.template __incr<value_type>(); ++__first2; - ::new ((void*)__first2) value_type(_VSTD::move(*__last1)); + ::new ((void*)__first2) value_type(_Ops::__iter_move(__last1)); } __h2.release(); return; } if (__len <= 8) { - _VSTD::__insertion_sort_move<_Compare>(__first1, __last1, __first2, __comp); + std::__insertion_sort_move<_AlgPolicy, _Compare>(__first1, __last1, __first2, __comp); return; } typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; _RandomAccessIterator __m = __first1 + __l2; - _VSTD::__stable_sort<_Compare>(__first1, __m, __comp, __l2, __first2, __l2); - _VSTD::__stable_sort<_Compare>(__m, __last1, __comp, __len - __l2, __first2 + __l2, __len - __l2); - _VSTD::__merge_move_construct<_Compare>(__first1, __m, __m, __last1, __first2, __comp); + 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 <class _Tp> @@ -153,7 +159,7 @@ struct __stable_sort_switch static const unsigned value = 128*is_trivially_copy_assignable<_Tp>::value; }; -template <class _Compare, class _RandomAccessIterator> +template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> void __stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, typename iterator_traits<_RandomAccessIterator>::difference_type __len, @@ -168,12 +174,12 @@ __stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp return; case 2: if (__comp(*--__last, *__first)) - swap(*__first, *__last); + _IterOps<_AlgPolicy>::iter_swap(__first, __last); return; } if (__len <= static_cast<difference_type>(__stable_sort_switch<value_type>::value)) { - _VSTD::__insertion_sort<_Compare>(__first, __last, __comp); + std::__insertion_sort<_AlgPolicy, _Compare>(__first, __last, __comp); return; } typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; @@ -182,11 +188,12 @@ __stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp { __destruct_n __d(0); unique_ptr<value_type, __destruct_n&> __h2(__buff, __d); - _VSTD::__stable_sort_move<_Compare>(__first, __m, __comp, __l2, __buff); + std::__stable_sort_move<_AlgPolicy, _Compare>(__first, __m, __comp, __l2, __buff); __d.__set(__l2, (value_type*)nullptr); - _VSTD::__stable_sort_move<_Compare>(__m, __last, __comp, __len - __l2, __buff + __l2); + std::__stable_sort_move<_AlgPolicy, _Compare>(__m, __last, __comp, __len - __l2, __buff + __l2); __d.__set(__len, (value_type*)nullptr); - _VSTD::__merge_move_assign<_Compare>(__buff, __buff + __l2, __buff + __l2, __buff + __len, __first, __comp); + std::__merge_move_assign<_AlgPolicy, _Compare>( + __buff, __buff + __l2, __buff + __l2, __buff + __len, __first, __comp); // _VSTD::__merge<_Compare>(move_iterator<value_type*>(__buff), // move_iterator<value_type*>(__buff + __l2), // move_iterator<_RandomAccessIterator>(__buff + __l2), @@ -194,12 +201,12 @@ __stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp // __first, __comp); return; } - _VSTD::__stable_sort<_Compare>(__first, __m, __comp, __l2, __buff, __buff_size); - _VSTD::__stable_sort<_Compare>(__m, __last, __comp, __len - __l2, __buff, __buff_size); - _VSTD::__inplace_merge<_Compare>(__first, __m, __last, __comp, __l2, __len - __l2, __buff, __buff_size); + 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, _Compare>(__first, __m, __last, __comp, __l2, __len - __l2, __buff, __buff_size); } -template <class _RandomAccessIterator, class _Compare> +template <class _AlgPolicy, class _RandomAccessIterator, class _Compare> inline _LIBCPP_HIDE_FROM_ABI void __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) { using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; @@ -217,13 +224,13 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP } using _Comp_ref = typename __comp_ref_type<_Compare>::type; - std::__stable_sort<_Comp_ref>(__first, __last, __comp, __len, __buf.first, __buf.second); + std::__stable_sort<_AlgPolicy, _Comp_ref>(__first, __last, __comp, __len, __buf.first, __buf.second); } template <class _RandomAccessIterator, class _Compare> inline _LIBCPP_HIDE_FROM_ABI void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { - std::__stable_sort_impl(std::move(__first), std::move(__last), __comp); + std::__stable_sort_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); } template <class _RandomAccessIterator> diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/unwrap_iter.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/unwrap_iter.h index 7d1807b7bb..fa9a8fbf2d 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/unwrap_iter.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/unwrap_iter.h @@ -12,6 +12,7 @@ #include <__config> #include <__iterator/iterator_traits.h> #include <__memory/pointer_traits.h> +#include <__utility/move.h> #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -20,77 +21,50 @@ _LIBCPP_BEGIN_NAMESPACE_STD -// The job of __unwrap_iter is to lower contiguous iterators (such as -// vector<T>::iterator) into pointers, to reduce the number of template -// instantiations and to enable pointer-based optimizations e.g. in std::copy. -// For iterators that are not contiguous, it must be a no-op. +// 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. // -// __unwrap_iter is non-constexpr for user-defined iterators whose -// `to_address` and/or `operator->` is non-constexpr. This is okay; but we -// try to avoid doing __unwrap_iter in constant-evaluated contexts anyway. -// // Some algorithms (e.g. std::copy, but not std::sort) need to convert an -// "unwrapped" result back into a contiguous iterator. Since contiguous iterators -// are random-access, we can do this portably using iterator arithmetic; this -// is the job of __rewrap_iter. +// "unwrapped" result back into the original iterator type. Doing that is the job of __rewrap_iter. +// Default case - we can't unwrap anything template <class _Iter, bool = __is_cpp17_contiguous_iterator<_Iter>::value> struct __unwrap_iter_impl { - static _LIBCPP_CONSTEXPR _Iter - __apply(_Iter __i) _NOEXCEPT { - return __i; - } + 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 <class _Iter> struct __unwrap_iter_impl<_Iter, true> { - static _LIBCPP_CONSTEXPR decltype(_VSTD::__to_address(declval<_Iter>())) - __apply(_Iter __i) _NOEXCEPT { - return _VSTD::__to_address(__i); - } -}; + using _ToAddressT = decltype(std::__to_address(std::declval<_Iter>())); -#endif // !_LIBCPP_ENABLE_DEBUG_MODE - -template<class _Iter, class _Impl = __unwrap_iter_impl<_Iter> > -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -decltype(_Impl::__apply(declval<_Iter>())) -__unwrap_iter(_Iter __i) _NOEXCEPT -{ - return _Impl::__apply(__i); -} - -template <class _OrigIter, class _UnwrappedIter> -struct __rewrap_iter_impl { - static _LIBCPP_CONSTEXPR _OrigIter __apply(_OrigIter __first, _UnwrappedIter __result) { - // Precondition: __result is reachable from __first - // Precondition: _OrigIter is a contiguous iterator - return __first + (__result - std::__unwrap_iter(__first)); + 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)); } -}; -template <class _OrigIter> -struct __rewrap_iter_impl<_OrigIter, _OrigIter> { - static _LIBCPP_CONSTEXPR _OrigIter __apply(_OrigIter, _OrigIter __result) { - return __result; + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToAddressT __unwrap(_Iter __i) _NOEXCEPT { + return std::__to_address(__i); } }; -template<class _OrigIter> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR -_OrigIter __rewrap_iter(_OrigIter, _OrigIter __result) -{ - return __result; +#endif // !_LIBCPP_ENABLE_DEBUG_MODE + +template<class _Iter, + class _Impl = __unwrap_iter_impl<_Iter>, + __enable_if_t<is_copy_constructible<_Iter>::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +decltype(_Impl::__unwrap(std::declval<_Iter>())) __unwrap_iter(_Iter __i) _NOEXCEPT { + return _Impl::__unwrap(__i); } -template<class _OrigIter, class _UnwrappedIter, class _Impl = __rewrap_iter_impl<_OrigIter, _UnwrappedIter> > -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR -_OrigIter __rewrap_iter(_OrigIter __first, _UnwrappedIter __result) -{ - return _Impl::__apply(__first, __result); +template <class _OrigIter, class _Iter, class _Impl = __unwrap_iter_impl<_OrigIter> > +_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 diff --git a/contrib/libs/cxxsupp/libcxx/include/__chrono/day.h b/contrib/libs/cxxsupp/libcxx/include/__chrono/day.h index 7e425558e3..d9fa4ffbc4 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__chrono/day.h +++ b/contrib/libs/cxxsupp/libcxx/include/__chrono/day.h @@ -12,6 +12,7 @@ #include <__chrono/duration.h> #include <__config> +#include <compare> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -45,25 +46,9 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr bool operator==(const day& __lhs, const day& __rhs) noexcept { return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); } -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator!=(const day& __lhs, const day& __rhs) noexcept -{ return !(__lhs == __rhs); } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator< (const day& __lhs, const day& __rhs) noexcept -{ return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator> (const day& __lhs, const day& __rhs) noexcept -{ return __rhs < __lhs; } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator<=(const day& __lhs, const day& __rhs) noexcept -{ return !(__rhs < __lhs);} - -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator>=(const day& __lhs, const day& __rhs) noexcept -{ return !(__lhs < __rhs); } +_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const day& __lhs, const day& __rhs) noexcept { + return static_cast<unsigned>(__lhs) <=> static_cast<unsigned>(__rhs); +} _LIBCPP_HIDE_FROM_ABI inline constexpr day operator+ (const day& __lhs, const days& __rhs) noexcept diff --git a/contrib/libs/cxxsupp/libcxx/include/__config b/contrib/libs/cxxsupp/libcxx/include/__config index bf358075a7..a43e1b4ff6 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__config +++ b/contrib/libs/cxxsupp/libcxx/include/__config @@ -229,6 +229,12 @@ # error "libc++ only supports C++03 with Clang-based compilers. Please enable C++11" # endif +# ifdef _LIBCPP_COMPILER_MSVC +# error If you successfully use libc++ with MSVC please tell the libc++ developers and consider upstreaming your \ +changes. We are not aware of anybody using this configuration and know that at least some code is currently broken. \ +If there are users of this configuration we are happy to provide support. +# 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, @@ -252,6 +258,13 @@ # define _LIBCPP_ABI_VCRUNTIME # 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 +//# define _LIBCPP_HAS_NO_INCOMPLETE_RANGES +# endif + // Need to detect which libc we're using if we're on Linux. # if defined(__linux__) # include <features.h> @@ -560,11 +573,15 @@ typedef __char32_t char32_t; # 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_OVERRIDABLE_FUNC_VIS _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 diff --git a/contrib/libs/cxxsupp/libcxx/include/__debug_utils/randomize_range.h b/contrib/libs/cxxsupp/libcxx/include/__debug_utils/randomize_range.h index fd5b9e5884..9ed22556c4 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__debug_utils/randomize_range.h +++ b/contrib/libs/cxxsupp/libcxx/include/__debug_utils/randomize_range.h @@ -22,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Iterator> +template <class _AlgPolicy, class _Iterator> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 void __debug_randomize_range(_Iterator __first, _Iterator __last) { #ifdef _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY # ifdef _LIBCPP_CXX03_LANG @@ -30,7 +30,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 void __debug_randomize_range # endif if (!__libcpp_is_constant_evaluated()) - std::shuffle(__first, __last, __libcpp_debug_randomizer()); + std::__shuffle<_AlgPolicy>(__first, __last, __libcpp_debug_randomizer()); #else (void)__first; (void)__last; diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/extended_grapheme_cluster_table.h b/contrib/libs/cxxsupp/libcxx/include/__format/extended_grapheme_cluster_table.h new file mode 100644 index 0000000000..00cd0e91cd --- /dev/null +++ b/contrib/libs/cxxsupp/libcxx/include/__format/extended_grapheme_cluster_table.h @@ -0,0 +1,332 @@ +// -*- 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 +// utiles/generate_extended_grapheme_cluster_table.py +// DO NOT MODIFY! + +// UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE +// +// See Terms of Use <https://www.unicode.org/copyright.html> +// 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/upper_bound.h> +#include <__config> +#include <__iterator/access.h> +#include <cstddef> +#include <cstdint> + +#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 form 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[1480] = { + 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, 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, 0x00764052, 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, 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, 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, 0x09a18081, 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, 0x0f098062, 0x0f157002, + 0x0f176032, 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 { + // TODO FMT use std::ranges::upper_bound. + + // 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::upper_bound(__entries, std::end(__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/contrib/libs/cxxsupp/libcxx/include/__format/formatter_bool.h b/contrib/libs/cxxsupp/libcxx/include/__format/formatter_bool.h index 4c9d3fc774..cdb0631f87 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__format/formatter_bool.h +++ b/contrib/libs/cxxsupp/libcxx/include/__format/formatter_bool.h @@ -47,6 +47,7 @@ public: _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)); diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/formatter_char.h b/contrib/libs/cxxsupp/libcxx/include/__format/formatter_char.h index cd54abba34..a3ca36ec0a 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__format/formatter_char.h +++ b/contrib/libs/cxxsupp/libcxx/include/__format/formatter_char.h @@ -41,7 +41,7 @@ public: } _LIBCPP_HIDE_FROM_ABI auto format(_CharT __value, auto& __ctx) const -> decltype(__ctx.out()) { - if (__parser_.__type_ == __format_spec::__type::__char) + 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 constexpr (sizeof(_CharT) <= sizeof(int)) diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/formatter_integral.h b/contrib/libs/cxxsupp/libcxx/include/__format/formatter_integral.h index 4ad6de0ec6..b9ed5fe80f 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__format/formatter_integral.h +++ b/contrib/libs/cxxsupp/libcxx/include/__format/formatter_integral.h @@ -207,10 +207,6 @@ _LIBCPP_HIDE_FROM_ABI auto __format_integer( char* __end, const char* __prefix, int __base) -> decltype(__ctx.out()) { - _LIBCPP_ASSERT( - __specs.__alignment_ != __format_spec::__alignment::__default, - "the caller should adjust the default to the value required by the type"); - char* __first = __formatter::__insert_sign(__begin, __negative, __specs.__std_.__sign_); if (__specs.__std_.__alternate_form_ && __prefix) while (*__prefix) @@ -280,6 +276,7 @@ _LIBCPP_HIDE_FROM_ABI auto __format_integer( 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<char, __formatter::__buffer_size<decltype(__value), 10>()> __array; return __formatter::__format_integer( @@ -346,7 +343,7 @@ __format_bool(bool __value, auto& __ctx, __format_spec::__parsed_specifications< if (__specs.__std_.__locale_specific_form_) { const auto& __np = use_facet<numpunct<_CharT>>(__ctx.locale()); basic_string<_CharT> __str = __value ? __np.truename() : __np.falsename(); - return __formatter::__write_unicode_no_precision(basic_string_view<_CharT>{__str}, __ctx.out(), __specs); + return __formatter::__write_string_no_precision(basic_string_view<_CharT>{__str}, __ctx.out(), __specs); } # endif basic_string_view<_CharT> __str = diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/formatter_output.h b/contrib/libs/cxxsupp/libcxx/include/__format/formatter_output.h index fabc04b9a0..e09534c41d 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__format/formatter_output.h +++ b/contrib/libs/cxxsupp/libcxx/include/__format/formatter_output.h @@ -17,6 +17,7 @@ #include <__config> #include <__format/formatter.h> #include <__format/parser_std_format_spec.h> +#include <__format/unicode.h> #include <__utility/move.h> #include <__utility/unreachable.h> #include <cstddef> @@ -59,14 +60,11 @@ struct _LIBCPP_TYPE_VIS __padding_size_result { _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::__default, - "the caller should adjust the default to the value required by the type"); - _LIBCPP_ASSERT(__align != __format_spec::__alignment::__zero_padding, - "the caller should have handled the zero-padding"); + _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::__default: case __format_spec::__alignment::__zero_padding: __libcpp_unreachable(); @@ -78,9 +76,10 @@ __padding_size(size_t __size, size_t __width, __format_spec::__alignment __align // __before = floor(__fill, 2); // __after = ceil(__fill, 2); size_t __before = __fill / 2; - size_t __after = __fill - __before; + size_t __after = __fill - __before; return {__before, __after}; } + case __format_spec::__alignment::__default: case __format_spec::__alignment::__right: return {__fill, 0}; } @@ -91,9 +90,6 @@ template <class _OutIt, class _CharT> _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) { - _LIBCPP_ASSERT(__specs.__alignment_ != __format_spec::__alignment::__default, - "the caller should adjust the default to the value required by the type"); - int __size = (__first - __begin) + // [sign][prefix] (__last - __first) + // data (__grouping.size() - 1); // number of separator characters @@ -178,10 +174,12 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __write_using_decimal_separators(_OutIt __out_it, c /// conversion, which means the [\a __first, \a __last) always contains elements /// of the type \c char. template <class _CharT, class _ParserCharT> -_LIBCPP_HIDE_FROM_ABI auto __write(const _CharT* __first, const _CharT* __last, - output_iterator<const _CharT&> auto __out_it, - __format_spec::__parsed_specifications<_ParserCharT> __specs, ptrdiff_t __size) - -> decltype(__out_it) { +_LIBCPP_HIDE_FROM_ABI auto __write( + const _CharT* __first, + const _CharT* __last, + output_iterator<const _CharT&> auto __out_it, + __format_spec::__parsed_specifications<_ParserCharT> __specs, + ptrdiff_t __size) -> decltype(__out_it) { _LIBCPP_ASSERT(__first <= __last, "Not a valid range"); if (__size >= __specs.__width_) @@ -194,6 +192,7 @@ _LIBCPP_HIDE_FROM_ABI auto __write(const _CharT* __first, const _CharT* __last, } /// \overload +/// /// Calls the function above where \a __size = \a __last - \a __first. template <class _CharT, class _ParserCharT> _LIBCPP_HIDE_FROM_ABI auto __write(const _CharT* __first, const _CharT* __last, @@ -248,77 +247,56 @@ _LIBCPP_HIDE_FROM_ABI auto __write_using_trailing_zeros( return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_); } -# ifndef _LIBCPP_HAS_NO_UNICODE +/// 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 <class _CharT> -_LIBCPP_HIDE_FROM_ABI auto __write_unicode_no_precision(basic_string_view<_CharT> __str, - output_iterator<const _CharT&> auto __out_it, - __format_spec::__parsed_specifications<_CharT> __specs) - -> decltype(__out_it) { +_LIBCPP_HIDE_FROM_ABI auto __write_string_no_precision( + basic_string_view<_CharT> __str, + output_iterator<const _CharT&> auto __out_it, + __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { + _LIBCPP_ASSERT(!__specs.__has_precision(), "use __write_string"); - _LIBCPP_ASSERT(!__specs.__has_precision(), "use __write_unicode"); // No padding -> copy the string if (!__specs.__has_width()) return _VSTD::copy(__str.begin(), __str.end(), _VSTD::move(__out_it)); - // Non Unicode part larger than width -> copy the string - auto __last = __format_spec::__detail::__estimate_column_width_fast(__str.begin(), __str.end()); - ptrdiff_t __size = __last - __str.begin(); - if (__size >= __specs.__width_) - return _VSTD::copy(__str.begin(), __str.end(), _VSTD::move(__out_it)); - - // Is there a non Unicode part? - if (__last != __str.end()) { - // Non Unicode and Unicode part larger than width -> copy the string - __format_spec::__detail::__column_width_result __column_width = - __format_spec::__detail::__estimate_column_width(__last, __str.end(), __specs.__width_); - __size += __column_width.__width; // Note this new size is used when __size < __specs.__width_ - if (__size >= __specs.__width_) - return _VSTD::copy(__str.begin(), __str.end(), _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.begin(), __str.end(), _VSTD::move(__out_it), __specs, __size); } -# endif template <class _CharT> -_LIBCPP_HIDE_FROM_ABI auto __write_unicode(basic_string_view<_CharT> __str, - output_iterator<const _CharT&> auto __out_it, - __format_spec::__parsed_specifications<_CharT> __specs) - -> decltype(__out_it) { -# ifndef _LIBCPP_HAS_NO_UNICODE - if (!__specs.__has_precision()) - return __formatter::__write_unicode_no_precision(__str, _VSTD::move(__out_it), __specs); - - // Non unicode part larger than precision -> truncate the output and use the normal write operation. - auto __last = __format_spec::__detail::__estimate_column_width_fast(__str.begin(), __str.end()); - ptrdiff_t __size = __last - __str.begin(); - if (__size >= __specs.__precision_) - return __formatter::__write(__str.begin(), __str.begin() + __specs.__precision_, _VSTD::move(__out_it), __specs, - __specs.__precision_); - - // No non Unicode part, implies __size < __specs.__precision_ -> use normal write operation - if (__last == __str.end()) - return __formatter::__write(__str.begin(), __str.end(), _VSTD::move(__out_it), __specs, __str.size()); - - __format_spec::__detail::__column_width_result __column_width = - __format_spec::__detail::__estimate_column_width(__last, __str.end(), __specs.__precision_ - __size); - __size += __column_width.__width; - // Truncate the output - if (__column_width.__ptr != __str.end()) - __str.remove_suffix(__str.end() - __column_width.__ptr); +_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_; +} - return __formatter::__write(__str.begin(), __str.end(), _VSTD::move(__out_it), __specs, __size); +/// 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 <class _CharT> +_LIBCPP_HIDE_FROM_ABI auto __write_string( + basic_string_view<_CharT> __str, + output_iterator<const _CharT&> 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); -# else - if (__specs.__has_precision()) { - ptrdiff_t __size = __str.size(); - if (__size > __specs.__precision_) - return __formatter::__write(__str.begin(), __str.begin() + __specs.__precision_, _VSTD::move(__out_it), __specs, - __specs.__precision_); - } - return __formatter::__write(__str.begin(), __str.end(), _VSTD::move(__out_it), __specs, __str.size()); + int __size = __formatter::__truncate(__str, __specs.__precision_); -# endif + return __write(__str.begin(), __str.end(), _VSTD::move(__out_it), __specs, __size); } } // namespace __formatter diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/formatter_string.h b/contrib/libs/cxxsupp/libcxx/include/__format/formatter_string.h index 139c05e58c..71bda4fcde 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__format/formatter_string.h +++ b/contrib/libs/cxxsupp/libcxx/include/__format/formatter_string.h @@ -40,7 +40,7 @@ public: } _LIBCPP_HIDE_FROM_ABI auto format(basic_string_view<_CharT> __str, auto& __ctx) const -> decltype(__ctx.out()) { - return __formatter::__write_unicode(__str, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx)); + return __formatter::__write_string(__str, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx)); } __format_spec::__parser<_CharT> __parser_; @@ -69,7 +69,7 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const _CharT*, // TODO FMT Implement these improvements. __format_spec::__parsed_specifications<_CharT> __specs = _Base::__parser_.__get_parsed_std_specifications(__ctx); if (__specs.__has_width() || __specs.__has_precision()) - return __formatter::__write_unicode(basic_string_view<_CharT>{__str}, __ctx.out(), __specs); + 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(); diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/parser_std_format_spec.h b/contrib/libs/cxxsupp/libcxx/include/__format/parser_std_format_spec.h index 319ef24d3e..1425a953eb 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__format/parser_std_format_spec.h +++ b/contrib/libs/cxxsupp/libcxx/include/__format/parser_std_format_spec.h @@ -25,10 +25,12 @@ #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 <bit> #include <concepts> #include <cstdint> +#include <string_view> #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -91,462 +93,6 @@ __substitute_arg_id(basic_format_arg<_Context> __format_arg) { __format_arg); } -/** Helper struct returned from @ref __get_string_alignment. */ -template <class _CharT> -struct _LIBCPP_TEMPLATE_VIS __string_alignment { - /** Points beyond the last character to write to the output. */ - const _CharT* __last; - /** - * The estimated number of columns in the output or 0. - * - * Only when the output needs to be aligned it's required to know the exact - * number of columns in the output. So if the formatted output has only a - * minimum width the exact size isn't important. It's only important to know - * the minimum has been reached. The minimum width is the width specified in - * the format-spec. - * - * For example in this code @code std::format("{:10}", MyString); @endcode - * the width estimation can stop once the algorithm has determined the output - * width is 10 columns. - * - * So if: - * * @ref __align == @c true the @ref __size is the estimated number of - * columns required. - * * @ref __align == @c false the @ref __size is the estimated number of - * columns required or 0 when the estimation algorithm stopped prematurely. - */ - ptrdiff_t __size; - /** - * Does the output need to be aligned. - * - * When alignment is needed the output algorithm needs to add the proper - * padding. Else the output algorithm just needs to copy the input up to - * @ref __last. - */ - bool __align; -}; - -#ifndef _LIBCPP_HAS_NO_UNICODE -namespace __detail { - -/** - * Unicode column width estimates. - * - * 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 isn't well defined. The code uses the - * estimations defined in [format.string.std]/11. This list might change in the - * future. - * - * The algorithm of @ref __get_string_alignment uses two different scanners: - * - The simple scanner @ref __estimate_column_width_fast. This scanner assumes - * 1 code unit is 1 column. This scanner stops when it can't be sure the - * assumption is valid: - * - UTF-8 when the code point is encoded in more than 1 code unit. - * - UTF-16 and UTF-32 when the first multi-column code point is encountered. - * (The code unit's value is lower than 0xd800 so the 2 code unit encoding - * is irrelevant for this scanner.) - * Due to these assumptions the scanner is faster than the full scanner. It - * can process all text only containing ASCII. For UTF-16/32 it can process - * most (all?) European languages. (Note the set it can process might be - * reduced in the future, due to updates in the scanning rules.) - * - The full scanner @ref __estimate_column_width. This scanner, if needed, - * converts multiple code units into one code point then converts the code - * point to a column width. - * - * 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 - */ - -/** - * The first 2 column code point. - * - * This is the point where the fast UTF-16/32 scanner needs to stop processing. - */ -inline constexpr uint32_t __two_column_code_point = 0x1100; - -/** Helper concept for an UTF-8 character type. */ -template <class _CharT> -concept __utf8_character = same_as<_CharT, char> || same_as<_CharT, char8_t>; - -/** Helper concept for an UTF-16 character type. */ -template <class _CharT> -concept __utf16_character = (same_as<_CharT, wchar_t> && sizeof(wchar_t) == 2) || same_as<_CharT, char16_t>; - -/** Helper concept for an UTF-32 character type. */ -template <class _CharT> -concept __utf32_character = (same_as<_CharT, wchar_t> && sizeof(wchar_t) == 4) || same_as<_CharT, char32_t>; - -/** Helper concept for an UTF-16 or UTF-32 character type. */ -template <class _CharT> -concept __utf16_or_32_character = __utf16_character<_CharT> || __utf32_character<_CharT>; - -/** - * 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 inline 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 inline 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 inline constexpr int __column_width(uint32_t __c) noexcept { - if (__c < 0x10000) - return __column_width_3(__c); - - return __column_width_4(__c); -} - -/** - * Estimate the column width for the UTF-8 sequence using the fast algorithm. - */ -template <__utf8_character _CharT> -_LIBCPP_HIDE_FROM_ABI constexpr const _CharT* -__estimate_column_width_fast(const _CharT* __first, - const _CharT* __last) noexcept { - return _VSTD::find_if(__first, __last, - [](unsigned char __c) { return __c & 0x80; }); -} - -/** - * @overload - * - * The implementation for UTF-16/32. - */ -template <__utf16_or_32_character _CharT> -_LIBCPP_HIDE_FROM_ABI constexpr const _CharT* -__estimate_column_width_fast(const _CharT* __first, - const _CharT* __last) noexcept { - return _VSTD::find_if(__first, __last, - [](uint32_t __c) { return __c >= 0x1100; }); -} - -template <class _CharT> -struct _LIBCPP_TEMPLATE_VIS __column_width_result { - /** The number of output columns. */ - size_t __width; - /** - * The last parsed element. - * - * This limits the original output to fit in the wanted number of columns. - */ - const _CharT* __ptr; -}; - -/** - * Small helper to determine the width of malformed Unicode. - * - * @note This function's only needed for UTF-8. During scanning UTF-8 there - * are multiple place where it can be detected that the Unicode is malformed. - * UTF-16 only requires 1 test and UTF-32 requires no testing. - */ -template <__utf8_character _CharT> -_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> -__estimate_column_width_malformed(const _CharT* __first, const _CharT* __last, - size_t __maximum, size_t __result) noexcept { - size_t __size = __last - __first; - size_t __n = _VSTD::min(__size, __maximum); - return {__result + __n, __first + __n}; -} - -/** - * 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 at the end of the input is one output column. It's expected the output - * terminal will replace these malformed code units with a one column - * replacement characters. - * - * @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. - */ -template <__utf8_character _CharT> -_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> -__estimate_column_width(const _CharT* __first, const _CharT* __last, - size_t __maximum) noexcept { - size_t __result = 0; - - while (__first != __last) { - // 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<unsigned char>(*__first))) { - case 0: // 1-code unit encoding: all 1 column - ++__result; - ++__first; - break; - - case 2: // 2-code unit encoding: all 1 column - // Malformed Unicode. - if (__last - __first < 2) [[unlikely]] - return __estimate_column_width_malformed(__first, __last, __maximum, - __result); - __first += 2; - ++__result; - break; - - case 3: // 3-code unit encoding: either 1 or 2 columns - // Malformed Unicode. - if (__last - __first < 3) [[unlikely]] - return __estimate_column_width_malformed(__first, __last, __maximum, - __result); - { - uint32_t __c = static_cast<unsigned char>(*__first++) & 0x0f; - __c <<= 6; - __c |= static_cast<unsigned char>(*__first++) & 0x3f; - __c <<= 6; - __c |= static_cast<unsigned char>(*__first++) & 0x3f; - __result += __column_width_3(__c); - if (__result > __maximum) - return {__result - 2, __first - 3}; - } - break; - case 4: // 4-code unit encoding: either 1 or 2 columns - // Malformed Unicode. - if (__last - __first < 4) [[unlikely]] - return __estimate_column_width_malformed(__first, __last, __maximum, - __result); - { - uint32_t __c = static_cast<unsigned char>(*__first++) & 0x07; - __c <<= 6; - __c |= static_cast<unsigned char>(*__first++) & 0x3f; - __c <<= 6; - __c |= static_cast<unsigned char>(*__first++) & 0x3f; - __c <<= 6; - __c |= static_cast<unsigned char>(*__first++) & 0x3f; - __result += __column_width_4(__c); - if (__result > __maximum) - return {__result - 2, __first - 4}; - } - break; - default: - // Malformed Unicode. - return __estimate_column_width_malformed(__first, __last, __maximum, - __result); - } - - if (__result >= __maximum) - return {__result, __first}; - } - return {__result, __first}; -} - -template <__utf16_character _CharT> -_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> -__estimate_column_width(const _CharT* __first, const _CharT* __last, - size_t __maximum) noexcept { - size_t __result = 0; - - while (__first != __last) { - uint32_t __c = *__first; - // Is the code unit part of a surrogate pair? See - // https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF - if (__c >= 0xd800 && __c <= 0xDfff) { - // Malformed Unicode. - if (__last - __first < 2) [[unlikely]] - return {__result + 1, __first + 1}; - - __c -= 0xd800; - __c <<= 10; - __c += (*(__first + 1) - 0xdc00); - __c += 0x10000; - - __result += __column_width_4(__c); - if (__result > __maximum) - return {__result - 2, __first}; - __first += 2; - } else { - __result += __column_width_3(__c); - if (__result > __maximum) - return {__result - 2, __first}; - ++__first; - } - - if (__result >= __maximum) - return {__result, __first}; - } - - return {__result, __first}; -} - -template <__utf32_character _CharT> -_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> -__estimate_column_width(const _CharT* __first, const _CharT* __last, - size_t __maximum) noexcept { - size_t __result = 0; - - while (__first != __last) { - uint32_t __c = *__first; - __result += __column_width(__c); - - if (__result > __maximum) - return {__result - 2, __first}; - - ++__first; - if (__result >= __maximum) - return {__result, __first}; - } - - return {__result, __first}; -} - -} // namespace __detail - -template <class _CharT> -_LIBCPP_HIDE_FROM_ABI constexpr __string_alignment<_CharT> -__get_string_alignment(const _CharT* __first, const _CharT* __last, - ptrdiff_t __width, ptrdiff_t __precision) noexcept { - _LIBCPP_ASSERT(__width != 0 || __precision != -1, - "The function has no effect and shouldn't be used"); - - // TODO FMT There might be more optimizations possible: - // If __precision == __format::__number_max and the encoding is: - // * UTF-8 : 4 * (__last - __first) >= __width - // * UTF-16 : 2 * (__last - __first) >= __width - // * UTF-32 : (__last - __first) >= __width - // In these cases it's certain the output is at least the requested width. - // It's unknown how often this happens in practice. For now the improvement - // isn't implemented. - - /* - * First assume there are no special Unicode code units in the input. - * - Apply the precision (this may reduce the size of the input). When - * __precison == -1 this step is omitted. - * - Scan for special code units in the input. - * If our assumption was correct the __pos will be at the end of the input. - */ - const ptrdiff_t __length = __last - __first; - const _CharT* __limit = - __first + - (__precision == -1 ? __length : _VSTD::min(__length, __precision)); - ptrdiff_t __size = __limit - __first; - const _CharT* __pos = - __detail::__estimate_column_width_fast(__first, __limit); - - if (__pos == __limit) - return {__limit, __size, __size < __width}; - - /* - * Our assumption was wrong, there are special Unicode code units. - * The range [__first, __pos) contains a set of code units with the - * following property: - * Every _CharT in the range will be rendered in 1 column. - * - * If there's no maximum width and the parsed size already exceeds the - * minimum required width. The real size isn't important. So bail out. - */ - if (__precision == -1 && (__pos - __first) >= __width) - return {__last, 0, false}; - - /* If there's a __precision, truncate the output to that width. */ - ptrdiff_t __prefix = __pos - __first; - if (__precision != -1) { - _LIBCPP_ASSERT(__precision > __prefix, "Logic error."); - auto __lengh_info = __detail::__estimate_column_width( - __pos, __last, __precision - __prefix); - __size = __lengh_info.__width + __prefix; - return {__lengh_info.__ptr, __size, __size < __width}; - } - - /* Else use __width to determine the number of required padding characters. */ - _LIBCPP_ASSERT(__width > __prefix, "Logic error."); - /* - * The column width is always one or two columns. For the precision the wanted - * column width is the maximum, for the width it's the minimum. Using the - * width estimation with its truncating behavior will result in the wrong - * result in the following case: - * - The last code unit processed requires two columns and exceeds the - * maximum column width. - * By increasing the __maximum by one avoids this issue. (It means it may - * pass one code point more than required to determine the proper result; - * that however isn't a problem for the algorithm.) - */ - size_t __maximum = 1 + __width - __prefix; - auto __lengh_info = - __detail::__estimate_column_width(__pos, __last, __maximum); - if (__lengh_info.__ptr != __last) { - // Consumed the width number of code units. The exact size of the string - // is unknown. We only know we don't need to align the output. - _LIBCPP_ASSERT(static_cast<ptrdiff_t>(__lengh_info.__width + __prefix) >= - __width, - "Logic error"); - return {__last, 0, false}; - } - - __size = __lengh_info.__width + __prefix; - return {__last, __size, __size < __width}; -} -#else // _LIBCPP_HAS_NO_UNICODE -template <class _CharT> -_LIBCPP_HIDE_FROM_ABI constexpr __string_alignment<_CharT> -__get_string_alignment(const _CharT* __first, const _CharT* __last, - ptrdiff_t __width, ptrdiff_t __precision) noexcept { - const ptrdiff_t __length = __last - __first; - const _CharT* __limit = - __first + - (__precision == -1 ? __length : _VSTD::min(__length, __precision)); - ptrdiff_t __size = __limit - __first; - return {__limit, __size, __size < __width}; -} -#endif // _LIBCPP_HAS_NO_UNICODE - /// 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 @@ -1041,17 +587,9 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_char(__parser<_CharT } template <class _CharT> -_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_integer(__parser<_CharT>& __parser) { - if (__parser.__alignment_ == __alignment::__default) - __parser.__alignment_ = __alignment::__right; -} - -template <class _CharT> _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_bool(__parser<_CharT>& __parser) { switch (__parser.__type_) { case __format_spec::__type::__default: - __parser.__type_ = __format_spec::__type::__string; - [[fallthrough]]; case __format_spec::__type::__string: __format_spec::__process_display_type_bool_string(__parser); break; @@ -1062,7 +600,6 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_bool(__parser<_CharT>& __p case __format_spec::__type::__decimal: case __format_spec::__type::__hexadecimal_lower_case: case __format_spec::__type::__hexadecimal_upper_case: - __process_display_type_integer(__parser); break; default: @@ -1074,8 +611,6 @@ template <class _CharT> _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_char(__parser<_CharT>& __parser) { switch (__parser.__type_) { case __format_spec::__type::__default: - __parser.__type_ = __format_spec::__type::__char; - [[fallthrough]]; case __format_spec::__type::__char: __format_spec::__process_display_type_char(__parser); break; @@ -1086,7 +621,6 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_char(__parser<_CharT>& __p case __format_spec::__type::__decimal: case __format_spec::__type::__hexadecimal_lower_case: case __format_spec::__type::__hexadecimal_upper_case: - __format_spec::__process_display_type_integer(__parser); break; default: @@ -1098,15 +632,12 @@ template <class _CharT> _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_integer(__parser<_CharT>& __parser) { switch (__parser.__type_) { case __format_spec::__type::__default: - __parser.__type_ = __format_spec::__type::__decimal; - [[fallthrough]]; 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: - __format_spec::__process_display_type_integer(__parser); break; case __format_spec::__type::__char: @@ -1120,8 +651,6 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_integer(__parser<_CharT>& template <class _CharT> _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_floating_point(__parser<_CharT>& __parser) { - __format_spec::__process_display_type_integer(__parser); - switch (__parser.__type_) { case __format_spec::__type::__default: // When no precision specified then it keeps default since that @@ -1160,6 +689,212 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_pointer(__format_spe } } +template <class _CharT> +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_; +}; + +/// 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 <class _CharT> +_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 <class _CharT> +_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 (__is_ascii(*__it)) { + do { + --__maximum; + ++__it; + if (__it == __str.end()) + return {__str.size(), __str.end()}; + + if (__maximum == 0) { + if (__is_ascii(*__it)) + return {static_cast<size_t>(__it - __str.begin()), __it}; + + break; + } + } while (__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 <class _CharT> +_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 diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/unicode.h b/contrib/libs/cxxsupp/libcxx/include/__format/unicode.h new file mode 100644 index 0000000000..3316217f4a --- /dev/null +++ b/contrib/libs/cxxsupp/libcxx/include/__format/unicode.h @@ -0,0 +1,339 @@ +// -*- 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 <__utility/unreachable.h> +#include <bit> + +#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_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) + +namespace __unicode { + +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 _CharT> +class __code_point_view; + +/// UTF-8 specialization. +template <> +class __code_point_view<char> { +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<unsigned char>(*__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<unsigned char>(*__first_++) & 0x1f; + __value <<= 6; + __value |= static_cast<unsigned char>(*__first_++) & 0x3f; + return __value; + } + + case 3: + if (__last_ - __first_ < 3 || !__unicode::__is_continuation(__first_ + 1, 2)) [[unlikely]] + break; + else { + char32_t __value = static_cast<unsigned char>(*__first_++) & 0x0f; + __value <<= 6; + __value |= static_cast<unsigned char>(*__first_++) & 0x3f; + __value <<= 6; + __value |= static_cast<unsigned char>(*__first_++) & 0x3f; + return __value; + } + + case 4: + if (__last_ - __first_ < 4 || !__unicode::__is_continuation(__first_ + 1, 3)) [[unlikely]] + break; + else { + char32_t __value = static_cast<unsigned char>(*__first_++) & 0x07; + __value <<= 6; + __value |= static_cast<unsigned char>(*__first_++) & 0x3f; + __value <<= 6; + __value |= static_cast<unsigned char>(*__first_++) & 0x3f; + __value <<= 6; + __value |= static_cast<unsigned char>(*__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; + } + +private: + const char* __first_; + const char* __last_; +}; + +# ifndef TEST_HAS_NO_WIDE_CHARACTERS +/// 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<wchar_t> { +public: + _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 { + // TODO FMT P2593R0 Use static_assert(false, "sizeof(wchar_t) has a not implemented value"); + _LIBCPP_ASSERT(sizeof(wchar_t) == 0, "sizeof(wchar_t) has a not implemented value"); + __libcpp_unreachable(); + } + } + +private: + const wchar_t* __first_; + const wchar_t* __last_; +}; +# endif + +_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; + if (__ri_break_allowed) + return true; + + return false; + } + + // *** 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 _CharT> +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; + } + } +}; + +} // namespace __unicode + +# endif // _LIBCPP_HAS_NO_UNICODE + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_UNICODE_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__functional/default_searcher.h b/contrib/libs/cxxsupp/libcxx/include/__functional/default_searcher.h index 05fb23d7c3..8e37082b6b 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__functional/default_searcher.h +++ b/contrib/libs/cxxsupp/libcxx/include/__functional/default_searcher.h @@ -12,6 +12,7 @@ #include <__algorithm/search.h> #include <__config> +#include <__functional/identity.h> #include <__functional/operations.h> #include <__iterator/iterator_traits.h> #include <__utility/pair.h> @@ -38,16 +39,15 @@ public: pair<_ForwardIterator2, _ForwardIterator2> operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const { - return _VSTD::__search(__f, __l, __first_, __last_, __pred_, - typename iterator_traits<_ForwardIterator>::iterator_category(), - typename iterator_traits<_ForwardIterator2>::iterator_category()); + auto __proj = __identity(); + return std::__search_impl(__f, __l, __first_, __last_, __pred_, __proj, __proj); } private: _ForwardIterator __first_; _ForwardIterator __last_; _BinaryPredicate __pred_; - }; +}; #endif // _LIBCPP_STD_VER > 14 diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/iterator_traits.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/iterator_traits.h index 1fbdc955d1..63525e230a 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__iterator/iterator_traits.h +++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/iterator_traits.h @@ -481,6 +481,12 @@ struct __is_exactly_cpp17_forward_iterator __has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value && !__has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value> {}; +template <class _Tp> +struct __is_exactly_cpp17_bidirectional_iterator + : public integral_constant<bool, + __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value && + !__has_iterator_category_convertible_to<_Tp, random_access_iterator_tag>::value> {}; + template<class _InputIterator> using __iter_value_type = typename iterator_traits<_InputIterator>::value_type; diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/reverse_iterator.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/reverse_iterator.h index a915609dbe..7f4ef3c3d5 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__iterator/reverse_iterator.h +++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/reverse_iterator.h @@ -332,41 +332,16 @@ using _ReverseWrapper = reverse_iterator<reverse_iterator<_Iter> >; template <class _Iter, bool __b> struct __unwrap_iter_impl<_ReverseWrapper<_Iter>, __b> { - static _LIBCPP_CONSTEXPR decltype(std::__unwrap_iter(std::declval<_Iter>())) - __apply(_ReverseWrapper<_Iter> __i) _NOEXCEPT { - return std::__unwrap_iter(__i.base().base()); - } -}; - -template <class _OrigIter, class _UnwrappedIter> -struct __rewrap_iter_impl<_ReverseWrapper<_OrigIter>, _UnwrappedIter> { - template <class _Iter> - struct _ReverseWrapperCount { - static _LIBCPP_CONSTEXPR const size_t value = 1; - }; - - template <class _Iter> - struct _ReverseWrapperCount<_ReverseWrapper<_Iter> > { - static _LIBCPP_CONSTEXPR const size_t value = 1 + _ReverseWrapperCount<_Iter>::value; - }; - - template <size_t _RewrapCount, class _OIter, class _UIter, __enable_if_t<_RewrapCount != 0, int> = 0> - _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _ReverseWrapper<_OIter> __rewrap(_ReverseWrapper<_OIter> __iter1, - _UIter __iter2) { - return _ReverseWrapper<_OIter>( - reverse_iterator<_OIter>(__rewrap<_RewrapCount - 1>(__iter1.base().base(), __iter2))); - } + using _UnwrappedIter = decltype(__unwrap_iter_impl<_Iter>::__unwrap(std::declval<_Iter>())); - template <size_t _RewrapCount, class _OIter, class _UIter, __enable_if_t<_RewrapCount == 0, int> = 0> - _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR decltype(std::__rewrap_iter(std::declval<_OIter>(), - std::declval<_UIter>())) - __rewrap(_OIter __iter1, _UIter __iter2) { - return std::__rewrap_iter(__iter1, __iter2); + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ReverseWrapper<_Iter> + __rewrap(_ReverseWrapper<_Iter> __orig_iter, _UnwrappedIter __unwrapped_iter) { + return _ReverseWrapper<_Iter>( + reverse_iterator<_Iter>(__unwrap_iter_impl<_Iter>::__rewrap(__orig_iter.base().base(), __unwrapped_iter))); } - _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _ReverseWrapper<_OrigIter> __apply(_ReverseWrapper<_OrigIter> __iter1, - _UnwrappedIter __iter2) { - return __rewrap<_ReverseWrapperCount<_OrigIter>::value>(__iter1, __iter2); + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _UnwrappedIter __unwrap(_ReverseWrapper<_Iter> __i) _NOEXCEPT { + return __unwrap_iter_impl<_Iter>::__unwrap(__i.base().base()); } }; diff --git a/contrib/libs/cxxsupp/libcxx/include/__locale b/contrib/libs/cxxsupp/libcxx/include/__locale index 41a53188d6..3aa8e7505c 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__locale +++ b/contrib/libs/cxxsupp/libcxx/include/__locale @@ -34,7 +34,7 @@ # include <__support/newlib/xlocale.h> #elif defined(__OpenBSD__) # include <__support/openbsd/xlocale.h> -#elif (defined(__APPLE__) || defined(__FreeBSD__) || defined(__IBMCPP__)) +#elif (defined(__APPLE__) || defined(__FreeBSD__)) # include <xlocale.h> #elif defined(__Fuchsia__) # include <__support/fuchsia/xlocale.h> @@ -490,7 +490,11 @@ public: static const mask punct = _ISPUNCT; static const mask xdigit = _ISXDIGIT; static const mask blank = _ISBLANK; +# if defined(_AIX) + static const mask __regex_word = 0x8000; +# else static const mask __regex_word = 0x80; +# endif #elif defined(_NEWLIB_VERSION) // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h. typedef char mask; @@ -543,11 +547,8 @@ public: _LIBCPP_INLINE_VISIBILITY ctype_base() {} -// TODO: Remove the ifndef when the assert no longer fails on AIX. -#ifndef _AIX static_assert((__regex_word & ~(space | print | cntrl | upper | lower | alpha | digit | punct | xdigit | blank)) == __regex_word, "__regex_word can't overlap other bits"); -#endif }; template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype; diff --git a/contrib/libs/cxxsupp/libcxx/include/__string/char_traits.h b/contrib/libs/cxxsupp/libcxx/include/__string/char_traits.h index 9ec7f9a0e6..aa2b936341 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__string/char_traits.h +++ b/contrib/libs/cxxsupp/libcxx/include/__string/char_traits.h @@ -802,9 +802,7 @@ __str_rfind(const _CharT *__p, _SizeT __sz, __pos += __n; else __pos = __sz; - const _CharT* __r = _VSTD::__find_end( - __p, __p + __pos, __s, __s + __n, _Traits::eq, - random_access_iterator_tag(), random_access_iterator_tag()); + const _CharT* __r = std::__find_end_classic(__p, __p + __pos, __s, __s + __n, _Traits::eq); if (__n > 0 && __r == __p + __pos) return __npos; return static_cast<_SizeT>(__r - __p); diff --git a/contrib/libs/cxxsupp/libcxx/include/__support/android/locale_bionic.h b/contrib/libs/cxxsupp/libcxx/include/__support/android/locale_bionic.h index 535bad7856..c41e26420f 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__support/android/locale_bionic.h +++ b/contrib/libs/cxxsupp/libcxx/include/__support/android/locale_bionic.h @@ -46,18 +46,18 @@ extern "C" { extern "C" { #endif -inline _LIBCPP_INLINE_VISIBILITY float strtof_l(const char* __nptr, char** __endptr, - locale_t) { +inline _LIBCPP_HIDE_FROM_ABI float +strtof_l(const char* __nptr, char** __endptr, locale_t) { return ::strtof(__nptr, __endptr); } -inline _LIBCPP_INLINE_VISIBILITY double strtod_l(const char* __nptr, - char** __endptr, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI double +strtod_l(const char* __nptr, char** __endptr, locale_t) { return ::strtod(__nptr, __endptr); } -inline _LIBCPP_INLINE_VISIBILITY long strtol_l(const char* __nptr, char** __endptr, - int __base, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI long +strtol_l(const char* __nptr, char** __endptr, int __base, locale_t) { return ::strtol(__nptr, __endptr, __base); } diff --git a/contrib/libs/cxxsupp/libcxx/include/__support/ibm/limits.h b/contrib/libs/cxxsupp/libcxx/include/__support/ibm/limits.h deleted file mode 100644 index 45f1f1e368..0000000000 --- a/contrib/libs/cxxsupp/libcxx/include/__support/ibm/limits.h +++ /dev/null @@ -1,98 +0,0 @@ -// -*- 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_SUPPORT_IBM_LIMITS_H -#define _LIBCPP_SUPPORT_IBM_LIMITS_H - -#if !defined(_AIX) // Linux -#include <math.h> // for HUGE_VAL, HUGE_VALF, HUGE_VALL, and NAN - -static const unsigned int _QNAN_F = 0x7fc00000; -#define NANF (*((float *)(&_QNAN_F))) -static const unsigned int _QNAN_LDBL128[4] = {0x7ff80000, 0x0, 0x0, 0x0}; -#define NANL (*((long double *)(&_QNAN_LDBL128))) -static const unsigned int _SNAN_F= 0x7f855555; -#define NANSF (*((float *)(&_SNAN_F))) -static const unsigned int _SNAN_D[2] = {0x7ff55555, 0x55555555}; -#define NANS (*((double *)(&_SNAN_D))) -static const unsigned int _SNAN_LDBL128[4] = {0x7ff55555, 0x55555555, 0x0, 0x0}; -#define NANSL (*((long double *)(&_SNAN_LDBL128))) - -#define __builtin_huge_val() HUGE_VAL -#define __builtin_huge_valf() HUGE_VALF -#define __builtin_huge_vall() HUGE_VALL -#define __builtin_nan(__dummy) NAN -#define __builtin_nanf(__dummy) NANF -#define __builtin_nanl(__dummy) NANL -#define __builtin_nans(__dummy) NANS -#define __builtin_nansf(__dummy) NANSF -#define __builtin_nansl(__dummy) NANSL - -#else - -#include <math.h> -#include <float.h> // limit constants - -#define __builtin_huge_val() HUGE_VAL //0x7ff0000000000000 -#define __builtin_huge_valf() HUGE_VALF //0x7f800000 -#define __builtin_huge_vall() HUGE_VALL //0x7ff0000000000000 -#define __builtin_nan(__dummy) nan(__dummy) //0x7ff8000000000000 -#define __builtin_nanf(__dummy) nanf(__dummy) // 0x7ff80000 -#define __builtin_nanl(__dummy) nanl(__dummy) //0x7ff8000000000000 -#define __builtin_nans(__dummy) DBL_SNAN //0x7ff5555555555555 -#define __builtin_nansf(__dummy) FLT_SNAN //0x7f855555 -#define __builtin_nansl(__dummy) DBL_SNAN //0x7ff5555555555555 - -#define __FLT_MANT_DIG__ FLT_MANT_DIG -#define __FLT_DIG__ FLT_DIG -#define __FLT_RADIX__ FLT_RADIX -#define __FLT_MIN_EXP__ FLT_MIN_EXP -#define __FLT_MIN_10_EXP__ FLT_MIN_10_EXP -#define __FLT_MAX_EXP__ FLT_MAX_EXP -#define __FLT_MAX_10_EXP__ FLT_MAX_10_EXP -#define __FLT_MIN__ FLT_MIN -#define __FLT_MAX__ FLT_MAX -#define __FLT_EPSILON__ FLT_EPSILON -// predefined by XLC on LoP -#define __FLT_DENORM_MIN__ 1.40129846e-45F - -#define __DBL_MANT_DIG__ DBL_MANT_DIG -#define __DBL_DIG__ DBL_DIG -#define __DBL_MIN_EXP__ DBL_MIN_EXP -#define __DBL_MIN_10_EXP__ DBL_MIN_10_EXP -#define __DBL_MAX_EXP__ DBL_MAX_EXP -#define __DBL_MAX_10_EXP__ DBL_MAX_10_EXP -#define __DBL_MIN__ DBL_MIN -#define __DBL_MAX__ DBL_MAX -#define __DBL_EPSILON__ DBL_EPSILON -// predefined by XLC on LoP -#define __DBL_DENORM_MIN__ 4.9406564584124654e-324 - -#define __LDBL_MANT_DIG__ LDBL_MANT_DIG -#define __LDBL_DIG__ LDBL_DIG -#define __LDBL_MIN_EXP__ LDBL_MIN_EXP -#define __LDBL_MIN_10_EXP__ LDBL_MIN_10_EXP -#define __LDBL_MAX_EXP__ LDBL_MAX_EXP -#define __LDBL_MAX_10_EXP__ LDBL_MAX_10_EXP -#define __LDBL_MIN__ LDBL_MIN -#define __LDBL_MAX__ LDBL_MAX -#define __LDBL_EPSILON__ LDBL_EPSILON -// predefined by XLC on LoP -#if __LONGDOUBLE128 -#define __LDBL_DENORM_MIN__ 4.94065645841246544176568792868221e-324L -#else -#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L -#endif - -// predefined by XLC on LoP -#define __CHAR_BIT__ 8 - -#endif // _AIX - -#endif // _LIBCPP_SUPPORT_IBM_LIMITS_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__support/ibm/support.h b/contrib/libs/cxxsupp/libcxx/include/__support/ibm/support.h deleted file mode 100644 index a7751b0176..0000000000 --- a/contrib/libs/cxxsupp/libcxx/include/__support/ibm/support.h +++ /dev/null @@ -1,53 +0,0 @@ -// -*- 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_SUPPORT_IBM_SUPPORT_H -#define _LIBCPP_SUPPORT_IBM_SUPPORT_H - -extern "builtin" int __popcnt4(unsigned int); -extern "builtin" int __popcnt8(unsigned long long); -extern "builtin" unsigned int __cnttz4(unsigned int); -extern "builtin" unsigned int __cnttz8(unsigned long long); -extern "builtin" unsigned int __cntlz4(unsigned int); -extern "builtin" unsigned int __cntlz8(unsigned long long); - -// Builtin functions for counting population -#define __builtin_popcount(x) __popcnt4(x) -#define __builtin_popcountll(x) __popcnt8(x) -#if defined(__64BIT__) -#define __builtin_popcountl(x) __builtin_popcountll(x) -#else -#define __builtin_popcountl(x) __builtin_popcount(x) -#endif - -// Builtin functions for counting trailing zeros -#define __builtin_ctz(x) __cnttz4(x) -#define __builtin_ctzll(x) __cnttz8(x) -#if defined(__64BIT__) -#define __builtin_ctzl(x) __builtin_ctzll(x) -#else -#define __builtin_ctzl(x) __builtin_ctz(x) -#endif - -// Builtin functions for counting leading zeros -#define __builtin_clz(x) __cntlz4(x) -#define __builtin_clzll(x) __cntlz8(x) -#if defined(__64BIT__) -#define __builtin_clzl(x) __builtin_clzll(x) -#else -#define __builtin_clzl(x) __builtin_clz(x) -#endif - -#if defined(__64BIT__) -#define __SIZE_WIDTH__ 64 -#else -#define __SIZE_WIDTH__ 32 -#endif - -#endif // _LIBCPP_SUPPORT_IBM_SUPPORT_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__support/ibm/xlocale.h b/contrib/libs/cxxsupp/libcxx/include/__support/ibm/xlocale.h index 11c1847e4c..5a09212c6a 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__support/ibm/xlocale.h +++ b/contrib/libs/cxxsupp/libcxx/include/__support/ibm/xlocale.h @@ -10,7 +10,10 @@ #ifndef _LIBCPP_SUPPORT_IBM_XLOCALE_H #define _LIBCPP_SUPPORT_IBM_XLOCALE_H +#if defined(__MVS__) #include <__support/ibm/locale_mgmt_zos.h> +#endif // defined(__MVS__) + #include <stdarg.h> #include "cstdlib" diff --git a/contrib/libs/cxxsupp/libcxx/include/__support/xlocale/__posix_l_fallback.h b/contrib/libs/cxxsupp/libcxx/include/__support/xlocale/__posix_l_fallback.h index e2b1f62f57..294149eb8f 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__support/xlocale/__posix_l_fallback.h +++ b/contrib/libs/cxxsupp/libcxx/include/__support/xlocale/__posix_l_fallback.h @@ -19,141 +19,141 @@ extern "C" { #endif -inline _LIBCPP_INLINE_VISIBILITY int isalnum_l(int __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int isalnum_l(int __c, locale_t) { return ::isalnum(__c); } -inline _LIBCPP_INLINE_VISIBILITY int isalpha_l(int __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int isalpha_l(int __c, locale_t) { return ::isalpha(__c); } -inline _LIBCPP_INLINE_VISIBILITY int isblank_l(int __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int isblank_l(int __c, locale_t) { return ::isblank(__c); } -inline _LIBCPP_INLINE_VISIBILITY int iscntrl_l(int __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int iscntrl_l(int __c, locale_t) { return ::iscntrl(__c); } -inline _LIBCPP_INLINE_VISIBILITY int isdigit_l(int __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int isdigit_l(int __c, locale_t) { return ::isdigit(__c); } -inline _LIBCPP_INLINE_VISIBILITY int isgraph_l(int __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int isgraph_l(int __c, locale_t) { return ::isgraph(__c); } -inline _LIBCPP_INLINE_VISIBILITY int islower_l(int __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int islower_l(int __c, locale_t) { return ::islower(__c); } -inline _LIBCPP_INLINE_VISIBILITY int isprint_l(int __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int isprint_l(int __c, locale_t) { return ::isprint(__c); } -inline _LIBCPP_INLINE_VISIBILITY int ispunct_l(int __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int ispunct_l(int __c, locale_t) { return ::ispunct(__c); } -inline _LIBCPP_INLINE_VISIBILITY int isspace_l(int __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int isspace_l(int __c, locale_t) { return ::isspace(__c); } -inline _LIBCPP_INLINE_VISIBILITY int isupper_l(int __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int isupper_l(int __c, locale_t) { return ::isupper(__c); } -inline _LIBCPP_INLINE_VISIBILITY int isxdigit_l(int __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int isxdigit_l(int __c, locale_t) { return ::isxdigit(__c); } -inline _LIBCPP_INLINE_VISIBILITY int iswalnum_l(wint_t __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int iswalnum_l(wint_t __c, locale_t) { return ::iswalnum(__c); } -inline _LIBCPP_INLINE_VISIBILITY int iswalpha_l(wint_t __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int iswalpha_l(wint_t __c, locale_t) { return ::iswalpha(__c); } -inline _LIBCPP_INLINE_VISIBILITY int iswblank_l(wint_t __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int iswblank_l(wint_t __c, locale_t) { return ::iswblank(__c); } -inline _LIBCPP_INLINE_VISIBILITY int iswcntrl_l(wint_t __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int iswcntrl_l(wint_t __c, locale_t) { return ::iswcntrl(__c); } -inline _LIBCPP_INLINE_VISIBILITY int iswdigit_l(wint_t __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int iswdigit_l(wint_t __c, locale_t) { return ::iswdigit(__c); } -inline _LIBCPP_INLINE_VISIBILITY int iswgraph_l(wint_t __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int iswgraph_l(wint_t __c, locale_t) { return ::iswgraph(__c); } -inline _LIBCPP_INLINE_VISIBILITY int iswlower_l(wint_t __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int iswlower_l(wint_t __c, locale_t) { return ::iswlower(__c); } -inline _LIBCPP_INLINE_VISIBILITY int iswprint_l(wint_t __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int iswprint_l(wint_t __c, locale_t) { return ::iswprint(__c); } -inline _LIBCPP_INLINE_VISIBILITY int iswpunct_l(wint_t __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int iswpunct_l(wint_t __c, locale_t) { return ::iswpunct(__c); } -inline _LIBCPP_INLINE_VISIBILITY int iswspace_l(wint_t __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int iswspace_l(wint_t __c, locale_t) { return ::iswspace(__c); } -inline _LIBCPP_INLINE_VISIBILITY int iswupper_l(wint_t __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int iswupper_l(wint_t __c, locale_t) { return ::iswupper(__c); } -inline _LIBCPP_INLINE_VISIBILITY int iswxdigit_l(wint_t __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int iswxdigit_l(wint_t __c, locale_t) { return ::iswxdigit(__c); } -inline _LIBCPP_INLINE_VISIBILITY int toupper_l(int __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int toupper_l(int __c, locale_t) { return ::toupper(__c); } -inline _LIBCPP_INLINE_VISIBILITY int tolower_l(int __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int tolower_l(int __c, locale_t) { return ::tolower(__c); } -inline _LIBCPP_INLINE_VISIBILITY wint_t towupper_l(wint_t __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI wint_t towupper_l(wint_t __c, locale_t) { return ::towupper(__c); } -inline _LIBCPP_INLINE_VISIBILITY wint_t towlower_l(wint_t __c, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI wint_t towlower_l(wint_t __c, locale_t) { return ::towlower(__c); } -inline _LIBCPP_INLINE_VISIBILITY int strcoll_l(const char *__s1, const char *__s2, - locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int +strcoll_l(const char *__s1, const char *__s2, locale_t) { return ::strcoll(__s1, __s2); } -inline _LIBCPP_INLINE_VISIBILITY size_t strxfrm_l(char *__dest, const char *__src, - size_t __n, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI size_t +strxfrm_l(char *__dest, const char *__src, size_t __n, locale_t) { return ::strxfrm(__dest, __src, __n); } -inline _LIBCPP_INLINE_VISIBILITY size_t strftime_l(char *__s, size_t __max, - const char *__format, - const struct tm *__tm, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI size_t +strftime_l(char *__s, size_t __max, const char *__format, const struct tm *__tm, + locale_t) { return ::strftime(__s, __max, __format, __tm); } -inline _LIBCPP_INLINE_VISIBILITY int wcscoll_l(const wchar_t *__ws1, - const wchar_t *__ws2, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int +wcscoll_l(const wchar_t *__ws1, const wchar_t *__ws2, locale_t) { return ::wcscoll(__ws1, __ws2); } -inline _LIBCPP_INLINE_VISIBILITY size_t wcsxfrm_l(wchar_t *__dest, const wchar_t *__src, - size_t __n, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI size_t +wcsxfrm_l(wchar_t *__dest, const wchar_t *__src, size_t __n, locale_t) { return ::wcsxfrm(__dest, __src, __n); } diff --git a/contrib/libs/cxxsupp/libcxx/include/__support/xlocale/__strtonum_fallback.h b/contrib/libs/cxxsupp/libcxx/include/__support/xlocale/__strtonum_fallback.h index 497148a662..19780909b2 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__support/xlocale/__strtonum_fallback.h +++ b/contrib/libs/cxxsupp/libcxx/include/__support/xlocale/__strtonum_fallback.h @@ -19,43 +19,43 @@ extern "C" { #endif -inline _LIBCPP_INLINE_VISIBILITY float strtof_l(const char *__nptr, - char **__endptr, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI float +strtof_l(const char *__nptr, char **__endptr, locale_t) { return ::strtof(__nptr, __endptr); } -inline _LIBCPP_INLINE_VISIBILITY double strtod_l(const char *__nptr, - char **__endptr, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI double +strtod_l(const char *__nptr, char **__endptr, locale_t) { return ::strtod(__nptr, __endptr); } -inline _LIBCPP_INLINE_VISIBILITY long double strtold_l(const char *__nptr, - char **__endptr, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI long double +strtold_l(const char *__nptr, char **__endptr, locale_t) { return ::strtold(__nptr, __endptr); } -inline _LIBCPP_INLINE_VISIBILITY long long +inline _LIBCPP_HIDE_FROM_ABI long long strtoll_l(const char *__nptr, char **__endptr, int __base, locale_t) { return ::strtoll(__nptr, __endptr, __base); } -inline _LIBCPP_INLINE_VISIBILITY unsigned long long +inline _LIBCPP_HIDE_FROM_ABI unsigned long long strtoull_l(const char *__nptr, char **__endptr, int __base, locale_t) { return ::strtoull(__nptr, __endptr, __base); } -inline _LIBCPP_INLINE_VISIBILITY long long +inline _LIBCPP_HIDE_FROM_ABI long long wcstoll_l(const wchar_t *__nptr, wchar_t **__endptr, int __base, locale_t) { return ::wcstoll(__nptr, __endptr, __base); } -inline _LIBCPP_INLINE_VISIBILITY unsigned long long +inline _LIBCPP_HIDE_FROM_ABI unsigned long long wcstoull_l(const wchar_t *__nptr, wchar_t **__endptr, int __base, locale_t) { return ::wcstoull(__nptr, __endptr, __base); } -inline _LIBCPP_INLINE_VISIBILITY long double wcstold_l(const wchar_t *__nptr, - wchar_t **__endptr, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI long double +wcstold_l(const wchar_t *__nptr, wchar_t **__endptr, locale_t) { return ::wcstold(__nptr, __endptr); } diff --git a/contrib/libs/cxxsupp/libcxx/include/algorithm b/contrib/libs/cxxsupp/libcxx/include/algorithm index 67741e30d8..e972a34d06 100644 --- a/contrib/libs/cxxsupp/libcxx/include/algorithm +++ b/contrib/libs/cxxsupp/libcxx/include/algorithm @@ -360,6 +360,17 @@ namespace ranges { borrowed_iterator_t<R> ranges::stable_sort(R&& r, Comp comp = {}, Proj proj = {}); // since C++20 + template<random_access_iterator I, sentinel_for<I> S, class Comp = ranges::less, + class Proj = identity> + requires sortable<I, Comp, Proj> + constexpr I + ranges::partial_sort(I first, I middle, S last, Comp comp = {}, Proj proj = {}); // since C++20 + + template<random_access_range R, class Comp = ranges::less, class Proj = identity> + requires sortable<iterator_t<R>, Comp, Proj> + constexpr borrowed_iterator_t<R> + ranges::partial_sort(R&& r, iterator_t<R> middle, Comp comp = {}, Proj proj = {}); // since C++20 + template<class T, output_iterator<const T&> O, sentinel_for<O> S> constexpr O ranges::fill(O first, S last, const T& value); // since C++20 @@ -464,6 +475,28 @@ namespace ranges { ranges::less> constexpr bool binary_search(R&& r, const T& value, Comp comp = {}, Proj proj = {}); // since C++20 + + template<permutable I, sentinel_for<I> S, class Proj = identity, + indirect_unary_predicate<projected<I, Proj>> Pred> + constexpr subrange<I> + partition(I first, S last, Pred pred, Proj proj = {}); // Since C++20 + + template<forward_range R, class Proj = identity, + indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred> + requires permutable<iterator_t<R>> + constexpr borrowed_subrange_t<R> + partition(R&& r, Pred pred, Proj proj = {}); // Since C++20 + + template<bidirectional_iterator I, sentinel_for<I> S, class Proj = identity, + indirect_unary_predicate<projected<I, Proj>> Pred> + requires permutable<I> + subrange<I> stable_partition(I first, S last, Pred pred, Proj proj = {}); // Since C++20 + + template<bidirectional_range R, class Proj = identity, + indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred> + requires permutable<iterator_t<R>> + borrowed_subrange_t<R> stable_partition(R&& r, Pred pred, Proj proj = {}); // Since C++20 + template<input_iterator I1, sentinel_for<I1> S1, forward_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> @@ -548,6 +581,34 @@ namespace ranges { constexpr ranges::move_result<borrowed_iterator_t<R>, O> ranges::move(R&& r, O result); // since C++20 + template<class I, class O1, class O2> + using partition_copy_result = in_out_out_result<I, O1, O2>; // since C++20 + + template<input_iterator I, sentinel_for<I> S, + weakly_incrementable O1, weakly_incrementable O2, + class Proj = identity, indirect_unary_predicate<projected<I, Proj>> Pred> + requires indirectly_copyable<I, O1> && indirectly_copyable<I, O2> + constexpr partition_copy_result<I, O1, O2> + partition_copy(I first, S last, O1 out_true, O2 out_false, Pred pred, + Proj proj = {}); // Since C++20 + + template<input_range R, weakly_incrementable O1, weakly_incrementable O2, + class Proj = identity, + indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred> + requires indirectly_copyable<iterator_t<R>, O1> && + indirectly_copyable<iterator_t<R>, O2> + constexpr partition_copy_result<borrowed_iterator_t<R>, O1, O2> + partition_copy(R&& r, O1 out_true, O2 out_false, Pred pred, Proj proj = {}); // Since C++20 + + template<forward_iterator I, sentinel_for<I> S, class Proj = identity, + indirect_unary_predicate<projected<I, Proj>> Pred> + constexpr I partition_point(I first, S last, Pred pred, Proj proj = {}); // Since C++20 + + template<forward_range R, class Proj = identity, + indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred> + constexpr borrowed_iterator_t<R> + partition_point(R&& r, Pred pred, Proj proj = {}); // Since C++20 + template<class I1, class I2, class O> using merge_result = in_in_out_result<I1, I2, O>; // since C++20 @@ -649,6 +710,86 @@ namespace ranges { constexpr ranges::rotate_copy_result<borrowed_iterator_t<R>, O> ranges::rotate_copy(R&& r, iterator_t<R> middle, O result); // since C++20 + template<forward_iterator I1, sentinel_for<I1> S1, forward_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> + constexpr subrange<I1> + ranges::search(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20 + + template<forward_range R1, forward_range R2, class Pred = ranges::equal_to, + class Proj1 = identity, class Proj2 = identity> + requires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2> + constexpr borrowed_subrange_t<R1> + ranges::search(R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20 + + template<forward_iterator I, sentinel_for<I> S, class T, + class Pred = ranges::equal_to, class Proj = identity> + requires indirectly_comparable<I, const T*, Pred, Proj> + constexpr subrange<I> + ranges::search_n(I first, S last, iter_difference_t<I> count, + const T& value, Pred pred = {}, Proj proj = {}); // since C++20 + + template<forward_range R, class T, class Pred = ranges::equal_to, + class Proj = identity> + requires indirectly_comparable<iterator_t<R>, const T*, Pred, Proj> + constexpr borrowed_subrange_t<R> + ranges::search_n(R&& r, range_difference_t<R> count, + const T& value, Pred pred = {}, Proj proj = {}); // since C++20 + + template<forward_iterator I1, sentinel_for<I1> S1, forward_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> + constexpr subrange<I1> + ranges::find_end(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20 + + template<forward_range R1, forward_range R2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2> + constexpr borrowed_subrange_t<R1> + ranges::find_end(R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20 + + template<class I1, class I2, class O> + using set_symmetric_difference_result = in_in_out_result<I1, I2, O>; // since C++20 + + template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2, + weakly_incrementable O, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires mergeable<I1, I2, O, Comp, Proj1, Proj2> + constexpr set_symmetric_difference_result<I1, I2, O> + set_symmetric_difference(I1 first1, S1 last1, I2 first2, S2 last2, O result, + Comp comp = {}, Proj1 proj1 = {}, + Proj2 proj2 = {}); // since C++20 + + template<input_range R1, input_range R2, weakly_incrementable O, + class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> + requires mergeable<iterator_t<R1>, iterator_t<R2>, O, Comp, Proj1, Proj2> + constexpr set_symmetric_difference_result<borrowed_iterator_t<R1>, + borrowed_iterator_t<R2>, O> + set_symmetric_difference(R1&& r1, R2&& r2, O result, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20 + + template<class I1, class I2, class O> + using set_union_result = in_in_out_result<I1, I2, O>; // since C++20 + + template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2, + weakly_incrementable O, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires mergeable<I1, I2, O, Comp, Proj1, Proj2> + constexpr set_union_result<I1, I2, O> + set_union(I1 first1, S1 last1, I2 first2, S2 last2, O result, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20 + + template<input_range R1, input_range R2, weakly_incrementable O, + class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> + requires mergeable<iterator_t<R1>, iterator_t<R2>, O, Comp, Proj1, Proj2> + constexpr set_union_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>, O> + set_union(R1&& r1, R2&& r2, O result, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20 } constexpr bool // constexpr in C++20 @@ -1392,6 +1533,7 @@ template <class BidirectionalIterator, class Compare> #include <__algorithm/ranges_fill.h> #include <__algorithm/ranges_fill_n.h> #include <__algorithm/ranges_find.h> +#include <__algorithm/ranges_find_end.h> #include <__algorithm/ranges_find_first_of.h> #include <__algorithm/ranges_find_if.h> #include <__algorithm/ranges_find_if_not.h> @@ -1415,6 +1557,10 @@ template <class BidirectionalIterator, class Compare> #include <__algorithm/ranges_move_backward.h> #include <__algorithm/ranges_none_of.h> #include <__algorithm/ranges_nth_element.h> +#include <__algorithm/ranges_partial_sort.h> +#include <__algorithm/ranges_partition.h> +#include <__algorithm/ranges_partition_copy.h> +#include <__algorithm/ranges_partition_point.h> #include <__algorithm/ranges_pop_heap.h> #include <__algorithm/ranges_push_heap.h> #include <__algorithm/ranges_remove.h> @@ -1424,10 +1570,15 @@ template <class BidirectionalIterator, class Compare> #include <__algorithm/ranges_reverse.h> #include <__algorithm/ranges_reverse_copy.h> #include <__algorithm/ranges_rotate_copy.h> +#include <__algorithm/ranges_search.h> +#include <__algorithm/ranges_search_n.h> #include <__algorithm/ranges_set_difference.h> #include <__algorithm/ranges_set_intersection.h> +#include <__algorithm/ranges_set_symmetric_difference.h> +#include <__algorithm/ranges_set_union.h> #include <__algorithm/ranges_sort.h> #include <__algorithm/ranges_sort_heap.h> +#include <__algorithm/ranges_stable_partition.h> #include <__algorithm/ranges_stable_sort.h> #include <__algorithm/ranges_swap_ranges.h> #include <__algorithm/ranges_transform.h> diff --git a/contrib/libs/cxxsupp/libcxx/include/bit b/contrib/libs/cxxsupp/libcxx/include/bit index fe1bcadc81..15bc13a504 100644 --- a/contrib/libs/cxxsupp/libcxx/include/bit +++ b/contrib/libs/cxxsupp/libcxx/include/bit @@ -75,9 +75,6 @@ namespace std { # include <iosfwd> #endif -#if defined(__IBMCPP__) -# include "__support/ibm/support.h" -#endif #if defined(_LIBCPP_COMPILER_MSVC) # include <intrin.h> #endif diff --git a/contrib/libs/cxxsupp/libcxx/include/chrono b/contrib/libs/cxxsupp/libcxx/include/chrono index 9185d74c09..2af5fbcc51 100644 --- a/contrib/libs/cxxsupp/libcxx/include/chrono +++ b/contrib/libs/cxxsupp/libcxx/include/chrono @@ -13,6 +13,8 @@ /* chrono synopsis +#include <compare> // C++20 + namespace std { namespace chrono @@ -325,11 +327,7 @@ struct last_spec; class day; constexpr bool operator==(const day& x, const day& y) noexcept; -constexpr bool operator!=(const day& x, const day& y) noexcept; -constexpr bool operator< (const day& x, const day& y) noexcept; -constexpr bool operator> (const day& x, const day& y) noexcept; -constexpr bool operator<=(const day& x, const day& y) noexcept; -constexpr bool operator>=(const day& x, const day& y) noexcept; +constexpr strong_ordering operator<=>(const day& x, const day& y) noexcept; constexpr day operator+(const day& x, const days& y) noexcept; constexpr day operator+(const days& x, const day& y) noexcept; constexpr day operator-(const day& x, const days& y) noexcept; @@ -715,9 +713,11 @@ constexpr chrono::year operator ""y(unsigned lo #include <__chrono/year_month_day.h> #include <__chrono/year_month_weekday.h> #include <__config> -#include <compare> #include <version> +// standard-mandated includes +#include <compare> + #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif diff --git a/contrib/libs/cxxsupp/libcxx/include/format b/contrib/libs/cxxsupp/libcxx/include/format index dd7d08dbbe..d2ec8fc233 100644 --- a/contrib/libs/cxxsupp/libcxx/include/format +++ b/contrib/libs/cxxsupp/libcxx/include/format @@ -131,7 +131,7 @@ namespace std { #include <__assert> // all public C++ headers provide the assertion handler // Make sure all feature-test macros are available. #include <version> -// Enable the contents of the header only when libc++ was built with LIBCXX_ENABLE_INCOMPLETE_FEATURES. +// Enable the contents of the header only when libc++ was built with experimental features enabled. #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) #include <__algorithm/clamp.h> @@ -157,6 +157,7 @@ namespace std { #include <__format/formatter_pointer.h> #include <__format/formatter_string.h> #include <__format/parser_std_format_spec.h> +#include <__format/unicode.h> #include <__iterator/back_insert_iterator.h> #include <__iterator/incrementable_traits.h> #include <__variant/monostate.h> @@ -376,6 +377,7 @@ __handle_replacement_field(const _CharT* __begin, const _CharT* __end, __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. @@ -395,7 +397,7 @@ __handle_replacement_field(const _CharT* __begin, const _CharT* __end, if (__type == __arg_t::__handle) __ctx.__handle(__r.__value).__parse(__parse_ctx); else - __format::__compile_time_visit_format_arg(__parse_ctx, __ctx, __type); + __format::__compile_time_visit_format_arg(__parse_ctx, __ctx, __type); } else _VSTD::visit_format_arg( [&](auto __arg) { @@ -405,7 +407,8 @@ __handle_replacement_field(const _CharT* __begin, const _CharT* __end, __arg.format(__parse_ctx, __ctx); else { formatter<decltype(__arg), _CharT> __formatter; - __parse_ctx.advance_to(__formatter.parse(__parse_ctx)); + if (__parse) + __parse_ctx.advance_to(__formatter.parse(__parse_ctx)); __ctx.advance_to(__formatter.format(__arg, __ctx)); } }, diff --git a/contrib/libs/cxxsupp/libcxx/include/limits b/contrib/libs/cxxsupp/libcxx/include/limits index 35e4d85734..1fa3a8228f 100644 --- a/contrib/libs/cxxsupp/libcxx/include/limits +++ b/contrib/libs/cxxsupp/libcxx/include/limits @@ -110,10 +110,6 @@ template<> class numeric_limits<cv long double>; #include "__support/win32/limits_msvc_win32.h" #endif // _LIBCPP_MSVCRT -#if defined(__IBMCPP__) -#include "__support/ibm/limits.h" -#endif // __IBMCPP__ - #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif diff --git a/contrib/libs/cxxsupp/libcxx/include/ostream b/contrib/libs/cxxsupp/libcxx/include/ostream index 283774585b..b3b3e3e4fa 100644 --- a/contrib/libs/cxxsupp/libcxx/include/ostream +++ b/contrib/libs/cxxsupp/libcxx/include/ostream @@ -130,6 +130,35 @@ template <class charT, class traits> template <class Stream, class T> Stream&& operator<<(Stream&& os, const T& x); +template<class traits> +basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, wchar_t) = delete; // since C++20 +template<class traits> +basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, char8_t) = delete; // since C++20 +template<class traits> +basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, char16_t) = delete; // since C++20 +template<class traits> +basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, char32_t) = delete; // since C++20 +template<class traits> +basic_ostream<wchar_t, traits>& operator<<(basic_ostream<wchar_t, traits>&, char8_t) = delete; // since C++20 +template<class traits> +basic_ostream<wchar_t, traits>& operator<<(basic_ostream<wchar_t, traits>&, char16_t) = delete; // since C++20 +template<class traits> +basic_ostream<wchar_t, traits>& operator<<(basic_ostream<wchar_t, traits>&, char32_t) = delete; // since C++20 +template<class traits> +basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, const wchar_t*) = delete; // since C++20 +template<class traits> +basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, const char8_t*) = delete; // since C++20 +template<class traits> +basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, const char16_t*) = delete; // since C++20 +template<class traits> +basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, const char32_t*) = delete; // since C++20 +template<class traits> +basic_ostream<wchar_t, traits>& operator<<(basic_ostream<wchar_t, traits>&, const char8_t*) = delete; // since C++20 +template<class traits> +basic_ostream<wchar_t, traits>& operator<<(basic_ostream<wchar_t, traits>&, const char16_t*) = delete; // since C++20 +template<class traits> +basic_ostream<wchar_t, traits>& operator<<(basic_ostream<wchar_t, traits>&, const char32_t*) = delete; // since C++20 + } // std */ @@ -225,9 +254,13 @@ public: basic_ostream& operator<<(basic_streambuf<char_type, traits_type>* __sb); +#if _LIBCPP_STD_VER > 14 +// LWG 2221 - nullptr. This is not backported to older standards modes. +// See https://reviews.llvm.org/D127033 for more info on the rationale. _LIBCPP_INLINE_VISIBILITY basic_ostream& operator<<(nullptr_t) { return *this << "nullptr"; } +#endif // 27.7.2.7 Unformatted output: basic_ostream& put(char_type __c); @@ -1098,6 +1131,57 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x) use_facet<ctype<_CharT> >(__os.getloc()).widen('1')); } +#if 0 + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template <class _Traits> +basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, wchar_t) = delete; + +template <class _Traits> +basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, const wchar_t*) = delete; + +template <class _Traits> +basic_ostream<wchar_t, _Traits>& operator<<(basic_ostream<wchar_t, _Traits>&, char16_t) = delete; + +template <class _Traits> +basic_ostream<wchar_t, _Traits>& operator<<(basic_ostream<wchar_t, _Traits>&, char32_t) = delete; + +template <class _Traits> +basic_ostream<wchar_t, _Traits>& operator<<(basic_ostream<wchar_t, _Traits>&, const char16_t*) = delete; + +template <class _Traits> +basic_ostream<wchar_t, _Traits>& operator<<(basic_ostream<wchar_t, _Traits>&, const char32_t*) = delete; + +#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS + +#ifndef _LIBCPP_HAS_NO_CHAR8_T +template <class _Traits> +basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, char8_t) = delete; + +template <class _Traits> +basic_ostream<wchar_t, _Traits>& operator<<(basic_ostream<wchar_t, _Traits>&, char8_t) = delete; + +template <class _Traits> +basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, const char8_t*) = delete; + +template <class _Traits> +basic_ostream<wchar_t, _Traits>& operator<<(basic_ostream<wchar_t, _Traits>&, const char8_t*) = delete; +#endif + +template <class _Traits> +basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, char16_t) = delete; + +template <class _Traits> +basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, char32_t) = delete; + +template <class _Traits> +basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, const char16_t*) = delete; + +template <class _Traits> +basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, const char32_t*) = delete; + +#endif // _LIBCPP_STD_VER > 17 + extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<char>; #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<wchar_t>; diff --git a/contrib/libs/cxxsupp/libcxx/include/version b/contrib/libs/cxxsupp/libcxx/include/version index ec27c5ed25..25441d2ab1 100644 --- a/contrib/libs/cxxsupp/libcxx/include/version +++ b/contrib/libs/cxxsupp/libcxx/include/version @@ -248,7 +248,7 @@ __cpp_lib_void_t 201411L <type_traits> # define __cpp_lib_enable_shared_from_this 201603L // # define __cpp_lib_execution 201603L # if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem) -# define __cpp_lib_filesystem 201703L +# define __cpp_lib_filesystem 201703L # endif # define __cpp_lib_gcd_lcm 201606L # if defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE) diff --git a/contrib/libs/cxxsupp/libcxx/ya.make b/contrib/libs/cxxsupp/libcxx/ya.make index fe93dae953..c72710f6c8 100644 --- a/contrib/libs/cxxsupp/libcxx/ya.make +++ b/contrib/libs/cxxsupp/libcxx/ya.make @@ -8,14 +8,15 @@ LICENSE( BSD-2-Clause AND BSL-1.0 AND MIT AND - NCSA + NCSA AND + Unicode ) LICENSE_TEXTS(.yandex_meta/licenses.list.txt) -VERSION(2022-07-12) +VERSION(2022-07-22) -ORIGINAL_SOURCE(https://github.com/llvm/llvm-project/archive/81c48436bbd29736f77a111fc207e28854939907.tar.gz) +ORIGINAL_SOURCE(https://github.com/llvm/llvm-project/archive/1d057a6d43060eaf6c679e0593a43f99ecd70987.tar.gz) ADDINCL( GLOBAL contrib/libs/cxxsupp/libcxx/include diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__coroutine/coroutine_handle.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__coroutine/coroutine_handle.h deleted file mode 100644 index 4bf3237892..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__coroutine/coroutine_handle.h +++ /dev/null @@ -1,202 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.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 <compare> -#include <type_traits> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX20_COROUTINES) - -_LIBCPP_BEGIN_NAMESPACE_STD - -// [coroutine.handle] -template <class _Promise = void> -struct _LIBCPP_TEMPLATE_VIS coroutine_handle; - -template <> -struct _LIBCPP_TEMPLATE_VIS coroutine_handle<void> { -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 <class _Promise> -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 = typename remove_cv<_Promise>::type; - 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 <class _Tp> -struct hash<coroutine_handle<_Tp>> { - _LIBCPP_HIDE_FROM_ABI - size_t operator()(const coroutine_handle<_Tp>& __v) const noexcept { return hash<void*>()(__v.address()); } -}; - -_LIBCPP_END_NAMESPACE_STD - -#endif // __LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX20_COROUTINES) - -#endif // _LIBCPP___COROUTINE_COROUTINE_HANDLE_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__coroutine/coroutine_traits.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__coroutine/coroutine_traits.h deleted file mode 100644 index 0a5229b459..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__coroutine/coroutine_traits.h +++ /dev/null @@ -1,53 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.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> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX20_COROUTINES) - -_LIBCPP_BEGIN_NAMESPACE_STD - -// [coroutine.traits] -// [coroutine.traits.primary] -// The header <coroutine> 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<R, ArgTypes...> -// has the following publicly accessible memebr: -// -// using promise_type = typename R::promise_type; -// -// Otherwise, coroutine_traits<R, ArgTypes...> has no members. -template <class _Tp, class = void> -struct __coroutine_traits_sfinae {}; - -template <class _Tp> -struct __coroutine_traits_sfinae< - _Tp, typename __void_t<typename _Tp::promise_type>::type> -{ - using promise_type = typename _Tp::promise_type; -}; - -template <class _Ret, class... _Args> -struct coroutine_traits - : public __coroutine_traits_sfinae<_Ret> -{ -}; - -_LIBCPP_END_NAMESPACE_STD - -#endif // __LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX20_COROUTINES) - -#endif // _LIBCPP___COROUTINE_COROUTINE_TRAITS_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__coroutine/noop_coroutine_handle.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__coroutine/noop_coroutine_handle.h deleted file mode 100644 index 7a2c672057..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__coroutine/noop_coroutine_handle.h +++ /dev/null @@ -1,112 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.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 && !defined(_LIBCPP_HAS_NO_CXX20_COROUTINES) - -_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<noop_coroutine_promise> { -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<noop_coroutine_promise*>( - __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_promise> 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<noop_coroutine_promise>; - -#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 && !defined(_LIBCPP_HAS_NO_CXX20_COROUTINES) - -#endif // _LIBCPP___COROUTINE_NOOP_COROUTINE_HANDLE_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__coroutine/trivial_awaitables.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__coroutine/trivial_awaitables.h deleted file mode 100644 index 31399ab29a..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__coroutine/trivial_awaitables.h +++ /dev/null @@ -1,46 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.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 && !defined(_LIBCPP_HAS_NO_CXX20_COROUTINES) - -_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 && !defined(_LIBCPP_HAS_NO_CXX20_COROUTINES) - -#endif // __LIBCPP___COROUTINE_TRIVIAL_AWAITABLES_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__iterator/iterator_traits.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__iterator/iterator_traits.h index 6ffb2ab806..79637f3fbf 100644 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__iterator/iterator_traits.h +++ b/contrib/libs/cxxsupp/libcxxmsvc/include/__iterator/iterator_traits.h @@ -401,10 +401,11 @@ struct _LIBCPP_TEMPLATE_VIS iterator_traits }; #endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) -template<class _Tp> + #if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +template<class _Tp> requires is_object_v<_Tp> -#endif struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*> { typedef ptrdiff_t difference_type; @@ -417,6 +418,30 @@ struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*> #endif }; +#else // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +template <class _Tp, bool is_pointer_to_object> +struct _LIBCPP_TEMPLATE_VIS __iterator_traits_pointer +{ + typedef ptrdiff_t difference_type; + typedef typename remove_cv<_Tp>::type 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 <class _Tp> +struct _LIBCPP_TEMPLATE_VIS __iterator_traits_pointer<_Tp, false> {}; + +template <class _Tp> +struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*> : public __iterator_traits_pointer<_Tp, is_object_v<_Tp>> {}; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + + template <class _Tp, class _Up, bool = __has_iterator_category<iterator_traits<_Tp> >::value> struct __has_iterator_category_convertible_to : is_convertible<typename iterator_traits<_Tp>::iterator_category, _Up> diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/all.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/all.h deleted file mode 100644 index 77396222d6..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/all.h +++ /dev/null @@ -1,82 +0,0 @@ -// -*- 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___RANGES_ALL_H -#define _LIBCPP___RANGES_ALL_H - -#include <__config> -#include <__iterator/concepts.h> -#include <__iterator/iterator_traits.h> -#include <__ranges/access.h> -#include <__ranges/concepts.h> -#include <__ranges/owning_view.h> -#include <__ranges/range_adaptor.h> -#include <__ranges/ref_view.h> -#include <__utility/auto_cast.h> -#include <__utility/declval.h> -#include <__utility/forward.h> -#include <type_traits> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -namespace ranges::views { - -namespace __all { - struct __fn : __range_adaptor_closure<__fn> { - template<class _Tp> - requires ranges::view<decay_t<_Tp>> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI - constexpr auto operator()(_Tp&& __t) const - noexcept(noexcept(_LIBCPP_AUTO_CAST(std::forward<_Tp>(__t)))) - { - return _LIBCPP_AUTO_CAST(std::forward<_Tp>(__t)); - } - - template<class _Tp> - requires (!ranges::view<decay_t<_Tp>>) && - requires (_Tp&& __t) { ranges::ref_view{std::forward<_Tp>(__t)}; } - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI - constexpr auto operator()(_Tp&& __t) const - noexcept(noexcept(ranges::ref_view{std::forward<_Tp>(__t)})) - { - return ranges::ref_view{std::forward<_Tp>(__t)}; - } - - template<class _Tp> - requires (!ranges::view<decay_t<_Tp>> && - !requires (_Tp&& __t) { ranges::ref_view{std::forward<_Tp>(__t)}; } && - requires (_Tp&& __t) { ranges::owning_view{std::forward<_Tp>(__t)}; }) - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI - constexpr auto operator()(_Tp&& __t) const - noexcept(noexcept(ranges::owning_view{std::forward<_Tp>(__t)})) - { - return ranges::owning_view{std::forward<_Tp>(__t)}; - } - }; -} // namespace __all - -inline namespace __cpo { - inline constexpr auto all = __all::__fn{}; -} // namespace __cpo - -template<ranges::viewable_range _Range> -using all_t = decltype(views::all(declval<_Range>())); - -} // namespace ranges::views - -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___RANGES_ALL_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/common_view.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/common_view.h deleted file mode 100644 index 78911284bb..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/common_view.h +++ /dev/null @@ -1,135 +0,0 @@ -// -*- 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___RANGES_COMMON_VIEW_H -#define _LIBCPP___RANGES_COMMON_VIEW_H - -#include <__config> -#include <__iterator/common_iterator.h> -#include <__iterator/iterator_traits.h> -#include <__ranges/access.h> -#include <__ranges/all.h> -#include <__ranges/concepts.h> -#include <__ranges/enable_borrowed_range.h> -#include <__ranges/range_adaptor.h> -#include <__ranges/size.h> -#include <__ranges/view_interface.h> -#include <__utility/forward.h> -#include <__utility/move.h> -#include <concepts> -#include <type_traits> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -namespace ranges { - -template<view _View> - requires (!common_range<_View> && copyable<iterator_t<_View>>) -class common_view : public view_interface<common_view<_View>> { - _View __base_ = _View(); - -public: - _LIBCPP_HIDE_FROM_ABI - common_view() requires default_initializable<_View> = default; - - _LIBCPP_HIDE_FROM_ABI - constexpr explicit common_view(_View __v) : __base_(std::move(__v)) { } - - _LIBCPP_HIDE_FROM_ABI - constexpr _View base() const& requires copy_constructible<_View> { return __base_; } - - _LIBCPP_HIDE_FROM_ABI - constexpr _View base() && { return std::move(__base_); } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto begin() { - if constexpr (random_access_range<_View> && sized_range<_View>) - return ranges::begin(__base_); - else - return common_iterator<iterator_t<_View>, sentinel_t<_View>>(ranges::begin(__base_)); - } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto begin() const requires range<const _View> { - if constexpr (random_access_range<const _View> && sized_range<const _View>) - return ranges::begin(__base_); - else - return common_iterator<iterator_t<const _View>, sentinel_t<const _View>>(ranges::begin(__base_)); - } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto end() { - if constexpr (random_access_range<_View> && sized_range<_View>) - return ranges::begin(__base_) + ranges::size(__base_); - else - return common_iterator<iterator_t<_View>, sentinel_t<_View>>(ranges::end(__base_)); - } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto end() const requires range<const _View> { - if constexpr (random_access_range<const _View> && sized_range<const _View>) - return ranges::begin(__base_) + ranges::size(__base_); - else - return common_iterator<iterator_t<const _View>, sentinel_t<const _View>>(ranges::end(__base_)); - } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto size() requires sized_range<_View> { - return ranges::size(__base_); - } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto size() const requires sized_range<const _View> { - return ranges::size(__base_); - } -}; - -template<class _Range> -common_view(_Range&&) - -> common_view<views::all_t<_Range>>; - -template<class _View> -inline constexpr bool enable_borrowed_range<common_view<_View>> = enable_borrowed_range<_View>; - -namespace views { -namespace __common { - struct __fn : __range_adaptor_closure<__fn> { - template<class _Range> - requires common_range<_Range> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI - constexpr auto operator()(_Range&& __range) const - noexcept(noexcept(views::all(std::forward<_Range>(__range)))) - -> decltype( views::all(std::forward<_Range>(__range))) - { return views::all(std::forward<_Range>(__range)); } - - template<class _Range> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI - constexpr auto operator()(_Range&& __range) const - noexcept(noexcept(common_view{std::forward<_Range>(__range)})) - -> decltype( common_view{std::forward<_Range>(__range)}) - { return common_view{std::forward<_Range>(__range)}; } - }; -} // namespace __common - -inline namespace __cpo { - inline constexpr auto common = __common::__fn{}; -} // namespace __cpo -} // namespace views -} // namespace ranges - -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___RANGES_COMMON_VIEW_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/copyable_box.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/copyable_box.h deleted file mode 100644 index e1c08a7ea1..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/copyable_box.h +++ /dev/null @@ -1,178 +0,0 @@ -// -*- 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___RANGES_COPYABLE_BOX_H -#define _LIBCPP___RANGES_COPYABLE_BOX_H - -#include <__config> -#include <__memory/addressof.h> -#include <__memory/construct_at.h> -#include <__utility/move.h> -#include <concepts> -#include <optional> -#include <type_traits> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -// __copyable_box allows turning a type that is copy-constructible (but maybe not copy-assignable) into -// a type that is both copy-constructible and copy-assignable. It does that by introducing an empty state -// and basically doing destroy-then-copy-construct in the assignment operator. The empty state is necessary -// to handle the case where the copy construction fails after destroying the object. -// -// In some cases, we can completely avoid the use of an empty state; we provide a specialization of -// __copyable_box that does this, see below for the details. - -template<class _Tp> -concept __copy_constructible_object = copy_constructible<_Tp> && is_object_v<_Tp>; - -namespace ranges { - // Primary template - uses std::optional and introduces an empty state in case assignment fails. - template<__copy_constructible_object _Tp> - class __copyable_box { - _LIBCPP_NO_UNIQUE_ADDRESS optional<_Tp> __val_; - - public: - template<class ..._Args> - requires is_constructible_v<_Tp, _Args...> - _LIBCPP_HIDE_FROM_ABI - constexpr explicit __copyable_box(in_place_t, _Args&& ...__args) - noexcept(is_nothrow_constructible_v<_Tp, _Args...>) - : __val_(in_place, std::forward<_Args>(__args)...) - { } - - _LIBCPP_HIDE_FROM_ABI - constexpr __copyable_box() noexcept(is_nothrow_default_constructible_v<_Tp>) - requires default_initializable<_Tp> - : __val_(in_place) - { } - - _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box const&) = default; - _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box&&) = default; - - _LIBCPP_HIDE_FROM_ABI - constexpr __copyable_box& operator=(__copyable_box const& __other) - noexcept(is_nothrow_copy_constructible_v<_Tp>) - { - if (this != std::addressof(__other)) { - if (__other.__has_value()) __val_.emplace(*__other); - else __val_.reset(); - } - return *this; - } - - _LIBCPP_HIDE_FROM_ABI - __copyable_box& operator=(__copyable_box&&) requires movable<_Tp> = default; - - _LIBCPP_HIDE_FROM_ABI - constexpr __copyable_box& operator=(__copyable_box&& __other) - noexcept(is_nothrow_move_constructible_v<_Tp>) - { - if (this != std::addressof(__other)) { - if (__other.__has_value()) __val_.emplace(std::move(*__other)); - else __val_.reset(); - } - return *this; - } - - _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return *__val_; } - _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return *__val_; } - - _LIBCPP_HIDE_FROM_ABI constexpr const _Tp *operator->() const noexcept { return __val_.operator->(); } - _LIBCPP_HIDE_FROM_ABI constexpr _Tp *operator->() noexcept { return __val_.operator->(); } - - _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return __val_.has_value(); } - }; - - // This partial specialization implements an optimization for when we know we don't need to store - // an empty state to represent failure to perform an assignment. For copy-assignment, this happens: - // - // 1. If the type is copyable (which includes copy-assignment), we can use the type's own assignment operator - // directly and avoid using std::optional. - // 2. If the type is not copyable, but it is nothrow-copy-constructible, then we can implement assignment as - // destroy-and-then-construct and we know it will never fail, so we don't need an empty state. - // - // The exact same reasoning can be applied for move-assignment, with copyable replaced by movable and - // nothrow-copy-constructible replaced by nothrow-move-constructible. This specialization is enabled - // whenever we can apply any of these optimizations for both the copy assignment and the move assignment - // operator. - template<class _Tp> - concept __doesnt_need_empty_state_for_copy = copyable<_Tp> || is_nothrow_copy_constructible_v<_Tp>; - - template<class _Tp> - concept __doesnt_need_empty_state_for_move = movable<_Tp> || is_nothrow_move_constructible_v<_Tp>; - - template<__copy_constructible_object _Tp> - requires __doesnt_need_empty_state_for_copy<_Tp> && __doesnt_need_empty_state_for_move<_Tp> - class __copyable_box<_Tp> { - _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_; - - public: - template<class ..._Args> - requires is_constructible_v<_Tp, _Args...> - _LIBCPP_HIDE_FROM_ABI - constexpr explicit __copyable_box(in_place_t, _Args&& ...__args) - noexcept(is_nothrow_constructible_v<_Tp, _Args...>) - : __val_(std::forward<_Args>(__args)...) - { } - - _LIBCPP_HIDE_FROM_ABI - constexpr __copyable_box() noexcept(is_nothrow_default_constructible_v<_Tp>) - requires default_initializable<_Tp> - : __val_() - { } - - _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box const&) = default; - _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box&&) = default; - - // Implementation of assignment operators in case we perform optimization (1) - _LIBCPP_HIDE_FROM_ABI __copyable_box& operator=(__copyable_box const&) requires copyable<_Tp> = default; - _LIBCPP_HIDE_FROM_ABI __copyable_box& operator=(__copyable_box&&) requires movable<_Tp> = default; - - // Implementation of assignment operators in case we perform optimization (2) - _LIBCPP_HIDE_FROM_ABI - constexpr __copyable_box& operator=(__copyable_box const& __other) noexcept { - static_assert(is_nothrow_copy_constructible_v<_Tp>); - if (this != std::addressof(__other)) { - std::destroy_at(std::addressof(__val_)); - std::construct_at(std::addressof(__val_), __other.__val_); - } - return *this; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __copyable_box& operator=(__copyable_box&& __other) noexcept { - static_assert(is_nothrow_move_constructible_v<_Tp>); - if (this != std::addressof(__other)) { - std::destroy_at(std::addressof(__val_)); - std::construct_at(std::addressof(__val_), std::move(__other.__val_)); - } - return *this; - } - - _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return __val_; } - _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return __val_; } - - _LIBCPP_HIDE_FROM_ABI constexpr const _Tp *operator->() const noexcept { return std::addressof(__val_); } - _LIBCPP_HIDE_FROM_ABI constexpr _Tp *operator->() noexcept { return std::addressof(__val_); } - - _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return true; } - }; -} // namespace ranges - -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___RANGES_COPYABLE_BOX_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/counted.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/counted.h deleted file mode 100644 index 0a2d828578..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/counted.h +++ /dev/null @@ -1,81 +0,0 @@ -// -*- 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___RANGES_COUNTED_H -#define _LIBCPP___RANGES_COUNTED_H - -#include <__concepts/convertible_to.h> -#include <__config> -#include <__iterator/concepts.h> -#include <__iterator/counted_iterator.h> -#include <__iterator/default_sentinel.h> -#include <__iterator/incrementable_traits.h> -#include <__iterator/iterator_traits.h> -#include <__memory/pointer_traits.h> -#include <__ranges/subrange.h> -#include <__utility/forward.h> -#include <__utility/move.h> -#include <span> -#include <type_traits> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -namespace ranges::views { - -namespace __counted { - - struct __fn { - template<contiguous_iterator _It> - _LIBCPP_HIDE_FROM_ABI - static constexpr auto __go(_It __it, iter_difference_t<_It> __count) - noexcept(noexcept(span(std::to_address(__it), static_cast<size_t>(__count)))) - // Deliberately omit return-type SFINAE, because to_address is not SFINAE-friendly - { return span(std::to_address(__it), static_cast<size_t>(__count)); } - - template<random_access_iterator _It> - _LIBCPP_HIDE_FROM_ABI - static constexpr auto __go(_It __it, iter_difference_t<_It> __count) - noexcept(noexcept(subrange(__it, __it + __count))) - -> decltype( subrange(__it, __it + __count)) - { return subrange(__it, __it + __count); } - - template<class _It> - _LIBCPP_HIDE_FROM_ABI - static constexpr auto __go(_It __it, iter_difference_t<_It> __count) - noexcept(noexcept(subrange(counted_iterator(std::move(__it), __count), default_sentinel))) - -> decltype( subrange(counted_iterator(std::move(__it), __count), default_sentinel)) - { return subrange(counted_iterator(std::move(__it), __count), default_sentinel); } - - template<class _It, convertible_to<iter_difference_t<_It>> _Diff> - requires input_or_output_iterator<decay_t<_It>> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI - constexpr auto operator()(_It&& __it, _Diff&& __count) const - noexcept(noexcept(__go(std::forward<_It>(__it), std::forward<_Diff>(__count)))) - -> decltype( __go(std::forward<_It>(__it), std::forward<_Diff>(__count))) - { return __go(std::forward<_It>(__it), std::forward<_Diff>(__count)); } - }; - -} // namespace __counted - -inline namespace __cpo { - inline constexpr auto counted = __counted::__fn{}; -} // namespace __cpo - -} // namespace ranges::views - -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___RANGES_COUNTED_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/drop_view.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/drop_view.h deleted file mode 100644 index 079a74d4b8..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/drop_view.h +++ /dev/null @@ -1,127 +0,0 @@ -// -*- 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___RANGES_DROP_VIEW_H -#define _LIBCPP___RANGES_DROP_VIEW_H - -#include <__assert> -#include <__config> -#include <__iterator/concepts.h> -#include <__iterator/iterator_traits.h> -#include <__iterator/next.h> -#include <__ranges/access.h> -#include <__ranges/all.h> -#include <__ranges/concepts.h> -#include <__ranges/enable_borrowed_range.h> -#include <__ranges/non_propagating_cache.h> -#include <__ranges/size.h> -#include <__ranges/view_interface.h> -#include <__utility/move.h> -#include <concepts> -#include <type_traits> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -namespace ranges { - template<view _View> - class drop_view - : public view_interface<drop_view<_View>> - { - // We cache begin() whenever ranges::next is not guaranteed O(1) to provide an - // amortized O(1) begin() method. If this is an input_range, then we cannot cache - // begin because begin is not equality preserving. - // Note: drop_view<input-range>::begin() is still trivially amortized O(1) because - // one can't call begin() on it more than once. - static constexpr bool _UseCache = forward_range<_View> && !(random_access_range<_View> && sized_range<_View>); - using _Cache = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>; - _LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_ = _Cache(); - range_difference_t<_View> __count_ = 0; - _View __base_ = _View(); - -public: - drop_view() requires default_initializable<_View> = default; - - _LIBCPP_HIDE_FROM_ABI - constexpr drop_view(_View __base, range_difference_t<_View> __count) - : __count_(__count) - , __base_(std::move(__base)) - { - _LIBCPP_ASSERT(__count_ >= 0, "count must be greater than or equal to zero."); - } - - _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& requires copy_constructible<_View> { return __base_; } - _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto begin() - requires (!(__simple_view<_View> && - random_access_range<const _View> && sized_range<const _View>)) - { - if constexpr (_UseCache) - if (__cached_begin_.__has_value()) - return *__cached_begin_; - - auto __tmp = ranges::next(ranges::begin(__base_), __count_, ranges::end(__base_)); - if constexpr (_UseCache) - __cached_begin_.__emplace(__tmp); - return __tmp; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto begin() const - requires random_access_range<const _View> && sized_range<const _View> - { - return ranges::next(ranges::begin(__base_), __count_, ranges::end(__base_)); - } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto end() - requires (!__simple_view<_View>) - { return ranges::end(__base_); } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto end() const - requires range<const _View> - { return ranges::end(__base_); } - - _LIBCPP_HIDE_FROM_ABI - static constexpr auto __size(auto& __self) { - const auto __s = ranges::size(__self.__base_); - const auto __c = static_cast<decltype(__s)>(__self.__count_); - return __s < __c ? 0 : __s - __c; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto size() - requires sized_range<_View> - { return __size(*this); } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto size() const - requires sized_range<const _View> - { return __size(*this); } - }; - - template<class _Range> - drop_view(_Range&&, range_difference_t<_Range>) -> drop_view<views::all_t<_Range>>; - - template<class _Tp> - inline constexpr bool enable_borrowed_range<drop_view<_Tp>> = enable_borrowed_range<_Tp>; -} // namespace ranges - -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___RANGES_DROP_VIEW_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/empty.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/empty.h deleted file mode 100644 index c0b55b221a..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/empty.h +++ /dev/null @@ -1,82 +0,0 @@ -// -*- 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___RANGES_EMPTY_H -#define _LIBCPP___RANGES_EMPTY_H - -#include <__concepts/class_or_enum.h> -#include <__config> -#include <__iterator/concepts.h> -#include <__ranges/access.h> -#include <__ranges/size.h> -#include <type_traits> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -// [range.prim.empty] - -namespace ranges { -namespace __empty { - template <class _Tp> - concept __member_empty = - __workaround_52970<_Tp> && - requires(_Tp&& __t) { - bool(__t.empty()); - }; - - template<class _Tp> - concept __can_invoke_size = - !__member_empty<_Tp> && - requires(_Tp&& __t) { ranges::size(__t); }; - - template <class _Tp> - concept __can_compare_begin_end = - !__member_empty<_Tp> && - !__can_invoke_size<_Tp> && - requires(_Tp&& __t) { - bool(ranges::begin(__t) == ranges::end(__t)); - { ranges::begin(__t) } -> forward_iterator; - }; - - struct __fn { - template <__member_empty _Tp> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const - noexcept(noexcept(bool(__t.empty()))) { - return bool(__t.empty()); - } - - template <__can_invoke_size _Tp> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const - noexcept(noexcept(ranges::size(__t))) { - return ranges::size(__t) == 0; - } - - template<__can_compare_begin_end _Tp> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const - noexcept(noexcept(bool(ranges::begin(__t) == ranges::end(__t)))) { - return ranges::begin(__t) == ranges::end(__t); - } - }; -} // namespace __empty - -inline namespace __cpo { - inline constexpr auto empty = __empty::__fn{}; -} // namespace __cpo -} // namespace ranges - -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___RANGES_EMPTY_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/empty_view.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/empty_view.h deleted file mode 100644 index 6a08727678..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/empty_view.h +++ /dev/null @@ -1,45 +0,0 @@ -// -*- 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___RANGES_EMPTY_VIEW_H -#define _LIBCPP___RANGES_EMPTY_VIEW_H - -#include <__config> -#include <__ranges/enable_borrowed_range.h> -#include <__ranges/view_interface.h> -#include <type_traits> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -namespace ranges { - template<class _Tp> - requires is_object_v<_Tp> - class empty_view : public view_interface<empty_view<_Tp>> { - public: - _LIBCPP_HIDE_FROM_ABI static constexpr _Tp* begin() noexcept { return nullptr; } - _LIBCPP_HIDE_FROM_ABI static constexpr _Tp* end() noexcept { return nullptr; } - _LIBCPP_HIDE_FROM_ABI static constexpr _Tp* data() noexcept { return nullptr; } - _LIBCPP_HIDE_FROM_ABI static constexpr size_t size() noexcept { return 0; } - _LIBCPP_HIDE_FROM_ABI static constexpr bool empty() noexcept { return true; } - }; - - template<class _Tp> - inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true; -} // namespace ranges - -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___RANGES_EMPTY_VIEW_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/iota_view.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/iota_view.h deleted file mode 100644 index b7c099e049..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/iota_view.h +++ /dev/null @@ -1,408 +0,0 @@ -// -*- 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___RANGES_IOTA_VIEW_H -#define _LIBCPP___RANGES_IOTA_VIEW_H - -#include <__assert> -#include <__compare/three_way_comparable.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/invocable.h> -#include <__concepts/same_as.h> -#include <__concepts/semiregular.h> -#include <__concepts/totally_ordered.h> -#include <__config> -#include <__functional/ranges_operations.h> -#include <__iterator/concepts.h> -#include <__iterator/incrementable_traits.h> -#include <__iterator/iterator_traits.h> -#include <__iterator/unreachable_sentinel.h> -#include <__ranges/copyable_box.h> -#include <__ranges/enable_borrowed_range.h> -#include <__ranges/view_interface.h> -#include <__utility/forward.h> -#include <__utility/move.h> -#include <type_traits> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -namespace ranges { - template<class _Int> - struct __get_wider_signed { - static auto __call() { - if constexpr (sizeof(_Int) < sizeof(short)) return type_identity<short>{}; - else if constexpr (sizeof(_Int) < sizeof(int)) return type_identity<int>{}; - else if constexpr (sizeof(_Int) < sizeof(long)) return type_identity<long>{}; - else return type_identity<long long>{}; - - static_assert(sizeof(_Int) <= sizeof(long long), - "Found integer-like type that is bigger than largest integer like type."); - } - - using type = typename decltype(__call())::type; - }; - - template<class _Start> - using _IotaDiffT = typename _If< - (!integral<_Start> || sizeof(iter_difference_t<_Start>) > sizeof(_Start)), - type_identity<iter_difference_t<_Start>>, - __get_wider_signed<_Start> - >::type; - - template<class _Iter> - concept __decrementable = incrementable<_Iter> && requires(_Iter __i) { - { --__i } -> same_as<_Iter&>; - { __i-- } -> same_as<_Iter>; - }; - - template<class _Iter> - concept __advanceable = - __decrementable<_Iter> && totally_ordered<_Iter> && - requires(_Iter __i, const _Iter __j, const _IotaDiffT<_Iter> __n) { - { __i += __n } -> same_as<_Iter&>; - { __i -= __n } -> same_as<_Iter&>; - _Iter(__j + __n); - _Iter(__n + __j); - _Iter(__j - __n); - { __j - __j } -> convertible_to<_IotaDiffT<_Iter>>; - }; - - template<class> - struct __iota_iterator_category {}; - - template<incrementable _Tp> - struct __iota_iterator_category<_Tp> { - using iterator_category = input_iterator_tag; - }; - - template<weakly_incrementable _Start, semiregular _Bound = unreachable_sentinel_t> - requires __weakly_equality_comparable_with<_Start, _Bound> && copyable<_Start> - class iota_view : public view_interface<iota_view<_Start, _Bound>> { - struct __iterator : public __iota_iterator_category<_Start> { - friend class iota_view; - - using iterator_concept = - _If<__advanceable<_Start>, random_access_iterator_tag, - _If<__decrementable<_Start>, bidirectional_iterator_tag, - _If<incrementable<_Start>, forward_iterator_tag, - /*Else*/ input_iterator_tag>>>; - - using value_type = _Start; - using difference_type = _IotaDiffT<_Start>; - - _Start __value_ = _Start(); - - _LIBCPP_HIDE_FROM_ABI - __iterator() requires default_initializable<_Start> = default; - - _LIBCPP_HIDE_FROM_ABI - constexpr explicit __iterator(_Start __value) : __value_(std::move(__value)) {} - - _LIBCPP_HIDE_FROM_ABI - constexpr _Start operator*() const noexcept(is_nothrow_copy_constructible_v<_Start>) { - return __value_; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator& operator++() { - ++__value_; - return *this; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr void operator++(int) { ++*this; } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator operator++(int) requires incrementable<_Start> { - auto __tmp = *this; - ++*this; - return __tmp; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator& operator--() requires __decrementable<_Start> { - --__value_; - return *this; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator operator--(int) requires __decrementable<_Start> { - auto __tmp = *this; - --*this; - return __tmp; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator& operator+=(difference_type __n) - requires __advanceable<_Start> - { - if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) { - if (__n >= difference_type(0)) { - __value_ += static_cast<_Start>(__n); - } else { - __value_ -= static_cast<_Start>(-__n); - } - } else { - __value_ += __n; - } - return *this; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator& operator-=(difference_type __n) - requires __advanceable<_Start> - { - if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) { - if (__n >= difference_type(0)) { - __value_ -= static_cast<_Start>(__n); - } else { - __value_ += static_cast<_Start>(-__n); - } - } else { - __value_ -= __n; - } - return *this; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr _Start operator[](difference_type __n) const - requires __advanceable<_Start> - { - return _Start(__value_ + __n); - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) - requires equality_comparable<_Start> - { - return __x.__value_ == __y.__value_; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator<(const __iterator& __x, const __iterator& __y) - requires totally_ordered<_Start> - { - return __x.__value_ < __y.__value_; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator>(const __iterator& __x, const __iterator& __y) - requires totally_ordered<_Start> - { - return __y < __x; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y) - requires totally_ordered<_Start> - { - return !(__y < __x); - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y) - requires totally_ordered<_Start> - { - return !(__x < __y); - } - - friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y) - requires totally_ordered<_Start> && three_way_comparable<_Start> - { - return __x.__value_ <=> __y.__value_; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr __iterator operator+(__iterator __i, difference_type __n) - requires __advanceable<_Start> - { - __i += __n; - return __i; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr __iterator operator+(difference_type __n, __iterator __i) - requires __advanceable<_Start> - { - return __i + __n; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr __iterator operator-(__iterator __i, difference_type __n) - requires __advanceable<_Start> - { - __i -= __n; - return __i; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y) - requires __advanceable<_Start> - { - if constexpr (__integer_like<_Start>) { - if constexpr (__signed_integer_like<_Start>) { - return difference_type(difference_type(__x.__value_) - difference_type(__y.__value_)); - } - if (__y.__value_ > __x.__value_) { - return difference_type(-difference_type(__y.__value_ - __x.__value_)); - } - return difference_type(__x.__value_ - __y.__value_); - } - return __x.__value_ - __y.__value_; - } - }; - - struct __sentinel { - friend class iota_view; - - private: - _Bound __bound_ = _Bound(); - - public: - _LIBCPP_HIDE_FROM_ABI - __sentinel() = default; - constexpr explicit __sentinel(_Bound __bound) : __bound_(std::move(__bound)) {} - - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(const __iterator& __x, const __sentinel& __y) { - return __x.__value_ == __y.__bound_; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr iter_difference_t<_Start> operator-(const __iterator& __x, const __sentinel& __y) - requires sized_sentinel_for<_Bound, _Start> - { - return __x.__value_ - __y.__bound_; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr iter_difference_t<_Start> operator-(const __sentinel& __x, const __iterator& __y) - requires sized_sentinel_for<_Bound, _Start> - { - return -(__y - __x); - } - }; - - _Start __value_ = _Start(); - _Bound __bound_ = _Bound(); - - public: - _LIBCPP_HIDE_FROM_ABI - iota_view() requires default_initializable<_Start> = default; - - _LIBCPP_HIDE_FROM_ABI - constexpr explicit iota_view(_Start __value) : __value_(std::move(__value)) { } - - _LIBCPP_HIDE_FROM_ABI - constexpr iota_view(type_identity_t<_Start> __value, type_identity_t<_Bound> __bound) - : __value_(std::move(__value)), __bound_(std::move(__bound)) { - // Validate the precondition if possible. - if constexpr (totally_ordered_with<_Start, _Bound>) { - _LIBCPP_ASSERT(ranges::less_equal()(__value_, __bound_), - "Precondition violated: value is greater than bound."); - } - } - - _LIBCPP_HIDE_FROM_ABI - constexpr iota_view(__iterator __first, __iterator __last) - requires same_as<_Start, _Bound> - : iota_view(std::move(__first.__value_), std::move(__last.__value_)) {} - - _LIBCPP_HIDE_FROM_ABI - constexpr iota_view(__iterator __first, _Bound __last) - requires same_as<_Bound, unreachable_sentinel_t> - : iota_view(std::move(__first.__value_), std::move(__last)) {} - - _LIBCPP_HIDE_FROM_ABI - constexpr iota_view(__iterator __first, __sentinel __last) - requires (!same_as<_Start, _Bound> && !same_as<_Start, unreachable_sentinel_t>) - : iota_view(std::move(__first.__value_), std::move(__last.__bound_)) {} - - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator begin() const { return __iterator{__value_}; } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto end() const { - if constexpr (same_as<_Bound, unreachable_sentinel_t>) - return unreachable_sentinel; - else - return __sentinel{__bound_}; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator end() const requires same_as<_Start, _Bound> { - return __iterator{__bound_}; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto size() const - requires (same_as<_Start, _Bound> && __advanceable<_Start>) || - (integral<_Start> && integral<_Bound>) || - sized_sentinel_for<_Bound, _Start> - { - if constexpr (__integer_like<_Start> && __integer_like<_Bound>) { - if (__value_ < 0) { - if (__bound_ < 0) { - return std::__to_unsigned_like(-__value_) - std::__to_unsigned_like(-__bound_); - } - return std::__to_unsigned_like(__bound_) + std::__to_unsigned_like(-__value_); - } - return std::__to_unsigned_like(__bound_) - std::__to_unsigned_like(__value_); - } - return std::__to_unsigned_like(__bound_ - __value_); - } - }; - - template<class _Start, class _Bound> - requires (!__integer_like<_Start> || !__integer_like<_Bound> || - (__signed_integer_like<_Start> == __signed_integer_like<_Bound>)) - iota_view(_Start, _Bound) -> iota_view<_Start, _Bound>; - - template<class _Start, class _Bound> - inline constexpr bool enable_borrowed_range<iota_view<_Start, _Bound>> = true; - -namespace views { -namespace __iota { - struct __fn { - template<class _Start> - _LIBCPP_HIDE_FROM_ABI - constexpr auto operator()(_Start&& __start) const - noexcept(noexcept(ranges::iota_view(std::forward<_Start>(__start)))) - -> decltype( ranges::iota_view(std::forward<_Start>(__start))) - { return ranges::iota_view(std::forward<_Start>(__start)); } - - template<class _Start, class _Bound> - _LIBCPP_HIDE_FROM_ABI - constexpr auto operator()(_Start&& __start, _Bound&& __bound) const - noexcept(noexcept(ranges::iota_view(std::forward<_Start>(__start), std::forward<_Bound>(__bound)))) - -> decltype( ranges::iota_view(std::forward<_Start>(__start), std::forward<_Bound>(__bound))) - { return ranges::iota_view(std::forward<_Start>(__start), std::forward<_Bound>(__bound)); } - }; -} // namespace __iota - -inline namespace __cpo { - inline constexpr auto iota = __iota::__fn{}; -} // namespace __cpo -} // namespace views -} // namespace ranges - -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___RANGES_IOTA_VIEW_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/join_view.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/join_view.h deleted file mode 100644 index 395e5c7ece..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/join_view.h +++ /dev/null @@ -1,350 +0,0 @@ -// -*- 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___RANGES_JOIN_VIEW_H -#define _LIBCPP___RANGES_JOIN_VIEW_H - -#include <__config> -#include <__iterator/concepts.h> -#include <__iterator/iterator_traits.h> -#include <__ranges/access.h> -#include <__ranges/all.h> -#include <__ranges/concepts.h> -#include <__ranges/non_propagating_cache.h> -#include <__ranges/ref_view.h> -#include <__ranges/subrange.h> -#include <__ranges/view_interface.h> -#include <__utility/declval.h> -#include <__utility/forward.h> -#include <optional> -#include <type_traits> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -namespace ranges { - template<class> - struct __join_view_iterator_category {}; - - template<class _View> - requires is_reference_v<range_reference_t<_View>> && - forward_range<_View> && - forward_range<range_reference_t<_View>> - struct __join_view_iterator_category<_View> { - using _OuterC = typename iterator_traits<iterator_t<_View>>::iterator_category; - using _InnerC = typename iterator_traits<iterator_t<range_reference_t<_View>>>::iterator_category; - - using iterator_category = _If< - derived_from<_OuterC, bidirectional_iterator_tag> && derived_from<_InnerC, bidirectional_iterator_tag>, - bidirectional_iterator_tag, - _If< - derived_from<_OuterC, forward_iterator_tag> && derived_from<_InnerC, forward_iterator_tag>, - forward_iterator_tag, - input_iterator_tag - > - >; - }; - - template<input_range _View> - requires view<_View> && input_range<range_reference_t<_View>> - class join_view - : public view_interface<join_view<_View>> { - private: - using _InnerRange = range_reference_t<_View>; - - template<bool> struct __iterator; - template<bool> struct __sentinel; - - static constexpr bool _UseCache = !is_reference_v<_InnerRange>; - using _Cache = _If<_UseCache, __non_propagating_cache<remove_cvref_t<_InnerRange>>, __empty_cache>; - _LIBCPP_NO_UNIQUE_ADDRESS _Cache __cache_; - _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); - - public: - _LIBCPP_HIDE_FROM_ABI - join_view() requires default_initializable<_View> = default; - - _LIBCPP_HIDE_FROM_ABI - constexpr explicit join_view(_View __base) - : __base_(std::move(__base)) {} - - _LIBCPP_HIDE_FROM_ABI - constexpr _View base() const& requires copy_constructible<_View> { return __base_; } - - _LIBCPP_HIDE_FROM_ABI - constexpr _View base() && { return std::move(__base_); } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto begin() { - constexpr bool __use_const = __simple_view<_View> && - is_reference_v<range_reference_t<_View>>; - return __iterator<__use_const>{*this, ranges::begin(__base_)}; - } - - template<class _V2 = _View> - _LIBCPP_HIDE_FROM_ABI - constexpr auto begin() const - requires input_range<const _V2> && - is_reference_v<range_reference_t<const _V2>> - { - return __iterator<true>{*this, ranges::begin(__base_)}; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto end() { - if constexpr (forward_range<_View> && - is_reference_v<_InnerRange> && - forward_range<_InnerRange> && - common_range<_View> && - common_range<_InnerRange>) - return __iterator<__simple_view<_View>>{*this, ranges::end(__base_)}; - else - return __sentinel<__simple_view<_View>>{*this}; - } - - template<class _V2 = _View> - _LIBCPP_HIDE_FROM_ABI - constexpr auto end() const - requires input_range<const _V2> && - is_reference_v<range_reference_t<const _V2>> - { - using _ConstInnerRange = range_reference_t<const _View>; - if constexpr (forward_range<const _View> && - is_reference_v<_ConstInnerRange> && - forward_range<_ConstInnerRange> && - common_range<const _View> && - common_range<_ConstInnerRange>) { - return __iterator<true>{*this, ranges::end(__base_)}; - } else { - return __sentinel<true>{*this}; - } - } - }; - - template<input_range _View> - requires view<_View> && input_range<range_reference_t<_View>> - template<bool _Const> struct join_view<_View>::__sentinel { - template<bool> friend struct __sentinel; - - private: - using _Parent = __maybe_const<_Const, join_view>; - using _Base = __maybe_const<_Const, _View>; - sentinel_t<_Base> __end_ = sentinel_t<_Base>(); - - public: - _LIBCPP_HIDE_FROM_ABI - __sentinel() = default; - - _LIBCPP_HIDE_FROM_ABI - constexpr explicit __sentinel(_Parent& __parent) - : __end_(ranges::end(__parent.__base_)) {} - - _LIBCPP_HIDE_FROM_ABI - constexpr __sentinel(__sentinel<!_Const> __s) - requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>> - : __end_(std::move(__s.__end_)) {} - - template<bool _OtherConst> - requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>> - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) { - return __x.__outer_ == __y.__end_; - } - }; - - template<input_range _View> - requires view<_View> && input_range<range_reference_t<_View>> - template<bool _Const> struct join_view<_View>::__iterator - : public __join_view_iterator_category<__maybe_const<_Const, _View>> { - - template<bool> friend struct __iterator; - - private: - using _Parent = __maybe_const<_Const, join_view>; - using _Base = __maybe_const<_Const, _View>; - using _Outer = iterator_t<_Base>; - using _Inner = iterator_t<range_reference_t<_Base>>; - - static constexpr bool __ref_is_glvalue = is_reference_v<range_reference_t<_Base>>; - - public: - _Outer __outer_ = _Outer(); - - private: - optional<_Inner> __inner_; - _Parent *__parent_ = nullptr; - - _LIBCPP_HIDE_FROM_ABI - constexpr void __satisfy() { - for (; __outer_ != ranges::end(__parent_->__base_); ++__outer_) { - auto&& __inner = [&]() -> auto&& { - if constexpr (__ref_is_glvalue) - return *__outer_; - else - return __parent_->__cache_.__emplace_from([&]() -> decltype(auto) { return *__outer_; }); - }(); - __inner_ = ranges::begin(__inner); - if (*__inner_ != ranges::end(__inner)) - return; - } - - if constexpr (__ref_is_glvalue) - __inner_.reset(); - } - - public: - using iterator_concept = _If< - __ref_is_glvalue && bidirectional_range<_Base> && bidirectional_range<range_reference_t<_Base>>, - bidirectional_iterator_tag, - _If< - __ref_is_glvalue && forward_range<_Base> && forward_range<range_reference_t<_Base>>, - forward_iterator_tag, - input_iterator_tag - > - >; - - using value_type = range_value_t<range_reference_t<_Base>>; - - using difference_type = common_type_t< - range_difference_t<_Base>, range_difference_t<range_reference_t<_Base>>>; - - _LIBCPP_HIDE_FROM_ABI - __iterator() requires default_initializable<_Outer> = default; - - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator(_Parent& __parent, _Outer __outer) - : __outer_(std::move(__outer)) - , __parent_(std::addressof(__parent)) { - __satisfy(); - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator(__iterator<!_Const> __i) - requires _Const && - convertible_to<iterator_t<_View>, _Outer> && - convertible_to<iterator_t<_InnerRange>, _Inner> - : __outer_(std::move(__i.__outer_)) - , __inner_(std::move(__i.__inner_)) - , __parent_(__i.__parent_) {} - - _LIBCPP_HIDE_FROM_ABI - constexpr decltype(auto) operator*() const { - return **__inner_; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr _Inner operator->() const - requires __has_arrow<_Inner> && copyable<_Inner> - { - return *__inner_; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator& operator++() { - auto&& __inner = [&]() -> auto&& { - if constexpr (__ref_is_glvalue) - return *__outer_; - else - return *__parent_->__cache_; - }(); - if (++*__inner_ == ranges::end(__inner)) { - ++__outer_; - __satisfy(); - } - return *this; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr void operator++(int) { - ++*this; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator operator++(int) - requires __ref_is_glvalue && - forward_range<_Base> && - forward_range<range_reference_t<_Base>> - { - auto __tmp = *this; - ++*this; - return __tmp; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator& operator--() - requires __ref_is_glvalue && - bidirectional_range<_Base> && - bidirectional_range<range_reference_t<_Base>> && - common_range<range_reference_t<_Base>> - { - if (__outer_ == ranges::end(__parent_->__base_)) - __inner_ = ranges::end(*--__outer_); - - // Skip empty inner ranges when going backwards. - while (*__inner_ == ranges::begin(*__outer_)) { - __inner_ = ranges::end(*--__outer_); - } - - --*__inner_; - return *this; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator operator--(int) - requires __ref_is_glvalue && - bidirectional_range<_Base> && - bidirectional_range<range_reference_t<_Base>> && - common_range<range_reference_t<_Base>> - { - auto __tmp = *this; - --*this; - return __tmp; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) - requires __ref_is_glvalue && - equality_comparable<iterator_t<_Base>> && - equality_comparable<iterator_t<range_reference_t<_Base>>> - { - return __x.__outer_ == __y.__outer_ && __x.__inner_ == __y.__inner_; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr decltype(auto) iter_move(const __iterator& __i) - noexcept(noexcept(ranges::iter_move(*__i.__inner_))) - { - return ranges::iter_move(*__i.__inner_); - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr void iter_swap(const __iterator& __x, const __iterator& __y) - noexcept(noexcept(ranges::iter_swap(*__x.__inner_, *__y.__inner_))) - requires indirectly_swappable<_Inner> - { - return ranges::iter_swap(*__x.__inner_, *__y.__inner_); - } - }; - - template<class _Range> - explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>; - -} // namespace ranges - -#undef _CONSTEXPR_TERNARY - -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___RANGES_JOIN_VIEW_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/non_propagating_cache.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/non_propagating_cache.h deleted file mode 100644 index d9589ae46c..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/non_propagating_cache.h +++ /dev/null @@ -1,114 +0,0 @@ -// -*- 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___RANGES_NON_PROPAGATING_CACHE_H -#define _LIBCPP___RANGES_NON_PROPAGATING_CACHE_H - -#include <__config> -#include <__iterator/concepts.h> // indirectly_readable -#include <__iterator/iterator_traits.h> // iter_reference_t -#include <__memory/addressof.h> -#include <__utility/forward.h> -#include <concepts> // constructible_from -#include <optional> -#include <type_traits> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -namespace ranges { - // __non_propagating_cache is a helper type that allows storing an optional value in it, - // but which does not copy the source's value when it is copy constructed/assigned to, - // and which resets the source's value when it is moved-from. - // - // This type is used as an implementation detail of some views that need to cache the - // result of `begin()` in order to provide an amortized O(1) begin() method. Typically, - // we don't want to propagate the value of the cache upon copy because the cached iterator - // may refer to internal details of the source view. - template<class _Tp> - requires is_object_v<_Tp> - class _LIBCPP_TEMPLATE_VIS __non_propagating_cache { - struct __from_tag { }; - struct __forward_tag { }; - - // This helper class is needed to perform copy and move elision when - // constructing the contained type from an iterator. - struct __wrapper { - template<class ..._Args> - constexpr explicit __wrapper(__forward_tag, _Args&& ...__args) : __t_(std::forward<_Args>(__args)...) { } - template<class _Fn> - constexpr explicit __wrapper(__from_tag, _Fn const& __f) : __t_(__f()) { } - _Tp __t_; - }; - - optional<__wrapper> __value_ = nullopt; - - public: - _LIBCPP_HIDE_FROM_ABI __non_propagating_cache() = default; - - _LIBCPP_HIDE_FROM_ABI - constexpr __non_propagating_cache(__non_propagating_cache const&) noexcept - : __value_(nullopt) - { } - - _LIBCPP_HIDE_FROM_ABI - constexpr __non_propagating_cache(__non_propagating_cache&& __other) noexcept - : __value_(nullopt) - { - __other.__value_.reset(); - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __non_propagating_cache& operator=(__non_propagating_cache const& __other) noexcept { - if (this != std::addressof(__other)) { - __value_.reset(); - } - return *this; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __non_propagating_cache& operator=(__non_propagating_cache&& __other) noexcept { - __value_.reset(); - __other.__value_.reset(); - return *this; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr _Tp& operator*() { return __value_->__t_; } - _LIBCPP_HIDE_FROM_ABI - constexpr _Tp const& operator*() const { return __value_->__t_; } - - _LIBCPP_HIDE_FROM_ABI - constexpr bool __has_value() const { return __value_.has_value(); } - - template<class _Fn> - _LIBCPP_HIDE_FROM_ABI - constexpr _Tp& __emplace_from(_Fn const& __f) { - return __value_.emplace(__from_tag{}, __f).__t_; - } - - template<class ..._Args> - _LIBCPP_HIDE_FROM_ABI - constexpr _Tp& __emplace(_Args&& ...__args) { - return __value_.emplace(__forward_tag{}, std::forward<_Args>(__args)...).__t_; - } - }; - - struct __empty_cache { }; -} // namespace ranges - -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___RANGES_NON_PROPAGATING_CACHE_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/owning_view.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/owning_view.h deleted file mode 100644 index 7987c60751..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/owning_view.h +++ /dev/null @@ -1,81 +0,0 @@ -// -*- 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___RANGES_OWNING_VIEW_H -#define _LIBCPP___RANGES_OWNING_VIEW_H - -#include <__concepts/constructible.h> -#include <__concepts/movable.h> -#include <__config> -#include <__ranges/access.h> -#include <__ranges/concepts.h> -#include <__ranges/data.h> -#include <__ranges/empty.h> -#include <__ranges/enable_borrowed_range.h> -#include <__ranges/size.h> -#include <__ranges/view_interface.h> -#include <__utility/move.h> -#include <type_traits> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -namespace ranges { - template<range _Rp> - requires movable<_Rp> && (!__is_std_initializer_list<remove_cvref_t<_Rp>>) - class owning_view : public view_interface<owning_view<_Rp>> { - _Rp __r_ = _Rp(); - -public: - owning_view() requires default_initializable<_Rp> = default; - _LIBCPP_HIDE_FROM_ABI constexpr owning_view(_Rp&& __r) : __r_(std::move(__r)) {} - - owning_view(owning_view&&) = default; - owning_view& operator=(owning_view&&) = default; - - _LIBCPP_HIDE_FROM_ABI constexpr _Rp& base() & noexcept { return __r_; } - _LIBCPP_HIDE_FROM_ABI constexpr const _Rp& base() const& noexcept { return __r_; } - _LIBCPP_HIDE_FROM_ABI constexpr _Rp&& base() && noexcept { return std::move(__r_); } - _LIBCPP_HIDE_FROM_ABI constexpr const _Rp&& base() const&& noexcept { return std::move(__r_); } - - _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Rp> begin() { return ranges::begin(__r_); } - _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Rp> end() { return ranges::end(__r_); } - _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const requires range<const _Rp> { return ranges::begin(__r_); } - _LIBCPP_HIDE_FROM_ABI constexpr auto end() const requires range<const _Rp> { return ranges::end(__r_); } - - _LIBCPP_HIDE_FROM_ABI constexpr bool empty() requires requires { ranges::empty(__r_); } - { return ranges::empty(__r_); } - _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const requires requires { ranges::empty(__r_); } - { return ranges::empty(__r_); } - - _LIBCPP_HIDE_FROM_ABI constexpr auto size() requires sized_range<_Rp> - { return ranges::size(__r_); } - _LIBCPP_HIDE_FROM_ABI constexpr auto size() const requires sized_range<const _Rp> - { return ranges::size(__r_); } - - _LIBCPP_HIDE_FROM_ABI constexpr auto data() requires contiguous_range<_Rp> - { return ranges::data(__r_); } - _LIBCPP_HIDE_FROM_ABI constexpr auto data() const requires contiguous_range<const _Rp> - { return ranges::data(__r_); } - }; - - template<class _Tp> - inline constexpr bool enable_borrowed_range<owning_view<_Tp>> = enable_borrowed_range<_Tp>; - -} // namespace ranges - -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___RANGES_OWNING_VIEW_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/range_adaptor.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/range_adaptor.h deleted file mode 100644 index 9c53488ba6..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/range_adaptor.h +++ /dev/null @@ -1,73 +0,0 @@ -// -*- 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___RANGES_RANGE_ADAPTOR_H -#define _LIBCPP___RANGES_RANGE_ADAPTOR_H - -#include <__config> -#include <__functional/compose.h> -#include <__functional/invoke.h> -#include <__ranges/concepts.h> -#include <__utility/forward.h> -#include <__utility/move.h> -#include <concepts> -#include <type_traits> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -// CRTP base that one can derive from in order to be considered a range adaptor closure -// by the library. When deriving from this class, a pipe operator will be provided to -// make the following hold: -// - `x | f` is equivalent to `f(x)` -// - `f1 | f2` is an adaptor closure `g` such that `g(x)` is equivalent to `f2(f1(x))` -template <class _Tp> -struct __range_adaptor_closure; - -// Type that wraps an arbitrary function object and makes it into a range adaptor closure, -// i.e. something that can be called via the `x | f` notation. -template <class _Fn> -struct __range_adaptor_closure_t : _Fn, __range_adaptor_closure<__range_adaptor_closure_t<_Fn>> { - constexpr explicit __range_adaptor_closure_t(_Fn&& __f) : _Fn(std::move(__f)) { } -}; - -template <class _Tp> -concept _RangeAdaptorClosure = derived_from<remove_cvref_t<_Tp>, __range_adaptor_closure<remove_cvref_t<_Tp>>>; - -template <class _Tp> -struct __range_adaptor_closure { - template <ranges::viewable_range _View, _RangeAdaptorClosure _Closure> - requires same_as<_Tp, remove_cvref_t<_Closure>> && - invocable<_Closure, _View> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI - friend constexpr decltype(auto) operator|(_View&& __view, _Closure&& __closure) - noexcept(is_nothrow_invocable_v<_Closure, _View>) - { return std::invoke(std::forward<_Closure>(__closure), std::forward<_View>(__view)); } - - template <_RangeAdaptorClosure _Closure, _RangeAdaptorClosure _OtherClosure> - requires same_as<_Tp, remove_cvref_t<_Closure>> && - constructible_from<decay_t<_Closure>, _Closure> && - constructible_from<decay_t<_OtherClosure>, _OtherClosure> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI - friend constexpr auto operator|(_Closure&& __c1, _OtherClosure&& __c2) - noexcept(is_nothrow_constructible_v<decay_t<_Closure>, _Closure> && - is_nothrow_constructible_v<decay_t<_OtherClosure>, _OtherClosure>) - { return __range_adaptor_closure_t(std::__compose(std::forward<_OtherClosure>(__c2), std::forward<_Closure>(__c1))); } -}; - -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___RANGES_RANGE_ADAPTOR_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/rbegin.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/rbegin.h deleted file mode 100644 index 20f5489c50..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/rbegin.h +++ /dev/null @@ -1,130 +0,0 @@ -// -*- 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___RANGES_RBEGIN_H -#define _LIBCPP___RANGES_RBEGIN_H - -#include <__concepts/class_or_enum.h> -#include <__concepts/same_as.h> -#include <__config> -#include <__iterator/concepts.h> -#include <__iterator/readable_traits.h> -#include <__iterator/reverse_iterator.h> -#include <__ranges/access.h> -#include <__utility/auto_cast.h> -#include <type_traits> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -// [ranges.access.rbegin] - -namespace ranges { -namespace __rbegin { -template <class _Tp> -concept __member_rbegin = - __can_borrow<_Tp> && - __workaround_52970<_Tp> && - requires(_Tp&& __t) { - { _LIBCPP_AUTO_CAST(__t.rbegin()) } -> input_or_output_iterator; - }; - -void rbegin(auto&) = delete; -void rbegin(const auto&) = delete; - -template <class _Tp> -concept __unqualified_rbegin = - !__member_rbegin<_Tp> && - __can_borrow<_Tp> && - __class_or_enum<remove_cvref_t<_Tp>> && - requires(_Tp&& __t) { - { _LIBCPP_AUTO_CAST(rbegin(__t)) } -> input_or_output_iterator; - }; - -template <class _Tp> -concept __can_reverse = - __can_borrow<_Tp> && - !__member_rbegin<_Tp> && - !__unqualified_rbegin<_Tp> && - requires(_Tp&& __t) { - { ranges::begin(__t) } -> same_as<decltype(ranges::end(__t))>; - { ranges::begin(__t) } -> bidirectional_iterator; - }; - -struct __fn { - template <class _Tp> - requires __member_rbegin<_Tp> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const - noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.rbegin()))) - { - return _LIBCPP_AUTO_CAST(__t.rbegin()); - } - - template <class _Tp> - requires __unqualified_rbegin<_Tp> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const - noexcept(noexcept(_LIBCPP_AUTO_CAST(rbegin(__t)))) - { - return _LIBCPP_AUTO_CAST(rbegin(__t)); - } - - template <class _Tp> - requires __can_reverse<_Tp> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const - noexcept(noexcept(ranges::end(__t))) - { - return std::make_reverse_iterator(ranges::end(__t)); - } - - void operator()(auto&&) const = delete; -}; -} // namespace __rbegin - -inline namespace __cpo { - inline constexpr auto rbegin = __rbegin::__fn{}; -} // namespace __cpo -} // namespace ranges - -// [range.access.crbegin] - -namespace ranges { -namespace __crbegin { -struct __fn { - template <class _Tp> - requires is_lvalue_reference_v<_Tp&&> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI - constexpr auto operator()(_Tp&& __t) const - noexcept(noexcept(ranges::rbegin(static_cast<const remove_reference_t<_Tp>&>(__t)))) - -> decltype( ranges::rbegin(static_cast<const remove_reference_t<_Tp>&>(__t))) - { return ranges::rbegin(static_cast<const remove_reference_t<_Tp>&>(__t)); } - - template <class _Tp> - requires is_rvalue_reference_v<_Tp&&> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI - constexpr auto operator()(_Tp&& __t) const - noexcept(noexcept(ranges::rbegin(static_cast<const _Tp&&>(__t)))) - -> decltype( ranges::rbegin(static_cast<const _Tp&&>(__t))) - { return ranges::rbegin(static_cast<const _Tp&&>(__t)); } -}; -} // namespace __crbegin - -inline namespace __cpo { - inline constexpr auto crbegin = __crbegin::__fn{}; -} // namespace __cpo -} // namespace ranges - -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___RANGES_RBEGIN_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/ref_view.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/ref_view.h deleted file mode 100644 index 255a468606..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/ref_view.h +++ /dev/null @@ -1,86 +0,0 @@ -// -*- 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___RANGES_REF_VIEW_H -#define _LIBCPP___RANGES_REF_VIEW_H - -#include <__config> -#include <__iterator/concepts.h> -#include <__iterator/incrementable_traits.h> -#include <__iterator/iterator_traits.h> -#include <__memory/addressof.h> -#include <__ranges/access.h> -#include <__ranges/concepts.h> -#include <__ranges/data.h> -#include <__ranges/empty.h> -#include <__ranges/enable_borrowed_range.h> -#include <__ranges/size.h> -#include <__ranges/view_interface.h> -#include <__utility/forward.h> -#include <concepts> -#include <type_traits> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -namespace ranges { - template<range _Range> - requires is_object_v<_Range> - class ref_view : public view_interface<ref_view<_Range>> { - _Range *__range_; - - static void __fun(_Range&); - static void __fun(_Range&&) = delete; - -public: - template<class _Tp> - requires __different_from<_Tp, ref_view> && - convertible_to<_Tp, _Range&> && requires { __fun(declval<_Tp>()); } - _LIBCPP_HIDE_FROM_ABI - constexpr ref_view(_Tp&& __t) - : __range_(std::addressof(static_cast<_Range&>(std::forward<_Tp>(__t)))) - {} - - _LIBCPP_HIDE_FROM_ABI constexpr _Range& base() const { return *__range_; } - - _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Range> begin() const { return ranges::begin(*__range_); } - _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Range> end() const { return ranges::end(*__range_); } - - _LIBCPP_HIDE_FROM_ABI - constexpr bool empty() const - requires requires { ranges::empty(*__range_); } - { return ranges::empty(*__range_); } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto size() const - requires sized_range<_Range> - { return ranges::size(*__range_); } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto data() const - requires contiguous_range<_Range> - { return ranges::data(*__range_); } - }; - - template<class _Range> - ref_view(_Range&) -> ref_view<_Range>; - - template<class _Tp> - inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true; -} // namespace ranges - -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___RANGES_REF_VIEW_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/rend.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/rend.h deleted file mode 100644 index 4f1597e073..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/rend.h +++ /dev/null @@ -1,134 +0,0 @@ -// -*- 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___RANGES_REND_H -#define _LIBCPP___RANGES_REND_H - -#include <__concepts/class_or_enum.h> -#include <__concepts/same_as.h> -#include <__config> -#include <__iterator/concepts.h> -#include <__iterator/readable_traits.h> -#include <__iterator/reverse_iterator.h> -#include <__ranges/access.h> -#include <__ranges/rbegin.h> -#include <__utility/auto_cast.h> -#include <type_traits> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -// [range.access.rend] - -namespace ranges { -namespace __rend { -template <class _Tp> -concept __member_rend = - __can_borrow<_Tp> && - __workaround_52970<_Tp> && - requires(_Tp&& __t) { - ranges::rbegin(__t); - { _LIBCPP_AUTO_CAST(__t.rend()) } -> sentinel_for<decltype(ranges::rbegin(__t))>; - }; - -void rend(auto&) = delete; -void rend(const auto&) = delete; - -template <class _Tp> -concept __unqualified_rend = - !__member_rend<_Tp> && - __can_borrow<_Tp> && - __class_or_enum<remove_cvref_t<_Tp>> && - requires(_Tp&& __t) { - ranges::rbegin(__t); - { _LIBCPP_AUTO_CAST(rend(__t)) } -> sentinel_for<decltype(ranges::rbegin(__t))>; - }; - -template <class _Tp> -concept __can_reverse = - __can_borrow<_Tp> && - !__member_rend<_Tp> && - !__unqualified_rend<_Tp> && - requires(_Tp&& __t) { - { ranges::begin(__t) } -> same_as<decltype(ranges::end(__t))>; - { ranges::begin(__t) } -> bidirectional_iterator; - }; - -class __fn { -public: - template <class _Tp> - requires __member_rend<_Tp> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const - noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.rend()))) - { - return _LIBCPP_AUTO_CAST(__t.rend()); - } - - template <class _Tp> - requires __unqualified_rend<_Tp> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const - noexcept(noexcept(_LIBCPP_AUTO_CAST(rend(__t)))) - { - return _LIBCPP_AUTO_CAST(rend(__t)); - } - - template <class _Tp> - requires __can_reverse<_Tp> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const - noexcept(noexcept(ranges::begin(__t))) - { - return std::make_reverse_iterator(ranges::begin(__t)); - } - - void operator()(auto&&) const = delete; -}; -} // namespace __rend - -inline namespace __cpo { - inline constexpr auto rend = __rend::__fn{}; -} // namespace __cpo -} // namespace ranges - -// [range.access.crend] - -namespace ranges { -namespace __crend { -struct __fn { - template <class _Tp> - requires is_lvalue_reference_v<_Tp&&> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI - constexpr auto operator()(_Tp&& __t) const - noexcept(noexcept(ranges::rend(static_cast<const remove_reference_t<_Tp>&>(__t)))) - -> decltype( ranges::rend(static_cast<const remove_reference_t<_Tp>&>(__t))) - { return ranges::rend(static_cast<const remove_reference_t<_Tp>&>(__t)); } - - template <class _Tp> - requires is_rvalue_reference_v<_Tp&&> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI - constexpr auto operator()(_Tp&& __t) const - noexcept(noexcept(ranges::rend(static_cast<const _Tp&&>(__t)))) - -> decltype( ranges::rend(static_cast<const _Tp&&>(__t))) - { return ranges::rend(static_cast<const _Tp&&>(__t)); } -}; -} // namespace __crend - -inline namespace __cpo { - inline constexpr auto crend = __crend::__fn{}; -} // namespace __cpo -} // namespace ranges - -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___RANGES_REND_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/reverse_view.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/reverse_view.h deleted file mode 100644 index c3ab6261f0..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/reverse_view.h +++ /dev/null @@ -1,190 +0,0 @@ -// -*- 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___RANGES_REVERSE_VIEW_H -#define _LIBCPP___RANGES_REVERSE_VIEW_H - -#include <__concepts/constructible.h> -#include <__config> -#include <__iterator/concepts.h> -#include <__iterator/next.h> -#include <__iterator/reverse_iterator.h> -#include <__ranges/access.h> -#include <__ranges/all.h> -#include <__ranges/concepts.h> -#include <__ranges/enable_borrowed_range.h> -#include <__ranges/non_propagating_cache.h> -#include <__ranges/range_adaptor.h> -#include <__ranges/size.h> -#include <__ranges/subrange.h> -#include <__ranges/view_interface.h> -#include <__utility/forward.h> -#include <__utility/move.h> -#include <type_traits> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -namespace ranges { - template<view _View> - requires bidirectional_range<_View> - class reverse_view : public view_interface<reverse_view<_View>> { - // We cache begin() whenever ranges::next is not guaranteed O(1) to provide an - // amortized O(1) begin() method. - static constexpr bool _UseCache = !random_access_range<_View> && !common_range<_View>; - using _Cache = _If<_UseCache, __non_propagating_cache<reverse_iterator<iterator_t<_View>>>, __empty_cache>; - _LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_ = _Cache(); - _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); - - public: - _LIBCPP_HIDE_FROM_ABI - reverse_view() requires default_initializable<_View> = default; - - _LIBCPP_HIDE_FROM_ABI - constexpr explicit reverse_view(_View __view) : __base_(std::move(__view)) {} - - _LIBCPP_HIDE_FROM_ABI - constexpr _View base() const& requires copy_constructible<_View> { return __base_; } - - _LIBCPP_HIDE_FROM_ABI - constexpr _View base() && { return std::move(__base_); } - - _LIBCPP_HIDE_FROM_ABI - constexpr reverse_iterator<iterator_t<_View>> begin() { - if constexpr (_UseCache) - if (__cached_begin_.__has_value()) - return *__cached_begin_; - - auto __tmp = std::make_reverse_iterator(ranges::next(ranges::begin(__base_), ranges::end(__base_))); - if constexpr (_UseCache) - __cached_begin_.__emplace(__tmp); - return __tmp; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr reverse_iterator<iterator_t<_View>> begin() requires common_range<_View> { - return std::make_reverse_iterator(ranges::end(__base_)); - } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto begin() const requires common_range<const _View> { - return std::make_reverse_iterator(ranges::end(__base_)); - } - - _LIBCPP_HIDE_FROM_ABI - constexpr reverse_iterator<iterator_t<_View>> end() { - return std::make_reverse_iterator(ranges::begin(__base_)); - } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto end() const requires common_range<const _View> { - return std::make_reverse_iterator(ranges::begin(__base_)); - } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto size() requires sized_range<_View> { - return ranges::size(__base_); - } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto size() const requires sized_range<const _View> { - return ranges::size(__base_); - } - }; - - template<class _Range> - reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>; - - template<class _Tp> - inline constexpr bool enable_borrowed_range<reverse_view<_Tp>> = enable_borrowed_range<_Tp>; - - namespace views { - namespace __reverse { - template<class _Tp> - constexpr bool __is_reverse_view = false; - - template<class _Tp> - constexpr bool __is_reverse_view<reverse_view<_Tp>> = true; - - template<class _Tp> - constexpr bool __is_sized_reverse_subrange = false; - - template<class _Iter> - constexpr bool __is_sized_reverse_subrange<subrange<reverse_iterator<_Iter>, reverse_iterator<_Iter>, subrange_kind::sized>> = true; - - template<class _Tp> - constexpr bool __is_unsized_reverse_subrange = false; - - template<class _Iter, subrange_kind _Kind> - constexpr bool __is_unsized_reverse_subrange<subrange<reverse_iterator<_Iter>, reverse_iterator<_Iter>, _Kind>> = _Kind == subrange_kind::unsized; - - template<class _Tp> - struct __unwrapped_reverse_subrange { - using type = void; // avoid SFINAE-ing out the overload below -- let the concept requirements do it for better diagnostics - }; - - template<class _Iter, subrange_kind _Kind> - struct __unwrapped_reverse_subrange<subrange<reverse_iterator<_Iter>, reverse_iterator<_Iter>, _Kind>> { - using type = subrange<_Iter, _Iter, _Kind>; - }; - - struct __fn : __range_adaptor_closure<__fn> { - template<class _Range> - requires __is_reverse_view<remove_cvref_t<_Range>> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI - constexpr auto operator()(_Range&& __range) const - noexcept(noexcept(std::forward<_Range>(__range).base())) - -> decltype( std::forward<_Range>(__range).base()) - { return std::forward<_Range>(__range).base(); } - - template<class _Range, - class _UnwrappedSubrange = typename __unwrapped_reverse_subrange<remove_cvref_t<_Range>>::type> - requires __is_sized_reverse_subrange<remove_cvref_t<_Range>> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI - constexpr auto operator()(_Range&& __range) const - noexcept(noexcept(_UnwrappedSubrange(__range.end().base(), __range.begin().base(), __range.size()))) - -> decltype( _UnwrappedSubrange(__range.end().base(), __range.begin().base(), __range.size())) - { return _UnwrappedSubrange(__range.end().base(), __range.begin().base(), __range.size()); } - - template<class _Range, - class _UnwrappedSubrange = typename __unwrapped_reverse_subrange<remove_cvref_t<_Range>>::type> - requires __is_unsized_reverse_subrange<remove_cvref_t<_Range>> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI - constexpr auto operator()(_Range&& __range) const - noexcept(noexcept(_UnwrappedSubrange(__range.end().base(), __range.begin().base()))) - -> decltype( _UnwrappedSubrange(__range.end().base(), __range.begin().base())) - { return _UnwrappedSubrange(__range.end().base(), __range.begin().base()); } - - template<class _Range> - requires (!__is_reverse_view<remove_cvref_t<_Range>> && - !__is_sized_reverse_subrange<remove_cvref_t<_Range>> && - !__is_unsized_reverse_subrange<remove_cvref_t<_Range>>) - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI - constexpr auto operator()(_Range&& __range) const - noexcept(noexcept(reverse_view{std::forward<_Range>(__range)})) - -> decltype( reverse_view{std::forward<_Range>(__range)}) - { return reverse_view{std::forward<_Range>(__range)}; } - }; - } // namespace __reverse - - inline namespace __cpo { - inline constexpr auto reverse = __reverse::__fn{}; - } // namespace __cpo - } // namespace views -} // namespace ranges - -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___RANGES_REVERSE_VIEW_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/single_view.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/single_view.h deleted file mode 100644 index e0fd4849f4..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/single_view.h +++ /dev/null @@ -1,81 +0,0 @@ -// -*- 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___RANGES_SINGLE_VIEW_H -#define _LIBCPP___RANGES_SINGLE_VIEW_H - -#include <__config> -#include <__ranges/copyable_box.h> -#include <__ranges/view_interface.h> -#include <__utility/forward.h> -#include <__utility/in_place.h> -#include <__utility/move.h> -#include <concepts> -#include <type_traits> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -namespace ranges { - template<copy_constructible _Tp> - requires is_object_v<_Tp> - class single_view : public view_interface<single_view<_Tp>> { - __copyable_box<_Tp> __value_; - - public: - _LIBCPP_HIDE_FROM_ABI - single_view() requires default_initializable<_Tp> = default; - - _LIBCPP_HIDE_FROM_ABI - constexpr explicit single_view(const _Tp& __t) : __value_(in_place, __t) {} - - _LIBCPP_HIDE_FROM_ABI - constexpr explicit single_view(_Tp&& __t) : __value_(in_place, std::move(__t)) {} - - template<class... _Args> - requires constructible_from<_Tp, _Args...> - _LIBCPP_HIDE_FROM_ABI - constexpr explicit single_view(in_place_t, _Args&&... __args) - : __value_{in_place, std::forward<_Args>(__args)...} {} - - _LIBCPP_HIDE_FROM_ABI - constexpr _Tp* begin() noexcept { return data(); } - - _LIBCPP_HIDE_FROM_ABI - constexpr const _Tp* begin() const noexcept { return data(); } - - _LIBCPP_HIDE_FROM_ABI - constexpr _Tp* end() noexcept { return data() + 1; } - - _LIBCPP_HIDE_FROM_ABI - constexpr const _Tp* end() const noexcept { return data() + 1; } - - _LIBCPP_HIDE_FROM_ABI - static constexpr size_t size() noexcept { return 1; } - - _LIBCPP_HIDE_FROM_ABI - constexpr _Tp* data() noexcept { return __value_.operator->(); } - - _LIBCPP_HIDE_FROM_ABI - constexpr const _Tp* data() const noexcept { return __value_.operator->(); } - }; - - template<class _Tp> - single_view(_Tp) -> single_view<_Tp>; -} // namespace ranges - -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___RANGES_SINGLE_VIEW_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/subrange.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/subrange.h deleted file mode 100644 index c54f7710fc..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/subrange.h +++ /dev/null @@ -1,289 +0,0 @@ -// -*- 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___RANGES_SUBRANGE_H -#define _LIBCPP___RANGES_SUBRANGE_H - -#include <__assert> -#include <__concepts/constructible.h> -#include <__concepts/convertible_to.h> -#include <__concepts/copyable.h> -#include <__concepts/derived_from.h> -#include <__concepts/different_from.h> -#include <__config> -#include <__iterator/advance.h> -#include <__iterator/concepts.h> -#include <__iterator/incrementable_traits.h> -#include <__iterator/iterator_traits.h> -#include <__ranges/access.h> -#include <__ranges/concepts.h> -#include <__ranges/dangling.h> -#include <__ranges/enable_borrowed_range.h> -#include <__ranges/size.h> -#include <__ranges/view_interface.h> -#include <__tuple> -#include <__utility/move.h> -#include <type_traits> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -namespace ranges { - template<class _From, class _To> - concept __uses_nonqualification_pointer_conversion = - is_pointer_v<_From> && is_pointer_v<_To> && - !convertible_to<remove_pointer_t<_From>(*)[], remove_pointer_t<_To>(*)[]>; - - template<class _From, class _To> - concept __convertible_to_non_slicing = - convertible_to<_From, _To> && - !__uses_nonqualification_pointer_conversion<decay_t<_From>, decay_t<_To>>; - - template<class _Tp> - concept __pair_like = - !is_reference_v<_Tp> && requires(_Tp __t) { - typename tuple_size<_Tp>::type; // Ensures `tuple_size<T>` is complete. - requires derived_from<tuple_size<_Tp>, integral_constant<size_t, 2>>; - typename tuple_element_t<0, remove_const_t<_Tp>>; - typename tuple_element_t<1, remove_const_t<_Tp>>; - { std::get<0>(__t) } -> convertible_to<const tuple_element_t<0, _Tp>&>; - { std::get<1>(__t) } -> convertible_to<const tuple_element_t<1, _Tp>&>; - }; - - template<class _Pair, class _Iter, class _Sent> - concept __pair_like_convertible_from = - !range<_Pair> && __pair_like<_Pair> && - constructible_from<_Pair, _Iter, _Sent> && - __convertible_to_non_slicing<_Iter, tuple_element_t<0, _Pair>> && - convertible_to<_Sent, tuple_element_t<1, _Pair>>; - - enum class _LIBCPP_ENUM_VIS subrange_kind : bool { unsized, sized }; - - template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent = _Iter, - subrange_kind _Kind = sized_sentinel_for<_Sent, _Iter> - ? subrange_kind::sized - : subrange_kind::unsized> - requires (_Kind == subrange_kind::sized || !sized_sentinel_for<_Sent, _Iter>) - class _LIBCPP_TEMPLATE_VIS subrange - : public view_interface<subrange<_Iter, _Sent, _Kind>> - { - private: - static constexpr bool _StoreSize = (_Kind == subrange_kind::sized && !sized_sentinel_for<_Sent, _Iter>); - static constexpr bool _MustProvideSizeAtConstruction = !_StoreSize; // just to improve compiler diagnostics - struct _Empty { constexpr _Empty(auto) noexcept { } }; - using _Size = conditional_t<_StoreSize, make_unsigned_t<iter_difference_t<_Iter>>, _Empty>; - _LIBCPP_NO_UNIQUE_ADDRESS _Iter __begin_ = _Iter(); - _LIBCPP_NO_UNIQUE_ADDRESS _Sent __end_ = _Sent(); - _LIBCPP_NO_UNIQUE_ADDRESS _Size __size_ = 0; - - public: - _LIBCPP_HIDE_FROM_ABI - subrange() requires default_initializable<_Iter> = default; - - _LIBCPP_HIDE_FROM_ABI - constexpr subrange(__convertible_to_non_slicing<_Iter> auto __iter, _Sent __sent) - requires _MustProvideSizeAtConstruction - : __begin_(std::move(__iter)), __end_(std::move(__sent)) - { } - - _LIBCPP_HIDE_FROM_ABI - constexpr subrange(__convertible_to_non_slicing<_Iter> auto __iter, _Sent __sent, - make_unsigned_t<iter_difference_t<_Iter>> __n) - requires (_Kind == subrange_kind::sized) - : __begin_(std::move(__iter)), __end_(std::move(__sent)), __size_(__n) - { - if constexpr (sized_sentinel_for<_Sent, _Iter>) - _LIBCPP_ASSERT((__end_ - __begin_) == static_cast<iter_difference_t<_Iter>>(__n), - "std::ranges::subrange was passed an invalid size hint"); - } - - template<__different_from<subrange> _Range> - requires borrowed_range<_Range> && - __convertible_to_non_slicing<iterator_t<_Range>, _Iter> && - convertible_to<sentinel_t<_Range>, _Sent> - _LIBCPP_HIDE_FROM_ABI - constexpr subrange(_Range&& __range) - requires (!_StoreSize) - : subrange(ranges::begin(__range), ranges::end(__range)) - { } - - template<__different_from<subrange> _Range> - requires borrowed_range<_Range> && - __convertible_to_non_slicing<iterator_t<_Range>, _Iter> && - convertible_to<sentinel_t<_Range>, _Sent> - _LIBCPP_HIDE_FROM_ABI - constexpr subrange(_Range&& __range) - requires _StoreSize && sized_range<_Range> - : subrange(__range, ranges::size(__range)) - { } - - template<borrowed_range _Range> - requires __convertible_to_non_slicing<iterator_t<_Range>, _Iter> && - convertible_to<sentinel_t<_Range>, _Sent> - _LIBCPP_HIDE_FROM_ABI - constexpr subrange(_Range&& __range, make_unsigned_t<iter_difference_t<_Iter>> __n) - requires (_Kind == subrange_kind::sized) - : subrange(ranges::begin(__range), ranges::end(__range), __n) - { } - - template<__different_from<subrange> _Pair> - requires __pair_like_convertible_from<_Pair, const _Iter&, const _Sent&> - _LIBCPP_HIDE_FROM_ABI - constexpr operator _Pair() const { - return _Pair(__begin_, __end_); - } - - _LIBCPP_HIDE_FROM_ABI - constexpr _Iter begin() const requires copyable<_Iter> { - return __begin_; - } - - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter begin() requires (!copyable<_Iter>) { - return std::move(__begin_); - } - - _LIBCPP_HIDE_FROM_ABI - constexpr _Sent end() const { - return __end_; - } - - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const { - return __begin_ == __end_; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr make_unsigned_t<iter_difference_t<_Iter>> size() const - requires (_Kind == subrange_kind::sized) - { - if constexpr (_StoreSize) - return __size_; - else - return std::__to_unsigned_like(__end_ - __begin_); - } - - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange next(iter_difference_t<_Iter> __n = 1) const& - requires forward_iterator<_Iter> - { - auto __tmp = *this; - __tmp.advance(__n); - return __tmp; - } - - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange next(iter_difference_t<_Iter> __n = 1) && { - advance(__n); - return std::move(*this); - } - - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange prev(iter_difference_t<_Iter> __n = 1) const - requires bidirectional_iterator<_Iter> - { - auto __tmp = *this; - __tmp.advance(-__n); - return __tmp; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr subrange& advance(iter_difference_t<_Iter> __n) { - if constexpr (bidirectional_iterator<_Iter>) { - if (__n < 0) { - ranges::advance(__begin_, __n); - if constexpr (_StoreSize) - __size_ += std::__to_unsigned_like(-__n); - return *this; - } - } - - auto __d = __n - ranges::advance(__begin_, __n, __end_); - if constexpr (_StoreSize) - __size_ -= std::__to_unsigned_like(__d); - return *this; - } - }; - - template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent> - subrange(_Iter, _Sent) -> subrange<_Iter, _Sent>; - - template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent> - subrange(_Iter, _Sent, make_unsigned_t<iter_difference_t<_Iter>>) - -> subrange<_Iter, _Sent, subrange_kind::sized>; - - template<borrowed_range _Range> - subrange(_Range&&) -> subrange<iterator_t<_Range>, sentinel_t<_Range>, - (sized_range<_Range> || sized_sentinel_for<sentinel_t<_Range>, iterator_t<_Range>>) - ? subrange_kind::sized : subrange_kind::unsized>; - - template<borrowed_range _Range> - subrange(_Range&&, make_unsigned_t<range_difference_t<_Range>>) - -> subrange<iterator_t<_Range>, sentinel_t<_Range>, subrange_kind::sized>; - - template<size_t _Index, class _Iter, class _Sent, subrange_kind _Kind> - requires ((_Index == 0 && copyable<_Iter>) || _Index == 1) - _LIBCPP_HIDE_FROM_ABI - constexpr auto get(const subrange<_Iter, _Sent, _Kind>& __subrange) { - if constexpr (_Index == 0) - return __subrange.begin(); - else - return __subrange.end(); - } - - template<size_t _Index, class _Iter, class _Sent, subrange_kind _Kind> - requires (_Index < 2) - _LIBCPP_HIDE_FROM_ABI - constexpr auto get(subrange<_Iter, _Sent, _Kind>&& __subrange) { - if constexpr (_Index == 0) - return __subrange.begin(); - else - return __subrange.end(); - } - - template<class _Ip, class _Sp, subrange_kind _Kp> - inline constexpr bool enable_borrowed_range<subrange<_Ip, _Sp, _Kp>> = true; - - template<range _Rp> - using borrowed_subrange_t = _If<borrowed_range<_Rp>, subrange<iterator_t<_Rp>>, dangling>; -} // namespace ranges - -// [range.subrange.general] - -using ranges::get; - -// [ranges.syn] - -template<class _Ip, class _Sp, ranges::subrange_kind _Kp> -struct tuple_size<ranges::subrange<_Ip, _Sp, _Kp>> : integral_constant<size_t, 2> {}; - -template<class _Ip, class _Sp, ranges::subrange_kind _Kp> -struct tuple_element<0, ranges::subrange<_Ip, _Sp, _Kp>> { - using type = _Ip; -}; - -template<class _Ip, class _Sp, ranges::subrange_kind _Kp> -struct tuple_element<1, ranges::subrange<_Ip, _Sp, _Kp>> { - using type = _Sp; -}; - -template<class _Ip, class _Sp, ranges::subrange_kind _Kp> -struct tuple_element<0, const ranges::subrange<_Ip, _Sp, _Kp>> { - using type = _Ip; -}; - -template<class _Ip, class _Sp, ranges::subrange_kind _Kp> -struct tuple_element<1, const ranges::subrange<_Ip, _Sp, _Kp>> { - using type = _Sp; -}; - -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___RANGES_SUBRANGE_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/take_view.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/take_view.h deleted file mode 100644 index b5f194f9a0..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/take_view.h +++ /dev/null @@ -1,185 +0,0 @@ -// -*- 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___RANGES_TAKE_VIEW_H -#define _LIBCPP___RANGES_TAKE_VIEW_H - -#include <__algorithm/min.h> -#include <__config> -#include <__iterator/concepts.h> -#include <__iterator/counted_iterator.h> -#include <__iterator/default_sentinel.h> -#include <__iterator/iterator_traits.h> -#include <__ranges/access.h> -#include <__ranges/all.h> -#include <__ranges/concepts.h> -#include <__ranges/enable_borrowed_range.h> -#include <__ranges/size.h> -#include <__ranges/view_interface.h> -#include <__utility/move.h> -#include <concepts> -#include <type_traits> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -namespace ranges { - template<view _View> - class take_view : public view_interface<take_view<_View>> { - _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); - range_difference_t<_View> __count_ = 0; - - template<bool> class __sentinel; - - public: - _LIBCPP_HIDE_FROM_ABI - take_view() requires default_initializable<_View> = default; - - _LIBCPP_HIDE_FROM_ABI - constexpr take_view(_View __base, range_difference_t<_View> __count) - : __base_(std::move(__base)), __count_(__count) {} - - _LIBCPP_HIDE_FROM_ABI - constexpr _View base() const& requires copy_constructible<_View> { return __base_; } - - _LIBCPP_HIDE_FROM_ABI - constexpr _View base() && { return std::move(__base_); } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto begin() requires (!__simple_view<_View>) { - if constexpr (sized_range<_View>) { - if constexpr (random_access_range<_View>) { - return ranges::begin(__base_); - } else { - using _DifferenceT = range_difference_t<_View>; - auto __size = size(); - return counted_iterator(ranges::begin(__base_), static_cast<_DifferenceT>(__size)); - } - } else { - return counted_iterator(ranges::begin(__base_), __count_); - } - } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto begin() const requires range<const _View> { - if constexpr (sized_range<const _View>) { - if constexpr (random_access_range<const _View>) { - return ranges::begin(__base_); - } else { - using _DifferenceT = range_difference_t<const _View>; - auto __size = size(); - return counted_iterator(ranges::begin(__base_), static_cast<_DifferenceT>(__size)); - } - } else { - return counted_iterator(ranges::begin(__base_), __count_); - } - } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto end() requires (!__simple_view<_View>) { - if constexpr (sized_range<_View>) { - if constexpr (random_access_range<_View>) { - return ranges::begin(__base_) + size(); - } else { - return default_sentinel; - } - } else { - return __sentinel<false>{ranges::end(__base_)}; - } - } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto end() const requires range<const _View> { - if constexpr (sized_range<const _View>) { - if constexpr (random_access_range<const _View>) { - return ranges::begin(__base_) + size(); - } else { - return default_sentinel; - } - } else { - return __sentinel<true>{ranges::end(__base_)}; - } - } - - - _LIBCPP_HIDE_FROM_ABI - constexpr auto size() requires sized_range<_View> { - auto __n = ranges::size(__base_); - // TODO: use ranges::min here. - return std::min(__n, static_cast<decltype(__n)>(__count_)); - } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto size() const requires sized_range<const _View> { - auto __n = ranges::size(__base_); - // TODO: use ranges::min here. - return std::min(__n, static_cast<decltype(__n)>(__count_)); - } - }; - - template<view _View> - template<bool _Const> - class take_view<_View>::__sentinel { - using _Base = __maybe_const<_Const, _View>; - template<bool _OtherConst> - using _Iter = counted_iterator<iterator_t<__maybe_const<_OtherConst, _View>>>; - _LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_Base> __end_ = sentinel_t<_Base>(); - - template<bool> - friend class take_view<_View>::__sentinel; - -public: - _LIBCPP_HIDE_FROM_ABI - __sentinel() = default; - - _LIBCPP_HIDE_FROM_ABI - constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(std::move(__end)) {} - - _LIBCPP_HIDE_FROM_ABI - constexpr __sentinel(__sentinel<!_Const> __s) - requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>> - : __end_(std::move(__s.__end_)) {} - - _LIBCPP_HIDE_FROM_ABI - constexpr sentinel_t<_Base> base() const { return __end_; } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(const _Iter<_Const>& __lhs, const __sentinel& __rhs) { - return __lhs.count() == 0 || __lhs.base() == __rhs.__end_; - } - - template<bool _OtherConst = !_Const> - requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>> - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(const _Iter<_Const>& __lhs, const __sentinel& __rhs) { - return __lhs.count() == 0 || __lhs.base() == __rhs.__end_; - } - }; - - template<class _Range> - take_view(_Range&&, range_difference_t<_Range>) -> take_view<views::all_t<_Range>>; - - template<class _Tp> - inline constexpr bool enable_borrowed_range<take_view<_Tp>> = enable_borrowed_range<_Tp>; -} // namespace ranges - -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -_LIBCPP_POP_MACROS - -#endif // _LIBCPP___RANGES_TAKE_VIEW_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/transform_view.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/transform_view.h deleted file mode 100644 index 4cc582faeb..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/transform_view.h +++ /dev/null @@ -1,440 +0,0 @@ -// -*- 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___RANGES_TRANSFORM_VIEW_H -#define _LIBCPP___RANGES_TRANSFORM_VIEW_H - -#include <__compare/three_way_comparable.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/invocable.h> -#include <__config> -#include <__functional/bind_back.h> -#include <__functional/invoke.h> -#include <__iterator/concepts.h> -#include <__iterator/iterator_traits.h> -#include <__memory/addressof.h> -#include <__ranges/access.h> -#include <__ranges/all.h> -#include <__ranges/concepts.h> -#include <__ranges/copyable_box.h> -#include <__ranges/empty.h> -#include <__ranges/range_adaptor.h> -#include <__ranges/size.h> -#include <__ranges/view_interface.h> -#include <__utility/forward.h> -#include <__utility/in_place.h> -#include <__utility/move.h> -#include <type_traits> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -namespace ranges { - -template<class _Fn, class _View> -concept __regular_invocable_with_range_ref = - regular_invocable<_Fn, range_reference_t<_View>>; - -template<class _View, class _Fn> -concept __transform_view_constraints = - view<_View> && is_object_v<_Fn> && - regular_invocable<_Fn&, range_reference_t<_View>> && - __can_reference<invoke_result_t<_Fn&, range_reference_t<_View>>>; - -template<input_range _View, copy_constructible _Fn> - requires __transform_view_constraints<_View, _Fn> -class transform_view : public view_interface<transform_view<_View, _Fn>> { - template<bool> class __iterator; - template<bool> class __sentinel; - - _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Fn> __func_; - _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); - -public: - _LIBCPP_HIDE_FROM_ABI - transform_view() - requires default_initializable<_View> && default_initializable<_Fn> = default; - - _LIBCPP_HIDE_FROM_ABI - constexpr transform_view(_View __base, _Fn __func) - : __func_(std::in_place, std::move(__func)), __base_(std::move(__base)) {} - - _LIBCPP_HIDE_FROM_ABI - constexpr _View base() const& requires copy_constructible<_View> { return __base_; } - _LIBCPP_HIDE_FROM_ABI - constexpr _View base() && { return std::move(__base_); } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator<false> begin() { - return __iterator<false>{*this, ranges::begin(__base_)}; - } - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator<true> begin() const - requires range<const _View> && - __regular_invocable_with_range_ref<const _Fn&, const _View> - { - return __iterator<true>(*this, ranges::begin(__base_)); - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __sentinel<false> end() { - return __sentinel<false>(ranges::end(__base_)); - } - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator<false> end() - requires common_range<_View> - { - return __iterator<false>(*this, ranges::end(__base_)); - } - _LIBCPP_HIDE_FROM_ABI - constexpr __sentinel<true> end() const - requires range<const _View> && - __regular_invocable_with_range_ref<const _Fn&, const _View> - { - return __sentinel<true>(ranges::end(__base_)); - } - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator<true> end() const - requires common_range<const _View> && - __regular_invocable_with_range_ref<const _Fn&, const _View> - { - return __iterator<true>(*this, ranges::end(__base_)); - } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto size() requires sized_range<_View> { return ranges::size(__base_); } - _LIBCPP_HIDE_FROM_ABI - constexpr auto size() const requires sized_range<const _View> { return ranges::size(__base_); } -}; - -template<class _Range, class _Fn> -transform_view(_Range&&, _Fn) -> transform_view<views::all_t<_Range>, _Fn>; - -template<class _View> -struct __transform_view_iterator_concept { using type = input_iterator_tag; }; - -template<random_access_range _View> -struct __transform_view_iterator_concept<_View> { using type = random_access_iterator_tag; }; - -template<bidirectional_range _View> -struct __transform_view_iterator_concept<_View> { using type = bidirectional_iterator_tag; }; - -template<forward_range _View> -struct __transform_view_iterator_concept<_View> { using type = forward_iterator_tag; }; - -template<class, class> -struct __transform_view_iterator_category_base {}; - -template<forward_range _View, class _Fn> -struct __transform_view_iterator_category_base<_View, _Fn> { - using _Cat = typename iterator_traits<iterator_t<_View>>::iterator_category; - - using iterator_category = conditional_t< - is_lvalue_reference_v<invoke_result_t<_Fn&, range_reference_t<_View>>>, - conditional_t< - derived_from<_Cat, contiguous_iterator_tag>, - random_access_iterator_tag, - _Cat - >, - input_iterator_tag - >; -}; - -template<input_range _View, copy_constructible _Fn> - requires __transform_view_constraints<_View, _Fn> -template<bool _Const> -class transform_view<_View, _Fn>::__iterator - : public __transform_view_iterator_category_base<_View, _Fn> { - - using _Parent = __maybe_const<_Const, transform_view>; - using _Base = __maybe_const<_Const, _View>; - - _Parent *__parent_ = nullptr; - - template<bool> - friend class transform_view<_View, _Fn>::__iterator; - - template<bool> - friend class transform_view<_View, _Fn>::__sentinel; - -public: - iterator_t<_Base> __current_ = iterator_t<_Base>(); - - using iterator_concept = typename __transform_view_iterator_concept<_View>::type; - using value_type = remove_cvref_t<invoke_result_t<_Fn&, range_reference_t<_Base>>>; - using difference_type = range_difference_t<_Base>; - - _LIBCPP_HIDE_FROM_ABI - __iterator() requires default_initializable<iterator_t<_Base>> = default; - - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator(_Parent& __parent, iterator_t<_Base> __current) - : __parent_(std::addressof(__parent)), __current_(std::move(__current)) {} - - // Note: `__i` should always be `__iterator<false>`, but directly using - // `__iterator<false>` is ill-formed when `_Const` is false - // (see http://wg21.link/class.copy.ctor#5). - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator(__iterator<!_Const> __i) - requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>> - : __parent_(__i.__parent_), __current_(std::move(__i.__current_)) {} - - _LIBCPP_HIDE_FROM_ABI - constexpr const iterator_t<_Base>& base() const& noexcept { - return __current_; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr iterator_t<_Base> base() && { - return std::move(__current_); - } - - _LIBCPP_HIDE_FROM_ABI - constexpr decltype(auto) operator*() const - noexcept(noexcept(std::invoke(*__parent_->__func_, *__current_))) - { - return std::invoke(*__parent_->__func_, *__current_); - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator& operator++() { - ++__current_; - return *this; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr void operator++(int) { ++__current_; } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator operator++(int) - requires forward_range<_Base> - { - auto __tmp = *this; - ++*this; - return __tmp; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator& operator--() - requires bidirectional_range<_Base> - { - --__current_; - return *this; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator operator--(int) - requires bidirectional_range<_Base> - { - auto __tmp = *this; - --*this; - return __tmp; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator& operator+=(difference_type __n) - requires random_access_range<_Base> - { - __current_ += __n; - return *this; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iterator& operator-=(difference_type __n) - requires random_access_range<_Base> - { - __current_ -= __n; - return *this; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr decltype(auto) operator[](difference_type __n) const - noexcept(noexcept(std::invoke(*__parent_->__func_, __current_[__n]))) - requires random_access_range<_Base> - { - return std::invoke(*__parent_->__func_, __current_[__n]); - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) - requires equality_comparable<iterator_t<_Base>> - { - return __x.__current_ == __y.__current_; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator<(const __iterator& __x, const __iterator& __y) - requires random_access_range<_Base> - { - return __x.__current_ < __y.__current_; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator>(const __iterator& __x, const __iterator& __y) - requires random_access_range<_Base> - { - return __x.__current_ > __y.__current_; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y) - requires random_access_range<_Base> - { - return __x.__current_ <= __y.__current_; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y) - requires random_access_range<_Base> - { - return __x.__current_ >= __y.__current_; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y) - requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>> - { - return __x.__current_ <=> __y.__current_; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr __iterator operator+(__iterator __i, difference_type __n) - requires random_access_range<_Base> - { - return __iterator{*__i.__parent_, __i.__current_ + __n}; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr __iterator operator+(difference_type __n, __iterator __i) - requires random_access_range<_Base> - { - return __iterator{*__i.__parent_, __i.__current_ + __n}; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr __iterator operator-(__iterator __i, difference_type __n) - requires random_access_range<_Base> - { - return __iterator{*__i.__parent_, __i.__current_ - __n}; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y) - requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>> - { - return __x.__current_ - __y.__current_; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr decltype(auto) iter_move(const __iterator& __i) - noexcept(noexcept(*__i)) - { - if constexpr (is_lvalue_reference_v<decltype(*__i)>) - return std::move(*__i); - else - return *__i; - } -}; - -template<input_range _View, copy_constructible _Fn> - requires __transform_view_constraints<_View, _Fn> -template<bool _Const> -class transform_view<_View, _Fn>::__sentinel { - using _Parent = __maybe_const<_Const, transform_view>; - using _Base = __maybe_const<_Const, _View>; - - sentinel_t<_Base> __end_ = sentinel_t<_Base>(); - - template<bool> - friend class transform_view<_View, _Fn>::__iterator; - - template<bool> - friend class transform_view<_View, _Fn>::__sentinel; - -public: - _LIBCPP_HIDE_FROM_ABI - __sentinel() = default; - - _LIBCPP_HIDE_FROM_ABI - constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(__end) {} - - // Note: `__i` should always be `__sentinel<false>`, but directly using - // `__sentinel<false>` is ill-formed when `_Const` is false - // (see http://wg21.link/class.copy.ctor#5). - _LIBCPP_HIDE_FROM_ABI - constexpr __sentinel(__sentinel<!_Const> __i) - requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>> - : __end_(std::move(__i.__end_)) {} - - _LIBCPP_HIDE_FROM_ABI - constexpr sentinel_t<_Base> base() const { return __end_; } - - template<bool _OtherConst> - requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>> - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) { - return __x.__current_ == __y.__end_; - } - - template<bool _OtherConst> - requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>> - _LIBCPP_HIDE_FROM_ABI - friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>> - operator-(const __iterator<_OtherConst>& __x, const __sentinel& __y) { - return __x.__current_ - __y.__end_; - } - - template<bool _OtherConst> - requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>> - _LIBCPP_HIDE_FROM_ABI - friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>> - operator-(const __sentinel& __x, const __iterator<_OtherConst>& __y) { - return __x.__end_ - __y.__current_; - } -}; - -namespace views { -namespace __transform { - struct __fn { - template<class _Range, class _Fn> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI - constexpr auto operator()(_Range&& __range, _Fn&& __f) const - noexcept(noexcept(transform_view(std::forward<_Range>(__range), std::forward<_Fn>(__f)))) - -> decltype( transform_view(std::forward<_Range>(__range), std::forward<_Fn>(__f))) - { return transform_view(std::forward<_Range>(__range), std::forward<_Fn>(__f)); } - - template<class _Fn> - requires constructible_from<decay_t<_Fn>, _Fn> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI - constexpr auto operator()(_Fn&& __f) const - noexcept(is_nothrow_constructible_v<decay_t<_Fn>, _Fn>) - { return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Fn>(__f))); } - }; -} // namespace __transform - -inline namespace __cpo { - inline constexpr auto transform = __transform::__fn{}; -} // namespace __cpo -} // namespace views - -} // namespace ranges - -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___RANGES_TRANSFORM_VIEW_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/view_interface.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/view_interface.h deleted file mode 100644 index eecc475111..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/view_interface.h +++ /dev/null @@ -1,174 +0,0 @@ -// -*- 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___RANGES_VIEW_INTERFACE_H -#define _LIBCPP___RANGES_VIEW_INTERFACE_H - -#include <__assert> -#include <__concepts/derived_from.h> -#include <__concepts/same_as.h> -#include <__config> -#include <__iterator/concepts.h> -#include <__iterator/iterator_traits.h> -#include <__iterator/prev.h> -#include <__memory/pointer_traits.h> -#include <__ranges/access.h> -#include <__ranges/concepts.h> -#include <__ranges/empty.h> -#include <type_traits> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -namespace ranges { - -template<class _Derived> - requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>> -class view_interface { - _LIBCPP_HIDE_FROM_ABI - constexpr _Derived& __derived() noexcept { - static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>); - return static_cast<_Derived&>(*this); - } - - _LIBCPP_HIDE_FROM_ABI - constexpr _Derived const& __derived() const noexcept { - static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>); - return static_cast<_Derived const&>(*this); - } - -public: - template<class _D2 = _Derived> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() - requires forward_range<_D2> - { - return ranges::begin(__derived()) == ranges::end(__derived()); - } - - template<class _D2 = _Derived> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const - requires forward_range<const _D2> - { - return ranges::begin(__derived()) == ranges::end(__derived()); - } - - template<class _D2 = _Derived> - _LIBCPP_HIDE_FROM_ABI - constexpr explicit operator bool() - requires requires (_D2& __t) { ranges::empty(__t); } - { - return !ranges::empty(__derived()); - } - - template<class _D2 = _Derived> - _LIBCPP_HIDE_FROM_ABI - constexpr explicit operator bool() const - requires requires (const _D2& __t) { ranges::empty(__t); } - { - return !ranges::empty(__derived()); - } - - template<class _D2 = _Derived> - _LIBCPP_HIDE_FROM_ABI - constexpr auto data() - requires contiguous_iterator<iterator_t<_D2>> - { - return std::to_address(ranges::begin(__derived())); - } - - template<class _D2 = _Derived> - _LIBCPP_HIDE_FROM_ABI - constexpr auto data() const - requires range<const _D2> && contiguous_iterator<iterator_t<const _D2>> - { - return std::to_address(ranges::begin(__derived())); - } - - template<class _D2 = _Derived> - _LIBCPP_HIDE_FROM_ABI - constexpr auto size() - requires forward_range<_D2> && sized_sentinel_for<sentinel_t<_D2>, iterator_t<_D2>> - { - return ranges::end(__derived()) - ranges::begin(__derived()); - } - - template<class _D2 = _Derived> - _LIBCPP_HIDE_FROM_ABI - constexpr auto size() const - requires forward_range<const _D2> && sized_sentinel_for<sentinel_t<const _D2>, iterator_t<const _D2>> - { - return ranges::end(__derived()) - ranges::begin(__derived()); - } - - template<class _D2 = _Derived> - _LIBCPP_HIDE_FROM_ABI - constexpr decltype(auto) front() - requires forward_range<_D2> - { - _LIBCPP_ASSERT(!empty(), - "Precondition `!empty()` not satisfied. `.front()` called on an empty view."); - return *ranges::begin(__derived()); - } - - template<class _D2 = _Derived> - _LIBCPP_HIDE_FROM_ABI - constexpr decltype(auto) front() const - requires forward_range<const _D2> - { - _LIBCPP_ASSERT(!empty(), - "Precondition `!empty()` not satisfied. `.front()` called on an empty view."); - return *ranges::begin(__derived()); - } - - template<class _D2 = _Derived> - _LIBCPP_HIDE_FROM_ABI - constexpr decltype(auto) back() - requires bidirectional_range<_D2> && common_range<_D2> - { - _LIBCPP_ASSERT(!empty(), - "Precondition `!empty()` not satisfied. `.back()` called on an empty view."); - return *ranges::prev(ranges::end(__derived())); - } - - template<class _D2 = _Derived> - _LIBCPP_HIDE_FROM_ABI - constexpr decltype(auto) back() const - requires bidirectional_range<const _D2> && common_range<const _D2> - { - _LIBCPP_ASSERT(!empty(), - "Precondition `!empty()` not satisfied. `.back()` called on an empty view."); - return *ranges::prev(ranges::end(__derived())); - } - - template<random_access_range _RARange = _Derived> - _LIBCPP_HIDE_FROM_ABI - constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) - { - return ranges::begin(__derived())[__index]; - } - - template<random_access_range _RARange = const _Derived> - _LIBCPP_HIDE_FROM_ABI - constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) const - { - return ranges::begin(__derived())[__index]; - } -}; - -} // namespace ranges - -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___RANGES_VIEW_INTERFACE_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/views.h b/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/views.h deleted file mode 100644 index 8cc5ba3d2a..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/__ranges/views.h +++ /dev/null @@ -1,35 +0,0 @@ -// -*- 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___RANGES_VIEWS -#define _LIBCPP___RANGES_VIEWS - -#include <__config> - -#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_RANGES) - -namespace ranges { - -namespace views { } - -} // namespace ranges - -namespace views = ranges::views; - -#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___RANGES_VIEWS diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/cassert b/contrib/libs/cxxsupp/libcxxmsvc/include/cassert deleted file mode 100644 index 3c5bb7b110..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/cassert +++ /dev/null @@ -1,24 +0,0 @@ -// -*- 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 -// -//===----------------------------------------------------------------------===// - -/* - cassert synopsis - -Macros: - - assert - -*/ - -#include <__config> -#include <assert.h> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/ccomplex b/contrib/libs/cxxsupp/libcxxmsvc/include/ccomplex deleted file mode 100644 index f1037f2841..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/ccomplex +++ /dev/null @@ -1,28 +0,0 @@ -// -*- 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_CCOMPLEX -#define _LIBCPP_CCOMPLEX - -/* - ccomplex synopsis - -#include <complex> - -*/ - -#include <complex> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -// hh 080623 Created - -#endif // _LIBCPP_CCOMPLEX diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/cfenv b/contrib/libs/cxxsupp/libcxxmsvc/include/cfenv deleted file mode 100644 index e1aae2f009..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/cfenv +++ /dev/null @@ -1,81 +0,0 @@ -// -*- 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_CFENV -#define _LIBCPP_CFENV - -/* - cfenv synopsis - -This entire header is C99 / C++0X - -Macros: - - FE_DIVBYZERO - FE_INEXACT - FE_INVALID - FE_OVERFLOW - FE_UNDERFLOW - FE_ALL_EXCEPT - FE_DOWNWARD - FE_TONEAREST - FE_TOWARDZERO - FE_UPWARD - FE_DFL_ENV - -namespace std -{ - -Types: - - fenv_t - fexcept_t - -int feclearexcept(int excepts); -int fegetexceptflag(fexcept_t* flagp, int excepts); -int feraiseexcept(int excepts); -int fesetexceptflag(const fexcept_t* flagp, int excepts); -int fetestexcept(int excepts); -int fegetround(); -int fesetround(int round); -int fegetenv(fenv_t* envp); -int feholdexcept(fenv_t* envp); -int fesetenv(const fenv_t* envp); -int feupdateenv(const fenv_t* envp); - -} // std -*/ - -#include <__config> -#include <fenv.h> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -using ::fenv_t _LIBCPP_USING_IF_EXISTS; -using ::fexcept_t _LIBCPP_USING_IF_EXISTS; - -using ::feclearexcept _LIBCPP_USING_IF_EXISTS; -using ::fegetexceptflag _LIBCPP_USING_IF_EXISTS; -using ::feraiseexcept _LIBCPP_USING_IF_EXISTS; -using ::fesetexceptflag _LIBCPP_USING_IF_EXISTS; -using ::fetestexcept _LIBCPP_USING_IF_EXISTS; -using ::fegetround _LIBCPP_USING_IF_EXISTS; -using ::fesetround _LIBCPP_USING_IF_EXISTS; -using ::fegetenv _LIBCPP_USING_IF_EXISTS; -using ::feholdexcept _LIBCPP_USING_IF_EXISTS; -using ::fesetenv _LIBCPP_USING_IF_EXISTS; -using ::feupdateenv _LIBCPP_USING_IF_EXISTS; - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP_CFENV diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/cinttypes b/contrib/libs/cxxsupp/libcxxmsvc/include/cinttypes deleted file mode 100644 index 0674384b79..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/cinttypes +++ /dev/null @@ -1,257 +0,0 @@ -// -*- 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_CINTTYPES -#define _LIBCPP_CINTTYPES - -/* - cinttypes synopsis - -This entire header is C99 / C++0X - -#include <cstdint> // <cinttypes> includes <cstdint> - -Macros: - - PRId8 - PRId16 - PRId32 - PRId64 - - PRIdLEAST8 - PRIdLEAST16 - PRIdLEAST32 - PRIdLEAST64 - - PRIdFAST8 - PRIdFAST16 - PRIdFAST32 - PRIdFAST64 - - PRIdMAX - PRIdPTR - - PRIi8 - PRIi16 - PRIi32 - PRIi64 - - PRIiLEAST8 - PRIiLEAST16 - PRIiLEAST32 - PRIiLEAST64 - - PRIiFAST8 - PRIiFAST16 - PRIiFAST32 - PRIiFAST64 - - PRIiMAX - PRIiPTR - - PRIo8 - PRIo16 - PRIo32 - PRIo64 - - PRIoLEAST8 - PRIoLEAST16 - PRIoLEAST32 - PRIoLEAST64 - - PRIoFAST8 - PRIoFAST16 - PRIoFAST32 - PRIoFAST64 - - PRIoMAX - PRIoPTR - - PRIu8 - PRIu16 - PRIu32 - PRIu64 - - PRIuLEAST8 - PRIuLEAST16 - PRIuLEAST32 - PRIuLEAST64 - - PRIuFAST8 - PRIuFAST16 - PRIuFAST32 - PRIuFAST64 - - PRIuMAX - PRIuPTR - - PRIx8 - PRIx16 - PRIx32 - PRIx64 - - PRIxLEAST8 - PRIxLEAST16 - PRIxLEAST32 - PRIxLEAST64 - - PRIxFAST8 - PRIxFAST16 - PRIxFAST32 - PRIxFAST64 - - PRIxMAX - PRIxPTR - - PRIX8 - PRIX16 - PRIX32 - PRIX64 - - PRIXLEAST8 - PRIXLEAST16 - PRIXLEAST32 - PRIXLEAST64 - - PRIXFAST8 - PRIXFAST16 - PRIXFAST32 - PRIXFAST64 - - PRIXMAX - PRIXPTR - - SCNd8 - SCNd16 - SCNd32 - SCNd64 - - SCNdLEAST8 - SCNdLEAST16 - SCNdLEAST32 - SCNdLEAST64 - - SCNdFAST8 - SCNdFAST16 - SCNdFAST32 - SCNdFAST64 - - SCNdMAX - SCNdPTR - - SCNi8 - SCNi16 - SCNi32 - SCNi64 - - SCNiLEAST8 - SCNiLEAST16 - SCNiLEAST32 - SCNiLEAST64 - - SCNiFAST8 - SCNiFAST16 - SCNiFAST32 - SCNiFAST64 - - SCNiMAX - SCNiPTR - - SCNo8 - SCNo16 - SCNo32 - SCNo64 - - SCNoLEAST8 - SCNoLEAST16 - SCNoLEAST32 - SCNoLEAST64 - - SCNoFAST8 - SCNoFAST16 - SCNoFAST32 - SCNoFAST64 - - SCNoMAX - SCNoPTR - - SCNu8 - SCNu16 - SCNu32 - SCNu64 - - SCNuLEAST8 - SCNuLEAST16 - SCNuLEAST32 - SCNuLEAST64 - - SCNuFAST8 - SCNuFAST16 - SCNuFAST32 - SCNuFAST64 - - SCNuMAX - SCNuPTR - - SCNx8 - SCNx16 - SCNx32 - SCNx64 - - SCNxLEAST8 - SCNxLEAST16 - SCNxLEAST32 - SCNxLEAST64 - - SCNxFAST8 - SCNxFAST16 - SCNxFAST32 - SCNxFAST64 - - SCNxMAX - SCNxPTR - -namespace std -{ - -Types: - - imaxdiv_t - -intmax_t imaxabs(intmax_t j); -imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom); -intmax_t strtoimax(const char* restrict nptr, char** restrict endptr, int base); -uintmax_t strtoumax(const char* restrict nptr, char** restrict endptr, int base); -intmax_t wcstoimax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base); -uintmax_t wcstoumax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base); - -} // std -*/ - -#include <__config> -#include <cstdint> -#include <inttypes.h> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -using ::imaxdiv_t _LIBCPP_USING_IF_EXISTS; -using ::imaxabs _LIBCPP_USING_IF_EXISTS; -using ::imaxdiv _LIBCPP_USING_IF_EXISTS; -using ::strtoimax _LIBCPP_USING_IF_EXISTS; -using ::strtoumax _LIBCPP_USING_IF_EXISTS; -using ::wcstoimax _LIBCPP_USING_IF_EXISTS; -using ::wcstoumax _LIBCPP_USING_IF_EXISTS; - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP_CINTTYPES diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/ciso646 b/contrib/libs/cxxsupp/libcxxmsvc/include/ciso646 deleted file mode 100644 index 1d859f08fa..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/ciso646 +++ /dev/null @@ -1,24 +0,0 @@ -// -*- 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_CISO646 -#define _LIBCPP_CISO646 - -/* - ciso646 synopsis - -*/ - -#include <__config> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#endif // _LIBCPP_CISO646 diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/complex b/contrib/libs/cxxsupp/libcxxmsvc/include/complex deleted file mode 100644 index a11334f6cf..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/complex +++ /dev/null @@ -1,1496 +0,0 @@ -// -*- 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_COMPLEX -#define _LIBCPP_COMPLEX - -/* - complex synopsis - -namespace std -{ - -template<class T> -class complex -{ -public: - typedef T value_type; - - complex(const T& re = T(), const T& im = T()); // constexpr in C++14 - complex(const complex&); // constexpr in C++14 - template<class X> complex(const complex<X>&); // constexpr in C++14 - - T real() const; // constexpr in C++14 - T imag() const; // constexpr in C++14 - - void real(T); - void imag(T); - - complex<T>& operator= (const T&); - complex<T>& operator+=(const T&); - complex<T>& operator-=(const T&); - complex<T>& operator*=(const T&); - complex<T>& operator/=(const T&); - - complex& operator=(const complex&); - template<class X> complex<T>& operator= (const complex<X>&); - template<class X> complex<T>& operator+=(const complex<X>&); - template<class X> complex<T>& operator-=(const complex<X>&); - template<class X> complex<T>& operator*=(const complex<X>&); - template<class X> complex<T>& operator/=(const complex<X>&); -}; - -template<> -class complex<float> -{ -public: - typedef float value_type; - - constexpr complex(float re = 0.0f, float im = 0.0f); - explicit constexpr complex(const complex<double>&); - explicit constexpr complex(const complex<long double>&); - - constexpr float real() const; - void real(float); - constexpr float imag() const; - void imag(float); - - complex<float>& operator= (float); - complex<float>& operator+=(float); - complex<float>& operator-=(float); - complex<float>& operator*=(float); - complex<float>& operator/=(float); - - complex<float>& operator=(const complex<float>&); - template<class X> complex<float>& operator= (const complex<X>&); - template<class X> complex<float>& operator+=(const complex<X>&); - template<class X> complex<float>& operator-=(const complex<X>&); - template<class X> complex<float>& operator*=(const complex<X>&); - template<class X> complex<float>& operator/=(const complex<X>&); -}; - -template<> -class complex<double> -{ -public: - typedef double value_type; - - constexpr complex(double re = 0.0, double im = 0.0); - constexpr complex(const complex<float>&); - explicit constexpr complex(const complex<long double>&); - - constexpr double real() const; - void real(double); - constexpr double imag() const; - void imag(double); - - complex<double>& operator= (double); - complex<double>& operator+=(double); - complex<double>& operator-=(double); - complex<double>& operator*=(double); - complex<double>& operator/=(double); - complex<double>& operator=(const complex<double>&); - - template<class X> complex<double>& operator= (const complex<X>&); - template<class X> complex<double>& operator+=(const complex<X>&); - template<class X> complex<double>& operator-=(const complex<X>&); - template<class X> complex<double>& operator*=(const complex<X>&); - template<class X> complex<double>& operator/=(const complex<X>&); -}; - -template<> -class complex<long double> -{ -public: - typedef long double value_type; - - constexpr complex(long double re = 0.0L, long double im = 0.0L); - constexpr complex(const complex<float>&); - constexpr complex(const complex<double>&); - - constexpr long double real() const; - void real(long double); - constexpr long double imag() const; - void imag(long double); - - complex<long double>& operator=(const complex<long double>&); - complex<long double>& operator= (long double); - complex<long double>& operator+=(long double); - complex<long double>& operator-=(long double); - complex<long double>& operator*=(long double); - complex<long double>& operator/=(long double); - - template<class X> complex<long double>& operator= (const complex<X>&); - template<class X> complex<long double>& operator+=(const complex<X>&); - template<class X> complex<long double>& operator-=(const complex<X>&); - template<class X> complex<long double>& operator*=(const complex<X>&); - template<class X> complex<long double>& operator/=(const complex<X>&); -}; - -// 26.3.6 operators: -template<class T> complex<T> operator+(const complex<T>&, const complex<T>&); -template<class T> complex<T> operator+(const complex<T>&, const T&); -template<class T> complex<T> operator+(const T&, const complex<T>&); -template<class T> complex<T> operator-(const complex<T>&, const complex<T>&); -template<class T> complex<T> operator-(const complex<T>&, const T&); -template<class T> complex<T> operator-(const T&, const complex<T>&); -template<class T> complex<T> operator*(const complex<T>&, const complex<T>&); -template<class T> complex<T> operator*(const complex<T>&, const T&); -template<class T> complex<T> operator*(const T&, const complex<T>&); -template<class T> complex<T> operator/(const complex<T>&, const complex<T>&); -template<class T> complex<T> operator/(const complex<T>&, const T&); -template<class T> complex<T> operator/(const T&, const complex<T>&); -template<class T> complex<T> operator+(const complex<T>&); -template<class T> complex<T> operator-(const complex<T>&); -template<class T> bool operator==(const complex<T>&, const complex<T>&); // constexpr in C++14 -template<class T> bool operator==(const complex<T>&, const T&); // constexpr in C++14 -template<class T> bool operator==(const T&, const complex<T>&); // constexpr in C++14 -template<class T> bool operator!=(const complex<T>&, const complex<T>&); // constexpr in C++14 -template<class T> bool operator!=(const complex<T>&, const T&); // constexpr in C++14 -template<class T> bool operator!=(const T&, const complex<T>&); // constexpr in C++14 - -template<class T, class charT, class traits> - basic_istream<charT, traits>& - operator>>(basic_istream<charT, traits>&, complex<T>&); -template<class T, class charT, class traits> - basic_ostream<charT, traits>& - operator<<(basic_ostream<charT, traits>&, const complex<T>&); - -// 26.3.7 values: - -template<class T> T real(const complex<T>&); // constexpr in C++14 - long double real(long double); // constexpr in C++14 - double real(double); // constexpr in C++14 -template<Integral T> double real(T); // constexpr in C++14 - float real(float); // constexpr in C++14 - -template<class T> T imag(const complex<T>&); // constexpr in C++14 - long double imag(long double); // constexpr in C++14 - double imag(double); // constexpr in C++14 -template<Integral T> double imag(T); // constexpr in C++14 - float imag(float); // constexpr in C++14 - -template<class T> T abs(const complex<T>&); - -template<class T> T arg(const complex<T>&); - long double arg(long double); - double arg(double); -template<Integral T> double arg(T); - float arg(float); - -template<class T> T norm(const complex<T>&); - long double norm(long double); - double norm(double); -template<Integral T> double norm(T); - float norm(float); - -template<class T> complex<T> conj(const complex<T>&); - complex<long double> conj(long double); - complex<double> conj(double); -template<Integral T> complex<double> conj(T); - complex<float> conj(float); - -template<class T> complex<T> proj(const complex<T>&); - complex<long double> proj(long double); - complex<double> proj(double); -template<Integral T> complex<double> proj(T); - complex<float> proj(float); - -template<class T> complex<T> polar(const T&, const T& = T()); - -// 26.3.8 transcendentals: -template<class T> complex<T> acos(const complex<T>&); -template<class T> complex<T> asin(const complex<T>&); -template<class T> complex<T> atan(const complex<T>&); -template<class T> complex<T> acosh(const complex<T>&); -template<class T> complex<T> asinh(const complex<T>&); -template<class T> complex<T> atanh(const complex<T>&); -template<class T> complex<T> cos (const complex<T>&); -template<class T> complex<T> cosh (const complex<T>&); -template<class T> complex<T> exp (const complex<T>&); -template<class T> complex<T> log (const complex<T>&); -template<class T> complex<T> log10(const complex<T>&); - -template<class T> complex<T> pow(const complex<T>&, const T&); -template<class T> complex<T> pow(const complex<T>&, const complex<T>&); -template<class T> complex<T> pow(const T&, const complex<T>&); - -template<class T> complex<T> sin (const complex<T>&); -template<class T> complex<T> sinh (const complex<T>&); -template<class T> complex<T> sqrt (const complex<T>&); -template<class T> complex<T> tan (const complex<T>&); -template<class T> complex<T> tanh (const complex<T>&); - -} // std - -*/ - -#include <__config> -#include <cmath> -#include <iosfwd> -#include <stdexcept> -#include <type_traits> -#include <version> - -#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) -# include <sstream> // for std::basic_ostringstream -#endif - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -template<class _Tp> class _LIBCPP_TEMPLATE_VIS complex; - -template<class _Tp> complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w); -template<class _Tp> complex<_Tp> operator/(const complex<_Tp>& __x, const complex<_Tp>& __y); - -template<class _Tp> -class _LIBCPP_TEMPLATE_VIS complex -{ -public: - typedef _Tp value_type; -private: - value_type __re_; - value_type __im_; -public: - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 - complex(const value_type& __re = value_type(), const value_type& __im = value_type()) - : __re_(__re), __im_(__im) {} - template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 - complex(const complex<_Xp>& __c) - : __re_(__c.real()), __im_(__c.imag()) {} - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type real() const {return __re_;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type imag() const {return __im_;} - - _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;} - _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;} - - _LIBCPP_INLINE_VISIBILITY complex& operator= (const value_type& __re) - {__re_ = __re; __im_ = value_type(); return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator+=(const value_type& __re) {__re_ += __re; return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator-=(const value_type& __re) {__re_ -= __re; return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator*=(const value_type& __re) {__re_ *= __re; __im_ *= __re; return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator/=(const value_type& __re) {__re_ /= __re; __im_ /= __re; return *this;} - - template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) - { - __re_ = __c.real(); - __im_ = __c.imag(); - return *this; - } - template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c) - { - __re_ += __c.real(); - __im_ += __c.imag(); - return *this; - } - template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c) - { - __re_ -= __c.real(); - __im_ -= __c.imag(); - return *this; - } - template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c) - { - *this = *this * complex(__c.real(), __c.imag()); - return *this; - } - template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c) - { - *this = *this / complex(__c.real(), __c.imag()); - return *this; - } -}; - -template<> class _LIBCPP_TEMPLATE_VIS complex<double>; -template<> class _LIBCPP_TEMPLATE_VIS complex<long double>; - -template<> -class _LIBCPP_TEMPLATE_VIS complex<float> -{ - float __re_; - float __im_; -public: - typedef float value_type; - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(float __re = 0.0f, float __im = 0.0f) - : __re_(__re), __im_(__im) {} - _LIBCPP_INLINE_VISIBILITY - explicit _LIBCPP_CONSTEXPR complex(const complex<double>& __c); - _LIBCPP_INLINE_VISIBILITY - explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c); - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float real() const {return __re_;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float imag() const {return __im_;} - - _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;} - _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;} - - _LIBCPP_INLINE_VISIBILITY complex& operator= (float __re) - {__re_ = __re; __im_ = value_type(); return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator+=(float __re) {__re_ += __re; return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator-=(float __re) {__re_ -= __re; return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator*=(float __re) {__re_ *= __re; __im_ *= __re; return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator/=(float __re) {__re_ /= __re; __im_ /= __re; return *this;} - - template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) - { - __re_ = __c.real(); - __im_ = __c.imag(); - return *this; - } - template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c) - { - __re_ += __c.real(); - __im_ += __c.imag(); - return *this; - } - template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c) - { - __re_ -= __c.real(); - __im_ -= __c.imag(); - return *this; - } - template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c) - { - *this = *this * complex(__c.real(), __c.imag()); - return *this; - } - template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c) - { - *this = *this / complex(__c.real(), __c.imag()); - return *this; - } -}; - -template<> -class _LIBCPP_TEMPLATE_VIS complex<double> -{ - double __re_; - double __im_; -public: - typedef double value_type; - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(double __re = 0.0, double __im = 0.0) - : __re_(__re), __im_(__im) {} - _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR complex(const complex<float>& __c); - _LIBCPP_INLINE_VISIBILITY - explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c); - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double real() const {return __re_;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double imag() const {return __im_;} - - _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;} - _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;} - - _LIBCPP_INLINE_VISIBILITY complex& operator= (double __re) - {__re_ = __re; __im_ = value_type(); return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator+=(double __re) {__re_ += __re; return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator-=(double __re) {__re_ -= __re; return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator*=(double __re) {__re_ *= __re; __im_ *= __re; return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator/=(double __re) {__re_ /= __re; __im_ /= __re; return *this;} - - template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) - { - __re_ = __c.real(); - __im_ = __c.imag(); - return *this; - } - template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c) - { - __re_ += __c.real(); - __im_ += __c.imag(); - return *this; - } - template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c) - { - __re_ -= __c.real(); - __im_ -= __c.imag(); - return *this; - } - template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c) - { - *this = *this * complex(__c.real(), __c.imag()); - return *this; - } - template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c) - { - *this = *this / complex(__c.real(), __c.imag()); - return *this; - } -}; - -template<> -class _LIBCPP_TEMPLATE_VIS complex<long double> -{ - long double __re_; - long double __im_; -public: - typedef long double value_type; - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(long double __re = 0.0L, long double __im = 0.0L) - : __re_(__re), __im_(__im) {} - _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR complex(const complex<float>& __c); - _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR complex(const complex<double>& __c); - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double real() const {return __re_;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double imag() const {return __im_;} - - _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;} - _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;} - - _LIBCPP_INLINE_VISIBILITY complex& operator= (long double __re) - {__re_ = __re; __im_ = value_type(); return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator+=(long double __re) {__re_ += __re; return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator-=(long double __re) {__re_ -= __re; return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator*=(long double __re) {__re_ *= __re; __im_ *= __re; return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator/=(long double __re) {__re_ /= __re; __im_ /= __re; return *this;} - - template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) - { - __re_ = __c.real(); - __im_ = __c.imag(); - return *this; - } - template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c) - { - __re_ += __c.real(); - __im_ += __c.imag(); - return *this; - } - template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c) - { - __re_ -= __c.real(); - __im_ -= __c.imag(); - return *this; - } - template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c) - { - *this = *this * complex(__c.real(), __c.imag()); - return *this; - } - template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c) - { - *this = *this / complex(__c.real(), __c.imag()); - return *this; - } -}; - -inline -_LIBCPP_CONSTEXPR -complex<float>::complex(const complex<double>& __c) - : __re_(__c.real()), __im_(__c.imag()) {} - -inline -_LIBCPP_CONSTEXPR -complex<float>::complex(const complex<long double>& __c) - : __re_(__c.real()), __im_(__c.imag()) {} - -inline -_LIBCPP_CONSTEXPR -complex<double>::complex(const complex<float>& __c) - : __re_(__c.real()), __im_(__c.imag()) {} - -inline -_LIBCPP_CONSTEXPR -complex<double>::complex(const complex<long double>& __c) - : __re_(__c.real()), __im_(__c.imag()) {} - -inline -_LIBCPP_CONSTEXPR -complex<long double>::complex(const complex<float>& __c) - : __re_(__c.real()), __im_(__c.imag()) {} - -inline -_LIBCPP_CONSTEXPR -complex<long double>::complex(const complex<double>& __c) - : __re_(__c.real()), __im_(__c.imag()) {} - -// 26.3.6 operators: - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -complex<_Tp> -operator+(const complex<_Tp>& __x, const complex<_Tp>& __y) -{ - complex<_Tp> __t(__x); - __t += __y; - return __t; -} - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -complex<_Tp> -operator+(const complex<_Tp>& __x, const _Tp& __y) -{ - complex<_Tp> __t(__x); - __t += __y; - return __t; -} - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -complex<_Tp> -operator+(const _Tp& __x, const complex<_Tp>& __y) -{ - complex<_Tp> __t(__y); - __t += __x; - return __t; -} - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -complex<_Tp> -operator-(const complex<_Tp>& __x, const complex<_Tp>& __y) -{ - complex<_Tp> __t(__x); - __t -= __y; - return __t; -} - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -complex<_Tp> -operator-(const complex<_Tp>& __x, const _Tp& __y) -{ - complex<_Tp> __t(__x); - __t -= __y; - return __t; -} - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -complex<_Tp> -operator-(const _Tp& __x, const complex<_Tp>& __y) -{ - complex<_Tp> __t(-__y); - __t += __x; - return __t; -} - -template<class _Tp> -complex<_Tp> -operator*(const complex<_Tp>& __z, const complex<_Tp>& __w) -{ - _Tp __a = __z.real(); - _Tp __b = __z.imag(); - _Tp __c = __w.real(); - _Tp __d = __w.imag(); - _Tp __ac = __a * __c; - _Tp __bd = __b * __d; - _Tp __ad = __a * __d; - _Tp __bc = __b * __c; - _Tp __x = __ac - __bd; - _Tp __y = __ad + __bc; - if (__libcpp_isnan_or_builtin(__x) && __libcpp_isnan_or_builtin(__y)) - { - bool __recalc = false; - if (__libcpp_isinf_or_builtin(__a) || __libcpp_isinf_or_builtin(__b)) - { - __a = copysign(__libcpp_isinf_or_builtin(__a) ? _Tp(1) : _Tp(0), __a); - __b = copysign(__libcpp_isinf_or_builtin(__b) ? _Tp(1) : _Tp(0), __b); - if (__libcpp_isnan_or_builtin(__c)) - __c = copysign(_Tp(0), __c); - if (__libcpp_isnan_or_builtin(__d)) - __d = copysign(_Tp(0), __d); - __recalc = true; - } - if (__libcpp_isinf_or_builtin(__c) || __libcpp_isinf_or_builtin(__d)) - { - __c = copysign(__libcpp_isinf_or_builtin(__c) ? _Tp(1) : _Tp(0), __c); - __d = copysign(__libcpp_isinf_or_builtin(__d) ? _Tp(1) : _Tp(0), __d); - if (__libcpp_isnan_or_builtin(__a)) - __a = copysign(_Tp(0), __a); - if (__libcpp_isnan_or_builtin(__b)) - __b = copysign(_Tp(0), __b); - __recalc = true; - } - if (!__recalc && (__libcpp_isinf_or_builtin(__ac) || __libcpp_isinf_or_builtin(__bd) || - __libcpp_isinf_or_builtin(__ad) || __libcpp_isinf_or_builtin(__bc))) - { - if (__libcpp_isnan_or_builtin(__a)) - __a = copysign(_Tp(0), __a); - if (__libcpp_isnan_or_builtin(__b)) - __b = copysign(_Tp(0), __b); - if (__libcpp_isnan_or_builtin(__c)) - __c = copysign(_Tp(0), __c); - if (__libcpp_isnan_or_builtin(__d)) - __d = copysign(_Tp(0), __d); - __recalc = true; - } - if (__recalc) - { - __x = _Tp(INFINITY) * (__a * __c - __b * __d); - __y = _Tp(INFINITY) * (__a * __d + __b * __c); - } - } - return complex<_Tp>(__x, __y); -} - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -complex<_Tp> -operator*(const complex<_Tp>& __x, const _Tp& __y) -{ - complex<_Tp> __t(__x); - __t *= __y; - return __t; -} - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -complex<_Tp> -operator*(const _Tp& __x, const complex<_Tp>& __y) -{ - complex<_Tp> __t(__y); - __t *= __x; - return __t; -} - -template<class _Tp> -complex<_Tp> -operator/(const complex<_Tp>& __z, const complex<_Tp>& __w) -{ - int __ilogbw = 0; - _Tp __a = __z.real(); - _Tp __b = __z.imag(); - _Tp __c = __w.real(); - _Tp __d = __w.imag(); - _Tp __logbw = logb(fmax(fabs(__c), fabs(__d))); - if (__libcpp_isfinite_or_builtin(__logbw)) - { - __ilogbw = static_cast<int>(__logbw); - __c = scalbn(__c, -__ilogbw); - __d = scalbn(__d, -__ilogbw); - } - _Tp __denom = __c * __c + __d * __d; - _Tp __x = scalbn((__a * __c + __b * __d) / __denom, -__ilogbw); - _Tp __y = scalbn((__b * __c - __a * __d) / __denom, -__ilogbw); - if (__libcpp_isnan_or_builtin(__x) && __libcpp_isnan_or_builtin(__y)) - { - if ((__denom == _Tp(0)) && (!__libcpp_isnan_or_builtin(__a) || !__libcpp_isnan_or_builtin(__b))) - { - __x = copysign(_Tp(INFINITY), __c) * __a; - __y = copysign(_Tp(INFINITY), __c) * __b; - } - else if ((__libcpp_isinf_or_builtin(__a) || __libcpp_isinf_or_builtin(__b)) && __libcpp_isfinite_or_builtin(__c) && __libcpp_isfinite_or_builtin(__d)) - { - __a = copysign(__libcpp_isinf_or_builtin(__a) ? _Tp(1) : _Tp(0), __a); - __b = copysign(__libcpp_isinf_or_builtin(__b) ? _Tp(1) : _Tp(0), __b); - __x = _Tp(INFINITY) * (__a * __c + __b * __d); - __y = _Tp(INFINITY) * (__b * __c - __a * __d); - } - else if (__libcpp_isinf_or_builtin(__logbw) && __logbw > _Tp(0) && __libcpp_isfinite_or_builtin(__a) && __libcpp_isfinite_or_builtin(__b)) - { - __c = copysign(__libcpp_isinf_or_builtin(__c) ? _Tp(1) : _Tp(0), __c); - __d = copysign(__libcpp_isinf_or_builtin(__d) ? _Tp(1) : _Tp(0), __d); - __x = _Tp(0) * (__a * __c + __b * __d); - __y = _Tp(0) * (__b * __c - __a * __d); - } - } - return complex<_Tp>(__x, __y); -} - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -complex<_Tp> -operator/(const complex<_Tp>& __x, const _Tp& __y) -{ - return complex<_Tp>(__x.real() / __y, __x.imag() / __y); -} - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -complex<_Tp> -operator/(const _Tp& __x, const complex<_Tp>& __y) -{ - complex<_Tp> __t(__x); - __t /= __y; - return __t; -} - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -complex<_Tp> -operator+(const complex<_Tp>& __x) -{ - return __x; -} - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -complex<_Tp> -operator-(const complex<_Tp>& __x) -{ - return complex<_Tp>(-__x.real(), -__x.imag()); -} - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -bool -operator==(const complex<_Tp>& __x, const complex<_Tp>& __y) -{ - return __x.real() == __y.real() && __x.imag() == __y.imag(); -} - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -bool -operator==(const complex<_Tp>& __x, const _Tp& __y) -{ - return __x.real() == __y && __x.imag() == 0; -} - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -bool -operator==(const _Tp& __x, const complex<_Tp>& __y) -{ - return __x == __y.real() && 0 == __y.imag(); -} - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -bool -operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y) -{ - return !(__x == __y); -} - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -bool -operator!=(const complex<_Tp>& __x, const _Tp& __y) -{ - return !(__x == __y); -} - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -bool -operator!=(const _Tp& __x, const complex<_Tp>& __y) -{ - return !(__x == __y); -} - -// 26.3.7 values: - -template <class _Tp, bool = is_integral<_Tp>::value, - bool = is_floating_point<_Tp>::value - > -struct __libcpp_complex_overload_traits {}; - -// Integral Types -template <class _Tp> -struct __libcpp_complex_overload_traits<_Tp, true, false> -{ - typedef double _ValueType; - typedef complex<double> _ComplexType; -}; - -// Floating point types -template <class _Tp> -struct __libcpp_complex_overload_traits<_Tp, false, true> -{ - typedef _Tp _ValueType; - typedef complex<_Tp> _ComplexType; -}; - -// real - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -_Tp -real(const complex<_Tp>& __c) -{ - return __c.real(); -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -typename __libcpp_complex_overload_traits<_Tp>::_ValueType -real(_Tp __re) -{ - return __re; -} - -// imag - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -_Tp -imag(const complex<_Tp>& __c) -{ - return __c.imag(); -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -typename __libcpp_complex_overload_traits<_Tp>::_ValueType -imag(_Tp) -{ - return 0; -} - -// abs - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -_Tp -abs(const complex<_Tp>& __c) -{ - return hypot(__c.real(), __c.imag()); -} - -// arg - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -_Tp -arg(const complex<_Tp>& __c) -{ - return atan2(__c.imag(), __c.real()); -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if< - is_same<_Tp, long double>::value, - long double ->::type -arg(_Tp __re) -{ - return atan2l(0.L, __re); -} - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_integral<_Tp>::value || is_same<_Tp, double>::value, - double ->::type -arg(_Tp __re) -{ - return atan2(0., __re); -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if< - is_same<_Tp, float>::value, - float ->::type -arg(_Tp __re) -{ - return atan2f(0.F, __re); -} - -// norm - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -_Tp -norm(const complex<_Tp>& __c) -{ - if (__libcpp_isinf_or_builtin(__c.real())) - return abs(__c.real()); - if (__libcpp_isinf_or_builtin(__c.imag())) - return abs(__c.imag()); - return __c.real() * __c.real() + __c.imag() * __c.imag(); -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -typename __libcpp_complex_overload_traits<_Tp>::_ValueType -norm(_Tp __re) -{ - typedef typename __libcpp_complex_overload_traits<_Tp>::_ValueType _ValueType; - return static_cast<_ValueType>(__re) * __re; -} - -// conj - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -complex<_Tp> -conj(const complex<_Tp>& __c) -{ - return complex<_Tp>(__c.real(), -__c.imag()); -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -typename __libcpp_complex_overload_traits<_Tp>::_ComplexType -conj(_Tp __re) -{ - typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType; - return _ComplexType(__re); -} - - - -// proj - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -complex<_Tp> -proj(const complex<_Tp>& __c) -{ - complex<_Tp> __r = __c; - if (__libcpp_isinf_or_builtin(__c.real()) || __libcpp_isinf_or_builtin(__c.imag())) - __r = complex<_Tp>(INFINITY, copysign(_Tp(0), __c.imag())); - return __r; -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_floating_point<_Tp>::value, - typename __libcpp_complex_overload_traits<_Tp>::_ComplexType ->::type -proj(_Tp __re) -{ - if (__libcpp_isinf_or_builtin(__re)) - __re = abs(__re); - return complex<_Tp>(__re); -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_integral<_Tp>::value, - typename __libcpp_complex_overload_traits<_Tp>::_ComplexType ->::type -proj(_Tp __re) -{ - typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType; - return _ComplexType(__re); -} - -// polar - -template<class _Tp> -complex<_Tp> -polar(const _Tp& __rho, const _Tp& __theta = _Tp()) -{ - if (__libcpp_isnan_or_builtin(__rho) || signbit(__rho)) - return complex<_Tp>(_Tp(NAN), _Tp(NAN)); - if (__libcpp_isnan_or_builtin(__theta)) - { - if (__libcpp_isinf_or_builtin(__rho)) - return complex<_Tp>(__rho, __theta); - return complex<_Tp>(__theta, __theta); - } - if (__libcpp_isinf_or_builtin(__theta)) - { - if (__libcpp_isinf_or_builtin(__rho)) - return complex<_Tp>(__rho, _Tp(NAN)); - return complex<_Tp>(_Tp(NAN), _Tp(NAN)); - } - _Tp __x = __rho * cos(__theta); - if (__libcpp_isnan_or_builtin(__x)) - __x = 0; - _Tp __y = __rho * sin(__theta); - if (__libcpp_isnan_or_builtin(__y)) - __y = 0; - return complex<_Tp>(__x, __y); -} - -// log - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -complex<_Tp> -log(const complex<_Tp>& __x) -{ - return complex<_Tp>(log(abs(__x)), arg(__x)); -} - -// log10 - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -complex<_Tp> -log10(const complex<_Tp>& __x) -{ - return log(__x) / log(_Tp(10)); -} - -// sqrt - -template<class _Tp> -complex<_Tp> -sqrt(const complex<_Tp>& __x) -{ - if (__libcpp_isinf_or_builtin(__x.imag())) - return complex<_Tp>(_Tp(INFINITY), __x.imag()); - if (__libcpp_isinf_or_builtin(__x.real())) - { - if (__x.real() > _Tp(0)) - return complex<_Tp>(__x.real(), __libcpp_isnan_or_builtin(__x.imag()) ? __x.imag() : copysign(_Tp(0), __x.imag())); - return complex<_Tp>(__libcpp_isnan_or_builtin(__x.imag()) ? __x.imag() : _Tp(0), copysign(__x.real(), __x.imag())); - } - return polar(sqrt(abs(__x)), arg(__x) / _Tp(2)); -} - -// exp - -template<class _Tp> -complex<_Tp> -exp(const complex<_Tp>& __x) -{ - _Tp __i = __x.imag(); - if (__i == 0) { - return complex<_Tp>(exp(__x.real()), copysign(_Tp(0), __x.imag())); - } - if (__libcpp_isinf_or_builtin(__x.real())) - { - if (__x.real() < _Tp(0)) - { - if (!__libcpp_isfinite_or_builtin(__i)) - __i = _Tp(1); - } - else if (__i == 0 || !__libcpp_isfinite_or_builtin(__i)) - { - if (__libcpp_isinf_or_builtin(__i)) - __i = _Tp(NAN); - return complex<_Tp>(__x.real(), __i); - } - } - _Tp __e = exp(__x.real()); - return complex<_Tp>(__e * cos(__i), __e * sin(__i)); -} - -// pow - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -complex<_Tp> -pow(const complex<_Tp>& __x, const complex<_Tp>& __y) -{ - return exp(__y * log(__x)); -} - -template<class _Tp, class _Up> -inline _LIBCPP_INLINE_VISIBILITY -complex<typename __promote<_Tp, _Up>::type> -pow(const complex<_Tp>& __x, const complex<_Up>& __y) -{ - typedef complex<typename __promote<_Tp, _Up>::type> result_type; - return _VSTD::pow(result_type(__x), result_type(__y)); -} - -template<class _Tp, class _Up> -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_arithmetic<_Up>::value, - complex<typename __promote<_Tp, _Up>::type> ->::type -pow(const complex<_Tp>& __x, const _Up& __y) -{ - typedef complex<typename __promote<_Tp, _Up>::type> result_type; - return _VSTD::pow(result_type(__x), result_type(__y)); -} - -template<class _Tp, class _Up> -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_arithmetic<_Tp>::value, - complex<typename __promote<_Tp, _Up>::type> ->::type -pow(const _Tp& __x, const complex<_Up>& __y) -{ - typedef complex<typename __promote<_Tp, _Up>::type> result_type; - return _VSTD::pow(result_type(__x), result_type(__y)); -} - -// __sqr, computes pow(x, 2) - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -complex<_Tp> -__sqr(const complex<_Tp>& __x) -{ - return complex<_Tp>((__x.real() - __x.imag()) * (__x.real() + __x.imag()), - _Tp(2) * __x.real() * __x.imag()); -} - -// asinh - -template<class _Tp> -complex<_Tp> -asinh(const complex<_Tp>& __x) -{ - const _Tp __pi(atan2(+0., -0.)); - if (__libcpp_isinf_or_builtin(__x.real())) - { - if (__libcpp_isnan_or_builtin(__x.imag())) - return __x; - if (__libcpp_isinf_or_builtin(__x.imag())) - return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag())); - return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag())); - } - if (__libcpp_isnan_or_builtin(__x.real())) - { - if (__libcpp_isinf_or_builtin(__x.imag())) - return complex<_Tp>(__x.imag(), __x.real()); - if (__x.imag() == 0) - return __x; - return complex<_Tp>(__x.real(), __x.real()); - } - if (__libcpp_isinf_or_builtin(__x.imag())) - return complex<_Tp>(copysign(__x.imag(), __x.real()), copysign(__pi/_Tp(2), __x.imag())); - complex<_Tp> __z = log(__x + sqrt(__sqr(__x) + _Tp(1))); - return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag())); -} - -// acosh - -template<class _Tp> -complex<_Tp> -acosh(const complex<_Tp>& __x) -{ - const _Tp __pi(atan2(+0., -0.)); - if (__libcpp_isinf_or_builtin(__x.real())) - { - if (__libcpp_isnan_or_builtin(__x.imag())) - return complex<_Tp>(abs(__x.real()), __x.imag()); - if (__libcpp_isinf_or_builtin(__x.imag())) - { - if (__x.real() > 0) - return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag())); - else - return complex<_Tp>(-__x.real(), copysign(__pi * _Tp(0.75), __x.imag())); - } - if (__x.real() < 0) - return complex<_Tp>(-__x.real(), copysign(__pi, __x.imag())); - return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag())); - } - if (__libcpp_isnan_or_builtin(__x.real())) - { - if (__libcpp_isinf_or_builtin(__x.imag())) - return complex<_Tp>(abs(__x.imag()), __x.real()); - return complex<_Tp>(__x.real(), __x.real()); - } - if (__libcpp_isinf_or_builtin(__x.imag())) - return complex<_Tp>(abs(__x.imag()), copysign(__pi/_Tp(2), __x.imag())); - complex<_Tp> __z = log(__x + sqrt(__sqr(__x) - _Tp(1))); - return complex<_Tp>(copysign(__z.real(), _Tp(0)), copysign(__z.imag(), __x.imag())); -} - -// atanh - -template<class _Tp> -complex<_Tp> -atanh(const complex<_Tp>& __x) -{ - const _Tp __pi(atan2(+0., -0.)); - if (__libcpp_isinf_or_builtin(__x.imag())) - { - return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag())); - } - if (__libcpp_isnan_or_builtin(__x.imag())) - { - if (__libcpp_isinf_or_builtin(__x.real()) || __x.real() == 0) - return complex<_Tp>(copysign(_Tp(0), __x.real()), __x.imag()); - return complex<_Tp>(__x.imag(), __x.imag()); - } - if (__libcpp_isnan_or_builtin(__x.real())) - { - return complex<_Tp>(__x.real(), __x.real()); - } - if (__libcpp_isinf_or_builtin(__x.real())) - { - return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag())); - } - if (abs(__x.real()) == _Tp(1) && __x.imag() == _Tp(0)) - { - return complex<_Tp>(copysign(_Tp(INFINITY), __x.real()), copysign(_Tp(0), __x.imag())); - } - complex<_Tp> __z = log((_Tp(1) + __x) / (_Tp(1) - __x)) / _Tp(2); - return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag())); -} - -// sinh - -template<class _Tp> -complex<_Tp> -sinh(const complex<_Tp>& __x) -{ - if (__libcpp_isinf_or_builtin(__x.real()) && !__libcpp_isfinite_or_builtin(__x.imag())) - return complex<_Tp>(__x.real(), _Tp(NAN)); - if (__x.real() == 0 && !__libcpp_isfinite_or_builtin(__x.imag())) - return complex<_Tp>(__x.real(), _Tp(NAN)); - if (__x.imag() == 0 && !__libcpp_isfinite_or_builtin(__x.real())) - return __x; - return complex<_Tp>(sinh(__x.real()) * cos(__x.imag()), cosh(__x.real()) * sin(__x.imag())); -} - -// cosh - -template<class _Tp> -complex<_Tp> -cosh(const complex<_Tp>& __x) -{ - if (__libcpp_isinf_or_builtin(__x.real()) && !__libcpp_isfinite_or_builtin(__x.imag())) - return complex<_Tp>(abs(__x.real()), _Tp(NAN)); - if (__x.real() == 0 && !__libcpp_isfinite_or_builtin(__x.imag())) - return complex<_Tp>(_Tp(NAN), __x.real()); - if (__x.real() == 0 && __x.imag() == 0) - return complex<_Tp>(_Tp(1), __x.imag()); - if (__x.imag() == 0 && !__libcpp_isfinite_or_builtin(__x.real())) - return complex<_Tp>(abs(__x.real()), __x.imag()); - return complex<_Tp>(cosh(__x.real()) * cos(__x.imag()), sinh(__x.real()) * sin(__x.imag())); -} - -// tanh - -template<class _Tp> -complex<_Tp> -tanh(const complex<_Tp>& __x) -{ - if (__libcpp_isinf_or_builtin(__x.real())) - { - if (!__libcpp_isfinite_or_builtin(__x.imag())) - return complex<_Tp>(copysign(_Tp(1), __x.real()), _Tp(0)); - return complex<_Tp>(copysign(_Tp(1), __x.real()), copysign(_Tp(0), sin(_Tp(2) * __x.imag()))); - } - if (__libcpp_isnan_or_builtin(__x.real()) && __x.imag() == 0) - return __x; - _Tp __2r(_Tp(2) * __x.real()); - _Tp __2i(_Tp(2) * __x.imag()); - _Tp __d(cosh(__2r) + cos(__2i)); - _Tp __2rsh(sinh(__2r)); - if (__libcpp_isinf_or_builtin(__2rsh) && __libcpp_isinf_or_builtin(__d)) - return complex<_Tp>(__2rsh > _Tp(0) ? _Tp(1) : _Tp(-1), - __2i > _Tp(0) ? _Tp(0) : _Tp(-0.)); - return complex<_Tp>(__2rsh/__d, sin(__2i)/__d); -} - -// asin - -template<class _Tp> -complex<_Tp> -asin(const complex<_Tp>& __x) -{ - complex<_Tp> __z = asinh(complex<_Tp>(-__x.imag(), __x.real())); - return complex<_Tp>(__z.imag(), -__z.real()); -} - -// acos - -template<class _Tp> -complex<_Tp> -acos(const complex<_Tp>& __x) -{ - const _Tp __pi(atan2(+0., -0.)); - if (__libcpp_isinf_or_builtin(__x.real())) - { - if (__libcpp_isnan_or_builtin(__x.imag())) - return complex<_Tp>(__x.imag(), __x.real()); - if (__libcpp_isinf_or_builtin(__x.imag())) - { - if (__x.real() < _Tp(0)) - return complex<_Tp>(_Tp(0.75) * __pi, -__x.imag()); - return complex<_Tp>(_Tp(0.25) * __pi, -__x.imag()); - } - if (__x.real() < _Tp(0)) - return complex<_Tp>(__pi, signbit(__x.imag()) ? -__x.real() : __x.real()); - return complex<_Tp>(_Tp(0), signbit(__x.imag()) ? __x.real() : -__x.real()); - } - if (__libcpp_isnan_or_builtin(__x.real())) - { - if (__libcpp_isinf_or_builtin(__x.imag())) - return complex<_Tp>(__x.real(), -__x.imag()); - return complex<_Tp>(__x.real(), __x.real()); - } - if (__libcpp_isinf_or_builtin(__x.imag())) - return complex<_Tp>(__pi/_Tp(2), -__x.imag()); - if (__x.real() == 0 && (__x.imag() == 0 || isnan(__x.imag()))) - return complex<_Tp>(__pi/_Tp(2), -__x.imag()); - complex<_Tp> __z = log(__x + sqrt(__sqr(__x) - _Tp(1))); - if (signbit(__x.imag())) - return complex<_Tp>(abs(__z.imag()), abs(__z.real())); - return complex<_Tp>(abs(__z.imag()), -abs(__z.real())); -} - -// atan - -template<class _Tp> -complex<_Tp> -atan(const complex<_Tp>& __x) -{ - complex<_Tp> __z = atanh(complex<_Tp>(-__x.imag(), __x.real())); - return complex<_Tp>(__z.imag(), -__z.real()); -} - -// sin - -template<class _Tp> -complex<_Tp> -sin(const complex<_Tp>& __x) -{ - complex<_Tp> __z = sinh(complex<_Tp>(-__x.imag(), __x.real())); - return complex<_Tp>(__z.imag(), -__z.real()); -} - -// cos - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -complex<_Tp> -cos(const complex<_Tp>& __x) -{ - return cosh(complex<_Tp>(-__x.imag(), __x.real())); -} - -// tan - -template<class _Tp> -complex<_Tp> -tan(const complex<_Tp>& __x) -{ - complex<_Tp> __z = tanh(complex<_Tp>(-__x.imag(), __x.real())); - return complex<_Tp>(__z.imag(), -__z.real()); -} - -template<class _Tp, class _CharT, class _Traits> -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) -{ - if (__is.good()) - { - ws(__is); - if (__is.peek() == _CharT('(')) - { - __is.get(); - _Tp __r; - __is >> __r; - if (!__is.fail()) - { - ws(__is); - _CharT __c = __is.peek(); - if (__c == _CharT(',')) - { - __is.get(); - _Tp __i; - __is >> __i; - if (!__is.fail()) - { - ws(__is); - __c = __is.peek(); - if (__c == _CharT(')')) - { - __is.get(); - __x = complex<_Tp>(__r, __i); - } - else - __is.setstate(__is.failbit); - } - else - __is.setstate(__is.failbit); - } - else if (__c == _CharT(')')) - { - __is.get(); - __x = complex<_Tp>(__r, _Tp(0)); - } - else - __is.setstate(__is.failbit); - } - else - __is.setstate(__is.failbit); - } - else - { - _Tp __r; - __is >> __r; - if (!__is.fail()) - __x = complex<_Tp>(__r, _Tp(0)); - else - __is.setstate(__is.failbit); - } - } - else - __is.setstate(__is.failbit); - return __is; -} - -#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) -template<class _Tp, class _CharT, class _Traits> -basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) -{ - basic_ostringstream<_CharT, _Traits> __s; - __s.flags(__os.flags()); - __s.imbue(__os.getloc()); - __s.precision(__os.precision()); - __s << '(' << __x.real() << ',' << __x.imag() << ')'; - return __os << __s.str(); -} -#endif // !_LIBCPP_HAS_NO_LOCALIZATION - -#if _LIBCPP_STD_VER > 11 -// Literal suffix for complex number literals [complex.literals] -inline namespace literals -{ - inline namespace complex_literals - { - constexpr complex<long double> operator""il(long double __im) - { - return { 0.0l, __im }; - } - - constexpr complex<long double> operator""il(unsigned long long __im) - { - return { 0.0l, static_cast<long double>(__im) }; - } - - - constexpr complex<double> operator""i(long double __im) - { - return { 0.0, static_cast<double>(__im) }; - } - - constexpr complex<double> operator""i(unsigned long long __im) - { - return { 0.0, static_cast<double>(__im) }; - } - - -#if !defined(__CUDACC__) - constexpr complex<float> operator""if(long double __im) - { - return { 0.0f, static_cast<float>(__im) }; - } - - constexpr complex<float> operator""if(unsigned long long __im) - { - return { 0.0f, static_cast<float>(__im) }; - } -#endif - } // namespace complex_literals -} // namespace literals -#endif - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP_COMPLEX diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/complex.h b/contrib/libs/cxxsupp/libcxxmsvc/include/complex.h deleted file mode 100644 index 58cbbaaeef..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/complex.h +++ /dev/null @@ -1,40 +0,0 @@ -// -*- 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_COMPLEX_H -#define _LIBCPP_COMPLEX_H - -/* - complex.h synopsis - -#include <ccomplex> - -*/ - -#include <__config> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#ifdef __cplusplus - -#include <ccomplex> - -#else // __cplusplus - -#ifdef _LIBCPP_COMPILER_MSVC -#include Y_UCRT_INCLUDE_NEXT(complex.h) -#else -#include_next <complex.h> -#endif - -#endif // __cplusplus - -#endif // _LIBCPP_COMPLEX_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/coroutine b/contrib/libs/cxxsupp/libcxxmsvc/include/coroutine deleted file mode 100644 index 478f4723f9..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/coroutine +++ /dev/null @@ -1,52 +0,0 @@ -// -*- 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_COROUTINE -#define _LIBCPP_COROUTINE - -/** - coroutine synopsis - -namespace std { -// [coroutine.traits] -template <class R, class... ArgTypes> - struct coroutine_traits; -// [coroutine.handle] -template <class Promise = void> - struct coroutine_handle; -// [coroutine.handle.compare] -constexpr bool operator==(coroutine_handle<> x, coroutine_handle<> y) noexcept; -constexpr strong_ordering operator<=>(coroutine_handle<> x, coroutine_handle<> y) noexcept; -// [coroutine.handle.hash] -template <class T> struct hash; -template <class P> struct hash<coroutine_handle<P>>; -// [coroutine.noop] -struct noop_coroutine_promise; -template<> struct coroutine_handle<noop_coroutine_promise>; -using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>; -noop_coroutine_handle noop_coroutine() noexcept; -// [coroutine.trivial.awaitables] -struct suspend_never; -struct suspend_always; -} // namespace std - - */ - -#include <__config> -#include <__coroutine/coroutine_handle.h> -#include <__coroutine/coroutine_traits.h> -#include <__coroutine/noop_coroutine_handle.h> -#include <__coroutine/trivial_awaitables.h> -#include <version> - -#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER -# pragma GCC system_header -#endif - -#endif // _LIBCPP_COROUTINE diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/csetjmp b/contrib/libs/cxxsupp/libcxxmsvc/include/csetjmp deleted file mode 100644 index 76cbaab4c3..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/csetjmp +++ /dev/null @@ -1,47 +0,0 @@ -// -*- 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_CSETJMP -#define _LIBCPP_CSETJMP - -/* - csetjmp synopsis - -Macros: - - setjmp - -namespace std -{ - -Types: - - jmp_buf - -void longjmp(jmp_buf env, int val); - -} // std - -*/ - -#include <__config> -#include <setjmp.h> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -using ::jmp_buf _LIBCPP_USING_IF_EXISTS; -using ::longjmp _LIBCPP_USING_IF_EXISTS; - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP_CSETJMP diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/csignal b/contrib/libs/cxxsupp/libcxxmsvc/include/csignal deleted file mode 100644 index 19091cfaa2..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/csignal +++ /dev/null @@ -1,57 +0,0 @@ -// -*- 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_CSIGNAL -#define _LIBCPP_CSIGNAL - -/* - csignal synopsis - -Macros: - - SIG_DFL - SIG_ERR - SIG_IGN - SIGABRT - SIGFPE - SIGILL - SIGINT - SIGSEGV - SIGTERM - -namespace std -{ - -Types: - - sig_atomic_t - -void (*signal(int sig, void (*func)(int)))(int); -int raise(int sig); - -} // std - -*/ - -#include <__config> -#include <signal.h> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -using ::sig_atomic_t _LIBCPP_USING_IF_EXISTS; -using ::signal _LIBCPP_USING_IF_EXISTS; -using ::raise _LIBCPP_USING_IF_EXISTS; - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP_CSIGNAL diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/fenv.h b/contrib/libs/cxxsupp/libcxxmsvc/include/fenv.h deleted file mode 100644 index 5a8cebf65f..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/fenv.h +++ /dev/null @@ -1,120 +0,0 @@ -// -*- 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_FENV_H -#define _LIBCPP_FENV_H - - -/* - fenv.h synopsis - -This entire header is C99 / C++0X - -Macros: - - FE_DIVBYZERO - FE_INEXACT - FE_INVALID - FE_OVERFLOW - FE_UNDERFLOW - FE_ALL_EXCEPT - FE_DOWNWARD - FE_TONEAREST - FE_TOWARDZERO - FE_UPWARD - FE_DFL_ENV - -Types: - - fenv_t - fexcept_t - -int feclearexcept(int excepts); -int fegetexceptflag(fexcept_t* flagp, int excepts); -int feraiseexcept(int excepts); -int fesetexceptflag(const fexcept_t* flagp, int excepts); -int fetestexcept(int excepts); -int fegetround(); -int fesetround(int round); -int fegetenv(fenv_t* envp); -int feholdexcept(fenv_t* envp); -int fesetenv(const fenv_t* envp); -int feupdateenv(const fenv_t* envp); - - -*/ - -#include <__config> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#ifdef _LIBCPP_COMPILER_MSVC -#include Y_UCRT_INCLUDE_NEXT(fenv.h) -#else -#include_next <fenv.h> -#endif - -#ifdef __cplusplus - -extern "C++" { - -#ifdef feclearexcept -#undef feclearexcept -#endif - -#ifdef fegetexceptflag -#undef fegetexceptflag -#endif - - -#ifdef feraiseexcept -#undef feraiseexcept -#endif - -#ifdef fesetexceptflag -#undef fesetexceptflag -#endif - - -#ifdef fetestexcept -#undef fetestexcept -#endif - -#ifdef fegetround -#undef fegetround -#endif - -#ifdef fesetround -#undef fesetround -#endif - -#ifdef fegetenv -#undef fegetenv -#endif - -#ifdef feholdexcept -#undef feholdexcept -#endif - - -#ifdef fesetenv -#undef fesetenv -#endif - -#ifdef feupdateenv -#undef feupdateenv -#endif - -} // extern "C++" - -#endif // defined(__cplusplus) - -#endif // _LIBCPP_FENV_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/forward_list b/contrib/libs/cxxsupp/libcxxmsvc/include/forward_list deleted file mode 100644 index e01a8e7189..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/forward_list +++ /dev/null @@ -1,1791 +0,0 @@ -// -*- 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_FORWARD_LIST -#define _LIBCPP_FORWARD_LIST - -/* - forward_list synopsis - -namespace std -{ - -template <class T, class Allocator = allocator<T>> -class forward_list -{ -public: - typedef T value_type; - typedef Allocator allocator_type; - - typedef value_type& reference; - typedef const value_type& const_reference; - typedef typename allocator_traits<allocator_type>::pointer pointer; - typedef typename allocator_traits<allocator_type>::const_pointer const_pointer; - typedef typename allocator_traits<allocator_type>::size_type size_type; - typedef typename allocator_traits<allocator_type>::difference_type difference_type; - - typedef <details> iterator; - typedef <details> const_iterator; - - forward_list() - noexcept(is_nothrow_default_constructible<allocator_type>::value); - explicit forward_list(const allocator_type& a); - explicit forward_list(size_type n); - explicit forward_list(size_type n, const allocator_type& a); // C++14 - forward_list(size_type n, const value_type& v); - forward_list(size_type n, const value_type& v, const allocator_type& a); - template <class InputIterator> - forward_list(InputIterator first, InputIterator last); - template <class InputIterator> - forward_list(InputIterator first, InputIterator last, const allocator_type& a); - forward_list(const forward_list& x); - forward_list(const forward_list& x, const allocator_type& a); - forward_list(forward_list&& x) - noexcept(is_nothrow_move_constructible<allocator_type>::value); - forward_list(forward_list&& x, const allocator_type& a); - forward_list(initializer_list<value_type> il); - forward_list(initializer_list<value_type> il, const allocator_type& a); - - ~forward_list(); - - forward_list& operator=(const forward_list& x); - forward_list& operator=(forward_list&& x) - noexcept( - allocator_type::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<allocator_type>::value); - forward_list& operator=(initializer_list<value_type> il); - - template <class InputIterator> - void assign(InputIterator first, InputIterator last); - void assign(size_type n, const value_type& v); - void assign(initializer_list<value_type> il); - - allocator_type get_allocator() const noexcept; - - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; - - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - - iterator before_begin() noexcept; - const_iterator before_begin() const noexcept; - const_iterator cbefore_begin() const noexcept; - - bool empty() const noexcept; - size_type max_size() const noexcept; - - reference front(); - const_reference front() const; - - template <class... Args> reference emplace_front(Args&&... args); // reference in C++17 - void push_front(const value_type& v); - void push_front(value_type&& v); - - void pop_front(); - - template <class... Args> - iterator emplace_after(const_iterator p, Args&&... args); - iterator insert_after(const_iterator p, const value_type& v); - iterator insert_after(const_iterator p, value_type&& v); - iterator insert_after(const_iterator p, size_type n, const value_type& v); - template <class InputIterator> - iterator insert_after(const_iterator p, - InputIterator first, InputIterator last); - iterator insert_after(const_iterator p, initializer_list<value_type> il); - - iterator erase_after(const_iterator p); - iterator erase_after(const_iterator first, const_iterator last); - - void swap(forward_list& x) - noexcept(allocator_traits<allocator_type>::is_always_equal::value); // C++17 - - void resize(size_type n); - void resize(size_type n, const value_type& v); - void clear() noexcept; - - void splice_after(const_iterator p, forward_list& x); - void splice_after(const_iterator p, forward_list&& x); - void splice_after(const_iterator p, forward_list& x, const_iterator i); - void splice_after(const_iterator p, forward_list&& x, const_iterator i); - void splice_after(const_iterator p, forward_list& x, - const_iterator first, const_iterator last); - void splice_after(const_iterator p, forward_list&& x, - const_iterator first, const_iterator last); - size_type remove(const value_type& v); // void before C++20 - template <class Predicate> - size_type remove_if(Predicate pred); // void before C++20 - size_type unique(); // void before C++20 - template <class BinaryPredicate> - size_type unique(BinaryPredicate binary_pred); // void before C++20 - void merge(forward_list& x); - void merge(forward_list&& x); - template <class Compare> void merge(forward_list& x, Compare comp); - template <class Compare> void merge(forward_list&& x, Compare comp); - void sort(); - template <class Compare> void sort(Compare comp); - void reverse() noexcept; -}; - - -template <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>> - forward_list(InputIterator, InputIterator, Allocator = Allocator()) - -> forward_list<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17 - -template <class T, class Allocator> - bool operator==(const forward_list<T, Allocator>& x, - const forward_list<T, Allocator>& y); - -template <class T, class Allocator> - bool operator< (const forward_list<T, Allocator>& x, - const forward_list<T, Allocator>& y); - -template <class T, class Allocator> - bool operator!=(const forward_list<T, Allocator>& x, - const forward_list<T, Allocator>& y); - -template <class T, class Allocator> - bool operator> (const forward_list<T, Allocator>& x, - const forward_list<T, Allocator>& y); - -template <class T, class Allocator> - bool operator>=(const forward_list<T, Allocator>& x, - const forward_list<T, Allocator>& y); - -template <class T, class Allocator> - bool operator<=(const forward_list<T, Allocator>& x, - const forward_list<T, Allocator>& y); - -template <class T, class Allocator> - void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y) - noexcept(noexcept(x.swap(y))); - -template <class T, class Allocator, class U> - typename forward_list<T, Allocator>::size_type - erase(forward_list<T, Allocator>& c, const U& value); // C++20 -template <class T, class Allocator, class Predicate> - typename forward_list<T, Allocator>::size_type - erase_if(forward_list<T, Allocator>& c, Predicate pred); // C++20 - -} // std - -*/ - -#include <__algorithm/comp.h> -#include <__algorithm/lexicographical_compare.h> -#include <__algorithm/min.h> -#include <__config> -#include <__utility/forward.h> -#include <initializer_list> -#include <iterator> -#include <limits> -#include <memory> -#include <type_traits> -#include <version> - -#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 _Tp, class _VoidPtr> struct __forward_list_node; -template <class _NodePtr> struct __forward_begin_node; - - -template <class> -struct __forward_list_node_value_type; - -template <class _Tp, class _VoidPtr> -struct __forward_list_node_value_type<__forward_list_node<_Tp, _VoidPtr> > { - typedef _Tp type; -}; - -template <class _NodePtr> -struct __forward_node_traits { - - typedef typename remove_cv< - typename pointer_traits<_NodePtr>::element_type>::type __node; - typedef typename __forward_list_node_value_type<__node>::type __node_value_type; - typedef _NodePtr __node_pointer; - typedef __forward_begin_node<_NodePtr> __begin_node; - typedef typename __rebind_pointer<_NodePtr, __begin_node>::type - __begin_node_pointer; - typedef typename __rebind_pointer<_NodePtr, void>::type __void_pointer; - -#if defined(_LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB) - typedef __begin_node_pointer __iter_node_pointer; -#else - typedef typename conditional< - is_pointer<__void_pointer>::value, - __begin_node_pointer, - __node_pointer - >::type __iter_node_pointer; -#endif - - typedef typename conditional< - is_same<__iter_node_pointer, __node_pointer>::value, - __begin_node_pointer, - __node_pointer - >::type __non_iter_node_pointer; - - _LIBCPP_INLINE_VISIBILITY - static __iter_node_pointer __as_iter_node(__iter_node_pointer __p) { - return __p; - } - _LIBCPP_INLINE_VISIBILITY - static __iter_node_pointer __as_iter_node(__non_iter_node_pointer __p) { - return static_cast<__iter_node_pointer>(static_cast<__void_pointer>(__p)); - } -}; - -template <class _NodePtr> -struct __forward_begin_node -{ - typedef _NodePtr pointer; - typedef typename __rebind_pointer<_NodePtr, __forward_begin_node>::type __begin_node_pointer; - - pointer __next_; - - _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {} - - _LIBCPP_INLINE_VISIBILITY - __begin_node_pointer __next_as_begin() const { - return static_cast<__begin_node_pointer>(__next_); - } -}; - -template <class _Tp, class _VoidPtr> -struct _LIBCPP_HIDDEN __begin_node_of -{ - typedef __forward_begin_node< - typename __rebind_pointer<_VoidPtr, __forward_list_node<_Tp, _VoidPtr> >::type - > type; -}; - -template <class _Tp, class _VoidPtr> -struct _LIBCPP_STANDALONE_DEBUG __forward_list_node - : public __begin_node_of<_Tp, _VoidPtr>::type -{ - typedef _Tp value_type; - - value_type __value_; -}; - - -template <class _Tp, class _Alloc = allocator<_Tp> > class _LIBCPP_TEMPLATE_VIS forward_list; -template<class _NodeConstPtr> class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator; - -template <class _NodePtr> -class _LIBCPP_TEMPLATE_VIS __forward_list_iterator -{ - typedef __forward_node_traits<_NodePtr> __traits; - typedef typename __traits::__node_pointer __node_pointer; - typedef typename __traits::__begin_node_pointer __begin_node_pointer; - typedef typename __traits::__iter_node_pointer __iter_node_pointer; - typedef typename __traits::__void_pointer __void_pointer; - - __iter_node_pointer __ptr_; - - _LIBCPP_INLINE_VISIBILITY - __begin_node_pointer __get_begin() const { - return static_cast<__begin_node_pointer>( - static_cast<__void_pointer>(__ptr_)); - } - _LIBCPP_INLINE_VISIBILITY - __node_pointer __get_unsafe_node_pointer() const { - return static_cast<__node_pointer>( - static_cast<__void_pointer>(__ptr_)); - } - - _LIBCPP_INLINE_VISIBILITY - explicit __forward_list_iterator(nullptr_t) _NOEXCEPT : __ptr_(nullptr) {} - - _LIBCPP_INLINE_VISIBILITY - explicit __forward_list_iterator(__begin_node_pointer __p) _NOEXCEPT - : __ptr_(__traits::__as_iter_node(__p)) {} - - _LIBCPP_INLINE_VISIBILITY - explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT - : __ptr_(__traits::__as_iter_node(__p)) {} - - template<class, class> friend class _LIBCPP_TEMPLATE_VIS forward_list; - template<class> friend class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator; - -public: - typedef forward_iterator_tag iterator_category; - typedef typename __traits::__node_value_type value_type; - typedef value_type& reference; - typedef typename pointer_traits<__node_pointer>::difference_type - difference_type; - typedef typename __rebind_pointer<__node_pointer, value_type>::type pointer; - - _LIBCPP_INLINE_VISIBILITY - __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {} - - _LIBCPP_INLINE_VISIBILITY - reference operator*() const {return __get_unsafe_node_pointer()->__value_;} - _LIBCPP_INLINE_VISIBILITY - pointer operator->() const { - return pointer_traits<pointer>::pointer_to(__get_unsafe_node_pointer()->__value_); - } - - _LIBCPP_INLINE_VISIBILITY - __forward_list_iterator& operator++() - { - __ptr_ = __traits::__as_iter_node(__ptr_->__next_); - return *this; - } - _LIBCPP_INLINE_VISIBILITY - __forward_list_iterator operator++(int) - { - __forward_list_iterator __t(*this); - ++(*this); - return __t; - } - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const __forward_list_iterator& __x, - const __forward_list_iterator& __y) - {return __x.__ptr_ == __y.__ptr_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const __forward_list_iterator& __x, - const __forward_list_iterator& __y) - {return !(__x == __y);} -}; - -template <class _NodeConstPtr> -class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator -{ - static_assert((!is_const<typename pointer_traits<_NodeConstPtr>::element_type>::value), ""); - typedef _NodeConstPtr _NodePtr; - - typedef __forward_node_traits<_NodePtr> __traits; - typedef typename __traits::__node __node; - typedef typename __traits::__node_pointer __node_pointer; - typedef typename __traits::__begin_node_pointer __begin_node_pointer; - typedef typename __traits::__iter_node_pointer __iter_node_pointer; - typedef typename __traits::__void_pointer __void_pointer; - - __iter_node_pointer __ptr_; - - __begin_node_pointer __get_begin() const { - return static_cast<__begin_node_pointer>( - static_cast<__void_pointer>(__ptr_)); - } - __node_pointer __get_unsafe_node_pointer() const { - return static_cast<__node_pointer>( - static_cast<__void_pointer>(__ptr_)); - } - - _LIBCPP_INLINE_VISIBILITY - explicit __forward_list_const_iterator(nullptr_t) _NOEXCEPT - : __ptr_(nullptr) {} - - _LIBCPP_INLINE_VISIBILITY - explicit __forward_list_const_iterator(__begin_node_pointer __p) _NOEXCEPT - : __ptr_(__traits::__as_iter_node(__p)) {} - - _LIBCPP_INLINE_VISIBILITY - explicit __forward_list_const_iterator(__node_pointer __p) _NOEXCEPT - : __ptr_(__traits::__as_iter_node(__p)) {} - - - template<class, class> friend class forward_list; - -public: - typedef forward_iterator_tag iterator_category; - typedef typename __traits::__node_value_type value_type; - typedef const value_type& reference; - typedef typename pointer_traits<__node_pointer>::difference_type - difference_type; - typedef typename __rebind_pointer<__node_pointer, const value_type>::type - pointer; - - _LIBCPP_INLINE_VISIBILITY - __forward_list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {} - _LIBCPP_INLINE_VISIBILITY - __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p) _NOEXCEPT - : __ptr_(__p.__ptr_) {} - - _LIBCPP_INLINE_VISIBILITY - reference operator*() const {return __get_unsafe_node_pointer()->__value_;} - _LIBCPP_INLINE_VISIBILITY - pointer operator->() const {return pointer_traits<pointer>::pointer_to( - __get_unsafe_node_pointer()->__value_);} - - _LIBCPP_INLINE_VISIBILITY - __forward_list_const_iterator& operator++() - { - __ptr_ = __traits::__as_iter_node(__ptr_->__next_); - return *this; - } - _LIBCPP_INLINE_VISIBILITY - __forward_list_const_iterator operator++(int) - { - __forward_list_const_iterator __t(*this); - ++(*this); - return __t; - } - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const __forward_list_const_iterator& __x, - const __forward_list_const_iterator& __y) - {return __x.__ptr_ == __y.__ptr_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const __forward_list_const_iterator& __x, - const __forward_list_const_iterator& __y) - {return !(__x == __y);} -}; - -template <class _Tp, class _Alloc> -class __forward_list_base -{ -protected: - typedef _Tp value_type; - typedef _Alloc allocator_type; - - typedef typename allocator_traits<allocator_type>::void_pointer void_pointer; - typedef __forward_list_node<value_type, void_pointer> __node; - typedef typename __begin_node_of<value_type, void_pointer>::type __begin_node; - typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, __node>::type __node_allocator; - typedef allocator_traits<__node_allocator> __node_traits; - typedef typename __node_traits::pointer __node_pointer; - - typedef typename __rebind_alloc_helper< - allocator_traits<allocator_type>, __begin_node - >::type __begin_node_allocator; - typedef typename allocator_traits<__begin_node_allocator>::pointer - __begin_node_pointer; - - static_assert((!is_same<allocator_type, __node_allocator>::value), - "internal allocator type must differ from user-specified " - "type; otherwise overload resolution breaks"); - - __compressed_pair<__begin_node, __node_allocator> __before_begin_; - - _LIBCPP_INLINE_VISIBILITY - __begin_node_pointer __before_begin() _NOEXCEPT - {return pointer_traits<__begin_node_pointer>::pointer_to(__before_begin_.first());} - _LIBCPP_INLINE_VISIBILITY - __begin_node_pointer __before_begin() const _NOEXCEPT - {return pointer_traits<__begin_node_pointer>::pointer_to(const_cast<__begin_node&>(__before_begin_.first()));} - - _LIBCPP_INLINE_VISIBILITY - __node_allocator& __alloc() _NOEXCEPT - {return __before_begin_.second();} - _LIBCPP_INLINE_VISIBILITY - const __node_allocator& __alloc() const _NOEXCEPT - {return __before_begin_.second();} - - typedef __forward_list_iterator<__node_pointer> iterator; - typedef __forward_list_const_iterator<__node_pointer> const_iterator; - - _LIBCPP_INLINE_VISIBILITY - __forward_list_base() - _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) - : __before_begin_(__begin_node(), __default_init_tag()) {} - _LIBCPP_INLINE_VISIBILITY - explicit __forward_list_base(const allocator_type& __a) - : __before_begin_(__begin_node(), __node_allocator(__a)) {} - _LIBCPP_INLINE_VISIBILITY - explicit __forward_list_base(const __node_allocator& __a) - : __before_begin_(__begin_node(), __a) {} -#ifndef _LIBCPP_CXX03_LANG -public: - _LIBCPP_INLINE_VISIBILITY - __forward_list_base(__forward_list_base&& __x) - _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value); - _LIBCPP_INLINE_VISIBILITY - __forward_list_base(__forward_list_base&& __x, const allocator_type& __a); -#endif // _LIBCPP_CXX03_LANG - -private: - __forward_list_base(const __forward_list_base&); - __forward_list_base& operator=(const __forward_list_base&); - -public: - ~__forward_list_base(); - -protected: - _LIBCPP_INLINE_VISIBILITY - void __copy_assign_alloc(const __forward_list_base& __x) - {__copy_assign_alloc(__x, integral_constant<bool, - __node_traits::propagate_on_container_copy_assignment::value>());} - - _LIBCPP_INLINE_VISIBILITY - void __move_assign_alloc(__forward_list_base& __x) - _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value || - is_nothrow_move_assignable<__node_allocator>::value) - {__move_assign_alloc(__x, integral_constant<bool, - __node_traits::propagate_on_container_move_assignment::value>());} - -public: - _LIBCPP_INLINE_VISIBILITY - void swap(__forward_list_base& __x) -#if _LIBCPP_STD_VER >= 14 - _NOEXCEPT; -#else - _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value || - __is_nothrow_swappable<__node_allocator>::value); -#endif -protected: - void clear() _NOEXCEPT; - -private: - _LIBCPP_INLINE_VISIBILITY - void __copy_assign_alloc(const __forward_list_base&, false_type) {} - _LIBCPP_INLINE_VISIBILITY - void __copy_assign_alloc(const __forward_list_base& __x, true_type) - { - if (__alloc() != __x.__alloc()) - clear(); - __alloc() = __x.__alloc(); - } - - _LIBCPP_INLINE_VISIBILITY - void __move_assign_alloc(__forward_list_base&, false_type) _NOEXCEPT - {} - _LIBCPP_INLINE_VISIBILITY - void __move_assign_alloc(__forward_list_base& __x, true_type) - _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) - {__alloc() = _VSTD::move(__x.__alloc());} -}; - -#ifndef _LIBCPP_CXX03_LANG - -template <class _Tp, class _Alloc> -inline -__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x) - _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value) - : __before_begin_(_VSTD::move(__x.__before_begin_)) -{ - __x.__before_begin()->__next_ = nullptr; -} - -template <class _Tp, class _Alloc> -inline -__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x, - const allocator_type& __a) - : __before_begin_(__begin_node(), __node_allocator(__a)) -{ - if (__alloc() == __x.__alloc()) - { - __before_begin()->__next_ = __x.__before_begin()->__next_; - __x.__before_begin()->__next_ = nullptr; - } -} - -#endif // _LIBCPP_CXX03_LANG - -template <class _Tp, class _Alloc> -__forward_list_base<_Tp, _Alloc>::~__forward_list_base() -{ - clear(); -} - -template <class _Tp, class _Alloc> -inline -void -__forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x) -#if _LIBCPP_STD_VER >= 14 - _NOEXCEPT -#else - _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value || - __is_nothrow_swappable<__node_allocator>::value) -#endif -{ - _VSTD::__swap_allocator(__alloc(), __x.__alloc(), - integral_constant<bool, __node_traits::propagate_on_container_swap::value>()); - using _VSTD::swap; - swap(__before_begin()->__next_, __x.__before_begin()->__next_); -} - -template <class _Tp, class _Alloc> -void -__forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT -{ - __node_allocator& __a = __alloc(); - for (__node_pointer __p = __before_begin()->__next_; __p != nullptr;) - { - __node_pointer __next = __p->__next_; - __node_traits::destroy(__a, _VSTD::addressof(__p->__value_)); - __node_traits::deallocate(__a, __p, 1); - __p = __next; - } - __before_begin()->__next_ = nullptr; -} - -template <class _Tp, class _Alloc /*= allocator<_Tp>*/> -class _LIBCPP_TEMPLATE_VIS forward_list - : private __forward_list_base<_Tp, _Alloc> -{ - typedef __forward_list_base<_Tp, _Alloc> base; - typedef typename base::__node_allocator __node_allocator; - typedef typename base::__node __node; - typedef typename base::__node_traits __node_traits; - typedef typename base::__node_pointer __node_pointer; - typedef typename base::__begin_node_pointer __begin_node_pointer; - -public: - typedef _Tp value_type; - typedef _Alloc allocator_type; - - static_assert((is_same<typename allocator_type::value_type, value_type>::value), - "Allocator::value_type must be same type as value_type"); - - typedef value_type& reference; - typedef const value_type& const_reference; - typedef typename allocator_traits<allocator_type>::pointer pointer; - typedef typename allocator_traits<allocator_type>::const_pointer const_pointer; - typedef typename allocator_traits<allocator_type>::size_type size_type; - typedef typename allocator_traits<allocator_type>::difference_type difference_type; - - typedef typename base::iterator iterator; - typedef typename base::const_iterator const_iterator; -#if _LIBCPP_STD_VER > 17 - typedef size_type __remove_return_type; -#else - typedef void __remove_return_type; -#endif - - _LIBCPP_INLINE_VISIBILITY - forward_list() - _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) - {} // = default; - _LIBCPP_INLINE_VISIBILITY - explicit forward_list(const allocator_type& __a); - explicit forward_list(size_type __n); -#if _LIBCPP_STD_VER > 11 - explicit forward_list(size_type __n, const allocator_type& __a); -#endif - forward_list(size_type __n, const value_type& __v); - - template <class = __enable_if_t<__is_allocator<_Alloc>::value> > - forward_list(size_type __n, const value_type& __v, const allocator_type& __a) : base(__a) - { - insert_after(cbefore_begin(), __n, __v); - } - - template <class _InputIterator> - forward_list(_InputIterator __f, _InputIterator __l, - typename enable_if< - __is_cpp17_input_iterator<_InputIterator>::value - >::type* = nullptr); - template <class _InputIterator> - forward_list(_InputIterator __f, _InputIterator __l, - const allocator_type& __a, - typename enable_if< - __is_cpp17_input_iterator<_InputIterator>::value - >::type* = nullptr); - forward_list(const forward_list& __x); - forward_list(const forward_list& __x, const __identity_t<allocator_type>& __a); - - forward_list& operator=(const forward_list& __x); - -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - forward_list(forward_list&& __x) - _NOEXCEPT_(is_nothrow_move_constructible<base>::value) - : base(_VSTD::move(__x)) {} - forward_list(forward_list&& __x, const __identity_t<allocator_type>& __a); - - forward_list(initializer_list<value_type> __il); - forward_list(initializer_list<value_type> __il, const allocator_type& __a); - - _LIBCPP_INLINE_VISIBILITY - forward_list& operator=(forward_list&& __x) - _NOEXCEPT_( - __node_traits::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<allocator_type>::value); - - _LIBCPP_INLINE_VISIBILITY - forward_list& operator=(initializer_list<value_type> __il); - - _LIBCPP_INLINE_VISIBILITY - void assign(initializer_list<value_type> __il); -#endif // _LIBCPP_CXX03_LANG - - // ~forward_list() = default; - - template <class _InputIterator> - typename enable_if - < - __is_cpp17_input_iterator<_InputIterator>::value, - void - >::type - assign(_InputIterator __f, _InputIterator __l); - void assign(size_type __n, const value_type& __v); - - _LIBCPP_INLINE_VISIBILITY - allocator_type get_allocator() const _NOEXCEPT - {return allocator_type(base::__alloc());} - - _LIBCPP_INLINE_VISIBILITY - iterator begin() _NOEXCEPT - {return iterator(base::__before_begin()->__next_);} - _LIBCPP_INLINE_VISIBILITY - const_iterator begin() const _NOEXCEPT - {return const_iterator(base::__before_begin()->__next_);} - _LIBCPP_INLINE_VISIBILITY - iterator end() _NOEXCEPT - {return iterator(nullptr);} - _LIBCPP_INLINE_VISIBILITY - const_iterator end() const _NOEXCEPT - {return const_iterator(nullptr);} - - _LIBCPP_INLINE_VISIBILITY - const_iterator cbegin() const _NOEXCEPT - {return const_iterator(base::__before_begin()->__next_);} - _LIBCPP_INLINE_VISIBILITY - const_iterator cend() const _NOEXCEPT - {return const_iterator(nullptr);} - - _LIBCPP_INLINE_VISIBILITY - iterator before_begin() _NOEXCEPT - {return iterator(base::__before_begin());} - _LIBCPP_INLINE_VISIBILITY - const_iterator before_begin() const _NOEXCEPT - {return const_iterator(base::__before_begin());} - _LIBCPP_INLINE_VISIBILITY - const_iterator cbefore_begin() const _NOEXCEPT - {return const_iterator(base::__before_begin());} - - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY - bool empty() const _NOEXCEPT - {return base::__before_begin()->__next_ == nullptr;} - _LIBCPP_INLINE_VISIBILITY - size_type max_size() const _NOEXCEPT { - return _VSTD::min<size_type>( - __node_traits::max_size(base::__alloc()), - numeric_limits<difference_type>::max()); - } - - _LIBCPP_INLINE_VISIBILITY - reference front() {return base::__before_begin()->__next_->__value_;} - _LIBCPP_INLINE_VISIBILITY - const_reference front() const {return base::__before_begin()->__next_->__value_;} - -#ifndef _LIBCPP_CXX03_LANG -#if _LIBCPP_STD_VER > 14 - template <class... _Args> reference emplace_front(_Args&&... __args); -#else - template <class... _Args> void emplace_front(_Args&&... __args); -#endif - void push_front(value_type&& __v); -#endif // _LIBCPP_CXX03_LANG - void push_front(const value_type& __v); - - void pop_front(); - -#ifndef _LIBCPP_CXX03_LANG - template <class... _Args> - iterator emplace_after(const_iterator __p, _Args&&... __args); - - iterator insert_after(const_iterator __p, value_type&& __v); - iterator insert_after(const_iterator __p, initializer_list<value_type> __il) - {return insert_after(__p, __il.begin(), __il.end());} -#endif // _LIBCPP_CXX03_LANG - iterator insert_after(const_iterator __p, const value_type& __v); - iterator insert_after(const_iterator __p, size_type __n, const value_type& __v); - template <class _InputIterator> - _LIBCPP_INLINE_VISIBILITY - typename enable_if - < - __is_cpp17_input_iterator<_InputIterator>::value, - iterator - >::type - insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l); - - iterator erase_after(const_iterator __p); - iterator erase_after(const_iterator __f, const_iterator __l); - - _LIBCPP_INLINE_VISIBILITY - void swap(forward_list& __x) -#if _LIBCPP_STD_VER >= 14 - _NOEXCEPT -#else - _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value || - __is_nothrow_swappable<__node_allocator>::value) -#endif - {base::swap(__x);} - - void resize(size_type __n); - void resize(size_type __n, const value_type& __v); - _LIBCPP_INLINE_VISIBILITY - void clear() _NOEXCEPT {base::clear();} - - _LIBCPP_INLINE_VISIBILITY - void splice_after(const_iterator __p, forward_list&& __x); - _LIBCPP_INLINE_VISIBILITY - void splice_after(const_iterator __p, forward_list&& __x, const_iterator __i); - _LIBCPP_INLINE_VISIBILITY - void splice_after(const_iterator __p, forward_list&& __x, - const_iterator __f, const_iterator __l); - void splice_after(const_iterator __p, forward_list& __x); - void splice_after(const_iterator __p, forward_list& __x, const_iterator __i); - void splice_after(const_iterator __p, forward_list& __x, - const_iterator __f, const_iterator __l); - __remove_return_type remove(const value_type& __v); - template <class _Predicate> __remove_return_type remove_if(_Predicate __pred); - _LIBCPP_INLINE_VISIBILITY - __remove_return_type unique() {return unique(__equal_to<value_type>());} - template <class _BinaryPredicate> __remove_return_type unique(_BinaryPredicate __binary_pred); -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - void merge(forward_list&& __x) {merge(__x, __less<value_type>());} - template <class _Compare> - _LIBCPP_INLINE_VISIBILITY - void merge(forward_list&& __x, _Compare __comp) - {merge(__x, _VSTD::move(__comp));} -#endif // _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - void merge(forward_list& __x) {merge(__x, __less<value_type>());} - template <class _Compare> void merge(forward_list& __x, _Compare __comp); - _LIBCPP_INLINE_VISIBILITY - void sort() {sort(__less<value_type>());} - template <class _Compare> _LIBCPP_INLINE_VISIBILITY void sort(_Compare __comp); - void reverse() _NOEXCEPT; - -private: - -#ifndef _LIBCPP_CXX03_LANG - void __move_assign(forward_list& __x, true_type) - _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value); - void __move_assign(forward_list& __x, false_type); -#endif // _LIBCPP_CXX03_LANG - - template <class _Compare> - static - __node_pointer - __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp); - - template <class _Compare> - static - __node_pointer - __sort(__node_pointer __f, difference_type __sz, _Compare& __comp); -}; - - -#if _LIBCPP_STD_VER >= 17 -template<class _InputIterator, - class _Alloc = allocator<__iter_value_type<_InputIterator>>, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = enable_if_t<__is_allocator<_Alloc>::value> - > -forward_list(_InputIterator, _InputIterator) - -> forward_list<__iter_value_type<_InputIterator>, _Alloc>; - -template<class _InputIterator, - class _Alloc, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = enable_if_t<__is_allocator<_Alloc>::value> - > -forward_list(_InputIterator, _InputIterator, _Alloc) - -> forward_list<__iter_value_type<_InputIterator>, _Alloc>; -#endif - -template <class _Tp, class _Alloc> -inline -forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a) - : base(__a) -{ -} - -template <class _Tp, class _Alloc> -forward_list<_Tp, _Alloc>::forward_list(size_type __n) -{ - if (__n > 0) - { - __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); - for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n, - __p = __p->__next_as_begin()) - { - __h.reset(__node_traits::allocate(__a, 1)); - __node_traits::construct(__a, _VSTD::addressof(__h->__value_)); - __h->__next_ = nullptr; - __p->__next_ = __h.release(); - } - } -} - -#if _LIBCPP_STD_VER > 11 -template <class _Tp, class _Alloc> -forward_list<_Tp, _Alloc>::forward_list(size_type __n, - const allocator_type& __base_alloc) - : base ( __base_alloc ) -{ - if (__n > 0) - { - __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); - for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n, - __p = __p->__next_as_begin()) - { - __h.reset(__node_traits::allocate(__a, 1)); - __node_traits::construct(__a, _VSTD::addressof(__h->__value_)); - __h->__next_ = nullptr; - __p->__next_ = __h.release(); - } - } -} -#endif - -template <class _Tp, class _Alloc> -forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v) -{ - insert_after(cbefore_begin(), __n, __v); -} - -template <class _Tp, class _Alloc> -template <class _InputIterator> -forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l, - typename enable_if< - __is_cpp17_input_iterator<_InputIterator>::value - >::type*) -{ - insert_after(cbefore_begin(), __f, __l); -} - -template <class _Tp, class _Alloc> -template <class _InputIterator> -forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l, - const allocator_type& __a, - typename enable_if< - __is_cpp17_input_iterator<_InputIterator>::value - >::type*) - : base(__a) -{ - insert_after(cbefore_begin(), __f, __l); -} - -template <class _Tp, class _Alloc> -forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x) - : base( - __node_traits::select_on_container_copy_construction(__x.__alloc())) { - insert_after(cbefore_begin(), __x.begin(), __x.end()); -} - -template <class _Tp, class _Alloc> -forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x, - const __identity_t<allocator_type>& __a) - : base(__a) -{ - insert_after(cbefore_begin(), __x.begin(), __x.end()); -} - -template <class _Tp, class _Alloc> -forward_list<_Tp, _Alloc>& -forward_list<_Tp, _Alloc>::operator=(const forward_list& __x) -{ - if (this != _VSTD::addressof(__x)) - { - base::__copy_assign_alloc(__x); - assign(__x.begin(), __x.end()); - } - return *this; -} - -#ifndef _LIBCPP_CXX03_LANG -template <class _Tp, class _Alloc> -forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x, - const __identity_t<allocator_type>& __a) - : base(_VSTD::move(__x), __a) -{ - if (base::__alloc() != __x.__alloc()) - { - typedef move_iterator<iterator> _Ip; - insert_after(cbefore_begin(), _Ip(__x.begin()), _Ip(__x.end())); - } -} - -template <class _Tp, class _Alloc> -forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il) -{ - insert_after(cbefore_begin(), __il.begin(), __il.end()); -} - -template <class _Tp, class _Alloc> -forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il, - const allocator_type& __a) - : base(__a) -{ - insert_after(cbefore_begin(), __il.begin(), __il.end()); -} - -template <class _Tp, class _Alloc> -void -forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type) - _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) -{ - clear(); - base::__move_assign_alloc(__x); - base::__before_begin()->__next_ = __x.__before_begin()->__next_; - __x.__before_begin()->__next_ = nullptr; -} - -template <class _Tp, class _Alloc> -void -forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type) -{ - if (base::__alloc() == __x.__alloc()) - __move_assign(__x, true_type()); - else - { - typedef move_iterator<iterator> _Ip; - assign(_Ip(__x.begin()), _Ip(__x.end())); - } -} - -template <class _Tp, class _Alloc> -inline -forward_list<_Tp, _Alloc>& -forward_list<_Tp, _Alloc>::operator=(forward_list&& __x) - _NOEXCEPT_( - __node_traits::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<allocator_type>::value) -{ - __move_assign(__x, integral_constant<bool, - __node_traits::propagate_on_container_move_assignment::value>()); - return *this; -} - -template <class _Tp, class _Alloc> -inline -forward_list<_Tp, _Alloc>& -forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il) -{ - assign(__il.begin(), __il.end()); - return *this; -} - -#endif // _LIBCPP_CXX03_LANG - -template <class _Tp, class _Alloc> -template <class _InputIterator> -typename enable_if -< - __is_cpp17_input_iterator<_InputIterator>::value, - void ->::type -forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l) -{ - iterator __i = before_begin(); - iterator __j = _VSTD::next(__i); - iterator __e = end(); - for (; __j != __e && __f != __l; ++__i, (void) ++__j, ++__f) - *__j = *__f; - if (__j == __e) - insert_after(__i, __f, __l); - else - erase_after(__i, __e); -} - -template <class _Tp, class _Alloc> -void -forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v) -{ - iterator __i = before_begin(); - iterator __j = _VSTD::next(__i); - iterator __e = end(); - for (; __j != __e && __n > 0; --__n, ++__i, ++__j) - *__j = __v; - if (__j == __e) - insert_after(__i, __n, __v); - else - erase_after(__i, __e); -} - -#ifndef _LIBCPP_CXX03_LANG - -template <class _Tp, class _Alloc> -inline -void -forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il) -{ - assign(__il.begin(), __il.end()); -} - -template <class _Tp, class _Alloc> -template <class... _Args> -#if _LIBCPP_STD_VER > 14 -typename forward_list<_Tp, _Alloc>::reference -#else -void -#endif -forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args) -{ - __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); - __node_traits::construct(__a, _VSTD::addressof(__h->__value_), - _VSTD::forward<_Args>(__args)...); - __h->__next_ = base::__before_begin()->__next_; - base::__before_begin()->__next_ = __h.release(); -#if _LIBCPP_STD_VER > 14 - return base::__before_begin()->__next_->__value_; -#endif -} - -template <class _Tp, class _Alloc> -void -forward_list<_Tp, _Alloc>::push_front(value_type&& __v) -{ - __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); - __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v)); - __h->__next_ = base::__before_begin()->__next_; - base::__before_begin()->__next_ = __h.release(); -} - -#endif // _LIBCPP_CXX03_LANG - -template <class _Tp, class _Alloc> -void -forward_list<_Tp, _Alloc>::push_front(const value_type& __v) -{ - __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); - __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); - __h->__next_ = base::__before_begin()->__next_; - base::__before_begin()->__next_ = __h.release(); -} - -template <class _Tp, class _Alloc> -void -forward_list<_Tp, _Alloc>::pop_front() -{ - __node_allocator& __a = base::__alloc(); - __node_pointer __p = base::__before_begin()->__next_; - base::__before_begin()->__next_ = __p->__next_; - __node_traits::destroy(__a, _VSTD::addressof(__p->__value_)); - __node_traits::deallocate(__a, __p, 1); -} - -#ifndef _LIBCPP_CXX03_LANG - -template <class _Tp, class _Alloc> -template <class... _Args> -typename forward_list<_Tp, _Alloc>::iterator -forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args) -{ - __begin_node_pointer const __r = __p.__get_begin(); - __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); - __node_traits::construct(__a, _VSTD::addressof(__h->__value_), - _VSTD::forward<_Args>(__args)...); - __h->__next_ = __r->__next_; - __r->__next_ = __h.release(); - return iterator(__r->__next_); -} - -template <class _Tp, class _Alloc> -typename forward_list<_Tp, _Alloc>::iterator -forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v) -{ - __begin_node_pointer const __r = __p.__get_begin(); - __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); - __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v)); - __h->__next_ = __r->__next_; - __r->__next_ = __h.release(); - return iterator(__r->__next_); -} - -#endif // _LIBCPP_CXX03_LANG - -template <class _Tp, class _Alloc> -typename forward_list<_Tp, _Alloc>::iterator -forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v) -{ - __begin_node_pointer const __r = __p.__get_begin(); - __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); - __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); - __h->__next_ = __r->__next_; - __r->__next_ = __h.release(); - return iterator(__r->__next_); -} - -template <class _Tp, class _Alloc> -typename forward_list<_Tp, _Alloc>::iterator -forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n, - const value_type& __v) -{ - __begin_node_pointer __r = __p.__get_begin(); - if (__n > 0) - { - __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); - __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); - __node_pointer __first = __h.release(); - __node_pointer __last = __first; -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - for (--__n; __n != 0; --__n, __last = __last->__next_) - { - __h.reset(__node_traits::allocate(__a, 1)); - __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); - __last->__next_ = __h.release(); - } -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - while (__first != nullptr) - { - __node_pointer __next = __first->__next_; - __node_traits::destroy(__a, _VSTD::addressof(__first->__value_)); - __node_traits::deallocate(__a, __first, 1); - __first = __next; - } - throw; - } -#endif // _LIBCPP_NO_EXCEPTIONS - __last->__next_ = __r->__next_; - __r->__next_ = __first; - __r = static_cast<__begin_node_pointer>(__last); - } - return iterator(__r); -} - -template <class _Tp, class _Alloc> -template <class _InputIterator> -typename enable_if -< - __is_cpp17_input_iterator<_InputIterator>::value, - typename forward_list<_Tp, _Alloc>::iterator ->::type -forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, - _InputIterator __f, _InputIterator __l) -{ - __begin_node_pointer __r = __p.__get_begin(); - if (__f != __l) - { - __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); - __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f); - __node_pointer __first = __h.release(); - __node_pointer __last = __first; -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - for (++__f; __f != __l; ++__f, ((void)(__last = __last->__next_))) - { - __h.reset(__node_traits::allocate(__a, 1)); - __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f); - __last->__next_ = __h.release(); - } -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - while (__first != nullptr) - { - __node_pointer __next = __first->__next_; - __node_traits::destroy(__a, _VSTD::addressof(__first->__value_)); - __node_traits::deallocate(__a, __first, 1); - __first = __next; - } - throw; - } -#endif // _LIBCPP_NO_EXCEPTIONS - __last->__next_ = __r->__next_; - __r->__next_ = __first; - __r = static_cast<__begin_node_pointer>(__last); - } - return iterator(__r); -} - -template <class _Tp, class _Alloc> -typename forward_list<_Tp, _Alloc>::iterator -forward_list<_Tp, _Alloc>::erase_after(const_iterator __f) -{ - __begin_node_pointer __p = __f.__get_begin(); - __node_pointer __n = __p->__next_; - __p->__next_ = __n->__next_; - __node_allocator& __a = base::__alloc(); - __node_traits::destroy(__a, _VSTD::addressof(__n->__value_)); - __node_traits::deallocate(__a, __n, 1); - return iterator(__p->__next_); -} - -template <class _Tp, class _Alloc> -typename forward_list<_Tp, _Alloc>::iterator -forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l) -{ - __node_pointer __e = __l.__get_unsafe_node_pointer(); - if (__f != __l) - { - __begin_node_pointer __bp = __f.__get_begin(); - - __node_pointer __n = __bp->__next_; - if (__n != __e) - { - __bp->__next_ = __e; - __node_allocator& __a = base::__alloc(); - do - { - __node_pointer __tmp = __n->__next_; - __node_traits::destroy(__a, _VSTD::addressof(__n->__value_)); - __node_traits::deallocate(__a, __n, 1); - __n = __tmp; - } while (__n != __e); - } - } - return iterator(__e); -} - -template <class _Tp, class _Alloc> -void -forward_list<_Tp, _Alloc>::resize(size_type __n) -{ - size_type __sz = 0; - iterator __p = before_begin(); - iterator __i = begin(); - iterator __e = end(); - for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz) - ; - if (__i != __e) - erase_after(__p, __e); - else - { - __n -= __sz; - if (__n > 0) - { - __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); - for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n, - __ptr = __ptr->__next_as_begin()) - { - __h.reset(__node_traits::allocate(__a, 1)); - __node_traits::construct(__a, _VSTD::addressof(__h->__value_)); - __h->__next_ = nullptr; - __ptr->__next_ = __h.release(); - } - } - } -} - -template <class _Tp, class _Alloc> -void -forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v) -{ - size_type __sz = 0; - iterator __p = before_begin(); - iterator __i = begin(); - iterator __e = end(); - for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz) - ; - if (__i != __e) - erase_after(__p, __e); - else - { - __n -= __sz; - if (__n > 0) - { - __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); - for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n, - __ptr = __ptr->__next_as_begin()) - { - __h.reset(__node_traits::allocate(__a, 1)); - __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); - __h->__next_ = nullptr; - __ptr->__next_ = __h.release(); - } - } - } -} - -template <class _Tp, class _Alloc> -void -forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, - forward_list& __x) -{ - if (!__x.empty()) - { - if (__p.__get_begin()->__next_ != nullptr) - { - const_iterator __lm1 = __x.before_begin(); - while (__lm1.__get_begin()->__next_ != nullptr) - ++__lm1; - __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_; - } - __p.__get_begin()->__next_ = __x.__before_begin()->__next_; - __x.__before_begin()->__next_ = nullptr; - } -} - -template <class _Tp, class _Alloc> -void -forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, - forward_list& /*__other*/, - const_iterator __i) -{ - const_iterator __lm1 = _VSTD::next(__i); - if (__p != __i && __p != __lm1) - { - __i.__get_begin()->__next_ = __lm1.__get_begin()->__next_; - __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_; - __p.__get_begin()->__next_ = __lm1.__get_unsafe_node_pointer(); - } -} - -template <class _Tp, class _Alloc> -void -forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, - forward_list& /*__other*/, - const_iterator __f, const_iterator __l) -{ - if (__f != __l && __p != __f) - { - const_iterator __lm1 = __f; - while (__lm1.__get_begin()->__next_ != __l.__get_begin()) - ++__lm1; - if (__f != __lm1) - { - __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_; - __p.__get_begin()->__next_ = __f.__get_begin()->__next_; - __f.__get_begin()->__next_ = __l.__get_unsafe_node_pointer(); - } - } -} - -template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -void -forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, - forward_list&& __x) -{ - splice_after(__p, __x); -} - -template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -void -forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, - forward_list&& __x, - const_iterator __i) -{ - splice_after(__p, __x, __i); -} - -template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -void -forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, - forward_list&& __x, - const_iterator __f, const_iterator __l) -{ - splice_after(__p, __x, __f, __l); -} - -template <class _Tp, class _Alloc> -typename forward_list<_Tp, _Alloc>::__remove_return_type -forward_list<_Tp, _Alloc>::remove(const value_type& __v) -{ - forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing - typename forward_list<_Tp, _Alloc>::size_type __count_removed = 0; - const iterator __e = end(); - for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;) - { - if (__i.__get_begin()->__next_->__value_ == __v) - { - ++__count_removed; - iterator __j = _VSTD::next(__i, 2); - for (; __j != __e && *__j == __v; ++__j) - ++__count_removed; - __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j); - if (__j == __e) - break; - __i = __j; - } - else - ++__i; - } - - return (__remove_return_type) __count_removed; -} - -template <class _Tp, class _Alloc> -template <class _Predicate> -typename forward_list<_Tp, _Alloc>::__remove_return_type -forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred) -{ - forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing - typename forward_list<_Tp, _Alloc>::size_type __count_removed = 0; - const iterator __e = end(); - for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;) - { - if (__pred(__i.__get_begin()->__next_->__value_)) - { - ++__count_removed; - iterator __j = _VSTD::next(__i, 2); - for (; __j != __e && __pred(*__j); ++__j) - ++__count_removed; - __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j); - if (__j == __e) - break; - __i = __j; - } - else - ++__i; - } - - return (__remove_return_type) __count_removed; -} - -template <class _Tp, class _Alloc> -template <class _BinaryPredicate> -typename forward_list<_Tp, _Alloc>::__remove_return_type -forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred) -{ - forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing - typename forward_list<_Tp, _Alloc>::size_type __count_removed = 0; - for (iterator __i = begin(), __e = end(); __i != __e;) - { - iterator __j = _VSTD::next(__i); - for (; __j != __e && __binary_pred(*__i, *__j); ++__j) - ++__count_removed; - if (__i.__get_begin()->__next_ != __j.__get_unsafe_node_pointer()) - __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j); - __i = __j; - } - - return (__remove_return_type) __count_removed; -} - -template <class _Tp, class _Alloc> -template <class _Compare> -void -forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp) -{ - if (this != _VSTD::addressof(__x)) - { - base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_, - __x.__before_begin()->__next_, - __comp); - __x.__before_begin()->__next_ = nullptr; - } -} - -template <class _Tp, class _Alloc> -template <class _Compare> -typename forward_list<_Tp, _Alloc>::__node_pointer -forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2, - _Compare& __comp) -{ - if (__f1 == nullptr) - return __f2; - if (__f2 == nullptr) - return __f1; - __node_pointer __r; - if (__comp(__f2->__value_, __f1->__value_)) - { - __node_pointer __t = __f2; - while (__t->__next_ != nullptr && - __comp(__t->__next_->__value_, __f1->__value_)) - __t = __t->__next_; - __r = __f2; - __f2 = __t->__next_; - __t->__next_ = __f1; - } - else - __r = __f1; - __node_pointer __p = __f1; - __f1 = __f1->__next_; - while (__f1 != nullptr && __f2 != nullptr) - { - if (__comp(__f2->__value_, __f1->__value_)) - { - __node_pointer __t = __f2; - while (__t->__next_ != nullptr && - __comp(__t->__next_->__value_, __f1->__value_)) - __t = __t->__next_; - __p->__next_ = __f2; - __f2 = __t->__next_; - __t->__next_ = __f1; - } - __p = __f1; - __f1 = __f1->__next_; - } - if (__f2 != nullptr) - __p->__next_ = __f2; - return __r; -} - -template <class _Tp, class _Alloc> -template <class _Compare> -inline -void -forward_list<_Tp, _Alloc>::sort(_Compare __comp) -{ - base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_, - _VSTD::distance(begin(), end()), __comp); -} - -template <class _Tp, class _Alloc> -template <class _Compare> -typename forward_list<_Tp, _Alloc>::__node_pointer -forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz, - _Compare& __comp) -{ - switch (__sz) - { - case 0: - case 1: - return __f1; - case 2: - if (__comp(__f1->__next_->__value_, __f1->__value_)) - { - __node_pointer __t = __f1->__next_; - __t->__next_ = __f1; - __f1->__next_ = nullptr; - __f1 = __t; - } - return __f1; - } - difference_type __sz1 = __sz / 2; - difference_type __sz2 = __sz - __sz1; - __node_pointer __t = _VSTD::next(iterator(__f1), __sz1 - 1).__get_unsafe_node_pointer(); - __node_pointer __f2 = __t->__next_; - __t->__next_ = nullptr; - return __merge(__sort(__f1, __sz1, __comp), - __sort(__f2, __sz2, __comp), __comp); -} - -template <class _Tp, class _Alloc> -void -forward_list<_Tp, _Alloc>::reverse() _NOEXCEPT -{ - __node_pointer __p = base::__before_begin()->__next_; - if (__p != nullptr) - { - __node_pointer __f = __p->__next_; - __p->__next_ = nullptr; - while (__f != nullptr) - { - __node_pointer __t = __f->__next_; - __f->__next_ = __p; - __p = __f; - __f = __t; - } - base::__before_begin()->__next_ = __p; - } -} - -template <class _Tp, class _Alloc> -bool operator==(const forward_list<_Tp, _Alloc>& __x, - const forward_list<_Tp, _Alloc>& __y) -{ - typedef forward_list<_Tp, _Alloc> _Cp; - typedef typename _Cp::const_iterator _Ip; - _Ip __ix = __x.begin(); - _Ip __ex = __x.end(); - _Ip __iy = __y.begin(); - _Ip __ey = __y.end(); - for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy) - if (!(*__ix == *__iy)) - return false; - return (__ix == __ex) == (__iy == __ey); -} - -template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -bool operator!=(const forward_list<_Tp, _Alloc>& __x, - const forward_list<_Tp, _Alloc>& __y) -{ - return !(__x == __y); -} - -template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -bool operator< (const forward_list<_Tp, _Alloc>& __x, - const forward_list<_Tp, _Alloc>& __y) -{ - return _VSTD::lexicographical_compare(__x.begin(), __x.end(), - __y.begin(), __y.end()); -} - -template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -bool operator> (const forward_list<_Tp, _Alloc>& __x, - const forward_list<_Tp, _Alloc>& __y) -{ - return __y < __x; -} - -template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -bool operator>=(const forward_list<_Tp, _Alloc>& __x, - const forward_list<_Tp, _Alloc>& __y) -{ - return !(__x < __y); -} - -template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -bool operator<=(const forward_list<_Tp, _Alloc>& __x, - const forward_list<_Tp, _Alloc>& __y) -{ - return !(__y < __x); -} - -template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -void -swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y) - _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) -{ - __x.swap(__y); -} - -#if _LIBCPP_STD_VER > 17 -template <class _Tp, class _Allocator, class _Predicate> -inline _LIBCPP_INLINE_VISIBILITY - typename forward_list<_Tp, _Allocator>::size_type - erase_if(forward_list<_Tp, _Allocator>& __c, _Predicate __pred) { - return __c.remove_if(__pred); -} - -template <class _Tp, class _Allocator, class _Up> -inline _LIBCPP_INLINE_VISIBILITY - typename forward_list<_Tp, _Allocator>::size_type - erase(forward_list<_Tp, _Allocator>& __c, const _Up& __v) { - return _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; }); -} -#endif - -_LIBCPP_END_NAMESPACE_STD - -_LIBCPP_POP_MACROS - -#endif // _LIBCPP_FORWARD_LIST diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/inttypes.h b/contrib/libs/cxxsupp/libcxxmsvc/include/inttypes.h deleted file mode 100644 index 5873e3f647..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/inttypes.h +++ /dev/null @@ -1,266 +0,0 @@ -// -*- 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_INTTYPES_H -// AIX system headers need inttypes.h to be re-enterable while _STD_TYPES_T -// is defined until an inclusion of it without _STD_TYPES_T occurs, in which -// case the header guard macro is defined. -#if !defined(_AIX) || !defined(_STD_TYPES_T) -#define _LIBCPP_INTTYPES_H -#endif // _STD_TYPES_T - -/* - inttypes.h synopsis - -This entire header is C99 / C++0X - -#include <stdint.h> // <cinttypes> includes <cstdint> - -Macros: - - PRId8 - PRId16 - PRId32 - PRId64 - - PRIdLEAST8 - PRIdLEAST16 - PRIdLEAST32 - PRIdLEAST64 - - PRIdFAST8 - PRIdFAST16 - PRIdFAST32 - PRIdFAST64 - - PRIdMAX - PRIdPTR - - PRIi8 - PRIi16 - PRIi32 - PRIi64 - - PRIiLEAST8 - PRIiLEAST16 - PRIiLEAST32 - PRIiLEAST64 - - PRIiFAST8 - PRIiFAST16 - PRIiFAST32 - PRIiFAST64 - - PRIiMAX - PRIiPTR - - PRIo8 - PRIo16 - PRIo32 - PRIo64 - - PRIoLEAST8 - PRIoLEAST16 - PRIoLEAST32 - PRIoLEAST64 - - PRIoFAST8 - PRIoFAST16 - PRIoFAST32 - PRIoFAST64 - - PRIoMAX - PRIoPTR - - PRIu8 - PRIu16 - PRIu32 - PRIu64 - - PRIuLEAST8 - PRIuLEAST16 - PRIuLEAST32 - PRIuLEAST64 - - PRIuFAST8 - PRIuFAST16 - PRIuFAST32 - PRIuFAST64 - - PRIuMAX - PRIuPTR - - PRIx8 - PRIx16 - PRIx32 - PRIx64 - - PRIxLEAST8 - PRIxLEAST16 - PRIxLEAST32 - PRIxLEAST64 - - PRIxFAST8 - PRIxFAST16 - PRIxFAST32 - PRIxFAST64 - - PRIxMAX - PRIxPTR - - PRIX8 - PRIX16 - PRIX32 - PRIX64 - - PRIXLEAST8 - PRIXLEAST16 - PRIXLEAST32 - PRIXLEAST64 - - PRIXFAST8 - PRIXFAST16 - PRIXFAST32 - PRIXFAST64 - - PRIXMAX - PRIXPTR - - SCNd8 - SCNd16 - SCNd32 - SCNd64 - - SCNdLEAST8 - SCNdLEAST16 - SCNdLEAST32 - SCNdLEAST64 - - SCNdFAST8 - SCNdFAST16 - SCNdFAST32 - SCNdFAST64 - - SCNdMAX - SCNdPTR - - SCNi8 - SCNi16 - SCNi32 - SCNi64 - - SCNiLEAST8 - SCNiLEAST16 - SCNiLEAST32 - SCNiLEAST64 - - SCNiFAST8 - SCNiFAST16 - SCNiFAST32 - SCNiFAST64 - - SCNiMAX - SCNiPTR - - SCNo8 - SCNo16 - SCNo32 - SCNo64 - - SCNoLEAST8 - SCNoLEAST16 - SCNoLEAST32 - SCNoLEAST64 - - SCNoFAST8 - SCNoFAST16 - SCNoFAST32 - SCNoFAST64 - - SCNoMAX - SCNoPTR - - SCNu8 - SCNu16 - SCNu32 - SCNu64 - - SCNuLEAST8 - SCNuLEAST16 - SCNuLEAST32 - SCNuLEAST64 - - SCNuFAST8 - SCNuFAST16 - SCNuFAST32 - SCNuFAST64 - - SCNuMAX - SCNuPTR - - SCNx8 - SCNx16 - SCNx32 - SCNx64 - - SCNxLEAST8 - SCNxLEAST16 - SCNxLEAST32 - SCNxLEAST64 - - SCNxFAST8 - SCNxFAST16 - SCNxFAST32 - SCNxFAST64 - - SCNxMAX - SCNxPTR - -Types: - - imaxdiv_t - -intmax_t imaxabs(intmax_t j); -imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom); -intmax_t strtoimax(const char* restrict nptr, char** restrict endptr, int base); -uintmax_t strtoumax(const char* restrict nptr, char** restrict endptr, int base); -intmax_t wcstoimax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base); -uintmax_t wcstoumax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base); - -*/ - -#include <__config> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -/* C99 stdlib (e.g. glibc < 2.18) does not provide format macros needed - for C++11 unless __STDC_FORMAT_MACROS is defined -*/ -#if defined(__cplusplus) && !defined(__STDC_FORMAT_MACROS) -# define __STDC_FORMAT_MACROS -#endif - -#ifdef _LIBCPP_COMPILER_MSVC -#include Y_UCRT_INCLUDE_NEXT(inttypes.h) -#else -#include_next <inttypes.h> -#endif - -#ifdef __cplusplus - -#include <stdint.h> - -#undef imaxabs -#undef imaxdiv - -#endif // __cplusplus - -#endif // _LIBCPP_INTTYPES_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/iostream b/contrib/libs/cxxsupp/libcxxmsvc/include/iostream deleted file mode 100644 index dbabf3ad32..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/iostream +++ /dev/null @@ -1,89 +0,0 @@ -// -*- 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_IOSTREAM -#define _LIBCPP_IOSTREAM - -/* - iostream synopsis - -#include <ios> -#include <istream> -#include <ostream> -#include <streambuf> - -namespace std { - -extern istream cin; -extern ostream cout; -extern ostream cerr; -extern ostream clog; -extern wistream wcin; -extern wostream wcout; -extern wostream wcerr; -extern wostream wclog; - -} // std - -*/ - -#include <__config> -#include <ios> -#include <istream> -#include <ostream> -#include <streambuf> -#include <version> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if defined(_MSC_VER) && !defined(__clang__) -extern _LIBCPP_FUNC_VIS istream& cin; -#else -extern _LIBCPP_FUNC_VIS istream cin; -#endif -#if defined(_MSC_VER) && !defined(__clang__) -extern _LIBCPP_FUNC_VIS ostream& cout; -#else -extern _LIBCPP_FUNC_VIS ostream cout; -#endif -#if defined(_MSC_VER) && !defined(__clang__) -extern _LIBCPP_FUNC_VIS ostream& cerr; -extern _LIBCPP_FUNC_VIS ostream& clog; -#else -extern _LIBCPP_FUNC_VIS ostream cerr; -extern _LIBCPP_FUNC_VIS ostream clog; -#endif - -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -#if defined(_MSC_VER) && !defined(__clang__) -extern _LIBCPP_FUNC_VIS wistream& wcin; -#else -extern _LIBCPP_FUNC_VIS wistream wcin; -#endif -#if defined(_MSC_VER) && !defined(__clang__) -extern _LIBCPP_FUNC_VIS wostream& wcout; -#else -extern _LIBCPP_FUNC_VIS wostream wcout; -#endif -#if defined(_MSC_VER) && !defined(__clang__) -extern _LIBCPP_FUNC_VIS wostream& wcerr; -extern _LIBCPP_FUNC_VIS wostream& wclog; -#else -extern _LIBCPP_FUNC_VIS wostream wcerr; -extern _LIBCPP_FUNC_VIS wostream wclog; -#endif -#endif - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP_IOSTREAM diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/list b/contrib/libs/cxxsupp/libcxxmsvc/include/list deleted file mode 100644 index b1f6c57007..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/list +++ /dev/null @@ -1,2422 +0,0 @@ -// -*- 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_LIST -#define _LIBCPP_LIST - -/* - list synopsis - -namespace std -{ - -template <class T, class Alloc = allocator<T> > -class list -{ -public: - - // types: - typedef T value_type; - typedef Alloc allocator_type; - typedef typename allocator_type::reference reference; - typedef typename allocator_type::const_reference const_reference; - typedef typename allocator_type::pointer pointer; - typedef typename allocator_type::const_pointer const_pointer; - typedef implementation-defined iterator; - typedef implementation-defined const_iterator; - typedef implementation-defined size_type; - typedef implementation-defined difference_type; - typedef reverse_iterator<iterator> reverse_iterator; - typedef reverse_iterator<const_iterator> const_reverse_iterator; - - list() - noexcept(is_nothrow_default_constructible<allocator_type>::value); - explicit list(const allocator_type& a); - explicit list(size_type n); - explicit list(size_type n, const allocator_type& a); // C++14 - list(size_type n, const value_type& value); - list(size_type n, const value_type& value, const allocator_type& a); - template <class Iter> - list(Iter first, Iter last); - template <class Iter> - list(Iter first, Iter last, const allocator_type& a); - list(const list& x); - list(const list&, const allocator_type& a); - list(list&& x) - noexcept(is_nothrow_move_constructible<allocator_type>::value); - list(list&&, const allocator_type& a); - list(initializer_list<value_type>); - list(initializer_list<value_type>, const allocator_type& a); - - ~list(); - - list& operator=(const list& x); - list& operator=(list&& x) - noexcept( - allocator_type::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<allocator_type>::value); - list& operator=(initializer_list<value_type>); - template <class Iter> - void assign(Iter first, Iter last); - void assign(size_type n, const value_type& t); - void assign(initializer_list<value_type>); - - allocator_type get_allocator() const noexcept; - - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; - - reference front(); - const_reference front() const; - reference back(); - const_reference back() const; - - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; - - template <class... Args> - reference emplace_front(Args&&... args); // reference in C++17 - void pop_front(); - template <class... Args> - reference emplace_back(Args&&... args); // reference in C++17 - void pop_back(); - void push_front(const value_type& x); - void push_front(value_type&& x); - void push_back(const value_type& x); - void push_back(value_type&& x); - template <class... Args> - iterator emplace(const_iterator position, Args&&... args); - iterator insert(const_iterator position, const value_type& x); - iterator insert(const_iterator position, value_type&& x); - iterator insert(const_iterator position, size_type n, const value_type& x); - template <class Iter> - iterator insert(const_iterator position, Iter first, Iter last); - iterator insert(const_iterator position, initializer_list<value_type> il); - - iterator erase(const_iterator position); - iterator erase(const_iterator position, const_iterator last); - - void resize(size_type sz); - void resize(size_type sz, const value_type& c); - - void swap(list&) - noexcept(allocator_traits<allocator_type>::is_always_equal::value); // C++17 - void clear() noexcept; - - void splice(const_iterator position, list& x); - void splice(const_iterator position, list&& x); - void splice(const_iterator position, list& x, const_iterator i); - void splice(const_iterator position, list&& x, const_iterator i); - void splice(const_iterator position, list& x, const_iterator first, - const_iterator last); - void splice(const_iterator position, list&& x, const_iterator first, - const_iterator last); - - size_type remove(const value_type& value); // void before C++20 - template <class Pred> - size_type remove_if(Pred pred); // void before C++20 - size_type unique(); // void before C++20 - template <class BinaryPredicate> - size_type unique(BinaryPredicate binary_pred); // void before C++20 - void merge(list& x); - void merge(list&& x); - template <class Compare> - void merge(list& x, Compare comp); - template <class Compare> - void merge(list&& x, Compare comp); - void sort(); - template <class Compare> - void sort(Compare comp); - void reverse() noexcept; -}; - - -template <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>> - list(InputIterator, InputIterator, Allocator = Allocator()) - -> list<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17 - -template <class T, class Alloc> - bool operator==(const list<T,Alloc>& x, const list<T,Alloc>& y); -template <class T, class Alloc> - bool operator< (const list<T,Alloc>& x, const list<T,Alloc>& y); -template <class T, class Alloc> - bool operator!=(const list<T,Alloc>& x, const list<T,Alloc>& y); -template <class T, class Alloc> - bool operator> (const list<T,Alloc>& x, const list<T,Alloc>& y); -template <class T, class Alloc> - bool operator>=(const list<T,Alloc>& x, const list<T,Alloc>& y); -template <class T, class Alloc> - bool operator<=(const list<T,Alloc>& x, const list<T,Alloc>& y); - -template <class T, class Alloc> - void swap(list<T,Alloc>& x, list<T,Alloc>& y) - noexcept(noexcept(x.swap(y))); - -template <class T, class Allocator, class U> - typename list<T, Allocator>::size_type - erase(list<T, Allocator>& c, const U& value); // C++20 -template <class T, class Allocator, class Predicate> - typename list<T, Allocator>::size_type - erase_if(list<T, Allocator>& c, Predicate pred); // C++20 - -} // std - -*/ - -#include <__algorithm/comp.h> -#include <__algorithm/equal.h> -#include <__algorithm/lexicographical_compare.h> -#include <__algorithm/min.h> -#include <__assert> -#include <__config> -#include <__debug> -#include <__utility/forward.h> -#include <initializer_list> -#include <iterator> -#include <limits> -#include <memory> -#include <type_traits> -#include <version> - -#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 _Tp, class _VoidPtr> struct __list_node; -template <class _Tp, class _VoidPtr> struct __list_node_base; - -template <class _Tp, class _VoidPtr> -struct __list_node_pointer_traits { - typedef typename __rebind_pointer<_VoidPtr, __list_node<_Tp, _VoidPtr> >::type - __node_pointer; - typedef typename __rebind_pointer<_VoidPtr, __list_node_base<_Tp, _VoidPtr> >::type - __base_pointer; - -#if defined(_LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB) - typedef __base_pointer __link_pointer; -#else - typedef typename conditional< - is_pointer<_VoidPtr>::value, - __base_pointer, - __node_pointer - >::type __link_pointer; -#endif - - typedef typename conditional< - is_same<__link_pointer, __node_pointer>::value, - __base_pointer, - __node_pointer - >::type __non_link_pointer; - - static _LIBCPP_INLINE_VISIBILITY - __link_pointer __unsafe_link_pointer_cast(__link_pointer __p) { - return __p; - } - - static _LIBCPP_INLINE_VISIBILITY - __link_pointer __unsafe_link_pointer_cast(__non_link_pointer __p) { - return static_cast<__link_pointer>(static_cast<_VoidPtr>(__p)); - } - -}; - -template <class _Tp, class _VoidPtr> -struct __list_node_base -{ - typedef __list_node_pointer_traits<_Tp, _VoidPtr> _NodeTraits; - typedef typename _NodeTraits::__node_pointer __node_pointer; - typedef typename _NodeTraits::__base_pointer __base_pointer; - typedef typename _NodeTraits::__link_pointer __link_pointer; - - __link_pointer __prev_; - __link_pointer __next_; - - _LIBCPP_INLINE_VISIBILITY - __list_node_base() : __prev_(_NodeTraits::__unsafe_link_pointer_cast(__self())), - __next_(_NodeTraits::__unsafe_link_pointer_cast(__self())) {} - - _LIBCPP_INLINE_VISIBILITY - __base_pointer __self() { - return pointer_traits<__base_pointer>::pointer_to(*this); - } - - _LIBCPP_INLINE_VISIBILITY - __node_pointer __as_node() { - return static_cast<__node_pointer>(__self()); - } -}; - -template <class _Tp, class _VoidPtr> -struct _LIBCPP_STANDALONE_DEBUG __list_node - : public __list_node_base<_Tp, _VoidPtr> -{ - _Tp __value_; - - typedef __list_node_base<_Tp, _VoidPtr> __base; - typedef typename __base::__link_pointer __link_pointer; - - _LIBCPP_INLINE_VISIBILITY - __link_pointer __as_link() { - return static_cast<__link_pointer>(__base::__self()); - } -}; - -template <class _Tp, class _Alloc = allocator<_Tp> > class _LIBCPP_TEMPLATE_VIS list; -template <class _Tp, class _Alloc> class __list_imp; -template <class _Tp, class _VoidPtr> class _LIBCPP_TEMPLATE_VIS __list_const_iterator; - -template <class _Tp, class _VoidPtr> -class _LIBCPP_TEMPLATE_VIS __list_iterator -{ - typedef __list_node_pointer_traits<_Tp, _VoidPtr> _NodeTraits; - typedef typename _NodeTraits::__link_pointer __link_pointer; - - __link_pointer __ptr_; - -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_INLINE_VISIBILITY - explicit __list_iterator(__link_pointer __p, const void* __c) _NOEXCEPT - : __ptr_(__p) - { - __get_db()->__insert_ic(this, __c); - } -#else - _LIBCPP_INLINE_VISIBILITY - explicit __list_iterator(__link_pointer __p) _NOEXCEPT : __ptr_(__p) {} -#endif - - - - template<class, class> friend class list; - template<class, class> friend class __list_imp; - template<class, class> friend class __list_const_iterator; -public: - typedef bidirectional_iterator_tag iterator_category; - typedef _Tp value_type; - typedef value_type& reference; - typedef typename __rebind_pointer<_VoidPtr, value_type>::type pointer; - typedef typename pointer_traits<pointer>::difference_type difference_type; - - _LIBCPP_INLINE_VISIBILITY - __list_iterator() _NOEXCEPT : __ptr_(nullptr) - { - _VSTD::__debug_db_insert_i(this); - } - -#if _LIBCPP_DEBUG_LEVEL == 2 - - _LIBCPP_INLINE_VISIBILITY - __list_iterator(const __list_iterator& __p) - : __ptr_(__p.__ptr_) - { - __get_db()->__iterator_copy(this, _VSTD::addressof(__p)); - } - - _LIBCPP_INLINE_VISIBILITY - ~__list_iterator() - { - __get_db()->__erase_i(this); - } - - _LIBCPP_INLINE_VISIBILITY - __list_iterator& operator=(const __list_iterator& __p) - { - if (this != _VSTD::addressof(__p)) - { - __get_db()->__iterator_copy(this, _VSTD::addressof(__p)); - __ptr_ = __p.__ptr_; - } - return *this; - } - -#endif // _LIBCPP_DEBUG_LEVEL == 2 - - _LIBCPP_INLINE_VISIBILITY - reference operator*() const - { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable list::iterator"); - return __ptr_->__as_node()->__value_; - } - _LIBCPP_INLINE_VISIBILITY - pointer operator->() const - { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable list::iterator"); - return pointer_traits<pointer>::pointer_to(__ptr_->__as_node()->__value_); - } - - _LIBCPP_INLINE_VISIBILITY - __list_iterator& operator++() - { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to increment a non-incrementable list::iterator"); - __ptr_ = __ptr_->__next_; - return *this; - } - _LIBCPP_INLINE_VISIBILITY - __list_iterator operator++(int) {__list_iterator __t(*this); ++(*this); return __t;} - - _LIBCPP_INLINE_VISIBILITY - __list_iterator& operator--() - { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__decrementable(this), - "Attempted to decrement a non-decrementable list::iterator"); - __ptr_ = __ptr_->__prev_; - return *this; - } - _LIBCPP_INLINE_VISIBILITY - __list_iterator operator--(int) {__list_iterator __t(*this); --(*this); return __t;} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const __list_iterator& __x, const __list_iterator& __y) - { - return __x.__ptr_ == __y.__ptr_; - } - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const __list_iterator& __x, const __list_iterator& __y) - {return !(__x == __y);} -}; - -template <class _Tp, class _VoidPtr> -class _LIBCPP_TEMPLATE_VIS __list_const_iterator -{ - typedef __list_node_pointer_traits<_Tp, _VoidPtr> _NodeTraits; - typedef typename _NodeTraits::__link_pointer __link_pointer; - - __link_pointer __ptr_; - -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_INLINE_VISIBILITY - explicit __list_const_iterator(__link_pointer __p, const void* __c) _NOEXCEPT - : __ptr_(__p) - { - __get_db()->__insert_ic(this, __c); - } -#else - _LIBCPP_INLINE_VISIBILITY - explicit __list_const_iterator(__link_pointer __p) _NOEXCEPT : __ptr_(__p) {} -#endif - - template<class, class> friend class list; - template<class, class> friend class __list_imp; -public: - typedef bidirectional_iterator_tag iterator_category; - typedef _Tp value_type; - typedef const value_type& reference; - typedef typename __rebind_pointer<_VoidPtr, const value_type>::type pointer; - typedef typename pointer_traits<pointer>::difference_type difference_type; - - _LIBCPP_INLINE_VISIBILITY - __list_const_iterator() _NOEXCEPT : __ptr_(nullptr) - { - _VSTD::__debug_db_insert_i(this); - } - _LIBCPP_INLINE_VISIBILITY - __list_const_iterator(const __list_iterator<_Tp, _VoidPtr>& __p) _NOEXCEPT - : __ptr_(__p.__ptr_) - { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__iterator_copy(this, _VSTD::addressof(__p)); -#endif - } - -#if _LIBCPP_DEBUG_LEVEL == 2 - - _LIBCPP_INLINE_VISIBILITY - __list_const_iterator(const __list_const_iterator& __p) - : __ptr_(__p.__ptr_) - { - __get_db()->__iterator_copy(this, _VSTD::addressof(__p)); - } - - _LIBCPP_INLINE_VISIBILITY - ~__list_const_iterator() - { - __get_db()->__erase_i(this); - } - - _LIBCPP_INLINE_VISIBILITY - __list_const_iterator& operator=(const __list_const_iterator& __p) - { - if (this != _VSTD::addressof(__p)) - { - __get_db()->__iterator_copy(this, _VSTD::addressof(__p)); - __ptr_ = __p.__ptr_; - } - return *this; - } - -#endif // _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_INLINE_VISIBILITY - reference operator*() const - { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable list::const_iterator"); - return __ptr_->__as_node()->__value_; - } - _LIBCPP_INLINE_VISIBILITY - pointer operator->() const - { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable list::const_iterator"); - return pointer_traits<pointer>::pointer_to(__ptr_->__as_node()->__value_); - } - - _LIBCPP_INLINE_VISIBILITY - __list_const_iterator& operator++() - { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to increment a non-incrementable list::const_iterator"); - __ptr_ = __ptr_->__next_; - return *this; - } - _LIBCPP_INLINE_VISIBILITY - __list_const_iterator operator++(int) {__list_const_iterator __t(*this); ++(*this); return __t;} - - _LIBCPP_INLINE_VISIBILITY - __list_const_iterator& operator--() - { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__decrementable(this), - "Attempted to decrement a non-decrementable list::const_iterator"); - __ptr_ = __ptr_->__prev_; - return *this; - } - _LIBCPP_INLINE_VISIBILITY - __list_const_iterator operator--(int) {__list_const_iterator __t(*this); --(*this); return __t;} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const __list_const_iterator& __x, const __list_const_iterator& __y) - { - return __x.__ptr_ == __y.__ptr_; - } - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const __list_const_iterator& __x, const __list_const_iterator& __y) - {return !(__x == __y);} -}; - -template <class _Tp, class _Alloc> -class __list_imp -{ - __list_imp(const __list_imp&); - __list_imp& operator=(const __list_imp&); -public: - typedef _Alloc allocator_type; - typedef allocator_traits<allocator_type> __alloc_traits; - typedef typename __alloc_traits::size_type size_type; -protected: - typedef _Tp value_type; - typedef typename __alloc_traits::void_pointer __void_pointer; - typedef __list_iterator<value_type, __void_pointer> iterator; - typedef __list_const_iterator<value_type, __void_pointer> const_iterator; - typedef __list_node_base<value_type, __void_pointer> __node_base; - typedef __list_node<value_type, __void_pointer> __node; - typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator; - typedef allocator_traits<__node_allocator> __node_alloc_traits; - typedef typename __node_alloc_traits::pointer __node_pointer; - typedef typename __node_alloc_traits::pointer __node_const_pointer; - typedef __list_node_pointer_traits<value_type, __void_pointer> __node_pointer_traits; - typedef typename __node_pointer_traits::__link_pointer __link_pointer; - typedef __link_pointer __link_const_pointer; - typedef typename __alloc_traits::pointer pointer; - typedef typename __alloc_traits::const_pointer const_pointer; - typedef typename __alloc_traits::difference_type difference_type; - - typedef typename __rebind_alloc_helper<__alloc_traits, __node_base>::type __node_base_allocator; - typedef typename allocator_traits<__node_base_allocator>::pointer __node_base_pointer; - static_assert((!is_same<allocator_type, __node_allocator>::value), - "internal allocator type must differ from user-specified " - "type; otherwise overload resolution breaks"); - - __node_base __end_; - __compressed_pair<size_type, __node_allocator> __size_alloc_; - - _LIBCPP_INLINE_VISIBILITY - __link_pointer __end_as_link() const _NOEXCEPT { - return __node_pointer_traits::__unsafe_link_pointer_cast( - const_cast<__node_base&>(__end_).__self()); - } - - _LIBCPP_INLINE_VISIBILITY - size_type& __sz() _NOEXCEPT {return __size_alloc_.first();} - _LIBCPP_INLINE_VISIBILITY - const size_type& __sz() const _NOEXCEPT - {return __size_alloc_.first();} - _LIBCPP_INLINE_VISIBILITY - __node_allocator& __node_alloc() _NOEXCEPT - {return __size_alloc_.second();} - _LIBCPP_INLINE_VISIBILITY - const __node_allocator& __node_alloc() const _NOEXCEPT - {return __size_alloc_.second();} - - _LIBCPP_INLINE_VISIBILITY - size_type __node_alloc_max_size() const _NOEXCEPT { - return __node_alloc_traits::max_size(__node_alloc()); - } - _LIBCPP_INLINE_VISIBILITY - static void __unlink_nodes(__link_pointer __f, __link_pointer __l) _NOEXCEPT; - - _LIBCPP_INLINE_VISIBILITY - __list_imp() - _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value); - _LIBCPP_INLINE_VISIBILITY - __list_imp(const allocator_type& __a); - _LIBCPP_INLINE_VISIBILITY - __list_imp(const __node_allocator& __a); -#ifndef _LIBCPP_CXX03_LANG - __list_imp(__node_allocator&& __a) _NOEXCEPT; -#endif - ~__list_imp(); - void clear() _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - bool empty() const _NOEXCEPT {return __sz() == 0;} - - _LIBCPP_INLINE_VISIBILITY - iterator begin() _NOEXCEPT - { -#if _LIBCPP_DEBUG_LEVEL == 2 - return iterator(__end_.__next_, this); -#else - return iterator(__end_.__next_); -#endif - } - _LIBCPP_INLINE_VISIBILITY - const_iterator begin() const _NOEXCEPT - { -#if _LIBCPP_DEBUG_LEVEL == 2 - return const_iterator(__end_.__next_, this); -#else - return const_iterator(__end_.__next_); -#endif - } - _LIBCPP_INLINE_VISIBILITY - iterator end() _NOEXCEPT - { -#if _LIBCPP_DEBUG_LEVEL == 2 - return iterator(__end_as_link(), this); -#else - return iterator(__end_as_link()); -#endif - } - _LIBCPP_INLINE_VISIBILITY - const_iterator end() const _NOEXCEPT - { -#if _LIBCPP_DEBUG_LEVEL == 2 - return const_iterator(__end_as_link(), this); -#else - return const_iterator(__end_as_link()); -#endif - } - - void swap(__list_imp& __c) -#if _LIBCPP_STD_VER >= 14 - _NOEXCEPT; -#else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || - __is_nothrow_swappable<allocator_type>::value); -#endif - - _LIBCPP_INLINE_VISIBILITY - void __copy_assign_alloc(const __list_imp& __c) - {__copy_assign_alloc(__c, integral_constant<bool, - __node_alloc_traits::propagate_on_container_copy_assignment::value>());} - - _LIBCPP_INLINE_VISIBILITY - void __move_assign_alloc(__list_imp& __c) - _NOEXCEPT_( - !__node_alloc_traits::propagate_on_container_move_assignment::value || - is_nothrow_move_assignable<__node_allocator>::value) - {__move_assign_alloc(__c, integral_constant<bool, - __node_alloc_traits::propagate_on_container_move_assignment::value>());} - -private: - _LIBCPP_INLINE_VISIBILITY - void __copy_assign_alloc(const __list_imp& __c, true_type) - { - if (__node_alloc() != __c.__node_alloc()) - clear(); - __node_alloc() = __c.__node_alloc(); - } - - _LIBCPP_INLINE_VISIBILITY - void __copy_assign_alloc(const __list_imp&, false_type) - {} - - _LIBCPP_INLINE_VISIBILITY - void __move_assign_alloc(__list_imp& __c, true_type) - _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) - { - __node_alloc() = _VSTD::move(__c.__node_alloc()); - } - - _LIBCPP_INLINE_VISIBILITY - void __move_assign_alloc(__list_imp&, false_type) - _NOEXCEPT - {} - - _LIBCPP_INLINE_VISIBILITY - void __invalidate_all_iterators() { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__invalidate_all(this); -#endif - } -}; - -// Unlink nodes [__f, __l] -template <class _Tp, class _Alloc> -inline -void -__list_imp<_Tp, _Alloc>::__unlink_nodes(__link_pointer __f, __link_pointer __l) - _NOEXCEPT -{ - __f->__prev_->__next_ = __l->__next_; - __l->__next_->__prev_ = __f->__prev_; -} - -template <class _Tp, class _Alloc> -inline -__list_imp<_Tp, _Alloc>::__list_imp() - _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) - : __size_alloc_(0, __default_init_tag()) -{ -} - -template <class _Tp, class _Alloc> -inline -__list_imp<_Tp, _Alloc>::__list_imp(const allocator_type& __a) - : __size_alloc_(0, __node_allocator(__a)) -{ -} - -template <class _Tp, class _Alloc> -inline __list_imp<_Tp, _Alloc>::__list_imp(const __node_allocator& __a) - : __size_alloc_(0, __a) {} - -#ifndef _LIBCPP_CXX03_LANG -template <class _Tp, class _Alloc> -inline __list_imp<_Tp, _Alloc>::__list_imp(__node_allocator&& __a) _NOEXCEPT - : __size_alloc_(0, _VSTD::move(__a)) {} -#endif - -template <class _Tp, class _Alloc> -__list_imp<_Tp, _Alloc>::~__list_imp() { - clear(); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__erase_c(this); -#endif -} - -template <class _Tp, class _Alloc> -void -__list_imp<_Tp, _Alloc>::clear() _NOEXCEPT -{ - if (!empty()) - { - __node_allocator& __na = __node_alloc(); - __link_pointer __f = __end_.__next_; - __link_pointer __l = __end_as_link(); - __unlink_nodes(__f, __l->__prev_); - __sz() = 0; - while (__f != __l) - { - __node_pointer __np = __f->__as_node(); - __f = __f->__next_; - __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); - __node_alloc_traits::deallocate(__na, __np, 1); - } - __invalidate_all_iterators(); - } -} - -template <class _Tp, class _Alloc> -void -__list_imp<_Tp, _Alloc>::swap(__list_imp& __c) -#if _LIBCPP_STD_VER >= 14 - _NOEXCEPT -#else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || - __is_nothrow_swappable<allocator_type>::value) -#endif -{ - _LIBCPP_ASSERT(__alloc_traits::propagate_on_container_swap::value || - this->__node_alloc() == __c.__node_alloc(), - "list::swap: Either propagate_on_container_swap must be true" - " or the allocators must compare equal"); - using _VSTD::swap; - _VSTD::__swap_allocator(__node_alloc(), __c.__node_alloc()); - swap(__sz(), __c.__sz()); - swap(__end_, __c.__end_); - if (__sz() == 0) - __end_.__next_ = __end_.__prev_ = __end_as_link(); - else - __end_.__prev_->__next_ = __end_.__next_->__prev_ = __end_as_link(); - if (__c.__sz() == 0) - __c.__end_.__next_ = __c.__end_.__prev_ = __c.__end_as_link(); - else - __c.__end_.__prev_->__next_ = __c.__end_.__next_->__prev_ = __c.__end_as_link(); - -#if _LIBCPP_DEBUG_LEVEL == 2 - __libcpp_db* __db = __get_db(); - __c_node* __cn1 = __db->__find_c_and_lock(this); - __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c)); - _VSTD::swap(__cn1->beg_, __cn2->beg_); - _VSTD::swap(__cn1->end_, __cn2->end_); - _VSTD::swap(__cn1->cap_, __cn2->cap_); - for (__i_node** __p = __cn1->end_; __p != __cn1->beg_;) - { - --__p; - const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_); - if (__i->__ptr_ == __c.__end_as_link()) - { - __cn2->__add(*__p); - if (--__cn1->end_ != __p) - _VSTD::memmove(__p, __p+1, (__cn1->end_ - __p)*sizeof(__i_node*)); - } - else - (*__p)->__c_ = __cn1; - } - for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;) - { - --__p; - const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_); - if (__i->__ptr_ == __end_as_link()) - { - __cn1->__add(*__p); - if (--__cn2->end_ != __p) - _VSTD::memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*)); - } - else - (*__p)->__c_ = __cn2; - } - __db->unlock(); -#endif -} - -template <class _Tp, class _Alloc /*= allocator<_Tp>*/> -class _LIBCPP_TEMPLATE_VIS list - : private __list_imp<_Tp, _Alloc> -{ - typedef __list_imp<_Tp, _Alloc> base; - typedef typename base::__node __node; - typedef typename base::__node_allocator __node_allocator; - typedef typename base::__node_pointer __node_pointer; - typedef typename base::__node_alloc_traits __node_alloc_traits; - typedef typename base::__node_base __node_base; - typedef typename base::__node_base_pointer __node_base_pointer; - typedef typename base::__link_pointer __link_pointer; - -public: - typedef _Tp value_type; - typedef _Alloc allocator_type; - static_assert((is_same<value_type, typename allocator_type::value_type>::value), - "Invalid allocator::value_type"); - typedef value_type& reference; - typedef const value_type& const_reference; - typedef typename base::pointer pointer; - typedef typename base::const_pointer const_pointer; - typedef typename base::size_type size_type; - typedef typename base::difference_type difference_type; - typedef typename base::iterator iterator; - typedef typename base::const_iterator const_iterator; - typedef _VSTD::reverse_iterator<iterator> reverse_iterator; - typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator; -#if _LIBCPP_STD_VER > 17 - typedef size_type __remove_return_type; -#else - typedef void __remove_return_type; -#endif - - _LIBCPP_INLINE_VISIBILITY - list() - _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) - { - _VSTD::__debug_db_insert_c(this); - } - _LIBCPP_INLINE_VISIBILITY - explicit list(const allocator_type& __a) : base(__a) - { - _VSTD::__debug_db_insert_c(this); - } - explicit list(size_type __n); -#if _LIBCPP_STD_VER > 11 - explicit list(size_type __n, const allocator_type& __a); -#endif - list(size_type __n, const value_type& __x); - template <class = __enable_if_t<__is_allocator<_Alloc>::value> > - list(size_type __n, const value_type& __x, const allocator_type& __a) : base(__a) - { - _VSTD::__debug_db_insert_c(this); - for (; __n > 0; --__n) - push_back(__x); - } - - template <class _InpIter> - list(_InpIter __f, _InpIter __l, - typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type* = 0); - template <class _InpIter> - list(_InpIter __f, _InpIter __l, const allocator_type& __a, - typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type* = 0); - - list(const list& __c); - list(const list& __c, const __identity_t<allocator_type>& __a); - _LIBCPP_INLINE_VISIBILITY - list& operator=(const list& __c); -#ifndef _LIBCPP_CXX03_LANG - list(initializer_list<value_type> __il); - list(initializer_list<value_type> __il, const allocator_type& __a); - - _LIBCPP_INLINE_VISIBILITY - list(list&& __c) - _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value); - _LIBCPP_INLINE_VISIBILITY - list(list&& __c, const __identity_t<allocator_type>& __a); - _LIBCPP_INLINE_VISIBILITY - list& operator=(list&& __c) - _NOEXCEPT_( - __node_alloc_traits::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<__node_allocator>::value); - - _LIBCPP_INLINE_VISIBILITY - list& operator=(initializer_list<value_type> __il) - {assign(__il.begin(), __il.end()); return *this;} - - _LIBCPP_INLINE_VISIBILITY - void assign(initializer_list<value_type> __il) - {assign(__il.begin(), __il.end());} -#endif // _LIBCPP_CXX03_LANG - - template <class _InpIter> - void assign(_InpIter __f, _InpIter __l, - typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type* = 0); - void assign(size_type __n, const value_type& __x); - - _LIBCPP_INLINE_VISIBILITY - allocator_type get_allocator() const _NOEXCEPT; - - _LIBCPP_INLINE_VISIBILITY - size_type size() const _NOEXCEPT {return base::__sz();} - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY - bool empty() const _NOEXCEPT {return base::empty();} - _LIBCPP_INLINE_VISIBILITY - size_type max_size() const _NOEXCEPT - { - return _VSTD::min<size_type>( - base::__node_alloc_max_size(), - numeric_limits<difference_type >::max()); - } - - _LIBCPP_INLINE_VISIBILITY - iterator begin() _NOEXCEPT {return base::begin();} - _LIBCPP_INLINE_VISIBILITY - const_iterator begin() const _NOEXCEPT {return base::begin();} - _LIBCPP_INLINE_VISIBILITY - iterator end() _NOEXCEPT {return base::end();} - _LIBCPP_INLINE_VISIBILITY - const_iterator end() const _NOEXCEPT {return base::end();} - _LIBCPP_INLINE_VISIBILITY - const_iterator cbegin() const _NOEXCEPT {return base::begin();} - _LIBCPP_INLINE_VISIBILITY - const_iterator cend() const _NOEXCEPT {return base::end();} - - _LIBCPP_INLINE_VISIBILITY - reverse_iterator rbegin() _NOEXCEPT - {return reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY - const_reverse_iterator rbegin() const _NOEXCEPT - {return const_reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY - reverse_iterator rend() _NOEXCEPT - {return reverse_iterator(begin());} - _LIBCPP_INLINE_VISIBILITY - const_reverse_iterator rend() const _NOEXCEPT - {return const_reverse_iterator(begin());} - _LIBCPP_INLINE_VISIBILITY - const_reverse_iterator crbegin() const _NOEXCEPT - {return const_reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY - const_reverse_iterator crend() const _NOEXCEPT - {return const_reverse_iterator(begin());} - - _LIBCPP_INLINE_VISIBILITY - reference front() - { - _LIBCPP_ASSERT(!empty(), "list::front called on empty list"); - return base::__end_.__next_->__as_node()->__value_; - } - _LIBCPP_INLINE_VISIBILITY - const_reference front() const - { - _LIBCPP_ASSERT(!empty(), "list::front called on empty list"); - return base::__end_.__next_->__as_node()->__value_; - } - _LIBCPP_INLINE_VISIBILITY - reference back() - { - _LIBCPP_ASSERT(!empty(), "list::back called on empty list"); - return base::__end_.__prev_->__as_node()->__value_; - } - _LIBCPP_INLINE_VISIBILITY - const_reference back() const - { - _LIBCPP_ASSERT(!empty(), "list::back called on empty list"); - return base::__end_.__prev_->__as_node()->__value_; - } - -#ifndef _LIBCPP_CXX03_LANG - void push_front(value_type&& __x); - void push_back(value_type&& __x); - - template <class... _Args> -#if _LIBCPP_STD_VER > 14 - reference emplace_front(_Args&&... __args); -#else - void emplace_front(_Args&&... __args); -#endif - template <class... _Args> -#if _LIBCPP_STD_VER > 14 - reference emplace_back(_Args&&... __args); -#else - void emplace_back(_Args&&... __args); -#endif - template <class... _Args> - iterator emplace(const_iterator __p, _Args&&... __args); - - iterator insert(const_iterator __p, value_type&& __x); - - _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __p, initializer_list<value_type> __il) - {return insert(__p, __il.begin(), __il.end());} -#endif // _LIBCPP_CXX03_LANG - - void push_front(const value_type& __x); - void push_back(const value_type& __x); - -#ifndef _LIBCPP_CXX03_LANG - template <class _Arg> - _LIBCPP_INLINE_VISIBILITY - void __emplace_back(_Arg&& __arg) { emplace_back(_VSTD::forward<_Arg>(__arg)); } -#else - _LIBCPP_INLINE_VISIBILITY - void __emplace_back(value_type const& __arg) { push_back(__arg); } -#endif - - iterator insert(const_iterator __p, const value_type& __x); - iterator insert(const_iterator __p, size_type __n, const value_type& __x); - template <class _InpIter> - iterator insert(const_iterator __p, _InpIter __f, _InpIter __l, - typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type* = 0); - - _LIBCPP_INLINE_VISIBILITY - void swap(list& __c) -#if _LIBCPP_STD_VER >= 14 - _NOEXCEPT -#else - _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value || - __is_nothrow_swappable<__node_allocator>::value) -#endif - {base::swap(__c);} - _LIBCPP_INLINE_VISIBILITY - void clear() _NOEXCEPT {base::clear();} - - void pop_front(); - void pop_back(); - - iterator erase(const_iterator __p); - iterator erase(const_iterator __f, const_iterator __l); - - void resize(size_type __n); - void resize(size_type __n, const value_type& __x); - - void splice(const_iterator __p, list& __c); -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - void splice(const_iterator __p, list&& __c) {splice(__p, __c);} - _LIBCPP_INLINE_VISIBILITY - void splice(const_iterator __p, list&& __c, const_iterator __i) - {splice(__p, __c, __i);} - _LIBCPP_INLINE_VISIBILITY - void splice(const_iterator __p, list&& __c, const_iterator __f, const_iterator __l) - {splice(__p, __c, __f, __l);} -#endif - void splice(const_iterator __p, list& __c, const_iterator __i); - void splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l); - - __remove_return_type remove(const value_type& __x); - template <class _Pred> __remove_return_type remove_if(_Pred __pred); - _LIBCPP_INLINE_VISIBILITY - __remove_return_type unique() { return unique(__equal_to<value_type>()); } - template <class _BinaryPred> - __remove_return_type unique(_BinaryPred __binary_pred); - _LIBCPP_INLINE_VISIBILITY - void merge(list& __c); -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - void merge(list&& __c) {merge(__c);} - - template <class _Comp> - _LIBCPP_INLINE_VISIBILITY - void merge(list&& __c, _Comp __comp) {merge(__c, __comp);} -#endif - template <class _Comp> - void merge(list& __c, _Comp __comp); - - _LIBCPP_INLINE_VISIBILITY - void sort(); - template <class _Comp> - _LIBCPP_INLINE_VISIBILITY - void sort(_Comp __comp); - - void reverse() _NOEXCEPT; - - bool __invariants() const; - - typedef __allocator_destructor<__node_allocator> __node_destructor; - typedef unique_ptr<__node, __node_destructor> __hold_pointer; - - _LIBCPP_INLINE_VISIBILITY - __hold_pointer __allocate_node(__node_allocator& __na) { - __node_pointer __p = __node_alloc_traits::allocate(__na, 1); - __p->__prev_ = nullptr; - return __hold_pointer(__p, __node_destructor(__na, 1)); - } - -#if _LIBCPP_DEBUG_LEVEL == 2 - - 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_DEBUG_LEVEL == 2 - -private: - _LIBCPP_INLINE_VISIBILITY - static void __link_nodes (__link_pointer __p, __link_pointer __f, __link_pointer __l); - _LIBCPP_INLINE_VISIBILITY - void __link_nodes_at_front(__link_pointer __f, __link_pointer __l); - _LIBCPP_INLINE_VISIBILITY - void __link_nodes_at_back (__link_pointer __f, __link_pointer __l); - iterator __iterator(size_type __n); - template <class _Comp> - static iterator __sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp); - - void __move_assign(list& __c, true_type) - _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value); - void __move_assign(list& __c, false_type); -}; - -#if _LIBCPP_STD_VER >= 17 -template<class _InputIterator, - class _Alloc = allocator<__iter_value_type<_InputIterator>>, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = enable_if_t<__is_allocator<_Alloc>::value> - > -list(_InputIterator, _InputIterator) - -> list<__iter_value_type<_InputIterator>, _Alloc>; - -template<class _InputIterator, - class _Alloc, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = enable_if_t<__is_allocator<_Alloc>::value> - > -list(_InputIterator, _InputIterator, _Alloc) - -> list<__iter_value_type<_InputIterator>, _Alloc>; -#endif - -// Link in nodes [__f, __l] just prior to __p -template <class _Tp, class _Alloc> -inline -void -list<_Tp, _Alloc>::__link_nodes(__link_pointer __p, __link_pointer __f, __link_pointer __l) -{ - __p->__prev_->__next_ = __f; - __f->__prev_ = __p->__prev_; - __p->__prev_ = __l; - __l->__next_ = __p; -} - -// Link in nodes [__f, __l] at the front of the list -template <class _Tp, class _Alloc> -inline -void -list<_Tp, _Alloc>::__link_nodes_at_front(__link_pointer __f, __link_pointer __l) -{ - __f->__prev_ = base::__end_as_link(); - __l->__next_ = base::__end_.__next_; - __l->__next_->__prev_ = __l; - base::__end_.__next_ = __f; -} - -// Link in nodes [__f, __l] at the back of the list -template <class _Tp, class _Alloc> -inline -void -list<_Tp, _Alloc>::__link_nodes_at_back(__link_pointer __f, __link_pointer __l) -{ - __l->__next_ = base::__end_as_link(); - __f->__prev_ = base::__end_.__prev_; - __f->__prev_->__next_ = __f; - base::__end_.__prev_ = __l; -} - - -template <class _Tp, class _Alloc> -inline -typename list<_Tp, _Alloc>::iterator -list<_Tp, _Alloc>::__iterator(size_type __n) -{ - return __n <= base::__sz() / 2 ? _VSTD::next(begin(), __n) - : _VSTD::prev(end(), base::__sz() - __n); -} - -template <class _Tp, class _Alloc> -list<_Tp, _Alloc>::list(size_type __n) -{ - _VSTD::__debug_db_insert_c(this); - for (; __n > 0; --__n) -#ifndef _LIBCPP_CXX03_LANG - emplace_back(); -#else - push_back(value_type()); -#endif -} - -#if _LIBCPP_STD_VER > 11 -template <class _Tp, class _Alloc> -list<_Tp, _Alloc>::list(size_type __n, const allocator_type& __a) : base(__a) -{ - _VSTD::__debug_db_insert_c(this); - for (; __n > 0; --__n) - emplace_back(); -} -#endif - -template <class _Tp, class _Alloc> -list<_Tp, _Alloc>::list(size_type __n, const value_type& __x) -{ - _VSTD::__debug_db_insert_c(this); - for (; __n > 0; --__n) - push_back(__x); -} - -template <class _Tp, class _Alloc> -template <class _InpIter> -list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, - typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type*) -{ - _VSTD::__debug_db_insert_c(this); - for (; __f != __l; ++__f) - __emplace_back(*__f); -} - -template <class _Tp, class _Alloc> -template <class _InpIter> -list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, const allocator_type& __a, - typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type*) - : base(__a) -{ - _VSTD::__debug_db_insert_c(this); - for (; __f != __l; ++__f) - __emplace_back(*__f); -} - -template <class _Tp, class _Alloc> -list<_Tp, _Alloc>::list(const list& __c) - : base(__node_alloc_traits::select_on_container_copy_construction( - __c.__node_alloc())) { - _VSTD::__debug_db_insert_c(this); - for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i) - push_back(*__i); -} - -template <class _Tp, class _Alloc> -list<_Tp, _Alloc>::list(const list& __c, const __identity_t<allocator_type>& __a) - : base(__a) -{ - _VSTD::__debug_db_insert_c(this); - for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i) - push_back(*__i); -} - -#ifndef _LIBCPP_CXX03_LANG - -template <class _Tp, class _Alloc> -list<_Tp, _Alloc>::list(initializer_list<value_type> __il, const allocator_type& __a) - : base(__a) -{ - _VSTD::__debug_db_insert_c(this); - for (typename initializer_list<value_type>::const_iterator __i = __il.begin(), - __e = __il.end(); __i != __e; ++__i) - push_back(*__i); -} - -template <class _Tp, class _Alloc> -list<_Tp, _Alloc>::list(initializer_list<value_type> __il) -{ - _VSTD::__debug_db_insert_c(this); - for (typename initializer_list<value_type>::const_iterator __i = __il.begin(), - __e = __il.end(); __i != __e; ++__i) - push_back(*__i); -} - -template <class _Tp, class _Alloc> -inline list<_Tp, _Alloc>::list(list&& __c) - _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value) - : base(_VSTD::move(__c.__node_alloc())) { - _VSTD::__debug_db_insert_c(this); - splice(end(), __c); -} - -template <class _Tp, class _Alloc> -inline -list<_Tp, _Alloc>::list(list&& __c, const __identity_t<allocator_type>& __a) - : base(__a) -{ - _VSTD::__debug_db_insert_c(this); - if (__a == __c.get_allocator()) - splice(end(), __c); - else - { - typedef move_iterator<iterator> _Ip; - assign(_Ip(__c.begin()), _Ip(__c.end())); - } -} - -template <class _Tp, class _Alloc> -inline -list<_Tp, _Alloc>& -list<_Tp, _Alloc>::operator=(list&& __c) - _NOEXCEPT_( - __node_alloc_traits::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<__node_allocator>::value) -{ - __move_assign(__c, integral_constant<bool, - __node_alloc_traits::propagate_on_container_move_assignment::value>()); - return *this; -} - -template <class _Tp, class _Alloc> -void -list<_Tp, _Alloc>::__move_assign(list& __c, false_type) -{ - if (base::__node_alloc() != __c.__node_alloc()) - { - typedef move_iterator<iterator> _Ip; - assign(_Ip(__c.begin()), _Ip(__c.end())); - } - else - __move_assign(__c, true_type()); -} - -template <class _Tp, class _Alloc> -void -list<_Tp, _Alloc>::__move_assign(list& __c, true_type) - _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) -{ - clear(); - base::__move_assign_alloc(__c); - splice(end(), __c); -} - -#endif // _LIBCPP_CXX03_LANG - -template <class _Tp, class _Alloc> -inline -list<_Tp, _Alloc>& -list<_Tp, _Alloc>::operator=(const list& __c) -{ - if (this != _VSTD::addressof(__c)) - { - base::__copy_assign_alloc(__c); - assign(__c.begin(), __c.end()); - } - return *this; -} - -template <class _Tp, class _Alloc> -template <class _InpIter> -void -list<_Tp, _Alloc>::assign(_InpIter __f, _InpIter __l, - typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type*) -{ - iterator __i = begin(); - iterator __e = end(); - for (; __f != __l && __i != __e; ++__f, (void) ++__i) - *__i = *__f; - if (__i == __e) - insert(__e, __f, __l); - else - erase(__i, __e); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__invalidate_all(this); -#endif -} - -template <class _Tp, class _Alloc> -void -list<_Tp, _Alloc>::assign(size_type __n, const value_type& __x) -{ - iterator __i = begin(); - iterator __e = end(); - for (; __n > 0 && __i != __e; --__n, (void) ++__i) - *__i = __x; - if (__i == __e) - insert(__e, __n, __x); - else - erase(__i, __e); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__invalidate_all(this); -#endif -} - -template <class _Tp, class _Alloc> -inline -_Alloc -list<_Tp, _Alloc>::get_allocator() const _NOEXCEPT -{ - return allocator_type(base::__node_alloc()); -} - -template <class _Tp, class _Alloc> -typename list<_Tp, _Alloc>::iterator -list<_Tp, _Alloc>::insert(const_iterator __p, const value_type& __x) -{ - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::insert(iterator, x) called with an iterator not referring to this list"); - __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); - __link_nodes(__p.__ptr_, __hold->__as_link(), __hold->__as_link()); - ++base::__sz(); -#if _LIBCPP_DEBUG_LEVEL == 2 - return iterator(__hold.release()->__as_link(), this); -#else - return iterator(__hold.release()->__as_link()); -#endif -} - -template <class _Tp, class _Alloc> -typename list<_Tp, _Alloc>::iterator -list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& __x) -{ - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::insert(iterator, n, x) called with an iterator not referring to this list"); -#if _LIBCPP_DEBUG_LEVEL == 2 - iterator __r(__p.__ptr_, this); -#else - iterator __r(__p.__ptr_); -#endif - if (__n > 0) - { - size_type __ds = 0; - __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); - ++__ds; -#if _LIBCPP_DEBUG_LEVEL == 2 - __r = iterator(__hold->__as_link(), this); -#else - __r = iterator(__hold->__as_link()); -#endif - __hold.release(); - iterator __e = __r; -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - for (--__n; __n != 0; --__n, (void) ++__e, ++__ds) - { - __hold.reset(__node_alloc_traits::allocate(__na, 1)); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); - __e.__ptr_->__next_ = __hold->__as_link(); - __hold->__prev_ = __e.__ptr_; - __hold.release(); - } -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - while (true) - { - __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e)); - __link_pointer __prev = __e.__ptr_->__prev_; - __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1); - if (__prev == 0) - break; -#if _LIBCPP_DEBUG_LEVEL == 2 - __e = iterator(__prev, this); -#else - __e = iterator(__prev); -#endif - } - throw; - } -#endif // _LIBCPP_NO_EXCEPTIONS - __link_nodes(__p.__ptr_, __r.__ptr_, __e.__ptr_); - base::__sz() += __ds; - } - return __r; -} - -template <class _Tp, class _Alloc> -template <class _InpIter> -typename list<_Tp, _Alloc>::iterator -list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l, - typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type*) -{ - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::insert(iterator, range) called with an iterator not referring to this list"); -#if _LIBCPP_DEBUG_LEVEL == 2 - iterator __r(__p.__ptr_, this); -#else - iterator __r(__p.__ptr_); -#endif - if (__f != __l) - { - size_type __ds = 0; - __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f); - ++__ds; -#if _LIBCPP_DEBUG_LEVEL == 2 - __r = iterator(__hold.get()->__as_link(), this); -#else - __r = iterator(__hold.get()->__as_link()); -#endif - __hold.release(); - iterator __e = __r; -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - for (++__f; __f != __l; ++__f, (void) ++__e, ++__ds) - { - __hold.reset(__node_alloc_traits::allocate(__na, 1)); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f); - __e.__ptr_->__next_ = __hold.get()->__as_link(); - __hold->__prev_ = __e.__ptr_; - __hold.release(); - } -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - while (true) - { - __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e)); - __link_pointer __prev = __e.__ptr_->__prev_; - __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1); - if (__prev == 0) - break; -#if _LIBCPP_DEBUG_LEVEL == 2 - __e = iterator(__prev, this); -#else - __e = iterator(__prev); -#endif - } - throw; - } -#endif // _LIBCPP_NO_EXCEPTIONS - __link_nodes(__p.__ptr_, __r.__ptr_, __e.__ptr_); - base::__sz() += __ds; - } - return __r; -} - -template <class _Tp, class _Alloc> -void -list<_Tp, _Alloc>::push_front(const value_type& __x) -{ - __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); - __link_pointer __nl = __hold->__as_link(); - __link_nodes_at_front(__nl, __nl); - ++base::__sz(); - __hold.release(); -} - -template <class _Tp, class _Alloc> -void -list<_Tp, _Alloc>::push_back(const value_type& __x) -{ - __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); - __link_nodes_at_back(__hold.get()->__as_link(), __hold.get()->__as_link()); - ++base::__sz(); - __hold.release(); -} - -#ifndef _LIBCPP_CXX03_LANG - -template <class _Tp, class _Alloc> -void -list<_Tp, _Alloc>::push_front(value_type&& __x) -{ - __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x)); - __link_nodes_at_front(__hold.get()->__as_link(), __hold.get()->__as_link()); - ++base::__sz(); - __hold.release(); -} - -template <class _Tp, class _Alloc> -void -list<_Tp, _Alloc>::push_back(value_type&& __x) -{ - __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x)); - __link_nodes_at_back(__hold.get()->__as_link(), __hold.get()->__as_link()); - ++base::__sz(); - __hold.release(); -} - -template <class _Tp, class _Alloc> -template <class... _Args> -#if _LIBCPP_STD_VER > 14 -typename list<_Tp, _Alloc>::reference -#else -void -#endif -list<_Tp, _Alloc>::emplace_front(_Args&&... __args) -{ - __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...); - __link_nodes_at_front(__hold.get()->__as_link(), __hold.get()->__as_link()); - ++base::__sz(); -#if _LIBCPP_STD_VER > 14 - return __hold.release()->__value_; -#else - __hold.release(); -#endif -} - -template <class _Tp, class _Alloc> -template <class... _Args> -#if _LIBCPP_STD_VER > 14 -typename list<_Tp, _Alloc>::reference -#else -void -#endif -list<_Tp, _Alloc>::emplace_back(_Args&&... __args) -{ - __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...); - __link_pointer __nl = __hold->__as_link(); - __link_nodes_at_back(__nl, __nl); - ++base::__sz(); -#if _LIBCPP_STD_VER > 14 - return __hold.release()->__value_; -#else - __hold.release(); -#endif -} - -template <class _Tp, class _Alloc> -template <class... _Args> -typename list<_Tp, _Alloc>::iterator -list<_Tp, _Alloc>::emplace(const_iterator __p, _Args&&... __args) -{ - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::emplace(iterator, args...) called with an iterator not referring to this list"); - __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...); - __link_pointer __nl = __hold.get()->__as_link(); - __link_nodes(__p.__ptr_, __nl, __nl); - ++base::__sz(); - __hold.release(); -#if _LIBCPP_DEBUG_LEVEL == 2 - return iterator(__nl, this); -#else - return iterator(__nl); -#endif -} - -template <class _Tp, class _Alloc> -typename list<_Tp, _Alloc>::iterator -list<_Tp, _Alloc>::insert(const_iterator __p, value_type&& __x) -{ - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::insert(iterator, x) called with an iterator not referring to this list"); - __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x)); - __link_pointer __nl = __hold->__as_link(); - __link_nodes(__p.__ptr_, __nl, __nl); - ++base::__sz(); - __hold.release(); -#if _LIBCPP_DEBUG_LEVEL == 2 - return iterator(__nl, this); -#else - return iterator(__nl); -#endif -} - -#endif // _LIBCPP_CXX03_LANG - -template <class _Tp, class _Alloc> -void -list<_Tp, _Alloc>::pop_front() -{ - _LIBCPP_ASSERT(!empty(), "list::pop_front() called with empty list"); - __node_allocator& __na = base::__node_alloc(); - __link_pointer __n = base::__end_.__next_; - base::__unlink_nodes(__n, __n); - --base::__sz(); -#if _LIBCPP_DEBUG_LEVEL == 2 - __c_node* __c = __get_db()->__find_c_and_lock(this); - for (__i_node** __p = __c->end_; __p != __c->beg_; ) - { - --__p; - iterator* __i = static_cast<iterator*>((*__p)->__i_); - if (__i->__ptr_ == __n) - { - (*__p)->__c_ = nullptr; - if (--__c->end_ != __p) - _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); - } - } - __get_db()->unlock(); -#endif - __node_pointer __np = __n->__as_node(); - __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); - __node_alloc_traits::deallocate(__na, __np, 1); -} - -template <class _Tp, class _Alloc> -void -list<_Tp, _Alloc>::pop_back() -{ - _LIBCPP_ASSERT(!empty(), "list::pop_back() called on an empty list"); - __node_allocator& __na = base::__node_alloc(); - __link_pointer __n = base::__end_.__prev_; - base::__unlink_nodes(__n, __n); - --base::__sz(); -#if _LIBCPP_DEBUG_LEVEL == 2 - __c_node* __c = __get_db()->__find_c_and_lock(this); - for (__i_node** __p = __c->end_; __p != __c->beg_; ) - { - --__p; - iterator* __i = static_cast<iterator*>((*__p)->__i_); - if (__i->__ptr_ == __n) - { - (*__p)->__c_ = nullptr; - if (--__c->end_ != __p) - _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); - } - } - __get_db()->unlock(); -#endif - __node_pointer __np = __n->__as_node(); - __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); - __node_alloc_traits::deallocate(__na, __np, 1); -} - -template <class _Tp, class _Alloc> -typename list<_Tp, _Alloc>::iterator -list<_Tp, _Alloc>::erase(const_iterator __p) -{ - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::erase(iterator) called with an iterator not referring to this list"); - _LIBCPP_ASSERT(__p != end(), - "list::erase(iterator) called with a non-dereferenceable iterator"); - __node_allocator& __na = base::__node_alloc(); - __link_pointer __n = __p.__ptr_; - __link_pointer __r = __n->__next_; - base::__unlink_nodes(__n, __n); - --base::__sz(); -#if _LIBCPP_DEBUG_LEVEL == 2 - __c_node* __c = __get_db()->__find_c_and_lock(this); - for (__i_node** __ip = __c->end_; __ip != __c->beg_; ) - { - --__ip; - iterator* __i = static_cast<iterator*>((*__ip)->__i_); - if (__i->__ptr_ == __n) - { - (*__ip)->__c_ = nullptr; - if (--__c->end_ != __ip) - _VSTD::memmove(__ip, __ip+1, (__c->end_ - __ip)*sizeof(__i_node*)); - } - } - __get_db()->unlock(); -#endif - __node_pointer __np = __n->__as_node(); - __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); - __node_alloc_traits::deallocate(__na, __np, 1); -#if _LIBCPP_DEBUG_LEVEL == 2 - return iterator(__r, this); -#else - return iterator(__r); -#endif -} - -template <class _Tp, class _Alloc> -typename list<_Tp, _Alloc>::iterator -list<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l) -{ - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__f)) == this, - "list::erase(iterator, iterator) called with an iterator not referring to this list"); - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__l)) == this, - "list::erase(iterator, iterator) called with an iterator not referring to this list"); - if (__f != __l) - { - __node_allocator& __na = base::__node_alloc(); - base::__unlink_nodes(__f.__ptr_, __l.__ptr_->__prev_); - while (__f != __l) - { - __link_pointer __n = __f.__ptr_; - ++__f; - --base::__sz(); -#if _LIBCPP_DEBUG_LEVEL == 2 - __c_node* __c = __get_db()->__find_c_and_lock(this); - for (__i_node** __p = __c->end_; __p != __c->beg_; ) - { - --__p; - iterator* __i = static_cast<iterator*>((*__p)->__i_); - if (__i->__ptr_ == __n) - { - (*__p)->__c_ = nullptr; - if (--__c->end_ != __p) - _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); - } - } - __get_db()->unlock(); -#endif - __node_pointer __np = __n->__as_node(); - __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); - __node_alloc_traits::deallocate(__na, __np, 1); - } - } -#if _LIBCPP_DEBUG_LEVEL == 2 - return iterator(__l.__ptr_, this); -#else - return iterator(__l.__ptr_); -#endif -} - -template <class _Tp, class _Alloc> -void -list<_Tp, _Alloc>::resize(size_type __n) -{ - if (__n < base::__sz()) - erase(__iterator(__n), end()); - else if (__n > base::__sz()) - { - __n -= base::__sz(); - size_type __ds = 0; - __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_)); - ++__ds; -#if _LIBCPP_DEBUG_LEVEL == 2 - iterator __r = iterator(__hold.release()->__as_link(), this); -#else - iterator __r = iterator(__hold.release()->__as_link()); -#endif - iterator __e = __r; -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - for (--__n; __n != 0; --__n, (void) ++__e, ++__ds) - { - __hold.reset(__node_alloc_traits::allocate(__na, 1)); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_)); - __e.__ptr_->__next_ = __hold.get()->__as_link(); - __hold->__prev_ = __e.__ptr_; - __hold.release(); - } -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - while (true) - { - __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e)); - __link_pointer __prev = __e.__ptr_->__prev_; - __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1); - if (__prev == 0) - break; -#if _LIBCPP_DEBUG_LEVEL == 2 - __e = iterator(__prev, this); -#else - __e = iterator(__prev); -#endif - } - throw; - } -#endif // _LIBCPP_NO_EXCEPTIONS - __link_nodes_at_back(__r.__ptr_, __e.__ptr_); - base::__sz() += __ds; - } -} - -template <class _Tp, class _Alloc> -void -list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x) -{ - if (__n < base::__sz()) - erase(__iterator(__n), end()); - else if (__n > base::__sz()) - { - __n -= base::__sz(); - size_type __ds = 0; - __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); - ++__ds; - __link_pointer __nl = __hold.release()->__as_link(); -#if _LIBCPP_DEBUG_LEVEL == 2 - iterator __r = iterator(__nl, this); -#else - iterator __r = iterator(__nl); -#endif - iterator __e = __r; -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - for (--__n; __n != 0; --__n, (void) ++__e, ++__ds) - { - __hold.reset(__node_alloc_traits::allocate(__na, 1)); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); - __e.__ptr_->__next_ = __hold.get()->__as_link(); - __hold->__prev_ = __e.__ptr_; - __hold.release(); - } -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - while (true) - { - __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e)); - __link_pointer __prev = __e.__ptr_->__prev_; - __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1); - if (__prev == 0) - break; -#if _LIBCPP_DEBUG_LEVEL == 2 - __e = iterator(__prev, this); -#else - __e = iterator(__prev); -#endif - } - throw; - } -#endif // _LIBCPP_NO_EXCEPTIONS - __link_nodes(base::__end_as_link(), __r.__ptr_, __e.__ptr_); - base::__sz() += __ds; - } -} - -template <class _Tp, class _Alloc> -void -list<_Tp, _Alloc>::splice(const_iterator __p, list& __c) -{ - _LIBCPP_ASSERT(this != _VSTD::addressof(__c), - "list::splice(iterator, list) called with this == &list"); - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::splice(iterator, list) called with an iterator not referring to this list"); - if (!__c.empty()) - { - __link_pointer __f = __c.__end_.__next_; - __link_pointer __l = __c.__end_.__prev_; - base::__unlink_nodes(__f, __l); - __link_nodes(__p.__ptr_, __f, __l); - base::__sz() += __c.__sz(); - __c.__sz() = 0; -#if _LIBCPP_DEBUG_LEVEL == 2 - if (_VSTD::addressof(__c) != this) { - __libcpp_db* __db = __get_db(); - __c_node* __cn1 = __db->__find_c_and_lock(this); - __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c)); - for (__i_node** __ip = __cn2->end_; __ip != __cn2->beg_;) - { - --__ip; - iterator* __i = static_cast<iterator*>((*__ip)->__i_); - if (__i->__ptr_ != __c.__end_as_link()) - { - __cn1->__add(*__ip); - (*__ip)->__c_ = __cn1; - if (--__cn2->end_ != __ip) - memmove(__ip, __ip+1, (__cn2->end_ - __ip)*sizeof(__i_node*)); - } - } - __db->unlock(); - } -#endif - } -} - -template <class _Tp, class _Alloc> -void -list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i) -{ - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::splice(iterator, list, iterator) called with the first iterator not referring to this list"); - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__i)) == _VSTD::addressof(__c), - "list::splice(iterator, list, iterator) called with the second iterator not referring to the list argument"); - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(_VSTD::addressof(__i)), - "list::splice(iterator, list, iterator) called with the second iterator not dereferenceable"); - - if (__p.__ptr_ != __i.__ptr_ && __p.__ptr_ != __i.__ptr_->__next_) - { - __link_pointer __f = __i.__ptr_; - base::__unlink_nodes(__f, __f); - __link_nodes(__p.__ptr_, __f, __f); - --__c.__sz(); - ++base::__sz(); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (_VSTD::addressof(__c) != this) { - __libcpp_db* __db = __get_db(); - __c_node* __cn1 = __db->__find_c_and_lock(this); - __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c)); - for (__i_node** __ip = __cn2->end_; __ip != __cn2->beg_;) - { - --__ip; - iterator* __j = static_cast<iterator*>((*__ip)->__i_); - if (__j->__ptr_ == __f) - { - __cn1->__add(*__ip); - (*__ip)->__c_ = __cn1; - if (--__cn2->end_ != __ip) - _VSTD::memmove(__ip, __ip+1, (__cn2->end_ - __ip)*sizeof(__i_node*)); - } - } - __db->unlock(); - } -#endif - } -} - -template <class _Tp, class _Alloc> -void -list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l) -{ - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::splice(iterator, list, iterator, iterator) called with first iterator not referring to this list"); - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__f)) == _VSTD::addressof(__c), - "list::splice(iterator, list, iterator, iterator) called with second iterator not referring to the list argument"); - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__l)) == _VSTD::addressof(__c), - "list::splice(iterator, list, iterator, iterator) called with third iterator not referring to the list argument"); - -#if _LIBCPP_DEBUG_LEVEL == 2 - if (this == _VSTD::addressof(__c)) - { - for (const_iterator __i = __f; __i != __l; ++__i) - _LIBCPP_DEBUG_ASSERT(__i != __p, - "list::splice(iterator, list, iterator, iterator)" - " called with the first iterator within the range of the second and third iterators"); - } -#endif - if (__f != __l) - { - __link_pointer __first = __f.__ptr_; - --__l; - __link_pointer __last = __l.__ptr_; - if (this != _VSTD::addressof(__c)) - { - size_type __s = _VSTD::distance(__f, __l) + 1; - __c.__sz() -= __s; - base::__sz() += __s; - } - base::__unlink_nodes(__first, __last); - __link_nodes(__p.__ptr_, __first, __last); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (_VSTD::addressof(__c) != this) { - __libcpp_db* __db = __get_db(); - __c_node* __cn1 = __db->__find_c_and_lock(this); - __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c)); - for (__i_node** __ip = __cn2->end_; __ip != __cn2->beg_;) - { - --__ip; - iterator* __j = static_cast<iterator*>((*__ip)->__i_); - for (__link_pointer __k = __f.__ptr_; - __k != __l.__ptr_; __k = __k->__next_) - { - if (__j->__ptr_ == __k) - { - __cn1->__add(*__ip); - (*__ip)->__c_ = __cn1; - if (--__cn2->end_ != __ip) - _VSTD::memmove(__ip, __ip+1, (__cn2->end_ - __ip)*sizeof(__i_node*)); - } - } - } - __db->unlock(); - } -#endif - } -} - -template <class _Tp, class _Alloc> -typename list<_Tp, _Alloc>::__remove_return_type -list<_Tp, _Alloc>::remove(const value_type& __x) -{ - list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing - for (const_iterator __i = begin(), __e = end(); __i != __e;) - { - if (*__i == __x) - { - const_iterator __j = _VSTD::next(__i); - for (; __j != __e && *__j == __x; ++__j) - ; - __deleted_nodes.splice(__deleted_nodes.end(), *this, __i, __j); - __i = __j; - if (__i != __e) - ++__i; - } - else - ++__i; - } - - return (__remove_return_type) __deleted_nodes.size(); -} - -template <class _Tp, class _Alloc> -template <class _Pred> -typename list<_Tp, _Alloc>::__remove_return_type -list<_Tp, _Alloc>::remove_if(_Pred __pred) -{ - list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing - for (iterator __i = begin(), __e = end(); __i != __e;) - { - if (__pred(*__i)) - { - iterator __j = _VSTD::next(__i); - for (; __j != __e && __pred(*__j); ++__j) - ; - __deleted_nodes.splice(__deleted_nodes.end(), *this, __i, __j); - __i = __j; - if (__i != __e) - ++__i; - } - else - ++__i; - } - - return (__remove_return_type) __deleted_nodes.size(); -} - -template <class _Tp, class _Alloc> -template <class _BinaryPred> -typename list<_Tp, _Alloc>::__remove_return_type -list<_Tp, _Alloc>::unique(_BinaryPred __binary_pred) -{ - list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing - for (iterator __i = begin(), __e = end(); __i != __e;) - { - iterator __j = _VSTD::next(__i); - for (; __j != __e && __binary_pred(*__i, *__j); ++__j) - ; - if (++__i != __j) { - __deleted_nodes.splice(__deleted_nodes.end(), *this, __i, __j); - __i = __j; - } - } - - return (__remove_return_type) __deleted_nodes.size(); -} - -template <class _Tp, class _Alloc> -inline -void -list<_Tp, _Alloc>::merge(list& __c) -{ - merge(__c, __less<value_type>()); -} - -template <class _Tp, class _Alloc> -template <class _Comp> -void -list<_Tp, _Alloc>::merge(list& __c, _Comp __comp) -{ - if (this != _VSTD::addressof(__c)) - { - iterator __f1 = begin(); - iterator __e1 = end(); - iterator __f2 = __c.begin(); - iterator __e2 = __c.end(); - while (__f1 != __e1 && __f2 != __e2) - { - if (__comp(*__f2, *__f1)) - { - size_type __ds = 1; - iterator __m2 = _VSTD::next(__f2); - for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2, (void) ++__ds) - ; - base::__sz() += __ds; - __c.__sz() -= __ds; - __link_pointer __f = __f2.__ptr_; - __link_pointer __l = __m2.__ptr_->__prev_; - __f2 = __m2; - base::__unlink_nodes(__f, __l); - __m2 = _VSTD::next(__f1); - __link_nodes(__f1.__ptr_, __f, __l); - __f1 = __m2; - } - else - ++__f1; - } - splice(__e1, __c); -#if _LIBCPP_DEBUG_LEVEL == 2 - __libcpp_db* __db = __get_db(); - __c_node* __cn1 = __db->__find_c_and_lock(this); - __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c)); - for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;) - { - --__p; - iterator* __i = static_cast<iterator*>((*__p)->__i_); - if (__i->__ptr_ != __c.__end_as_link()) - { - __cn1->__add(*__p); - (*__p)->__c_ = __cn1; - if (--__cn2->end_ != __p) - _VSTD::memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*)); - } - } - __db->unlock(); -#endif - } -} - -template <class _Tp, class _Alloc> -inline -void -list<_Tp, _Alloc>::sort() -{ - sort(__less<value_type>()); -} - -template <class _Tp, class _Alloc> -template <class _Comp> -inline -void -list<_Tp, _Alloc>::sort(_Comp __comp) -{ - __sort(begin(), end(), base::__sz(), __comp); -} - -template <class _Tp, class _Alloc> -template <class _Comp> -typename list<_Tp, _Alloc>::iterator -list<_Tp, _Alloc>::__sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp) -{ - switch (__n) - { - case 0: - case 1: - return __f1; - case 2: - if (__comp(*--__e2, *__f1)) - { - __link_pointer __f = __e2.__ptr_; - base::__unlink_nodes(__f, __f); - __link_nodes(__f1.__ptr_, __f, __f); - return __e2; - } - return __f1; - } - size_type __n2 = __n / 2; - iterator __e1 = _VSTD::next(__f1, __n2); - iterator __r = __f1 = __sort(__f1, __e1, __n2, __comp); - iterator __f2 = __e1 = __sort(__e1, __e2, __n - __n2, __comp); - if (__comp(*__f2, *__f1)) - { - iterator __m2 = _VSTD::next(__f2); - for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2) - ; - __link_pointer __f = __f2.__ptr_; - __link_pointer __l = __m2.__ptr_->__prev_; - __r = __f2; - __e1 = __f2 = __m2; - base::__unlink_nodes(__f, __l); - __m2 = _VSTD::next(__f1); - __link_nodes(__f1.__ptr_, __f, __l); - __f1 = __m2; - } - else - ++__f1; - while (__f1 != __e1 && __f2 != __e2) - { - if (__comp(*__f2, *__f1)) - { - iterator __m2 = _VSTD::next(__f2); - for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2) - ; - __link_pointer __f = __f2.__ptr_; - __link_pointer __l = __m2.__ptr_->__prev_; - if (__e1 == __f2) - __e1 = __m2; - __f2 = __m2; - base::__unlink_nodes(__f, __l); - __m2 = _VSTD::next(__f1); - __link_nodes(__f1.__ptr_, __f, __l); - __f1 = __m2; - } - else - ++__f1; - } - return __r; -} - -template <class _Tp, class _Alloc> -void -list<_Tp, _Alloc>::reverse() _NOEXCEPT -{ - if (base::__sz() > 1) - { - iterator __e = end(); - for (iterator __i = begin(); __i.__ptr_ != __e.__ptr_;) - { - _VSTD::swap(__i.__ptr_->__prev_, __i.__ptr_->__next_); - __i.__ptr_ = __i.__ptr_->__prev_; - } - _VSTD::swap(__e.__ptr_->__prev_, __e.__ptr_->__next_); - } -} - -template <class _Tp, class _Alloc> -bool -list<_Tp, _Alloc>::__invariants() const -{ - return size() == _VSTD::distance(begin(), end()); -} - -#if _LIBCPP_DEBUG_LEVEL == 2 - -template <class _Tp, class _Alloc> -bool -list<_Tp, _Alloc>::__dereferenceable(const const_iterator* __i) const -{ - return __i->__ptr_ != this->__end_as_link(); -} - -template <class _Tp, class _Alloc> -bool -list<_Tp, _Alloc>::__decrementable(const const_iterator* __i) const -{ - return !empty() && __i->__ptr_ != base::__end_.__next_; -} - -template <class _Tp, class _Alloc> -bool -list<_Tp, _Alloc>::__addable(const const_iterator*, ptrdiff_t) const -{ - return false; -} - -template <class _Tp, class _Alloc> -bool -list<_Tp, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const -{ - return false; -} - -#endif // _LIBCPP_DEBUG_LEVEL == 2 - -template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator==(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) -{ - return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin()); -} - -template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator< (const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) -{ - return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); -} - -template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator!=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) -{ - return !(__x == __y); -} - -template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator> (const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) -{ - return __y < __x; -} - -template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator>=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) -{ - return !(__x < __y); -} - -template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator<=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) -{ - return !(__y < __x); -} - -template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -void -swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) - _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) -{ - __x.swap(__y); -} - -#if _LIBCPP_STD_VER > 17 -template <class _Tp, class _Allocator, class _Predicate> -inline _LIBCPP_INLINE_VISIBILITY typename list<_Tp, _Allocator>::size_type -erase_if(list<_Tp, _Allocator>& __c, _Predicate __pred) { - return __c.remove_if(__pred); -} - -template <class _Tp, class _Allocator, class _Up> -inline _LIBCPP_INLINE_VISIBILITY typename list<_Tp, _Allocator>::size_type -erase(list<_Tp, _Allocator>& __c, const _Up& __v) { - return _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; }); -} -#endif - -_LIBCPP_END_NAMESPACE_STD - -_LIBCPP_POP_MACROS - -#endif // _LIBCPP_LIST diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/numbers b/contrib/libs/cxxsupp/libcxxmsvc/include/numbers deleted file mode 100644 index 9a52d142c4..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/numbers +++ /dev/null @@ -1,133 +0,0 @@ -// -*- 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_NUMBERS -#define _LIBCPP_NUMBERS - -/* - numbers synopsis - -namespace std::numbers { - template<class T> inline constexpr T e_v = unspecified; - template<class T> inline constexpr T log2e_v = unspecified; - template<class T> inline constexpr T log10e_v = unspecified; - template<class T> inline constexpr T pi_v = unspecified; - template<class T> inline constexpr T inv_pi_v = unspecified; - template<class T> inline constexpr T inv_sqrtpi_v = unspecified; - template<class T> inline constexpr T ln2_v = unspecified; - template<class T> inline constexpr T ln10_v = unspecified; - template<class T> inline constexpr T sqrt2_v = unspecified; - template<class T> inline constexpr T sqrt3_v = unspecified; - template<class T> inline constexpr T inv_sqrt3_v = unspecified; - template<class T> inline constexpr T egamma_v = unspecified; - template<class T> inline constexpr T phi_v = unspecified; - - template<floating_point T> inline constexpr T e_v<T> = see below; - template<floating_point T> inline constexpr T log2e_v<T> = see below; - template<floating_point T> inline constexpr T log10e_v<T> = see below; - template<floating_point T> inline constexpr T pi_v<T> = see below; - template<floating_point T> inline constexpr T inv_pi_v<T> = see below; - template<floating_point T> inline constexpr T inv_sqrtpi_v<T> = see below; - template<floating_point T> inline constexpr T ln2_v<T> = see below; - template<floating_point T> inline constexpr T ln10_v<T> = see below; - template<floating_point T> inline constexpr T sqrt2_v<T> = see below; - template<floating_point T> inline constexpr T sqrt3_v<T> = see below; - template<floating_point T> inline constexpr T inv_sqrt3_v<T> = see below; - template<floating_point T> inline constexpr T egamma_v<T> = see below; - template<floating_point T> inline constexpr T phi_v<T> = see below; - - inline constexpr double e = e_v<double>; - inline constexpr double log2e = log2e_v<double>; - inline constexpr double log10e = log10e_v<double>; - inline constexpr double pi = pi_v<double>; - inline constexpr double inv_pi = inv_pi_v<double>; - inline constexpr double inv_sqrtpi = inv_sqrtpi_v<double>; - inline constexpr double ln2 = ln2_v<double>; - inline constexpr double ln10 = ln10_v<double>; - inline constexpr double sqrt2 = sqrt2_v<double>; - inline constexpr double sqrt3 = sqrt3_v<double>; - inline constexpr double inv_sqrt3 = inv_sqrt3_v<double>; - inline constexpr double egamma = egamma_v<double>; - inline constexpr double phi = phi_v<double>; -} -*/ - -#include <__config> -#include <concepts> -#include <type_traits> -#include <version> - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -namespace numbers { - -template <class _Tp> -inline constexpr bool __false = false; - -template <class _Tp> -struct __illformed -{ - static_assert(__false<_Tp>, "A program that instantiates a primary template of a mathematical constant variable template is ill-formed."); -}; - -template <class _Tp> inline constexpr _Tp e_v = __illformed<_Tp>{}; -template <class _Tp> inline constexpr _Tp log2e_v = __illformed<_Tp>{}; -template <class _Tp> inline constexpr _Tp log10e_v = __illformed<_Tp>{}; -template <class _Tp> inline constexpr _Tp pi_v = __illformed<_Tp>{}; -template <class _Tp> inline constexpr _Tp inv_pi_v = __illformed<_Tp>{}; -template <class _Tp> inline constexpr _Tp inv_sqrtpi_v = __illformed<_Tp>{}; -template <class _Tp> inline constexpr _Tp ln2_v = __illformed<_Tp>{}; -template <class _Tp> inline constexpr _Tp ln10_v = __illformed<_Tp>{}; -template <class _Tp> inline constexpr _Tp sqrt2_v = __illformed<_Tp>{}; -template <class _Tp> inline constexpr _Tp sqrt3_v = __illformed<_Tp>{}; -template <class _Tp> inline constexpr _Tp inv_sqrt3_v = __illformed<_Tp>{}; -template <class _Tp> inline constexpr _Tp egamma_v = __illformed<_Tp>{}; -template <class _Tp> inline constexpr _Tp phi_v = __illformed<_Tp>{}; - -template <floating_point _Tp> inline constexpr _Tp e_v<_Tp> = 2.718281828459045235360287471352662L; -template <floating_point _Tp> inline constexpr _Tp log2e_v<_Tp> = 1.442695040888963407359924681001892L; -template <floating_point _Tp> inline constexpr _Tp log10e_v<_Tp> = 0.434294481903251827651128918916605L; -template <floating_point _Tp> inline constexpr _Tp pi_v<_Tp> = 3.141592653589793238462643383279502L; -template <floating_point _Tp> inline constexpr _Tp inv_pi_v<_Tp> = 0.318309886183790671537767526745028L; -template <floating_point _Tp> inline constexpr _Tp inv_sqrtpi_v<_Tp> = 0.564189583547756286948079451560772L; -template <floating_point _Tp> inline constexpr _Tp ln2_v<_Tp> = 0.693147180559945309417232121458176L; -template <floating_point _Tp> inline constexpr _Tp ln10_v<_Tp> = 2.302585092994045684017991454684364L; -template <floating_point _Tp> inline constexpr _Tp sqrt2_v<_Tp> = 1.414213562373095048801688724209698L; -template <floating_point _Tp> inline constexpr _Tp sqrt3_v<_Tp> = 1.732050807568877293527446341505872L; -template <floating_point _Tp> inline constexpr _Tp inv_sqrt3_v<_Tp> = 0.577350269189625764509148780501957L; -template <floating_point _Tp> inline constexpr _Tp egamma_v<_Tp> = 0.577215664901532860606512090082402L; -template <floating_point _Tp> inline constexpr _Tp phi_v<_Tp> = 1.618033988749894848204586834365638L; - -inline constexpr double e = e_v<double>; -inline constexpr double log2e = log2e_v<double>; -inline constexpr double log10e = log10e_v<double>; -inline constexpr double pi = pi_v<double>; -inline constexpr double inv_pi = inv_pi_v<double>; -inline constexpr double inv_sqrtpi = inv_sqrtpi_v<double>; -inline constexpr double ln2 = ln2_v<double>; -inline constexpr double ln10 = ln10_v<double>; -inline constexpr double sqrt2 = sqrt2_v<double>; -inline constexpr double sqrt3 = sqrt3_v<double>; -inline constexpr double inv_sqrt3 = inv_sqrt3_v<double>; -inline constexpr double egamma = egamma_v<double>; -inline constexpr double phi = phi_v<double>; - -} // namespace numbers - -_LIBCPP_END_NAMESPACE_STD - -#endif //!defined(_LIBCPP_HAS_NO_CONCEPTS) - -#endif // _LIBCPP_NUMBERS diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/queue b/contrib/libs/cxxsupp/libcxxmsvc/include/queue deleted file mode 100644 index b8b7ec46d9..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/queue +++ /dev/null @@ -1,955 +0,0 @@ -// -*- 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_QUEUE -#define _LIBCPP_QUEUE - -/* - queue synopsis - -namespace std -{ - -template <class T, class Container = deque<T>> -class queue -{ -public: - typedef Container container_type; - typedef typename container_type::value_type value_type; - typedef typename container_type::reference reference; - typedef typename container_type::const_reference const_reference; - typedef typename container_type::size_type size_type; - -protected: - container_type c; - -public: - queue() = default; - ~queue() = default; - - queue(const queue& q) = default; - queue(queue&& q) = default; - - queue& operator=(const queue& q) = default; - queue& operator=(queue&& q) = default; - - explicit queue(const container_type& c); - explicit queue(container_type&& c) - template<class InputIterator> - queue(InputIterator first, InputIterator last); // since C++23 - template <class Alloc> - explicit queue(const Alloc& a); - template <class Alloc> - queue(const container_type& c, const Alloc& a); - template <class Alloc> - queue(container_type&& c, const Alloc& a); - template <class Alloc> - queue(const queue& q, const Alloc& a); - template <class Alloc> - queue(queue&& q, const Alloc& a); - template <class InputIterator, class Alloc> - queue(InputIterator first, InputIterator last, const Alloc&); // since C++23 - - bool empty() const; - size_type size() const; - - reference front(); - const_reference front() const; - reference back(); - const_reference back() const; - - void push(const value_type& v); - void push(value_type&& v); - template <class... Args> reference emplace(Args&&... args); // reference in C++17 - void pop(); - - void swap(queue& q) noexcept(is_nothrow_swappable_v<Container>) -}; - -template<class Container> - queue(Container) -> queue<typename Container::value_type, Container>; // C++17 - -template<class InputIterator> - queue(InputIterator, InputIterator) -> queue<iter-value-type<InputIterator>>; // since C++23 - -template<class Container, class Allocator> - queue(Container, Allocator) -> queue<typename Container::value_type, Container>; // C++17 - -template<class InputIterator, class Allocator> - queue(InputIterator, InputIterator, Allocator) - -> queue<iter-value-type<InputIterator>, - deque<iter-value-type<InputIterator>, Allocator>>; // since C++23 - -template <class T, class Container> - bool operator==(const queue<T, Container>& x,const queue<T, Container>& y); - -template <class T, class Container> - bool operator< (const queue<T, Container>& x,const queue<T, Container>& y); - -template <class T, class Container> - bool operator!=(const queue<T, Container>& x,const queue<T, Container>& y); - -template <class T, class Container> - bool operator> (const queue<T, Container>& x,const queue<T, Container>& y); - -template <class T, class Container> - bool operator>=(const queue<T, Container>& x,const queue<T, Container>& y); - -template <class T, class Container> - bool operator<=(const queue<T, Container>& x,const queue<T, Container>& y); - -template <class T, class Container> - void swap(queue<T, Container>& x, queue<T, Container>& y) - noexcept(noexcept(x.swap(y))); - -template <class T, class Container = vector<T>, - class Compare = less<typename Container::value_type>> -class priority_queue -{ -public: - typedef Container container_type; - typedef typename container_type::value_type value_type; - typedef typename container_type::reference reference; - typedef typename container_type::const_reference const_reference; - typedef typename container_type::size_type size_type; - -protected: - container_type c; - Compare comp; - -public: - priority_queue() : priority_queue(Compare()) {} // C++20 - explicit priority_queue(const Compare& x) : priority_queue(x, Container()) {} - priority_queue(const Compare& x, const Container&); - explicit priority_queue(const Compare& x = Compare(), Container&& = Container()); // before C++20 - priority_queue(const Compare& x, Container&&); // C++20 - template <class InputIterator> - priority_queue(InputIterator first, InputIterator last, - const Compare& comp = Compare()); - template <class InputIterator> - priority_queue(InputIterator first, InputIterator last, - const Compare& comp, const Container& c); - template <class InputIterator> - priority_queue(InputIterator first, InputIterator last, - const Compare& comp, Container&& c); - template <class Alloc> - explicit priority_queue(const Alloc& a); - template <class Alloc> - priority_queue(const Compare& comp, const Alloc& a); - template <class Alloc> - priority_queue(const Compare& comp, const Container& c, - const Alloc& a); - template <class Alloc> - priority_queue(const Compare& comp, Container&& c, - const Alloc& a); - template <class InputIterator> - priority_queue(InputIterator first, InputIterator last, - const Alloc& a); - template <class InputIterator> - priority_queue(InputIterator first, InputIterator last, - const Compare& comp, const Alloc& a); - template <class InputIterator> - priority_queue(InputIterator first, InputIterator last, - const Compare& comp, const Container& c, const Alloc& a); - template <class InputIterator> - priority_queue(InputIterator first, InputIterator last, - const Compare& comp, Container&& c, const Alloc& a); - template <class Alloc> - priority_queue(const priority_queue& q, const Alloc& a); - template <class Alloc> - priority_queue(priority_queue&& q, const Alloc& a); - - bool empty() const; - size_type size() const; - const_reference top() const; - - void push(const value_type& v); - void push(value_type&& v); - template <class... Args> void emplace(Args&&... args); - void pop(); - - void swap(priority_queue& q) - noexcept(is_nothrow_swappable_v<Container> && - is_nothrow_swappable_v<Comp>) -}; - -template <class Compare, class Container> -priority_queue(Compare, Container) - -> priority_queue<typename Container::value_type, Container, Compare>; // C++17 - -template<class InputIterator, - class Compare = less<iter-value-type<InputIterator>>, - class Container = vector<iter-value-type<InputIterator>>> -priority_queue(InputIterator, InputIterator, Compare = Compare(), Container = Container()) - -> priority_queue<iter-value-type<InputIterator>, Container, Compare>; // C++17 - -template<class Compare, class Container, class Allocator> -priority_queue(Compare, Container, Allocator) - -> priority_queue<typename Container::value_type, Container, Compare>; // C++17 - -template<class InputIterator, class Allocator> -priority_queue(InputIterator, InputIterator, Allocator) - -> priority_queue<iter-value-type<InputIterator>, - vector<iter-value-type<InputIterator>, Allocator>, - less<iter-value-type<InputIterator>>>; // C++17 - -template<class InputIterator, class Compare, class Allocator> -priority_queue(InputIterator, InputIterator, Compare, Allocator) - -> priority_queue<iter-value-type<InputIterator>, - vector<iter-value-type<InputIterator>, Allocator>, Compare>; // C++17 - -template<class InputIterator, class Compare, class Container, class Allocator> -priority_queue(InputIterator, InputIterator, Compare, Container, Allocator) - -> priority_queue<typename Container::value_type, Container, Compare>; // C++17 - -template <class T, class Container, class Compare> - void swap(priority_queue<T, Container, Compare>& x, - priority_queue<T, Container, Compare>& y) - noexcept(noexcept(x.swap(y))); - -} // std - -*/ - -#include <__algorithm/make_heap.h> -#include <__algorithm/pop_heap.h> -#include <__algorithm/push_heap.h> -#include <__config> -#include <__iterator/iterator_traits.h> -#include <__memory/uses_allocator.h> -#include <__utility/forward.h> -#include <compare> -#include <deque> -#include <functional> -#include <type_traits> -#include <vector> -#include <version> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -template <class _Tp, class _Container = deque<_Tp> > class _LIBCPP_TEMPLATE_VIS queue; - -template <class _Tp, class _Container> -_LIBCPP_INLINE_VISIBILITY -bool -operator==(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y); - -template <class _Tp, class _Container> -_LIBCPP_INLINE_VISIBILITY -bool -operator< (const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y); - -template <class _Tp, class _Container /*= deque<_Tp>*/> -class _LIBCPP_TEMPLATE_VIS queue -{ -public: - typedef _Container container_type; - typedef typename container_type::value_type value_type; - typedef typename container_type::reference reference; - typedef typename container_type::const_reference const_reference; - typedef typename container_type::size_type size_type; - static_assert((is_same<_Tp, value_type>::value), "" ); - -protected: - container_type c; - -public: - _LIBCPP_INLINE_VISIBILITY - queue() - _NOEXCEPT_(is_nothrow_default_constructible<container_type>::value) - : c() {} - - _LIBCPP_INLINE_VISIBILITY - queue(const queue& __q) : c(__q.c) {} - -#if _LIBCPP_STD_VER > 20 - template <class _InputIterator, - class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>> - _LIBCPP_HIDE_FROM_ABI - queue(_InputIterator __first, _InputIterator __last) : c(__first, __last) {} - - template <class _InputIterator, - class _Alloc, - class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>> - _LIBCPP_HIDE_FROM_ABI - queue(_InputIterator __first, _InputIterator __second, const _Alloc& __alloc) : c(__first, __second, __alloc) {} -#endif - - _LIBCPP_INLINE_VISIBILITY - queue& operator=(const queue& __q) {c = __q.c; return *this;} - -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - queue(queue&& __q) - _NOEXCEPT_(is_nothrow_move_constructible<container_type>::value) - : c(_VSTD::move(__q.c)) {} - - _LIBCPP_INLINE_VISIBILITY - queue& operator=(queue&& __q) - _NOEXCEPT_(is_nothrow_move_assignable<container_type>::value) - {c = _VSTD::move(__q.c); return *this;} -#endif // _LIBCPP_CXX03_LANG - - _LIBCPP_INLINE_VISIBILITY - explicit queue(const container_type& __c) : c(__c) {} -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - explicit queue(container_type&& __c) : c(_VSTD::move(__c)) {} -#endif // _LIBCPP_CXX03_LANG - template <class _Alloc> - _LIBCPP_INLINE_VISIBILITY - explicit queue(const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0) - : c(__a) {} - template <class _Alloc> - _LIBCPP_INLINE_VISIBILITY - queue(const queue& __q, const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0) - : c(__q.c, __a) {} - template <class _Alloc> - _LIBCPP_INLINE_VISIBILITY - queue(const container_type& __c, const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0) - : c(__c, __a) {} -#ifndef _LIBCPP_CXX03_LANG - template <class _Alloc> - _LIBCPP_INLINE_VISIBILITY - queue(container_type&& __c, const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0) - : c(_VSTD::move(__c), __a) {} - template <class _Alloc> - _LIBCPP_INLINE_VISIBILITY - queue(queue&& __q, const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0) - : c(_VSTD::move(__q.c), __a) {} - -#endif // _LIBCPP_CXX03_LANG - - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY - bool empty() const {return c.empty();} - _LIBCPP_INLINE_VISIBILITY - size_type size() const {return c.size();} - - _LIBCPP_INLINE_VISIBILITY - reference front() {return c.front();} - _LIBCPP_INLINE_VISIBILITY - const_reference front() const {return c.front();} - _LIBCPP_INLINE_VISIBILITY - reference back() {return c.back();} - _LIBCPP_INLINE_VISIBILITY - const_reference back() const {return c.back();} - - _LIBCPP_INLINE_VISIBILITY - void push(const value_type& __v) {c.push_back(__v);} -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - void push(value_type&& __v) {c.push_back(_VSTD::move(__v));} - template <class... _Args> - _LIBCPP_INLINE_VISIBILITY -#if _LIBCPP_STD_VER > 14 - decltype(auto) emplace(_Args&&... __args) - { return c.emplace_back(_VSTD::forward<_Args>(__args)...);} -#else - void emplace(_Args&&... __args) - { c.emplace_back(_VSTD::forward<_Args>(__args)...);} -#endif -#endif // _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - void pop() {c.pop_front();} - - _LIBCPP_INLINE_VISIBILITY - void swap(queue& __q) - _NOEXCEPT_(__is_nothrow_swappable<container_type>::value) - { - using _VSTD::swap; - swap(c, __q.c); - } - - template <class _T1, class _C1> - friend - _LIBCPP_INLINE_VISIBILITY - bool - operator==(const queue<_T1, _C1>& __x,const queue<_T1, _C1>& __y); - - template <class _T1, class _C1> - friend - _LIBCPP_INLINE_VISIBILITY - bool - operator< (const queue<_T1, _C1>& __x,const queue<_T1, _C1>& __y); -}; - -#if _LIBCPP_STD_VER > 14 -template<class _Container, - class = enable_if_t<!__is_allocator<_Container>::value> -> -queue(_Container) - -> queue<typename _Container::value_type, _Container>; - -template<class _Container, - class _Alloc, - class = enable_if_t<!__is_allocator<_Container>::value>, - class = enable_if_t<uses_allocator<_Container, _Alloc>::value> -> -queue(_Container, _Alloc) - -> queue<typename _Container::value_type, _Container>; -#endif - -#if _LIBCPP_STD_VER > 20 -template <class _InputIterator, - class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>> -queue(_InputIterator, _InputIterator) - -> queue<__iter_value_type<_InputIterator>>; - -template <class _InputIterator, - class _Alloc, - class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = __enable_if_t<__is_allocator<_Alloc>::value>> -queue(_InputIterator, _InputIterator, _Alloc) - -> queue<__iter_value_type<_InputIterator>, deque<__iter_value_type<_InputIterator>, _Alloc>>; -#endif - -template <class _Tp, class _Container> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator==(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y) -{ - return __x.c == __y.c; -} - -template <class _Tp, class _Container> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator< (const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y) -{ - return __x.c < __y.c; -} - -template <class _Tp, class _Container> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator!=(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y) -{ - return !(__x == __y); -} - -template <class _Tp, class _Container> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator> (const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y) -{ - return __y < __x; -} - -template <class _Tp, class _Container> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator>=(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y) -{ - return !(__x < __y); -} - -template <class _Tp, class _Container> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator<=(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y) -{ - return !(__y < __x); -} - -template <class _Tp, class _Container> -inline _LIBCPP_INLINE_VISIBILITY -__enable_if_t<__is_swappable<_Container>::value, void> -swap(queue<_Tp, _Container>& __x, queue<_Tp, _Container>& __y) - _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) -{ - __x.swap(__y); -} - -template <class _Tp, class _Container, class _Alloc> -struct _LIBCPP_TEMPLATE_VIS uses_allocator<queue<_Tp, _Container>, _Alloc> - : public uses_allocator<_Container, _Alloc> -{ -}; - -template <class _Tp, class _Container = vector<_Tp>, - class _Compare = less<typename _Container::value_type> > -class _LIBCPP_TEMPLATE_VIS priority_queue -{ -public: - typedef _Container container_type; - typedef _Compare value_compare; - typedef typename container_type::value_type value_type; - typedef typename container_type::reference reference; - typedef typename container_type::const_reference const_reference; - typedef typename container_type::size_type size_type; - static_assert((is_same<_Tp, value_type>::value), "" ); - -protected: - container_type c; - value_compare comp; - -public: - _LIBCPP_INLINE_VISIBILITY - priority_queue() - _NOEXCEPT_(is_nothrow_default_constructible<container_type>::value && - is_nothrow_default_constructible<value_compare>::value) - : c(), comp() {} - - _LIBCPP_INLINE_VISIBILITY - priority_queue(const priority_queue& __q) : c(__q.c), comp(__q.comp) {} - - _LIBCPP_INLINE_VISIBILITY - priority_queue& operator=(const priority_queue& __q) - {c = __q.c; comp = __q.comp; return *this;} - -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - priority_queue(priority_queue&& __q) - _NOEXCEPT_(is_nothrow_move_constructible<container_type>::value && - is_nothrow_move_constructible<value_compare>::value) - : c(_VSTD::move(__q.c)), comp(_VSTD::move(__q.comp)) {} - - _LIBCPP_INLINE_VISIBILITY - priority_queue& operator=(priority_queue&& __q) - _NOEXCEPT_(is_nothrow_move_assignable<container_type>::value && - is_nothrow_move_assignable<value_compare>::value) - {c = _VSTD::move(__q.c); comp = _VSTD::move(__q.comp); return *this;} -#endif // _LIBCPP_CXX03_LANG - - _LIBCPP_INLINE_VISIBILITY - explicit priority_queue(const value_compare& __comp) - : c(), comp(__comp) {} - _LIBCPP_INLINE_VISIBILITY - priority_queue(const value_compare& __comp, const container_type& __c); -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - priority_queue(const value_compare& __comp, container_type&& __c); -#endif - template <class _InputIter, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> > - _LIBCPP_INLINE_VISIBILITY - priority_queue(_InputIter __f, _InputIter __l, - const value_compare& __comp = value_compare()); - template <class _InputIter, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> > - _LIBCPP_INLINE_VISIBILITY - priority_queue(_InputIter __f, _InputIter __l, - const value_compare& __comp, const container_type& __c); -#ifndef _LIBCPP_CXX03_LANG - template <class _InputIter, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> > - _LIBCPP_INLINE_VISIBILITY - priority_queue(_InputIter __f, _InputIter __l, - const value_compare& __comp, container_type&& __c); -#endif // _LIBCPP_CXX03_LANG - template <class _Alloc> - _LIBCPP_INLINE_VISIBILITY - explicit priority_queue(const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0); - template <class _Alloc> - _LIBCPP_INLINE_VISIBILITY - priority_queue(const value_compare& __comp, const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0); - template <class _Alloc> - _LIBCPP_INLINE_VISIBILITY - priority_queue(const value_compare& __comp, const container_type& __c, - const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0); - template <class _Alloc> - _LIBCPP_INLINE_VISIBILITY - priority_queue(const priority_queue& __q, const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0); -#ifndef _LIBCPP_CXX03_LANG - template <class _Alloc> - _LIBCPP_INLINE_VISIBILITY - priority_queue(const value_compare& __comp, container_type&& __c, - const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0); - template <class _Alloc> - _LIBCPP_INLINE_VISIBILITY - priority_queue(priority_queue&& __q, const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0); -#endif // _LIBCPP_CXX03_LANG - - template <class _InputIter, class _Alloc, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> > - _LIBCPP_INLINE_VISIBILITY - priority_queue(_InputIter __f, _InputIter __l, const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0); - - template <class _InputIter, class _Alloc, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> > - _LIBCPP_INLINE_VISIBILITY - priority_queue(_InputIter __f, _InputIter __l, - const value_compare& __comp, const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0); - - template <class _InputIter, class _Alloc, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> > - _LIBCPP_INLINE_VISIBILITY - priority_queue(_InputIter __f, _InputIter __l, - const value_compare& __comp, const container_type& __c, const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0); - -#ifndef _LIBCPP_CXX03_LANG - template <class _InputIter, class _Alloc, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> > - _LIBCPP_INLINE_VISIBILITY - priority_queue(_InputIter __f, _InputIter __l, - const value_compare& __comp, container_type&& __c, const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0); -#endif // _LIBCPP_CXX03_LANG - - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY - bool empty() const {return c.empty();} - _LIBCPP_INLINE_VISIBILITY - size_type size() const {return c.size();} - _LIBCPP_INLINE_VISIBILITY - const_reference top() const {return c.front();} - - _LIBCPP_INLINE_VISIBILITY - void push(const value_type& __v); -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - void push(value_type&& __v); - template <class... _Args> - _LIBCPP_INLINE_VISIBILITY - void emplace(_Args&&... __args); -#endif // _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - void pop(); - - _LIBCPP_INLINE_VISIBILITY - void swap(priority_queue& __q) - _NOEXCEPT_(__is_nothrow_swappable<container_type>::value && - __is_nothrow_swappable<value_compare>::value); -}; - -#if _LIBCPP_STD_VER >= 17 -template <class _Compare, - class _Container, - class = enable_if_t<!__is_allocator<_Compare>::value>, - class = enable_if_t<!__is_allocator<_Container>::value> -> -priority_queue(_Compare, _Container) - -> priority_queue<typename _Container::value_type, _Container, _Compare>; - -template<class _InputIterator, - class _Compare = less<__iter_value_type<_InputIterator>>, - class _Container = vector<__iter_value_type<_InputIterator>>, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = enable_if_t<!__is_allocator<_Compare>::value>, - class = enable_if_t<!__is_allocator<_Container>::value> -> -priority_queue(_InputIterator, _InputIterator, _Compare = _Compare(), _Container = _Container()) - -> priority_queue<__iter_value_type<_InputIterator>, _Container, _Compare>; - -template<class _Compare, - class _Container, - class _Alloc, - class = enable_if_t<!__is_allocator<_Compare>::value>, - class = enable_if_t<!__is_allocator<_Container>::value>, - class = enable_if_t<uses_allocator<_Container, _Alloc>::value> -> -priority_queue(_Compare, _Container, _Alloc) - -> priority_queue<typename _Container::value_type, _Container, _Compare>; - -template<class _InputIterator, class _Allocator, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = enable_if_t<__is_allocator<_Allocator>::value> -> -priority_queue(_InputIterator, _InputIterator, _Allocator) - -> priority_queue<__iter_value_type<_InputIterator>, - vector<__iter_value_type<_InputIterator>, _Allocator>, - less<__iter_value_type<_InputIterator>>>; - -template<class _InputIterator, class _Compare, class _Allocator, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = enable_if_t<!__is_allocator<_Compare>::value>, - class = enable_if_t<__is_allocator<_Allocator>::value> -> -priority_queue(_InputIterator, _InputIterator, _Compare, _Allocator) - -> priority_queue<__iter_value_type<_InputIterator>, - vector<__iter_value_type<_InputIterator>, _Allocator>, _Compare>; - -template<class _InputIterator, class _Compare, class _Container, class _Alloc, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = enable_if_t<!__is_allocator<_Compare>::value>, - class = enable_if_t<!__is_allocator<_Container>::value>, - class = enable_if_t<uses_allocator<_Container, _Alloc>::value> -> -priority_queue(_InputIterator, _InputIterator, _Compare, _Container, _Alloc) - -> priority_queue<typename _Container::value_type, _Container, _Compare>; -#endif - -template <class _Tp, class _Container, class _Compare> -inline -priority_queue<_Tp, _Container, _Compare>::priority_queue(const _Compare& __comp, - const container_type& __c) - : c(__c), - comp(__comp) -{ - _VSTD::make_heap(c.begin(), c.end(), comp); -} - -#ifndef _LIBCPP_CXX03_LANG - -template <class _Tp, class _Container, class _Compare> -inline -priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp, - container_type&& __c) - : c(_VSTD::move(__c)), - comp(__comp) -{ - _VSTD::make_heap(c.begin(), c.end(), comp); -} - -#endif // _LIBCPP_CXX03_LANG - -template <class _Tp, class _Container, class _Compare> -template <class _InputIter, class> -inline -priority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _InputIter __l, - const value_compare& __comp) - : c(__f, __l), - comp(__comp) -{ - _VSTD::make_heap(c.begin(), c.end(), comp); -} - -template <class _Tp, class _Container, class _Compare> -template <class _InputIter, class> -inline -priority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _InputIter __l, - const value_compare& __comp, - const container_type& __c) - : c(__c), - comp(__comp) -{ - c.insert(c.end(), __f, __l); - _VSTD::make_heap(c.begin(), c.end(), comp); -} - -#ifndef _LIBCPP_CXX03_LANG - -template <class _Tp, class _Container, class _Compare> -template <class _InputIter, class> -inline -priority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _InputIter __l, - const value_compare& __comp, - container_type&& __c) - : c(_VSTD::move(__c)), - comp(__comp) -{ - c.insert(c.end(), __f, __l); - _VSTD::make_heap(c.begin(), c.end(), comp); -} - -#endif // _LIBCPP_CXX03_LANG - -template <class _Tp, class _Container, class _Compare> -template <class _Alloc> -inline -priority_queue<_Tp, _Container, _Compare>::priority_queue(const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>*) - : c(__a) -{ -} - -template <class _Tp, class _Container, class _Compare> -template <class _Alloc> -inline -priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp, - const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>*) - : c(__a), - comp(__comp) -{ -} - -template <class _Tp, class _Container, class _Compare> -template <class _Alloc> -inline -priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp, - const container_type& __c, - const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>*) - : c(__c, __a), - comp(__comp) -{ - _VSTD::make_heap(c.begin(), c.end(), comp); -} - -template <class _Tp, class _Container, class _Compare> -template <class _Alloc> -inline -priority_queue<_Tp, _Container, _Compare>::priority_queue(const priority_queue& __q, - const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>*) - : c(__q.c, __a), - comp(__q.comp) -{ -} - -#ifndef _LIBCPP_CXX03_LANG - -template <class _Tp, class _Container, class _Compare> -template <class _Alloc> -inline -priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp, - container_type&& __c, - const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>*) - : c(_VSTD::move(__c), __a), - comp(__comp) -{ - _VSTD::make_heap(c.begin(), c.end(), comp); -} - -template <class _Tp, class _Container, class _Compare> -template <class _Alloc> -inline -priority_queue<_Tp, _Container, _Compare>::priority_queue(priority_queue&& __q, - const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>*) - : c(_VSTD::move(__q.c), __a), - comp(_VSTD::move(__q.comp)) -{ -} - -#endif // _LIBCPP_CXX03_LANG - -template <class _Tp, class _Container, class _Compare> -template <class _InputIter, class _Alloc, class> -inline -priority_queue<_Tp, _Container, _Compare>::priority_queue( - _InputIter __f, _InputIter __l, const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>*) - : c(__f, __l, __a), - comp() -{ - _VSTD::make_heap(c.begin(), c.end(), comp); -} - -template <class _Tp, class _Container, class _Compare> -template <class _InputIter, class _Alloc, class> -inline -priority_queue<_Tp, _Container, _Compare>::priority_queue( - _InputIter __f, _InputIter __l, - const value_compare& __comp, const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>*) - : c(__f, __l, __a), - comp(__comp) -{ - _VSTD::make_heap(c.begin(), c.end(), comp); -} - -template <class _Tp, class _Container, class _Compare> -template <class _InputIter, class _Alloc, class> -inline -priority_queue<_Tp, _Container, _Compare>::priority_queue( - _InputIter __f, _InputIter __l, - const value_compare& __comp, const container_type& __c, const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>*) - : c(__c, __a), - comp(__comp) -{ - c.insert(c.end(), __f, __l); - _VSTD::make_heap(c.begin(), c.end(), comp); -} - -#ifndef _LIBCPP_CXX03_LANG -template <class _Tp, class _Container, class _Compare> -template <class _InputIter, class _Alloc, class> -inline -priority_queue<_Tp, _Container, _Compare>::priority_queue( - _InputIter __f, _InputIter __l, const value_compare& __comp, - container_type&& __c, const _Alloc& __a, - __enable_if_t<uses_allocator<container_type, _Alloc>::value>*) - : c(_VSTD::move(__c), __a), - comp(__comp) -{ - c.insert(c.end(), __f, __l); - _VSTD::make_heap(c.begin(), c.end(), comp); -} -#endif // _LIBCPP_CXX03_LANG - -template <class _Tp, class _Container, class _Compare> -inline -void -priority_queue<_Tp, _Container, _Compare>::push(const value_type& __v) -{ - c.push_back(__v); - _VSTD::push_heap(c.begin(), c.end(), comp); -} - -#ifndef _LIBCPP_CXX03_LANG - -template <class _Tp, class _Container, class _Compare> -inline -void -priority_queue<_Tp, _Container, _Compare>::push(value_type&& __v) -{ - c.push_back(_VSTD::move(__v)); - _VSTD::push_heap(c.begin(), c.end(), comp); -} - -template <class _Tp, class _Container, class _Compare> -template <class... _Args> -inline -void -priority_queue<_Tp, _Container, _Compare>::emplace(_Args&&... __args) -{ - c.emplace_back(_VSTD::forward<_Args>(__args)...); - _VSTD::push_heap(c.begin(), c.end(), comp); -} - -#endif // _LIBCPP_CXX03_LANG - -template <class _Tp, class _Container, class _Compare> -inline -void -priority_queue<_Tp, _Container, _Compare>::pop() -{ - _VSTD::pop_heap(c.begin(), c.end(), comp); - c.pop_back(); -} - -template <class _Tp, class _Container, class _Compare> -inline -void -priority_queue<_Tp, _Container, _Compare>::swap(priority_queue& __q) - _NOEXCEPT_(__is_nothrow_swappable<container_type>::value && - __is_nothrow_swappable<value_compare>::value) -{ - using _VSTD::swap; - swap(c, __q.c); - swap(comp, __q.comp); -} - -template <class _Tp, class _Container, class _Compare> -inline _LIBCPP_INLINE_VISIBILITY -__enable_if_t< - __is_swappable<_Container>::value && __is_swappable<_Compare>::value, - void -> -swap(priority_queue<_Tp, _Container, _Compare>& __x, - priority_queue<_Tp, _Container, _Compare>& __y) - _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) -{ - __x.swap(__y); -} - -template <class _Tp, class _Container, class _Compare, class _Alloc> -struct _LIBCPP_TEMPLATE_VIS uses_allocator<priority_queue<_Tp, _Container, _Compare>, _Alloc> - : public uses_allocator<_Container, _Alloc> -{ -}; - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP_QUEUE diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/ranges b/contrib/libs/cxxsupp/libcxxmsvc/include/ranges deleted file mode 100644 index 25ed65ba1e..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/ranges +++ /dev/null @@ -1,269 +0,0 @@ -// -*- 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_RANGES -#define _LIBCPP_RANGES - -/* - -#include <compare> // see [compare.syn] -#include <initializer_list> // see [initializer.list.syn] -#include <iterator> // see [iterator.synopsis] - -namespace std::ranges { - inline namespace unspecified { - // [range.access], range access - inline constexpr unspecified begin = unspecified; - inline constexpr unspecified end = unspecified; - inline constexpr unspecified cbegin = unspecified; - inline constexpr unspecified cend = unspecified; - - inline constexpr unspecified size = unspecified; - inline constexpr unspecified ssize = unspecified; - } - - // [range.range], ranges - template<class T> - concept range = see below; - - template<class T> - inline constexpr bool enable_borrowed_range = false; - - template<class T> - using iterator_t = decltype(ranges::begin(declval<T&>())); - template<range R> - using sentinel_t = decltype(ranges::end(declval<R&>())); - template<range R> - using range_difference_t = iter_difference_t<iterator_t<R>>; - template<sized_range R> - using range_size_t = decltype(ranges::size(declval<R&>())); - template<range R> - using range_value_t = iter_value_t<iterator_t<R>>; - template<range R> - using range_reference_t = iter_reference_t<iterator_t<R>>; - template<range R> - using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<R>>; - - // [range.sized], sized ranges - template<class> - inline constexpr bool disable_sized_range = false; - - template<class T> - concept sized_range = ...; - - // [range.view], views - template<class T> - inline constexpr bool enable_view = ...; - - struct view_base { }; - - template<class T> - concept view = ...; - - // [range.refinements], other range refinements - template<class R, class T> - concept output_range = see below; - - template<class T> - concept input_range = see below; - - template<class T> - concept forward_range = see below; - - template<class T> - concept bidirectional_range = see below; - - template<class T> - concept random_access_range = see below; - - template<class T> - concept contiguous_range = see below; - - template <class _Tp> - concept common_range = see below; - - template<class T> - concept viewable_range = see below; - - // [view.interface], class template view_interface - template<class D> - requires is_class_v<D> && same_as<D, remove_cv_t<D>> - class view_interface; - - // [range.subrange], sub-ranges - enum class subrange_kind : bool { unsized, sized }; - - template<input_or_output_iterator I, sentinel_for<I> S = I, subrange_kind K = see below> - requires (K == subrange_kind::sized || !sized_sentinel_for<S, I>) - class subrange; - - template<class I, class S, subrange_kind K> - inline constexpr bool enable_borrowed_range<subrange<I, S, K>> = true; - - // [range.dangling], dangling iterator handling - struct dangling; - - template<range R> - using borrowed_iterator_t = see below; - - template<range R> - using borrowed_subrange_t = see below; - - // [range.empty], empty view - template<class T> - requires is_object_v<T> - class empty_view; - - // [range.all], all view - namespace views { - inline constexpr unspecified all = unspecified; - - template<viewable_range R> - using all_t = decltype(all(declval<R>())); - } - - template<range R> - requires is_object_v<R> - class ref_view; - - template<class T> - inline constexpr bool enable_borrowed_range<ref_view<T>> = true; - - template<range R> - requires see below - class owning_view; - - template<class T> - inline constexpr bool enable_borrowed_range<owning_view<T>> = enable_borrowed_range<T>; - - // [range.drop], drop view - template<view V> - class drop_view; - - template<class T> - inline constexpr bool enable_borrowed_range<drop_view<T>> = enable_borrowed_range<T>; - - // [range.transform], transform view - template<input_range V, copy_constructible F> - requires view<V> && is_object_v<F> && - regular_invocable<F&, range_reference_t<V>> && - can-reference<invoke_result_t<F&, range_reference_t<V>>> - class transform_view; - - // [range.counted], counted view - namespace views { inline constexpr unspecified counted = unspecified; } - - // [range.common], common view - template<view V> - requires (!common_range<V> && copyable<iterator_t<V>>) - class common_view; - - // [range.reverse], reverse view - template<view V> - requires bidirectional_range<V> - class reverse_view; - - template<class T> - inline constexpr bool enable_borrowed_range<reverse_view<T>> = enable_borrowed_range<T>; - - template<class T> - inline constexpr bool enable_borrowed_range<common_view<T>> = enable_borrowed_range<T>; - - // [range.take], take view - template<view> class take_view; - - template<class T> - inline constexpr bool enable_borrowed_range<take_view<T>> = enable_borrowed_range<T>; - - template<copy_constructible T> - requires is_object_v<T> - class single_view; - - template<weakly_incrementable W, semiregular Bound = unreachable_sentinel_t> - requires weakly-equality-comparable-with<W, Bound> && copyable<W> - class iota_view; - - template<class W, class Bound> - inline constexpr bool enable_borrowed_range<iota_view<W, Bound>> = true; - - // [range.join], join view - template<input_range V> - requires view<V> && input_range<range_reference_t<V>> - class join_view; -} - -namespace std { - namespace views = ranges::views; - - template<class T> struct tuple_size; - template<size_t I, class T> struct tuple_element; - - template<class I, class S, ranges::subrange_kind K> - struct tuple_size<ranges::subrange<I, S, K>> - : integral_constant<size_t, 2> {}; - - template<class I, class S, ranges::subrange_kind K> - struct tuple_element<0, ranges::subrange<I, S, K>> { - using type = I; - }; - - template<class I, class S, ranges::subrange_kind K> - struct tuple_element<1, ranges::subrange<I, S, K>> { - using type = S; - }; - - template<class I, class S, ranges::subrange_kind K> - struct tuple_element<0, const ranges::subrange<I, S, K>> { - using type = I; - }; - - template<class I, class S, ranges::subrange_kind K> - struct tuple_element<1, const ranges::subrange<I, S, K>> { - using type = S; - }; -} -*/ - -#include <__config> -#include <__ranges/access.h> -#include <__ranges/all.h> -#include <__ranges/common_view.h> -#include <__ranges/concepts.h> -#include <__ranges/counted.h> -#include <__ranges/dangling.h> -#include <__ranges/data.h> -#include <__ranges/drop_view.h> -#include <__ranges/empty.h> -#include <__ranges/empty_view.h> -#include <__ranges/enable_borrowed_range.h> -#include <__ranges/enable_view.h> -#include <__ranges/iota_view.h> -#include <__ranges/join_view.h> -#include <__ranges/rbegin.h> -#include <__ranges/ref_view.h> -#include <__ranges/rend.h> -#include <__ranges/reverse_view.h> -#include <__ranges/single_view.h> -#include <__ranges/size.h> -#include <__ranges/subrange.h> -#include <__ranges/take_view.h> -#include <__ranges/transform_view.h> -#include <__ranges/view_interface.h> -#include <__ranges/views.h> -#include <compare> // Required by the standard. -#include <initializer_list> // Required by the standard. -#include <iterator> // Required by the standard. -#include <type_traits> -#include <version> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#endif // _LIBCPP_RANGES diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/set b/contrib/libs/cxxsupp/libcxxmsvc/include/set deleted file mode 100644 index 176369e81b..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/set +++ /dev/null @@ -1,1564 +0,0 @@ -// -*- 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_SET -#define _LIBCPP_SET - -/* - - set synopsis - -namespace std -{ - -template <class Key, class Compare = less<Key>, - class Allocator = allocator<Key>> -class set -{ -public: - // types: - typedef Key key_type; - typedef key_type value_type; - typedef Compare key_compare; - typedef key_compare value_compare; - typedef Allocator allocator_type; - typedef typename allocator_type::reference reference; - typedef typename allocator_type::const_reference const_reference; - typedef typename allocator_type::size_type size_type; - typedef typename allocator_type::difference_type difference_type; - typedef typename allocator_type::pointer pointer; - typedef typename allocator_type::const_pointer const_pointer; - - typedef implementation-defined iterator; - typedef implementation-defined const_iterator; - typedef std::reverse_iterator<iterator> reverse_iterator; - typedef std::reverse_iterator<const_iterator> const_reverse_iterator; - typedef unspecified node_type; // C++17 - typedef INSERT_RETURN_TYPE<iterator, node_type> insert_return_type; // C++17 - - // construct/copy/destroy: - set() - noexcept( - is_nothrow_default_constructible<allocator_type>::value && - is_nothrow_default_constructible<key_compare>::value && - is_nothrow_copy_constructible<key_compare>::value); - explicit set(const value_compare& comp); - set(const value_compare& comp, const allocator_type& a); - template <class InputIterator> - set(InputIterator first, InputIterator last, - const value_compare& comp = value_compare()); - template <class InputIterator> - set(InputIterator first, InputIterator last, const value_compare& comp, - const allocator_type& a); - set(const set& s); - set(set&& s) - noexcept( - is_nothrow_move_constructible<allocator_type>::value && - is_nothrow_move_constructible<key_compare>::value); - explicit set(const allocator_type& a); - set(const set& s, const allocator_type& a); - set(set&& s, const allocator_type& a); - set(initializer_list<value_type> il, const value_compare& comp = value_compare()); - set(initializer_list<value_type> il, const value_compare& comp, - const allocator_type& a); - template <class InputIterator> - set(InputIterator first, InputIterator last, const allocator_type& a) - : set(first, last, Compare(), a) {} // C++14 - set(initializer_list<value_type> il, const allocator_type& a) - : set(il, Compare(), a) {} // C++14 - ~set(); - - set& operator=(const set& s); - set& operator=(set&& s) - noexcept( - allocator_type::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<allocator_type>::value && - is_nothrow_move_assignable<key_compare>::value); - set& operator=(initializer_list<value_type> il); - - // iterators: - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; - - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; - - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; - - // capacity: - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; - - // modifiers: - template <class... Args> - pair<iterator, bool> emplace(Args&&... args); - template <class... Args> - iterator emplace_hint(const_iterator position, Args&&... args); - pair<iterator,bool> insert(const value_type& v); - pair<iterator,bool> insert(value_type&& v); - iterator insert(const_iterator position, const value_type& v); - iterator insert(const_iterator position, value_type&& v); - template <class InputIterator> - void insert(InputIterator first, InputIterator last); - void insert(initializer_list<value_type> il); - - node_type extract(const_iterator position); // C++17 - node_type extract(const key_type& x); // C++17 - insert_return_type insert(node_type&& nh); // C++17 - iterator insert(const_iterator hint, node_type&& nh); // C++17 - - iterator erase(const_iterator position); - iterator erase(iterator position); // C++14 - size_type erase(const key_type& k); - iterator erase(const_iterator first, const_iterator last); - void clear() noexcept; - - template<class C2> - void merge(set<Key, C2, Allocator>& source); // C++17 - template<class C2> - void merge(set<Key, C2, Allocator>&& source); // C++17 - template<class C2> - void merge(multiset<Key, C2, Allocator>& source); // C++17 - template<class C2> - void merge(multiset<Key, C2, Allocator>&& source); // C++17 - - void swap(set& s) - noexcept( - __is_nothrow_swappable<key_compare>::value && - (!allocator_type::propagate_on_container_swap::value || - __is_nothrow_swappable<allocator_type>::value)); - - // observers: - allocator_type get_allocator() const noexcept; - key_compare key_comp() const; - value_compare value_comp() const; - - // set operations: - iterator find(const key_type& k); - const_iterator find(const key_type& k) const; - template<typename K> - iterator find(const K& x); - template<typename K> - const_iterator find(const K& x) const; // C++14 - - template<typename K> - size_type count(const K& x) const; // C++14 - size_type count(const key_type& k) const; - - bool contains(const key_type& x) const; // C++20 - template<class K> bool contains(const K& x) const; // C++20 - - iterator lower_bound(const key_type& k); - const_iterator lower_bound(const key_type& k) const; - template<typename K> - iterator lower_bound(const K& x); // C++14 - template<typename K> - const_iterator lower_bound(const K& x) const; // C++14 - - iterator upper_bound(const key_type& k); - const_iterator upper_bound(const key_type& k) const; - template<typename K> - iterator upper_bound(const K& x); // C++14 - template<typename K> - const_iterator upper_bound(const K& x) const; // C++14 - pair<iterator,iterator> equal_range(const key_type& k); - pair<const_iterator,const_iterator> equal_range(const key_type& k) const; - template<typename K> - pair<iterator,iterator> equal_range(const K& x); // C++14 - template<typename K> - pair<const_iterator,const_iterator> equal_range(const K& x) const; // C++14 -}; - -template <class InputIterator, - class Compare = less<typename iterator_traits<InputIterator>::value_type>, - class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>> -set(InputIterator, InputIterator, - Compare = Compare(), Allocator = Allocator()) - -> set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>; // C++17 - -template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>> -set(initializer_list<Key>, Compare = Compare(), Allocator = Allocator()) - -> set<Key, Compare, Allocator>; // C++17 - -template<class InputIterator, class Allocator> -set(InputIterator, InputIterator, Allocator) - -> set<typename iterator_traits<InputIterator>::value_type, - less<typename iterator_traits<InputIterator>::value_type>, Allocator>; // C++17 - -template<class Key, class Allocator> -set(initializer_list<Key>, Allocator) -> set<Key, less<Key>, Allocator>; // C++17 - -template <class Key, class Compare, class Allocator> -bool -operator==(const set<Key, Compare, Allocator>& x, - const set<Key, Compare, Allocator>& y); - -template <class Key, class Compare, class Allocator> -bool -operator< (const set<Key, Compare, Allocator>& x, - const set<Key, Compare, Allocator>& y); - -template <class Key, class Compare, class Allocator> -bool -operator!=(const set<Key, Compare, Allocator>& x, - const set<Key, Compare, Allocator>& y); - -template <class Key, class Compare, class Allocator> -bool -operator> (const set<Key, Compare, Allocator>& x, - const set<Key, Compare, Allocator>& y); - -template <class Key, class Compare, class Allocator> -bool -operator>=(const set<Key, Compare, Allocator>& x, - const set<Key, Compare, Allocator>& y); - -template <class Key, class Compare, class Allocator> -bool -operator<=(const set<Key, Compare, Allocator>& x, - const set<Key, Compare, Allocator>& y); - -// specialized algorithms: -template <class Key, class Compare, class Allocator> -void -swap(set<Key, Compare, Allocator>& x, set<Key, Compare, Allocator>& y) - noexcept(noexcept(x.swap(y))); - -template <class Key, class Compare, class Allocator, class Predicate> -typename set<Key, Compare, Allocator>::size_type -erase_if(set<Key, Compare, Allocator>& c, Predicate pred); // C++20 - -template <class Key, class Compare = less<Key>, - class Allocator = allocator<Key>> -class multiset -{ -public: - // types: - typedef Key key_type; - typedef key_type value_type; - typedef Compare key_compare; - typedef key_compare value_compare; - typedef Allocator allocator_type; - typedef typename allocator_type::reference reference; - typedef typename allocator_type::const_reference const_reference; - typedef typename allocator_type::size_type size_type; - typedef typename allocator_type::difference_type difference_type; - typedef typename allocator_type::pointer pointer; - typedef typename allocator_type::const_pointer const_pointer; - - typedef implementation-defined iterator; - typedef implementation-defined const_iterator; - typedef std::reverse_iterator<iterator> reverse_iterator; - typedef std::reverse_iterator<const_iterator> const_reverse_iterator; - typedef unspecified node_type; // C++17 - - // construct/copy/destroy: - multiset() - noexcept( - is_nothrow_default_constructible<allocator_type>::value && - is_nothrow_default_constructible<key_compare>::value && - is_nothrow_copy_constructible<key_compare>::value); - explicit multiset(const value_compare& comp); - multiset(const value_compare& comp, const allocator_type& a); - template <class InputIterator> - multiset(InputIterator first, InputIterator last, - const value_compare& comp = value_compare()); - template <class InputIterator> - multiset(InputIterator first, InputIterator last, - const value_compare& comp, const allocator_type& a); - multiset(const multiset& s); - multiset(multiset&& s) - noexcept( - is_nothrow_move_constructible<allocator_type>::value && - is_nothrow_move_constructible<key_compare>::value); - explicit multiset(const allocator_type& a); - multiset(const multiset& s, const allocator_type& a); - multiset(multiset&& s, const allocator_type& a); - multiset(initializer_list<value_type> il, const value_compare& comp = value_compare()); - multiset(initializer_list<value_type> il, const value_compare& comp, - const allocator_type& a); - template <class InputIterator> - multiset(InputIterator first, InputIterator last, const allocator_type& a) - : set(first, last, Compare(), a) {} // C++14 - multiset(initializer_list<value_type> il, const allocator_type& a) - : set(il, Compare(), a) {} // C++14 - ~multiset(); - - multiset& operator=(const multiset& s); - multiset& operator=(multiset&& s) - noexcept( - allocator_type::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<allocator_type>::value && - is_nothrow_move_assignable<key_compare>::value); - multiset& operator=(initializer_list<value_type> il); - - // iterators: - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; - - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; - - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; - - // capacity: - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; - - // modifiers: - template <class... Args> - iterator emplace(Args&&... args); - template <class... Args> - iterator emplace_hint(const_iterator position, Args&&... args); - iterator insert(const value_type& v); - iterator insert(value_type&& v); - iterator insert(const_iterator position, const value_type& v); - iterator insert(const_iterator position, value_type&& v); - template <class InputIterator> - void insert(InputIterator first, InputIterator last); - void insert(initializer_list<value_type> il); - - node_type extract(const_iterator position); // C++17 - node_type extract(const key_type& x); // C++17 - iterator insert(node_type&& nh); // C++17 - iterator insert(const_iterator hint, node_type&& nh); // C++17 - - iterator erase(const_iterator position); - iterator erase(iterator position); // C++14 - size_type erase(const key_type& k); - iterator erase(const_iterator first, const_iterator last); - void clear() noexcept; - - template<class C2> - void merge(multiset<Key, C2, Allocator>& source); // C++17 - template<class C2> - void merge(multiset<Key, C2, Allocator>&& source); // C++17 - template<class C2> - void merge(set<Key, C2, Allocator>& source); // C++17 - template<class C2> - void merge(set<Key, C2, Allocator>&& source); // C++17 - - void swap(multiset& s) - noexcept( - __is_nothrow_swappable<key_compare>::value && - (!allocator_type::propagate_on_container_swap::value || - __is_nothrow_swappable<allocator_type>::value)); - - // observers: - allocator_type get_allocator() const noexcept; - key_compare key_comp() const; - value_compare value_comp() const; - - // set operations: - iterator find(const key_type& k); - const_iterator find(const key_type& k) const; - template<typename K> - iterator find(const K& x); - template<typename K> - const_iterator find(const K& x) const; // C++14 - - template<typename K> - size_type count(const K& x) const; // C++14 - size_type count(const key_type& k) const; - - bool contains(const key_type& x) const; // C++20 - template<class K> bool contains(const K& x) const; // C++20 - - iterator lower_bound(const key_type& k); - const_iterator lower_bound(const key_type& k) const; - template<typename K> - iterator lower_bound(const K& x); // C++14 - template<typename K> - const_iterator lower_bound(const K& x) const; // C++14 - - iterator upper_bound(const key_type& k); - const_iterator upper_bound(const key_type& k) const; - template<typename K> - iterator upper_bound(const K& x); // C++14 - template<typename K> - const_iterator upper_bound(const K& x) const; // C++14 - - pair<iterator,iterator> equal_range(const key_type& k); - pair<const_iterator,const_iterator> equal_range(const key_type& k) const; - template<typename K> - pair<iterator,iterator> equal_range(const K& x); // C++14 - template<typename K> - pair<const_iterator,const_iterator> equal_range(const K& x) const; // C++14 -}; - -template <class InputIterator, - class Compare = less<typename iterator_traits<InputIterator>::value_type>, - class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>> -multiset(InputIterator, InputIterator, - Compare = Compare(), Allocator = Allocator()) - -> multiset<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>; // C++17 - -template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>> -multiset(initializer_list<Key>, Compare = Compare(), Allocator = Allocator()) - -> multiset<Key, Compare, Allocator>; // C++17 - -template<class InputIterator, class Allocator> -multiset(InputIterator, InputIterator, Allocator) - -> multiset<typename iterator_traits<InputIterator>::value_type, - less<typename iterator_traits<InputIterator>::value_type>, Allocator>; // C++17 - -template<class Key, class Allocator> -multiset(initializer_list<Key>, Allocator) -> multiset<Key, less<Key>, Allocator>; // C++17 - -template <class Key, class Compare, class Allocator> -bool -operator==(const multiset<Key, Compare, Allocator>& x, - const multiset<Key, Compare, Allocator>& y); - -template <class Key, class Compare, class Allocator> -bool -operator< (const multiset<Key, Compare, Allocator>& x, - const multiset<Key, Compare, Allocator>& y); - -template <class Key, class Compare, class Allocator> -bool -operator!=(const multiset<Key, Compare, Allocator>& x, - const multiset<Key, Compare, Allocator>& y); - -template <class Key, class Compare, class Allocator> -bool -operator> (const multiset<Key, Compare, Allocator>& x, - const multiset<Key, Compare, Allocator>& y); - -template <class Key, class Compare, class Allocator> -bool -operator>=(const multiset<Key, Compare, Allocator>& x, - const multiset<Key, Compare, Allocator>& y); - -template <class Key, class Compare, class Allocator> -bool -operator<=(const multiset<Key, Compare, Allocator>& x, - const multiset<Key, Compare, Allocator>& y); - -// specialized algorithms: -template <class Key, class Compare, class Allocator> -void -swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y) - noexcept(noexcept(x.swap(y))); - -template <class Key, class Compare, class Allocator, class Predicate> -typename multiset<Key, Compare, Allocator>::size_type -erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); // C++20 - -} // std - -*/ - -#include <__algorithm/equal.h> -#include <__algorithm/lexicographical_compare.h> -#include <__assert> -#include <__config> -#include <__functional/is_transparent.h> -#include <__iterator/iterator_traits.h> -#include <__node_handle> -#include <__tree> -#include <__utility/forward.h> -#include <compare> -#include <functional> -#include <initializer_list> -#include <iterator> // __libcpp_erase_if_container -#include <version> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -template <class _Key, class _Compare, class _Allocator> -class multiset; - -template <class _Key, class _Compare = less<_Key>, - class _Allocator = allocator<_Key> > -class _LIBCPP_TEMPLATE_VIS set -{ -public: - // types: - typedef _Key key_type; - typedef key_type value_type; - typedef __identity_t<_Compare> key_compare; - typedef key_compare value_compare; - typedef __identity_t<_Allocator> allocator_type; - typedef value_type& reference; - typedef const value_type& const_reference; - - static_assert((is_same<typename allocator_type::value_type, value_type>::value), - "Allocator::value_type must be same type as value_type"); - -private: - typedef __tree<value_type, value_compare, allocator_type> __base; - typedef allocator_traits<allocator_type> __alloc_traits; - - __base __tree_; - -public: - typedef typename __base::pointer pointer; - typedef typename __base::const_pointer const_pointer; - typedef typename __base::size_type size_type; - typedef typename __base::difference_type difference_type; - typedef typename __base::const_iterator iterator; - typedef typename __base::const_iterator const_iterator; - typedef _VSTD::reverse_iterator<iterator> reverse_iterator; - typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator; - -#if _LIBCPP_STD_VER > 14 - typedef __set_node_handle<typename __base::__node, allocator_type> node_type; - typedef __insert_return_type<iterator, node_type> insert_return_type; -#endif - - template <class _Key2, class _Compare2, class _Alloc2> - friend class _LIBCPP_TEMPLATE_VIS set; - template <class _Key2, class _Compare2, class _Alloc2> - friend class _LIBCPP_TEMPLATE_VIS multiset; - - _LIBCPP_INLINE_VISIBILITY - set() - _NOEXCEPT_( - is_nothrow_default_constructible<allocator_type>::value && - is_nothrow_default_constructible<key_compare>::value && - is_nothrow_copy_constructible<key_compare>::value) - : __tree_(value_compare()) {} - - _LIBCPP_INLINE_VISIBILITY - explicit set(const value_compare& __comp) - _NOEXCEPT_( - is_nothrow_default_constructible<allocator_type>::value && - is_nothrow_copy_constructible<key_compare>::value) - : __tree_(__comp) {} - - _LIBCPP_INLINE_VISIBILITY - explicit set(const value_compare& __comp, const allocator_type& __a) - : __tree_(__comp, __a) {} - template <class _InputIterator> - _LIBCPP_INLINE_VISIBILITY - set(_InputIterator __f, _InputIterator __l, - const value_compare& __comp = value_compare()) - : __tree_(__comp) - { - insert(__f, __l); - } - - template <class _InputIterator> - _LIBCPP_INLINE_VISIBILITY - set(_InputIterator __f, _InputIterator __l, const value_compare& __comp, - const allocator_type& __a) - : __tree_(__comp, __a) - { - insert(__f, __l); - } - -#if _LIBCPP_STD_VER > 11 - template <class _InputIterator> - _LIBCPP_INLINE_VISIBILITY - set(_InputIterator __f, _InputIterator __l, const allocator_type& __a) - : set(__f, __l, key_compare(), __a) {} -#endif - - _LIBCPP_INLINE_VISIBILITY - set(const set& __s) - : __tree_(__s.__tree_) - { - insert(__s.begin(), __s.end()); - } - - _LIBCPP_INLINE_VISIBILITY - set& operator=(const set& __s) - { - __tree_ = __s.__tree_; - return *this; - } - -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - set(set&& __s) - _NOEXCEPT_(is_nothrow_move_constructible<__base>::value) - : __tree_(_VSTD::move(__s.__tree_)) {} -#endif // _LIBCPP_CXX03_LANG - - _LIBCPP_INLINE_VISIBILITY - explicit set(const allocator_type& __a) - : __tree_(__a) {} - - _LIBCPP_INLINE_VISIBILITY - set(const set& __s, const allocator_type& __a) - : __tree_(__s.__tree_.value_comp(), __a) - { - insert(__s.begin(), __s.end()); - } - -#ifndef _LIBCPP_CXX03_LANG - set(set&& __s, const allocator_type& __a); - - _LIBCPP_INLINE_VISIBILITY - set(initializer_list<value_type> __il, const value_compare& __comp = value_compare()) - : __tree_(__comp) - { - insert(__il.begin(), __il.end()); - } - - _LIBCPP_INLINE_VISIBILITY - set(initializer_list<value_type> __il, const value_compare& __comp, - const allocator_type& __a) - : __tree_(__comp, __a) - { - insert(__il.begin(), __il.end()); - } - -#if _LIBCPP_STD_VER > 11 - _LIBCPP_INLINE_VISIBILITY - set(initializer_list<value_type> __il, const allocator_type& __a) - : set(__il, key_compare(), __a) {} -#endif - - _LIBCPP_INLINE_VISIBILITY - set& operator=(initializer_list<value_type> __il) - { - __tree_.__assign_unique(__il.begin(), __il.end()); - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - set& operator=(set&& __s) - _NOEXCEPT_(is_nothrow_move_assignable<__base>::value) - { - __tree_ = _VSTD::move(__s.__tree_); - return *this; - } -#endif // _LIBCPP_CXX03_LANG - - _LIBCPP_INLINE_VISIBILITY - ~set() { - static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), ""); - } - - _LIBCPP_INLINE_VISIBILITY - iterator begin() _NOEXCEPT {return __tree_.begin();} - _LIBCPP_INLINE_VISIBILITY - const_iterator begin() const _NOEXCEPT {return __tree_.begin();} - _LIBCPP_INLINE_VISIBILITY - iterator end() _NOEXCEPT {return __tree_.end();} - _LIBCPP_INLINE_VISIBILITY - const_iterator end() const _NOEXCEPT {return __tree_.end();} - - _LIBCPP_INLINE_VISIBILITY - reverse_iterator rbegin() _NOEXCEPT - {return reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY - const_reverse_iterator rbegin() const _NOEXCEPT - {return const_reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY - reverse_iterator rend() _NOEXCEPT - {return reverse_iterator(begin());} - _LIBCPP_INLINE_VISIBILITY - const_reverse_iterator rend() const _NOEXCEPT - {return const_reverse_iterator(begin());} - - _LIBCPP_INLINE_VISIBILITY - const_iterator cbegin() const _NOEXCEPT {return begin();} - _LIBCPP_INLINE_VISIBILITY - const_iterator cend() const _NOEXCEPT {return end();} - _LIBCPP_INLINE_VISIBILITY - const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();} - _LIBCPP_INLINE_VISIBILITY - const_reverse_iterator crend() const _NOEXCEPT {return rend();} - - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY - bool empty() const _NOEXCEPT {return __tree_.size() == 0;} - _LIBCPP_INLINE_VISIBILITY - size_type size() const _NOEXCEPT {return __tree_.size();} - _LIBCPP_INLINE_VISIBILITY - size_type max_size() const _NOEXCEPT {return __tree_.max_size();} - - // modifiers: -#ifndef _LIBCPP_CXX03_LANG - template <class... _Args> - _LIBCPP_INLINE_VISIBILITY - pair<iterator, bool> emplace(_Args&&... __args) - {return __tree_.__emplace_unique(_VSTD::forward<_Args>(__args)...);} - template <class... _Args> - _LIBCPP_INLINE_VISIBILITY - iterator emplace_hint(const_iterator __p, _Args&&... __args) - {return __tree_.__emplace_hint_unique(__p, _VSTD::forward<_Args>(__args)...);} -#endif // _LIBCPP_CXX03_LANG - - _LIBCPP_INLINE_VISIBILITY - pair<iterator,bool> insert(const value_type& __v) - {return __tree_.__insert_unique(__v);} - _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __p, const value_type& __v) - {return __tree_.__insert_unique(__p, __v);} - - template <class _InputIterator> - _LIBCPP_INLINE_VISIBILITY - void insert(_InputIterator __f, _InputIterator __l) - { - for (const_iterator __e = cend(); __f != __l; ++__f) - __tree_.__insert_unique(__e, *__f); - } - -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - pair<iterator,bool> insert(value_type&& __v) - {return __tree_.__insert_unique(_VSTD::move(__v));} - - _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __p, value_type&& __v) - {return __tree_.__insert_unique(__p, _VSTD::move(__v));} - - _LIBCPP_INLINE_VISIBILITY - void insert(initializer_list<value_type> __il) - {insert(__il.begin(), __il.end());} -#endif // _LIBCPP_CXX03_LANG - - _LIBCPP_INLINE_VISIBILITY - iterator erase(const_iterator __p) {return __tree_.erase(__p);} - _LIBCPP_INLINE_VISIBILITY - size_type erase(const key_type& __k) - {return __tree_.__erase_unique(__k);} - _LIBCPP_INLINE_VISIBILITY - iterator erase(const_iterator __f, const_iterator __l) - {return __tree_.erase(__f, __l);} - _LIBCPP_REINITIALIZES_OBJECT _LIBCPP_INLINE_VISIBILITY - void clear() _NOEXCEPT {__tree_.clear();} - -#if _LIBCPP_STD_VER > 14 - _LIBCPP_INLINE_VISIBILITY - insert_return_type insert(node_type&& __nh) - { - _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), - "node_type with incompatible allocator passed to set::insert()"); - return __tree_.template __node_handle_insert_unique< - node_type, insert_return_type>(_VSTD::move(__nh)); - } - _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __hint, node_type&& __nh) - { - _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), - "node_type with incompatible allocator passed to set::insert()"); - return __tree_.template __node_handle_insert_unique<node_type>( - __hint, _VSTD::move(__nh)); - } - _LIBCPP_INLINE_VISIBILITY - node_type extract(key_type const& __key) - { - return __tree_.template __node_handle_extract<node_type>(__key); - } - _LIBCPP_INLINE_VISIBILITY - node_type extract(const_iterator __it) - { - return __tree_.template __node_handle_extract<node_type>(__it); - } - template <class _Compare2> - _LIBCPP_INLINE_VISIBILITY - void merge(set<key_type, _Compare2, allocator_type>& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - __tree_.__node_handle_merge_unique(__source.__tree_); - } - template <class _Compare2> - _LIBCPP_INLINE_VISIBILITY - void merge(set<key_type, _Compare2, allocator_type>&& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - __tree_.__node_handle_merge_unique(__source.__tree_); - } - template <class _Compare2> - _LIBCPP_INLINE_VISIBILITY - void merge(multiset<key_type, _Compare2, allocator_type>& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - __tree_.__node_handle_merge_unique(__source.__tree_); - } - template <class _Compare2> - _LIBCPP_INLINE_VISIBILITY - void merge(multiset<key_type, _Compare2, allocator_type>&& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - __tree_.__node_handle_merge_unique(__source.__tree_); - } -#endif - - _LIBCPP_INLINE_VISIBILITY - void swap(set& __s) _NOEXCEPT_(__is_nothrow_swappable<__base>::value) - {__tree_.swap(__s.__tree_);} - - _LIBCPP_INLINE_VISIBILITY - allocator_type get_allocator() const _NOEXCEPT {return __tree_.__alloc();} - _LIBCPP_INLINE_VISIBILITY - key_compare key_comp() const {return __tree_.value_comp();} - _LIBCPP_INLINE_VISIBILITY - value_compare value_comp() const {return __tree_.value_comp();} - - // set operations: - _LIBCPP_INLINE_VISIBILITY - iterator find(const key_type& __k) {return __tree_.find(__k);} - _LIBCPP_INLINE_VISIBILITY - const_iterator find(const key_type& __k) const {return __tree_.find(__k);} -#if _LIBCPP_STD_VER > 11 - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type - find(const _K2& __k) {return __tree_.find(__k);} - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type - find(const _K2& __k) const {return __tree_.find(__k);} -#endif - - _LIBCPP_INLINE_VISIBILITY - size_type count(const key_type& __k) const - {return __tree_.__count_unique(__k);} -#if _LIBCPP_STD_VER > 11 - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type - count(const _K2& __k) const {return __tree_.__count_multi(__k);} -#endif - -#if _LIBCPP_STD_VER > 17 - _LIBCPP_INLINE_VISIBILITY - bool contains(const key_type& __k) const {return find(__k) != end();} - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type - contains(const _K2& __k) const { return find(__k) != end(); } -#endif // _LIBCPP_STD_VER > 17 - - _LIBCPP_INLINE_VISIBILITY - iterator lower_bound(const key_type& __k) - {return __tree_.lower_bound(__k);} - _LIBCPP_INLINE_VISIBILITY - const_iterator lower_bound(const key_type& __k) const - {return __tree_.lower_bound(__k);} -#if _LIBCPP_STD_VER > 11 - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type - lower_bound(const _K2& __k) {return __tree_.lower_bound(__k);} - - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type - lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);} -#endif - - _LIBCPP_INLINE_VISIBILITY - iterator upper_bound(const key_type& __k) - {return __tree_.upper_bound(__k);} - _LIBCPP_INLINE_VISIBILITY - const_iterator upper_bound(const key_type& __k) const - {return __tree_.upper_bound(__k);} -#if _LIBCPP_STD_VER > 11 - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type - upper_bound(const _K2& __k) {return __tree_.upper_bound(__k);} - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type - upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);} -#endif - - _LIBCPP_INLINE_VISIBILITY - pair<iterator,iterator> equal_range(const key_type& __k) - {return __tree_.__equal_range_unique(__k);} - _LIBCPP_INLINE_VISIBILITY - pair<const_iterator,const_iterator> equal_range(const key_type& __k) const - {return __tree_.__equal_range_unique(__k);} -#if _LIBCPP_STD_VER > 11 - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type - equal_range(const _K2& __k) {return __tree_.__equal_range_multi(__k);} - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type - equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);} -#endif -}; - -#if _LIBCPP_STD_VER >= 17 -template<class _InputIterator, - class _Compare = less<__iter_value_type<_InputIterator>>, - class _Allocator = allocator<__iter_value_type<_InputIterator>>, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>, - class = enable_if_t<__is_allocator<_Allocator>::value, void>, - class = enable_if_t<!__is_allocator<_Compare>::value, void>> -set(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator()) - -> set<__iter_value_type<_InputIterator>, _Compare, _Allocator>; - -template<class _Key, class _Compare = less<_Key>, - class _Allocator = allocator<_Key>, - class = enable_if_t<!__is_allocator<_Compare>::value, void>, - class = enable_if_t<__is_allocator<_Allocator>::value, void>> -set(initializer_list<_Key>, _Compare = _Compare(), _Allocator = _Allocator()) - -> set<_Key, _Compare, _Allocator>; - -template<class _InputIterator, class _Allocator, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>, - class = enable_if_t<__is_allocator<_Allocator>::value, void>> -set(_InputIterator, _InputIterator, _Allocator) - -> set<__iter_value_type<_InputIterator>, - less<__iter_value_type<_InputIterator>>, _Allocator>; - -template<class _Key, class _Allocator, - class = enable_if_t<__is_allocator<_Allocator>::value, void>> -set(initializer_list<_Key>, _Allocator) - -> set<_Key, less<_Key>, _Allocator>; -#endif - -#ifndef _LIBCPP_CXX03_LANG - -template <class _Key, class _Compare, class _Allocator> -set<_Key, _Compare, _Allocator>::set(set&& __s, const allocator_type& __a) - : __tree_(_VSTD::move(__s.__tree_), __a) -{ - if (__a != __s.get_allocator()) - { - const_iterator __e = cend(); - while (!__s.empty()) - insert(__e, _VSTD::move(__s.__tree_.remove(__s.begin())->__value_)); - } -} - -#endif // _LIBCPP_CXX03_LANG - -template <class _Key, class _Compare, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator==(const set<_Key, _Compare, _Allocator>& __x, - const set<_Key, _Compare, _Allocator>& __y) -{ - return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin()); -} - -template <class _Key, class _Compare, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator< (const set<_Key, _Compare, _Allocator>& __x, - const set<_Key, _Compare, _Allocator>& __y) -{ - return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); -} - -template <class _Key, class _Compare, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator!=(const set<_Key, _Compare, _Allocator>& __x, - const set<_Key, _Compare, _Allocator>& __y) -{ - return !(__x == __y); -} - -template <class _Key, class _Compare, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator> (const set<_Key, _Compare, _Allocator>& __x, - const set<_Key, _Compare, _Allocator>& __y) -{ - return __y < __x; -} - -template <class _Key, class _Compare, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator>=(const set<_Key, _Compare, _Allocator>& __x, - const set<_Key, _Compare, _Allocator>& __y) -{ - return !(__x < __y); -} - -template <class _Key, class _Compare, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator<=(const set<_Key, _Compare, _Allocator>& __x, - const set<_Key, _Compare, _Allocator>& __y) -{ - return !(__y < __x); -} - -// specialized algorithms: -template <class _Key, class _Compare, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -void -swap(set<_Key, _Compare, _Allocator>& __x, - set<_Key, _Compare, _Allocator>& __y) - _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) -{ - __x.swap(__y); -} - -#if _LIBCPP_STD_VER > 17 -template <class _Key, class _Compare, class _Allocator, class _Predicate> -inline _LIBCPP_INLINE_VISIBILITY - typename set<_Key, _Compare, _Allocator>::size_type - erase_if(set<_Key, _Compare, _Allocator>& __c, _Predicate __pred) { - return _VSTD::__libcpp_erase_if_container(__c, __pred); -} -#endif - -template <class _Key, class _Compare = less<_Key>, - class _Allocator = allocator<_Key> > -class _LIBCPP_TEMPLATE_VIS multiset -{ -public: - // types: - typedef _Key key_type; - typedef key_type value_type; - typedef __identity_t<_Compare> key_compare; - typedef key_compare value_compare; - typedef __identity_t<_Allocator> allocator_type; - typedef value_type& reference; - typedef const value_type& const_reference; - - static_assert((is_same<typename allocator_type::value_type, value_type>::value), - "Allocator::value_type must be same type as value_type"); - -private: - typedef __tree<value_type, value_compare, allocator_type> __base; - typedef allocator_traits<allocator_type> __alloc_traits; - - __base __tree_; - -public: - typedef typename __base::pointer pointer; - typedef typename __base::const_pointer const_pointer; - typedef typename __base::size_type size_type; - typedef typename __base::difference_type difference_type; - typedef typename __base::const_iterator iterator; - typedef typename __base::const_iterator const_iterator; - typedef _VSTD::reverse_iterator<iterator> reverse_iterator; - typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator; - -#if _LIBCPP_STD_VER > 14 - typedef __set_node_handle<typename __base::__node, allocator_type> node_type; -#endif - - template <class _Key2, class _Compare2, class _Alloc2> - friend class _LIBCPP_TEMPLATE_VIS set; - template <class _Key2, class _Compare2, class _Alloc2> - friend class _LIBCPP_TEMPLATE_VIS multiset; - - // construct/copy/destroy: - _LIBCPP_INLINE_VISIBILITY - multiset() - _NOEXCEPT_( - is_nothrow_default_constructible<allocator_type>::value && - is_nothrow_default_constructible<key_compare>::value && - is_nothrow_copy_constructible<key_compare>::value) - : __tree_(value_compare()) {} - - _LIBCPP_INLINE_VISIBILITY - explicit multiset(const value_compare& __comp) - _NOEXCEPT_( - is_nothrow_default_constructible<allocator_type>::value && - is_nothrow_copy_constructible<key_compare>::value) - : __tree_(__comp) {} - - _LIBCPP_INLINE_VISIBILITY - explicit multiset(const value_compare& __comp, const allocator_type& __a) - : __tree_(__comp, __a) {} - template <class _InputIterator> - _LIBCPP_INLINE_VISIBILITY - multiset(_InputIterator __f, _InputIterator __l, - const value_compare& __comp = value_compare()) - : __tree_(__comp) - { - insert(__f, __l); - } - -#if _LIBCPP_STD_VER > 11 - template <class _InputIterator> - _LIBCPP_INLINE_VISIBILITY - multiset(_InputIterator __f, _InputIterator __l, const allocator_type& __a) - : multiset(__f, __l, key_compare(), __a) {} -#endif - - template <class _InputIterator> - _LIBCPP_INLINE_VISIBILITY - multiset(_InputIterator __f, _InputIterator __l, - const value_compare& __comp, const allocator_type& __a) - : __tree_(__comp, __a) - { - insert(__f, __l); - } - - _LIBCPP_INLINE_VISIBILITY - multiset(const multiset& __s) - : __tree_(__s.__tree_.value_comp(), - __alloc_traits::select_on_container_copy_construction(__s.__tree_.__alloc())) - { - insert(__s.begin(), __s.end()); - } - - _LIBCPP_INLINE_VISIBILITY - multiset& operator=(const multiset& __s) - { - __tree_ = __s.__tree_; - return *this; - } - -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - multiset(multiset&& __s) - _NOEXCEPT_(is_nothrow_move_constructible<__base>::value) - : __tree_(_VSTD::move(__s.__tree_)) {} - - multiset(multiset&& __s, const allocator_type& __a); -#endif // _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - explicit multiset(const allocator_type& __a) - : __tree_(__a) {} - _LIBCPP_INLINE_VISIBILITY - multiset(const multiset& __s, const allocator_type& __a) - : __tree_(__s.__tree_.value_comp(), __a) - { - insert(__s.begin(), __s.end()); - } - -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - multiset(initializer_list<value_type> __il, const value_compare& __comp = value_compare()) - : __tree_(__comp) - { - insert(__il.begin(), __il.end()); - } - - _LIBCPP_INLINE_VISIBILITY - multiset(initializer_list<value_type> __il, const value_compare& __comp, - const allocator_type& __a) - : __tree_(__comp, __a) - { - insert(__il.begin(), __il.end()); - } - -#if _LIBCPP_STD_VER > 11 - _LIBCPP_INLINE_VISIBILITY - multiset(initializer_list<value_type> __il, const allocator_type& __a) - : multiset(__il, key_compare(), __a) {} -#endif - - _LIBCPP_INLINE_VISIBILITY - multiset& operator=(initializer_list<value_type> __il) - { - __tree_.__assign_multi(__il.begin(), __il.end()); - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - multiset& operator=(multiset&& __s) - _NOEXCEPT_(is_nothrow_move_assignable<__base>::value) - { - __tree_ = _VSTD::move(__s.__tree_); - return *this; - } -#endif // _LIBCPP_CXX03_LANG - - _LIBCPP_INLINE_VISIBILITY - ~multiset() { - static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), ""); - } - - _LIBCPP_INLINE_VISIBILITY - iterator begin() _NOEXCEPT {return __tree_.begin();} - _LIBCPP_INLINE_VISIBILITY - const_iterator begin() const _NOEXCEPT {return __tree_.begin();} - _LIBCPP_INLINE_VISIBILITY - iterator end() _NOEXCEPT {return __tree_.end();} - _LIBCPP_INLINE_VISIBILITY - const_iterator end() const _NOEXCEPT {return __tree_.end();} - - _LIBCPP_INLINE_VISIBILITY - reverse_iterator rbegin() _NOEXCEPT - {return reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY - const_reverse_iterator rbegin() const _NOEXCEPT - {return const_reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY - reverse_iterator rend() _NOEXCEPT - {return reverse_iterator(begin());} - _LIBCPP_INLINE_VISIBILITY - const_reverse_iterator rend() const _NOEXCEPT - {return const_reverse_iterator(begin());} - - _LIBCPP_INLINE_VISIBILITY - const_iterator cbegin() const _NOEXCEPT {return begin();} - _LIBCPP_INLINE_VISIBILITY - const_iterator cend() const _NOEXCEPT {return end();} - _LIBCPP_INLINE_VISIBILITY - const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();} - _LIBCPP_INLINE_VISIBILITY - const_reverse_iterator crend() const _NOEXCEPT {return rend();} - - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY - bool empty() const _NOEXCEPT {return __tree_.size() == 0;} - _LIBCPP_INLINE_VISIBILITY - size_type size() const _NOEXCEPT {return __tree_.size();} - _LIBCPP_INLINE_VISIBILITY - size_type max_size() const _NOEXCEPT {return __tree_.max_size();} - - // modifiers: -#ifndef _LIBCPP_CXX03_LANG - template <class... _Args> - _LIBCPP_INLINE_VISIBILITY - iterator emplace(_Args&&... __args) - {return __tree_.__emplace_multi(_VSTD::forward<_Args>(__args)...);} - template <class... _Args> - _LIBCPP_INLINE_VISIBILITY - iterator emplace_hint(const_iterator __p, _Args&&... __args) - {return __tree_.__emplace_hint_multi(__p, _VSTD::forward<_Args>(__args)...);} -#endif // _LIBCPP_CXX03_LANG - - _LIBCPP_INLINE_VISIBILITY - iterator insert(const value_type& __v) - {return __tree_.__insert_multi(__v);} - _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __p, const value_type& __v) - {return __tree_.__insert_multi(__p, __v);} - - template <class _InputIterator> - _LIBCPP_INLINE_VISIBILITY - void insert(_InputIterator __f, _InputIterator __l) - { - for (const_iterator __e = cend(); __f != __l; ++__f) - __tree_.__insert_multi(__e, *__f); - } - -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - iterator insert(value_type&& __v) - {return __tree_.__insert_multi(_VSTD::move(__v));} - - _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __p, value_type&& __v) - {return __tree_.__insert_multi(__p, _VSTD::move(__v));} - - _LIBCPP_INLINE_VISIBILITY - void insert(initializer_list<value_type> __il) - {insert(__il.begin(), __il.end());} -#endif // _LIBCPP_CXX03_LANG - - _LIBCPP_INLINE_VISIBILITY - iterator erase(const_iterator __p) {return __tree_.erase(__p);} - _LIBCPP_INLINE_VISIBILITY - size_type erase(const key_type& __k) {return __tree_.__erase_multi(__k);} - _LIBCPP_INLINE_VISIBILITY - iterator erase(const_iterator __f, const_iterator __l) - {return __tree_.erase(__f, __l);} - _LIBCPP_REINITIALIZES_OBJECT _LIBCPP_INLINE_VISIBILITY - void clear() _NOEXCEPT {__tree_.clear();} - -#if _LIBCPP_STD_VER > 14 - _LIBCPP_INLINE_VISIBILITY - iterator insert(node_type&& __nh) - { - _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), - "node_type with incompatible allocator passed to multiset::insert()"); - return __tree_.template __node_handle_insert_multi<node_type>( - _VSTD::move(__nh)); - } - _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __hint, node_type&& __nh) - { - _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), - "node_type with incompatible allocator passed to multiset::insert()"); - return __tree_.template __node_handle_insert_multi<node_type>( - __hint, _VSTD::move(__nh)); - } - _LIBCPP_INLINE_VISIBILITY - node_type extract(key_type const& __key) - { - return __tree_.template __node_handle_extract<node_type>(__key); - } - _LIBCPP_INLINE_VISIBILITY - node_type extract(const_iterator __it) - { - return __tree_.template __node_handle_extract<node_type>(__it); - } - template <class _Compare2> - _LIBCPP_INLINE_VISIBILITY - void merge(multiset<key_type, _Compare2, allocator_type>& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - __tree_.__node_handle_merge_multi(__source.__tree_); - } - template <class _Compare2> - _LIBCPP_INLINE_VISIBILITY - void merge(multiset<key_type, _Compare2, allocator_type>&& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - __tree_.__node_handle_merge_multi(__source.__tree_); - } - template <class _Compare2> - _LIBCPP_INLINE_VISIBILITY - void merge(set<key_type, _Compare2, allocator_type>& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - __tree_.__node_handle_merge_multi(__source.__tree_); - } - template <class _Compare2> - _LIBCPP_INLINE_VISIBILITY - void merge(set<key_type, _Compare2, allocator_type>&& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - __tree_.__node_handle_merge_multi(__source.__tree_); - } -#endif - - _LIBCPP_INLINE_VISIBILITY - void swap(multiset& __s) - _NOEXCEPT_(__is_nothrow_swappable<__base>::value) - {__tree_.swap(__s.__tree_);} - - _LIBCPP_INLINE_VISIBILITY - allocator_type get_allocator() const _NOEXCEPT {return __tree_.__alloc();} - _LIBCPP_INLINE_VISIBILITY - key_compare key_comp() const {return __tree_.value_comp();} - _LIBCPP_INLINE_VISIBILITY - value_compare value_comp() const {return __tree_.value_comp();} - - // set operations: - _LIBCPP_INLINE_VISIBILITY - iterator find(const key_type& __k) {return __tree_.find(__k);} - _LIBCPP_INLINE_VISIBILITY - const_iterator find(const key_type& __k) const {return __tree_.find(__k);} -#if _LIBCPP_STD_VER > 11 - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type - find(const _K2& __k) {return __tree_.find(__k);} - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type - find(const _K2& __k) const {return __tree_.find(__k);} -#endif - - _LIBCPP_INLINE_VISIBILITY - size_type count(const key_type& __k) const - {return __tree_.__count_multi(__k);} -#if _LIBCPP_STD_VER > 11 - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type - count(const _K2& __k) const {return __tree_.__count_multi(__k);} -#endif - -#if _LIBCPP_STD_VER > 17 - _LIBCPP_INLINE_VISIBILITY - bool contains(const key_type& __k) const {return find(__k) != end();} - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type - contains(const _K2& __k) const { return find(__k) != end(); } -#endif // _LIBCPP_STD_VER > 17 - - _LIBCPP_INLINE_VISIBILITY - iterator lower_bound(const key_type& __k) - {return __tree_.lower_bound(__k);} - _LIBCPP_INLINE_VISIBILITY - const_iterator lower_bound(const key_type& __k) const - {return __tree_.lower_bound(__k);} -#if _LIBCPP_STD_VER > 11 - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type - lower_bound(const _K2& __k) {return __tree_.lower_bound(__k);} - - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type - lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);} -#endif - - _LIBCPP_INLINE_VISIBILITY - iterator upper_bound(const key_type& __k) - {return __tree_.upper_bound(__k);} - _LIBCPP_INLINE_VISIBILITY - const_iterator upper_bound(const key_type& __k) const - {return __tree_.upper_bound(__k);} -#if _LIBCPP_STD_VER > 11 - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type - upper_bound(const _K2& __k) {return __tree_.upper_bound(__k);} - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type - upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);} -#endif - - _LIBCPP_INLINE_VISIBILITY - pair<iterator,iterator> equal_range(const key_type& __k) - {return __tree_.__equal_range_multi(__k);} - _LIBCPP_INLINE_VISIBILITY - pair<const_iterator,const_iterator> equal_range(const key_type& __k) const - {return __tree_.__equal_range_multi(__k);} -#if _LIBCPP_STD_VER > 11 - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type - equal_range(const _K2& __k) {return __tree_.__equal_range_multi(__k);} - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type - equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);} -#endif -}; - -#if _LIBCPP_STD_VER >= 17 -template<class _InputIterator, - class _Compare = less<__iter_value_type<_InputIterator>>, - class _Allocator = allocator<__iter_value_type<_InputIterator>>, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>, - class = enable_if_t<__is_allocator<_Allocator>::value, void>, - class = enable_if_t<!__is_allocator<_Compare>::value, void>> -multiset(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator()) - -> multiset<__iter_value_type<_InputIterator>, _Compare, _Allocator>; - -template<class _Key, class _Compare = less<_Key>, - class _Allocator = allocator<_Key>, - class = enable_if_t<__is_allocator<_Allocator>::value, void>, - class = enable_if_t<!__is_allocator<_Compare>::value, void>> -multiset(initializer_list<_Key>, _Compare = _Compare(), _Allocator = _Allocator()) - -> multiset<_Key, _Compare, _Allocator>; - -template<class _InputIterator, class _Allocator, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>, - class = enable_if_t<__is_allocator<_Allocator>::value, void>> -multiset(_InputIterator, _InputIterator, _Allocator) - -> multiset<__iter_value_type<_InputIterator>, - less<__iter_value_type<_InputIterator>>, _Allocator>; - -template<class _Key, class _Allocator, - class = enable_if_t<__is_allocator<_Allocator>::value, void>> -multiset(initializer_list<_Key>, _Allocator) - -> multiset<_Key, less<_Key>, _Allocator>; -#endif - -#ifndef _LIBCPP_CXX03_LANG - -template <class _Key, class _Compare, class _Allocator> -multiset<_Key, _Compare, _Allocator>::multiset(multiset&& __s, const allocator_type& __a) - : __tree_(_VSTD::move(__s.__tree_), __a) -{ - if (__a != __s.get_allocator()) - { - const_iterator __e = cend(); - while (!__s.empty()) - insert(__e, _VSTD::move(__s.__tree_.remove(__s.begin())->__value_)); - } -} - -#endif // _LIBCPP_CXX03_LANG - -template <class _Key, class _Compare, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator==(const multiset<_Key, _Compare, _Allocator>& __x, - const multiset<_Key, _Compare, _Allocator>& __y) -{ - return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin()); -} - -template <class _Key, class _Compare, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator< (const multiset<_Key, _Compare, _Allocator>& __x, - const multiset<_Key, _Compare, _Allocator>& __y) -{ - return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); -} - -template <class _Key, class _Compare, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator!=(const multiset<_Key, _Compare, _Allocator>& __x, - const multiset<_Key, _Compare, _Allocator>& __y) -{ - return !(__x == __y); -} - -template <class _Key, class _Compare, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator> (const multiset<_Key, _Compare, _Allocator>& __x, - const multiset<_Key, _Compare, _Allocator>& __y) -{ - return __y < __x; -} - -template <class _Key, class _Compare, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator>=(const multiset<_Key, _Compare, _Allocator>& __x, - const multiset<_Key, _Compare, _Allocator>& __y) -{ - return !(__x < __y); -} - -template <class _Key, class _Compare, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator<=(const multiset<_Key, _Compare, _Allocator>& __x, - const multiset<_Key, _Compare, _Allocator>& __y) -{ - return !(__y < __x); -} - -template <class _Key, class _Compare, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -void -swap(multiset<_Key, _Compare, _Allocator>& __x, - multiset<_Key, _Compare, _Allocator>& __y) - _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) -{ - __x.swap(__y); -} - -#if _LIBCPP_STD_VER > 17 -template <class _Key, class _Compare, class _Allocator, class _Predicate> -inline _LIBCPP_INLINE_VISIBILITY - typename multiset<_Key, _Compare, _Allocator>::size_type - erase_if(multiset<_Key, _Compare, _Allocator>& __c, _Predicate __pred) { - return _VSTD::__libcpp_erase_if_container(__c, __pred); -} -#endif - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP_SET diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/setjmp.h b/contrib/libs/cxxsupp/libcxxmsvc/include/setjmp.h deleted file mode 100644 index fca41aa31b..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/setjmp.h +++ /dev/null @@ -1,48 +0,0 @@ -// -*- 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_SETJMP_H -#define _LIBCPP_SETJMP_H - -/* - setjmp.h synopsis - -Macros: - - setjmp - -Types: - - jmp_buf - -void longjmp(jmp_buf env, int val); - -*/ - -#include <__config> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#ifdef _LIBCPP_COMPILER_MSVC -#include Y_MSVC_INCLUDE_NEXT(setjmp.h) -#else -#include_next <setjmp.h> -#endif - -#ifdef __cplusplus - -#ifndef setjmp -#define setjmp(env) setjmp(env) -#endif - -#endif // __cplusplus - -#endif // _LIBCPP_SETJMP_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/span b/contrib/libs/cxxsupp/libcxxmsvc/include/span deleted file mode 100644 index 0101dcb822..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/span +++ /dev/null @@ -1,658 +0,0 @@ -// -*- 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_SPAN -#define _LIBCPP_SPAN - -/* - span synopsis - -namespace std { - -// constants -inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max(); - -// [views.span], class template span -template <class ElementType, size_t Extent = dynamic_extent> - class span; - -template<class ElementType, size_t Extent> - inline constexpr bool ranges::enable_view<span<ElementType, Extent>> = true; - -template<class ElementType, size_t Extent> - inline constexpr bool ranges::enable_borrowed_range<span<ElementType, Extent>> = true; - -// [span.objectrep], views of object representation -template <class ElementType, size_t Extent> - span<const byte, ((Extent == dynamic_extent) ? dynamic_extent : - (sizeof(ElementType) * Extent))> as_bytes(span<ElementType, Extent> s) noexcept; - -template <class ElementType, size_t Extent> - span< byte, ((Extent == dynamic_extent) ? dynamic_extent : - (sizeof(ElementType) * Extent))> as_writable_bytes(span<ElementType, Extent> s) noexcept; - - -template <class ElementType, size_t Extent = dynamic_extent> -class span { -public: - // constants and types - using element_type = ElementType; - using value_type = remove_cv_t<ElementType>; - using size_type = size_t; - using difference_type = ptrdiff_t; - using pointer = element_type*; - using const_pointer = const element_type*; - using reference = element_type&; - using const_reference = const element_type&; - using iterator = implementation-defined; - using reverse_iterator = std::reverse_iterator<iterator>; - static constexpr size_type extent = Extent; - - // [span.cons], span constructors, copy, assignment, and destructor - constexpr span() noexcept; - template <class It> - constexpr explicit(Extent != dynamic_extent) span(It first, size_type count); - template <class It, class End> - constexpr explicit(Extent != dynamic_extent) span(It first, End last); - template <size_t N> - constexpr span(type_identity_t<element_type> (&arr)[N]) noexcept; - template <size_t N> - constexpr span(array<value_type, N>& arr) noexcept; - template <size_t N> - constexpr span(const array<value_type, N>& arr) noexcept; - template<class R> - constexpr explicit(Extent != dynamic_extent) span(R&& r); - constexpr span(const span& other) noexcept = default; - template <class OtherElementType, size_t OtherExtent> - constexpr explicit(Extent != dynamic_extent) span(const span<OtherElementType, OtherExtent>& s) noexcept; - ~span() noexcept = default; - constexpr span& operator=(const span& other) noexcept = default; - - // [span.sub], span subviews - template <size_t Count> - constexpr span<element_type, Count> first() const; - template <size_t Count> - constexpr span<element_type, Count> last() const; - template <size_t Offset, size_t Count = dynamic_extent> - constexpr span<element_type, see below> subspan() const; - - constexpr span<element_type, dynamic_extent> first(size_type count) const; - constexpr span<element_type, dynamic_extent> last(size_type count) const; - constexpr span<element_type, dynamic_extent> subspan(size_type offset, size_type count = dynamic_extent) const; - - // [span.obs], span observers - constexpr size_type size() const noexcept; - constexpr size_type size_bytes() const noexcept; - [[nodiscard]] constexpr bool empty() const noexcept; - - // [span.elem], span element access - constexpr reference operator[](size_type idx) const; - constexpr reference front() const; - constexpr reference back() const; - constexpr pointer data() const noexcept; - - // [span.iterators], span iterator support - constexpr iterator begin() const noexcept; - constexpr iterator end() const noexcept; - constexpr reverse_iterator rbegin() const noexcept; - constexpr reverse_iterator rend() const noexcept; - -private: - pointer data_; // exposition only - size_type size_; // exposition only -}; - -template<class It, class EndOrSize> - span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>; - -template<class T, size_t N> - span(T (&)[N]) -> span<T, N>; - -template<class T, size_t N> - span(array<T, N>&) -> span<T, N>; - -template<class T, size_t N> - span(const array<T, N>&) -> span<const T, N>; - -template<class R> - span(R&&) -> span<remove_reference_t<ranges::range_reference_t<R>>>; - -} // namespace std - -*/ - -#include <__assert> -#include <__config> -#include <__debug> -#include <__iterator/concepts.h> -#include <__iterator/wrap_iter.h> -#include <__ranges/concepts.h> -#include <__ranges/data.h> -#include <__ranges/enable_borrowed_range.h> -#include <__ranges/enable_view.h> -#include <__ranges/size.h> -#include <array> // for array -#include <cstddef> // for byte -#include <iterator> // for iterators -#include <limits> -#include <type_traits> // for remove_cv, etc -#include <version> - -#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<size_t>::max(); -template <typename _Tp, size_t _Extent = dynamic_extent> class span; - - -template <class _Tp> -struct __is_std_array : false_type {}; - -template <class _Tp, size_t _Sz> -struct __is_std_array<array<_Tp, _Sz>> : true_type {}; - -template <class _Tp> -struct __is_std_span : false_type {}; - -template <class _Tp, size_t _Sz> -struct __is_std_span<span<_Tp, _Sz>> : true_type {}; - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) -template <class _Range, class _ElementType> -concept __span_compatible_range = - ranges::contiguous_range<_Range> && - ranges::sized_range<_Range> && - (ranges::borrowed_range<_Range> || is_const_v<_ElementType>) && - !__is_std_span<remove_cvref_t<_Range>>::value && - !__is_std_array<remove_cvref_t<_Range>>::value && - !is_array_v<remove_cvref_t<_Range>> && - is_convertible_v<remove_reference_t<ranges::range_reference_t<_Range>>(*)[], _ElementType(*)[]>; -#else -template <class _Tp, class _ElementType, class = void> -struct __is_span_compatible_container : public false_type {}; - -template <class _Tp, class _ElementType> -struct __is_span_compatible_container<_Tp, _ElementType, - void_t< - // is not a specialization of span - enable_if_t<!__is_std_span<_Tp>::value, nullptr_t>, - // is not a specialization of array - enable_if_t<!__is_std_array<_Tp>::value, nullptr_t>, - // is_array_v<Container> is false, - enable_if_t<!is_array_v<_Tp>, nullptr_t>, - // data(cont) and size(cont) are well formed - decltype(data(declval<_Tp>())), - decltype(size(declval<_Tp>())), - // remove_pointer_t<decltype(data(cont))>(*)[] is convertible to ElementType(*)[] - enable_if_t< - is_convertible_v<remove_pointer_t<decltype(data(declval<_Tp &>()))>(*)[], - _ElementType(*)[]>, - nullptr_t> - >> - : public true_type {}; -#endif - -template <typename _Tp, size_t _Extent> -class _LIBCPP_TEMPLATE_VIS span { -public: -// constants and types - using element_type = _Tp; - using value_type = remove_cv_t<_Tp>; - using size_type = size_t; - using difference_type = ptrdiff_t; - using pointer = _Tp *; - using const_pointer = const _Tp *; - using reference = _Tp &; - using const_reference = const _Tp &; -#if (_LIBCPP_DEBUG_LEVEL == 2) || defined(_LIBCPP_ABI_SPAN_POINTER_ITERATORS) - using iterator = pointer; -#else - using iterator = __wrap_iter<pointer>; -#endif - using reverse_iterator = _VSTD::reverse_iterator<iterator>; - - static constexpr size_type extent = _Extent; - -// [span.cons], span constructors, copy, assignment, and destructor - template <size_t _Sz = _Extent, enable_if_t<_Sz == 0, nullptr_t> = nullptr> - _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr} {} - - constexpr span (const span&) noexcept = default; - constexpr span& operator=(const span&) noexcept = default; - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) - template <class _It, - enable_if_t<contiguous_iterator<_It> && - is_convertible_v<remove_reference_t<iter_reference_t<_It>>(*)[], element_type (*)[]>, - nullptr_t> = nullptr> - _LIBCPP_INLINE_VISIBILITY - constexpr explicit span(_It __first, size_type __count) - : __data{_VSTD::to_address(__first)} { - (void)__count; - _LIBCPP_ASSERT(_Extent == __count, "size mismatch in span's constructor (iterator, len)"); - } - - template < - class _It, class _End, - enable_if_t<is_convertible_v<remove_reference_t<iter_reference_t<_It> > (*)[], element_type (*)[]> && - contiguous_iterator<_It> && sized_sentinel_for<_End, _It> && !is_convertible_v<_End, size_t>, - nullptr_t> = nullptr> - _LIBCPP_INLINE_VISIBILITY - constexpr explicit span(_It __first, _End __last) : __data{_VSTD::to_address(__first)} { - (void)__last; - _LIBCPP_ASSERT((__last - __first >= 0), "invalid range in span's constructor (iterator, sentinel)"); - _LIBCPP_ASSERT(__last - __first == _Extent, - "invalid range in span's constructor (iterator, sentinel): last - first != extent"); - } -#else - _LIBCPP_INLINE_VISIBILITY constexpr explicit span(pointer __ptr, size_type __count) : __data{__ptr} - { (void)__count; _LIBCPP_ASSERT(_Extent == __count, "size mismatch in span's constructor (ptr, len)"); } - _LIBCPP_INLINE_VISIBILITY constexpr explicit span(pointer __f, pointer __l) : __data{__f} - { (void)__l; _LIBCPP_ASSERT(_Extent == distance(__f, __l), "size mismatch in span's constructor (ptr, ptr)"); } -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) - - _LIBCPP_INLINE_VISIBILITY constexpr span(type_identity_t<element_type> (&__arr)[_Extent]) noexcept : __data{__arr} {} - - template <class _OtherElementType, - enable_if_t<is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr> - _LIBCPP_INLINE_VISIBILITY - constexpr span(array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {} - - template <class _OtherElementType, - enable_if_t<is_convertible_v<const _OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr> - _LIBCPP_INLINE_VISIBILITY - constexpr span(const array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {} - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - template <__span_compatible_range<element_type> _Range> - _LIBCPP_INLINE_VISIBILITY - constexpr explicit span(_Range&& __r) : __data{ranges::data(__r)} { - _LIBCPP_ASSERT(ranges::size(__r) == _Extent, "size mismatch in span's constructor (range)"); - } -#else - template <class _Container> - _LIBCPP_INLINE_VISIBILITY - constexpr explicit span( _Container& __c, - enable_if_t<__is_span_compatible_container<_Container, _Tp>::value, nullptr_t> = nullptr) - : __data{_VSTD::data(__c)} { - _LIBCPP_ASSERT(_Extent == _VSTD::size(__c), "size mismatch in span's constructor (range)"); - } - - template <class _Container> - _LIBCPP_INLINE_VISIBILITY - constexpr explicit span(const _Container& __c, - enable_if_t<__is_span_compatible_container<const _Container, _Tp>::value, nullptr_t> = nullptr) - : __data{_VSTD::data(__c)} { - _LIBCPP_ASSERT(_Extent == _VSTD::size(__c), "size mismatch in span's constructor (range)"); - } -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - - template <class _OtherElementType> - _LIBCPP_INLINE_VISIBILITY - constexpr span(const span<_OtherElementType, _Extent>& __other, - enable_if_t< - is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, - nullptr_t> = nullptr) - : __data{__other.data()} {} - - template <class _OtherElementType> - _LIBCPP_INLINE_VISIBILITY - constexpr explicit span(const span<_OtherElementType, dynamic_extent>& __other, - enable_if_t< - is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, - nullptr_t> = nullptr) noexcept - : __data{__other.data()} { _LIBCPP_ASSERT(_Extent == __other.size(), "size mismatch in span's constructor (other span)"); } - - -// ~span() noexcept = default; - - template <size_t _Count> - _LIBCPP_INLINE_VISIBILITY - constexpr span<element_type, _Count> first() const noexcept - { - static_assert(_Count <= _Extent, "Count out of range in span::first()"); - return span<element_type, _Count>{data(), _Count}; - } - - template <size_t _Count> - _LIBCPP_INLINE_VISIBILITY - constexpr span<element_type, _Count> last() const noexcept - { - static_assert(_Count <= _Extent, "Count out of range in span::last()"); - return span<element_type, _Count>{data() + size() - _Count, _Count}; - } - - _LIBCPP_INLINE_VISIBILITY - constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept - { - _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::first(count)"); - return {data(), __count}; - } - - _LIBCPP_INLINE_VISIBILITY - constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept - { - _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::last(count)"); - return {data() + size() - __count, __count}; - } - - template <size_t _Offset, size_t _Count = dynamic_extent> - _LIBCPP_INLINE_VISIBILITY - constexpr auto subspan() const noexcept - -> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset> - { - static_assert(_Offset <= _Extent, "Offset out of range in span::subspan()"); - static_assert(_Count == dynamic_extent || _Count <= _Extent - _Offset, "Offset + count out of range in span::subspan()"); - - using _ReturnType = span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset>; - return _ReturnType{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; - } - - - _LIBCPP_INLINE_VISIBILITY - constexpr span<element_type, dynamic_extent> - subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept - { - _LIBCPP_ASSERT(__offset <= size(), "Offset out of range in span::subspan(offset, count)"); - _LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "Count out of range in span::subspan(offset, count)"); - if (__count == dynamic_extent) - return {data() + __offset, size() - __offset}; - _LIBCPP_ASSERT(__count <= size() - __offset, "Offset + count out of range in span::subspan(offset, count)"); - return {data() + __offset, __count}; - } - - _LIBCPP_INLINE_VISIBILITY constexpr size_type size() const noexcept { return _Extent; } - _LIBCPP_INLINE_VISIBILITY constexpr size_type size_bytes() const noexcept { return _Extent * sizeof(element_type); } - [[nodiscard]] _LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return _Extent == 0; } - - _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept - { - _LIBCPP_ASSERT(__idx < size(), "span<T,N>[] index out of bounds"); - return __data[__idx]; - } - - _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept - { - _LIBCPP_ASSERT(!empty(), "span<T, N>::front() on empty span"); - return __data[0]; - } - - _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept - { - _LIBCPP_ASSERT(!empty(), "span<T, N>::back() on empty span"); - return __data[size()-1]; - } - - _LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; } - -// [span.iter], span iterator support - _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); } - _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); } - _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } - _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } - - _LIBCPP_INLINE_VISIBILITY span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept - { return span<const byte, _Extent * sizeof(element_type)>{reinterpret_cast<const byte *>(data()), size_bytes()}; } - - _LIBCPP_INLINE_VISIBILITY span<byte, _Extent * sizeof(element_type)> __as_writable_bytes() const noexcept - { return span<byte, _Extent * sizeof(element_type)>{reinterpret_cast<byte *>(data()), size_bytes()}; } - -private: - pointer __data; - -}; - - -template <typename _Tp> -class _LIBCPP_TEMPLATE_VIS span<_Tp, dynamic_extent> { -private: - -public: -// constants and types - using element_type = _Tp; - using value_type = remove_cv_t<_Tp>; - using size_type = size_t; - using difference_type = ptrdiff_t; - using pointer = _Tp *; - using const_pointer = const _Tp *; - using reference = _Tp &; - using const_reference = const _Tp &; -#if (_LIBCPP_DEBUG_LEVEL == 2) || defined(_LIBCPP_ABI_SPAN_POINTER_ITERATORS) - using iterator = pointer; -#else - using iterator = __wrap_iter<pointer>; -#endif - using reverse_iterator = _VSTD::reverse_iterator<iterator>; - - static constexpr size_type extent = dynamic_extent; - -// [span.cons], span constructors, copy, assignment, and destructor - _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr}, __size{0} {} - - constexpr span (const span&) noexcept = default; - constexpr span& operator=(const span&) noexcept = default; - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) - template <class _It, - enable_if_t<contiguous_iterator<_It> && - is_convertible_v<remove_reference_t<iter_reference_t<_It> > (*)[], element_type (*)[]>, - nullptr_t> = nullptr> - _LIBCPP_INLINE_VISIBILITY - constexpr span(_It __first, size_type __count) - : __data{_VSTD::to_address(__first)}, __size{__count} {} - - template < - class _It, class _End, - enable_if_t<is_convertible_v<remove_reference_t<iter_reference_t<_It> > (*)[], element_type (*)[]> && - contiguous_iterator<_It> && sized_sentinel_for<_End, _It> && !is_convertible_v<_End, size_t>, - nullptr_t> = nullptr> - _LIBCPP_INLINE_VISIBILITY - constexpr span(_It __first, _End __last) - : __data(_VSTD::to_address(__first)), __size(__last - __first) {} -#else - _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __ptr, size_type __count) : __data{__ptr}, __size{__count} {} - _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l) : __data{__f}, __size{static_cast<size_t>(distance(__f, __l))} {} -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) - - template <size_t _Sz> - _LIBCPP_INLINE_VISIBILITY - constexpr span(type_identity_t<element_type> (&__arr)[_Sz]) noexcept : __data{__arr}, __size{_Sz} {} - - template <class _OtherElementType, size_t _Sz, - enable_if_t<is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr> - _LIBCPP_INLINE_VISIBILITY - constexpr span(array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} - - template <class _OtherElementType, size_t _Sz, - enable_if_t<is_convertible_v<const _OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr> - _LIBCPP_INLINE_VISIBILITY - constexpr span(const array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - template <__span_compatible_range<element_type> _Range> - _LIBCPP_INLINE_VISIBILITY - constexpr span(_Range&& __r) : __data(ranges::data(__r)), __size{ranges::size(__r)} {} -#else - template <class _Container> - _LIBCPP_INLINE_VISIBILITY - constexpr span( _Container& __c, - enable_if_t<__is_span_compatible_container<_Container, _Tp>::value, nullptr_t> = nullptr) - : __data{_VSTD::data(__c)}, __size{(size_type) _VSTD::size(__c)} {} - - template <class _Container> - _LIBCPP_INLINE_VISIBILITY - constexpr span(const _Container& __c, - enable_if_t<__is_span_compatible_container<const _Container, _Tp>::value, nullptr_t> = nullptr) - : __data{_VSTD::data(__c)}, __size{(size_type) _VSTD::size(__c)} {} -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - - template <class _OtherElementType, size_t _OtherExtent> - _LIBCPP_INLINE_VISIBILITY - constexpr span(const span<_OtherElementType, _OtherExtent>& __other, - enable_if_t< - is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, - nullptr_t> = nullptr) noexcept - : __data{__other.data()}, __size{__other.size()} {} - -// ~span() noexcept = default; - - template <size_t _Count> - _LIBCPP_INLINE_VISIBILITY - constexpr span<element_type, _Count> first() const noexcept - { - _LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::first()"); - return span<element_type, _Count>{data(), _Count}; - } - - template <size_t _Count> - _LIBCPP_INLINE_VISIBILITY - constexpr span<element_type, _Count> last() const noexcept - { - _LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::last()"); - return span<element_type, _Count>{data() + size() - _Count, _Count}; - } - - _LIBCPP_INLINE_VISIBILITY - constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept - { - _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::first(count)"); - return {data(), __count}; - } - - _LIBCPP_INLINE_VISIBILITY - constexpr span<element_type, dynamic_extent> last (size_type __count) const noexcept - { - _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::last(count)"); - return {data() + size() - __count, __count}; - } - - template <size_t _Offset, size_t _Count = dynamic_extent> - _LIBCPP_INLINE_VISIBILITY - constexpr span<element_type, _Count> subspan() const noexcept - { - _LIBCPP_ASSERT(_Offset <= size(), "Offset out of range in span::subspan()"); - _LIBCPP_ASSERT(_Count == dynamic_extent || _Count <= size() - _Offset, "Offset + count out of range in span::subspan()"); - return span<element_type, _Count>{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; - } - - constexpr span<element_type, dynamic_extent> - _LIBCPP_INLINE_VISIBILITY - subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept - { - _LIBCPP_ASSERT(__offset <= size(), "Offset out of range in span::subspan(offset, count)"); - _LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "count out of range in span::subspan(offset, count)"); - if (__count == dynamic_extent) - return {data() + __offset, size() - __offset}; - _LIBCPP_ASSERT(__count <= size() - __offset, "Offset + count out of range in span::subspan(offset, count)"); - return {data() + __offset, __count}; - } - - _LIBCPP_INLINE_VISIBILITY constexpr size_type size() const noexcept { return __size; } - _LIBCPP_INLINE_VISIBILITY constexpr size_type size_bytes() const noexcept { return __size * sizeof(element_type); } - [[nodiscard]] _LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return __size == 0; } - - _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept - { - _LIBCPP_ASSERT(__idx < size(), "span<T>[] index out of bounds"); - return __data[__idx]; - } - - _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept - { - _LIBCPP_ASSERT(!empty(), "span<T>[].front() on empty span"); - return __data[0]; - } - - _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept - { - _LIBCPP_ASSERT(!empty(), "span<T>[].back() on empty span"); - return __data[size()-1]; - } - - - _LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; } - -// [span.iter], span iterator support - _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); } - _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); } - _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } - _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } - - inline _LIBCPP_INLINE_VISIBILITY span<const byte, dynamic_extent> __as_bytes() const noexcept; - - inline _LIBCPP_INLINE_VISIBILITY span<byte, dynamic_extent> __as_writable_bytes() const noexcept; - -private: - pointer __data; - size_type __size; -}; - -template<typename _Tp> -inline _LIBCPP_INLINE_VISIBILITY span<const byte, dynamic_extent> span<_Tp, dynamic_extent>::__as_bytes() const noexcept -{ return {reinterpret_cast<const byte *>(data()), size_bytes()}; } - -template<typename _Tp> -inline _LIBCPP_INLINE_VISIBILITY span<byte, dynamic_extent> span<_Tp, dynamic_extent>::__as_writable_bytes() const noexcept -{ return {reinterpret_cast<byte *>(data()), size_bytes()}; } - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) -template <class _Tp, size_t _Extent> -inline constexpr bool ranges::enable_borrowed_range<span<_Tp, _Extent> > = true; - -template <class _ElementType, size_t _Extent> -inline constexpr bool ranges::enable_view<span<_ElementType, _Extent>> = true; -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) - -// as_bytes & as_writable_bytes -template <class _Tp, size_t _Extent> -_LIBCPP_INLINE_VISIBILITY -auto as_bytes(span<_Tp, _Extent> __s) noexcept --> decltype(__s.__as_bytes()) -{ return __s.__as_bytes(); } - -template <class _Tp, size_t _Extent> -_LIBCPP_INLINE_VISIBILITY -auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept --> enable_if_t<!is_const_v<_Tp>, decltype(__s.__as_writable_bytes())> -{ return __s.__as_writable_bytes(); } - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) -template<contiguous_iterator _It, class _EndOrSize> - span(_It, _EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>; -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) - -template<class _Tp, size_t _Sz> - span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>; - -template<class _Tp, size_t _Sz> - span(array<_Tp, _Sz>&) -> span<_Tp, _Sz>; - -template<class _Tp, size_t _Sz> - span(const array<_Tp, _Sz>&) -> span<const _Tp, _Sz>; - -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) -template<ranges::contiguous_range _Range> - span(_Range&&) -> span<remove_reference_t<ranges::range_reference_t<_Range>>>; -#endif - -#endif // _LIBCPP_STD_VER > 17 - -_LIBCPP_END_NAMESPACE_STD - -_LIBCPP_POP_MACROS - -#endif // _LIBCPP_SPAN diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/stdatomic.h b/contrib/libs/cxxsupp/libcxxmsvc/include/stdatomic.h deleted file mode 100644 index d9550c4406..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/stdatomic.h +++ /dev/null @@ -1,235 +0,0 @@ -// -*- 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_STDATOMIC_H -#define _LIBCPP_STDATOMIC_H - -/* - stdatomic.h synopsis - -template<class T> - using std-atomic = std::atomic<T>; // exposition only - -#define _Atomic(T) std-atomic<T> - -#define ATOMIC_BOOL_LOCK_FREE see below -#define ATOMIC_CHAR_LOCK_FREE see below -#define ATOMIC_CHAR16_T_LOCK_FREE see below -#define ATOMIC_CHAR32_T_LOCK_FREE see below -#define ATOMIC_WCHAR_T_LOCK_FREE see below -#define ATOMIC_SHORT_LOCK_FREE see below -#define ATOMIC_INT_LOCK_FREE see below -#define ATOMIC_LONG_LOCK_FREE see below -#define ATOMIC_LLONG_LOCK_FREE see below -#define ATOMIC_POINTER_LOCK_FREE see below - -using std::memory_order // see below -using std::memory_order_relaxed // see below -using std::memory_order_consume // see below -using std::memory_order_acquire // see below -using std::memory_order_release // see below -using std::memory_order_acq_rel // see below -using std::memory_order_seq_cst // see below - -using std::atomic_flag // see below - -using std::atomic_bool // see below -using std::atomic_char // see below -using std::atomic_schar // see below -using std::atomic_uchar // see below -using std::atomic_short // see below -using std::atomic_ushort // see below -using std::atomic_int // see below -using std::atomic_uint // see below -using std::atomic_long // see below -using std::atomic_ulong // see below -using std::atomic_llong // see below -using std::atomic_ullong // see below -using std::atomic_char8_t // see below -using std::atomic_char16_t // see below -using std::atomic_char32_t // see below -using std::atomic_wchar_t // see below -using std::atomic_int8_t // see below -using std::atomic_uint8_t // see below -using std::atomic_int16_t // see below -using std::atomic_uint16_t // see below -using std::atomic_int32_t // see below -using std::atomic_uint32_t // see below -using std::atomic_int64_t // see below -using std::atomic_uint64_t // see below -using std::atomic_int_least8_t // see below -using std::atomic_uint_least8_t // see below -using std::atomic_int_least16_t // see below -using std::atomic_uint_least16_t // see below -using std::atomic_int_least32_t // see below -using std::atomic_uint_least32_t // see below -using std::atomic_int_least64_t // see below -using std::atomic_uint_least64_t // see below -using std::atomic_int_fast8_t // see below -using std::atomic_uint_fast8_t // see below -using std::atomic_int_fast16_t // see below -using std::atomic_uint_fast16_t // see below -using std::atomic_int_fast32_t // see below -using std::atomic_uint_fast32_t // see below -using std::atomic_int_fast64_t // see below -using std::atomic_uint_fast64_t // see below -using std::atomic_intptr_t // see below -using std::atomic_uintptr_t // see below -using std::atomic_size_t // see below -using std::atomic_ptrdiff_t // see below -using std::atomic_intmax_t // see below -using std::atomic_uintmax_t // see below - -using std::atomic_is_lock_free // see below -using std::atomic_load // see below -using std::atomic_load_explicit // see below -using std::atomic_store // see below -using std::atomic_store_explicit // see below -using std::atomic_exchange // see below -using std::atomic_exchange_explicit // see below -using std::atomic_compare_exchange_strong // see below -using std::atomic_compare_exchange_strong_explicit // see below -using std::atomic_compare_exchange_weak // see below -using std::atomic_compare_exchange_weak_explicit // see below -using std::atomic_fetch_add // see below -using std::atomic_fetch_add_explicit // see below -using std::atomic_fetch_sub // see below -using std::atomic_fetch_sub_explicit // see below -using std::atomic_fetch_or // see below -using std::atomic_fetch_or_explicit // see below -using std::atomic_fetch_and // see below -using std::atomic_fetch_and_explicit // see below -using std::atomic_flag_test_and_set // see below -using std::atomic_flag_test_and_set_explicit // see below -using std::atomic_flag_clear // see below -using std::atomic_flag_clear_explicit // see below - -using std::atomic_thread_fence // see below -using std::atomic_signal_fence // see below - -*/ - -#include <__config> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#if _LIBCPP_STD_VER > 20 - -#include <atomic> -#include <version> - -#ifdef _Atomic -# undef _Atomic -#endif - -#define _Atomic(_Tp) ::std::atomic<_Tp> - -using std::memory_order _LIBCPP_USING_IF_EXISTS; -using std::memory_order_relaxed _LIBCPP_USING_IF_EXISTS; -using std::memory_order_consume _LIBCPP_USING_IF_EXISTS; -using std::memory_order_acquire _LIBCPP_USING_IF_EXISTS; -using std::memory_order_release _LIBCPP_USING_IF_EXISTS; -using std::memory_order_acq_rel _LIBCPP_USING_IF_EXISTS; -using std::memory_order_seq_cst _LIBCPP_USING_IF_EXISTS; - -using std::atomic_flag _LIBCPP_USING_IF_EXISTS; - -using std::atomic_bool _LIBCPP_USING_IF_EXISTS; -using std::atomic_char _LIBCPP_USING_IF_EXISTS; -using std::atomic_schar _LIBCPP_USING_IF_EXISTS; -using std::atomic_uchar _LIBCPP_USING_IF_EXISTS; -using std::atomic_short _LIBCPP_USING_IF_EXISTS; -using std::atomic_ushort _LIBCPP_USING_IF_EXISTS; -using std::atomic_int _LIBCPP_USING_IF_EXISTS; -using std::atomic_uint _LIBCPP_USING_IF_EXISTS; -using std::atomic_long _LIBCPP_USING_IF_EXISTS; -using std::atomic_ulong _LIBCPP_USING_IF_EXISTS; -using std::atomic_llong _LIBCPP_USING_IF_EXISTS; -using std::atomic_ullong _LIBCPP_USING_IF_EXISTS; -using std::atomic_char8_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_char16_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_char32_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_wchar_t _LIBCPP_USING_IF_EXISTS; - -using std::atomic_int8_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_uint8_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_int16_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_uint16_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_int32_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_uint32_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_int64_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_uint64_t _LIBCPP_USING_IF_EXISTS; - -using std::atomic_int_least8_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_uint_least8_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_int_least16_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_uint_least16_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_int_least32_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_uint_least32_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_int_least64_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_uint_least64_t _LIBCPP_USING_IF_EXISTS; - -using std::atomic_int_fast8_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_uint_fast8_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_int_fast16_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_uint_fast16_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_int_fast32_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_uint_fast32_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_int_fast64_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_uint_fast64_t _LIBCPP_USING_IF_EXISTS; - -using std::atomic_intptr_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_uintptr_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_size_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_ptrdiff_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_intmax_t _LIBCPP_USING_IF_EXISTS; -using std::atomic_uintmax_t _LIBCPP_USING_IF_EXISTS; - -using std::atomic_compare_exchange_strong _LIBCPP_USING_IF_EXISTS; -using std::atomic_compare_exchange_strong_explicit _LIBCPP_USING_IF_EXISTS; -using std::atomic_compare_exchange_weak _LIBCPP_USING_IF_EXISTS; -using std::atomic_compare_exchange_weak_explicit _LIBCPP_USING_IF_EXISTS; -using std::atomic_exchange _LIBCPP_USING_IF_EXISTS; -using std::atomic_exchange_explicit _LIBCPP_USING_IF_EXISTS; -using std::atomic_fetch_add _LIBCPP_USING_IF_EXISTS; -using std::atomic_fetch_add_explicit _LIBCPP_USING_IF_EXISTS; -using std::atomic_fetch_and _LIBCPP_USING_IF_EXISTS; -using std::atomic_fetch_and_explicit _LIBCPP_USING_IF_EXISTS; -using std::atomic_fetch_or _LIBCPP_USING_IF_EXISTS; -using std::atomic_fetch_or_explicit _LIBCPP_USING_IF_EXISTS; -using std::atomic_fetch_sub _LIBCPP_USING_IF_EXISTS; -using std::atomic_fetch_sub_explicit _LIBCPP_USING_IF_EXISTS; -using std::atomic_flag_clear _LIBCPP_USING_IF_EXISTS; -using std::atomic_flag_clear_explicit _LIBCPP_USING_IF_EXISTS; -using std::atomic_flag_test_and_set _LIBCPP_USING_IF_EXISTS; -using std::atomic_flag_test_and_set_explicit _LIBCPP_USING_IF_EXISTS; -using std::atomic_is_lock_free _LIBCPP_USING_IF_EXISTS; -using std::atomic_load _LIBCPP_USING_IF_EXISTS; -using std::atomic_load_explicit _LIBCPP_USING_IF_EXISTS; -using std::atomic_store _LIBCPP_USING_IF_EXISTS; -using std::atomic_store_explicit _LIBCPP_USING_IF_EXISTS; - -using std::atomic_signal_fence _LIBCPP_USING_IF_EXISTS; -using std::atomic_thread_fence _LIBCPP_USING_IF_EXISTS; - -#elif defined(_LIBCPP_COMPILER_CLANG_BASED) - -// Before C++23, we include the next <stdatomic.h> on the path to avoid hijacking -// the header. We do this because Clang has historically shipped a <stdatomic.h> -// header that would be available in all Standard modes, and we don't want to -// break that use case. -# if __has_include_next(<stdatomic.h>) -# include_next <stdatomic.h> -# endif - -#endif // _LIBCPP_STD_VER > 20 - -#endif // _LIBCPP_STDATOMIC_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/stdbool.h b/contrib/libs/cxxsupp/libcxxmsvc/include/stdbool.h deleted file mode 100644 index c596f2441c..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/stdbool.h +++ /dev/null @@ -1,42 +0,0 @@ -// -*- 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_STDBOOL_H -#define _LIBCPP_STDBOOL_H - - -/* - stdbool.h synopsis - -Macros: - - __bool_true_false_are_defined - -*/ - -#include <__config> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#ifdef _LIBCPP_COMPILER_MSVC -#include Y_MSVC_INCLUDE_NEXT(stdbool.h) -#else -#include_next <stdbool.h> -#endif - -#ifdef __cplusplus -#undef bool -#undef true -#undef false -#undef __bool_true_false_are_defined -#define __bool_true_false_are_defined 1 -#endif - -#endif // _LIBCPP_STDBOOL_H diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/stlfwd b/contrib/libs/cxxsupp/libcxxmsvc/include/stlfwd index adad6790dc..235ae7f0e2 100644 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/stlfwd +++ b/contrib/libs/cxxsupp/libcxxmsvc/include/stlfwd @@ -61,3 +61,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + + class path; + +_LIBCPP_END_NAMESPACE_FILESYSTEM diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/typeindex b/contrib/libs/cxxsupp/libcxxmsvc/include/typeindex deleted file mode 100644 index b5dcd8496a..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/typeindex +++ /dev/null @@ -1,115 +0,0 @@ -// -*- 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_TYPEINDEX -#define _LIBCPP_TYPEINDEX - -/* - - typeindex synopsis - -namespace std -{ - -class type_index -{ -public: - type_index(const type_info& rhs) noexcept; - - bool operator==(const type_index& rhs) const noexcept; - bool operator!=(const type_index& rhs) const noexcept; - bool operator< (const type_index& rhs) const noexcept; - bool operator<=(const type_index& rhs) const noexcept; - bool operator> (const type_index& rhs) const noexcept; - bool operator>=(const type_index& rhs) const noexcept; - - size_t hash_code() const noexcept; - const char* name() const noexcept; -}; - -template <> -struct hash<type_index> - : public unary_function<type_index, size_t> -{ - size_t operator()(type_index index) const noexcept; -}; - -} // std - -*/ - -#include <__config> -#include <__functional/unary_function.h> -#include <compare> -#include <typeinfo> -#include <version> - -// TODO: remove these headers -#include <__functional/binary_function.h> -#include <__functional/invoke.h> -#include <__functional/operations.h> -#include <__functional/reference_wrapper.h> -#include <__functional/weak_result_type.h> -#include <__memory/allocator_arg_t.h> -#include <__memory/uses_allocator.h> -#include <new> -#include <utility> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -class _LIBCPP_TEMPLATE_VIS type_index -{ - const type_info* __t_; -public: - _LIBCPP_INLINE_VISIBILITY - type_index(const type_info& __y) _NOEXCEPT : __t_(&__y) {} - - _LIBCPP_INLINE_VISIBILITY - bool operator==(const type_index& __y) const _NOEXCEPT - {return *__t_ == *__y.__t_;} - _LIBCPP_INLINE_VISIBILITY - bool operator!=(const type_index& __y) const _NOEXCEPT - {return *__t_ != *__y.__t_;} - _LIBCPP_INLINE_VISIBILITY - bool operator< (const type_index& __y) const _NOEXCEPT - {return __t_->before(*__y.__t_);} - _LIBCPP_INLINE_VISIBILITY - bool operator<=(const type_index& __y) const _NOEXCEPT - {return !__y.__t_->before(*__t_);} - _LIBCPP_INLINE_VISIBILITY - bool operator> (const type_index& __y) const _NOEXCEPT - {return __y.__t_->before(*__t_);} - _LIBCPP_INLINE_VISIBILITY - bool operator>=(const type_index& __y) const _NOEXCEPT - {return !__t_->before(*__y.__t_);} - - _LIBCPP_INLINE_VISIBILITY - size_t hash_code() const _NOEXCEPT {return __t_->hash_code();} - _LIBCPP_INLINE_VISIBILITY - const char* name() const _NOEXCEPT {return __t_->name();} -}; - -template <class _Tp> struct _LIBCPP_TEMPLATE_VIS hash; - -template <> -struct _LIBCPP_TEMPLATE_VIS hash<type_index> - : public unary_function<type_index, size_t> -{ - _LIBCPP_INLINE_VISIBILITY - size_t operator()(type_index __index) const _NOEXCEPT - {return __index.hash_code();} -}; - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP_TYPEINDEX diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/unordered_map b/contrib/libs/cxxsupp/libcxxmsvc/include/unordered_map deleted file mode 100644 index c854548950..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/unordered_map +++ /dev/null @@ -1,2619 +0,0 @@ -// -*- 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_UNORDERED_MAP -#define _LIBCPP_UNORDERED_MAP - -/* - - unordered_map synopsis - -#include <initializer_list> - -namespace std -{ - -template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, - class Alloc = allocator<pair<const Key, T>>> -class unordered_map -{ -public: - // types - typedef Key key_type; - typedef T mapped_type; - typedef Hash hasher; - typedef Pred key_equal; - typedef Alloc allocator_type; - typedef pair<const key_type, mapped_type> value_type; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef typename allocator_traits<allocator_type>::pointer pointer; - typedef typename allocator_traits<allocator_type>::const_pointer const_pointer; - typedef typename allocator_traits<allocator_type>::size_type size_type; - typedef typename allocator_traits<allocator_type>::difference_type difference_type; - - typedef /unspecified/ iterator; - typedef /unspecified/ const_iterator; - typedef /unspecified/ local_iterator; - typedef /unspecified/ const_local_iterator; - - typedef unspecified node_type; // C++17 - typedef INSERT_RETURN_TYPE<iterator, node_type> insert_return_type; // C++17 - - unordered_map() - noexcept( - is_nothrow_default_constructible<hasher>::value && - is_nothrow_default_constructible<key_equal>::value && - is_nothrow_default_constructible<allocator_type>::value); - explicit unordered_map(size_type n, const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - template <class InputIterator> - unordered_map(InputIterator f, InputIterator l, - size_type n = 0, const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - explicit unordered_map(const allocator_type&); - unordered_map(const unordered_map&); - unordered_map(const unordered_map&, const Allocator&); - unordered_map(unordered_map&&) - noexcept( - is_nothrow_move_constructible<hasher>::value && - is_nothrow_move_constructible<key_equal>::value && - is_nothrow_move_constructible<allocator_type>::value); - unordered_map(unordered_map&&, const Allocator&); - unordered_map(initializer_list<value_type>, size_type n = 0, - const hasher& hf = hasher(), const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - unordered_map(size_type n, const allocator_type& a) - : unordered_map(n, hasher(), key_equal(), a) {} // C++14 - unordered_map(size_type n, const hasher& hf, const allocator_type& a) - : unordered_map(n, hf, key_equal(), a) {} // C++14 - template <class InputIterator> - unordered_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a) - : unordered_map(f, l, n, hasher(), key_equal(), a) {} // C++14 - template <class InputIterator> - unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, - const allocator_type& a) - : unordered_map(f, l, n, hf, key_equal(), a) {} // C++14 - unordered_map(initializer_list<value_type> il, size_type n, const allocator_type& a) - : unordered_map(il, n, hasher(), key_equal(), a) {} // C++14 - unordered_map(initializer_list<value_type> il, size_type n, const hasher& hf, - const allocator_type& a) - : unordered_map(il, n, hf, key_equal(), a) {} // C++14 - ~unordered_map(); - unordered_map& operator=(const unordered_map&); - unordered_map& operator=(unordered_map&&) - noexcept( - allocator_type::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<allocator_type>::value && - is_nothrow_move_assignable<hasher>::value && - is_nothrow_move_assignable<key_equal>::value); - unordered_map& operator=(initializer_list<value_type>); - - allocator_type get_allocator() const noexcept; - - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; - - iterator begin() noexcept; - iterator end() noexcept; - const_iterator begin() const noexcept; - const_iterator end() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - - template <class... Args> - pair<iterator, bool> emplace(Args&&... args); - template <class... Args> - iterator emplace_hint(const_iterator position, Args&&... args); - pair<iterator, bool> insert(const value_type& obj); - template <class P> - pair<iterator, bool> insert(P&& obj); - iterator insert(const_iterator hint, const value_type& obj); - template <class P> - iterator insert(const_iterator hint, P&& obj); - template <class InputIterator> - void insert(InputIterator first, InputIterator last); - void insert(initializer_list<value_type>); - - node_type extract(const_iterator position); // C++17 - node_type extract(const key_type& x); // C++17 - insert_return_type insert(node_type&& nh); // C++17 - iterator insert(const_iterator hint, node_type&& nh); // C++17 - - template <class... Args> - pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); // C++17 - template <class... Args> - pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); // C++17 - template <class... Args> - iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17 - template <class... Args> - iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); // C++17 - template <class M> - pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); // C++17 - template <class M> - pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); // C++17 - template <class M> - iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); // C++17 - template <class M> - iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); // C++17 - - iterator erase(const_iterator position); - iterator erase(iterator position); // C++14 - size_type erase(const key_type& k); - iterator erase(const_iterator first, const_iterator last); - void clear() noexcept; - - template<class H2, class P2> - void merge(unordered_map<Key, T, H2, P2, Allocator>& source); // C++17 - template<class H2, class P2> - void merge(unordered_map<Key, T, H2, P2, Allocator>&& source); // C++17 - template<class H2, class P2> - void merge(unordered_multimap<Key, T, H2, P2, Allocator>& source); // C++17 - template<class H2, class P2> - void merge(unordered_multimap<Key, T, H2, P2, Allocator>&& source); // C++17 - - void swap(unordered_map&) - noexcept( - (!allocator_type::propagate_on_container_swap::value || - __is_nothrow_swappable<allocator_type>::value) && - __is_nothrow_swappable<hasher>::value && - __is_nothrow_swappable<key_equal>::value); - - hasher hash_function() const; - key_equal key_eq() const; - - iterator find(const key_type& k); - const_iterator find(const key_type& k) const; - template<typename K> - iterator find(const K& x); // C++20 - template<typename K> - const_iterator find(const K& x) const; // C++20 - size_type count(const key_type& k) const; - template<typename K> - size_type count(const K& k) const; // C++20 - bool contains(const key_type& k) const; // C++20 - template<typename K> - bool contains(const K& k) const; // C++20 - pair<iterator, iterator> equal_range(const key_type& k); - pair<const_iterator, const_iterator> equal_range(const key_type& k) const; - template<typename K> - pair<iterator, iterator> equal_range(const K& k); // C++20 - template<typename K> - pair<const_iterator, const_iterator> equal_range(const K& k) const; // C++20 - - mapped_type& operator[](const key_type& k); - mapped_type& operator[](key_type&& k); - - mapped_type& at(const key_type& k); - const mapped_type& at(const key_type& k) const; - - size_type bucket_count() const noexcept; - size_type max_bucket_count() const noexcept; - - size_type bucket_size(size_type n) const; - size_type bucket(const key_type& k) const; - - local_iterator begin(size_type n); - local_iterator end(size_type n); - const_local_iterator begin(size_type n) const; - const_local_iterator end(size_type n) const; - const_local_iterator cbegin(size_type n) const; - const_local_iterator cend(size_type n) const; - - float load_factor() const noexcept; - float max_load_factor() const noexcept; - void max_load_factor(float z); - void rehash(size_type n); - void reserve(size_type n); -}; - -template<class InputIterator, - class Hash = hash<iter_key_t<InputIterator>>, class Pred = equal_to<iter_key_t<InputIterator>>, - class Allocator = allocator<iter_to_alloc_t<InputIterator>>> -unordered_map(InputIterator, InputIterator, typename see below::size_type = see below, - Hash = Hash(), Pred = Pred(), Allocator = Allocator()) - -> unordered_map<iter_key_t<InputIterator>, iter_value_t<InputIterator>, Hash, Pred, - Allocator>; // C++17 - -template<class Key, class T, class Hash = hash<Key>, - class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>> -unordered_map(initializer_list<pair<const Key, T>>, typename see below::size_type = see below, - Hash = Hash(), Pred = Pred(), Allocator = Allocator()) - -> unordered_map<Key, T, Hash, Pred, Allocator>; // C++17 - -template<class InputIterator, class Allocator> -unordered_map(InputIterator, InputIterator, typename see below::size_type, Allocator) - -> unordered_map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, - hash<iter_key_t<InputIterator>>, equal_to<iter_key_t<InputIterator>>, Allocator>; // C++17 - -template<class InputIterator, class Allocator> -unordered_map(InputIterator, InputIterator, Allocator) - -> unordered_map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, - hash<iter_key_t<InputIterator>>, equal_to<iter_key_t<InputIterator>>, Allocator>; // C++17 - -template<class InputIterator, class Hash, class Allocator> -unordered_map(InputIterator, InputIterator, typename see below::size_type, Hash, Allocator) - -> unordered_map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Hash, - equal_to<iter_key_t<InputIterator>>, Allocator>; // C++17 - -template<class Key, class T, typename Allocator> -unordered_map(initializer_list<pair<const Key, T>>, typename see below::size_type, Allocator) - -> unordered_map<Key, T, hash<Key>, equal_to<Key>, Allocator>; // C++17 - -template<class Key, class T, typename Allocator> -unordered_map(initializer_list<pair<const Key, T>>, Allocator) - -> unordered_map<Key, T, hash<Key>, equal_to<Key>, Allocator>; // C++17 - -template<class Key, class T, class Hash, class Allocator> -unordered_map(initializer_list<pair<const Key, T>>, typename see below::size_type, Hash, Allocator) - -> unordered_map<Key, T, Hash, equal_to<Key>, Allocator>; // C++17 - -template <class Key, class T, class Hash, class Pred, class Alloc> - void swap(unordered_map<Key, T, Hash, Pred, Alloc>& x, - unordered_map<Key, T, Hash, Pred, Alloc>& y) - noexcept(noexcept(x.swap(y))); - -template <class Key, class T, class Hash, class Pred, class Alloc> - bool - operator==(const unordered_map<Key, T, Hash, Pred, Alloc>& x, - const unordered_map<Key, T, Hash, Pred, Alloc>& y); - -template <class Key, class T, class Hash, class Pred, class Alloc> - bool - operator!=(const unordered_map<Key, T, Hash, Pred, Alloc>& x, - const unordered_map<Key, T, Hash, Pred, Alloc>& y); - -template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, - class Alloc = allocator<pair<const Key, T>>> -class unordered_multimap -{ -public: - // types - typedef Key key_type; - typedef T mapped_type; - typedef Hash hasher; - typedef Pred key_equal; - typedef Alloc allocator_type; - typedef pair<const key_type, mapped_type> value_type; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef typename allocator_traits<allocator_type>::pointer pointer; - typedef typename allocator_traits<allocator_type>::const_pointer const_pointer; - typedef typename allocator_traits<allocator_type>::size_type size_type; - typedef typename allocator_traits<allocator_type>::difference_type difference_type; - - typedef /unspecified/ iterator; - typedef /unspecified/ const_iterator; - typedef /unspecified/ local_iterator; - typedef /unspecified/ const_local_iterator; - - typedef unspecified node_type; // C++17 - - unordered_multimap() - noexcept( - is_nothrow_default_constructible<hasher>::value && - is_nothrow_default_constructible<key_equal>::value && - is_nothrow_default_constructible<allocator_type>::value); - explicit unordered_multimap(size_type n, const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - template <class InputIterator> - unordered_multimap(InputIterator f, InputIterator l, - size_type n = 0, const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - explicit unordered_multimap(const allocator_type&); - unordered_multimap(const unordered_multimap&); - unordered_multimap(const unordered_multimap&, const Allocator&); - unordered_multimap(unordered_multimap&&) - noexcept( - is_nothrow_move_constructible<hasher>::value && - is_nothrow_move_constructible<key_equal>::value && - is_nothrow_move_constructible<allocator_type>::value); - unordered_multimap(unordered_multimap&&, const Allocator&); - unordered_multimap(initializer_list<value_type>, size_type n = 0, - const hasher& hf = hasher(), const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - unordered_multimap(size_type n, const allocator_type& a) - : unordered_multimap(n, hasher(), key_equal(), a) {} // C++14 - unordered_multimap(size_type n, const hasher& hf, const allocator_type& a) - : unordered_multimap(n, hf, key_equal(), a) {} // C++14 - template <class InputIterator> - unordered_multimap(InputIterator f, InputIterator l, size_type n, const allocator_type& a) - : unordered_multimap(f, l, n, hasher(), key_equal(), a) {} // C++14 - template <class InputIterator> - unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf, - const allocator_type& a) - : unordered_multimap(f, l, n, hf, key_equal(), a) {} // C++14 - unordered_multimap(initializer_list<value_type> il, size_type n, const allocator_type& a) - : unordered_multimap(il, n, hasher(), key_equal(), a) {} // C++14 - unordered_multimap(initializer_list<value_type> il, size_type n, const hasher& hf, - const allocator_type& a) - : unordered_multimap(il, n, hf, key_equal(), a) {} // C++14 - ~unordered_multimap(); - unordered_multimap& operator=(const unordered_multimap&); - unordered_multimap& operator=(unordered_multimap&&) - noexcept( - allocator_type::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<allocator_type>::value && - is_nothrow_move_assignable<hasher>::value && - is_nothrow_move_assignable<key_equal>::value); - unordered_multimap& operator=(initializer_list<value_type>); - - allocator_type get_allocator() const noexcept; - - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; - - iterator begin() noexcept; - iterator end() noexcept; - const_iterator begin() const noexcept; - const_iterator end() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - - template <class... Args> - iterator emplace(Args&&... args); - template <class... Args> - iterator emplace_hint(const_iterator position, Args&&... args); - iterator insert(const value_type& obj); - template <class P> - iterator insert(P&& obj); - iterator insert(const_iterator hint, const value_type& obj); - template <class P> - iterator insert(const_iterator hint, P&& obj); - template <class InputIterator> - void insert(InputIterator first, InputIterator last); - void insert(initializer_list<value_type>); - - node_type extract(const_iterator position); // C++17 - node_type extract(const key_type& x); // C++17 - iterator insert(node_type&& nh); // C++17 - iterator insert(const_iterator hint, node_type&& nh); // C++17 - - iterator erase(const_iterator position); - iterator erase(iterator position); // C++14 - size_type erase(const key_type& k); - iterator erase(const_iterator first, const_iterator last); - void clear() noexcept; - - template<class H2, class P2> - void merge(unordered_multimap<Key, T, H2, P2, Allocator>& source); // C++17 - template<class H2, class P2> - void merge(unordered_multimap<Key, T, H2, P2, Allocator>&& source); // C++17 - template<class H2, class P2> - void merge(unordered_map<Key, T, H2, P2, Allocator>& source); // C++17 - template<class H2, class P2> - void merge(unordered_map<Key, T, H2, P2, Allocator>&& source); // C++17 - - void swap(unordered_multimap&) - noexcept( - (!allocator_type::propagate_on_container_swap::value || - __is_nothrow_swappable<allocator_type>::value) && - __is_nothrow_swappable<hasher>::value && - __is_nothrow_swappable<key_equal>::value); - - hasher hash_function() const; - key_equal key_eq() const; - - iterator find(const key_type& k); - const_iterator find(const key_type& k) const; - template<typename K> - iterator find(const K& x); // C++20 - template<typename K> - const_iterator find(const K& x) const; // C++20 - size_type count(const key_type& k) const; - template<typename K> - size_type count(const K& k) const; // C++20 - bool contains(const key_type& k) const; // C++20 - template<typename K> - bool contains(const K& k) const; // C++20 - pair<iterator, iterator> equal_range(const key_type& k); - pair<const_iterator, const_iterator> equal_range(const key_type& k) const; - template<typename K> - pair<iterator, iterator> equal_range(const K& k); // C++20 - template<typename K> - pair<const_iterator, const_iterator> equal_range(const K& k) const; // C++20 - - size_type bucket_count() const noexcept; - size_type max_bucket_count() const noexcept; - - size_type bucket_size(size_type n) const; - size_type bucket(const key_type& k) const; - - local_iterator begin(size_type n); - local_iterator end(size_type n); - const_local_iterator begin(size_type n) const; - const_local_iterator end(size_type n) const; - const_local_iterator cbegin(size_type n) const; - const_local_iterator cend(size_type n) const; - - float load_factor() const noexcept; - float max_load_factor() const noexcept; - void max_load_factor(float z); - void rehash(size_type n); - void reserve(size_type n); -}; - -template<class InputIterator, - class Hash = hash<iter_key_t<InputIterator>>, class Pred = equal_to<iter_key_t<InputIterator>>, - class Allocator = allocator<iter_to_alloc_t<InputIterator>>> -unordered_multimap(InputIterator, InputIterator, typename see below::size_type = see below, - Hash = Hash(), Pred = Pred(), Allocator = Allocator()) - -> unordered_multimap<iter_key_t<InputIterator>, iter_value_t<InputIterator>, Hash, Pred, - Allocator>; // C++17 - -template<class Key, class T, class Hash = hash<Key>, - class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>> -unordered_multimap(initializer_list<pair<const Key, T>>, typename see below::size_type = see below, - Hash = Hash(), Pred = Pred(), Allocator = Allocator()) - -> unordered_multimap<Key, T, Hash, Pred, Allocator>; // C++17 - -template<class InputIterator, class Allocator> -unordered_multimap(InputIterator, InputIterator, typename see below::size_type, Allocator) - -> unordered_multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>, - hash<iter_key_t<InputIterator>>, equal_to<iter_key_t<InputIterator>>, Allocator>; // C++17 - -template<class InputIterator, class Allocator> -unordered_multimap(InputIterator, InputIterator, Allocator) - -> unordered_multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>, - hash<iter_key_t<InputIterator>>, equal_to<iter_key_t<InputIterator>>, Allocator>; // C++17 - -template<class InputIterator, class Hash, class Allocator> -unordered_multimap(InputIterator, InputIterator, typename see below::size_type, Hash, Allocator) - -> unordered_multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Hash, - equal_to<iter_key_t<InputIterator>>, Allocator>; // C++17 - -template<class Key, class T, typename Allocator> -unordered_multimap(initializer_list<pair<const Key, T>>, typename see below::size_type, Allocator) - -> unordered_multimap<Key, T, hash<Key>, equal_to<Key>, Allocator>; // C++17 - -template<class Key, class T, typename Allocator> -unordered_multimap(initializer_list<pair<const Key, T>>, Allocator) - -> unordered_multimap<Key, T, hash<Key>, equal_to<Key>, Allocator>; // C++17 - -template<class Key, class T, class Hash, class Allocator> -unordered_multimap(initializer_list<pair<const Key, T>>, typename see below::size_type, Hash, - Allocator) - -> unordered_multimap<Key, T, Hash, equal_to<Key>, Allocator>; // C++17 - -template <class Key, class T, class Hash, class Pred, class Alloc> - void swap(unordered_multimap<Key, T, Hash, Pred, Alloc>& x, - unordered_multimap<Key, T, Hash, Pred, Alloc>& y) - noexcept(noexcept(x.swap(y))); - -template <class K, class T, class H, class P, class A, class Predicate> - typename unordered_map<K, T, H, P, A>::size_type - erase_if(unordered_map<K, T, H, P, A>& c, Predicate pred); // C++20 - -template <class K, class T, class H, class P, class A, class Predicate> - typename unordered_multimap<K, T, H, P, A>::size_type - erase_if(unordered_multimap<K, T, H, P, A>& c, Predicate pred); // C++20 - -template <class Key, class T, class Hash, class Pred, class Alloc> - bool - operator==(const unordered_multimap<Key, T, Hash, Pred, Alloc>& x, - const unordered_multimap<Key, T, Hash, Pred, Alloc>& y); - -template <class Key, class T, class Hash, class Pred, class Alloc> - bool - operator!=(const unordered_multimap<Key, T, Hash, Pred, Alloc>& x, - const unordered_multimap<Key, T, Hash, Pred, Alloc>& y); - -} // std - -*/ - -#include <__algorithm/is_permutation.h> -#include <__assert> -#include <__config> -#include <__debug> -#include <__functional/is_transparent.h> -#include <__hash_table> -#include <__iterator/iterator_traits.h> -#include <__memory/addressof.h> -#include <__node_handle> -#include <__utility/forward.h> -#include <compare> -#include <functional> -#include <iterator> // __libcpp_erase_if_container -#include <stdexcept> -#include <tuple> -#include <version> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -template <class _Key, class _Cp, class _Hash, class _Pred, - bool = is_empty<_Hash>::value && !__libcpp_is_final<_Hash>::value> -class __unordered_map_hasher - : private _Hash -{ -public: - _LIBCPP_INLINE_VISIBILITY - __unordered_map_hasher() - _NOEXCEPT_(is_nothrow_default_constructible<_Hash>::value) - : _Hash() {} - _LIBCPP_INLINE_VISIBILITY - __unordered_map_hasher(const _Hash& __h) - _NOEXCEPT_(is_nothrow_copy_constructible<_Hash>::value) - : _Hash(__h) {} - _LIBCPP_INLINE_VISIBILITY - const _Hash& hash_function() const _NOEXCEPT {return *this;} - _LIBCPP_INLINE_VISIBILITY - size_t operator()(const _Cp& __x) const - {return static_cast<const _Hash&>(*this)(__x.__get_value().first);} - _LIBCPP_INLINE_VISIBILITY - size_t operator()(const _Key& __x) const - {return static_cast<const _Hash&>(*this)(__x);} -#if _LIBCPP_STD_VER > 17 - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - size_t operator()(const _K2& __x) const - {return static_cast<const _Hash&>(*this)(__x);} -#endif - _LIBCPP_INLINE_VISIBILITY - void swap(__unordered_map_hasher& __y) - _NOEXCEPT_(__is_nothrow_swappable<_Hash>::value) - { - using _VSTD::swap; - swap(static_cast<_Hash&>(*this), static_cast<_Hash&>(__y)); - } -}; - -template <class _Key, class _Cp, class _Hash, class _Pred> -class __unordered_map_hasher<_Key, _Cp, _Hash, _Pred, false> -{ - _Hash __hash_; -public: - _LIBCPP_INLINE_VISIBILITY - __unordered_map_hasher() - _NOEXCEPT_(is_nothrow_default_constructible<_Hash>::value) - : __hash_() {} - _LIBCPP_INLINE_VISIBILITY - __unordered_map_hasher(const _Hash& __h) - _NOEXCEPT_(is_nothrow_copy_constructible<_Hash>::value) - : __hash_(__h) {} - _LIBCPP_INLINE_VISIBILITY - const _Hash& hash_function() const _NOEXCEPT {return __hash_;} - _LIBCPP_INLINE_VISIBILITY - size_t operator()(const _Cp& __x) const - {return __hash_(__x.__get_value().first);} - _LIBCPP_INLINE_VISIBILITY - size_t operator()(const _Key& __x) const - {return __hash_(__x);} -#if _LIBCPP_STD_VER > 17 - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - size_t operator()(const _K2& __x) const - {return __hash_(__x);} -#endif - _LIBCPP_INLINE_VISIBILITY - void swap(__unordered_map_hasher& __y) - _NOEXCEPT_(__is_nothrow_swappable<_Hash>::value) - { - using _VSTD::swap; - swap(__hash_, __y.__hash_); - } -}; - -template <class _Key, class _Cp, class _Hash, class _Pred, bool __b> -inline _LIBCPP_INLINE_VISIBILITY -void -swap(__unordered_map_hasher<_Key, _Cp, _Hash, _Pred, __b>& __x, - __unordered_map_hasher<_Key, _Cp, _Hash, _Pred, __b>& __y) - _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) -{ - __x.swap(__y); -} - -template <class _Key, class _Cp, class _Pred, class _Hash, - bool = is_empty<_Pred>::value && !__libcpp_is_final<_Pred>::value> -class __unordered_map_equal - : private _Pred -{ -public: - _LIBCPP_INLINE_VISIBILITY - __unordered_map_equal() - _NOEXCEPT_(is_nothrow_default_constructible<_Pred>::value) - : _Pred() {} - _LIBCPP_INLINE_VISIBILITY - __unordered_map_equal(const _Pred& __p) - _NOEXCEPT_(is_nothrow_copy_constructible<_Pred>::value) - : _Pred(__p) {} - _LIBCPP_INLINE_VISIBILITY - const _Pred& key_eq() const _NOEXCEPT {return *this;} - _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Cp& __x, const _Cp& __y) const - {return static_cast<const _Pred&>(*this)(__x.__get_value().first, __y.__get_value().first);} - _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Cp& __x, const _Key& __y) const - {return static_cast<const _Pred&>(*this)(__x.__get_value().first, __y);} - _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Key& __x, const _Cp& __y) const - {return static_cast<const _Pred&>(*this)(__x, __y.__get_value().first);} -#if _LIBCPP_STD_VER > 17 - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Cp& __x, const _K2& __y) const - {return static_cast<const _Pred&>(*this)(__x.__get_value().first, __y);} - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - bool operator()(const _K2& __x, const _Cp& __y) const - {return static_cast<const _Pred&>(*this)(__x, __y.__get_value().first);} - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Key& __x, const _K2& __y) const - {return static_cast<const _Pred&>(*this)(__x, __y);} - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - bool operator()(const _K2& __x, const _Key& __y) const - {return static_cast<const _Pred&>(*this)(__x, __y);} -#endif - _LIBCPP_INLINE_VISIBILITY - void swap(__unordered_map_equal& __y) - _NOEXCEPT_(__is_nothrow_swappable<_Pred>::value) - { - using _VSTD::swap; - swap(static_cast<_Pred&>(*this), static_cast<_Pred&>(__y)); - } -}; - -template <class _Key, class _Cp, class _Pred, class _Hash> -class __unordered_map_equal<_Key, _Cp, _Pred, _Hash, false> -{ - _Pred __pred_; -public: - _LIBCPP_INLINE_VISIBILITY - __unordered_map_equal() - _NOEXCEPT_(is_nothrow_default_constructible<_Pred>::value) - : __pred_() {} - _LIBCPP_INLINE_VISIBILITY - __unordered_map_equal(const _Pred& __p) - _NOEXCEPT_(is_nothrow_copy_constructible<_Pred>::value) - : __pred_(__p) {} - _LIBCPP_INLINE_VISIBILITY - const _Pred& key_eq() const _NOEXCEPT {return __pred_;} - _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Cp& __x, const _Cp& __y) const - {return __pred_(__x.__get_value().first, __y.__get_value().first);} - _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Cp& __x, const _Key& __y) const - {return __pred_(__x.__get_value().first, __y);} - _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Key& __x, const _Cp& __y) const - {return __pred_(__x, __y.__get_value().first);} -#if _LIBCPP_STD_VER > 17 - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Cp& __x, const _K2& __y) const - {return __pred_(__x.__get_value().first, __y);} - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - bool operator()(const _K2& __x, const _Cp& __y) const - {return __pred_(__x, __y.__get_value().first);} - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Key& __x, const _K2& __y) const - {return __pred_(__x, __y);} - template <typename _K2> - _LIBCPP_INLINE_VISIBILITY - bool operator()(const _K2& __x, const _Key& __y) const - {return __pred_(__x, __y);} -#endif - _LIBCPP_INLINE_VISIBILITY - void swap(__unordered_map_equal& __y) - _NOEXCEPT_(__is_nothrow_swappable<_Pred>::value) - { - using _VSTD::swap; - swap(__pred_, __y.__pred_); - } -}; - -template <class _Key, class _Cp, class _Pred, class _Hash, bool __b> -inline _LIBCPP_INLINE_VISIBILITY -void -swap(__unordered_map_equal<_Key, _Cp, _Pred, _Hash, __b>& __x, - __unordered_map_equal<_Key, _Cp, _Pred, _Hash, __b>& __y) - _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) -{ - __x.swap(__y); -} - -template <class _Alloc> -class __hash_map_node_destructor -{ - typedef _Alloc allocator_type; - typedef allocator_traits<allocator_type> __alloc_traits; - -public: - - typedef typename __alloc_traits::pointer pointer; -private: - - allocator_type& __na_; - - __hash_map_node_destructor& operator=(const __hash_map_node_destructor&); - -public: - bool __first_constructed; - bool __second_constructed; - - _LIBCPP_INLINE_VISIBILITY - explicit __hash_map_node_destructor(allocator_type& __na) _NOEXCEPT - : __na_(__na), - __first_constructed(false), - __second_constructed(false) - {} - -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - __hash_map_node_destructor(__hash_node_destructor<allocator_type>&& __x) - _NOEXCEPT - : __na_(__x.__na_), - __first_constructed(__x.__value_constructed), - __second_constructed(__x.__value_constructed) - { - __x.__value_constructed = false; - } -#else // _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - __hash_map_node_destructor(const __hash_node_destructor<allocator_type>& __x) - : __na_(__x.__na_), - __first_constructed(__x.__value_constructed), - __second_constructed(__x.__value_constructed) - { - const_cast<bool&>(__x.__value_constructed) = false; - } -#endif // _LIBCPP_CXX03_LANG - - _LIBCPP_INLINE_VISIBILITY - void operator()(pointer __p) _NOEXCEPT - { - if (__second_constructed) - __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__get_value().second)); - if (__first_constructed) - __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__get_value().first)); - if (__p) - __alloc_traits::deallocate(__na_, __p, 1); - } -}; - -#ifndef _LIBCPP_CXX03_LANG -template <class _Key, class _Tp> -struct _LIBCPP_STANDALONE_DEBUG __hash_value_type -{ - typedef _Key key_type; - typedef _Tp mapped_type; - typedef pair<const key_type, mapped_type> value_type; - typedef pair<key_type&, mapped_type&> __nc_ref_pair_type; - typedef pair<key_type&&, mapped_type&&> __nc_rref_pair_type; - -private: - value_type __cc; - -public: - _LIBCPP_INLINE_VISIBILITY - value_type& __get_value() - { -#if _LIBCPP_STD_VER > 14 - return *_VSTD::launder(_VSTD::addressof(__cc)); -#else - return __cc; -#endif - } - - _LIBCPP_INLINE_VISIBILITY - const value_type& __get_value() const - { -#if _LIBCPP_STD_VER > 14 - return *_VSTD::launder(_VSTD::addressof(__cc)); -#else - return __cc; -#endif - } - - _LIBCPP_INLINE_VISIBILITY - __nc_ref_pair_type __ref() - { - value_type& __v = __get_value(); - return __nc_ref_pair_type(const_cast<key_type&>(__v.first), __v.second); - } - - _LIBCPP_INLINE_VISIBILITY - __nc_rref_pair_type __move() - { - value_type& __v = __get_value(); - return __nc_rref_pair_type( - _VSTD::move(const_cast<key_type&>(__v.first)), - _VSTD::move(__v.second)); - } - - _LIBCPP_INLINE_VISIBILITY - __hash_value_type& operator=(const __hash_value_type& __v) - { - __ref() = __v.__get_value(); - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - __hash_value_type& operator=(__hash_value_type&& __v) - { - __ref() = __v.__move(); - return *this; - } - - template <class _ValueTp, - class = typename enable_if< - __is_same_uncvref<_ValueTp, value_type>::value - >::type - > - _LIBCPP_INLINE_VISIBILITY - __hash_value_type& operator=(_ValueTp&& __v) - { - __ref() = _VSTD::forward<_ValueTp>(__v); - return *this; - } - -private: - __hash_value_type(const __hash_value_type& __v) = delete; - __hash_value_type(__hash_value_type&& __v) = delete; - template <class ..._Args> - explicit __hash_value_type(_Args&& ...__args) = delete; - - ~__hash_value_type() = delete; -}; - -#else - -template <class _Key, class _Tp> -struct __hash_value_type -{ - typedef _Key key_type; - typedef _Tp mapped_type; - typedef pair<const key_type, mapped_type> value_type; - -private: - value_type __cc; - -public: - _LIBCPP_INLINE_VISIBILITY - value_type& __get_value() { return __cc; } - _LIBCPP_INLINE_VISIBILITY - const value_type& __get_value() const { return __cc; } - -private: - ~__hash_value_type(); -}; - -#endif - -template <class _HashIterator> -class _LIBCPP_TEMPLATE_VIS __hash_map_iterator -{ - _HashIterator __i_; - - typedef __hash_node_types_from_iterator<_HashIterator> _NodeTypes; - -public: - typedef forward_iterator_tag iterator_category; - typedef typename _NodeTypes::__map_value_type value_type; - typedef typename _NodeTypes::difference_type difference_type; - typedef value_type& reference; - typedef typename _NodeTypes::__map_value_type_pointer pointer; - - _LIBCPP_INLINE_VISIBILITY - __hash_map_iterator() _NOEXCEPT {} - - _LIBCPP_INLINE_VISIBILITY - __hash_map_iterator(_HashIterator __i) _NOEXCEPT : __i_(__i) {} - - _LIBCPP_INLINE_VISIBILITY - reference operator*() const {return __i_->__get_value();} - _LIBCPP_INLINE_VISIBILITY - pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__get_value());} - - _LIBCPP_INLINE_VISIBILITY - __hash_map_iterator& operator++() {++__i_; return *this;} - _LIBCPP_INLINE_VISIBILITY - __hash_map_iterator operator++(int) - { - __hash_map_iterator __t(*this); - ++(*this); - return __t; - } - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const __hash_map_iterator& __x, const __hash_map_iterator& __y) - {return __x.__i_ == __y.__i_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y) - {return __x.__i_ != __y.__i_;} - - template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map; - template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; - template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; - template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; - template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; -}; - -template <class _HashIterator> -class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator -{ - _HashIterator __i_; - - typedef __hash_node_types_from_iterator<_HashIterator> _NodeTypes; - -public: - typedef forward_iterator_tag iterator_category; - typedef typename _NodeTypes::__map_value_type value_type; - typedef typename _NodeTypes::difference_type difference_type; - typedef const value_type& reference; - typedef typename _NodeTypes::__const_map_value_type_pointer pointer; - - _LIBCPP_INLINE_VISIBILITY - __hash_map_const_iterator() _NOEXCEPT {} - - _LIBCPP_INLINE_VISIBILITY - __hash_map_const_iterator(_HashIterator __i) _NOEXCEPT : __i_(__i) {} - _LIBCPP_INLINE_VISIBILITY - __hash_map_const_iterator( - __hash_map_iterator<typename _HashIterator::__non_const_iterator> __i) - _NOEXCEPT - : __i_(__i.__i_) {} - - _LIBCPP_INLINE_VISIBILITY - reference operator*() const {return __i_->__get_value();} - _LIBCPP_INLINE_VISIBILITY - pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__get_value());} - - _LIBCPP_INLINE_VISIBILITY - __hash_map_const_iterator& operator++() {++__i_; return *this;} - _LIBCPP_INLINE_VISIBILITY - __hash_map_const_iterator operator++(int) - { - __hash_map_const_iterator __t(*this); - ++(*this); - return __t; - } - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y) - {return __x.__i_ == __y.__i_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y) - {return __x.__i_ != __y.__i_;} - - template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map; - template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; - template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; - template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; -}; - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -class unordered_multimap; - -template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>, - class _Alloc = allocator<pair<const _Key, _Tp> > > -class _LIBCPP_TEMPLATE_VIS unordered_map -{ -public: - // types - typedef _Key key_type; - typedef _Tp mapped_type; - typedef __identity_t<_Hash> hasher; - typedef __identity_t<_Pred> key_equal; - typedef __identity_t<_Alloc> allocator_type; - typedef pair<const key_type, mapped_type> value_type; - typedef value_type& reference; - typedef const value_type& const_reference; - static_assert((is_same<value_type, typename allocator_type::value_type>::value), - "Invalid allocator::value_type"); - -private: - typedef __hash_value_type<key_type, mapped_type> __value_type; - typedef __unordered_map_hasher<key_type, __value_type, hasher, key_equal> __hasher; - typedef __unordered_map_equal<key_type, __value_type, key_equal, hasher> __key_equal; - typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, - __value_type>::type __allocator_type; - - typedef __hash_table<__value_type, __hasher, - __key_equal, __allocator_type> __table; - - __table __table_; - - typedef typename __table::_NodeTypes _NodeTypes; - typedef typename __table::__node_pointer __node_pointer; - typedef typename __table::__node_const_pointer __node_const_pointer; - typedef typename __table::__node_traits __node_traits; - typedef typename __table::__node_allocator __node_allocator; - typedef typename __table::__node __node; - typedef __hash_map_node_destructor<__node_allocator> _Dp; - typedef unique_ptr<__node, _Dp> __node_holder; - typedef allocator_traits<allocator_type> __alloc_traits; - - static_assert((is_same<typename __table::__container_value_type, value_type>::value), ""); - static_assert((is_same<typename __table::__node_value_type, __value_type>::value), ""); -public: - typedef typename __alloc_traits::pointer pointer; - typedef typename __alloc_traits::const_pointer const_pointer; - typedef typename __table::size_type size_type; - typedef typename __table::difference_type difference_type; - - typedef __hash_map_iterator<typename __table::iterator> iterator; - typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator; - typedef __hash_map_iterator<typename __table::local_iterator> local_iterator; - typedef __hash_map_const_iterator<typename __table::const_local_iterator> const_local_iterator; - -#if _LIBCPP_STD_VER > 14 - typedef __map_node_handle<__node, allocator_type> node_type; - typedef __insert_return_type<iterator, node_type> insert_return_type; -#endif - - template <class _Key2, class _Tp2, class _Hash2, class _Pred2, class _Alloc2> - friend class _LIBCPP_TEMPLATE_VIS unordered_map; - template <class _Key2, class _Tp2, class _Hash2, class _Pred2, class _Alloc2> - friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; - - _LIBCPP_INLINE_VISIBILITY - unordered_map() - _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) - { - _VSTD::__debug_db_insert_c(this); - } - explicit unordered_map(size_type __n, const hasher& __hf = hasher(), - const key_equal& __eql = key_equal()); - unordered_map(size_type __n, const hasher& __hf, - const key_equal& __eql, - const allocator_type& __a); - template <class _InputIterator> - unordered_map(_InputIterator __first, _InputIterator __last); - template <class _InputIterator> - unordered_map(_InputIterator __first, _InputIterator __last, - size_type __n, const hasher& __hf = hasher(), - const key_equal& __eql = key_equal()); - template <class _InputIterator> - unordered_map(_InputIterator __first, _InputIterator __last, - size_type __n, const hasher& __hf, - const key_equal& __eql, - const allocator_type& __a); - _LIBCPP_INLINE_VISIBILITY - explicit unordered_map(const allocator_type& __a); - unordered_map(const unordered_map& __u); - unordered_map(const unordered_map& __u, const allocator_type& __a); -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - unordered_map(unordered_map&& __u) - _NOEXCEPT_(is_nothrow_move_constructible<__table>::value); - unordered_map(unordered_map&& __u, const allocator_type& __a); - unordered_map(initializer_list<value_type> __il); - unordered_map(initializer_list<value_type> __il, size_type __n, - const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); - unordered_map(initializer_list<value_type> __il, size_type __n, - const hasher& __hf, const key_equal& __eql, - const allocator_type& __a); -#endif // _LIBCPP_CXX03_LANG -#if _LIBCPP_STD_VER > 11 - _LIBCPP_INLINE_VISIBILITY - unordered_map(size_type __n, const allocator_type& __a) - : unordered_map(__n, hasher(), key_equal(), __a) {} - _LIBCPP_INLINE_VISIBILITY - unordered_map(size_type __n, const hasher& __hf, const allocator_type& __a) - : unordered_map(__n, __hf, key_equal(), __a) {} - template <class _InputIterator> - _LIBCPP_INLINE_VISIBILITY - unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) - : unordered_map(__first, __last, __n, hasher(), key_equal(), __a) {} - template <class _InputIterator> - _LIBCPP_INLINE_VISIBILITY - unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, - const allocator_type& __a) - : unordered_map(__first, __last, __n, __hf, key_equal(), __a) {} - _LIBCPP_INLINE_VISIBILITY - unordered_map(initializer_list<value_type> __il, size_type __n, const allocator_type& __a) - : unordered_map(__il, __n, hasher(), key_equal(), __a) {} - _LIBCPP_INLINE_VISIBILITY - unordered_map(initializer_list<value_type> __il, size_type __n, const hasher& __hf, - const allocator_type& __a) - : unordered_map(__il, __n, __hf, key_equal(), __a) {} -#endif - _LIBCPP_INLINE_VISIBILITY - ~unordered_map() { - static_assert(sizeof(__diagnose_unordered_container_requirements<_Key, _Hash, _Pred>(0)), ""); - } - - _LIBCPP_INLINE_VISIBILITY - unordered_map& operator=(const unordered_map& __u) - { -#ifndef _LIBCPP_CXX03_LANG - __table_ = __u.__table_; -#else - if (this != _VSTD::addressof(__u)) { - __table_.clear(); - __table_.hash_function() = __u.__table_.hash_function(); - __table_.key_eq() = __u.__table_.key_eq(); - __table_.max_load_factor() = __u.__table_.max_load_factor(); - __table_.__copy_assign_alloc(__u.__table_); - insert(__u.begin(), __u.end()); - } -#endif - return *this; - } -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - unordered_map& operator=(unordered_map&& __u) - _NOEXCEPT_(is_nothrow_move_assignable<__table>::value); - _LIBCPP_INLINE_VISIBILITY - unordered_map& operator=(initializer_list<value_type> __il); -#endif // _LIBCPP_CXX03_LANG - - _LIBCPP_INLINE_VISIBILITY - allocator_type get_allocator() const _NOEXCEPT - {return allocator_type(__table_.__node_alloc());} - - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY - bool empty() const _NOEXCEPT {return __table_.size() == 0;} - _LIBCPP_INLINE_VISIBILITY - size_type size() const _NOEXCEPT {return __table_.size();} - _LIBCPP_INLINE_VISIBILITY - size_type max_size() const _NOEXCEPT {return __table_.max_size();} - - _LIBCPP_INLINE_VISIBILITY - iterator begin() _NOEXCEPT {return __table_.begin();} - _LIBCPP_INLINE_VISIBILITY - iterator end() _NOEXCEPT {return __table_.end();} - _LIBCPP_INLINE_VISIBILITY - const_iterator begin() const _NOEXCEPT {return __table_.begin();} - _LIBCPP_INLINE_VISIBILITY - const_iterator end() const _NOEXCEPT {return __table_.end();} - _LIBCPP_INLINE_VISIBILITY - const_iterator cbegin() const _NOEXCEPT {return __table_.begin();} - _LIBCPP_INLINE_VISIBILITY - const_iterator cend() const _NOEXCEPT {return __table_.end();} - - _LIBCPP_INLINE_VISIBILITY - pair<iterator, bool> insert(const value_type& __x) - {return __table_.__insert_unique(__x);} - - iterator insert(const_iterator __p, const value_type& __x) { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "unordered_map::insert(const_iterator, const value_type&) called with an iterator not " - "referring to this unordered_map"); - ((void)__p); - return insert(__x).first; - } - - template <class _InputIterator> - _LIBCPP_INLINE_VISIBILITY - void insert(_InputIterator __first, _InputIterator __last); - -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - void insert(initializer_list<value_type> __il) - {insert(__il.begin(), __il.end());} - - _LIBCPP_INLINE_VISIBILITY - pair<iterator, bool> insert(value_type&& __x) - {return __table_.__insert_unique(_VSTD::move(__x));} - - iterator insert(const_iterator __p, value_type&& __x) { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "unordered_map::insert(const_iterator, const value_type&) called with an iterator not" - " referring to this unordered_map"); - ((void)__p); - return __table_.__insert_unique(_VSTD::move(__x)).first; - } - - template <class _Pp, - class = typename enable_if<is_constructible<value_type, _Pp>::value>::type> - _LIBCPP_INLINE_VISIBILITY - pair<iterator, bool> insert(_Pp&& __x) - {return __table_.__insert_unique(_VSTD::forward<_Pp>(__x));} - - template <class _Pp, - class = typename enable_if<is_constructible<value_type, _Pp>::value>::type> - _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __p, _Pp&& __x) - { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "unordered_map::insert(const_iterator, value_type&&) called with an iterator not" - " referring to this unordered_map"); - ((void)__p); - return insert(_VSTD::forward<_Pp>(__x)).first; - } - - template <class... _Args> - _LIBCPP_INLINE_VISIBILITY - pair<iterator, bool> emplace(_Args&&... __args) { - return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...); - } - - template <class... _Args> - _LIBCPP_INLINE_VISIBILITY - iterator emplace_hint(const_iterator __p, _Args&&... __args) { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "unordered_map::emplace_hint(const_iterator, args...) called with an iterator not" - " referring to this unordered_map"); - ((void)__p); - return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first; - } - -#endif // _LIBCPP_CXX03_LANG - -#if _LIBCPP_STD_VER > 14 - template <class... _Args> - _LIBCPP_INLINE_VISIBILITY - pair<iterator, bool> try_emplace(const key_type& __k, _Args&&... __args) - { - return __table_.__emplace_unique_key_args(__k, piecewise_construct, - _VSTD::forward_as_tuple(__k), - _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); - } - - template <class... _Args> - _LIBCPP_INLINE_VISIBILITY - pair<iterator, bool> try_emplace(key_type&& __k, _Args&&... __args) - { - return __table_.__emplace_unique_key_args(__k, piecewise_construct, - _VSTD::forward_as_tuple(_VSTD::move(__k)), - _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); - } - - template <class... _Args> - _LIBCPP_INLINE_VISIBILITY - iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args) - { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__h)) == this, - "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not" - " referring to this unordered_map"); - ((void)__h); - return try_emplace(__k, _VSTD::forward<_Args>(__args)...).first; - } - - template <class... _Args> - _LIBCPP_INLINE_VISIBILITY - iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args) - { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__h)) == this, - "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not" - " referring to this unordered_map"); - ((void)__h); - return try_emplace(_VSTD::move(__k), _VSTD::forward<_Args>(__args)...).first; - } - - template <class _Vp> - _LIBCPP_INLINE_VISIBILITY - pair<iterator, bool> insert_or_assign(const key_type& __k, _Vp&& __v) - { - pair<iterator, bool> __res = __table_.__emplace_unique_key_args(__k, - __k, _VSTD::forward<_Vp>(__v)); - if (!__res.second) { - __res.first->second = _VSTD::forward<_Vp>(__v); - } - return __res; - } - - template <class _Vp> - _LIBCPP_INLINE_VISIBILITY - pair<iterator, bool> insert_or_assign(key_type&& __k, _Vp&& __v) - { - pair<iterator, bool> __res = __table_.__emplace_unique_key_args(__k, - _VSTD::move(__k), _VSTD::forward<_Vp>(__v)); - if (!__res.second) { - __res.first->second = _VSTD::forward<_Vp>(__v); - } - return __res; - } - - template <class _Vp> - _LIBCPP_INLINE_VISIBILITY - iterator insert_or_assign(const_iterator, const key_type& __k, _Vp&& __v) - { - // FIXME: Add debug mode checking for the iterator input - return insert_or_assign(__k, _VSTD::forward<_Vp>(__v)).first; - } - - template <class _Vp> - _LIBCPP_INLINE_VISIBILITY - iterator insert_or_assign(const_iterator, key_type&& __k, _Vp&& __v) - { - // FIXME: Add debug mode checking for the iterator input - return insert_or_assign(_VSTD::move(__k), _VSTD::forward<_Vp>(__v)).first; - } -#endif // _LIBCPP_STD_VER > 14 - - _LIBCPP_INLINE_VISIBILITY - iterator erase(const_iterator __p) {return __table_.erase(__p.__i_);} - _LIBCPP_INLINE_VISIBILITY - iterator erase(iterator __p) {return __table_.erase(__p.__i_);} - _LIBCPP_INLINE_VISIBILITY - size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);} - _LIBCPP_INLINE_VISIBILITY - iterator erase(const_iterator __first, const_iterator __last) - {return __table_.erase(__first.__i_, __last.__i_);} - _LIBCPP_INLINE_VISIBILITY - void clear() _NOEXCEPT {__table_.clear();} - -#if _LIBCPP_STD_VER > 14 - _LIBCPP_INLINE_VISIBILITY - insert_return_type insert(node_type&& __nh) - { - _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), - "node_type with incompatible allocator passed to unordered_map::insert()"); - return __table_.template __node_handle_insert_unique< - node_type, insert_return_type>(_VSTD::move(__nh)); - } - _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __hint, node_type&& __nh) - { - _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), - "node_type with incompatible allocator passed to unordered_map::insert()"); - return __table_.template __node_handle_insert_unique<node_type>( - __hint.__i_, _VSTD::move(__nh)); - } - _LIBCPP_INLINE_VISIBILITY - node_type extract(key_type const& __key) - { - return __table_.template __node_handle_extract<node_type>(__key); - } - _LIBCPP_INLINE_VISIBILITY - node_type extract(const_iterator __it) - { - return __table_.template __node_handle_extract<node_type>( - __it.__i_); - } - - template <class _H2, class _P2> - _LIBCPP_INLINE_VISIBILITY - void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - return __table_.__node_handle_merge_unique(__source.__table_); - } - template <class _H2, class _P2> - _LIBCPP_INLINE_VISIBILITY - void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>&& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - return __table_.__node_handle_merge_unique(__source.__table_); - } - template <class _H2, class _P2> - _LIBCPP_INLINE_VISIBILITY - void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - return __table_.__node_handle_merge_unique(__source.__table_); - } - template <class _H2, class _P2> - _LIBCPP_INLINE_VISIBILITY - void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>&& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - return __table_.__node_handle_merge_unique(__source.__table_); - } -#endif - - _LIBCPP_INLINE_VISIBILITY - void swap(unordered_map& __u) - _NOEXCEPT_(__is_nothrow_swappable<__table>::value) - { __table_.swap(__u.__table_);} - - _LIBCPP_INLINE_VISIBILITY - hasher hash_function() const - {return __table_.hash_function().hash_function();} - _LIBCPP_INLINE_VISIBILITY - key_equal key_eq() const - {return __table_.key_eq().key_eq();} - - _LIBCPP_INLINE_VISIBILITY - iterator find(const key_type& __k) {return __table_.find(__k);} - _LIBCPP_INLINE_VISIBILITY - const_iterator find(const key_type& __k) const {return __table_.find(__k);} -#if _LIBCPP_STD_VER > 17 - template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - iterator find(const _K2& __k) {return __table_.find(__k);} - template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - const_iterator find(const _K2& __k) const {return __table_.find(__k);} -#endif // _LIBCPP_STD_VER > 17 - - _LIBCPP_INLINE_VISIBILITY - size_type count(const key_type& __k) const {return __table_.__count_unique(__k);} -#if _LIBCPP_STD_VER > 17 - template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - size_type count(const _K2& __k) const {return __table_.__count_unique(__k);} -#endif // _LIBCPP_STD_VER > 17 - -#if _LIBCPP_STD_VER > 17 - _LIBCPP_INLINE_VISIBILITY - bool contains(const key_type& __k) const {return find(__k) != end();} - - template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - bool contains(const _K2& __k) const {return find(__k) != end();} -#endif // _LIBCPP_STD_VER > 17 - - _LIBCPP_INLINE_VISIBILITY - pair<iterator, iterator> equal_range(const key_type& __k) - {return __table_.__equal_range_unique(__k);} - _LIBCPP_INLINE_VISIBILITY - pair<const_iterator, const_iterator> equal_range(const key_type& __k) const - {return __table_.__equal_range_unique(__k);} -#if _LIBCPP_STD_VER > 17 - template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - pair<iterator, iterator> equal_range(const _K2& __k) - {return __table_.__equal_range_unique(__k);} - template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - pair<const_iterator, const_iterator> equal_range(const _K2& __k) const - {return __table_.__equal_range_unique(__k);} -#endif // _LIBCPP_STD_VER > 17 - - mapped_type& operator[](const key_type& __k); -#ifndef _LIBCPP_CXX03_LANG - mapped_type& operator[](key_type&& __k); -#endif - - mapped_type& at(const key_type& __k); - const mapped_type& at(const key_type& __k) const; - - _LIBCPP_INLINE_VISIBILITY - size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();} - _LIBCPP_INLINE_VISIBILITY - size_type max_bucket_count() const _NOEXCEPT {return __table_.max_bucket_count();} - - _LIBCPP_INLINE_VISIBILITY - size_type bucket_size(size_type __n) const - {return __table_.bucket_size(__n);} - _LIBCPP_INLINE_VISIBILITY - size_type bucket(const key_type& __k) const {return __table_.bucket(__k);} - - _LIBCPP_INLINE_VISIBILITY - local_iterator begin(size_type __n) {return __table_.begin(__n);} - _LIBCPP_INLINE_VISIBILITY - local_iterator end(size_type __n) {return __table_.end(__n);} - _LIBCPP_INLINE_VISIBILITY - const_local_iterator begin(size_type __n) const {return __table_.cbegin(__n);} - _LIBCPP_INLINE_VISIBILITY - const_local_iterator end(size_type __n) const {return __table_.cend(__n);} - _LIBCPP_INLINE_VISIBILITY - const_local_iterator cbegin(size_type __n) const {return __table_.cbegin(__n);} - _LIBCPP_INLINE_VISIBILITY - const_local_iterator cend(size_type __n) const {return __table_.cend(__n);} - - _LIBCPP_INLINE_VISIBILITY - float load_factor() const _NOEXCEPT {return __table_.load_factor();} - _LIBCPP_INLINE_VISIBILITY - float max_load_factor() const _NOEXCEPT {return __table_.max_load_factor();} - _LIBCPP_INLINE_VISIBILITY - void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);} - _LIBCPP_INLINE_VISIBILITY - void rehash(size_type __n) {__table_.rehash(__n);} - _LIBCPP_INLINE_VISIBILITY - void reserve(size_type __n) {__table_.reserve(__n);} - -#if _LIBCPP_DEBUG_LEVEL == 2 - - bool __dereferenceable(const const_iterator* __i) const - {return __table_.__dereferenceable(_VSTD::addressof(__i->__i_));} - bool __decrementable(const const_iterator* __i) const - {return __table_.__decrementable(_VSTD::addressof(__i->__i_));} - bool __addable(const const_iterator* __i, ptrdiff_t __n) const - {return __table_.__addable(_VSTD::addressof(__i->__i_), __n);} - bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const - {return __table_.__addable(_VSTD::addressof(__i->__i_), __n);} - -#endif // _LIBCPP_DEBUG_LEVEL == 2 - -private: - -#ifdef _LIBCPP_CXX03_LANG - __node_holder __construct_node_with_key(const key_type& __k); -#endif -}; - -#if _LIBCPP_STD_VER >= 17 -template<class _InputIterator, - class _Hash = hash<__iter_key_type<_InputIterator>>, - class _Pred = equal_to<__iter_key_type<_InputIterator>>, - class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = enable_if_t<!__is_allocator<_Hash>::value>, - class = enable_if_t<!is_integral<_Hash>::value>, - class = enable_if_t<!__is_allocator<_Pred>::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_map(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type = 0, - _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) - -> unordered_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Hash, _Pred, _Allocator>; - -template<class _Key, class _Tp, class _Hash = hash<remove_const_t<_Key>>, - class _Pred = equal_to<remove_const_t<_Key>>, - class _Allocator = allocator<pair<const _Key, _Tp>>, - class = enable_if_t<!__is_allocator<_Hash>::value>, - class = enable_if_t<!is_integral<_Hash>::value>, - class = enable_if_t<!__is_allocator<_Pred>::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_map(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allocator>::size_type = 0, - _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) - -> unordered_map<remove_const_t<_Key>, _Tp, _Hash, _Pred, _Allocator>; - -template<class _InputIterator, class _Allocator, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_map(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Allocator) - -> unordered_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, - hash<__iter_key_type<_InputIterator>>, equal_to<__iter_key_type<_InputIterator>>, _Allocator>; - -template<class _InputIterator, class _Allocator, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_map(_InputIterator, _InputIterator, _Allocator) - -> unordered_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, - hash<__iter_key_type<_InputIterator>>, equal_to<__iter_key_type<_InputIterator>>, _Allocator>; - -template<class _InputIterator, class _Hash, class _Allocator, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = enable_if_t<!__is_allocator<_Hash>::value>, - class = enable_if_t<!is_integral<_Hash>::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_map(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator) - -> unordered_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, - _Hash, equal_to<__iter_key_type<_InputIterator>>, _Allocator>; - -template<class _Key, class _Tp, class _Allocator, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_map(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allocator>::size_type, _Allocator) - -> unordered_map<remove_const_t<_Key>, _Tp, - hash<remove_const_t<_Key>>, - equal_to<remove_const_t<_Key>>, _Allocator>; - -template<class _Key, class _Tp, class _Allocator, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_map(initializer_list<pair<_Key, _Tp>>, _Allocator) - -> unordered_map<remove_const_t<_Key>, _Tp, - hash<remove_const_t<_Key>>, - equal_to<remove_const_t<_Key>>, _Allocator>; - -template<class _Key, class _Tp, class _Hash, class _Allocator, - class = enable_if_t<!__is_allocator<_Hash>::value>, - class = enable_if_t<!is_integral<_Hash>::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_map(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator) - -> unordered_map<remove_const_t<_Key>, _Tp, _Hash, - equal_to<remove_const_t<_Key>>, _Allocator>; -#endif - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( - size_type __n, const hasher& __hf, const key_equal& __eql) - : __table_(__hf, __eql) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__n); -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( - size_type __n, const hasher& __hf, const key_equal& __eql, - const allocator_type& __a) - : __table_(__hf, __eql, typename __table::allocator_type(__a)) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__n); -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( - const allocator_type& __a) - : __table_(typename __table::allocator_type(__a)) -{ - _VSTD::__debug_db_insert_c(this); -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -template <class _InputIterator> -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( - _InputIterator __first, _InputIterator __last) -{ - _VSTD::__debug_db_insert_c(this); - insert(__first, __last); -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -template <class _InputIterator> -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( - _InputIterator __first, _InputIterator __last, size_type __n, - const hasher& __hf, const key_equal& __eql) - : __table_(__hf, __eql) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__n); - insert(__first, __last); -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -template <class _InputIterator> -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( - _InputIterator __first, _InputIterator __last, size_type __n, - const hasher& __hf, const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, typename __table::allocator_type(__a)) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__n); - insert(__first, __last); -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( - const unordered_map& __u) - : __table_(__u.__table_) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__u.bucket_count()); - insert(__u.begin(), __u.end()); -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( - const unordered_map& __u, const allocator_type& __a) - : __table_(__u.__table_, typename __table::allocator_type(__a)) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__u.bucket_count()); - insert(__u.begin(), __u.end()); -} - -#ifndef _LIBCPP_CXX03_LANG - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( - unordered_map&& __u) - _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) - : __table_(_VSTD::move(__u.__table_)) -{ - _VSTD::__debug_db_insert_c(this); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->swap(this, _VSTD::addressof(__u)); -#endif -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( - unordered_map&& __u, const allocator_type& __a) - : __table_(_VSTD::move(__u.__table_), typename __table::allocator_type(__a)) -{ - _VSTD::__debug_db_insert_c(this); - if (__a != __u.get_allocator()) - { - iterator __i = __u.begin(); - while (__u.size() != 0) { - __table_.__emplace_unique( - __u.__table_.remove((__i++).__i_)->__value_.__move()); - } - } -#if _LIBCPP_DEBUG_LEVEL == 2 - else - __get_db()->swap(this, _VSTD::addressof(__u)); -#endif -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( - initializer_list<value_type> __il) -{ - _VSTD::__debug_db_insert_c(this); - insert(__il.begin(), __il.end()); -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( - initializer_list<value_type> __il, size_type __n, const hasher& __hf, - const key_equal& __eql) - : __table_(__hf, __eql) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__n); - insert(__il.begin(), __il.end()); -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( - initializer_list<value_type> __il, size_type __n, const hasher& __hf, - const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, typename __table::allocator_type(__a)) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__n); - insert(__il.begin(), __il.end()); -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_map&& __u) - _NOEXCEPT_(is_nothrow_move_assignable<__table>::value) -{ - __table_ = _VSTD::move(__u.__table_); - return *this; -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=( - initializer_list<value_type> __il) -{ - __table_.__assign_unique(__il.begin(), __il.end()); - return *this; -} - -#endif // _LIBCPP_CXX03_LANG - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -template <class _InputIterator> -inline -void -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, - _InputIterator __last) -{ - for (; __first != __last; ++__first) - __table_.__insert_unique(*__first); -} - -#ifndef _LIBCPP_CXX03_LANG - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -_Tp& -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k) -{ - return __table_.__emplace_unique_key_args(__k, - piecewise_construct, _VSTD::forward_as_tuple(__k), - _VSTD::forward_as_tuple()).first->__get_value().second; -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -_Tp& -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](key_type&& __k) -{ - return __table_.__emplace_unique_key_args(__k, - piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__k)), - _VSTD::forward_as_tuple()).first->__get_value().second; -} -#else // _LIBCPP_CXX03_LANG - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node_with_key(const key_type& __k) -{ - __node_allocator& __na = __table_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__get_value().first), __k); - __h.get_deleter().__first_constructed = true; - __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__get_value().second)); - __h.get_deleter().__second_constructed = true; - return __h; -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -_Tp& -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k) -{ - iterator __i = find(__k); - if (__i != end()) - return __i->second; - __node_holder __h = __construct_node_with_key(__k); - pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get()); - __h.release(); - return __r.first->second; -} - -#endif // _LIBCPP_CXX03_LANG - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -_Tp& -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::at(const key_type& __k) -{ - iterator __i = find(__k); - if (__i == end()) - __throw_out_of_range("unordered_map::at: key not found"); - return __i->second; -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -const _Tp& -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::at(const key_type& __k) const -{ - const_iterator __i = find(__k); - if (__i == end()) - __throw_out_of_range("unordered_map::at: key not found"); - return __i->second; -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -void -swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, - unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) - _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) -{ - __x.swap(__y); -} - -#if _LIBCPP_STD_VER > 17 -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, - class _Predicate> -inline _LIBCPP_INLINE_VISIBILITY - typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::size_type - erase_if(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __c, - _Predicate __pred) { - return _VSTD::__libcpp_erase_if_container(__c, __pred); -} -#endif - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -bool -operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, - const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) -{ - if (__x.size() != __y.size()) - return false; - typedef typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator - const_iterator; - for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end(); - __i != __ex; ++__i) - { - const_iterator __j = __y.find(__i->first); - if (__j == __ey || !(*__i == *__j)) - return false; - } - return true; -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, - const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) -{ - return !(__x == __y); -} - -template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>, - class _Alloc = allocator<pair<const _Key, _Tp> > > -class _LIBCPP_TEMPLATE_VIS unordered_multimap -{ -public: - // types - typedef _Key key_type; - typedef _Tp mapped_type; - typedef __identity_t<_Hash> hasher; - typedef __identity_t<_Pred> key_equal; - typedef __identity_t<_Alloc> allocator_type; - typedef pair<const key_type, mapped_type> value_type; - typedef value_type& reference; - typedef const value_type& const_reference; - static_assert((is_same<value_type, typename allocator_type::value_type>::value), - "Invalid allocator::value_type"); - -private: - typedef __hash_value_type<key_type, mapped_type> __value_type; - typedef __unordered_map_hasher<key_type, __value_type, hasher, key_equal> __hasher; - typedef __unordered_map_equal<key_type, __value_type, key_equal, hasher> __key_equal; - typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, - __value_type>::type __allocator_type; - - typedef __hash_table<__value_type, __hasher, - __key_equal, __allocator_type> __table; - - __table __table_; - - typedef typename __table::_NodeTypes _NodeTypes; - typedef typename __table::__node_traits __node_traits; - typedef typename __table::__node_allocator __node_allocator; - typedef typename __table::__node __node; - typedef __hash_map_node_destructor<__node_allocator> _Dp; - typedef unique_ptr<__node, _Dp> __node_holder; - typedef allocator_traits<allocator_type> __alloc_traits; - static_assert((is_same<typename __node_traits::size_type, - typename __alloc_traits::size_type>::value), - "Allocator uses different size_type for different types"); -public: - typedef typename __alloc_traits::pointer pointer; - typedef typename __alloc_traits::const_pointer const_pointer; - typedef typename __table::size_type size_type; - typedef typename __table::difference_type difference_type; - - typedef __hash_map_iterator<typename __table::iterator> iterator; - typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator; - typedef __hash_map_iterator<typename __table::local_iterator> local_iterator; - typedef __hash_map_const_iterator<typename __table::const_local_iterator> const_local_iterator; - -#if _LIBCPP_STD_VER > 14 - typedef __map_node_handle<__node, allocator_type> node_type; -#endif - - template <class _Key2, class _Tp2, class _Hash2, class _Pred2, class _Alloc2> - friend class _LIBCPP_TEMPLATE_VIS unordered_map; - template <class _Key2, class _Tp2, class _Hash2, class _Pred2, class _Alloc2> - friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; - - _LIBCPP_INLINE_VISIBILITY - unordered_multimap() - _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) - { - _VSTD::__debug_db_insert_c(this); - } - explicit unordered_multimap(size_type __n, const hasher& __hf = hasher(), - const key_equal& __eql = key_equal()); - unordered_multimap(size_type __n, const hasher& __hf, - const key_equal& __eql, - const allocator_type& __a); - template <class _InputIterator> - unordered_multimap(_InputIterator __first, _InputIterator __last); - template <class _InputIterator> - unordered_multimap(_InputIterator __first, _InputIterator __last, - size_type __n, const hasher& __hf = hasher(), - const key_equal& __eql = key_equal()); - template <class _InputIterator> - unordered_multimap(_InputIterator __first, _InputIterator __last, - size_type __n, const hasher& __hf, - const key_equal& __eql, - const allocator_type& __a); - _LIBCPP_INLINE_VISIBILITY - explicit unordered_multimap(const allocator_type& __a); - unordered_multimap(const unordered_multimap& __u); - unordered_multimap(const unordered_multimap& __u, const allocator_type& __a); -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - unordered_multimap(unordered_multimap&& __u) - _NOEXCEPT_(is_nothrow_move_constructible<__table>::value); - unordered_multimap(unordered_multimap&& __u, const allocator_type& __a); - unordered_multimap(initializer_list<value_type> __il); - unordered_multimap(initializer_list<value_type> __il, size_type __n, - const hasher& __hf = hasher(), - const key_equal& __eql = key_equal()); - unordered_multimap(initializer_list<value_type> __il, size_type __n, - const hasher& __hf, const key_equal& __eql, - const allocator_type& __a); -#endif // _LIBCPP_CXX03_LANG -#if _LIBCPP_STD_VER > 11 - _LIBCPP_INLINE_VISIBILITY - unordered_multimap(size_type __n, const allocator_type& __a) - : unordered_multimap(__n, hasher(), key_equal(), __a) {} - _LIBCPP_INLINE_VISIBILITY - unordered_multimap(size_type __n, const hasher& __hf, const allocator_type& __a) - : unordered_multimap(__n, __hf, key_equal(), __a) {} - template <class _InputIterator> - _LIBCPP_INLINE_VISIBILITY - unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) - : unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a) {} - template <class _InputIterator> - _LIBCPP_INLINE_VISIBILITY - unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, - const allocator_type& __a) - : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a) {} - _LIBCPP_INLINE_VISIBILITY - unordered_multimap(initializer_list<value_type> __il, size_type __n, const allocator_type& __a) - : unordered_multimap(__il, __n, hasher(), key_equal(), __a) {} - _LIBCPP_INLINE_VISIBILITY - unordered_multimap(initializer_list<value_type> __il, size_type __n, const hasher& __hf, - const allocator_type& __a) - : unordered_multimap(__il, __n, __hf, key_equal(), __a) {} -#endif - _LIBCPP_INLINE_VISIBILITY - ~unordered_multimap() { - static_assert(sizeof(__diagnose_unordered_container_requirements<_Key, _Hash, _Pred>(0)), ""); - } - - _LIBCPP_INLINE_VISIBILITY - unordered_multimap& operator=(const unordered_multimap& __u) - { -#ifndef _LIBCPP_CXX03_LANG - __table_ = __u.__table_; -#else - if (this != _VSTD::addressof(__u)) { - __table_.clear(); - __table_.hash_function() = __u.__table_.hash_function(); - __table_.key_eq() = __u.__table_.key_eq(); - __table_.max_load_factor() = __u.__table_.max_load_factor(); - __table_.__copy_assign_alloc(__u.__table_); - insert(__u.begin(), __u.end()); - } -#endif - return *this; - } -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - unordered_multimap& operator=(unordered_multimap&& __u) - _NOEXCEPT_(is_nothrow_move_assignable<__table>::value); - _LIBCPP_INLINE_VISIBILITY - unordered_multimap& operator=(initializer_list<value_type> __il); -#endif // _LIBCPP_CXX03_LANG - - _LIBCPP_INLINE_VISIBILITY - allocator_type get_allocator() const _NOEXCEPT - {return allocator_type(__table_.__node_alloc());} - - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY - bool empty() const _NOEXCEPT {return __table_.size() == 0;} - _LIBCPP_INLINE_VISIBILITY - size_type size() const _NOEXCEPT {return __table_.size();} - _LIBCPP_INLINE_VISIBILITY - size_type max_size() const _NOEXCEPT {return __table_.max_size();} - - _LIBCPP_INLINE_VISIBILITY - iterator begin() _NOEXCEPT {return __table_.begin();} - _LIBCPP_INLINE_VISIBILITY - iterator end() _NOEXCEPT {return __table_.end();} - _LIBCPP_INLINE_VISIBILITY - const_iterator begin() const _NOEXCEPT {return __table_.begin();} - _LIBCPP_INLINE_VISIBILITY - const_iterator end() const _NOEXCEPT {return __table_.end();} - _LIBCPP_INLINE_VISIBILITY - const_iterator cbegin() const _NOEXCEPT {return __table_.begin();} - _LIBCPP_INLINE_VISIBILITY - const_iterator cend() const _NOEXCEPT {return __table_.end();} - - _LIBCPP_INLINE_VISIBILITY - iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);} - - _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __p, const value_type& __x) - {return __table_.__insert_multi(__p.__i_, __x);} - - template <class _InputIterator> - _LIBCPP_INLINE_VISIBILITY - void insert(_InputIterator __first, _InputIterator __last); - -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - void insert(initializer_list<value_type> __il) - {insert(__il.begin(), __il.end());} - _LIBCPP_INLINE_VISIBILITY - iterator insert(value_type&& __x) {return __table_.__insert_multi(_VSTD::move(__x));} - - _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __p, value_type&& __x) - {return __table_.__insert_multi(__p.__i_, _VSTD::move(__x));} - - template <class _Pp, - class = typename enable_if<is_constructible<value_type, _Pp>::value>::type> - _LIBCPP_INLINE_VISIBILITY - iterator insert(_Pp&& __x) - {return __table_.__insert_multi(_VSTD::forward<_Pp>(__x));} - - template <class _Pp, - class = typename enable_if<is_constructible<value_type, _Pp>::value>::type> - _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __p, _Pp&& __x) - {return __table_.__insert_multi(__p.__i_, _VSTD::forward<_Pp>(__x));} - - template <class... _Args> - iterator emplace(_Args&&... __args) { - return __table_.__emplace_multi(_VSTD::forward<_Args>(__args)...); - } - - template <class... _Args> - iterator emplace_hint(const_iterator __p, _Args&&... __args) { - return __table_.__emplace_hint_multi(__p.__i_, _VSTD::forward<_Args>(__args)...); - } -#endif // _LIBCPP_CXX03_LANG - - - _LIBCPP_INLINE_VISIBILITY - iterator erase(const_iterator __p) {return __table_.erase(__p.__i_);} - _LIBCPP_INLINE_VISIBILITY - iterator erase(iterator __p) {return __table_.erase(__p.__i_);} - _LIBCPP_INLINE_VISIBILITY - size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);} - _LIBCPP_INLINE_VISIBILITY - iterator erase(const_iterator __first, const_iterator __last) - {return __table_.erase(__first.__i_, __last.__i_);} - _LIBCPP_INLINE_VISIBILITY - void clear() _NOEXCEPT {__table_.clear();} - -#if _LIBCPP_STD_VER > 14 - _LIBCPP_INLINE_VISIBILITY - iterator insert(node_type&& __nh) - { - _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), - "node_type with incompatible allocator passed to unordered_multimap::insert()"); - return __table_.template __node_handle_insert_multi<node_type>( - _VSTD::move(__nh)); - } - _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __hint, node_type&& __nh) - { - _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), - "node_type with incompatible allocator passed to unordered_multimap::insert()"); - return __table_.template __node_handle_insert_multi<node_type>( - __hint.__i_, _VSTD::move(__nh)); - } - _LIBCPP_INLINE_VISIBILITY - node_type extract(key_type const& __key) - { - return __table_.template __node_handle_extract<node_type>(__key); - } - _LIBCPP_INLINE_VISIBILITY - node_type extract(const_iterator __it) - { - return __table_.template __node_handle_extract<node_type>( - __it.__i_); - } - - template <class _H2, class _P2> - _LIBCPP_INLINE_VISIBILITY - void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - return __table_.__node_handle_merge_multi(__source.__table_); - } - template <class _H2, class _P2> - _LIBCPP_INLINE_VISIBILITY - void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>&& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - return __table_.__node_handle_merge_multi(__source.__table_); - } - template <class _H2, class _P2> - _LIBCPP_INLINE_VISIBILITY - void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - return __table_.__node_handle_merge_multi(__source.__table_); - } - template <class _H2, class _P2> - _LIBCPP_INLINE_VISIBILITY - void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>&& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - return __table_.__node_handle_merge_multi(__source.__table_); - } -#endif - - _LIBCPP_INLINE_VISIBILITY - void swap(unordered_multimap& __u) - _NOEXCEPT_(__is_nothrow_swappable<__table>::value) - {__table_.swap(__u.__table_);} - - _LIBCPP_INLINE_VISIBILITY - hasher hash_function() const - {return __table_.hash_function().hash_function();} - _LIBCPP_INLINE_VISIBILITY - key_equal key_eq() const - {return __table_.key_eq().key_eq();} - - _LIBCPP_INLINE_VISIBILITY - iterator find(const key_type& __k) {return __table_.find(__k);} - _LIBCPP_INLINE_VISIBILITY - const_iterator find(const key_type& __k) const {return __table_.find(__k);} -#if _LIBCPP_STD_VER > 17 - template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - iterator find(const _K2& __k) {return __table_.find(__k);} - template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - const_iterator find(const _K2& __k) const {return __table_.find(__k);} -#endif // _LIBCPP_STD_VER > 17 - - _LIBCPP_INLINE_VISIBILITY - size_type count(const key_type& __k) const {return __table_.__count_multi(__k);} -#if _LIBCPP_STD_VER > 17 - template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - size_type count(const _K2& __k) const {return __table_.__count_multi(__k);} -#endif // _LIBCPP_STD_VER > 17 - -#if _LIBCPP_STD_VER > 17 - _LIBCPP_INLINE_VISIBILITY - bool contains(const key_type& __k) const {return find(__k) != end();} - - template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - bool contains(const _K2& __k) const {return find(__k) != end();} -#endif // _LIBCPP_STD_VER > 17 - - _LIBCPP_INLINE_VISIBILITY - pair<iterator, iterator> equal_range(const key_type& __k) - {return __table_.__equal_range_multi(__k);} - _LIBCPP_INLINE_VISIBILITY - pair<const_iterator, const_iterator> equal_range(const key_type& __k) const - {return __table_.__equal_range_multi(__k);} -#if _LIBCPP_STD_VER > 17 - template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - pair<iterator, iterator> equal_range(const _K2& __k) - {return __table_.__equal_range_multi(__k);} - template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - pair<const_iterator, const_iterator> equal_range(const _K2& __k) const - {return __table_.__equal_range_multi(__k);} -#endif // _LIBCPP_STD_VER > 17 - - _LIBCPP_INLINE_VISIBILITY - size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();} - _LIBCPP_INLINE_VISIBILITY - size_type max_bucket_count() const _NOEXCEPT - {return __table_.max_bucket_count();} - - _LIBCPP_INLINE_VISIBILITY - size_type bucket_size(size_type __n) const - {return __table_.bucket_size(__n);} - _LIBCPP_INLINE_VISIBILITY - size_type bucket(const key_type& __k) const {return __table_.bucket(__k);} - - _LIBCPP_INLINE_VISIBILITY - local_iterator begin(size_type __n) {return __table_.begin(__n);} - _LIBCPP_INLINE_VISIBILITY - local_iterator end(size_type __n) {return __table_.end(__n);} - _LIBCPP_INLINE_VISIBILITY - const_local_iterator begin(size_type __n) const {return __table_.cbegin(__n);} - _LIBCPP_INLINE_VISIBILITY - const_local_iterator end(size_type __n) const {return __table_.cend(__n);} - _LIBCPP_INLINE_VISIBILITY - const_local_iterator cbegin(size_type __n) const {return __table_.cbegin(__n);} - _LIBCPP_INLINE_VISIBILITY - const_local_iterator cend(size_type __n) const {return __table_.cend(__n);} - - _LIBCPP_INLINE_VISIBILITY - float load_factor() const _NOEXCEPT {return __table_.load_factor();} - _LIBCPP_INLINE_VISIBILITY - float max_load_factor() const _NOEXCEPT {return __table_.max_load_factor();} - _LIBCPP_INLINE_VISIBILITY - void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);} - _LIBCPP_INLINE_VISIBILITY - void rehash(size_type __n) {__table_.rehash(__n);} - _LIBCPP_INLINE_VISIBILITY - void reserve(size_type __n) {__table_.reserve(__n);} - -#if _LIBCPP_DEBUG_LEVEL == 2 - - bool __dereferenceable(const const_iterator* __i) const - {return __table_.__dereferenceable(_VSTD::addressof(__i->__i_));} - bool __decrementable(const const_iterator* __i) const - {return __table_.__decrementable(_VSTD::addressof(__i->__i_));} - bool __addable(const const_iterator* __i, ptrdiff_t __n) const - {return __table_.__addable(_VSTD::addressof(__i->__i_), __n);} - bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const - {return __table_.__addable(_VSTD::addressof(__i->__i_), __n);} - -#endif // _LIBCPP_DEBUG_LEVEL == 2 - - -}; - -#if _LIBCPP_STD_VER >= 17 -template<class _InputIterator, - class _Hash = hash<__iter_key_type<_InputIterator>>, - class _Pred = equal_to<__iter_key_type<_InputIterator>>, - class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = enable_if_t<!__is_allocator<_Hash>::value>, - class = enable_if_t<!is_integral<_Hash>::value>, - class = enable_if_t<!__is_allocator<_Pred>::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_multimap(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type = 0, - _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) - -> unordered_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Hash, _Pred, _Allocator>; - -template<class _Key, class _Tp, class _Hash = hash<remove_const_t<_Key>>, - class _Pred = equal_to<remove_const_t<_Key>>, - class _Allocator = allocator<pair<const _Key, _Tp>>, - class = enable_if_t<!__is_allocator<_Hash>::value>, - class = enable_if_t<!is_integral<_Hash>::value>, - class = enable_if_t<!__is_allocator<_Pred>::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_multimap(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allocator>::size_type = 0, - _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) - -> unordered_multimap<remove_const_t<_Key>, _Tp, _Hash, _Pred, _Allocator>; - -template<class _InputIterator, class _Allocator, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_multimap(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Allocator) - -> unordered_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, - hash<__iter_key_type<_InputIterator>>, equal_to<__iter_key_type<_InputIterator>>, _Allocator>; - -template<class _InputIterator, class _Allocator, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_multimap(_InputIterator, _InputIterator, _Allocator) - -> unordered_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, - hash<__iter_key_type<_InputIterator>>, equal_to<__iter_key_type<_InputIterator>>, _Allocator>; - -template<class _InputIterator, class _Hash, class _Allocator, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = enable_if_t<!__is_allocator<_Hash>::value>, - class = enable_if_t<!is_integral<_Hash>::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_multimap(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator) - -> unordered_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, - _Hash, equal_to<__iter_key_type<_InputIterator>>, _Allocator>; - -template<class _Key, class _Tp, class _Allocator, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_multimap(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allocator>::size_type, _Allocator) - -> unordered_multimap<remove_const_t<_Key>, _Tp, - hash<remove_const_t<_Key>>, - equal_to<remove_const_t<_Key>>, _Allocator>; - -template<class _Key, class _Tp, class _Allocator, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_multimap(initializer_list<pair<_Key, _Tp>>, _Allocator) - -> unordered_multimap<remove_const_t<_Key>, _Tp, - hash<remove_const_t<_Key>>, - equal_to<remove_const_t<_Key>>, _Allocator>; - -template<class _Key, class _Tp, class _Hash, class _Allocator, - class = enable_if_t<!__is_allocator<_Hash>::value>, - class = enable_if_t<!is_integral<_Hash>::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_multimap(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator) - -> unordered_multimap<remove_const_t<_Key>, _Tp, _Hash, - equal_to<remove_const_t<_Key>>, _Allocator>; -#endif - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - size_type __n, const hasher& __hf, const key_equal& __eql) - : __table_(__hf, __eql) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__n); -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - size_type __n, const hasher& __hf, const key_equal& __eql, - const allocator_type& __a) - : __table_(__hf, __eql, typename __table::allocator_type(__a)) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__n); -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -template <class _InputIterator> -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - _InputIterator __first, _InputIterator __last) -{ - _VSTD::__debug_db_insert_c(this); - insert(__first, __last); -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -template <class _InputIterator> -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - _InputIterator __first, _InputIterator __last, size_type __n, - const hasher& __hf, const key_equal& __eql) - : __table_(__hf, __eql) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__n); - insert(__first, __last); -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -template <class _InputIterator> -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - _InputIterator __first, _InputIterator __last, size_type __n, - const hasher& __hf, const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, typename __table::allocator_type(__a)) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__n); - insert(__first, __last); -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - const allocator_type& __a) - : __table_(typename __table::allocator_type(__a)) -{ - _VSTD::__debug_db_insert_c(this); -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - const unordered_multimap& __u) - : __table_(__u.__table_) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__u.bucket_count()); - insert(__u.begin(), __u.end()); -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - const unordered_multimap& __u, const allocator_type& __a) - : __table_(__u.__table_, typename __table::allocator_type(__a)) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__u.bucket_count()); - insert(__u.begin(), __u.end()); -} - -#ifndef _LIBCPP_CXX03_LANG - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - unordered_multimap&& __u) - _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) - : __table_(_VSTD::move(__u.__table_)) -{ - _VSTD::__debug_db_insert_c(this); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->swap(this, _VSTD::addressof(__u)); -#endif -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - unordered_multimap&& __u, const allocator_type& __a) - : __table_(_VSTD::move(__u.__table_), typename __table::allocator_type(__a)) -{ - _VSTD::__debug_db_insert_c(this); - if (__a != __u.get_allocator()) - { - iterator __i = __u.begin(); - while (__u.size() != 0) - { - __table_.__insert_multi( - __u.__table_.remove((__i++).__i_)->__value_.__move()); - } - } -#if _LIBCPP_DEBUG_LEVEL == 2 - else - __get_db()->swap(this, _VSTD::addressof(__u)); -#endif -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - initializer_list<value_type> __il) -{ - _VSTD::__debug_db_insert_c(this); - insert(__il.begin(), __il.end()); -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - initializer_list<value_type> __il, size_type __n, const hasher& __hf, - const key_equal& __eql) - : __table_(__hf, __eql) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__n); - insert(__il.begin(), __il.end()); -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - initializer_list<value_type> __il, size_type __n, const hasher& __hf, - const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, typename __table::allocator_type(__a)) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__n); - insert(__il.begin(), __il.end()); -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_multimap&& __u) - _NOEXCEPT_(is_nothrow_move_assignable<__table>::value) -{ - __table_ = _VSTD::move(__u.__table_); - return *this; -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=( - initializer_list<value_type> __il) -{ - __table_.__assign_multi(__il.begin(), __il.end()); - return *this; -} - -#endif // _LIBCPP_CXX03_LANG - - - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -template <class _InputIterator> -inline -void -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, - _InputIterator __last) -{ - for (; __first != __last; ++__first) - __table_.__insert_multi(*__first); -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -void -swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, - unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) - _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) -{ - __x.swap(__y); -} - -#if _LIBCPP_STD_VER > 17 -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, - class _Predicate> -inline _LIBCPP_INLINE_VISIBILITY - typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::size_type - erase_if(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __c, - _Predicate __pred) { - return _VSTD::__libcpp_erase_if_container(__c, __pred); -} -#endif - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -bool -operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, - const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) -{ - if (__x.size() != __y.size()) - return false; - typedef typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator - const_iterator; - typedef pair<const_iterator, const_iterator> _EqRng; - for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;) - { - _EqRng __xeq = __x.equal_range(__i->first); - _EqRng __yeq = __y.equal_range(__i->first); - if (_VSTD::distance(__xeq.first, __xeq.second) != - _VSTD::distance(__yeq.first, __yeq.second) || - !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first)) - return false; - __i = __xeq.second; - } - return true; -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, - const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) -{ - return !(__x == __y); -} - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP_UNORDERED_MAP diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/unordered_set b/contrib/libs/cxxsupp/libcxxmsvc/include/unordered_set deleted file mode 100644 index 2f902cc793..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/unordered_set +++ /dev/null @@ -1,1807 +0,0 @@ -// -*- 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_UNORDERED_SET -#define _LIBCPP_UNORDERED_SET - -/* - - unordered_set synopsis - -#include <initializer_list> - -namespace std -{ - -template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>, - class Alloc = allocator<Value>> -class unordered_set -{ -public: - // types - typedef Value key_type; - typedef key_type value_type; - typedef Hash hasher; - typedef Pred key_equal; - typedef Alloc allocator_type; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef typename allocator_traits<allocator_type>::pointer pointer; - typedef typename allocator_traits<allocator_type>::const_pointer const_pointer; - typedef typename allocator_traits<allocator_type>::size_type size_type; - typedef typename allocator_traits<allocator_type>::difference_type difference_type; - - typedef /unspecified/ iterator; - typedef /unspecified/ const_iterator; - typedef /unspecified/ local_iterator; - typedef /unspecified/ const_local_iterator; - - typedef unspecified node_type unspecified; // C++17 - typedef INSERT_RETURN_TYPE<iterator, node_type> insert_return_type; // C++17 - - unordered_set() - noexcept( - is_nothrow_default_constructible<hasher>::value && - is_nothrow_default_constructible<key_equal>::value && - is_nothrow_default_constructible<allocator_type>::value); - explicit unordered_set(size_type n, const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - template <class InputIterator> - unordered_set(InputIterator f, InputIterator l, - size_type n = 0, const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - explicit unordered_set(const allocator_type&); - unordered_set(const unordered_set&); - unordered_set(const unordered_set&, const Allocator&); - unordered_set(unordered_set&&) - noexcept( - is_nothrow_move_constructible<hasher>::value && - is_nothrow_move_constructible<key_equal>::value && - is_nothrow_move_constructible<allocator_type>::value); - unordered_set(unordered_set&&, const Allocator&); - unordered_set(initializer_list<value_type>, size_type n = 0, - const hasher& hf = hasher(), const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - unordered_set(size_type n, const allocator_type& a); // C++14 - unordered_set(size_type n, const hasher& hf, const allocator_type& a); // C++14 - template <class InputIterator> - unordered_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a); // C++14 - template <class InputIterator> - unordered_set(InputIterator f, InputIterator l, size_type n, - const hasher& hf, const allocator_type& a); // C++14 - unordered_set(initializer_list<value_type> il, size_type n, const allocator_type& a); // C++14 - unordered_set(initializer_list<value_type> il, size_type n, - const hasher& hf, const allocator_type& a); // C++14 - ~unordered_set(); - unordered_set& operator=(const unordered_set&); - unordered_set& operator=(unordered_set&&) - noexcept( - allocator_type::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<allocator_type>::value && - is_nothrow_move_assignable<hasher>::value && - is_nothrow_move_assignable<key_equal>::value); - unordered_set& operator=(initializer_list<value_type>); - - allocator_type get_allocator() const noexcept; - - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; - - iterator begin() noexcept; - iterator end() noexcept; - const_iterator begin() const noexcept; - const_iterator end() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - - template <class... Args> - pair<iterator, bool> emplace(Args&&... args); - template <class... Args> - iterator emplace_hint(const_iterator position, Args&&... args); - pair<iterator, bool> insert(const value_type& obj); - pair<iterator, bool> insert(value_type&& obj); - iterator insert(const_iterator hint, const value_type& obj); - iterator insert(const_iterator hint, value_type&& obj); - template <class InputIterator> - void insert(InputIterator first, InputIterator last); - void insert(initializer_list<value_type>); - - node_type extract(const_iterator position); // C++17 - node_type extract(const key_type& x); // C++17 - insert_return_type insert(node_type&& nh); // C++17 - iterator insert(const_iterator hint, node_type&& nh); // C++17 - - iterator erase(const_iterator position); - iterator erase(iterator position); // C++14 - size_type erase(const key_type& k); - iterator erase(const_iterator first, const_iterator last); - void clear() noexcept; - - template<class H2, class P2> - void merge(unordered_set<Key, H2, P2, Allocator>& source); // C++17 - template<class H2, class P2> - void merge(unordered_set<Key, H2, P2, Allocator>&& source); // C++17 - template<class H2, class P2> - void merge(unordered_multiset<Key, H2, P2, Allocator>& source); // C++17 - template<class H2, class P2> - void merge(unordered_multiset<Key, H2, P2, Allocator>&& source); // C++17 - - void swap(unordered_set&) - noexcept(allocator_traits<Allocator>::is_always_equal::value && - noexcept(swap(declval<hasher&>(), declval<hasher&>())) && - noexcept(swap(declval<key_equal&>(), declval<key_equal&>()))); // C++17 - - hasher hash_function() const; - key_equal key_eq() const; - - iterator find(const key_type& k); - const_iterator find(const key_type& k) const; - template<typename K> - iterator find(const K& x); // C++20 - template<typename K> - const_iterator find(const K& x) const; // C++20 - size_type count(const key_type& k) const; - template<typename K> - size_type count(const K& k) const; // C++20 - bool contains(const key_type& k) const; // C++20 - template<typename K> - bool contains(const K& k) const; // C++20 - pair<iterator, iterator> equal_range(const key_type& k); - pair<const_iterator, const_iterator> equal_range(const key_type& k) const; - template<typename K> - pair<iterator, iterator> equal_range(const K& k); // C++20 - template<typename K> - pair<const_iterator, const_iterator> equal_range(const K& k) const; // C++20 - - size_type bucket_count() const noexcept; - size_type max_bucket_count() const noexcept; - - size_type bucket_size(size_type n) const; - size_type bucket(const key_type& k) const; - - local_iterator begin(size_type n); - local_iterator end(size_type n); - const_local_iterator begin(size_type n) const; - const_local_iterator end(size_type n) const; - const_local_iterator cbegin(size_type n) const; - const_local_iterator cend(size_type n) const; - - float load_factor() const noexcept; - float max_load_factor() const noexcept; - void max_load_factor(float z); - void rehash(size_type n); - void reserve(size_type n); -}; - -template<class InputIterator, - class Hash = hash<typename iterator_traits<InputIterator>::value_type>, - class Pred = equal_to<typename iterator_traits<InputIterator>::value_type>, - class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>> -unordered_set(InputIterator, InputIterator, typename see below::size_type = see below, - Hash = Hash(), Pred = Pred(), Allocator = Allocator()) - -> unordered_set<typename iterator_traits<InputIterator>::value_type, - Hash, Pred, Allocator>; // C++17 - -template<class T, class Hash = hash<T>, - class Pred = equal_to<T>, class Allocator = allocator<T>> -unordered_set(initializer_list<T>, typename see below::size_type = see below, - Hash = Hash(), Pred = Pred(), Allocator = Allocator()) - -> unordered_set<T, Hash, Pred, Allocator>; // C++17 - -template<class InputIterator, class Allocator> -unordered_set(InputIterator, InputIterator, typename see below::size_type, Allocator) - -> unordered_set<typename iterator_traits<InputIterator>::value_type, - hash<typename iterator_traits<InputIterator>::value_type>, - equal_to<typename iterator_traits<InputIterator>::value_type>, - Allocator>; // C++17 - -template<class InputIterator, class Hash, class Allocator> -unordered_set(InputIterator, InputIterator, typename see below::size_type, - Hash, Allocator) - -> unordered_set<typename iterator_traits<InputIterator>::value_type, Hash, - equal_to<typename iterator_traits<InputIterator>::value_type>, - Allocator>; // C++17 - -template<class T, class Allocator> -unordered_set(initializer_list<T>, typename see below::size_type, Allocator) - -> unordered_set<T, hash<T>, equal_to<T>, Allocator>; // C++17 - -template<class T, class Hash, class Allocator> -unordered_set(initializer_list<T>, typename see below::size_type, Hash, Allocator) - -> unordered_set<T, Hash, equal_to<T>, Allocator>; // C++17 - -template <class Value, class Hash, class Pred, class Alloc> - void swap(unordered_set<Value, Hash, Pred, Alloc>& x, - unordered_set<Value, Hash, Pred, Alloc>& y) - noexcept(noexcept(x.swap(y))); - -template <class Value, class Hash, class Pred, class Alloc> - bool - operator==(const unordered_set<Value, Hash, Pred, Alloc>& x, - const unordered_set<Value, Hash, Pred, Alloc>& y); - -template <class Value, class Hash, class Pred, class Alloc> - bool - operator!=(const unordered_set<Value, Hash, Pred, Alloc>& x, - const unordered_set<Value, Hash, Pred, Alloc>& y); - -template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>, - class Alloc = allocator<Value>> -class unordered_multiset -{ -public: - // types - typedef Value key_type; - typedef key_type value_type; - typedef Hash hasher; - typedef Pred key_equal; - typedef Alloc allocator_type; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef typename allocator_traits<allocator_type>::pointer pointer; - typedef typename allocator_traits<allocator_type>::const_pointer const_pointer; - typedef typename allocator_traits<allocator_type>::size_type size_type; - typedef typename allocator_traits<allocator_type>::difference_type difference_type; - - typedef /unspecified/ iterator; - typedef /unspecified/ const_iterator; - typedef /unspecified/ local_iterator; - typedef /unspecified/ const_local_iterator; - - typedef unspecified node_type unspecified; // C++17 - - unordered_multiset() - noexcept( - is_nothrow_default_constructible<hasher>::value && - is_nothrow_default_constructible<key_equal>::value && - is_nothrow_default_constructible<allocator_type>::value); - explicit unordered_multiset(size_type n, const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - template <class InputIterator> - unordered_multiset(InputIterator f, InputIterator l, - size_type n = 0, const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - explicit unordered_multiset(const allocator_type&); - unordered_multiset(const unordered_multiset&); - unordered_multiset(const unordered_multiset&, const Allocator&); - unordered_multiset(unordered_multiset&&) - noexcept( - is_nothrow_move_constructible<hasher>::value && - is_nothrow_move_constructible<key_equal>::value && - is_nothrow_move_constructible<allocator_type>::value); - unordered_multiset(unordered_multiset&&, const Allocator&); - unordered_multiset(initializer_list<value_type>, size_type n = /see below/, - const hasher& hf = hasher(), const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - unordered_multiset(size_type n, const allocator_type& a); // C++14 - unordered_multiset(size_type n, const hasher& hf, const allocator_type& a); // C++14 - template <class InputIterator> - unordered_multiset(InputIterator f, InputIterator l, size_type n, const allocator_type& a); // C++14 - template <class InputIterator> - unordered_multiset(InputIterator f, InputIterator l, size_type n, - const hasher& hf, const allocator_type& a); // C++14 - unordered_multiset(initializer_list<value_type> il, size_type n, const allocator_type& a); // C++14 - unordered_multiset(initializer_list<value_type> il, size_type n, - const hasher& hf, const allocator_type& a); // C++14 - ~unordered_multiset(); - unordered_multiset& operator=(const unordered_multiset&); - unordered_multiset& operator=(unordered_multiset&&) - noexcept( - allocator_type::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<allocator_type>::value && - is_nothrow_move_assignable<hasher>::value && - is_nothrow_move_assignable<key_equal>::value); - unordered_multiset& operator=(initializer_list<value_type>); - - allocator_type get_allocator() const noexcept; - - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; - - iterator begin() noexcept; - iterator end() noexcept; - const_iterator begin() const noexcept; - const_iterator end() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - - template <class... Args> - iterator emplace(Args&&... args); - template <class... Args> - iterator emplace_hint(const_iterator position, Args&&... args); - iterator insert(const value_type& obj); - iterator insert(value_type&& obj); - iterator insert(const_iterator hint, const value_type& obj); - iterator insert(const_iterator hint, value_type&& obj); - template <class InputIterator> - void insert(InputIterator first, InputIterator last); - void insert(initializer_list<value_type>); - - node_type extract(const_iterator position); // C++17 - node_type extract(const key_type& x); // C++17 - iterator insert(node_type&& nh); // C++17 - iterator insert(const_iterator hint, node_type&& nh); // C++17 - - iterator erase(const_iterator position); - iterator erase(iterator position); // C++14 - size_type erase(const key_type& k); - iterator erase(const_iterator first, const_iterator last); - void clear() noexcept; - - template<class H2, class P2> - void merge(unordered_multiset<Key, H2, P2, Allocator>& source); // C++17 - template<class H2, class P2> - void merge(unordered_multiset<Key, H2, P2, Allocator>&& source); // C++17 - template<class H2, class P2> - void merge(unordered_set<Key, H2, P2, Allocator>& source); // C++17 - template<class H2, class P2> - void merge(unordered_set<Key, H2, P2, Allocator>&& source); // C++17 - - void swap(unordered_multiset&) - noexcept(allocator_traits<Allocator>::is_always_equal::value && - noexcept(swap(declval<hasher&>(), declval<hasher&>())) && - noexcept(swap(declval<key_equal&>(), declval<key_equal&>()))); // C++17 - - hasher hash_function() const; - key_equal key_eq() const; - - iterator find(const key_type& k); - const_iterator find(const key_type& k) const; - template<typename K> - iterator find(const K& x); // C++20 - template<typename K> - const_iterator find(const K& x) const; // C++20 - size_type count(const key_type& k) const; - template<typename K> - size_type count(const K& k) const; // C++20 - bool contains(const key_type& k) const; // C++20 - template<typename K> - bool contains(const K& k) const; // C++20 - pair<iterator, iterator> equal_range(const key_type& k); - pair<const_iterator, const_iterator> equal_range(const key_type& k) const; - template<typename K> - pair<iterator, iterator> equal_range(const K& k); // C++20 - template<typename K> - pair<const_iterator, const_iterator> equal_range(const K& k) const; // C++20 - - size_type bucket_count() const noexcept; - size_type max_bucket_count() const noexcept; - - size_type bucket_size(size_type n) const; - size_type bucket(const key_type& k) const; - - local_iterator begin(size_type n); - local_iterator end(size_type n); - const_local_iterator begin(size_type n) const; - const_local_iterator end(size_type n) const; - const_local_iterator cbegin(size_type n) const; - const_local_iterator cend(size_type n) const; - - float load_factor() const noexcept; - float max_load_factor() const noexcept; - void max_load_factor(float z); - void rehash(size_type n); - void reserve(size_type n); -}; - -template<class InputIterator, - class Hash = hash<typename iterator_traits<InputIterator>::value_type>, - class Pred = equal_to<typename iterator_traits<InputIterator>::value_type>, - class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>> -unordered_multiset(InputIterator, InputIterator, see below::size_type = see below, - Hash = Hash(), Pred = Pred(), Allocator = Allocator()) - -> unordered_multiset<typename iterator_traits<InputIterator>::value_type, - Hash, Pred, Allocator>; // C++17 - -template<class T, class Hash = hash<T>, - class Pred = equal_to<T>, class Allocator = allocator<T>> -unordered_multiset(initializer_list<T>, typename see below::size_type = see below, - Hash = Hash(), Pred = Pred(), Allocator = Allocator()) - -> unordered_multiset<T, Hash, Pred, Allocator>; // C++17 - -template<class InputIterator, class Allocator> -unordered_multiset(InputIterator, InputIterator, typename see below::size_type, Allocator) - -> unordered_multiset<typename iterator_traits<InputIterator>::value_type, - hash<typename iterator_traits<InputIterator>::value_type>, - equal_to<typename iterator_traits<InputIterator>::value_type>, - Allocator>; // C++17 - -template<class InputIterator, class Hash, class Allocator> -unordered_multiset(InputIterator, InputIterator, typename see below::size_type, - Hash, Allocator) - -> unordered_multiset<typename iterator_traits<InputIterator>::value_type, Hash, - equal_to<typename iterator_traits<InputIterator>::value_type>, Allocator>; // C++17 - -template<class T, class Allocator> -unordered_multiset(initializer_list<T>, typename see below::size_type, Allocator) - -> unordered_multiset<T, hash<T>, equal_to<T>, Allocator>; // C++17 - -template<class T, class Hash, class Allocator> -unordered_multiset(initializer_list<T>, typename see below::size_type, Hash, Allocator) - -> unordered_multiset<T, Hash, equal_to<T>, Allocator>; // C++17 - -template <class Value, class Hash, class Pred, class Alloc> - void swap(unordered_multiset<Value, Hash, Pred, Alloc>& x, - unordered_multiset<Value, Hash, Pred, Alloc>& y) - noexcept(noexcept(x.swap(y))); - -template <class K, class T, class H, class P, class A, class Predicate> - typename unordered_set<K, T, H, P, A>::size_type - erase_if(unordered_set<K, T, H, P, A>& c, Predicate pred); // C++20 - -template <class K, class T, class H, class P, class A, class Predicate> - typename unordered_multiset<K, T, H, P, A>::size_type - erase_if(unordered_multiset<K, T, H, P, A>& c, Predicate pred); // C++20 - - -template <class Value, class Hash, class Pred, class Alloc> - bool - operator==(const unordered_multiset<Value, Hash, Pred, Alloc>& x, - const unordered_multiset<Value, Hash, Pred, Alloc>& y); - -template <class Value, class Hash, class Pred, class Alloc> - bool - operator!=(const unordered_multiset<Value, Hash, Pred, Alloc>& x, - const unordered_multiset<Value, Hash, Pred, Alloc>& y); -} // std - -*/ - -#include <__algorithm/is_permutation.h> -#include <__assert> -#include <__config> -#include <__debug> -#include <__functional/is_transparent.h> -#include <__hash_table> -#include <__memory/addressof.h> -#include <__node_handle> -#include <__utility/forward.h> -#include <compare> -#include <functional> -#include <iterator> // __libcpp_erase_if_container -#include <version> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -template <class _Value, class _Hash, class _Pred, class _Alloc> -class unordered_multiset; - -template <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>, - class _Alloc = allocator<_Value> > -class _LIBCPP_TEMPLATE_VIS unordered_set -{ -public: - // types - typedef _Value key_type; - typedef key_type value_type; - typedef __identity_t<_Hash> hasher; - typedef __identity_t<_Pred> key_equal; - typedef __identity_t<_Alloc> allocator_type; - typedef value_type& reference; - typedef const value_type& const_reference; - static_assert((is_same<value_type, typename allocator_type::value_type>::value), - "Invalid allocator::value_type"); - -private: - typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table; - - __table __table_; - -public: - typedef typename __table::pointer pointer; - typedef typename __table::const_pointer const_pointer; - typedef typename __table::size_type size_type; - typedef typename __table::difference_type difference_type; - - typedef typename __table::const_iterator iterator; - typedef typename __table::const_iterator const_iterator; - typedef typename __table::const_local_iterator local_iterator; - typedef typename __table::const_local_iterator const_local_iterator; - -#if _LIBCPP_STD_VER > 14 - typedef __set_node_handle<typename __table::__node, allocator_type> node_type; - typedef __insert_return_type<iterator, node_type> insert_return_type; -#endif - - template <class _Value2, class _Hash2, class _Pred2, class _Alloc2> - friend class _LIBCPP_TEMPLATE_VIS unordered_set; - template <class _Value2, class _Hash2, class _Pred2, class _Alloc2> - friend class _LIBCPP_TEMPLATE_VIS unordered_multiset; - - _LIBCPP_INLINE_VISIBILITY - unordered_set() - _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) - { - _VSTD::__debug_db_insert_c(this); - } - explicit unordered_set(size_type __n, const hasher& __hf = hasher(), - const key_equal& __eql = key_equal()); -#if _LIBCPP_STD_VER > 11 - inline _LIBCPP_INLINE_VISIBILITY - unordered_set(size_type __n, const allocator_type& __a) - : unordered_set(__n, hasher(), key_equal(), __a) {} - inline _LIBCPP_INLINE_VISIBILITY - unordered_set(size_type __n, const hasher& __hf, const allocator_type& __a) - : unordered_set(__n, __hf, key_equal(), __a) {} -#endif - unordered_set(size_type __n, const hasher& __hf, const key_equal& __eql, - const allocator_type& __a); - template <class _InputIterator> - unordered_set(_InputIterator __first, _InputIterator __last); - template <class _InputIterator> - unordered_set(_InputIterator __first, _InputIterator __last, - size_type __n, const hasher& __hf = hasher(), - const key_equal& __eql = key_equal()); - template <class _InputIterator> - unordered_set(_InputIterator __first, _InputIterator __last, - size_type __n, const hasher& __hf, const key_equal& __eql, - const allocator_type& __a); -#if _LIBCPP_STD_VER > 11 - template <class _InputIterator> - inline _LIBCPP_INLINE_VISIBILITY - unordered_set(_InputIterator __first, _InputIterator __last, - size_type __n, const allocator_type& __a) - : unordered_set(__first, __last, __n, hasher(), key_equal(), __a) {} - template <class _InputIterator> - unordered_set(_InputIterator __first, _InputIterator __last, - size_type __n, const hasher& __hf, const allocator_type& __a) - : unordered_set(__first, __last, __n, __hf, key_equal(), __a) {} -#endif - _LIBCPP_INLINE_VISIBILITY - explicit unordered_set(const allocator_type& __a); - unordered_set(const unordered_set& __u); - unordered_set(const unordered_set& __u, const allocator_type& __a); -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - unordered_set(unordered_set&& __u) - _NOEXCEPT_(is_nothrow_move_constructible<__table>::value); - unordered_set(unordered_set&& __u, const allocator_type& __a); - unordered_set(initializer_list<value_type> __il); - unordered_set(initializer_list<value_type> __il, size_type __n, - const hasher& __hf = hasher(), - const key_equal& __eql = key_equal()); - unordered_set(initializer_list<value_type> __il, size_type __n, - const hasher& __hf, const key_equal& __eql, - const allocator_type& __a); -#if _LIBCPP_STD_VER > 11 - inline _LIBCPP_INLINE_VISIBILITY - unordered_set(initializer_list<value_type> __il, size_type __n, - const allocator_type& __a) - : unordered_set(__il, __n, hasher(), key_equal(), __a) {} - inline _LIBCPP_INLINE_VISIBILITY - unordered_set(initializer_list<value_type> __il, size_type __n, - const hasher& __hf, const allocator_type& __a) - : unordered_set(__il, __n, __hf, key_equal(), __a) {} -#endif -#endif // _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - ~unordered_set() { - static_assert(sizeof(__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), ""); - } - - _LIBCPP_INLINE_VISIBILITY - unordered_set& operator=(const unordered_set& __u) - { - __table_ = __u.__table_; - return *this; - } -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - unordered_set& operator=(unordered_set&& __u) - _NOEXCEPT_(is_nothrow_move_assignable<__table>::value); - _LIBCPP_INLINE_VISIBILITY - unordered_set& operator=(initializer_list<value_type> __il); -#endif // _LIBCPP_CXX03_LANG - - _LIBCPP_INLINE_VISIBILITY - allocator_type get_allocator() const _NOEXCEPT - {return allocator_type(__table_.__node_alloc());} - - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY - bool empty() const _NOEXCEPT {return __table_.size() == 0;} - _LIBCPP_INLINE_VISIBILITY - size_type size() const _NOEXCEPT {return __table_.size();} - _LIBCPP_INLINE_VISIBILITY - size_type max_size() const _NOEXCEPT {return __table_.max_size();} - - _LIBCPP_INLINE_VISIBILITY - iterator begin() _NOEXCEPT {return __table_.begin();} - _LIBCPP_INLINE_VISIBILITY - iterator end() _NOEXCEPT {return __table_.end();} - _LIBCPP_INLINE_VISIBILITY - const_iterator begin() const _NOEXCEPT {return __table_.begin();} - _LIBCPP_INLINE_VISIBILITY - const_iterator end() const _NOEXCEPT {return __table_.end();} - _LIBCPP_INLINE_VISIBILITY - const_iterator cbegin() const _NOEXCEPT {return __table_.begin();} - _LIBCPP_INLINE_VISIBILITY - const_iterator cend() const _NOEXCEPT {return __table_.end();} - -#ifndef _LIBCPP_CXX03_LANG - template <class... _Args> - _LIBCPP_INLINE_VISIBILITY - pair<iterator, bool> emplace(_Args&&... __args) - {return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...);} - template <class... _Args> - _LIBCPP_INLINE_VISIBILITY -#if _LIBCPP_DEBUG_LEVEL == 2 - iterator emplace_hint(const_iterator __p, _Args&&... __args) - { - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "unordered_set::emplace_hint(const_iterator, args...) called with an iterator not" - " referring to this unordered_set"); - return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first; - } -#else - iterator emplace_hint(const_iterator, _Args&&... __args) - {return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first;} -#endif - - _LIBCPP_INLINE_VISIBILITY - pair<iterator, bool> insert(value_type&& __x) - {return __table_.__insert_unique(_VSTD::move(__x));} - _LIBCPP_INLINE_VISIBILITY -#if _LIBCPP_DEBUG_LEVEL == 2 - iterator insert(const_iterator __p, value_type&& __x) - { - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "unordered_set::insert(const_iterator, value_type&&) called with an iterator not" - " referring to this unordered_set"); - return insert(_VSTD::move(__x)).first; - } -#else - iterator insert(const_iterator, value_type&& __x) - {return insert(_VSTD::move(__x)).first;} -#endif - _LIBCPP_INLINE_VISIBILITY - void insert(initializer_list<value_type> __il) - {insert(__il.begin(), __il.end());} -#endif // _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - pair<iterator, bool> insert(const value_type& __x) - {return __table_.__insert_unique(__x);} - - _LIBCPP_INLINE_VISIBILITY -#if _LIBCPP_DEBUG_LEVEL == 2 - iterator insert(const_iterator __p, const value_type& __x) - { - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "unordered_set::insert(const_iterator, const value_type&) called with an iterator not" - " referring to this unordered_set"); - return insert(__x).first; - } -#else - iterator insert(const_iterator, const value_type& __x) - {return insert(__x).first;} -#endif - template <class _InputIterator> - _LIBCPP_INLINE_VISIBILITY - void insert(_InputIterator __first, _InputIterator __last); - - _LIBCPP_INLINE_VISIBILITY - iterator erase(const_iterator __p) {return __table_.erase(__p);} - _LIBCPP_INLINE_VISIBILITY - size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);} - _LIBCPP_INLINE_VISIBILITY - iterator erase(const_iterator __first, const_iterator __last) - {return __table_.erase(__first, __last);} - _LIBCPP_INLINE_VISIBILITY - void clear() _NOEXCEPT {__table_.clear();} - -#if _LIBCPP_STD_VER > 14 - _LIBCPP_INLINE_VISIBILITY - insert_return_type insert(node_type&& __nh) - { - _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), - "node_type with incompatible allocator passed to unordered_set::insert()"); - return __table_.template __node_handle_insert_unique< - node_type, insert_return_type>(_VSTD::move(__nh)); - } - _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __h, node_type&& __nh) - { - _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), - "node_type with incompatible allocator passed to unordered_set::insert()"); - return __table_.template __node_handle_insert_unique<node_type>( - __h, _VSTD::move(__nh)); - } - _LIBCPP_INLINE_VISIBILITY - node_type extract(key_type const& __key) - { - return __table_.template __node_handle_extract<node_type>(__key); - } - _LIBCPP_INLINE_VISIBILITY - node_type extract(const_iterator __it) - { - return __table_.template __node_handle_extract<node_type>(__it); - } - - template<class _H2, class _P2> - _LIBCPP_INLINE_VISIBILITY - void merge(unordered_set<key_type, _H2, _P2, allocator_type>& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - __table_.__node_handle_merge_unique(__source.__table_); - } - template<class _H2, class _P2> - _LIBCPP_INLINE_VISIBILITY - void merge(unordered_set<key_type, _H2, _P2, allocator_type>&& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - __table_.__node_handle_merge_unique(__source.__table_); - } - template<class _H2, class _P2> - _LIBCPP_INLINE_VISIBILITY - void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - __table_.__node_handle_merge_unique(__source.__table_); - } - template<class _H2, class _P2> - _LIBCPP_INLINE_VISIBILITY - void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>&& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - __table_.__node_handle_merge_unique(__source.__table_); - } -#endif - - _LIBCPP_INLINE_VISIBILITY - void swap(unordered_set& __u) - _NOEXCEPT_(__is_nothrow_swappable<__table>::value) - {__table_.swap(__u.__table_);} - - _LIBCPP_INLINE_VISIBILITY - hasher hash_function() const {return __table_.hash_function();} - _LIBCPP_INLINE_VISIBILITY - key_equal key_eq() const {return __table_.key_eq();} - - _LIBCPP_INLINE_VISIBILITY - iterator find(const key_type& __k) {return __table_.find(__k);} - _LIBCPP_INLINE_VISIBILITY - const_iterator find(const key_type& __k) const {return __table_.find(__k);} -#if _LIBCPP_STD_VER > 17 - template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - iterator find(const _K2& __k) {return __table_.find(__k);} - template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - const_iterator find(const _K2& __k) const {return __table_.find(__k);} -#endif // _LIBCPP_STD_VER > 17 - - _LIBCPP_INLINE_VISIBILITY - size_type count(const key_type& __k) const {return __table_.__count_unique(__k);} -#if _LIBCPP_STD_VER > 17 - template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - size_type count(const _K2& __k) const {return __table_.__count_unique(__k);} -#endif // _LIBCPP_STD_VER > 17 - -#if _LIBCPP_STD_VER > 17 - _LIBCPP_INLINE_VISIBILITY - bool contains(const key_type& __k) const {return find(__k) != end();} - - template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - bool contains(const _K2& __k) const {return find(__k) != end();} -#endif // _LIBCPP_STD_VER > 17 - - _LIBCPP_INLINE_VISIBILITY - pair<iterator, iterator> equal_range(const key_type& __k) - {return __table_.__equal_range_unique(__k);} - _LIBCPP_INLINE_VISIBILITY - pair<const_iterator, const_iterator> equal_range(const key_type& __k) const - {return __table_.__equal_range_unique(__k);} -#if _LIBCPP_STD_VER > 17 - template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - pair<iterator, iterator> equal_range(const _K2& __k) - {return __table_.__equal_range_unique(__k);} - template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - pair<const_iterator, const_iterator> equal_range(const _K2& __k) const - {return __table_.__equal_range_unique(__k);} -#endif // _LIBCPP_STD_VER > 17 - - _LIBCPP_INLINE_VISIBILITY - size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();} - _LIBCPP_INLINE_VISIBILITY - size_type max_bucket_count() const _NOEXCEPT {return __table_.max_bucket_count();} - - _LIBCPP_INLINE_VISIBILITY - size_type bucket_size(size_type __n) const {return __table_.bucket_size(__n);} - _LIBCPP_INLINE_VISIBILITY - size_type bucket(const key_type& __k) const {return __table_.bucket(__k);} - - _LIBCPP_INLINE_VISIBILITY - local_iterator begin(size_type __n) {return __table_.begin(__n);} - _LIBCPP_INLINE_VISIBILITY - local_iterator end(size_type __n) {return __table_.end(__n);} - _LIBCPP_INLINE_VISIBILITY - const_local_iterator begin(size_type __n) const {return __table_.cbegin(__n);} - _LIBCPP_INLINE_VISIBILITY - const_local_iterator end(size_type __n) const {return __table_.cend(__n);} - _LIBCPP_INLINE_VISIBILITY - const_local_iterator cbegin(size_type __n) const {return __table_.cbegin(__n);} - _LIBCPP_INLINE_VISIBILITY - const_local_iterator cend(size_type __n) const {return __table_.cend(__n);} - - _LIBCPP_INLINE_VISIBILITY - float load_factor() const _NOEXCEPT {return __table_.load_factor();} - _LIBCPP_INLINE_VISIBILITY - float max_load_factor() const _NOEXCEPT {return __table_.max_load_factor();} - _LIBCPP_INLINE_VISIBILITY - void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);} - _LIBCPP_INLINE_VISIBILITY - void rehash(size_type __n) {__table_.rehash(__n);} - _LIBCPP_INLINE_VISIBILITY - void reserve(size_type __n) {__table_.reserve(__n);} - -#if _LIBCPP_DEBUG_LEVEL == 2 - - bool __dereferenceable(const const_iterator* __i) const - {return __table_.__dereferenceable(__i);} - bool __decrementable(const const_iterator* __i) const - {return __table_.__decrementable(__i);} - bool __addable(const const_iterator* __i, ptrdiff_t __n) const - {return __table_.__addable(__i, __n);} - bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const - {return __table_.__addable(__i, __n);} - -#endif // _LIBCPP_DEBUG_LEVEL == 2 - -}; - -#if _LIBCPP_STD_VER >= 17 -template<class _InputIterator, - class _Hash = hash<__iter_value_type<_InputIterator>>, - class _Pred = equal_to<__iter_value_type<_InputIterator>>, - class _Allocator = allocator<__iter_value_type<_InputIterator>>, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = enable_if_t<!__is_allocator<_Hash>::value>, - class = enable_if_t<!is_integral<_Hash>::value>, - class = enable_if_t<!__is_allocator<_Pred>::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_set(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type = 0, - _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) - -> unordered_set<__iter_value_type<_InputIterator>, _Hash, _Pred, _Allocator>; - -template<class _Tp, class _Hash = hash<_Tp>, - class _Pred = equal_to<_Tp>, - class _Allocator = allocator<_Tp>, - class = enable_if_t<!__is_allocator<_Hash>::value>, - class = enable_if_t<!is_integral<_Hash>::value>, - class = enable_if_t<!__is_allocator<_Pred>::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_set(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type = 0, - _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) - -> unordered_set<_Tp, _Hash, _Pred, _Allocator>; - -template<class _InputIterator, class _Allocator, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_set(_InputIterator, _InputIterator, - typename allocator_traits<_Allocator>::size_type, _Allocator) - -> unordered_set<__iter_value_type<_InputIterator>, - hash<__iter_value_type<_InputIterator>>, - equal_to<__iter_value_type<_InputIterator>>, - _Allocator>; - -template<class _InputIterator, class _Hash, class _Allocator, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = enable_if_t<!__is_allocator<_Hash>::value>, - class = enable_if_t<!is_integral<_Hash>::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_set(_InputIterator, _InputIterator, - typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator) - -> unordered_set<__iter_value_type<_InputIterator>, _Hash, - equal_to<__iter_value_type<_InputIterator>>, - _Allocator>; - -template<class _Tp, class _Allocator, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_set(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Allocator) - -> unordered_set<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>; - -template<class _Tp, class _Hash, class _Allocator, - class = enable_if_t<!__is_allocator<_Hash>::value>, - class = enable_if_t<!is_integral<_Hash>::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_set(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator) - -> unordered_set<_Tp, _Hash, equal_to<_Tp>, _Allocator>; -#endif - -template <class _Value, class _Hash, class _Pred, class _Alloc> -unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n, - const hasher& __hf, const key_equal& __eql) - : __table_(__hf, __eql) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__n); -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n, - const hasher& __hf, const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, __a) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__n); -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -template <class _InputIterator> -unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( - _InputIterator __first, _InputIterator __last) -{ - _VSTD::__debug_db_insert_c(this); - insert(__first, __last); -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -template <class _InputIterator> -unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( - _InputIterator __first, _InputIterator __last, size_type __n, - const hasher& __hf, const key_equal& __eql) - : __table_(__hf, __eql) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__n); - insert(__first, __last); -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -template <class _InputIterator> -unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( - _InputIterator __first, _InputIterator __last, size_type __n, - const hasher& __hf, const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, __a) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__n); - insert(__first, __last); -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -inline -unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( - const allocator_type& __a) - : __table_(__a) -{ - _VSTD::__debug_db_insert_c(this); -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( - const unordered_set& __u) - : __table_(__u.__table_) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__u.bucket_count()); - insert(__u.begin(), __u.end()); -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( - const unordered_set& __u, const allocator_type& __a) - : __table_(__u.__table_, __a) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__u.bucket_count()); - insert(__u.begin(), __u.end()); -} - -#ifndef _LIBCPP_CXX03_LANG - -template <class _Value, class _Hash, class _Pred, class _Alloc> -inline -unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( - unordered_set&& __u) - _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) - : __table_(_VSTD::move(__u.__table_)) -{ - _VSTD::__debug_db_insert_c(this); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->swap(this, _VSTD::addressof(__u)); -#endif -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( - unordered_set&& __u, const allocator_type& __a) - : __table_(_VSTD::move(__u.__table_), __a) -{ - _VSTD::__debug_db_insert_c(this); - if (__a != __u.get_allocator()) - { - iterator __i = __u.begin(); - while (__u.size() != 0) - __table_.__insert_unique(_VSTD::move(__u.__table_.remove(__i++)->__value_)); - } -#if _LIBCPP_DEBUG_LEVEL == 2 - else - __get_db()->swap(this, _VSTD::addressof(__u)); -#endif -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( - initializer_list<value_type> __il) -{ - _VSTD::__debug_db_insert_c(this); - insert(__il.begin(), __il.end()); -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( - initializer_list<value_type> __il, size_type __n, const hasher& __hf, - const key_equal& __eql) - : __table_(__hf, __eql) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__n); - insert(__il.begin(), __il.end()); -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( - initializer_list<value_type> __il, size_type __n, const hasher& __hf, - const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, __a) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__n); - insert(__il.begin(), __il.end()); -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -inline -unordered_set<_Value, _Hash, _Pred, _Alloc>& -unordered_set<_Value, _Hash, _Pred, _Alloc>::operator=(unordered_set&& __u) - _NOEXCEPT_(is_nothrow_move_assignable<__table>::value) -{ - __table_ = _VSTD::move(__u.__table_); - return *this; -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -inline -unordered_set<_Value, _Hash, _Pred, _Alloc>& -unordered_set<_Value, _Hash, _Pred, _Alloc>::operator=( - initializer_list<value_type> __il) -{ - __table_.__assign_unique(__il.begin(), __il.end()); - return *this; -} - -#endif // _LIBCPP_CXX03_LANG - -template <class _Value, class _Hash, class _Pred, class _Alloc> -template <class _InputIterator> -inline -void -unordered_set<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, - _InputIterator __last) -{ - for (; __first != __last; ++__first) - __table_.__insert_unique(*__first); -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -void -swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, - unordered_set<_Value, _Hash, _Pred, _Alloc>& __y) - _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) -{ - __x.swap(__y); -} - -#if _LIBCPP_STD_VER > 17 -template <class _Value, class _Hash, class _Pred, class _Alloc, - class _Predicate> -inline _LIBCPP_INLINE_VISIBILITY - typename unordered_set<_Value, _Hash, _Pred, _Alloc>::size_type - erase_if(unordered_set<_Value, _Hash, _Pred, _Alloc>& __c, - _Predicate __pred) { - return _VSTD::__libcpp_erase_if_container(__c, __pred); -} -#endif - -template <class _Value, class _Hash, class _Pred, class _Alloc> -bool -operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, - const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y) -{ - if (__x.size() != __y.size()) - return false; - typedef typename unordered_set<_Value, _Hash, _Pred, _Alloc>::const_iterator - const_iterator; - for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end(); - __i != __ex; ++__i) - { - const_iterator __j = __y.find(*__i); - if (__j == __ey || !(*__i == *__j)) - return false; - } - return true; -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, - const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y) -{ - return !(__x == __y); -} - -template <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>, - class _Alloc = allocator<_Value> > -class _LIBCPP_TEMPLATE_VIS unordered_multiset -{ -public: - // types - typedef _Value key_type; - typedef key_type value_type; - typedef __identity_t<_Hash> hasher; - typedef __identity_t<_Pred> key_equal; - typedef __identity_t<_Alloc> allocator_type; - typedef value_type& reference; - typedef const value_type& const_reference; - static_assert((is_same<value_type, typename allocator_type::value_type>::value), - "Invalid allocator::value_type"); - -private: - typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table; - - __table __table_; - -public: - typedef typename __table::pointer pointer; - typedef typename __table::const_pointer const_pointer; - typedef typename __table::size_type size_type; - typedef typename __table::difference_type difference_type; - - typedef typename __table::const_iterator iterator; - typedef typename __table::const_iterator const_iterator; - typedef typename __table::const_local_iterator local_iterator; - typedef typename __table::const_local_iterator const_local_iterator; - -#if _LIBCPP_STD_VER > 14 - typedef __set_node_handle<typename __table::__node, allocator_type> node_type; -#endif - - template <class _Value2, class _Hash2, class _Pred2, class _Alloc2> - friend class _LIBCPP_TEMPLATE_VIS unordered_set; - template <class _Value2, class _Hash2, class _Pred2, class _Alloc2> - friend class _LIBCPP_TEMPLATE_VIS unordered_multiset; - - _LIBCPP_INLINE_VISIBILITY - unordered_multiset() - _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) - { - _VSTD::__debug_db_insert_c(this); - } - explicit unordered_multiset(size_type __n, const hasher& __hf = hasher(), - const key_equal& __eql = key_equal()); - unordered_multiset(size_type __n, const hasher& __hf, - const key_equal& __eql, const allocator_type& __a); -#if _LIBCPP_STD_VER > 11 - inline _LIBCPP_INLINE_VISIBILITY - unordered_multiset(size_type __n, const allocator_type& __a) - : unordered_multiset(__n, hasher(), key_equal(), __a) {} - inline _LIBCPP_INLINE_VISIBILITY - unordered_multiset(size_type __n, const hasher& __hf, const allocator_type& __a) - : unordered_multiset(__n, __hf, key_equal(), __a) {} -#endif - template <class _InputIterator> - unordered_multiset(_InputIterator __first, _InputIterator __last); - template <class _InputIterator> - unordered_multiset(_InputIterator __first, _InputIterator __last, - size_type __n, const hasher& __hf = hasher(), - const key_equal& __eql = key_equal()); - template <class _InputIterator> - unordered_multiset(_InputIterator __first, _InputIterator __last, - size_type __n , const hasher& __hf, - const key_equal& __eql, const allocator_type& __a); -#if _LIBCPP_STD_VER > 11 - template <class _InputIterator> - inline _LIBCPP_INLINE_VISIBILITY - unordered_multiset(_InputIterator __first, _InputIterator __last, - size_type __n, const allocator_type& __a) - : unordered_multiset(__first, __last, __n, hasher(), key_equal(), __a) {} - template <class _InputIterator> - inline _LIBCPP_INLINE_VISIBILITY - unordered_multiset(_InputIterator __first, _InputIterator __last, - size_type __n, const hasher& __hf, const allocator_type& __a) - : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a) {} -#endif - _LIBCPP_INLINE_VISIBILITY - explicit unordered_multiset(const allocator_type& __a); - unordered_multiset(const unordered_multiset& __u); - unordered_multiset(const unordered_multiset& __u, const allocator_type& __a); -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - unordered_multiset(unordered_multiset&& __u) - _NOEXCEPT_(is_nothrow_move_constructible<__table>::value); - unordered_multiset(unordered_multiset&& __u, const allocator_type& __a); - unordered_multiset(initializer_list<value_type> __il); - unordered_multiset(initializer_list<value_type> __il, size_type __n, - const hasher& __hf = hasher(), - const key_equal& __eql = key_equal()); - unordered_multiset(initializer_list<value_type> __il, size_type __n, - const hasher& __hf, const key_equal& __eql, - const allocator_type& __a); -#if _LIBCPP_STD_VER > 11 - inline _LIBCPP_INLINE_VISIBILITY - unordered_multiset(initializer_list<value_type> __il, size_type __n, const allocator_type& __a) - : unordered_multiset(__il, __n, hasher(), key_equal(), __a) {} - inline _LIBCPP_INLINE_VISIBILITY - unordered_multiset(initializer_list<value_type> __il, size_type __n, const hasher& __hf, const allocator_type& __a) - : unordered_multiset(__il, __n, __hf, key_equal(), __a) {} -#endif -#endif // _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - ~unordered_multiset() { - static_assert(sizeof(__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), ""); - } - - _LIBCPP_INLINE_VISIBILITY - unordered_multiset& operator=(const unordered_multiset& __u) - { - __table_ = __u.__table_; - return *this; - } -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - unordered_multiset& operator=(unordered_multiset&& __u) - _NOEXCEPT_(is_nothrow_move_assignable<__table>::value); - unordered_multiset& operator=(initializer_list<value_type> __il); -#endif // _LIBCPP_CXX03_LANG - - _LIBCPP_INLINE_VISIBILITY - allocator_type get_allocator() const _NOEXCEPT - {return allocator_type(__table_.__node_alloc());} - - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY - bool empty() const _NOEXCEPT {return __table_.size() == 0;} - _LIBCPP_INLINE_VISIBILITY - size_type size() const _NOEXCEPT {return __table_.size();} - _LIBCPP_INLINE_VISIBILITY - size_type max_size() const _NOEXCEPT {return __table_.max_size();} - - _LIBCPP_INLINE_VISIBILITY - iterator begin() _NOEXCEPT {return __table_.begin();} - _LIBCPP_INLINE_VISIBILITY - iterator end() _NOEXCEPT {return __table_.end();} - _LIBCPP_INLINE_VISIBILITY - const_iterator begin() const _NOEXCEPT {return __table_.begin();} - _LIBCPP_INLINE_VISIBILITY - const_iterator end() const _NOEXCEPT {return __table_.end();} - _LIBCPP_INLINE_VISIBILITY - const_iterator cbegin() const _NOEXCEPT {return __table_.begin();} - _LIBCPP_INLINE_VISIBILITY - const_iterator cend() const _NOEXCEPT {return __table_.end();} - -#ifndef _LIBCPP_CXX03_LANG - template <class... _Args> - _LIBCPP_INLINE_VISIBILITY - iterator emplace(_Args&&... __args) - {return __table_.__emplace_multi(_VSTD::forward<_Args>(__args)...);} - template <class... _Args> - _LIBCPP_INLINE_VISIBILITY - iterator emplace_hint(const_iterator __p, _Args&&... __args) - {return __table_.__emplace_hint_multi(__p, _VSTD::forward<_Args>(__args)...);} - - _LIBCPP_INLINE_VISIBILITY - iterator insert(value_type&& __x) {return __table_.__insert_multi(_VSTD::move(__x));} - _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __p, value_type&& __x) - {return __table_.__insert_multi(__p, _VSTD::move(__x));} - _LIBCPP_INLINE_VISIBILITY - void insert(initializer_list<value_type> __il) - {insert(__il.begin(), __il.end());} -#endif // _LIBCPP_CXX03_LANG - - _LIBCPP_INLINE_VISIBILITY - iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);} - - _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __p, const value_type& __x) - {return __table_.__insert_multi(__p, __x);} - - template <class _InputIterator> - _LIBCPP_INLINE_VISIBILITY - void insert(_InputIterator __first, _InputIterator __last); - -#if _LIBCPP_STD_VER > 14 - _LIBCPP_INLINE_VISIBILITY - iterator insert(node_type&& __nh) - { - _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), - "node_type with incompatible allocator passed to unordered_multiset::insert()"); - return __table_.template __node_handle_insert_multi<node_type>( - _VSTD::move(__nh)); - } - _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __hint, node_type&& __nh) - { - _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), - "node_type with incompatible allocator passed to unordered_multiset::insert()"); - return __table_.template __node_handle_insert_multi<node_type>( - __hint, _VSTD::move(__nh)); - } - _LIBCPP_INLINE_VISIBILITY - node_type extract(const_iterator __position) - { - return __table_.template __node_handle_extract<node_type>( - __position); - } - _LIBCPP_INLINE_VISIBILITY - node_type extract(key_type const& __key) - { - return __table_.template __node_handle_extract<node_type>(__key); - } - - template <class _H2, class _P2> - _LIBCPP_INLINE_VISIBILITY - void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - return __table_.__node_handle_merge_multi(__source.__table_); - } - template <class _H2, class _P2> - _LIBCPP_INLINE_VISIBILITY - void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>&& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - return __table_.__node_handle_merge_multi(__source.__table_); - } - template <class _H2, class _P2> - _LIBCPP_INLINE_VISIBILITY - void merge(unordered_set<key_type, _H2, _P2, allocator_type>& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - return __table_.__node_handle_merge_multi(__source.__table_); - } - template <class _H2, class _P2> - _LIBCPP_INLINE_VISIBILITY - void merge(unordered_set<key_type, _H2, _P2, allocator_type>&& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - return __table_.__node_handle_merge_multi(__source.__table_); - } -#endif - - _LIBCPP_INLINE_VISIBILITY - iterator erase(const_iterator __p) {return __table_.erase(__p);} - _LIBCPP_INLINE_VISIBILITY - size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);} - _LIBCPP_INLINE_VISIBILITY - iterator erase(const_iterator __first, const_iterator __last) - {return __table_.erase(__first, __last);} - _LIBCPP_INLINE_VISIBILITY - void clear() _NOEXCEPT {__table_.clear();} - - _LIBCPP_INLINE_VISIBILITY - void swap(unordered_multiset& __u) - _NOEXCEPT_(__is_nothrow_swappable<__table>::value) - {__table_.swap(__u.__table_);} - - _LIBCPP_INLINE_VISIBILITY - hasher hash_function() const {return __table_.hash_function();} - _LIBCPP_INLINE_VISIBILITY - key_equal key_eq() const {return __table_.key_eq();} - - _LIBCPP_INLINE_VISIBILITY - iterator find(const key_type& __k) {return __table_.find(__k);} - _LIBCPP_INLINE_VISIBILITY - const_iterator find(const key_type& __k) const {return __table_.find(__k);} -#if _LIBCPP_STD_VER > 17 - template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - iterator find(const _K2& __k) {return __table_.find(__k);} - template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - const_iterator find(const _K2& __k) const {return __table_.find(__k);} -#endif // _LIBCPP_STD_VER > 17 - - _LIBCPP_INLINE_VISIBILITY - size_type count(const key_type& __k) const {return __table_.__count_multi(__k);} -#if _LIBCPP_STD_VER > 17 - template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - size_type count(const _K2& __k) const {return __table_.__count_multi(__k);} -#endif // _LIBCPP_STD_VER > 17 - -#if _LIBCPP_STD_VER > 17 - _LIBCPP_INLINE_VISIBILITY - bool contains(const key_type& __k) const {return find(__k) != end();} - - template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - bool contains(const _K2& __k) const {return find(__k) != end();} -#endif // _LIBCPP_STD_VER > 17 - - _LIBCPP_INLINE_VISIBILITY - pair<iterator, iterator> equal_range(const key_type& __k) - {return __table_.__equal_range_multi(__k);} - _LIBCPP_INLINE_VISIBILITY - pair<const_iterator, const_iterator> equal_range(const key_type& __k) const - {return __table_.__equal_range_multi(__k);} -#if _LIBCPP_STD_VER > 17 - template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - pair<iterator, iterator> equal_range(const _K2& __k) - {return __table_.__equal_range_multi(__k);} - template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - pair<const_iterator, const_iterator> equal_range(const _K2& __k) const - {return __table_.__equal_range_multi(__k);} -#endif // _LIBCPP_STD_VER > 17 - - _LIBCPP_INLINE_VISIBILITY - size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();} - _LIBCPP_INLINE_VISIBILITY - size_type max_bucket_count() const _NOEXCEPT {return __table_.max_bucket_count();} - - _LIBCPP_INLINE_VISIBILITY - size_type bucket_size(size_type __n) const {return __table_.bucket_size(__n);} - _LIBCPP_INLINE_VISIBILITY - size_type bucket(const key_type& __k) const {return __table_.bucket(__k);} - - _LIBCPP_INLINE_VISIBILITY - local_iterator begin(size_type __n) {return __table_.begin(__n);} - _LIBCPP_INLINE_VISIBILITY - local_iterator end(size_type __n) {return __table_.end(__n);} - _LIBCPP_INLINE_VISIBILITY - const_local_iterator begin(size_type __n) const {return __table_.cbegin(__n);} - _LIBCPP_INLINE_VISIBILITY - const_local_iterator end(size_type __n) const {return __table_.cend(__n);} - _LIBCPP_INLINE_VISIBILITY - const_local_iterator cbegin(size_type __n) const {return __table_.cbegin(__n);} - _LIBCPP_INLINE_VISIBILITY - const_local_iterator cend(size_type __n) const {return __table_.cend(__n);} - - _LIBCPP_INLINE_VISIBILITY - float load_factor() const _NOEXCEPT {return __table_.load_factor();} - _LIBCPP_INLINE_VISIBILITY - float max_load_factor() const _NOEXCEPT {return __table_.max_load_factor();} - _LIBCPP_INLINE_VISIBILITY - void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);} - _LIBCPP_INLINE_VISIBILITY - void rehash(size_type __n) {__table_.rehash(__n);} - _LIBCPP_INLINE_VISIBILITY - void reserve(size_type __n) {__table_.reserve(__n);} - -#if _LIBCPP_DEBUG_LEVEL == 2 - - bool __dereferenceable(const const_iterator* __i) const - {return __table_.__dereferenceable(__i);} - bool __decrementable(const const_iterator* __i) const - {return __table_.__decrementable(__i);} - bool __addable(const const_iterator* __i, ptrdiff_t __n) const - {return __table_.__addable(__i, __n);} - bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const - {return __table_.__addable(__i, __n);} - -#endif // _LIBCPP_DEBUG_LEVEL == 2 - -}; - -#if _LIBCPP_STD_VER >= 17 -template<class _InputIterator, - class _Hash = hash<__iter_value_type<_InputIterator>>, - class _Pred = equal_to<__iter_value_type<_InputIterator>>, - class _Allocator = allocator<__iter_value_type<_InputIterator>>, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = enable_if_t<!__is_allocator<_Hash>::value>, - class = enable_if_t<!is_integral<_Hash>::value>, - class = enable_if_t<!__is_allocator<_Pred>::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type = 0, - _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) - -> unordered_multiset<__iter_value_type<_InputIterator>, _Hash, _Pred, _Allocator>; - -template<class _Tp, class _Hash = hash<_Tp>, - class _Pred = equal_to<_Tp>, class _Allocator = allocator<_Tp>, - class = enable_if_t<!__is_allocator<_Hash>::value>, - class = enable_if_t<!is_integral<_Hash>::value>, - class = enable_if_t<!__is_allocator<_Pred>::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_multiset(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type = 0, - _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) - -> unordered_multiset<_Tp, _Hash, _Pred, _Allocator>; - -template<class _InputIterator, class _Allocator, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Allocator) - -> unordered_multiset<__iter_value_type<_InputIterator>, - hash<__iter_value_type<_InputIterator>>, - equal_to<__iter_value_type<_InputIterator>>, - _Allocator>; - -template<class _InputIterator, class _Hash, class _Allocator, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = enable_if_t<!__is_allocator<_Hash>::value>, - class = enable_if_t<!is_integral<_Hash>::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, - _Hash, _Allocator) - -> unordered_multiset<__iter_value_type<_InputIterator>, _Hash, - equal_to<__iter_value_type<_InputIterator>>, - _Allocator>; - -template<class _Tp, class _Allocator, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_multiset(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Allocator) - -> unordered_multiset<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>; - -template<class _Tp, class _Hash, class _Allocator, - class = enable_if_t<!__is_allocator<_Hash>::value>, - class = enable_if_t<!is_integral<_Hash>::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_multiset(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator) - -> unordered_multiset<_Tp, _Hash, equal_to<_Tp>, _Allocator>; -#endif - -template <class _Value, class _Hash, class _Pred, class _Alloc> -unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( - size_type __n, const hasher& __hf, const key_equal& __eql) - : __table_(__hf, __eql) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__n); -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( - size_type __n, const hasher& __hf, const key_equal& __eql, - const allocator_type& __a) - : __table_(__hf, __eql, __a) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__n); -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -template <class _InputIterator> -unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( - _InputIterator __first, _InputIterator __last) -{ - _VSTD::__debug_db_insert_c(this); - insert(__first, __last); -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -template <class _InputIterator> -unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( - _InputIterator __first, _InputIterator __last, size_type __n, - const hasher& __hf, const key_equal& __eql) - : __table_(__hf, __eql) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__n); - insert(__first, __last); -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -template <class _InputIterator> -unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( - _InputIterator __first, _InputIterator __last, size_type __n, - const hasher& __hf, const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, __a) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__n); - insert(__first, __last); -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -inline -unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( - const allocator_type& __a) - : __table_(__a) -{ - _VSTD::__debug_db_insert_c(this); -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( - const unordered_multiset& __u) - : __table_(__u.__table_) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__u.bucket_count()); - insert(__u.begin(), __u.end()); -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( - const unordered_multiset& __u, const allocator_type& __a) - : __table_(__u.__table_, __a) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__u.bucket_count()); - insert(__u.begin(), __u.end()); -} - -#ifndef _LIBCPP_CXX03_LANG - -template <class _Value, class _Hash, class _Pred, class _Alloc> -inline -unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( - unordered_multiset&& __u) - _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) - : __table_(_VSTD::move(__u.__table_)) -{ - _VSTD::__debug_db_insert_c(this); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->swap(this, _VSTD::addressof(__u)); -#endif -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( - unordered_multiset&& __u, const allocator_type& __a) - : __table_(_VSTD::move(__u.__table_), __a) -{ - _VSTD::__debug_db_insert_c(this); - if (__a != __u.get_allocator()) - { - iterator __i = __u.begin(); - while (__u.size() != 0) - __table_.__insert_multi(_VSTD::move(__u.__table_.remove(__i++)->__value_)); - } -#if _LIBCPP_DEBUG_LEVEL == 2 - else - __get_db()->swap(this, _VSTD::addressof(__u)); -#endif -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( - initializer_list<value_type> __il) -{ - _VSTD::__debug_db_insert_c(this); - insert(__il.begin(), __il.end()); -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( - initializer_list<value_type> __il, size_type __n, const hasher& __hf, - const key_equal& __eql) - : __table_(__hf, __eql) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__n); - insert(__il.begin(), __il.end()); -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( - initializer_list<value_type> __il, size_type __n, const hasher& __hf, - const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, __a) -{ - _VSTD::__debug_db_insert_c(this); - __table_.rehash(__n); - insert(__il.begin(), __il.end()); -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -inline -unordered_multiset<_Value, _Hash, _Pred, _Alloc>& -unordered_multiset<_Value, _Hash, _Pred, _Alloc>::operator=( - unordered_multiset&& __u) - _NOEXCEPT_(is_nothrow_move_assignable<__table>::value) -{ - __table_ = _VSTD::move(__u.__table_); - return *this; -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -inline -unordered_multiset<_Value, _Hash, _Pred, _Alloc>& -unordered_multiset<_Value, _Hash, _Pred, _Alloc>::operator=( - initializer_list<value_type> __il) -{ - __table_.__assign_multi(__il.begin(), __il.end()); - return *this; -} - -#endif // _LIBCPP_CXX03_LANG - -template <class _Value, class _Hash, class _Pred, class _Alloc> -template <class _InputIterator> -inline -void -unordered_multiset<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, - _InputIterator __last) -{ - for (; __first != __last; ++__first) - __table_.__insert_multi(*__first); -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -void -swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, - unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) - _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) -{ - __x.swap(__y); -} - -#if _LIBCPP_STD_VER > 17 -template <class _Value, class _Hash, class _Pred, class _Alloc, - class _Predicate> -inline _LIBCPP_INLINE_VISIBILITY - typename unordered_multiset<_Value, _Hash, _Pred, _Alloc>::size_type - erase_if(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __c, - _Predicate __pred) { - return _VSTD::__libcpp_erase_if_container(__c, __pred); -} -#endif - -template <class _Value, class _Hash, class _Pred, class _Alloc> -bool -operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, - const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) -{ - if (__x.size() != __y.size()) - return false; - typedef typename unordered_multiset<_Value, _Hash, _Pred, _Alloc>::const_iterator - const_iterator; - typedef pair<const_iterator, const_iterator> _EqRng; - for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;) - { - _EqRng __xeq = __x.equal_range(*__i); - _EqRng __yeq = __y.equal_range(*__i); - if (_VSTD::distance(__xeq.first, __xeq.second) != - _VSTD::distance(__yeq.first, __yeq.second) || - !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first)) - return false; - __i = __xeq.second; - } - return true; -} - -template <class _Value, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -bool -operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, - const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) -{ - return !(__x == __y); -} - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP_UNORDERED_SET diff --git a/contrib/libs/cxxsupp/libcxxmsvc/include/unwind.h b/contrib/libs/cxxsupp/libcxxmsvc/include/unwind.h deleted file mode 100644 index c608202230..0000000000 --- a/contrib/libs/cxxsupp/libcxxmsvc/include/unwind.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#if defined(__IOS__) -#include_next <unwind.h> -#else -#include <contrib/libs/cxxsupp/libcxxrt/unwind.h> -#endif diff --git a/contrib/libs/googleapis-common-protos/CHANGELOG.md b/contrib/libs/googleapis-common-protos/CHANGELOG.md index 05ce40674d..35b025b48b 100644 --- a/contrib/libs/googleapis-common-protos/CHANGELOG.md +++ b/contrib/libs/googleapis-common-protos/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## [1.62.0](https://github.com/googleapis/python-api-common-protos/compare/v1.61.0...v1.62.0) (2023-12-01) + + +### Features + +* Add `auto_populated_fields` field of `MethodSettings` in `google/api/client_pb2` ([#194](https://github.com/googleapis/python-api-common-protos/issues/194)) ([4b0c73a](https://github.com/googleapis/python-api-common-protos/commit/4b0c73a40f9bf5337fe451c0210f73eadd196b99)) +* Add support for Python 3.12 ([#192](https://github.com/googleapis/python-api-common-protos/issues/192)) ([336cdf3](https://github.com/googleapis/python-api-common-protos/commit/336cdf351d4e87891d735837817d2cfc4e5a9fc7)) + + +### Bug Fixes + +* Migrate to native namespace packages ([#187](https://github.com/googleapis/python-api-common-protos/issues/187)) ([713e388](https://github.com/googleapis/python-api-common-protos/commit/713e3887a3293aea314060e84bdcf8a12eda3d6c)) + ## [1.61.0](https://github.com/googleapis/python-api-common-protos/compare/v1.60.0...v1.61.0) (2023-10-09) diff --git a/contrib/libs/googleapis-common-protos/google/api/client.proto b/contrib/libs/googleapis-common-protos/google/api/client.proto index 6d01954eee..39bdde82a9 100644 --- a/contrib/libs/googleapis-common-protos/google/api/client.proto +++ b/contrib/libs/googleapis-common-protos/google/api/client.proto @@ -349,6 +349,19 @@ message MethodSettings { // total_poll_timeout: // seconds: 54000 # 90 minutes LongRunning long_running = 2; + + // List of top-level fields of the request message, that should be + // automatically populated by the client libraries based on their + // (google.api.field_info).format. Currently supported format: UUID4. + // + // Example of a YAML configuration: + // + // publishing: + // method_settings: + // - selector: google.example.v1.ExampleService.CreateExample + // auto_populated_fields: + // - request_id + repeated string auto_populated_fields = 3; } // The organization for which the client libraries are being published. diff --git a/contrib/libs/googleapis-common-protos/ya.make b/contrib/libs/googleapis-common-protos/ya.make index cb0e4cd27f..78f9707f39 100644 --- a/contrib/libs/googleapis-common-protos/ya.make +++ b/contrib/libs/googleapis-common-protos/ya.make @@ -6,9 +6,9 @@ LICENSE(Apache-2.0) LICENSE_TEXTS(.yandex_meta/licenses.list.txt) -VERSION(1.61.0) +VERSION(1.62.0) -ORIGINAL_SOURCE(https://github.com/googleapis/python-api-common-protos/archive/v1.61.0.tar.gz) +ORIGINAL_SOURCE(https://github.com/googleapis/python-api-common-protos/archive/v1.62.0.tar.gz) PY_NAMESPACE(.) diff --git a/contrib/python/argcomplete/py3/.dist-info/METADATA b/contrib/python/argcomplete/py3/.dist-info/METADATA index d9b6891313..c86dfbcaf5 100644 --- a/contrib/python/argcomplete/py3/.dist-info/METADATA +++ b/contrib/python/argcomplete/py3/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: argcomplete -Version: 3.1.6 +Version: 3.2.1 Summary: Bash tab completion for argparse Home-page: https://github.com/kislyuk/argcomplete Author: Andrey Kislyuk diff --git a/contrib/python/argcomplete/py3/argcomplete/_check_console_script.py b/contrib/python/argcomplete/py3/argcomplete/_check_console_script.py index bd324b4e71..63eac73f6f 100644 --- a/contrib/python/argcomplete/py3/argcomplete/_check_console_script.py +++ b/contrib/python/argcomplete/py3/argcomplete/_check_console_script.py @@ -13,12 +13,11 @@ Intended to be invoked by argcomplete's global completion function. """ import os import sys - -from importlib.metadata import entry_points as importlib_entry_points from importlib.metadata import EntryPoint +from importlib.metadata import entry_points as importlib_entry_points +from typing import Iterable from ._check_module import ArgcompleteMarkerNotFound, find -from typing import Iterable def main(): @@ -29,15 +28,14 @@ def main(): # assuming it is actually a console script. name = os.path.basename(script_path) - entry_points : Iterable[EntryPoint] = importlib_entry_points() # type:ignore + entry_points: Iterable[EntryPoint] = importlib_entry_points() # type:ignore # Python 3.12+ returns a tuple of entry point objects # whereas <=3.11 returns a SelectableGroups object if sys.version_info < (3, 12): - entry_points = entry_points["console_scripts"] # type:ignore + entry_points = entry_points["console_scripts"] # type:ignore - entry_points = [ep for ep in entry_points \ - if ep.name == name and ep.group == "console_scripts" ] # type:ignore + entry_points = [ep for ep in entry_points if ep.name == name and ep.group == "console_scripts"] # type:ignore if not entry_points: raise ArgcompleteMarkerNotFound("no entry point found matching script") diff --git a/contrib/python/argcomplete/py3/argcomplete/bash_completion.d/_python-argcomplete b/contrib/python/argcomplete/py3/argcomplete/bash_completion.d/_python-argcomplete index 1e4c66ce80..3023ff289e 100644 --- a/contrib/python/argcomplete/py3/argcomplete/bash_completion.d/_python-argcomplete +++ b/contrib/python/argcomplete/py3/argcomplete/bash_completion.d/_python-argcomplete @@ -1,10 +1,15 @@ -#compdef -P * +#compdef -default- # Copyright 2012-2023, Andrey Kislyuk and argcomplete contributors. # Licensed under the Apache License. See https://github.com/kislyuk/argcomplete for more info. # Note: both the leading underscore in the name of this file and the first line (compdef) are required by zsh +# In zsh, this file is autoloaded and used as the default completer (_default). +# There are many other special contexts we don't want to override +# (as would be the case with `#compdef -P *`). +# https://zsh.sourceforge.io/Doc/Release/Completion-System.html + # Copy of __expand_tilde_by_ref from bash-completion # ZSH implementation added __python_argcomplete_expand_tilde_by_ref () { @@ -138,12 +143,6 @@ _python_argcomplete_global() { req_argv=( "" "${COMP_WORDS[@]:1}" ) __python_argcomplete_expand_tilde_by_ref executable else - if [[ "$service" != "-default-" ]]; then - # TODO: this may not be sufficient - see https://zsh.sourceforge.io/Doc/Release/Completion-System.html - # May need to call _complete with avoid-completer=_python-argcomplete or something like that - _default - return - fi executable="${words[1]}" req_argv=( "${words[@]:1}" ) fi @@ -208,7 +207,15 @@ _python_argcomplete_global() { _ARGCOMPLETE_SHELL="zsh" \ _ARGCOMPLETE_SUPPRESS_SPACE=1 \ __python_argcomplete_run "$executable" "${(@)req_argv[1, ${ARGCOMPLETE}-1]}")) - _describe "$executable" completions + local nosort=() + local nospace=() + if is-at-least 5.8; then + nosort=(-o nosort) + fi + if [[ "${completions-}" =~ ([^\\]): && "${BASH_REMATCH[2]}" =~ [=/:] ]]; then + nospace=(-S '') + fi + _describe "$executable" completions "${nosort[@]}" "${nospace[@]}" else COMPREPLY=($(IFS="$IFS" \ COMP_LINE="$COMP_LINE" \ @@ -234,5 +241,20 @@ _python_argcomplete_global() { if [[ -z "${ZSH_VERSION-}" ]]; then complete -o default -o bashdefault -D -F _python_argcomplete_global else - compdef _python_argcomplete_global -P '*' + # -Uz is recommended for the use of functions supplied with the zsh distribution. + # https://unix.stackexchange.com/a/214306 + autoload -Uz is-at-least + # If this is being implicitly loaded because we placed it on fpath, + # the comment at the top of this file causes zsh to invoke this script directly, + # so we must explicitly call the global completion function. + # Note $service should only ever be -default- because the comment at the top + # registers this script as the default completer (#compdef -default-). + if [[ $service == -default- ]]; then + _python_argcomplete_global + fi + # If this has been executed directly (e.g. `eval "$(activate-global-python-argcomplete --dest=-)"`) + # we need to explicitly call compdef to register the completion function. + # If we have been implicitly loaded, we still call compdef as a slight optimisation + # (there is no need to execute any top-level code more than once). + compdef _python_argcomplete_global -default- fi diff --git a/contrib/python/argcomplete/py3/argcomplete/shell_integration.py b/contrib/python/argcomplete/py3/argcomplete/shell_integration.py index 53b8e18234..73214bb651 100644 --- a/contrib/python/argcomplete/py3/argcomplete/shell_integration.py +++ b/contrib/python/argcomplete/py3/argcomplete/shell_integration.py @@ -42,7 +42,15 @@ _python_argcomplete%(function_suffix)s() { _ARGCOMPLETE_SHELL="zsh" \ _ARGCOMPLETE_SUPPRESS_SPACE=1 \ __python_argcomplete_run ${script:-${words[1]}})) - _describe "${words[1]}" completions -o nosort + local nosort=() + local nospace=() + if is-at-least 5.8; then + nosort=(-o nosort) + fi + if [[ "${completions-}" =~ ([^\\]): && "${match[1]}" =~ [=/:] ]]; then + nospace=(-S '') + fi + _describe "${words[1]}" completions "${nosort[@]}" "${nospace[@]}" else local SUPPRESS_SPACE=0 if compopt +o nospace 2> /dev/null; then @@ -67,6 +75,7 @@ _python_argcomplete%(function_suffix)s() { if [[ -z "${ZSH_VERSION-}" ]]; then complete %(complete_opts)s -F _python_argcomplete%(function_suffix)s %(executables)s else + autoload is-at-least compdef _python_argcomplete%(function_suffix)s %(executables)s fi """ diff --git a/contrib/python/argcomplete/py3/ya.make b/contrib/python/argcomplete/py3/ya.make index 6c09efa674..ceca768f4d 100644 --- a/contrib/python/argcomplete/py3/ya.make +++ b/contrib/python/argcomplete/py3/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(3.1.6) +VERSION(3.2.1) LICENSE(Apache-2.0) diff --git a/contrib/python/google-auth/py3/.dist-info/METADATA b/contrib/python/google-auth/py3/.dist-info/METADATA index 23841a2ee7..f86d77d41b 100644 --- a/contrib/python/google-auth/py3/.dist-info/METADATA +++ b/contrib/python/google-auth/py3/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: google-auth -Version: 2.23.0 +Version: 2.25.2 Summary: Google Authentication Library Home-page: https://github.com/googleapis/google-auth-library-python Author: Google Cloud Platform @@ -13,6 +13,7 @@ Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: Apache Software License @@ -23,23 +24,22 @@ Classifier: Operating System :: OS Independent Classifier: Topic :: Internet :: WWW/HTTP Requires-Python: >=3.7 License-File: LICENSE -Requires-Dist: cachetools (<6.0,>=2.0.0) -Requires-Dist: pyasn1-modules (>=0.2.1) -Requires-Dist: rsa (<5,>=3.1.4) -Requires-Dist: urllib3 (<2.0) +Requires-Dist: cachetools <6.0,>=2.0.0 +Requires-Dist: pyasn1-modules >=0.2.1 +Requires-Dist: rsa <5,>=3.1.4 Provides-Extra: aiohttp -Requires-Dist: aiohttp (<4.0.0.dev0,>=3.6.2) ; extra == 'aiohttp' -Requires-Dist: requests (<3.0.0.dev0,>=2.20.0) ; extra == 'aiohttp' +Requires-Dist: aiohttp <4.0.0.dev0,>=3.6.2 ; extra == 'aiohttp' +Requires-Dist: requests <3.0.0.dev0,>=2.20.0 ; extra == 'aiohttp' Provides-Extra: enterprise_cert -Requires-Dist: cryptography (==36.0.2) ; extra == 'enterprise_cert' -Requires-Dist: pyopenssl (==22.0.0) ; extra == 'enterprise_cert' +Requires-Dist: cryptography ==36.0.2 ; extra == 'enterprise_cert' +Requires-Dist: pyopenssl ==22.0.0 ; extra == 'enterprise_cert' Provides-Extra: pyopenssl -Requires-Dist: pyopenssl (>=20.0.0) ; extra == 'pyopenssl' -Requires-Dist: cryptography (>=38.0.3) ; extra == 'pyopenssl' +Requires-Dist: pyopenssl >=20.0.0 ; extra == 'pyopenssl' +Requires-Dist: cryptography >=38.0.3 ; extra == 'pyopenssl' Provides-Extra: reauth -Requires-Dist: pyu2f (>=0.1.5) ; extra == 'reauth' +Requires-Dist: pyu2f >=0.1.5 ; extra == 'reauth' Provides-Extra: requests -Requires-Dist: requests (<3.0.0.dev0,>=2.20.0) ; extra == 'requests' +Requires-Dist: requests <3.0.0.dev0,>=2.20.0 ; extra == 'requests' Google Auth Python Library ========================== @@ -63,7 +63,7 @@ You can install using `pip`_:: For more information on setting up your Python development environment, please refer to `Python Development Environment Setup Guide`_ for Google Cloud Platform. -.. _`Python Development Environment Setup Guide`: https://cloud.google.com/python/setup +.. _`Python Development Environment Setup Guide`: https://cloud.google.com/python/docs/setup Extras ------ @@ -80,6 +80,16 @@ Supported Python Versions ^^^^^^^^^^^^^^^^^^^^^^^^^ Python >= 3.7 +**NOTE**: +Python 3.7 was marked as `unsupported`_ by the python community in June 2023. +We recommend that all developers upgrade to Python 3.8 and newer as soon as +they can. Support for Python 3.7 will be removed from this library after +January 1 2024. Previous releases that support Python 3.7 will continue to be available +for download, but releases after January 1 2024 will only target Python 3.8 and +newer. + +.. _unsupported: https://devguide.python.org/versions/#unsupported-versions + Unsupported Python Versions ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Python == 2.7: The last version of this library with support for Python 2.7 diff --git a/contrib/python/google-auth/py3/README.rst b/contrib/python/google-auth/py3/README.rst index cdd19bed50..e058f24713 100644 --- a/contrib/python/google-auth/py3/README.rst +++ b/contrib/python/google-auth/py3/README.rst @@ -20,7 +20,7 @@ You can install using `pip`_:: For more information on setting up your Python development environment, please refer to `Python Development Environment Setup Guide`_ for Google Cloud Platform. -.. _`Python Development Environment Setup Guide`: https://cloud.google.com/python/setup +.. _`Python Development Environment Setup Guide`: https://cloud.google.com/python/docs/setup Extras ------ @@ -37,6 +37,16 @@ Supported Python Versions ^^^^^^^^^^^^^^^^^^^^^^^^^ Python >= 3.7 +**NOTE**: +Python 3.7 was marked as `unsupported`_ by the python community in June 2023. +We recommend that all developers upgrade to Python 3.8 and newer as soon as +they can. Support for Python 3.7 will be removed from this library after +January 1 2024. Previous releases that support Python 3.7 will continue to be available +for download, but releases after January 1 2024 will only target Python 3.8 and +newer. + +.. _unsupported: https://devguide.python.org/versions/#unsupported-versions + Unsupported Python Versions ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Python == 2.7: The last version of this library with support for Python 2.7 diff --git a/contrib/python/google-auth/py3/google/auth/__init__.py b/contrib/python/google-auth/py3/google/auth/__init__.py index 2875772b37..765bbd7058 100644 --- a/contrib/python/google-auth/py3/google/auth/__init__.py +++ b/contrib/python/google-auth/py3/google/auth/__init__.py @@ -15,6 +15,8 @@ """Google Auth Library for Python.""" import logging +import sys +import warnings from google.auth import version as google_auth_version from google.auth._default import ( @@ -29,5 +31,23 @@ __version__ = google_auth_version.__version__ __all__ = ["default", "load_credentials_from_file", "load_credentials_from_dict"] + +class Python37DeprecationWarning(DeprecationWarning): # pragma: NO COVER + """ + Deprecation warning raised when Python 3.7 runtime is detected. + Python 3.7 support will be dropped after January 1, 2024. + """ + + pass + + +# Checks if the current runtime is Python 3.7. +if sys.version_info.major == 3 and sys.version_info.minor == 7: # pragma: NO COVER + message = ( + "After January 1, 2024, new releases of this library will drop support " + "for Python 3.7." + ) + warnings.warn(message, Python37DeprecationWarning) + # Set default logging handler to avoid "No handler found" warnings. logging.getLogger(__name__).addHandler(logging.NullHandler()) diff --git a/contrib/python/google-auth/py3/google/auth/_helpers.py b/contrib/python/google-auth/py3/google/auth/_helpers.py index ad2c095f28..a6c07f7d82 100644 --- a/contrib/python/google-auth/py3/google/auth/_helpers.py +++ b/contrib/python/google-auth/py3/google/auth/_helpers.py @@ -17,16 +17,15 @@ import base64 import calendar import datetime +from email.message import Message import sys import urllib from google.auth import exceptions -# Token server doesn't provide a new a token when doing refresh unless the -# token is expiring within 30 seconds, so refresh threshold should not be -# more than 30 seconds. Otherwise auth lib will send tons of refresh requests -# until 30 seconds before the expiration, and cause a spike of CPU usage. -REFRESH_THRESHOLD = datetime.timedelta(seconds=20) +# The smallest MDS cache used by this library stores tokens until 4 minutes from +# expiry. +REFRESH_THRESHOLD = datetime.timedelta(minutes=3, seconds=45) def copy_docstring(source_class): @@ -63,13 +62,42 @@ def copy_docstring(source_class): return decorator +def parse_content_type(header_value): + """Parse a 'content-type' header value to get just the plain media-type (without parameters). + + This is done using the class Message from email.message as suggested in PEP 594 + (because the cgi is now deprecated and will be removed in python 3.13, + see https://peps.python.org/pep-0594/#cgi). + + Args: + header_value (str): The value of a 'content-type' header as a string. + + Returns: + str: A string with just the lowercase media-type from the parsed 'content-type' header. + If the provided content-type is not parsable, returns 'text/plain', + the default value for textual files. + """ + m = Message() + m["content-type"] = header_value + return ( + m.get_content_type() + ) # Despite the name, actually returns just the media-type + + def utcnow(): """Returns the current UTC datetime. Returns: datetime: The current time in UTC. """ - return datetime.datetime.utcnow() + # We used datetime.utcnow() before, since it's deprecated from python 3.12, + # we are using datetime.now(timezone.utc) now. "utcnow()" is offset-native + # (no timezone info), but "now()" is offset-aware (with timezone info). + # This will cause datetime comparison problem. For backward compatibility, + # we need to remove the timezone info. + now = datetime.datetime.now(datetime.timezone.utc) + now = now.replace(tzinfo=None) + return now def datetime_to_secs(value): diff --git a/contrib/python/google-auth/py3/google/auth/compute_engine/__init__.py b/contrib/python/google-auth/py3/google/auth/compute_engine/__init__.py index 5c84234e93..7e1206fc1b 100644 --- a/contrib/python/google-auth/py3/google/auth/compute_engine/__init__.py +++ b/contrib/python/google-auth/py3/google/auth/compute_engine/__init__.py @@ -14,8 +14,9 @@ """Google Compute Engine authentication.""" +from google.auth.compute_engine._metadata import detect_gce_residency_linux from google.auth.compute_engine.credentials import Credentials from google.auth.compute_engine.credentials import IDTokenCredentials -__all__ = ["Credentials", "IDTokenCredentials"] +__all__ = ["Credentials", "IDTokenCredentials", "detect_gce_residency_linux"] diff --git a/contrib/python/google-auth/py3/google/auth/compute_engine/_metadata.py b/contrib/python/google-auth/py3/google/auth/compute_engine/_metadata.py index 04abe178f5..1c884c3c43 100644 --- a/contrib/python/google-auth/py3/google/auth/compute_engine/_metadata.py +++ b/contrib/python/google-auth/py3/google/auth/compute_engine/_metadata.py @@ -156,6 +156,7 @@ def get( recursive=False, retry_count=5, headers=None, + return_none_for_not_found_error=False, ): """Fetch a resource from the metadata server. @@ -173,6 +174,8 @@ def get( retry_count (int): How many times to attempt connecting to metadata server using above timeout. headers (Optional[Mapping[str, str]]): Headers for the request. + return_none_for_not_found_error (Optional[bool]): If True, returns None + for 404 error instead of throwing an exception. Returns: Union[Mapping, str]: If the metadata server returns JSON, a mapping of @@ -216,9 +219,21 @@ def get( "metadata service. Compute Engine Metadata server unavailable".format(url) ) + content = _helpers.from_bytes(response.data) + + if response.status == http_client.NOT_FOUND and return_none_for_not_found_error: + _LOGGER.info( + "Compute Engine Metadata server call to %s returned 404, reason: %s", + path, + content, + ) + return None + if response.status == http_client.OK: - content = _helpers.from_bytes(response.data) - if response.headers["content-type"] == "application/json": + if ( + _helpers.parse_content_type(response.headers["content-type"]) + == "application/json" + ): try: return json.loads(content) except ValueError as caught_exc: @@ -229,14 +244,14 @@ def get( raise new_exc from caught_exc else: return content - else: - raise exceptions.TransportError( - "Failed to retrieve {} from the Google Compute Engine " - "metadata service. Status: {} Response:\n{}".format( - url, response.status, response.data - ), - response, - ) + + raise exceptions.TransportError( + "Failed to retrieve {} from the Google Compute Engine " + "metadata service. Status: {} Response:\n{}".format( + url, response.status, response.data + ), + response, + ) def get_project_id(request): @@ -256,6 +271,29 @@ def get_project_id(request): return get(request, "project/project-id") +def get_universe_domain(request): + """Get the universe domain value from the metadata server. + + Args: + request (google.auth.transport.Request): A callable used to make + HTTP requests. + + Returns: + str: The universe domain value. If the universe domain endpoint is not + not found, return the default value, which is googleapis.com + + Raises: + google.auth.exceptions.TransportError: if an error other than + 404 occurs while retrieving metadata. + """ + universe_domain = get( + request, "universe/universe_domain", return_none_for_not_found_error=True + ) + if not universe_domain: + return "googleapis.com" + return universe_domain + + def get_service_account_info(request, service_account="default"): """Get information about a service account from the metadata server. diff --git a/contrib/python/google-auth/py3/google/auth/compute_engine/credentials.py b/contrib/python/google-auth/py3/google/auth/compute_engine/credentials.py index 7ae673880f..a035c7697a 100644 --- a/contrib/python/google-auth/py3/google/auth/compute_engine/credentials.py +++ b/contrib/python/google-auth/py3/google/auth/compute_engine/credentials.py @@ -28,6 +28,7 @@ from google.auth import iam from google.auth import jwt from google.auth import metrics from google.auth.compute_engine import _metadata +from google.auth.transport import requests as google_auth_requests from google.oauth2 import _client @@ -73,6 +74,8 @@ class Credentials(credentials.Scoped, credentials.CredentialsWithQuotaProject): self._quota_project_id = quota_project_id self._scopes = scopes self._default_scopes = default_scopes + self._universe_domain_cached = False + self._universe_domain_request = google_auth_requests.Request() def _retrieve_info(self, request): """Retrieve information about the service account. @@ -131,6 +134,16 @@ class Credentials(credentials.Scoped, credentials.CredentialsWithQuotaProject): def requires_scopes(self): return not self._scopes + @property + def universe_domain(self): + if self._universe_domain_cached: + return self._universe_domain + self._universe_domain = _metadata.get_universe_domain( + self._universe_domain_request + ) + self._universe_domain_cached = True + return self._universe_domain + @_helpers.copy_docstring(credentials.CredentialsWithQuotaProject) def with_quota_project(self, quota_project_id): return self.__class__( diff --git a/contrib/python/google-auth/py3/google/auth/credentials.py b/contrib/python/google-auth/py3/google/auth/credentials.py index 80a2a5c0b4..800781c408 100644 --- a/contrib/python/google-auth/py3/google/auth/credentials.py +++ b/contrib/python/google-auth/py3/google/auth/credentials.py @@ -52,8 +52,9 @@ class Credentials(metaclass=abc.ABCMeta): self._quota_project_id = None """Optional[str]: Project to use for quota and billing purposes.""" self._trust_boundary = None - """Optional[str]: Encoded string representation of credentials trust - boundary.""" + """Optional[dict]: Cache of a trust boundary response which has a list + of allowed regions and an encoded string representation of credentials + trust boundary.""" self._universe_domain = "googleapis.com" """Optional[str]: The universe domain value, default is googleapis.com """ @@ -135,8 +136,21 @@ class Credentials(metaclass=abc.ABCMeta): headers["authorization"] = "Bearer {}".format( _helpers.from_bytes(token or self.token) ) + """Trust boundary value will be a cached value from global lookup. + + The response of trust boundary will be a list of regions and a hex + encoded representation. + + An example of global lookup response: + { + "locations": [ + "us-central1", "us-east1", "europe-west1", "asia-east1" + ] + "encoded_locations": "0xA30" + } + """ if self._trust_boundary is not None: - headers["x-identity-trust-boundary"] = self._trust_boundary + headers["x-allowed-locations"] = self._trust_boundary["encoded_locations"] if self.quota_project_id: headers["x-goog-user-project"] = self.quota_project_id diff --git a/contrib/python/google-auth/py3/google/auth/crypt/_cryptography_rsa.py b/contrib/python/google-auth/py3/google/auth/crypt/_cryptography_rsa.py index 4f2d611666..1a3e9ff52c 100644 --- a/contrib/python/google-auth/py3/google/auth/crypt/_cryptography_rsa.py +++ b/contrib/python/google-auth/py3/google/auth/crypt/_cryptography_rsa.py @@ -134,3 +134,18 @@ class RSASigner(base.Signer, base.FromServiceAccountMixin): key, password=None, backend=_BACKEND ) return cls(private_key, key_id=key_id) + + def __getstate__(self): + """Pickle helper that serializes the _key attribute.""" + state = self.__dict__.copy() + state["_key"] = self._key.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.PKCS8, + encryption_algorithm=serialization.NoEncryption(), + ) + return state + + def __setstate__(self, state): + """Pickle helper that deserializes the _key attribute.""" + state["_key"] = serialization.load_pem_private_key(state["_key"], None) + self.__dict__.update(state) diff --git a/contrib/python/google-auth/py3/google/auth/crypt/es256.py b/contrib/python/google-auth/py3/google/auth/crypt/es256.py index 7920cc7ffb..820e4becce 100644 --- a/contrib/python/google-auth/py3/google/auth/crypt/es256.py +++ b/contrib/python/google-auth/py3/google/auth/crypt/es256.py @@ -158,3 +158,18 @@ class ES256Signer(base.Signer, base.FromServiceAccountMixin): key, password=None, backend=_BACKEND ) return cls(private_key, key_id=key_id) + + def __getstate__(self): + """Pickle helper that serializes the _key attribute.""" + state = self.__dict__.copy() + state["_key"] = self._key.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.PKCS8, + encryption_algorithm=serialization.NoEncryption(), + ) + return state + + def __setstate__(self, state): + """Pickle helper that deserializes the _key attribute.""" + state["_key"] = serialization.load_pem_private_key(state["_key"], None) + self.__dict__.update(state) diff --git a/contrib/python/google-auth/py3/google/auth/external_account.py b/contrib/python/google-auth/py3/google/auth/external_account.py index c45e6f2133..e7fed8695a 100644 --- a/contrib/python/google-auth/py3/google/auth/external_account.py +++ b/contrib/python/google-auth/py3/google/auth/external_account.py @@ -132,7 +132,10 @@ class Credentials( self._default_scopes = default_scopes self._workforce_pool_user_project = workforce_pool_user_project self._universe_domain = universe_domain or _DEFAULT_UNIVERSE_DOMAIN - self._trust_boundary = "0" # expose a placeholder trust boundary value. + self._trust_boundary = { + "locations": [], + "encoded_locations": "0x0", + } # expose a placeholder trust boundary value. if self._client_id: self._client_auth = utils.ClientAuthentication( @@ -412,6 +415,22 @@ class Credentials( new_cred._metrics_options = self._metrics_options return new_cred + def with_universe_domain(self, universe_domain): + """Create a copy of these credentials with the given universe domain. + + Args: + universe_domain (str): The universe domain value. + + Returns: + google.auth.external_account.Credentials: A new credentials + instance. + """ + kwargs = self._constructor_args() + kwargs.update(universe_domain=universe_domain) + new_cred = self.__class__(**kwargs) + new_cred._metrics_options = self._metrics_options + return new_cred + def _initialize_impersonated_credentials(self): """Generates an impersonated credentials. diff --git a/contrib/python/google-auth/py3/google/auth/transport/_custom_tls_signer.py b/contrib/python/google-auth/py3/google/auth/transport/_custom_tls_signer.py index 07f14df02d..57a563d03b 100644 --- a/contrib/python/google-auth/py3/google/auth/transport/_custom_tls_signer.py +++ b/contrib/python/google-auth/py3/google/auth/transport/_custom_tls_signer.py @@ -107,6 +107,22 @@ def load_signer_lib(signer_lib_path): return lib +def load_provider_lib(provider_lib_path): + _LOGGER.debug("loading provider library from %s", provider_lib_path) + + # winmode parameter is only available for python 3.8+. + lib = ( + ctypes.CDLL(provider_lib_path, winmode=0) + if sys.version_info >= (3, 8) and os.name == "nt" + else ctypes.CDLL(provider_lib_path) + ) + + lib.ECP_attach_to_ctx.argtypes = [ctypes.c_void_p, ctypes.c_char_p] + lib.ECP_attach_to_ctx.restype = ctypes.c_int + + return lib + + # Computes SHA256 hash. def _compute_sha256_digest(to_be_signed, to_be_signed_len): from cryptography.hazmat.primitives import hashes @@ -199,21 +215,31 @@ class CustomTlsSigner(object): self._enterprise_cert_file_path = enterprise_cert_file_path self._cert = None self._sign_callback = None + self._provider_lib = None def load_libraries(self): - try: - with open(self._enterprise_cert_file_path, "r") as f: - enterprise_cert_json = json.load(f) - libs = enterprise_cert_json["libs"] - signer_library = libs["ecp_client"] - offload_library = libs["tls_offload"] - except (KeyError, ValueError) as caught_exc: - new_exc = exceptions.MutualTLSChannelError( - "enterprise cert file is invalid", caught_exc - ) - raise new_exc from caught_exc - self._offload_lib = load_offload_lib(offload_library) - self._signer_lib = load_signer_lib(signer_library) + with open(self._enterprise_cert_file_path, "r") as f: + enterprise_cert_json = json.load(f) + libs = enterprise_cert_json.get("libs", {}) + + signer_library = libs.get("ecp_client", None) + offload_library = libs.get("tls_offload", None) + provider_library = libs.get("ecp_provider", None) + + # Using newer provider implementation. This is mutually exclusive to the + # offload implementation. + if provider_library: + self._provider_lib = load_provider_lib(provider_library) + return + + # Using old offload implementation + if offload_library and signer_library: + self._offload_lib = load_offload_lib(offload_library) + self._signer_lib = load_signer_lib(signer_library) + self.set_up_custom_key() + return + + raise exceptions.MutualTLSChannelError("enterprise cert file is invalid") def set_up_custom_key(self): # We need to keep a reference of the cert and sign callback so it won't @@ -224,11 +250,22 @@ class CustomTlsSigner(object): ) def attach_to_ssl_context(self, ctx): - # In the TLS handshake, the signing operation will be done by the - # sign_callback. - if not self._offload_lib.ConfigureSslContext( - self._sign_callback, - ctypes.c_char_p(self._cert), - _cast_ssl_ctx_to_void_p(ctx._ctx._context), - ): - raise exceptions.MutualTLSChannelError("failed to configure SSL context") + if self._provider_lib: + if not self._provider_lib.ECP_attach_to_ctx( + _cast_ssl_ctx_to_void_p(ctx._ctx._context), + self._enterprise_cert_file_path.encode("ascii"), + ): + raise exceptions.MutualTLSChannelError( + "failed to configure ECP Provider SSL context" + ) + elif self._offload_lib and self._signer_lib: + if not self._offload_lib.ConfigureSslContext( + self._sign_callback, + ctypes.c_char_p(self._cert), + _cast_ssl_ctx_to_void_p(ctx._ctx._context), + ): + raise exceptions.MutualTLSChannelError( + "failed to configure ECP Offload SSL context" + ) + else: + raise exceptions.MutualTLSChannelError("Invalid ECP configuration.") diff --git a/contrib/python/google-auth/py3/google/auth/transport/requests.py b/contrib/python/google-auth/py3/google/auth/transport/requests.py index b9bcad359f..aa16113226 100644 --- a/contrib/python/google-auth/py3/google/auth/transport/requests.py +++ b/contrib/python/google-auth/py3/google/auth/transport/requests.py @@ -274,7 +274,6 @@ class _MutualTlsOffloadAdapter(requests.adapters.HTTPAdapter): self.signer = _custom_tls_signer.CustomTlsSigner(enterprise_cert_file_path) self.signer.load_libraries() - self.signer.set_up_custom_key() poolmanager = create_urllib3_context() poolmanager.load_verify_locations(cafile=certifi.where()) diff --git a/contrib/python/google-auth/py3/google/auth/transport/urllib3.py b/contrib/python/google-auth/py3/google/auth/transport/urllib3.py index 053d6f7b72..63144f5fff 100644 --- a/contrib/python/google-auth/py3/google/auth/transport/urllib3.py +++ b/contrib/python/google-auth/py3/google/auth/transport/urllib3.py @@ -40,11 +40,18 @@ except ImportError as caught_exc: # pragma: NO COVER "urllib3 package to use the urllib3 transport." ) from caught_exc +from packaging import version # type: ignore + from google.auth import environment_vars from google.auth import exceptions from google.auth import transport from google.oauth2 import service_account +if version.parse(urllib3.__version__) >= version.parse("2.0.0"): # pragma: NO COVER + RequestMethods = urllib3._request_methods.RequestMethods # type: ignore +else: # pragma: NO COVER + RequestMethods = urllib3.request.RequestMethods # type: ignore + _LOGGER = logging.getLogger(__name__) @@ -179,7 +186,7 @@ def _make_mutual_tls_http(cert, key): return http -class AuthorizedHttp(urllib3.request.RequestMethods): +class AuthorizedHttp(RequestMethods): # type: ignore """A urllib3 HTTP class with credentials. This class is used to perform requests to API endpoints that require diff --git a/contrib/python/google-auth/py3/google/auth/version.py b/contrib/python/google-auth/py3/google/auth/version.py index 491187e6d7..31cc30242a 100644 --- a/contrib/python/google-auth/py3/google/auth/version.py +++ b/contrib/python/google-auth/py3/google/auth/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "2.23.0" +__version__ = "2.25.2" diff --git a/contrib/python/google-auth/py3/google/oauth2/__init__.py b/contrib/python/google-auth/py3/google/oauth2/__init__.py index 4fb71fd1ad..accae96579 100644 --- a/contrib/python/google-auth/py3/google/oauth2/__init__.py +++ b/contrib/python/google-auth/py3/google/oauth2/__init__.py @@ -13,3 +13,24 @@ # limitations under the License. """Google OAuth 2.0 Library for Python.""" + +import sys +import warnings + + +class Python37DeprecationWarning(DeprecationWarning): # pragma: NO COVER + """ + Deprecation warning raised when Python 3.7 runtime is detected. + Python 3.7 support will be dropped after January 1, 2024. + """ + + pass + + +# Checks if the current runtime is Python 3.7. +if sys.version_info.major == 3 and sys.version_info.minor == 7: # pragma: NO COVER + message = ( + "After January 1, 2024, new releases of this library will drop support " + "for Python 3.7." + ) + warnings.warn(message, Python37DeprecationWarning) diff --git a/contrib/python/google-auth/py3/google/oauth2/_credentials_async.py b/contrib/python/google-auth/py3/google/oauth2/_credentials_async.py index e7b9637c82..b5561aae02 100644 --- a/contrib/python/google-auth/py3/google/oauth2/_credentials_async.py +++ b/contrib/python/google-auth/py3/google/oauth2/_credentials_async.py @@ -96,6 +96,12 @@ class Credentials(oauth2_credentials.Credentials): ) ) + @_helpers.copy_docstring(credentials.Credentials) + async def before_request(self, request, method, url, headers): + if not self.valid: + await self.refresh(request) + self.apply(headers) + class UserAccessTokenCredentials(oauth2_credentials.UserAccessTokenCredentials): """Access token credentials for user account. diff --git a/contrib/python/google-auth/py3/google/oauth2/credentials.py b/contrib/python/google-auth/py3/google/oauth2/credentials.py index 4643fdbea6..a5c93ecc2f 100644 --- a/contrib/python/google-auth/py3/google/oauth2/credentials.py +++ b/contrib/python/google-auth/py3/google/oauth2/credentials.py @@ -49,13 +49,15 @@ _LOGGER = logging.getLogger(__name__) # The Google OAuth 2.0 token endpoint. Used for authorized user credentials. _GOOGLE_OAUTH2_TOKEN_ENDPOINT = "https://oauth2.googleapis.com/token" +_DEFAULT_UNIVERSE_DOMAIN = "googleapis.com" class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaProject): """Credentials using OAuth 2.0 access and refresh tokens. - The credentials are considered immutable. If you want to modify the - quota project, use :meth:`with_quota_project` or :: + The credentials are considered immutable except the tokens and the token + expiry, which are updated after refresh. If you want to modify the quota + project, use :meth:`with_quota_project` or :: credentials = credentials.with_quota_project('myproject-123') @@ -84,6 +86,7 @@ class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaPr enable_reauth_refresh=False, granted_scopes=None, trust_boundary=None, + universe_domain=_DEFAULT_UNIVERSE_DOMAIN, ): """ Args: @@ -125,6 +128,9 @@ class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaPr granted_scopes (Optional[Sequence[str]]): The scopes that were consented/granted by the user. This could be different from the requested scopes and it could be empty if granted and requested scopes were same. + trust_boundary (str): String representation of trust boundary meta. + universe_domain (Optional[str]): The universe domain. The default + universe domain is googleapis.com. """ super(Credentials, self).__init__() self.token = token @@ -142,6 +148,7 @@ class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaPr self.refresh_handler = refresh_handler self._enable_reauth_refresh = enable_reauth_refresh self._trust_boundary = trust_boundary + self._universe_domain = universe_domain or _DEFAULT_UNIVERSE_DOMAIN def __getstate__(self): """A __getstate__ method must exist for the __setstate__ to be called @@ -173,7 +180,7 @@ class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaPr self._rapt_token = d.get("_rapt_token") self._enable_reauth_refresh = d.get("_enable_reauth_refresh") self._trust_boundary = d.get("_trust_boundary") - self._universe_domain = d.get("_universe_domain") + self._universe_domain = d.get("_universe_domain") or _DEFAULT_UNIVERSE_DOMAIN # The refresh_handler setter should be used to repopulate this. self._refresh_handler = None @@ -272,6 +279,7 @@ class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaPr rapt_token=self.rapt_token, enable_reauth_refresh=self._enable_reauth_refresh, trust_boundary=self._trust_boundary, + universe_domain=self._universe_domain, ) @_helpers.copy_docstring(credentials.CredentialsWithTokenUri) @@ -291,6 +299,34 @@ class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaPr rapt_token=self.rapt_token, enable_reauth_refresh=self._enable_reauth_refresh, trust_boundary=self._trust_boundary, + universe_domain=self._universe_domain, + ) + + def with_universe_domain(self, universe_domain): + """Create a copy of the credential with the given universe domain. + + Args: + universe_domain (str): The universe domain value. + + Returns: + google.oauth2.credentials.Credentials: A new credentials instance. + """ + + return self.__class__( + self.token, + refresh_token=self.refresh_token, + id_token=self.id_token, + token_uri=self._token_uri, + client_id=self.client_id, + client_secret=self.client_secret, + scopes=self.scopes, + default_scopes=self.default_scopes, + granted_scopes=self.granted_scopes, + quota_project_id=self.quota_project_id, + rapt_token=self.rapt_token, + enable_reauth_refresh=self._enable_reauth_refresh, + trust_boundary=self._trust_boundary, + universe_domain=universe_domain, ) def _metric_header_for_usage(self): @@ -298,6 +334,17 @@ class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaPr @_helpers.copy_docstring(credentials.Credentials) def refresh(self, request): + if self._universe_domain != _DEFAULT_UNIVERSE_DOMAIN: + raise exceptions.RefreshError( + "User credential refresh is only supported in the default " + "googleapis.com universe domain, but the current universe " + "domain is {}. If you created the credential with an access " + "token, it's likely that the provided token is expired now, " + "please update your code with a valid token.".format( + self._universe_domain + ) + ) + scopes = self._scopes if self._scopes is not None else self._default_scopes # Use refresh handler if available and no refresh token is # available. This is useful in general when tokens are obtained by calling @@ -427,6 +474,7 @@ class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaPr expiry=expiry, rapt_token=info.get("rapt_token"), # may not exist trust_boundary=info.get("trust_boundary"), # may not exist + universe_domain=info.get("universe_domain"), # may not exist ) @classmethod @@ -470,6 +518,7 @@ class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaPr "client_secret": self.client_secret, "scopes": self.scopes, "rapt_token": self.rapt_token, + "universe_domain": self._universe_domain, } if self.expiry: # flatten expiry timestamp prep["expiry"] = self.expiry.isoformat() + "Z" diff --git a/contrib/python/google-auth/py3/google/oauth2/service_account.py b/contrib/python/google-auth/py3/google/oauth2/service_account.py index e08899f8e5..68db41af40 100644 --- a/contrib/python/google-auth/py3/google/oauth2/service_account.py +++ b/contrib/python/google-auth/py3/google/oauth2/service_account.py @@ -182,10 +182,7 @@ class Credentials( self._quota_project_id = quota_project_id self._token_uri = token_uri self._always_use_jwt_access = always_use_jwt_access - if not universe_domain: - self._universe_domain = _DEFAULT_UNIVERSE_DOMAIN - else: - self._universe_domain = universe_domain + self._universe_domain = universe_domain or _DEFAULT_UNIVERSE_DOMAIN if universe_domain != _DEFAULT_UNIVERSE_DOMAIN: self._always_use_jwt_access = True @@ -196,7 +193,7 @@ class Credentials( self._additional_claims = additional_claims else: self._additional_claims = {} - self._trust_boundary = "0" + self._trust_boundary = {"locations": [], "encoded_locations": "0x0"} @classmethod def _from_signer_and_info(cls, signer, info, **kwargs): @@ -328,6 +325,22 @@ class Credentials( cred._always_use_jwt_access = always_use_jwt_access return cred + def with_universe_domain(self, universe_domain): + """Create a copy of these credentials with the given universe domain. + + Args: + universe_domain (str): The universe domain value. + + Returns: + google.auth.service_account.Credentials: A new credentials + instance. + """ + cred = self._make_copy() + cred._universe_domain = universe_domain + if universe_domain != _DEFAULT_UNIVERSE_DOMAIN: + cred._always_use_jwt_access = True + return cred + def with_subject(self, subject): """Create a copy of these credentials with the specified subject. @@ -417,13 +430,11 @@ class Credentials( @_helpers.copy_docstring(credentials.Credentials) def refresh(self, request): - if ( - self._universe_domain != _DEFAULT_UNIVERSE_DOMAIN - and not self._jwt_credentials - ): - raise exceptions.RefreshError( - "self._jwt_credentials is missing for non-default universe domain" - ) + if self._always_use_jwt_access and not self._jwt_credentials: + # If self signed jwt should be used but jwt credential is not + # created, try to create one with scopes + self._create_self_signed_jwt(None) + if self._universe_domain != _DEFAULT_UNIVERSE_DOMAIN and self._subject: raise exceptions.RefreshError( "domain wide delegation is not supported for non-default universe domain" diff --git a/contrib/python/google-auth/py3/tests/compute_engine/test__metadata.py b/contrib/python/google-auth/py3/tests/compute_engine/test__metadata.py index ddf84596af..5e037a940b 100644 --- a/contrib/python/google-auth/py3/tests/compute_engine/test__metadata.py +++ b/contrib/python/google-auth/py3/tests/compute_engine/test__metadata.py @@ -63,6 +63,7 @@ def make_request(data, status=http_client.OK, headers=None, retry=False): return request +@pytest.mark.xfail def test_detect_gce_residency_linux_success(): _metadata._GCE_PRODUCT_NAME_FILE = SMBIOS_PRODUCT_NAME_FILE assert _metadata.detect_gce_residency_linux() @@ -89,6 +90,7 @@ def test_is_on_gce_windows_success(): assert not _metadata.is_on_gce(request) +@pytest.mark.xfail @mock.patch("os.name", new="posix") def test_is_on_gce_linux_success(): request = make_request("", headers={_metadata._METADATA_FLAVOR_HEADER: "meep"}) @@ -176,6 +178,24 @@ def test_get_success_json(): assert result[key] == value +def test_get_success_json_content_type_charset(): + key, value = "foo", "bar" + + data = json.dumps({key: value}) + request = make_request( + data, headers={"content-type": "application/json; charset=UTF-8"} + ) + + result = _metadata.get(request, PATH) + + request.assert_called_once_with( + method="GET", + url=_metadata._METADATA_ROOT + PATH, + headers=_metadata._METADATA_HEADERS, + ) + assert result[key] == value + + def test_get_success_retry(): key, value = "foo", "bar" @@ -307,6 +327,18 @@ def test_get_failure(): ) +def test_get_return_none_for_not_found_error(): + request = make_request("Metadata error", status=http_client.NOT_FOUND) + + assert _metadata.get(request, PATH, return_none_for_not_found_error=True) is None + + request.assert_called_once_with( + method="GET", + url=_metadata._METADATA_ROOT + PATH, + headers=_metadata._METADATA_HEADERS, + ) + + def test_get_failure_connection_failed(): request = make_request("") request.side_effect = exceptions.TransportError() @@ -353,6 +385,53 @@ def test_get_project_id(): assert project_id == project +def test_get_universe_domain_success(): + request = make_request( + "fake_universe_domain", headers={"content-type": "text/plain"} + ) + + universe_domain = _metadata.get_universe_domain(request) + + request.assert_called_once_with( + method="GET", + url=_metadata._METADATA_ROOT + "universe/universe_domain", + headers=_metadata._METADATA_HEADERS, + ) + assert universe_domain == "fake_universe_domain" + + +def test_get_universe_domain_not_found(): + # Test that if the universe domain endpoint returns 404 error, we should + # use googleapis.com as the universe domain + request = make_request("not found", status=http_client.NOT_FOUND) + + universe_domain = _metadata.get_universe_domain(request) + + request.assert_called_once_with( + method="GET", + url=_metadata._METADATA_ROOT + "universe/universe_domain", + headers=_metadata._METADATA_HEADERS, + ) + assert universe_domain == "googleapis.com" + + +def test_get_universe_domain_other_error(): + # Test that if the universe domain endpoint returns an error other than 404 + # we should throw the error + request = make_request("unauthorized", status=http_client.UNAUTHORIZED) + + with pytest.raises(exceptions.TransportError) as excinfo: + _metadata.get_universe_domain(request) + + assert excinfo.match(r"unauthorized") + + request.assert_called_once_with( + method="GET", + url=_metadata._METADATA_ROOT + "universe/universe_domain", + headers=_metadata._METADATA_HEADERS, + ) + + @mock.patch( "google.auth.metrics.token_request_access_token_mds", return_value=ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE, diff --git a/contrib/python/google-auth/py3/tests/compute_engine/test_credentials.py b/contrib/python/google-auth/py3/tests/compute_engine/test_credentials.py index 507fea9fcc..5d6ccdcdec 100644 --- a/contrib/python/google-auth/py3/tests/compute_engine/test_credentials.py +++ b/contrib/python/google-auth/py3/tests/compute_engine/test_credentials.py @@ -208,6 +208,30 @@ class TestCredentials(object): assert headers["authorization"] == "Bearer token" assert headers["x-goog-api-client"] == "cred-type/mds" + @mock.patch( + "google.auth.compute_engine._metadata.get_universe_domain", + return_value="fake_universe_domain", + ) + def test_universe_domain(self, get_universe_domain): + self.credentials._universe_domain_cached = False + self.credentials._universe_domain = "googleapis.com" + + # calling the universe_domain property should trigger a call to + # get_universe_domain to fetch the value. The value should be cached. + assert self.credentials.universe_domain == "fake_universe_domain" + assert self.credentials._universe_domain == "fake_universe_domain" + assert self.credentials._universe_domain_cached + get_universe_domain.assert_called_once_with( + self.credentials._universe_domain_request + ) + + # calling the universe_domain property the second time should use the + # cached value instead of calling get_universe_domain + assert self.credentials.universe_domain == "fake_universe_domain" + get_universe_domain.assert_called_once_with( + self.credentials._universe_domain_request + ) + class TestIDTokenCredentials(object): credentials = None diff --git a/contrib/python/google-auth/py3/tests/conftest.py b/contrib/python/google-auth/py3/tests/conftest.py index 08896b0f82..7658d8f456 100644 --- a/contrib/python/google-auth/py3/tests/conftest.py +++ b/contrib/python/google-auth/py3/tests/conftest.py @@ -21,9 +21,14 @@ import pytest # type: ignore def pytest_configure(): """Load public certificate and private key.""" - import __res - pytest.private_key_bytes = __res.find("data/privatekey.pem") - pytest.public_cert_bytes = __res.find("data/public_cert.pem") + import yatest.common as yc + pytest.data_dir = os.path.join(os.path.dirname(yc.source_path("contrib/python/google-auth/py3/tests/conftest.py")), "data") + + with open(os.path.join(pytest.data_dir, "privatekey.pem"), "rb") as fh: + pytest.private_key_bytes = fh.read() + + with open(os.path.join(pytest.data_dir, "public_cert.pem"), "rb") as fh: + pytest.public_cert_bytes = fh.read() @pytest.fixture diff --git a/contrib/python/google-auth/py3/tests/crypt/test__cryptography_rsa.py b/contrib/python/google-auth/py3/tests/crypt/test__cryptography_rsa.py index d19154b61b..2c4cebe0d7 100644 --- a/contrib/python/google-auth/py3/tests/crypt/test__cryptography_rsa.py +++ b/contrib/python/google-auth/py3/tests/crypt/test__cryptography_rsa.py @@ -14,6 +14,7 @@ import json import os +import pickle from cryptography.hazmat.primitives.asymmetric import rsa import pytest # type: ignore @@ -23,8 +24,8 @@ from google.auth.crypt import _cryptography_rsa from google.auth.crypt import base -import yatest.common -DATA_DIR = os.path.join(yatest.common.test_source_path(), "data") +import yatest.common as yc +DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "..", "data") # To generate privatekey.pem, privatekey.pub, and public_cert.pem: # $ openssl req -new -newkey rsa:1024 -x509 -nodes -out public_cert.pem \ @@ -160,3 +161,17 @@ class TestRSASigner(object): assert signer.key_id == SERVICE_ACCOUNT_INFO[base._JSON_FILE_PRIVATE_KEY_ID] assert isinstance(signer._key, rsa.RSAPrivateKey) + + def test_pickle(self): + signer = _cryptography_rsa.RSASigner.from_service_account_file( + SERVICE_ACCOUNT_JSON_FILE + ) + + assert signer.key_id == SERVICE_ACCOUNT_INFO[base._JSON_FILE_PRIVATE_KEY_ID] + assert isinstance(signer._key, rsa.RSAPrivateKey) + + pickled_signer = pickle.dumps(signer) + signer = pickle.loads(pickled_signer) + + assert signer.key_id == SERVICE_ACCOUNT_INFO[base._JSON_FILE_PRIVATE_KEY_ID] + assert isinstance(signer._key, rsa.RSAPrivateKey) diff --git a/contrib/python/google-auth/py3/tests/crypt/test__python_rsa.py b/contrib/python/google-auth/py3/tests/crypt/test__python_rsa.py index 592b523d92..75dcb314f7 100644 --- a/contrib/python/google-auth/py3/tests/crypt/test__python_rsa.py +++ b/contrib/python/google-auth/py3/tests/crypt/test__python_rsa.py @@ -26,8 +26,8 @@ from google.auth.crypt import _python_rsa from google.auth.crypt import base -import yatest.common -DATA_DIR = os.path.join(yatest.common.test_source_path(), "data") +import yatest.common as yc +DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "..", "data") # To generate privatekey.pem, privatekey.pub, and public_cert.pem: # $ openssl req -new -newkey rsa:1024 -x509 -nodes -out public_cert.pem \ diff --git a/contrib/python/google-auth/py3/tests/crypt/test_crypt.py b/contrib/python/google-auth/py3/tests/crypt/test_crypt.py index 97c2abc257..30de18a5dd 100644 --- a/contrib/python/google-auth/py3/tests/crypt/test_crypt.py +++ b/contrib/python/google-auth/py3/tests/crypt/test_crypt.py @@ -17,8 +17,8 @@ import os from google.auth import crypt -import yatest.common -DATA_DIR = os.path.join(yatest.common.test_source_path(), "data") +import yatest.common as yc +DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "..", "data") # To generate privatekey.pem, privatekey.pub, and public_cert.pem: # $ openssl req -new -newkey rsa:1024 -x509 -nodes -out public_cert.pem \ diff --git a/contrib/python/google-auth/py3/tests/crypt/test_es256.py b/contrib/python/google-auth/py3/tests/crypt/test_es256.py index 1a43a2f01b..3ba5b64fad 100644 --- a/contrib/python/google-auth/py3/tests/crypt/test_es256.py +++ b/contrib/python/google-auth/py3/tests/crypt/test_es256.py @@ -15,6 +15,7 @@ import base64 import json import os +import pickle from cryptography.hazmat.primitives.asymmetric import ec import pytest # type: ignore @@ -24,8 +25,8 @@ from google.auth.crypt import base from google.auth.crypt import es256 -import yatest.common -DATA_DIR = os.path.join(yatest.common.test_source_path(), "data") +import yatest.common as yc +DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "..", "data") # To generate es256_privatekey.pem, es256_privatekey.pub, and # es256_public_cert.pem: @@ -142,3 +143,15 @@ class TestES256Signer(object): assert signer.key_id == SERVICE_ACCOUNT_INFO[base._JSON_FILE_PRIVATE_KEY_ID] assert isinstance(signer._key, ec.EllipticCurvePrivateKey) + + def test_pickle(self): + signer = es256.ES256Signer.from_service_account_file(SERVICE_ACCOUNT_JSON_FILE) + + assert signer.key_id == SERVICE_ACCOUNT_INFO[base._JSON_FILE_PRIVATE_KEY_ID] + assert isinstance(signer._key, ec.EllipticCurvePrivateKey) + + pickled_signer = pickle.dumps(signer) + signer = pickle.loads(pickled_signer) + + assert signer.key_id == SERVICE_ACCOUNT_INFO[base._JSON_FILE_PRIVATE_KEY_ID] + assert isinstance(signer._key, ec.EllipticCurvePrivateKey) diff --git a/contrib/python/google-auth/py3/tests/data/enterprise_cert_valid_provider.json b/contrib/python/google-auth/py3/tests/data/enterprise_cert_valid_provider.json new file mode 100644 index 0000000000..9b7adf8bc3 --- /dev/null +++ b/contrib/python/google-auth/py3/tests/data/enterprise_cert_valid_provider.json @@ -0,0 +1,6 @@ +{ + "libs": { + "ecp_client": "/path/to/signer/lib", + "ecp_provider": "/path/to/provider/lib" + } +} diff --git a/contrib/python/google-auth/py3/tests/oauth2/test__client.py b/contrib/python/google-auth/py3/tests/oauth2/test__client.py index 54179269bd..444232f396 100644 --- a/contrib/python/google-auth/py3/tests/oauth2/test__client.py +++ b/contrib/python/google-auth/py3/tests/oauth2/test__client.py @@ -29,8 +29,8 @@ from google.auth import transport from google.oauth2 import _client -import yatest.common -DATA_DIR = os.path.join(yatest.common.test_source_path(), "data") +import yatest.common as yc +DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "..", "data") with open(os.path.join(DATA_DIR, "privatekey.pem"), "rb") as fh: PRIVATE_KEY_BYTES = fh.read() diff --git a/contrib/python/google-auth/py3/tests/oauth2/test_credentials.py b/contrib/python/google-auth/py3/tests/oauth2/test_credentials.py index f2604a5f18..d6a1915862 100644 --- a/contrib/python/google-auth/py3/tests/oauth2/test_credentials.py +++ b/contrib/python/google-auth/py3/tests/oauth2/test_credentials.py @@ -27,8 +27,8 @@ from google.auth import transport from google.oauth2 import credentials -import yatest.common -DATA_DIR = os.path.join(yatest.common.test_source_path(), "data") +import yatest.common as yc +DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "..", "data") AUTH_USER_JSON_FILE = os.path.join(DATA_DIR, "authorized_user.json") @@ -123,6 +123,17 @@ class TestCredentials(object): assert excinfo.match("The provided refresh_handler is not a callable or None.") + def test_refresh_with_non_default_universe_domain(self): + creds = credentials.Credentials( + token="token", universe_domain="dummy_universe.com" + ) + with pytest.raises(exceptions.RefreshError) as excinfo: + creds.refresh(mock.Mock()) + + assert excinfo.match( + "refresh is only supported in the default googleapis.com universe domain" + ) + @mock.patch("google.oauth2.reauth.refresh_grant", autospec=True) @mock.patch( "google.auth._helpers.utcnow", @@ -775,6 +786,12 @@ class TestCredentials(object): creds.apply(headers) assert "x-goog-user-project" in headers + def test_with_universe_domain(self): + creds = credentials.Credentials(token="token") + assert creds.universe_domain == "googleapis.com" + new_creds = creds.with_universe_domain("dummy_universe.com") + assert new_creds.universe_domain == "dummy_universe.com" + def test_with_token_uri(self): info = AUTH_USER_INFO.copy() @@ -869,6 +886,7 @@ class TestCredentials(object): assert json_asdict.get("scopes") == creds.scopes assert json_asdict.get("client_secret") == creds.client_secret assert json_asdict.get("expiry") == info["expiry"] + assert json_asdict.get("universe_domain") == creds.universe_domain # Test with a `strip` arg json_output = creds.to_json(strip=["client_secret"]) @@ -896,6 +914,17 @@ class TestCredentials(object): for attr in list(creds.__dict__): assert getattr(creds, attr) == getattr(unpickled, attr) + def test_pickle_and_unpickle_universe_domain(self): + # old version of auth lib doesn't have _universe_domain, so the pickled + # cred doesn't have such a field. + creds = self.make_credentials() + del creds._universe_domain + + unpickled = pickle.loads(pickle.dumps(creds)) + + # make sure the unpickled cred sets _universe_domain to default. + assert unpickled.universe_domain == "googleapis.com" + def test_pickle_and_unpickle_with_refresh_handler(self): expected_expiry = _helpers.utcnow() + datetime.timedelta(seconds=2800) refresh_handler = mock.Mock(return_value=("TOKEN", expected_expiry)) diff --git a/contrib/python/google-auth/py3/tests/oauth2/test_gdch_credentials.py b/contrib/python/google-auth/py3/tests/oauth2/test_gdch_credentials.py index 1ff61d8683..9a67a07345 100644 --- a/contrib/python/google-auth/py3/tests/oauth2/test_gdch_credentials.py +++ b/contrib/python/google-auth/py3/tests/oauth2/test_gdch_credentials.py @@ -27,7 +27,7 @@ import google.auth.transport.requests from google.oauth2 import gdch_credentials from google.oauth2.gdch_credentials import ServiceAccountCredentials -import yatest.common +import yatest.common as yc class TestServiceAccountCredentials(object): @@ -39,7 +39,7 @@ class TestServiceAccountCredentials(object): TOKEN_URI = "https://service-identity.<Domain>/authenticate" JSON_PATH = os.path.join( - yatest.common.test_source_path(), "data", "gdch_service_account.json" + os.path.dirname(yc.source_path(__file__)), "..", "data", "gdch_service_account.json" ) with open(JSON_PATH, "rb") as fh: INFO = json.load(fh) diff --git a/contrib/python/google-auth/py3/tests/oauth2/test_id_token.py b/contrib/python/google-auth/py3/tests/oauth2/test_id_token.py index 861f76ce4f..8657bdfb7e 100644 --- a/contrib/python/google-auth/py3/tests/oauth2/test_id_token.py +++ b/contrib/python/google-auth/py3/tests/oauth2/test_id_token.py @@ -24,9 +24,9 @@ from google.auth import transport from google.oauth2 import id_token from google.oauth2 import service_account -import yatest.common +import yatest.common as yc SERVICE_ACCOUNT_FILE = os.path.join( - yatest.common.test_source_path(), "data/service_account.json" + os.path.dirname(yc.source_path(__file__)), "../data/service_account.json" ) ID_TOKEN_AUDIENCE = "https://pubsub.googleapis.com" @@ -263,7 +263,7 @@ def test_fetch_id_token_credentials_no_cred_exists(monkeypatch): def test_fetch_id_token_credentials_invalid_cred_file_type(monkeypatch): user_credentials_file = os.path.join( - yatest.common.test_source_path(), "data/authorized_user.json" + os.path.dirname(yc.source_path(__file__)), "../data/authorized_user.json" ) monkeypatch.setenv(environment_vars.CREDENTIALS, user_credentials_file) @@ -276,7 +276,7 @@ def test_fetch_id_token_credentials_invalid_cred_file_type(monkeypatch): def test_fetch_id_token_credentials_invalid_json(monkeypatch): - not_json_file = os.path.join(yatest.common.test_source_path(), "data/public_cert.pem") + not_json_file = os.path.join(os.path.dirname(yc.source_path(__file__)), "../data/public_cert.pem") monkeypatch.setenv(environment_vars.CREDENTIALS, not_json_file) with pytest.raises(exceptions.DefaultCredentialsError) as excinfo: @@ -287,7 +287,7 @@ def test_fetch_id_token_credentials_invalid_json(monkeypatch): def test_fetch_id_token_credentials_invalid_cred_path(monkeypatch): - not_json_file = os.path.join(yatest.common.test_source_path(), "data/not_exists.json") + not_json_file = os.path.join(os.path.dirname(yc.source_path(__file__)), "../data/not_exists.json") monkeypatch.setenv(environment_vars.CREDENTIALS, not_json_file) with pytest.raises(exceptions.DefaultCredentialsError) as excinfo: diff --git a/contrib/python/google-auth/py3/tests/oauth2/test_service_account.py b/contrib/python/google-auth/py3/tests/oauth2/test_service_account.py index c474c90e6b..8dd5f219be 100644 --- a/contrib/python/google-auth/py3/tests/oauth2/test_service_account.py +++ b/contrib/python/google-auth/py3/tests/oauth2/test_service_account.py @@ -27,8 +27,8 @@ from google.auth import transport from google.oauth2 import service_account -import yatest.common -DATA_DIR = os.path.join(yatest.common.test_source_path(), "data") +import yatest.common as yc +DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "..", "data") with open(os.path.join(DATA_DIR, "privatekey.pem"), "rb") as fh: PRIVATE_KEY_BYTES = fh.read() @@ -206,6 +206,17 @@ class TestCredentials(object): creds_with_new_token_uri = credentials.with_token_uri(new_token_uri) assert creds_with_new_token_uri._token_uri == new_token_uri + def test_with_universe_domain(self): + credentials = self.make_credentials() + + new_credentials = credentials.with_universe_domain("dummy_universe.com") + assert new_credentials.universe_domain == "dummy_universe.com" + assert new_credentials._always_use_jwt_access + + new_credentials = credentials.with_universe_domain("googleapis.com") + assert new_credentials.universe_domain == "googleapis.com" + assert not new_credentials._always_use_jwt_access + def test__with_always_use_jwt_access(self): credentials = self.make_credentials() assert not credentials._always_use_jwt_access @@ -558,12 +569,16 @@ class TestCredentials(object): assert jwt_grant.called assert not self_signed_jwt_refresh.called - def test_refresh_non_gdu_missing_jwt_credentials(self): - credentials = self.make_credentials(universe_domain="foo") + def test_refresh_missing_jwt_credentials(self): + credentials = self.make_credentials() + credentials = credentials.with_scopes(["foo", "bar"]) + credentials = credentials.with_always_use_jwt_access(True) + assert not credentials._jwt_credentials - with pytest.raises(exceptions.RefreshError) as excinfo: - credentials.refresh(None) - assert excinfo.match("self._jwt_credentials is missing") + credentials.refresh(mock.Mock()) + + # jwt credentials should have been automatically created with scopes + assert credentials._jwt_credentials is not None def test_refresh_non_gdu_domain_wide_delegation_not_supported(self): credentials = self.make_credentials(universe_domain="foo") diff --git a/contrib/python/google-auth/py3/tests/test__cloud_sdk.py b/contrib/python/google-auth/py3/tests/test__cloud_sdk.py index 18ac18fa35..d46621a7f3 100644 --- a/contrib/python/google-auth/py3/tests/test__cloud_sdk.py +++ b/contrib/python/google-auth/py3/tests/test__cloud_sdk.py @@ -26,8 +26,8 @@ from google.auth import environment_vars from google.auth import exceptions -import yatest.common -DATA_DIR = os.path.join(yatest.common.test_source_path(), "data") +import yatest.common as yc +DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "data") AUTHORIZED_USER_FILE = os.path.join(DATA_DIR, "authorized_user.json") with io.open(AUTHORIZED_USER_FILE, "rb") as fh: @@ -66,8 +66,7 @@ def test_get_project_id_call_error(check_output): assert check_output.called -@pytest.mark.xfail -def test__run_subprocess_ignore_stderr(): +def _test__run_subprocess_ignore_stderr(): command = [ sys.executable, "-c", diff --git a/contrib/python/google-auth/py3/tests/test__default.py b/contrib/python/google-auth/py3/tests/test__default.py index 29904ec7aa..d619614790 100644 --- a/contrib/python/google-auth/py3/tests/test__default.py +++ b/contrib/python/google-auth/py3/tests/test__default.py @@ -36,8 +36,8 @@ from google.oauth2 import service_account import google.oauth2.credentials -import yatest.common -DATA_DIR = os.path.join(yatest.common.test_source_path(), "data") +import yatest.common as yc +DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "data") AUTHORIZED_USER_FILE = os.path.join(DATA_DIR, "authorized_user.json") with open(AUTHORIZED_USER_FILE) as fh: diff --git a/contrib/python/google-auth/py3/tests/test__helpers.py b/contrib/python/google-auth/py3/tests/test__helpers.py index c1f1d812e5..c9a3847ac4 100644 --- a/contrib/python/google-auth/py3/tests/test__helpers.py +++ b/contrib/python/google-auth/py3/tests/test__helpers.py @@ -51,6 +51,32 @@ def test_copy_docstring_non_existing(): _helpers.copy_docstring(SourceClass)(func2) +def test_parse_content_type_plain(): + assert _helpers.parse_content_type("text/html") == "text/html" + assert _helpers.parse_content_type("application/xml") == "application/xml" + assert _helpers.parse_content_type("application/json") == "application/json" + + +def test_parse_content_type_with_parameters(): + content_type_html = "text/html; charset=UTF-8" + content_type_xml = "application/xml; charset=UTF-16; version=1.0" + content_type_json = "application/json; charset=UTF-8; indent=2" + assert _helpers.parse_content_type(content_type_html) == "text/html" + assert _helpers.parse_content_type(content_type_xml) == "application/xml" + assert _helpers.parse_content_type(content_type_json) == "application/json" + + +def test_parse_content_type_missing_or_broken(): + content_type_foo = None + content_type_bar = "" + content_type_baz = "1234" + content_type_qux = " ; charset=UTF-8" + assert _helpers.parse_content_type(content_type_foo) == "text/plain" + assert _helpers.parse_content_type(content_type_bar) == "text/plain" + assert _helpers.parse_content_type(content_type_baz) == "text/plain" + assert _helpers.parse_content_type(content_type_qux) == "text/plain" + + def test_utcnow(): assert isinstance(_helpers.utcnow(), datetime.datetime) diff --git a/contrib/python/google-auth/py3/tests/test__oauth2client.py b/contrib/python/google-auth/py3/tests/test__oauth2client.py index 72db6535bc..1db595fd9a 100644 --- a/contrib/python/google-auth/py3/tests/test__oauth2client.py +++ b/contrib/python/google-auth/py3/tests/test__oauth2client.py @@ -33,8 +33,8 @@ except ImportError: # pragma: NO COVER from google.auth import _oauth2client -import yatest.common -DATA_DIR = os.path.join(yatest.common.test_source_path(), "data") +import yatest.common as yc +DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "data") SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, "service_account.json") diff --git a/contrib/python/google-auth/py3/tests/test__service_account_info.py b/contrib/python/google-auth/py3/tests/test__service_account_info.py index db8106081c..2335765bb4 100644 --- a/contrib/python/google-auth/py3/tests/test__service_account_info.py +++ b/contrib/python/google-auth/py3/tests/test__service_account_info.py @@ -21,8 +21,8 @@ from google.auth import _service_account_info from google.auth import crypt -import yatest.common -DATA_DIR = os.path.join(yatest.common.test_source_path(), "data") +import yatest.common as yc +DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "data") SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, "service_account.json") GDCH_SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, "gdch_service_account.json") diff --git a/contrib/python/google-auth/py3/tests/test_aws.py b/contrib/python/google-auth/py3/tests/test_aws.py index 39138ab12e..db2e984100 100644 --- a/contrib/python/google-auth/py3/tests/test_aws.py +++ b/contrib/python/google-auth/py3/tests/test_aws.py @@ -1969,7 +1969,7 @@ class TestCredentials(object): "authorization": "Bearer {}".format(self.SUCCESS_RESPONSE["access_token"]), "x-goog-user-project": QUOTA_PROJECT_ID, "x-goog-api-client": IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE, - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", } impersonation_request_data = { "delegates": None, @@ -2066,7 +2066,7 @@ class TestCredentials(object): "authorization": "Bearer {}".format(self.SUCCESS_RESPONSE["access_token"]), "x-goog-user-project": QUOTA_PROJECT_ID, "x-goog-api-client": IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE, - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", } impersonation_request_data = { "delegates": None, diff --git a/contrib/python/google-auth/py3/tests/test_credentials.py b/contrib/python/google-auth/py3/tests/test_credentials.py index 99235cda61..d64f3abb50 100644 --- a/contrib/python/google-auth/py3/tests/test_credentials.py +++ b/contrib/python/google-auth/py3/tests/test_credentials.py @@ -55,9 +55,7 @@ def test_expired_and_valid(): # Set the expiration to one second more than now plus the clock skew # accomodation. These credentials should be valid. credentials.expiry = ( - datetime.datetime.utcnow() - + _helpers.REFRESH_THRESHOLD - + datetime.timedelta(seconds=1) + _helpers.utcnow() + _helpers.REFRESH_THRESHOLD + datetime.timedelta(seconds=1) ) assert credentials.valid @@ -65,7 +63,7 @@ def test_expired_and_valid(): # Set the credentials expiration to now. Because of the clock skew # accomodation, these credentials should report as expired. - credentials.expiry = datetime.datetime.utcnow() + credentials.expiry = _helpers.utcnow() assert not credentials.valid assert credentials.expired @@ -81,7 +79,7 @@ def test_before_request(): assert credentials.valid assert credentials.token == "token" assert headers["authorization"] == "Bearer token" - assert "x-identity-trust-boundary" not in headers + assert "x-allowed-locations" not in headers request = "token2" headers = {} @@ -91,13 +89,13 @@ def test_before_request(): assert credentials.valid assert credentials.token == "token" assert headers["authorization"] == "Bearer token" - assert "x-identity-trust-boundary" not in headers + assert "x-allowed-locations" not in headers def test_before_request_with_trust_boundary(): - DUMMY_BOUNDARY = "00110101" + DUMMY_BOUNDARY = "0xA30" credentials = CredentialsImpl() - credentials._trust_boundary = DUMMY_BOUNDARY + credentials._trust_boundary = {"locations": [], "encoded_locations": DUMMY_BOUNDARY} request = "token" headers = {} @@ -106,7 +104,7 @@ def test_before_request_with_trust_boundary(): assert credentials.valid assert credentials.token == "token" assert headers["authorization"] == "Bearer token" - assert headers["x-identity-trust-boundary"] == DUMMY_BOUNDARY + assert headers["x-allowed-locations"] == DUMMY_BOUNDARY request = "token2" headers = {} @@ -116,7 +114,7 @@ def test_before_request_with_trust_boundary(): assert credentials.valid assert credentials.token == "token" assert headers["authorization"] == "Bearer token" - assert headers["x-identity-trust-boundary"] == DUMMY_BOUNDARY + assert headers["x-allowed-locations"] == DUMMY_BOUNDARY def test_before_request_metrics(): diff --git a/contrib/python/google-auth/py3/tests/test_external_account.py b/contrib/python/google-auth/py3/tests/test_external_account.py index 0b165bc70b..5225dcf342 100644 --- a/contrib/python/google-auth/py3/tests/test_external_account.py +++ b/contrib/python/google-auth/py3/tests/test_external_account.py @@ -505,6 +505,11 @@ class TestCredentials(object): credentials = self.make_credentials() assert credentials.universe_domain == external_account._DEFAULT_UNIVERSE_DOMAIN + def test_with_universe_domain(self): + credentials = self.make_credentials() + new_credentials = credentials.with_universe_domain("dummy_universe.com") + assert new_credentials.universe_domain == "dummy_universe.com" + def test_info_workforce_pool(self): credentials = self.make_workforce_pool_credentials( workforce_pool_user_project=self.WORKFORCE_POOL_USER_PROJECT @@ -833,7 +838,7 @@ class TestCredentials(object): "Content-Type": "application/json", "authorization": "Bearer {}".format(token_response["access_token"]), "x-goog-api-client": IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE, - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", } impersonation_request_data = { "delegates": None, @@ -915,7 +920,7 @@ class TestCredentials(object): "Content-Type": "application/json", "authorization": "Bearer {}".format(token_response["access_token"]), "x-goog-api-client": IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE, - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", } impersonation_request_data = { "delegates": None, @@ -1134,7 +1139,7 @@ class TestCredentials(object): "Content-Type": "application/json", "authorization": "Bearer {}".format(token_response["access_token"]), "x-goog-api-client": IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE, - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", } impersonation_request_data = { "delegates": None, @@ -1218,7 +1223,7 @@ class TestCredentials(object): "Content-Type": "application/json", "authorization": "Bearer {}".format(token_response["access_token"]), "x-goog-api-client": IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE, - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", } impersonation_request_data = { "delegates": None, @@ -1274,7 +1279,7 @@ class TestCredentials(object): assert headers == { "authorization": "Bearer {}".format(self.SUCCESS_RESPONSE["access_token"]), - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", } def test_apply_workforce_without_quota_project_id(self): @@ -1291,7 +1296,7 @@ class TestCredentials(object): assert headers == { "authorization": "Bearer {}".format(self.SUCCESS_RESPONSE["access_token"]), - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", } def test_apply_impersonation_without_quota_project_id(self): @@ -1323,7 +1328,7 @@ class TestCredentials(object): assert headers == { "authorization": "Bearer {}".format(impersonation_response["accessToken"]), - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", } def test_apply_with_quota_project_id(self): @@ -1340,7 +1345,7 @@ class TestCredentials(object): "other": "header-value", "authorization": "Bearer {}".format(self.SUCCESS_RESPONSE["access_token"]), "x-goog-user-project": self.QUOTA_PROJECT_ID, - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", } def test_apply_impersonation_with_quota_project_id(self): @@ -1375,7 +1380,7 @@ class TestCredentials(object): "other": "header-value", "authorization": "Bearer {}".format(impersonation_response["accessToken"]), "x-goog-user-project": self.QUOTA_PROJECT_ID, - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", } def test_before_request(self): @@ -1391,7 +1396,7 @@ class TestCredentials(object): assert headers == { "other": "header-value", "authorization": "Bearer {}".format(self.SUCCESS_RESPONSE["access_token"]), - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", } # Second call shouldn't call refresh. @@ -1400,7 +1405,7 @@ class TestCredentials(object): assert headers == { "other": "header-value", "authorization": "Bearer {}".format(self.SUCCESS_RESPONSE["access_token"]), - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", } def test_before_request_workforce(self): @@ -1418,7 +1423,7 @@ class TestCredentials(object): assert headers == { "other": "header-value", "authorization": "Bearer {}".format(self.SUCCESS_RESPONSE["access_token"]), - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", } # Second call shouldn't call refresh. @@ -1427,7 +1432,7 @@ class TestCredentials(object): assert headers == { "other": "header-value", "authorization": "Bearer {}".format(self.SUCCESS_RESPONSE["access_token"]), - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", } def test_before_request_impersonation(self): @@ -1458,7 +1463,7 @@ class TestCredentials(object): assert headers == { "other": "header-value", "authorization": "Bearer {}".format(impersonation_response["accessToken"]), - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", } # Second call shouldn't call refresh. @@ -1467,7 +1472,7 @@ class TestCredentials(object): assert headers == { "other": "header-value", "authorization": "Bearer {}".format(impersonation_response["accessToken"]), - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", } @mock.patch("google.auth._helpers.utcnow") @@ -1495,7 +1500,7 @@ class TestCredentials(object): # Cached token should be used. assert headers == { "authorization": "Bearer token", - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", } # Next call should simulate 1 second passed. @@ -1509,7 +1514,7 @@ class TestCredentials(object): # New token should be retrieved. assert headers == { "authorization": "Bearer {}".format(self.SUCCESS_RESPONSE["access_token"]), - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", } @mock.patch("google.auth._helpers.utcnow") @@ -1552,7 +1557,7 @@ class TestCredentials(object): # Cached token should be used. assert headers == { "authorization": "Bearer token", - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", } # Next call should simulate 1 second passed. This will trigger the expiration @@ -1567,7 +1572,7 @@ class TestCredentials(object): # New token should be retrieved. assert headers == { "authorization": "Bearer {}".format(impersonation_response["accessToken"]), - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", } @pytest.mark.parametrize( @@ -1666,7 +1671,7 @@ class TestCredentials(object): "x-goog-user-project": self.QUOTA_PROJECT_ID, "authorization": "Bearer {}".format(token_response["access_token"]), "x-goog-api-client": IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE, - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", } impersonation_request_data = { "delegates": None, @@ -1720,7 +1725,7 @@ class TestCredentials(object): "authorization": "Bearer {}".format( impersonation_response["accessToken"] ), - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", }, ) @@ -1792,7 +1797,7 @@ class TestCredentials(object): "authorization": "Bearer {}".format( self.SUCCESS_RESPONSE["access_token"] ), - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", }, ) @@ -1842,7 +1847,7 @@ class TestCredentials(object): "Content-Type": "application/json", "authorization": "Bearer {}".format(token_response["access_token"]), "x-goog-api-client": IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE, - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", } impersonation_request_data = { "delegates": None, diff --git a/contrib/python/google-auth/py3/tests/test_identity_pool.py b/contrib/python/google-auth/py3/tests/test_identity_pool.py index d126a579bd..2d10a5d268 100644 --- a/contrib/python/google-auth/py3/tests/test_identity_pool.py +++ b/contrib/python/google-auth/py3/tests/test_identity_pool.py @@ -45,8 +45,8 @@ SERVICE_ACCOUNT_IMPERSONATION_URL = ( QUOTA_PROJECT_ID = "QUOTA_PROJECT_ID" SCOPES = ["scope1", "scope2"] -import yatest.common -DATA_DIR = os.path.join(yatest.common.test_source_path(), "data") +import yatest.common as yc +DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "data") SUBJECT_TOKEN_TEXT_FILE = os.path.join(DATA_DIR, "external_subject_token.txt") SUBJECT_TOKEN_JSON_FILE = os.path.join(DATA_DIR, "external_subject_token.json") SUBJECT_TOKEN_FIELD_NAME = "access_token" @@ -320,7 +320,7 @@ class TestCredentials(object): "Content-Type": "application/json", "authorization": "Bearer {}".format(token_response["access_token"]), "x-goog-api-client": metrics_header_value, - "x-identity-trust-boundary": "0", + "x-allowed-locations": "0x0", } impersonation_request_data = { "delegates": None, diff --git a/contrib/python/google-auth/py3/tests/test_impersonated_credentials.py b/contrib/python/google-auth/py3/tests/test_impersonated_credentials.py index d63d2d5d3b..9696e823ff 100644 --- a/contrib/python/google-auth/py3/tests/test_impersonated_credentials.py +++ b/contrib/python/google-auth/py3/tests/test_impersonated_credentials.py @@ -29,8 +29,8 @@ from google.auth.impersonated_credentials import Credentials from google.oauth2 import credentials from google.oauth2 import service_account -import yatest.common -DATA_DIR = os.path.join(yatest.common.test_source_path(), "data") +import yatest.common as yc +DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "data") with open(os.path.join(DATA_DIR, "privatekey.pem"), "rb") as fh: PRIVATE_KEY_BYTES = fh.read() diff --git a/contrib/python/google-auth/py3/tests/test_jwt.py b/contrib/python/google-auth/py3/tests/test_jwt.py index 62f310606d..ff8fd67da6 100644 --- a/contrib/python/google-auth/py3/tests/test_jwt.py +++ b/contrib/python/google-auth/py3/tests/test_jwt.py @@ -26,8 +26,8 @@ from google.auth import exceptions from google.auth import jwt -import yatest.common -DATA_DIR = os.path.join(yatest.common.test_source_path(), "data") +import yatest.common as yc +DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "data") with open(os.path.join(DATA_DIR, "privatekey.pem"), "rb") as fh: PRIVATE_KEY_BYTES = fh.read() diff --git a/contrib/python/google-auth/py3/tests/transport/test__custom_tls_signer.py b/contrib/python/google-auth/py3/tests/transport/test__custom_tls_signer.py index 5836b325ad..d2907bad29 100644 --- a/contrib/python/google-auth/py3/tests/transport/test__custom_tls_signer.py +++ b/contrib/python/google-auth/py3/tests/transport/test__custom_tls_signer.py @@ -11,7 +11,6 @@ # 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. - import base64 import ctypes import os @@ -30,11 +29,19 @@ FAKE_ENTERPRISE_CERT_FILE_PATH = "/path/to/enterprise/cert/file" ENTERPRISE_CERT_FILE = os.path.join( os.path.dirname(__file__), "../data/enterprise_cert_valid.json" ) +ENTERPRISE_CERT_FILE_PROVIDER = os.path.join( + os.path.dirname(__file__), "../data/enterprise_cert_valid_provider.json" +) INVALID_ENTERPRISE_CERT_FILE = os.path.join( os.path.dirname(__file__), "../data/enterprise_cert_invalid.json" ) +def test_load_provider_lib(): + with mock.patch("ctypes.CDLL", return_value=mock.MagicMock()): + _custom_tls_signer.load_provider_lib("/path/to/provider/lib") + + def test_load_offload_lib(): with mock.patch("ctypes.CDLL", return_value=mock.MagicMock()): lib = _custom_tls_signer.load_offload_lib("/path/to/offload/lib") @@ -173,62 +180,81 @@ def test_custom_tls_signer(): ) as load_offload_lib: load_offload_lib.return_value = offload_lib load_signer_lib.return_value = signer_lib - signer_object = _custom_tls_signer.CustomTlsSigner(ENTERPRISE_CERT_FILE) - signer_object.load_libraries() - assert signer_object._cert is None + with mock.patch( + "google.auth.transport._custom_tls_signer.get_cert" + ) as get_cert: + with mock.patch( + "google.auth.transport._custom_tls_signer.get_sign_callback" + ) as get_sign_callback: + get_cert.return_value = b"mock_cert" + signer_object = _custom_tls_signer.CustomTlsSigner( + ENTERPRISE_CERT_FILE + ) + signer_object.load_libraries() + signer_object.attach_to_ssl_context(create_urllib3_context()) + get_cert.assert_called_once() + get_sign_callback.assert_called_once() + offload_lib.ConfigureSslContext.assert_called_once() assert signer_object._enterprise_cert_file_path == ENTERPRISE_CERT_FILE assert signer_object._offload_lib == offload_lib assert signer_object._signer_lib == signer_lib load_signer_lib.assert_called_with("/path/to/signer/lib") load_offload_lib.assert_called_with("/path/to/offload/lib") - # Test set_up_custom_key and set_up_ssl_context methods - with mock.patch("google.auth.transport._custom_tls_signer.get_cert") as get_cert: - with mock.patch( - "google.auth.transport._custom_tls_signer.get_sign_callback" - ) as get_sign_callback: - get_cert.return_value = b"mock_cert" - signer_object.set_up_custom_key() - signer_object.attach_to_ssl_context(create_urllib3_context()) - get_cert.assert_called_once() - get_sign_callback.assert_called_once() - offload_lib.ConfigureSslContext.assert_called_once() +def test_custom_tls_signer_provider(): + provider_lib = mock.MagicMock() -def test_custom_tls_signer_failed_to_load_libraries(): # Test load_libraries method + with mock.patch( + "google.auth.transport._custom_tls_signer.load_provider_lib" + ) as load_provider_lib: + load_provider_lib.return_value = provider_lib + signer_object = _custom_tls_signer.CustomTlsSigner( + ENTERPRISE_CERT_FILE_PROVIDER + ) + signer_object.load_libraries() + signer_object.attach_to_ssl_context(mock.MagicMock()) + + assert signer_object._enterprise_cert_file_path == ENTERPRISE_CERT_FILE_PROVIDER + assert signer_object._provider_lib == provider_lib + load_provider_lib.assert_called_with("/path/to/provider/lib") + + +def test_custom_tls_signer_failed_to_load_libraries(): with pytest.raises(exceptions.MutualTLSChannelError) as excinfo: signer_object = _custom_tls_signer.CustomTlsSigner(INVALID_ENTERPRISE_CERT_FILE) signer_object.load_libraries() assert excinfo.match("enterprise cert file is invalid") -def test_custom_tls_signer_fail_to_offload(): - offload_lib = mock.MagicMock() - signer_lib = mock.MagicMock() +def test_custom_tls_signer_failed_to_attach(): + with pytest.raises(exceptions.MutualTLSChannelError) as excinfo: + signer_object = _custom_tls_signer.CustomTlsSigner(ENTERPRISE_CERT_FILE) + signer_object._offload_lib = mock.MagicMock() + signer_object._signer_lib = mock.MagicMock() + signer_object._sign_callback = mock.MagicMock() + signer_object._cert = b"mock cert" + signer_object._offload_lib.ConfigureSslContext.return_value = False + signer_object.attach_to_ssl_context(mock.MagicMock()) + assert excinfo.match("failed to configure ECP Offload SSL context") - with mock.patch( - "google.auth.transport._custom_tls_signer.load_signer_lib" - ) as load_signer_lib: - with mock.patch( - "google.auth.transport._custom_tls_signer.load_offload_lib" - ) as load_offload_lib: - load_offload_lib.return_value = offload_lib - load_signer_lib.return_value = signer_lib - signer_object = _custom_tls_signer.CustomTlsSigner(ENTERPRISE_CERT_FILE) - signer_object.load_libraries() - # set the return value to be 0 which indicts offload fails - offload_lib.ConfigureSslContext.return_value = 0 +def test_custom_tls_signer_failed_to_attach_provider(): + with pytest.raises(exceptions.MutualTLSChannelError) as excinfo: + signer_object = _custom_tls_signer.CustomTlsSigner( + ENTERPRISE_CERT_FILE_PROVIDER + ) + signer_object._provider_lib = mock.MagicMock() + signer_object._provider_lib.ECP_attach_to_ctx.return_value = False + signer_object.attach_to_ssl_context(mock.MagicMock()) + assert excinfo.match("failed to configure ECP Provider SSL context") + +def test_custom_tls_signer_failed_to_attach_no_libs(): with pytest.raises(exceptions.MutualTLSChannelError) as excinfo: - with mock.patch( - "google.auth.transport._custom_tls_signer.get_cert" - ) as get_cert: - with mock.patch( - "google.auth.transport._custom_tls_signer.get_sign_callback" - ): - get_cert.return_value = b"mock_cert" - signer_object.set_up_custom_key() - signer_object.attach_to_ssl_context(create_urllib3_context()) - assert excinfo.match("failed to configure SSL context") + signer_object = _custom_tls_signer.CustomTlsSigner(ENTERPRISE_CERT_FILE) + signer_object._offload_lib = None + signer_object._signer_lib = None + signer_object.attach_to_ssl_context(mock.MagicMock()) + assert excinfo.match("Invalid ECP configuration.") diff --git a/contrib/python/google-auth/py3/tests/transport/test__mtls_helper.py b/contrib/python/google-auth/py3/tests/transport/test__mtls_helper.py index 642283a5c5..1621a05302 100644 --- a/contrib/python/google-auth/py3/tests/transport/test__mtls_helper.py +++ b/contrib/python/google-auth/py3/tests/transport/test__mtls_helper.py @@ -22,9 +22,6 @@ import pytest # type: ignore from google.auth import exceptions from google.auth.transport import _mtls_helper -import yatest.common -DATA_DIR = os.path.join(yatest.common.test_source_path(), "data") - CONTEXT_AWARE_METADATA = {"cert_provider_command": ["some command"]} ENCRYPTED_EC_PRIVATE_KEY = b"""-----BEGIN ENCRYPTED PRIVATE KEY----- @@ -116,26 +113,26 @@ class TestCertAndKeyRegex(object): class TestCheckaMetadataPath(object): def test_success(self): - metadata_path = os.path.join(DATA_DIR, "context_aware_metadata.json") + metadata_path = os.path.join(pytest.data_dir, "context_aware_metadata.json") returned_path = _mtls_helper._check_dca_metadata_path(metadata_path) assert returned_path is not None def test_failure(self): - metadata_path = os.path.join(DATA_DIR, "not_exists.json") + metadata_path = os.path.join(pytest.data_dir, "not_exists.json") returned_path = _mtls_helper._check_dca_metadata_path(metadata_path) assert returned_path is None class TestReadMetadataFile(object): def test_success(self): - metadata_path = os.path.join(DATA_DIR, "context_aware_metadata.json") + metadata_path = os.path.join(pytest.data_dir, "context_aware_metadata.json") metadata = _mtls_helper._read_dca_metadata_file(metadata_path) assert "cert_provider_command" in metadata def test_file_not_json(self): # read a file which is not json format. - metadata_path = os.path.join(DATA_DIR, "privatekey.pem") + metadata_path = os.path.join(pytest.data_dir, "privatekey.pem") with pytest.raises(exceptions.ClientCertError): _mtls_helper._read_dca_metadata_file(metadata_path) diff --git a/contrib/python/google-auth/py3/tests/transport/test_grpc.py b/contrib/python/google-auth/py3/tests/transport/test_grpc.py index 05dc5fad0e..29fae4cdf6 100644 --- a/contrib/python/google-auth/py3/tests/transport/test_grpc.py +++ b/contrib/python/google-auth/py3/tests/transport/test_grpc.py @@ -35,8 +35,8 @@ try: except ImportError: # pragma: NO COVER HAS_GRPC = False -import yatest.common -DATA_DIR = os.path.join(yatest.common.test_source_path(), "data") +import yatest.common as yc +DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "..", "data") METADATA_PATH = os.path.join(DATA_DIR, "context_aware_metadata.json") with open(os.path.join(DATA_DIR, "privatekey.pem"), "rb") as fh: PRIVATE_KEY_BYTES = fh.read() diff --git a/contrib/python/google-auth/py3/tests/transport/test_requests.py b/contrib/python/google-auth/py3/tests/transport/test_requests.py index d962814346..aadc1ddbfd 100644 --- a/contrib/python/google-auth/py3/tests/transport/test_requests.py +++ b/contrib/python/google-auth/py3/tests/transport/test_requests.py @@ -545,16 +545,12 @@ class TestMutualTlsOffloadAdapter(object): google.auth.transport._custom_tls_signer.CustomTlsSigner, "load_libraries" ) @mock.patch.object( - google.auth.transport._custom_tls_signer.CustomTlsSigner, "set_up_custom_key" - ) - @mock.patch.object( google.auth.transport._custom_tls_signer.CustomTlsSigner, "attach_to_ssl_context", ) def test_success( self, mock_attach_to_ssl_context, - mock_set_up_custom_key, mock_load_libraries, mock_proxy_manager_for, mock_init_poolmanager, @@ -565,7 +561,6 @@ class TestMutualTlsOffloadAdapter(object): ) mock_load_libraries.assert_called_once() - mock_set_up_custom_key.assert_called_once() assert mock_attach_to_ssl_context.call_count == 2 adapter.init_poolmanager() diff --git a/contrib/python/google-auth/py3/tests/ya.make b/contrib/python/google-auth/py3/tests/ya.make index e7a1b3b272..dfcabf5bfb 100644 --- a/contrib/python/google-auth/py3/tests/ya.make +++ b/contrib/python/google-auth/py3/tests/ya.make @@ -67,11 +67,6 @@ TEST_SRCS( # transport/test_urllib3.py ) -RESOURCE( - data/privatekey.pem data/privatekey.pem - data/public_cert.pem data/public_cert.pem -) - NO_LINT() END() diff --git a/contrib/python/google-auth/py3/ya.make b/contrib/python/google-auth/py3/ya.make index 77b6e5f741..ec71907cc6 100644 --- a/contrib/python/google-auth/py3/ya.make +++ b/contrib/python/google-auth/py3/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(2.23.0) +VERSION(2.25.2) LICENSE(Apache-2.0) @@ -10,10 +10,10 @@ PEERDIR( contrib/python/cachetools contrib/python/cryptography contrib/python/grpcio + contrib/python/packaging contrib/python/pyasn1-modules contrib/python/requests contrib/python/rsa - contrib/python/urllib3 ) NO_LINT() diff --git a/contrib/python/hypothesis/py3/.dist-info/METADATA b/contrib/python/hypothesis/py3/.dist-info/METADATA index 2a7e253367..c243f74513 100644 --- a/contrib/python/hypothesis/py3/.dist-info/METADATA +++ b/contrib/python/hypothesis/py3/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: hypothesis -Version: 6.91.0 +Version: 6.92.0 Summary: A library for property-based testing Home-page: https://hypothesis.works Author: David R. MacIver and Zac Hatfield-Dodds @@ -35,7 +35,7 @@ Classifier: Typing :: Typed Requires-Python: >=3.8 Description-Content-Type: text/x-rst License-File: LICENSE.txt -Requires-Dist: attrs >=19.2.0 +Requires-Dist: attrs >=22.2.0 Requires-Dist: sortedcontainers <3.0.0,>=2.1.0 Requires-Dist: exceptiongroup >=1.0.0 ; python_version < "3.11" Provides-Extra: all diff --git a/contrib/python/hypothesis/py3/_hypothesis_pytestplugin.py b/contrib/python/hypothesis/py3/_hypothesis_pytestplugin.py index 3bb2535f3b..9875e067f5 100644 --- a/contrib/python/hypothesis/py3/_hypothesis_pytestplugin.py +++ b/contrib/python/hypothesis/py3/_hypothesis_pytestplugin.py @@ -373,6 +373,13 @@ else: if fex: failing_examples.append(json.loads(fex)) + from hypothesis.internal.observability import _WROTE_TO + + if _WROTE_TO: + terminalreporter.section("Hypothesis") + for fname in sorted(_WROTE_TO): + terminalreporter.write_line(f"observations written to {fname}") + if failing_examples: # This must have been imported already to write the failing examples from hypothesis.extra._patching import gc_patches, make_patch, save_patch @@ -384,7 +391,8 @@ else: except Exception: # fail gracefully if we hit any filesystem or permissions problems return - terminalreporter.section("Hypothesis") + if not _WROTE_TO: + terminalreporter.section("Hypothesis") terminalreporter.write_line( f"`git apply {fname}` to add failing examples to your code." ) diff --git a/contrib/python/hypothesis/py3/hypothesis/core.py b/contrib/python/hypothesis/py3/hypothesis/core.py index b2298418c8..82e359fc2f 100644 --- a/contrib/python/hypothesis/py3/hypothesis/core.py +++ b/contrib/python/hypothesis/py3/hypothesis/core.py @@ -87,6 +87,11 @@ from hypothesis.internal.escalation import ( get_trimmed_traceback, ) from hypothesis.internal.healthcheck import fail_health_check +from hypothesis.internal.observability import ( + TESTCASE_CALLBACKS, + deliver_json_blob, + make_testcase, +) from hypothesis.internal.reflection import ( convert_positional_arguments, define_function_signature, @@ -99,7 +104,12 @@ from hypothesis.internal.reflection import ( proxies, repr_call, ) -from hypothesis.internal.scrutineer import Tracer, explanatory_lines +from hypothesis.internal.scrutineer import ( + Trace, + Tracer, + explanatory_lines, + tractable_coverage_report, +) from hypothesis.internal.validation import check_type from hypothesis.reporting import ( current_verbosity, @@ -107,13 +117,14 @@ from hypothesis.reporting import ( verbose_report, with_reporter, ) -from hypothesis.statistics import describe_targets, note_statistics +from hypothesis.statistics import describe_statistics, describe_targets, note_statistics from hypothesis.strategies._internal.misc import NOTHING from hypothesis.strategies._internal.strategies import ( Ex, SearchStrategy, check_strategy, ) +from hypothesis.strategies._internal.utils import to_jsonable from hypothesis.vendor.pretty import RepresentationPrinter from hypothesis.version import __version__ @@ -484,13 +495,14 @@ def execute_explicit_examples(state, wrapped_test, arguments, kwargs, original_s with local_settings(state.settings): fragments_reported = [] + empty_data = ConjectureData.for_buffer(b"") try: bits = ", ".join(nicerepr(x) for x in arguments) + ", ".join( f"{k}={nicerepr(v)}" for k, v in example_kwargs.items() ) execute_example = partial( state.execute_once, - ConjectureData.for_buffer(b""), + empty_data, is_final=True, print_example=True, example_kwargs=example_kwargs, @@ -544,7 +556,8 @@ def execute_explicit_examples(state, wrapped_test, arguments, kwargs, original_s # development, this is rather useful to replay Hypothesis' part of # a saved failure when other arguments are supplied by e.g. pytest. # See https://github.com/HypothesisWorks/hypothesis/issues/2125 - pass + with contextlib.suppress(StopTest): + empty_data.conclude_test(Status.INVALID) except BaseException as err: # In order to support reporting of multiple failing examples, we yield # each of the (report text, error) pairs we find back to the top-level @@ -567,6 +580,8 @@ def execute_explicit_examples(state, wrapped_test, arguments, kwargs, original_s new.__cause__ = err err = new + with contextlib.suppress(StopTest): + empty_data.conclude_test(Status.INVALID) yield (fragments_reported, err) if ( state.settings.report_multiple_bugs @@ -583,6 +598,15 @@ def execute_explicit_examples(state, wrapped_test, arguments, kwargs, original_s "Falsifying example", "Falsifying explicit example", 1 ) + tc = make_testcase( + start_timestamp=state._start_timestamp, + test_name_or_nodeid=state.test_identifier, + data=empty_data, + how_generated="explicit example", + string_repr=state._string_repr, + ) + deliver_json_blob(tc) + if fragments_reported: verbose_report(fragments_reported[0].replace("Falsifying", "Trying", 1)) for f in fragments_reported[1:]: @@ -738,7 +762,6 @@ class StateForActualGivenExecution: self.last_exception = None self.falsifying_examples = () self.random = random - self.__test_runtime = None self.ever_executed = False self.is_find = getattr(wrapped_test, "_hypothesis_internal_is_find", False) @@ -756,6 +779,16 @@ class StateForActualGivenExecution: self.failed_due_to_deadline = False self.explain_traces = defaultdict(set) + self._start_timestamp = time.time() + self._string_repr = "" + self._jsonable_arguments = {} + self._timing_features = {} + + @property + def test_identifier(self): + return getattr( + current_pytest_item.value, "nodeid", None + ) or get_pretty_function_description(self.wrapped_test) def execute_once( self, @@ -780,6 +813,7 @@ class StateForActualGivenExecution: self.ever_executed = True data.is_find = self.is_find + self._string_repr = "" text_repr = None if self.settings.deadline is None: test = self.test @@ -787,16 +821,23 @@ class StateForActualGivenExecution: @proxies(self.test) def test(*args, **kwargs): - self.__test_runtime = None + arg_drawtime = sum(data.draw_times) initial_draws = len(data.draw_times) start = time.perf_counter() - result = self.test(*args, **kwargs) - finish = time.perf_counter() - internal_draw_time = sum(data.draw_times[initial_draws:]) - runtime = datetime.timedelta( - seconds=finish - start - internal_draw_time - ) - self.__test_runtime = runtime + try: + result = self.test(*args, **kwargs) + finally: + finish = time.perf_counter() + internal_draw_time = sum(data.draw_times[initial_draws:]) + runtime = datetime.timedelta( + seconds=finish - start - internal_draw_time + ) + self._timing_features = { + "time_running_test": finish - start - internal_draw_time, + "time_drawing_args": arg_drawtime, + "time_interactive_draws": internal_draw_time, + } + current_deadline = self.settings.deadline if not is_final: current_deadline = (current_deadline // 4) * 5 @@ -855,6 +896,26 @@ class StateForActualGivenExecution: ), ) report(printer.getvalue()) + + if TESTCASE_CALLBACKS: + printer = RepresentationPrinter(context=context) + printer.repr_call( + test.__name__, + args, + kwargs, + force_split=True, + arg_slices=argslices, + leading_comment=( + "# " + context.data.slice_comments[(0, 0)] + if (0, 0) in context.data.slice_comments + else None + ), + ) + self._string_repr = printer.getvalue() + self._jsonable_arguments = { + **dict(enumerate(map(to_jsonable, args))), + **{k: to_jsonable(v) for k, v in kwargs.items()}, + } return test(*args, **kwargs) # self.test_runner can include the execute_example method, or setup/teardown @@ -870,9 +931,8 @@ class StateForActualGivenExecution: # instead raise an appropriate diagnostic error. if expected_failure is not None: exception, traceback = expected_failure - if ( - isinstance(exception, DeadlineExceeded) - and self.__test_runtime is not None + if isinstance(exception, DeadlineExceeded) and ( + runtime_secs := self._timing_features.get("time_running_test") ): report( "Unreliable test timings! On an initial run, this " @@ -884,7 +944,7 @@ class StateForActualGivenExecution: % ( exception.runtime.total_seconds() * 1000, self.settings.deadline.total_seconds() * 1000, - self.__test_runtime.total_seconds() * 1000, + runtime_secs * 1000, ) ) else: @@ -895,7 +955,7 @@ class StateForActualGivenExecution: ) from exception return result - def _execute_once_for_engine(self, data): + def _execute_once_for_engine(self, data: ConjectureData) -> None: """Wrapper around ``execute_once`` that intercepts test failure exceptions and single-test control exceptions, and turns them into appropriate method calls to `data` instead. @@ -903,16 +963,18 @@ class StateForActualGivenExecution: This allows the engine to assume that any exception other than ``StopTest`` must be a fatal error, and should stop the entire engine. """ + trace: Trace = set() try: - trace = frozenset() - if ( + _can_trace = ( + sys.gettrace() is None or sys.version_info[:2] >= (3, 12) + ) and not PYPY + _trace_obs = TESTCASE_CALLBACKS + _trace_failure = ( self.failed_normally and not self.failed_due_to_deadline - and Phase.shrink in self.settings.phases - and Phase.explain in self.settings.phases - and (sys.gettrace() is None or sys.version_info[:2] >= (3, 12)) - and not PYPY - ): # pragma: no cover + and {Phase.shrink, Phase.explain}.issubset(self.settings.phases) + ) + if _can_trace and (_trace_obs or _trace_failure): # pragma: no cover # This is in fact covered by our *non-coverage* tests, but due to the # settrace() contention *not* by our coverage tests. Ah well. with Tracer() as tracer: @@ -921,7 +983,7 @@ class StateForActualGivenExecution: if data.status == Status.VALID: self.explain_traces[None].add(frozenset(tracer.branches)) finally: - trace = frozenset(tracer.branches) + trace = tracer.branches else: result = self.execute_once(data) if result is not None: @@ -964,20 +1026,40 @@ class StateForActualGivenExecution: tb = get_trimmed_traceback() info = data.extra_information - info.__expected_traceback = format_exception(e, tb) - info.__expected_exception = e - verbose_report(info.__expected_traceback) + info._expected_traceback = format_exception(e, tb) # type: ignore + info._expected_exception = e # type: ignore + verbose_report(info._expected_traceback) # type: ignore self.failed_normally = True interesting_origin = InterestingOrigin.from_exception(e) if trace: # pragma: no cover # Trace collection is explicitly disabled under coverage. - self.explain_traces[interesting_origin].add(trace) + self.explain_traces[interesting_origin].add(frozenset(trace)) if interesting_origin[0] == DeadlineExceeded: self.failed_due_to_deadline = True self.explain_traces.clear() - data.mark_interesting(interesting_origin) + data.mark_interesting(interesting_origin) # type: ignore # mypy bug? + finally: + # Conditional here so we can save some time constructing the payload; in + # other cases (without coverage) it's cheap enough to do that regardless. + if TESTCASE_CALLBACKS: + if self.failed_normally or self.failed_due_to_deadline: + phase = "shrink" + else: + phase = "unknown" + tc = make_testcase( + start_timestamp=self._start_timestamp, + test_name_or_nodeid=self.test_identifier, + data=data, + how_generated=f"generated during {phase} phase", + string_repr=self._string_repr, + arguments={**self._jsonable_arguments, **data._observability_args}, + metadata=self._timing_features, + coverage=tractable_coverage_report(trace) or None, + ) + deliver_json_blob(tc) + self._timing_features.clear() def run_engine(self): """Run the test function many times, on database input and generated @@ -1003,6 +1085,15 @@ class StateForActualGivenExecution: # on different inputs. runner.run() note_statistics(runner.statistics) + deliver_json_blob( + { + "type": "info", + "run_start": self._start_timestamp, + "property": self.test_identifier, + "title": "Hypothesis Statistics", + "content": describe_statistics(runner.statistics), + } + ) if runner.call_count == 0: return @@ -1041,7 +1132,9 @@ class StateForActualGivenExecution: falsifying_example.buffer ) ran_example.slice_comments = falsifying_example.slice_comments - assert info.__expected_exception is not None + tb = None + origin = None + assert info._expected_exception is not None try: with with_reporter(fragments.append): self.execute_once( @@ -1049,8 +1142,8 @@ class StateForActualGivenExecution: print_example=not self.is_find, is_final=True, expected_failure=( - info.__expected_exception, - info.__expected_traceback, + info._expected_exception, + info._expected_traceback, ), ) except (UnsatisfiedAssumption, StopTest) as e: @@ -1066,10 +1159,34 @@ class StateForActualGivenExecution: errors_to_report.append( (fragments, e.with_traceback(get_trimmed_traceback())) ) + tb = format_exception(e, get_trimmed_traceback(e)) + origin = InterestingOrigin.from_exception(e) else: # execute_once() will always raise either the expected error, or Flaky. raise NotImplementedError("This should be unreachable") finally: + # log our observability line for the final failing example + tc = { + "type": "test_case", + "run_start": self._start_timestamp, + "property": self.test_identifier, + "status": "passed" if sys.exc_info()[0] else "failed", + "status_reason": str(origin or "unexpected/flaky pass"), + "representation": self._string_repr, + "how_generated": "minimal failing example", + "features": { + **{ + k: v + for k, v in ran_example.target_observations.items() + if isinstance(k, str) + }, + **ran_example.events, + **self._timing_features, + }, + "coverage": None, # TODO: expose this? + "metadata": {"traceback": tb}, + } + deliver_json_blob(tc) # Whether or not replay actually raised the exception again, we want # to print the reproduce_failure decorator for the failing example. if self.settings.print_blob: diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py b/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py index 2f086bf04f..7a5542b0bd 100644 --- a/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py +++ b/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py @@ -75,7 +75,6 @@ else: ONE_BOUND_INTEGERS_LABEL = calc_label_from_name("trying a one-bound int allowing 0") INTEGER_RANGE_DRAW_LABEL = calc_label_from_name("another draw in integer_range()") BIASED_COIN_LABEL = calc_label_from_name("biased_coin()") -BIASED_COIN_INNER_LABEL = calc_label_from_name("inside biased_coin()") TOP_LABEL = calc_label_from_name("top") DRAW_BYTES_LABEL = calc_label_from_name("draw_bytes() in ConjectureData") @@ -936,18 +935,9 @@ class PrimitiveProvider: else: partial = True - if forced is None: - # We want to get to the point where True is represented by - # 1 and False is represented by 0 as quickly as possible, so - # we use the remove_discarded machinery in the shrinker to - # achieve that by discarding any draws that are > 1 and writing - # a suitable draw into the choice sequence at the end of the - # loop. - self._cd.start_example(BIASED_COIN_INNER_LABEL) - i = self._cd.draw_bits(bits) - self._cd.stop_example(discard=i > 1) - else: - i = self._cd.draw_bits(bits, forced=int(forced)) + i = self._cd.draw_bits( + bits, forced=None if forced is None else int(forced) + ) # We always choose the region that causes us to repeat the loop as # the maximum value, so that shrinking the drawn bits never causes @@ -977,8 +967,6 @@ class PrimitiveProvider: # becomes i > falsey. result = i > falsey - if i > 1: - self._cd.draw_bits(bits, forced=int(result)) break self._cd.stop_example() return result @@ -993,6 +981,11 @@ class PrimitiveProvider: shrink_towards: int = 0, forced: Optional[int] = None, ) -> int: + if min_value is not None: + shrink_towards = max(min_value, shrink_towards) + if max_value is not None: + shrink_towards = min(max_value, shrink_towards) + # This is easy to build on top of our existing conjecture utils, # and it's easy to build sampled_from and weighted_coin on this. if weights is not None: @@ -1000,45 +993,46 @@ class PrimitiveProvider: assert max_value is not None sampler = Sampler(weights) - idx = sampler.sample(self._cd) + gap = max_value - shrink_towards - if shrink_towards <= min_value: - return min_value + idx - elif max_value <= shrink_towards: - return max_value - idx - else: - # For range -2..2, interpret idx = 0..4 as [0, 1, 2, -1, -2] - if idx <= (gap := max_value - shrink_towards): - return shrink_towards + idx + forced_idx = None + if forced is not None: + if forced >= shrink_towards: + forced_idx = forced - shrink_towards else: - return shrink_towards - (idx - gap) + forced_idx = shrink_towards + gap - forced + idx = sampler.sample(self._cd, forced=forced_idx) + + # For range -2..2, interpret idx = 0..4 as [0, 1, 2, -1, -2] + if idx <= gap: + return shrink_towards + idx + else: + return shrink_towards - (idx - gap) if min_value is None and max_value is None: - return self._draw_unbounded_integer() + return self._draw_unbounded_integer(forced=forced) if min_value is None: assert max_value is not None # make mypy happy - if max_value <= shrink_towards: - return max_value - abs(self._draw_unbounded_integer()) - else: - probe = max_value + 1 - while max_value < probe: - self._cd.start_example(ONE_BOUND_INTEGERS_LABEL) - probe = self._draw_unbounded_integer() + shrink_towards - self._cd.stop_example(discard=max_value < probe) - return probe + probe = max_value + 1 + while max_value < probe: + self._cd.start_example(ONE_BOUND_INTEGERS_LABEL) + probe = shrink_towards + self._draw_unbounded_integer( + forced=None if forced is None else forced - shrink_towards + ) + self._cd.stop_example(discard=max_value < probe) + return probe if max_value is None: assert min_value is not None - if min_value >= shrink_towards: - return min_value + abs(self._draw_unbounded_integer()) - else: - probe = min_value - 1 - while probe < min_value: - self._cd.start_example(ONE_BOUND_INTEGERS_LABEL) - probe = self._draw_unbounded_integer() + shrink_towards - self._cd.stop_example(discard=probe < min_value) - return probe + probe = min_value - 1 + while probe < min_value: + self._cd.start_example(ONE_BOUND_INTEGERS_LABEL) + probe = shrink_towards + self._draw_unbounded_integer( + forced=None if forced is None else forced - shrink_towards + ) + self._cd.stop_example(discard=probe < min_value) + return probe return self._draw_bounded_integer( min_value, @@ -1057,7 +1051,8 @@ class PrimitiveProvider: # TODO: consider supporting these float widths at the IR level in the # future. # width: Literal[16, 32, 64] = 64, - # exclude_min and exclude_max handled higher up + # exclude_min and exclude_max handled higher up, + forced: Optional[float] = None, ) -> float: ( sampler, @@ -1074,17 +1069,25 @@ class PrimitiveProvider: while True: self._cd.start_example(FLOAT_STRATEGY_DO_DRAW_LABEL) - i = sampler.sample(self._cd) if sampler else 0 + # If `forced in nasty_floats`, then `forced` was *probably* + # generated by drawing a nonzero index from the sampler. However, we + # have no obligation to generate it that way when forcing. In particular, + # i == 0 is able to produce all possible floats, and the forcing + # logic is simpler if we assume this choice. + forced_i = None if forced is None else 0 + i = sampler.sample(self._cd, forced=forced_i) if sampler else 0 self._cd.start_example(DRAW_FLOAT_LABEL) if i == 0: - result = self._draw_float(forced_sign_bit=forced_sign_bit) + result = self._draw_float( + forced_sign_bit=forced_sign_bit, forced=forced + ) if math.copysign(1.0, result) == -1: assert neg_clamper is not None clamped = -neg_clamper(-result) else: assert pos_clamper is not None clamped = pos_clamper(result) - if clamped != result: + if clamped != result and not (math.isnan(result) and allow_nan): self._cd.stop_example(discard=True) self._cd.start_example(DRAW_FLOAT_LABEL) self._write_float(clamped) @@ -1104,10 +1107,13 @@ class PrimitiveProvider: *, min_size: int = 0, max_size: Optional[int] = None, + forced: Optional[str] = None, ) -> str: if max_size is None: max_size = 10**10 # "arbitrarily large" + assert forced is None or min_size <= len(forced) <= max_size + average_size = min( max(min_size * 2, min_size + 5), 0.5 * (min_size + max_size), @@ -1119,31 +1125,57 @@ class PrimitiveProvider: min_size=min_size, max_size=max_size, average_size=average_size, + forced=None if forced is None else len(forced), ) while elements.more(): + forced_i: Optional[int] = None + if forced is not None: + c = forced[elements.count - 1] + forced_i = intervals.index_from_char_in_shrink_order(c) + if len(intervals) > 256: - if self.draw_boolean(0.2): - i = self._draw_bounded_integer(256, len(intervals) - 1) + if self.draw_boolean( + 0.2, forced=None if forced_i is None else forced_i > 255 + ): + i = self._draw_bounded_integer( + 256, len(intervals) - 1, forced=forced_i + ) else: - i = self._draw_bounded_integer(0, 255) + i = self._draw_bounded_integer(0, 255, forced=forced_i) else: - i = self._draw_bounded_integer(0, len(intervals) - 1) + i = self._draw_bounded_integer(0, len(intervals) - 1, forced=forced_i) chars.append(intervals.char_in_shrink_order(i)) return "".join(chars) - def draw_bytes(self, size: int) -> bytes: - return self._cd.draw_bits(8 * size).to_bytes(size, "big") + def draw_bytes(self, size: int, *, forced: Optional[bytes] = None) -> bytes: + forced_i = None + if forced is not None: + forced_i = int_from_bytes(forced) + size = len(forced) + + return self._cd.draw_bits(8 * size, forced=forced_i).to_bytes(size, "big") - def _draw_float(self, forced_sign_bit: Optional[int] = None) -> float: + def _draw_float( + self, forced_sign_bit: Optional[int] = None, *, forced: Optional[float] = None + ) -> float: """ Helper for draw_float which draws a random 64-bit float. """ + if forced is not None: + # sign_aware_lte(forced, -0.0) does not correctly handle the + # math.nan case here. + forced_sign_bit = math.copysign(1, forced) == -1 + self._cd.start_example(DRAW_FLOAT_LABEL) try: is_negative = self._cd.draw_bits(1, forced=forced_sign_bit) - f = lex_to_float(self._cd.draw_bits(64)) + f = lex_to_float( + self._cd.draw_bits( + 64, forced=None if forced is None else float_to_lex(abs(forced)) + ) + ) return -f if is_negative else f finally: self._cd.stop_example() @@ -1153,14 +1185,37 @@ class PrimitiveProvider: self._cd.draw_bits(1, forced=sign) self._cd.draw_bits(64, forced=float_to_lex(abs(f))) - def _draw_unbounded_integer(self) -> int: - size = INT_SIZES[INT_SIZES_SAMPLER.sample(self._cd)] - r = self._cd.draw_bits(size) + def _draw_unbounded_integer(self, *, forced: Optional[int] = None) -> int: + forced_i = None + if forced is not None: + # Using any bucket large enough to contain this integer would be a + # valid way to force it. This is because an n bit integer could have + # been drawn from a bucket of size n, or from any bucket of size + # m > n. + # We'll always choose the smallest eligible bucket here. + + # We need an extra bit to handle forced signed integers. INT_SIZES + # is interpreted as unsigned sizes. + bit_size = forced.bit_length() + 1 + size = min(size for size in INT_SIZES if bit_size <= size) + forced_i = INT_SIZES.index(size) + + size = INT_SIZES[INT_SIZES_SAMPLER.sample(self._cd, forced=forced_i)] + + forced_r = None + if forced is not None: + forced_r = forced + forced_r <<= 1 + if forced < 0: + forced_r = -forced_r + forced_r |= 1 + + r = self._cd.draw_bits(size, forced=forced_r) sign = r & 1 r >>= 1 if sign: r = -r - return int(r) + return r def _draw_bounded_integer( self, @@ -1202,7 +1257,9 @@ class PrimitiveProvider: bits = gap.bit_length() probe = gap + 1 - if bits > 24 and self._cd.draw_bits(3, forced=None if forced is None else 0): + if bits > 24 and self.draw_boolean( + 7 / 8, forced=None if forced is None else False + ): # For large ranges, we combine the uniform random distribution from draw_bits # with a weighting scheme with moderate chance. Cutoff at 2 ** 24 so that our # choice of unicode characters is uniform but the 32bit distribution is not. @@ -1399,6 +1456,7 @@ class ConjectureData: # try varying, to report if the minimal example always fails anyway. self.arg_slices: Set[Tuple[int, int]] = set() self.slice_comments: Dict[Tuple[int, int], str] = {} + self._observability_args: Dict[str, Any] = {} self.extra_information = ExtraInformation() @@ -1425,11 +1483,20 @@ class ConjectureData: if weights is not None: assert min_value is not None assert max_value is not None - assert (max_value - min_value) <= 1024 # arbitrary practical limit - - if forced is not None: - assert min_value is not None - assert max_value is not None + width = max_value - min_value + 1 + assert width <= 1024 # arbitrary practical limit + assert len(weights) == width + + if forced is not None and (min_value is None or max_value is None): + # We draw `forced=forced - shrink_towards` here internally. If that + # grows larger than a 128 bit signed integer, we can't represent it. + # Disallow this combination for now. + # Note that bit_length() = 128 -> signed bit size = 129. + assert (forced - shrink_towards).bit_length() < 128 + if forced is not None and min_value is not None: + assert min_value <= forced + if forced is not None and max_value is not None: + assert forced <= max_value return self.provider.draw_integer( min_value=min_value, @@ -1449,14 +1516,23 @@ class ConjectureData: # TODO: consider supporting these float widths at the IR level in the # future. # width: Literal[16, 32, 64] = 64, - # exclude_min and exclude_max handled higher up + # exclude_min and exclude_max handled higher up, + forced: Optional[float] = None, ) -> float: assert smallest_nonzero_magnitude > 0 + assert not math.isnan(min_value) + assert not math.isnan(max_value) + + if forced is not None: + assert allow_nan or not math.isnan(forced) + assert math.isnan(forced) or min_value <= forced <= max_value + return self.provider.draw_float( min_value=min_value, max_value=max_value, allow_nan=allow_nan, smallest_nonzero_magnitude=smallest_nonzero_magnitude, + forced=forced, ) def draw_string( @@ -1465,13 +1541,16 @@ class ConjectureData: *, min_size: int = 0, max_size: Optional[int] = None, + forced: Optional[str] = None, ) -> str: + assert forced is None or min_size <= len(forced) return self.provider.draw_string( - intervals, min_size=min_size, max_size=max_size + intervals, min_size=min_size, max_size=max_size, forced=forced ) - def draw_bytes(self, size: int) -> bytes: - return self.provider.draw_bytes(size) + def draw_bytes(self, size: int, *, forced: Optional[bytes] = None) -> bytes: + assert forced is None or len(forced) == size + return self.provider.draw_bytes(size, forced=forced) def draw_boolean(self, p: float = 0.5, *, forced: Optional[bool] = None) -> bool: return self.provider.draw_boolean(p, forced=forced) diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/utils.py b/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/utils.py index 48a5ec3f27..0712b2d8c8 100644 --- a/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/utils.py +++ b/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/utils.py @@ -81,8 +81,12 @@ def check_sample( return tuple(values) -def choice(data: "ConjectureData", values: Sequence[T]) -> T: - return values[data.draw_integer(0, len(values) - 1)] +def choice( + data: "ConjectureData", values: Sequence[T], *, forced: Optional[T] = None +) -> T: + forced_i = None if forced is None else values.index(forced) + i = data.draw_integer(0, len(values) - 1, forced=forced_i) + return values[i] class Sampler: @@ -171,14 +175,25 @@ class Sampler: self.table.append((base, alternate, alternate_chance)) self.table.sort() - def sample(self, data: "ConjectureData") -> int: + def sample(self, data: "ConjectureData", forced: Optional[int] = None) -> int: data.start_example(SAMPLE_IN_SAMPLER_LABEL) - base, alternate, alternate_chance = choice(data, self.table) - use_alternate = data.draw_boolean(alternate_chance) + forced_choice = ( # pragma: no branch # https://github.com/nedbat/coveragepy/issues/1617 + None + if forced is None + else next((b, a, a_c) for (b, a, a_c) in self.table if forced in (b, a)) + ) + base, alternate, alternate_chance = choice( + data, self.table, forced=forced_choice + ) + use_alternate = data.draw_boolean( + alternate_chance, forced=None if forced is None else forced == alternate + ) data.stop_example() if use_alternate: + assert forced is None or alternate == forced, (forced, alternate) return alternate else: + assert forced is None or base == forced, (forced, base) return base @@ -204,11 +219,15 @@ class many: min_size: int, max_size: Union[int, float], average_size: Union[int, float], + *, + forced: Optional[int] = None, ) -> None: assert 0 <= min_size <= average_size <= max_size + assert forced is None or min_size <= forced <= max_size self.min_size = min_size self.max_size = max_size self.data = data + self.forced_size = forced self.p_continue = _calc_p_continue(average_size - min_size, max_size - min_size) self.count = 0 self.rejections = 0 @@ -227,15 +246,22 @@ class many: self.data.start_example(ONE_FROM_MANY_LABEL) if self.min_size == self.max_size: + # if we have to hit an exact size, draw unconditionally until that + # point, and no further. should_continue = self.count < self.min_size else: forced_result = None if self.force_stop: + # if our size is forced, we can't reject in a way that would + # cause us to differ from the forced size. + assert self.forced_size is None or self.count == self.forced_size forced_result = False elif self.count < self.min_size: forced_result = True elif self.count >= self.max_size: forced_result = False + elif self.forced_size is not None: + forced_result = self.count < self.forced_size should_continue = self.data.draw_boolean( self.p_continue, forced=forced_result ) diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/intervalsets.py b/contrib/python/hypothesis/py3/hypothesis/internal/intervalsets.py index c5e82f6b22..4a143c80b8 100644 --- a/contrib/python/hypothesis/py3/hypothesis/internal/intervalsets.py +++ b/contrib/python/hypothesis/py3/hypothesis/internal/intervalsets.py @@ -8,6 +8,8 @@ # v. 2.0. If a copy of the MPL was not distributed with this file, You can # obtain one at https://mozilla.org/MPL/2.0/. +from typing import Union + class IntervalSet: @classmethod @@ -61,17 +63,16 @@ class IntervalSet: assert r <= v return r - def __contains__(self, elem): + def __contains__(self, elem: Union[str, int]) -> bool: if isinstance(elem, str): elem = ord(elem) - assert isinstance(elem, int) assert 0 <= elem <= 0x10FFFF return any(start <= elem <= end for start, end in self.intervals) def __repr__(self): return f"IntervalSet({self.intervals!r})" - def index(self, value): + def index(self, value: int) -> int: for offset, (u, v) in zip(self.offsets, self.intervals): if u == value: return offset @@ -81,7 +82,7 @@ class IntervalSet: return offset + (value - u) raise ValueError(f"{value} is not in list") - def index_above(self, value): + def index_above(self, value: int) -> int: for offset, (u, v) in zip(self.offsets, self.intervals): if u >= value: return offset @@ -254,3 +255,24 @@ class IntervalSet: assert 0 <= i <= self._idx_of_Z return chr(self[i]) + + def index_from_char_in_shrink_order(self, c: str) -> int: + """ + Inverse of char_in_shrink_order. + """ + assert len(c) == 1 + i = self.index(ord(c)) + + if i <= self._idx_of_Z: + n = self._idx_of_Z - self._idx_of_zero + # Rewrite [zero_point, Z_point] to [0, n]. + if self._idx_of_zero <= i <= self._idx_of_Z: + i -= self._idx_of_zero + assert 0 <= i <= n + # Rewrite [zero_point, 0] to [n + 1, Z_point]. + else: + i = self._idx_of_zero - i + n + assert n + 1 <= i <= self._idx_of_Z + assert 0 <= i <= self._idx_of_Z + + return i diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/observability.py b/contrib/python/hypothesis/py3/hypothesis/internal/observability.py new file mode 100644 index 0000000000..6752868737 --- /dev/null +++ b/contrib/python/hypothesis/py3/hypothesis/internal/observability.py @@ -0,0 +1,92 @@ +# This file is part of Hypothesis, which may be found at +# https://github.com/HypothesisWorks/hypothesis/ +# +# Copyright the Hypothesis Authors. +# Individual contributors are listed in AUTHORS.rst and the git log. +# +# This Source Code Form is subject to the terms of the Mozilla Public License, +# v. 2.0. If a copy of the MPL was not distributed with this file, You can +# obtain one at https://mozilla.org/MPL/2.0/. + +"""Observability tools to spit out analysis-ready tables, one row per test case.""" + +import json +import os +from datetime import date, timedelta +from typing import Callable, Dict, List, Optional + +from hypothesis.configuration import storage_directory +from hypothesis.internal.conjecture.data import ConjectureData, Status + +TESTCASE_CALLBACKS: List[Callable[[dict], None]] = [] + + +def deliver_json_blob(value: dict) -> None: + for callback in TESTCASE_CALLBACKS: + callback(value) + + +def make_testcase( + *, + start_timestamp: float, + test_name_or_nodeid: str, + data: ConjectureData, + how_generated: str = "unknown", + string_repr: str = "<unknown>", + arguments: Optional[dict] = None, + metadata: Optional[dict] = None, + coverage: Optional[Dict[str, List[int]]] = None, +) -> dict: + if data.interesting_origin: + status_reason = str(data.interesting_origin) + else: + status_reason = str(data.events.pop("invalid because", "")) + + return { + "type": "test_case", + "run_start": start_timestamp, + "property": test_name_or_nodeid, + "status": { + Status.OVERRUN: "gave_up", + Status.INVALID: "gave_up", + Status.VALID: "passed", + Status.INTERESTING: "failed", + }[data.status], + "status_reason": status_reason, + "representation": string_repr, + "arguments": arguments or {}, + "how_generated": how_generated, # iid, mutation, etc. + "features": { + **{ + f"target:{k}".strip(":"): v for k, v in data.target_observations.items() + }, + **data.events, + }, + "metadata": { + **(metadata or {}), + "traceback": getattr(data.extra_information, "_expected_traceback", None), + }, + "coverage": coverage, + } + + +_WROTE_TO = set() + + +def _deliver_to_file(value): # pragma: no cover + kind = "testcases" if value["type"] == "test_case" else "info" + fname = storage_directory("observed", f"{date.today().isoformat()}_{kind}.jsonl") + fname.parent.mkdir(exist_ok=True) + _WROTE_TO.add(fname) + with fname.open(mode="a") as f: + f.write(json.dumps(value) + "\n") + + +if "HYPOTHESIS_EXPERIMENTAL_OBSERVABILITY" in os.environ: # pragma: no cover + TESTCASE_CALLBACKS.append(_deliver_to_file) + + # Remove files more than a week old, to cap the size on disk + max_age = (date.today() - timedelta(days=8)).isoformat() + for f in storage_directory("observed").glob("*.jsonl"): + if f.stem < max_age: # pragma: no branch + f.unlink(missing_ok=True) diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/reflection.py b/contrib/python/hypothesis/py3/hypothesis/internal/reflection.py index 31123b61ec..2f0480c987 100644 --- a/contrib/python/hypothesis/py3/hypothesis/internal/reflection.py +++ b/contrib/python/hypothesis/py3/hypothesis/internal/reflection.py @@ -306,8 +306,12 @@ def extract_lambda_source(f): This is not a good function and I am sorry for it. Forgive me my sins, oh lord """ + # You might be wondering how a lambda can have a return-type annotation? + # The answer is that we add this at runtime, in new_given_signature(), + # and we do support strange choices as applying @given() to a lambda. sig = inspect.signature(f) - assert sig.return_annotation is inspect.Parameter.empty + assert sig.return_annotation in (inspect.Parameter.empty, None), sig + if sig.parameters: if_confused = f"lambda {str(sig)[1:-1]}: <unknown>" else: diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/scrutineer.py b/contrib/python/hypothesis/py3/hypothesis/internal/scrutineer.py index 5b372ffd65..39352844b4 100644 --- a/contrib/python/hypothesis/py3/hypothesis/internal/scrutineer.py +++ b/contrib/python/hypothesis/py3/hypothesis/internal/scrutineer.py @@ -8,16 +8,29 @@ # v. 2.0. If a copy of the MPL was not distributed with this file, You can # obtain one at https://mozilla.org/MPL/2.0/. +import functools +import os +import subprocess import sys import types from collections import defaultdict from functools import lru_cache, reduce from os import sep from pathlib import Path +from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple from hypothesis._settings import Phase, Verbosity from hypothesis.internal.escalation import is_hypothesis_file +if TYPE_CHECKING: + from typing import TypeAlias +else: + TypeAlias = object + +Location: TypeAlias = Tuple[str, int] +Branch: TypeAlias = Tuple[Optional[Location], Location] +Trace: TypeAlias = Set[Branch] + @lru_cache(maxsize=None) def should_trace_file(fname): @@ -41,7 +54,7 @@ class Tracer: __slots__ = ("branches", "_previous_location") def __init__(self): - self.branches = set() + self.branches: Trace = set() self._previous_location = None def trace(self, frame, event, arg): @@ -179,3 +192,50 @@ def explanatory_lines(traces, settings): explanations = get_explaining_locations(traces) max_lines = 5 if settings.verbosity <= Verbosity.normal else float("inf") return make_report(explanations, cap_lines_at=max_lines) + + +# beware the code below; we're using some heuristics to make a nicer report... + + +@functools.lru_cache +def _get_git_repo_root() -> Path: + try: + where = subprocess.run( + ["git", "rev-parse", "--show-toplevel"], + check=True, + timeout=10, + capture_output=True, + text=True, + encoding="utf-8", + ).stdout.strip() + except Exception: # pragma: no cover + return Path().absolute().parents[-1] + else: + return Path(where) + + +if sys.version_info[:2] <= (3, 8): + + def is_relative_to(self, other): + return other == self or other in self.parents + +else: + is_relative_to = Path.is_relative_to + + +def tractable_coverage_report(trace: Trace) -> Dict[str, List[int]]: + """Report a simple coverage map which is (probably most) of the user's code.""" + coverage: dict = {} + t = dict(trace) + for file, line in set(t.keys()).union(t.values()) - {None}: # type: ignore + # On Python <= 3.11, we can use coverage.py xor Hypothesis' tracer, + # so the trace will be empty and this line never run under coverage. + coverage.setdefault(file, set()).add(line) # pragma: no cover + stdlib_fragment = f"{os.sep}lib{os.sep}python3.{sys.version_info.minor}{os.sep}" + return { + k: sorted(v) + for k, v in coverage.items() + if stdlib_fragment not in k + and is_relative_to(p := Path(k), _get_git_repo_root()) + and "site-packages" not in p.parts + } diff --git a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/attrs.py b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/attrs.py index d4f56a1f3a..3b08f3a43d 100644 --- a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/attrs.py +++ b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/attrs.py @@ -21,12 +21,38 @@ from hypothesis.strategies._internal.types import is_a_type, type_sorting_key from hypothesis.utils.conventions import infer +def get_attribute_by_alias(fields, alias, *, target=None): + """ + Get an attrs attribute by its alias, rather than its name (compare + getattr(fields, name)). + + ``target`` is used only to provide a nicer error message, and can be safely + omitted. + """ + # attrs supports defining an alias for a field, which is the name used when + # defining __init__. The init args are what we pull from when determining + # what parameters we need to supply to the class, so it's what we need to + # match against as well, rather than the class-level attribute name. + matched_fields = [f for f in fields if f.alias == alias] + if not matched_fields: + raise TypeError( + f"Unexpected keyword argument {alias} for attrs class" + f"{f' {target}' if target else ''}. Expected one of " + f"{[f.name for f in fields]}" + ) + # alias is used as an arg in __init__, so it is guaranteed to be unique, if + # it exists. + assert len(matched_fields) == 1 + return matched_fields[0] + + def from_attrs(target, args, kwargs, to_infer): """An internal version of builds(), specialised for Attrs classes.""" fields = attr.fields(target) kwargs = {k: v for k, v in kwargs.items() if v is not infer} for name in to_infer: - kwargs[name] = from_attrs_attribute(getattr(fields, name), target) + attrib = get_attribute_by_alias(fields, name, target=target) + kwargs[name] = from_attrs_attribute(attrib, target) # We might make this strategy more efficient if we added a layer here that # retries drawing if validation fails, for improved composition. # The treatment of timezones in datetimes() provides a precedent. diff --git a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/core.py b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/core.py index b8c5601587..a5a862635a 100644 --- a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/core.py +++ b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/core.py @@ -129,7 +129,11 @@ from hypothesis.strategies._internal.strings import ( OneCharStringStrategy, TextStrategy, ) -from hypothesis.strategies._internal.utils import cacheable, defines_strategy +from hypothesis.strategies._internal.utils import ( + cacheable, + defines_strategy, + to_jsonable, +) from hypothesis.utils.conventions import not_set from hypothesis.vendor.pretty import RepresentationPrinter @@ -2098,8 +2102,9 @@ class DataObject: result = self.conjecture_data.draw(strategy) self.count += 1 printer = RepresentationPrinter(context=current_build_context()) - printer.text(f"Draw {self.count}") - printer.text(": " if label is None else f" ({label}): ") + desc = f"Draw {self.count}{'' if label is None else f' ({label})'}: " + self.conjecture_data._observability_args[desc] = to_jsonable(result) + printer.text(desc) printer.pretty(result) note(printer.getvalue()) return result diff --git a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/utils.py b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/utils.py index b0e0746314..995b179b40 100644 --- a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/utils.py +++ b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/utils.py @@ -8,13 +8,17 @@ # v. 2.0. If a copy of the MPL was not distributed with this file, You can # obtain one at https://mozilla.org/MPL/2.0/. +import sys import threading from inspect import signature from typing import TYPE_CHECKING, Callable, Dict +import attr + from hypothesis.internal.cache import LRUReusedCache from hypothesis.internal.floats import float_to_int from hypothesis.internal.reflection import proxies +from hypothesis.vendor.pretty import pretty if TYPE_CHECKING: from hypothesis.strategies._internal.strategies import SearchStrategy, T @@ -144,3 +148,40 @@ def defines_strategy( return accept return decorator + + +def to_jsonable(obj: object) -> object: + """Recursively convert an object to json-encodable form. + + This is not intended to round-trip, but rather provide an analysis-ready + format for observability. To avoid side affects, we pretty-print all but + known types. + """ + if isinstance(obj, (str, int, float, bool, type(None))): + if isinstance(obj, int) and abs(obj) >= 2**63: + return float(obj) + return obj + if isinstance(obj, (list, tuple, set, frozenset)): + if isinstance(obj, tuple) and hasattr(obj, "_asdict"): + return to_jsonable(obj._asdict()) # treat namedtuples as dicts + return [to_jsonable(x) for x in obj] + if isinstance(obj, dict): + return { + k if isinstance(k, str) else pretty(k): to_jsonable(v) + for k, v in obj.items() + } + + # Special handling for dataclasses, attrs, and pydantic classes + if ( + (dcs := sys.modules.get("dataclasses")) + and dcs.is_dataclass(obj) + and not isinstance(obj, type) + ): + return to_jsonable(dcs.asdict(obj)) + if attr.has(type(obj)): + return to_jsonable(attr.asdict(obj, recurse=False)) # type: ignore + if (pyd := sys.modules.get("pydantic")) and isinstance(obj, pyd.BaseModel): + return to_jsonable(obj.model_dump()) + + # If all else fails, we'll just pretty-print as a string. + return pretty(obj) diff --git a/contrib/python/hypothesis/py3/hypothesis/version.py b/contrib/python/hypothesis/py3/hypothesis/version.py index 9b0a5e2eb1..8357097704 100644 --- a/contrib/python/hypothesis/py3/hypothesis/version.py +++ b/contrib/python/hypothesis/py3/hypothesis/version.py @@ -8,5 +8,5 @@ # v. 2.0. If a copy of the MPL was not distributed with this file, You can # obtain one at https://mozilla.org/MPL/2.0/. -__version_info__ = (6, 91, 0) +__version_info__ = (6, 92, 0) __version__ = ".".join(map(str, __version_info__)) diff --git a/contrib/python/hypothesis/py3/ya.make b/contrib/python/hypothesis/py3/ya.make index 100509362e..456dabd865 100644 --- a/contrib/python/hypothesis/py3/ya.make +++ b/contrib/python/hypothesis/py3/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(6.91.0) +VERSION(6.92.0) LICENSE(MPL-2.0) @@ -82,6 +82,7 @@ PY_SRCS( hypothesis/internal/floats.py hypothesis/internal/healthcheck.py hypothesis/internal/intervalsets.py + hypothesis/internal/observability.py hypothesis/internal/reflection.py hypothesis/internal/scrutineer.py hypothesis/internal/validation.py diff --git a/contrib/python/jsonschema/py3/jsonschema/tests/test_validators.py b/contrib/python/jsonschema/py3/jsonschema/tests/test_validators.py index 07be4f08bc..7088b0b824 100644 --- a/contrib/python/jsonschema/py3/jsonschema/tests/test_validators.py +++ b/contrib/python/jsonschema/py3/jsonschema/tests/test_validators.py @@ -1525,7 +1525,7 @@ class TestValidate(SynchronousTestCase): def test_validation_error_message(self): with self.assertRaises(exceptions.ValidationError) as e: validators.validate(12, {"type": "string"}) - self.assertRegexpMatches( + self.assertRegex( str(e.exception), "(?s)Failed validating u?'.*' in schema.*On instance", ) @@ -1533,7 +1533,7 @@ class TestValidate(SynchronousTestCase): def test_schema_error_message(self): with self.assertRaises(exceptions.SchemaError) as e: validators.validate(12, {"type": 12}) - self.assertRegexpMatches( + self.assertRegex( str(e.exception), "(?s)Failed validating u?'.*' in metaschema.*On schema", ) diff --git a/contrib/python/multidict/multidict/_multidict.c b/contrib/python/multidict/multidict/_multidict.c index 1ba79df304..cbc6179932 100644 --- a/contrib/python/multidict/multidict/_multidict.c +++ b/contrib/python/multidict/multidict/_multidict.c @@ -455,7 +455,11 @@ multidict_getall(MultiDictObject *self, PyObject *const *args, return NULL; } #else - static _PyArg_Parser _parser = {NULL, _keywords, "getall", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "getall", + .kwtuple = NULL, + }; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, @@ -500,7 +504,11 @@ multidict_getone(MultiDictObject *self, PyObject *const *args, return NULL; } #else - static _PyArg_Parser _parser = {NULL, _keywords, "getone", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "getone", + .kwtuple = NULL, + }; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, @@ -535,7 +543,11 @@ multidict_get(MultiDictObject *self, PyObject *const *args, return NULL; } #else - static _PyArg_Parser _parser = {NULL, _keywords, "get", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "get", + .kwtuple = NULL, + }; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, @@ -777,7 +789,11 @@ multidict_add(MultiDictObject *self, PyObject *const *args, return NULL; } #else - static _PyArg_Parser _parser = {NULL, _keywords, "add", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "add", + .kwtuple = NULL, + }; PyObject *argsbuf[2]; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, @@ -836,7 +852,11 @@ multidict_setdefault(MultiDictObject *self, PyObject *const *args, return NULL; } #else - static _PyArg_Parser _parser = {NULL, _keywords, "setdefault", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "setdefault", + .kwtuple = NULL, + }; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; @@ -872,7 +892,11 @@ multidict_popone(MultiDictObject *self, PyObject *const *args, return NULL; } #else - static _PyArg_Parser _parser = {NULL, _keywords, "popone", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "popone", + .kwtuple = NULL, + }; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; @@ -919,7 +943,11 @@ multidict_pop(MultiDictObject *self, PyObject *const *args, return NULL; } #else - static _PyArg_Parser _parser = {NULL, _keywords, "pop", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "pop", + .kwtuple = NULL, + }; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; @@ -967,7 +995,11 @@ multidict_popall(MultiDictObject *self, PyObject *const *args, return NULL; } #else - static _PyArg_Parser _parser = {NULL, _keywords, "popall", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "popall", + .kwtuple = NULL, + }; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; diff --git a/contrib/python/multidict/tests/test_multidict.py b/contrib/python/multidict/tests/test_multidict.py index 706fc93e75..e2ad71ee34 100644 --- a/contrib/python/multidict/tests/test_multidict.py +++ b/contrib/python/multidict/tests/test_multidict.py @@ -199,6 +199,7 @@ class BaseMultiDictTest: d.getone("key2") assert d.getone("key2", "default") == "default" + assert d.getone(key="key2", default="default") == "default" def test__iter__( self, @@ -532,6 +533,8 @@ class TestMultiDict(BaseMultiDictTest): def test_get(self, cls: Type[MultiDict[int]]) -> None: d = cls([("a", 1), ("a", 2)]) assert d["a"] == 1 + assert d.get("a") == 1 + assert d.get("z", 3) == 3 def test_items__repr__(self, cls: Type[MultiDict[str]]) -> None: d = cls([("key", "value1")], key="value2") diff --git a/contrib/python/multidict/tests/test_mutable_multidict.py b/contrib/python/multidict/tests/test_mutable_multidict.py index 3d4d16ac03..3f66e279ad 100644 --- a/contrib/python/multidict/tests/test_mutable_multidict.py +++ b/contrib/python/multidict/tests/test_mutable_multidict.py @@ -44,6 +44,7 @@ class TestMutableMultiDict: default = object() assert d.getall("some_key", default) is default + assert d.getall(key="some_key", default=default) is default def test_add(self, cls): d = cls() @@ -124,7 +125,7 @@ class TestMutableMultiDict: def test_set_default(self, cls): d = cls([("key", "one"), ("key", "two")], foo="bar") assert "one" == d.setdefault("key", "three") - assert "three" == d.setdefault("otherkey", "three") + assert "three" == d.setdefault(key="otherkey", default="three") assert "otherkey" in d assert "three" == d["otherkey"] @@ -163,6 +164,7 @@ class TestMutableMultiDict: d = cls(other="val") assert "default" == d.pop("key", "default") + assert "default" == d.pop(key="key", default="default") assert "other" in d def test_pop_raises(self, cls): @@ -229,6 +231,7 @@ class TestMutableMultiDict: def test_popall_default(self, cls): d = cls() assert "val" == d.popall("key", "val") + assert "val" == d.popall(key="key", default="val") def test_popall_key_error(self, cls): d = cls() diff --git a/contrib/python/multidict/tests/test_version.py b/contrib/python/multidict/tests/test_version.py index 067d6210ce..9b25c0e72d 100644 --- a/contrib/python/multidict/tests/test_version.py +++ b/contrib/python/multidict/tests/test_version.py @@ -95,6 +95,8 @@ class VersionMixin: v = self.getver(m) m.popone("key2", "default") assert self.getver(m) == v + m.popone(key="key2", default="default") + assert self.getver(m) == v def test_popone_key_error(self): m = self.cls() diff --git a/contrib/python/numpy/py3/numpy/tests/test_public_api.py b/contrib/python/numpy/py3/numpy/tests/test_public_api.py index 79d05407e5..3711c2f96b 100644 --- a/contrib/python/numpy/py3/numpy/tests/test_public_api.py +++ b/contrib/python/numpy/py3/numpy/tests/test_public_api.py @@ -339,6 +339,8 @@ SKIP_LIST = [ ] if sys.version_info < (3, 12): SKIP_LIST += ["numpy.distutils.msvc9compiler"] +else: + SKIP_LIST += ["numpy.distutils"] # suppressing warnings from deprecated modules diff --git a/contrib/python/olefile/py3/.dist-info/METADATA b/contrib/python/olefile/py3/.dist-info/METADATA index fe7735d0fd..2521b75751 100644 --- a/contrib/python/olefile/py3/.dist-info/METADATA +++ b/contrib/python/olefile/py3/.dist-info/METADATA @@ -1,13 +1,12 @@ Metadata-Version: 2.1 Name: olefile -Version: 0.46 +Version: 0.47 Summary: Python package to parse, read and write Microsoft OLE2 files (Structured Storage or Compound Document, Microsoft Office) Home-page: https://www.decalage.info/python/olefileio Author: Philippe Lagadec Author-email: nospam@decalage.info License: BSD Download-URL: https://github.com/decalage2/olefile/tarball/master -Description-Content-Type: UNKNOWN Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers @@ -20,74 +19,79 @@ Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Software Development :: Libraries :: Python Modules -Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.* +Description-Content-Type: text/markdown +Provides-Extra: tests +Requires-Dist: pytest ; extra == 'tests' +Requires-Dist: pytest-cov ; extra == 'tests' olefile ======= -|Build Status TravisCI| |Build Status AppVeyor| |Coverage Status| -|Documentation Status| |PyPI| |Can I Use Python 3?| |Say Thanks!| - -`olefile <https://www.decalage.info/olefile>`__ is a Python package to -parse, read and write `Microsoft OLE2 -files <http://en.wikipedia.org/wiki/Compound_File_Binary_Format>`__ -(also called Structured Storage, Compound File Binary Format or Compound -Document File Format), such as Microsoft Office 97-2003 documents, -vbaProject.bin in MS Office 2007+ files, Image Composer and FlashPix -files, Outlook messages, StickyNotes, several Microscopy file formats, -McAfee antivirus quarantine files, etc. - -**Quick links:** `Home page <https://www.decalage.info/olefile>`__ - -`Download/Install <http://olefile.readthedocs.io/en/latest/Install.html>`__ -- `Documentation <http://olefile.readthedocs.io/en/latest>`__ - `Report -Issues/Suggestions/Questions <https://github.com/decalage2/olefile/issues>`__ -- `Contact the author <https://www.decalage.info/contact>`__ - -`Repository <https://github.com/decalage2/olefile>`__ - `Updates on -Twitter <https://twitter.com/decalage2>`__ +[![Test](https://github.com/decalage2/olefile/actions/workflows/test.yml/badge.svg)](https://github.com/decalage2/olefile/actions) +[![Build Status AppVeyor](https://ci.appveyor.com/api/projects/status/github/decalage2/olefile?svg=true)](https://ci.appveyor.com/project/decalage2/olefile) +[![codecov](https://codecov.io/gh/decalage2/olefile/branch/main/graph/badge.svg)](https://codecov.io/gh/decalage2/olefile) +[![Documentation Status](http://readthedocs.org/projects/olefile/badge/?version=latest)](http://olefile.readthedocs.io/en/latest/?badge=latest) +[![PyPI](https://img.shields.io/pypi/v/olefile.svg)](https://pypi.org/project/olefile/) +[![Say Thanks!](https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg)](https://saythanks.io/to/decalage2) + +[olefile](https://www.decalage.info/olefile) is a Python package to parse, read and write +[Microsoft OLE2 files](http://en.wikipedia.org/wiki/Compound_File_Binary_Format) +(also called Structured Storage, Compound File Binary Format or Compound Document File Format), +such as Microsoft Office 97-2003 documents, vbaProject.bin in MS Office 2007+ files, Image Composer +and FlashPix files, Outlook messages, StickyNotes, several Microscopy file formats, McAfee antivirus quarantine files, +etc. + + +**Quick links:** [Home page](https://www.decalage.info/olefile) - +[Download/Install](http://olefile.readthedocs.io/en/latest/Install.html) - +[Documentation](http://olefile.readthedocs.io/en/latest) - +[Report Issues/Suggestions/Questions](https://github.com/decalage2/olefile/issues) - +[Contact the author](https://www.decalage.info/contact) - +[Repository](https://github.com/decalage2/olefile) - +[Updates on Twitter](https://twitter.com/decalage2) + News ---- -Follow all updates and news on Twitter: https://twitter.com/decalage2 - -- **2018-09-09 v0.46**: OleFileIO can now be used as a context manager - (with...as), to close the file automatically (see - `doc <https://olefile.readthedocs.io/en/latest/Howto.html#open-an-ole-file-from-disk>`__). - Improved handling of malformed files, fixed several bugs. -- 2018-01-24 v0.45: olefile can now overwrite streams of any size, - improved handling of malformed files, fixed several - `bugs <https://github.com/decalage2/olefile/milestone/4?closed=1>`__, - end of support for Python 2.6 and 3.3. -- 2017-01-06 v0.44: several bugfixes, removed support for Python 2.5 - (olefile2), added support for incomplete streams and incorrect - directory entries (to read malformed documents), added getclsid, - improved `documentation <http://olefile.readthedocs.io/en/latest>`__ - with API reference. -- 2017-01-04: moved the documentation to - `ReadTheDocs <http://olefile.readthedocs.io/en/latest>`__ -- 2016-05-20: moved olefile repository to - `GitHub <https://github.com/decalage2/olefile>`__ -- 2016-02-02 v0.43: fixed issues - `#26 <https://github.com/decalage2/olefile/issues/26>`__ and - `#27 <https://github.com/decalage2/olefile/issues/27>`__, better - handling of malformed files, use python logging. -- see - `changelog <https://github.com/decalage2/olefile/blob/master/CHANGELOG.md>`__ - for more detailed information and the latest changes. +Follow all updates and news on Twitter: <https://twitter.com/decalage2> + +- **2023-12-01 v0.47**: now distributed as wheel package, added VT_VECTOR support for properties, + added get_userdefined_properties, fixed bugs in isOleFile and write_sect, improved file closure +- 2018-09-09 v0.46: OleFileIO can now be used as a context manager +(with...as), to close the file automatically +(see [doc](https://olefile.readthedocs.io/en/latest/Howto.html#open-an-ole-file-from-disk)). +Improved handling of malformed files, fixed several bugs. +- 2018-01-24 v0.45: olefile can now overwrite streams of any size, improved handling of malformed files, +fixed several [bugs](https://github.com/decalage2/olefile/milestone/4?closed=1), end of support for Python 2.6 and 3.3. +- 2017-01-06 v0.44: several bugfixes, removed support for Python 2.5 (olefile2), +added support for incomplete streams and incorrect directory entries (to read malformed documents), +added getclsid, improved [documentation](http://olefile.readthedocs.io/en/latest) with API reference. +- 2017-01-04: moved the documentation to [ReadTheDocs](http://olefile.readthedocs.io/en/latest) +- 2016-05-20: moved olefile repository to [GitHub](https://github.com/decalage2/olefile) +- 2016-02-02 v0.43: fixed issues [#26](https://github.com/decalage2/olefile/issues/26) + and [#27](https://github.com/decalage2/olefile/issues/27), + better handling of malformed files, use python logging. +- see [changelog](https://github.com/decalage2/olefile/blob/master/CHANGELOG.md) for more detailed information and +the latest changes. Download/Install ---------------- -If you have pip or setuptools installed (pip is included in Python -2.7.9+), you may simply run **pip install olefile** or **easy_install -olefile** for the first installation. +If you have pip or setuptools installed (pip is included in Python 2.7.9+), you may simply run **pip install olefile** +or **easy_install olefile** for the first installation. To update olefile, run **pip install -U olefile**. @@ -96,115 +100,86 @@ Otherwise, see http://olefile.readthedocs.io/en/latest/Install.html Features -------- -- Parse, read and write any OLE file such as Microsoft Office 97-2003 - legacy document formats (Word .doc, Excel .xls, PowerPoint .ppt, - Visio .vsd, Project .mpp), Image Composer and FlashPix files, Outlook - messages, StickyNotes, Zeiss AxioVision ZVI files, Olympus FluoView - OIB files, etc -- List all the streams and storages contained in an OLE file -- Open streams as files -- Parse and read property streams, containing metadata of the file -- Portable, pure Python module, no dependency +- Parse, read and write any OLE file such as Microsoft Office 97-2003 legacy document formats (Word .doc, Excel .xls, + PowerPoint .ppt, Visio .vsd, Project .mpp), MSI files, Image Composer and FlashPix files, Outlook messages, StickyNotes, + Zeiss AxioVision ZVI files, Olympus FluoView OIB files, etc +- List all the streams and storages contained in an OLE file +- Open streams as files +- Parse and read property streams, containing metadata of the file +- Portable, pure Python module, no dependency olefile can be used as an independent package or with PIL/Pillow. -olefile is mostly meant for developers. If you are looking for tools to -analyze OLE files or to extract data (especially for security purposes -such as malware analysis and forensics), then please also check my -`python-oletools <https://www.decalage.info/python/oletools>`__, which -are built upon olefile and provide a higher-level interface. +olefile is mostly meant for developers. If you are looking for tools to analyze OLE files or to extract data (especially +for security purposes such as malware analysis and forensics), then please also check my +[python-oletools](https://www.decalage.info/python/oletools), which are built upon olefile and provide a higher-level interface. + Documentation ------------- -Please see the `online -documentation <http://olefile.readthedocs.io/en/latest>`__ for more -information. +Please see the [online documentation](http://olefile.readthedocs.io/en/latest) for more information. + -Real-life examples ------------------- +## Real-life examples ## -A real-life example: `using OleFileIO_PL for malware analysis and -forensics <http://blog.gregback.net/2011/03/using-remnux-for-forensic-puzzle-6/>`__. +A real-life example: [using OleFileIO_PL for malware analysis and forensics](http://blog.gregback.net/2011/03/using-remnux-for-forensic-puzzle-6/). + +See also [this paper](https://computer-forensics.sans.org/community/papers/gcfa/grow-forensic-tools-taxonomy-python-libraries-helpful-forensic-analysis_6879) about python tools for forensics, which features olefile. -See also `this -paper <https://computer-forensics.sans.org/community/papers/gcfa/grow-forensic-tools-taxonomy-python-libraries-helpful-forensic-analysis_6879>`__ -about python tools for forensics, which features olefile. License ------- -olefile (formerly OleFileIO_PL) is copyright (c) 2005-2018 Philippe -Lagadec (https://www.decalage.info) +olefile (formerly OleFileIO_PL) is copyright (c) 2005-2023 Philippe Lagadec +([https://www.decalage.info](https://www.decalage.info)) All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -- Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -- 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT -HOLDER OR CONTRIBUTORS 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. - --------------- - -olefile is based on source code from the OleFileIO module of the Python -Imaging Library (PIL) published by Fredrik Lundh under the following -license: +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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. + + +---------- + +olefile is based on source code from the OleFileIO module of the Python Imaging Library (PIL) published by Fredrik +Lundh under the following license: The Python Imaging Library (PIL) is -- Copyright (c) 1997-2009 by Secret Labs AB -- Copyright (c) 1995-2009 by Fredrik Lundh - -By obtaining, using, and/or copying this software and/or its associated -documentation, you agree that you have read, understood, and will comply -with the following terms and conditions: - -Permission to use, copy, modify, and distribute this software and its -associated documentation for any purpose and without fee is hereby -granted, provided that the above copyright notice appears in all copies, -and that both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Secret Labs AB or the -author not be used in advertising or publicity pertaining to -distribution of the software without specific, written prior permission. - -SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO -THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR -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 THIS SOFTWARE. - -.. |Build Status TravisCI| image:: https://travis-ci.org/decalage2/olefile.svg?branch=master - :target: https://travis-ci.org/decalage2/olefile -.. |Build Status AppVeyor| image:: https://ci.appveyor.com/api/projects/status/github/decalage2/olefile?svg=true - :target: https://ci.appveyor.com/project/decalage2/olefile -.. |Coverage Status| image:: https://coveralls.io/repos/github/decalage2/olefile/badge.svg?branch=master - :target: https://coveralls.io/github/decalage2/olefile?branch=master -.. |Documentation Status| image:: http://readthedocs.org/projects/olefile/badge/?version=latest - :target: http://olefile.readthedocs.io/en/latest/?badge=latest -.. |PyPI| image:: https://img.shields.io/pypi/v/olefile.svg - :target: https://pypi.org/project/olefile/ -.. |Can I Use Python 3?| image:: https://caniusepython3.com/project/olefile.svg - :target: https://caniusepython3.com/project/olefile -.. |Say Thanks!| image:: https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg - :target: https://saythanks.io/to/decalage2 +- Copyright (c) 1997-2009 by Secret Labs AB +- Copyright (c) 1995-2009 by Fredrik Lundh + +By obtaining, using, and/or copying this software and/or its associated documentation, you agree that you have read, +understood, and will comply with the following terms and conditions: + +Permission to use, copy, modify, and distribute this software and its associated documentation for any purpose and +without fee is hereby granted, provided that the above copyright notice appears in all copies, and that both that +copyright notice and this permission notice appear in supporting documentation, and that the name of Secret Labs AB or +the author not be used in advertising or publicity pertaining to distribution of the software without specific, written +prior permission. + +SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR 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 THIS +SOFTWARE. diff --git a/contrib/python/olefile/py3/LICENSE.txt b/contrib/python/olefile/py3/LICENSE.txt index 81dad32622..5f53714a94 100644 --- a/contrib/python/olefile/py3/LICENSE.txt +++ b/contrib/python/olefile/py3/LICENSE.txt @@ -1,6 +1,6 @@ LICENSE for the olefile package: -olefile (formerly OleFileIO_PL) is copyright (c) 2005-2018 Philippe Lagadec +olefile (formerly OleFileIO_PL) is copyright (c) 2005-2023 Philippe Lagadec (https://www.decalage.info) All rights reserved. diff --git a/contrib/python/olefile/py3/OleFileIO_PL.py b/contrib/python/olefile/py3/OleFileIO_PL.py new file mode 100644 index 0000000000..ffa4075e3b --- /dev/null +++ b/contrib/python/olefile/py3/OleFileIO_PL.py @@ -0,0 +1,37 @@ +#!/usr/local/bin/python +# -*- coding: latin-1 -*- +""" +olefile (formerly OleFileIO_PL) + +Module to read/write Microsoft OLE2 files (also called Structured Storage or +Microsoft Compound Document File Format), such as Microsoft Office 97-2003 +documents, Image Composer and FlashPix files, Outlook messages, ... +This version is compatible with Python 2.6+ and 3.x + +Project website: http://www.decalage.info/olefile + +olefile is copyright (c) 2005-2015 Philippe Lagadec (http://www.decalage.info) + +olefile is based on the OleFileIO module from the PIL library v1.1.6 +See: http://www.pythonware.com/products/pil/index.htm + +The Python Imaging Library (PIL) is + Copyright (c) 1997-2005 by Secret Labs AB + Copyright (c) 1995-2005 by Fredrik Lundh + +See source code and LICENSE.txt for information on usage and redistribution. +""" + +# The OleFileIO_PL module is for backward compatibility + +try: + # first try to import olefile for Python 2.6+/3.x + from olefile.olefile import * + # import metadata not covered by *: + from olefile.olefile import __version__, __author__, __date__ + +except: + # if it fails, fallback to the old version olefile2 for Python 2.x: + from olefile.olefile2 import * + # import metadata not covered by *: + from olefile.olefile2 import __doc__, __version__, __author__, __date__ diff --git a/contrib/python/olefile/py3/README.md b/contrib/python/olefile/py3/README.md index 8987e1b8a2..f053489a47 100644 --- a/contrib/python/olefile/py3/README.md +++ b/contrib/python/olefile/py3/README.md @@ -1,12 +1,11 @@ olefile ======= -[![Build Status TravisCI](https://travis-ci.org/decalage2/olefile.svg?branch=master)](https://travis-ci.org/decalage2/olefile) +[![Test](https://github.com/decalage2/olefile/actions/workflows/test.yml/badge.svg)](https://github.com/decalage2/olefile/actions) [![Build Status AppVeyor](https://ci.appveyor.com/api/projects/status/github/decalage2/olefile?svg=true)](https://ci.appveyor.com/project/decalage2/olefile) -[![Coverage Status](https://coveralls.io/repos/github/decalage2/olefile/badge.svg?branch=master)](https://coveralls.io/github/decalage2/olefile?branch=master) +[![codecov](https://codecov.io/gh/decalage2/olefile/branch/main/graph/badge.svg)](https://codecov.io/gh/decalage2/olefile) [![Documentation Status](http://readthedocs.org/projects/olefile/badge/?version=latest)](http://olefile.readthedocs.io/en/latest/?badge=latest) [![PyPI](https://img.shields.io/pypi/v/olefile.svg)](https://pypi.org/project/olefile/) -[![Can I Use Python 3?](https://caniusepython3.com/project/olefile.svg)](https://caniusepython3.com/project/olefile) [![Say Thanks!](https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg)](https://saythanks.io/to/decalage2) [olefile](https://www.decalage.info/olefile) is a Python package to parse, read and write @@ -31,7 +30,9 @@ News Follow all updates and news on Twitter: <https://twitter.com/decalage2> -- **2018-09-09 v0.46**: OleFileIO can now be used as a context manager +- **2023-12-01 v0.47**: now distributed as wheel package, added VT_VECTOR support for properties, + added get_userdefined_properties, fixed bugs in isOleFile and write_sect, improved file closure +- 2018-09-09 v0.46: OleFileIO can now be used as a context manager (with...as), to close the file automatically (see [doc](https://olefile.readthedocs.io/en/latest/Howto.html#open-an-ole-file-from-disk)). Improved handling of malformed files, fixed several bugs. @@ -62,7 +63,7 @@ Features -------- - Parse, read and write any OLE file such as Microsoft Office 97-2003 legacy document formats (Word .doc, Excel .xls, - PowerPoint .ppt, Visio .vsd, Project .mpp), Image Composer and FlashPix files, Outlook messages, StickyNotes, + PowerPoint .ppt, Visio .vsd, Project .mpp), MSI files, Image Composer and FlashPix files, Outlook messages, StickyNotes, Zeiss AxioVision ZVI files, Olympus FluoView OIB files, etc - List all the streams and storages contained in an OLE file - Open streams as files @@ -92,7 +93,7 @@ See also [this paper](https://computer-forensics.sans.org/community/papers/gcfa/ License ------- -olefile (formerly OleFileIO_PL) is copyright (c) 2005-2018 Philippe Lagadec +olefile (formerly OleFileIO_PL) is copyright (c) 2005-2023 Philippe Lagadec ([https://www.decalage.info](https://www.decalage.info)) All rights reserved. diff --git a/contrib/python/olefile/py3/README.rst b/contrib/python/olefile/py3/README.rst deleted file mode 100644 index df8fb11462..0000000000 --- a/contrib/python/olefile/py3/README.rst +++ /dev/null @@ -1,177 +0,0 @@ -olefile -======= - -|Build Status TravisCI| |Build Status AppVeyor| |Coverage Status| -|Documentation Status| |PyPI| |Can I Use Python 3?| |Say Thanks!| - -`olefile <https://www.decalage.info/olefile>`__ is a Python package to -parse, read and write `Microsoft OLE2 -files <http://en.wikipedia.org/wiki/Compound_File_Binary_Format>`__ -(also called Structured Storage, Compound File Binary Format or Compound -Document File Format), such as Microsoft Office 97-2003 documents, -vbaProject.bin in MS Office 2007+ files, Image Composer and FlashPix -files, Outlook messages, StickyNotes, several Microscopy file formats, -McAfee antivirus quarantine files, etc. - -**Quick links:** `Home page <https://www.decalage.info/olefile>`__ - -`Download/Install <http://olefile.readthedocs.io/en/latest/Install.html>`__ -- `Documentation <http://olefile.readthedocs.io/en/latest>`__ - `Report -Issues/Suggestions/Questions <https://github.com/decalage2/olefile/issues>`__ -- `Contact the author <https://www.decalage.info/contact>`__ - -`Repository <https://github.com/decalage2/olefile>`__ - `Updates on -Twitter <https://twitter.com/decalage2>`__ - -News ----- - -Follow all updates and news on Twitter: https://twitter.com/decalage2 - -- **2018-09-09 v0.46**: OleFileIO can now be used as a context manager - (with...as), to close the file automatically (see - `doc <https://olefile.readthedocs.io/en/latest/Howto.html#open-an-ole-file-from-disk>`__). - Improved handling of malformed files, fixed several bugs. -- 2018-01-24 v0.45: olefile can now overwrite streams of any size, - improved handling of malformed files, fixed several - `bugs <https://github.com/decalage2/olefile/milestone/4?closed=1>`__, - end of support for Python 2.6 and 3.3. -- 2017-01-06 v0.44: several bugfixes, removed support for Python 2.5 - (olefile2), added support for incomplete streams and incorrect - directory entries (to read malformed documents), added getclsid, - improved `documentation <http://olefile.readthedocs.io/en/latest>`__ - with API reference. -- 2017-01-04: moved the documentation to - `ReadTheDocs <http://olefile.readthedocs.io/en/latest>`__ -- 2016-05-20: moved olefile repository to - `GitHub <https://github.com/decalage2/olefile>`__ -- 2016-02-02 v0.43: fixed issues - `#26 <https://github.com/decalage2/olefile/issues/26>`__ and - `#27 <https://github.com/decalage2/olefile/issues/27>`__, better - handling of malformed files, use python logging. -- see - `changelog <https://github.com/decalage2/olefile/blob/master/CHANGELOG.md>`__ - for more detailed information and the latest changes. - -Download/Install ----------------- - -If you have pip or setuptools installed (pip is included in Python -2.7.9+), you may simply run **pip install olefile** or **easy_install -olefile** for the first installation. - -To update olefile, run **pip install -U olefile**. - -Otherwise, see http://olefile.readthedocs.io/en/latest/Install.html - -Features --------- - -- Parse, read and write any OLE file such as Microsoft Office 97-2003 - legacy document formats (Word .doc, Excel .xls, PowerPoint .ppt, - Visio .vsd, Project .mpp), Image Composer and FlashPix files, Outlook - messages, StickyNotes, Zeiss AxioVision ZVI files, Olympus FluoView - OIB files, etc -- List all the streams and storages contained in an OLE file -- Open streams as files -- Parse and read property streams, containing metadata of the file -- Portable, pure Python module, no dependency - -olefile can be used as an independent package or with PIL/Pillow. - -olefile is mostly meant for developers. If you are looking for tools to -analyze OLE files or to extract data (especially for security purposes -such as malware analysis and forensics), then please also check my -`python-oletools <https://www.decalage.info/python/oletools>`__, which -are built upon olefile and provide a higher-level interface. - -Documentation -------------- - -Please see the `online -documentation <http://olefile.readthedocs.io/en/latest>`__ for more -information. - -Real-life examples ------------------- - -A real-life example: `using OleFileIO_PL for malware analysis and -forensics <http://blog.gregback.net/2011/03/using-remnux-for-forensic-puzzle-6/>`__. - -See also `this -paper <https://computer-forensics.sans.org/community/papers/gcfa/grow-forensic-tools-taxonomy-python-libraries-helpful-forensic-analysis_6879>`__ -about python tools for forensics, which features olefile. - -License -------- - -olefile (formerly OleFileIO_PL) is copyright (c) 2005-2018 Philippe -Lagadec (https://www.decalage.info) - -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -- Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -- 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT -HOLDER OR CONTRIBUTORS 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. - --------------- - -olefile is based on source code from the OleFileIO module of the Python -Imaging Library (PIL) published by Fredrik Lundh under the following -license: - -The Python Imaging Library (PIL) is - -- Copyright (c) 1997-2009 by Secret Labs AB -- Copyright (c) 1995-2009 by Fredrik Lundh - -By obtaining, using, and/or copying this software and/or its associated -documentation, you agree that you have read, understood, and will comply -with the following terms and conditions: - -Permission to use, copy, modify, and distribute this software and its -associated documentation for any purpose and without fee is hereby -granted, provided that the above copyright notice appears in all copies, -and that both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Secret Labs AB or the -author not be used in advertising or publicity pertaining to -distribution of the software without specific, written prior permission. - -SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO -THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR -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 THIS SOFTWARE. - -.. |Build Status TravisCI| image:: https://travis-ci.org/decalage2/olefile.svg?branch=master - :target: https://travis-ci.org/decalage2/olefile -.. |Build Status AppVeyor| image:: https://ci.appveyor.com/api/projects/status/github/decalage2/olefile?svg=true - :target: https://ci.appveyor.com/project/decalage2/olefile -.. |Coverage Status| image:: https://coveralls.io/repos/github/decalage2/olefile/badge.svg?branch=master - :target: https://coveralls.io/github/decalage2/olefile?branch=master -.. |Documentation Status| image:: http://readthedocs.org/projects/olefile/badge/?version=latest - :target: http://olefile.readthedocs.io/en/latest/?badge=latest -.. |PyPI| image:: https://img.shields.io/pypi/v/olefile.svg - :target: https://pypi.org/project/olefile/ -.. |Can I Use Python 3?| image:: https://caniusepython3.com/project/olefile.svg - :target: https://caniusepython3.com/project/olefile -.. |Say Thanks!| image:: https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg - :target: https://saythanks.io/to/decalage2 diff --git a/contrib/python/olefile/py3/olefile/CONTRIBUTORS.txt b/contrib/python/olefile/py3/olefile/CONTRIBUTORS.txt new file mode 100644 index 0000000000..45c56828c3 --- /dev/null +++ b/contrib/python/olefile/py3/olefile/CONTRIBUTORS.txt @@ -0,0 +1,17 @@ +CONTRIBUTORS for the olefile project +==================================== + +This is a non-exhaustive list of all the people who helped me improve the +olefile project (formerly OleFileIO_PL), in approximative chronological order. +Please contact me if I forgot to mention your name. + +A big thank you to all of them: + +- Niko Ehrenfeuchter: added support for Jython +- Niko Ehrenfeuchter, Martijn Berger and Dave Jones: helped fix 4K sector support +- Martin Panter: conversion to Python 3.x/2.6+ +- mete0r_kr: added support for file-like objects +- chuckleberryfinn: fixed bug in getproperties +- Martijn, Ben G.: bug report for 64 bits platforms +- Philippe Lagadec: main author and maintainer since 2005 +- and of course Fredrik Lundh: original author of OleFileIO from 1995 to 2005 diff --git a/contrib/python/olefile/py3/olefile/LICENSE.txt b/contrib/python/olefile/py3/olefile/LICENSE.txt new file mode 100644 index 0000000000..61ecdd96c1 --- /dev/null +++ b/contrib/python/olefile/py3/olefile/LICENSE.txt @@ -0,0 +1,56 @@ +LICENSE for the olefile package: + +olefile (formerly OleFileIO_PL) is copyright (c) 2005-2015 Philippe Lagadec +(http://www.decalage.info) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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. + + +---------- + +olefile is based on source code from the OleFileIO module of the Python +Imaging Library (PIL) published by Fredrik Lundh under the following license: + +The Python Imaging Library (PIL) is +- Copyright (c) 1997-2005 by Secret Labs AB +- Copyright (c) 1995-2005 by Fredrik Lundh + +By obtaining, using, and/or copying this software and/or its associated +documentation, you agree that you have read, understood, and will comply with +the following terms and conditions: + +Permission to use, copy, modify, and distribute this software and its +associated documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appears in all copies, and that both +that copyright notice and this permission notice appear in supporting +documentation, and that the name of Secret Labs AB or the author not be used +in advertising or publicity pertaining to distribution of the software without +specific, written prior permission. + +SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN +NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR 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 THIS SOFTWARE. diff --git a/contrib/python/olefile/py3/olefile/README.rst b/contrib/python/olefile/py3/olefile/README.rst new file mode 100644 index 0000000000..4c5fbc4579 --- /dev/null +++ b/contrib/python/olefile/py3/olefile/README.rst @@ -0,0 +1,221 @@ +olefile (formerly OleFileIO\_PL) +================================ + +`olefile <http://www.decalage.info/olefile>`_ is a Python package to +parse, read and write `Microsoft OLE2 +files <http://en.wikipedia.org/wiki/Compound_File_Binary_Format>`_ (also +called Structured Storage, Compound File Binary Format or Compound +Document File Format), such as Microsoft Office 97-2003 documents, +vbaProject.bin in MS Office 2007+ files, Image Composer and FlashPix +files, Outlook messages, StickyNotes, several Microscopy file formats, +McAfee antivirus quarantine files, etc. + +**Quick links:** `Home page <http://www.decalage.info/olefile>`_ - +`Download/Install <https://bitbucket.org/decalage/olefileio_pl/wiki/Install>`_ +- `Documentation <https://bitbucket.org/decalage/olefileio_pl/wiki>`_ - +`Report +Issues/Suggestions/Questions <https://bitbucket.org/decalage/olefileio_pl/issues?status=new&status=open>`_ +- `Contact the author <http://decalage.info/contact>`_ - +`Repository <https://bitbucket.org/decalage/olefileio_pl>`_ - `Updates +on Twitter <https://twitter.com/decalage2>`_ + +News +---- + +Follow all updates and news on Twitter: https://twitter.com/decalage2 + +- **2015-01-25 v0.42**: improved handling of special characters in + stream/storage names on Python 2.x (using UTF-8 instead of Latin-1), + fixed bug in listdir with empty storages. +- 2014-11-25 v0.41: OleFileIO.open and isOleFile now support OLE files + stored in byte strings, fixed installer for python 3, added support + for Jython (Niko Ehrenfeuchter) +- 2014-10-01 v0.40: renamed OleFileIO\_PL to olefile, added initial + write support for streams >4K, updated doc and license, improved the + setup script. +- 2014-07-27 v0.31: fixed support for large files with 4K sectors, + thanks to Niko Ehrenfeuchter, Martijn Berger and Dave Jones. Added + test scripts from Pillow (by hugovk). Fixed setup for Python 3 + (Martin Panter) +- 2014-02-04 v0.30: now compatible with Python 3.x, thanks to Martin + Panter who did most of the hard work. +- 2013-07-24 v0.26: added methods to parse stream/storage timestamps, + improved listdir to include storages, fixed parsing of direntry + timestamps +- 2013-05-27 v0.25: improved metadata extraction, properties parsing + and exception handling, fixed `issue + #12 <https://bitbucket.org/decalage/olefileio_pl/issue/12/error-when-converting-timestamps-in-ole>`_ +- 2013-05-07 v0.24: new features to extract metadata (get\_metadata + method and OleMetadata class), improved getproperties to convert + timestamps to Python datetime +- 2012-10-09: published + `python-oletools <http://www.decalage.info/python/oletools>`_, a + package of analysis tools based on OleFileIO\_PL +- 2012-09-11 v0.23: added support for file-like objects, fixed `issue + #8 <https://bitbucket.org/decalage/olefileio_pl/issue/8/bug-with-file-object>`_ +- 2012-02-17 v0.22: fixed issues #7 (bug in getproperties) and #2 + (added close method) +- 2011-10-20: code hosted on bitbucket to ease contributions and bug + tracking +- 2010-01-24 v0.21: fixed support for big-endian CPUs, such as PowerPC + Macs. +- 2009-12-11 v0.20: small bugfix in OleFileIO.open when filename is not + plain str. +- 2009-12-10 v0.19: fixed support for 64 bits platforms (thanks to Ben + G. and Martijn for reporting the bug) +- see changelog in source code for more info. + +Download/Install +---------------- + +If you have pip or setuptools installed (pip is included in Python +2.7.9+), you may simply run **pip install olefile** or **easy\_install +olefile** for the first installation. + +To update olefile, run **pip install -U olefile**. + +Otherwise, see https://bitbucket.org/decalage/olefileio\_pl/wiki/Install + +Features +-------- + +- Parse, read and write any OLE file such as Microsoft Office 97-2003 + legacy document formats (Word .doc, Excel .xls, PowerPoint .ppt, + Visio .vsd, Project .mpp), Image Composer and FlashPix files, Outlook + messages, StickyNotes, Zeiss AxioVision ZVI files, Olympus FluoView + OIB files, etc +- List all the streams and storages contained in an OLE file +- Open streams as files +- Parse and read property streams, containing metadata of the file +- Portable, pure Python module, no dependency + +olefile can be used as an independent package or with PIL/Pillow. + +olefile is mostly meant for developers. If you are looking for tools to +analyze OLE files or to extract data (especially for security purposes +such as malware analysis and forensics), then please also check my +`python-oletools <http://www.decalage.info/python/oletools>`_, which are +built upon olefile and provide a higher-level interface. + +History +------- + +olefile is based on the OleFileIO module from +`PIL <http://www.pythonware.com/products/pil/index.htm>`_, the excellent +Python Imaging Library, created and maintained by Fredrik Lundh. The +olefile API is still compatible with PIL, but since 2005 I have improved +the internal implementation significantly, with new features, bugfixes +and a more robust design. From 2005 to 2014 the project was called +OleFileIO\_PL, and in 2014 I changed its name to olefile to celebrate +its 9 years and its new write features. + +As far as I know, olefile is the most complete and robust Python +implementation to read MS OLE2 files, portable on several operating +systems. (please tell me if you know other similar Python modules) + +Since 2014 olefile/OleFileIO\_PL has been integrated into +`Pillow <http://python-imaging.github.io/>`_, the friendly fork of PIL. +olefile will continue to be improved as a separate project, and new +versions will be merged into Pillow regularly. + +Main improvements over the original version of OleFileIO in PIL: +---------------------------------------------------------------- + +- Compatible with Python 3.x and 2.6+ +- Many bug fixes +- Support for files larger than 6.8MB +- Support for 64 bits platforms and big-endian CPUs +- Robust: many checks to detect malformed files +- Runtime option to choose if malformed files should be parsed or raise + exceptions +- Improved API +- Metadata extraction, stream/storage timestamps (e.g. for document + forensics) +- Can open file-like objects +- Added setup.py and install.bat to ease installation +- More convenient slash-based syntax for stream paths +- Write features + +Documentation +------------- + +Please see the `online +documentation <https://bitbucket.org/decalage/olefileio_pl/wiki>`_ for +more information, especially the `OLE +overview <https://bitbucket.org/decalage/olefileio_pl/wiki/OLE_Overview>`_ +and the `API +page <https://bitbucket.org/decalage/olefileio_pl/wiki/API>`_ which +describe how to use olefile in Python applications. A copy of the same +documentation is also provided in the doc subfolder of the olefile +package. + +Real-life examples +------------------ + +A real-life example: `using OleFileIO\_PL for malware analysis and +forensics <http://blog.gregback.net/2011/03/using-remnux-for-forensic-puzzle-6/>`_. + +See also `this +paper <https://computer-forensics.sans.org/community/papers/gcfa/grow-forensic-tools-taxonomy-python-libraries-helpful-forensic-analysis_6879>`_ +about python tools for forensics, which features olefile. + +License +------- + +olefile (formerly OleFileIO\_PL) is copyright (c) 2005-2015 Philippe +Lagadec (`http://www.decalage.info <http://www.decalage.info>`_) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +- Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +- 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT +HOLDER OR CONTRIBUTORS 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. + +-------------- + +olefile is based on source code from the OleFileIO module of the Python +Imaging Library (PIL) published by Fredrik Lundh under the following +license: + +The Python Imaging Library (PIL) is + +- Copyright (c) 1997-2005 by Secret Labs AB +- Copyright (c) 1995-2005 by Fredrik Lundh + +By obtaining, using, and/or copying this software and/or its associated +documentation, you agree that you have read, understood, and will comply +with the following terms and conditions: + +Permission to use, copy, modify, and distribute this software and its +associated documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appears in all copies, +and that both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Secret Labs AB or the +author not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. + +SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR +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 THIS SOFTWARE. diff --git a/contrib/python/olefile/py3/olefile/__init__.py b/contrib/python/olefile/py3/olefile/__init__.py index 52247f3e01..72c91df7fa 100644 --- a/contrib/python/olefile/py3/olefile/__init__.py +++ b/contrib/python/olefile/py3/olefile/__init__.py @@ -4,11 +4,11 @@ olefile (formerly OleFileIO_PL) Module to read/write Microsoft OLE2 files (also called Structured Storage or Microsoft Compound Document File Format), such as Microsoft Office 97-2003 documents, Image Composer and FlashPix files, Outlook messages, ... -This version is compatible with Python 2.7 and 3.4+ +This version is compatible with Python 2.7 and 3.5+ Project website: https://www.decalage.info/olefile -olefile is copyright (c) 2005-2018 Philippe Lagadec (https://www.decalage.info) +olefile is copyright (c) 2005-2023 Philippe Lagadec (https://www.decalage.info) olefile is based on the OleFileIO module from the PIL library v1.1.7 See: http://www.pythonware.com/products/pil/index.htm diff --git a/contrib/python/olefile/py3/olefile/olefile.py b/contrib/python/olefile/py3/olefile/olefile.py index 1bfa2a6a65..60f8963c19 100644 --- a/contrib/python/olefile/py3/olefile/olefile.py +++ b/contrib/python/olefile/py3/olefile/olefile.py @@ -4,11 +4,11 @@ olefile (formerly OleFileIO_PL) Module to read/write Microsoft OLE2 files (also called Structured Storage or Microsoft Compound Document File Format), such as Microsoft Office 97-2003 documents, Image Composer and FlashPix files, Outlook messages, ... -This version is compatible with Python 2.7 and 3.4+ +This version is compatible with Python 2.7 and 3.5+ Project website: https://www.decalage.info/olefile -olefile is copyright (c) 2005-2018 Philippe Lagadec +olefile is copyright (c) 2005-2023 Philippe Lagadec (https://www.decalage.info) olefile is based on the OleFileIO module from the PIL library v1.1.7 @@ -22,16 +22,16 @@ Copyright (c) 1995-2009 by Fredrik Lundh See source code and LICENSE.txt for information on usage and redistribution. """ -# Since OleFileIO_PL v0.45, only Python 2.7 and 3.4+ are supported +# Since olefile v0.47, only Python 2.7 and 3.5+ are supported # This import enables print() as a function rather than a keyword # (main requirement to be compatible with Python 3.x) # The comment on the line below should be printed on Python 2.5 or older: -from __future__ import print_function # This version of olefile requires Python 2.7 or 3.4+. +from __future__ import print_function # This version of olefile requires Python 2.7 or 3.5+. #--- LICENSE ------------------------------------------------------------------ -# olefile (formerly OleFileIO_PL) is copyright (c) 2005-2018 Philippe Lagadec +# olefile (formerly OleFileIO_PL) is copyright (c) 2005-2023 Philippe Lagadec # (https://www.decalage.info) # # All rights reserved. @@ -86,23 +86,24 @@ from __future__ import print_function # This version of olefile requires Pytho # OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -__date__ = "2018-09-09" -__version__ = '0.46' +__date__ = "2023-12-01" +__version__ = '0.47' __author__ = "Philippe Lagadec" __all__ = ['isOleFile', 'OleFileIO', 'OleMetadata', 'enable_logging', - 'MAGIC', 'STGTY_EMPTY', 'KEEP_UNICODE_NAMES', + 'MAGIC', 'STGTY_EMPTY', 'STGTY_STREAM', 'STGTY_STORAGE', 'STGTY_ROOT', 'STGTY_PROPERTY', 'STGTY_LOCKBYTES', 'MINIMAL_OLEFILE_SIZE', 'DEFECT_UNSURE', 'DEFECT_POTENTIAL', 'DEFECT_INCORRECT', 'DEFECT_FATAL', 'DEFAULT_PATH_ENCODING', 'MAXREGSECT', 'DIFSECT', 'FATSECT', 'ENDOFCHAIN', 'FREESECT', - 'MAXREGSID', 'NOSTREAM', 'UNKNOWN_SIZE', 'WORD_CLSID' + 'MAXREGSID', 'NOSTREAM', 'UNKNOWN_SIZE', 'WORD_CLSID', + 'OleFileIONotClosed' ] import io import sys -import struct, array, os.path, datetime, logging +import struct, array, os.path, datetime, logging, warnings, traceback #=== COMPATIBILITY WORKAROUNDS ================================================ @@ -114,11 +115,11 @@ if str is not bytes: try: # on Python 2 we need xrange: iterrange = xrange -except: +except Exception: # no xrange, for Python 3 it was renamed as range: iterrange = range -#[PL] workaround to fix an issue with array item size on 64 bits systems: +# [PL] workaround to fix an issue with array item size on 64 bits systems: if array.array('L').itemsize == 4: # on 32 bits platforms, long integers in an array are 32 bits: UINT32 = 'L' @@ -142,17 +143,14 @@ else: raise ValueError('Need to fix a bug with 32 bit arrays, please contact author...') -#[PL] These workarounds were inspired from the Path module +# [PL] These workarounds were inspired from the Path module # (see http://www.jorendorff.com/articles/python/path/) +# TODO: remove the use of basestring, as it was removed in Python 3 try: basestring except NameError: basestring = str -#[PL] Experimental setting: if True, OLE filenames will be kept in Unicode -# if False (default PIL behaviour), all filenames are converted to Latin-1. -KEEP_UNICODE_NAMES = True - if sys.version_info[0] < 3: # On Python 2.x, the default encoding for path names is UTF-8: DEFAULT_PATH_ENCODING = 'utf-8' @@ -208,18 +206,18 @@ def enable_logging(): #: magic bytes that should be at the beginning of every OLE file: MAGIC = b'\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1' -#[PL]: added constants for Sector IDs (from AAF specifications) +# [PL]: added constants for Sector IDs (from AAF specifications) MAXREGSECT = 0xFFFFFFFA #: (-6) maximum SECT DIFSECT = 0xFFFFFFFC #: (-4) denotes a DIFAT sector in a FAT FATSECT = 0xFFFFFFFD #: (-3) denotes a FAT sector in a FAT ENDOFCHAIN = 0xFFFFFFFE #: (-2) end of a virtual stream chain FREESECT = 0xFFFFFFFF #: (-1) unallocated sector -#[PL]: added constants for Directory Entry IDs (from AAF specifications) +# [PL]: added constants for Directory Entry IDs (from AAF specifications) MAXREGSID = 0xFFFFFFFA #: (-6) maximum directory entry ID NOSTREAM = 0xFFFFFFFF #: (-1) unallocated directory entry -#[PL] object types in storage (from AAF specifications) +# [PL] object types in storage (from AAF specifications) STGTY_EMPTY = 0 #: empty directory entry STGTY_STORAGE = 1 #: element is a storage object STGTY_STREAM = 2 #: element is a stream object @@ -245,19 +243,19 @@ VT_STORED_OBJECT=69; VT_BLOB_OBJECT=70; VT_CF=71; VT_CLSID=72; VT_VECTOR=0x1000; # map property id to name (for debugging purposes) -# VT = {} -# for keyword, var in list(vars().items()): -# if keyword[:3] == "VT_": -# VT[var] = keyword +VT = {} +for keyword, var in list(vars().items()): + if keyword[:3] == "VT_": + VT[var] = keyword # # -------------------------------------------------------------------- # Some common document types (root.clsid fields) WORD_CLSID = "00020900-0000-0000-C000-000000000046" -#TODO: check Excel, PPT, ... +# TODO: check Excel, PPT, ... -#[PL]: Defect levels to classify parsing errors - see OleFileIO._raise_defect() +# [PL]: Defect levels to classify parsing errors - see OleFileIO._raise_defect() DEFECT_UNSURE = 10 # a case which looks weird, but not sure it's a defect DEFECT_POTENTIAL = 20 # a potential defect DEFECT_INCORRECT = 30 # an error according to specifications, but parsing @@ -266,37 +264,55 @@ DEFECT_FATAL = 40 # an error which cannot be ignored, parsing is # impossible # Minimal size of an empty OLE file, with 512-bytes sectors = 1536 bytes -# (this is used in isOleFile and OleFile.open) +# (this is used in isOleFile and OleFileIO.open) MINIMAL_OLEFILE_SIZE = 1536 - #=== FUNCTIONS =============================================================== -def isOleFile (filename): +def isOleFile (filename=None, data=None): """ Test if a file is an OLE container (according to the magic bytes in its header). .. note:: This function only checks the first 8 bytes of the file, not the rest of the OLE structure. + If data is provided, it also checks if the file size is above + the minimal size of an OLE file (1536 bytes). + If filename is provided with the path of the file on disk, the file is + open only to read the first 8 bytes, then closed. .. versionadded:: 0.16 :param filename: filename, contents or file-like object of the OLE file (string-like or file-like object) - - if filename is a string smaller than 1536 bytes, it is the path - of the file to open. (bytes or unicode string) - - if filename is a string longer than 1535 bytes, it is parsed + - if data is provided, filename is ignored. + - if filename is a unicode string, it is used as path of the file to open on disk. + - if filename is a bytes string smaller than 1536 bytes, it is used as path + of the file to open on disk. + - [deprecated] if filename is a bytes string longer than 1535 bytes, it is parsed as the content of an OLE file in memory. (bytes type only) + Note that this use case is deprecated and should be replaced by the new data parameter - if filename is a file-like object (with read and seek methods), it is parsed as-is. + :type filename: bytes, str, unicode or file-like object + + :param data: bytes string with the contents of the file to be checked, when the file is in memory + (added in olefile 0.47) + :type data: bytes - :type filename: bytes or str or unicode or file :returns: True if OLE, False otherwise. :rtype: bool """ + header = None + # first check if data is provided and large enough + if data is not None: + if len(data) >= MINIMAL_OLEFILE_SIZE: + header = data[:len(MAGIC)] + else: + # the file is too small, cannot be OLE + return False # check if filename is a string-like or file-like object: - if hasattr(filename, 'read'): + elif hasattr(filename, 'read') and hasattr(filename, 'seek'): # file-like object: use it directly header = filename.read(len(MAGIC)) # just in case, seek back to start of file: @@ -362,22 +378,34 @@ def _clsid(clsid): def filetime2datetime(filetime): - """ - convert FILETIME (64 bits int) to Python datetime.datetime - """ - # TODO: manage exception when microseconds is too large - # inspired from https://code.activestate.com/recipes/511425-filetime-to-datetime/ - _FILETIME_null_date = datetime.datetime(1601, 1, 1, 0, 0, 0) - #log.debug('timedelta days=%d' % (filetime//(10*1000000*3600*24))) - return _FILETIME_null_date + datetime.timedelta(microseconds=filetime//10) + """ + convert FILETIME (64 bits int) to Python datetime.datetime + """ + # TODO: manage exception when microseconds is too large + # inspired from https://code.activestate.com/recipes/511425-filetime-to-datetime/ + _FILETIME_null_date = datetime.datetime(1601, 1, 1, 0, 0, 0) + # log.debug('timedelta days=%d' % (filetime//(10*1000000*3600*24))) + return _FILETIME_null_date + datetime.timedelta(microseconds=filetime//10) #=== CLASSES ================================================================== +class OleFileError(IOError): + """ + Generic base error for this module. + """ + pass + +class NotOleFileError(OleFileError): + """ + Error raised when the opened file is not an OLE file. + """ + pass + class OleMetadata: """ - class to parse and store metadata from standard properties of OLE files. + Class to parse and store metadata from standard properties of OLE files. Available attributes: codepage, title, subject, author, keywords, comments, template, @@ -407,7 +435,7 @@ class OleMetadata: - https://msdn.microsoft.com/en-us/library/windows/desktop/aa380374%28v=vs.85%29.aspx - https://poi.apache.org/apidocs/org/apache/poi/hpsf/DocumentSummaryInformation.html - new in version 0.25 + New in version 0.25 """ # attribute names for SummaryInformation stream properties: @@ -482,33 +510,34 @@ class OleMetadata: self.language = None self.doc_version = None - - def parse_properties(self, olefile): + def parse_properties(self, ole_file): """ Parse standard properties of an OLE file, from the streams ``\\x05SummaryInformation`` and ``\\x05DocumentSummaryInformation``, if present. Properties are converted to strings, integers or python datetime objects. If a property is not present, its value is set to None. + + :param ole_file: OleFileIO object from which to parse properties """ # first set all attributes to None: for attrib in (self.SUMMARY_ATTRIBS + self.DOCSUM_ATTRIBS): setattr(self, attrib, None) - if olefile.exists("\x05SummaryInformation"): + if ole_file.exists("\x05SummaryInformation"): # get properties from the stream: # (converting timestamps to python datetime, except total_edit_time, # which is property #10) - props = olefile.getproperties("\x05SummaryInformation", - convert_time=True, no_conversion=[10]) + props = ole_file.getproperties("\x05SummaryInformation", + convert_time=True, no_conversion=[10]) # store them into this object's attributes: for i in range(len(self.SUMMARY_ATTRIBS)): # ids for standards properties start at 0x01, until 0x13 value = props.get(i+1, None) setattr(self, self.SUMMARY_ATTRIBS[i], value) - if olefile.exists("\x05DocumentSummaryInformation"): + if ole_file.exists("\x05DocumentSummaryInformation"): # get properties from the stream: - props = olefile.getproperties("\x05DocumentSummaryInformation", - convert_time=True) + props = ole_file.getproperties("\x05DocumentSummaryInformation", + convert_time=True) # store them into this object's attributes: for i in range(len(self.DOCSUM_ATTRIBS)): # ids for standards properties start at 0x01, until 0x13 @@ -522,14 +551,33 @@ class OleMetadata: print('Properties from SummaryInformation stream:') for prop in self.SUMMARY_ATTRIBS: value = getattr(self, prop) - print('- %s: %s' % (prop, repr(value))) + print('- {}: {}'.format(prop, repr(value))) print('Properties from DocumentSummaryInformation stream:') for prop in self.DOCSUM_ATTRIBS: value = getattr(self, prop) - print('- %s: %s' % (prop, repr(value))) + print('- {}: {}'.format(prop, repr(value))) +class OleFileIONotClosed(RuntimeWarning): + """ + Warning type used when OleFileIO is destructed but has open file handle. + """ + def __init__(self, stack_of_open=None): + super(OleFileIONotClosed, self).__init__() + self.stack_of_open = stack_of_open + + def __str__(self): + msg = 'Deleting OleFileIO instance with open file handle. ' \ + 'You should ensure that OleFileIO is never deleted ' \ + 'without calling close() first. Consider using '\ + '"with OleFileIO(...) as ole: ...".' + if self.stack_of_open: + return ''.join([msg, '\n', 'Stacktrace of open() call:\n'] + + self.stack_of_open.format()) + else: + return msg -#--- OleStream --------------------------------------------------------------- + +# --- OleStream --------------------------------------------------------------- class OleStream(io.BytesIO): """ @@ -537,7 +585,7 @@ class OleStream(io.BytesIO): Returns a read-only file object which can be used to read the contents of a OLE stream (instance of the BytesIO class). - To open a stream, use the openstream method in the OleFile class. + To open a stream, use the openstream method in the OleFileIO class. This function can be used with either ordinary streams, or ministreams, depending on the offset, sectorsize, and @@ -570,11 +618,11 @@ class OleStream(io.BytesIO): %(sect,sect,size,offset,sectorsize,len(fat), repr(fp))) self.ole = olefileio # this check is necessary, otherwise when attempting to open a stream - # from a closed OleFile, a stream of size zero is returned without + # from a closed OleFileIO, a stream of size zero is returned without # raising an exception. (see issue #81) if self.ole.fp.closed: raise OSError('Attempting to open a stream from a closed OLE File') - #[PL] To detect malformed documents with FAT loops, we compute the + # [PL] To detect malformed documents with FAT loops, we compute the # expected number of sectors in the stream: unknown_size = False if size == UNKNOWN_SIZE: @@ -599,7 +647,7 @@ class OleStream(io.BytesIO): if size == 0 and sect != ENDOFCHAIN: log.debug('size == 0 and sect != ENDOFCHAIN:') self.ole._raise_defect(DEFECT_INCORRECT, 'incorrect OLE sector index for empty stream') - #[PL] A fixed-length for loop is used instead of an undefined while + # [PL] A fixed-length for loop is used instead of an undefined while # loop to avoid DoS attacks: for i in range(nb_sectors): log.debug('Reading stream sector[%d] = %Xh' % (i, sect)) @@ -624,11 +672,11 @@ class OleStream(io.BytesIO): self.ole._raise_defect(DEFECT_INCORRECT, 'incorrect OLE FAT, sector index out of range') # stop reading here if the exception is ignored: break - #TODO: merge this code with OleFileIO.getsect() ? - #TODO: check if this works with 4K sectors: + # TODO: merge this code with OleFileIO.getsect() ? + # TODO: check if this works with 4K sectors: try: fp.seek(offset + sectorsize * sect) - except: + except Exception: log.debug('sect=%d, seek=%d, filesize=%d' % (sect, offset+sectorsize*sect, filesize)) self.ole._raise_defect(DEFECT_INCORRECT, 'OLE sector index out of range') @@ -653,7 +701,7 @@ class OleStream(io.BytesIO): self.ole._raise_defect(DEFECT_INCORRECT, 'incorrect OLE FAT, sector index out of range') # stop reading here if the exception is ignored: break - #[PL] Last sector should be a "end of chain" marker: + # [PL] Last sector should be a "end of chain" marker: # if sect != ENDOFCHAIN: # raise IOError('incorrect last sector index in OLE stream') data = b"".join(data) @@ -679,15 +727,12 @@ class OleStream(io.BytesIO): # Then the OleStream object can be used as a read-only file object. -#--- OleDirectoryEntry ------------------------------------------------------- +# --- OleDirectoryEntry ------------------------------------------------------- class OleDirectoryEntry: - """ - OLE2 Directory Entry + OLE2 Directory Entry pointing to a stream or a storage """ - #[PL] parsing code moved from OleFileIO.loaddirectory - # struct to parse directory entries: # <: little-endian byte order, standard sizes # (note: this should guarantee that Q returns a 64 bits int) @@ -711,19 +756,18 @@ class OleDirectoryEntry: DIRENTRY_SIZE = 128 assert struct.calcsize(STRUCT_DIRENTRY) == DIRENTRY_SIZE - - def __init__(self, entry, sid, olefile): + def __init__(self, entry, sid, ole_file): """ Constructor for an OleDirectoryEntry object. Parses a 128-bytes entry from the OLE Directory stream. - :param entry : string (must be 128 bytes long) - :param sid : index of this directory entry in the OLE file directory - :param olefile: OleFileIO containing this directory entry + :param bytes entry: bytes string (must be 128 bytes long) + :param int sid: index of this directory entry in the OLE file directory + :param OleFileIO ole_file: OleFileIO object containing this directory entry """ self.sid = sid - # ref to olefile is stored for future use - self.olefile = olefile + # ref to ole_file is stored for future use + self.olefile = ole_file # kids is a list of children entries, if this entry is a storage: # (list of OleDirectoryEntry objects) self.kids = [] @@ -752,26 +796,26 @@ class OleDirectoryEntry: self.sizeHigh ) = struct.unpack(OleDirectoryEntry.STRUCT_DIRENTRY, entry) if self.entry_type not in [STGTY_ROOT, STGTY_STORAGE, STGTY_STREAM, STGTY_EMPTY]: - olefile._raise_defect(DEFECT_INCORRECT, 'unhandled OLE storage type') + ole_file._raise_defect(DEFECT_INCORRECT, 'unhandled OLE storage type') # only first directory entry can (and should) be root: if self.entry_type == STGTY_ROOT and sid != 0: - olefile._raise_defect(DEFECT_INCORRECT, 'duplicate OLE root entry') + ole_file._raise_defect(DEFECT_INCORRECT, 'duplicate OLE root entry') if sid == 0 and self.entry_type != STGTY_ROOT: - olefile._raise_defect(DEFECT_INCORRECT, 'incorrect OLE root entry') - #log.debug(struct.unpack(fmt_entry, entry[:len_entry])) + ole_file._raise_defect(DEFECT_INCORRECT, 'incorrect OLE root entry') + # log.debug(struct.unpack(fmt_entry, entry[:len_entry])) # name should be at most 31 unicode characters + null character, # so 64 bytes in total (31*2 + 2): - if self.namelength>64: - olefile._raise_defect(DEFECT_INCORRECT, 'incorrect DirEntry name length >64 bytes') + if self.namelength > 64: + ole_file._raise_defect(DEFECT_INCORRECT, 'incorrect DirEntry name length >64 bytes') # if exception not raised, namelength is set to the maximum value: self.namelength = 64 # only characters without ending null char are kept: self.name_utf16 = self.name_raw[:(self.namelength-2)] - #TODO: check if the name is actually followed by a null unicode character ([MS-CFB] 2.6.1) - #TODO: check if the name does not contain forbidden characters: + # TODO: check if the name is actually followed by a null unicode character ([MS-CFB] 2.6.1) + # TODO: check if the name does not contain forbidden characters: # [MS-CFB] 2.6.1: "The following characters are illegal and MUST NOT be part of the name: '/', '\', ':', '!'." # name is converted from UTF-16LE to the path encoding specified in the OleFileIO: - self.name = olefile._decode_utf16_str(self.name_utf16) + self.name = ole_file._decode_utf16_str(self.name_utf16) log.debug('DirEntry SID=%d: %s' % (self.sid, repr(self.name))) log.debug(' - type: %d' % self.entry_type) @@ -782,11 +826,11 @@ class OleDirectoryEntry: # sizeHigh is only used for 4K sectors, it should be zero for 512 bytes # sectors, BUT apparently some implementations set it as 0xFFFFFFFF, 1 # or some other value so it cannot be raised as a defect in general: - if olefile.sectorsize == 512: + if ole_file.sectorsize == 512: if self.sizeHigh != 0 and self.sizeHigh != 0xFFFFFFFF: log.debug('sectorsize=%d, sizeLow=%d, sizeHigh=%d (%X)' % - (olefile.sectorsize, self.sizeLow, self.sizeHigh, self.sizeHigh)) - olefile._raise_defect(DEFECT_UNSURE, 'incorrect OLE stream size') + (ole_file.sectorsize, self.sizeLow, self.sizeHigh, self.sizeHigh)) + ole_file._raise_defect(DEFECT_UNSURE, 'incorrect OLE stream size') self.size = self.sizeLow else: self.size = self.sizeLow + (long(self.sizeHigh)<<32) @@ -796,21 +840,28 @@ class OleDirectoryEntry: # a storage should have a null size, BUT some implementations such as # Word 8 for Mac seem to allow non-null values => Potential defect: if self.entry_type == STGTY_STORAGE and self.size != 0: - olefile._raise_defect(DEFECT_POTENTIAL, 'OLE storage with size>0') + ole_file._raise_defect(DEFECT_POTENTIAL, 'OLE storage with size>0') # check if stream is not already referenced elsewhere: self.is_minifat = False if self.entry_type in (STGTY_ROOT, STGTY_STREAM) and self.size>0: - if self.size < olefile.minisectorcutoff \ + if self.size < ole_file.minisectorcutoff \ and self.entry_type==STGTY_STREAM: # only streams can be in MiniFAT # ministream object self.is_minifat = True else: self.is_minifat = False - olefile._check_duplicate_stream(self.isectStart, self.is_minifat) + ole_file._check_duplicate_stream(self.isectStart, self.is_minifat) self.sect_chain = None + def build_sect_chain(self, ole_file): + """ + Build the sector chain for a stream (from the FAT or the MiniFAT) - def build_sect_chain(self, olefile): + :param OleFileIO ole_file: OleFileIO object containing this directory entry + :return: nothing + """ + # TODO: seems to be used only from _write_mini_stream, is it useful? + # TODO: use self.olefile instead of ole_file if self.sect_chain: return if self.entry_type not in (STGTY_ROOT, STGTY_STREAM) or self.size == 0: @@ -818,16 +869,16 @@ class OleDirectoryEntry: self.sect_chain = list() - if self.is_minifat and not olefile.minifat: - olefile.loadminifat() + if self.is_minifat and not ole_file.minifat: + ole_file.loadminifat() next_sect = self.isectStart while next_sect != ENDOFCHAIN: self.sect_chain.append(next_sect) if self.is_minifat: - next_sect = olefile.minifat[next_sect] + next_sect = ole_file.minifat[next_sect] else: - next_sect = olefile.fat[next_sect] + next_sect = ole_file.fat[next_sect] def build_storage_tree(self): """ @@ -852,7 +903,6 @@ class OleDirectoryEntry: # (see rich comparison methods in this class) self.kids.sort() - def append_kids(self, child_sid): """ Walk through red-black tree of children of this directory entry to add @@ -862,7 +912,7 @@ class OleDirectoryEntry: first time for the root. (only used during recursion) """ log.debug('append_kids: child_sid=%d' % child_sid) - #[PL] this method was added to use simple recursion instead of a complex + # [PL] this method was added to use simple recursion instead of a complex # algorithm. # if this is not a storage or a leaf of the tree, nothing to do: if child_sid == NOSTREAM: @@ -899,7 +949,6 @@ class OleDirectoryEntry: # Afterwards build kid's own tree if it's also a storage: child.build_storage_tree() - def __eq__(self, other): "Compare entries by name" return self.name == other.name @@ -916,10 +965,9 @@ class OleDirectoryEntry: # Reflected __lt__() and __le__() will be used for __gt__() and __ge__() - #TODO: replace by the same function as MS implementation ? + # TODO: replace by the same function as MS implementation ? # (order by name length first, then case-insensitive order) - def dump(self, tab = 0): "Dump this entry, and all its subentries (for debug purposes only)" TYPES = ["(invalid)", "(storage)", "(stream)", "(lockbytes)", @@ -938,7 +986,6 @@ class OleDirectoryEntry: for kid in self.kids: kid.dump(tab + 2) - def getmtime(self): """ Return modification time of a directory entry. @@ -981,17 +1028,17 @@ class OleFileIO: level. The root entry should be omitted. For example, the following code extracts all image streams from a Microsoft Image Composer file:: - ole = OleFileIO("fan.mic") + with OleFileIO("fan.mic") as ole: - for entry in ole.listdir(): - if entry[1:2] == "Image": - fin = ole.openstream(entry) - fout = open(entry[0:1], "wb") - while True: - s = fin.read(8192) - if not s: - break - fout.write(s) + for entry in ole.listdir(): + if entry[1:2] == "Image": + fin = ole.openstream(entry) + fout = open(entry[0:1], "wb") + while True: + s = fin.read(8192) + if not s: + break + fout.write(s) You can use the viewer application provided with the Python Imaging Library to view the resulting files (which happens to be standard @@ -1010,7 +1057,7 @@ class OleFileIO: - if filename is a string longer than 1535 bytes, it is parsed as the content of an OLE file in memory. (bytes type only) - if filename is a file-like object (with read, seek and tell methods), - it is parsed as-is. + it is parsed as-is. The caller is responsible for closing it when done. :param raise_defects: minimal level for defects to be raised as exceptions. (use DEFECT_FATAL for a typical application, DEFECT_INCORRECT for a @@ -1071,8 +1118,22 @@ class OleFileIO: self.sector_shift = None self.sector_size = None self.transaction_signature_number = None + self.warn_if_not_closed = False + self._we_opened_fp = False + self._open_stack = None if filename: - self.open(filename, write_mode=write_mode) + # try opening, ensure fp is closed if that fails + try: + self.open(filename, write_mode=write_mode) + except Exception: + # caller has no chance of calling close() now + self._close(warn=False) + raise + + def __del__(self): + """Destructor, ensures all file handles are closed that we opened.""" + self._close(warn=True) + # super(OleFileIO, self).__del__() # there's no super-class destructor def __enter__(self): @@ -1080,13 +1141,13 @@ class OleFileIO: def __exit__(self, *args): - self.close() + self._close(warn=False) - def _raise_defect(self, defect_level, message, exception_type=IOError): + def _raise_defect(self, defect_level, message, exception_type=OleFileError): """ This method should be called for any defect found during file parsing. - It may raise an IOError exception according to the minimal level chosen + It may raise an OleFileError exception according to the minimal level chosen for the OleFileIO object. :param defect_level: defect level, possible values are: @@ -1097,7 +1158,7 @@ class OleFileIO: - DEFECT_FATAL : an error which cannot be ignored, parsing is impossible :param message: string describing the defect, used with raised exception. - :param exception_type: exception class to be raised, IOError by default + :param exception_type: exception class to be raised, OleFileError by default """ # added by [PL] if defect_level >= self._raise_defects_level: @@ -1115,9 +1176,10 @@ class OleFileIO: directory or in property streams. Return a string encoded according to the path_encoding specified for the OleFileIO object. - :param utf16_str: bytes string encoded in UTF-16 LE format - :param errors: str, see python documentation for str.decode() + :param bytes utf16_str: bytes string encoded in UTF-16 LE format + :param str errors: str, see python documentation for str.decode() :return: str, encoded according to path_encoding + :rtype: str """ unicode_str = utf16_str.decode('UTF-16LE', errors) if self.path_encoding: @@ -1140,16 +1202,16 @@ class OleFileIO: - if filename is a string longer than 1535 bytes, it is parsed as the content of an OLE file in memory. (bytes type only) - if filename is a file-like object (with read, seek and tell methods), - it is parsed as-is. + it is parsed as-is. The caller is responsible for closing it when done :param write_mode: bool, if True the file is opened in read/write mode instead of read-only by default. (ignored if filename is not a path) """ self.write_mode = write_mode - #[PL] check if filename is a string-like or file-like object: + # [PL] check if filename is a string-like or file-like object: # (it is better to check for a read() method) if hasattr(filename, 'read'): - #TODO: also check seek and tell methods? + # TODO: also check seek and tell methods? # file-like object: use it directly self.fp = filename elif isinstance(filename, bytes) and len(filename) >= MINIMAL_OLEFILE_SIZE: @@ -1160,18 +1222,20 @@ class OleFileIO: # string-like object: filename of file on disk if self.write_mode: # open file in mode 'read with update, binary' - # According to https://docs.python.org/2/library/functions.html#open + # According to https://docs.python.org/library/functions.html#open # 'w' would truncate the file, 'a' may only append on some Unixes mode = 'r+b' else: # read-only mode by default mode = 'rb' self.fp = open(filename, mode) + self._we_opened_fp = True + self._open_stack = traceback.extract_stack() # remember for warning # obtain the filesize by using seek and tell, which should work on most # file-like objects: - #TODO: do it above, using getsize with filename when possible? - #TODO: fix code to fail with clear exception when filesize cannot be obtained - filesize=0 + # TODO: do it above, using getsize with filename when possible? + # TODO: fix code to fail with clear exception when filesize cannot be obtained + filesize = 0 self.fp.seek(0, os.SEEK_END) try: filesize = self.fp.tell() @@ -1188,8 +1252,8 @@ class OleFileIO: header = self.fp.read(512) if len(header) != 512 or header[:8] != MAGIC: - log.debug('Magic = %r instead of %r' % (header[:8], MAGIC)) - self._raise_defect(DEFECT_FATAL, "not an OLE2 structured storage file") + log.debug('Magic = {!r} instead of {!r}'.format(header[:8], MAGIC)) + self._raise_defect(DEFECT_FATAL, "not an OLE2 structured storage file", NotOleFileError) # [PL] header structure according to AAF specifications: ##Header @@ -1323,13 +1387,13 @@ class OleFileIO: # (-1 because header doesn't count) self.nb_sect = ( (filesize + self.sector_size-1) // self.sector_size) - 1 log.debug( "Maximum number of sectors in the file: %d (%Xh)" % (self.nb_sect, self.nb_sect)) - #TODO: change this test, because an OLE file MAY contain other data + # TODO: change this test, because an OLE file MAY contain other data # after the last sector. # file clsid self.header_clsid = _clsid(header[8:24]) - #TODO: remove redundant attributes, and fix the code which uses them? + # TODO: remove redundant attributes, and fix the code which uses them? self.sectorsize = self.sector_size #1 << i16(header, 30) self.minisectorsize = self.mini_sector_size #1 << i16(header, 32) self.minisectorcutoff = self.mini_stream_cutoff_size # i32(header, 56) @@ -1351,13 +1415,23 @@ class OleFileIO: self.loaddirectory(self.first_dir_sector) self.minifatsect = self.first_mini_fat_sector - def close(self): """ - close the OLE file, to release the file object + close the OLE file, release the file object if we created it ourselves. + + Leaves the file handle open if it was provided by the caller. """ - self.fp.close() + self._close(warn=False) + def _close(self, warn=False): + """Implementation of close() with internal arg `warn`.""" + if self._we_opened_fp: + if warn and self.warn_if_not_closed: + # we only raise a warning if the file was not explicitly closed, + # and if the option warn_if_not_closed is enabled + warnings.warn(OleFileIONotClosed(self._open_stack)) + self.fp.close() + self._we_opened_fp = False def _check_duplicate_stream(self, first_sect, minifat=False): """ @@ -1377,14 +1451,13 @@ class OleFileIO: if first_sect in (DIFSECT,FATSECT,ENDOFCHAIN,FREESECT): return used_streams = self._used_streams_fat - #TODO: would it be more efficient using a dict or hash values, instead + # TODO: would it be more efficient using a dict or hash values, instead # of a list of long ? if first_sect in used_streams: self._raise_defect(DEFECT_INCORRECT, 'Stream referenced twice') else: used_streams.append(first_sect) - def dumpfat(self, fat, firstindex=0): """ Display a part of FAT in human-readable form for debugging purposes @@ -1421,7 +1494,6 @@ class OleFileIO: print(name, end=" ") print() - def dumpsect(self, sector, firstindex=0): """ Display a sector in a human-readable form, for debugging purposes @@ -1452,13 +1524,13 @@ class OleFileIO: convert a sector to an array of 32 bits unsigned integers, swapping bytes on big endian CPUs such as PowerPC (old Macs) """ + # TODO: make this a static function a = array.array(UINT32, sect) # if CPU is big endian, swap bytes: if sys.byteorder == 'big': a.byteswap() return a - def loadfat_sect(self, sect): """ Adds the indexes of the given sector to the FAT @@ -1494,7 +1566,6 @@ class OleFileIO: self.fat = self.fat + nextfat return isect - def loadfat(self, header): """ Load the FAT table. @@ -1507,21 +1578,21 @@ class OleFileIO: log.debug('Loading the FAT table, starting with the 1st sector after the header') sect = header[76:512] log.debug( "len(sect)=%d, so %d integers" % (len(sect), len(sect)//4) ) - #fat = [] - # [PL] FAT is an array of 32 bits unsigned ints, it's more effective + # fat = [] + # FAT is an array of 32 bits unsigned ints, it's more effective # to use an array than a list in Python. # It's initialized as empty first: self.fat = array.array(UINT32) self.loadfat_sect(sect) - #self.dumpfat(self.fat) -## for i in range(0, len(sect), 4): -## ix = i32(sect, i) -## #[PL] if ix == -2 or ix == -1: # ix == 0xFFFFFFFE or ix == 0xFFFFFFFF: -## if ix == 0xFFFFFFFE or ix == 0xFFFFFFFF: -## break -## s = self.getsect(ix) -## #fat = fat + [i32(s, i) for i in range(0, len(s), 4)] -## fat = fat + array.array(UINT32, s) + # self.dumpfat(self.fat) + # for i in range(0, len(sect), 4): + # ix = i32(sect, i) + # # [PL] if ix == -2 or ix == -1: # ix == 0xFFFFFFFE or ix == 0xFFFFFFFF: + # if ix == 0xFFFFFFFE or ix == 0xFFFFFFFF: + # break + # s = self.getsect(ix) + # # fat = fat + [i32(s, i) for i in range(0, len(s), 4)] + # fat = fat + array.array(UINT32, s) if self.num_difat_sectors != 0: log.debug('DIFAT is used, because file size > 6.8MB.') # [PL] There's a DIFAT because file is larger than 6.8MB @@ -1546,7 +1617,7 @@ class OleFileIO: isect_difat = self.first_difat_sector for i in iterrange(nb_difat): log.debug( "DIFAT block %d, sector %X" % (i, isect_difat) ) - #TODO: check if corresponding FAT SID = DIFSECT + # TODO: check if corresponding FAT SID = DIFSECT sector_difat = self.getsect(isect_difat) difat = self.sect2array(sector_difat) # Display the sector contents only if the logging level is debug: @@ -1560,10 +1631,10 @@ class OleFileIO: if isect_difat not in [ENDOFCHAIN, FREESECT]: # last DIFAT pointer value must be ENDOFCHAIN or FREESECT raise IOError('incorrect end of DIFAT') -## if len(self.fat) != self.num_fat_sectors: -## # FAT should contain num_fat_sectors blocks -## print("FAT length: %d instead of %d" % (len(self.fat), self.num_fat_sectors)) -## raise IOError('incorrect DIFAT') + # if len(self.fat) != self.num_fat_sectors: + # # FAT should contain num_fat_sectors blocks + # print("FAT length: %d instead of %d" % (len(self.fat), self.num_fat_sectors)) + # raise IOError('incorrect DIFAT') else: log.debug('No DIFAT, because file size < 6.8MB.') # since FAT is read from fixed-size sectors, it may contain more values @@ -1578,7 +1649,6 @@ class OleFileIO: log.debug('\nFAT:') self.dumpfat(self.fat) - def loadminifat(self): """ Load the MiniFAT table. @@ -1603,7 +1673,7 @@ class OleFileIO: self._raise_defect(DEFECT_INCORRECT, 'OLE MiniStream is larger than MiniFAT') # In any case, first read stream_size: s = self._open(self.minifatsect, stream_size, force_FAT=True).read() - #[PL] Old code replaced by an array: + # [PL] Old code replaced by an array: #self.minifat = [i32(s, i) for i in range(0, len(s), 4)] self.minifat = self.sect2array(s) # Then shrink the array to used size, to avoid indexes out of MiniStream: @@ -1631,11 +1701,11 @@ class OleFileIO: # [PL] the original code in PIL was wrong when sectors are 4KB instead of # 512 bytes: #self.fp.seek(512 + self.sectorsize * sect) - #[PL]: added safety checks: + # [PL]: added safety checks: #print("getsect(%X)" % sect) try: self.fp.seek(self.sectorsize * (sect+1)) - except: + except Exception: log.debug('getsect(): sect=%X, seek=%d, filesize=%d' % (sect, self.sectorsize*(sect+1), self._filesize)) self._raise_defect(DEFECT_FATAL, 'OLE sector index out of range') @@ -1646,7 +1716,6 @@ class OleFileIO: self._raise_defect(DEFECT_FATAL, 'incomplete OLE sector') return sector - def write_sect(self, sect, data, padding=b'\x00'): """ Write given sector to file on disk. @@ -1659,17 +1728,17 @@ class OleFileIO: raise TypeError("write_sect: data must be a bytes string") if not isinstance(padding, bytes) or len(padding)!=1: raise TypeError("write_sect: padding must be a bytes string of 1 char") - #TODO: we could allow padding=None for no padding at all + # TODO: we could allow padding=None for no padding at all try: self.fp.seek(self.sectorsize * (sect+1)) - except: + except Exception: log.debug('write_sect(): sect=%X, seek=%d, filesize=%d' % (sect, self.sectorsize*(sect+1), self._filesize)) self._raise_defect(DEFECT_FATAL, 'OLE sector index out of range') if len(data) < self.sectorsize: # add padding data += padding * (self.sectorsize - len(data)) - elif len(data) < self.sectorsize: + elif len(data) > self.sectorsize: raise ValueError("Data is larger than sector size") self.fp.write(data) @@ -1688,7 +1757,7 @@ class OleFileIO: try: self.fp.seek(fp_pos) - except: + except Exception: log.debug('write_mini_sect(): fp_pos=%d, filesize=%d' % (fp_pos, self._filesize)) self._raise_defect(DEFECT_FATAL, 'OLE sector index out of range') @@ -1713,21 +1782,21 @@ class OleFileIO: # (stream size is not known in advance) self.directory_fp = self._open(sect, force_FAT=True) - #[PL] to detect malformed documents and avoid DoS attacks, the maximum + # [PL] to detect malformed documents and avoid DoS attacks, the maximum # number of directory entries can be calculated: max_entries = self.directory_fp.size // 128 log.debug('loaddirectory: size=%d, max_entries=%d' % (self.directory_fp.size, max_entries)) # Create list of directory entries - #self.direntries = [] + # self.direntries = [] # We start with a list of "None" object self.direntries = [None] * max_entries -## for sid in iterrange(max_entries): -## entry = fp.read(128) -## if not entry: -## break -## self.direntries.append(OleDirectoryEntry(entry, sid, self)) + # for sid in iterrange(max_entries): + # entry = fp.read(128) + # if not entry: + # break + # self.direntries.append(OleDirectoryEntry(entry, sid, self)) # load root entry: root_entry = self._load_direntry(0) # Root entry is the first entry: @@ -1739,7 +1808,6 @@ class OleFileIO: # read and build all storage trees, starting from the root: self.root.build_storage_tree() - def _load_direntry (self, sid): """ Load a directory entry from the directory. @@ -1749,7 +1817,7 @@ class OleFileIO: :param sid: index of storage/stream in the directory. :returns: a OleDirectoryEntry object - :exception IOError: if the entry has always been referenced. + :exception OleFileError: if the entry has always been referenced. """ # check if SID is OK: if sid<0 or sid>=len(self.direntries): @@ -1765,14 +1833,12 @@ class OleFileIO: self.direntries[sid] = OleDirectoryEntry(entry, sid, self) return self.direntries[sid] - def dumpdirectory(self): """ Dump directory (for debugging only) """ self.root.dump() - def _open(self, start, size = UNKNOWN_SIZE, force_FAT=False): """ Open a stream, either in FAT or MiniFAT according to its size. @@ -1810,7 +1876,6 @@ class OleFileIO: filesize=self._filesize, olefileio=self) - def _list(self, files, prefix, node, streams=True, storages=False): """ listdir helper @@ -1839,7 +1904,6 @@ class OleFileIO: else: self._raise_defect(DEFECT_INCORRECT, 'The directory tree contains an entry which is not a stream nor a storage.') - def listdir(self, streams=True, storages=False): """ Return a list of streams and/or storages stored in this file @@ -1853,7 +1917,6 @@ class OleFileIO: self._list(files, [], self.root, streams, storages) return files - def _find(self, filename): """ Returns directory entry of given filename. (openstream helper) @@ -1885,7 +1948,6 @@ class OleFileIO: node = kid return node.sid - def openstream(self, filename): """ Open a stream as a read-only file object (BytesIO). @@ -1957,36 +2019,35 @@ class OleFileIO: nb_sectors = (size + (self.sectorsize-1)) // self.sectorsize log.debug('nb_sectors = %d' % nb_sectors) for i in range(nb_sectors): -## try: -## self.fp.seek(offset + self.sectorsize * sect) -## except: -## log.debug('sect=%d, seek=%d' % -## (sect, offset+self.sectorsize*sect)) -## raise IOError('OLE sector index out of range') + # try: + # self.fp.seek(offset + self.sectorsize * sect) + # except Exception: + # log.debug('sect=%d, seek=%d' % + # (sect, offset+self.sectorsize*sect)) + # raise IOError('OLE sector index out of range') # extract one sector from data, the last one being smaller: if i<(nb_sectors-1): data_sector = data [i*self.sectorsize : (i+1)*self.sectorsize] - #TODO: comment this if it works + # TODO: comment this if it works assert(len(data_sector)==self.sectorsize) else: data_sector = data [i*self.sectorsize:] - #TODO: comment this if it works + # TODO: comment this if it works log.debug('write_stream: size=%d sectorsize=%d data_sector=%Xh size%%sectorsize=%d' % (size, self.sectorsize, len(data_sector), size % self.sectorsize)) assert(len(data_sector) % self.sectorsize==size % self.sectorsize) self.write_sect(sect, data_sector) -## self.fp.write(data_sector) + # self.fp.write(data_sector) # jump to next sector in the FAT: try: sect = self.fat[sect] except IndexError: # [PL] if pointer is out of the FAT an exception is raised raise IOError('incorrect OLE FAT, sector index out of range') - #[PL] Last sector should be a "end of chain" marker: + # [PL] Last sector should be a "end of chain" marker: if sect != ENDOFCHAIN: raise IOError('incorrect last sector index in OLE stream') - def get_type(self, filename): """ Test if given filename exists as a stream or a storage in the OLE @@ -2003,10 +2064,9 @@ class OleFileIO: sid = self._find(filename) entry = self.direntries[sid] return entry.entry_type - except: + except Exception: return False - def getclsid(self, filename): """ Return clsid of a stream/storage. @@ -2021,7 +2081,6 @@ class OleFileIO: entry = self.direntries[sid] return entry.clsid - def getmtime(self, filename): """ Return modification time of a stream/storage. @@ -2037,7 +2096,6 @@ class OleFileIO: entry = self.direntries[sid] return entry.getmtime() - def getctime(self, filename): """ Return creation time of a stream/storage. @@ -2053,7 +2111,6 @@ class OleFileIO: entry = self.direntries[sid] return entry.getctime() - def exists(self, filename): """ Test if given filename exists as a stream or a storage in the OLE @@ -2066,10 +2123,9 @@ class OleFileIO: try: sid = self._find(filename) return True - except: + except Exception: return False - def get_size(self, filename): """ Return size of a stream in the OLE container, in bytes. @@ -2082,11 +2138,10 @@ class OleFileIO: sid = self._find(filename) entry = self.direntries[sid] if entry.entry_type != STGTY_STREAM: - #TODO: Should it return zero instead of raising an exception ? + # TODO: Should it return zero instead of raising an exception ? raise TypeError('object is not an OLE stream') return entry.size - def get_rootentry_name(self): """ Return root entry name. Should usually be 'Root Entry' or 'R' in most @@ -2094,7 +2149,6 @@ class OleFileIO: """ return self.root.name - def getproperties(self, filename, convert_time=False, no_conversion=None): """ Return properties described in substream. @@ -2114,21 +2168,16 @@ class OleFileIO: streampath = filename if not isinstance(streampath, str): streampath = '/'.join(streampath) - fp = self.openstream(filename) - data = {} - try: # header s = fp.read(28) clsid = _clsid(s[8:24]) - # format id s = fp.read(20) fmtid = _clsid(s[:16]) fp.seek(i32(s, 16)) - # get section s = b"****" + fp.read(i32(fp.read(4))-4) # number of properties: @@ -2137,14 +2186,12 @@ class OleFileIO: # catch exception while parsing property header, and only raise # a DEFECT_INCORRECT then return an empty dict, because this is not # a fatal error when parsing the whole file - msg = 'Error while parsing properties header in stream %s: %s' % ( + msg = 'Error while parsing properties header in stream {}: {}'.format( repr(streampath), exc) self._raise_defect(DEFECT_INCORRECT, msg, type(exc)) return data - # clamp num_props based on the data length num_props = min(num_props, int(len(s) / 8)) - for i in iterrange(num_props): property_id = 0 # just in case of an exception try: @@ -2152,91 +2199,10 @@ class OleFileIO: offset = i32(s, 12+i*8) property_type = i32(s, offset) - log.debug('property id=%d: type=%d offset=%X' % (property_id, property_type, offset)) - - # test for common types first (should perhaps use - # a dictionary instead?) - - if property_type == VT_I2: # 16-bit signed integer - value = i16(s, offset+4) - if value >= 32768: - value = value - 65536 - elif property_type == VT_UI2: # 2-byte unsigned integer - value = i16(s, offset+4) - elif property_type in (VT_I4, VT_INT, VT_ERROR): - # VT_I4: 32-bit signed integer - # VT_ERROR: HRESULT, similar to 32-bit signed integer, - # see https://msdn.microsoft.com/en-us/library/cc230330.aspx - value = i32(s, offset+4) - elif property_type in (VT_UI4, VT_UINT): # 4-byte unsigned integer - value = i32(s, offset+4) # FIXME - elif property_type in (VT_BSTR, VT_LPSTR): - # CodePageString, see https://msdn.microsoft.com/en-us/library/dd942354.aspx - # size is a 32 bits integer, including the null terminator, and - # possibly trailing or embedded null chars - #TODO: if codepage is unicode, the string should be converted as such - count = i32(s, offset+4) - value = s[offset+8:offset+8+count-1] - # remove all null chars: - value = value.replace(b'\x00', b'') - elif property_type == VT_BLOB: - # binary large object (BLOB) - # see https://msdn.microsoft.com/en-us/library/dd942282.aspx - count = i32(s, offset+4) - value = s[offset+8:offset+8+count] - elif property_type == VT_LPWSTR: - # UnicodeString - # see https://msdn.microsoft.com/en-us/library/dd942313.aspx - # "the string should NOT contain embedded or additional trailing - # null characters." - count = i32(s, offset+4) - value = self._decode_utf16_str(s[offset+8:offset+8+count*2]) - elif property_type == VT_FILETIME: - value = long(i32(s, offset+4)) + (long(i32(s, offset+8))<<32) - # FILETIME is a 64-bit int: "number of 100ns periods - # since Jan 1,1601". - if convert_time and property_id not in no_conversion: - log.debug('Converting property #%d to python datetime, value=%d=%fs' - %(property_id, value, float(value)/10000000)) - # convert FILETIME to Python datetime.datetime - # inspired from https://code.activestate.com/recipes/511425-filetime-to-datetime/ - _FILETIME_null_date = datetime.datetime(1601, 1, 1, 0, 0, 0) - log.debug('timedelta days=%d' % (value//(10*1000000*3600*24))) - value = _FILETIME_null_date + datetime.timedelta(microseconds=value//10) - else: - # legacy code kept for backward compatibility: returns a - # number of seconds since Jan 1,1601 - value = value // 10000000 # seconds - elif property_type == VT_UI1: # 1-byte unsigned integer - value = i8(s[offset+4]) - elif property_type == VT_CLSID: - value = _clsid(s[offset+4:offset+20]) - elif property_type == VT_CF: - # PropertyIdentifier or ClipboardData?? - # see https://msdn.microsoft.com/en-us/library/dd941945.aspx - count = i32(s, offset+4) - value = s[offset+8:offset+8+count] - elif property_type == VT_BOOL: - # VARIANT_BOOL, 16 bits bool, 0x0000=Fals, 0xFFFF=True - # see https://msdn.microsoft.com/en-us/library/cc237864.aspx - value = bool(i16(s, offset+4)) - else: - value = None # everything else yields "None" - log.debug('property id=%d: type=%d not implemented in parser yet' % (property_id, property_type)) - - # missing: VT_EMPTY, VT_NULL, VT_R4, VT_R8, VT_CY, VT_DATE, - # VT_DECIMAL, VT_I1, VT_I8, VT_UI8, - # see https://msdn.microsoft.com/en-us/library/dd942033.aspx - - # FIXME: add support for VT_VECTOR - # VT_VECTOR is a 32 uint giving the number of items, followed by - # the items in sequence. The VT_VECTOR value is combined with the - # type of items, e.g. VT_VECTOR|VT_BSTR - # see https://msdn.microsoft.com/en-us/library/dd942011.aspx - - #print("%08x" % property_id, repr(value), end=" ") - #print("(%s)" % VT[i32(s, offset) & 0xFFF]) + vt_name = VT.get(property_type, 'UNKNOWN') + log.debug('property id=%d: type=%d/%s offset=%X' % (property_id, property_type, vt_name, offset)) + value = self._parse_property(s, offset+4, property_id, property_type, convert_time, no_conversion) data[property_id] = value except BaseException as exc: # catch exception while parsing each property, and only raise @@ -2247,6 +2213,131 @@ class OleFileIO: return data + def _parse_property(self, s, offset, property_id, property_type, convert_time, no_conversion): + v = None + if property_type <= VT_BLOB or property_type in (VT_CLSID, VT_CF): + v, _ = self._parse_property_basic(s, offset, property_id, property_type, convert_time, no_conversion) + elif property_type == VT_VECTOR | VT_VARIANT: + log.debug('property_type == VT_VECTOR | VT_VARIANT') + off = 4 + count = i32(s, offset) + values = [] + for _ in range(count): + property_type = i32(s, offset + off) + v, sz = self._parse_property_basic(s, offset + off + 4, property_id, property_type, convert_time, no_conversion) + values.append(v) + off += sz + 4 + v = values + + elif property_type & VT_VECTOR: + property_type_base = property_type & ~VT_VECTOR + log.debug('property_type == VT_VECTOR | %s' % VT.get(property_type_base, 'UNKNOWN')) + off = 4 + count = i32(s, offset) + values = [] + for _ in range(count): + v, sz = self._parse_property_basic(s, offset + off, property_id, property_type & ~VT_VECTOR, convert_time, no_conversion) + values.append(v) + off += sz + v = values + else: + log.debug('property id=%d: type=%d not implemented in parser yet' % (property_id, property_type)) + return v + + def _parse_property_basic(self, s, offset, property_id, property_type, convert_time, no_conversion): + value = None + size = 0 + # test for common types first (should perhaps use + # a dictionary instead?) + + if property_type == VT_I2: # 16-bit signed integer + value = i16(s, offset) + if value >= 32768: + value = value - 65536 + size = 2 + elif property_type == VT_UI2: # 2-byte unsigned integer + value = i16(s, offset) + size = 2 + elif property_type in (VT_I4, VT_INT, VT_ERROR): + # VT_I4: 32-bit signed integer + # VT_ERROR: HRESULT, similar to 32-bit signed integer, + # see https://msdn.microsoft.com/en-us/library/cc230330.aspx + value = i32(s, offset) + size = 4 + elif property_type in (VT_UI4, VT_UINT): # 4-byte unsigned integer + value = i32(s, offset) # FIXME + size = 4 + elif property_type in (VT_BSTR, VT_LPSTR): + # CodePageString, see https://msdn.microsoft.com/en-us/library/dd942354.aspx + # size is a 32 bits integer, including the null terminator, and + # possibly trailing or embedded null chars + #TODO: if codepage is unicode, the string should be converted as such + count = i32(s, offset) + value = s[offset+4:offset+4+count-1] + # remove all null chars: + value = value.replace(b'\x00', b'') + size = 4 + count + elif property_type == VT_BLOB: + # binary large object (BLOB) + # see https://msdn.microsoft.com/en-us/library/dd942282.aspx + count = i32(s, offset) + value = s[offset+4:offset+4+count] + size = 4 + count + elif property_type == VT_LPWSTR: + # UnicodeString + # see https://msdn.microsoft.com/en-us/library/dd942313.aspx + # "the string should NOT contain embedded or additional trailing + # null characters." + count = i32(s, offset+4) + value = self._decode_utf16_str(s[offset+4:offset+4+count*2]) + size = 4 + count * 2 + elif property_type == VT_FILETIME: + value = long(i32(s, offset)) + (long(i32(s, offset+4))<<32) + # FILETIME is a 64-bit int: "number of 100ns periods + # since Jan 1,1601". + if convert_time and property_id not in no_conversion: + log.debug('Converting property #%d to python datetime, value=%d=%fs' + %(property_id, value, float(value)/10000000)) + # convert FILETIME to Python datetime.datetime + # inspired from https://code.activestate.com/recipes/511425-filetime-to-datetime/ + _FILETIME_null_date = datetime.datetime(1601, 1, 1, 0, 0, 0) + log.debug('timedelta days=%d' % (value//(10*1000000*3600*24))) + value = _FILETIME_null_date + datetime.timedelta(microseconds=value//10) + else: + # legacy code kept for backward compatibility: returns a + # number of seconds since Jan 1,1601 + value = value // 10000000 # seconds + size = 8 + elif property_type == VT_UI1: # 1-byte unsigned integer + value = i8(s[offset]) + size = 1 + elif property_type == VT_CLSID: + value = _clsid(s[offset:offset+16]) + size = 16 + elif property_type == VT_CF: + # PropertyIdentifier or ClipboardData?? + # see https://msdn.microsoft.com/en-us/library/dd941945.aspx + count = i32(s, offset) + value = s[offset+4:offset+4+count] + size = 4 + count + elif property_type == VT_BOOL: + # VARIANT_BOOL, 16 bits bool, 0x0000=Fals, 0xFFFF=True + # see https://msdn.microsoft.com/en-us/library/cc237864.aspx + value = bool(i16(s, offset)) + size = 2 + else: + value = None # everything else yields "None" + log.debug('property id=%d: type=%d not implemented in parser yet' % (property_id, property_type)) + + # missing: VT_EMPTY, VT_NULL, VT_R4, VT_R8, VT_CY, VT_DATE, + # VT_DECIMAL, VT_I1, VT_I8, VT_UI8, + # see https://msdn.microsoft.com/en-us/library/dd942033.aspx + + #print("%08x" % property_id, repr(value), end=" ") + #print("(%s)" % VT[i32(s, offset) & 0xFFF]) + return value, size + + def get_metadata(self): """ Parse standard properties streams, return an OleMetadata object @@ -2259,7 +2350,196 @@ class OleFileIO: self.metadata.parse_properties(self) return self.metadata -# + def get_userdefined_properties(self, filename, convert_time=False, no_conversion=None): + """ + Return properties described in substream. + + :param filename: path of stream in storage tree (see openstream for syntax) + :param convert_time: bool, if True timestamps will be converted to Python datetime + :param no_conversion: None or list of int, timestamps not to be converted + (for example total editing time is not a real timestamp) + + :returns: a dictionary of values indexed by id (integer) + """ + # REFERENCE: [MS-OLEPS] https://msdn.microsoft.com/en-us/library/dd942421.aspx + # REFERENCE: https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-oshared/2ea8be67-a4a0-4e2e-b42f-49a182645562 + #'D5CDD502-2E9C-101B-9397-08002B2CF9AE' + # TODO: testing the code more rigorously + # TODO: adding exception handeling + FMTID_USERDEFINED_PROPERTIES = _clsid(b'\x05\xD5\xCD\xD5\x9C\x2E\x1B\x10\x93\x97\x08\x00\x2B\x2C\xF9\xAE') + + # make sure no_conversion is a list, just to simplify code below: + if no_conversion == None: + no_conversion = [] + # stream path as a string to report exceptions: + streampath = filename + if not isinstance(streampath, str): + streampath = '/'.join(streampath) + + fp = self.openstream(filename) + + data = [] + + # header + s = fp.read(28) + clsid = _clsid(s[8:24]) + + # PropertySetStream.cSections (4 bytes starts at 1c): number of property sets in this stream + sections_count = i32(s, 24) + + section_file_pointers = [] + + try: + for i in range(sections_count): + # format id + s = fp.read(20) + fmtid = _clsid(s[:16]) + + if fmtid == FMTID_USERDEFINED_PROPERTIES: + file_pointer = i32(s, 16) + fp.seek(file_pointer) + # read saved sections + s = b"****" + fp.read(i32(fp.read(4)) - 4) + # number of properties: + num_props = i32(s, 4) + + PropertyIdentifierAndOffset = s[8: 8+8*num_props] + + # property names (dictionary) + # ref: https://docs.microsoft.com/en-us/openspecs/windows_protocols/MS-OLEPS/99127b7f-c440-4697-91a4-c853086d6b33 + index = 8+8*num_props + entry_count = i32(s[index: index+4]) + index += 4 + for i in range(entry_count): + identifier = s[index: index +4] + str_size = i32(s[index+4: index + 8]) + string = s[index+8: index+8+str_size].decode('utf_8').strip('\0') + data.append({'property_name':string, 'value':None}) + index = index+8+str_size + # clamp num_props based on the data length + num_props = min(num_props, int(len(s) / 8)) + + # property values + # ref: https://docs.microsoft.com/en-us/openspecs/windows_protocols/MS-OLEPS/f122b9d7-e5cf-4484-8466-83f6fd94b3cc + for i in iterrange(2, num_props): + property_id = 0 # just in case of an exception + try: + property_id = i32(s, 8 + i * 8) + offset = i32(s, 12 + i * 8) + property_type = i32(s, offset) + + vt_name = VT.get(property_type, 'UNKNOWN') + log.debug('property id=%d: type=%d/%s offset=%X' % (property_id, property_type, vt_name, offset)) + + # test for common types first (should perhaps use + # a dictionary instead?) + + if property_type == VT_I2: # 16-bit signed integer + value = i16(s, offset + 4) + if value >= 32768: + value = value - 65536 + elif property_type == 1: + # supposed to be VT_NULL but seems it is not NULL + str_size = i32(s, offset + 8) + value = s[offset + 12:offset + 12 + str_size - 1] + + elif property_type == VT_UI2: # 2-byte unsigned integer + value = i16(s, offset + 4) + elif property_type in (VT_I4, VT_INT, VT_ERROR): + # VT_I4: 32-bit signed integer + # VT_ERROR: HRESULT, similar to 32-bit signed integer, + # see https://msdn.microsoft.com/en-us/library/cc230330.aspx + value = i32(s, offset + 4) + elif property_type in (VT_UI4, VT_UINT): # 4-byte unsigned integer + value = i32(s, offset + 4) # FIXME + elif property_type in (VT_BSTR, VT_LPSTR): + # CodePageString, see https://msdn.microsoft.com/en-us/library/dd942354.aspx + # size is a 32 bits integer, including the null terminator, and + # possibly trailing or embedded null chars + # TODO: if codepage is unicode, the string should be converted as such + count = i32(s, offset + 4) + value = s[offset + 8:offset + 8 + count - 1] + # remove all null chars: + value = value.replace(b'\x00', b'') + elif property_type == VT_BLOB: + # binary large object (BLOB) + # see https://msdn.microsoft.com/en-us/library/dd942282.aspx + count = i32(s, offset + 4) + value = s[offset + 8:offset + 8 + count] + elif property_type == VT_LPWSTR: + # UnicodeString + # see https://msdn.microsoft.com/en-us/library/dd942313.aspx + # "the string should NOT contain embedded or additional trailing + # null characters." + count = i32(s, offset + 4) + value = self._decode_utf16_str(s[offset + 8:offset + 8 + count * 2]) + elif property_type == VT_FILETIME: + value = long(i32(s, offset + 4)) + (long(i32(s, offset + 8)) << 32) + # FILETIME is a 64-bit int: "number of 100ns periods + # since Jan 1,1601". + if convert_time and property_id not in no_conversion: + log.debug('Converting property #%d to python datetime, value=%d=%fs' + % (property_id, value, float(value) / 10000000)) + # convert FILETIME to Python datetime.datetime + # inspired from https://code.activestate.com/recipes/511425-filetime-to-datetime/ + _FILETIME_null_date = datetime.datetime(1601, 1, 1, 0, 0, 0) + log.debug('timedelta days=%d' % (value // (10 * 1000000 * 3600 * 24))) + value = _FILETIME_null_date + datetime.timedelta(microseconds=value // 10) + else: + # legacy code kept for backward compatibility: returns a + # number of seconds since Jan 1,1601 + value = value // 10000000 # seconds + elif property_type == VT_UI1: # 1-byte unsigned integer + value = i8(s[offset + 4]) + elif property_type == VT_CLSID: + value = _clsid(s[offset + 4:offset + 20]) + elif property_type == VT_CF: + # PropertyIdentifier or ClipboardData?? + # see https://msdn.microsoft.com/en-us/library/dd941945.aspx + count = i32(s, offset + 4) + value = s[offset + 8:offset + 8 + count] + elif property_type == VT_BOOL: + # VARIANT_BOOL, 16 bits bool, 0x0000=Fals, 0xFFFF=True + # see https://msdn.microsoft.com/en-us/library/cc237864.aspx + value = bool(i16(s, offset + 4)) + else: + value = None # everything else yields "None" + log.debug( + 'property id=%d: type=%d not implemented in parser yet' % (property_id, property_type)) + + # missing: VT_EMPTY, VT_NULL, VT_R4, VT_R8, VT_CY, VT_DATE, + # VT_DECIMAL, VT_I1, VT_I8, VT_UI8, + # see https://msdn.microsoft.com/en-us/library/dd942033.aspx + + # FIXME: add support for VT_VECTOR + # VT_VECTOR is a 32 uint giving the number of items, followed by + # the items in sequence. The VT_VECTOR value is combined with the + # type of items, e.g. VT_VECTOR|VT_BSTR + # see https://msdn.microsoft.com/en-us/library/dd942011.aspx + + # print("%08x" % property_id, repr(value), end=" ") + # print("(%s)" % VT[i32(s, offset) & 0xFFF]) + + data[i-2]['value']=value + except BaseException as exc: + # catch exception while parsing each property, and only raise + # a DEFECT_INCORRECT, because parsing can go on + msg = 'Error while parsing property id %d in stream %s: %s' % ( + property_id, repr(streampath), exc) + self._raise_defect(DEFECT_INCORRECT, msg, type(exc)) + + except BaseException as exc: + # catch exception while parsing property header, and only raise + # a DEFECT_INCORRECT then return an empty dict, because this is not + # a fatal error when parsing the whole file + msg = 'Error while parsing properties header in stream %s: %s' % ( + repr(streampath), exc) + self._raise_defect(DEFECT_INCORRECT, msg, type(exc)) + return data + + return data + + # -------------------------------------------------------------------- # This script can be used to dump the directory of any OLE2 structured # storage file. @@ -2283,8 +2563,11 @@ def main(): usage = 'usage: %prog [options] <filename> [filename2 ...]' parser = optparse.OptionParser(usage=usage) + parser.add_option("-c", action="store_true", dest="check_streams", help='check all streams (for debugging purposes)') + parser.add_option("-p", action="store_true", dest="extract_customprop", + help='extract all user-defined propertires') parser.add_option("-d", action="store_true", dest="debug_mode", help='debug mode, shortcut for -l debug (displays a lot of debug information, for developers only)') parser.add_option('-l', '--loglevel', dest="loglevel", action="store", default=DEFAULT_LOG_LEVEL, @@ -2292,7 +2575,7 @@ def main(): (options, args) = parser.parse_args() - print('olefile version %s %s - https://www.decalage.info/en/olefile\n' % (__version__, __date__)) + print('olefile version {} {} - https://www.decalage.info/en/olefile\n'.format(__version__, __date__)) # Print help if no arguments are passed if len(args) == 0: @@ -2323,21 +2606,33 @@ def main(): props = ole.getproperties(streamname, convert_time=True) props = sorted(props.items()) for k, v in props: - #[PL]: avoid to display too large or binary values: + # [PL]: avoid to display too large or binary values: if isinstance(v, (basestring, bytes)): if len(v) > 50: v = v[:50] if isinstance(v, bytes): # quick and dirty binary check: for c in (1,2,3,4,5,6,7,11,12,14,15,16,17,18,19,20, - 21,22,23,24,25,26,27,28,29,30,31): + 21,22,23,24,25,26,27,28,29,30,31): if c in bytearray(v): v = '(binary data)' break print(" ", k, v) - except: + except Exception: log.exception('Error while parsing property stream %r' % streamname) + try: + if options.extract_customprop: + variables = ole.get_userdefined_properties(streamname, convert_time=True) + if len(variables): + print("%r: user-defined properties" % streamname) + for index, variable in enumerate(variables): + print('\t{} {}: {}'.format(index, variable['property_name'],variable['value'])) + + except: + log.exception('Error while parsing user-defined property stream %r' % streamname) + + if options.check_streams: # Read all streams to check if there are errors: print('\nChecking streams...') @@ -2353,16 +2648,16 @@ def main(): print('NOT a stream : type=%d' % st_type) print() -## for streamname in ole.listdir(): -## # print name using repr() to convert binary chars to \xNN: -## print('-', repr('/'.join(streamname)),'-', end=' ') -## print(ole.getmtime(streamname)) -## print() + # for streamname in ole.listdir(): + # # print name using repr() to convert binary chars to \xNN: + # print('-', repr('/'.join(streamname)),'-', end=' ') + # print(ole.getmtime(streamname)) + # print() print('Modification/Creation times of all directory entries:') for entry in ole.direntries: if entry is not None: - print('- %s: mtime=%s ctime=%s' % (entry.name, + print('- {}: mtime={} ctime={}'.format(entry.name, entry.getmtime(), entry.getctime())) print() @@ -2370,10 +2665,10 @@ def main(): try: meta = ole.get_metadata() meta.dump() - except: + except Exception: log.exception('Error while parsing metadata') print() - #[PL] Test a few new methods: + # [PL] Test a few new methods: root = ole.get_rootentry_name() print('Root entry name: "%s"' % root) if ole.exists('worddocument'): @@ -2387,10 +2682,11 @@ def main(): print('\nNon-fatal issues raised during parsing:') if ole.parsing_issues: for exctype, msg in ole.parsing_issues: - print('- %s: %s' % (exctype.__name__, msg)) + print('- {}: {}'.format(exctype.__name__, msg)) else: print('None') - except: + ole.close() + except Exception: log.exception('Error while parsing file %r' % filename) diff --git a/contrib/python/olefile/py3/ya.make b/contrib/python/olefile/py3/ya.make index 085f594332..33e0be14d2 100644 --- a/contrib/python/olefile/py3/ya.make +++ b/contrib/python/olefile/py3/ya.make @@ -2,14 +2,15 @@ PY3_LIBRARY() -VERSION(0.46) +VERSION(0.47) -LICENSE(BSD-3-Clause AND PIL) +LICENSE(BSD-2-Clause AND PIL) NO_LINT() PY_SRCS( TOP_LEVEL + OleFileIO_PL.py olefile/__init__.py olefile/olefile.py ) diff --git a/contrib/python/pexpect/py2/.dist-info/METADATA b/contrib/python/pexpect/py2/.dist-info/METADATA index 4c417227db..c5ea4a1a59 100644 --- a/contrib/python/pexpect/py2/.dist-info/METADATA +++ b/contrib/python/pexpect/py2/.dist-info/METADATA @@ -1,11 +1,15 @@ Metadata-Version: 2.1 Name: pexpect -Version: 4.8.0 +Version: 4.9.0 Summary: Pexpect allows easy control of interactive console applications. Home-page: https://pexpect.readthedocs.io/ Author: Noah Spurrier; Thomas Kluyver; Jeff Quast Author-email: noah@noah.org, thomas@kluyver.me.uk, contact@jeffquast.com License: ISC license +Project-URL: Bug Tracker, https://github.com/pexpect/pexpect/issues +Project-URL: Documentation, https://pexpect.readthedocs.io/ +Project-URL: Source Code, https://github.com/pexpect/pexpect +Project-URL: History, https://pexpect.readthedocs.io/en/stable/history.html Platform: UNIX Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Console @@ -27,6 +31,7 @@ Classifier: Topic :: System :: Installation/Setup Classifier: Topic :: System :: Shells Classifier: Topic :: System :: Software Distribution Classifier: Topic :: Terminals +License-File: LICENSE Requires-Dist: ptyprocess (>=0.5) @@ -36,7 +41,7 @@ Don Libes' Expect. Pexpect allows your script to spawn a child application and control it as if a human were typing commands. Pexpect can be used for automating interactive applications such as ssh, ftp, -passwd, telnet, etc. It can be used to a automate setup scripts for duplicating +passwd, telnet, etc. It can be used to automate setup scripts for duplicating software package installations on different servers. It can be used for automated software testing. Pexpect is in the spirit of Don Libes' Expect, but Pexpect is pure Python. @@ -45,5 +50,3 @@ The main features of Pexpect require the pty module in the Python standard library, which is only available on Unix-like systems. Some features—waiting for patterns from file descriptors or subprocesses—are also available on Windows. - - diff --git a/contrib/python/pexpect/py2/pexpect/__init__.py b/contrib/python/pexpect/py2/pexpect/__init__.py index 7e30453787..86254ee720 100644 --- a/contrib/python/pexpect/py2/pexpect/__init__.py +++ b/contrib/python/pexpect/py2/pexpect/__init__.py @@ -1,6 +1,6 @@ '''Pexpect is a Python module for spawning child applications and controlling them automatically. Pexpect can be used for automating interactive applications -such as ssh, ftp, passwd, telnet, etc. It can be used to a automate setup +such as ssh, ftp, passwd, telnet, etc. It can be used to automate setup scripts for duplicating software package installations on different servers. It can be used for automated software testing. Pexpect is in the spirit of Don Libes' Expect, but Pexpect is pure Python. Other Expect-like modules for Python @@ -29,6 +29,12 @@ For example:: child.expect('Password:') child.sendline(mypassword) +Context manager can be used for the spawn() function:: + + with pexpect.spawn('scp foo user@example.com:.') as child: + child.expect('Password:') + child.sendline(mypassword) + This works even for commands that ask for passwords or other input outside of the normal stdio streams. For example, ssh reads input directly from the TTY device which bypasses stdin. @@ -75,7 +81,7 @@ if sys.platform != 'win32': from .pty_spawn import spawn, spawnu from .run import run, runu -__version__ = '4.8.0' +__version__ = '4.9.0' __revision__ = '' __all__ = ['ExceptionPexpect', 'EOF', 'TIMEOUT', 'spawn', 'spawnu', 'run', 'runu', 'which', 'split_command_line', '__version__', '__revision__'] diff --git a/contrib/python/pexpect/py2/pexpect/bashrc.sh b/contrib/python/pexpect/py2/pexpect/bashrc.sh index c734ac90b8..d75d1a5b62 100644 --- a/contrib/python/pexpect/py2/pexpect/bashrc.sh +++ b/contrib/python/pexpect/py2/pexpect/bashrc.sh @@ -14,3 +14,5 @@ PS1="$" # Unset PROMPT_COMMAND, so that it can't change PS1 to something unexpected. unset PROMPT_COMMAND + +bind 'set enable-bracketed-paste off' diff --git a/contrib/python/pexpect/py2/pexpect/fdpexpect.py b/contrib/python/pexpect/py2/pexpect/fdpexpect.py index cddd50e100..140bdfeeda 100644 --- a/contrib/python/pexpect/py2/pexpect/fdpexpect.py +++ b/contrib/python/pexpect/py2/pexpect/fdpexpect.py @@ -1,7 +1,11 @@ -'''This is like pexpect, but it will work with any file descriptor that you +'''This is like :mod:`pexpect`, but it will work with any file descriptor that you pass it. You are responsible for opening and close the file descriptor. This allows you to use Pexpect with sockets and named pipes (FIFOs). +.. note:: + socket.fileno() does not give a readable file descriptor on windows. + Use :mod:`pexpect.socket_pexpect` for cross-platform socket support + PEXPECT LICENSE This license is approved by the OSI and FSF as GPL-compatible. diff --git a/contrib/python/pexpect/py2/pexpect/popen_spawn.py b/contrib/python/pexpect/py2/pexpect/popen_spawn.py index 4bb58cfe76..e6bdf07d61 100644 --- a/contrib/python/pexpect/py2/pexpect/popen_spawn.py +++ b/contrib/python/pexpect/py2/pexpect/popen_spawn.py @@ -57,7 +57,7 @@ class PopenSpawn(SpawnBase): self._read_queue = Queue() self._read_thread = threading.Thread(target=self._read_incoming) - self._read_thread.setDaemon(True) + self._read_thread.daemon = True self._read_thread.start() _read_reached_eof = False diff --git a/contrib/python/pexpect/py2/pexpect/pxssh.py b/contrib/python/pexpect/py2/pexpect/pxssh.py index 3d53bd9746..742f59e406 100644 --- a/contrib/python/pexpect/py2/pexpect/pxssh.py +++ b/contrib/python/pexpect/py2/pexpect/pxssh.py @@ -143,8 +143,8 @@ class pxssh (spawn): # used to set shell command-line prompt to UNIQUE_PROMPT. self.PROMPT_SET_SH = r"PS1='[PEXPECT]\$ '" self.PROMPT_SET_CSH = r"set prompt='[PEXPECT]\$ '" - self.SSH_OPTS = ("-o'RSAAuthentication=no'" - + " -o 'PubkeyAuthentication=no'") + self.PROMPT_SET_ZSH = "prompt restore;\nPS1='[PEXPECT]%(!.#.$) '" + self.SSH_OPTS = (" -o 'PubkeyAuthentication=no'") # Disabling host key checking, makes you vulnerable to MITM attacks. # + " -o 'StrictHostKeyChecking=no'" # + " -o 'UserKnownHostsFile /dev/null' ") @@ -152,7 +152,7 @@ class pxssh (spawn): # displaying a GUI password dialog. I have not figured out how to # disable only SSH_ASKPASS without also disabling X11 forwarding. # Unsetting SSH_ASKPASS on the remote side doesn't disable it! Annoying! - #self.SSH_OPTS = "-x -o'RSAAuthentication=no' -o 'PubkeyAuthentication=no'" + #self.SSH_OPTS = "-x -o 'PubkeyAuthentication=no'" self.force_password = False self.debug_command_string = debug_command_string @@ -530,8 +530,11 @@ class pxssh (spawn): if i == 0: # csh-style self.sendline(self.PROMPT_SET_CSH) i = self.expect([TIMEOUT, self.PROMPT], timeout=10) - if i == 0: - return False + if i == 0: # zsh-style + self.sendline(self.PROMPT_SET_ZSH) + i = self.expect([TIMEOUT, self.PROMPT], timeout=10) + if i == 0: + return False return True # vi:ts=4:sw=4:expandtab:ft=python: diff --git a/contrib/python/pexpect/py2/pexpect/replwrap.py b/contrib/python/pexpect/py2/pexpect/replwrap.py index c930f1e4fe..08dbd5e869 100644 --- a/contrib/python/pexpect/py2/pexpect/replwrap.py +++ b/contrib/python/pexpect/py2/pexpect/replwrap.py @@ -108,23 +108,29 @@ class REPLWrapper(object): + command) return u''.join(res + [self.child.before]) -def python(command="python"): +def python(command=sys.executable): """Start a Python shell and return a :class:`REPLWrapper` object.""" return REPLWrapper(command, u">>> ", u"import sys; sys.ps1={0!r}; sys.ps2={1!r}") -def bash(command="bash"): - """Start a bash shell and return a :class:`REPLWrapper` object.""" - bashrc = os.path.join(os.path.dirname(__file__), 'bashrc.sh') - child = pexpect.spawn(command, ['--rcfile', bashrc], echo=False, - encoding='utf-8') +def _repl_sh(command, args, non_printable_insert): + child = pexpect.spawn(command, args, echo=False, encoding='utf-8') # If the user runs 'env', the value of PS1 will be in the output. To avoid # replwrap seeing that as the next prompt, we'll embed the marker characters # for invisible characters in the prompt; these show up when inspecting the # environment variable, but not when bash displays the prompt. - ps1 = PEXPECT_PROMPT[:5] + u'\\[\\]' + PEXPECT_PROMPT[5:] - ps2 = PEXPECT_CONTINUATION_PROMPT[:5] + u'\\[\\]' + PEXPECT_CONTINUATION_PROMPT[5:] + ps1 = PEXPECT_PROMPT[:5] + non_printable_insert + PEXPECT_PROMPT[5:] + ps2 = PEXPECT_CONTINUATION_PROMPT[:5] + non_printable_insert + PEXPECT_CONTINUATION_PROMPT[5:] prompt_change = u"PS1='{0}' PS2='{1}' PROMPT_COMMAND=''".format(ps1, ps2) return REPLWrapper(child, u'\\$', prompt_change, extra_init_cmd="export PAGER=cat") + +def bash(command="bash"): + """Start a bash shell and return a :class:`REPLWrapper` object.""" + bashrc = os.path.join(os.path.dirname(__file__), 'bashrc.sh') + return _repl_sh(command, ['--rcfile', bashrc], non_printable_insert='\\[\\]') + +def zsh(command="zsh", args=("--no-rcs", "-V", "+Z")): + """Start a zsh shell and return a :class:`REPLWrapper` object.""" + return _repl_sh(command, list(args), non_printable_insert='%(!..)') diff --git a/contrib/python/pexpect/py2/pexpect/run.py b/contrib/python/pexpect/py2/pexpect/run.py index ff288a1246..5695ab7f7b 100644 --- a/contrib/python/pexpect/py2/pexpect/run.py +++ b/contrib/python/pexpect/py2/pexpect/run.py @@ -66,7 +66,7 @@ def run(command, timeout=30, withexitstatus=False, events=None, The 'events' argument should be either a dictionary or a tuple list that contains patterns and responses. Whenever one of the patterns is seen in the command output, run() will send the associated response string. - So, run() in the above example can be also written as: + So, run() in the above example can be also written as:: run("mencoder dvd://1 -o video.avi -oac copy -ovc copy", events=[(TIMEOUT,print_ticks)], timeout=5) diff --git a/contrib/python/pexpect/py2/pexpect/spawnbase.py b/contrib/python/pexpect/py2/pexpect/spawnbase.py index 59e905764c..abf8071ec1 100644 --- a/contrib/python/pexpect/py2/pexpect/spawnbase.py +++ b/contrib/python/pexpect/py2/pexpect/spawnbase.py @@ -141,6 +141,16 @@ class SpawnBase(object): return s.encode('ascii') return s + # In bytes mode, regex patterns should also be of bytes type + def _coerce_expect_re(self, r): + p = r.pattern + if self.encoding is None and not isinstance(p, bytes): + return re.compile(p.encode('utf-8')) + # And vice-versa + elif self.encoding is not None and isinstance(p, bytes): + return re.compile(p.decode('utf-8')) + return r + def _coerce_send_string(self, s): if self.encoding is None and not isinstance(s, bytes): return s.encode('utf-8') @@ -153,7 +163,7 @@ class SpawnBase(object): self._buffer = self.buffer_type() self._buffer.write(value) - # This property is provided for backwards compatability (self.buffer used + # This property is provided for backwards compatibility (self.buffer used # to be a string/bytes object) buffer = property(_get_buffer, _set_buffer) @@ -235,6 +245,7 @@ class SpawnBase(object): elif p is TIMEOUT: compiled_pattern_list.append(TIMEOUT) elif isinstance(p, type(re.compile(''))): + p = self._coerce_expect_re(p) compiled_pattern_list.append(p) else: self._pattern_type_err(p) diff --git a/contrib/python/pexpect/py2/ya.make b/contrib/python/pexpect/py2/ya.make index 9dc28a63d0..2498af4417 100644 --- a/contrib/python/pexpect/py2/ya.make +++ b/contrib/python/pexpect/py2/ya.make @@ -2,7 +2,7 @@ PY2_LIBRARY() -VERSION(4.8.0) +VERSION(4.9.0) LICENSE(ISC) diff --git a/contrib/python/prompt-toolkit/py3/.dist-info/METADATA b/contrib/python/prompt-toolkit/py3/.dist-info/METADATA index ab2db30bbf..13de29c342 100644 --- a/contrib/python/prompt-toolkit/py3/.dist-info/METADATA +++ b/contrib/python/prompt-toolkit/py3/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: prompt-toolkit -Version: 3.0.41 +Version: 3.0.43 Summary: Library for building powerful interactive command lines in Python Home-page: https://github.com/prompt-toolkit/python-prompt-toolkit Author: Jonathan Slenders diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/__init__.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/__init__.py index 2d408152fe..82324cb815 100644 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/__init__.py +++ b/contrib/python/prompt-toolkit/py3/prompt_toolkit/__init__.py @@ -27,7 +27,7 @@ from .formatted_text import ANSI, HTML from .shortcuts import PromptSession, print_formatted_text, prompt # Don't forget to update in `docs/conf.py`! -__version__ = "3.0.41" +__version__ = "3.0.43" assert pep440.match(__version__) diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/application/application.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/application/application.py index 726fc0a067..d4637811ba 100644 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/application/application.py +++ b/contrib/python/prompt-toolkit/py3/prompt_toolkit/application/application.py @@ -807,16 +807,19 @@ class Application(Generic[_AppResult]): @contextmanager def set_handle_sigint(loop: AbstractEventLoop) -> Iterator[None]: if handle_sigint: - loop.add_signal_handler( - signal.SIGINT, - lambda *_: loop.call_soon_threadsafe( - self.key_processor.send_sigint - ), - ) - try: - yield - finally: - loop.remove_signal_handler(signal.SIGINT) + with _restore_sigint_from_ctypes(): + # save sigint handlers (python and os level) + # See: https://github.com/prompt-toolkit/python-prompt-toolkit/issues/1576 + loop.add_signal_handler( + signal.SIGINT, + lambda *_: loop.call_soon_threadsafe( + self.key_processor.send_sigint + ), + ) + try: + yield + finally: + loop.remove_signal_handler(signal.SIGINT) else: yield @@ -960,7 +963,8 @@ class Application(Generic[_AppResult]): def _called_from_ipython() -> bool: try: return ( - "IPython/terminal/interactiveshell.py" + sys.modules["IPython"].version_info < (8, 18, 0, "") + and "IPython/terminal/interactiveshell.py" in sys._getframe(3).f_code.co_filename ) except BaseException: @@ -1545,7 +1549,7 @@ async def _do_wait_for_enter(wait_text: AnyFormattedText) -> None: @contextmanager def attach_winch_signal_handler( - handler: Callable[[], None] + handler: Callable[[], None], ) -> Generator[None, None, None]: """ Attach the given callback as a WINCH signal handler within the context @@ -1586,3 +1590,36 @@ def attach_winch_signal_handler( previous_winch_handler._callback, *previous_winch_handler._args, ) + + +@contextmanager +def _restore_sigint_from_ctypes() -> Generator[None, None, None]: + # The following functions are part of the stable ABI since python 3.2 + # See: https://docs.python.org/3/c-api/sys.html#c.PyOS_getsig + # Inline import: these are not available on Pypy. + try: + from ctypes import c_int, c_void_p, pythonapi + except ImportError: + # Any of the above imports don't exist? Don't do anything here. + yield + return + + # PyOS_sighandler_t PyOS_getsig(int i) + pythonapi.PyOS_getsig.restype = c_void_p + pythonapi.PyOS_getsig.argtypes = (c_int,) + + # PyOS_sighandler_t PyOS_setsig(int i, PyOS_sighandler_t h) + pythonapi.PyOS_setsig.restype = c_void_p + pythonapi.PyOS_setsig.argtypes = ( + c_int, + c_void_p, + ) + + sigint = signal.getsignal(signal.SIGINT) + sigint_os = pythonapi.PyOS_getsig(signal.SIGINT) + + try: + yield + finally: + signal.signal(signal.SIGINT, sigint) + pythonapi.PyOS_setsig(signal.SIGINT, sigint_os) diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/buffer.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/buffer.py index 7dbc7a6fb3..100ca78d7b 100644 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/buffer.py +++ b/contrib/python/prompt-toolkit/py3/prompt_toolkit/buffer.py @@ -15,7 +15,7 @@ import tempfile from collections import deque from enum import Enum from functools import wraps -from typing import Any, Awaitable, Callable, Coroutine, Iterable, TypeVar, cast +from typing import Any, Callable, Coroutine, Iterable, TypeVar, cast from .application.current import get_app from .application.run_in_terminal import run_in_terminal @@ -1891,7 +1891,7 @@ class Buffer: self.reset() -_T = TypeVar("_T", bound=Callable[..., Awaitable[None]]) +_T = TypeVar("_T", bound=Callable[..., Coroutine[Any, Any, None]]) def _only_one_at_a_time(coroutine: _T) -> _T: diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/contrib/regular_languages/__init__.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/contrib/regular_languages/__init__.py index 1743af4e74..c947fd5337 100644 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/contrib/regular_languages/__init__.py +++ b/contrib/python/prompt-toolkit/py3/prompt_toolkit/contrib/regular_languages/__init__.py @@ -30,7 +30,7 @@ What can we do with this grammar? --------------------------------- - Syntax highlighting: We could use this for instance to give file names - different colour. + different color. - Parse the result: .. We can extract the file names and commands by using a regular expression with named groups. - Input validation: .. Don't accept anything that does not match this grammar. diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/contrib/ssh/server.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/contrib/ssh/server.py index 5f9b5f6b7c..9a5d4022a0 100644 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/contrib/ssh/server.py +++ b/contrib/python/prompt-toolkit/py3/prompt_toolkit/contrib/ssh/server.py @@ -6,7 +6,7 @@ from __future__ import annotations import asyncio import traceback from asyncio import get_running_loop -from typing import Any, Awaitable, Callable, TextIO, cast +from typing import Any, Callable, Coroutine, TextIO, cast import asyncssh @@ -21,7 +21,7 @@ __all__ = ["PromptToolkitSSHSession", "PromptToolkitSSHServer"] class PromptToolkitSSHSession(asyncssh.SSHServerSession): # type: ignore def __init__( self, - interact: Callable[[PromptToolkitSSHSession], Awaitable[None]], + interact: Callable[[PromptToolkitSSHSession], Coroutine[Any, Any, None]], *, enable_cpr: bool, ) -> None: @@ -162,7 +162,7 @@ class PromptToolkitSSHServer(asyncssh.SSHServer): def __init__( self, - interact: Callable[[PromptToolkitSSHSession], Awaitable[None]], + interact: Callable[[PromptToolkitSSHSession], Coroutine[Any, Any, None]], *, enable_cpr: bool = True, ) -> None: diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/contrib/telnet/server.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/contrib/telnet/server.py index 81c19f6c88..9ebe66c62d 100644 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/contrib/telnet/server.py +++ b/contrib/python/prompt-toolkit/py3/prompt_toolkit/contrib/telnet/server.py @@ -7,7 +7,7 @@ import asyncio import contextvars import socket from asyncio import get_running_loop -from typing import Awaitable, Callable, TextIO, cast +from typing import Any, Callable, Coroutine, TextIO, cast from prompt_toolkit.application.current import create_app_session, get_app from prompt_toolkit.application.run_in_terminal import run_in_terminal @@ -124,7 +124,7 @@ class TelnetConnection: self, conn: socket.socket, addr: tuple[str, int], - interact: Callable[[TelnetConnection], Awaitable[None]], + interact: Callable[[TelnetConnection], Coroutine[Any, Any, None]], server: TelnetServer, encoding: str, style: BaseStyle | None, @@ -283,7 +283,9 @@ class TelnetServer: self, host: str = "127.0.0.1", port: int = 23, - interact: Callable[[TelnetConnection], Awaitable[None]] = _dummy_interact, + interact: Callable[ + [TelnetConnection], Coroutine[Any, Any, None] + ] = _dummy_interact, encoding: str = "utf-8", style: BaseStyle | None = None, enable_cpr: bool = True, diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/eventloop/inputhook.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/eventloop/inputhook.py index 5731573f52..a4c0eee6bb 100644 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/eventloop/inputhook.py +++ b/contrib/python/prompt-toolkit/py3/prompt_toolkit/eventloop/inputhook.py @@ -66,7 +66,7 @@ InputHook: TypeAlias = Callable[[InputHookContext], None] def new_eventloop_with_inputhook( - inputhook: Callable[[InputHookContext], None] + inputhook: Callable[[InputHookContext], None], ) -> AbstractEventLoop: """ Create a new event loop with the given inputhook. @@ -77,7 +77,7 @@ def new_eventloop_with_inputhook( def set_eventloop_with_inputhook( - inputhook: Callable[[InputHookContext], None] + inputhook: Callable[[InputHookContext], None], ) -> AbstractEventLoop: """ Create a new event loop with the given inputhook, and activate it. diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/filters/app.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/filters/app.py index 303a078c4e..aacb228416 100644 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/filters/app.py +++ b/contrib/python/prompt-toolkit/py3/prompt_toolkit/filters/app.py @@ -50,7 +50,7 @@ __all__ = [ # NOTE: `has_focus` below should *not* be `memoized`. It can reference any user -# control. For instance, if we would contiously create new +# control. For instance, if we would continuously create new # `PromptSession` instances, then previous instances won't be released, # because this memoize (which caches results in the global scope) will # still refer to each instance. diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/formatted_text/__init__.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/formatted_text/__init__.py index e34db13d80..db44ab9266 100644 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/formatted_text/__init__.py +++ b/contrib/python/prompt-toolkit/py3/prompt_toolkit/formatted_text/__init__.py @@ -16,6 +16,7 @@ from .ansi import ANSI from .base import ( AnyFormattedText, FormattedText, + OneStyleAndTextTuple, StyleAndTextTuples, Template, is_formatted_text, @@ -35,6 +36,7 @@ from .utils import ( __all__ = [ # Base. "AnyFormattedText", + "OneStyleAndTextTuple", "to_formatted_text", "is_formatted_text", "Template", diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/formatted_text/utils.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/formatted_text/utils.py index b242c2cc89..c8c37e0946 100644 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/formatted_text/utils.py +++ b/contrib/python/prompt-toolkit/py3/prompt_toolkit/formatted_text/utils.py @@ -72,13 +72,15 @@ def fragment_list_to_text(fragments: StyleAndTextTuples) -> str: return "".join(item[1] for item in fragments if ZeroWidthEscape not in item[0]) -def split_lines(fragments: StyleAndTextTuples) -> Iterable[StyleAndTextTuples]: +def split_lines( + fragments: Iterable[OneStyleAndTextTuple], +) -> Iterable[StyleAndTextTuples]: """ Take a single list of (style_str, text) tuples and yield one such list for each line. Just like str.split, this will yield at least one item. - :param fragments: List of (style_str, text) or (style_str, text, mouse_handler) - tuples. + :param fragments: Iterable of ``(style_str, text)`` or + ``(style_str, text, mouse_handler)`` tuples. """ line: StyleAndTextTuples = [] diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/input/posix_utils.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/input/posix_utils.py index e9c73fecc6..4a78dc421b 100644 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/input/posix_utils.py +++ b/contrib/python/prompt-toolkit/py3/prompt_toolkit/input/posix_utils.py @@ -26,7 +26,7 @@ class PosixStdinReader: On Python3, this can be 'surrogateescape', which is the default. 'surrogateescape' is preferred, because this allows us to transfer - unrecognised bytes to the key bindings. Some terminals, like lxterminal + unrecognized bytes to the key bindings. Some terminals, like lxterminal and Guake, use the 'Mxx' notation to send mouse events, where each 'x' can be any possible byte. """ diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/key_binding/key_bindings.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/key_binding/key_bindings.py index 6abb595daf..62530f2b77 100644 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/key_binding/key_bindings.py +++ b/contrib/python/prompt-toolkit/py3/prompt_toolkit/key_binding/key_bindings.py @@ -40,8 +40,9 @@ from abc import ABCMeta, abstractmethod, abstractproperty from inspect import isawaitable from typing import ( TYPE_CHECKING, - Awaitable, + Any, Callable, + Coroutine, Hashable, Sequence, Tuple, @@ -89,7 +90,8 @@ __all__ = [ # This is mainly used in case of mouse move events, to prevent excessive # repainting during mouse move events. KeyHandlerCallable = Callable[ - ["KeyPressEvent"], Union["NotImplementedOrNone", Awaitable["NotImplementedOrNone"]] + ["KeyPressEvent"], + Union["NotImplementedOrNone", Coroutine[Any, Any, "NotImplementedOrNone"]], ] @@ -125,7 +127,7 @@ class Binding: # If the handler is a coroutine, create an asyncio task. if isawaitable(result): - awaitable = cast(Awaitable["NotImplementedOrNone"], result) + awaitable = cast(Coroutine[Any, Any, "NotImplementedOrNone"], result) async def bg_task() -> None: result = await awaitable diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/layout/containers.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/layout/containers.py index 5de87b08a7..100d4aaebc 100644 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/layout/containers.py +++ b/contrib/python/prompt-toolkit/py3/prompt_toolkit/layout/containers.py @@ -2050,7 +2050,7 @@ class Window(Container): new_buffer_row[x + xpos] = char # When we print a multi width character, make sure - # to erase the neighbours positions in the screen. + # to erase the neighbors positions in the screen. # (The empty string if different from everything, # so next redraw this cell will repaint anyway.) if char_width > 1: @@ -2537,7 +2537,7 @@ class Window(Container): scroll_offset_end=offsets.right, cursor_pos=get_cwidth(current_line_text[: ui_content.cursor_position.x]), window_size=width - current_line_prefix_width, - # We can only analyse the current line. Calculating the width off + # We can only analyze the current line. Calculating the width off # all the lines is too expensive. content_size=max( get_cwidth(current_line_text), self.horizontal_scroll + width diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/layout/controls.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/layout/controls.py index c13960bc43..c30c0effa8 100644 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/layout/controls.py +++ b/contrib/python/prompt-toolkit/py3/prompt_toolkit/layout/controls.py @@ -491,7 +491,7 @@ class _ProcessedLine(NamedTuple): class BufferControl(UIControl): """ - Control for visualising the content of a :class:`.Buffer`. + Control for visualizing the content of a :class:`.Buffer`. :param buffer: The :class:`.Buffer` object to be displayed. :param input_processors: A list of @@ -603,7 +603,7 @@ class BufferControl(UIControl): width can be done by calculating the longest line, but this would require applying all the processors to each line. This is unfeasible for a larger document, and doing it for small - documents only would result in inconsistent behaviour. + documents only would result in inconsistent behavior. """ return None diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/layout/menus.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/layout/menus.py index 1a21237a84..2c2ccb6436 100644 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/layout/menus.py +++ b/contrib/python/prompt-toolkit/py3/prompt_toolkit/layout/menus.py @@ -679,7 +679,7 @@ class MultiColumnCompletionsMenu(HSplit): filter=full_filter & show_meta & any_completion_has_meta, ) - # Initialise split. + # Initialize split. super().__init__([completions_window, meta_window], z_index=z_index) diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/layout/processors.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/layout/processors.py index 90c017ade7..b7376115e4 100644 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/layout/processors.py +++ b/contrib/python/prompt-toolkit/py3/prompt_toolkit/layout/processors.py @@ -288,7 +288,7 @@ class HighlightSelectionProcessor(Processor): if from_ == 0 and to == 0 and len(fragments) == 0: # When this is an empty line, insert a space in order to - # visualise the selection. + # visualize the selection. return Transformation([(selected_fragment, " ")]) else: for i in range(from_, to): diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/lexers/pygments.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/lexers/pygments.py index 16ed29a287..4721d730c8 100644 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/lexers/pygments.py +++ b/contrib/python/prompt-toolkit/py3/prompt_toolkit/lexers/pygments.py @@ -31,7 +31,7 @@ __all__ = [ class SyntaxSync(metaclass=ABCMeta): """ - Syntax synchroniser. This is a tool that finds a start position for the + Syntax synchronizer. This is a tool that finds a start position for the lexer. This is especially important when editing big documents; we don't want to start the highlighting by running the lexer from the beginning of the file. That is very slow when editing. @@ -67,12 +67,12 @@ class RegexSync(SyntaxSync): Synchronize by starting at a line that matches the given regex pattern. """ - # Never go more than this amount of lines backwards for synchronisation. + # Never go more than this amount of lines backwards for synchronization. # That would be too CPU intensive. MAX_BACKWARDS = 500 # Start lexing at the start, if we are in the first 'n' lines and no - # synchronisation position was found. + # synchronization position was found. FROM_START_IF_NO_SYNC_POS_FOUND = 100 def __init__(self, pattern: str) -> None: @@ -88,13 +88,13 @@ class RegexSync(SyntaxSync): lines = document.lines # Scan upwards, until we find a point where we can start the syntax - # synchronisation. + # synchronization. for i in range(lineno, max(-1, lineno - self.MAX_BACKWARDS), -1): match = pattern.match(lines[i]) if match: return i, match.start() - # No synchronisation point found. If we aren't that far from the + # No synchronization point found. If we aren't that far from the # beginning, start at the very beginning, otherwise, just try to start # at the current line. if lineno < self.FROM_START_IF_NO_SYNC_POS_FOUND: @@ -228,7 +228,7 @@ class PygmentsLexer(Lexer): line_generators: dict[LineGenerator, int] = {} def get_syntax_sync() -> SyntaxSync: - "The Syntax synchronisation object that we currently use." + "The Syntax synchronization object that we currently use." if self.sync_from_start(): return SyncFromStart() else: @@ -271,7 +271,7 @@ class PygmentsLexer(Lexer): return generator # No generator found. Determine starting point for the syntax - # synchronisation first. + # synchronization first. # Go at least x lines back. (Make scrolling upwards more # efficient.) @@ -291,7 +291,7 @@ class PygmentsLexer(Lexer): generator = create_line_generator(row, column) # If the column is not 0, ignore the first line. (Which is - # incomplete. This happens when the synchronisation algorithm tells + # incomplete. This happens when the synchronization algorithm tells # us to start parsing in the middle of a line.) if column: next(generator) @@ -316,7 +316,7 @@ class PygmentsLexer(Lexer): # Remove the next item from the cache. # (It could happen that it's already there, because of # another generator that started filling these lines, - # but we want to synchronise these lines with the + # but we want to synchronize these lines with the # current lexer's state.) if num + 1 in cache: del cache[num + 1] diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/output/base.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/output/base.py index 6b06a50eed..3c38cec86e 100644 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/output/base.py +++ b/contrib/python/prompt-toolkit/py3/prompt_toolkit/output/base.py @@ -66,7 +66,7 @@ class Output(metaclass=ABCMeta): @abstractmethod def erase_screen(self) -> None: """ - Erases the screen with the background colour and moves the cursor to + Erases the screen with the background color and moves the cursor to home. """ diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/output/vt100.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/output/vt100.py index 29743db21d..142deab077 100644 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/output/vt100.py +++ b/contrib/python/prompt-toolkit/py3/prompt_toolkit/output/vt100.py @@ -529,7 +529,7 @@ class Vt100_Output(Output): def erase_screen(self) -> None: """ - Erases the screen with the background colour and moves the cursor to + Erases the screen with the background color and moves the cursor to home. """ self.write_raw("\x1b[2J") diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/patch_stdout.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/patch_stdout.py index 81a7ccbb44..528bec7ffe 100644 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/patch_stdout.py +++ b/contrib/python/prompt-toolkit/py3/prompt_toolkit/patch_stdout.py @@ -43,7 +43,7 @@ def patch_stdout(raw: bool = False) -> Generator[None, None, None]: Writing to this proxy will make sure that the text appears above the prompt, and that it doesn't destroy the output from the renderer. If no - application is curring, the behaviour should be identical to writing to + application is curring, the behavior should be identical to writing to `sys.stdout` directly. Warning: If a new event loop is installed using `asyncio.set_event_loop()`, @@ -203,6 +203,13 @@ class StdoutProxy: """ def write_and_flush() -> None: + # Ensure that autowrap is enabled before calling `write`. + # XXX: On Windows, the `Windows10_Output` enables/disables VT + # terminal processing for every flush. It turns out that this + # causes autowrap to be reset (disabled) after each flush. So, + # we have to enable it again before writing text. + self._output.enable_autowrap() + if self.raw: self._output.write_raw(text) else: diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/renderer.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/renderer.py index 7a3b88a608..5ad1dd68d0 100644 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/renderer.py +++ b/contrib/python/prompt-toolkit/py3/prompt_toolkit/renderer.py @@ -233,7 +233,7 @@ def _output_screen_diff( # output. That way, we're sure that the terminal scrolls up, even when the # lower lines of the canvas just contain whitespace. - # The most obvious reason that we actually want this behaviour is the avoid + # The most obvious reason that we actually want this behavior is the avoid # the artifact of the input scrolling when the completion menu is shown. # (If the scrolling is actually wanted, the layout can still be build in a # way to behave that way by setting a dynamic height.) diff --git a/contrib/python/prompt-toolkit/py3/tests/test_async_generator.py b/contrib/python/prompt-toolkit/py3/tests/test_async_generator.py index 4a01c0e3d6..8c95f8c087 100644 --- a/contrib/python/prompt-toolkit/py3/tests/test_async_generator.py +++ b/contrib/python/prompt-toolkit/py3/tests/test_async_generator.py @@ -12,7 +12,7 @@ def _sync_generator(): def test_generator_to_async_generator(): """ - Test conversion of sync to asycn generator. + Test conversion of sync to async generator. This should run the synchronous parts in a background thread. """ async_gen = generator_to_async_generator(_sync_generator) diff --git a/contrib/python/prompt-toolkit/py3/tests/test_formatted_text.py b/contrib/python/prompt-toolkit/py3/tests/test_formatted_text.py index 2d8e184ade..843aac1619 100644 --- a/contrib/python/prompt-toolkit/py3/tests/test_formatted_text.py +++ b/contrib/python/prompt-toolkit/py3/tests/test_formatted_text.py @@ -28,7 +28,7 @@ def test_basic_html(): ] # It's important that `to_formatted_text` returns a `FormattedText` - # instance. Otherwise, `print_formatted_text` won't recognise it and will + # instance. Otherwise, `print_formatted_text` won't recognize it and will # print a list literal instead. assert isinstance(to_formatted_text(html), FormattedText) diff --git a/contrib/python/prompt-toolkit/py3/tests/test_widgets.py b/contrib/python/prompt-toolkit/py3/tests/test_widgets.py index 1fc8ae4398..ee7745a2d0 100644 --- a/contrib/python/prompt-toolkit/py3/tests/test_widgets.py +++ b/contrib/python/prompt-toolkit/py3/tests/test_widgets.py @@ -10,7 +10,7 @@ def _to_text(button: Button) -> str: return fragment_list_to_text(control.text()) -def test_defaulf_button(): +def test_default_button(): button = Button("Exit") assert _to_text(button) == "< Exit >" diff --git a/contrib/python/prompt-toolkit/py3/ya.make b/contrib/python/prompt-toolkit/py3/ya.make index 74bf71f6b0..90f446832b 100644 --- a/contrib/python/prompt-toolkit/py3/ya.make +++ b/contrib/python/prompt-toolkit/py3/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(3.0.41) +VERSION(3.0.43) LICENSE(BSD-3-Clause) diff --git a/contrib/python/pyasn1/py2/.dist-info/METADATA b/contrib/python/pyasn1/py2/.dist-info/METADATA index 530fe5bf7b..1a6727cecc 100644 --- a/contrib/python/pyasn1/py2/.dist-info/METADATA +++ b/contrib/python/pyasn1/py2/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pyasn1 -Version: 0.5.0 +Version: 0.5.1 Summary: Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208) Home-page: https://github.com/pyasn1/pyasn1 Author: Ilya Etingof @@ -32,6 +32,7 @@ Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Communications diff --git a/contrib/python/pyasn1/py2/pyasn1/__init__.py b/contrib/python/pyasn1/py2/pyasn1/__init__.py index a979d291f2..73d47f3424 100644 --- a/contrib/python/pyasn1/py2/pyasn1/__init__.py +++ b/contrib/python/pyasn1/py2/pyasn1/__init__.py @@ -1,2 +1,2 @@ # https://www.python.org/dev/peps/pep-0396/ -__version__ = '0.5.0' +__version__ = '0.5.1' diff --git a/contrib/python/pyasn1/py2/pyasn1/codec/ber/decoder.py b/contrib/python/pyasn1/py2/pyasn1/codec/ber/decoder.py index 070733fd28..7cc863d1c7 100644 --- a/contrib/python/pyasn1/py2/pyasn1/codec/ber/decoder.py +++ b/contrib/python/pyasn1/py2/pyasn1/codec/ber/decoder.py @@ -4,7 +4,10 @@ # Copyright (c) 2005-2020, Ilya Etingof <etingof@gmail.com> # License: https://pyasn1.readthedocs.io/en/latest/license.html # +import io import os +import sys + from pyasn1 import debug from pyasn1 import error @@ -1762,7 +1765,14 @@ class SingleItemDecoder(object): if state is stDecodeValue: if not options.get('recursiveFlag', True) and not substrateFun: # deprecate this - substrateFun = lambda a, b, c: (a, b[:c]) + def substrateFun(asn1Object, _substrate, _length, _options): + """Legacy hack to keep the recursiveFlag=False option supported. + + The decode(..., substrateFun=userCallback) option was introduced in 0.1.4 as a generalization + of the old recursiveFlag=False option. Users should pass their callback instead of using + recursiveFlag. + """ + yield asn1Object original_position = substrate.tell() @@ -1783,9 +1793,13 @@ class SingleItemDecoder(object): yield value bytesRead = substrate.tell() - original_position - if bytesRead != length: + if not substrateFun and bytesRead != length: raise PyAsn1Error( "Read %s bytes instead of expected %s." % (bytesRead, length)) + elif substrateFun and bytesRead > length: + # custom substrateFun may be used for partial decoding, reading less is expected there + raise PyAsn1Error( + "Read %s bytes are more than expected %s." % (bytesRead, length)) if LOG: LOG('codec %s yields type %s, value:\n%s\n...' % ( @@ -1959,6 +1973,27 @@ class Decoder(object): may not be required. Most common reason for it to require is that ASN.1 structure is encoded in *IMPLICIT* tagging mode. + substrateFun: :py:class:`Union[ + Callable[[pyasn1.type.base.PyAsn1Item, bytes, int], + Tuple[pyasn1.type.base.PyAsn1Item, bytes]], + Callable[[pyasn1.type.base.PyAsn1Item, io.BytesIO, int, dict], + Generator[Union[pyasn1.type.base.PyAsn1Item, + pyasn1.error.SubstrateUnderrunError], + None, None]] + ]` + User callback meant to generalize special use cases like non-recursive or + partial decoding. A 3-arg non-streaming variant is supported for backwards + compatiblilty in addition to the newer 4-arg streaming variant. + The callback will receive the uninitialized object recovered from substrate + as 1st argument, the uninterpreted payload as 2nd argument, and the length + of the uninterpreted payload as 3rd argument. The streaming variant will + additionally receive the decode(..., **options) kwargs as 4th argument. + The non-streaming variant shall return an object that will be propagated + as decode() return value as 1st item, and the remainig payload for further + decode passes as 2nd item. + The streaming variant shall yield an object that will be propagated as + decode() return value, and leave the remaining payload in the stream. + Returns ------- : :py:class:`tuple` @@ -1997,6 +2032,31 @@ class Decoder(object): """ substrate = asSeekableStream(substrate) + if "substrateFun" in options: + origSubstrateFun = options["substrateFun"] + + def substrateFunWrapper(asn1Object, substrate, length, options=None): + """Support both 0.4 and 0.5 style APIs. + + substrateFun API has changed in 0.5 for use with streaming decoders. To stay backwards compatible, + we first try if we received a streaming user callback. If that fails,we assume we've received a + non-streaming v0.4 user callback and convert it for streaming on the fly + """ + try: + substrate_gen = origSubstrateFun(asn1Object, substrate, length, options) + except TypeError: + _type, _value, traceback = sys.exc_info() + if traceback.tb_next: + # Traceback depth > 1 means TypeError from inside user provided function + raise + # invariant maintained at Decoder.__call__ entry + assert isinstance(substrate, io.BytesIO) # nosec assert_used + substrate_gen = Decoder._callSubstrateFunV4asV5(origSubstrateFun, asn1Object, substrate, length) + for value in substrate_gen: + yield value + + options["substrateFun"] = substrateFunWrapper + streamingDecoder = cls.STREAMING_DECODER( substrate, asn1Spec, **options) @@ -2012,6 +2072,16 @@ class Decoder(object): return asn1Object, tail + @staticmethod + def _callSubstrateFunV4asV5(substrateFunV4, asn1Object, substrate, length): + substrate_bytes = substrate.read() + if length == -1: + length = len(substrate_bytes) + value, nextSubstrate = substrateFunV4(asn1Object, substrate_bytes, length) + nbytes = substrate.write(nextSubstrate) + substrate.truncate() + substrate.seek(-nbytes, os.SEEK_CUR) + yield value #: Turns BER octet stream into an ASN.1 object. #: diff --git a/contrib/python/pyasn1/py2/tests/codec/ber/test_decoder.py b/contrib/python/pyasn1/py2/tests/codec/ber/test_decoder.py index 9e238cd458..35d12d0536 100644 --- a/contrib/python/pyasn1/py2/tests/codec/ber/test_decoder.py +++ b/contrib/python/pyasn1/py2/tests/codec/ber/test_decoder.py @@ -141,12 +141,24 @@ class BitStringDecoderTestCase(BaseTestCase): substrateFun=lambda a, b, c, d: streaming.readFromStream(b, c) ) == (ints2octs((3, 2, 0, 169, 3, 2, 1, 138)), str2octs('')) + def testDefModeChunkedSubstV04(self): + assert decoder.decode( + ints2octs((35, 8, 3, 2, 0, 169, 3, 2, 1, 138)), + substrateFun=lambda a, b, c: (b, b[c:]) + ) == (ints2octs((3, 2, 0, 169, 3, 2, 1, 138)), str2octs('')) + def testIndefModeChunkedSubst(self): assert decoder.decode( ints2octs((35, 128, 3, 2, 0, 169, 3, 2, 1, 138, 0, 0)), substrateFun=lambda a, b, c, d: streaming.readFromStream(b, c) ) == (ints2octs((3, 2, 0, 169, 3, 2, 1, 138, 0, 0)), str2octs('')) + def testIndefModeChunkedSubstV04(self): + assert decoder.decode( + ints2octs((35, 128, 3, 2, 0, 169, 3, 2, 1, 138, 0, 0)), + substrateFun=lambda a, b, c: (b, b[c:]) + ) == (ints2octs((3, 2, 0, 169, 3, 2, 1, 138, 0, 0)), str2octs('')) + def testTypeChecking(self): try: decoder.decode(ints2octs((35, 4, 2, 2, 42, 42))) @@ -185,6 +197,13 @@ class OctetStringDecoderTestCase(BaseTestCase): substrateFun=lambda a, b, c, d: streaming.readFromStream(b, c) ) == (ints2octs((4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120)), str2octs('')) + def testDefModeChunkedSubstV04(self): + assert decoder.decode( + ints2octs( + (36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120)), + substrateFun=lambda a, b, c: (b, b[c:]) + ) == (ints2octs((4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120)), str2octs('')) + def testIndefModeChunkedSubst(self): assert decoder.decode( ints2octs((36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, @@ -193,6 +212,14 @@ class OctetStringDecoderTestCase(BaseTestCase): ) == (ints2octs( (4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120, 0, 0)), str2octs('')) + def testIndefModeChunkedSubstV04(self): + assert decoder.decode( + ints2octs((36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, + 120, 0, 0)), + substrateFun=lambda a, b, c: (b, b[c:]) + ) == (ints2octs( + (4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120, 0, 0)), str2octs('')) + class ExpTaggedOctetStringDecoderTestCase(BaseTestCase): def setUp(self): @@ -245,6 +272,12 @@ class ExpTaggedOctetStringDecoderTestCase(BaseTestCase): substrateFun=lambda a, b, c, d: streaming.readFromStream(b, c) ) == (ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)), str2octs('')) + def testDefModeSubstV04(self): + assert decoder.decode( + ints2octs((101, 17, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)), + substrateFun=lambda a, b, c: (b, b[c:]) + ) == (ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)), str2octs('')) + def testIndefModeSubst(self): assert decoder.decode( ints2octs(( @@ -254,6 +287,15 @@ class ExpTaggedOctetStringDecoderTestCase(BaseTestCase): ) == (ints2octs( (36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0, 0, 0)), str2octs('')) + def testIndefModeSubstV04(self): + assert decoder.decode( + ints2octs(( + 101, 128, 36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, + 0, 0, 0)), + substrateFun=lambda a, b, c: (b, b[c:]) + ) == (ints2octs( + (36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0, 0, 0)), str2octs('')) + class NullDecoderTestCase(BaseTestCase): def testNull(self): @@ -680,6 +722,12 @@ class SequenceDecoderTestCase(BaseTestCase): substrateFun=lambda a, b, c, d: streaming.readFromStream(b, c) ) == (ints2octs((5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)), str2octs('')) + def testWithOptionalAndDefaultedDefModeSubstV04(self): + assert decoder.decode( + ints2octs((48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)), + substrateFun=lambda a, b, c: (b, b[c:]) + ) == (ints2octs((5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)), str2octs('')) + def testWithOptionalAndDefaultedIndefModeSubst(self): assert decoder.decode( ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), @@ -687,6 +735,13 @@ class SequenceDecoderTestCase(BaseTestCase): ) == (ints2octs( (5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), str2octs('')) + def testWithOptionalAndDefaultedIndefModeSubstV04(self): + assert decoder.decode( + ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), + substrateFun=lambda a, b, c: (b, b[c:]) + ) == (ints2octs( + (5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), str2octs('')) + def testTagFormat(self): try: decoder.decode( @@ -1166,6 +1221,12 @@ class SetDecoderTestCase(BaseTestCase): substrateFun=lambda a, b, c, d: streaming.readFromStream(b, c) ) == (ints2octs((5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)), str2octs('')) + def testWithOptionalAndDefaultedDefModeSubstV04(self): + assert decoder.decode( + ints2octs((49, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)), + substrateFun=lambda a, b, c: (b, b[c:]) + ) == (ints2octs((5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)), str2octs('')) + def testWithOptionalAndDefaultedIndefModeSubst(self): assert decoder.decode( ints2octs((49, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), @@ -1173,6 +1234,13 @@ class SetDecoderTestCase(BaseTestCase): ) == (ints2octs( (5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), str2octs('')) + def testWithOptionalAndDefaultedIndefModeSubstV04(self): + assert decoder.decode( + ints2octs((49, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), + substrateFun=lambda a, b, c: (b, b[c:]) + ) == (ints2octs( + (5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), str2octs('')) + def testTagFormat(self): try: decoder.decode( @@ -1498,6 +1566,13 @@ class AnyDecoderTestCase(BaseTestCase): substrateFun=lambda a, b, c, d: streaming.readFromStream(b, c) ) == (ints2octs((4, 3, 102, 111, 120)), str2octs('')) + def testByUntaggedSubstV04(self): + assert decoder.decode( + ints2octs((4, 3, 102, 111, 120)), + asn1Spec=self.s, + substrateFun=lambda a, b, c: (b, b[c:]) + ) == (ints2octs((4, 3, 102, 111, 120)), str2octs('')) + def testTaggedExSubst(self): assert decoder.decode( ints2octs((164, 5, 4, 3, 102, 111, 120)), @@ -1505,6 +1580,13 @@ class AnyDecoderTestCase(BaseTestCase): substrateFun=lambda a, b, c, d: streaming.readFromStream(b, c) ) == (ints2octs((164, 5, 4, 3, 102, 111, 120)), str2octs('')) + def testTaggedExSubstV04(self): + assert decoder.decode( + ints2octs((164, 5, 4, 3, 102, 111, 120)), + asn1Spec=self.s, + substrateFun=lambda a, b, c: (b, b[c:]) + ) == (ints2octs((164, 5, 4, 3, 102, 111, 120)), str2octs('')) + class EndOfOctetsTestCase(BaseTestCase): def testUnexpectedEoo(self): @@ -1841,6 +1923,50 @@ class CompressedFilesTestCase(BaseTestCase): os.remove(path) +class NonStreamingCompatibilityTestCase(BaseTestCase): + def setUp(self): + from pyasn1 import debug + BaseTestCase.setUp(self) + debug.setLogger(None) # undo logger setup from BaseTestCase to work around unrelated issue + + def testPartialDecodeWithCustomSubstrateFun(self): + snmp_req_substrate = ints2octs(( + 0x30, 0x22, 0x02, 0x01, 0x01, 0x04, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0xa0, 0x15, 0x02, 0x04, 0x69, + 0x30, 0xdb, 0xeb, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x30, 0x07, 0x30, 0x05, 0x06, 0x01, 0x01, 0x05, 0x00)) + seq, next_substrate = decoder.decode( + snmp_req_substrate, asn1Spec=univ.Sequence(), + recursiveFlag=False, substrateFun=lambda a, b, c: (a, b[:c]) + ) + assert seq.isSameTypeWith(univ.Sequence) + assert next_substrate == snmp_req_substrate[2:] + version, next_substrate = decoder.decode( + next_substrate, asn1Spec=univ.Integer(), recursiveFlag=False, + substrateFun=lambda a, b, c: (a, b[:c]) + ) + assert version == 1 + + def testPartialDecodeWithDefaultSubstrateFun(self): + substrate = ints2octs(( + 0x04, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x3c, 0x03, 0x02 + )) + result, rest = decoder.decode(substrate, recursiveFlag=False) + assert result.isSameTypeWith(univ.OctetString) + assert rest == substrate[2:] + + def testPropagateUserException(self): + substrate = io.BytesIO(ints2octs((0x04, 0x00))) + + def userSubstrateFun(_asn1Object, _substrate, _length, _options): + raise TypeError("error inside user function") + + try: + decoder.decode(substrate, asn1Spec=univ.OctetString, substrateFun=userSubstrateFun) + except TypeError as exc: + assert str(exc) == "error inside user function" + else: + raise AssertionError("decode() must not hide TypeError from inside user provided callback") + + suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': diff --git a/contrib/python/pyasn1/py2/ya.make b/contrib/python/pyasn1/py2/ya.make index cd11432c2f..78da352060 100644 --- a/contrib/python/pyasn1/py2/ya.make +++ b/contrib/python/pyasn1/py2/ya.make @@ -2,7 +2,7 @@ PY2_LIBRARY() -VERSION(0.5.0) +VERSION(0.5.1) LICENSE(BSD-3-Clause) diff --git a/contrib/python/ruamel.yaml.clib/py2/.dist-info/METADATA b/contrib/python/ruamel.yaml.clib/py2/.dist-info/METADATA index 7b8ca2a332..6c952ac9d6 100644 --- a/contrib/python/ruamel.yaml.clib/py2/.dist-info/METADATA +++ b/contrib/python/ruamel.yaml.clib/py2/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: ruamel.yaml.clib -Version: 0.2.7 +Version: 0.2.2 Summary: C version of reader, parser and emitter for ruamel.yaml derived from libyaml Home-page: https://sourceforge.net/p/ruamel-yaml-clib/code/ci/default/tree Author: Anthon van der Neut @@ -13,17 +13,14 @@ Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 -Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Topic :: Software Development :: Libraries :: Python Modules -Requires-Python: >=3.6 Description-Content-Type: text/x-rst -License-File: LICENSE ruamel.yaml.clib @@ -31,8 +28,8 @@ ruamel.yaml.clib ``ruamel.yaml.clib`` is the C based reader/scanner and emitter for ruamel.yaml -:version: 0.2.7 -:updated: 2022-10-19 +:version: 0.2.2 +:updated: 2020-09-04 :documentation: http://yaml.readthedocs.io :repository: https://sourceforge.net/projects/ruamel-yaml-clib/ :pypi: https://pypi.org/project/ruamel.yaml.clib/ @@ -49,7 +46,6 @@ directory) and the Python code for ruamel.yaml under /usr/lib/pythonX.Y. .. image:: https://sourceforge.net/p/ruamel-yaml-clib/code/ci/default/tree/_doc/_static/license.svg?format=raw :target: https://opensource.org/licenses/MIT - -This release in loving memory of Johanna Clasina van der Neut-Bandel [1922-10-19 - 2015-11-21] + diff --git a/contrib/python/ruamel.yaml.clib/py2/LICENSE b/contrib/python/ruamel.yaml.clib/py2/LICENSE index 786ebed939..630d5ecbac 100644 --- a/contrib/python/ruamel.yaml.clib/py2/LICENSE +++ b/contrib/python/ruamel.yaml.clib/py2/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) - Copyright (c) 2019-2022 Anthon van der Neut, Ruamel bvba + Copyright (c) 2019-2020 Anthon van der Neut, Ruamel bvba Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/contrib/python/ruamel.yaml.clib/py2/README.rst b/contrib/python/ruamel.yaml.clib/py2/README.rst index c41aca60e6..c8fc5e463c 100644 --- a/contrib/python/ruamel.yaml.clib/py2/README.rst +++ b/contrib/python/ruamel.yaml.clib/py2/README.rst @@ -4,8 +4,8 @@ ruamel.yaml.clib ``ruamel.yaml.clib`` is the C based reader/scanner and emitter for ruamel.yaml -:version: 0.2.6 -:updated: 2021-07-04 +:version: 0.2.2 +:updated: 2020-09-04 :documentation: http://yaml.readthedocs.io :repository: https://sourceforge.net/projects/ruamel-yaml-clib/ :pypi: https://pypi.org/project/ruamel.yaml.clib/ diff --git a/contrib/python/ruamel.yaml.clib/py2/ya.make b/contrib/python/ruamel.yaml.clib/py2/ya.make index 0f53126bd7..b4bf40fbce 100644 --- a/contrib/python/ruamel.yaml.clib/py2/ya.make +++ b/contrib/python/ruamel.yaml.clib/py2/ya.make @@ -1,6 +1,8 @@ +# Generated by devtools/yamaker (pypi). + PY2_LIBRARY() -VERSION(0.2.7) +VERSION(0.2.2) LICENSE(MIT) diff --git a/contrib/python/ruamel.yaml.clib/py3/.dist-info/METADATA b/contrib/python/ruamel.yaml.clib/py3/.dist-info/METADATA index 7b8ca2a332..01aea7bcfa 100644 --- a/contrib/python/ruamel.yaml.clib/py3/.dist-info/METADATA +++ b/contrib/python/ruamel.yaml.clib/py3/.dist-info/METADATA @@ -1,13 +1,12 @@ Metadata-Version: 2.1 Name: ruamel.yaml.clib -Version: 0.2.7 +Version: 0.2.8 Summary: C version of reader, parser and emitter for ruamel.yaml derived from libyaml Home-page: https://sourceforge.net/p/ruamel-yaml-clib/code/ci/default/tree Author: Anthon van der Neut Author-email: a.van.der.neut@ruamel.eu License: MIT Keywords: yaml 1.2 parser c-library config -Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License @@ -51,5 +50,3 @@ directory) and the Python code for ruamel.yaml under /usr/lib/pythonX.Y. :target: https://opensource.org/licenses/MIT This release in loving memory of Johanna Clasina van der Neut-Bandel [1922-10-19 - 2015-11-21] - - diff --git a/contrib/python/ruamel.yaml.clib/py3/LICENSE b/contrib/python/ruamel.yaml.clib/py3/LICENSE index 786ebed939..2383b7c6c4 100644 --- a/contrib/python/ruamel.yaml.clib/py3/LICENSE +++ b/contrib/python/ruamel.yaml.clib/py3/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) - Copyright (c) 2019-2022 Anthon van der Neut, Ruamel bvba + Copyright (c) 2019-2023 Anthon van der Neut, Ruamel bvba Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/contrib/python/ruamel.yaml.clib/py3/README.rst b/contrib/python/ruamel.yaml.clib/py3/README.rst index c41aca60e6..0e83f9e423 100644 --- a/contrib/python/ruamel.yaml.clib/py3/README.rst +++ b/contrib/python/ruamel.yaml.clib/py3/README.rst @@ -4,8 +4,8 @@ ruamel.yaml.clib ``ruamel.yaml.clib`` is the C based reader/scanner and emitter for ruamel.yaml -:version: 0.2.6 -:updated: 2021-07-04 +:version: 0.2.7 +:updated: 2022-10-19 :documentation: http://yaml.readthedocs.io :repository: https://sourceforge.net/projects/ruamel-yaml-clib/ :pypi: https://pypi.org/project/ruamel.yaml.clib/ @@ -23,3 +23,4 @@ directory) and the Python code for ruamel.yaml under /usr/lib/pythonX.Y. .. image:: https://sourceforge.net/p/ruamel-yaml-clib/code/ci/default/tree/_doc/_static/license.svg?format=raw :target: https://opensource.org/licenses/MIT +This release in loving memory of Johanna Clasina van der Neut-Bandel [1922-10-19 - 2015-11-21] diff --git a/contrib/python/ruamel.yaml.clib/py3/ya.make b/contrib/python/ruamel.yaml.clib/py3/ya.make index af7562fd1c..1c874c3925 100644 --- a/contrib/python/ruamel.yaml.clib/py3/ya.make +++ b/contrib/python/ruamel.yaml.clib/py3/ya.make @@ -1,6 +1,8 @@ +# Generated by devtools/yamaker (pypi). + PY3_LIBRARY() -VERSION(0.2.7) +VERSION(0.2.8) LICENSE(MIT) diff --git a/contrib/python/typing-extensions/py3/.dist-info/METADATA b/contrib/python/typing-extensions/py3/.dist-info/METADATA index dc7c951a0f..863e977c2f 100644 --- a/contrib/python/typing-extensions/py3/.dist-info/METADATA +++ b/contrib/python/typing-extensions/py3/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: typing_extensions -Version: 4.8.0 +Version: 4.9.0 Summary: Backported and Experimental Type Hints for Python 3.8+ Keywords: annotations,backport,checker,checking,function,hinting,hints,type,typechecking,typehinting,typehints,typing Author-email: "Guido van Rossum, Jukka Lehtosalo, Łukasz Langa, Michael Lee" <levkivskyi@gmail.com> diff --git a/contrib/python/typing-extensions/py3/typing_extensions.py b/contrib/python/typing-extensions/py3/typing_extensions.py index c96bf90fec..1666e96b7e 100644 --- a/contrib/python/typing-extensions/py3/typing_extensions.py +++ b/contrib/python/typing-extensions/py3/typing_extensions.py @@ -86,6 +86,7 @@ __all__ = [ 'TYPE_CHECKING', 'Never', 'NoReturn', + 'ReadOnly', 'Required', 'NotRequired', @@ -473,6 +474,7 @@ _EXCLUDED_ATTRS = { "__orig_bases__", "__module__", "_MutableMapping__marker", "__doc__", "__subclasshook__", "__orig_class__", "__init__", "__new__", "__protocol_attrs__", "__callable_proto_members_only__", + "__match_args__", } if sys.version_info >= (3, 9): @@ -503,9 +505,9 @@ def _caller(depth=2): return None -# The performance of runtime-checkable protocols is significantly improved on Python 3.12, -# so we backport the 3.12 version of Protocol to Python <=3.11 -if sys.version_info >= (3, 12): +# `__match_args__` attribute was removed from protocol members in 3.13, +# we want to backport this change to older Python versions. +if sys.version_info >= (3, 13): Protocol = typing.Protocol else: def _allow_reckless_class_checks(depth=3): @@ -569,8 +571,13 @@ else: not cls.__callable_proto_members_only__ and cls.__dict__.get("__subclasshook__") is _proto_hook ): + non_method_attrs = sorted( + attr for attr in cls.__protocol_attrs__ + if not callable(getattr(cls, attr, None)) + ) raise TypeError( - "Protocols with non-method members don't support issubclass()" + "Protocols with non-method members don't support issubclass()." + f" Non-method members: {str(non_method_attrs)[1:-1]}." ) if not getattr(cls, '_is_runtime_protocol', False): raise TypeError( @@ -767,7 +774,7 @@ def _ensure_subclassable(mro_entries): return inner -if sys.version_info >= (3, 13): +if hasattr(typing, "ReadOnly"): # The standard library TypedDict in Python 3.8 does not store runtime information # about which (if any) keys are optional. See https://bugs.python.org/issue38834 # The standard library TypedDict in Python 3.9.0/1 does not honour the "total" @@ -778,6 +785,7 @@ if sys.version_info >= (3, 13): # Aaaand on 3.12 we add __orig_bases__ to TypedDict # to enable better runtime introspection. # On 3.13 we deprecate some odd ways of creating TypedDicts. + # PEP 705 proposes adding the ReadOnly[] qualifier. TypedDict = typing.TypedDict _TypedDictMeta = typing._TypedDictMeta is_typeddict = typing.is_typeddict @@ -785,8 +793,29 @@ else: # 3.10.0 and later _TAKES_MODULE = "module" in inspect.signature(typing._type_check).parameters + def _get_typeddict_qualifiers(annotation_type): + while True: + annotation_origin = get_origin(annotation_type) + if annotation_origin is Annotated: + annotation_args = get_args(annotation_type) + if annotation_args: + annotation_type = annotation_args[0] + else: + break + elif annotation_origin is Required: + yield Required + annotation_type, = get_args(annotation_type) + elif annotation_origin is NotRequired: + yield NotRequired + annotation_type, = get_args(annotation_type) + elif annotation_origin is ReadOnly: + yield ReadOnly + annotation_type, = get_args(annotation_type) + else: + break + class _TypedDictMeta(type): - def __new__(cls, name, bases, ns, total=True): + def __new__(cls, name, bases, ns, *, total=True): """Create new typed dict class object. This method is called when TypedDict is subclassed, @@ -829,33 +858,46 @@ else: } required_keys = set() optional_keys = set() + readonly_keys = set() + mutable_keys = set() for base in bases: - annotations.update(base.__dict__.get('__annotations__', {})) - required_keys.update(base.__dict__.get('__required_keys__', ())) - optional_keys.update(base.__dict__.get('__optional_keys__', ())) + base_dict = base.__dict__ + + annotations.update(base_dict.get('__annotations__', {})) + required_keys.update(base_dict.get('__required_keys__', ())) + optional_keys.update(base_dict.get('__optional_keys__', ())) + readonly_keys.update(base_dict.get('__readonly_keys__', ())) + mutable_keys.update(base_dict.get('__mutable_keys__', ())) annotations.update(own_annotations) for annotation_key, annotation_type in own_annotations.items(): - annotation_origin = get_origin(annotation_type) - if annotation_origin is Annotated: - annotation_args = get_args(annotation_type) - if annotation_args: - annotation_type = annotation_args[0] - annotation_origin = get_origin(annotation_type) - - if annotation_origin is Required: + qualifiers = set(_get_typeddict_qualifiers(annotation_type)) + + if Required in qualifiers: required_keys.add(annotation_key) - elif annotation_origin is NotRequired: + elif NotRequired in qualifiers: optional_keys.add(annotation_key) elif total: required_keys.add(annotation_key) else: optional_keys.add(annotation_key) + if ReadOnly in qualifiers: + if annotation_key in mutable_keys: + raise TypeError( + f"Cannot override mutable key {annotation_key!r}" + " with read-only key" + ) + readonly_keys.add(annotation_key) + else: + mutable_keys.add(annotation_key) + readonly_keys.discard(annotation_key) tp_dict.__annotations__ = annotations tp_dict.__required_keys__ = frozenset(required_keys) tp_dict.__optional_keys__ = frozenset(optional_keys) + tp_dict.__readonly_keys__ = frozenset(readonly_keys) + tp_dict.__mutable_keys__ = frozenset(mutable_keys) if not hasattr(tp_dict, '__total__'): tp_dict.__total__ = total return tp_dict @@ -936,6 +978,8 @@ else: raise TypeError("TypedDict takes either a dict or keyword arguments," " but not both") if kwargs: + if sys.version_info >= (3, 13): + raise TypeError("TypedDict takes no keyword arguments") warnings.warn( "The kwargs-based syntax for TypedDict definitions is deprecated " "in Python 3.11, will be removed in Python 3.13, and may not be " @@ -1924,6 +1968,53 @@ else: # 3.8 """) +if hasattr(typing, 'ReadOnly'): + ReadOnly = typing.ReadOnly +elif sys.version_info[:2] >= (3, 9): # 3.9-3.12 + @_ExtensionsSpecialForm + def ReadOnly(self, parameters): + """A special typing construct to mark an item of a TypedDict as read-only. + + For example: + + class Movie(TypedDict): + title: ReadOnly[str] + year: int + + def mutate_movie(m: Movie) -> None: + m["year"] = 1992 # allowed + m["title"] = "The Matrix" # typechecker error + + There is no runtime checking for this property. + """ + item = typing._type_check(parameters, f'{self._name} accepts only a single type.') + return typing._GenericAlias(self, (item,)) + +else: # 3.8 + class _ReadOnlyForm(_ExtensionsSpecialForm, _root=True): + def __getitem__(self, parameters): + item = typing._type_check(parameters, + f'{self._name} accepts only a single type.') + return typing._GenericAlias(self, (item,)) + + ReadOnly = _ReadOnlyForm( + 'ReadOnly', + doc="""A special typing construct to mark a key of a TypedDict as read-only. + + For example: + + class Movie(TypedDict): + title: ReadOnly[str] + year: int + + def mutate_movie(m: Movie) -> None: + m["year"] = 1992 # allowed + m["title"] = "The Matrix" # typechecker error + + There is no runtime checking for this propery. + """) + + _UNPACK_DOC = """\ Type unpack operator. @@ -2251,7 +2342,7 @@ else: # <=3.11 Usage: class Base: - def method(self) -> None: ... + def method(self) -> None: pass class Child(Base): @@ -2281,20 +2372,17 @@ else: # <=3.11 return arg -if hasattr(typing, "deprecated"): - deprecated = typing.deprecated +if hasattr(warnings, "deprecated"): + deprecated = warnings.deprecated else: _T = typing.TypeVar("_T") - def deprecated( - msg: str, - /, - *, - category: typing.Optional[typing.Type[Warning]] = DeprecationWarning, - stacklevel: int = 1, - ) -> typing.Callable[[_T], _T]: + class deprecated: """Indicate that a class, function or overload is deprecated. + When this decorator is applied to an object, the type checker + will generate a diagnostic on usage of the deprecated object. + Usage: @deprecated("Use B instead") @@ -2311,49 +2399,100 @@ else: @overload def g(x: str) -> int: ... - When this decorator is applied to an object, the type checker - will generate a diagnostic on usage of the deprecated object. - - The warning specified by ``category`` will be emitted on use - of deprecated objects. For functions, that happens on calls; - for classes, on instantiation. If the ``category`` is ``None``, - no warning is emitted. The ``stacklevel`` determines where the + The warning specified by *category* will be emitted at runtime + on use of deprecated objects. For functions, that happens on calls; + for classes, on instantiation and on creation of subclasses. + If the *category* is ``None``, no warning is emitted at runtime. + The *stacklevel* determines where the warning is emitted. If it is ``1`` (the default), the warning is emitted at the direct caller of the deprecated object; if it is higher, it is emitted further up the stack. + Static type checker behavior is not affected by the *category* + and *stacklevel* arguments. - The decorator sets the ``__deprecated__`` - attribute on the decorated object to the deprecation message - passed to the decorator. If applied to an overload, the decorator + The deprecation message passed to the decorator is saved in the + ``__deprecated__`` attribute on the decorated object. + If applied to an overload, the decorator must be after the ``@overload`` decorator for the attribute to exist on the overload as returned by ``get_overloads()``. See PEP 702 for details. """ - def decorator(arg: _T, /) -> _T: + def __init__( + self, + message: str, + /, + *, + category: typing.Optional[typing.Type[Warning]] = DeprecationWarning, + stacklevel: int = 1, + ) -> None: + if not isinstance(message, str): + raise TypeError( + "Expected an object of type str for 'message', not " + f"{type(message).__name__!r}" + ) + self.message = message + self.category = category + self.stacklevel = stacklevel + + def __call__(self, arg: _T, /) -> _T: + # Make sure the inner functions created below don't + # retain a reference to self. + msg = self.message + category = self.category + stacklevel = self.stacklevel if category is None: arg.__deprecated__ = msg return arg elif isinstance(arg, type): + import functools + from types import MethodType + original_new = arg.__new__ - has_init = arg.__init__ is not object.__init__ @functools.wraps(original_new) def __new__(cls, *args, **kwargs): - warnings.warn(msg, category=category, stacklevel=stacklevel + 1) + if cls is arg: + warnings.warn(msg, category=category, stacklevel=stacklevel + 1) if original_new is not object.__new__: return original_new(cls, *args, **kwargs) # Mirrors a similar check in object.__new__. - elif not has_init and (args or kwargs): + elif cls.__init__ is object.__init__ and (args or kwargs): raise TypeError(f"{cls.__name__}() takes no arguments") else: return original_new(cls) arg.__new__ = staticmethod(__new__) + + original_init_subclass = arg.__init_subclass__ + # We need slightly different behavior if __init_subclass__ + # is a bound method (likely if it was implemented in Python) + if isinstance(original_init_subclass, MethodType): + original_init_subclass = original_init_subclass.__func__ + + @functools.wraps(original_init_subclass) + def __init_subclass__(*args, **kwargs): + warnings.warn(msg, category=category, stacklevel=stacklevel + 1) + return original_init_subclass(*args, **kwargs) + + arg.__init_subclass__ = classmethod(__init_subclass__) + # Or otherwise, which likely means it's a builtin such as + # object's implementation of __init_subclass__. + else: + @functools.wraps(original_init_subclass) + def __init_subclass__(*args, **kwargs): + warnings.warn(msg, category=category, stacklevel=stacklevel + 1) + return original_init_subclass(*args, **kwargs) + + arg.__init_subclass__ = __init_subclass__ + arg.__deprecated__ = __new__.__deprecated__ = msg + __init_subclass__.__deprecated__ = msg return arg elif callable(arg): + import functools + @functools.wraps(arg) def wrapper(*args, **kwargs): warnings.warn(msg, category=category, stacklevel=stacklevel + 1) @@ -2367,8 +2506,6 @@ else: f"a class or callable, not {arg!r}" ) - return decorator - # We have to do some monkey patching to deal with the dual nature of # Unpack/TypeVarTuple: @@ -2437,11 +2574,35 @@ else: class_getitem = typing.Generic.__class_getitem__.__func__ nm_tpl.__class_getitem__ = classmethod(class_getitem) # update from user namespace without overriding special namedtuple attributes - for key in ns: + for key, val in ns.items(): if key in _prohibited_namedtuple_fields: raise AttributeError("Cannot overwrite NamedTuple attribute " + key) - elif key not in _special_namedtuple_fields and key not in nm_tpl._fields: - setattr(nm_tpl, key, ns[key]) + elif key not in _special_namedtuple_fields: + if key not in nm_tpl._fields: + setattr(nm_tpl, key, ns[key]) + try: + set_name = type(val).__set_name__ + except AttributeError: + pass + else: + try: + set_name(val, nm_tpl, key) + except BaseException as e: + msg = ( + f"Error calling __set_name__ on {type(val).__name__!r} " + f"instance {key!r} in {typename!r}" + ) + # BaseException.add_note() existed on py311, + # but the __set_name__ machinery didn't start + # using add_note() until py312. + # Making sure exceptions are raised in the same way + # as in "normal" classes seems most important here. + if sys.version_info >= (3, 12): + e.add_note(msg) + raise + else: + raise RuntimeError(msg) from e + if typing.Generic in bases: nm_tpl.__init_subclass__() return nm_tpl @@ -2600,7 +2761,7 @@ else: num = UserId(5) + 1 # type: int """ - def __call__(self, obj): + def __call__(self, obj, /): return obj def __init__(self, name, tp): diff --git a/contrib/python/typing-extensions/py3/ya.make b/contrib/python/typing-extensions/py3/ya.make index d6837aed7b..1e65722a16 100644 --- a/contrib/python/typing-extensions/py3/ya.make +++ b/contrib/python/typing-extensions/py3/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(4.8.0) +VERSION(4.9.0) LICENSE(PSF-2.0) diff --git a/contrib/python/wcwidth/py2/.dist-info/METADATA b/contrib/python/wcwidth/py2/.dist-info/METADATA index ce98bebb24..2539b52f73 100644 --- a/contrib/python/wcwidth/py2/.dist-info/METADATA +++ b/contrib/python/wcwidth/py2/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: wcwidth -Version: 0.2.6 +Version: 0.2.12 Summary: Measures the displayed width of unicode strings in a terminal Home-page: https://github.com/jquast/wcwidth Author: Jeff Quast @@ -18,12 +18,16 @@ Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 Classifier: Topic :: Software Development :: Libraries Classifier: Topic :: Software Development :: Localization Classifier: Topic :: Software Development :: Internationalization Classifier: Topic :: Terminals License-File: LICENSE -Requires-Dist: backports.functools-lru-cache (>=1.2.1) ; python_version < "3.2" +Requires-Dist: backports.functools-lru-cache >=1.2.1 ; python_version < "3.2" |pypi_downloads| |codecov| |license| @@ -122,7 +126,7 @@ Briefly, return values of function ``wcwidth()`` are: Function ``wcswidth()`` simply returns the sum of all values for each character along a string, or ``-1`` when it occurs anywhere along a string. -Full API Documentation at http://wcwidth.readthedocs.org +Full API Documentation at https://wcwidth.readthedocs.org ========== Developing @@ -130,32 +134,70 @@ Developing Install wcwidth in editable mode:: - pip install -e. + pip install -e . Execute unit tests using tox_:: - tox + tox -e py27,py35,py36,py37,py38,py39,py310,py311,py312 + +Updating Unicode Version +------------------------ Regenerate python code tables from latest Unicode Specification data files:: tox -e update +The script is located at ``bin/update-tables.py``, requires Python 3.9 or +later. It is recommended but not necessary to run this script with the newest +Python, because the newest Python has the latest ``unicodedata`` for generating +comments. + +Building Documentation +---------------------- + +This project is using `sphinx`_ 4.5 to build documentation:: + + tox -e sphinx + +The output will be in ``docs/_build/html/``. + +Updating Requirements +--------------------- + +This project is using `pip-tools`_ to manage requirements. + +To upgrade requirements for updating unicode version, run:: + + tox -e update_requirements_update + +To upgrade requirements for testing, run:: + + tox -e update_requirements37,update_requirements39 + +To upgrade requirements for building documentation, run:: + + tox -e update_requirements_docs + +Utilities +--------- + Supplementary tools for browsing and testing terminals for wide unicode characters are found in the `bin/`_ of this project's source code. Just ensure -to first ``pip install -erequirements-develop.txt`` from this projects main +to first ``pip install -r requirements-develop.txt`` from this projects main folder. For example, an interactive browser for testing:: python ./bin/wcwidth-browser.py +==== Uses ----- +==== This library is used in: - `jquast/blessed`_: a thin, practical wrapper around terminal capabilities in Python. -- `jonathanslenders/python-prompt-toolkit`_: a Library for building powerful +- `prompt-toolkit/python-prompt-toolkit`_: a Library for building powerful interactive command lines in Python. - `dbcli/pgcli`_: Postgres CLI with autocompletion and syntax highlighting. @@ -168,7 +210,7 @@ This library is used in: - `astanin/python-tabulate`_: Pretty-print tabular data in Python, a library and a command-line utility. -- `LuminosoInsight/python-ftfy`_: Fixes mojibake and other glitches in Unicode +- `rspeer/python-ftfy`_: Fixes mojibake and other glitches in Unicode text. - `nbedos/termtosvg`_: Terminal recorder that renders sessions as SVG @@ -177,23 +219,57 @@ This library is used in: - `peterbrittain/asciimatics`_: Package to help people create full-screen text UIs. +- `python-cmd2/cmd2`_: A tool for building interactive command line apps + +- `stratis-storage/stratis-cli`_: CLI for the Stratis project + +- `ihabunek/toot`_: A Mastodon CLI/TUI client + +- `saulpw/visidata`_: Terminal spreadsheet multitool for discovering and + arranging data + +=============== Other Languages ---------------- +=============== - `timoxley/wcwidth`_: JavaScript - `janlelis/unicode-display_width`_: Ruby - `alecrabbit/php-wcwidth`_: PHP - `Text::CharWidth`_: Perl -- `bluebear94/Terminal-WCWidth`: Perl 6 +- `bluebear94/Terminal-WCWidth`_: Perl 6 - `mattn/go-runewidth`_: Go -- `emugel/wcwidth`_: Haxe -- `aperezdc/lua-wcwidth`: Lua -- `joachimschmidt557/zig-wcwidth`: Zig -- `fumiyas/wcwidth-cjk`: `LD_PRELOAD` override -- `joshuarubin/wcwidth9`: Unicode version 9 in C +- `grepsuzette/wcwidth`_: Haxe +- `aperezdc/lua-wcwidth`_: Lua +- `joachimschmidt557/zig-wcwidth`_: Zig +- `fumiyas/wcwidth-cjk`_: `LD_PRELOAD` override +- `joshuarubin/wcwidth9`_: Unicode version 9 in C +======= History -------- +======= +0.2.12 *2023-11-21* + * re-release to remove .pyi file misplaced in wheel files `Issue #101`. + +0.2.11 *2023-11-20* + * Include tests files in the source distribution (`PR #98`_, `PR #100`_). + +0.2.10 *2023-11-13* + * **Bugfix** accounting of some kinds of emoji sequences using U+FE0F + Variation Selector 16 (`PR #97`_). + * **Updated** `Specification <Specification_from_pypi_>`_. + +0.2.9 *2023-10-30* + * **Bugfix** zero-width characters used in Emoji ZWJ sequences, Balinese, + Jamo, Devanagari, Tamil, Kannada and others (`PR #91`_). + * **Updated** to include `Specification <Specification_from_pypi_>`_ of + character measurements. + +0.2.8 *2023-09-30* + * Include requirements files in the source distribution (`PR #82`_). + +0.2.7 *2023-09-28* + * **Updated** tables to include Unicode Specification 15.1.0. + * Include ``bin``, ``docs``, and ``tox.ini`` in the source distribution 0.2.6 *2023-01-14* * **Updated** tables to include Unicode Specification 14.0.0 and 15.0.0. @@ -259,7 +335,7 @@ History This code was originally derived directly from C code of the same name, whose latest version is available at -http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c:: +https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c:: * Markus Kuhn -- 2007-05-26 (Unicode 5.0) * @@ -267,11 +343,12 @@ http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c:: * for any purpose and without fee is hereby granted. The author * disclaims all warranties with regard to this software. -.. _`tox`: https://testrun.org/tox/latest/install.html +.. _`Specification_from_pypi`: https://wcwidth.readthedocs.io/en/latest/specs.html +.. _`tox`: https://tox.wiki/en/latest/ .. _`prospector`: https://github.com/landscapeio/prospector .. _`combining`: https://en.wikipedia.org/wiki/Combining_character .. _`bin/`: https://github.com/jquast/wcwidth/tree/master/bin -.. _`bin/wcwidth-browser.py`: https://github.com/jquast/wcwidth/tree/master/bin/wcwidth-browser.py +.. _`bin/wcwidth-browser.py`: https://github.com/jquast/wcwidth/blob/master/bin/wcwidth-browser.py .. _`Thomas Ballinger`: https://github.com/thomasballinger .. _`Leta Montopoli`: https://github.com/lmontopo .. _`Philip Craig`: https://github.com/philipc @@ -282,34 +359,48 @@ http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c:: .. _`PR #18`: https://github.com/jquast/wcwidth/pull/18 .. _`PR #30`: https://github.com/jquast/wcwidth/pull/30 .. _`PR #35`: https://github.com/jquast/wcwidth/pull/35 +.. _`PR #82`: https://github.com/jquast/wcwidth/pull/82 +.. _`PR #91`: https://github.com/jquast/wcwidth/pull/91 +.. _`PR #97`: https://github.com/jquast/wcwidth/pull/97 +.. _`PR #98`: https://github.com/jquast/wcwidth/pull/98 +.. _`PR #100`: https://github.com/jquast/wcwidth/pull/100 +.. _`Issue #101`: https://github.com/jquast/wcwidth/issues/101 .. _`jquast/blessed`: https://github.com/jquast/blessed .. _`selectel/pyte`: https://github.com/selectel/pyte .. _`thomasballinger/curtsies`: https://github.com/thomasballinger/curtsies .. _`dbcli/pgcli`: https://github.com/dbcli/pgcli -.. _`jonathanslenders/python-prompt-toolkit`: https://github.com/jonathanslenders/python-prompt-toolkit +.. _`prompt-toolkit/python-prompt-toolkit`: https://github.com/prompt-toolkit/python-prompt-toolkit .. _`timoxley/wcwidth`: https://github.com/timoxley/wcwidth -.. _`wcwidth(3)`: http://man7.org/linux/man-pages/man3/wcwidth.3.html -.. _`wcswidth(3)`: http://man7.org/linux/man-pages/man3/wcswidth.3.html +.. _`wcwidth(3)`: https://man7.org/linux/man-pages/man3/wcwidth.3.html +.. _`wcswidth(3)`: https://man7.org/linux/man-pages/man3/wcswidth.3.html .. _`astanin/python-tabulate`: https://github.com/astanin/python-tabulate .. _`janlelis/unicode-display_width`: https://github.com/janlelis/unicode-display_width -.. _`LuminosoInsight/python-ftfy`: https://github.com/LuminosoInsight/python-ftfy +.. _`rspeer/python-ftfy`: https://github.com/rspeer/python-ftfy .. _`alecrabbit/php-wcwidth`: https://github.com/alecrabbit/php-wcwidth .. _`Text::CharWidth`: https://metacpan.org/pod/Text::CharWidth .. _`bluebear94/Terminal-WCWidth`: https://github.com/bluebear94/Terminal-WCWidth .. _`mattn/go-runewidth`: https://github.com/mattn/go-runewidth -.. _`emugel/wcwidth`: https://github.com/emugel/wcwidth +.. _`grepsuzette/wcwidth`: https://github.com/grepsuzette/wcwidth .. _`jquast/ucs-detect`: https://github.com/jquast/ucs-detect .. _`Avram Lubkin`: https://github.com/avylove .. _`nbedos/termtosvg`: https://github.com/nbedos/termtosvg .. _`peterbrittain/asciimatics`: https://github.com/peterbrittain/asciimatics .. _`aperezdc/lua-wcwidth`: https://github.com/aperezdc/lua-wcwidth +.. _`joachimschmidt557/zig-wcwidth`: https://github.com/joachimschmidt557/zig-wcwidth .. _`fumiyas/wcwidth-cjk`: https://github.com/fumiyas/wcwidth-cjk +.. _`joshuarubin/wcwidth9`: https://github.com/joshuarubin/wcwidth9 +.. _`python-cmd2/cmd2`: https://github.com/python-cmd2/cmd2 +.. _`stratis-storage/stratis-cli`: https://github.com/stratis-storage/stratis-cli +.. _`ihabunek/toot`: https://github.com/ihabunek/toot +.. _`saulpw/visidata`: https://github.com/saulpw/visidata +.. _`pip-tools`: https://pip-tools.readthedocs.io/ +.. _`sphinx`: https://www.sphinx-doc.org/ .. |pypi_downloads| image:: https://img.shields.io/pypi/dm/wcwidth.svg?logo=pypi :alt: Downloads :target: https://pypi.org/project/wcwidth/ .. |codecov| image:: https://codecov.io/gh/jquast/wcwidth/branch/master/graph/badge.svg :alt: codecov.io Code Coverage - :target: https://codecov.io/gh/jquast/wcwidth/ -.. |license| image:: https://img.shields.io/github/license/jquast/wcwidth.svg - :target: https://pypi.python.org/pypi/wcwidth/ + :target: https://app.codecov.io/gh/jquast/wcwidth/ +.. |license| image:: https://img.shields.io/pypi/l/wcwidth.svg + :target: https://pypi.org/project/wcwidth/ :alt: MIT License diff --git a/contrib/python/wcwidth/py2/README.rst b/contrib/python/wcwidth/py2/README.rst index 813e244ba2..a0dd44cb83 100644 --- a/contrib/python/wcwidth/py2/README.rst +++ b/contrib/python/wcwidth/py2/README.rst @@ -95,7 +95,7 @@ Briefly, return values of function ``wcwidth()`` are: Function ``wcswidth()`` simply returns the sum of all values for each character along a string, or ``-1`` when it occurs anywhere along a string. -Full API Documentation at http://wcwidth.readthedocs.org +Full API Documentation at https://wcwidth.readthedocs.org ========== Developing @@ -103,32 +103,70 @@ Developing Install wcwidth in editable mode:: - pip install -e. + pip install -e . Execute unit tests using tox_:: - tox + tox -e py27,py35,py36,py37,py38,py39,py310,py311,py312 + +Updating Unicode Version +------------------------ Regenerate python code tables from latest Unicode Specification data files:: tox -e update +The script is located at ``bin/update-tables.py``, requires Python 3.9 or +later. It is recommended but not necessary to run this script with the newest +Python, because the newest Python has the latest ``unicodedata`` for generating +comments. + +Building Documentation +---------------------- + +This project is using `sphinx`_ 4.5 to build documentation:: + + tox -e sphinx + +The output will be in ``docs/_build/html/``. + +Updating Requirements +--------------------- + +This project is using `pip-tools`_ to manage requirements. + +To upgrade requirements for updating unicode version, run:: + + tox -e update_requirements_update + +To upgrade requirements for testing, run:: + + tox -e update_requirements37,update_requirements39 + +To upgrade requirements for building documentation, run:: + + tox -e update_requirements_docs + +Utilities +--------- + Supplementary tools for browsing and testing terminals for wide unicode characters are found in the `bin/`_ of this project's source code. Just ensure -to first ``pip install -erequirements-develop.txt`` from this projects main +to first ``pip install -r requirements-develop.txt`` from this projects main folder. For example, an interactive browser for testing:: python ./bin/wcwidth-browser.py +==== Uses ----- +==== This library is used in: - `jquast/blessed`_: a thin, practical wrapper around terminal capabilities in Python. -- `jonathanslenders/python-prompt-toolkit`_: a Library for building powerful +- `prompt-toolkit/python-prompt-toolkit`_: a Library for building powerful interactive command lines in Python. - `dbcli/pgcli`_: Postgres CLI with autocompletion and syntax highlighting. @@ -141,7 +179,7 @@ This library is used in: - `astanin/python-tabulate`_: Pretty-print tabular data in Python, a library and a command-line utility. -- `LuminosoInsight/python-ftfy`_: Fixes mojibake and other glitches in Unicode +- `rspeer/python-ftfy`_: Fixes mojibake and other glitches in Unicode text. - `nbedos/termtosvg`_: Terminal recorder that renders sessions as SVG @@ -150,23 +188,57 @@ This library is used in: - `peterbrittain/asciimatics`_: Package to help people create full-screen text UIs. +- `python-cmd2/cmd2`_: A tool for building interactive command line apps + +- `stratis-storage/stratis-cli`_: CLI for the Stratis project + +- `ihabunek/toot`_: A Mastodon CLI/TUI client + +- `saulpw/visidata`_: Terminal spreadsheet multitool for discovering and + arranging data + +=============== Other Languages ---------------- +=============== - `timoxley/wcwidth`_: JavaScript - `janlelis/unicode-display_width`_: Ruby - `alecrabbit/php-wcwidth`_: PHP - `Text::CharWidth`_: Perl -- `bluebear94/Terminal-WCWidth`: Perl 6 +- `bluebear94/Terminal-WCWidth`_: Perl 6 - `mattn/go-runewidth`_: Go -- `emugel/wcwidth`_: Haxe -- `aperezdc/lua-wcwidth`: Lua -- `joachimschmidt557/zig-wcwidth`: Zig -- `fumiyas/wcwidth-cjk`: `LD_PRELOAD` override -- `joshuarubin/wcwidth9`: Unicode version 9 in C +- `grepsuzette/wcwidth`_: Haxe +- `aperezdc/lua-wcwidth`_: Lua +- `joachimschmidt557/zig-wcwidth`_: Zig +- `fumiyas/wcwidth-cjk`_: `LD_PRELOAD` override +- `joshuarubin/wcwidth9`_: Unicode version 9 in C +======= History -------- +======= +0.2.12 *2023-11-21* + * re-release to remove .pyi file misplaced in wheel files `Issue #101`. + +0.2.11 *2023-11-20* + * Include tests files in the source distribution (`PR #98`_, `PR #100`_). + +0.2.10 *2023-11-13* + * **Bugfix** accounting of some kinds of emoji sequences using U+FE0F + Variation Selector 16 (`PR #97`_). + * **Updated** `Specification <Specification_from_pypi_>`_. + +0.2.9 *2023-10-30* + * **Bugfix** zero-width characters used in Emoji ZWJ sequences, Balinese, + Jamo, Devanagari, Tamil, Kannada and others (`PR #91`_). + * **Updated** to include `Specification <Specification_from_pypi_>`_ of + character measurements. + +0.2.8 *2023-09-30* + * Include requirements files in the source distribution (`PR #82`_). + +0.2.7 *2023-09-28* + * **Updated** tables to include Unicode Specification 15.1.0. + * Include ``bin``, ``docs``, and ``tox.ini`` in the source distribution 0.2.6 *2023-01-14* * **Updated** tables to include Unicode Specification 14.0.0 and 15.0.0. @@ -232,7 +304,7 @@ History This code was originally derived directly from C code of the same name, whose latest version is available at -http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c:: +https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c:: * Markus Kuhn -- 2007-05-26 (Unicode 5.0) * @@ -240,11 +312,12 @@ http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c:: * for any purpose and without fee is hereby granted. The author * disclaims all warranties with regard to this software. -.. _`tox`: https://testrun.org/tox/latest/install.html +.. _`Specification_from_pypi`: https://wcwidth.readthedocs.io/en/latest/specs.html +.. _`tox`: https://tox.wiki/en/latest/ .. _`prospector`: https://github.com/landscapeio/prospector .. _`combining`: https://en.wikipedia.org/wiki/Combining_character .. _`bin/`: https://github.com/jquast/wcwidth/tree/master/bin -.. _`bin/wcwidth-browser.py`: https://github.com/jquast/wcwidth/tree/master/bin/wcwidth-browser.py +.. _`bin/wcwidth-browser.py`: https://github.com/jquast/wcwidth/blob/master/bin/wcwidth-browser.py .. _`Thomas Ballinger`: https://github.com/thomasballinger .. _`Leta Montopoli`: https://github.com/lmontopo .. _`Philip Craig`: https://github.com/philipc @@ -255,34 +328,48 @@ http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c:: .. _`PR #18`: https://github.com/jquast/wcwidth/pull/18 .. _`PR #30`: https://github.com/jquast/wcwidth/pull/30 .. _`PR #35`: https://github.com/jquast/wcwidth/pull/35 +.. _`PR #82`: https://github.com/jquast/wcwidth/pull/82 +.. _`PR #91`: https://github.com/jquast/wcwidth/pull/91 +.. _`PR #97`: https://github.com/jquast/wcwidth/pull/97 +.. _`PR #98`: https://github.com/jquast/wcwidth/pull/98 +.. _`PR #100`: https://github.com/jquast/wcwidth/pull/100 +.. _`Issue #101`: https://github.com/jquast/wcwidth/issues/101 .. _`jquast/blessed`: https://github.com/jquast/blessed .. _`selectel/pyte`: https://github.com/selectel/pyte .. _`thomasballinger/curtsies`: https://github.com/thomasballinger/curtsies .. _`dbcli/pgcli`: https://github.com/dbcli/pgcli -.. _`jonathanslenders/python-prompt-toolkit`: https://github.com/jonathanslenders/python-prompt-toolkit +.. _`prompt-toolkit/python-prompt-toolkit`: https://github.com/prompt-toolkit/python-prompt-toolkit .. _`timoxley/wcwidth`: https://github.com/timoxley/wcwidth -.. _`wcwidth(3)`: http://man7.org/linux/man-pages/man3/wcwidth.3.html -.. _`wcswidth(3)`: http://man7.org/linux/man-pages/man3/wcswidth.3.html +.. _`wcwidth(3)`: https://man7.org/linux/man-pages/man3/wcwidth.3.html +.. _`wcswidth(3)`: https://man7.org/linux/man-pages/man3/wcswidth.3.html .. _`astanin/python-tabulate`: https://github.com/astanin/python-tabulate .. _`janlelis/unicode-display_width`: https://github.com/janlelis/unicode-display_width -.. _`LuminosoInsight/python-ftfy`: https://github.com/LuminosoInsight/python-ftfy +.. _`rspeer/python-ftfy`: https://github.com/rspeer/python-ftfy .. _`alecrabbit/php-wcwidth`: https://github.com/alecrabbit/php-wcwidth .. _`Text::CharWidth`: https://metacpan.org/pod/Text::CharWidth .. _`bluebear94/Terminal-WCWidth`: https://github.com/bluebear94/Terminal-WCWidth .. _`mattn/go-runewidth`: https://github.com/mattn/go-runewidth -.. _`emugel/wcwidth`: https://github.com/emugel/wcwidth +.. _`grepsuzette/wcwidth`: https://github.com/grepsuzette/wcwidth .. _`jquast/ucs-detect`: https://github.com/jquast/ucs-detect .. _`Avram Lubkin`: https://github.com/avylove .. _`nbedos/termtosvg`: https://github.com/nbedos/termtosvg .. _`peterbrittain/asciimatics`: https://github.com/peterbrittain/asciimatics .. _`aperezdc/lua-wcwidth`: https://github.com/aperezdc/lua-wcwidth +.. _`joachimschmidt557/zig-wcwidth`: https://github.com/joachimschmidt557/zig-wcwidth .. _`fumiyas/wcwidth-cjk`: https://github.com/fumiyas/wcwidth-cjk +.. _`joshuarubin/wcwidth9`: https://github.com/joshuarubin/wcwidth9 +.. _`python-cmd2/cmd2`: https://github.com/python-cmd2/cmd2 +.. _`stratis-storage/stratis-cli`: https://github.com/stratis-storage/stratis-cli +.. _`ihabunek/toot`: https://github.com/ihabunek/toot +.. _`saulpw/visidata`: https://github.com/saulpw/visidata +.. _`pip-tools`: https://pip-tools.readthedocs.io/ +.. _`sphinx`: https://www.sphinx-doc.org/ .. |pypi_downloads| image:: https://img.shields.io/pypi/dm/wcwidth.svg?logo=pypi :alt: Downloads :target: https://pypi.org/project/wcwidth/ .. |codecov| image:: https://codecov.io/gh/jquast/wcwidth/branch/master/graph/badge.svg :alt: codecov.io Code Coverage - :target: https://codecov.io/gh/jquast/wcwidth/ -.. |license| image:: https://img.shields.io/github/license/jquast/wcwidth.svg - :target: https://pypi.python.org/pypi/wcwidth/ + :target: https://app.codecov.io/gh/jquast/wcwidth/ +.. |license| image:: https://img.shields.io/pypi/l/wcwidth.svg + :target: https://pypi.org/project/wcwidth/ :alt: MIT License diff --git a/contrib/python/wcwidth/py2/tests/emoji-variation-sequences.txt b/contrib/python/wcwidth/py2/tests/emoji-variation-sequences.txt new file mode 100644 index 0000000000..d8a3c9f431 --- /dev/null +++ b/contrib/python/wcwidth/py2/tests/emoji-variation-sequences.txt @@ -0,0 +1,757 @@ +# emoji-variation-sequences.txt +# Date: 2023-02-01, 02:22:54 GMT +# © 2023 Unicode®, Inc. +# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. +# For terms of use, see https://www.unicode.org/terms_of_use.html +# +# Emoji Variation Sequences for UTS #51 +# Used with Emoji Version 15.1 and subsequent minor revisions (if any) +# +# For documentation and usage, see https://www.unicode.org/reports/tr51 +# +0023 FE0E ; text style; # (1.1) NUMBER SIGN +0023 FE0F ; emoji style; # (1.1) NUMBER SIGN +002A FE0E ; text style; # (1.1) ASTERISK +002A FE0F ; emoji style; # (1.1) ASTERISK +0030 FE0E ; text style; # (1.1) DIGIT ZERO +0030 FE0F ; emoji style; # (1.1) DIGIT ZERO +0031 FE0E ; text style; # (1.1) DIGIT ONE +0031 FE0F ; emoji style; # (1.1) DIGIT ONE +0032 FE0E ; text style; # (1.1) DIGIT TWO +0032 FE0F ; emoji style; # (1.1) DIGIT TWO +0033 FE0E ; text style; # (1.1) DIGIT THREE +0033 FE0F ; emoji style; # (1.1) DIGIT THREE +0034 FE0E ; text style; # (1.1) DIGIT FOUR +0034 FE0F ; emoji style; # (1.1) DIGIT FOUR +0035 FE0E ; text style; # (1.1) DIGIT FIVE +0035 FE0F ; emoji style; # (1.1) DIGIT FIVE +0036 FE0E ; text style; # (1.1) DIGIT SIX +0036 FE0F ; emoji style; # (1.1) DIGIT SIX +0037 FE0E ; text style; # (1.1) DIGIT SEVEN +0037 FE0F ; emoji style; # (1.1) DIGIT SEVEN +0038 FE0E ; text style; # (1.1) DIGIT EIGHT +0038 FE0F ; emoji style; # (1.1) DIGIT EIGHT +0039 FE0E ; text style; # (1.1) DIGIT NINE +0039 FE0F ; emoji style; # (1.1) DIGIT NINE +00A9 FE0E ; text style; # (1.1) COPYRIGHT SIGN +00A9 FE0F ; emoji style; # (1.1) COPYRIGHT SIGN +00AE FE0E ; text style; # (1.1) REGISTERED SIGN +00AE FE0F ; emoji style; # (1.1) REGISTERED SIGN +203C FE0E ; text style; # (1.1) DOUBLE EXCLAMATION MARK +203C FE0F ; emoji style; # (1.1) DOUBLE EXCLAMATION MARK +2049 FE0E ; text style; # (3.0) EXCLAMATION QUESTION MARK +2049 FE0F ; emoji style; # (3.0) EXCLAMATION QUESTION MARK +2122 FE0E ; text style; # (1.1) TRADE MARK SIGN +2122 FE0F ; emoji style; # (1.1) TRADE MARK SIGN +2139 FE0E ; text style; # (3.0) INFORMATION SOURCE +2139 FE0F ; emoji style; # (3.0) INFORMATION SOURCE +2194 FE0E ; text style; # (1.1) LEFT RIGHT ARROW +2194 FE0F ; emoji style; # (1.1) LEFT RIGHT ARROW +2195 FE0E ; text style; # (1.1) UP DOWN ARROW +2195 FE0F ; emoji style; # (1.1) UP DOWN ARROW +2196 FE0E ; text style; # (1.1) NORTH WEST ARROW +2196 FE0F ; emoji style; # (1.1) NORTH WEST ARROW +2197 FE0E ; text style; # (1.1) NORTH EAST ARROW +2197 FE0F ; emoji style; # (1.1) NORTH EAST ARROW +2198 FE0E ; text style; # (1.1) SOUTH EAST ARROW +2198 FE0F ; emoji style; # (1.1) SOUTH EAST ARROW +2199 FE0E ; text style; # (1.1) SOUTH WEST ARROW +2199 FE0F ; emoji style; # (1.1) SOUTH WEST ARROW +21A9 FE0E ; text style; # (1.1) LEFTWARDS ARROW WITH HOOK +21A9 FE0F ; emoji style; # (1.1) LEFTWARDS ARROW WITH HOOK +21AA FE0E ; text style; # (1.1) RIGHTWARDS ARROW WITH HOOK +21AA FE0F ; emoji style; # (1.1) RIGHTWARDS ARROW WITH HOOK +231A FE0E ; text style; # (1.1) WATCH +231A FE0F ; emoji style; # (1.1) WATCH +231B FE0E ; text style; # (1.1) HOURGLASS +231B FE0F ; emoji style; # (1.1) HOURGLASS +2328 FE0E ; text style; # (1.1) KEYBOARD +2328 FE0F ; emoji style; # (1.1) KEYBOARD +23CF FE0E ; text style; # (4.0) EJECT SYMBOL +23CF FE0F ; emoji style; # (4.0) EJECT SYMBOL +23E9 FE0E ; text style; # (6.0) BLACK RIGHT-POINTING DOUBLE TRIANGLE +23E9 FE0F ; emoji style; # (6.0) BLACK RIGHT-POINTING DOUBLE TRIANGLE +23EA FE0E ; text style; # (6.0) BLACK LEFT-POINTING DOUBLE TRIANGLE +23EA FE0F ; emoji style; # (6.0) BLACK LEFT-POINTING DOUBLE TRIANGLE +23EB FE0E ; text style; # (6.0) BLACK UP-POINTING DOUBLE TRIANGLE +23EB FE0F ; emoji style; # (6.0) BLACK UP-POINTING DOUBLE TRIANGLE +23EC FE0E ; text style; # (6.0) BLACK DOWN-POINTING DOUBLE TRIANGLE +23EC FE0F ; emoji style; # (6.0) BLACK DOWN-POINTING DOUBLE TRIANGLE +23ED FE0E ; text style; # (6.0) BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR +23ED FE0F ; emoji style; # (6.0) BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR +23EE FE0E ; text style; # (6.0) BLACK LEFT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR +23EE FE0F ; emoji style; # (6.0) BLACK LEFT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR +23EF FE0E ; text style; # (6.0) BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR +23EF FE0F ; emoji style; # (6.0) BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR +23F0 FE0E ; text style; # (6.0) ALARM CLOCK +23F0 FE0F ; emoji style; # (6.0) ALARM CLOCK +23F1 FE0E ; text style; # (6.0) STOPWATCH +23F1 FE0F ; emoji style; # (6.0) STOPWATCH +23F2 FE0E ; text style; # (6.0) TIMER CLOCK +23F2 FE0F ; emoji style; # (6.0) TIMER CLOCK +23F3 FE0E ; text style; # (6.0) HOURGLASS WITH FLOWING SAND +23F3 FE0F ; emoji style; # (6.0) HOURGLASS WITH FLOWING SAND +23F8 FE0E ; text style; # (7.0) DOUBLE VERTICAL BAR +23F8 FE0F ; emoji style; # (7.0) DOUBLE VERTICAL BAR +23F9 FE0E ; text style; # (7.0) BLACK SQUARE FOR STOP +23F9 FE0F ; emoji style; # (7.0) BLACK SQUARE FOR STOP +23FA FE0E ; text style; # (7.0) BLACK CIRCLE FOR RECORD +23FA FE0F ; emoji style; # (7.0) BLACK CIRCLE FOR RECORD +24C2 FE0E ; text style; # (1.1) CIRCLED LATIN CAPITAL LETTER M +24C2 FE0F ; emoji style; # (1.1) CIRCLED LATIN CAPITAL LETTER M +25AA FE0E ; text style; # (1.1) BLACK SMALL SQUARE +25AA FE0F ; emoji style; # (1.1) BLACK SMALL SQUARE +25AB FE0E ; text style; # (1.1) WHITE SMALL SQUARE +25AB FE0F ; emoji style; # (1.1) WHITE SMALL SQUARE +25B6 FE0E ; text style; # (1.1) BLACK RIGHT-POINTING TRIANGLE +25B6 FE0F ; emoji style; # (1.1) BLACK RIGHT-POINTING TRIANGLE +25C0 FE0E ; text style; # (1.1) BLACK LEFT-POINTING TRIANGLE +25C0 FE0F ; emoji style; # (1.1) BLACK LEFT-POINTING TRIANGLE +25FB FE0E ; text style; # (3.2) WHITE MEDIUM SQUARE +25FB FE0F ; emoji style; # (3.2) WHITE MEDIUM SQUARE +25FC FE0E ; text style; # (3.2) BLACK MEDIUM SQUARE +25FC FE0F ; emoji style; # (3.2) BLACK MEDIUM SQUARE +25FD FE0E ; text style; # (3.2) WHITE MEDIUM SMALL SQUARE +25FD FE0F ; emoji style; # (3.2) WHITE MEDIUM SMALL SQUARE +25FE FE0E ; text style; # (3.2) BLACK MEDIUM SMALL SQUARE +25FE FE0F ; emoji style; # (3.2) BLACK MEDIUM SMALL SQUARE +2600 FE0E ; text style; # (1.1) BLACK SUN WITH RAYS +2600 FE0F ; emoji style; # (1.1) BLACK SUN WITH RAYS +2601 FE0E ; text style; # (1.1) CLOUD +2601 FE0F ; emoji style; # (1.1) CLOUD +2602 FE0E ; text style; # (1.1) UMBRELLA +2602 FE0F ; emoji style; # (1.1) UMBRELLA +2603 FE0E ; text style; # (1.1) SNOWMAN +2603 FE0F ; emoji style; # (1.1) SNOWMAN +2604 FE0E ; text style; # (1.1) COMET +2604 FE0F ; emoji style; # (1.1) COMET +260E FE0E ; text style; # (1.1) BLACK TELEPHONE +260E FE0F ; emoji style; # (1.1) BLACK TELEPHONE +2611 FE0E ; text style; # (1.1) BALLOT BOX WITH CHECK +2611 FE0F ; emoji style; # (1.1) BALLOT BOX WITH CHECK +2614 FE0E ; text style; # (4.0) UMBRELLA WITH RAIN DROPS +2614 FE0F ; emoji style; # (4.0) UMBRELLA WITH RAIN DROPS +2615 FE0E ; text style; # (4.0) HOT BEVERAGE +2615 FE0F ; emoji style; # (4.0) HOT BEVERAGE +2618 FE0E ; text style; # (4.1) SHAMROCK +2618 FE0F ; emoji style; # (4.1) SHAMROCK +261D FE0E ; text style; # (1.1) WHITE UP POINTING INDEX +261D FE0F ; emoji style; # (1.1) WHITE UP POINTING INDEX +2620 FE0E ; text style; # (1.1) SKULL AND CROSSBONES +2620 FE0F ; emoji style; # (1.1) SKULL AND CROSSBONES +2622 FE0E ; text style; # (1.1) RADIOACTIVE SIGN +2622 FE0F ; emoji style; # (1.1) RADIOACTIVE SIGN +2623 FE0E ; text style; # (1.1) BIOHAZARD SIGN +2623 FE0F ; emoji style; # (1.1) BIOHAZARD SIGN +2626 FE0E ; text style; # (1.1) ORTHODOX CROSS +2626 FE0F ; emoji style; # (1.1) ORTHODOX CROSS +262A FE0E ; text style; # (1.1) STAR AND CRESCENT +262A FE0F ; emoji style; # (1.1) STAR AND CRESCENT +262E FE0E ; text style; # (1.1) PEACE SYMBOL +262E FE0F ; emoji style; # (1.1) PEACE SYMBOL +262F FE0E ; text style; # (1.1) YIN YANG +262F FE0F ; emoji style; # (1.1) YIN YANG +2638 FE0E ; text style; # (1.1) WHEEL OF DHARMA +2638 FE0F ; emoji style; # (1.1) WHEEL OF DHARMA +2639 FE0E ; text style; # (1.1) WHITE FROWNING FACE +2639 FE0F ; emoji style; # (1.1) WHITE FROWNING FACE +263A FE0E ; text style; # (1.1) WHITE SMILING FACE +263A FE0F ; emoji style; # (1.1) WHITE SMILING FACE +2640 FE0E ; text style; # (1.1) FEMALE SIGN +2640 FE0F ; emoji style; # (1.1) FEMALE SIGN +2642 FE0E ; text style; # (1.1) MALE SIGN +2642 FE0F ; emoji style; # (1.1) MALE SIGN +2648 FE0E ; text style; # (1.1) ARIES +2648 FE0F ; emoji style; # (1.1) ARIES +2649 FE0E ; text style; # (1.1) TAURUS +2649 FE0F ; emoji style; # (1.1) TAURUS +264A FE0E ; text style; # (1.1) GEMINI +264A FE0F ; emoji style; # (1.1) GEMINI +264B FE0E ; text style; # (1.1) CANCER +264B FE0F ; emoji style; # (1.1) CANCER +264C FE0E ; text style; # (1.1) LEO +264C FE0F ; emoji style; # (1.1) LEO +264D FE0E ; text style; # (1.1) VIRGO +264D FE0F ; emoji style; # (1.1) VIRGO +264E FE0E ; text style; # (1.1) LIBRA +264E FE0F ; emoji style; # (1.1) LIBRA +264F FE0E ; text style; # (1.1) SCORPIUS +264F FE0F ; emoji style; # (1.1) SCORPIUS +2650 FE0E ; text style; # (1.1) SAGITTARIUS +2650 FE0F ; emoji style; # (1.1) SAGITTARIUS +2651 FE0E ; text style; # (1.1) CAPRICORN +2651 FE0F ; emoji style; # (1.1) CAPRICORN +2652 FE0E ; text style; # (1.1) AQUARIUS +2652 FE0F ; emoji style; # (1.1) AQUARIUS +2653 FE0E ; text style; # (1.1) PISCES +2653 FE0F ; emoji style; # (1.1) PISCES +265F FE0E ; text style; # (1.1) BLACK CHESS PAWN +265F FE0F ; emoji style; # (1.1) BLACK CHESS PAWN +2660 FE0E ; text style; # (1.1) BLACK SPADE SUIT +2660 FE0F ; emoji style; # (1.1) BLACK SPADE SUIT +2663 FE0E ; text style; # (1.1) BLACK CLUB SUIT +2663 FE0F ; emoji style; # (1.1) BLACK CLUB SUIT +2665 FE0E ; text style; # (1.1) BLACK HEART SUIT +2665 FE0F ; emoji style; # (1.1) BLACK HEART SUIT +2666 FE0E ; text style; # (1.1) BLACK DIAMOND SUIT +2666 FE0F ; emoji style; # (1.1) BLACK DIAMOND SUIT +2668 FE0E ; text style; # (1.1) HOT SPRINGS +2668 FE0F ; emoji style; # (1.1) HOT SPRINGS +267B FE0E ; text style; # (3.2) BLACK UNIVERSAL RECYCLING SYMBOL +267B FE0F ; emoji style; # (3.2) BLACK UNIVERSAL RECYCLING SYMBOL +267E FE0E ; text style; # (4.1) PERMANENT PAPER SIGN +267E FE0F ; emoji style; # (4.1) PERMANENT PAPER SIGN +267F FE0E ; text style; # (4.1) WHEELCHAIR SYMBOL +267F FE0F ; emoji style; # (4.1) WHEELCHAIR SYMBOL +2692 FE0E ; text style; # (4.1) HAMMER AND PICK +2692 FE0F ; emoji style; # (4.1) HAMMER AND PICK +2693 FE0E ; text style; # (4.1) ANCHOR +2693 FE0F ; emoji style; # (4.1) ANCHOR +2694 FE0E ; text style; # (4.1) CROSSED SWORDS +2694 FE0F ; emoji style; # (4.1) CROSSED SWORDS +2695 FE0E ; text style; # (4.1) STAFF OF AESCULAPIUS +2695 FE0F ; emoji style; # (4.1) STAFF OF AESCULAPIUS +2696 FE0E ; text style; # (4.1) SCALES +2696 FE0F ; emoji style; # (4.1) SCALES +2697 FE0E ; text style; # (4.1) ALEMBIC +2697 FE0F ; emoji style; # (4.1) ALEMBIC +2699 FE0E ; text style; # (4.1) GEAR +2699 FE0F ; emoji style; # (4.1) GEAR +269B FE0E ; text style; # (4.1) ATOM SYMBOL +269B FE0F ; emoji style; # (4.1) ATOM SYMBOL +269C FE0E ; text style; # (4.1) FLEUR-DE-LIS +269C FE0F ; emoji style; # (4.1) FLEUR-DE-LIS +26A0 FE0E ; text style; # (4.0) WARNING SIGN +26A0 FE0F ; emoji style; # (4.0) WARNING SIGN +26A1 FE0E ; text style; # (4.0) HIGH VOLTAGE SIGN +26A1 FE0F ; emoji style; # (4.0) HIGH VOLTAGE SIGN +26A7 FE0E ; text style; # (4.1) MALE WITH STROKE AND MALE AND FEMALE SIGN +26A7 FE0F ; emoji style; # (4.1) MALE WITH STROKE AND MALE AND FEMALE SIGN +26AA FE0E ; text style; # (4.1) MEDIUM WHITE CIRCLE +26AA FE0F ; emoji style; # (4.1) MEDIUM WHITE CIRCLE +26AB FE0E ; text style; # (4.1) MEDIUM BLACK CIRCLE +26AB FE0F ; emoji style; # (4.1) MEDIUM BLACK CIRCLE +26B0 FE0E ; text style; # (4.1) COFFIN +26B0 FE0F ; emoji style; # (4.1) COFFIN +26B1 FE0E ; text style; # (4.1) FUNERAL URN +26B1 FE0F ; emoji style; # (4.1) FUNERAL URN +26BD FE0E ; text style; # (5.2) SOCCER BALL +26BD FE0F ; emoji style; # (5.2) SOCCER BALL +26BE FE0E ; text style; # (5.2) BASEBALL +26BE FE0F ; emoji style; # (5.2) BASEBALL +26C4 FE0E ; text style; # (5.2) SNOWMAN WITHOUT SNOW +26C4 FE0F ; emoji style; # (5.2) SNOWMAN WITHOUT SNOW +26C5 FE0E ; text style; # (5.2) SUN BEHIND CLOUD +26C5 FE0F ; emoji style; # (5.2) SUN BEHIND CLOUD +26C8 FE0E ; text style; # (5.2) THUNDER CLOUD AND RAIN +26C8 FE0F ; emoji style; # (5.2) THUNDER CLOUD AND RAIN +26CE FE0E ; text style; # (6.0) OPHIUCHUS +26CE FE0F ; emoji style; # (6.0) OPHIUCHUS +26CF FE0E ; text style; # (5.2) PICK +26CF FE0F ; emoji style; # (5.2) PICK +26D1 FE0E ; text style; # (5.2) HELMET WITH WHITE CROSS +26D1 FE0F ; emoji style; # (5.2) HELMET WITH WHITE CROSS +26D3 FE0E ; text style; # (5.2) CHAINS +26D3 FE0F ; emoji style; # (5.2) CHAINS +26D4 FE0E ; text style; # (5.2) NO ENTRY +26D4 FE0F ; emoji style; # (5.2) NO ENTRY +26E9 FE0E ; text style; # (5.2) SHINTO SHRINE +26E9 FE0F ; emoji style; # (5.2) SHINTO SHRINE +26EA FE0E ; text style; # (5.2) CHURCH +26EA FE0F ; emoji style; # (5.2) CHURCH +26F0 FE0E ; text style; # (5.2) MOUNTAIN +26F0 FE0F ; emoji style; # (5.2) MOUNTAIN +26F1 FE0E ; text style; # (5.2) UMBRELLA ON GROUND +26F1 FE0F ; emoji style; # (5.2) UMBRELLA ON GROUND +26F2 FE0E ; text style; # (5.2) FOUNTAIN +26F2 FE0F ; emoji style; # (5.2) FOUNTAIN +26F3 FE0E ; text style; # (5.2) FLAG IN HOLE +26F3 FE0F ; emoji style; # (5.2) FLAG IN HOLE +26F4 FE0E ; text style; # (5.2) FERRY +26F4 FE0F ; emoji style; # (5.2) FERRY +26F5 FE0E ; text style; # (5.2) SAILBOAT +26F5 FE0F ; emoji style; # (5.2) SAILBOAT +26F7 FE0E ; text style; # (5.2) SKIER +26F7 FE0F ; emoji style; # (5.2) SKIER +26F8 FE0E ; text style; # (5.2) ICE SKATE +26F8 FE0F ; emoji style; # (5.2) ICE SKATE +26F9 FE0E ; text style; # (5.2) PERSON WITH BALL +26F9 FE0F ; emoji style; # (5.2) PERSON WITH BALL +26FA FE0E ; text style; # (5.2) TENT +26FA FE0F ; emoji style; # (5.2) TENT +26FD FE0E ; text style; # (5.2) FUEL PUMP +26FD FE0F ; emoji style; # (5.2) FUEL PUMP +2702 FE0E ; text style; # (1.1) BLACK SCISSORS +2702 FE0F ; emoji style; # (1.1) BLACK SCISSORS +2705 FE0E ; text style; # (6.0) WHITE HEAVY CHECK MARK +2705 FE0F ; emoji style; # (6.0) WHITE HEAVY CHECK MARK +2708 FE0E ; text style; # (1.1) AIRPLANE +2708 FE0F ; emoji style; # (1.1) AIRPLANE +2709 FE0E ; text style; # (1.1) ENVELOPE +2709 FE0F ; emoji style; # (1.1) ENVELOPE +270A FE0E ; text style; # (6.0) RAISED FIST +270A FE0F ; emoji style; # (6.0) RAISED FIST +270B FE0E ; text style; # (6.0) RAISED HAND +270B FE0F ; emoji style; # (6.0) RAISED HAND +270C FE0E ; text style; # (1.1) VICTORY HAND +270C FE0F ; emoji style; # (1.1) VICTORY HAND +270D FE0E ; text style; # (1.1) WRITING HAND +270D FE0F ; emoji style; # (1.1) WRITING HAND +270F FE0E ; text style; # (1.1) PENCIL +270F FE0F ; emoji style; # (1.1) PENCIL +2712 FE0E ; text style; # (1.1) BLACK NIB +2712 FE0F ; emoji style; # (1.1) BLACK NIB +2714 FE0E ; text style; # (1.1) HEAVY CHECK MARK +2714 FE0F ; emoji style; # (1.1) HEAVY CHECK MARK +2716 FE0E ; text style; # (1.1) HEAVY MULTIPLICATION X +2716 FE0F ; emoji style; # (1.1) HEAVY MULTIPLICATION X +271D FE0E ; text style; # (1.1) LATIN CROSS +271D FE0F ; emoji style; # (1.1) LATIN CROSS +2721 FE0E ; text style; # (1.1) STAR OF DAVID +2721 FE0F ; emoji style; # (1.1) STAR OF DAVID +2728 FE0E ; text style; # (6.0) SPARKLES +2728 FE0F ; emoji style; # (6.0) SPARKLES +2733 FE0E ; text style; # (1.1) EIGHT SPOKED ASTERISK +2733 FE0F ; emoji style; # (1.1) EIGHT SPOKED ASTERISK +2734 FE0E ; text style; # (1.1) EIGHT POINTED BLACK STAR +2734 FE0F ; emoji style; # (1.1) EIGHT POINTED BLACK STAR +2744 FE0E ; text style; # (1.1) SNOWFLAKE +2744 FE0F ; emoji style; # (1.1) SNOWFLAKE +2747 FE0E ; text style; # (1.1) SPARKLE +2747 FE0F ; emoji style; # (1.1) SPARKLE +274C FE0E ; text style; # (6.0) CROSS MARK +274C FE0F ; emoji style; # (6.0) CROSS MARK +274E FE0E ; text style; # (6.0) NEGATIVE SQUARED CROSS MARK +274E FE0F ; emoji style; # (6.0) NEGATIVE SQUARED CROSS MARK +2753 FE0E ; text style; # (6.0) BLACK QUESTION MARK ORNAMENT +2753 FE0F ; emoji style; # (6.0) BLACK QUESTION MARK ORNAMENT +2754 FE0E ; text style; # (6.0) WHITE QUESTION MARK ORNAMENT +2754 FE0F ; emoji style; # (6.0) WHITE QUESTION MARK ORNAMENT +2755 FE0E ; text style; # (6.0) WHITE EXCLAMATION MARK ORNAMENT +2755 FE0F ; emoji style; # (6.0) WHITE EXCLAMATION MARK ORNAMENT +2757 FE0E ; text style; # (5.2) HEAVY EXCLAMATION MARK SYMBOL +2757 FE0F ; emoji style; # (5.2) HEAVY EXCLAMATION MARK SYMBOL +2763 FE0E ; text style; # (1.1) HEAVY HEART EXCLAMATION MARK ORNAMENT +2763 FE0F ; emoji style; # (1.1) HEAVY HEART EXCLAMATION MARK ORNAMENT +2764 FE0E ; text style; # (1.1) HEAVY BLACK HEART +2764 FE0F ; emoji style; # (1.1) HEAVY BLACK HEART +2795 FE0E ; text style; # (6.0) HEAVY PLUS SIGN +2795 FE0F ; emoji style; # (6.0) HEAVY PLUS SIGN +2796 FE0E ; text style; # (6.0) HEAVY MINUS SIGN +2796 FE0F ; emoji style; # (6.0) HEAVY MINUS SIGN +2797 FE0E ; text style; # (6.0) HEAVY DIVISION SIGN +2797 FE0F ; emoji style; # (6.0) HEAVY DIVISION SIGN +27A1 FE0E ; text style; # (1.1) BLACK RIGHTWARDS ARROW +27A1 FE0F ; emoji style; # (1.1) BLACK RIGHTWARDS ARROW +27B0 FE0E ; text style; # (6.0) CURLY LOOP +27B0 FE0F ; emoji style; # (6.0) CURLY LOOP +27BF FE0E ; text style; # (6.0) DOUBLE CURLY LOOP +27BF FE0F ; emoji style; # (6.0) DOUBLE CURLY LOOP +2934 FE0E ; text style; # (3.2) ARROW POINTING RIGHTWARDS THEN CURVING UPWARDS +2934 FE0F ; emoji style; # (3.2) ARROW POINTING RIGHTWARDS THEN CURVING UPWARDS +2935 FE0E ; text style; # (3.2) ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS +2935 FE0F ; emoji style; # (3.2) ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS +2B05 FE0E ; text style; # (4.0) LEFTWARDS BLACK ARROW +2B05 FE0F ; emoji style; # (4.0) LEFTWARDS BLACK ARROW +2B06 FE0E ; text style; # (4.0) UPWARDS BLACK ARROW +2B06 FE0F ; emoji style; # (4.0) UPWARDS BLACK ARROW +2B07 FE0E ; text style; # (4.0) DOWNWARDS BLACK ARROW +2B07 FE0F ; emoji style; # (4.0) DOWNWARDS BLACK ARROW +2B1B FE0E ; text style; # (5.1) BLACK LARGE SQUARE +2B1B FE0F ; emoji style; # (5.1) BLACK LARGE SQUARE +2B1C FE0E ; text style; # (5.1) WHITE LARGE SQUARE +2B1C FE0F ; emoji style; # (5.1) WHITE LARGE SQUARE +2B50 FE0E ; text style; # (5.1) WHITE MEDIUM STAR +2B50 FE0F ; emoji style; # (5.1) WHITE MEDIUM STAR +2B55 FE0E ; text style; # (5.2) HEAVY LARGE CIRCLE +2B55 FE0F ; emoji style; # (5.2) HEAVY LARGE CIRCLE +3030 FE0E ; text style; # (1.1) WAVY DASH +3030 FE0F ; emoji style; # (1.1) WAVY DASH +303D FE0E ; text style; # (3.2) PART ALTERNATION MARK +303D FE0F ; emoji style; # (3.2) PART ALTERNATION MARK +3297 FE0E ; text style; # (1.1) CIRCLED IDEOGRAPH CONGRATULATION +3297 FE0F ; emoji style; # (1.1) CIRCLED IDEOGRAPH CONGRATULATION +3299 FE0E ; text style; # (1.1) CIRCLED IDEOGRAPH SECRET +3299 FE0F ; emoji style; # (1.1) CIRCLED IDEOGRAPH SECRET +1F004 FE0E ; text style; # (5.1) MAHJONG TILE RED DRAGON +1F004 FE0F ; emoji style; # (5.1) MAHJONG TILE RED DRAGON +1F170 FE0E ; text style; # (6.0) NEGATIVE SQUARED LATIN CAPITAL LETTER A +1F170 FE0F ; emoji style; # (6.0) NEGATIVE SQUARED LATIN CAPITAL LETTER A +1F171 FE0E ; text style; # (6.0) NEGATIVE SQUARED LATIN CAPITAL LETTER B +1F171 FE0F ; emoji style; # (6.0) NEGATIVE SQUARED LATIN CAPITAL LETTER B +1F17E FE0E ; text style; # (6.0) NEGATIVE SQUARED LATIN CAPITAL LETTER O +1F17E FE0F ; emoji style; # (6.0) NEGATIVE SQUARED LATIN CAPITAL LETTER O +1F17F FE0E ; text style; # (5.2) NEGATIVE SQUARED LATIN CAPITAL LETTER P +1F17F FE0F ; emoji style; # (5.2) NEGATIVE SQUARED LATIN CAPITAL LETTER P +1F202 FE0E ; text style; # (6.0) SQUARED KATAKANA SA +1F202 FE0F ; emoji style; # (6.0) SQUARED KATAKANA SA +1F21A FE0E ; text style; # (5.2) SQUARED CJK UNIFIED IDEOGRAPH-7121 +1F21A FE0F ; emoji style; # (5.2) SQUARED CJK UNIFIED IDEOGRAPH-7121 +1F22F FE0E ; text style; # (5.2) SQUARED CJK UNIFIED IDEOGRAPH-6307 +1F22F FE0F ; emoji style; # (5.2) SQUARED CJK UNIFIED IDEOGRAPH-6307 +1F237 FE0E ; text style; # (6.0) SQUARED CJK UNIFIED IDEOGRAPH-6708 +1F237 FE0F ; emoji style; # (6.0) SQUARED CJK UNIFIED IDEOGRAPH-6708 +1F30D FE0E ; text style; # (6.0) EARTH GLOBE EUROPE-AFRICA +1F30D FE0F ; emoji style; # (6.0) EARTH GLOBE EUROPE-AFRICA +1F30E FE0E ; text style; # (6.0) EARTH GLOBE AMERICAS +1F30E FE0F ; emoji style; # (6.0) EARTH GLOBE AMERICAS +1F30F FE0E ; text style; # (6.0) EARTH GLOBE ASIA-AUSTRALIA +1F30F FE0F ; emoji style; # (6.0) EARTH GLOBE ASIA-AUSTRALIA +1F315 FE0E ; text style; # (6.0) FULL MOON SYMBOL +1F315 FE0F ; emoji style; # (6.0) FULL MOON SYMBOL +1F31C FE0E ; text style; # (6.0) LAST QUARTER MOON WITH FACE +1F31C FE0F ; emoji style; # (6.0) LAST QUARTER MOON WITH FACE +1F321 FE0E ; text style; # (7.0) THERMOMETER +1F321 FE0F ; emoji style; # (7.0) THERMOMETER +1F324 FE0E ; text style; # (7.0) WHITE SUN WITH SMALL CLOUD +1F324 FE0F ; emoji style; # (7.0) WHITE SUN WITH SMALL CLOUD +1F325 FE0E ; text style; # (7.0) WHITE SUN BEHIND CLOUD +1F325 FE0F ; emoji style; # (7.0) WHITE SUN BEHIND CLOUD +1F326 FE0E ; text style; # (7.0) WHITE SUN BEHIND CLOUD WITH RAIN +1F326 FE0F ; emoji style; # (7.0) WHITE SUN BEHIND CLOUD WITH RAIN +1F327 FE0E ; text style; # (7.0) CLOUD WITH RAIN +1F327 FE0F ; emoji style; # (7.0) CLOUD WITH RAIN +1F328 FE0E ; text style; # (7.0) CLOUD WITH SNOW +1F328 FE0F ; emoji style; # (7.0) CLOUD WITH SNOW +1F329 FE0E ; text style; # (7.0) CLOUD WITH LIGHTNING +1F329 FE0F ; emoji style; # (7.0) CLOUD WITH LIGHTNING +1F32A FE0E ; text style; # (7.0) CLOUD WITH TORNADO +1F32A FE0F ; emoji style; # (7.0) CLOUD WITH TORNADO +1F32B FE0E ; text style; # (7.0) FOG +1F32B FE0F ; emoji style; # (7.0) FOG +1F32C FE0E ; text style; # (7.0) WIND BLOWING FACE +1F32C FE0F ; emoji style; # (7.0) WIND BLOWING FACE +1F336 FE0E ; text style; # (7.0) HOT PEPPER +1F336 FE0F ; emoji style; # (7.0) HOT PEPPER +1F378 FE0E ; text style; # (6.0) COCKTAIL GLASS +1F378 FE0F ; emoji style; # (6.0) COCKTAIL GLASS +1F37D FE0E ; text style; # (7.0) FORK AND KNIFE WITH PLATE +1F37D FE0F ; emoji style; # (7.0) FORK AND KNIFE WITH PLATE +1F393 FE0E ; text style; # (6.0) GRADUATION CAP +1F393 FE0F ; emoji style; # (6.0) GRADUATION CAP +1F396 FE0E ; text style; # (7.0) MILITARY MEDAL +1F396 FE0F ; emoji style; # (7.0) MILITARY MEDAL +1F397 FE0E ; text style; # (7.0) REMINDER RIBBON +1F397 FE0F ; emoji style; # (7.0) REMINDER RIBBON +1F399 FE0E ; text style; # (7.0) STUDIO MICROPHONE +1F399 FE0F ; emoji style; # (7.0) STUDIO MICROPHONE +1F39A FE0E ; text style; # (7.0) LEVEL SLIDER +1F39A FE0F ; emoji style; # (7.0) LEVEL SLIDER +1F39B FE0E ; text style; # (7.0) CONTROL KNOBS +1F39B FE0F ; emoji style; # (7.0) CONTROL KNOBS +1F39E FE0E ; text style; # (7.0) FILM FRAMES +1F39E FE0F ; emoji style; # (7.0) FILM FRAMES +1F39F FE0E ; text style; # (7.0) ADMISSION TICKETS +1F39F FE0F ; emoji style; # (7.0) ADMISSION TICKETS +1F3A7 FE0E ; text style; # (6.0) HEADPHONE +1F3A7 FE0F ; emoji style; # (6.0) HEADPHONE +1F3AC FE0E ; text style; # (6.0) CLAPPER BOARD +1F3AC FE0F ; emoji style; # (6.0) CLAPPER BOARD +1F3AD FE0E ; text style; # (6.0) PERFORMING ARTS +1F3AD FE0F ; emoji style; # (6.0) PERFORMING ARTS +1F3AE FE0E ; text style; # (6.0) VIDEO GAME +1F3AE FE0F ; emoji style; # (6.0) VIDEO GAME +1F3C2 FE0E ; text style; # (6.0) SNOWBOARDER +1F3C2 FE0F ; emoji style; # (6.0) SNOWBOARDER +1F3C4 FE0E ; text style; # (6.0) SURFER +1F3C4 FE0F ; emoji style; # (6.0) SURFER +1F3C6 FE0E ; text style; # (6.0) TROPHY +1F3C6 FE0F ; emoji style; # (6.0) TROPHY +1F3CA FE0E ; text style; # (6.0) SWIMMER +1F3CA FE0F ; emoji style; # (6.0) SWIMMER +1F3CB FE0E ; text style; # (7.0) WEIGHT LIFTER +1F3CB FE0F ; emoji style; # (7.0) WEIGHT LIFTER +1F3CC FE0E ; text style; # (7.0) GOLFER +1F3CC FE0F ; emoji style; # (7.0) GOLFER +1F3CD FE0E ; text style; # (7.0) RACING MOTORCYCLE +1F3CD FE0F ; emoji style; # (7.0) RACING MOTORCYCLE +1F3CE FE0E ; text style; # (7.0) RACING CAR +1F3CE FE0F ; emoji style; # (7.0) RACING CAR +1F3D4 FE0E ; text style; # (7.0) SNOW CAPPED MOUNTAIN +1F3D4 FE0F ; emoji style; # (7.0) SNOW CAPPED MOUNTAIN +1F3D5 FE0E ; text style; # (7.0) CAMPING +1F3D5 FE0F ; emoji style; # (7.0) CAMPING +1F3D6 FE0E ; text style; # (7.0) BEACH WITH UMBRELLA +1F3D6 FE0F ; emoji style; # (7.0) BEACH WITH UMBRELLA +1F3D7 FE0E ; text style; # (7.0) BUILDING CONSTRUCTION +1F3D7 FE0F ; emoji style; # (7.0) BUILDING CONSTRUCTION +1F3D8 FE0E ; text style; # (7.0) HOUSE BUILDINGS +1F3D8 FE0F ; emoji style; # (7.0) HOUSE BUILDINGS +1F3D9 FE0E ; text style; # (7.0) CITYSCAPE +1F3D9 FE0F ; emoji style; # (7.0) CITYSCAPE +1F3DA FE0E ; text style; # (7.0) DERELICT HOUSE BUILDING +1F3DA FE0F ; emoji style; # (7.0) DERELICT HOUSE BUILDING +1F3DB FE0E ; text style; # (7.0) CLASSICAL BUILDING +1F3DB FE0F ; emoji style; # (7.0) CLASSICAL BUILDING +1F3DC FE0E ; text style; # (7.0) DESERT +1F3DC FE0F ; emoji style; # (7.0) DESERT +1F3DD FE0E ; text style; # (7.0) DESERT ISLAND +1F3DD FE0F ; emoji style; # (7.0) DESERT ISLAND +1F3DE FE0E ; text style; # (7.0) NATIONAL PARK +1F3DE FE0F ; emoji style; # (7.0) NATIONAL PARK +1F3DF FE0E ; text style; # (7.0) STADIUM +1F3DF FE0F ; emoji style; # (7.0) STADIUM +1F3E0 FE0E ; text style; # (6.0) HOUSE BUILDING +1F3E0 FE0F ; emoji style; # (6.0) HOUSE BUILDING +1F3ED FE0E ; text style; # (6.0) FACTORY +1F3ED FE0F ; emoji style; # (6.0) FACTORY +1F3F3 FE0E ; text style; # (7.0) WAVING WHITE FLAG +1F3F3 FE0F ; emoji style; # (7.0) WAVING WHITE FLAG +1F3F5 FE0E ; text style; # (7.0) ROSETTE +1F3F5 FE0F ; emoji style; # (7.0) ROSETTE +1F3F7 FE0E ; text style; # (7.0) LABEL +1F3F7 FE0F ; emoji style; # (7.0) LABEL +1F408 FE0E ; text style; # (6.0) CAT +1F408 FE0F ; emoji style; # (6.0) CAT +1F415 FE0E ; text style; # (6.0) DOG +1F415 FE0F ; emoji style; # (6.0) DOG +1F41F FE0E ; text style; # (6.0) FISH +1F41F FE0F ; emoji style; # (6.0) FISH +1F426 FE0E ; text style; # (6.0) BIRD +1F426 FE0F ; emoji style; # (6.0) BIRD +1F43F FE0E ; text style; # (7.0) CHIPMUNK +1F43F FE0F ; emoji style; # (7.0) CHIPMUNK +1F441 FE0E ; text style; # (7.0) EYE +1F441 FE0F ; emoji style; # (7.0) EYE +1F442 FE0E ; text style; # (6.0) EAR +1F442 FE0F ; emoji style; # (6.0) EAR +1F446 FE0E ; text style; # (6.0) WHITE UP POINTING BACKHAND INDEX +1F446 FE0F ; emoji style; # (6.0) WHITE UP POINTING BACKHAND INDEX +1F447 FE0E ; text style; # (6.0) WHITE DOWN POINTING BACKHAND INDEX +1F447 FE0F ; emoji style; # (6.0) WHITE DOWN POINTING BACKHAND INDEX +1F448 FE0E ; text style; # (6.0) WHITE LEFT POINTING BACKHAND INDEX +1F448 FE0F ; emoji style; # (6.0) WHITE LEFT POINTING BACKHAND INDEX +1F449 FE0E ; text style; # (6.0) WHITE RIGHT POINTING BACKHAND INDEX +1F449 FE0F ; emoji style; # (6.0) WHITE RIGHT POINTING BACKHAND INDEX +1F44D FE0E ; text style; # (6.0) THUMBS UP SIGN +1F44D FE0F ; emoji style; # (6.0) THUMBS UP SIGN +1F44E FE0E ; text style; # (6.0) THUMBS DOWN SIGN +1F44E FE0F ; emoji style; # (6.0) THUMBS DOWN SIGN +1F453 FE0E ; text style; # (6.0) EYEGLASSES +1F453 FE0F ; emoji style; # (6.0) EYEGLASSES +1F46A FE0E ; text style; # (6.0) FAMILY +1F46A FE0F ; emoji style; # (6.0) FAMILY +1F47D FE0E ; text style; # (6.0) EXTRATERRESTRIAL ALIEN +1F47D FE0F ; emoji style; # (6.0) EXTRATERRESTRIAL ALIEN +1F4A3 FE0E ; text style; # (6.0) BOMB +1F4A3 FE0F ; emoji style; # (6.0) BOMB +1F4B0 FE0E ; text style; # (6.0) MONEY BAG +1F4B0 FE0F ; emoji style; # (6.0) MONEY BAG +1F4B3 FE0E ; text style; # (6.0) CREDIT CARD +1F4B3 FE0F ; emoji style; # (6.0) CREDIT CARD +1F4BB FE0E ; text style; # (6.0) PERSONAL COMPUTER +1F4BB FE0F ; emoji style; # (6.0) PERSONAL COMPUTER +1F4BF FE0E ; text style; # (6.0) OPTICAL DISC +1F4BF FE0F ; emoji style; # (6.0) OPTICAL DISC +1F4CB FE0E ; text style; # (6.0) CLIPBOARD +1F4CB FE0F ; emoji style; # (6.0) CLIPBOARD +1F4DA FE0E ; text style; # (6.0) BOOKS +1F4DA FE0F ; emoji style; # (6.0) BOOKS +1F4DF FE0E ; text style; # (6.0) PAGER +1F4DF FE0F ; emoji style; # (6.0) PAGER +1F4E4 FE0E ; text style; # (6.0) OUTBOX TRAY +1F4E4 FE0F ; emoji style; # (6.0) OUTBOX TRAY +1F4E5 FE0E ; text style; # (6.0) INBOX TRAY +1F4E5 FE0F ; emoji style; # (6.0) INBOX TRAY +1F4E6 FE0E ; text style; # (6.0) PACKAGE +1F4E6 FE0F ; emoji style; # (6.0) PACKAGE +1F4EA FE0E ; text style; # (6.0) CLOSED MAILBOX WITH LOWERED FLAG +1F4EA FE0F ; emoji style; # (6.0) CLOSED MAILBOX WITH LOWERED FLAG +1F4EB FE0E ; text style; # (6.0) CLOSED MAILBOX WITH RAISED FLAG +1F4EB FE0F ; emoji style; # (6.0) CLOSED MAILBOX WITH RAISED FLAG +1F4EC FE0E ; text style; # (6.0) OPEN MAILBOX WITH RAISED FLAG +1F4EC FE0F ; emoji style; # (6.0) OPEN MAILBOX WITH RAISED FLAG +1F4ED FE0E ; text style; # (6.0) OPEN MAILBOX WITH LOWERED FLAG +1F4ED FE0F ; emoji style; # (6.0) OPEN MAILBOX WITH LOWERED FLAG +1F4F7 FE0E ; text style; # (6.0) CAMERA +1F4F7 FE0F ; emoji style; # (6.0) CAMERA +1F4F9 FE0E ; text style; # (6.0) VIDEO CAMERA +1F4F9 FE0F ; emoji style; # (6.0) VIDEO CAMERA +1F4FA FE0E ; text style; # (6.0) TELEVISION +1F4FA FE0F ; emoji style; # (6.0) TELEVISION +1F4FB FE0E ; text style; # (6.0) RADIO +1F4FB FE0F ; emoji style; # (6.0) RADIO +1F4FD FE0E ; text style; # (7.0) FILM PROJECTOR +1F4FD FE0F ; emoji style; # (7.0) FILM PROJECTOR +1F508 FE0E ; text style; # (6.0) SPEAKER +1F508 FE0F ; emoji style; # (6.0) SPEAKER +1F50D FE0E ; text style; # (6.0) LEFT-POINTING MAGNIFYING GLASS +1F50D FE0F ; emoji style; # (6.0) LEFT-POINTING MAGNIFYING GLASS +1F512 FE0E ; text style; # (6.0) LOCK +1F512 FE0F ; emoji style; # (6.0) LOCK +1F513 FE0E ; text style; # (6.0) OPEN LOCK +1F513 FE0F ; emoji style; # (6.0) OPEN LOCK +1F549 FE0E ; text style; # (7.0) OM SYMBOL +1F549 FE0F ; emoji style; # (7.0) OM SYMBOL +1F54A FE0E ; text style; # (7.0) DOVE OF PEACE +1F54A FE0F ; emoji style; # (7.0) DOVE OF PEACE +1F550 FE0E ; text style; # (6.0) CLOCK FACE ONE OCLOCK +1F550 FE0F ; emoji style; # (6.0) CLOCK FACE ONE OCLOCK +1F551 FE0E ; text style; # (6.0) CLOCK FACE TWO OCLOCK +1F551 FE0F ; emoji style; # (6.0) CLOCK FACE TWO OCLOCK +1F552 FE0E ; text style; # (6.0) CLOCK FACE THREE OCLOCK +1F552 FE0F ; emoji style; # (6.0) CLOCK FACE THREE OCLOCK +1F553 FE0E ; text style; # (6.0) CLOCK FACE FOUR OCLOCK +1F553 FE0F ; emoji style; # (6.0) CLOCK FACE FOUR OCLOCK +1F554 FE0E ; text style; # (6.0) CLOCK FACE FIVE OCLOCK +1F554 FE0F ; emoji style; # (6.0) CLOCK FACE FIVE OCLOCK +1F555 FE0E ; text style; # (6.0) CLOCK FACE SIX OCLOCK +1F555 FE0F ; emoji style; # (6.0) CLOCK FACE SIX OCLOCK +1F556 FE0E ; text style; # (6.0) CLOCK FACE SEVEN OCLOCK +1F556 FE0F ; emoji style; # (6.0) CLOCK FACE SEVEN OCLOCK +1F557 FE0E ; text style; # (6.0) CLOCK FACE EIGHT OCLOCK +1F557 FE0F ; emoji style; # (6.0) CLOCK FACE EIGHT OCLOCK +1F558 FE0E ; text style; # (6.0) CLOCK FACE NINE OCLOCK +1F558 FE0F ; emoji style; # (6.0) CLOCK FACE NINE OCLOCK +1F559 FE0E ; text style; # (6.0) CLOCK FACE TEN OCLOCK +1F559 FE0F ; emoji style; # (6.0) CLOCK FACE TEN OCLOCK +1F55A FE0E ; text style; # (6.0) CLOCK FACE ELEVEN OCLOCK +1F55A FE0F ; emoji style; # (6.0) CLOCK FACE ELEVEN OCLOCK +1F55B FE0E ; text style; # (6.0) CLOCK FACE TWELVE OCLOCK +1F55B FE0F ; emoji style; # (6.0) CLOCK FACE TWELVE OCLOCK +1F55C FE0E ; text style; # (6.0) CLOCK FACE ONE-THIRTY +1F55C FE0F ; emoji style; # (6.0) CLOCK FACE ONE-THIRTY +1F55D FE0E ; text style; # (6.0) CLOCK FACE TWO-THIRTY +1F55D FE0F ; emoji style; # (6.0) CLOCK FACE TWO-THIRTY +1F55E FE0E ; text style; # (6.0) CLOCK FACE THREE-THIRTY +1F55E FE0F ; emoji style; # (6.0) CLOCK FACE THREE-THIRTY +1F55F FE0E ; text style; # (6.0) CLOCK FACE FOUR-THIRTY +1F55F FE0F ; emoji style; # (6.0) CLOCK FACE FOUR-THIRTY +1F560 FE0E ; text style; # (6.0) CLOCK FACE FIVE-THIRTY +1F560 FE0F ; emoji style; # (6.0) CLOCK FACE FIVE-THIRTY +1F561 FE0E ; text style; # (6.0) CLOCK FACE SIX-THIRTY +1F561 FE0F ; emoji style; # (6.0) CLOCK FACE SIX-THIRTY +1F562 FE0E ; text style; # (6.0) CLOCK FACE SEVEN-THIRTY +1F562 FE0F ; emoji style; # (6.0) CLOCK FACE SEVEN-THIRTY +1F563 FE0E ; text style; # (6.0) CLOCK FACE EIGHT-THIRTY +1F563 FE0F ; emoji style; # (6.0) CLOCK FACE EIGHT-THIRTY +1F564 FE0E ; text style; # (6.0) CLOCK FACE NINE-THIRTY +1F564 FE0F ; emoji style; # (6.0) CLOCK FACE NINE-THIRTY +1F565 FE0E ; text style; # (6.0) CLOCK FACE TEN-THIRTY +1F565 FE0F ; emoji style; # (6.0) CLOCK FACE TEN-THIRTY +1F566 FE0E ; text style; # (6.0) CLOCK FACE ELEVEN-THIRTY +1F566 FE0F ; emoji style; # (6.0) CLOCK FACE ELEVEN-THIRTY +1F567 FE0E ; text style; # (6.0) CLOCK FACE TWELVE-THIRTY +1F567 FE0F ; emoji style; # (6.0) CLOCK FACE TWELVE-THIRTY +1F56F FE0E ; text style; # (7.0) CANDLE +1F56F FE0F ; emoji style; # (7.0) CANDLE +1F570 FE0E ; text style; # (7.0) MANTELPIECE CLOCK +1F570 FE0F ; emoji style; # (7.0) MANTELPIECE CLOCK +1F573 FE0E ; text style; # (7.0) HOLE +1F573 FE0F ; emoji style; # (7.0) HOLE +1F574 FE0E ; text style; # (7.0) MAN IN BUSINESS SUIT LEVITATING +1F574 FE0F ; emoji style; # (7.0) MAN IN BUSINESS SUIT LEVITATING +1F575 FE0E ; text style; # (7.0) SLEUTH OR SPY +1F575 FE0F ; emoji style; # (7.0) SLEUTH OR SPY +1F576 FE0E ; text style; # (7.0) DARK SUNGLASSES +1F576 FE0F ; emoji style; # (7.0) DARK SUNGLASSES +1F577 FE0E ; text style; # (7.0) SPIDER +1F577 FE0F ; emoji style; # (7.0) SPIDER +1F578 FE0E ; text style; # (7.0) SPIDER WEB +1F578 FE0F ; emoji style; # (7.0) SPIDER WEB +1F579 FE0E ; text style; # (7.0) JOYSTICK +1F579 FE0F ; emoji style; # (7.0) JOYSTICK +1F587 FE0E ; text style; # (7.0) LINKED PAPERCLIPS +1F587 FE0F ; emoji style; # (7.0) LINKED PAPERCLIPS +1F58A FE0E ; text style; # (7.0) LOWER LEFT BALLPOINT PEN +1F58A FE0F ; emoji style; # (7.0) LOWER LEFT BALLPOINT PEN +1F58B FE0E ; text style; # (7.0) LOWER LEFT FOUNTAIN PEN +1F58B FE0F ; emoji style; # (7.0) LOWER LEFT FOUNTAIN PEN +1F58C FE0E ; text style; # (7.0) LOWER LEFT PAINTBRUSH +1F58C FE0F ; emoji style; # (7.0) LOWER LEFT PAINTBRUSH +1F58D FE0E ; text style; # (7.0) LOWER LEFT CRAYON +1F58D FE0F ; emoji style; # (7.0) LOWER LEFT CRAYON +1F590 FE0E ; text style; # (7.0) RAISED HAND WITH FINGERS SPLAYED +1F590 FE0F ; emoji style; # (7.0) RAISED HAND WITH FINGERS SPLAYED +1F5A5 FE0E ; text style; # (7.0) DESKTOP COMPUTER +1F5A5 FE0F ; emoji style; # (7.0) DESKTOP COMPUTER +1F5A8 FE0E ; text style; # (7.0) PRINTER +1F5A8 FE0F ; emoji style; # (7.0) PRINTER +1F5B1 FE0E ; text style; # (7.0) THREE BUTTON MOUSE +1F5B1 FE0F ; emoji style; # (7.0) THREE BUTTON MOUSE +1F5B2 FE0E ; text style; # (7.0) TRACKBALL +1F5B2 FE0F ; emoji style; # (7.0) TRACKBALL +1F5BC FE0E ; text style; # (7.0) FRAME WITH PICTURE +1F5BC FE0F ; emoji style; # (7.0) FRAME WITH PICTURE +1F5C2 FE0E ; text style; # (7.0) CARD INDEX DIVIDERS +1F5C2 FE0F ; emoji style; # (7.0) CARD INDEX DIVIDERS +1F5C3 FE0E ; text style; # (7.0) CARD FILE BOX +1F5C3 FE0F ; emoji style; # (7.0) CARD FILE BOX +1F5C4 FE0E ; text style; # (7.0) FILE CABINET +1F5C4 FE0F ; emoji style; # (7.0) FILE CABINET +1F5D1 FE0E ; text style; # (7.0) WASTEBASKET +1F5D1 FE0F ; emoji style; # (7.0) WASTEBASKET +1F5D2 FE0E ; text style; # (7.0) SPIRAL NOTE PAD +1F5D2 FE0F ; emoji style; # (7.0) SPIRAL NOTE PAD +1F5D3 FE0E ; text style; # (7.0) SPIRAL CALENDAR PAD +1F5D3 FE0F ; emoji style; # (7.0) SPIRAL CALENDAR PAD +1F5DC FE0E ; text style; # (7.0) COMPRESSION +1F5DC FE0F ; emoji style; # (7.0) COMPRESSION +1F5DD FE0E ; text style; # (7.0) OLD KEY +1F5DD FE0F ; emoji style; # (7.0) OLD KEY +1F5DE FE0E ; text style; # (7.0) ROLLED-UP NEWSPAPER +1F5DE FE0F ; emoji style; # (7.0) ROLLED-UP NEWSPAPER +1F5E1 FE0E ; text style; # (7.0) DAGGER KNIFE +1F5E1 FE0F ; emoji style; # (7.0) DAGGER KNIFE +1F5E3 FE0E ; text style; # (7.0) SPEAKING HEAD IN SILHOUETTE +1F5E3 FE0F ; emoji style; # (7.0) SPEAKING HEAD IN SILHOUETTE +1F5E8 FE0E ; text style; # (7.0) LEFT SPEECH BUBBLE +1F5E8 FE0F ; emoji style; # (7.0) LEFT SPEECH BUBBLE +1F5EF FE0E ; text style; # (7.0) RIGHT ANGER BUBBLE +1F5EF FE0F ; emoji style; # (7.0) RIGHT ANGER BUBBLE +1F5F3 FE0E ; text style; # (7.0) BALLOT BOX WITH BALLOT +1F5F3 FE0F ; emoji style; # (7.0) BALLOT BOX WITH BALLOT +1F5FA FE0E ; text style; # (7.0) WORLD MAP +1F5FA FE0F ; emoji style; # (7.0) WORLD MAP +1F610 FE0E ; text style; # (6.0) NEUTRAL FACE +1F610 FE0F ; emoji style; # (6.0) NEUTRAL FACE +1F687 FE0E ; text style; # (6.0) METRO +1F687 FE0F ; emoji style; # (6.0) METRO +1F68D FE0E ; text style; # (6.0) ONCOMING BUS +1F68D FE0F ; emoji style; # (6.0) ONCOMING BUS +1F691 FE0E ; text style; # (6.0) AMBULANCE +1F691 FE0F ; emoji style; # (6.0) AMBULANCE +1F694 FE0E ; text style; # (6.0) ONCOMING POLICE CAR +1F694 FE0F ; emoji style; # (6.0) ONCOMING POLICE CAR +1F698 FE0E ; text style; # (6.0) ONCOMING AUTOMOBILE +1F698 FE0F ; emoji style; # (6.0) ONCOMING AUTOMOBILE +1F6AD FE0E ; text style; # (6.0) NO SMOKING SYMBOL +1F6AD FE0F ; emoji style; # (6.0) NO SMOKING SYMBOL +1F6B2 FE0E ; text style; # (6.0) BICYCLE +1F6B2 FE0F ; emoji style; # (6.0) BICYCLE +1F6B9 FE0E ; text style; # (6.0) MENS SYMBOL +1F6B9 FE0F ; emoji style; # (6.0) MENS SYMBOL +1F6BA FE0E ; text style; # (6.0) WOMENS SYMBOL +1F6BA FE0F ; emoji style; # (6.0) WOMENS SYMBOL +1F6BC FE0E ; text style; # (6.0) BABY SYMBOL +1F6BC FE0F ; emoji style; # (6.0) BABY SYMBOL +1F6CB FE0E ; text style; # (7.0) COUCH AND LAMP +1F6CB FE0F ; emoji style; # (7.0) COUCH AND LAMP +1F6CD FE0E ; text style; # (7.0) SHOPPING BAGS +1F6CD FE0F ; emoji style; # (7.0) SHOPPING BAGS +1F6CE FE0E ; text style; # (7.0) BELLHOP BELL +1F6CE FE0F ; emoji style; # (7.0) BELLHOP BELL +1F6CF FE0E ; text style; # (7.0) BED +1F6CF FE0F ; emoji style; # (7.0) BED +1F6E0 FE0E ; text style; # (7.0) HAMMER AND WRENCH +1F6E0 FE0F ; emoji style; # (7.0) HAMMER AND WRENCH +1F6E1 FE0E ; text style; # (7.0) SHIELD +1F6E1 FE0F ; emoji style; # (7.0) SHIELD +1F6E2 FE0E ; text style; # (7.0) OIL DRUM +1F6E2 FE0F ; emoji style; # (7.0) OIL DRUM +1F6E3 FE0E ; text style; # (7.0) MOTORWAY +1F6E3 FE0F ; emoji style; # (7.0) MOTORWAY +1F6E4 FE0E ; text style; # (7.0) RAILWAY TRACK +1F6E4 FE0F ; emoji style; # (7.0) RAILWAY TRACK +1F6E5 FE0E ; text style; # (7.0) MOTOR BOAT +1F6E5 FE0F ; emoji style; # (7.0) MOTOR BOAT +1F6E9 FE0E ; text style; # (7.0) SMALL AIRPLANE +1F6E9 FE0F ; emoji style; # (7.0) SMALL AIRPLANE +1F6F0 FE0E ; text style; # (7.0) SATELLITE +1F6F0 FE0F ; emoji style; # (7.0) SATELLITE +1F6F3 FE0E ; text style; # (7.0) PASSENGER SHIP +1F6F3 FE0F ; emoji style; # (7.0) PASSENGER SHIP + +#Total sequences: 371 + +#EOF diff --git a/contrib/python/wcwidth/py2/tests/emoji-zwj-sequences.txt b/contrib/python/wcwidth/py2/tests/emoji-zwj-sequences.txt new file mode 100644 index 0000000000..25f8b6154b --- /dev/null +++ b/contrib/python/wcwidth/py2/tests/emoji-zwj-sequences.txt @@ -0,0 +1,1529 @@ +# emoji-zwj-sequences.txt +# Date: 2023-06-05, 20:04:50 GMT +# © 2023 Unicode®, Inc. +# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. +# For terms of use, see https://www.unicode.org/terms_of_use.html +# +# Emoji ZWJ Sequences for UTS #51 +# Version: 15.1 +# +# For documentation and usage, see https://www.unicode.org/reports/tr51 +# +# Format: +# code_point(s) ; type_field ; description # comments +# Fields: +# code_point(s): one or more code points in hex format, separated by spaces +# type_field :RGI_Emoji_ZWJ_Sequence +# The type_field is a convenience for parsing the emoji sequence files, and is not intended to be maintained as a property. +# short name: CLDR short name of sequence; characters may be escaped with \x{hex}. +# +# For the purpose of regular expressions, the above type field defines the name of +# a binary property of strings. The short name of the property is the same as the long name. +# +# Characters and sequences are listed in code point order. Users should be shown a more natural order. +# See the CLDR collation order for Emoji. + +# ================================================ + +# RGI_Emoji_ZWJ_Sequence: Family + +1F468 200D 2764 FE0F 200D 1F468 ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man # E2.0 [1] (👨❤️👨) +1F468 200D 2764 FE0F 200D 1F48B 200D 1F468 ; RGI_Emoji_ZWJ_Sequence ; kiss: man, man # E2.0 [1] (👨❤️💋👨) +1F468 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: man, boy # E4.0 [1] (👨👦) +1F468 200D 1F466 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: man, boy, boy # E4.0 [1] (👨👦👦) +1F468 200D 1F467 ; RGI_Emoji_ZWJ_Sequence ; family: man, girl # E4.0 [1] (👨👧) +1F468 200D 1F467 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: man, girl, boy # E4.0 [1] (👨👧👦) +1F468 200D 1F467 200D 1F467 ; RGI_Emoji_ZWJ_Sequence ; family: man, girl, girl # E4.0 [1] (👨👧👧) +1F468 200D 1F468 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: man, man, boy # E2.0 [1] (👨👨👦) +1F468 200D 1F468 200D 1F466 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: man, man, boy, boy # E2.0 [1] (👨👨👦👦) +1F468 200D 1F468 200D 1F467 ; RGI_Emoji_ZWJ_Sequence ; family: man, man, girl # E2.0 [1] (👨👨👧) +1F468 200D 1F468 200D 1F467 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: man, man, girl, boy # E2.0 [1] (👨👨👧👦) +1F468 200D 1F468 200D 1F467 200D 1F467 ; RGI_Emoji_ZWJ_Sequence ; family: man, man, girl, girl # E2.0 [1] (👨👨👧👧) +1F468 200D 1F469 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: man, woman, boy # E2.0 [1] (👨👩👦) +1F468 200D 1F469 200D 1F466 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: man, woman, boy, boy # E2.0 [1] (👨👩👦👦) +1F468 200D 1F469 200D 1F467 ; RGI_Emoji_ZWJ_Sequence ; family: man, woman, girl # E2.0 [1] (👨👩👧) +1F468 200D 1F469 200D 1F467 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: man, woman, girl, boy # E2.0 [1] (👨👩👧👦) +1F468 200D 1F469 200D 1F467 200D 1F467 ; RGI_Emoji_ZWJ_Sequence ; family: man, woman, girl, girl # E2.0 [1] (👨👩👧👧) +1F468 1F3FB 200D 2764 FE0F 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, light skin tone # E13.1 [1] (👨🏻❤️👨🏻) +1F468 1F3FB 200D 2764 FE0F 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, light skin tone, medium-light skin tone #E13.1[1] (👨🏻❤️👨🏼) +1F468 1F3FB 200D 2764 FE0F 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, light skin tone, medium skin tone # E13.1 [1] (👨🏻❤️👨🏽) +1F468 1F3FB 200D 2764 FE0F 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, light skin tone, medium-dark skin tone #E13.1[1] (👨🏻❤️👨🏾) +1F468 1F3FB 200D 2764 FE0F 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, light skin tone, dark skin tone # E13.1 [1] (👨🏻❤️👨🏿) +1F468 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: man, man, light skin tone # E13.1 [1] (👨🏻❤️💋👨🏻) +1F468 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: man, man, light skin tone, medium-light skin tone #E13.1 [1] (👨🏻❤️💋👨🏼) +1F468 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: man, man, light skin tone, medium skin tone # E13.1 [1] (👨🏻❤️💋👨🏽) +1F468 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: man, man, light skin tone, medium-dark skin tone # E13.1 [1] (👨🏻❤️💋👨🏾) +1F468 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: man, man, light skin tone, dark skin tone # E13.1 [1] (👨🏻❤️💋👨🏿) +1F468 1F3FB 200D 1F91D 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; men holding hands: light skin tone, medium-light skin tone # E12.1 [1] (👨🏻🤝👨🏼) +1F468 1F3FB 200D 1F91D 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; men holding hands: light skin tone, medium skin tone # E12.1 [1] (👨🏻🤝👨🏽) +1F468 1F3FB 200D 1F91D 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; men holding hands: light skin tone, medium-dark skin tone # E12.1 [1] (👨🏻🤝👨🏾) +1F468 1F3FB 200D 1F91D 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; men holding hands: light skin tone, dark skin tone # E12.1 [1] (👨🏻🤝👨🏿) +1F468 1F3FC 200D 2764 FE0F 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium-light skin tone, light skin tone #E13.1[1] (👨🏼❤️👨🏻) +1F468 1F3FC 200D 2764 FE0F 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium-light skin tone # E13.1 [1] (👨🏼❤️👨🏼) +1F468 1F3FC 200D 2764 FE0F 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium-light skin tone, medium skin tone #E13.1[1] (👨🏼❤️👨🏽) +1F468 1F3FC 200D 2764 FE0F 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium-light skin tone, medium-dark skin tone #E13.1[1] (👨🏼❤️👨🏾) +1F468 1F3FC 200D 2764 FE0F 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium-light skin tone, dark skin tone #E13.1[1] (👨🏼❤️👨🏿) +1F468 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium-light skin tone, light skin tone #E13.1 [1] (👨🏼❤️💋👨🏻) +1F468 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium-light skin tone # E13.1 [1] (👨🏼❤️💋👨🏼) +1F468 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium-light skin tone, medium skin tone #E13.1 [1] (👨🏼❤️💋👨🏽) +1F468 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium-light skin tone, medium-dark skin tone #E13.1[1] (👨🏼❤️💋👨🏾) +1F468 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium-light skin tone, dark skin tone # E13.1 [1] (👨🏼❤️💋👨🏿) +1F468 1F3FC 200D 1F91D 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; men holding hands: medium-light skin tone, light skin tone # E12.0 [1] (👨🏼🤝👨🏻) +1F468 1F3FC 200D 1F91D 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; men holding hands: medium-light skin tone, medium skin tone # E12.1 [1] (👨🏼🤝👨🏽) +1F468 1F3FC 200D 1F91D 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; men holding hands: medium-light skin tone, medium-dark skin tone #E12.1 [1] (👨🏼🤝👨🏾) +1F468 1F3FC 200D 1F91D 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; men holding hands: medium-light skin tone, dark skin tone # E12.1 [1] (👨🏼🤝👨🏿) +1F468 1F3FD 200D 2764 FE0F 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium skin tone, light skin tone # E13.1 [1] (👨🏽❤️👨🏻) +1F468 1F3FD 200D 2764 FE0F 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium skin tone, medium-light skin tone #E13.1[1] (👨🏽❤️👨🏼) +1F468 1F3FD 200D 2764 FE0F 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium skin tone # E13.1 [1] (👨🏽❤️👨🏽) +1F468 1F3FD 200D 2764 FE0F 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium skin tone, medium-dark skin tone #E13.1[1] (👨🏽❤️👨🏾) +1F468 1F3FD 200D 2764 FE0F 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium skin tone, dark skin tone # E13.1 [1] (👨🏽❤️👨🏿) +1F468 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium skin tone, light skin tone # E13.1 [1] (👨🏽❤️💋👨🏻) +1F468 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium skin tone, medium-light skin tone #E13.1 [1] (👨🏽❤️💋👨🏼) +1F468 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium skin tone # E13.1 [1] (👨🏽❤️💋👨🏽) +1F468 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium skin tone, medium-dark skin tone #E13.1 [1] (👨🏽❤️💋👨🏾) +1F468 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium skin tone, dark skin tone # E13.1 [1] (👨🏽❤️💋👨🏿) +1F468 1F3FD 200D 1F91D 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; men holding hands: medium skin tone, light skin tone # E12.0 [1] (👨🏽🤝👨🏻) +1F468 1F3FD 200D 1F91D 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; men holding hands: medium skin tone, medium-light skin tone # E12.0 [1] (👨🏽🤝👨🏼) +1F468 1F3FD 200D 1F91D 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; men holding hands: medium skin tone, medium-dark skin tone # E12.1 [1] (👨🏽🤝👨🏾) +1F468 1F3FD 200D 1F91D 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; men holding hands: medium skin tone, dark skin tone # E12.1 [1] (👨🏽🤝👨🏿) +1F468 1F3FE 200D 2764 FE0F 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium-dark skin tone, light skin tone #E13.1[1] (👨🏾❤️👨🏻) +1F468 1F3FE 200D 2764 FE0F 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium-dark skin tone, medium-light skin tone #E13.1[1] (👨🏾❤️👨🏼) +1F468 1F3FE 200D 2764 FE0F 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium-dark skin tone, medium skin tone #E13.1[1] (👨🏾❤️👨🏽) +1F468 1F3FE 200D 2764 FE0F 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium-dark skin tone # E13.1 [1] (👨🏾❤️👨🏾) +1F468 1F3FE 200D 2764 FE0F 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium-dark skin tone, dark skin tone #E13.1[1] (👨🏾❤️👨🏿) +1F468 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium-dark skin tone, light skin tone # E13.1 [1] (👨🏾❤️💋👨🏻) +1F468 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium-dark skin tone, medium-light skin tone #E13.1[1] (👨🏾❤️💋👨🏼) +1F468 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium-dark skin tone, medium skin tone #E13.1 [1] (👨🏾❤️💋👨🏽) +1F468 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium-dark skin tone # E13.1 [1] (👨🏾❤️💋👨🏾) +1F468 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium-dark skin tone, dark skin tone # E13.1 [1] (👨🏾❤️💋👨🏿) +1F468 1F3FE 200D 1F91D 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; men holding hands: medium-dark skin tone, light skin tone # E12.0 [1] (👨🏾🤝👨🏻) +1F468 1F3FE 200D 1F91D 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; men holding hands: medium-dark skin tone, medium-light skin tone #E12.0 [1] (👨🏾🤝👨🏼) +1F468 1F3FE 200D 1F91D 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; men holding hands: medium-dark skin tone, medium skin tone # E12.0 [1] (👨🏾🤝👨🏽) +1F468 1F3FE 200D 1F91D 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; men holding hands: medium-dark skin tone, dark skin tone # E12.1 [1] (👨🏾🤝👨🏿) +1F468 1F3FF 200D 2764 FE0F 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, dark skin tone, light skin tone # E13.1 [1] (👨🏿❤️👨🏻) +1F468 1F3FF 200D 2764 FE0F 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, dark skin tone, medium-light skin tone #E13.1[1] (👨🏿❤️👨🏼) +1F468 1F3FF 200D 2764 FE0F 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, dark skin tone, medium skin tone # E13.1 [1] (👨🏿❤️👨🏽) +1F468 1F3FF 200D 2764 FE0F 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, dark skin tone, medium-dark skin tone #E13.1[1] (👨🏿❤️👨🏾) +1F468 1F3FF 200D 2764 FE0F 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, dark skin tone # E13.1 [1] (👨🏿❤️👨🏿) +1F468 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: man, man, dark skin tone, light skin tone # E13.1 [1] (👨🏿❤️💋👨🏻) +1F468 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: man, man, dark skin tone, medium-light skin tone # E13.1 [1] (👨🏿❤️💋👨🏼) +1F468 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: man, man, dark skin tone, medium skin tone # E13.1 [1] (👨🏿❤️💋👨🏽) +1F468 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: man, man, dark skin tone, medium-dark skin tone # E13.1 [1] (👨🏿❤️💋👨🏾) +1F468 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: man, man, dark skin tone # E13.1 [1] (👨🏿❤️💋👨🏿) +1F468 1F3FF 200D 1F91D 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; men holding hands: dark skin tone, light skin tone # E12.0 [1] (👨🏿🤝👨🏻) +1F468 1F3FF 200D 1F91D 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; men holding hands: dark skin tone, medium-light skin tone # E12.0 [1] (👨🏿🤝👨🏼) +1F468 1F3FF 200D 1F91D 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; men holding hands: dark skin tone, medium skin tone # E12.0 [1] (👨🏿🤝👨🏽) +1F468 1F3FF 200D 1F91D 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; men holding hands: dark skin tone, medium-dark skin tone # E12.0 [1] (👨🏿🤝👨🏾) +1F469 200D 2764 FE0F 200D 1F468 ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man # E2.0 [1] (👩❤️👨) +1F469 200D 2764 FE0F 200D 1F469 ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman # E2.0 [1] (👩❤️👩) +1F469 200D 2764 FE0F 200D 1F48B 200D 1F468 ; RGI_Emoji_ZWJ_Sequence ; kiss: woman, man # E2.0 [1] (👩❤️💋👨) +1F469 200D 2764 FE0F 200D 1F48B 200D 1F469 ; RGI_Emoji_ZWJ_Sequence ; kiss: woman, woman # E2.0 [1] (👩❤️💋👩) +1F469 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: woman, boy # E4.0 [1] (👩👦) +1F469 200D 1F466 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: woman, boy, boy # E4.0 [1] (👩👦👦) +1F469 200D 1F467 ; RGI_Emoji_ZWJ_Sequence ; family: woman, girl # E4.0 [1] (👩👧) +1F469 200D 1F467 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: woman, girl, boy # E4.0 [1] (👩👧👦) +1F469 200D 1F467 200D 1F467 ; RGI_Emoji_ZWJ_Sequence ; family: woman, girl, girl # E4.0 [1] (👩👧👧) +1F469 200D 1F469 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: woman, woman, boy # E2.0 [1] (👩👩👦) +1F469 200D 1F469 200D 1F466 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: woman, woman, boy, boy # E2.0 [1] (👩👩👦👦) +1F469 200D 1F469 200D 1F467 ; RGI_Emoji_ZWJ_Sequence ; family: woman, woman, girl # E2.0 [1] (👩👩👧) +1F469 200D 1F469 200D 1F467 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: woman, woman, girl, boy # E2.0 [1] (👩👩👧👦) +1F469 200D 1F469 200D 1F467 200D 1F467 ; RGI_Emoji_ZWJ_Sequence ; family: woman, woman, girl, girl # E2.0 [1] (👩👩👧👧) +1F469 1F3FB 200D 2764 FE0F 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, light skin tone # E13.1 [1] (👩🏻❤️👨🏻) +1F469 1F3FB 200D 2764 FE0F 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, light skin tone, medium-light skin tone #E13.1[1] (👩🏻❤️👨🏼) +1F469 1F3FB 200D 2764 FE0F 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, light skin tone, medium skin tone #E13.1 [1] (👩🏻❤️👨🏽) +1F469 1F3FB 200D 2764 FE0F 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, light skin tone, medium-dark skin tone #E13.1[1] (👩🏻❤️👨🏾) +1F469 1F3FB 200D 2764 FE0F 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, light skin tone, dark skin tone # E13.1 [1] (👩🏻❤️👨🏿) +1F469 1F3FB 200D 2764 FE0F 200D 1F469 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, light skin tone # E13.1 [1] (👩🏻❤️👩🏻) +1F469 1F3FB 200D 2764 FE0F 200D 1F469 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, light skin tone, medium-light skin tone #E13.1[1] (👩🏻❤️👩🏼) +1F469 1F3FB 200D 2764 FE0F 200D 1F469 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, light skin tone, medium skin tone #E13.1[1] (👩🏻❤️👩🏽) +1F469 1F3FB 200D 2764 FE0F 200D 1F469 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, light skin tone, medium-dark skin tone #E13.1[1] (👩🏻❤️👩🏾) +1F469 1F3FB 200D 2764 FE0F 200D 1F469 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, light skin tone, dark skin tone #E13.1 [1] (👩🏻❤️👩🏿) +1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, light skin tone # E13.1 [1] (👩🏻❤️💋👨🏻) +1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, light skin tone, medium-light skin tone #E13.1[1] (👩🏻❤️💋👨🏼) +1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, light skin tone, medium skin tone # E13.1 [1] (👩🏻❤️💋👨🏽) +1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, light skin tone, medium-dark skin tone #E13.1 [1] (👩🏻❤️💋👨🏾) +1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, light skin tone, dark skin tone # E13.1 [1] (👩🏻❤️💋👨🏿) +1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, light skin tone # E13.1 [1] (👩🏻❤️💋👩🏻) +1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, light skin tone, medium-light skin tone #E13.1[1] (👩🏻❤️💋👩🏼) +1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, light skin tone, medium skin tone # E13.1 [1] (👩🏻❤️💋👩🏽) +1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, light skin tone, medium-dark skin tone #E13.1[1] (👩🏻❤️💋👩🏾) +1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, light skin tone, dark skin tone # E13.1 [1] (👩🏻❤️💋👩🏿) +1F469 1F3FB 200D 1F91D 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: light skin tone, medium-light skin tone #E12.0[1] (👩🏻🤝👨🏼) +1F469 1F3FB 200D 1F91D 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: light skin tone, medium skin tone # E12.0 [1] (👩🏻🤝👨🏽) +1F469 1F3FB 200D 1F91D 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: light skin tone, medium-dark skin tone #E12.0[1] (👩🏻🤝👨🏾) +1F469 1F3FB 200D 1F91D 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: light skin tone, dark skin tone # E12.0 [1] (👩🏻🤝👨🏿) +1F469 1F3FB 200D 1F91D 200D 1F469 1F3FC ; RGI_Emoji_ZWJ_Sequence ; women holding hands: light skin tone, medium-light skin tone # E12.1 [1] (👩🏻🤝👩🏼) +1F469 1F3FB 200D 1F91D 200D 1F469 1F3FD ; RGI_Emoji_ZWJ_Sequence ; women holding hands: light skin tone, medium skin tone # E12.1 [1] (👩🏻🤝👩🏽) +1F469 1F3FB 200D 1F91D 200D 1F469 1F3FE ; RGI_Emoji_ZWJ_Sequence ; women holding hands: light skin tone, medium-dark skin tone # E12.1 [1] (👩🏻🤝👩🏾) +1F469 1F3FB 200D 1F91D 200D 1F469 1F3FF ; RGI_Emoji_ZWJ_Sequence ; women holding hands: light skin tone, dark skin tone # E12.1 [1] (👩🏻🤝👩🏿) +1F469 1F3FC 200D 2764 FE0F 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium-light skin tone, light skin tone #E13.1[1] (👩🏼❤️👨🏻) +1F469 1F3FC 200D 2764 FE0F 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium-light skin tone # E13.1 [1] (👩🏼❤️👨🏼) +1F469 1F3FC 200D 2764 FE0F 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium-light skin tone, medium skin tone #E13.1[1] (👩🏼❤️👨🏽) +1F469 1F3FC 200D 2764 FE0F 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium-light skin tone, medium-dark skin tone #E13.1[1] (👩🏼❤️👨🏾) +1F469 1F3FC 200D 2764 FE0F 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium-light skin tone, dark skin tone #E13.1[1] (👩🏼❤️👨🏿) +1F469 1F3FC 200D 2764 FE0F 200D 1F469 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium-light skin tone, light skin tone #E13.1[1] (👩🏼❤️👩🏻) +1F469 1F3FC 200D 2764 FE0F 200D 1F469 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium-light skin tone # E13.1 [1] (👩🏼❤️👩🏼) +1F469 1F3FC 200D 2764 FE0F 200D 1F469 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium-light skin tone, medium skin tone #E13.1[1] (👩🏼❤️👩🏽) +1F469 1F3FC 200D 2764 FE0F 200D 1F469 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium-light skin tone, medium-dark skin tone #E13.1[1] (👩🏼❤️👩🏾) +1F469 1F3FC 200D 2764 FE0F 200D 1F469 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium-light skin tone, dark skin tone #E13.1[1] (👩🏼❤️👩🏿) +1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium-light skin tone, light skin tone #E13.1[1] (👩🏼❤️💋👨🏻) +1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium-light skin tone # E13.1 [1] (👩🏼❤️💋👨🏼) +1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium-light skin tone, medium skin tone #E13.1[1] (👩🏼❤️💋👨🏽) +1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium-light skin tone, medium-dark skin tone #E13.1[1] (👩🏼❤️💋👨🏾) +1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium-light skin tone, dark skin tone #E13.1 [1] (👩🏼❤️💋👨🏿) +1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium-light skin tone, light skin tone #E13.1[1] (👩🏼❤️💋👩🏻) +1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium-light skin tone # E13.1 [1] (👩🏼❤️💋👩🏼) +1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium-light skin tone, medium skin tone #E13.1[1] (👩🏼❤️💋👩🏽) +1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium-light skin tone, medium-dark skin tone #E13.1[1] (👩🏼❤️💋👩🏾) +1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium-light skin tone, dark skin tone #E13.1[1] (👩🏼❤️💋👩🏿) +1F469 1F3FC 200D 1F91D 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: medium-light skin tone, light skin tone #E12.0[1] (👩🏼🤝👨🏻) +1F469 1F3FC 200D 1F91D 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: medium-light skin tone, medium skin tone #E12.0[1] (👩🏼🤝👨🏽) +1F469 1F3FC 200D 1F91D 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: medium-light skin tone, medium-dark skin tone #E12.0[1] (👩🏼🤝👨🏾) +1F469 1F3FC 200D 1F91D 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: medium-light skin tone, dark skin tone #E12.0[1] (👩🏼🤝👨🏿) +1F469 1F3FC 200D 1F91D 200D 1F469 1F3FB ; RGI_Emoji_ZWJ_Sequence ; women holding hands: medium-light skin tone, light skin tone # E12.0 [1] (👩🏼🤝👩🏻) +1F469 1F3FC 200D 1F91D 200D 1F469 1F3FD ; RGI_Emoji_ZWJ_Sequence ; women holding hands: medium-light skin tone, medium skin tone # E12.1 [1] (👩🏼🤝👩🏽) +1F469 1F3FC 200D 1F91D 200D 1F469 1F3FE ; RGI_Emoji_ZWJ_Sequence ; women holding hands: medium-light skin tone, medium-dark skin tone #E12.1[1] (👩🏼🤝👩🏾) +1F469 1F3FC 200D 1F91D 200D 1F469 1F3FF ; RGI_Emoji_ZWJ_Sequence ; women holding hands: medium-light skin tone, dark skin tone # E12.1 [1] (👩🏼🤝👩🏿) +1F469 1F3FD 200D 2764 FE0F 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium skin tone, light skin tone #E13.1 [1] (👩🏽❤️👨🏻) +1F469 1F3FD 200D 2764 FE0F 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium skin tone, medium-light skin tone #E13.1[1] (👩🏽❤️👨🏼) +1F469 1F3FD 200D 2764 FE0F 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium skin tone # E13.1 [1] (👩🏽❤️👨🏽) +1F469 1F3FD 200D 2764 FE0F 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium skin tone, medium-dark skin tone #E13.1[1] (👩🏽❤️👨🏾) +1F469 1F3FD 200D 2764 FE0F 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium skin tone, dark skin tone #E13.1 [1] (👩🏽❤️👨🏿) +1F469 1F3FD 200D 2764 FE0F 200D 1F469 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium skin tone, light skin tone #E13.1[1] (👩🏽❤️👩🏻) +1F469 1F3FD 200D 2764 FE0F 200D 1F469 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium skin tone, medium-light skin tone #E13.1[1] (👩🏽❤️👩🏼) +1F469 1F3FD 200D 2764 FE0F 200D 1F469 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium skin tone # E13.1 [1] (👩🏽❤️👩🏽) +1F469 1F3FD 200D 2764 FE0F 200D 1F469 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium skin tone, medium-dark skin tone #E13.1[1] (👩🏽❤️👩🏾) +1F469 1F3FD 200D 2764 FE0F 200D 1F469 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium skin tone, dark skin tone #E13.1[1] (👩🏽❤️👩🏿) +1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium skin tone, light skin tone # E13.1 [1] (👩🏽❤️💋👨🏻) +1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium skin tone, medium-light skin tone #E13.1[1] (👩🏽❤️💋👨🏼) +1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium skin tone # E13.1 [1] (👩🏽❤️💋👨🏽) +1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium skin tone, medium-dark skin tone #E13.1[1] (👩🏽❤️💋👨🏾) +1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium skin tone, dark skin tone # E13.1 [1] (👩🏽❤️💋👨🏿) +1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium skin tone, light skin tone # E13.1 [1] (👩🏽❤️💋👩🏻) +1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium skin tone, medium-light skin tone #E13.1[1] (👩🏽❤️💋👩🏼) +1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium skin tone # E13.1 [1] (👩🏽❤️💋👩🏽) +1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium skin tone, medium-dark skin tone #E13.1[1] (👩🏽❤️💋👩🏾) +1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium skin tone, dark skin tone # E13.1 [1] (👩🏽❤️💋👩🏿) +1F469 1F3FD 200D 1F91D 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: medium skin tone, light skin tone # E12.0 [1] (👩🏽🤝👨🏻) +1F469 1F3FD 200D 1F91D 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: medium skin tone, medium-light skin tone #E12.0[1] (👩🏽🤝👨🏼) +1F469 1F3FD 200D 1F91D 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: medium skin tone, medium-dark skin tone #E12.0[1] (👩🏽🤝👨🏾) +1F469 1F3FD 200D 1F91D 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: medium skin tone, dark skin tone # E12.0 [1] (👩🏽🤝👨🏿) +1F469 1F3FD 200D 1F91D 200D 1F469 1F3FB ; RGI_Emoji_ZWJ_Sequence ; women holding hands: medium skin tone, light skin tone # E12.0 [1] (👩🏽🤝👩🏻) +1F469 1F3FD 200D 1F91D 200D 1F469 1F3FC ; RGI_Emoji_ZWJ_Sequence ; women holding hands: medium skin tone, medium-light skin tone # E12.0 [1] (👩🏽🤝👩🏼) +1F469 1F3FD 200D 1F91D 200D 1F469 1F3FE ; RGI_Emoji_ZWJ_Sequence ; women holding hands: medium skin tone, medium-dark skin tone # E12.1 [1] (👩🏽🤝👩🏾) +1F469 1F3FD 200D 1F91D 200D 1F469 1F3FF ; RGI_Emoji_ZWJ_Sequence ; women holding hands: medium skin tone, dark skin tone # E12.1 [1] (👩🏽🤝👩🏿) +1F469 1F3FE 200D 2764 FE0F 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium-dark skin tone, light skin tone #E13.1[1] (👩🏾❤️👨🏻) +1F469 1F3FE 200D 2764 FE0F 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium-dark skin tone, medium-light skin tone #E13.1[1] (👩🏾❤️👨🏼) +1F469 1F3FE 200D 2764 FE0F 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium-dark skin tone, medium skin tone #E13.1[1] (👩🏾❤️👨🏽) +1F469 1F3FE 200D 2764 FE0F 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium-dark skin tone # E13.1 [1] (👩🏾❤️👨🏾) +1F469 1F3FE 200D 2764 FE0F 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium-dark skin tone, dark skin tone #E13.1[1] (👩🏾❤️👨🏿) +1F469 1F3FE 200D 2764 FE0F 200D 1F469 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium-dark skin tone, light skin tone #E13.1[1] (👩🏾❤️👩🏻) +1F469 1F3FE 200D 2764 FE0F 200D 1F469 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium-dark skin tone, medium-light skin tone #E13.1[1] (👩🏾❤️👩🏼) +1F469 1F3FE 200D 2764 FE0F 200D 1F469 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium-dark skin tone, medium skin tone #E13.1[1] (👩🏾❤️👩🏽) +1F469 1F3FE 200D 2764 FE0F 200D 1F469 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium-dark skin tone # E13.1 [1] (👩🏾❤️👩🏾) +1F469 1F3FE 200D 2764 FE0F 200D 1F469 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium-dark skin tone, dark skin tone #E13.1[1] (👩🏾❤️👩🏿) +1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium-dark skin tone, light skin tone #E13.1 [1] (👩🏾❤️💋👨🏻) +1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium-dark skin tone, medium-light skin tone #E13.1[1] (👩🏾❤️💋👨🏼) +1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium-dark skin tone, medium skin tone #E13.1[1] (👩🏾❤️💋👨🏽) +1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium-dark skin tone # E13.1 [1] (👩🏾❤️💋👨🏾) +1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium-dark skin tone, dark skin tone #E13.1 [1] (👩🏾❤️💋👨🏿) +1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium-dark skin tone, light skin tone #E13.1[1] (👩🏾❤️💋👩🏻) +1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium-dark skin tone, medium-light skin tone #E13.1[1] (👩🏾❤️💋👩🏼) +1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium-dark skin tone, medium skin tone #E13.1[1] (👩🏾❤️💋👩🏽) +1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium-dark skin tone # E13.1 [1] (👩🏾❤️💋👩🏾) +1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium-dark skin tone, dark skin tone #E13.1[1] (👩🏾❤️💋👩🏿) +1F469 1F3FE 200D 1F91D 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: medium-dark skin tone, light skin tone #E12.0[1] (👩🏾🤝👨🏻) +1F469 1F3FE 200D 1F91D 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: medium-dark skin tone, medium-light skin tone #E12.0[1] (👩🏾🤝👨🏼) +1F469 1F3FE 200D 1F91D 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: medium-dark skin tone, medium skin tone #E12.0[1] (👩🏾🤝👨🏽) +1F469 1F3FE 200D 1F91D 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: medium-dark skin tone, dark skin tone #E12.0[1] (👩🏾🤝👨🏿) +1F469 1F3FE 200D 1F91D 200D 1F469 1F3FB ; RGI_Emoji_ZWJ_Sequence ; women holding hands: medium-dark skin tone, light skin tone # E12.0 [1] (👩🏾🤝👩🏻) +1F469 1F3FE 200D 1F91D 200D 1F469 1F3FC ; RGI_Emoji_ZWJ_Sequence ; women holding hands: medium-dark skin tone, medium-light skin tone #E12.0[1] (👩🏾🤝👩🏼) +1F469 1F3FE 200D 1F91D 200D 1F469 1F3FD ; RGI_Emoji_ZWJ_Sequence ; women holding hands: medium-dark skin tone, medium skin tone # E12.0 [1] (👩🏾🤝👩🏽) +1F469 1F3FE 200D 1F91D 200D 1F469 1F3FF ; RGI_Emoji_ZWJ_Sequence ; women holding hands: medium-dark skin tone, dark skin tone # E12.1 [1] (👩🏾🤝👩🏿) +1F469 1F3FF 200D 2764 FE0F 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, dark skin tone, light skin tone # E13.1 [1] (👩🏿❤️👨🏻) +1F469 1F3FF 200D 2764 FE0F 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, dark skin tone, medium-light skin tone #E13.1[1] (👩🏿❤️👨🏼) +1F469 1F3FF 200D 2764 FE0F 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, dark skin tone, medium skin tone #E13.1 [1] (👩🏿❤️👨🏽) +1F469 1F3FF 200D 2764 FE0F 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, dark skin tone, medium-dark skin tone #E13.1[1] (👩🏿❤️👨🏾) +1F469 1F3FF 200D 2764 FE0F 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, dark skin tone # E13.1 [1] (👩🏿❤️👨🏿) +1F469 1F3FF 200D 2764 FE0F 200D 1F469 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, dark skin tone, light skin tone #E13.1 [1] (👩🏿❤️👩🏻) +1F469 1F3FF 200D 2764 FE0F 200D 1F469 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, dark skin tone, medium-light skin tone #E13.1[1] (👩🏿❤️👩🏼) +1F469 1F3FF 200D 2764 FE0F 200D 1F469 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, dark skin tone, medium skin tone #E13.1[1] (👩🏿❤️👩🏽) +1F469 1F3FF 200D 2764 FE0F 200D 1F469 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, dark skin tone, medium-dark skin tone #E13.1[1] (👩🏿❤️👩🏾) +1F469 1F3FF 200D 2764 FE0F 200D 1F469 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, dark skin tone # E13.1 [1] (👩🏿❤️👩🏿) +1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, dark skin tone, light skin tone # E13.1 [1] (👩🏿❤️💋👨🏻) +1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, dark skin tone, medium-light skin tone #E13.1 [1] (👩🏿❤️💋👨🏼) +1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, dark skin tone, medium skin tone # E13.1 [1] (👩🏿❤️💋👨🏽) +1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, dark skin tone, medium-dark skin tone #E13.1 [1] (👩🏿❤️💋👨🏾) +1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, dark skin tone # E13.1 [1] (👩🏿❤️💋👨🏿) +1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, dark skin tone, light skin tone # E13.1 [1] (👩🏿❤️💋👩🏻) +1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, dark skin tone, medium-light skin tone #E13.1[1] (👩🏿❤️💋👩🏼) +1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, dark skin tone, medium skin tone # E13.1 [1] (👩🏿❤️💋👩🏽) +1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, dark skin tone, medium-dark skin tone #E13.1[1] (👩🏿❤️💋👩🏾) +1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, dark skin tone # E13.1 [1] (👩🏿❤️💋👩🏿) +1F469 1F3FF 200D 1F91D 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: dark skin tone, light skin tone # E12.0 [1] (👩🏿🤝👨🏻) +1F469 1F3FF 200D 1F91D 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: dark skin tone, medium-light skin tone #E12.0[1] (👩🏿🤝👨🏼) +1F469 1F3FF 200D 1F91D 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: dark skin tone, medium skin tone # E12.0 [1] (👩🏿🤝👨🏽) +1F469 1F3FF 200D 1F91D 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: dark skin tone, medium-dark skin tone #E12.0[1] (👩🏿🤝👨🏾) +1F469 1F3FF 200D 1F91D 200D 1F469 1F3FB ; RGI_Emoji_ZWJ_Sequence ; women holding hands: dark skin tone, light skin tone # E12.0 [1] (👩🏿🤝👩🏻) +1F469 1F3FF 200D 1F91D 200D 1F469 1F3FC ; RGI_Emoji_ZWJ_Sequence ; women holding hands: dark skin tone, medium-light skin tone # E12.0 [1] (👩🏿🤝👩🏼) +1F469 1F3FF 200D 1F91D 200D 1F469 1F3FD ; RGI_Emoji_ZWJ_Sequence ; women holding hands: dark skin tone, medium skin tone # E12.0 [1] (👩🏿🤝👩🏽) +1F469 1F3FF 200D 1F91D 200D 1F469 1F3FE ; RGI_Emoji_ZWJ_Sequence ; women holding hands: dark skin tone, medium-dark skin tone # E12.0 [1] (👩🏿🤝👩🏾) +1F9D1 200D 1F91D 200D 1F9D1 ; RGI_Emoji_ZWJ_Sequence ; people holding hands # E12.0 [1] (🧑🤝🧑) +1F9D1 200D 1F9D1 200D 1F9D2 ; RGI_Emoji_ZWJ_Sequence ; family: adult, adult, child # E15.1 [1] (🧑🧑🧒) +1F9D1 200D 1F9D1 200D 1F9D2 200D 1F9D2 ; RGI_Emoji_ZWJ_Sequence ; family: adult, adult, child, child # E15.1 [1] (🧑🧑🧒🧒) +1F9D1 200D 1F9D2 ; RGI_Emoji_ZWJ_Sequence ; family: adult, child # E15.1 [1] (🧑🧒) +1F9D1 200D 1F9D2 200D 1F9D2 ; RGI_Emoji_ZWJ_Sequence ; family: adult, child, child # E15.1 [1] (🧑🧒🧒) +1F9D1 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: person, person, light skin tone, medium-light skin tone #E13.1[1] (🧑🏻❤️💋🧑🏼) +1F9D1 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: person, person, light skin tone, medium skin tone #E13.1 [1] (🧑🏻❤️💋🧑🏽) +1F9D1 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: person, person, light skin tone, medium-dark skin tone #E13.1[1] (🧑🏻❤️💋🧑🏾) +1F9D1 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: person, person, light skin tone, dark skin tone # E13.1 [1] (🧑🏻❤️💋🧑🏿) +1F9D1 1F3FB 200D 2764 FE0F 200D 1F9D1 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, light skin tone, medium-light skin tone #E13.1[1] (🧑🏻❤️🧑🏼) +1F9D1 1F3FB 200D 2764 FE0F 200D 1F9D1 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, light skin tone, medium skin tone #E13.1[1] (🧑🏻❤️🧑🏽) +1F9D1 1F3FB 200D 2764 FE0F 200D 1F9D1 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, light skin tone, medium-dark skin tone #E13.1[1] (🧑🏻❤️🧑🏾) +1F9D1 1F3FB 200D 2764 FE0F 200D 1F9D1 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, light skin tone, dark skin tone #E13.1[1] (🧑🏻❤️🧑🏿) +1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FB ; RGI_Emoji_ZWJ_Sequence ; people holding hands: light skin tone # E12.0 [1] (🧑🏻🤝🧑🏻) +1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FC ; RGI_Emoji_ZWJ_Sequence ; people holding hands: light skin tone, medium-light skin tone # E12.1 [1] (🧑🏻🤝🧑🏼) +1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FD ; RGI_Emoji_ZWJ_Sequence ; people holding hands: light skin tone, medium skin tone # E12.1 [1] (🧑🏻🤝🧑🏽) +1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FE ; RGI_Emoji_ZWJ_Sequence ; people holding hands: light skin tone, medium-dark skin tone # E12.1 [1] (🧑🏻🤝🧑🏾) +1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FF ; RGI_Emoji_ZWJ_Sequence ; people holding hands: light skin tone, dark skin tone # E12.1 [1] (🧑🏻🤝🧑🏿) +1F9D1 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: person, person, medium-light skin tone, light skin tone #E13.1[1] (🧑🏼❤️💋🧑🏻) +1F9D1 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: person, person, medium-light skin tone, medium skin tone #E13.1[1] (🧑🏼❤️💋🧑🏽) +1F9D1 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: person, person, medium-light skin tone, medium-dark skin tone #E13.1[1] (🧑🏼❤️💋🧑🏾) +1F9D1 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: person, person, medium-light skin tone, dark skin tone #E13.1[1] (🧑🏼❤️💋🧑🏿) +1F9D1 1F3FC 200D 2764 FE0F 200D 1F9D1 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, medium-light skin tone, light skin tone #E13.1[1] (🧑🏼❤️🧑🏻) +1F9D1 1F3FC 200D 2764 FE0F 200D 1F9D1 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, medium-light skin tone, medium skin tone #E13.1[1] (🧑🏼❤️🧑🏽) +1F9D1 1F3FC 200D 2764 FE0F 200D 1F9D1 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, medium-light skin tone, medium-dark skin tone #E13.1[1] (🧑🏼❤️🧑🏾) +1F9D1 1F3FC 200D 2764 FE0F 200D 1F9D1 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, medium-light skin tone, dark skin tone #E13.1[1] (🧑🏼❤️🧑🏿) +1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FB ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium-light skin tone, light skin tone # E12.0 [1] (🧑🏼🤝🧑🏻) +1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FC ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium-light skin tone # E12.0 [1] (🧑🏼🤝🧑🏼) +1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FD ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium-light skin tone, medium skin tone # E12.1 [1] (🧑🏼🤝🧑🏽) +1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FE ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium-light skin tone, medium-dark skin tone #E12.1[1] (🧑🏼🤝🧑🏾) +1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FF ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium-light skin tone, dark skin tone # E12.1 [1] (🧑🏼🤝🧑🏿) +1F9D1 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: person, person, medium skin tone, light skin tone #E13.1 [1] (🧑🏽❤️💋🧑🏻) +1F9D1 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: person, person, medium skin tone, medium-light skin tone #E13.1[1] (🧑🏽❤️💋🧑🏼) +1F9D1 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: person, person, medium skin tone, medium-dark skin tone #E13.1[1] (🧑🏽❤️💋🧑🏾) +1F9D1 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: person, person, medium skin tone, dark skin tone # E13.1 [1] (🧑🏽❤️💋🧑🏿) +1F9D1 1F3FD 200D 2764 FE0F 200D 1F9D1 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, medium skin tone, light skin tone #E13.1[1] (🧑🏽❤️🧑🏻) +1F9D1 1F3FD 200D 2764 FE0F 200D 1F9D1 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, medium skin tone, medium-light skin tone #E13.1[1] (🧑🏽❤️🧑🏼) +1F9D1 1F3FD 200D 2764 FE0F 200D 1F9D1 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, medium skin tone, medium-dark skin tone #E13.1[1] (🧑🏽❤️🧑🏾) +1F9D1 1F3FD 200D 2764 FE0F 200D 1F9D1 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, medium skin tone, dark skin tone #E13.1[1] (🧑🏽❤️🧑🏿) +1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FB ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium skin tone, light skin tone # E12.0 [1] (🧑🏽🤝🧑🏻) +1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FC ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium skin tone, medium-light skin tone # E12.0 [1] (🧑🏽🤝🧑🏼) +1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FD ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium skin tone # E12.0 [1] (🧑🏽🤝🧑🏽) +1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FE ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium skin tone, medium-dark skin tone # E12.1 [1] (🧑🏽🤝🧑🏾) +1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FF ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium skin tone, dark skin tone # E12.1 [1] (🧑🏽🤝🧑🏿) +1F9D1 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: person, person, medium-dark skin tone, light skin tone #E13.1[1] (🧑🏾❤️💋🧑🏻) +1F9D1 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: person, person, medium-dark skin tone, medium-light skin tone #E13.1[1] (🧑🏾❤️💋🧑🏼) +1F9D1 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: person, person, medium-dark skin tone, medium skin tone #E13.1[1] (🧑🏾❤️💋🧑🏽) +1F9D1 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: person, person, medium-dark skin tone, dark skin tone #E13.1[1] (🧑🏾❤️💋🧑🏿) +1F9D1 1F3FE 200D 2764 FE0F 200D 1F9D1 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, medium-dark skin tone, light skin tone #E13.1[1] (🧑🏾❤️🧑🏻) +1F9D1 1F3FE 200D 2764 FE0F 200D 1F9D1 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, medium-dark skin tone, medium-light skin tone #E13.1[1] (🧑🏾❤️🧑🏼) +1F9D1 1F3FE 200D 2764 FE0F 200D 1F9D1 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, medium-dark skin tone, medium skin tone #E13.1[1] (🧑🏾❤️🧑🏽) +1F9D1 1F3FE 200D 2764 FE0F 200D 1F9D1 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, medium-dark skin tone, dark skin tone #E13.1[1] (🧑🏾❤️🧑🏿) +1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FB ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium-dark skin tone, light skin tone # E12.0 [1] (🧑🏾🤝🧑🏻) +1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FC ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium-dark skin tone, medium-light skin tone #E12.0[1] (🧑🏾🤝🧑🏼) +1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FD ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium-dark skin tone, medium skin tone # E12.0 [1] (🧑🏾🤝🧑🏽) +1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FE ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium-dark skin tone # E12.0 [1] (🧑🏾🤝🧑🏾) +1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FF ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium-dark skin tone, dark skin tone # E12.1 [1] (🧑🏾🤝🧑🏿) +1F9D1 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: person, person, dark skin tone, light skin tone # E13.1 [1] (🧑🏿❤️💋🧑🏻) +1F9D1 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: person, person, dark skin tone, medium-light skin tone #E13.1[1] (🧑🏿❤️💋🧑🏼) +1F9D1 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: person, person, dark skin tone, medium skin tone # E13.1 [1] (🧑🏿❤️💋🧑🏽) +1F9D1 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: person, person, dark skin tone, medium-dark skin tone #E13.1[1] (🧑🏿❤️💋🧑🏾) +1F9D1 1F3FF 200D 2764 FE0F 200D 1F9D1 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, dark skin tone, light skin tone #E13.1[1] (🧑🏿❤️🧑🏻) +1F9D1 1F3FF 200D 2764 FE0F 200D 1F9D1 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, dark skin tone, medium-light skin tone #E13.1[1] (🧑🏿❤️🧑🏼) +1F9D1 1F3FF 200D 2764 FE0F 200D 1F9D1 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, dark skin tone, medium skin tone #E13.1[1] (🧑🏿❤️🧑🏽) +1F9D1 1F3FF 200D 2764 FE0F 200D 1F9D1 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, dark skin tone, medium-dark skin tone #E13.1[1] (🧑🏿❤️🧑🏾) +1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FB ; RGI_Emoji_ZWJ_Sequence ; people holding hands: dark skin tone, light skin tone # E12.0 [1] (🧑🏿🤝🧑🏻) +1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FC ; RGI_Emoji_ZWJ_Sequence ; people holding hands: dark skin tone, medium-light skin tone # E12.0 [1] (🧑🏿🤝🧑🏼) +1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FD ; RGI_Emoji_ZWJ_Sequence ; people holding hands: dark skin tone, medium skin tone # E12.0 [1] (🧑🏿🤝🧑🏽) +1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FE ; RGI_Emoji_ZWJ_Sequence ; people holding hands: dark skin tone, medium-dark skin tone # E12.0 [1] (🧑🏿🤝🧑🏾) +1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FF ; RGI_Emoji_ZWJ_Sequence ; people holding hands: dark skin tone # E12.0 [1] (🧑🏿🤝🧑🏿) +1FAF1 1F3FB 200D 1FAF2 1F3FC ; RGI_Emoji_ZWJ_Sequence ; handshake: light skin tone, medium-light skin tone # E14.0 [1] (🫱🏻🫲🏼) +1FAF1 1F3FB 200D 1FAF2 1F3FD ; RGI_Emoji_ZWJ_Sequence ; handshake: light skin tone, medium skin tone # E14.0 [1] (🫱🏻🫲🏽) +1FAF1 1F3FB 200D 1FAF2 1F3FE ; RGI_Emoji_ZWJ_Sequence ; handshake: light skin tone, medium-dark skin tone # E14.0 [1] (🫱🏻🫲🏾) +1FAF1 1F3FB 200D 1FAF2 1F3FF ; RGI_Emoji_ZWJ_Sequence ; handshake: light skin tone, dark skin tone # E14.0 [1] (🫱🏻🫲🏿) +1FAF1 1F3FC 200D 1FAF2 1F3FB ; RGI_Emoji_ZWJ_Sequence ; handshake: medium-light skin tone, light skin tone # E14.0 [1] (🫱🏼🫲🏻) +1FAF1 1F3FC 200D 1FAF2 1F3FD ; RGI_Emoji_ZWJ_Sequence ; handshake: medium-light skin tone, medium skin tone # E14.0 [1] (🫱🏼🫲🏽) +1FAF1 1F3FC 200D 1FAF2 1F3FE ; RGI_Emoji_ZWJ_Sequence ; handshake: medium-light skin tone, medium-dark skin tone # E14.0 [1] (🫱🏼🫲🏾) +1FAF1 1F3FC 200D 1FAF2 1F3FF ; RGI_Emoji_ZWJ_Sequence ; handshake: medium-light skin tone, dark skin tone # E14.0 [1] (🫱🏼🫲🏿) +1FAF1 1F3FD 200D 1FAF2 1F3FB ; RGI_Emoji_ZWJ_Sequence ; handshake: medium skin tone, light skin tone # E14.0 [1] (🫱🏽🫲🏻) +1FAF1 1F3FD 200D 1FAF2 1F3FC ; RGI_Emoji_ZWJ_Sequence ; handshake: medium skin tone, medium-light skin tone # E14.0 [1] (🫱🏽🫲🏼) +1FAF1 1F3FD 200D 1FAF2 1F3FE ; RGI_Emoji_ZWJ_Sequence ; handshake: medium skin tone, medium-dark skin tone # E14.0 [1] (🫱🏽🫲🏾) +1FAF1 1F3FD 200D 1FAF2 1F3FF ; RGI_Emoji_ZWJ_Sequence ; handshake: medium skin tone, dark skin tone # E14.0 [1] (🫱🏽🫲🏿) +1FAF1 1F3FE 200D 1FAF2 1F3FB ; RGI_Emoji_ZWJ_Sequence ; handshake: medium-dark skin tone, light skin tone # E14.0 [1] (🫱🏾🫲🏻) +1FAF1 1F3FE 200D 1FAF2 1F3FC ; RGI_Emoji_ZWJ_Sequence ; handshake: medium-dark skin tone, medium-light skin tone # E14.0 [1] (🫱🏾🫲🏼) +1FAF1 1F3FE 200D 1FAF2 1F3FD ; RGI_Emoji_ZWJ_Sequence ; handshake: medium-dark skin tone, medium skin tone # E14.0 [1] (🫱🏾🫲🏽) +1FAF1 1F3FE 200D 1FAF2 1F3FF ; RGI_Emoji_ZWJ_Sequence ; handshake: medium-dark skin tone, dark skin tone # E14.0 [1] (🫱🏾🫲🏿) +1FAF1 1F3FF 200D 1FAF2 1F3FB ; RGI_Emoji_ZWJ_Sequence ; handshake: dark skin tone, light skin tone # E14.0 [1] (🫱🏿🫲🏻) +1FAF1 1F3FF 200D 1FAF2 1F3FC ; RGI_Emoji_ZWJ_Sequence ; handshake: dark skin tone, medium-light skin tone # E14.0 [1] (🫱🏿🫲🏼) +1FAF1 1F3FF 200D 1FAF2 1F3FD ; RGI_Emoji_ZWJ_Sequence ; handshake: dark skin tone, medium skin tone # E14.0 [1] (🫱🏿🫲🏽) +1FAF1 1F3FF 200D 1FAF2 1F3FE ; RGI_Emoji_ZWJ_Sequence ; handshake: dark skin tone, medium-dark skin tone # E14.0 [1] (🫱🏿🫲🏾) + +# Total elements: 331 + +# ================================================ + +# RGI_Emoji_ZWJ_Sequence: Role + +1F3C3 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person running facing right # E15.1 [1] (🏃➡️) +1F3C3 1F3FB 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person running facing right: light skin tone # E15.1 [1] (🏃🏻➡️) +1F3C3 1F3FC 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person running facing right: medium-light skin tone # E15.1 [1] (🏃🏼➡️) +1F3C3 1F3FD 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person running facing right: medium skin tone # E15.1 [1] (🏃🏽➡️) +1F3C3 1F3FE 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person running facing right: medium-dark skin tone # E15.1 [1] (🏃🏾➡️) +1F3C3 1F3FF 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person running facing right: dark skin tone # E15.1 [1] (🏃🏿➡️) +1F468 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; man health worker # E4.0 [1] (👨⚕️) +1F468 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; man judge # E4.0 [1] (👨⚖️) +1F468 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; man pilot # E4.0 [1] (👨✈️) +1F468 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; man farmer # E4.0 [1] (👨🌾) +1F468 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; man cook # E4.0 [1] (👨🍳) +1F468 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; man feeding baby # E13.0 [1] (👨🍼) +1F468 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; man student # E4.0 [1] (👨🎓) +1F468 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; man singer # E4.0 [1] (👨🎤) +1F468 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; man artist # E4.0 [1] (👨🎨) +1F468 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; man teacher # E4.0 [1] (👨🏫) +1F468 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; man factory worker # E4.0 [1] (👨🏭) +1F468 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; man technologist # E4.0 [1] (👨💻) +1F468 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; man office worker # E4.0 [1] (👨💼) +1F468 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; man mechanic # E4.0 [1] (👨🔧) +1F468 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; man scientist # E4.0 [1] (👨🔬) +1F468 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; man astronaut # E4.0 [1] (👨🚀) +1F468 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; man firefighter # E4.0 [1] (👨🚒) +1F468 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; man with white cane # E12.0 [1] (👨🦯) +1F468 200D 1F9AF 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man with white cane facing right # E15.1 [1] (👨🦯➡️) +1F468 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; man in motorized wheelchair # E12.0 [1] (👨🦼) +1F468 200D 1F9BC 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in motorized wheelchair facing right # E15.1 [1] (👨🦼➡️) +1F468 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; man in manual wheelchair # E12.0 [1] (👨🦽) +1F468 200D 1F9BD 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in manual wheelchair facing right # E15.1 [1] (👨🦽➡️) +1F468 1F3FB 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; man health worker: light skin tone # E4.0 [1] (👨🏻⚕️) +1F468 1F3FB 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; man judge: light skin tone # E4.0 [1] (👨🏻⚖️) +1F468 1F3FB 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; man pilot: light skin tone # E4.0 [1] (👨🏻✈️) +1F468 1F3FB 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; man farmer: light skin tone # E4.0 [1] (👨🏻🌾) +1F468 1F3FB 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; man cook: light skin tone # E4.0 [1] (👨🏻🍳) +1F468 1F3FB 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; man feeding baby: light skin tone # E13.0 [1] (👨🏻🍼) +1F468 1F3FB 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; man student: light skin tone # E4.0 [1] (👨🏻🎓) +1F468 1F3FB 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; man singer: light skin tone # E4.0 [1] (👨🏻🎤) +1F468 1F3FB 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; man artist: light skin tone # E4.0 [1] (👨🏻🎨) +1F468 1F3FB 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; man teacher: light skin tone # E4.0 [1] (👨🏻🏫) +1F468 1F3FB 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; man factory worker: light skin tone # E4.0 [1] (👨🏻🏭) +1F468 1F3FB 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; man technologist: light skin tone # E4.0 [1] (👨🏻💻) +1F468 1F3FB 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; man office worker: light skin tone # E4.0 [1] (👨🏻💼) +1F468 1F3FB 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; man mechanic: light skin tone # E4.0 [1] (👨🏻🔧) +1F468 1F3FB 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; man scientist: light skin tone # E4.0 [1] (👨🏻🔬) +1F468 1F3FB 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; man astronaut: light skin tone # E4.0 [1] (👨🏻🚀) +1F468 1F3FB 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; man firefighter: light skin tone # E4.0 [1] (👨🏻🚒) +1F468 1F3FB 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; man with white cane: light skin tone # E12.0 [1] (👨🏻🦯) +1F468 1F3FB 200D 1F9AF 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man with white cane facing right: light skin tone # E15.1 [1] (👨🏻🦯➡️) +1F468 1F3FB 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; man in motorized wheelchair: light skin tone # E12.0 [1] (👨🏻🦼) +1F468 1F3FB 200D 1F9BC 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in motorized wheelchair facing right: light skin tone # E15.1 [1] (👨🏻🦼➡️) +1F468 1F3FB 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; man in manual wheelchair: light skin tone # E12.0 [1] (👨🏻🦽) +1F468 1F3FB 200D 1F9BD 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in manual wheelchair facing right: light skin tone # E15.1 [1] (👨🏻🦽➡️) +1F468 1F3FC 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; man health worker: medium-light skin tone # E4.0 [1] (👨🏼⚕️) +1F468 1F3FC 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; man judge: medium-light skin tone # E4.0 [1] (👨🏼⚖️) +1F468 1F3FC 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; man pilot: medium-light skin tone # E4.0 [1] (👨🏼✈️) +1F468 1F3FC 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; man farmer: medium-light skin tone # E4.0 [1] (👨🏼🌾) +1F468 1F3FC 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; man cook: medium-light skin tone # E4.0 [1] (👨🏼🍳) +1F468 1F3FC 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; man feeding baby: medium-light skin tone # E13.0 [1] (👨🏼🍼) +1F468 1F3FC 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; man student: medium-light skin tone # E4.0 [1] (👨🏼🎓) +1F468 1F3FC 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; man singer: medium-light skin tone # E4.0 [1] (👨🏼🎤) +1F468 1F3FC 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; man artist: medium-light skin tone # E4.0 [1] (👨🏼🎨) +1F468 1F3FC 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; man teacher: medium-light skin tone # E4.0 [1] (👨🏼🏫) +1F468 1F3FC 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; man factory worker: medium-light skin tone # E4.0 [1] (👨🏼🏭) +1F468 1F3FC 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; man technologist: medium-light skin tone # E4.0 [1] (👨🏼💻) +1F468 1F3FC 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; man office worker: medium-light skin tone # E4.0 [1] (👨🏼💼) +1F468 1F3FC 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; man mechanic: medium-light skin tone # E4.0 [1] (👨🏼🔧) +1F468 1F3FC 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; man scientist: medium-light skin tone # E4.0 [1] (👨🏼🔬) +1F468 1F3FC 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; man astronaut: medium-light skin tone # E4.0 [1] (👨🏼🚀) +1F468 1F3FC 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; man firefighter: medium-light skin tone # E4.0 [1] (👨🏼🚒) +1F468 1F3FC 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; man with white cane: medium-light skin tone # E12.0 [1] (👨🏼🦯) +1F468 1F3FC 200D 1F9AF 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man with white cane facing right: medium-light skin tone # E15.1 [1] (👨🏼🦯➡️) +1F468 1F3FC 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; man in motorized wheelchair: medium-light skin tone # E12.0 [1] (👨🏼🦼) +1F468 1F3FC 200D 1F9BC 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in motorized wheelchair facing right: medium-light skin tone #E15.1 [1] (👨🏼🦼➡️) +1F468 1F3FC 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; man in manual wheelchair: medium-light skin tone # E12.0 [1] (👨🏼🦽) +1F468 1F3FC 200D 1F9BD 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in manual wheelchair facing right: medium-light skin tone # E15.1 [1] (👨🏼🦽➡️) +1F468 1F3FD 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; man health worker: medium skin tone # E4.0 [1] (👨🏽⚕️) +1F468 1F3FD 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; man judge: medium skin tone # E4.0 [1] (👨🏽⚖️) +1F468 1F3FD 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; man pilot: medium skin tone # E4.0 [1] (👨🏽✈️) +1F468 1F3FD 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; man farmer: medium skin tone # E4.0 [1] (👨🏽🌾) +1F468 1F3FD 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; man cook: medium skin tone # E4.0 [1] (👨🏽🍳) +1F468 1F3FD 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; man feeding baby: medium skin tone # E13.0 [1] (👨🏽🍼) +1F468 1F3FD 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; man student: medium skin tone # E4.0 [1] (👨🏽🎓) +1F468 1F3FD 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; man singer: medium skin tone # E4.0 [1] (👨🏽🎤) +1F468 1F3FD 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; man artist: medium skin tone # E4.0 [1] (👨🏽🎨) +1F468 1F3FD 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; man teacher: medium skin tone # E4.0 [1] (👨🏽🏫) +1F468 1F3FD 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; man factory worker: medium skin tone # E4.0 [1] (👨🏽🏭) +1F468 1F3FD 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; man technologist: medium skin tone # E4.0 [1] (👨🏽💻) +1F468 1F3FD 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; man office worker: medium skin tone # E4.0 [1] (👨🏽💼) +1F468 1F3FD 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; man mechanic: medium skin tone # E4.0 [1] (👨🏽🔧) +1F468 1F3FD 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; man scientist: medium skin tone # E4.0 [1] (👨🏽🔬) +1F468 1F3FD 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; man astronaut: medium skin tone # E4.0 [1] (👨🏽🚀) +1F468 1F3FD 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; man firefighter: medium skin tone # E4.0 [1] (👨🏽🚒) +1F468 1F3FD 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; man with white cane: medium skin tone # E12.0 [1] (👨🏽🦯) +1F468 1F3FD 200D 1F9AF 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man with white cane facing right: medium skin tone # E15.1 [1] (👨🏽🦯➡️) +1F468 1F3FD 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; man in motorized wheelchair: medium skin tone # E12.0 [1] (👨🏽🦼) +1F468 1F3FD 200D 1F9BC 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in motorized wheelchair facing right: medium skin tone # E15.1 [1] (👨🏽🦼➡️) +1F468 1F3FD 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; man in manual wheelchair: medium skin tone # E12.0 [1] (👨🏽🦽) +1F468 1F3FD 200D 1F9BD 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in manual wheelchair facing right: medium skin tone # E15.1 [1] (👨🏽🦽➡️) +1F468 1F3FE 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; man health worker: medium-dark skin tone # E4.0 [1] (👨🏾⚕️) +1F468 1F3FE 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; man judge: medium-dark skin tone # E4.0 [1] (👨🏾⚖️) +1F468 1F3FE 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; man pilot: medium-dark skin tone # E4.0 [1] (👨🏾✈️) +1F468 1F3FE 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; man farmer: medium-dark skin tone # E4.0 [1] (👨🏾🌾) +1F468 1F3FE 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; man cook: medium-dark skin tone # E4.0 [1] (👨🏾🍳) +1F468 1F3FE 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; man feeding baby: medium-dark skin tone # E13.0 [1] (👨🏾🍼) +1F468 1F3FE 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; man student: medium-dark skin tone # E4.0 [1] (👨🏾🎓) +1F468 1F3FE 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; man singer: medium-dark skin tone # E4.0 [1] (👨🏾🎤) +1F468 1F3FE 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; man artist: medium-dark skin tone # E4.0 [1] (👨🏾🎨) +1F468 1F3FE 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; man teacher: medium-dark skin tone # E4.0 [1] (👨🏾🏫) +1F468 1F3FE 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; man factory worker: medium-dark skin tone # E4.0 [1] (👨🏾🏭) +1F468 1F3FE 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; man technologist: medium-dark skin tone # E4.0 [1] (👨🏾💻) +1F468 1F3FE 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; man office worker: medium-dark skin tone # E4.0 [1] (👨🏾💼) +1F468 1F3FE 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; man mechanic: medium-dark skin tone # E4.0 [1] (👨🏾🔧) +1F468 1F3FE 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; man scientist: medium-dark skin tone # E4.0 [1] (👨🏾🔬) +1F468 1F3FE 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; man astronaut: medium-dark skin tone # E4.0 [1] (👨🏾🚀) +1F468 1F3FE 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; man firefighter: medium-dark skin tone # E4.0 [1] (👨🏾🚒) +1F468 1F3FE 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; man with white cane: medium-dark skin tone # E12.0 [1] (👨🏾🦯) +1F468 1F3FE 200D 1F9AF 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man with white cane facing right: medium-dark skin tone # E15.1 [1] (👨🏾🦯➡️) +1F468 1F3FE 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; man in motorized wheelchair: medium-dark skin tone # E12.0 [1] (👨🏾🦼) +1F468 1F3FE 200D 1F9BC 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in motorized wheelchair facing right: medium-dark skin tone #E15.1 [1] (👨🏾🦼➡️) +1F468 1F3FE 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; man in manual wheelchair: medium-dark skin tone # E12.0 [1] (👨🏾🦽) +1F468 1F3FE 200D 1F9BD 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in manual wheelchair facing right: medium-dark skin tone # E15.1 [1] (👨🏾🦽➡️) +1F468 1F3FF 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; man health worker: dark skin tone # E4.0 [1] (👨🏿⚕️) +1F468 1F3FF 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; man judge: dark skin tone # E4.0 [1] (👨🏿⚖️) +1F468 1F3FF 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; man pilot: dark skin tone # E4.0 [1] (👨🏿✈️) +1F468 1F3FF 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; man farmer: dark skin tone # E4.0 [1] (👨🏿🌾) +1F468 1F3FF 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; man cook: dark skin tone # E4.0 [1] (👨🏿🍳) +1F468 1F3FF 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; man feeding baby: dark skin tone # E13.0 [1] (👨🏿🍼) +1F468 1F3FF 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; man student: dark skin tone # E4.0 [1] (👨🏿🎓) +1F468 1F3FF 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; man singer: dark skin tone # E4.0 [1] (👨🏿🎤) +1F468 1F3FF 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; man artist: dark skin tone # E4.0 [1] (👨🏿🎨) +1F468 1F3FF 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; man teacher: dark skin tone # E4.0 [1] (👨🏿🏫) +1F468 1F3FF 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; man factory worker: dark skin tone # E4.0 [1] (👨🏿🏭) +1F468 1F3FF 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; man technologist: dark skin tone # E4.0 [1] (👨🏿💻) +1F468 1F3FF 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; man office worker: dark skin tone # E4.0 [1] (👨🏿💼) +1F468 1F3FF 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; man mechanic: dark skin tone # E4.0 [1] (👨🏿🔧) +1F468 1F3FF 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; man scientist: dark skin tone # E4.0 [1] (👨🏿🔬) +1F468 1F3FF 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; man astronaut: dark skin tone # E4.0 [1] (👨🏿🚀) +1F468 1F3FF 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; man firefighter: dark skin tone # E4.0 [1] (👨🏿🚒) +1F468 1F3FF 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; man with white cane: dark skin tone # E12.0 [1] (👨🏿🦯) +1F468 1F3FF 200D 1F9AF 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man with white cane facing right: dark skin tone # E15.1 [1] (👨🏿🦯➡️) +1F468 1F3FF 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; man in motorized wheelchair: dark skin tone # E12.0 [1] (👨🏿🦼) +1F468 1F3FF 200D 1F9BC 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in motorized wheelchair facing right: dark skin tone # E15.1 [1] (👨🏿🦼➡️) +1F468 1F3FF 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; man in manual wheelchair: dark skin tone # E12.0 [1] (👨🏿🦽) +1F468 1F3FF 200D 1F9BD 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in manual wheelchair facing right: dark skin tone # E15.1 [1] (👨🏿🦽➡️) +1F469 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman health worker # E4.0 [1] (👩⚕️) +1F469 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman judge # E4.0 [1] (👩⚖️) +1F469 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman pilot # E4.0 [1] (👩✈️) +1F469 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; woman farmer # E4.0 [1] (👩🌾) +1F469 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; woman cook # E4.0 [1] (👩🍳) +1F469 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; woman feeding baby # E13.0 [1] (👩🍼) +1F469 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; woman student # E4.0 [1] (👩🎓) +1F469 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; woman singer # E4.0 [1] (👩🎤) +1F469 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; woman artist # E4.0 [1] (👩🎨) +1F469 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; woman teacher # E4.0 [1] (👩🏫) +1F469 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; woman factory worker # E4.0 [1] (👩🏭) +1F469 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; woman technologist # E4.0 [1] (👩💻) +1F469 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; woman office worker # E4.0 [1] (👩💼) +1F469 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; woman mechanic # E4.0 [1] (👩🔧) +1F469 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; woman scientist # E4.0 [1] (👩🔬) +1F469 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; woman astronaut # E4.0 [1] (👩🚀) +1F469 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; woman firefighter # E4.0 [1] (👩🚒) +1F469 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; woman with white cane # E12.0 [1] (👩🦯) +1F469 200D 1F9AF 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman with white cane facing right # E15.1 [1] (👩🦯➡️) +1F469 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; woman in motorized wheelchair # E12.0 [1] (👩🦼) +1F469 200D 1F9BC 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in motorized wheelchair facing right # E15.1 [1] (👩🦼➡️) +1F469 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; woman in manual wheelchair # E12.0 [1] (👩🦽) +1F469 200D 1F9BD 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in manual wheelchair facing right # E15.1 [1] (👩🦽➡️) +1F469 1F3FB 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman health worker: light skin tone # E4.0 [1] (👩🏻⚕️) +1F469 1F3FB 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman judge: light skin tone # E4.0 [1] (👩🏻⚖️) +1F469 1F3FB 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman pilot: light skin tone # E4.0 [1] (👩🏻✈️) +1F469 1F3FB 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; woman farmer: light skin tone # E4.0 [1] (👩🏻🌾) +1F469 1F3FB 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; woman cook: light skin tone # E4.0 [1] (👩🏻🍳) +1F469 1F3FB 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; woman feeding baby: light skin tone # E13.0 [1] (👩🏻🍼) +1F469 1F3FB 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; woman student: light skin tone # E4.0 [1] (👩🏻🎓) +1F469 1F3FB 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; woman singer: light skin tone # E4.0 [1] (👩🏻🎤) +1F469 1F3FB 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; woman artist: light skin tone # E4.0 [1] (👩🏻🎨) +1F469 1F3FB 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; woman teacher: light skin tone # E4.0 [1] (👩🏻🏫) +1F469 1F3FB 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; woman factory worker: light skin tone # E4.0 [1] (👩🏻🏭) +1F469 1F3FB 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; woman technologist: light skin tone # E4.0 [1] (👩🏻💻) +1F469 1F3FB 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; woman office worker: light skin tone # E4.0 [1] (👩🏻💼) +1F469 1F3FB 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; woman mechanic: light skin tone # E4.0 [1] (👩🏻🔧) +1F469 1F3FB 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; woman scientist: light skin tone # E4.0 [1] (👩🏻🔬) +1F469 1F3FB 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; woman astronaut: light skin tone # E4.0 [1] (👩🏻🚀) +1F469 1F3FB 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; woman firefighter: light skin tone # E4.0 [1] (👩🏻🚒) +1F469 1F3FB 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; woman with white cane: light skin tone # E12.0 [1] (👩🏻🦯) +1F469 1F3FB 200D 1F9AF 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman with white cane facing right: light skin tone # E15.1 [1] (👩🏻🦯➡️) +1F469 1F3FB 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; woman in motorized wheelchair: light skin tone # E12.0 [1] (👩🏻🦼) +1F469 1F3FB 200D 1F9BC 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in motorized wheelchair facing right: light skin tone # E15.1 [1] (👩🏻🦼➡️) +1F469 1F3FB 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; woman in manual wheelchair: light skin tone # E12.0 [1] (👩🏻🦽) +1F469 1F3FB 200D 1F9BD 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in manual wheelchair facing right: light skin tone # E15.1 [1] (👩🏻🦽➡️) +1F469 1F3FC 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman health worker: medium-light skin tone # E4.0 [1] (👩🏼⚕️) +1F469 1F3FC 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman judge: medium-light skin tone # E4.0 [1] (👩🏼⚖️) +1F469 1F3FC 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman pilot: medium-light skin tone # E4.0 [1] (👩🏼✈️) +1F469 1F3FC 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; woman farmer: medium-light skin tone # E4.0 [1] (👩🏼🌾) +1F469 1F3FC 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; woman cook: medium-light skin tone # E4.0 [1] (👩🏼🍳) +1F469 1F3FC 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; woman feeding baby: medium-light skin tone # E13.0 [1] (👩🏼🍼) +1F469 1F3FC 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; woman student: medium-light skin tone # E4.0 [1] (👩🏼🎓) +1F469 1F3FC 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; woman singer: medium-light skin tone # E4.0 [1] (👩🏼🎤) +1F469 1F3FC 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; woman artist: medium-light skin tone # E4.0 [1] (👩🏼🎨) +1F469 1F3FC 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; woman teacher: medium-light skin tone # E4.0 [1] (👩🏼🏫) +1F469 1F3FC 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; woman factory worker: medium-light skin tone # E4.0 [1] (👩🏼🏭) +1F469 1F3FC 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; woman technologist: medium-light skin tone # E4.0 [1] (👩🏼💻) +1F469 1F3FC 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; woman office worker: medium-light skin tone # E4.0 [1] (👩🏼💼) +1F469 1F3FC 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; woman mechanic: medium-light skin tone # E4.0 [1] (👩🏼🔧) +1F469 1F3FC 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; woman scientist: medium-light skin tone # E4.0 [1] (👩🏼🔬) +1F469 1F3FC 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; woman astronaut: medium-light skin tone # E4.0 [1] (👩🏼🚀) +1F469 1F3FC 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; woman firefighter: medium-light skin tone # E4.0 [1] (👩🏼🚒) +1F469 1F3FC 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; woman with white cane: medium-light skin tone # E12.0 [1] (👩🏼🦯) +1F469 1F3FC 200D 1F9AF 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman with white cane facing right: medium-light skin tone # E15.1 [1] (👩🏼🦯➡️) +1F469 1F3FC 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; woman in motorized wheelchair: medium-light skin tone # E12.0 [1] (👩🏼🦼) +1F469 1F3FC 200D 1F9BC 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in motorized wheelchair facing right: medium-light skin tone #E15.1[1] (👩🏼🦼➡️) +1F469 1F3FC 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; woman in manual wheelchair: medium-light skin tone # E12.0 [1] (👩🏼🦽) +1F469 1F3FC 200D 1F9BD 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in manual wheelchair facing right: medium-light skin tone #E15.1 [1] (👩🏼🦽➡️) +1F469 1F3FD 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman health worker: medium skin tone # E4.0 [1] (👩🏽⚕️) +1F469 1F3FD 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman judge: medium skin tone # E4.0 [1] (👩🏽⚖️) +1F469 1F3FD 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman pilot: medium skin tone # E4.0 [1] (👩🏽✈️) +1F469 1F3FD 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; woman farmer: medium skin tone # E4.0 [1] (👩🏽🌾) +1F469 1F3FD 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; woman cook: medium skin tone # E4.0 [1] (👩🏽🍳) +1F469 1F3FD 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; woman feeding baby: medium skin tone # E13.0 [1] (👩🏽🍼) +1F469 1F3FD 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; woman student: medium skin tone # E4.0 [1] (👩🏽🎓) +1F469 1F3FD 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; woman singer: medium skin tone # E4.0 [1] (👩🏽🎤) +1F469 1F3FD 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; woman artist: medium skin tone # E4.0 [1] (👩🏽🎨) +1F469 1F3FD 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; woman teacher: medium skin tone # E4.0 [1] (👩🏽🏫) +1F469 1F3FD 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; woman factory worker: medium skin tone # E4.0 [1] (👩🏽🏭) +1F469 1F3FD 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; woman technologist: medium skin tone # E4.0 [1] (👩🏽💻) +1F469 1F3FD 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; woman office worker: medium skin tone # E4.0 [1] (👩🏽💼) +1F469 1F3FD 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; woman mechanic: medium skin tone # E4.0 [1] (👩🏽🔧) +1F469 1F3FD 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; woman scientist: medium skin tone # E4.0 [1] (👩🏽🔬) +1F469 1F3FD 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; woman astronaut: medium skin tone # E4.0 [1] (👩🏽🚀) +1F469 1F3FD 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; woman firefighter: medium skin tone # E4.0 [1] (👩🏽🚒) +1F469 1F3FD 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; woman with white cane: medium skin tone # E12.0 [1] (👩🏽🦯) +1F469 1F3FD 200D 1F9AF 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman with white cane facing right: medium skin tone # E15.1 [1] (👩🏽🦯➡️) +1F469 1F3FD 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; woman in motorized wheelchair: medium skin tone # E12.0 [1] (👩🏽🦼) +1F469 1F3FD 200D 1F9BC 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in motorized wheelchair facing right: medium skin tone # E15.1 [1] (👩🏽🦼➡️) +1F469 1F3FD 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; woman in manual wheelchair: medium skin tone # E12.0 [1] (👩🏽🦽) +1F469 1F3FD 200D 1F9BD 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in manual wheelchair facing right: medium skin tone # E15.1 [1] (👩🏽🦽➡️) +1F469 1F3FE 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman health worker: medium-dark skin tone # E4.0 [1] (👩🏾⚕️) +1F469 1F3FE 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman judge: medium-dark skin tone # E4.0 [1] (👩🏾⚖️) +1F469 1F3FE 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman pilot: medium-dark skin tone # E4.0 [1] (👩🏾✈️) +1F469 1F3FE 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; woman farmer: medium-dark skin tone # E4.0 [1] (👩🏾🌾) +1F469 1F3FE 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; woman cook: medium-dark skin tone # E4.0 [1] (👩🏾🍳) +1F469 1F3FE 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; woman feeding baby: medium-dark skin tone # E13.0 [1] (👩🏾🍼) +1F469 1F3FE 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; woman student: medium-dark skin tone # E4.0 [1] (👩🏾🎓) +1F469 1F3FE 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; woman singer: medium-dark skin tone # E4.0 [1] (👩🏾🎤) +1F469 1F3FE 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; woman artist: medium-dark skin tone # E4.0 [1] (👩🏾🎨) +1F469 1F3FE 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; woman teacher: medium-dark skin tone # E4.0 [1] (👩🏾🏫) +1F469 1F3FE 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; woman factory worker: medium-dark skin tone # E4.0 [1] (👩🏾🏭) +1F469 1F3FE 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; woman technologist: medium-dark skin tone # E4.0 [1] (👩🏾💻) +1F469 1F3FE 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; woman office worker: medium-dark skin tone # E4.0 [1] (👩🏾💼) +1F469 1F3FE 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; woman mechanic: medium-dark skin tone # E4.0 [1] (👩🏾🔧) +1F469 1F3FE 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; woman scientist: medium-dark skin tone # E4.0 [1] (👩🏾🔬) +1F469 1F3FE 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; woman astronaut: medium-dark skin tone # E4.0 [1] (👩🏾🚀) +1F469 1F3FE 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; woman firefighter: medium-dark skin tone # E4.0 [1] (👩🏾🚒) +1F469 1F3FE 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; woman with white cane: medium-dark skin tone # E12.0 [1] (👩🏾🦯) +1F469 1F3FE 200D 1F9AF 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman with white cane facing right: medium-dark skin tone # E15.1 [1] (👩🏾🦯➡️) +1F469 1F3FE 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; woman in motorized wheelchair: medium-dark skin tone # E12.0 [1] (👩🏾🦼) +1F469 1F3FE 200D 1F9BC 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in motorized wheelchair facing right: medium-dark skin tone #E15.1[1] (👩🏾🦼➡️) +1F469 1F3FE 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; woman in manual wheelchair: medium-dark skin tone # E12.0 [1] (👩🏾🦽) +1F469 1F3FE 200D 1F9BD 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in manual wheelchair facing right: medium-dark skin tone # E15.1 [1] (👩🏾🦽➡️) +1F469 1F3FF 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman health worker: dark skin tone # E4.0 [1] (👩🏿⚕️) +1F469 1F3FF 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman judge: dark skin tone # E4.0 [1] (👩🏿⚖️) +1F469 1F3FF 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman pilot: dark skin tone # E4.0 [1] (👩🏿✈️) +1F469 1F3FF 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; woman farmer: dark skin tone # E4.0 [1] (👩🏿🌾) +1F469 1F3FF 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; woman cook: dark skin tone # E4.0 [1] (👩🏿🍳) +1F469 1F3FF 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; woman feeding baby: dark skin tone # E13.0 [1] (👩🏿🍼) +1F469 1F3FF 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; woman student: dark skin tone # E4.0 [1] (👩🏿🎓) +1F469 1F3FF 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; woman singer: dark skin tone # E4.0 [1] (👩🏿🎤) +1F469 1F3FF 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; woman artist: dark skin tone # E4.0 [1] (👩🏿🎨) +1F469 1F3FF 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; woman teacher: dark skin tone # E4.0 [1] (👩🏿🏫) +1F469 1F3FF 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; woman factory worker: dark skin tone # E4.0 [1] (👩🏿🏭) +1F469 1F3FF 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; woman technologist: dark skin tone # E4.0 [1] (👩🏿💻) +1F469 1F3FF 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; woman office worker: dark skin tone # E4.0 [1] (👩🏿💼) +1F469 1F3FF 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; woman mechanic: dark skin tone # E4.0 [1] (👩🏿🔧) +1F469 1F3FF 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; woman scientist: dark skin tone # E4.0 [1] (👩🏿🔬) +1F469 1F3FF 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; woman astronaut: dark skin tone # E4.0 [1] (👩🏿🚀) +1F469 1F3FF 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; woman firefighter: dark skin tone # E4.0 [1] (👩🏿🚒) +1F469 1F3FF 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; woman with white cane: dark skin tone # E12.0 [1] (👩🏿🦯) +1F469 1F3FF 200D 1F9AF 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman with white cane facing right: dark skin tone # E15.1 [1] (👩🏿🦯➡️) +1F469 1F3FF 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; woman in motorized wheelchair: dark skin tone # E12.0 [1] (👩🏿🦼) +1F469 1F3FF 200D 1F9BC 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in motorized wheelchair facing right: dark skin tone # E15.1 [1] (👩🏿🦼➡️) +1F469 1F3FF 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; woman in manual wheelchair: dark skin tone # E12.0 [1] (👩🏿🦽) +1F469 1F3FF 200D 1F9BD 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in manual wheelchair facing right: dark skin tone # E15.1 [1] (👩🏿🦽➡️) +1F6B6 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person walking facing right # E15.1 [1] (🚶➡️) +1F6B6 1F3FB 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person walking facing right: light skin tone # E15.1 [1] (🚶🏻➡️) +1F6B6 1F3FC 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person walking facing right: medium-light skin tone # E15.1 [1] (🚶🏼➡️) +1F6B6 1F3FD 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person walking facing right: medium skin tone # E15.1 [1] (🚶🏽➡️) +1F6B6 1F3FE 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person walking facing right: medium-dark skin tone # E15.1 [1] (🚶🏾➡️) +1F6B6 1F3FF 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person walking facing right: dark skin tone # E15.1 [1] (🚶🏿➡️) +1F9CE 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person kneeling facing right # E15.1 [1] (🧎➡️) +1F9CE 1F3FB 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person kneeling facing right: light skin tone # E15.1 [1] (🧎🏻➡️) +1F9CE 1F3FC 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person kneeling facing right: medium-light skin tone # E15.1 [1] (🧎🏼➡️) +1F9CE 1F3FD 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person kneeling facing right: medium skin tone # E15.1 [1] (🧎🏽➡️) +1F9CE 1F3FE 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person kneeling facing right: medium-dark skin tone # E15.1 [1] (🧎🏾➡️) +1F9CE 1F3FF 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person kneeling facing right: dark skin tone # E15.1 [1] (🧎🏿➡️) +1F9D1 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; health worker # E12.1 [1] (🧑⚕️) +1F9D1 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; judge # E12.1 [1] (🧑⚖️) +1F9D1 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; pilot # E12.1 [1] (🧑✈️) +1F9D1 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; farmer # E12.1 [1] (🧑🌾) +1F9D1 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; cook # E12.1 [1] (🧑🍳) +1F9D1 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; person feeding baby # E13.0 [1] (🧑🍼) +1F9D1 200D 1F384 ; RGI_Emoji_ZWJ_Sequence ; mx claus # E13.0 [1] (🧑🎄) +1F9D1 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; student # E12.1 [1] (🧑🎓) +1F9D1 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; singer # E12.1 [1] (🧑🎤) +1F9D1 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; artist # E12.1 [1] (🧑🎨) +1F9D1 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; teacher # E12.1 [1] (🧑🏫) +1F9D1 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; factory worker # E12.1 [1] (🧑🏭) +1F9D1 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; technologist # E12.1 [1] (🧑💻) +1F9D1 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; office worker # E12.1 [1] (🧑💼) +1F9D1 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; mechanic # E12.1 [1] (🧑🔧) +1F9D1 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; scientist # E12.1 [1] (🧑🔬) +1F9D1 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; astronaut # E12.1 [1] (🧑🚀) +1F9D1 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; firefighter # E12.1 [1] (🧑🚒) +1F9D1 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; person with white cane # E12.1 [1] (🧑🦯) +1F9D1 200D 1F9AF 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person with white cane facing right # E15.1 [1] (🧑🦯➡️) +1F9D1 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; person in motorized wheelchair # E12.1 [1] (🧑🦼) +1F9D1 200D 1F9BC 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person in motorized wheelchair facing right # E15.1 [1] (🧑🦼➡️) +1F9D1 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; person in manual wheelchair # E12.1 [1] (🧑🦽) +1F9D1 200D 1F9BD 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person in manual wheelchair facing right # E15.1 [1] (🧑🦽➡️) +1F9D1 1F3FB 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; health worker: light skin tone # E12.1 [1] (🧑🏻⚕️) +1F9D1 1F3FB 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; judge: light skin tone # E12.1 [1] (🧑🏻⚖️) +1F9D1 1F3FB 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; pilot: light skin tone # E12.1 [1] (🧑🏻✈️) +1F9D1 1F3FB 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; farmer: light skin tone # E12.1 [1] (🧑🏻🌾) +1F9D1 1F3FB 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; cook: light skin tone # E12.1 [1] (🧑🏻🍳) +1F9D1 1F3FB 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; person feeding baby: light skin tone # E13.0 [1] (🧑🏻🍼) +1F9D1 1F3FB 200D 1F384 ; RGI_Emoji_ZWJ_Sequence ; mx claus: light skin tone # E13.0 [1] (🧑🏻🎄) +1F9D1 1F3FB 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; student: light skin tone # E12.1 [1] (🧑🏻🎓) +1F9D1 1F3FB 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; singer: light skin tone # E12.1 [1] (🧑🏻🎤) +1F9D1 1F3FB 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; artist: light skin tone # E12.1 [1] (🧑🏻🎨) +1F9D1 1F3FB 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; teacher: light skin tone # E12.1 [1] (🧑🏻🏫) +1F9D1 1F3FB 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; factory worker: light skin tone # E12.1 [1] (🧑🏻🏭) +1F9D1 1F3FB 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; technologist: light skin tone # E12.1 [1] (🧑🏻💻) +1F9D1 1F3FB 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; office worker: light skin tone # E12.1 [1] (🧑🏻💼) +1F9D1 1F3FB 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; mechanic: light skin tone # E12.1 [1] (🧑🏻🔧) +1F9D1 1F3FB 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; scientist: light skin tone # E12.1 [1] (🧑🏻🔬) +1F9D1 1F3FB 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; astronaut: light skin tone # E12.1 [1] (🧑🏻🚀) +1F9D1 1F3FB 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; firefighter: light skin tone # E12.1 [1] (🧑🏻🚒) +1F9D1 1F3FB 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; person with white cane: light skin tone # E12.1 [1] (🧑🏻🦯) +1F9D1 1F3FB 200D 1F9AF 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person with white cane facing right: light skin tone # E15.1 [1] (🧑🏻🦯➡️) +1F9D1 1F3FB 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; person in motorized wheelchair: light skin tone # E12.1 [1] (🧑🏻🦼) +1F9D1 1F3FB 200D 1F9BC 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person in motorized wheelchair facing right: light skin tone # E15.1 [1] (🧑🏻🦼➡️) +1F9D1 1F3FB 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; person in manual wheelchair: light skin tone # E12.1 [1] (🧑🏻🦽) +1F9D1 1F3FB 200D 1F9BD 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person in manual wheelchair facing right: light skin tone # E15.1 [1] (🧑🏻🦽➡️) +1F9D1 1F3FC 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; health worker: medium-light skin tone # E12.1 [1] (🧑🏼⚕️) +1F9D1 1F3FC 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; judge: medium-light skin tone # E12.1 [1] (🧑🏼⚖️) +1F9D1 1F3FC 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; pilot: medium-light skin tone # E12.1 [1] (🧑🏼✈️) +1F9D1 1F3FC 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; farmer: medium-light skin tone # E12.1 [1] (🧑🏼🌾) +1F9D1 1F3FC 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; cook: medium-light skin tone # E12.1 [1] (🧑🏼🍳) +1F9D1 1F3FC 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; person feeding baby: medium-light skin tone # E13.0 [1] (🧑🏼🍼) +1F9D1 1F3FC 200D 1F384 ; RGI_Emoji_ZWJ_Sequence ; mx claus: medium-light skin tone # E13.0 [1] (🧑🏼🎄) +1F9D1 1F3FC 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; student: medium-light skin tone # E12.1 [1] (🧑🏼🎓) +1F9D1 1F3FC 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; singer: medium-light skin tone # E12.1 [1] (🧑🏼🎤) +1F9D1 1F3FC 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; artist: medium-light skin tone # E12.1 [1] (🧑🏼🎨) +1F9D1 1F3FC 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; teacher: medium-light skin tone # E12.1 [1] (🧑🏼🏫) +1F9D1 1F3FC 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; factory worker: medium-light skin tone # E12.1 [1] (🧑🏼🏭) +1F9D1 1F3FC 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; technologist: medium-light skin tone # E12.1 [1] (🧑🏼💻) +1F9D1 1F3FC 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; office worker: medium-light skin tone # E12.1 [1] (🧑🏼💼) +1F9D1 1F3FC 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; mechanic: medium-light skin tone # E12.1 [1] (🧑🏼🔧) +1F9D1 1F3FC 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; scientist: medium-light skin tone # E12.1 [1] (🧑🏼🔬) +1F9D1 1F3FC 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; astronaut: medium-light skin tone # E12.1 [1] (🧑🏼🚀) +1F9D1 1F3FC 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; firefighter: medium-light skin tone # E12.1 [1] (🧑🏼🚒) +1F9D1 1F3FC 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; person with white cane: medium-light skin tone # E12.1 [1] (🧑🏼🦯) +1F9D1 1F3FC 200D 1F9AF 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person with white cane facing right: medium-light skin tone # E15.1 [1] (🧑🏼🦯➡️) +1F9D1 1F3FC 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; person in motorized wheelchair: medium-light skin tone # E12.1 [1] (🧑🏼🦼) +1F9D1 1F3FC 200D 1F9BC 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person in motorized wheelchair facing right: medium-light skin tone #E15.1[1] (🧑🏼🦼➡️) +1F9D1 1F3FC 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; person in manual wheelchair: medium-light skin tone # E12.1 [1] (🧑🏼🦽) +1F9D1 1F3FC 200D 1F9BD 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person in manual wheelchair facing right: medium-light skin tone #E15.1 [1] (🧑🏼🦽➡️) +1F9D1 1F3FD 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; health worker: medium skin tone # E12.1 [1] (🧑🏽⚕️) +1F9D1 1F3FD 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; judge: medium skin tone # E12.1 [1] (🧑🏽⚖️) +1F9D1 1F3FD 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; pilot: medium skin tone # E12.1 [1] (🧑🏽✈️) +1F9D1 1F3FD 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; farmer: medium skin tone # E12.1 [1] (🧑🏽🌾) +1F9D1 1F3FD 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; cook: medium skin tone # E12.1 [1] (🧑🏽🍳) +1F9D1 1F3FD 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; person feeding baby: medium skin tone # E13.0 [1] (🧑🏽🍼) +1F9D1 1F3FD 200D 1F384 ; RGI_Emoji_ZWJ_Sequence ; mx claus: medium skin tone # E13.0 [1] (🧑🏽🎄) +1F9D1 1F3FD 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; student: medium skin tone # E12.1 [1] (🧑🏽🎓) +1F9D1 1F3FD 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; singer: medium skin tone # E12.1 [1] (🧑🏽🎤) +1F9D1 1F3FD 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; artist: medium skin tone # E12.1 [1] (🧑🏽🎨) +1F9D1 1F3FD 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; teacher: medium skin tone # E12.1 [1] (🧑🏽🏫) +1F9D1 1F3FD 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; factory worker: medium skin tone # E12.1 [1] (🧑🏽🏭) +1F9D1 1F3FD 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; technologist: medium skin tone # E12.1 [1] (🧑🏽💻) +1F9D1 1F3FD 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; office worker: medium skin tone # E12.1 [1] (🧑🏽💼) +1F9D1 1F3FD 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; mechanic: medium skin tone # E12.1 [1] (🧑🏽🔧) +1F9D1 1F3FD 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; scientist: medium skin tone # E12.1 [1] (🧑🏽🔬) +1F9D1 1F3FD 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; astronaut: medium skin tone # E12.1 [1] (🧑🏽🚀) +1F9D1 1F3FD 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; firefighter: medium skin tone # E12.1 [1] (🧑🏽🚒) +1F9D1 1F3FD 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; person with white cane: medium skin tone # E12.1 [1] (🧑🏽🦯) +1F9D1 1F3FD 200D 1F9AF 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person with white cane facing right: medium skin tone # E15.1 [1] (🧑🏽🦯➡️) +1F9D1 1F3FD 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; person in motorized wheelchair: medium skin tone # E12.1 [1] (🧑🏽🦼) +1F9D1 1F3FD 200D 1F9BC 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person in motorized wheelchair facing right: medium skin tone # E15.1 [1] (🧑🏽🦼➡️) +1F9D1 1F3FD 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; person in manual wheelchair: medium skin tone # E12.1 [1] (🧑🏽🦽) +1F9D1 1F3FD 200D 1F9BD 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person in manual wheelchair facing right: medium skin tone # E15.1 [1] (🧑🏽🦽➡️) +1F9D1 1F3FE 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; health worker: medium-dark skin tone # E12.1 [1] (🧑🏾⚕️) +1F9D1 1F3FE 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; judge: medium-dark skin tone # E12.1 [1] (🧑🏾⚖️) +1F9D1 1F3FE 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; pilot: medium-dark skin tone # E12.1 [1] (🧑🏾✈️) +1F9D1 1F3FE 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; farmer: medium-dark skin tone # E12.1 [1] (🧑🏾🌾) +1F9D1 1F3FE 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; cook: medium-dark skin tone # E12.1 [1] (🧑🏾🍳) +1F9D1 1F3FE 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; person feeding baby: medium-dark skin tone # E13.0 [1] (🧑🏾🍼) +1F9D1 1F3FE 200D 1F384 ; RGI_Emoji_ZWJ_Sequence ; mx claus: medium-dark skin tone # E13.0 [1] (🧑🏾🎄) +1F9D1 1F3FE 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; student: medium-dark skin tone # E12.1 [1] (🧑🏾🎓) +1F9D1 1F3FE 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; singer: medium-dark skin tone # E12.1 [1] (🧑🏾🎤) +1F9D1 1F3FE 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; artist: medium-dark skin tone # E12.1 [1] (🧑🏾🎨) +1F9D1 1F3FE 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; teacher: medium-dark skin tone # E12.1 [1] (🧑🏾🏫) +1F9D1 1F3FE 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; factory worker: medium-dark skin tone # E12.1 [1] (🧑🏾🏭) +1F9D1 1F3FE 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; technologist: medium-dark skin tone # E12.1 [1] (🧑🏾💻) +1F9D1 1F3FE 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; office worker: medium-dark skin tone # E12.1 [1] (🧑🏾💼) +1F9D1 1F3FE 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; mechanic: medium-dark skin tone # E12.1 [1] (🧑🏾🔧) +1F9D1 1F3FE 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; scientist: medium-dark skin tone # E12.1 [1] (🧑🏾🔬) +1F9D1 1F3FE 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; astronaut: medium-dark skin tone # E12.1 [1] (🧑🏾🚀) +1F9D1 1F3FE 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; firefighter: medium-dark skin tone # E12.1 [1] (🧑🏾🚒) +1F9D1 1F3FE 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; person with white cane: medium-dark skin tone # E12.1 [1] (🧑🏾🦯) +1F9D1 1F3FE 200D 1F9AF 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person with white cane facing right: medium-dark skin tone # E15.1 [1] (🧑🏾🦯➡️) +1F9D1 1F3FE 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; person in motorized wheelchair: medium-dark skin tone # E12.1 [1] (🧑🏾🦼) +1F9D1 1F3FE 200D 1F9BC 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person in motorized wheelchair facing right: medium-dark skin tone #E15.1[1] (🧑🏾🦼➡️) +1F9D1 1F3FE 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; person in manual wheelchair: medium-dark skin tone # E12.1 [1] (🧑🏾🦽) +1F9D1 1F3FE 200D 1F9BD 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person in manual wheelchair facing right: medium-dark skin tone #E15.1 [1] (🧑🏾🦽➡️) +1F9D1 1F3FF 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; health worker: dark skin tone # E12.1 [1] (🧑🏿⚕️) +1F9D1 1F3FF 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; judge: dark skin tone # E12.1 [1] (🧑🏿⚖️) +1F9D1 1F3FF 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; pilot: dark skin tone # E12.1 [1] (🧑🏿✈️) +1F9D1 1F3FF 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; farmer: dark skin tone # E12.1 [1] (🧑🏿🌾) +1F9D1 1F3FF 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; cook: dark skin tone # E12.1 [1] (🧑🏿🍳) +1F9D1 1F3FF 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; person feeding baby: dark skin tone # E13.0 [1] (🧑🏿🍼) +1F9D1 1F3FF 200D 1F384 ; RGI_Emoji_ZWJ_Sequence ; mx claus: dark skin tone # E13.0 [1] (🧑🏿🎄) +1F9D1 1F3FF 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; student: dark skin tone # E12.1 [1] (🧑🏿🎓) +1F9D1 1F3FF 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; singer: dark skin tone # E12.1 [1] (🧑🏿🎤) +1F9D1 1F3FF 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; artist: dark skin tone # E12.1 [1] (🧑🏿🎨) +1F9D1 1F3FF 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; teacher: dark skin tone # E12.1 [1] (🧑🏿🏫) +1F9D1 1F3FF 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; factory worker: dark skin tone # E12.1 [1] (🧑🏿🏭) +1F9D1 1F3FF 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; technologist: dark skin tone # E12.1 [1] (🧑🏿💻) +1F9D1 1F3FF 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; office worker: dark skin tone # E12.1 [1] (🧑🏿💼) +1F9D1 1F3FF 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; mechanic: dark skin tone # E12.1 [1] (🧑🏿🔧) +1F9D1 1F3FF 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; scientist: dark skin tone # E12.1 [1] (🧑🏿🔬) +1F9D1 1F3FF 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; astronaut: dark skin tone # E12.1 [1] (🧑🏿🚀) +1F9D1 1F3FF 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; firefighter: dark skin tone # E12.1 [1] (🧑🏿🚒) +1F9D1 1F3FF 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; person with white cane: dark skin tone # E12.1 [1] (🧑🏿🦯) +1F9D1 1F3FF 200D 1F9AF 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person with white cane facing right: dark skin tone # E15.1 [1] (🧑🏿🦯➡️) +1F9D1 1F3FF 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; person in motorized wheelchair: dark skin tone # E12.1 [1] (🧑🏿🦼) +1F9D1 1F3FF 200D 1F9BC 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person in motorized wheelchair facing right: dark skin tone # E15.1 [1] (🧑🏿🦼➡️) +1F9D1 1F3FF 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; person in manual wheelchair: dark skin tone # E12.1 [1] (🧑🏿🦽) +1F9D1 1F3FF 200D 1F9BD 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; person in manual wheelchair facing right: dark skin tone # E15.1 [1] (🧑🏿🦽➡️) + +# Total elements: 438 + +# ================================================ + +# RGI_Emoji_ZWJ_Sequence: Gendered + +26F9 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman bouncing ball: light skin tone # E4.0 [1] (⛹🏻♀️) +26F9 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man bouncing ball: light skin tone # E4.0 [1] (⛹🏻♂️) +26F9 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman bouncing ball: medium-light skin tone # E4.0 [1] (⛹🏼♀️) +26F9 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man bouncing ball: medium-light skin tone # E4.0 [1] (⛹🏼♂️) +26F9 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman bouncing ball: medium skin tone # E4.0 [1] (⛹🏽♀️) +26F9 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man bouncing ball: medium skin tone # E4.0 [1] (⛹🏽♂️) +26F9 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman bouncing ball: medium-dark skin tone # E4.0 [1] (⛹🏾♀️) +26F9 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man bouncing ball: medium-dark skin tone # E4.0 [1] (⛹🏾♂️) +26F9 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman bouncing ball: dark skin tone # E4.0 [1] (⛹🏿♀️) +26F9 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man bouncing ball: dark skin tone # E4.0 [1] (⛹🏿♂️) +26F9 FE0F 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman bouncing ball # E4.0 [1] (⛹️♀️) +26F9 FE0F 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man bouncing ball # E4.0 [1] (⛹️♂️) +1F3C3 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman running # E4.0 [1] (🏃♀️) +1F3C3 200D 2640 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman running facing right # E15.1 [1] (🏃♀️➡️) +1F3C3 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man running # E4.0 [1] (🏃♂️) +1F3C3 200D 2642 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man running facing right # E15.1 [1] (🏃♂️➡️) +1F3C3 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman running: light skin tone # E4.0 [1] (🏃🏻♀️) +1F3C3 1F3FB 200D 2640 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman running facing right: light skin tone # E15.1 [1] (🏃🏻♀️➡️) +1F3C3 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man running: light skin tone # E4.0 [1] (🏃🏻♂️) +1F3C3 1F3FB 200D 2642 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man running facing right: light skin tone # E15.1 [1] (🏃🏻♂️➡️) +1F3C3 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman running: medium-light skin tone # E4.0 [1] (🏃🏼♀️) +1F3C3 1F3FC 200D 2640 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman running facing right: medium-light skin tone # E15.1 [1] (🏃🏼♀️➡️) +1F3C3 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man running: medium-light skin tone # E4.0 [1] (🏃🏼♂️) +1F3C3 1F3FC 200D 2642 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man running facing right: medium-light skin tone # E15.1 [1] (🏃🏼♂️➡️) +1F3C3 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman running: medium skin tone # E4.0 [1] (🏃🏽♀️) +1F3C3 1F3FD 200D 2640 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman running facing right: medium skin tone # E15.1 [1] (🏃🏽♀️➡️) +1F3C3 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man running: medium skin tone # E4.0 [1] (🏃🏽♂️) +1F3C3 1F3FD 200D 2642 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man running facing right: medium skin tone # E15.1 [1] (🏃🏽♂️➡️) +1F3C3 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman running: medium-dark skin tone # E4.0 [1] (🏃🏾♀️) +1F3C3 1F3FE 200D 2640 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman running facing right: medium-dark skin tone # E15.1 [1] (🏃🏾♀️➡️) +1F3C3 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man running: medium-dark skin tone # E4.0 [1] (🏃🏾♂️) +1F3C3 1F3FE 200D 2642 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man running facing right: medium-dark skin tone # E15.1 [1] (🏃🏾♂️➡️) +1F3C3 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman running: dark skin tone # E4.0 [1] (🏃🏿♀️) +1F3C3 1F3FF 200D 2640 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman running facing right: dark skin tone # E15.1 [1] (🏃🏿♀️➡️) +1F3C3 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man running: dark skin tone # E4.0 [1] (🏃🏿♂️) +1F3C3 1F3FF 200D 2642 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man running facing right: dark skin tone # E15.1 [1] (🏃🏿♂️➡️) +1F3C4 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman surfing # E4.0 [1] (🏄♀️) +1F3C4 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man surfing # E4.0 [1] (🏄♂️) +1F3C4 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman surfing: light skin tone # E4.0 [1] (🏄🏻♀️) +1F3C4 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man surfing: light skin tone # E4.0 [1] (🏄🏻♂️) +1F3C4 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman surfing: medium-light skin tone # E4.0 [1] (🏄🏼♀️) +1F3C4 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man surfing: medium-light skin tone # E4.0 [1] (🏄🏼♂️) +1F3C4 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman surfing: medium skin tone # E4.0 [1] (🏄🏽♀️) +1F3C4 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man surfing: medium skin tone # E4.0 [1] (🏄🏽♂️) +1F3C4 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman surfing: medium-dark skin tone # E4.0 [1] (🏄🏾♀️) +1F3C4 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man surfing: medium-dark skin tone # E4.0 [1] (🏄🏾♂️) +1F3C4 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman surfing: dark skin tone # E4.0 [1] (🏄🏿♀️) +1F3C4 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man surfing: dark skin tone # E4.0 [1] (🏄🏿♂️) +1F3CA 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman swimming # E4.0 [1] (🏊♀️) +1F3CA 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man swimming # E4.0 [1] (🏊♂️) +1F3CA 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman swimming: light skin tone # E4.0 [1] (🏊🏻♀️) +1F3CA 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man swimming: light skin tone # E4.0 [1] (🏊🏻♂️) +1F3CA 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman swimming: medium-light skin tone # E4.0 [1] (🏊🏼♀️) +1F3CA 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man swimming: medium-light skin tone # E4.0 [1] (🏊🏼♂️) +1F3CA 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman swimming: medium skin tone # E4.0 [1] (🏊🏽♀️) +1F3CA 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man swimming: medium skin tone # E4.0 [1] (🏊🏽♂️) +1F3CA 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman swimming: medium-dark skin tone # E4.0 [1] (🏊🏾♀️) +1F3CA 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man swimming: medium-dark skin tone # E4.0 [1] (🏊🏾♂️) +1F3CA 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman swimming: dark skin tone # E4.0 [1] (🏊🏿♀️) +1F3CA 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man swimming: dark skin tone # E4.0 [1] (🏊🏿♂️) +1F3CB 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman lifting weights: light skin tone # E4.0 [1] (🏋🏻♀️) +1F3CB 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man lifting weights: light skin tone # E4.0 [1] (🏋🏻♂️) +1F3CB 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman lifting weights: medium-light skin tone # E4.0 [1] (🏋🏼♀️) +1F3CB 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man lifting weights: medium-light skin tone # E4.0 [1] (🏋🏼♂️) +1F3CB 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman lifting weights: medium skin tone # E4.0 [1] (🏋🏽♀️) +1F3CB 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man lifting weights: medium skin tone # E4.0 [1] (🏋🏽♂️) +1F3CB 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman lifting weights: medium-dark skin tone # E4.0 [1] (🏋🏾♀️) +1F3CB 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man lifting weights: medium-dark skin tone # E4.0 [1] (🏋🏾♂️) +1F3CB 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman lifting weights: dark skin tone # E4.0 [1] (🏋🏿♀️) +1F3CB 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man lifting weights: dark skin tone # E4.0 [1] (🏋🏿♂️) +1F3CB FE0F 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman lifting weights # E4.0 [1] (🏋️♀️) +1F3CB FE0F 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man lifting weights # E4.0 [1] (🏋️♂️) +1F3CC 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman golfing: light skin tone # E4.0 [1] (🏌🏻♀️) +1F3CC 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man golfing: light skin tone # E4.0 [1] (🏌🏻♂️) +1F3CC 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman golfing: medium-light skin tone # E4.0 [1] (🏌🏼♀️) +1F3CC 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man golfing: medium-light skin tone # E4.0 [1] (🏌🏼♂️) +1F3CC 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman golfing: medium skin tone # E4.0 [1] (🏌🏽♀️) +1F3CC 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man golfing: medium skin tone # E4.0 [1] (🏌🏽♂️) +1F3CC 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman golfing: medium-dark skin tone # E4.0 [1] (🏌🏾♀️) +1F3CC 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man golfing: medium-dark skin tone # E4.0 [1] (🏌🏾♂️) +1F3CC 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman golfing: dark skin tone # E4.0 [1] (🏌🏿♀️) +1F3CC 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man golfing: dark skin tone # E4.0 [1] (🏌🏿♂️) +1F3CC FE0F 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman golfing # E4.0 [1] (🏌️♀️) +1F3CC FE0F 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man golfing # E4.0 [1] (🏌️♂️) +1F46E 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman police officer # E4.0 [1] (👮♀️) +1F46E 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man police officer # E4.0 [1] (👮♂️) +1F46E 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman police officer: light skin tone # E4.0 [1] (👮🏻♀️) +1F46E 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man police officer: light skin tone # E4.0 [1] (👮🏻♂️) +1F46E 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman police officer: medium-light skin tone # E4.0 [1] (👮🏼♀️) +1F46E 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man police officer: medium-light skin tone # E4.0 [1] (👮🏼♂️) +1F46E 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman police officer: medium skin tone # E4.0 [1] (👮🏽♀️) +1F46E 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man police officer: medium skin tone # E4.0 [1] (👮🏽♂️) +1F46E 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman police officer: medium-dark skin tone # E4.0 [1] (👮🏾♀️) +1F46E 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man police officer: medium-dark skin tone # E4.0 [1] (👮🏾♂️) +1F46E 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman police officer: dark skin tone # E4.0 [1] (👮🏿♀️) +1F46E 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man police officer: dark skin tone # E4.0 [1] (👮🏿♂️) +1F46F 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; women with bunny ears # E4.0 [1] (👯♀️) +1F46F 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; men with bunny ears # E4.0 [1] (👯♂️) +1F470 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman with veil # E13.0 [1] (👰♀️) +1F470 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man with veil # E13.0 [1] (👰♂️) +1F470 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman with veil: light skin tone # E13.0 [1] (👰🏻♀️) +1F470 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man with veil: light skin tone # E13.0 [1] (👰🏻♂️) +1F470 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman with veil: medium-light skin tone # E13.0 [1] (👰🏼♀️) +1F470 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man with veil: medium-light skin tone # E13.0 [1] (👰🏼♂️) +1F470 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman with veil: medium skin tone # E13.0 [1] (👰🏽♀️) +1F470 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man with veil: medium skin tone # E13.0 [1] (👰🏽♂️) +1F470 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman with veil: medium-dark skin tone # E13.0 [1] (👰🏾♀️) +1F470 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man with veil: medium-dark skin tone # E13.0 [1] (👰🏾♂️) +1F470 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman with veil: dark skin tone # E13.0 [1] (👰🏿♀️) +1F470 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man with veil: dark skin tone # E13.0 [1] (👰🏿♂️) +1F471 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman: blond hair # E4.0 [1] (👱♀️) +1F471 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man: blond hair # E4.0 [1] (👱♂️) +1F471 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman: light skin tone, blond hair # E4.0 [1] (👱🏻♀️) +1F471 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man: light skin tone, blond hair # E4.0 [1] (👱🏻♂️) +1F471 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman: medium-light skin tone, blond hair # E4.0 [1] (👱🏼♀️) +1F471 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man: medium-light skin tone, blond hair # E4.0 [1] (👱🏼♂️) +1F471 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman: medium skin tone, blond hair # E4.0 [1] (👱🏽♀️) +1F471 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man: medium skin tone, blond hair # E4.0 [1] (👱🏽♂️) +1F471 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman: medium-dark skin tone, blond hair # E4.0 [1] (👱🏾♀️) +1F471 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man: medium-dark skin tone, blond hair # E4.0 [1] (👱🏾♂️) +1F471 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman: dark skin tone, blond hair # E4.0 [1] (👱🏿♀️) +1F471 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man: dark skin tone, blond hair # E4.0 [1] (👱🏿♂️) +1F473 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman wearing turban # E4.0 [1] (👳♀️) +1F473 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man wearing turban # E4.0 [1] (👳♂️) +1F473 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman wearing turban: light skin tone # E4.0 [1] (👳🏻♀️) +1F473 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man wearing turban: light skin tone # E4.0 [1] (👳🏻♂️) +1F473 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman wearing turban: medium-light skin tone # E4.0 [1] (👳🏼♀️) +1F473 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man wearing turban: medium-light skin tone # E4.0 [1] (👳🏼♂️) +1F473 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman wearing turban: medium skin tone # E4.0 [1] (👳🏽♀️) +1F473 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man wearing turban: medium skin tone # E4.0 [1] (👳🏽♂️) +1F473 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman wearing turban: medium-dark skin tone # E4.0 [1] (👳🏾♀️) +1F473 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man wearing turban: medium-dark skin tone # E4.0 [1] (👳🏾♂️) +1F473 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman wearing turban: dark skin tone # E4.0 [1] (👳🏿♀️) +1F473 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man wearing turban: dark skin tone # E4.0 [1] (👳🏿♂️) +1F477 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman construction worker # E4.0 [1] (👷♀️) +1F477 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man construction worker # E4.0 [1] (👷♂️) +1F477 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman construction worker: light skin tone # E4.0 [1] (👷🏻♀️) +1F477 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man construction worker: light skin tone # E4.0 [1] (👷🏻♂️) +1F477 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman construction worker: medium-light skin tone # E4.0 [1] (👷🏼♀️) +1F477 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man construction worker: medium-light skin tone # E4.0 [1] (👷🏼♂️) +1F477 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman construction worker: medium skin tone # E4.0 [1] (👷🏽♀️) +1F477 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man construction worker: medium skin tone # E4.0 [1] (👷🏽♂️) +1F477 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman construction worker: medium-dark skin tone # E4.0 [1] (👷🏾♀️) +1F477 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man construction worker: medium-dark skin tone # E4.0 [1] (👷🏾♂️) +1F477 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman construction worker: dark skin tone # E4.0 [1] (👷🏿♀️) +1F477 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man construction worker: dark skin tone # E4.0 [1] (👷🏿♂️) +1F481 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman tipping hand # E4.0 [1] (💁♀️) +1F481 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man tipping hand # E4.0 [1] (💁♂️) +1F481 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman tipping hand: light skin tone # E4.0 [1] (💁🏻♀️) +1F481 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man tipping hand: light skin tone # E4.0 [1] (💁🏻♂️) +1F481 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman tipping hand: medium-light skin tone # E4.0 [1] (💁🏼♀️) +1F481 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man tipping hand: medium-light skin tone # E4.0 [1] (💁🏼♂️) +1F481 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman tipping hand: medium skin tone # E4.0 [1] (💁🏽♀️) +1F481 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man tipping hand: medium skin tone # E4.0 [1] (💁🏽♂️) +1F481 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman tipping hand: medium-dark skin tone # E4.0 [1] (💁🏾♀️) +1F481 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man tipping hand: medium-dark skin tone # E4.0 [1] (💁🏾♂️) +1F481 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman tipping hand: dark skin tone # E4.0 [1] (💁🏿♀️) +1F481 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man tipping hand: dark skin tone # E4.0 [1] (💁🏿♂️) +1F482 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman guard # E4.0 [1] (💂♀️) +1F482 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man guard # E4.0 [1] (💂♂️) +1F482 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman guard: light skin tone # E4.0 [1] (💂🏻♀️) +1F482 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man guard: light skin tone # E4.0 [1] (💂🏻♂️) +1F482 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman guard: medium-light skin tone # E4.0 [1] (💂🏼♀️) +1F482 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man guard: medium-light skin tone # E4.0 [1] (💂🏼♂️) +1F482 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman guard: medium skin tone # E4.0 [1] (💂🏽♀️) +1F482 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man guard: medium skin tone # E4.0 [1] (💂🏽♂️) +1F482 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman guard: medium-dark skin tone # E4.0 [1] (💂🏾♀️) +1F482 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man guard: medium-dark skin tone # E4.0 [1] (💂🏾♂️) +1F482 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman guard: dark skin tone # E4.0 [1] (💂🏿♀️) +1F482 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man guard: dark skin tone # E4.0 [1] (💂🏿♂️) +1F486 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman getting massage # E4.0 [1] (💆♀️) +1F486 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man getting massage # E4.0 [1] (💆♂️) +1F486 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman getting massage: light skin tone # E4.0 [1] (💆🏻♀️) +1F486 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man getting massage: light skin tone # E4.0 [1] (💆🏻♂️) +1F486 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman getting massage: medium-light skin tone # E4.0 [1] (💆🏼♀️) +1F486 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man getting massage: medium-light skin tone # E4.0 [1] (💆🏼♂️) +1F486 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman getting massage: medium skin tone # E4.0 [1] (💆🏽♀️) +1F486 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man getting massage: medium skin tone # E4.0 [1] (💆🏽♂️) +1F486 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman getting massage: medium-dark skin tone # E4.0 [1] (💆🏾♀️) +1F486 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man getting massage: medium-dark skin tone # E4.0 [1] (💆🏾♂️) +1F486 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman getting massage: dark skin tone # E4.0 [1] (💆🏿♀️) +1F486 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man getting massage: dark skin tone # E4.0 [1] (💆🏿♂️) +1F487 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman getting haircut # E4.0 [1] (💇♀️) +1F487 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man getting haircut # E4.0 [1] (💇♂️) +1F487 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman getting haircut: light skin tone # E4.0 [1] (💇🏻♀️) +1F487 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man getting haircut: light skin tone # E4.0 [1] (💇🏻♂️) +1F487 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman getting haircut: medium-light skin tone # E4.0 [1] (💇🏼♀️) +1F487 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man getting haircut: medium-light skin tone # E4.0 [1] (💇🏼♂️) +1F487 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman getting haircut: medium skin tone # E4.0 [1] (💇🏽♀️) +1F487 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man getting haircut: medium skin tone # E4.0 [1] (💇🏽♂️) +1F487 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman getting haircut: medium-dark skin tone # E4.0 [1] (💇🏾♀️) +1F487 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man getting haircut: medium-dark skin tone # E4.0 [1] (💇🏾♂️) +1F487 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman getting haircut: dark skin tone # E4.0 [1] (💇🏿♀️) +1F487 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man getting haircut: dark skin tone # E4.0 [1] (💇🏿♂️) +1F575 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman detective: light skin tone # E4.0 [1] (🕵🏻♀️) +1F575 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man detective: light skin tone # E4.0 [1] (🕵🏻♂️) +1F575 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman detective: medium-light skin tone # E4.0 [1] (🕵🏼♀️) +1F575 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man detective: medium-light skin tone # E4.0 [1] (🕵🏼♂️) +1F575 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman detective: medium skin tone # E4.0 [1] (🕵🏽♀️) +1F575 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man detective: medium skin tone # E4.0 [1] (🕵🏽♂️) +1F575 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman detective: medium-dark skin tone # E4.0 [1] (🕵🏾♀️) +1F575 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man detective: medium-dark skin tone # E4.0 [1] (🕵🏾♂️) +1F575 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman detective: dark skin tone # E4.0 [1] (🕵🏿♀️) +1F575 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man detective: dark skin tone # E4.0 [1] (🕵🏿♂️) +1F575 FE0F 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman detective # E4.0 [1] (🕵️♀️) +1F575 FE0F 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man detective # E4.0 [1] (🕵️♂️) +1F645 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman gesturing NO # E4.0 [1] (🙅♀️) +1F645 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man gesturing NO # E4.0 [1] (🙅♂️) +1F645 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman gesturing NO: light skin tone # E4.0 [1] (🙅🏻♀️) +1F645 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man gesturing NO: light skin tone # E4.0 [1] (🙅🏻♂️) +1F645 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman gesturing NO: medium-light skin tone # E4.0 [1] (🙅🏼♀️) +1F645 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man gesturing NO: medium-light skin tone # E4.0 [1] (🙅🏼♂️) +1F645 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman gesturing NO: medium skin tone # E4.0 [1] (🙅🏽♀️) +1F645 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man gesturing NO: medium skin tone # E4.0 [1] (🙅🏽♂️) +1F645 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman gesturing NO: medium-dark skin tone # E4.0 [1] (🙅🏾♀️) +1F645 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man gesturing NO: medium-dark skin tone # E4.0 [1] (🙅🏾♂️) +1F645 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman gesturing NO: dark skin tone # E4.0 [1] (🙅🏿♀️) +1F645 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man gesturing NO: dark skin tone # E4.0 [1] (🙅🏿♂️) +1F646 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman gesturing OK # E4.0 [1] (🙆♀️) +1F646 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man gesturing OK # E4.0 [1] (🙆♂️) +1F646 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman gesturing OK: light skin tone # E4.0 [1] (🙆🏻♀️) +1F646 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man gesturing OK: light skin tone # E4.0 [1] (🙆🏻♂️) +1F646 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman gesturing OK: medium-light skin tone # E4.0 [1] (🙆🏼♀️) +1F646 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man gesturing OK: medium-light skin tone # E4.0 [1] (🙆🏼♂️) +1F646 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman gesturing OK: medium skin tone # E4.0 [1] (🙆🏽♀️) +1F646 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man gesturing OK: medium skin tone # E4.0 [1] (🙆🏽♂️) +1F646 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman gesturing OK: medium-dark skin tone # E4.0 [1] (🙆🏾♀️) +1F646 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man gesturing OK: medium-dark skin tone # E4.0 [1] (🙆🏾♂️) +1F646 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman gesturing OK: dark skin tone # E4.0 [1] (🙆🏿♀️) +1F646 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man gesturing OK: dark skin tone # E4.0 [1] (🙆🏿♂️) +1F647 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman bowing # E4.0 [1] (🙇♀️) +1F647 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man bowing # E4.0 [1] (🙇♂️) +1F647 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman bowing: light skin tone # E4.0 [1] (🙇🏻♀️) +1F647 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man bowing: light skin tone # E4.0 [1] (🙇🏻♂️) +1F647 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman bowing: medium-light skin tone # E4.0 [1] (🙇🏼♀️) +1F647 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man bowing: medium-light skin tone # E4.0 [1] (🙇🏼♂️) +1F647 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman bowing: medium skin tone # E4.0 [1] (🙇🏽♀️) +1F647 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man bowing: medium skin tone # E4.0 [1] (🙇🏽♂️) +1F647 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman bowing: medium-dark skin tone # E4.0 [1] (🙇🏾♀️) +1F647 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man bowing: medium-dark skin tone # E4.0 [1] (🙇🏾♂️) +1F647 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman bowing: dark skin tone # E4.0 [1] (🙇🏿♀️) +1F647 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man bowing: dark skin tone # E4.0 [1] (🙇🏿♂️) +1F64B 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman raising hand # E4.0 [1] (🙋♀️) +1F64B 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man raising hand # E4.0 [1] (🙋♂️) +1F64B 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman raising hand: light skin tone # E4.0 [1] (🙋🏻♀️) +1F64B 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man raising hand: light skin tone # E4.0 [1] (🙋🏻♂️) +1F64B 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman raising hand: medium-light skin tone # E4.0 [1] (🙋🏼♀️) +1F64B 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man raising hand: medium-light skin tone # E4.0 [1] (🙋🏼♂️) +1F64B 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman raising hand: medium skin tone # E4.0 [1] (🙋🏽♀️) +1F64B 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man raising hand: medium skin tone # E4.0 [1] (🙋🏽♂️) +1F64B 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman raising hand: medium-dark skin tone # E4.0 [1] (🙋🏾♀️) +1F64B 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man raising hand: medium-dark skin tone # E4.0 [1] (🙋🏾♂️) +1F64B 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman raising hand: dark skin tone # E4.0 [1] (🙋🏿♀️) +1F64B 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man raising hand: dark skin tone # E4.0 [1] (🙋🏿♂️) +1F64D 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman frowning # E4.0 [1] (🙍♀️) +1F64D 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man frowning # E4.0 [1] (🙍♂️) +1F64D 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman frowning: light skin tone # E4.0 [1] (🙍🏻♀️) +1F64D 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man frowning: light skin tone # E4.0 [1] (🙍🏻♂️) +1F64D 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman frowning: medium-light skin tone # E4.0 [1] (🙍🏼♀️) +1F64D 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man frowning: medium-light skin tone # E4.0 [1] (🙍🏼♂️) +1F64D 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman frowning: medium skin tone # E4.0 [1] (🙍🏽♀️) +1F64D 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man frowning: medium skin tone # E4.0 [1] (🙍🏽♂️) +1F64D 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman frowning: medium-dark skin tone # E4.0 [1] (🙍🏾♀️) +1F64D 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man frowning: medium-dark skin tone # E4.0 [1] (🙍🏾♂️) +1F64D 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman frowning: dark skin tone # E4.0 [1] (🙍🏿♀️) +1F64D 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man frowning: dark skin tone # E4.0 [1] (🙍🏿♂️) +1F64E 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman pouting # E4.0 [1] (🙎♀️) +1F64E 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man pouting # E4.0 [1] (🙎♂️) +1F64E 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman pouting: light skin tone # E4.0 [1] (🙎🏻♀️) +1F64E 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man pouting: light skin tone # E4.0 [1] (🙎🏻♂️) +1F64E 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman pouting: medium-light skin tone # E4.0 [1] (🙎🏼♀️) +1F64E 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man pouting: medium-light skin tone # E4.0 [1] (🙎🏼♂️) +1F64E 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman pouting: medium skin tone # E4.0 [1] (🙎🏽♀️) +1F64E 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man pouting: medium skin tone # E4.0 [1] (🙎🏽♂️) +1F64E 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman pouting: medium-dark skin tone # E4.0 [1] (🙎🏾♀️) +1F64E 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man pouting: medium-dark skin tone # E4.0 [1] (🙎🏾♂️) +1F64E 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman pouting: dark skin tone # E4.0 [1] (🙎🏿♀️) +1F64E 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man pouting: dark skin tone # E4.0 [1] (🙎🏿♂️) +1F6A3 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman rowing boat # E4.0 [1] (🚣♀️) +1F6A3 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man rowing boat # E4.0 [1] (🚣♂️) +1F6A3 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman rowing boat: light skin tone # E4.0 [1] (🚣🏻♀️) +1F6A3 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man rowing boat: light skin tone # E4.0 [1] (🚣🏻♂️) +1F6A3 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman rowing boat: medium-light skin tone # E4.0 [1] (🚣🏼♀️) +1F6A3 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man rowing boat: medium-light skin tone # E4.0 [1] (🚣🏼♂️) +1F6A3 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman rowing boat: medium skin tone # E4.0 [1] (🚣🏽♀️) +1F6A3 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man rowing boat: medium skin tone # E4.0 [1] (🚣🏽♂️) +1F6A3 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman rowing boat: medium-dark skin tone # E4.0 [1] (🚣🏾♀️) +1F6A3 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man rowing boat: medium-dark skin tone # E4.0 [1] (🚣🏾♂️) +1F6A3 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman rowing boat: dark skin tone # E4.0 [1] (🚣🏿♀️) +1F6A3 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man rowing boat: dark skin tone # E4.0 [1] (🚣🏿♂️) +1F6B4 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman biking # E4.0 [1] (🚴♀️) +1F6B4 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man biking # E4.0 [1] (🚴♂️) +1F6B4 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman biking: light skin tone # E4.0 [1] (🚴🏻♀️) +1F6B4 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man biking: light skin tone # E4.0 [1] (🚴🏻♂️) +1F6B4 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman biking: medium-light skin tone # E4.0 [1] (🚴🏼♀️) +1F6B4 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man biking: medium-light skin tone # E4.0 [1] (🚴🏼♂️) +1F6B4 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman biking: medium skin tone # E4.0 [1] (🚴🏽♀️) +1F6B4 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man biking: medium skin tone # E4.0 [1] (🚴🏽♂️) +1F6B4 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman biking: medium-dark skin tone # E4.0 [1] (🚴🏾♀️) +1F6B4 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man biking: medium-dark skin tone # E4.0 [1] (🚴🏾♂️) +1F6B4 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman biking: dark skin tone # E4.0 [1] (🚴🏿♀️) +1F6B4 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man biking: dark skin tone # E4.0 [1] (🚴🏿♂️) +1F6B5 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman mountain biking # E4.0 [1] (🚵♀️) +1F6B5 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man mountain biking # E4.0 [1] (🚵♂️) +1F6B5 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman mountain biking: light skin tone # E4.0 [1] (🚵🏻♀️) +1F6B5 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man mountain biking: light skin tone # E4.0 [1] (🚵🏻♂️) +1F6B5 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman mountain biking: medium-light skin tone # E4.0 [1] (🚵🏼♀️) +1F6B5 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man mountain biking: medium-light skin tone # E4.0 [1] (🚵🏼♂️) +1F6B5 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman mountain biking: medium skin tone # E4.0 [1] (🚵🏽♀️) +1F6B5 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man mountain biking: medium skin tone # E4.0 [1] (🚵🏽♂️) +1F6B5 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman mountain biking: medium-dark skin tone # E4.0 [1] (🚵🏾♀️) +1F6B5 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man mountain biking: medium-dark skin tone # E4.0 [1] (🚵🏾♂️) +1F6B5 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman mountain biking: dark skin tone # E4.0 [1] (🚵🏿♀️) +1F6B5 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man mountain biking: dark skin tone # E4.0 [1] (🚵🏿♂️) +1F6B6 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman walking # E4.0 [1] (🚶♀️) +1F6B6 200D 2640 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman walking facing right # E15.1 [1] (🚶♀️➡️) +1F6B6 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man walking # E4.0 [1] (🚶♂️) +1F6B6 200D 2642 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man walking facing right # E15.1 [1] (🚶♂️➡️) +1F6B6 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman walking: light skin tone # E4.0 [1] (🚶🏻♀️) +1F6B6 1F3FB 200D 2640 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman walking facing right: light skin tone # E15.1 [1] (🚶🏻♀️➡️) +1F6B6 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man walking: light skin tone # E4.0 [1] (🚶🏻♂️) +1F6B6 1F3FB 200D 2642 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man walking facing right: light skin tone # E15.1 [1] (🚶🏻♂️➡️) +1F6B6 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman walking: medium-light skin tone # E4.0 [1] (🚶🏼♀️) +1F6B6 1F3FC 200D 2640 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman walking facing right: medium-light skin tone # E15.1 [1] (🚶🏼♀️➡️) +1F6B6 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man walking: medium-light skin tone # E4.0 [1] (🚶🏼♂️) +1F6B6 1F3FC 200D 2642 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man walking facing right: medium-light skin tone # E15.1 [1] (🚶🏼♂️➡️) +1F6B6 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman walking: medium skin tone # E4.0 [1] (🚶🏽♀️) +1F6B6 1F3FD 200D 2640 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman walking facing right: medium skin tone # E15.1 [1] (🚶🏽♀️➡️) +1F6B6 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man walking: medium skin tone # E4.0 [1] (🚶🏽♂️) +1F6B6 1F3FD 200D 2642 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man walking facing right: medium skin tone # E15.1 [1] (🚶🏽♂️➡️) +1F6B6 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman walking: medium-dark skin tone # E4.0 [1] (🚶🏾♀️) +1F6B6 1F3FE 200D 2640 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman walking facing right: medium-dark skin tone # E15.1 [1] (🚶🏾♀️➡️) +1F6B6 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man walking: medium-dark skin tone # E4.0 [1] (🚶🏾♂️) +1F6B6 1F3FE 200D 2642 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man walking facing right: medium-dark skin tone # E15.1 [1] (🚶🏾♂️➡️) +1F6B6 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman walking: dark skin tone # E4.0 [1] (🚶🏿♀️) +1F6B6 1F3FF 200D 2640 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman walking facing right: dark skin tone # E15.1 [1] (🚶🏿♀️➡️) +1F6B6 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man walking: dark skin tone # E4.0 [1] (🚶🏿♂️) +1F6B6 1F3FF 200D 2642 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man walking facing right: dark skin tone # E15.1 [1] (🚶🏿♂️➡️) +1F926 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman facepalming # E4.0 [1] (🤦♀️) +1F926 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man facepalming # E4.0 [1] (🤦♂️) +1F926 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman facepalming: light skin tone # E4.0 [1] (🤦🏻♀️) +1F926 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man facepalming: light skin tone # E4.0 [1] (🤦🏻♂️) +1F926 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman facepalming: medium-light skin tone # E4.0 [1] (🤦🏼♀️) +1F926 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man facepalming: medium-light skin tone # E4.0 [1] (🤦🏼♂️) +1F926 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman facepalming: medium skin tone # E4.0 [1] (🤦🏽♀️) +1F926 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man facepalming: medium skin tone # E4.0 [1] (🤦🏽♂️) +1F926 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman facepalming: medium-dark skin tone # E4.0 [1] (🤦🏾♀️) +1F926 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man facepalming: medium-dark skin tone # E4.0 [1] (🤦🏾♂️) +1F926 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman facepalming: dark skin tone # E4.0 [1] (🤦🏿♀️) +1F926 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man facepalming: dark skin tone # E4.0 [1] (🤦🏿♂️) +1F935 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in tuxedo # E13.0 [1] (🤵♀️) +1F935 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in tuxedo # E13.0 [1] (🤵♂️) +1F935 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in tuxedo: light skin tone # E13.0 [1] (🤵🏻♀️) +1F935 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in tuxedo: light skin tone # E13.0 [1] (🤵🏻♂️) +1F935 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in tuxedo: medium-light skin tone # E13.0 [1] (🤵🏼♀️) +1F935 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in tuxedo: medium-light skin tone # E13.0 [1] (🤵🏼♂️) +1F935 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in tuxedo: medium skin tone # E13.0 [1] (🤵🏽♀️) +1F935 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in tuxedo: medium skin tone # E13.0 [1] (🤵🏽♂️) +1F935 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in tuxedo: medium-dark skin tone # E13.0 [1] (🤵🏾♀️) +1F935 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in tuxedo: medium-dark skin tone # E13.0 [1] (🤵🏾♂️) +1F935 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in tuxedo: dark skin tone # E13.0 [1] (🤵🏿♀️) +1F935 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in tuxedo: dark skin tone # E13.0 [1] (🤵🏿♂️) +1F937 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman shrugging # E4.0 [1] (🤷♀️) +1F937 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man shrugging # E4.0 [1] (🤷♂️) +1F937 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman shrugging: light skin tone # E4.0 [1] (🤷🏻♀️) +1F937 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man shrugging: light skin tone # E4.0 [1] (🤷🏻♂️) +1F937 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman shrugging: medium-light skin tone # E4.0 [1] (🤷🏼♀️) +1F937 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man shrugging: medium-light skin tone # E4.0 [1] (🤷🏼♂️) +1F937 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman shrugging: medium skin tone # E4.0 [1] (🤷🏽♀️) +1F937 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man shrugging: medium skin tone # E4.0 [1] (🤷🏽♂️) +1F937 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman shrugging: medium-dark skin tone # E4.0 [1] (🤷🏾♀️) +1F937 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man shrugging: medium-dark skin tone # E4.0 [1] (🤷🏾♂️) +1F937 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman shrugging: dark skin tone # E4.0 [1] (🤷🏿♀️) +1F937 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man shrugging: dark skin tone # E4.0 [1] (🤷🏿♂️) +1F938 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman cartwheeling # E4.0 [1] (🤸♀️) +1F938 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man cartwheeling # E4.0 [1] (🤸♂️) +1F938 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman cartwheeling: light skin tone # E4.0 [1] (🤸🏻♀️) +1F938 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man cartwheeling: light skin tone # E4.0 [1] (🤸🏻♂️) +1F938 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman cartwheeling: medium-light skin tone # E4.0 [1] (🤸🏼♀️) +1F938 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man cartwheeling: medium-light skin tone # E4.0 [1] (🤸🏼♂️) +1F938 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman cartwheeling: medium skin tone # E4.0 [1] (🤸🏽♀️) +1F938 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man cartwheeling: medium skin tone # E4.0 [1] (🤸🏽♂️) +1F938 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman cartwheeling: medium-dark skin tone # E4.0 [1] (🤸🏾♀️) +1F938 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man cartwheeling: medium-dark skin tone # E4.0 [1] (🤸🏾♂️) +1F938 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman cartwheeling: dark skin tone # E4.0 [1] (🤸🏿♀️) +1F938 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man cartwheeling: dark skin tone # E4.0 [1] (🤸🏿♂️) +1F939 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman juggling # E4.0 [1] (🤹♀️) +1F939 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man juggling # E4.0 [1] (🤹♂️) +1F939 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman juggling: light skin tone # E4.0 [1] (🤹🏻♀️) +1F939 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man juggling: light skin tone # E4.0 [1] (🤹🏻♂️) +1F939 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman juggling: medium-light skin tone # E4.0 [1] (🤹🏼♀️) +1F939 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man juggling: medium-light skin tone # E4.0 [1] (🤹🏼♂️) +1F939 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman juggling: medium skin tone # E4.0 [1] (🤹🏽♀️) +1F939 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man juggling: medium skin tone # E4.0 [1] (🤹🏽♂️) +1F939 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman juggling: medium-dark skin tone # E4.0 [1] (🤹🏾♀️) +1F939 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man juggling: medium-dark skin tone # E4.0 [1] (🤹🏾♂️) +1F939 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman juggling: dark skin tone # E4.0 [1] (🤹🏿♀️) +1F939 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man juggling: dark skin tone # E4.0 [1] (🤹🏿♂️) +1F93C 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; women wrestling # E4.0 [1] (🤼♀️) +1F93C 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; men wrestling # E4.0 [1] (🤼♂️) +1F93D 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman playing water polo # E4.0 [1] (🤽♀️) +1F93D 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man playing water polo # E4.0 [1] (🤽♂️) +1F93D 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman playing water polo: light skin tone # E4.0 [1] (🤽🏻♀️) +1F93D 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man playing water polo: light skin tone # E4.0 [1] (🤽🏻♂️) +1F93D 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman playing water polo: medium-light skin tone # E4.0 [1] (🤽🏼♀️) +1F93D 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man playing water polo: medium-light skin tone # E4.0 [1] (🤽🏼♂️) +1F93D 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman playing water polo: medium skin tone # E4.0 [1] (🤽🏽♀️) +1F93D 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man playing water polo: medium skin tone # E4.0 [1] (🤽🏽♂️) +1F93D 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman playing water polo: medium-dark skin tone # E4.0 [1] (🤽🏾♀️) +1F93D 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man playing water polo: medium-dark skin tone # E4.0 [1] (🤽🏾♂️) +1F93D 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman playing water polo: dark skin tone # E4.0 [1] (🤽🏿♀️) +1F93D 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man playing water polo: dark skin tone # E4.0 [1] (🤽🏿♂️) +1F93E 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman playing handball # E4.0 [1] (🤾♀️) +1F93E 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man playing handball # E4.0 [1] (🤾♂️) +1F93E 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman playing handball: light skin tone # E4.0 [1] (🤾🏻♀️) +1F93E 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man playing handball: light skin tone # E4.0 [1] (🤾🏻♂️) +1F93E 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman playing handball: medium-light skin tone # E4.0 [1] (🤾🏼♀️) +1F93E 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man playing handball: medium-light skin tone # E4.0 [1] (🤾🏼♂️) +1F93E 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman playing handball: medium skin tone # E4.0 [1] (🤾🏽♀️) +1F93E 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man playing handball: medium skin tone # E4.0 [1] (🤾🏽♂️) +1F93E 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman playing handball: medium-dark skin tone # E4.0 [1] (🤾🏾♀️) +1F93E 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man playing handball: medium-dark skin tone # E4.0 [1] (🤾🏾♂️) +1F93E 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman playing handball: dark skin tone # E4.0 [1] (🤾🏿♀️) +1F93E 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man playing handball: dark skin tone # E4.0 [1] (🤾🏿♂️) +1F9B8 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman superhero # E11.0 [1] (🦸♀️) +1F9B8 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man superhero # E11.0 [1] (🦸♂️) +1F9B8 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman superhero: light skin tone # E11.0 [1] (🦸🏻♀️) +1F9B8 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man superhero: light skin tone # E11.0 [1] (🦸🏻♂️) +1F9B8 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman superhero: medium-light skin tone # E11.0 [1] (🦸🏼♀️) +1F9B8 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man superhero: medium-light skin tone # E11.0 [1] (🦸🏼♂️) +1F9B8 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman superhero: medium skin tone # E11.0 [1] (🦸🏽♀️) +1F9B8 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man superhero: medium skin tone # E11.0 [1] (🦸🏽♂️) +1F9B8 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman superhero: medium-dark skin tone # E11.0 [1] (🦸🏾♀️) +1F9B8 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man superhero: medium-dark skin tone # E11.0 [1] (🦸🏾♂️) +1F9B8 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman superhero: dark skin tone # E11.0 [1] (🦸🏿♀️) +1F9B8 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man superhero: dark skin tone # E11.0 [1] (🦸🏿♂️) +1F9B9 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman supervillain # E11.0 [1] (🦹♀️) +1F9B9 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man supervillain # E11.0 [1] (🦹♂️) +1F9B9 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman supervillain: light skin tone # E11.0 [1] (🦹🏻♀️) +1F9B9 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man supervillain: light skin tone # E11.0 [1] (🦹🏻♂️) +1F9B9 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman supervillain: medium-light skin tone # E11.0 [1] (🦹🏼♀️) +1F9B9 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man supervillain: medium-light skin tone # E11.0 [1] (🦹🏼♂️) +1F9B9 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman supervillain: medium skin tone # E11.0 [1] (🦹🏽♀️) +1F9B9 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man supervillain: medium skin tone # E11.0 [1] (🦹🏽♂️) +1F9B9 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman supervillain: medium-dark skin tone # E11.0 [1] (🦹🏾♀️) +1F9B9 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man supervillain: medium-dark skin tone # E11.0 [1] (🦹🏾♂️) +1F9B9 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman supervillain: dark skin tone # E11.0 [1] (🦹🏿♀️) +1F9B9 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man supervillain: dark skin tone # E11.0 [1] (🦹🏿♂️) +1F9CD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman standing # E12.0 [1] (🧍♀️) +1F9CD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man standing # E12.0 [1] (🧍♂️) +1F9CD 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman standing: light skin tone # E12.0 [1] (🧍🏻♀️) +1F9CD 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man standing: light skin tone # E12.0 [1] (🧍🏻♂️) +1F9CD 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman standing: medium-light skin tone # E12.0 [1] (🧍🏼♀️) +1F9CD 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man standing: medium-light skin tone # E12.0 [1] (🧍🏼♂️) +1F9CD 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman standing: medium skin tone # E12.0 [1] (🧍🏽♀️) +1F9CD 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man standing: medium skin tone # E12.0 [1] (🧍🏽♂️) +1F9CD 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman standing: medium-dark skin tone # E12.0 [1] (🧍🏾♀️) +1F9CD 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man standing: medium-dark skin tone # E12.0 [1] (🧍🏾♂️) +1F9CD 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman standing: dark skin tone # E12.0 [1] (🧍🏿♀️) +1F9CD 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man standing: dark skin tone # E12.0 [1] (🧍🏿♂️) +1F9CE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman kneeling # E12.0 [1] (🧎♀️) +1F9CE 200D 2640 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman kneeling facing right # E15.1 [1] (🧎♀️➡️) +1F9CE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man kneeling # E12.0 [1] (🧎♂️) +1F9CE 200D 2642 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man kneeling facing right # E15.1 [1] (🧎♂️➡️) +1F9CE 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman kneeling: light skin tone # E12.0 [1] (🧎🏻♀️) +1F9CE 1F3FB 200D 2640 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman kneeling facing right: light skin tone # E15.1 [1] (🧎🏻♀️➡️) +1F9CE 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man kneeling: light skin tone # E12.0 [1] (🧎🏻♂️) +1F9CE 1F3FB 200D 2642 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man kneeling facing right: light skin tone # E15.1 [1] (🧎🏻♂️➡️) +1F9CE 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman kneeling: medium-light skin tone # E12.0 [1] (🧎🏼♀️) +1F9CE 1F3FC 200D 2640 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman kneeling facing right: medium-light skin tone # E15.1 [1] (🧎🏼♀️➡️) +1F9CE 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man kneeling: medium-light skin tone # E12.0 [1] (🧎🏼♂️) +1F9CE 1F3FC 200D 2642 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man kneeling facing right: medium-light skin tone # E15.1 [1] (🧎🏼♂️➡️) +1F9CE 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman kneeling: medium skin tone # E12.0 [1] (🧎🏽♀️) +1F9CE 1F3FD 200D 2640 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman kneeling facing right: medium skin tone # E15.1 [1] (🧎🏽♀️➡️) +1F9CE 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man kneeling: medium skin tone # E12.0 [1] (🧎🏽♂️) +1F9CE 1F3FD 200D 2642 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man kneeling facing right: medium skin tone # E15.1 [1] (🧎🏽♂️➡️) +1F9CE 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman kneeling: medium-dark skin tone # E12.0 [1] (🧎🏾♀️) +1F9CE 1F3FE 200D 2640 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman kneeling facing right: medium-dark skin tone # E15.1 [1] (🧎🏾♀️➡️) +1F9CE 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man kneeling: medium-dark skin tone # E12.0 [1] (🧎🏾♂️) +1F9CE 1F3FE 200D 2642 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man kneeling facing right: medium-dark skin tone # E15.1 [1] (🧎🏾♂️➡️) +1F9CE 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman kneeling: dark skin tone # E12.0 [1] (🧎🏿♀️) +1F9CE 1F3FF 200D 2640 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman kneeling facing right: dark skin tone # E15.1 [1] (🧎🏿♀️➡️) +1F9CE 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man kneeling: dark skin tone # E12.0 [1] (🧎🏿♂️) +1F9CE 1F3FF 200D 2642 FE0F 200D 27A1 FE0F ; RGI_Emoji_ZWJ_Sequence ; man kneeling facing right: dark skin tone # E15.1 [1] (🧎🏿♂️➡️) +1F9CF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; deaf woman # E12.0 [1] (🧏♀️) +1F9CF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; deaf man # E12.0 [1] (🧏♂️) +1F9CF 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; deaf woman: light skin tone # E12.0 [1] (🧏🏻♀️) +1F9CF 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; deaf man: light skin tone # E12.0 [1] (🧏🏻♂️) +1F9CF 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; deaf woman: medium-light skin tone # E12.0 [1] (🧏🏼♀️) +1F9CF 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; deaf man: medium-light skin tone # E12.0 [1] (🧏🏼♂️) +1F9CF 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; deaf woman: medium skin tone # E12.0 [1] (🧏🏽♀️) +1F9CF 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; deaf man: medium skin tone # E12.0 [1] (🧏🏽♂️) +1F9CF 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; deaf woman: medium-dark skin tone # E12.0 [1] (🧏🏾♀️) +1F9CF 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; deaf man: medium-dark skin tone # E12.0 [1] (🧏🏾♂️) +1F9CF 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; deaf woman: dark skin tone # E12.0 [1] (🧏🏿♀️) +1F9CF 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; deaf man: dark skin tone # E12.0 [1] (🧏🏿♂️) +1F9D4 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman: beard # E13.1 [1] (🧔♀️) +1F9D4 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man: beard # E13.1 [1] (🧔♂️) +1F9D4 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman: light skin tone, beard # E13.1 [1] (🧔🏻♀️) +1F9D4 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man: light skin tone, beard # E13.1 [1] (🧔🏻♂️) +1F9D4 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman: medium-light skin tone, beard # E13.1 [1] (🧔🏼♀️) +1F9D4 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man: medium-light skin tone, beard # E13.1 [1] (🧔🏼♂️) +1F9D4 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman: medium skin tone, beard # E13.1 [1] (🧔🏽♀️) +1F9D4 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man: medium skin tone, beard # E13.1 [1] (🧔🏽♂️) +1F9D4 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman: medium-dark skin tone, beard # E13.1 [1] (🧔🏾♀️) +1F9D4 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man: medium-dark skin tone, beard # E13.1 [1] (🧔🏾♂️) +1F9D4 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman: dark skin tone, beard # E13.1 [1] (🧔🏿♀️) +1F9D4 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man: dark skin tone, beard # E13.1 [1] (🧔🏿♂️) +1F9D6 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in steamy room # E5.0 [1] (🧖♀️) +1F9D6 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in steamy room # E5.0 [1] (🧖♂️) +1F9D6 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in steamy room: light skin tone # E5.0 [1] (🧖🏻♀️) +1F9D6 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in steamy room: light skin tone # E5.0 [1] (🧖🏻♂️) +1F9D6 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in steamy room: medium-light skin tone # E5.0 [1] (🧖🏼♀️) +1F9D6 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in steamy room: medium-light skin tone # E5.0 [1] (🧖🏼♂️) +1F9D6 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in steamy room: medium skin tone # E5.0 [1] (🧖🏽♀️) +1F9D6 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in steamy room: medium skin tone # E5.0 [1] (🧖🏽♂️) +1F9D6 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in steamy room: medium-dark skin tone # E5.0 [1] (🧖🏾♀️) +1F9D6 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in steamy room: medium-dark skin tone # E5.0 [1] (🧖🏾♂️) +1F9D6 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in steamy room: dark skin tone # E5.0 [1] (🧖🏿♀️) +1F9D6 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in steamy room: dark skin tone # E5.0 [1] (🧖🏿♂️) +1F9D7 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman climbing # E5.0 [1] (🧗♀️) +1F9D7 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man climbing # E5.0 [1] (🧗♂️) +1F9D7 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman climbing: light skin tone # E5.0 [1] (🧗🏻♀️) +1F9D7 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man climbing: light skin tone # E5.0 [1] (🧗🏻♂️) +1F9D7 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman climbing: medium-light skin tone # E5.0 [1] (🧗🏼♀️) +1F9D7 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man climbing: medium-light skin tone # E5.0 [1] (🧗🏼♂️) +1F9D7 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman climbing: medium skin tone # E5.0 [1] (🧗🏽♀️) +1F9D7 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man climbing: medium skin tone # E5.0 [1] (🧗🏽♂️) +1F9D7 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman climbing: medium-dark skin tone # E5.0 [1] (🧗🏾♀️) +1F9D7 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man climbing: medium-dark skin tone # E5.0 [1] (🧗🏾♂️) +1F9D7 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman climbing: dark skin tone # E5.0 [1] (🧗🏿♀️) +1F9D7 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man climbing: dark skin tone # E5.0 [1] (🧗🏿♂️) +1F9D8 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in lotus position # E5.0 [1] (🧘♀️) +1F9D8 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in lotus position # E5.0 [1] (🧘♂️) +1F9D8 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in lotus position: light skin tone # E5.0 [1] (🧘🏻♀️) +1F9D8 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in lotus position: light skin tone # E5.0 [1] (🧘🏻♂️) +1F9D8 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in lotus position: medium-light skin tone # E5.0 [1] (🧘🏼♀️) +1F9D8 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in lotus position: medium-light skin tone # E5.0 [1] (🧘🏼♂️) +1F9D8 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in lotus position: medium skin tone # E5.0 [1] (🧘🏽♀️) +1F9D8 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in lotus position: medium skin tone # E5.0 [1] (🧘🏽♂️) +1F9D8 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in lotus position: medium-dark skin tone # E5.0 [1] (🧘🏾♀️) +1F9D8 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in lotus position: medium-dark skin tone # E5.0 [1] (🧘🏾♂️) +1F9D8 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in lotus position: dark skin tone # E5.0 [1] (🧘🏿♀️) +1F9D8 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in lotus position: dark skin tone # E5.0 [1] (🧘🏿♂️) +1F9D9 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman mage # E5.0 [1] (🧙♀️) +1F9D9 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man mage # E5.0 [1] (🧙♂️) +1F9D9 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman mage: light skin tone # E5.0 [1] (🧙🏻♀️) +1F9D9 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man mage: light skin tone # E5.0 [1] (🧙🏻♂️) +1F9D9 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman mage: medium-light skin tone # E5.0 [1] (🧙🏼♀️) +1F9D9 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man mage: medium-light skin tone # E5.0 [1] (🧙🏼♂️) +1F9D9 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman mage: medium skin tone # E5.0 [1] (🧙🏽♀️) +1F9D9 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man mage: medium skin tone # E5.0 [1] (🧙🏽♂️) +1F9D9 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman mage: medium-dark skin tone # E5.0 [1] (🧙🏾♀️) +1F9D9 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man mage: medium-dark skin tone # E5.0 [1] (🧙🏾♂️) +1F9D9 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman mage: dark skin tone # E5.0 [1] (🧙🏿♀️) +1F9D9 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man mage: dark skin tone # E5.0 [1] (🧙🏿♂️) +1F9DA 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman fairy # E5.0 [1] (🧚♀️) +1F9DA 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man fairy # E5.0 [1] (🧚♂️) +1F9DA 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman fairy: light skin tone # E5.0 [1] (🧚🏻♀️) +1F9DA 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man fairy: light skin tone # E5.0 [1] (🧚🏻♂️) +1F9DA 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman fairy: medium-light skin tone # E5.0 [1] (🧚🏼♀️) +1F9DA 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man fairy: medium-light skin tone # E5.0 [1] (🧚🏼♂️) +1F9DA 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman fairy: medium skin tone # E5.0 [1] (🧚🏽♀️) +1F9DA 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man fairy: medium skin tone # E5.0 [1] (🧚🏽♂️) +1F9DA 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman fairy: medium-dark skin tone # E5.0 [1] (🧚🏾♀️) +1F9DA 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man fairy: medium-dark skin tone # E5.0 [1] (🧚🏾♂️) +1F9DA 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman fairy: dark skin tone # E5.0 [1] (🧚🏿♀️) +1F9DA 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man fairy: dark skin tone # E5.0 [1] (🧚🏿♂️) +1F9DB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman vampire # E5.0 [1] (🧛♀️) +1F9DB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man vampire # E5.0 [1] (🧛♂️) +1F9DB 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman vampire: light skin tone # E5.0 [1] (🧛🏻♀️) +1F9DB 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man vampire: light skin tone # E5.0 [1] (🧛🏻♂️) +1F9DB 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman vampire: medium-light skin tone # E5.0 [1] (🧛🏼♀️) +1F9DB 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man vampire: medium-light skin tone # E5.0 [1] (🧛🏼♂️) +1F9DB 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman vampire: medium skin tone # E5.0 [1] (🧛🏽♀️) +1F9DB 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man vampire: medium skin tone # E5.0 [1] (🧛🏽♂️) +1F9DB 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman vampire: medium-dark skin tone # E5.0 [1] (🧛🏾♀️) +1F9DB 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man vampire: medium-dark skin tone # E5.0 [1] (🧛🏾♂️) +1F9DB 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman vampire: dark skin tone # E5.0 [1] (🧛🏿♀️) +1F9DB 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man vampire: dark skin tone # E5.0 [1] (🧛🏿♂️) +1F9DC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; mermaid # E5.0 [1] (🧜♀️) +1F9DC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; merman # E5.0 [1] (🧜♂️) +1F9DC 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; mermaid: light skin tone # E5.0 [1] (🧜🏻♀️) +1F9DC 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; merman: light skin tone # E5.0 [1] (🧜🏻♂️) +1F9DC 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; mermaid: medium-light skin tone # E5.0 [1] (🧜🏼♀️) +1F9DC 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; merman: medium-light skin tone # E5.0 [1] (🧜🏼♂️) +1F9DC 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; mermaid: medium skin tone # E5.0 [1] (🧜🏽♀️) +1F9DC 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; merman: medium skin tone # E5.0 [1] (🧜🏽♂️) +1F9DC 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; mermaid: medium-dark skin tone # E5.0 [1] (🧜🏾♀️) +1F9DC 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; merman: medium-dark skin tone # E5.0 [1] (🧜🏾♂️) +1F9DC 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; mermaid: dark skin tone # E5.0 [1] (🧜🏿♀️) +1F9DC 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; merman: dark skin tone # E5.0 [1] (🧜🏿♂️) +1F9DD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman elf # E5.0 [1] (🧝♀️) +1F9DD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man elf # E5.0 [1] (🧝♂️) +1F9DD 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman elf: light skin tone # E5.0 [1] (🧝🏻♀️) +1F9DD 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man elf: light skin tone # E5.0 [1] (🧝🏻♂️) +1F9DD 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman elf: medium-light skin tone # E5.0 [1] (🧝🏼♀️) +1F9DD 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man elf: medium-light skin tone # E5.0 [1] (🧝🏼♂️) +1F9DD 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman elf: medium skin tone # E5.0 [1] (🧝🏽♀️) +1F9DD 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man elf: medium skin tone # E5.0 [1] (🧝🏽♂️) +1F9DD 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman elf: medium-dark skin tone # E5.0 [1] (🧝🏾♀️) +1F9DD 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man elf: medium-dark skin tone # E5.0 [1] (🧝🏾♂️) +1F9DD 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman elf: dark skin tone # E5.0 [1] (🧝🏿♀️) +1F9DD 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man elf: dark skin tone # E5.0 [1] (🧝🏿♂️) +1F9DE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman genie # E5.0 [1] (🧞♀️) +1F9DE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man genie # E5.0 [1] (🧞♂️) +1F9DF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman zombie # E5.0 [1] (🧟♀️) +1F9DF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man zombie # E5.0 [1] (🧟♂️) + +# Total elements: 608 + +# ================================================ + +# RGI_Emoji_ZWJ_Sequence: Hair + +1F468 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; man: red hair # E11.0 [1] (👨🦰) +1F468 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; man: curly hair # E11.0 [1] (👨🦱) +1F468 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; man: bald # E11.0 [1] (👨🦲) +1F468 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; man: white hair # E11.0 [1] (👨🦳) +1F468 1F3FB 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; man: light skin tone, red hair # E11.0 [1] (👨🏻🦰) +1F468 1F3FB 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; man: light skin tone, curly hair # E11.0 [1] (👨🏻🦱) +1F468 1F3FB 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; man: light skin tone, bald # E11.0 [1] (👨🏻🦲) +1F468 1F3FB 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; man: light skin tone, white hair # E11.0 [1] (👨🏻🦳) +1F468 1F3FC 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; man: medium-light skin tone, red hair # E11.0 [1] (👨🏼🦰) +1F468 1F3FC 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; man: medium-light skin tone, curly hair # E11.0 [1] (👨🏼🦱) +1F468 1F3FC 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; man: medium-light skin tone, bald # E11.0 [1] (👨🏼🦲) +1F468 1F3FC 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; man: medium-light skin tone, white hair # E11.0 [1] (👨🏼🦳) +1F468 1F3FD 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; man: medium skin tone, red hair # E11.0 [1] (👨🏽🦰) +1F468 1F3FD 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; man: medium skin tone, curly hair # E11.0 [1] (👨🏽🦱) +1F468 1F3FD 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; man: medium skin tone, bald # E11.0 [1] (👨🏽🦲) +1F468 1F3FD 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; man: medium skin tone, white hair # E11.0 [1] (👨🏽🦳) +1F468 1F3FE 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; man: medium-dark skin tone, red hair # E11.0 [1] (👨🏾🦰) +1F468 1F3FE 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; man: medium-dark skin tone, curly hair # E11.0 [1] (👨🏾🦱) +1F468 1F3FE 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; man: medium-dark skin tone, bald # E11.0 [1] (👨🏾🦲) +1F468 1F3FE 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; man: medium-dark skin tone, white hair # E11.0 [1] (👨🏾🦳) +1F468 1F3FF 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; man: dark skin tone, red hair # E11.0 [1] (👨🏿🦰) +1F468 1F3FF 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; man: dark skin tone, curly hair # E11.0 [1] (👨🏿🦱) +1F468 1F3FF 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; man: dark skin tone, bald # E11.0 [1] (👨🏿🦲) +1F468 1F3FF 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; man: dark skin tone, white hair # E11.0 [1] (👨🏿🦳) +1F469 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; woman: red hair # E11.0 [1] (👩🦰) +1F469 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; woman: curly hair # E11.0 [1] (👩🦱) +1F469 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; woman: bald # E11.0 [1] (👩🦲) +1F469 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; woman: white hair # E11.0 [1] (👩🦳) +1F469 1F3FB 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; woman: light skin tone, red hair # E11.0 [1] (👩🏻🦰) +1F469 1F3FB 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; woman: light skin tone, curly hair # E11.0 [1] (👩🏻🦱) +1F469 1F3FB 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; woman: light skin tone, bald # E11.0 [1] (👩🏻🦲) +1F469 1F3FB 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; woman: light skin tone, white hair # E11.0 [1] (👩🏻🦳) +1F469 1F3FC 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; woman: medium-light skin tone, red hair # E11.0 [1] (👩🏼🦰) +1F469 1F3FC 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; woman: medium-light skin tone, curly hair # E11.0 [1] (👩🏼🦱) +1F469 1F3FC 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; woman: medium-light skin tone, bald # E11.0 [1] (👩🏼🦲) +1F469 1F3FC 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; woman: medium-light skin tone, white hair # E11.0 [1] (👩🏼🦳) +1F469 1F3FD 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; woman: medium skin tone, red hair # E11.0 [1] (👩🏽🦰) +1F469 1F3FD 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; woman: medium skin tone, curly hair # E11.0 [1] (👩🏽🦱) +1F469 1F3FD 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; woman: medium skin tone, bald # E11.0 [1] (👩🏽🦲) +1F469 1F3FD 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; woman: medium skin tone, white hair # E11.0 [1] (👩🏽🦳) +1F469 1F3FE 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; woman: medium-dark skin tone, red hair # E11.0 [1] (👩🏾🦰) +1F469 1F3FE 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; woman: medium-dark skin tone, curly hair # E11.0 [1] (👩🏾🦱) +1F469 1F3FE 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; woman: medium-dark skin tone, bald # E11.0 [1] (👩🏾🦲) +1F469 1F3FE 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; woman: medium-dark skin tone, white hair # E11.0 [1] (👩🏾🦳) +1F469 1F3FF 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; woman: dark skin tone, red hair # E11.0 [1] (👩🏿🦰) +1F469 1F3FF 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; woman: dark skin tone, curly hair # E11.0 [1] (👩🏿🦱) +1F469 1F3FF 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; woman: dark skin tone, bald # E11.0 [1] (👩🏿🦲) +1F469 1F3FF 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; woman: dark skin tone, white hair # E11.0 [1] (👩🏿🦳) +1F9D1 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; person: red hair # E12.1 [1] (🧑🦰) +1F9D1 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; person: curly hair # E12.1 [1] (🧑🦱) +1F9D1 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; person: bald # E12.1 [1] (🧑🦲) +1F9D1 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; person: white hair # E12.1 [1] (🧑🦳) +1F9D1 1F3FB 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; person: light skin tone, red hair # E12.1 [1] (🧑🏻🦰) +1F9D1 1F3FB 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; person: light skin tone, curly hair # E12.1 [1] (🧑🏻🦱) +1F9D1 1F3FB 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; person: light skin tone, bald # E12.1 [1] (🧑🏻🦲) +1F9D1 1F3FB 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; person: light skin tone, white hair # E12.1 [1] (🧑🏻🦳) +1F9D1 1F3FC 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; person: medium-light skin tone, red hair # E12.1 [1] (🧑🏼🦰) +1F9D1 1F3FC 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; person: medium-light skin tone, curly hair # E12.1 [1] (🧑🏼🦱) +1F9D1 1F3FC 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; person: medium-light skin tone, bald # E12.1 [1] (🧑🏼🦲) +1F9D1 1F3FC 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; person: medium-light skin tone, white hair # E12.1 [1] (🧑🏼🦳) +1F9D1 1F3FD 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; person: medium skin tone, red hair # E12.1 [1] (🧑🏽🦰) +1F9D1 1F3FD 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; person: medium skin tone, curly hair # E12.1 [1] (🧑🏽🦱) +1F9D1 1F3FD 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; person: medium skin tone, bald # E12.1 [1] (🧑🏽🦲) +1F9D1 1F3FD 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; person: medium skin tone, white hair # E12.1 [1] (🧑🏽🦳) +1F9D1 1F3FE 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; person: medium-dark skin tone, red hair # E12.1 [1] (🧑🏾🦰) +1F9D1 1F3FE 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; person: medium-dark skin tone, curly hair # E12.1 [1] (🧑🏾🦱) +1F9D1 1F3FE 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; person: medium-dark skin tone, bald # E12.1 [1] (🧑🏾🦲) +1F9D1 1F3FE 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; person: medium-dark skin tone, white hair # E12.1 [1] (🧑🏾🦳) +1F9D1 1F3FF 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; person: dark skin tone, red hair # E12.1 [1] (🧑🏿🦰) +1F9D1 1F3FF 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; person: dark skin tone, curly hair # E12.1 [1] (🧑🏿🦱) +1F9D1 1F3FF 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; person: dark skin tone, bald # E12.1 [1] (🧑🏿🦲) +1F9D1 1F3FF 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; person: dark skin tone, white hair # E12.1 [1] (🧑🏿🦳) + +# Total elements: 72 + +# ================================================ + +# RGI_Emoji_ZWJ_Sequence: Other + +26D3 FE0F 200D 1F4A5 ; RGI_Emoji_ZWJ_Sequence ; broken chain # E15.1 [1] (⛓️💥) +2764 FE0F 200D 1F525 ; RGI_Emoji_ZWJ_Sequence ; heart on fire # E13.1 [1] (❤️🔥) +2764 FE0F 200D 1FA79 ; RGI_Emoji_ZWJ_Sequence ; mending heart # E13.1 [1] (❤️🩹) +1F344 200D 1F7EB ; RGI_Emoji_ZWJ_Sequence ; brown mushroom # E15.1 [1] (🍄🟫) +1F34B 200D 1F7E9 ; RGI_Emoji_ZWJ_Sequence ; lime # E15.1 [1] (🍋🟩) +1F3F3 FE0F 200D 26A7 FE0F ; RGI_Emoji_ZWJ_Sequence ; transgender flag # E13.0 [1] (🏳️⚧️) +1F3F3 FE0F 200D 1F308 ; RGI_Emoji_ZWJ_Sequence ; rainbow flag # E4.0 [1] (🏳️🌈) +1F3F4 200D 2620 FE0F ; RGI_Emoji_ZWJ_Sequence ; pirate flag # E11.0 [1] (🏴☠️) +1F408 200D 2B1B ; RGI_Emoji_ZWJ_Sequence ; black cat # E13.0 [1] (🐈⬛) +1F415 200D 1F9BA ; RGI_Emoji_ZWJ_Sequence ; service dog # E12.0 [1] (🐕🦺) +1F426 200D 2B1B ; RGI_Emoji_ZWJ_Sequence ; black bird # E15.0 [1] (🐦⬛) +1F426 200D 1F525 ; RGI_Emoji_ZWJ_Sequence ; phoenix # E15.1 [1] (🐦🔥) +1F43B 200D 2744 FE0F ; RGI_Emoji_ZWJ_Sequence ; polar bear # E13.0 [1] (🐻❄️) +1F441 FE0F 200D 1F5E8 FE0F ; RGI_Emoji_ZWJ_Sequence ; eye in speech bubble # E2.0 [1] (👁️🗨️) +1F62E 200D 1F4A8 ; RGI_Emoji_ZWJ_Sequence ; face exhaling # E13.1 [1] (😮💨) +1F635 200D 1F4AB ; RGI_Emoji_ZWJ_Sequence ; face with spiral eyes # E13.1 [1] (😵💫) +1F636 200D 1F32B FE0F ; RGI_Emoji_ZWJ_Sequence ; face in clouds # E13.1 [1] (😶🌫️) +1F642 200D 2194 FE0F ; RGI_Emoji_ZWJ_Sequence ; head shaking horizontally # E15.1 [1] (🙂↔️) +1F642 200D 2195 FE0F ; RGI_Emoji_ZWJ_Sequence ; head shaking vertically # E15.1 [1] (🙂↕️) + +# Total elements: 19 + +#EOF diff --git a/contrib/python/wcwidth/py2/tests/test_core.py b/contrib/python/wcwidth/py2/tests/test_core.py index c8f791c016..d2776cd992 100644 --- a/contrib/python/wcwidth/py2/tests/test_core.py +++ b/contrib/python/wcwidth/py2/tests/test_core.py @@ -10,6 +10,13 @@ except ImportError: # local import wcwidth +try: + # python 2 + _ = unichr +except NameError: + # python 3 + unichr = chr + def test_package_version(): """wcwidth.__version__ is expected value.""" @@ -23,6 +30,45 @@ def test_package_version(): assert result == expected +def test_empty_string(): + """ + Test empty string is OK. + + https://github.com/jquast/wcwidth/issues/24 + """ + phrase = "" + expect_length_each = 0 + expect_length_phrase = 0 + + # exercise, + length_each = wcwidth.wcwidth(phrase) + length_phrase = wcwidth.wcswidth(phrase) + + # verify. + assert length_each == expect_length_each + assert length_phrase == expect_length_phrase + + +def basic_string_type(): + """ + This is a python 2-specific test of the basic "string type" + + Such strings cannot contain anything but ascii in python2. + """ + # given, + phrase = 'hello\x00world' + expect_length_each = (1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1) + expect_length_phrase = sum(expect_length_each) + + # exercise, + length_each = tuple(map(wcwidth.wcwidth, phrase)) + length_phrase = wcwidth.wcswidth(phrase) + + # verify. + assert length_each == expect_length_each + assert length_phrase == expect_length_phrase + + def test_hello_jp(): u""" Width of Japanese phrase: コンニチハ, セカイ! @@ -59,9 +105,11 @@ def test_wcswidth_substr(): expect_length_phrase = sum(expect_length_each) # exercise, + length_each = tuple(map(wcwidth.wcwidth, phrase))[:end] length_phrase = wcwidth.wcswidth(phrase, end) # verify. + assert length_each == expect_length_each assert length_phrase == expect_length_phrase @@ -82,7 +130,15 @@ def test_null_width_0(): def test_control_c0_width_negative_1(): - """CSI (Control sequence initiate) reports width -1 for ESC.""" + """How the API reacts to CSI (Control sequence initiate). + + An example of bad fortune, this terminal sequence is a width of 0 + on all terminals, but wcwidth doesn't parse Control-Sequence-Inducer + (CSI) sequences. + + Also the "legacy" posix functions wcwidth and wcswidth return -1 for + any string containing the C1 control character \x1b (ESC). + """ # given, phrase = u'\x1b[0m' expect_length_each = (-1, 1, 1, 1) @@ -90,9 +146,9 @@ def test_control_c0_width_negative_1(): # exercise, length_each = tuple(map(wcwidth.wcwidth, phrase)) - length_phrase = wcwidth.wcswidth(phrase, len(phrase)) + length_phrase = wcwidth.wcswidth(phrase) - # verify. + # verify, though this is actually *0* width for a terminal emulator assert length_each == expect_length_each assert length_phrase == expect_length_phrase @@ -106,7 +162,7 @@ def test_combining_width(): # exercise, length_each = tuple(map(wcwidth.wcwidth, phrase)) - length_phrase = wcwidth.wcswidth(phrase, len(phrase)) + length_phrase = wcwidth.wcswidth(phrase) # verify. assert length_each == expect_length_each @@ -121,7 +177,7 @@ def test_combining_cafe(): # exercise, length_each = tuple(map(wcwidth.wcwidth, phrase)) - length_phrase = wcwidth.wcswidth(phrase, len(phrase)) + length_phrase = wcwidth.wcswidth(phrase) # verify. assert length_each == expect_length_each @@ -129,29 +185,172 @@ def test_combining_cafe(): def test_combining_enclosing(): - u"""CYRILLIC CAPITAL LETTER A + COMBINING CYRILLIC HUNDRED THOUSANDS SIGN is А҈ of length 1.""" + u"""CYRILLIC CAPITAL LETTER A + COMBINING CYRILLIC HUNDRED THOUSANDS SIGN is of length 1.""" phrase = u"\u0410\u0488" expect_length_each = (1, 0) expect_length_phrase = 1 # exercise, length_each = tuple(map(wcwidth.wcwidth, phrase)) - length_phrase = wcwidth.wcswidth(phrase, len(phrase)) + length_phrase = wcwidth.wcswidth(phrase) # verify. assert length_each == expect_length_each assert length_phrase == expect_length_phrase -def test_combining_spacing(): - u"""Balinese kapal (ship) is ᬓᬨᬮ᭄ of length 4.""" - phrase = u"\u1B13\u1B28\u1B2E\u1B44" - expect_length_each = (1, 1, 1, 1) - expect_length_phrase = 4 +def test_balinese_script(): + u""" + Balinese kapal (ship) is length 3. + + This may be an example that is not yet correctly rendered by any terminal so + far, like devanagari. + """ + phrase = (u"\u1B13" # Category 'Lo', EAW 'N' -- BALINESE LETTER KA + u"\u1B28" # Category 'Lo', EAW 'N' -- BALINESE LETTER PA KAPAL + u"\u1B2E" # Category 'Lo', EAW 'N' -- BALINESE LETTER LA + u"\u1B44") # Category 'Mc', EAW 'N' -- BALINESE ADEG ADEG + expect_length_each = (1, 1, 1, 0) + expect_length_phrase = 3 # exercise, length_each = tuple(map(wcwidth.wcwidth, phrase)) - length_phrase = wcwidth.wcswidth(phrase, len(phrase)) + length_phrase = wcwidth.wcswidth(phrase) + + # verify. + assert length_each == expect_length_each + assert length_phrase == expect_length_phrase + + +def test_kr_jamo_filler(): + u""" + Jamo filler is 0 width. + + According to https://www.unicode.org/L2/L2006/06310-hangul-decompose9.pdf this character and others + like it, ``\uffa0``, ``\u1160``, ``\u115f``, ``\u1160``, are not commonly viewed with a terminal, + seems it doesn't matter whether it is implemented or not, they are not typically used ! + """ + phrase = u"\u1100\u1160" + expect_length_each = (2, 1) + expect_length_phrase = 3 + + # exercise, + length_each = tuple(map(wcwidth.wcwidth, phrase)) + length_phrase = wcwidth.wcswidth(phrase) + + # verify. + assert length_each == expect_length_each + assert length_phrase == expect_length_phrase + + +def test_devanagari_script(): + """ + Attempt to test the measurement width of Devanagari script. + + I believe this 'phrase' should be length 3. + + This is a difficult problem, and this library does not yet get it right, + because we interpret the unicode data files programmatically, but they do + not correctly describe how their terminal width is measured. + + There are very few Terminals that do! + + As of 2023, + + - iTerm2: correct length but individual characters are out of order and + horizaontally misplaced as to be unreadable in its language when + using 'Noto Sans' font. + - mlterm: mixed results, it offers several options in the configuration + dialog, "Xft", "Cario", and "Variable Column Width" have some + effect, but with neither 'Noto Sans' or 'unifont', it is not + recognizable as the Devanagari script it is meant to display. + + Previous testing with Devanagari documented at address https://benizi.com/vim/devanagari/ + + See also, https://askubuntu.com/questions/8437/is-there-a-good-mono-spaced-font-for-devanagari-script-in-the-terminal + """ + # This test adapted from https://www.unicode.org/L2/L2023/23107-terminal-suppt.pdf + # please note that document correctly points out that the final width cannot be determined + # as a sum of each individual width, as this library currently performs with exception of + # ZWJ, but I think it incorrectly gestures what a stateless call to wcwidth.wcwidth of + # each codepoint *should* return. + phrase = (u"\u0915" # Akhand, Category 'Lo', East Asian Width property 'N' -- DEVANAGARI LETTER KA + u"\u094D" # Joiner, Category 'Mn', East Asian Width property 'N' -- DEVANAGARI SIGN VIRAMA + u"\u0937" # Fused, Category 'Lo', East Asian Width property 'N' -- DEVANAGARI LETTER SSA + u"\u093F") # MatraL, Category 'Mc', East Asian Width property 'N' -- DEVANAGARI VOWEL SIGN I + # 23107-terminal-suppt.pdf suggests wcwidth.wcwidth should return (2, 0, 0, 1) + expect_length_each = (1, 0, 1, 0) + # I believe the final width *should* be 3. + expect_length_phrase = 2 + + # exercise, + length_each = tuple(map(wcwidth.wcwidth, phrase)) + length_phrase = wcwidth.wcswidth(phrase) + + # verify. + assert length_each == expect_length_each + assert length_phrase == expect_length_phrase + + +def test_tamil_script(): + # This test adapted from https://www.unicode.org/L2/L2023/23107-terminal-suppt.pdf + phrase = (u"\u0b95" # Akhand, Category 'Lo', East Asian Width property 'N' -- TAMIL LETTER KA + u"\u0bcd" # Joiner, Category 'Mn', East Asian Width property 'N' -- TAMIL SIGN VIRAMA + u"\u0bb7" # Fused, Category 'Lo', East Asian Width property 'N' -- TAMIL LETTER SSA + u"\u0bcc") # MatraLR, Category 'Mc', East Asian Width property 'N' -- TAMIL VOWEL SIGN AU + # 23107-terminal-suppt.pdf suggests wcwidth.wcwidth should return (3, 0, 0, 4) + expect_length_each = (1, 0, 1, 0) + + # I believe the final width should be about 5 or 6. + expect_length_phrase = 2 + + # exercise, + length_each = tuple(map(wcwidth.wcwidth, phrase)) + length_phrase = wcwidth.wcswidth(phrase) + + # verify. + assert length_each == expect_length_each + assert length_phrase == expect_length_phrase + + +def test_kannada_script(): + # This test adapted from https://www.unicode.org/L2/L2023/23107-terminal-suppt.pdf + # |ರ್ಝೈ| + # |123| + phrase = (u"\u0cb0" # Repha, Category 'Lo', East Asian Width property 'N' -- KANNADA LETTER RA + u"\u0ccd" # Joiner, Category 'Mn', East Asian Width property 'N' -- KANNADA SIGN VIRAMA + u"\u0c9d" # Base, Category 'Lo', East Asian Width property 'N' -- KANNADA LETTER JHA + u"\u0cc8") # MatraUR, Category 'Mc', East Asian Width property 'N' -- KANNADA VOWEL SIGN AI + # 23107-terminal-suppt.pdf suggests should be (2, 0, 3, 1) + expect_length_each = (1, 0, 1, 0) + # I believe the correct final width *should* be 3 or 4. + expect_length_phrase = 2 + + # exercise, + length_each = tuple(map(wcwidth.wcwidth, phrase)) + length_phrase = wcwidth.wcswidth(phrase) + + # verify. + assert length_each == expect_length_each + assert length_phrase == expect_length_phrase + + +def test_kannada_script_2(): + # This test adapted from https://www.unicode.org/L2/L2023/23107-terminal-suppt.pdf + # |ರ಼್ಚ| + # |12| + phrase = (u"\u0cb0" # Base, Category 'Lo', East Asian Width property 'N' -- KANNADA LETTER RA + u"\u0cbc" # Nukta, Category 'Mn', East Asian Width property 'N' -- KANNADA SIGN NUKTA + u"\u0ccd" # Joiner, Category 'Lo', East Asian Width property 'N' -- KANNADA SIGN VIRAMA + u"\u0c9a") # Subjoin, Category 'Mc', East Asian Width property 'N' -- KANNADA LETTER CA + # 23107-terminal-suppt.pdf suggests wcwidth.wcwidth should return (2, 0, 0, 1) + expect_length_each = (1, 0, 0, 1) + # I believe the final width is correct, but maybe for the wrong reasons! + expect_length_phrase = 2 + + # exercise, + length_each = tuple(map(wcwidth.wcwidth, phrase)) + length_phrase = wcwidth.wcswidth(phrase) # verify. assert length_each == expect_length_each diff --git a/contrib/python/wcwidth/py2/tests/test_emojis.py b/contrib/python/wcwidth/py2/tests/test_emojis.py new file mode 100644 index 0000000000..4f88e2330e --- /dev/null +++ b/contrib/python/wcwidth/py2/tests/test_emojis.py @@ -0,0 +1,243 @@ +# std imports +import os +import codecs + +# 3rd party +import pytest + +try: + # python 2 + _ = unichr +except NameError: + # python 3 + unichr = chr + +# some tests cannot be done on some builds of python, where the internal +# unicode structure is limited to 0x10000 for memory conservation, +# "ValueError: unichr() arg not in range(0x10000) (narrow Python build)" +try: + unichr(0x2fffe) + NARROW_ONLY = False +except ValueError: + NARROW_ONLY = True + +# local +import wcwidth + + +def make_sequence_from_line(line): + # convert '002A FE0F ; ..' -> (0x2a, 0xfe0f) -> chr(0x2a) + chr(0xfe0f) + return ''.join(unichr(int(cp, 16)) for cp in line.split(';', 1)[0].strip().split()) + + +@pytest.mark.skipif(NARROW_ONLY, reason="Test cannot verify on python 'narrow' builds") +def emoji_zwj_sequence(): + u""" + Emoji zwj sequence of four codepoints is just 2 cells. + """ + phrase = (u"\U0001f469" # Base, Category So, East Asian Width property 'W' -- WOMAN + u"\U0001f3fb" # Modifier, Category Sk, East Asian Width property 'W' -- EMOJI MODIFIER FITZPATRICK TYPE-1-2 + u"\u200d" # Joiner, Category Cf, East Asian Width property 'N' -- ZERO WIDTH JOINER + u"\U0001f4bb") # Fused, Category So, East Asian Width peroperty 'W' -- PERSONAL COMPUTER + # This test adapted from https://www.unicode.org/L2/L2023/23107-terminal-suppt.pdf + expect_length_each = (2, 0, 0, 2) + expect_length_phrase = 2 + + # exercise, + length_each = tuple(map(wcwidth.wcwidth, phrase)) + length_phrase = wcwidth.wcswidth(phrase) + + # verify. + assert length_each == expect_length_each + assert length_phrase == expect_length_phrase + + +@pytest.mark.skipif(NARROW_ONLY, reason="Test cannot verify on python 'narrow' builds") +def test_unfinished_zwj_sequence(): + u""" + Ensure index-out-of-bounds does not occur for zero-width joiner without any following character + """ + phrase = (u"\U0001f469" # Base, Category So, East Asian Width property 'W' -- WOMAN + u"\U0001f3fb" # Modifier, Category Sk, East Asian Width property 'W' -- EMOJI MODIFIER FITZPATRICK TYPE-1-2 + u"\u200d") # Joiner, Category Cf, East Asian Width property 'N' -- ZERO WIDTH JOINER + expect_length_each = (2, 0, 0) + expect_length_phrase = 2 + + # exercise, + length_each = tuple(map(wcwidth.wcwidth, phrase)) + length_phrase = wcwidth.wcswidth(phrase) + + # verify. + assert length_each == expect_length_each + assert length_phrase == expect_length_phrase + + +@pytest.mark.skipif(NARROW_ONLY, reason="Test cannot verify on python 'narrow' builds") +def test_non_recommended_zwj_sequence(): + """ + Verify ZWJ is measured as though successful with characters that cannot be joined, wcwidth does not verify + """ + phrase = (u"\U0001f469" # Base, Category So, East Asian Width property 'W' -- WOMAN + u"\U0001f3fb" # Modifier, Category Sk, East Asian Width property 'W' -- EMOJI MODIFIER FITZPATRICK TYPE-1-2 + u"\u200d") # Joiner, Category Cf, East Asian Width property 'N' -- ZERO WIDTH JOINER + expect_length_each = (2, 0, 0) + expect_length_phrase = 2 + + # exercise, + length_each = tuple(map(wcwidth.wcwidth, phrase)) + length_phrase = wcwidth.wcswidth(phrase) + + # verify. + assert length_each == expect_length_each + assert length_phrase == expect_length_phrase + + +@pytest.mark.skipif(NARROW_ONLY, reason="Test cannot verify on python 'narrow' builds") +def test_another_emoji_zwj_sequence(): + phrase = ( + u"\u26F9" # PERSON WITH BALL + u"\U0001F3FB" # EMOJI MODIFIER FITZPATRICK TYPE-1-2 + u"\u200D" # ZERO WIDTH JOINER + u"\u2640" # FEMALE SIGN + u"\uFE0F") # VARIATION SELECTOR-16 + expect_length_each = (1, 0, 0, 1, 0) + expect_length_phrase = 2 + + # exercise, + length_each = tuple(map(wcwidth.wcwidth, phrase)) + length_phrase = wcwidth.wcswidth(phrase) + + # verify. + assert length_each == expect_length_each + assert length_phrase == expect_length_phrase + + +@pytest.mark.skipif(NARROW_ONLY, reason="Test cannot verify on python 'narrow' builds") +def test_longer_emoji_zwj_sequence(): + """ + A much longer emoji ZWJ sequence of 10 total codepoints is just 2 cells! + + Also test the same sequence in duplicate, verifying multiple VS-16 sequences + in a single function call. + """ + # 'Category Code', 'East Asian Width property' -- 'description' + phrase = (u"\U0001F9D1" # 'So', 'W' -- ADULT + u"\U0001F3FB" # 'Sk', 'W' -- EMOJI MODIFIER FITZPATRICK TYPE-1-2 + u"\u200d" # 'Cf', 'N' -- ZERO WIDTH JOINER + u"\u2764" # 'So', 'N' -- HEAVY BLACK HEART + u"\uFE0F" # 'Mn', 'A' -- VARIATION SELECTOR-16 + u"\u200d" # 'Cf', 'N' -- ZERO WIDTH JOINER + u"\U0001F48B" # 'So', 'W' -- KISS MARK + u"\u200d" # 'Cf', 'N' -- ZERO WIDTH JOINER + u"\U0001F9D1" # 'So', 'W' -- ADULT + u"\U0001F3FD" # 'Sk', 'W' -- EMOJI MODIFIER FITZPATRICK TYPE-4 + ) * 2 + # This test adapted from https://www.unicode.org/L2/L2023/23107-terminal-suppt.pdf + expect_length_each = (2, 0, 0, 1, 0, 0, 2, 0, 2, 0) * 2 + expect_length_phrase = 4 + + # exercise, + length_each = tuple(map(wcwidth.wcwidth, phrase)) + length_phrase = wcwidth.wcswidth(phrase) + + # verify. + assert length_each == expect_length_each + assert length_phrase == expect_length_phrase + + +def read_sequences_from_file(filename): + fp = codecs.open(os.path.join(os.path.dirname(__file__), filename), 'r', encoding='utf-8') + lines = [line.strip() + for line in fp.readlines() + if not line.startswith('#') and line.strip()] + fp.close() + sequences = [make_sequence_from_line(line) for line in lines] + return lines, sequences + + +@pytest.mark.skipif(NARROW_ONLY, reason="Some sequences in text file are not compatible with 'narrow' builds") +def test_recommended_emoji_zwj_sequences(): + """ + Test wcswidth of all of the unicode.org-published emoji-zwj-sequences.txt + """ + # given, + lines, sequences = read_sequences_from_file('emoji-zwj-sequences.txt') + + errors = [] + # Exercise, track by zipping with original text file line, a debugging aide + num = 0 + for sequence, line in zip(sequences, lines): + num += 1 + measured_width = wcwidth.wcswidth(sequence) + if measured_width != 2: + errors.append({ + 'expected_width': 2, + 'line': line, + 'measured_width': measured_width, + 'sequence': sequence, + }) + + # verify + assert errors == [] + assert num >= 1468 + + +def test_recommended_variation_16_sequences(): + """ + Test wcswidth of all of the unicode.org-published emoji-variation-sequences.txt + """ + # given, + lines, sequences = read_sequences_from_file('emoji-variation-sequences.txt') + + errors = [] + num = 0 + for sequence, line in zip(sequences, lines): + num += 1 + if '\ufe0f' not in sequence: + # filter for only \uFE0F (VS-16) + continue + measured_width = wcwidth.wcswidth(sequence) + if measured_width != 2: + errors.append({ + 'expected_width': 2, + 'line': line, + 'measured_width': wcwidth.wcswidth(sequence), + 'sequence': sequence, + }) + + # verify + assert errors == [] + assert num >= 742 + + +def test_unicode_9_vs16(): + """Verify effect of VS-16 on unicode_version 9.0 and later""" + phrase = (u"\u2640" # FEMALE SIGN + u"\uFE0F") # VARIATION SELECTOR-16 + + expect_length_each = (1, 0) + expect_length_phrase = 2 + + # exercise, + length_each = tuple(wcwidth.wcwidth(w_char, unicode_version='9.0') for w_char in phrase) + length_phrase = wcwidth.wcswidth(phrase, unicode_version='9.0') + + # verify. + assert length_each == expect_length_each + assert length_phrase == expect_length_phrase + +def test_unicode_8_vs16(): + """Verify that VS-16 has no effect on unicode_version 8.0 and earler""" + phrase = (u"\u2640" # FEMALE SIGN + u"\uFE0F") # VARIATION SELECTOR-16 + + expect_length_each = (1, 0) + expect_length_phrase = 1 + + # exercise, + length_each = tuple(wcwidth.wcwidth(w_char, unicode_version='8.0') for w_char in phrase) + length_phrase = wcwidth.wcswidth(phrase, unicode_version='8.0') + + # verify. + assert length_each == expect_length_each + assert length_phrase == expect_length_phrase
\ No newline at end of file diff --git a/contrib/python/wcwidth/py2/wcwidth/__init__.py b/contrib/python/wcwidth/py2/wcwidth/__init__.py index ec554c383d..40eedb6d22 100644 --- a/contrib/python/wcwidth/py2/wcwidth/__init__.py +++ b/contrib/python/wcwidth/py2/wcwidth/__init__.py @@ -1,5 +1,5 @@ """ -wcwidth module. +Wcwidth module. https://github.com/jquast/wcwidth """ @@ -11,6 +11,7 @@ https://github.com/jquast/wcwidth # local from .wcwidth import ZERO_WIDTH # noqa from .wcwidth import (WIDE_EASTASIAN, + VS16_NARROW_TO_WIDE, wcwidth, wcswidth, _bisearch, @@ -25,4 +26,4 @@ __all__ = ('wcwidth', 'wcswidth', 'list_versions') # We also used pkg_resources to load unicode version tables from version.json, # generated by bin/update-tables.py, but some environments are unable to # import pkg_resources for one reason or another, yikes! -__version__ = '0.2.6' +__version__ = '0.2.12' diff --git a/contrib/python/wcwidth/py2/wcwidth/table_vs16.py b/contrib/python/wcwidth/py2/wcwidth/table_vs16.py new file mode 100644 index 0000000000..3249262d98 --- /dev/null +++ b/contrib/python/wcwidth/py2/wcwidth/table_vs16.py @@ -0,0 +1,125 @@ +""" +Exports VS16_NARROW_TO_WIDE table keyed by supporting unicode version level. + +This code generated by wcwidth/bin/update-tables.py on 2023-11-07 16:43:49 UTC. +""" +VS16_NARROW_TO_WIDE = { + '9.0.0': ( + # Source: 9.0.0 + # Date: 2023-02-01, 02:22:54 GMT + # + (0x00023, 0x00023,), # Number Sign + (0x0002a, 0x0002a,), # Asterisk + (0x00030, 0x00039,), # Digit Zero ..Digit Nine + (0x000a9, 0x000a9,), # Copyright Sign + (0x000ae, 0x000ae,), # Registered Sign + (0x0203c, 0x0203c,), # Double Exclamation Mark + (0x02049, 0x02049,), # Exclamation Question Mark + (0x02122, 0x02122,), # Trade Mark Sign + (0x02139, 0x02139,), # Information Source + (0x02194, 0x02199,), # Left Right Arrow ..South West Arrow + (0x021a9, 0x021aa,), # Leftwards Arrow With Hoo..Rightwards Arrow With Ho + (0x02328, 0x02328,), # Keyboard + (0x023cf, 0x023cf,), # Eject Symbol + (0x023ed, 0x023ef,), # Black Right-pointing Dou..Black Right-pointing Tri + (0x023f1, 0x023f2,), # Stopwatch ..Timer Clock + (0x023f8, 0x023fa,), # Double Vertical Bar ..Black Circle For Record + (0x024c2, 0x024c2,), # Circled Latin Capital Letter M + (0x025aa, 0x025ab,), # Black Small Square ..White Small Square + (0x025b6, 0x025b6,), # Black Right-pointing Triangle + (0x025c0, 0x025c0,), # Black Left-pointing Triangle + (0x025fb, 0x025fc,), # White Medium Square ..Black Medium Square + (0x02600, 0x02604,), # Black Sun With Rays ..Comet + (0x0260e, 0x0260e,), # Black Telephone + (0x02611, 0x02611,), # Ballot Box With Check + (0x02618, 0x02618,), # Shamrock + (0x0261d, 0x0261d,), # White Up Pointing Index + (0x02620, 0x02620,), # Skull And Crossbones + (0x02622, 0x02623,), # Radioactive Sign ..Biohazard Sign + (0x02626, 0x02626,), # Orthodox Cross + (0x0262a, 0x0262a,), # Star And Crescent + (0x0262e, 0x0262f,), # Peace Symbol ..Yin Yang + (0x02638, 0x0263a,), # Wheel Of Dharma ..White Smiling Face + (0x02640, 0x02640,), # Female Sign + (0x02642, 0x02642,), # Male Sign + (0x0265f, 0x02660,), # Black Chess Pawn ..Black Spade Suit + (0x02663, 0x02663,), # Black Club Suit + (0x02665, 0x02666,), # Black Heart Suit ..Black Diamond Suit + (0x02668, 0x02668,), # Hot Springs + (0x0267b, 0x0267b,), # Black Universal Recycling Symbol + (0x0267e, 0x0267e,), # Permanent Paper Sign + (0x02692, 0x02692,), # Hammer And Pick + (0x02694, 0x02697,), # Crossed Swords ..Alembic + (0x02699, 0x02699,), # Gear + (0x0269b, 0x0269c,), # Atom Symbol ..Fleur-de-lis + (0x026a0, 0x026a0,), # Warning Sign + (0x026a7, 0x026a7,), # Male With Stroke And Male And Female Sign + (0x026b0, 0x026b1,), # Coffin ..Funeral Urn + (0x026c8, 0x026c8,), # Thunder Cloud And Rain + (0x026cf, 0x026cf,), # Pick + (0x026d1, 0x026d1,), # Helmet With White Cross + (0x026d3, 0x026d3,), # Chains + (0x026e9, 0x026e9,), # Shinto Shrine + (0x026f0, 0x026f1,), # Mountain ..Umbrella On Ground + (0x026f4, 0x026f4,), # Ferry + (0x026f7, 0x026f9,), # Skier ..Person With Ball + (0x02702, 0x02702,), # Black Scissors + (0x02708, 0x02709,), # Airplane ..Envelope + (0x0270c, 0x0270d,), # Victory Hand ..Writing Hand + (0x0270f, 0x0270f,), # Pencil + (0x02712, 0x02712,), # Black Nib + (0x02714, 0x02714,), # Heavy Check Mark + (0x02716, 0x02716,), # Heavy Multiplication X + (0x0271d, 0x0271d,), # Latin Cross + (0x02721, 0x02721,), # Star Of David + (0x02733, 0x02734,), # Eight Spoked Asterisk ..Eight Pointed Black Star + (0x02744, 0x02744,), # Snowflake + (0x02747, 0x02747,), # Sparkle + (0x02763, 0x02764,), # Heavy Heart Exclamation ..Heavy Black Heart + (0x027a1, 0x027a1,), # Black Rightwards Arrow + (0x02934, 0x02935,), # Arrow Pointing Rightward..Arrow Pointing Rightward + (0x02b05, 0x02b07,), # Leftwards Black Arrow ..Downwards Black Arrow + (0x1f170, 0x1f171,), # Negative Squared Latin C..Negative Squared Latin C + (0x1f17e, 0x1f17f,), # Negative Squared Latin C..Negative Squared Latin C + (0x1f321, 0x1f321,), # Thermometer + (0x1f324, 0x1f32c,), # White Sun With Small Clo..Wind Blowing Face + (0x1f336, 0x1f336,), # Hot Pepper + (0x1f37d, 0x1f37d,), # Fork And Knife With Plate + (0x1f396, 0x1f397,), # Military Medal ..Reminder Ribbon + (0x1f399, 0x1f39b,), # Studio Microphone ..Control Knobs + (0x1f39e, 0x1f39f,), # Film Frames ..Admission Tickets + (0x1f3cb, 0x1f3ce,), # Weight Lifter ..Racing Car + (0x1f3d4, 0x1f3df,), # Snow Capped Mountain ..Stadium + (0x1f3f3, 0x1f3f3,), # Waving White Flag + (0x1f3f5, 0x1f3f5,), # Rosette + (0x1f3f7, 0x1f3f7,), # Label + (0x1f43f, 0x1f43f,), # Chipmunk + (0x1f441, 0x1f441,), # Eye + (0x1f4fd, 0x1f4fd,), # Film Projector + (0x1f549, 0x1f54a,), # Om Symbol ..Dove Of Peace + (0x1f56f, 0x1f570,), # Candle ..Mantelpiece Clock + (0x1f573, 0x1f579,), # Hole ..Joystick + (0x1f587, 0x1f587,), # Linked Paperclips + (0x1f58a, 0x1f58d,), # Lower Left Ballpoint Pen..Lower Left Crayon + (0x1f590, 0x1f590,), # Raised Hand With Fingers Splayed + (0x1f5a5, 0x1f5a5,), # Desktop Computer + (0x1f5a8, 0x1f5a8,), # Printer + (0x1f5b1, 0x1f5b2,), # Three Button Mouse ..Trackball + (0x1f5bc, 0x1f5bc,), # Frame With Picture + (0x1f5c2, 0x1f5c4,), # Card Index Dividers ..File Cabinet + (0x1f5d1, 0x1f5d3,), # Wastebasket ..Spiral Calendar Pad + (0x1f5dc, 0x1f5de,), # Compression ..Rolled-up Newspaper + (0x1f5e1, 0x1f5e1,), # Dagger Knife + (0x1f5e3, 0x1f5e3,), # Speaking Head In Silhouette + (0x1f5e8, 0x1f5e8,), # Left Speech Bubble + (0x1f5ef, 0x1f5ef,), # Right Anger Bubble + (0x1f5f3, 0x1f5f3,), # Ballot Box With Ballot + (0x1f5fa, 0x1f5fa,), # World Map + (0x1f6cb, 0x1f6cb,), # Couch And Lamp + (0x1f6cd, 0x1f6cf,), # Shopping Bags ..Bed + (0x1f6e0, 0x1f6e5,), # Hammer And Wrench ..Motor Boat + (0x1f6e9, 0x1f6e9,), # Small Airplane + (0x1f6f0, 0x1f6f0,), # Satellite + (0x1f6f3, 0x1f6f3,), # Passenger Ship + ), +} diff --git a/contrib/python/wcwidth/py2/wcwidth/table_wide.py b/contrib/python/wcwidth/py2/wcwidth/table_wide.py index 9f8cd0a845..02afd5c2b7 100644 --- a/contrib/python/wcwidth/py2/wcwidth/table_wide.py +++ b/contrib/python/wcwidth/py2/wcwidth/table_wide.py @@ -1,7 +1,7 @@ """ Exports WIDE_EASTASIAN table keyed by supporting unicode version level. -This code generated by wcwidth/bin/update-tables.py on 2023-01-14 03:25:41 UTC. +This code generated by wcwidth/bin/update-tables.py on 2023-09-14 15:45:33 UTC. """ WIDE_EASTASIAN = { '4.1.0': ( @@ -1299,9 +1299,9 @@ WIDE_EASTASIAN = { (0x1aff5, 0x1affb,), # Katakana Letter Minnan T..Katakana Letter Minnan N (0x1affd, 0x1affe,), # Katakana Letter Minnan N..Katakana Letter Minnan N (0x1b000, 0x1b122,), # Katakana Letter Archaic ..Katakana Letter Archaic - (0x1b132, 0x1b132,), # (nil) + (0x1b132, 0x1b132,), # Hiragana Letter Small Ko (0x1b150, 0x1b152,), # Hiragana Letter Small Wi..Hiragana Letter Small Wo - (0x1b155, 0x1b155,), # (nil) + (0x1b155, 0x1b155,), # Katakana Letter Small Ko (0x1b164, 0x1b167,), # Katakana Letter Small Wi..Katakana Letter Small N (0x1b170, 0x1b2fb,), # Nushu Character-1b170 ..Nushu Character-1b2fb (0x1f004, 0x1f004,), # Mahjong Tile Red Dragon @@ -1335,7 +1335,7 @@ WIDE_EASTASIAN = { (0x1f6cc, 0x1f6cc,), # Sleeping Accommodation (0x1f6d0, 0x1f6d2,), # Place Of Worship ..Shopping Trolley (0x1f6d5, 0x1f6d7,), # Hindu Temple ..Elevator - (0x1f6dc, 0x1f6df,), # (nil) ..Ring Buoy + (0x1f6dc, 0x1f6df,), # Wireless ..Ring Buoy (0x1f6eb, 0x1f6ec,), # Airplane Departure ..Airplane Arriving (0x1f6f4, 0x1f6fc,), # Scooter ..Roller Skate (0x1f7e0, 0x1f7eb,), # Large Orange Circle ..Large Brown Square @@ -1344,12 +1344,137 @@ WIDE_EASTASIAN = { (0x1f93c, 0x1f945,), # Wrestlers ..Goal Net (0x1f947, 0x1f9ff,), # First Place Medal ..Nazar Amulet (0x1fa70, 0x1fa7c,), # Ballet Shoes ..Crutch - (0x1fa80, 0x1fa88,), # Yo-yo ..(nil) - (0x1fa90, 0x1fabd,), # Ringed Planet ..(nil) - (0x1fabf, 0x1fac5,), # (nil) ..Person With Crown - (0x1face, 0x1fadb,), # (nil) - (0x1fae0, 0x1fae8,), # Melting Face ..(nil) - (0x1faf0, 0x1faf8,), # Hand With Index Finger A..(nil) + (0x1fa80, 0x1fa88,), # Yo-yo ..Flute + (0x1fa90, 0x1fabd,), # Ringed Planet ..Wing + (0x1fabf, 0x1fac5,), # Goose ..Person With Crown + (0x1face, 0x1fadb,), # Moose ..Pea Pod + (0x1fae0, 0x1fae8,), # Melting Face ..Shaking Face + (0x1faf0, 0x1faf8,), # Hand With Index Finger A..Rightwards Pushing Hand + (0x20000, 0x2fffd,), # Cjk Unified Ideograph-20..(nil) + (0x30000, 0x3fffd,), # Cjk Unified Ideograph-30..(nil) + ), + '15.1.0': ( + # Source: EastAsianWidth-15.1.0.txt + # Date: 2023-07-28, 23:34:08 GMT + # + (0x01100, 0x0115f,), # Hangul Choseong Kiyeok ..Hangul Choseong Filler + (0x0231a, 0x0231b,), # Watch ..Hourglass + (0x02329, 0x0232a,), # Left-pointing Angle Brac..Right-pointing Angle Bra + (0x023e9, 0x023ec,), # Black Right-pointing Dou..Black Down-pointing Doub + (0x023f0, 0x023f0,), # Alarm Clock + (0x023f3, 0x023f3,), # Hourglass With Flowing Sand + (0x025fd, 0x025fe,), # White Medium Small Squar..Black Medium Small Squar + (0x02614, 0x02615,), # Umbrella With Rain Drops..Hot Beverage + (0x02648, 0x02653,), # Aries ..Pisces + (0x0267f, 0x0267f,), # Wheelchair Symbol + (0x02693, 0x02693,), # Anchor + (0x026a1, 0x026a1,), # High Voltage Sign + (0x026aa, 0x026ab,), # Medium White Circle ..Medium Black Circle + (0x026bd, 0x026be,), # Soccer Ball ..Baseball + (0x026c4, 0x026c5,), # Snowman Without Snow ..Sun Behind Cloud + (0x026ce, 0x026ce,), # Ophiuchus + (0x026d4, 0x026d4,), # No Entry + (0x026ea, 0x026ea,), # Church + (0x026f2, 0x026f3,), # Fountain ..Flag In Hole + (0x026f5, 0x026f5,), # Sailboat + (0x026fa, 0x026fa,), # Tent + (0x026fd, 0x026fd,), # Fuel Pump + (0x02705, 0x02705,), # White Heavy Check Mark + (0x0270a, 0x0270b,), # Raised Fist ..Raised Hand + (0x02728, 0x02728,), # Sparkles + (0x0274c, 0x0274c,), # Cross Mark + (0x0274e, 0x0274e,), # Negative Squared Cross Mark + (0x02753, 0x02755,), # Black Question Mark Orna..White Exclamation Mark O + (0x02757, 0x02757,), # Heavy Exclamation Mark Symbol + (0x02795, 0x02797,), # Heavy Plus Sign ..Heavy Division Sign + (0x027b0, 0x027b0,), # Curly Loop + (0x027bf, 0x027bf,), # Double Curly Loop + (0x02b1b, 0x02b1c,), # Black Large Square ..White Large Square + (0x02b50, 0x02b50,), # White Medium Star + (0x02b55, 0x02b55,), # Heavy Large Circle + (0x02e80, 0x02e99,), # Cjk Radical Repeat ..Cjk Radical Rap + (0x02e9b, 0x02ef3,), # Cjk Radical Choke ..Cjk Radical C-simplified + (0x02f00, 0x02fd5,), # Kangxi Radical One ..Kangxi Radical Flute + (0x02ff0, 0x0303e,), # Ideographic Description ..Ideographic Variation In + (0x03041, 0x03096,), # Hiragana Letter Small A ..Hiragana Letter Small Ke + (0x03099, 0x030ff,), # Combining Katakana-hirag..Katakana Digraph Koto + (0x03105, 0x0312f,), # Bopomofo Letter B ..Bopomofo Letter Nn + (0x03131, 0x0318e,), # Hangul Letter Kiyeok ..Hangul Letter Araeae + (0x03190, 0x031e3,), # Ideographic Annotation L..Cjk Stroke Q + (0x031ef, 0x0321e,), # (nil) ..Parenthesized Korean Cha + (0x03220, 0x03247,), # Parenthesized Ideograph ..Circled Ideograph Koto + (0x03250, 0x04dbf,), # Partnership Sign ..Cjk Unified Ideograph-4d + (0x04e00, 0x0a48c,), # Cjk Unified Ideograph-4e..Yi Syllable Yyr + (0x0a490, 0x0a4c6,), # Yi Radical Qot ..Yi Radical Ke + (0x0a960, 0x0a97c,), # Hangul Choseong Tikeut-m..Hangul Choseong Ssangyeo + (0x0ac00, 0x0d7a3,), # Hangul Syllable Ga ..Hangul Syllable Hih + (0x0f900, 0x0faff,), # Cjk Compatibility Ideogr..(nil) + (0x0fe10, 0x0fe19,), # Presentation Form For Ve..Presentation Form For Ve + (0x0fe30, 0x0fe52,), # Presentation Form For Ve..Small Full Stop + (0x0fe54, 0x0fe66,), # Small Semicolon ..Small Equals Sign + (0x0fe68, 0x0fe6b,), # Small Reverse Solidus ..Small Commercial At + (0x0ff01, 0x0ff60,), # Fullwidth Exclamation Ma..Fullwidth Right White Pa + (0x0ffe0, 0x0ffe6,), # Fullwidth Cent Sign ..Fullwidth Won Sign + (0x16fe0, 0x16fe4,), # Tangut Iteration Mark ..Khitan Small Script Fill + (0x16ff0, 0x16ff1,), # Vietnamese Alternate Rea..Vietnamese Alternate Rea + (0x17000, 0x187f7,), # (nil) + (0x18800, 0x18cd5,), # Tangut Component-001 ..Khitan Small Script Char + (0x18d00, 0x18d08,), # (nil) + (0x1aff0, 0x1aff3,), # Katakana Letter Minnan T..Katakana Letter Minnan T + (0x1aff5, 0x1affb,), # Katakana Letter Minnan T..Katakana Letter Minnan N + (0x1affd, 0x1affe,), # Katakana Letter Minnan N..Katakana Letter Minnan N + (0x1b000, 0x1b122,), # Katakana Letter Archaic ..Katakana Letter Archaic + (0x1b132, 0x1b132,), # Hiragana Letter Small Ko + (0x1b150, 0x1b152,), # Hiragana Letter Small Wi..Hiragana Letter Small Wo + (0x1b155, 0x1b155,), # Katakana Letter Small Ko + (0x1b164, 0x1b167,), # Katakana Letter Small Wi..Katakana Letter Small N + (0x1b170, 0x1b2fb,), # Nushu Character-1b170 ..Nushu Character-1b2fb + (0x1f004, 0x1f004,), # Mahjong Tile Red Dragon + (0x1f0cf, 0x1f0cf,), # Playing Card Black Joker + (0x1f18e, 0x1f18e,), # Negative Squared Ab + (0x1f191, 0x1f19a,), # Squared Cl ..Squared Vs + (0x1f200, 0x1f202,), # Square Hiragana Hoka ..Squared Katakana Sa + (0x1f210, 0x1f23b,), # Squared Cjk Unified Ideo..Squared Cjk Unified Ideo + (0x1f240, 0x1f248,), # Tortoise Shell Bracketed..Tortoise Shell Bracketed + (0x1f250, 0x1f251,), # Circled Ideograph Advant..Circled Ideograph Accept + (0x1f260, 0x1f265,), # Rounded Symbol For Fu ..Rounded Symbol For Cai + (0x1f300, 0x1f320,), # Cyclone ..Shooting Star + (0x1f32d, 0x1f335,), # Hot Dog ..Cactus + (0x1f337, 0x1f37c,), # Tulip ..Baby Bottle + (0x1f37e, 0x1f393,), # Bottle With Popping Cork..Graduation Cap + (0x1f3a0, 0x1f3ca,), # Carousel Horse ..Swimmer + (0x1f3cf, 0x1f3d3,), # Cricket Bat And Ball ..Table Tennis Paddle And + (0x1f3e0, 0x1f3f0,), # House Building ..European Castle + (0x1f3f4, 0x1f3f4,), # Waving Black Flag + (0x1f3f8, 0x1f43e,), # Badminton Racquet And Sh..Paw Prints + (0x1f440, 0x1f440,), # Eyes + (0x1f442, 0x1f4fc,), # Ear ..Videocassette + (0x1f4ff, 0x1f53d,), # Prayer Beads ..Down-pointing Small Red + (0x1f54b, 0x1f54e,), # Kaaba ..Menorah With Nine Branch + (0x1f550, 0x1f567,), # Clock Face One Oclock ..Clock Face Twelve-thirty + (0x1f57a, 0x1f57a,), # Man Dancing + (0x1f595, 0x1f596,), # Reversed Hand With Middl..Raised Hand With Part Be + (0x1f5a4, 0x1f5a4,), # Black Heart + (0x1f5fb, 0x1f64f,), # Mount Fuji ..Person With Folded Hands + (0x1f680, 0x1f6c5,), # Rocket ..Left Luggage + (0x1f6cc, 0x1f6cc,), # Sleeping Accommodation + (0x1f6d0, 0x1f6d2,), # Place Of Worship ..Shopping Trolley + (0x1f6d5, 0x1f6d7,), # Hindu Temple ..Elevator + (0x1f6dc, 0x1f6df,), # Wireless ..Ring Buoy + (0x1f6eb, 0x1f6ec,), # Airplane Departure ..Airplane Arriving + (0x1f6f4, 0x1f6fc,), # Scooter ..Roller Skate + (0x1f7e0, 0x1f7eb,), # Large Orange Circle ..Large Brown Square + (0x1f7f0, 0x1f7f0,), # Heavy Equals Sign + (0x1f90c, 0x1f93a,), # Pinched Fingers ..Fencer + (0x1f93c, 0x1f945,), # Wrestlers ..Goal Net + (0x1f947, 0x1f9ff,), # First Place Medal ..Nazar Amulet + (0x1fa70, 0x1fa7c,), # Ballet Shoes ..Crutch + (0x1fa80, 0x1fa88,), # Yo-yo ..Flute + (0x1fa90, 0x1fabd,), # Ringed Planet ..Wing + (0x1fabf, 0x1fac5,), # Goose ..Person With Crown + (0x1face, 0x1fadb,), # Moose ..Pea Pod + (0x1fae0, 0x1fae8,), # Melting Face ..Shaking Face + (0x1faf0, 0x1faf8,), # Hand With Index Finger A..Rightwards Pushing Hand (0x20000, 0x2fffd,), # Cjk Unified Ideograph-20..(nil) (0x30000, 0x3fffd,), # Cjk Unified Ideograph-30..(nil) ), diff --git a/contrib/python/wcwidth/py2/wcwidth/table_zero.py b/contrib/python/wcwidth/py2/wcwidth/table_zero.py index a4abaea192..67261fd659 100644 --- a/contrib/python/wcwidth/py2/wcwidth/table_zero.py +++ b/contrib/python/wcwidth/py2/wcwidth/table_zero.py @@ -1,13 +1,15 @@ """ Exports ZERO_WIDTH table keyed by supporting unicode version level. -This code generated by wcwidth/bin/update-tables.py on 2023-01-14 03:25:41 UTC. +This code generated by wcwidth/bin/update-tables.py on 2023-10-19 20:57:31 UTC. """ ZERO_WIDTH = { '4.1.0': ( # Source: DerivedGeneralCategory-4.1.0.txt # Date: 2005-02-26, 02:35:50 GMT [MD] # + (0x00000, 0x00000,), # (nil) + (0x000ad, 0x000ad,), # Soft Hyphen (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le (0x00483, 0x00486,), # Combining Cyrillic Titlo..Combining Cyrillic Psili (0x00488, 0x00489,), # Combining Cyrillic Hundr..Combining Cyrillic Milli @@ -17,61 +19,74 @@ ZERO_WIDTH = { (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot (0x005c7, 0x005c7,), # Hebrew Point Qamats Qatan + (0x00600, 0x00603,), # Arabic Number Sign ..Arabic Sign Safha (0x00610, 0x00615,), # Arabic Sign Sallallahou ..Arabic Small High Tah (0x0064b, 0x0065e,), # Arabic Fathatan ..Arabic Fatha With Two Do (0x00670, 0x00670,), # Arabic Letter Superscript Alef - (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen - (0x006de, 0x006e4,), # Arabic Start Of Rub El H..Arabic Small High Madda + (0x006d6, 0x006e4,), # Arabic Small High Ligatu..Arabic Small High Madda (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x0070f, 0x0070f,), # Syriac Abbreviation Mark (0x00711, 0x00711,), # Syriac Letter Superscript Alaph (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun - (0x00901, 0x00902,), # Devanagari Sign Candrabi..Devanagari Sign Anusvara + (0x00901, 0x00903,), # Devanagari Sign Candrabi..Devanagari Sign Visarga (0x0093c, 0x0093c,), # Devanagari Sign Nukta - (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai - (0x0094d, 0x0094d,), # Devanagari Sign Virama + (0x0093e, 0x0094d,), # Devanagari Vowel Sign Aa..Devanagari Sign Virama (0x00951, 0x00954,), # Devanagari Stress Sign U..Devanagari Acute Accent (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo - (0x00981, 0x00981,), # Bengali Sign Candrabindu + (0x00981, 0x00983,), # Bengali Sign Candrabindu..Bengali Sign Visarga (0x009bc, 0x009bc,), # Bengali Sign Nukta - (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal - (0x009cd, 0x009cd,), # Bengali Sign Virama + (0x009be, 0x009c4,), # Bengali Vowel Sign Aa ..Bengali Vowel Sign Vocal + (0x009c7, 0x009c8,), # Bengali Vowel Sign E ..Bengali Vowel Sign Ai + (0x009cb, 0x009cd,), # Bengali Vowel Sign O ..Bengali Sign Virama + (0x009d7, 0x009d7,), # Bengali Au Length Mark (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal - (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a01, 0x00a03,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Visarga (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta - (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a3e, 0x00a42,), # Gurmukhi Vowel Sign Aa ..Gurmukhi Vowel Sign Uu (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak - (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00a81, 0x00a83,), # Gujarati Sign Candrabind..Gujarati Sign Visarga (0x00abc, 0x00abc,), # Gujarati Sign Nukta - (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand - (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai - (0x00acd, 0x00acd,), # Gujarati Sign Virama + (0x00abe, 0x00ac5,), # Gujarati Vowel Sign Aa ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac9,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Cand + (0x00acb, 0x00acd,), # Gujarati Vowel Sign O ..Gujarati Sign Virama (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca - (0x00b01, 0x00b01,), # Oriya Sign Candrabindu + (0x00b01, 0x00b03,), # Oriya Sign Candrabindu ..Oriya Sign Visarga (0x00b3c, 0x00b3c,), # Oriya Sign Nukta - (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I - (0x00b41, 0x00b43,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic - (0x00b4d, 0x00b4d,), # Oriya Sign Virama - (0x00b56, 0x00b56,), # Oriya Ai Length Mark + (0x00b3e, 0x00b43,), # Oriya Vowel Sign Aa ..Oriya Vowel Sign Vocalic + (0x00b47, 0x00b48,), # Oriya Vowel Sign E ..Oriya Vowel Sign Ai + (0x00b4b, 0x00b4d,), # Oriya Vowel Sign O ..Oriya Sign Virama + (0x00b56, 0x00b57,), # Oriya Ai Length Mark ..Oriya Au Length Mark (0x00b82, 0x00b82,), # Tamil Sign Anusvara - (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii - (0x00bcd, 0x00bcd,), # Tamil Sign Virama - (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00bbe, 0x00bc2,), # Tamil Vowel Sign Aa ..Tamil Vowel Sign Uu + (0x00bc6, 0x00bc8,), # Tamil Vowel Sign E ..Tamil Vowel Sign Ai + (0x00bca, 0x00bcd,), # Tamil Vowel Sign O ..Tamil Sign Virama + (0x00bd7, 0x00bd7,), # Tamil Au Length Mark + (0x00c01, 0x00c03,), # Telugu Sign Candrabindu ..Telugu Sign Visarga + (0x00c3e, 0x00c44,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Vocali (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark + (0x00c82, 0x00c83,), # Kannada Sign Anusvara ..Kannada Sign Visarga (0x00cbc, 0x00cbc,), # Kannada Sign Nukta - (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I - (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E - (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama - (0x00d41, 0x00d43,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc - (0x00d4d, 0x00d4d,), # Malayalam Sign Virama + (0x00cbe, 0x00cc4,), # Kannada Vowel Sign Aa ..Kannada Vowel Sign Vocal + (0x00cc6, 0x00cc8,), # Kannada Vowel Sign E ..Kannada Vowel Sign Ai + (0x00cca, 0x00ccd,), # Kannada Vowel Sign O ..Kannada Sign Virama + (0x00cd5, 0x00cd6,), # Kannada Length Mark ..Kannada Ai Length Mark + (0x00d02, 0x00d03,), # Malayalam Sign Anusvara ..Malayalam Sign Visarga + (0x00d3e, 0x00d43,), # Malayalam Vowel Sign Aa ..Malayalam Vowel Sign Voc + (0x00d46, 0x00d48,), # Malayalam Vowel Sign E ..Malayalam Vowel Sign Ai + (0x00d4a, 0x00d4d,), # Malayalam Vowel Sign O ..Malayalam Sign Virama + (0x00d57, 0x00d57,), # Malayalam Au Length Mark + (0x00d82, 0x00d83,), # Sinhala Sign Anusvaraya ..Sinhala Sign Visargaya (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna - (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dcf, 0x00dd4,), # Sinhala Vowel Sign Aela-..Sinhala Vowel Sign Ketti (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga Paa-pilla + (0x00dd8, 0x00ddf,), # Sinhala Vowel Sign Gaett..Sinhala Vowel Sign Gayan + (0x00df2, 0x00df3,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga (0x00e31, 0x00e31,), # Thai Character Mai Han-akat (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan @@ -83,59 +98,66 @@ ZERO_WIDTH = { (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung Nyi Zla (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung Sgor Rtags (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru - (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga - (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f3e, 0x00f3f,), # Tibetan Sign Yar Tshes ..Tibetan Sign Mar Tshes + (0x00f71, 0x00f84,), # Tibetan Vowel Sign Aa ..Tibetan Mark Halanta (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags (0x00f90, 0x00f97,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gdan - (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu - (0x01032, 0x01032,), # Myanmar Vowel Sign Ai - (0x01036, 0x01037,), # Myanmar Sign Anusvara ..Myanmar Sign Dot Below - (0x01039, 0x01039,), # Myanmar Sign Virama - (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0102c, 0x01032,), # Myanmar Vowel Sign Aa ..Myanmar Vowel Sign Ai + (0x01036, 0x01039,), # Myanmar Sign Anusvara ..Myanmar Sign Virama + (0x01056, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal (0x0135f, 0x0135f,), # Ethiopic Combining Gemination Mark (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U - (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua - (0x017c6, 0x017c6,), # Khmer Sign Nikahit - (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017b4, 0x017d3,), # Khmer Vowel Inherent Aq ..Khmer Sign Bathamasat (0x017dd, 0x017dd,), # Khmer Sign Atthacan (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation (0x018a9, 0x018a9,), # Mongolian Letter Ali Gali Dagalga - (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U - (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O - (0x01932, 0x01932,), # Limbu Small Letter Anusvara - (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i - (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U + (0x01920, 0x0192b,), # Limbu Vowel Sign A ..Limbu Subjoined Letter W + (0x01930, 0x0193b,), # Limbu Small Letter Ka ..Limbu Sign Sa-i + (0x019b0, 0x019c0,), # New Tai Lue Vowel Sign V..New Tai Lue Vowel Sign I + (0x019c8, 0x019c9,), # New Tai Lue Tone Mark-1 ..New Tai Lue Tone Mark-2 + (0x01a17, 0x01a1b,), # Buginese Vowel Sign I ..Buginese Vowel Sign Ae (0x01dc0, 0x01dc3,), # Combining Dotted Grave A..Combining Suspension Mar + (0x0200b, 0x0200f,), # Zero Width Space ..Right-to-left Mark + (0x02028, 0x0202e,), # Line Separator ..Right-to-left Override + (0x02060, 0x02063,), # Word Joiner ..Invisible Separator + (0x0206a, 0x0206f,), # Inhibit Symmetric Swappi..Nominal Digit Shapes (0x020d0, 0x020eb,), # Combining Left Harpoon A..Combining Long Double So (0x0302a, 0x0302f,), # Ideographic Level Tone M..Hangul Double Dot Tone M (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag + (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisvara (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasanta (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusvara - (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a823, 0x0a827,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spanish Varika (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 (0x0fe20, 0x0fe23,), # Combining Ligature Left ..Combining Double Tilde R + (0x0feff, 0x0feff,), # Zero Width No-break Space + (0x0fff9, 0x0fffb,), # Interlinear Annotation A..Interlinear Annotation T (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo (0x10a3f, 0x10a3f,), # Kharoshthi Virama - (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining - (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d165, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d16d, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0xe0001, 0xe0001,), # Language Tag + (0xe0020, 0xe007f,), # Tag Space ..Cancel Tag (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 ), '5.0.0': ( # Source: DerivedGeneralCategory-5.0.0.txt # Date: 2006-02-27, 23:41:27 GMT [MD] # + (0x00000, 0x00000,), # (nil) + (0x000ad, 0x000ad,), # Soft Hyphen (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le (0x00483, 0x00486,), # Combining Cyrillic Titlo..Combining Cyrillic Psili (0x00488, 0x00489,), # Combining Cyrillic Hundr..Combining Cyrillic Milli @@ -144,63 +166,76 @@ ZERO_WIDTH = { (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot (0x005c7, 0x005c7,), # Hebrew Point Qamats Qatan + (0x00600, 0x00603,), # Arabic Number Sign ..Arabic Sign Safha (0x00610, 0x00615,), # Arabic Sign Sallallahou ..Arabic Small High Tah (0x0064b, 0x0065e,), # Arabic Fathatan ..Arabic Fatha With Two Do (0x00670, 0x00670,), # Arabic Letter Superscript Alef - (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen - (0x006de, 0x006e4,), # Arabic Start Of Rub El H..Arabic Small High Madda + (0x006d6, 0x006e4,), # Arabic Small High Ligatu..Arabic Small High Madda (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x0070f, 0x0070f,), # Syriac Abbreviation Mark (0x00711, 0x00711,), # Syriac Letter Superscript Alaph (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun (0x007eb, 0x007f3,), # Nko Combining Short High..Nko Combining Double Dot - (0x00901, 0x00902,), # Devanagari Sign Candrabi..Devanagari Sign Anusvara + (0x00901, 0x00903,), # Devanagari Sign Candrabi..Devanagari Sign Visarga (0x0093c, 0x0093c,), # Devanagari Sign Nukta - (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai - (0x0094d, 0x0094d,), # Devanagari Sign Virama + (0x0093e, 0x0094d,), # Devanagari Vowel Sign Aa..Devanagari Sign Virama (0x00951, 0x00954,), # Devanagari Stress Sign U..Devanagari Acute Accent (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo - (0x00981, 0x00981,), # Bengali Sign Candrabindu + (0x00981, 0x00983,), # Bengali Sign Candrabindu..Bengali Sign Visarga (0x009bc, 0x009bc,), # Bengali Sign Nukta - (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal - (0x009cd, 0x009cd,), # Bengali Sign Virama + (0x009be, 0x009c4,), # Bengali Vowel Sign Aa ..Bengali Vowel Sign Vocal + (0x009c7, 0x009c8,), # Bengali Vowel Sign E ..Bengali Vowel Sign Ai + (0x009cb, 0x009cd,), # Bengali Vowel Sign O ..Bengali Sign Virama + (0x009d7, 0x009d7,), # Bengali Au Length Mark (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal - (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a01, 0x00a03,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Visarga (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta - (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a3e, 0x00a42,), # Gurmukhi Vowel Sign Aa ..Gurmukhi Vowel Sign Uu (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak - (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00a81, 0x00a83,), # Gujarati Sign Candrabind..Gujarati Sign Visarga (0x00abc, 0x00abc,), # Gujarati Sign Nukta - (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand - (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai - (0x00acd, 0x00acd,), # Gujarati Sign Virama + (0x00abe, 0x00ac5,), # Gujarati Vowel Sign Aa ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac9,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Cand + (0x00acb, 0x00acd,), # Gujarati Vowel Sign O ..Gujarati Sign Virama (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca - (0x00b01, 0x00b01,), # Oriya Sign Candrabindu + (0x00b01, 0x00b03,), # Oriya Sign Candrabindu ..Oriya Sign Visarga (0x00b3c, 0x00b3c,), # Oriya Sign Nukta - (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I - (0x00b41, 0x00b43,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic - (0x00b4d, 0x00b4d,), # Oriya Sign Virama - (0x00b56, 0x00b56,), # Oriya Ai Length Mark + (0x00b3e, 0x00b43,), # Oriya Vowel Sign Aa ..Oriya Vowel Sign Vocalic + (0x00b47, 0x00b48,), # Oriya Vowel Sign E ..Oriya Vowel Sign Ai + (0x00b4b, 0x00b4d,), # Oriya Vowel Sign O ..Oriya Sign Virama + (0x00b56, 0x00b57,), # Oriya Ai Length Mark ..Oriya Au Length Mark (0x00b82, 0x00b82,), # Tamil Sign Anusvara - (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii - (0x00bcd, 0x00bcd,), # Tamil Sign Virama - (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00bbe, 0x00bc2,), # Tamil Vowel Sign Aa ..Tamil Vowel Sign Uu + (0x00bc6, 0x00bc8,), # Tamil Vowel Sign E ..Tamil Vowel Sign Ai + (0x00bca, 0x00bcd,), # Tamil Vowel Sign O ..Tamil Sign Virama + (0x00bd7, 0x00bd7,), # Tamil Au Length Mark + (0x00c01, 0x00c03,), # Telugu Sign Candrabindu ..Telugu Sign Visarga + (0x00c3e, 0x00c44,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Vocali (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark + (0x00c82, 0x00c83,), # Kannada Sign Anusvara ..Kannada Sign Visarga (0x00cbc, 0x00cbc,), # Kannada Sign Nukta - (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I - (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E - (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00cbe, 0x00cc4,), # Kannada Vowel Sign Aa ..Kannada Vowel Sign Vocal + (0x00cc6, 0x00cc8,), # Kannada Vowel Sign E ..Kannada Vowel Sign Ai + (0x00cca, 0x00ccd,), # Kannada Vowel Sign O ..Kannada Sign Virama + (0x00cd5, 0x00cd6,), # Kannada Length Mark ..Kannada Ai Length Mark (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal - (0x00d41, 0x00d43,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc - (0x00d4d, 0x00d4d,), # Malayalam Sign Virama + (0x00d02, 0x00d03,), # Malayalam Sign Anusvara ..Malayalam Sign Visarga + (0x00d3e, 0x00d43,), # Malayalam Vowel Sign Aa ..Malayalam Vowel Sign Voc + (0x00d46, 0x00d48,), # Malayalam Vowel Sign E ..Malayalam Vowel Sign Ai + (0x00d4a, 0x00d4d,), # Malayalam Vowel Sign O ..Malayalam Sign Virama + (0x00d57, 0x00d57,), # Malayalam Au Length Mark + (0x00d82, 0x00d83,), # Sinhala Sign Anusvaraya ..Sinhala Sign Visargaya (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna - (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dcf, 0x00dd4,), # Sinhala Vowel Sign Aela-..Sinhala Vowel Sign Ketti (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga Paa-pilla + (0x00dd8, 0x00ddf,), # Sinhala Vowel Sign Gaett..Sinhala Vowel Sign Gayan + (0x00df2, 0x00df3,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga (0x00e31, 0x00e31,), # Thai Character Mai Han-akat (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan @@ -212,66 +247,70 @@ ZERO_WIDTH = { (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung Nyi Zla (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung Sgor Rtags (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru - (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga - (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f3e, 0x00f3f,), # Tibetan Sign Yar Tshes ..Tibetan Sign Mar Tshes + (0x00f71, 0x00f84,), # Tibetan Vowel Sign Aa ..Tibetan Mark Halanta (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags (0x00f90, 0x00f97,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gdan - (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu - (0x01032, 0x01032,), # Myanmar Vowel Sign Ai - (0x01036, 0x01037,), # Myanmar Sign Anusvara ..Myanmar Sign Dot Below - (0x01039, 0x01039,), # Myanmar Sign Virama - (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0102c, 0x01032,), # Myanmar Vowel Sign Aa ..Myanmar Vowel Sign Ai + (0x01036, 0x01039,), # Myanmar Sign Anusvara ..Myanmar Sign Virama + (0x01056, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal (0x0135f, 0x0135f,), # Ethiopic Combining Gemination Mark (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U - (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua - (0x017c6, 0x017c6,), # Khmer Sign Nikahit - (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017b4, 0x017d3,), # Khmer Vowel Inherent Aq ..Khmer Sign Bathamasat (0x017dd, 0x017dd,), # Khmer Sign Atthacan (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation (0x018a9, 0x018a9,), # Mongolian Letter Ali Gali Dagalga - (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U - (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O - (0x01932, 0x01932,), # Limbu Small Letter Anusvara - (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i - (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U - (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang - (0x01b34, 0x01b34,), # Balinese Sign Rerekan - (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R - (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La Lenga - (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepet + (0x01920, 0x0192b,), # Limbu Vowel Sign A ..Limbu Subjoined Letter W + (0x01930, 0x0193b,), # Limbu Small Letter Ka ..Limbu Sign Sa-i + (0x019b0, 0x019c0,), # New Tai Lue Vowel Sign V..New Tai Lue Vowel Sign I + (0x019c8, 0x019c9,), # New Tai Lue Tone Mark-1 ..New Tai Lue Tone Mark-2 + (0x01a17, 0x01a1b,), # Buginese Vowel Sign I ..Buginese Vowel Sign Ae + (0x01b00, 0x01b04,), # Balinese Sign Ulu Ricem ..Balinese Sign Bisah + (0x01b34, 0x01b44,), # Balinese Sign Rerekan ..Balinese Adeg Adeg (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol (0x01dc0, 0x01dca,), # Combining Dotted Grave A..Combining Latin Small Le (0x01dfe, 0x01dff,), # Combining Left Arrowhead..Combining Right Arrowhea + (0x0200b, 0x0200f,), # Zero Width Space ..Right-to-left Mark + (0x02028, 0x0202e,), # Line Separator ..Right-to-left Override + (0x02060, 0x02063,), # Word Joiner ..Invisible Separator + (0x0206a, 0x0206f,), # Inhibit Symmetric Swappi..Nominal Digit Shapes (0x020d0, 0x020ef,), # Combining Left Harpoon A..Combining Right Arrow Be (0x0302a, 0x0302f,), # Ideographic Level Tone M..Hangul Double Dot Tone M (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag + (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisvara (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasanta (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusvara - (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a823, 0x0a827,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spanish Varika (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 (0x0fe20, 0x0fe23,), # Combining Ligature Left ..Combining Double Tilde R + (0x0feff, 0x0feff,), # Zero Width No-break Space + (0x0fff9, 0x0fffb,), # Interlinear Annotation A..Interlinear Annotation T (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo (0x10a3f, 0x10a3f,), # Kharoshthi Virama - (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining - (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d165, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d16d, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0xe0001, 0xe0001,), # Language Tag + (0xe0020, 0xe007f,), # Tag Space ..Cancel Tag (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 ), '5.1.0': ( # Source: DerivedGeneralCategory-5.1.0.txt # Date: 2008-03-20, 17:54:57 GMT [MD] # + (0x00000, 0x00000,), # (nil) + (0x000ad, 0x000ad,), # Soft Hyphen (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg @@ -279,68 +318,81 @@ ZERO_WIDTH = { (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot (0x005c7, 0x005c7,), # Hebrew Point Qamats Qatan + (0x00600, 0x00603,), # Arabic Number Sign ..Arabic Sign Safha (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra (0x0064b, 0x0065e,), # Arabic Fathatan ..Arabic Fatha With Two Do (0x00670, 0x00670,), # Arabic Letter Superscript Alef - (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen - (0x006de, 0x006e4,), # Arabic Start Of Rub El H..Arabic Small High Madda + (0x006d6, 0x006e4,), # Arabic Small High Ligatu..Arabic Small High Madda (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x0070f, 0x0070f,), # Syriac Abbreviation Mark (0x00711, 0x00711,), # Syriac Letter Superscript Alaph (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun (0x007eb, 0x007f3,), # Nko Combining Short High..Nko Combining Double Dot - (0x00901, 0x00902,), # Devanagari Sign Candrabi..Devanagari Sign Anusvara + (0x00901, 0x00903,), # Devanagari Sign Candrabi..Devanagari Sign Visarga (0x0093c, 0x0093c,), # Devanagari Sign Nukta - (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai - (0x0094d, 0x0094d,), # Devanagari Sign Virama + (0x0093e, 0x0094d,), # Devanagari Vowel Sign Aa..Devanagari Sign Virama (0x00951, 0x00954,), # Devanagari Stress Sign U..Devanagari Acute Accent (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo - (0x00981, 0x00981,), # Bengali Sign Candrabindu + (0x00981, 0x00983,), # Bengali Sign Candrabindu..Bengali Sign Visarga (0x009bc, 0x009bc,), # Bengali Sign Nukta - (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal - (0x009cd, 0x009cd,), # Bengali Sign Virama + (0x009be, 0x009c4,), # Bengali Vowel Sign Aa ..Bengali Vowel Sign Vocal + (0x009c7, 0x009c8,), # Bengali Vowel Sign E ..Bengali Vowel Sign Ai + (0x009cb, 0x009cd,), # Bengali Vowel Sign O ..Bengali Sign Virama + (0x009d7, 0x009d7,), # Bengali Au Length Mark (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal - (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a01, 0x00a03,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Visarga (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta - (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a3e, 0x00a42,), # Gurmukhi Vowel Sign Aa ..Gurmukhi Vowel Sign Uu (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash - (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00a81, 0x00a83,), # Gujarati Sign Candrabind..Gujarati Sign Visarga (0x00abc, 0x00abc,), # Gujarati Sign Nukta - (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand - (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai - (0x00acd, 0x00acd,), # Gujarati Sign Virama + (0x00abe, 0x00ac5,), # Gujarati Vowel Sign Aa ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac9,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Cand + (0x00acb, 0x00acd,), # Gujarati Vowel Sign O ..Gujarati Sign Virama (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca - (0x00b01, 0x00b01,), # Oriya Sign Candrabindu + (0x00b01, 0x00b03,), # Oriya Sign Candrabindu ..Oriya Sign Visarga (0x00b3c, 0x00b3c,), # Oriya Sign Nukta - (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I - (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic - (0x00b4d, 0x00b4d,), # Oriya Sign Virama - (0x00b56, 0x00b56,), # Oriya Ai Length Mark + (0x00b3e, 0x00b44,), # Oriya Vowel Sign Aa ..Oriya Vowel Sign Vocalic + (0x00b47, 0x00b48,), # Oriya Vowel Sign E ..Oriya Vowel Sign Ai + (0x00b4b, 0x00b4d,), # Oriya Vowel Sign O ..Oriya Sign Virama + (0x00b56, 0x00b57,), # Oriya Ai Length Mark ..Oriya Au Length Mark (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic (0x00b82, 0x00b82,), # Tamil Sign Anusvara - (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii - (0x00bcd, 0x00bcd,), # Tamil Sign Virama - (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00bbe, 0x00bc2,), # Tamil Vowel Sign Aa ..Tamil Vowel Sign Uu + (0x00bc6, 0x00bc8,), # Tamil Vowel Sign E ..Tamil Vowel Sign Ai + (0x00bca, 0x00bcd,), # Tamil Vowel Sign O ..Tamil Sign Virama + (0x00bd7, 0x00bd7,), # Tamil Au Length Mark + (0x00c01, 0x00c03,), # Telugu Sign Candrabindu ..Telugu Sign Visarga + (0x00c3e, 0x00c44,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Vocali (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali + (0x00c82, 0x00c83,), # Kannada Sign Anusvara ..Kannada Sign Visarga (0x00cbc, 0x00cbc,), # Kannada Sign Nukta - (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I - (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E - (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00cbe, 0x00cc4,), # Kannada Vowel Sign Aa ..Kannada Vowel Sign Vocal + (0x00cc6, 0x00cc8,), # Kannada Vowel Sign E ..Kannada Vowel Sign Ai + (0x00cca, 0x00ccd,), # Kannada Vowel Sign O ..Kannada Sign Virama + (0x00cd5, 0x00cd6,), # Kannada Length Mark ..Kannada Ai Length Mark (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal - (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc - (0x00d4d, 0x00d4d,), # Malayalam Sign Virama + (0x00d02, 0x00d03,), # Malayalam Sign Anusvara ..Malayalam Sign Visarga + (0x00d3e, 0x00d44,), # Malayalam Vowel Sign Aa ..Malayalam Vowel Sign Voc + (0x00d46, 0x00d48,), # Malayalam Vowel Sign E ..Malayalam Vowel Sign Ai + (0x00d4a, 0x00d4d,), # Malayalam Vowel Sign O ..Malayalam Sign Virama + (0x00d57, 0x00d57,), # Malayalam Au Length Mark (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00d82, 0x00d83,), # Sinhala Sign Anusvaraya ..Sinhala Sign Visargaya (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna - (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dcf, 0x00dd4,), # Sinhala Vowel Sign Aela-..Sinhala Vowel Sign Ketti (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga Paa-pilla + (0x00dd8, 0x00ddf,), # Sinhala Vowel Sign Gaett..Sinhala Vowel Sign Gayan + (0x00df2, 0x00df3,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga (0x00e31, 0x00e31,), # Thai Character Mai Han-akat (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan @@ -352,51 +404,46 @@ ZERO_WIDTH = { (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung Nyi Zla (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung Sgor Rtags (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru - (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga - (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f3e, 0x00f3f,), # Tibetan Sign Yar Tshes ..Tibetan Sign Mar Tshes + (0x00f71, 0x00f84,), # Tibetan Vowel Sign Aa ..Tibetan Mark Halanta (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags (0x00f90, 0x00f97,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gdan - (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu - (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below - (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat - (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M - (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0102b, 0x0103e,), # Myanmar Vowel Sign Tall ..Myanmar Consonant Sign M + (0x01056, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01062, 0x01064,), # Myanmar Vowel Sign Sgaw ..Myanmar Tone Mark Sgaw K + (0x01067, 0x0106d,), # Myanmar Vowel Sign Weste..Myanmar Sign Western Pwo (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah - (0x01082, 0x01082,), # Myanmar Consonant Sign Shan Medial Wa - (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan - (0x0108d, 0x0108d,), # Myanmar Sign Shan Council Emphatic Tone + (0x01082, 0x0108d,), # Myanmar Consonant Sign S..Myanmar Sign Shan Counci + (0x0108f, 0x0108f,), # Myanmar Sign Rumai Palaung Tone-5 (0x0135f, 0x0135f,), # Ethiopic Combining Gemination Mark (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U - (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua - (0x017c6, 0x017c6,), # Khmer Sign Nikahit - (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017b4, 0x017d3,), # Khmer Vowel Inherent Aq ..Khmer Sign Bathamasat (0x017dd, 0x017dd,), # Khmer Sign Atthacan (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation (0x018a9, 0x018a9,), # Mongolian Letter Ali Gali Dagalga - (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U - (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O - (0x01932, 0x01932,), # Limbu Small Letter Anusvara - (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i - (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U - (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang - (0x01b34, 0x01b34,), # Balinese Sign Rerekan - (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R - (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La Lenga - (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepet + (0x01920, 0x0192b,), # Limbu Vowel Sign A ..Limbu Subjoined Letter W + (0x01930, 0x0193b,), # Limbu Small Letter Ka ..Limbu Sign Sa-i + (0x019b0, 0x019c0,), # New Tai Lue Vowel Sign V..New Tai Lue Vowel Sign I + (0x019c8, 0x019c9,), # New Tai Lue Tone Mark-1 ..New Tai Lue Tone Mark-2 + (0x01a17, 0x01a1b,), # Buginese Vowel Sign I ..Buginese Vowel Sign Ae + (0x01b00, 0x01b04,), # Balinese Sign Ulu Ricem ..Balinese Sign Bisah + (0x01b34, 0x01b44,), # Balinese Sign Rerekan ..Balinese Adeg Adeg (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol - (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar - (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan - (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan - (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T - (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01b80, 0x01b82,), # Sundanese Sign Panyecek ..Sundanese Sign Pangwisad + (0x01ba1, 0x01baa,), # Sundanese Consonant Sign..Sundanese Sign Pamaaeh + (0x01c24, 0x01c37,), # Lepcha Subjoined Letter ..Lepcha Sign Nukta (0x01dc0, 0x01de6,), # Combining Dotted Grave A..Combining Latin Small Le (0x01dfe, 0x01dff,), # Combining Left Arrowhead..Combining Right Arrowhea + (0x0200b, 0x0200f,), # Zero Width Space ..Right-to-left Mark + (0x02028, 0x0202e,), # Line Separator ..Right-to-left Override + (0x02060, 0x02064,), # Word Joiner ..Invisible Plus + (0x0206a, 0x0206f,), # Inhibit Symmetric Swappi..Nominal Digit Shapes (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette (0x0302a, 0x0302f,), # Ideographic Level Tone M..Hangul Double Dot Tone M @@ -406,35 +453,40 @@ ZERO_WIDTH = { (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisvara (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasanta (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusvara - (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign - (0x0a8c4, 0x0a8c4,), # Saurashtra Sign Virama + (0x0a823, 0x0a827,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a880, 0x0a881,), # Saurashtra Sign Anusvara..Saurashtra Sign Visarga + (0x0a8b4, 0x0a8c4,), # Saurashtra Consonant Sig..Saurashtra Sign Virama (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop - (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R - (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe - (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue - (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0a947, 0x0a953,), # Rejang Vowel Sign I ..Rejang Virama + (0x0aa29, 0x0aa36,), # Cham Vowel Sign Aa ..Cham Consonant Sign Wa (0x0aa43, 0x0aa43,), # Cham Consonant Sign Final Ng - (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Final M + (0x0aa4c, 0x0aa4d,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spanish Varika (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 (0x0fe20, 0x0fe26,), # Combining Ligature Left ..Combining Conjoining Mac + (0x0feff, 0x0feff,), # Zero Width No-break Space + (0x0fff9, 0x0fffb,), # Interlinear Annotation A..Interlinear Annotation T (0x101fd, 0x101fd,), # Phaistos Disc Sign Combining Oblique Stroke (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo (0x10a3f, 0x10a3f,), # Kharoshthi Virama - (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining - (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d165, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d16d, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0xe0001, 0xe0001,), # Language Tag + (0xe0020, 0xe007f,), # Tag Space ..Cancel Tag (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 ), '5.2.0': ( # Source: DerivedGeneralCategory-5.2.0.txt # Date: 2009-08-22, 04:58:21 GMT [MD] # + (0x00000, 0x00000,), # (nil) + (0x000ad, 0x000ad,), # Soft Hyphen (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg @@ -442,13 +494,14 @@ ZERO_WIDTH = { (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot (0x005c7, 0x005c7,), # Hebrew Point Qamats Qatan + (0x00600, 0x00603,), # Arabic Number Sign ..Arabic Sign Safha (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra (0x0064b, 0x0065e,), # Arabic Fathatan ..Arabic Fatha With Two Do (0x00670, 0x00670,), # Arabic Letter Superscript Alef - (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen - (0x006de, 0x006e4,), # Arabic Start Of Rub El H..Arabic Small High Madda + (0x006d6, 0x006e4,), # Arabic Small High Ligatu..Arabic Small High Madda (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x0070f, 0x0070f,), # Syriac Abbreviation Mark (0x00711, 0x00711,), # Syriac Letter Superscript Alaph (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun @@ -457,57 +510,69 @@ ZERO_WIDTH = { (0x0081b, 0x00823,), # Samaritan Mark Epentheti..Samaritan Vowel Sign A (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa - (0x00900, 0x00902,), # Devanagari Sign Inverted..Devanagari Sign Anusvara + (0x00900, 0x00903,), # Devanagari Sign Inverted..Devanagari Sign Visarga (0x0093c, 0x0093c,), # Devanagari Sign Nukta - (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai - (0x0094d, 0x0094d,), # Devanagari Sign Virama + (0x0093e, 0x0094e,), # Devanagari Vowel Sign Aa..Devanagari Vowel Sign Pr (0x00951, 0x00955,), # Devanagari Stress Sign U..Devanagari Vowel Sign Ca (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo - (0x00981, 0x00981,), # Bengali Sign Candrabindu + (0x00981, 0x00983,), # Bengali Sign Candrabindu..Bengali Sign Visarga (0x009bc, 0x009bc,), # Bengali Sign Nukta - (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal - (0x009cd, 0x009cd,), # Bengali Sign Virama + (0x009be, 0x009c4,), # Bengali Vowel Sign Aa ..Bengali Vowel Sign Vocal + (0x009c7, 0x009c8,), # Bengali Vowel Sign E ..Bengali Vowel Sign Ai + (0x009cb, 0x009cd,), # Bengali Vowel Sign O ..Bengali Sign Virama + (0x009d7, 0x009d7,), # Bengali Au Length Mark (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal - (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a01, 0x00a03,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Visarga (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta - (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a3e, 0x00a42,), # Gurmukhi Vowel Sign Aa ..Gurmukhi Vowel Sign Uu (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash - (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00a81, 0x00a83,), # Gujarati Sign Candrabind..Gujarati Sign Visarga (0x00abc, 0x00abc,), # Gujarati Sign Nukta - (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand - (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai - (0x00acd, 0x00acd,), # Gujarati Sign Virama + (0x00abe, 0x00ac5,), # Gujarati Vowel Sign Aa ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac9,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Cand + (0x00acb, 0x00acd,), # Gujarati Vowel Sign O ..Gujarati Sign Virama (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca - (0x00b01, 0x00b01,), # Oriya Sign Candrabindu + (0x00b01, 0x00b03,), # Oriya Sign Candrabindu ..Oriya Sign Visarga (0x00b3c, 0x00b3c,), # Oriya Sign Nukta - (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I - (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic - (0x00b4d, 0x00b4d,), # Oriya Sign Virama - (0x00b56, 0x00b56,), # Oriya Ai Length Mark + (0x00b3e, 0x00b44,), # Oriya Vowel Sign Aa ..Oriya Vowel Sign Vocalic + (0x00b47, 0x00b48,), # Oriya Vowel Sign E ..Oriya Vowel Sign Ai + (0x00b4b, 0x00b4d,), # Oriya Vowel Sign O ..Oriya Sign Virama + (0x00b56, 0x00b57,), # Oriya Ai Length Mark ..Oriya Au Length Mark (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic (0x00b82, 0x00b82,), # Tamil Sign Anusvara - (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii - (0x00bcd, 0x00bcd,), # Tamil Sign Virama - (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00bbe, 0x00bc2,), # Tamil Vowel Sign Aa ..Tamil Vowel Sign Uu + (0x00bc6, 0x00bc8,), # Tamil Vowel Sign E ..Tamil Vowel Sign Ai + (0x00bca, 0x00bcd,), # Tamil Vowel Sign O ..Tamil Sign Virama + (0x00bd7, 0x00bd7,), # Tamil Au Length Mark + (0x00c01, 0x00c03,), # Telugu Sign Candrabindu ..Telugu Sign Visarga + (0x00c3e, 0x00c44,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Vocali (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali + (0x00c82, 0x00c83,), # Kannada Sign Anusvara ..Kannada Sign Visarga (0x00cbc, 0x00cbc,), # Kannada Sign Nukta - (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I - (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E - (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00cbe, 0x00cc4,), # Kannada Vowel Sign Aa ..Kannada Vowel Sign Vocal + (0x00cc6, 0x00cc8,), # Kannada Vowel Sign E ..Kannada Vowel Sign Ai + (0x00cca, 0x00ccd,), # Kannada Vowel Sign O ..Kannada Sign Virama + (0x00cd5, 0x00cd6,), # Kannada Length Mark ..Kannada Ai Length Mark (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal - (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc - (0x00d4d, 0x00d4d,), # Malayalam Sign Virama + (0x00d02, 0x00d03,), # Malayalam Sign Anusvara ..Malayalam Sign Visarga + (0x00d3e, 0x00d44,), # Malayalam Vowel Sign Aa ..Malayalam Vowel Sign Voc + (0x00d46, 0x00d48,), # Malayalam Vowel Sign E ..Malayalam Vowel Sign Ai + (0x00d4a, 0x00d4d,), # Malayalam Vowel Sign O ..Malayalam Sign Virama + (0x00d57, 0x00d57,), # Malayalam Au Length Mark (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00d82, 0x00d83,), # Sinhala Sign Anusvaraya ..Sinhala Sign Visargaya (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna - (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dcf, 0x00dd4,), # Sinhala Vowel Sign Aela-..Sinhala Vowel Sign Ketti (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga Paa-pilla + (0x00dd8, 0x00ddf,), # Sinhala Vowel Sign Gaett..Sinhala Vowel Sign Gayan + (0x00df2, 0x00df3,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga (0x00e31, 0x00e31,), # Thai Character Mai Han-akat (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan @@ -519,63 +584,54 @@ ZERO_WIDTH = { (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung Nyi Zla (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung Sgor Rtags (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru - (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga - (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f3e, 0x00f3f,), # Tibetan Sign Yar Tshes ..Tibetan Sign Mar Tshes + (0x00f71, 0x00f84,), # Tibetan Vowel Sign Aa ..Tibetan Mark Halanta (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags (0x00f90, 0x00f97,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gdan - (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu - (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below - (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat - (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M - (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0102b, 0x0103e,), # Myanmar Vowel Sign Tall ..Myanmar Consonant Sign M + (0x01056, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01062, 0x01064,), # Myanmar Vowel Sign Sgaw ..Myanmar Tone Mark Sgaw K + (0x01067, 0x0106d,), # Myanmar Vowel Sign Weste..Myanmar Sign Western Pwo (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah - (0x01082, 0x01082,), # Myanmar Consonant Sign Shan Medial Wa - (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan - (0x0108d, 0x0108d,), # Myanmar Sign Shan Council Emphatic Tone - (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton Ai + (0x01082, 0x0108d,), # Myanmar Consonant Sign S..Myanmar Sign Shan Counci + (0x0108f, 0x0108f,), # Myanmar Sign Rumai Palaung Tone-5 + (0x0109a, 0x0109d,), # Myanmar Sign Khamti Tone..Myanmar Vowel Sign Aiton (0x0135f, 0x0135f,), # Ethiopic Combining Gemination Mark (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U - (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua - (0x017c6, 0x017c6,), # Khmer Sign Nikahit - (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017b4, 0x017d3,), # Khmer Vowel Inherent Aq ..Khmer Sign Bathamasat (0x017dd, 0x017dd,), # Khmer Sign Atthacan (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation (0x018a9, 0x018a9,), # Mongolian Letter Ali Gali Dagalga - (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U - (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O - (0x01932, 0x01932,), # Limbu Small Letter Anusvara - (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i - (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U - (0x01a56, 0x01a56,), # Tai Tham Consonant Sign Medial La - (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign - (0x01a60, 0x01a60,), # Tai Tham Sign Sakot - (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai Sat - (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B - (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01920, 0x0192b,), # Limbu Vowel Sign A ..Limbu Subjoined Letter W + (0x01930, 0x0193b,), # Limbu Small Letter Ka ..Limbu Sign Sa-i + (0x019b0, 0x019c0,), # New Tai Lue Vowel Sign V..New Tai Lue Vowel Sign I + (0x019c8, 0x019c9,), # New Tai Lue Tone Mark-1 ..New Tai Lue Tone Mark-2 + (0x01a17, 0x01a1b,), # Buginese Vowel Sign I ..Buginese Vowel Sign Ae + (0x01a55, 0x01a5e,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a60, 0x01a7c,), # Tai Tham Sign Sakot ..Tai Tham Sign Khuen-lue (0x01a7f, 0x01a7f,), # Tai Tham Combining Cryptogrammic Dot - (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang - (0x01b34, 0x01b34,), # Balinese Sign Rerekan - (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R - (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La Lenga - (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepet + (0x01b00, 0x01b04,), # Balinese Sign Ulu Ricem ..Balinese Sign Bisah + (0x01b34, 0x01b44,), # Balinese Sign Rerekan ..Balinese Adeg Adeg (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol - (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar - (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan - (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan - (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T - (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01b80, 0x01b82,), # Sundanese Sign Panyecek ..Sundanese Sign Pangwisad + (0x01ba1, 0x01baa,), # Sundanese Consonant Sign..Sundanese Sign Pamaaeh + (0x01c24, 0x01c37,), # Lepcha Subjoined Letter ..Lepcha Sign Nukta (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha - (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash - (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01cd4, 0x01ce8,), # Vedic Sign Yajurvedic Mi..Vedic Sign Visarga Anuda (0x01ced, 0x01ced,), # Vedic Sign Tiryak + (0x01cf2, 0x01cf2,), # Vedic Sign Ardhavisarga (0x01dc0, 0x01de6,), # Combining Dotted Grave A..Combining Latin Small Le (0x01dfd, 0x01dff,), # Combining Almost Equal T..Combining Right Arrowhea + (0x0200b, 0x0200f,), # Zero Width Space ..Right-to-left Mark + (0x02028, 0x0202e,), # Line Separator ..Right-to-left Override + (0x02060, 0x02064,), # Word Joiner ..Invisible Plus + (0x0206a, 0x0206f,), # Inhibit Symmetric Swappi..Nominal Digit Shapes (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette @@ -587,51 +643,54 @@ ZERO_WIDTH = { (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisvara (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasanta (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusvara - (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign - (0x0a8c4, 0x0a8c4,), # Saurashtra Sign Virama + (0x0a823, 0x0a827,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a880, 0x0a881,), # Saurashtra Sign Anusvara..Saurashtra Sign Visarga + (0x0a8b4, 0x0a8c4,), # Saurashtra Consonant Sig..Saurashtra Sign Virama (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop - (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R - (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar - (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu - (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku - (0x0a9bc, 0x0a9bc,), # Javanese Vowel Sign Pepet - (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe - (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue - (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0a947, 0x0a953,), # Rejang Vowel Sign I ..Rejang Virama + (0x0a980, 0x0a983,), # Javanese Sign Panyangga ..Javanese Sign Wignyan + (0x0a9b3, 0x0a9c0,), # Javanese Sign Cecak Telu..Javanese Pangkon + (0x0aa29, 0x0aa36,), # Cham Vowel Sign Aa ..Cham Consonant Sign Wa (0x0aa43, 0x0aa43,), # Cham Consonant Sign Final Ng - (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Final M + (0x0aa4c, 0x0aa4d,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa7b, 0x0aa7b,), # Myanmar Sign Pao Karen Tone (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho - (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign Anap - (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign Unap - (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek + (0x0abe3, 0x0abea,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abec, 0x0abed,), # Meetei Mayek Lum Iyek ..Meetei Mayek Apun Iyek (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spanish Varika (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 (0x0fe20, 0x0fe26,), # Combining Ligature Left ..Combining Conjoining Mac + (0x0feff, 0x0feff,), # Zero Width No-break Space + (0x0fff9, 0x0fffb,), # Interlinear Annotation A..Interlinear Annotation T (0x101fd, 0x101fd,), # Phaistos Disc Sign Combining Oblique Stroke (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo (0x10a3f, 0x10a3f,), # Kharoshthi Virama - (0x11080, 0x11081,), # Kaithi Sign Candrabindu ..Kaithi Sign Anusvara - (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai - (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta - (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining - (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x11080, 0x11082,), # Kaithi Sign Candrabindu ..Kaithi Sign Visarga + (0x110b0, 0x110ba,), # Kaithi Vowel Sign Aa ..Kaithi Sign Nukta + (0x110bd, 0x110bd,), # Kaithi Number Sign + (0x1d165, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d16d, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0xe0001, 0xe0001,), # Language Tag + (0xe0020, 0xe007f,), # Tag Space ..Cancel Tag (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 ), '6.0.0': ( # Source: DerivedGeneralCategory-6.0.0.txt # Date: 2010-08-19, 00:48:09 GMT [MD] # + (0x00000, 0x00000,), # (nil) + (0x000ad, 0x000ad,), # Soft Hyphen (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg @@ -639,13 +698,15 @@ ZERO_WIDTH = { (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot (0x005c7, 0x005c7,), # Hebrew Point Qamats Qatan + (0x00600, 0x00603,), # Arabic Number Sign ..Arabic Sign Safha (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below (0x00670, 0x00670,), # Arabic Letter Superscript Alef - (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006d6, 0x006dd,), # Arabic Small High Ligatu..Arabic End Of Ayah (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x0070f, 0x0070f,), # Syriac Abbreviation Mark (0x00711, 0x00711,), # Syriac Letter Superscript Alaph (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun @@ -655,58 +716,69 @@ ZERO_WIDTH = { (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark - (0x00900, 0x00902,), # Devanagari Sign Inverted..Devanagari Sign Anusvara - (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe - (0x0093c, 0x0093c,), # Devanagari Sign Nukta - (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai - (0x0094d, 0x0094d,), # Devanagari Sign Virama + (0x00900, 0x00903,), # Devanagari Sign Inverted..Devanagari Sign Visarga + (0x0093a, 0x0093c,), # Devanagari Vowel Sign Oe..Devanagari Sign Nukta + (0x0093e, 0x0094f,), # Devanagari Vowel Sign Aa..Devanagari Vowel Sign Aw (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo - (0x00981, 0x00981,), # Bengali Sign Candrabindu + (0x00981, 0x00983,), # Bengali Sign Candrabindu..Bengali Sign Visarga (0x009bc, 0x009bc,), # Bengali Sign Nukta - (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal - (0x009cd, 0x009cd,), # Bengali Sign Virama + (0x009be, 0x009c4,), # Bengali Vowel Sign Aa ..Bengali Vowel Sign Vocal + (0x009c7, 0x009c8,), # Bengali Vowel Sign E ..Bengali Vowel Sign Ai + (0x009cb, 0x009cd,), # Bengali Vowel Sign O ..Bengali Sign Virama + (0x009d7, 0x009d7,), # Bengali Au Length Mark (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal - (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a01, 0x00a03,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Visarga (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta - (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a3e, 0x00a42,), # Gurmukhi Vowel Sign Aa ..Gurmukhi Vowel Sign Uu (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash - (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00a81, 0x00a83,), # Gujarati Sign Candrabind..Gujarati Sign Visarga (0x00abc, 0x00abc,), # Gujarati Sign Nukta - (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand - (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai - (0x00acd, 0x00acd,), # Gujarati Sign Virama + (0x00abe, 0x00ac5,), # Gujarati Vowel Sign Aa ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac9,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Cand + (0x00acb, 0x00acd,), # Gujarati Vowel Sign O ..Gujarati Sign Virama (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca - (0x00b01, 0x00b01,), # Oriya Sign Candrabindu + (0x00b01, 0x00b03,), # Oriya Sign Candrabindu ..Oriya Sign Visarga (0x00b3c, 0x00b3c,), # Oriya Sign Nukta - (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I - (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic - (0x00b4d, 0x00b4d,), # Oriya Sign Virama - (0x00b56, 0x00b56,), # Oriya Ai Length Mark + (0x00b3e, 0x00b44,), # Oriya Vowel Sign Aa ..Oriya Vowel Sign Vocalic + (0x00b47, 0x00b48,), # Oriya Vowel Sign E ..Oriya Vowel Sign Ai + (0x00b4b, 0x00b4d,), # Oriya Vowel Sign O ..Oriya Sign Virama + (0x00b56, 0x00b57,), # Oriya Ai Length Mark ..Oriya Au Length Mark (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic (0x00b82, 0x00b82,), # Tamil Sign Anusvara - (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii - (0x00bcd, 0x00bcd,), # Tamil Sign Virama - (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00bbe, 0x00bc2,), # Tamil Vowel Sign Aa ..Tamil Vowel Sign Uu + (0x00bc6, 0x00bc8,), # Tamil Vowel Sign E ..Tamil Vowel Sign Ai + (0x00bca, 0x00bcd,), # Tamil Vowel Sign O ..Tamil Sign Virama + (0x00bd7, 0x00bd7,), # Tamil Au Length Mark + (0x00c01, 0x00c03,), # Telugu Sign Candrabindu ..Telugu Sign Visarga + (0x00c3e, 0x00c44,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Vocali (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali + (0x00c82, 0x00c83,), # Kannada Sign Anusvara ..Kannada Sign Visarga (0x00cbc, 0x00cbc,), # Kannada Sign Nukta - (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I - (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E - (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00cbe, 0x00cc4,), # Kannada Vowel Sign Aa ..Kannada Vowel Sign Vocal + (0x00cc6, 0x00cc8,), # Kannada Vowel Sign E ..Kannada Vowel Sign Ai + (0x00cca, 0x00ccd,), # Kannada Vowel Sign O ..Kannada Sign Virama + (0x00cd5, 0x00cd6,), # Kannada Length Mark ..Kannada Ai Length Mark (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal - (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc - (0x00d4d, 0x00d4d,), # Malayalam Sign Virama + (0x00d02, 0x00d03,), # Malayalam Sign Anusvara ..Malayalam Sign Visarga + (0x00d3e, 0x00d44,), # Malayalam Vowel Sign Aa ..Malayalam Vowel Sign Voc + (0x00d46, 0x00d48,), # Malayalam Vowel Sign E ..Malayalam Vowel Sign Ai + (0x00d4a, 0x00d4d,), # Malayalam Vowel Sign O ..Malayalam Sign Virama + (0x00d57, 0x00d57,), # Malayalam Au Length Mark (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00d82, 0x00d83,), # Sinhala Sign Anusvaraya ..Sinhala Sign Visargaya (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna - (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dcf, 0x00dd4,), # Sinhala Vowel Sign Aela-..Sinhala Vowel Sign Ketti (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga Paa-pilla + (0x00dd8, 0x00ddf,), # Sinhala Vowel Sign Gaett..Sinhala Vowel Sign Gayan + (0x00df2, 0x00df3,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga (0x00e31, 0x00e31,), # Thai Character Mai Han-akat (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan @@ -718,67 +790,55 @@ ZERO_WIDTH = { (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung Nyi Zla (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung Sgor Rtags (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru - (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga - (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f3e, 0x00f3f,), # Tibetan Sign Yar Tshes ..Tibetan Sign Mar Tshes + (0x00f71, 0x00f84,), # Tibetan Vowel Sign Aa ..Tibetan Mark Halanta (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gdan - (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu - (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below - (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat - (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M - (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0102b, 0x0103e,), # Myanmar Vowel Sign Tall ..Myanmar Consonant Sign M + (0x01056, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01062, 0x01064,), # Myanmar Vowel Sign Sgaw ..Myanmar Tone Mark Sgaw K + (0x01067, 0x0106d,), # Myanmar Vowel Sign Weste..Myanmar Sign Western Pwo (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah - (0x01082, 0x01082,), # Myanmar Consonant Sign Shan Medial Wa - (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan - (0x0108d, 0x0108d,), # Myanmar Sign Shan Council Emphatic Tone - (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton Ai + (0x01082, 0x0108d,), # Myanmar Consonant Sign S..Myanmar Sign Shan Counci + (0x0108f, 0x0108f,), # Myanmar Sign Rumai Palaung Tone-5 + (0x0109a, 0x0109d,), # Myanmar Sign Khamti Tone..Myanmar Vowel Sign Aiton (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U - (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua - (0x017c6, 0x017c6,), # Khmer Sign Nikahit - (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017b4, 0x017d3,), # Khmer Vowel Inherent Aq ..Khmer Sign Bathamasat (0x017dd, 0x017dd,), # Khmer Sign Atthacan (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation (0x018a9, 0x018a9,), # Mongolian Letter Ali Gali Dagalga - (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U - (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O - (0x01932, 0x01932,), # Limbu Small Letter Anusvara - (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i - (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U - (0x01a56, 0x01a56,), # Tai Tham Consonant Sign Medial La - (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign - (0x01a60, 0x01a60,), # Tai Tham Sign Sakot - (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai Sat - (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B - (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01920, 0x0192b,), # Limbu Vowel Sign A ..Limbu Subjoined Letter W + (0x01930, 0x0193b,), # Limbu Small Letter Ka ..Limbu Sign Sa-i + (0x019b0, 0x019c0,), # New Tai Lue Vowel Sign V..New Tai Lue Vowel Sign I + (0x019c8, 0x019c9,), # New Tai Lue Tone Mark-1 ..New Tai Lue Tone Mark-2 + (0x01a17, 0x01a1b,), # Buginese Vowel Sign I ..Buginese Vowel Sign Ae + (0x01a55, 0x01a5e,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a60, 0x01a7c,), # Tai Tham Sign Sakot ..Tai Tham Sign Khuen-lue (0x01a7f, 0x01a7f,), # Tai Tham Combining Cryptogrammic Dot - (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang - (0x01b34, 0x01b34,), # Balinese Sign Rerekan - (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R - (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La Lenga - (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepet + (0x01b00, 0x01b04,), # Balinese Sign Ulu Ricem ..Balinese Sign Bisah + (0x01b34, 0x01b44,), # Balinese Sign Rerekan ..Balinese Adeg Adeg (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol - (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar - (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan - (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan - (0x01be6, 0x01be6,), # Batak Sign Tompi - (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee - (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O - (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H - (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T - (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01b80, 0x01b82,), # Sundanese Sign Panyecek ..Sundanese Sign Pangwisad + (0x01ba1, 0x01baa,), # Sundanese Consonant Sign..Sundanese Sign Pamaaeh + (0x01be6, 0x01bf3,), # Batak Sign Tompi ..Batak Panongonan + (0x01c24, 0x01c37,), # Lepcha Subjoined Letter ..Lepcha Sign Nukta (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha - (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash - (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01cd4, 0x01ce8,), # Vedic Sign Yajurvedic Mi..Vedic Sign Visarga Anuda (0x01ced, 0x01ced,), # Vedic Sign Tiryak + (0x01cf2, 0x01cf2,), # Vedic Sign Ardhavisarga (0x01dc0, 0x01de6,), # Combining Dotted Grave A..Combining Latin Small Le (0x01dfc, 0x01dff,), # Combining Double Inverte..Combining Right Arrowhea + (0x0200b, 0x0200f,), # Zero Width Space ..Right-to-left Mark + (0x02028, 0x0202e,), # Line Separator ..Right-to-left Override + (0x02060, 0x02064,), # Word Joiner ..Invisible Plus + (0x0206a, 0x0206f,), # Inhibit Symmetric Swappi..Nominal Digit Shapes (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joiner @@ -791,53 +851,56 @@ ZERO_WIDTH = { (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisvara (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasanta (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusvara - (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign - (0x0a8c4, 0x0a8c4,), # Saurashtra Sign Virama + (0x0a823, 0x0a827,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a880, 0x0a881,), # Saurashtra Sign Anusvara..Saurashtra Sign Visarga + (0x0a8b4, 0x0a8c4,), # Saurashtra Consonant Sig..Saurashtra Sign Virama (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop - (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R - (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar - (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu - (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku - (0x0a9bc, 0x0a9bc,), # Javanese Vowel Sign Pepet - (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe - (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue - (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0a947, 0x0a953,), # Rejang Vowel Sign I ..Rejang Virama + (0x0a980, 0x0a983,), # Javanese Sign Panyangga ..Javanese Sign Wignyan + (0x0a9b3, 0x0a9c0,), # Javanese Sign Cecak Telu..Javanese Pangkon + (0x0aa29, 0x0aa36,), # Cham Vowel Sign Aa ..Cham Consonant Sign Wa (0x0aa43, 0x0aa43,), # Cham Consonant Sign Final Ng - (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Final M + (0x0aa4c, 0x0aa4d,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa7b, 0x0aa7b,), # Myanmar Sign Pao Karen Tone (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho - (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign Anap - (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign Unap - (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek + (0x0abe3, 0x0abea,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abec, 0x0abed,), # Meetei Mayek Lum Iyek ..Meetei Mayek Apun Iyek (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spanish Varika (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 (0x0fe20, 0x0fe26,), # Combining Ligature Left ..Combining Conjoining Mac + (0x0feff, 0x0feff,), # Zero Width No-break Space + (0x0fff9, 0x0fffb,), # Interlinear Annotation A..Interlinear Annotation T (0x101fd, 0x101fd,), # Phaistos Disc Sign Combining Oblique Stroke (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo (0x10a3f, 0x10a3f,), # Kharoshthi Virama - (0x11001, 0x11001,), # Brahmi Sign Anusvara + (0x11000, 0x11002,), # Brahmi Sign Candrabindu ..Brahmi Sign Visarga (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama - (0x11080, 0x11081,), # Kaithi Sign Candrabindu ..Kaithi Sign Anusvara - (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai - (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta - (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining - (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x11080, 0x11082,), # Kaithi Sign Candrabindu ..Kaithi Sign Visarga + (0x110b0, 0x110ba,), # Kaithi Vowel Sign Aa ..Kaithi Sign Nukta + (0x110bd, 0x110bd,), # Kaithi Number Sign + (0x1d165, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d16d, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0xe0001, 0xe0001,), # Language Tag + (0xe0020, 0xe007f,), # Tag Space ..Cancel Tag (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 ), '6.1.0': ( # Source: DerivedGeneralCategory-6.1.0.txt # Date: 2011-11-27, 05:10:22 GMT [MD] # + (0x00000, 0x00000,), # (nil) + (0x000ad, 0x000ad,), # Soft Hyphen (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg @@ -845,13 +908,15 @@ ZERO_WIDTH = { (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot (0x005c7, 0x005c7,), # Hebrew Point Qamats Qatan + (0x00600, 0x00604,), # Arabic Number Sign ..Arabic Sign Samvat (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below (0x00670, 0x00670,), # Arabic Letter Superscript Alef - (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006d6, 0x006dd,), # Arabic Small High Ligatu..Arabic End Of Ayah (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x0070f, 0x0070f,), # Syriac Abbreviation Mark (0x00711, 0x00711,), # Syriac Letter Superscript Alaph (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun @@ -862,58 +927,69 @@ ZERO_WIDTH = { (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark (0x008e4, 0x008fe,), # Arabic Curly Fatha ..Arabic Damma With Dot - (0x00900, 0x00902,), # Devanagari Sign Inverted..Devanagari Sign Anusvara - (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe - (0x0093c, 0x0093c,), # Devanagari Sign Nukta - (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai - (0x0094d, 0x0094d,), # Devanagari Sign Virama + (0x00900, 0x00903,), # Devanagari Sign Inverted..Devanagari Sign Visarga + (0x0093a, 0x0093c,), # Devanagari Vowel Sign Oe..Devanagari Sign Nukta + (0x0093e, 0x0094f,), # Devanagari Vowel Sign Aa..Devanagari Vowel Sign Aw (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo - (0x00981, 0x00981,), # Bengali Sign Candrabindu + (0x00981, 0x00983,), # Bengali Sign Candrabindu..Bengali Sign Visarga (0x009bc, 0x009bc,), # Bengali Sign Nukta - (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal - (0x009cd, 0x009cd,), # Bengali Sign Virama + (0x009be, 0x009c4,), # Bengali Vowel Sign Aa ..Bengali Vowel Sign Vocal + (0x009c7, 0x009c8,), # Bengali Vowel Sign E ..Bengali Vowel Sign Ai + (0x009cb, 0x009cd,), # Bengali Vowel Sign O ..Bengali Sign Virama + (0x009d7, 0x009d7,), # Bengali Au Length Mark (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal - (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a01, 0x00a03,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Visarga (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta - (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a3e, 0x00a42,), # Gurmukhi Vowel Sign Aa ..Gurmukhi Vowel Sign Uu (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash - (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00a81, 0x00a83,), # Gujarati Sign Candrabind..Gujarati Sign Visarga (0x00abc, 0x00abc,), # Gujarati Sign Nukta - (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand - (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai - (0x00acd, 0x00acd,), # Gujarati Sign Virama + (0x00abe, 0x00ac5,), # Gujarati Vowel Sign Aa ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac9,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Cand + (0x00acb, 0x00acd,), # Gujarati Vowel Sign O ..Gujarati Sign Virama (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca - (0x00b01, 0x00b01,), # Oriya Sign Candrabindu + (0x00b01, 0x00b03,), # Oriya Sign Candrabindu ..Oriya Sign Visarga (0x00b3c, 0x00b3c,), # Oriya Sign Nukta - (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I - (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic - (0x00b4d, 0x00b4d,), # Oriya Sign Virama - (0x00b56, 0x00b56,), # Oriya Ai Length Mark + (0x00b3e, 0x00b44,), # Oriya Vowel Sign Aa ..Oriya Vowel Sign Vocalic + (0x00b47, 0x00b48,), # Oriya Vowel Sign E ..Oriya Vowel Sign Ai + (0x00b4b, 0x00b4d,), # Oriya Vowel Sign O ..Oriya Sign Virama + (0x00b56, 0x00b57,), # Oriya Ai Length Mark ..Oriya Au Length Mark (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic (0x00b82, 0x00b82,), # Tamil Sign Anusvara - (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii - (0x00bcd, 0x00bcd,), # Tamil Sign Virama - (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00bbe, 0x00bc2,), # Tamil Vowel Sign Aa ..Tamil Vowel Sign Uu + (0x00bc6, 0x00bc8,), # Tamil Vowel Sign E ..Tamil Vowel Sign Ai + (0x00bca, 0x00bcd,), # Tamil Vowel Sign O ..Tamil Sign Virama + (0x00bd7, 0x00bd7,), # Tamil Au Length Mark + (0x00c01, 0x00c03,), # Telugu Sign Candrabindu ..Telugu Sign Visarga + (0x00c3e, 0x00c44,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Vocali (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali + (0x00c82, 0x00c83,), # Kannada Sign Anusvara ..Kannada Sign Visarga (0x00cbc, 0x00cbc,), # Kannada Sign Nukta - (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I - (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E - (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00cbe, 0x00cc4,), # Kannada Vowel Sign Aa ..Kannada Vowel Sign Vocal + (0x00cc6, 0x00cc8,), # Kannada Vowel Sign E ..Kannada Vowel Sign Ai + (0x00cca, 0x00ccd,), # Kannada Vowel Sign O ..Kannada Sign Virama + (0x00cd5, 0x00cd6,), # Kannada Length Mark ..Kannada Ai Length Mark (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal - (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc - (0x00d4d, 0x00d4d,), # Malayalam Sign Virama + (0x00d02, 0x00d03,), # Malayalam Sign Anusvara ..Malayalam Sign Visarga + (0x00d3e, 0x00d44,), # Malayalam Vowel Sign Aa ..Malayalam Vowel Sign Voc + (0x00d46, 0x00d48,), # Malayalam Vowel Sign E ..Malayalam Vowel Sign Ai + (0x00d4a, 0x00d4d,), # Malayalam Vowel Sign O ..Malayalam Sign Virama + (0x00d57, 0x00d57,), # Malayalam Au Length Mark (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00d82, 0x00d83,), # Sinhala Sign Anusvaraya ..Sinhala Sign Visargaya (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna - (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dcf, 0x00dd4,), # Sinhala Vowel Sign Aela-..Sinhala Vowel Sign Ketti (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga Paa-pilla + (0x00dd8, 0x00ddf,), # Sinhala Vowel Sign Gaett..Sinhala Vowel Sign Gayan + (0x00df2, 0x00df3,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga (0x00e31, 0x00e31,), # Thai Character Mai Han-akat (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan @@ -925,75 +1001,60 @@ ZERO_WIDTH = { (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung Nyi Zla (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung Sgor Rtags (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru - (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga - (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f3e, 0x00f3f,), # Tibetan Sign Yar Tshes ..Tibetan Sign Mar Tshes + (0x00f71, 0x00f84,), # Tibetan Vowel Sign Aa ..Tibetan Mark Halanta (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gdan - (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu - (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below - (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat - (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M - (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0102b, 0x0103e,), # Myanmar Vowel Sign Tall ..Myanmar Consonant Sign M + (0x01056, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01062, 0x01064,), # Myanmar Vowel Sign Sgaw ..Myanmar Tone Mark Sgaw K + (0x01067, 0x0106d,), # Myanmar Vowel Sign Weste..Myanmar Sign Western Pwo (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah - (0x01082, 0x01082,), # Myanmar Consonant Sign Shan Medial Wa - (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan - (0x0108d, 0x0108d,), # Myanmar Sign Shan Council Emphatic Tone - (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton Ai + (0x01082, 0x0108d,), # Myanmar Consonant Sign S..Myanmar Sign Shan Counci + (0x0108f, 0x0108f,), # Myanmar Sign Rumai Palaung Tone-5 + (0x0109a, 0x0109d,), # Myanmar Sign Khamti Tone..Myanmar Vowel Sign Aiton (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U - (0x017b4, 0x017b5,), # Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa - (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua - (0x017c6, 0x017c6,), # Khmer Sign Nikahit - (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017b4, 0x017d3,), # Khmer Vowel Inherent Aq ..Khmer Sign Bathamasat (0x017dd, 0x017dd,), # Khmer Sign Atthacan (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation (0x018a9, 0x018a9,), # Mongolian Letter Ali Gali Dagalga - (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U - (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O - (0x01932, 0x01932,), # Limbu Small Letter Anusvara - (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i - (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U - (0x01a56, 0x01a56,), # Tai Tham Consonant Sign Medial La - (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign - (0x01a60, 0x01a60,), # Tai Tham Sign Sakot - (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai Sat - (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B - (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01920, 0x0192b,), # Limbu Vowel Sign A ..Limbu Subjoined Letter W + (0x01930, 0x0193b,), # Limbu Small Letter Ka ..Limbu Sign Sa-i + (0x019b0, 0x019c0,), # New Tai Lue Vowel Sign V..New Tai Lue Vowel Sign I + (0x019c8, 0x019c9,), # New Tai Lue Tone Mark-1 ..New Tai Lue Tone Mark-2 + (0x01a17, 0x01a1b,), # Buginese Vowel Sign I ..Buginese Vowel Sign Ae + (0x01a55, 0x01a5e,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a60, 0x01a7c,), # Tai Tham Sign Sakot ..Tai Tham Sign Khuen-lue (0x01a7f, 0x01a7f,), # Tai Tham Combining Cryptogrammic Dot - (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang - (0x01b34, 0x01b34,), # Balinese Sign Rerekan - (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R - (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La Lenga - (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepet + (0x01b00, 0x01b04,), # Balinese Sign Ulu Ricem ..Balinese Sign Bisah + (0x01b34, 0x01b44,), # Balinese Sign Rerekan ..Balinese Adeg Adeg (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol - (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar - (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan - (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan - (0x01bab, 0x01bab,), # Sundanese Sign Virama - (0x01be6, 0x01be6,), # Batak Sign Tompi - (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee - (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O - (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H - (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T - (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01b80, 0x01b82,), # Sundanese Sign Panyecek ..Sundanese Sign Pangwisad + (0x01ba1, 0x01bad,), # Sundanese Consonant Sign..Sundanese Consonant Sign + (0x01be6, 0x01bf3,), # Batak Sign Tompi ..Batak Panongonan + (0x01c24, 0x01c37,), # Lepcha Subjoined Letter ..Lepcha Sign Nukta (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha - (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash - (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01cd4, 0x01ce8,), # Vedic Sign Yajurvedic Mi..Vedic Sign Visarga Anuda (0x01ced, 0x01ced,), # Vedic Sign Tiryak - (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above + (0x01cf2, 0x01cf4,), # Vedic Sign Ardhavisarga ..Vedic Tone Candra Above (0x01dc0, 0x01de6,), # Combining Dotted Grave A..Combining Latin Small Le (0x01dfc, 0x01dff,), # Combining Double Inverte..Combining Right Arrowhea + (0x0200b, 0x0200f,), # Zero Width Space ..Right-to-left Mark + (0x02028, 0x0202e,), # Line Separator ..Right-to-left Override + (0x02060, 0x02064,), # Word Joiner ..Invisible Plus + (0x0206a, 0x0206f,), # Inhibit Symmetric Swappi..Nominal Digit Shapes (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joiner (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette - (0x0302a, 0x0302d,), # Ideographic Level Tone M..Ideographic Entering Ton + (0x0302a, 0x0302f,), # Ideographic Level Tone M..Hangul Double Dot Tone M (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer @@ -1002,65 +1063,65 @@ ZERO_WIDTH = { (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisvara (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasanta (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusvara - (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign - (0x0a8c4, 0x0a8c4,), # Saurashtra Sign Virama + (0x0a823, 0x0a827,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a880, 0x0a881,), # Saurashtra Sign Anusvara..Saurashtra Sign Visarga + (0x0a8b4, 0x0a8c4,), # Saurashtra Consonant Sig..Saurashtra Sign Virama (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop - (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R - (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar - (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu - (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku - (0x0a9bc, 0x0a9bc,), # Javanese Vowel Sign Pepet - (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe - (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue - (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0a947, 0x0a953,), # Rejang Vowel Sign I ..Rejang Virama + (0x0a980, 0x0a983,), # Javanese Sign Panyangga ..Javanese Sign Wignyan + (0x0a9b3, 0x0a9c0,), # Javanese Sign Cecak Telu..Javanese Pangkon + (0x0aa29, 0x0aa36,), # Cham Vowel Sign Aa ..Cham Consonant Sign Wa (0x0aa43, 0x0aa43,), # Cham Consonant Sign Final Ng - (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Final M + (0x0aa4c, 0x0aa4d,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa7b, 0x0aa7b,), # Myanmar Sign Pao Karen Tone (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho - (0x0aaec, 0x0aaed,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign - (0x0aaf6, 0x0aaf6,), # Meetei Mayek Virama - (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign Anap - (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign Unap - (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek + (0x0aaeb, 0x0aaef,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf5, 0x0aaf6,), # Meetei Mayek Vowel Sign ..Meetei Mayek Virama + (0x0abe3, 0x0abea,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abec, 0x0abed,), # Meetei Mayek Lum Iyek ..Meetei Mayek Apun Iyek (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spanish Varika (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 (0x0fe20, 0x0fe26,), # Combining Ligature Left ..Combining Conjoining Mac + (0x0feff, 0x0feff,), # Zero Width No-break Space + (0x0fff9, 0x0fffb,), # Interlinear Annotation A..Interlinear Annotation T (0x101fd, 0x101fd,), # Phaistos Disc Sign Combining Oblique Stroke (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo (0x10a3f, 0x10a3f,), # Kharoshthi Virama - (0x11001, 0x11001,), # Brahmi Sign Anusvara + (0x11000, 0x11002,), # Brahmi Sign Candrabindu ..Brahmi Sign Visarga (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama - (0x11080, 0x11081,), # Kaithi Sign Candrabindu ..Kaithi Sign Anusvara - (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai - (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x11080, 0x11082,), # Kaithi Sign Candrabindu ..Kaithi Sign Visarga + (0x110b0, 0x110ba,), # Kaithi Vowel Sign Aa ..Kaithi Sign Nukta + (0x110bd, 0x110bd,), # Kaithi Number Sign (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga - (0x11127, 0x1112b,), # Chakma Vowel Sign A ..Chakma Vowel Sign Uu - (0x1112d, 0x11134,), # Chakma Vowel Sign Ai ..Chakma Maayyaa - (0x11180, 0x11181,), # Sharada Sign Candrabindu..Sharada Sign Anusvara - (0x111b6, 0x111be,), # Sharada Vowel Sign U ..Sharada Vowel Sign O - (0x116ab, 0x116ab,), # Takri Sign Anusvara - (0x116ad, 0x116ad,), # Takri Vowel Sign Aa - (0x116b0, 0x116b5,), # Takri Vowel Sign U ..Takri Vowel Sign Au - (0x116b7, 0x116b7,), # Takri Sign Nukta + (0x11127, 0x11134,), # Chakma Vowel Sign A ..Chakma Maayyaa + (0x11180, 0x11182,), # Sharada Sign Candrabindu..Sharada Sign Visarga + (0x111b3, 0x111c0,), # Sharada Vowel Sign Aa ..Sharada Sign Virama + (0x116ab, 0x116b7,), # Takri Sign Anusvara ..Takri Sign Nukta + (0x16f51, 0x16f7e,), # Miao Sign Aspiration ..Miao Vowel Sign Ng (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below - (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining - (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d165, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d16d, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0xe0001, 0xe0001,), # Language Tag + (0xe0020, 0xe007f,), # Tag Space ..Cancel Tag (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 ), '6.2.0': ( # Source: DerivedGeneralCategory-6.2.0.txt # Date: 2012-05-20, 00:42:34 GMT [MD] # + (0x00000, 0x00000,), # (nil) + (0x000ad, 0x000ad,), # Soft Hyphen (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg @@ -1068,13 +1129,15 @@ ZERO_WIDTH = { (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot (0x005c7, 0x005c7,), # Hebrew Point Qamats Qatan + (0x00600, 0x00604,), # Arabic Number Sign ..Arabic Sign Samvat (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below (0x00670, 0x00670,), # Arabic Letter Superscript Alef - (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006d6, 0x006dd,), # Arabic Small High Ligatu..Arabic End Of Ayah (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x0070f, 0x0070f,), # Syriac Abbreviation Mark (0x00711, 0x00711,), # Syriac Letter Superscript Alaph (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun @@ -1085,58 +1148,69 @@ ZERO_WIDTH = { (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark (0x008e4, 0x008fe,), # Arabic Curly Fatha ..Arabic Damma With Dot - (0x00900, 0x00902,), # Devanagari Sign Inverted..Devanagari Sign Anusvara - (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe - (0x0093c, 0x0093c,), # Devanagari Sign Nukta - (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai - (0x0094d, 0x0094d,), # Devanagari Sign Virama + (0x00900, 0x00903,), # Devanagari Sign Inverted..Devanagari Sign Visarga + (0x0093a, 0x0093c,), # Devanagari Vowel Sign Oe..Devanagari Sign Nukta + (0x0093e, 0x0094f,), # Devanagari Vowel Sign Aa..Devanagari Vowel Sign Aw (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo - (0x00981, 0x00981,), # Bengali Sign Candrabindu + (0x00981, 0x00983,), # Bengali Sign Candrabindu..Bengali Sign Visarga (0x009bc, 0x009bc,), # Bengali Sign Nukta - (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal - (0x009cd, 0x009cd,), # Bengali Sign Virama + (0x009be, 0x009c4,), # Bengali Vowel Sign Aa ..Bengali Vowel Sign Vocal + (0x009c7, 0x009c8,), # Bengali Vowel Sign E ..Bengali Vowel Sign Ai + (0x009cb, 0x009cd,), # Bengali Vowel Sign O ..Bengali Sign Virama + (0x009d7, 0x009d7,), # Bengali Au Length Mark (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal - (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a01, 0x00a03,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Visarga (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta - (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a3e, 0x00a42,), # Gurmukhi Vowel Sign Aa ..Gurmukhi Vowel Sign Uu (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash - (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00a81, 0x00a83,), # Gujarati Sign Candrabind..Gujarati Sign Visarga (0x00abc, 0x00abc,), # Gujarati Sign Nukta - (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand - (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai - (0x00acd, 0x00acd,), # Gujarati Sign Virama + (0x00abe, 0x00ac5,), # Gujarati Vowel Sign Aa ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac9,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Cand + (0x00acb, 0x00acd,), # Gujarati Vowel Sign O ..Gujarati Sign Virama (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca - (0x00b01, 0x00b01,), # Oriya Sign Candrabindu + (0x00b01, 0x00b03,), # Oriya Sign Candrabindu ..Oriya Sign Visarga (0x00b3c, 0x00b3c,), # Oriya Sign Nukta - (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I - (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic - (0x00b4d, 0x00b4d,), # Oriya Sign Virama - (0x00b56, 0x00b56,), # Oriya Ai Length Mark + (0x00b3e, 0x00b44,), # Oriya Vowel Sign Aa ..Oriya Vowel Sign Vocalic + (0x00b47, 0x00b48,), # Oriya Vowel Sign E ..Oriya Vowel Sign Ai + (0x00b4b, 0x00b4d,), # Oriya Vowel Sign O ..Oriya Sign Virama + (0x00b56, 0x00b57,), # Oriya Ai Length Mark ..Oriya Au Length Mark (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic (0x00b82, 0x00b82,), # Tamil Sign Anusvara - (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii - (0x00bcd, 0x00bcd,), # Tamil Sign Virama - (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00bbe, 0x00bc2,), # Tamil Vowel Sign Aa ..Tamil Vowel Sign Uu + (0x00bc6, 0x00bc8,), # Tamil Vowel Sign E ..Tamil Vowel Sign Ai + (0x00bca, 0x00bcd,), # Tamil Vowel Sign O ..Tamil Sign Virama + (0x00bd7, 0x00bd7,), # Tamil Au Length Mark + (0x00c01, 0x00c03,), # Telugu Sign Candrabindu ..Telugu Sign Visarga + (0x00c3e, 0x00c44,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Vocali (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali + (0x00c82, 0x00c83,), # Kannada Sign Anusvara ..Kannada Sign Visarga (0x00cbc, 0x00cbc,), # Kannada Sign Nukta - (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I - (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E - (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00cbe, 0x00cc4,), # Kannada Vowel Sign Aa ..Kannada Vowel Sign Vocal + (0x00cc6, 0x00cc8,), # Kannada Vowel Sign E ..Kannada Vowel Sign Ai + (0x00cca, 0x00ccd,), # Kannada Vowel Sign O ..Kannada Sign Virama + (0x00cd5, 0x00cd6,), # Kannada Length Mark ..Kannada Ai Length Mark (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal - (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc - (0x00d4d, 0x00d4d,), # Malayalam Sign Virama + (0x00d02, 0x00d03,), # Malayalam Sign Anusvara ..Malayalam Sign Visarga + (0x00d3e, 0x00d44,), # Malayalam Vowel Sign Aa ..Malayalam Vowel Sign Voc + (0x00d46, 0x00d48,), # Malayalam Vowel Sign E ..Malayalam Vowel Sign Ai + (0x00d4a, 0x00d4d,), # Malayalam Vowel Sign O ..Malayalam Sign Virama + (0x00d57, 0x00d57,), # Malayalam Au Length Mark (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00d82, 0x00d83,), # Sinhala Sign Anusvaraya ..Sinhala Sign Visargaya (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna - (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dcf, 0x00dd4,), # Sinhala Vowel Sign Aela-..Sinhala Vowel Sign Ketti (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga Paa-pilla + (0x00dd8, 0x00ddf,), # Sinhala Vowel Sign Gaett..Sinhala Vowel Sign Gayan + (0x00df2, 0x00df3,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga (0x00e31, 0x00e31,), # Thai Character Mai Han-akat (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan @@ -1148,75 +1222,60 @@ ZERO_WIDTH = { (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung Nyi Zla (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung Sgor Rtags (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru - (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga - (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f3e, 0x00f3f,), # Tibetan Sign Yar Tshes ..Tibetan Sign Mar Tshes + (0x00f71, 0x00f84,), # Tibetan Vowel Sign Aa ..Tibetan Mark Halanta (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gdan - (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu - (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below - (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat - (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M - (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0102b, 0x0103e,), # Myanmar Vowel Sign Tall ..Myanmar Consonant Sign M + (0x01056, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01062, 0x01064,), # Myanmar Vowel Sign Sgaw ..Myanmar Tone Mark Sgaw K + (0x01067, 0x0106d,), # Myanmar Vowel Sign Weste..Myanmar Sign Western Pwo (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah - (0x01082, 0x01082,), # Myanmar Consonant Sign Shan Medial Wa - (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan - (0x0108d, 0x0108d,), # Myanmar Sign Shan Council Emphatic Tone - (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton Ai + (0x01082, 0x0108d,), # Myanmar Consonant Sign S..Myanmar Sign Shan Counci + (0x0108f, 0x0108f,), # Myanmar Sign Rumai Palaung Tone-5 + (0x0109a, 0x0109d,), # Myanmar Sign Khamti Tone..Myanmar Vowel Sign Aiton (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U - (0x017b4, 0x017b5,), # Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa - (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua - (0x017c6, 0x017c6,), # Khmer Sign Nikahit - (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017b4, 0x017d3,), # Khmer Vowel Inherent Aq ..Khmer Sign Bathamasat (0x017dd, 0x017dd,), # Khmer Sign Atthacan (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation (0x018a9, 0x018a9,), # Mongolian Letter Ali Gali Dagalga - (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U - (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O - (0x01932, 0x01932,), # Limbu Small Letter Anusvara - (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i - (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U - (0x01a56, 0x01a56,), # Tai Tham Consonant Sign Medial La - (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign - (0x01a60, 0x01a60,), # Tai Tham Sign Sakot - (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai Sat - (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B - (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01920, 0x0192b,), # Limbu Vowel Sign A ..Limbu Subjoined Letter W + (0x01930, 0x0193b,), # Limbu Small Letter Ka ..Limbu Sign Sa-i + (0x019b0, 0x019c0,), # New Tai Lue Vowel Sign V..New Tai Lue Vowel Sign I + (0x019c8, 0x019c9,), # New Tai Lue Tone Mark-1 ..New Tai Lue Tone Mark-2 + (0x01a17, 0x01a1b,), # Buginese Vowel Sign I ..Buginese Vowel Sign Ae + (0x01a55, 0x01a5e,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a60, 0x01a7c,), # Tai Tham Sign Sakot ..Tai Tham Sign Khuen-lue (0x01a7f, 0x01a7f,), # Tai Tham Combining Cryptogrammic Dot - (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang - (0x01b34, 0x01b34,), # Balinese Sign Rerekan - (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R - (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La Lenga - (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepet + (0x01b00, 0x01b04,), # Balinese Sign Ulu Ricem ..Balinese Sign Bisah + (0x01b34, 0x01b44,), # Balinese Sign Rerekan ..Balinese Adeg Adeg (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol - (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar - (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan - (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan - (0x01bab, 0x01bab,), # Sundanese Sign Virama - (0x01be6, 0x01be6,), # Batak Sign Tompi - (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee - (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O - (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H - (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T - (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01b80, 0x01b82,), # Sundanese Sign Panyecek ..Sundanese Sign Pangwisad + (0x01ba1, 0x01bad,), # Sundanese Consonant Sign..Sundanese Consonant Sign + (0x01be6, 0x01bf3,), # Batak Sign Tompi ..Batak Panongonan + (0x01c24, 0x01c37,), # Lepcha Subjoined Letter ..Lepcha Sign Nukta (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha - (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash - (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01cd4, 0x01ce8,), # Vedic Sign Yajurvedic Mi..Vedic Sign Visarga Anuda (0x01ced, 0x01ced,), # Vedic Sign Tiryak - (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above + (0x01cf2, 0x01cf4,), # Vedic Sign Ardhavisarga ..Vedic Tone Candra Above (0x01dc0, 0x01de6,), # Combining Dotted Grave A..Combining Latin Small Le (0x01dfc, 0x01dff,), # Combining Double Inverte..Combining Right Arrowhea + (0x0200b, 0x0200f,), # Zero Width Space ..Right-to-left Mark + (0x02028, 0x0202e,), # Line Separator ..Right-to-left Override + (0x02060, 0x02064,), # Word Joiner ..Invisible Plus + (0x0206a, 0x0206f,), # Inhibit Symmetric Swappi..Nominal Digit Shapes (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joiner (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette - (0x0302a, 0x0302d,), # Ideographic Level Tone M..Ideographic Entering Ton + (0x0302a, 0x0302f,), # Ideographic Level Tone M..Hangul Double Dot Tone M (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer @@ -1225,65 +1284,65 @@ ZERO_WIDTH = { (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisvara (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasanta (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusvara - (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign - (0x0a8c4, 0x0a8c4,), # Saurashtra Sign Virama + (0x0a823, 0x0a827,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a880, 0x0a881,), # Saurashtra Sign Anusvara..Saurashtra Sign Visarga + (0x0a8b4, 0x0a8c4,), # Saurashtra Consonant Sig..Saurashtra Sign Virama (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop - (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R - (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar - (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu - (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku - (0x0a9bc, 0x0a9bc,), # Javanese Vowel Sign Pepet - (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe - (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue - (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0a947, 0x0a953,), # Rejang Vowel Sign I ..Rejang Virama + (0x0a980, 0x0a983,), # Javanese Sign Panyangga ..Javanese Sign Wignyan + (0x0a9b3, 0x0a9c0,), # Javanese Sign Cecak Telu..Javanese Pangkon + (0x0aa29, 0x0aa36,), # Cham Vowel Sign Aa ..Cham Consonant Sign Wa (0x0aa43, 0x0aa43,), # Cham Consonant Sign Final Ng - (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Final M + (0x0aa4c, 0x0aa4d,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa7b, 0x0aa7b,), # Myanmar Sign Pao Karen Tone (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho - (0x0aaec, 0x0aaed,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign - (0x0aaf6, 0x0aaf6,), # Meetei Mayek Virama - (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign Anap - (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign Unap - (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek + (0x0aaeb, 0x0aaef,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf5, 0x0aaf6,), # Meetei Mayek Vowel Sign ..Meetei Mayek Virama + (0x0abe3, 0x0abea,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abec, 0x0abed,), # Meetei Mayek Lum Iyek ..Meetei Mayek Apun Iyek (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spanish Varika (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 (0x0fe20, 0x0fe26,), # Combining Ligature Left ..Combining Conjoining Mac + (0x0feff, 0x0feff,), # Zero Width No-break Space + (0x0fff9, 0x0fffb,), # Interlinear Annotation A..Interlinear Annotation T (0x101fd, 0x101fd,), # Phaistos Disc Sign Combining Oblique Stroke (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo (0x10a3f, 0x10a3f,), # Kharoshthi Virama - (0x11001, 0x11001,), # Brahmi Sign Anusvara + (0x11000, 0x11002,), # Brahmi Sign Candrabindu ..Brahmi Sign Visarga (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama - (0x11080, 0x11081,), # Kaithi Sign Candrabindu ..Kaithi Sign Anusvara - (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai - (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x11080, 0x11082,), # Kaithi Sign Candrabindu ..Kaithi Sign Visarga + (0x110b0, 0x110ba,), # Kaithi Vowel Sign Aa ..Kaithi Sign Nukta + (0x110bd, 0x110bd,), # Kaithi Number Sign (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga - (0x11127, 0x1112b,), # Chakma Vowel Sign A ..Chakma Vowel Sign Uu - (0x1112d, 0x11134,), # Chakma Vowel Sign Ai ..Chakma Maayyaa - (0x11180, 0x11181,), # Sharada Sign Candrabindu..Sharada Sign Anusvara - (0x111b6, 0x111be,), # Sharada Vowel Sign U ..Sharada Vowel Sign O - (0x116ab, 0x116ab,), # Takri Sign Anusvara - (0x116ad, 0x116ad,), # Takri Vowel Sign Aa - (0x116b0, 0x116b5,), # Takri Vowel Sign U ..Takri Vowel Sign Au - (0x116b7, 0x116b7,), # Takri Sign Nukta + (0x11127, 0x11134,), # Chakma Vowel Sign A ..Chakma Maayyaa + (0x11180, 0x11182,), # Sharada Sign Candrabindu..Sharada Sign Visarga + (0x111b3, 0x111c0,), # Sharada Vowel Sign Aa ..Sharada Sign Virama + (0x116ab, 0x116b7,), # Takri Sign Anusvara ..Takri Sign Nukta + (0x16f51, 0x16f7e,), # Miao Sign Aspiration ..Miao Vowel Sign Ng (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below - (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining - (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d165, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d16d, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0xe0001, 0xe0001,), # Language Tag + (0xe0020, 0xe007f,), # Tag Space ..Cancel Tag (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 ), '6.3.0': ( # Source: DerivedGeneralCategory-6.3.0.txt # Date: 2013-07-05, 14:08:45 GMT [MD] # + (0x00000, 0x00000,), # (nil) + (0x000ad, 0x000ad,), # Soft Hyphen (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg @@ -1291,13 +1350,16 @@ ZERO_WIDTH = { (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot (0x005c7, 0x005c7,), # Hebrew Point Qamats Qatan + (0x00600, 0x00604,), # Arabic Number Sign ..Arabic Sign Samvat (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0061c, 0x0061c,), # Arabic Letter Mark (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below (0x00670, 0x00670,), # Arabic Letter Superscript Alef - (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006d6, 0x006dd,), # Arabic Small High Ligatu..Arabic End Of Ayah (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x0070f, 0x0070f,), # Syriac Abbreviation Mark (0x00711, 0x00711,), # Syriac Letter Superscript Alaph (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun @@ -1308,58 +1370,69 @@ ZERO_WIDTH = { (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark (0x008e4, 0x008fe,), # Arabic Curly Fatha ..Arabic Damma With Dot - (0x00900, 0x00902,), # Devanagari Sign Inverted..Devanagari Sign Anusvara - (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe - (0x0093c, 0x0093c,), # Devanagari Sign Nukta - (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai - (0x0094d, 0x0094d,), # Devanagari Sign Virama + (0x00900, 0x00903,), # Devanagari Sign Inverted..Devanagari Sign Visarga + (0x0093a, 0x0093c,), # Devanagari Vowel Sign Oe..Devanagari Sign Nukta + (0x0093e, 0x0094f,), # Devanagari Vowel Sign Aa..Devanagari Vowel Sign Aw (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo - (0x00981, 0x00981,), # Bengali Sign Candrabindu + (0x00981, 0x00983,), # Bengali Sign Candrabindu..Bengali Sign Visarga (0x009bc, 0x009bc,), # Bengali Sign Nukta - (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal - (0x009cd, 0x009cd,), # Bengali Sign Virama + (0x009be, 0x009c4,), # Bengali Vowel Sign Aa ..Bengali Vowel Sign Vocal + (0x009c7, 0x009c8,), # Bengali Vowel Sign E ..Bengali Vowel Sign Ai + (0x009cb, 0x009cd,), # Bengali Vowel Sign O ..Bengali Sign Virama + (0x009d7, 0x009d7,), # Bengali Au Length Mark (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal - (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a01, 0x00a03,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Visarga (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta - (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a3e, 0x00a42,), # Gurmukhi Vowel Sign Aa ..Gurmukhi Vowel Sign Uu (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash - (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00a81, 0x00a83,), # Gujarati Sign Candrabind..Gujarati Sign Visarga (0x00abc, 0x00abc,), # Gujarati Sign Nukta - (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand - (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai - (0x00acd, 0x00acd,), # Gujarati Sign Virama + (0x00abe, 0x00ac5,), # Gujarati Vowel Sign Aa ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac9,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Cand + (0x00acb, 0x00acd,), # Gujarati Vowel Sign O ..Gujarati Sign Virama (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca - (0x00b01, 0x00b01,), # Oriya Sign Candrabindu + (0x00b01, 0x00b03,), # Oriya Sign Candrabindu ..Oriya Sign Visarga (0x00b3c, 0x00b3c,), # Oriya Sign Nukta - (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I - (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic - (0x00b4d, 0x00b4d,), # Oriya Sign Virama - (0x00b56, 0x00b56,), # Oriya Ai Length Mark + (0x00b3e, 0x00b44,), # Oriya Vowel Sign Aa ..Oriya Vowel Sign Vocalic + (0x00b47, 0x00b48,), # Oriya Vowel Sign E ..Oriya Vowel Sign Ai + (0x00b4b, 0x00b4d,), # Oriya Vowel Sign O ..Oriya Sign Virama + (0x00b56, 0x00b57,), # Oriya Ai Length Mark ..Oriya Au Length Mark (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic (0x00b82, 0x00b82,), # Tamil Sign Anusvara - (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii - (0x00bcd, 0x00bcd,), # Tamil Sign Virama - (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00bbe, 0x00bc2,), # Tamil Vowel Sign Aa ..Tamil Vowel Sign Uu + (0x00bc6, 0x00bc8,), # Tamil Vowel Sign E ..Tamil Vowel Sign Ai + (0x00bca, 0x00bcd,), # Tamil Vowel Sign O ..Tamil Sign Virama + (0x00bd7, 0x00bd7,), # Tamil Au Length Mark + (0x00c01, 0x00c03,), # Telugu Sign Candrabindu ..Telugu Sign Visarga + (0x00c3e, 0x00c44,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Vocali (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali + (0x00c82, 0x00c83,), # Kannada Sign Anusvara ..Kannada Sign Visarga (0x00cbc, 0x00cbc,), # Kannada Sign Nukta - (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I - (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E - (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00cbe, 0x00cc4,), # Kannada Vowel Sign Aa ..Kannada Vowel Sign Vocal + (0x00cc6, 0x00cc8,), # Kannada Vowel Sign E ..Kannada Vowel Sign Ai + (0x00cca, 0x00ccd,), # Kannada Vowel Sign O ..Kannada Sign Virama + (0x00cd5, 0x00cd6,), # Kannada Length Mark ..Kannada Ai Length Mark (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal - (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc - (0x00d4d, 0x00d4d,), # Malayalam Sign Virama + (0x00d02, 0x00d03,), # Malayalam Sign Anusvara ..Malayalam Sign Visarga + (0x00d3e, 0x00d44,), # Malayalam Vowel Sign Aa ..Malayalam Vowel Sign Voc + (0x00d46, 0x00d48,), # Malayalam Vowel Sign E ..Malayalam Vowel Sign Ai + (0x00d4a, 0x00d4d,), # Malayalam Vowel Sign O ..Malayalam Sign Virama + (0x00d57, 0x00d57,), # Malayalam Au Length Mark (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00d82, 0x00d83,), # Sinhala Sign Anusvaraya ..Sinhala Sign Visargaya (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna - (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dcf, 0x00dd4,), # Sinhala Vowel Sign Aela-..Sinhala Vowel Sign Ketti (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga Paa-pilla + (0x00dd8, 0x00ddf,), # Sinhala Vowel Sign Gaett..Sinhala Vowel Sign Gayan + (0x00df2, 0x00df3,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga (0x00e31, 0x00e31,), # Thai Character Mai Han-akat (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan @@ -1371,76 +1444,60 @@ ZERO_WIDTH = { (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung Nyi Zla (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung Sgor Rtags (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru - (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga - (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f3e, 0x00f3f,), # Tibetan Sign Yar Tshes ..Tibetan Sign Mar Tshes + (0x00f71, 0x00f84,), # Tibetan Vowel Sign Aa ..Tibetan Mark Halanta (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gdan - (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu - (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below - (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat - (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M - (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0102b, 0x0103e,), # Myanmar Vowel Sign Tall ..Myanmar Consonant Sign M + (0x01056, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01062, 0x01064,), # Myanmar Vowel Sign Sgaw ..Myanmar Tone Mark Sgaw K + (0x01067, 0x0106d,), # Myanmar Vowel Sign Weste..Myanmar Sign Western Pwo (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah - (0x01082, 0x01082,), # Myanmar Consonant Sign Shan Medial Wa - (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan - (0x0108d, 0x0108d,), # Myanmar Sign Shan Council Emphatic Tone - (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton Ai + (0x01082, 0x0108d,), # Myanmar Consonant Sign S..Myanmar Sign Shan Counci + (0x0108f, 0x0108f,), # Myanmar Sign Rumai Palaung Tone-5 + (0x0109a, 0x0109d,), # Myanmar Sign Khamti Tone..Myanmar Vowel Sign Aiton (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U - (0x017b4, 0x017b5,), # Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa - (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua - (0x017c6, 0x017c6,), # Khmer Sign Nikahit - (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017b4, 0x017d3,), # Khmer Vowel Inherent Aq ..Khmer Sign Bathamasat (0x017dd, 0x017dd,), # Khmer Sign Atthacan - (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x0180b, 0x0180e,), # Mongolian Free Variation..Mongolian Vowel Separato (0x018a9, 0x018a9,), # Mongolian Letter Ali Gali Dagalga - (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U - (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O - (0x01932, 0x01932,), # Limbu Small Letter Anusvara - (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i - (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U - (0x01a1b, 0x01a1b,), # Buginese Vowel Sign Ae - (0x01a56, 0x01a56,), # Tai Tham Consonant Sign Medial La - (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign - (0x01a60, 0x01a60,), # Tai Tham Sign Sakot - (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai Sat - (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B - (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01920, 0x0192b,), # Limbu Vowel Sign A ..Limbu Subjoined Letter W + (0x01930, 0x0193b,), # Limbu Small Letter Ka ..Limbu Sign Sa-i + (0x019b0, 0x019c0,), # New Tai Lue Vowel Sign V..New Tai Lue Vowel Sign I + (0x019c8, 0x019c9,), # New Tai Lue Tone Mark-1 ..New Tai Lue Tone Mark-2 + (0x01a17, 0x01a1b,), # Buginese Vowel Sign I ..Buginese Vowel Sign Ae + (0x01a55, 0x01a5e,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a60, 0x01a7c,), # Tai Tham Sign Sakot ..Tai Tham Sign Khuen-lue (0x01a7f, 0x01a7f,), # Tai Tham Combining Cryptogrammic Dot - (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang - (0x01b34, 0x01b34,), # Balinese Sign Rerekan - (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R - (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La Lenga - (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepet + (0x01b00, 0x01b04,), # Balinese Sign Ulu Ricem ..Balinese Sign Bisah + (0x01b34, 0x01b44,), # Balinese Sign Rerekan ..Balinese Adeg Adeg (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol - (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar - (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan - (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan - (0x01bab, 0x01bab,), # Sundanese Sign Virama - (0x01be6, 0x01be6,), # Batak Sign Tompi - (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee - (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O - (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H - (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T - (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01b80, 0x01b82,), # Sundanese Sign Panyecek ..Sundanese Sign Pangwisad + (0x01ba1, 0x01bad,), # Sundanese Consonant Sign..Sundanese Consonant Sign + (0x01be6, 0x01bf3,), # Batak Sign Tompi ..Batak Panongonan + (0x01c24, 0x01c37,), # Lepcha Subjoined Letter ..Lepcha Sign Nukta (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha - (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash - (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01cd4, 0x01ce8,), # Vedic Sign Yajurvedic Mi..Vedic Sign Visarga Anuda (0x01ced, 0x01ced,), # Vedic Sign Tiryak - (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above + (0x01cf2, 0x01cf4,), # Vedic Sign Ardhavisarga ..Vedic Tone Candra Above (0x01dc0, 0x01de6,), # Combining Dotted Grave A..Combining Latin Small Le (0x01dfc, 0x01dff,), # Combining Double Inverte..Combining Right Arrowhea + (0x0200b, 0x0200f,), # Zero Width Space ..Right-to-left Mark + (0x02028, 0x0202e,), # Line Separator ..Right-to-left Override + (0x02060, 0x02064,), # Word Joiner ..Invisible Plus + (0x02066, 0x0206f,), # Left-to-right Isolate ..Nominal Digit Shapes (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joiner (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette - (0x0302a, 0x0302d,), # Ideographic Level Tone M..Ideographic Entering Ton + (0x0302a, 0x0302f,), # Ideographic Level Tone M..Hangul Double Dot Tone M (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer @@ -1449,65 +1506,65 @@ ZERO_WIDTH = { (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisvara (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasanta (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusvara - (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign - (0x0a8c4, 0x0a8c4,), # Saurashtra Sign Virama + (0x0a823, 0x0a827,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a880, 0x0a881,), # Saurashtra Sign Anusvara..Saurashtra Sign Visarga + (0x0a8b4, 0x0a8c4,), # Saurashtra Consonant Sig..Saurashtra Sign Virama (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop - (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R - (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar - (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu - (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku - (0x0a9bc, 0x0a9bc,), # Javanese Vowel Sign Pepet - (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe - (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue - (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0a947, 0x0a953,), # Rejang Vowel Sign I ..Rejang Virama + (0x0a980, 0x0a983,), # Javanese Sign Panyangga ..Javanese Sign Wignyan + (0x0a9b3, 0x0a9c0,), # Javanese Sign Cecak Telu..Javanese Pangkon + (0x0aa29, 0x0aa36,), # Cham Vowel Sign Aa ..Cham Consonant Sign Wa (0x0aa43, 0x0aa43,), # Cham Consonant Sign Final Ng - (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Final M + (0x0aa4c, 0x0aa4d,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa7b, 0x0aa7b,), # Myanmar Sign Pao Karen Tone (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho - (0x0aaec, 0x0aaed,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign - (0x0aaf6, 0x0aaf6,), # Meetei Mayek Virama - (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign Anap - (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign Unap - (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek + (0x0aaeb, 0x0aaef,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf5, 0x0aaf6,), # Meetei Mayek Vowel Sign ..Meetei Mayek Virama + (0x0abe3, 0x0abea,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abec, 0x0abed,), # Meetei Mayek Lum Iyek ..Meetei Mayek Apun Iyek (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spanish Varika (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 (0x0fe20, 0x0fe26,), # Combining Ligature Left ..Combining Conjoining Mac + (0x0feff, 0x0feff,), # Zero Width No-break Space + (0x0fff9, 0x0fffb,), # Interlinear Annotation A..Interlinear Annotation T (0x101fd, 0x101fd,), # Phaistos Disc Sign Combining Oblique Stroke (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo (0x10a3f, 0x10a3f,), # Kharoshthi Virama - (0x11001, 0x11001,), # Brahmi Sign Anusvara + (0x11000, 0x11002,), # Brahmi Sign Candrabindu ..Brahmi Sign Visarga (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama - (0x11080, 0x11081,), # Kaithi Sign Candrabindu ..Kaithi Sign Anusvara - (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai - (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x11080, 0x11082,), # Kaithi Sign Candrabindu ..Kaithi Sign Visarga + (0x110b0, 0x110ba,), # Kaithi Vowel Sign Aa ..Kaithi Sign Nukta + (0x110bd, 0x110bd,), # Kaithi Number Sign (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga - (0x11127, 0x1112b,), # Chakma Vowel Sign A ..Chakma Vowel Sign Uu - (0x1112d, 0x11134,), # Chakma Vowel Sign Ai ..Chakma Maayyaa - (0x11180, 0x11181,), # Sharada Sign Candrabindu..Sharada Sign Anusvara - (0x111b6, 0x111be,), # Sharada Vowel Sign U ..Sharada Vowel Sign O - (0x116ab, 0x116ab,), # Takri Sign Anusvara - (0x116ad, 0x116ad,), # Takri Vowel Sign Aa - (0x116b0, 0x116b5,), # Takri Vowel Sign U ..Takri Vowel Sign Au - (0x116b7, 0x116b7,), # Takri Sign Nukta + (0x11127, 0x11134,), # Chakma Vowel Sign A ..Chakma Maayyaa + (0x11180, 0x11182,), # Sharada Sign Candrabindu..Sharada Sign Visarga + (0x111b3, 0x111c0,), # Sharada Vowel Sign Aa ..Sharada Sign Virama + (0x116ab, 0x116b7,), # Takri Sign Anusvara ..Takri Sign Nukta + (0x16f51, 0x16f7e,), # Miao Sign Aspiration ..Miao Vowel Sign Ng (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below - (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining - (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d165, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d16d, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0xe0001, 0xe0001,), # Language Tag + (0xe0020, 0xe007f,), # Tag Space ..Cancel Tag (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 ), '7.0.0': ( # Source: DerivedGeneralCategory-7.0.0.txt # Date: 2014-02-07, 18:42:12 GMT [MD] # + (0x00000, 0x00000,), # (nil) + (0x000ad, 0x000ad,), # Soft Hyphen (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg @@ -1515,13 +1572,16 @@ ZERO_WIDTH = { (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot (0x005c7, 0x005c7,), # Hebrew Point Qamats Qatan + (0x00600, 0x00605,), # Arabic Number Sign ..Arabic Number Mark Above (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0061c, 0x0061c,), # Arabic Letter Mark (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below (0x00670, 0x00670,), # Arabic Letter Superscript Alef - (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006d6, 0x006dd,), # Arabic Small High Ligatu..Arabic End Of Ayah (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x0070f, 0x0070f,), # Syriac Abbreviation Mark (0x00711, 0x00711,), # Syriac Letter Superscript Alaph (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun @@ -1531,61 +1591,69 @@ ZERO_WIDTH = { (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark - (0x008e4, 0x00902,), # Arabic Curly Fatha ..Devanagari Sign Anusvara - (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe - (0x0093c, 0x0093c,), # Devanagari Sign Nukta - (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai - (0x0094d, 0x0094d,), # Devanagari Sign Virama + (0x008e4, 0x00903,), # Arabic Curly Fatha ..Devanagari Sign Visarga + (0x0093a, 0x0093c,), # Devanagari Vowel Sign Oe..Devanagari Sign Nukta + (0x0093e, 0x0094f,), # Devanagari Vowel Sign Aa..Devanagari Vowel Sign Aw (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo - (0x00981, 0x00981,), # Bengali Sign Candrabindu + (0x00981, 0x00983,), # Bengali Sign Candrabindu..Bengali Sign Visarga (0x009bc, 0x009bc,), # Bengali Sign Nukta - (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal - (0x009cd, 0x009cd,), # Bengali Sign Virama + (0x009be, 0x009c4,), # Bengali Vowel Sign Aa ..Bengali Vowel Sign Vocal + (0x009c7, 0x009c8,), # Bengali Vowel Sign E ..Bengali Vowel Sign Ai + (0x009cb, 0x009cd,), # Bengali Vowel Sign O ..Bengali Sign Virama + (0x009d7, 0x009d7,), # Bengali Au Length Mark (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal - (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a01, 0x00a03,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Visarga (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta - (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a3e, 0x00a42,), # Gurmukhi Vowel Sign Aa ..Gurmukhi Vowel Sign Uu (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash - (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00a81, 0x00a83,), # Gujarati Sign Candrabind..Gujarati Sign Visarga (0x00abc, 0x00abc,), # Gujarati Sign Nukta - (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand - (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai - (0x00acd, 0x00acd,), # Gujarati Sign Virama + (0x00abe, 0x00ac5,), # Gujarati Vowel Sign Aa ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac9,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Cand + (0x00acb, 0x00acd,), # Gujarati Vowel Sign O ..Gujarati Sign Virama (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca - (0x00b01, 0x00b01,), # Oriya Sign Candrabindu + (0x00b01, 0x00b03,), # Oriya Sign Candrabindu ..Oriya Sign Visarga (0x00b3c, 0x00b3c,), # Oriya Sign Nukta - (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I - (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic - (0x00b4d, 0x00b4d,), # Oriya Sign Virama - (0x00b56, 0x00b56,), # Oriya Ai Length Mark + (0x00b3e, 0x00b44,), # Oriya Vowel Sign Aa ..Oriya Vowel Sign Vocalic + (0x00b47, 0x00b48,), # Oriya Vowel Sign E ..Oriya Vowel Sign Ai + (0x00b4b, 0x00b4d,), # Oriya Vowel Sign O ..Oriya Sign Virama + (0x00b56, 0x00b57,), # Oriya Ai Length Mark ..Oriya Au Length Mark (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic (0x00b82, 0x00b82,), # Tamil Sign Anusvara - (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii - (0x00bcd, 0x00bcd,), # Tamil Sign Virama - (0x00c00, 0x00c00,), # Telugu Sign Combining Candrabindu Above - (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00bbe, 0x00bc2,), # Tamil Vowel Sign Aa ..Tamil Vowel Sign Uu + (0x00bc6, 0x00bc8,), # Tamil Vowel Sign E ..Tamil Vowel Sign Ai + (0x00bca, 0x00bcd,), # Tamil Vowel Sign O ..Tamil Sign Virama + (0x00bd7, 0x00bd7,), # Tamil Au Length Mark + (0x00c00, 0x00c03,), # Telugu Sign Combining Ca..Telugu Sign Visarga + (0x00c3e, 0x00c44,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Vocali (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali - (0x00c81, 0x00c81,), # Kannada Sign Candrabindu + (0x00c81, 0x00c83,), # Kannada Sign Candrabindu..Kannada Sign Visarga (0x00cbc, 0x00cbc,), # Kannada Sign Nukta - (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I - (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E - (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00cbe, 0x00cc4,), # Kannada Vowel Sign Aa ..Kannada Vowel Sign Vocal + (0x00cc6, 0x00cc8,), # Kannada Vowel Sign E ..Kannada Vowel Sign Ai + (0x00cca, 0x00ccd,), # Kannada Vowel Sign O ..Kannada Sign Virama + (0x00cd5, 0x00cd6,), # Kannada Length Mark ..Kannada Ai Length Mark (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal - (0x00d01, 0x00d01,), # Malayalam Sign Candrabindu - (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc - (0x00d4d, 0x00d4d,), # Malayalam Sign Virama + (0x00d01, 0x00d03,), # Malayalam Sign Candrabin..Malayalam Sign Visarga + (0x00d3e, 0x00d44,), # Malayalam Vowel Sign Aa ..Malayalam Vowel Sign Voc + (0x00d46, 0x00d48,), # Malayalam Vowel Sign E ..Malayalam Vowel Sign Ai + (0x00d4a, 0x00d4d,), # Malayalam Vowel Sign O ..Malayalam Sign Virama + (0x00d57, 0x00d57,), # Malayalam Au Length Mark (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00d82, 0x00d83,), # Sinhala Sign Anusvaraya ..Sinhala Sign Visargaya (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna - (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dcf, 0x00dd4,), # Sinhala Vowel Sign Aela-..Sinhala Vowel Sign Ketti (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga Paa-pilla + (0x00dd8, 0x00ddf,), # Sinhala Vowel Sign Gaett..Sinhala Vowel Sign Gayan + (0x00df2, 0x00df3,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga (0x00e31, 0x00e31,), # Thai Character Mai Han-akat (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan @@ -1597,78 +1665,62 @@ ZERO_WIDTH = { (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung Nyi Zla (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung Sgor Rtags (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru - (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga - (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f3e, 0x00f3f,), # Tibetan Sign Yar Tshes ..Tibetan Sign Mar Tshes + (0x00f71, 0x00f84,), # Tibetan Vowel Sign Aa ..Tibetan Mark Halanta (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gdan - (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu - (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below - (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat - (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M - (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0102b, 0x0103e,), # Myanmar Vowel Sign Tall ..Myanmar Consonant Sign M + (0x01056, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01062, 0x01064,), # Myanmar Vowel Sign Sgaw ..Myanmar Tone Mark Sgaw K + (0x01067, 0x0106d,), # Myanmar Vowel Sign Weste..Myanmar Sign Western Pwo (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah - (0x01082, 0x01082,), # Myanmar Consonant Sign Shan Medial Wa - (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan - (0x0108d, 0x0108d,), # Myanmar Sign Shan Council Emphatic Tone - (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton Ai + (0x01082, 0x0108d,), # Myanmar Consonant Sign S..Myanmar Sign Shan Counci + (0x0108f, 0x0108f,), # Myanmar Sign Rumai Palaung Tone-5 + (0x0109a, 0x0109d,), # Myanmar Sign Khamti Tone..Myanmar Vowel Sign Aiton (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U - (0x017b4, 0x017b5,), # Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa - (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua - (0x017c6, 0x017c6,), # Khmer Sign Nikahit - (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017b4, 0x017d3,), # Khmer Vowel Inherent Aq ..Khmer Sign Bathamasat (0x017dd, 0x017dd,), # Khmer Sign Atthacan - (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x0180b, 0x0180e,), # Mongolian Free Variation..Mongolian Vowel Separato (0x018a9, 0x018a9,), # Mongolian Letter Ali Gali Dagalga - (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U - (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O - (0x01932, 0x01932,), # Limbu Small Letter Anusvara - (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i - (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U - (0x01a1b, 0x01a1b,), # Buginese Vowel Sign Ae - (0x01a56, 0x01a56,), # Tai Tham Consonant Sign Medial La - (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign - (0x01a60, 0x01a60,), # Tai Tham Sign Sakot - (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai Sat - (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B - (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01920, 0x0192b,), # Limbu Vowel Sign A ..Limbu Subjoined Letter W + (0x01930, 0x0193b,), # Limbu Small Letter Ka ..Limbu Sign Sa-i + (0x019b0, 0x019c0,), # New Tai Lue Vowel Sign V..New Tai Lue Vowel Sign I + (0x019c8, 0x019c9,), # New Tai Lue Tone Mark-1 ..New Tai Lue Tone Mark-2 + (0x01a17, 0x01a1b,), # Buginese Vowel Sign I ..Buginese Vowel Sign Ae + (0x01a55, 0x01a5e,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a60, 0x01a7c,), # Tai Tham Sign Sakot ..Tai Tham Sign Khuen-lue (0x01a7f, 0x01a7f,), # Tai Tham Combining Cryptogrammic Dot (0x01ab0, 0x01abe,), # Combining Doubled Circum..Combining Parentheses Ov - (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang - (0x01b34, 0x01b34,), # Balinese Sign Rerekan - (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R - (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La Lenga - (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepet + (0x01b00, 0x01b04,), # Balinese Sign Ulu Ricem ..Balinese Sign Bisah + (0x01b34, 0x01b44,), # Balinese Sign Rerekan ..Balinese Adeg Adeg (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol - (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar - (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan - (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan - (0x01bab, 0x01bad,), # Sundanese Sign Virama ..Sundanese Consonant Sign - (0x01be6, 0x01be6,), # Batak Sign Tompi - (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee - (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O - (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H - (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T - (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01b80, 0x01b82,), # Sundanese Sign Panyecek ..Sundanese Sign Pangwisad + (0x01ba1, 0x01bad,), # Sundanese Consonant Sign..Sundanese Consonant Sign + (0x01be6, 0x01bf3,), # Batak Sign Tompi ..Batak Panongonan + (0x01c24, 0x01c37,), # Lepcha Subjoined Letter ..Lepcha Sign Nukta (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha - (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash - (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01cd4, 0x01ce8,), # Vedic Sign Yajurvedic Mi..Vedic Sign Visarga Anuda (0x01ced, 0x01ced,), # Vedic Sign Tiryak - (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above + (0x01cf2, 0x01cf4,), # Vedic Sign Ardhavisarga ..Vedic Tone Candra Above (0x01cf8, 0x01cf9,), # Vedic Tone Ring Above ..Vedic Tone Double Ring A (0x01dc0, 0x01df5,), # Combining Dotted Grave A..Combining Up Tack Above (0x01dfc, 0x01dff,), # Combining Double Inverte..Combining Right Arrowhea + (0x0200b, 0x0200f,), # Zero Width Space ..Right-to-left Mark + (0x02028, 0x0202e,), # Line Separator ..Right-to-left Override + (0x02060, 0x02064,), # Word Joiner ..Invisible Plus + (0x02066, 0x0206f,), # Left-to-right Isolate ..Nominal Digit Shapes (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joiner (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette - (0x0302a, 0x0302d,), # Ideographic Level Tone M..Ideographic Entering Ton + (0x0302a, 0x0302f,), # Ideographic Level Tone M..Hangul Double Dot Tone M (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer @@ -1677,35 +1729,33 @@ ZERO_WIDTH = { (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisvara (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasanta (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusvara - (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign - (0x0a8c4, 0x0a8c4,), # Saurashtra Sign Virama + (0x0a823, 0x0a827,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a880, 0x0a881,), # Saurashtra Sign Anusvara..Saurashtra Sign Visarga + (0x0a8b4, 0x0a8c4,), # Saurashtra Consonant Sig..Saurashtra Sign Virama (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop - (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R - (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar - (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu - (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku - (0x0a9bc, 0x0a9bc,), # Javanese Vowel Sign Pepet + (0x0a947, 0x0a953,), # Rejang Vowel Sign I ..Rejang Virama + (0x0a980, 0x0a983,), # Javanese Sign Panyangga ..Javanese Sign Wignyan + (0x0a9b3, 0x0a9c0,), # Javanese Sign Cecak Telu..Javanese Pangkon (0x0a9e5, 0x0a9e5,), # Myanmar Sign Shan Saw - (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe - (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue - (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0aa29, 0x0aa36,), # Cham Vowel Sign Aa ..Cham Consonant Sign Wa (0x0aa43, 0x0aa43,), # Cham Consonant Sign Final Ng - (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Final M - (0x0aa7c, 0x0aa7c,), # Myanmar Sign Tai Laing Tone-2 + (0x0aa4c, 0x0aa4d,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa7b, 0x0aa7d,), # Myanmar Sign Pao Karen T..Myanmar Sign Tai Laing T (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho - (0x0aaec, 0x0aaed,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign - (0x0aaf6, 0x0aaf6,), # Meetei Mayek Virama - (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign Anap - (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign Unap - (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek + (0x0aaeb, 0x0aaef,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf5, 0x0aaf6,), # Meetei Mayek Vowel Sign ..Meetei Mayek Virama + (0x0abe3, 0x0abea,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abec, 0x0abed,), # Meetei Mayek Lum Iyek ..Meetei Mayek Apun Iyek (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spanish Varika (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 (0x0fe20, 0x0fe2d,), # Combining Ligature Left ..Combining Conjoining Mac + (0x0feff, 0x0feff,), # Zero Width No-break Space + (0x0fff9, 0x0fffb,), # Interlinear Annotation A..Interlinear Annotation T (0x101fd, 0x101fd,), # Phaistos Disc Sign Combining Oblique Stroke (0x102e0, 0x102e0,), # Coptic Epact Thousands Mark (0x10376, 0x1037a,), # Combining Old Permic Let..Combining Old Permic Let @@ -1715,57 +1765,54 @@ ZERO_WIDTH = { (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo (0x10a3f, 0x10a3f,), # Kharoshthi Virama (0x10ae5, 0x10ae6,), # Manichaean Abbreviation ..Manichaean Abbreviation - (0x11001, 0x11001,), # Brahmi Sign Anusvara + (0x11000, 0x11002,), # Brahmi Sign Candrabindu ..Brahmi Sign Visarga (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama - (0x1107f, 0x11081,), # Brahmi Number Joiner ..Kaithi Sign Anusvara - (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai - (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x1107f, 0x11082,), # Brahmi Number Joiner ..Kaithi Sign Visarga + (0x110b0, 0x110ba,), # Kaithi Vowel Sign Aa ..Kaithi Sign Nukta + (0x110bd, 0x110bd,), # Kaithi Number Sign (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga - (0x11127, 0x1112b,), # Chakma Vowel Sign A ..Chakma Vowel Sign Uu - (0x1112d, 0x11134,), # Chakma Vowel Sign Ai ..Chakma Maayyaa + (0x11127, 0x11134,), # Chakma Vowel Sign A ..Chakma Maayyaa (0x11173, 0x11173,), # Mahajani Sign Nukta - (0x11180, 0x11181,), # Sharada Sign Candrabindu..Sharada Sign Anusvara - (0x111b6, 0x111be,), # Sharada Vowel Sign U ..Sharada Vowel Sign O - (0x1122f, 0x11231,), # Khojki Vowel Sign U ..Khojki Vowel Sign Ai - (0x11234, 0x11234,), # Khojki Sign Anusvara - (0x11236, 0x11237,), # Khojki Sign Nukta ..Khojki Sign Shadda - (0x112df, 0x112df,), # Khudawadi Sign Anusvara - (0x112e3, 0x112ea,), # Khudawadi Vowel Sign U ..Khudawadi Sign Virama - (0x11301, 0x11301,), # Grantha Sign Candrabindu + (0x11180, 0x11182,), # Sharada Sign Candrabindu..Sharada Sign Visarga + (0x111b3, 0x111c0,), # Sharada Vowel Sign Aa ..Sharada Sign Virama + (0x1122c, 0x11237,), # Khojki Vowel Sign Aa ..Khojki Sign Shadda + (0x112df, 0x112ea,), # Khudawadi Sign Anusvara ..Khudawadi Sign Virama + (0x11301, 0x11303,), # Grantha Sign Candrabindu..Grantha Sign Visarga (0x1133c, 0x1133c,), # Grantha Sign Nukta - (0x11340, 0x11340,), # Grantha Vowel Sign Ii + (0x1133e, 0x11344,), # Grantha Vowel Sign Aa ..Grantha Vowel Sign Vocal + (0x11347, 0x11348,), # Grantha Vowel Sign Ee ..Grantha Vowel Sign Ai + (0x1134b, 0x1134d,), # Grantha Vowel Sign Oo ..Grantha Sign Virama + (0x11357, 0x11357,), # Grantha Au Length Mark + (0x11362, 0x11363,), # Grantha Vowel Sign Vocal..Grantha Vowel Sign Vocal (0x11366, 0x1136c,), # Combining Grantha Digit ..Combining Grantha Digit (0x11370, 0x11374,), # Combining Grantha Letter..Combining Grantha Letter - (0x114b3, 0x114b8,), # Tirhuta Vowel Sign U ..Tirhuta Vowel Sign Vocal - (0x114ba, 0x114ba,), # Tirhuta Vowel Sign Short E - (0x114bf, 0x114c0,), # Tirhuta Sign Candrabindu..Tirhuta Sign Anusvara - (0x114c2, 0x114c3,), # Tirhuta Sign Virama ..Tirhuta Sign Nukta - (0x115b2, 0x115b5,), # Siddham Vowel Sign U ..Siddham Vowel Sign Vocal - (0x115bc, 0x115bd,), # Siddham Sign Candrabindu..Siddham Sign Anusvara - (0x115bf, 0x115c0,), # Siddham Sign Virama ..Siddham Sign Nukta - (0x11633, 0x1163a,), # Modi Vowel Sign U ..Modi Vowel Sign Ai - (0x1163d, 0x1163d,), # Modi Sign Anusvara - (0x1163f, 0x11640,), # Modi Sign Virama ..Modi Sign Ardhacandra - (0x116ab, 0x116ab,), # Takri Sign Anusvara - (0x116ad, 0x116ad,), # Takri Vowel Sign Aa - (0x116b0, 0x116b5,), # Takri Vowel Sign U ..Takri Vowel Sign Au - (0x116b7, 0x116b7,), # Takri Sign Nukta + (0x114b0, 0x114c3,), # Tirhuta Vowel Sign Aa ..Tirhuta Sign Nukta + (0x115af, 0x115b5,), # Siddham Vowel Sign Aa ..Siddham Vowel Sign Vocal + (0x115b8, 0x115c0,), # Siddham Vowel Sign E ..Siddham Sign Nukta + (0x11630, 0x11640,), # Modi Vowel Sign Aa ..Modi Sign Ardhacandra + (0x116ab, 0x116b7,), # Takri Sign Anusvara ..Takri Sign Nukta (0x16af0, 0x16af4,), # Bassa Vah Combining High..Bassa Vah Combining High (0x16b30, 0x16b36,), # Pahawh Hmong Mark Cim Tu..Pahawh Hmong Mark Cim Ta + (0x16f51, 0x16f7e,), # Miao Sign Aspiration ..Miao Vowel Sign Ng (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below (0x1bc9d, 0x1bc9e,), # Duployan Thick Letter Se..Duployan Double Mark - (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining - (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1bca0, 0x1bca3,), # Shorthand Format Letter ..Shorthand Format Up Step + (0x1d165, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d16d, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical (0x1e8d0, 0x1e8d6,), # Mende Kikakui Combining ..Mende Kikakui Combining + (0xe0001, 0xe0001,), # Language Tag + (0xe0020, 0xe007f,), # Tag Space ..Cancel Tag (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 ), '8.0.0': ( # Source: DerivedGeneralCategory-8.0.0.txt # Date: 2015-02-13, 13:47:11 GMT [MD] # + (0x00000, 0x00000,), # (nil) + (0x000ad, 0x000ad,), # Soft Hyphen (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg @@ -1773,13 +1820,16 @@ ZERO_WIDTH = { (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot (0x005c7, 0x005c7,), # Hebrew Point Qamats Qatan + (0x00600, 0x00605,), # Arabic Number Sign ..Arabic Number Mark Above (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0061c, 0x0061c,), # Arabic Letter Mark (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below (0x00670, 0x00670,), # Arabic Letter Superscript Alef - (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006d6, 0x006dd,), # Arabic Small High Ligatu..Arabic End Of Ayah (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x0070f, 0x0070f,), # Syriac Abbreviation Mark (0x00711, 0x00711,), # Syriac Letter Superscript Alaph (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun @@ -1789,61 +1839,69 @@ ZERO_WIDTH = { (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark - (0x008e3, 0x00902,), # Arabic Turned Damma Belo..Devanagari Sign Anusvara - (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe - (0x0093c, 0x0093c,), # Devanagari Sign Nukta - (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai - (0x0094d, 0x0094d,), # Devanagari Sign Virama + (0x008e3, 0x00903,), # Arabic Turned Damma Belo..Devanagari Sign Visarga + (0x0093a, 0x0093c,), # Devanagari Vowel Sign Oe..Devanagari Sign Nukta + (0x0093e, 0x0094f,), # Devanagari Vowel Sign Aa..Devanagari Vowel Sign Aw (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo - (0x00981, 0x00981,), # Bengali Sign Candrabindu + (0x00981, 0x00983,), # Bengali Sign Candrabindu..Bengali Sign Visarga (0x009bc, 0x009bc,), # Bengali Sign Nukta - (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal - (0x009cd, 0x009cd,), # Bengali Sign Virama + (0x009be, 0x009c4,), # Bengali Vowel Sign Aa ..Bengali Vowel Sign Vocal + (0x009c7, 0x009c8,), # Bengali Vowel Sign E ..Bengali Vowel Sign Ai + (0x009cb, 0x009cd,), # Bengali Vowel Sign O ..Bengali Sign Virama + (0x009d7, 0x009d7,), # Bengali Au Length Mark (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal - (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a01, 0x00a03,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Visarga (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta - (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a3e, 0x00a42,), # Gurmukhi Vowel Sign Aa ..Gurmukhi Vowel Sign Uu (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash - (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00a81, 0x00a83,), # Gujarati Sign Candrabind..Gujarati Sign Visarga (0x00abc, 0x00abc,), # Gujarati Sign Nukta - (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand - (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai - (0x00acd, 0x00acd,), # Gujarati Sign Virama + (0x00abe, 0x00ac5,), # Gujarati Vowel Sign Aa ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac9,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Cand + (0x00acb, 0x00acd,), # Gujarati Vowel Sign O ..Gujarati Sign Virama (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca - (0x00b01, 0x00b01,), # Oriya Sign Candrabindu + (0x00b01, 0x00b03,), # Oriya Sign Candrabindu ..Oriya Sign Visarga (0x00b3c, 0x00b3c,), # Oriya Sign Nukta - (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I - (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic - (0x00b4d, 0x00b4d,), # Oriya Sign Virama - (0x00b56, 0x00b56,), # Oriya Ai Length Mark + (0x00b3e, 0x00b44,), # Oriya Vowel Sign Aa ..Oriya Vowel Sign Vocalic + (0x00b47, 0x00b48,), # Oriya Vowel Sign E ..Oriya Vowel Sign Ai + (0x00b4b, 0x00b4d,), # Oriya Vowel Sign O ..Oriya Sign Virama + (0x00b56, 0x00b57,), # Oriya Ai Length Mark ..Oriya Au Length Mark (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic (0x00b82, 0x00b82,), # Tamil Sign Anusvara - (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii - (0x00bcd, 0x00bcd,), # Tamil Sign Virama - (0x00c00, 0x00c00,), # Telugu Sign Combining Candrabindu Above - (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00bbe, 0x00bc2,), # Tamil Vowel Sign Aa ..Tamil Vowel Sign Uu + (0x00bc6, 0x00bc8,), # Tamil Vowel Sign E ..Tamil Vowel Sign Ai + (0x00bca, 0x00bcd,), # Tamil Vowel Sign O ..Tamil Sign Virama + (0x00bd7, 0x00bd7,), # Tamil Au Length Mark + (0x00c00, 0x00c03,), # Telugu Sign Combining Ca..Telugu Sign Visarga + (0x00c3e, 0x00c44,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Vocali (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali - (0x00c81, 0x00c81,), # Kannada Sign Candrabindu + (0x00c81, 0x00c83,), # Kannada Sign Candrabindu..Kannada Sign Visarga (0x00cbc, 0x00cbc,), # Kannada Sign Nukta - (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I - (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E - (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00cbe, 0x00cc4,), # Kannada Vowel Sign Aa ..Kannada Vowel Sign Vocal + (0x00cc6, 0x00cc8,), # Kannada Vowel Sign E ..Kannada Vowel Sign Ai + (0x00cca, 0x00ccd,), # Kannada Vowel Sign O ..Kannada Sign Virama + (0x00cd5, 0x00cd6,), # Kannada Length Mark ..Kannada Ai Length Mark (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal - (0x00d01, 0x00d01,), # Malayalam Sign Candrabindu - (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc - (0x00d4d, 0x00d4d,), # Malayalam Sign Virama + (0x00d01, 0x00d03,), # Malayalam Sign Candrabin..Malayalam Sign Visarga + (0x00d3e, 0x00d44,), # Malayalam Vowel Sign Aa ..Malayalam Vowel Sign Voc + (0x00d46, 0x00d48,), # Malayalam Vowel Sign E ..Malayalam Vowel Sign Ai + (0x00d4a, 0x00d4d,), # Malayalam Vowel Sign O ..Malayalam Sign Virama + (0x00d57, 0x00d57,), # Malayalam Au Length Mark (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00d82, 0x00d83,), # Sinhala Sign Anusvaraya ..Sinhala Sign Visargaya (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna - (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dcf, 0x00dd4,), # Sinhala Vowel Sign Aela-..Sinhala Vowel Sign Ketti (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga Paa-pilla + (0x00dd8, 0x00ddf,), # Sinhala Vowel Sign Gaett..Sinhala Vowel Sign Gayan + (0x00df2, 0x00df3,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga (0x00e31, 0x00e31,), # Thai Character Mai Han-akat (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan @@ -1855,78 +1913,60 @@ ZERO_WIDTH = { (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung Nyi Zla (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung Sgor Rtags (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru - (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga - (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f3e, 0x00f3f,), # Tibetan Sign Yar Tshes ..Tibetan Sign Mar Tshes + (0x00f71, 0x00f84,), # Tibetan Vowel Sign Aa ..Tibetan Mark Halanta (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gdan - (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu - (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below - (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat - (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M - (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0102b, 0x0103e,), # Myanmar Vowel Sign Tall ..Myanmar Consonant Sign M + (0x01056, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01062, 0x01064,), # Myanmar Vowel Sign Sgaw ..Myanmar Tone Mark Sgaw K + (0x01067, 0x0106d,), # Myanmar Vowel Sign Weste..Myanmar Sign Western Pwo (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah - (0x01082, 0x01082,), # Myanmar Consonant Sign Shan Medial Wa - (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan - (0x0108d, 0x0108d,), # Myanmar Sign Shan Council Emphatic Tone - (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton Ai + (0x01082, 0x0108d,), # Myanmar Consonant Sign S..Myanmar Sign Shan Counci + (0x0108f, 0x0108f,), # Myanmar Sign Rumai Palaung Tone-5 + (0x0109a, 0x0109d,), # Myanmar Sign Khamti Tone..Myanmar Vowel Sign Aiton (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U - (0x017b4, 0x017b5,), # Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa - (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua - (0x017c6, 0x017c6,), # Khmer Sign Nikahit - (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017b4, 0x017d3,), # Khmer Vowel Inherent Aq ..Khmer Sign Bathamasat (0x017dd, 0x017dd,), # Khmer Sign Atthacan - (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x0180b, 0x0180e,), # Mongolian Free Variation..Mongolian Vowel Separato (0x018a9, 0x018a9,), # Mongolian Letter Ali Gali Dagalga - (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U - (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O - (0x01932, 0x01932,), # Limbu Small Letter Anusvara - (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i - (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U - (0x01a1b, 0x01a1b,), # Buginese Vowel Sign Ae - (0x01a56, 0x01a56,), # Tai Tham Consonant Sign Medial La - (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign - (0x01a60, 0x01a60,), # Tai Tham Sign Sakot - (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai Sat - (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B - (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01920, 0x0192b,), # Limbu Vowel Sign A ..Limbu Subjoined Letter W + (0x01930, 0x0193b,), # Limbu Small Letter Ka ..Limbu Sign Sa-i + (0x01a17, 0x01a1b,), # Buginese Vowel Sign I ..Buginese Vowel Sign Ae + (0x01a55, 0x01a5e,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a60, 0x01a7c,), # Tai Tham Sign Sakot ..Tai Tham Sign Khuen-lue (0x01a7f, 0x01a7f,), # Tai Tham Combining Cryptogrammic Dot (0x01ab0, 0x01abe,), # Combining Doubled Circum..Combining Parentheses Ov - (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang - (0x01b34, 0x01b34,), # Balinese Sign Rerekan - (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R - (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La Lenga - (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepet + (0x01b00, 0x01b04,), # Balinese Sign Ulu Ricem ..Balinese Sign Bisah + (0x01b34, 0x01b44,), # Balinese Sign Rerekan ..Balinese Adeg Adeg (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol - (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar - (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan - (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan - (0x01bab, 0x01bad,), # Sundanese Sign Virama ..Sundanese Consonant Sign - (0x01be6, 0x01be6,), # Batak Sign Tompi - (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee - (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O - (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H - (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T - (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01b80, 0x01b82,), # Sundanese Sign Panyecek ..Sundanese Sign Pangwisad + (0x01ba1, 0x01bad,), # Sundanese Consonant Sign..Sundanese Consonant Sign + (0x01be6, 0x01bf3,), # Batak Sign Tompi ..Batak Panongonan + (0x01c24, 0x01c37,), # Lepcha Subjoined Letter ..Lepcha Sign Nukta (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha - (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash - (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01cd4, 0x01ce8,), # Vedic Sign Yajurvedic Mi..Vedic Sign Visarga Anuda (0x01ced, 0x01ced,), # Vedic Sign Tiryak - (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above + (0x01cf2, 0x01cf4,), # Vedic Sign Ardhavisarga ..Vedic Tone Candra Above (0x01cf8, 0x01cf9,), # Vedic Tone Ring Above ..Vedic Tone Double Ring A (0x01dc0, 0x01df5,), # Combining Dotted Grave A..Combining Up Tack Above (0x01dfc, 0x01dff,), # Combining Double Inverte..Combining Right Arrowhea + (0x0200b, 0x0200f,), # Zero Width Space ..Right-to-left Mark + (0x02028, 0x0202e,), # Line Separator ..Right-to-left Override + (0x02060, 0x02064,), # Word Joiner ..Invisible Plus + (0x02066, 0x0206f,), # Left-to-right Isolate ..Nominal Digit Shapes (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joiner (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette - (0x0302a, 0x0302d,), # Ideographic Level Tone M..Ideographic Entering Ton + (0x0302a, 0x0302f,), # Ideographic Level Tone M..Hangul Double Dot Tone M (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer @@ -1935,35 +1975,33 @@ ZERO_WIDTH = { (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisvara (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasanta (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusvara - (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign - (0x0a8c4, 0x0a8c4,), # Saurashtra Sign Virama + (0x0a823, 0x0a827,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a880, 0x0a881,), # Saurashtra Sign Anusvara..Saurashtra Sign Visarga + (0x0a8b4, 0x0a8c4,), # Saurashtra Consonant Sig..Saurashtra Sign Virama (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop - (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R - (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar - (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu - (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku - (0x0a9bc, 0x0a9bc,), # Javanese Vowel Sign Pepet + (0x0a947, 0x0a953,), # Rejang Vowel Sign I ..Rejang Virama + (0x0a980, 0x0a983,), # Javanese Sign Panyangga ..Javanese Sign Wignyan + (0x0a9b3, 0x0a9c0,), # Javanese Sign Cecak Telu..Javanese Pangkon (0x0a9e5, 0x0a9e5,), # Myanmar Sign Shan Saw - (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe - (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue - (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0aa29, 0x0aa36,), # Cham Vowel Sign Aa ..Cham Consonant Sign Wa (0x0aa43, 0x0aa43,), # Cham Consonant Sign Final Ng - (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Final M - (0x0aa7c, 0x0aa7c,), # Myanmar Sign Tai Laing Tone-2 + (0x0aa4c, 0x0aa4d,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa7b, 0x0aa7d,), # Myanmar Sign Pao Karen T..Myanmar Sign Tai Laing T (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho - (0x0aaec, 0x0aaed,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign - (0x0aaf6, 0x0aaf6,), # Meetei Mayek Virama - (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign Anap - (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign Unap - (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek + (0x0aaeb, 0x0aaef,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf5, 0x0aaf6,), # Meetei Mayek Vowel Sign ..Meetei Mayek Virama + (0x0abe3, 0x0abea,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abec, 0x0abed,), # Meetei Mayek Lum Iyek ..Meetei Mayek Apun Iyek (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spanish Varika (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 (0x0fe20, 0x0fe2f,), # Combining Ligature Left ..Combining Cyrillic Titlo + (0x0feff, 0x0feff,), # Zero Width No-break Space + (0x0fff9, 0x0fffb,), # Interlinear Annotation A..Interlinear Annotation T (0x101fd, 0x101fd,), # Phaistos Disc Sign Combining Oblique Stroke (0x102e0, 0x102e0,), # Coptic Epact Thousands Mark (0x10376, 0x1037a,), # Combining Old Permic Let..Combining Old Permic Let @@ -1973,52 +2011,43 @@ ZERO_WIDTH = { (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo (0x10a3f, 0x10a3f,), # Kharoshthi Virama (0x10ae5, 0x10ae6,), # Manichaean Abbreviation ..Manichaean Abbreviation - (0x11001, 0x11001,), # Brahmi Sign Anusvara + (0x11000, 0x11002,), # Brahmi Sign Candrabindu ..Brahmi Sign Visarga (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama - (0x1107f, 0x11081,), # Brahmi Number Joiner ..Kaithi Sign Anusvara - (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai - (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x1107f, 0x11082,), # Brahmi Number Joiner ..Kaithi Sign Visarga + (0x110b0, 0x110ba,), # Kaithi Vowel Sign Aa ..Kaithi Sign Nukta + (0x110bd, 0x110bd,), # Kaithi Number Sign (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga - (0x11127, 0x1112b,), # Chakma Vowel Sign A ..Chakma Vowel Sign Uu - (0x1112d, 0x11134,), # Chakma Vowel Sign Ai ..Chakma Maayyaa + (0x11127, 0x11134,), # Chakma Vowel Sign A ..Chakma Maayyaa (0x11173, 0x11173,), # Mahajani Sign Nukta - (0x11180, 0x11181,), # Sharada Sign Candrabindu..Sharada Sign Anusvara - (0x111b6, 0x111be,), # Sharada Vowel Sign U ..Sharada Vowel Sign O + (0x11180, 0x11182,), # Sharada Sign Candrabindu..Sharada Sign Visarga + (0x111b3, 0x111c0,), # Sharada Vowel Sign Aa ..Sharada Sign Virama (0x111ca, 0x111cc,), # Sharada Sign Nukta ..Sharada Extra Short Vowe - (0x1122f, 0x11231,), # Khojki Vowel Sign U ..Khojki Vowel Sign Ai - (0x11234, 0x11234,), # Khojki Sign Anusvara - (0x11236, 0x11237,), # Khojki Sign Nukta ..Khojki Sign Shadda - (0x112df, 0x112df,), # Khudawadi Sign Anusvara - (0x112e3, 0x112ea,), # Khudawadi Vowel Sign U ..Khudawadi Sign Virama - (0x11300, 0x11301,), # Grantha Sign Combining A..Grantha Sign Candrabindu + (0x1122c, 0x11237,), # Khojki Vowel Sign Aa ..Khojki Sign Shadda + (0x112df, 0x112ea,), # Khudawadi Sign Anusvara ..Khudawadi Sign Virama + (0x11300, 0x11303,), # Grantha Sign Combining A..Grantha Sign Visarga (0x1133c, 0x1133c,), # Grantha Sign Nukta - (0x11340, 0x11340,), # Grantha Vowel Sign Ii + (0x1133e, 0x11344,), # Grantha Vowel Sign Aa ..Grantha Vowel Sign Vocal + (0x11347, 0x11348,), # Grantha Vowel Sign Ee ..Grantha Vowel Sign Ai + (0x1134b, 0x1134d,), # Grantha Vowel Sign Oo ..Grantha Sign Virama + (0x11357, 0x11357,), # Grantha Au Length Mark + (0x11362, 0x11363,), # Grantha Vowel Sign Vocal..Grantha Vowel Sign Vocal (0x11366, 0x1136c,), # Combining Grantha Digit ..Combining Grantha Digit (0x11370, 0x11374,), # Combining Grantha Letter..Combining Grantha Letter - (0x114b3, 0x114b8,), # Tirhuta Vowel Sign U ..Tirhuta Vowel Sign Vocal - (0x114ba, 0x114ba,), # Tirhuta Vowel Sign Short E - (0x114bf, 0x114c0,), # Tirhuta Sign Candrabindu..Tirhuta Sign Anusvara - (0x114c2, 0x114c3,), # Tirhuta Sign Virama ..Tirhuta Sign Nukta - (0x115b2, 0x115b5,), # Siddham Vowel Sign U ..Siddham Vowel Sign Vocal - (0x115bc, 0x115bd,), # Siddham Sign Candrabindu..Siddham Sign Anusvara - (0x115bf, 0x115c0,), # Siddham Sign Virama ..Siddham Sign Nukta + (0x114b0, 0x114c3,), # Tirhuta Vowel Sign Aa ..Tirhuta Sign Nukta + (0x115af, 0x115b5,), # Siddham Vowel Sign Aa ..Siddham Vowel Sign Vocal + (0x115b8, 0x115c0,), # Siddham Vowel Sign E ..Siddham Sign Nukta (0x115dc, 0x115dd,), # Siddham Vowel Sign Alter..Siddham Vowel Sign Alter - (0x11633, 0x1163a,), # Modi Vowel Sign U ..Modi Vowel Sign Ai - (0x1163d, 0x1163d,), # Modi Sign Anusvara - (0x1163f, 0x11640,), # Modi Sign Virama ..Modi Sign Ardhacandra - (0x116ab, 0x116ab,), # Takri Sign Anusvara - (0x116ad, 0x116ad,), # Takri Vowel Sign Aa - (0x116b0, 0x116b5,), # Takri Vowel Sign U ..Takri Vowel Sign Au - (0x116b7, 0x116b7,), # Takri Sign Nukta - (0x1171d, 0x1171f,), # Ahom Consonant Sign Medi..Ahom Consonant Sign Medi - (0x11722, 0x11725,), # Ahom Vowel Sign I ..Ahom Vowel Sign Uu - (0x11727, 0x1172b,), # Ahom Vowel Sign Aw ..Ahom Sign Killer + (0x11630, 0x11640,), # Modi Vowel Sign Aa ..Modi Sign Ardhacandra + (0x116ab, 0x116b7,), # Takri Sign Anusvara ..Takri Sign Nukta + (0x1171d, 0x1172b,), # Ahom Consonant Sign Medi..Ahom Sign Killer (0x16af0, 0x16af4,), # Bassa Vah Combining High..Bassa Vah Combining High (0x16b30, 0x16b36,), # Pahawh Hmong Mark Cim Tu..Pahawh Hmong Mark Cim Ta + (0x16f51, 0x16f7e,), # Miao Sign Aspiration ..Miao Vowel Sign Ng (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below (0x1bc9d, 0x1bc9e,), # Duployan Thick Letter Se..Duployan Double Mark - (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining - (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1bca0, 0x1bca3,), # Shorthand Format Letter ..Shorthand Format Up Step + (0x1d165, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d16d, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical @@ -2029,12 +2058,17 @@ ZERO_WIDTH = { (0x1da9b, 0x1da9f,), # Signwriting Fill Modifie..Signwriting Fill Modifie (0x1daa1, 0x1daaf,), # Signwriting Rotation Mod..Signwriting Rotation Mod (0x1e8d0, 0x1e8d6,), # Mende Kikakui Combining ..Mende Kikakui Combining + (0x1f3fb, 0x1f3ff,), # Emoji Modifier Fitzpatri..Emoji Modifier Fitzpatri + (0xe0001, 0xe0001,), # Language Tag + (0xe0020, 0xe007f,), # Tag Space ..Cancel Tag (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 ), '9.0.0': ( # Source: DerivedGeneralCategory-9.0.0.txt # Date: 2016-06-01, 10:34:26 GMT # + (0x00000, 0x00000,), # (nil) + (0x000ad, 0x000ad,), # Soft Hyphen (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg @@ -2042,13 +2076,16 @@ ZERO_WIDTH = { (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot (0x005c7, 0x005c7,), # Hebrew Point Qamats Qatan + (0x00600, 0x00605,), # Arabic Number Sign ..Arabic Number Mark Above (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0061c, 0x0061c,), # Arabic Letter Mark (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below (0x00670, 0x00670,), # Arabic Letter Superscript Alef - (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006d6, 0x006dd,), # Arabic Small High Ligatu..Arabic End Of Ayah (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x0070f, 0x0070f,), # Syriac Abbreviation Mark (0x00711, 0x00711,), # Syriac Letter Superscript Alaph (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun @@ -2058,62 +2095,69 @@ ZERO_WIDTH = { (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark - (0x008d4, 0x008e1,), # Arabic Small High Word A..Arabic Small High Sign S - (0x008e3, 0x00902,), # Arabic Turned Damma Belo..Devanagari Sign Anusvara - (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe - (0x0093c, 0x0093c,), # Devanagari Sign Nukta - (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai - (0x0094d, 0x0094d,), # Devanagari Sign Virama + (0x008d4, 0x00903,), # Arabic Small High Word A..Devanagari Sign Visarga + (0x0093a, 0x0093c,), # Devanagari Vowel Sign Oe..Devanagari Sign Nukta + (0x0093e, 0x0094f,), # Devanagari Vowel Sign Aa..Devanagari Vowel Sign Aw (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo - (0x00981, 0x00981,), # Bengali Sign Candrabindu + (0x00981, 0x00983,), # Bengali Sign Candrabindu..Bengali Sign Visarga (0x009bc, 0x009bc,), # Bengali Sign Nukta - (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal - (0x009cd, 0x009cd,), # Bengali Sign Virama + (0x009be, 0x009c4,), # Bengali Vowel Sign Aa ..Bengali Vowel Sign Vocal + (0x009c7, 0x009c8,), # Bengali Vowel Sign E ..Bengali Vowel Sign Ai + (0x009cb, 0x009cd,), # Bengali Vowel Sign O ..Bengali Sign Virama + (0x009d7, 0x009d7,), # Bengali Au Length Mark (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal - (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a01, 0x00a03,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Visarga (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta - (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a3e, 0x00a42,), # Gurmukhi Vowel Sign Aa ..Gurmukhi Vowel Sign Uu (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash - (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00a81, 0x00a83,), # Gujarati Sign Candrabind..Gujarati Sign Visarga (0x00abc, 0x00abc,), # Gujarati Sign Nukta - (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand - (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai - (0x00acd, 0x00acd,), # Gujarati Sign Virama + (0x00abe, 0x00ac5,), # Gujarati Vowel Sign Aa ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac9,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Cand + (0x00acb, 0x00acd,), # Gujarati Vowel Sign O ..Gujarati Sign Virama (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca - (0x00b01, 0x00b01,), # Oriya Sign Candrabindu + (0x00b01, 0x00b03,), # Oriya Sign Candrabindu ..Oriya Sign Visarga (0x00b3c, 0x00b3c,), # Oriya Sign Nukta - (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I - (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic - (0x00b4d, 0x00b4d,), # Oriya Sign Virama - (0x00b56, 0x00b56,), # Oriya Ai Length Mark + (0x00b3e, 0x00b44,), # Oriya Vowel Sign Aa ..Oriya Vowel Sign Vocalic + (0x00b47, 0x00b48,), # Oriya Vowel Sign E ..Oriya Vowel Sign Ai + (0x00b4b, 0x00b4d,), # Oriya Vowel Sign O ..Oriya Sign Virama + (0x00b56, 0x00b57,), # Oriya Ai Length Mark ..Oriya Au Length Mark (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic (0x00b82, 0x00b82,), # Tamil Sign Anusvara - (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii - (0x00bcd, 0x00bcd,), # Tamil Sign Virama - (0x00c00, 0x00c00,), # Telugu Sign Combining Candrabindu Above - (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00bbe, 0x00bc2,), # Tamil Vowel Sign Aa ..Tamil Vowel Sign Uu + (0x00bc6, 0x00bc8,), # Tamil Vowel Sign E ..Tamil Vowel Sign Ai + (0x00bca, 0x00bcd,), # Tamil Vowel Sign O ..Tamil Sign Virama + (0x00bd7, 0x00bd7,), # Tamil Au Length Mark + (0x00c00, 0x00c03,), # Telugu Sign Combining Ca..Telugu Sign Visarga + (0x00c3e, 0x00c44,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Vocali (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali - (0x00c81, 0x00c81,), # Kannada Sign Candrabindu + (0x00c81, 0x00c83,), # Kannada Sign Candrabindu..Kannada Sign Visarga (0x00cbc, 0x00cbc,), # Kannada Sign Nukta - (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I - (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E - (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00cbe, 0x00cc4,), # Kannada Vowel Sign Aa ..Kannada Vowel Sign Vocal + (0x00cc6, 0x00cc8,), # Kannada Vowel Sign E ..Kannada Vowel Sign Ai + (0x00cca, 0x00ccd,), # Kannada Vowel Sign O ..Kannada Sign Virama + (0x00cd5, 0x00cd6,), # Kannada Length Mark ..Kannada Ai Length Mark (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal - (0x00d01, 0x00d01,), # Malayalam Sign Candrabindu - (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc - (0x00d4d, 0x00d4d,), # Malayalam Sign Virama + (0x00d01, 0x00d03,), # Malayalam Sign Candrabin..Malayalam Sign Visarga + (0x00d3e, 0x00d44,), # Malayalam Vowel Sign Aa ..Malayalam Vowel Sign Voc + (0x00d46, 0x00d48,), # Malayalam Vowel Sign E ..Malayalam Vowel Sign Ai + (0x00d4a, 0x00d4d,), # Malayalam Vowel Sign O ..Malayalam Sign Virama + (0x00d57, 0x00d57,), # Malayalam Au Length Mark (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00d82, 0x00d83,), # Sinhala Sign Anusvaraya ..Sinhala Sign Visargaya (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna - (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dcf, 0x00dd4,), # Sinhala Vowel Sign Aela-..Sinhala Vowel Sign Ketti (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga Paa-pilla + (0x00dd8, 0x00ddf,), # Sinhala Vowel Sign Gaett..Sinhala Vowel Sign Gayan + (0x00df2, 0x00df3,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga (0x00e31, 0x00e31,), # Thai Character Mai Han-akat (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan @@ -2125,79 +2169,61 @@ ZERO_WIDTH = { (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung Nyi Zla (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung Sgor Rtags (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru - (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga - (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f3e, 0x00f3f,), # Tibetan Sign Yar Tshes ..Tibetan Sign Mar Tshes + (0x00f71, 0x00f84,), # Tibetan Vowel Sign Aa ..Tibetan Mark Halanta (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gdan - (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu - (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below - (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat - (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M - (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0102b, 0x0103e,), # Myanmar Vowel Sign Tall ..Myanmar Consonant Sign M + (0x01056, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01062, 0x01064,), # Myanmar Vowel Sign Sgaw ..Myanmar Tone Mark Sgaw K + (0x01067, 0x0106d,), # Myanmar Vowel Sign Weste..Myanmar Sign Western Pwo (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah - (0x01082, 0x01082,), # Myanmar Consonant Sign Shan Medial Wa - (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan - (0x0108d, 0x0108d,), # Myanmar Sign Shan Council Emphatic Tone - (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton Ai + (0x01082, 0x0108d,), # Myanmar Consonant Sign S..Myanmar Sign Shan Counci + (0x0108f, 0x0108f,), # Myanmar Sign Rumai Palaung Tone-5 + (0x0109a, 0x0109d,), # Myanmar Sign Khamti Tone..Myanmar Vowel Sign Aiton (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U - (0x017b4, 0x017b5,), # Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa - (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua - (0x017c6, 0x017c6,), # Khmer Sign Nikahit - (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017b4, 0x017d3,), # Khmer Vowel Inherent Aq ..Khmer Sign Bathamasat (0x017dd, 0x017dd,), # Khmer Sign Atthacan - (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x0180b, 0x0180e,), # Mongolian Free Variation..Mongolian Vowel Separato (0x01885, 0x01886,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal (0x018a9, 0x018a9,), # Mongolian Letter Ali Gali Dagalga - (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U - (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O - (0x01932, 0x01932,), # Limbu Small Letter Anusvara - (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i - (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U - (0x01a1b, 0x01a1b,), # Buginese Vowel Sign Ae - (0x01a56, 0x01a56,), # Tai Tham Consonant Sign Medial La - (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign - (0x01a60, 0x01a60,), # Tai Tham Sign Sakot - (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai Sat - (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B - (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01920, 0x0192b,), # Limbu Vowel Sign A ..Limbu Subjoined Letter W + (0x01930, 0x0193b,), # Limbu Small Letter Ka ..Limbu Sign Sa-i + (0x01a17, 0x01a1b,), # Buginese Vowel Sign I ..Buginese Vowel Sign Ae + (0x01a55, 0x01a5e,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a60, 0x01a7c,), # Tai Tham Sign Sakot ..Tai Tham Sign Khuen-lue (0x01a7f, 0x01a7f,), # Tai Tham Combining Cryptogrammic Dot (0x01ab0, 0x01abe,), # Combining Doubled Circum..Combining Parentheses Ov - (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang - (0x01b34, 0x01b34,), # Balinese Sign Rerekan - (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R - (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La Lenga - (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepet + (0x01b00, 0x01b04,), # Balinese Sign Ulu Ricem ..Balinese Sign Bisah + (0x01b34, 0x01b44,), # Balinese Sign Rerekan ..Balinese Adeg Adeg (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol - (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar - (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan - (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan - (0x01bab, 0x01bad,), # Sundanese Sign Virama ..Sundanese Consonant Sign - (0x01be6, 0x01be6,), # Batak Sign Tompi - (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee - (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O - (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H - (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T - (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01b80, 0x01b82,), # Sundanese Sign Panyecek ..Sundanese Sign Pangwisad + (0x01ba1, 0x01bad,), # Sundanese Consonant Sign..Sundanese Consonant Sign + (0x01be6, 0x01bf3,), # Batak Sign Tompi ..Batak Panongonan + (0x01c24, 0x01c37,), # Lepcha Subjoined Letter ..Lepcha Sign Nukta (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha - (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash - (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01cd4, 0x01ce8,), # Vedic Sign Yajurvedic Mi..Vedic Sign Visarga Anuda (0x01ced, 0x01ced,), # Vedic Sign Tiryak - (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above + (0x01cf2, 0x01cf4,), # Vedic Sign Ardhavisarga ..Vedic Tone Candra Above (0x01cf8, 0x01cf9,), # Vedic Tone Ring Above ..Vedic Tone Double Ring A (0x01dc0, 0x01df5,), # Combining Dotted Grave A..Combining Up Tack Above (0x01dfb, 0x01dff,), # Combining Deletion Mark ..Combining Right Arrowhea + (0x0200b, 0x0200f,), # Zero Width Space ..Right-to-left Mark + (0x02028, 0x0202e,), # Line Separator ..Right-to-left Override + (0x02060, 0x02064,), # Word Joiner ..Invisible Plus + (0x02066, 0x0206f,), # Left-to-right Isolate ..Nominal Digit Shapes (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joiner (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette - (0x0302a, 0x0302d,), # Ideographic Level Tone M..Ideographic Entering Ton + (0x0302a, 0x0302f,), # Ideographic Level Tone M..Hangul Double Dot Tone M (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer @@ -2206,35 +2232,33 @@ ZERO_WIDTH = { (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisvara (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasanta (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusvara - (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign - (0x0a8c4, 0x0a8c5,), # Saurashtra Sign Virama ..Saurashtra Sign Candrabi + (0x0a823, 0x0a827,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a880, 0x0a881,), # Saurashtra Sign Anusvara..Saurashtra Sign Visarga + (0x0a8b4, 0x0a8c5,), # Saurashtra Consonant Sig..Saurashtra Sign Candrabi (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop - (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R - (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar - (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu - (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku - (0x0a9bc, 0x0a9bc,), # Javanese Vowel Sign Pepet + (0x0a947, 0x0a953,), # Rejang Vowel Sign I ..Rejang Virama + (0x0a980, 0x0a983,), # Javanese Sign Panyangga ..Javanese Sign Wignyan + (0x0a9b3, 0x0a9c0,), # Javanese Sign Cecak Telu..Javanese Pangkon (0x0a9e5, 0x0a9e5,), # Myanmar Sign Shan Saw - (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe - (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue - (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0aa29, 0x0aa36,), # Cham Vowel Sign Aa ..Cham Consonant Sign Wa (0x0aa43, 0x0aa43,), # Cham Consonant Sign Final Ng - (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Final M - (0x0aa7c, 0x0aa7c,), # Myanmar Sign Tai Laing Tone-2 + (0x0aa4c, 0x0aa4d,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa7b, 0x0aa7d,), # Myanmar Sign Pao Karen T..Myanmar Sign Tai Laing T (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho - (0x0aaec, 0x0aaed,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign - (0x0aaf6, 0x0aaf6,), # Meetei Mayek Virama - (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign Anap - (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign Unap - (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek + (0x0aaeb, 0x0aaef,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf5, 0x0aaf6,), # Meetei Mayek Vowel Sign ..Meetei Mayek Virama + (0x0abe3, 0x0abea,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abec, 0x0abed,), # Meetei Mayek Lum Iyek ..Meetei Mayek Apun Iyek (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spanish Varika (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 (0x0fe20, 0x0fe2f,), # Combining Ligature Left ..Combining Cyrillic Titlo + (0x0feff, 0x0feff,), # Zero Width No-break Space + (0x0fff9, 0x0fffb,), # Interlinear Annotation A..Interlinear Annotation T (0x101fd, 0x101fd,), # Phaistos Disc Sign Combining Oblique Stroke (0x102e0, 0x102e0,), # Coptic Epact Thousands Mark (0x10376, 0x1037a,), # Combining Old Permic Let..Combining Old Permic Let @@ -2244,63 +2268,49 @@ ZERO_WIDTH = { (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo (0x10a3f, 0x10a3f,), # Kharoshthi Virama (0x10ae5, 0x10ae6,), # Manichaean Abbreviation ..Manichaean Abbreviation - (0x11001, 0x11001,), # Brahmi Sign Anusvara + (0x11000, 0x11002,), # Brahmi Sign Candrabindu ..Brahmi Sign Visarga (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama - (0x1107f, 0x11081,), # Brahmi Number Joiner ..Kaithi Sign Anusvara - (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai - (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x1107f, 0x11082,), # Brahmi Number Joiner ..Kaithi Sign Visarga + (0x110b0, 0x110ba,), # Kaithi Vowel Sign Aa ..Kaithi Sign Nukta + (0x110bd, 0x110bd,), # Kaithi Number Sign (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga - (0x11127, 0x1112b,), # Chakma Vowel Sign A ..Chakma Vowel Sign Uu - (0x1112d, 0x11134,), # Chakma Vowel Sign Ai ..Chakma Maayyaa + (0x11127, 0x11134,), # Chakma Vowel Sign A ..Chakma Maayyaa (0x11173, 0x11173,), # Mahajani Sign Nukta - (0x11180, 0x11181,), # Sharada Sign Candrabindu..Sharada Sign Anusvara - (0x111b6, 0x111be,), # Sharada Vowel Sign U ..Sharada Vowel Sign O + (0x11180, 0x11182,), # Sharada Sign Candrabindu..Sharada Sign Visarga + (0x111b3, 0x111c0,), # Sharada Vowel Sign Aa ..Sharada Sign Virama (0x111ca, 0x111cc,), # Sharada Sign Nukta ..Sharada Extra Short Vowe - (0x1122f, 0x11231,), # Khojki Vowel Sign U ..Khojki Vowel Sign Ai - (0x11234, 0x11234,), # Khojki Sign Anusvara - (0x11236, 0x11237,), # Khojki Sign Nukta ..Khojki Sign Shadda + (0x1122c, 0x11237,), # Khojki Vowel Sign Aa ..Khojki Sign Shadda (0x1123e, 0x1123e,), # Khojki Sign Sukun - (0x112df, 0x112df,), # Khudawadi Sign Anusvara - (0x112e3, 0x112ea,), # Khudawadi Vowel Sign U ..Khudawadi Sign Virama - (0x11300, 0x11301,), # Grantha Sign Combining A..Grantha Sign Candrabindu + (0x112df, 0x112ea,), # Khudawadi Sign Anusvara ..Khudawadi Sign Virama + (0x11300, 0x11303,), # Grantha Sign Combining A..Grantha Sign Visarga (0x1133c, 0x1133c,), # Grantha Sign Nukta - (0x11340, 0x11340,), # Grantha Vowel Sign Ii + (0x1133e, 0x11344,), # Grantha Vowel Sign Aa ..Grantha Vowel Sign Vocal + (0x11347, 0x11348,), # Grantha Vowel Sign Ee ..Grantha Vowel Sign Ai + (0x1134b, 0x1134d,), # Grantha Vowel Sign Oo ..Grantha Sign Virama + (0x11357, 0x11357,), # Grantha Au Length Mark + (0x11362, 0x11363,), # Grantha Vowel Sign Vocal..Grantha Vowel Sign Vocal (0x11366, 0x1136c,), # Combining Grantha Digit ..Combining Grantha Digit (0x11370, 0x11374,), # Combining Grantha Letter..Combining Grantha Letter - (0x11438, 0x1143f,), # Newa Vowel Sign U ..Newa Vowel Sign Ai - (0x11442, 0x11444,), # Newa Sign Virama ..Newa Sign Anusvara - (0x11446, 0x11446,), # Newa Sign Nukta - (0x114b3, 0x114b8,), # Tirhuta Vowel Sign U ..Tirhuta Vowel Sign Vocal - (0x114ba, 0x114ba,), # Tirhuta Vowel Sign Short E - (0x114bf, 0x114c0,), # Tirhuta Sign Candrabindu..Tirhuta Sign Anusvara - (0x114c2, 0x114c3,), # Tirhuta Sign Virama ..Tirhuta Sign Nukta - (0x115b2, 0x115b5,), # Siddham Vowel Sign U ..Siddham Vowel Sign Vocal - (0x115bc, 0x115bd,), # Siddham Sign Candrabindu..Siddham Sign Anusvara - (0x115bf, 0x115c0,), # Siddham Sign Virama ..Siddham Sign Nukta + (0x11435, 0x11446,), # Newa Vowel Sign Aa ..Newa Sign Nukta + (0x114b0, 0x114c3,), # Tirhuta Vowel Sign Aa ..Tirhuta Sign Nukta + (0x115af, 0x115b5,), # Siddham Vowel Sign Aa ..Siddham Vowel Sign Vocal + (0x115b8, 0x115c0,), # Siddham Vowel Sign E ..Siddham Sign Nukta (0x115dc, 0x115dd,), # Siddham Vowel Sign Alter..Siddham Vowel Sign Alter - (0x11633, 0x1163a,), # Modi Vowel Sign U ..Modi Vowel Sign Ai - (0x1163d, 0x1163d,), # Modi Sign Anusvara - (0x1163f, 0x11640,), # Modi Sign Virama ..Modi Sign Ardhacandra - (0x116ab, 0x116ab,), # Takri Sign Anusvara - (0x116ad, 0x116ad,), # Takri Vowel Sign Aa - (0x116b0, 0x116b5,), # Takri Vowel Sign U ..Takri Vowel Sign Au - (0x116b7, 0x116b7,), # Takri Sign Nukta - (0x1171d, 0x1171f,), # Ahom Consonant Sign Medi..Ahom Consonant Sign Medi - (0x11722, 0x11725,), # Ahom Vowel Sign I ..Ahom Vowel Sign Uu - (0x11727, 0x1172b,), # Ahom Vowel Sign Aw ..Ahom Sign Killer - (0x11c30, 0x11c36,), # Bhaiksuki Vowel Sign I ..Bhaiksuki Vowel Sign Voc - (0x11c38, 0x11c3d,), # Bhaiksuki Vowel Sign E ..Bhaiksuki Sign Anusvara - (0x11c3f, 0x11c3f,), # Bhaiksuki Sign Virama + (0x11630, 0x11640,), # Modi Vowel Sign Aa ..Modi Sign Ardhacandra + (0x116ab, 0x116b7,), # Takri Sign Anusvara ..Takri Sign Nukta + (0x1171d, 0x1172b,), # Ahom Consonant Sign Medi..Ahom Sign Killer + (0x11c2f, 0x11c36,), # Bhaiksuki Vowel Sign Aa ..Bhaiksuki Vowel Sign Voc + (0x11c38, 0x11c3f,), # Bhaiksuki Vowel Sign E ..Bhaiksuki Sign Virama (0x11c92, 0x11ca7,), # Marchen Subjoined Letter..Marchen Subjoined Letter - (0x11caa, 0x11cb0,), # Marchen Subjoined Letter..Marchen Vowel Sign Aa - (0x11cb2, 0x11cb3,), # Marchen Vowel Sign U ..Marchen Vowel Sign E - (0x11cb5, 0x11cb6,), # Marchen Sign Anusvara ..Marchen Sign Candrabindu + (0x11ca9, 0x11cb6,), # Marchen Subjoined Letter..Marchen Sign Candrabindu (0x16af0, 0x16af4,), # Bassa Vah Combining High..Bassa Vah Combining High (0x16b30, 0x16b36,), # Pahawh Hmong Mark Cim Tu..Pahawh Hmong Mark Cim Ta + (0x16f51, 0x16f7e,), # Miao Sign Aspiration ..Miao Vowel Sign Ng (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below (0x1bc9d, 0x1bc9e,), # Duployan Thick Letter Se..Duployan Double Mark - (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining - (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1bca0, 0x1bca3,), # Shorthand Format Letter ..Shorthand Format Up Step + (0x1d165, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d16d, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical @@ -2317,12 +2327,17 @@ ZERO_WIDTH = { (0x1e026, 0x1e02a,), # Combining Glagolitic Let..Combining Glagolitic Let (0x1e8d0, 0x1e8d6,), # Mende Kikakui Combining ..Mende Kikakui Combining (0x1e944, 0x1e94a,), # Adlam Alif Lengthener ..Adlam Nukta + (0x1f3fb, 0x1f3ff,), # Emoji Modifier Fitzpatri..Emoji Modifier Fitzpatri + (0xe0001, 0xe0001,), # Language Tag + (0xe0020, 0xe007f,), # Tag Space ..Cancel Tag (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 ), '10.0.0': ( # Source: DerivedGeneralCategory-10.0.0.txt # Date: 2017-03-08, 08:41:49 GMT # + (0x00000, 0x00000,), # (nil) + (0x000ad, 0x000ad,), # Soft Hyphen (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg @@ -2330,13 +2345,16 @@ ZERO_WIDTH = { (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot (0x005c7, 0x005c7,), # Hebrew Point Qamats Qatan + (0x00600, 0x00605,), # Arabic Number Sign ..Arabic Number Mark Above (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0061c, 0x0061c,), # Arabic Letter Mark (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below (0x00670, 0x00670,), # Arabic Letter Superscript Alef - (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006d6, 0x006dd,), # Arabic Small High Ligatu..Arabic End Of Ayah (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x0070f, 0x0070f,), # Syriac Abbreviation Mark (0x00711, 0x00711,), # Syriac Letter Superscript Alaph (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun @@ -2346,64 +2364,71 @@ ZERO_WIDTH = { (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark - (0x008d4, 0x008e1,), # Arabic Small High Word A..Arabic Small High Sign S - (0x008e3, 0x00902,), # Arabic Turned Damma Belo..Devanagari Sign Anusvara - (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe - (0x0093c, 0x0093c,), # Devanagari Sign Nukta - (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai - (0x0094d, 0x0094d,), # Devanagari Sign Virama + (0x008d4, 0x00903,), # Arabic Small High Word A..Devanagari Sign Visarga + (0x0093a, 0x0093c,), # Devanagari Vowel Sign Oe..Devanagari Sign Nukta + (0x0093e, 0x0094f,), # Devanagari Vowel Sign Aa..Devanagari Vowel Sign Aw (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo - (0x00981, 0x00981,), # Bengali Sign Candrabindu + (0x00981, 0x00983,), # Bengali Sign Candrabindu..Bengali Sign Visarga (0x009bc, 0x009bc,), # Bengali Sign Nukta - (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal - (0x009cd, 0x009cd,), # Bengali Sign Virama + (0x009be, 0x009c4,), # Bengali Vowel Sign Aa ..Bengali Vowel Sign Vocal + (0x009c7, 0x009c8,), # Bengali Vowel Sign E ..Bengali Vowel Sign Ai + (0x009cb, 0x009cd,), # Bengali Vowel Sign O ..Bengali Sign Virama + (0x009d7, 0x009d7,), # Bengali Au Length Mark (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal - (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a01, 0x00a03,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Visarga (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta - (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a3e, 0x00a42,), # Gurmukhi Vowel Sign Aa ..Gurmukhi Vowel Sign Uu (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash - (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00a81, 0x00a83,), # Gujarati Sign Candrabind..Gujarati Sign Visarga (0x00abc, 0x00abc,), # Gujarati Sign Nukta - (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand - (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai - (0x00acd, 0x00acd,), # Gujarati Sign Virama + (0x00abe, 0x00ac5,), # Gujarati Vowel Sign Aa ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac9,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Cand + (0x00acb, 0x00acd,), # Gujarati Vowel Sign O ..Gujarati Sign Virama (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca (0x00afa, 0x00aff,), # Gujarati Sign Sukun ..Gujarati Sign Two-circle - (0x00b01, 0x00b01,), # Oriya Sign Candrabindu + (0x00b01, 0x00b03,), # Oriya Sign Candrabindu ..Oriya Sign Visarga (0x00b3c, 0x00b3c,), # Oriya Sign Nukta - (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I - (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic - (0x00b4d, 0x00b4d,), # Oriya Sign Virama - (0x00b56, 0x00b56,), # Oriya Ai Length Mark + (0x00b3e, 0x00b44,), # Oriya Vowel Sign Aa ..Oriya Vowel Sign Vocalic + (0x00b47, 0x00b48,), # Oriya Vowel Sign E ..Oriya Vowel Sign Ai + (0x00b4b, 0x00b4d,), # Oriya Vowel Sign O ..Oriya Sign Virama + (0x00b56, 0x00b57,), # Oriya Ai Length Mark ..Oriya Au Length Mark (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic (0x00b82, 0x00b82,), # Tamil Sign Anusvara - (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii - (0x00bcd, 0x00bcd,), # Tamil Sign Virama - (0x00c00, 0x00c00,), # Telugu Sign Combining Candrabindu Above - (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00bbe, 0x00bc2,), # Tamil Vowel Sign Aa ..Tamil Vowel Sign Uu + (0x00bc6, 0x00bc8,), # Tamil Vowel Sign E ..Tamil Vowel Sign Ai + (0x00bca, 0x00bcd,), # Tamil Vowel Sign O ..Tamil Sign Virama + (0x00bd7, 0x00bd7,), # Tamil Au Length Mark + (0x00c00, 0x00c03,), # Telugu Sign Combining Ca..Telugu Sign Visarga + (0x00c3e, 0x00c44,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Vocali (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali - (0x00c81, 0x00c81,), # Kannada Sign Candrabindu + (0x00c81, 0x00c83,), # Kannada Sign Candrabindu..Kannada Sign Visarga (0x00cbc, 0x00cbc,), # Kannada Sign Nukta - (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I - (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E - (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00cbe, 0x00cc4,), # Kannada Vowel Sign Aa ..Kannada Vowel Sign Vocal + (0x00cc6, 0x00cc8,), # Kannada Vowel Sign E ..Kannada Vowel Sign Ai + (0x00cca, 0x00ccd,), # Kannada Vowel Sign O ..Kannada Sign Virama + (0x00cd5, 0x00cd6,), # Kannada Length Mark ..Kannada Ai Length Mark (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal - (0x00d00, 0x00d01,), # Malayalam Sign Combining..Malayalam Sign Candrabin + (0x00d00, 0x00d03,), # Malayalam Sign Combining..Malayalam Sign Visarga (0x00d3b, 0x00d3c,), # Malayalam Sign Vertical ..Malayalam Sign Circular - (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc - (0x00d4d, 0x00d4d,), # Malayalam Sign Virama + (0x00d3e, 0x00d44,), # Malayalam Vowel Sign Aa ..Malayalam Vowel Sign Voc + (0x00d46, 0x00d48,), # Malayalam Vowel Sign E ..Malayalam Vowel Sign Ai + (0x00d4a, 0x00d4d,), # Malayalam Vowel Sign O ..Malayalam Sign Virama + (0x00d57, 0x00d57,), # Malayalam Au Length Mark (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00d82, 0x00d83,), # Sinhala Sign Anusvaraya ..Sinhala Sign Visargaya (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna - (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dcf, 0x00dd4,), # Sinhala Vowel Sign Aela-..Sinhala Vowel Sign Ketti (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga Paa-pilla + (0x00dd8, 0x00ddf,), # Sinhala Vowel Sign Gaett..Sinhala Vowel Sign Gayan + (0x00df2, 0x00df3,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga (0x00e31, 0x00e31,), # Thai Character Mai Han-akat (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan @@ -2415,79 +2440,61 @@ ZERO_WIDTH = { (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung Nyi Zla (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung Sgor Rtags (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru - (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga - (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f3e, 0x00f3f,), # Tibetan Sign Yar Tshes ..Tibetan Sign Mar Tshes + (0x00f71, 0x00f84,), # Tibetan Vowel Sign Aa ..Tibetan Mark Halanta (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gdan - (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu - (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below - (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat - (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M - (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0102b, 0x0103e,), # Myanmar Vowel Sign Tall ..Myanmar Consonant Sign M + (0x01056, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01062, 0x01064,), # Myanmar Vowel Sign Sgaw ..Myanmar Tone Mark Sgaw K + (0x01067, 0x0106d,), # Myanmar Vowel Sign Weste..Myanmar Sign Western Pwo (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah - (0x01082, 0x01082,), # Myanmar Consonant Sign Shan Medial Wa - (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan - (0x0108d, 0x0108d,), # Myanmar Sign Shan Council Emphatic Tone - (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton Ai + (0x01082, 0x0108d,), # Myanmar Consonant Sign S..Myanmar Sign Shan Counci + (0x0108f, 0x0108f,), # Myanmar Sign Rumai Palaung Tone-5 + (0x0109a, 0x0109d,), # Myanmar Sign Khamti Tone..Myanmar Vowel Sign Aiton (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U - (0x017b4, 0x017b5,), # Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa - (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua - (0x017c6, 0x017c6,), # Khmer Sign Nikahit - (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017b4, 0x017d3,), # Khmer Vowel Inherent Aq ..Khmer Sign Bathamasat (0x017dd, 0x017dd,), # Khmer Sign Atthacan - (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x0180b, 0x0180e,), # Mongolian Free Variation..Mongolian Vowel Separato (0x01885, 0x01886,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal (0x018a9, 0x018a9,), # Mongolian Letter Ali Gali Dagalga - (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U - (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O - (0x01932, 0x01932,), # Limbu Small Letter Anusvara - (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i - (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U - (0x01a1b, 0x01a1b,), # Buginese Vowel Sign Ae - (0x01a56, 0x01a56,), # Tai Tham Consonant Sign Medial La - (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign - (0x01a60, 0x01a60,), # Tai Tham Sign Sakot - (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai Sat - (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B - (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01920, 0x0192b,), # Limbu Vowel Sign A ..Limbu Subjoined Letter W + (0x01930, 0x0193b,), # Limbu Small Letter Ka ..Limbu Sign Sa-i + (0x01a17, 0x01a1b,), # Buginese Vowel Sign I ..Buginese Vowel Sign Ae + (0x01a55, 0x01a5e,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a60, 0x01a7c,), # Tai Tham Sign Sakot ..Tai Tham Sign Khuen-lue (0x01a7f, 0x01a7f,), # Tai Tham Combining Cryptogrammic Dot (0x01ab0, 0x01abe,), # Combining Doubled Circum..Combining Parentheses Ov - (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang - (0x01b34, 0x01b34,), # Balinese Sign Rerekan - (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R - (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La Lenga - (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepet + (0x01b00, 0x01b04,), # Balinese Sign Ulu Ricem ..Balinese Sign Bisah + (0x01b34, 0x01b44,), # Balinese Sign Rerekan ..Balinese Adeg Adeg (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol - (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar - (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan - (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan - (0x01bab, 0x01bad,), # Sundanese Sign Virama ..Sundanese Consonant Sign - (0x01be6, 0x01be6,), # Batak Sign Tompi - (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee - (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O - (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H - (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T - (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01b80, 0x01b82,), # Sundanese Sign Panyecek ..Sundanese Sign Pangwisad + (0x01ba1, 0x01bad,), # Sundanese Consonant Sign..Sundanese Consonant Sign + (0x01be6, 0x01bf3,), # Batak Sign Tompi ..Batak Panongonan + (0x01c24, 0x01c37,), # Lepcha Subjoined Letter ..Lepcha Sign Nukta (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha - (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash - (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01cd4, 0x01ce8,), # Vedic Sign Yajurvedic Mi..Vedic Sign Visarga Anuda (0x01ced, 0x01ced,), # Vedic Sign Tiryak - (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above - (0x01cf8, 0x01cf9,), # Vedic Tone Ring Above ..Vedic Tone Double Ring A + (0x01cf2, 0x01cf4,), # Vedic Sign Ardhavisarga ..Vedic Tone Candra Above + (0x01cf7, 0x01cf9,), # Vedic Sign Atikrama ..Vedic Tone Double Ring A (0x01dc0, 0x01df9,), # Combining Dotted Grave A..Combining Wide Inverted (0x01dfb, 0x01dff,), # Combining Deletion Mark ..Combining Right Arrowhea + (0x0200b, 0x0200f,), # Zero Width Space ..Right-to-left Mark + (0x02028, 0x0202e,), # Line Separator ..Right-to-left Override + (0x02060, 0x02064,), # Word Joiner ..Invisible Plus + (0x02066, 0x0206f,), # Left-to-right Isolate ..Nominal Digit Shapes (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joiner (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette - (0x0302a, 0x0302d,), # Ideographic Level Tone M..Ideographic Entering Ton + (0x0302a, 0x0302f,), # Ideographic Level Tone M..Hangul Double Dot Tone M (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer @@ -2496,35 +2503,33 @@ ZERO_WIDTH = { (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisvara (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasanta (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusvara - (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign - (0x0a8c4, 0x0a8c5,), # Saurashtra Sign Virama ..Saurashtra Sign Candrabi + (0x0a823, 0x0a827,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a880, 0x0a881,), # Saurashtra Sign Anusvara..Saurashtra Sign Visarga + (0x0a8b4, 0x0a8c5,), # Saurashtra Consonant Sig..Saurashtra Sign Candrabi (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop - (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R - (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar - (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu - (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku - (0x0a9bc, 0x0a9bc,), # Javanese Vowel Sign Pepet + (0x0a947, 0x0a953,), # Rejang Vowel Sign I ..Rejang Virama + (0x0a980, 0x0a983,), # Javanese Sign Panyangga ..Javanese Sign Wignyan + (0x0a9b3, 0x0a9c0,), # Javanese Sign Cecak Telu..Javanese Pangkon (0x0a9e5, 0x0a9e5,), # Myanmar Sign Shan Saw - (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe - (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue - (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0aa29, 0x0aa36,), # Cham Vowel Sign Aa ..Cham Consonant Sign Wa (0x0aa43, 0x0aa43,), # Cham Consonant Sign Final Ng - (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Final M - (0x0aa7c, 0x0aa7c,), # Myanmar Sign Tai Laing Tone-2 + (0x0aa4c, 0x0aa4d,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa7b, 0x0aa7d,), # Myanmar Sign Pao Karen T..Myanmar Sign Tai Laing T (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho - (0x0aaec, 0x0aaed,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign - (0x0aaf6, 0x0aaf6,), # Meetei Mayek Virama - (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign Anap - (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign Unap - (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek + (0x0aaeb, 0x0aaef,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf5, 0x0aaf6,), # Meetei Mayek Vowel Sign ..Meetei Mayek Virama + (0x0abe3, 0x0abea,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abec, 0x0abed,), # Meetei Mayek Lum Iyek ..Meetei Mayek Apun Iyek (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spanish Varika (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 (0x0fe20, 0x0fe2f,), # Combining Ligature Left ..Combining Cyrillic Titlo + (0x0feff, 0x0feff,), # Zero Width No-break Space + (0x0fff9, 0x0fffb,), # Interlinear Annotation A..Interlinear Annotation T (0x101fd, 0x101fd,), # Phaistos Disc Sign Combining Oblique Stroke (0x102e0, 0x102e0,), # Coptic Epact Thousands Mark (0x10376, 0x1037a,), # Combining Old Permic Let..Combining Old Permic Let @@ -2534,66 +2539,47 @@ ZERO_WIDTH = { (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo (0x10a3f, 0x10a3f,), # Kharoshthi Virama (0x10ae5, 0x10ae6,), # Manichaean Abbreviation ..Manichaean Abbreviation - (0x11001, 0x11001,), # Brahmi Sign Anusvara + (0x11000, 0x11002,), # Brahmi Sign Candrabindu ..Brahmi Sign Visarga (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama - (0x1107f, 0x11081,), # Brahmi Number Joiner ..Kaithi Sign Anusvara - (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai - (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x1107f, 0x11082,), # Brahmi Number Joiner ..Kaithi Sign Visarga + (0x110b0, 0x110ba,), # Kaithi Vowel Sign Aa ..Kaithi Sign Nukta + (0x110bd, 0x110bd,), # Kaithi Number Sign (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga - (0x11127, 0x1112b,), # Chakma Vowel Sign A ..Chakma Vowel Sign Uu - (0x1112d, 0x11134,), # Chakma Vowel Sign Ai ..Chakma Maayyaa + (0x11127, 0x11134,), # Chakma Vowel Sign A ..Chakma Maayyaa (0x11173, 0x11173,), # Mahajani Sign Nukta - (0x11180, 0x11181,), # Sharada Sign Candrabindu..Sharada Sign Anusvara - (0x111b6, 0x111be,), # Sharada Vowel Sign U ..Sharada Vowel Sign O + (0x11180, 0x11182,), # Sharada Sign Candrabindu..Sharada Sign Visarga + (0x111b3, 0x111c0,), # Sharada Vowel Sign Aa ..Sharada Sign Virama (0x111ca, 0x111cc,), # Sharada Sign Nukta ..Sharada Extra Short Vowe - (0x1122f, 0x11231,), # Khojki Vowel Sign U ..Khojki Vowel Sign Ai - (0x11234, 0x11234,), # Khojki Sign Anusvara - (0x11236, 0x11237,), # Khojki Sign Nukta ..Khojki Sign Shadda + (0x1122c, 0x11237,), # Khojki Vowel Sign Aa ..Khojki Sign Shadda (0x1123e, 0x1123e,), # Khojki Sign Sukun - (0x112df, 0x112df,), # Khudawadi Sign Anusvara - (0x112e3, 0x112ea,), # Khudawadi Vowel Sign U ..Khudawadi Sign Virama - (0x11300, 0x11301,), # Grantha Sign Combining A..Grantha Sign Candrabindu + (0x112df, 0x112ea,), # Khudawadi Sign Anusvara ..Khudawadi Sign Virama + (0x11300, 0x11303,), # Grantha Sign Combining A..Grantha Sign Visarga (0x1133c, 0x1133c,), # Grantha Sign Nukta - (0x11340, 0x11340,), # Grantha Vowel Sign Ii + (0x1133e, 0x11344,), # Grantha Vowel Sign Aa ..Grantha Vowel Sign Vocal + (0x11347, 0x11348,), # Grantha Vowel Sign Ee ..Grantha Vowel Sign Ai + (0x1134b, 0x1134d,), # Grantha Vowel Sign Oo ..Grantha Sign Virama + (0x11357, 0x11357,), # Grantha Au Length Mark + (0x11362, 0x11363,), # Grantha Vowel Sign Vocal..Grantha Vowel Sign Vocal (0x11366, 0x1136c,), # Combining Grantha Digit ..Combining Grantha Digit (0x11370, 0x11374,), # Combining Grantha Letter..Combining Grantha Letter - (0x11438, 0x1143f,), # Newa Vowel Sign U ..Newa Vowel Sign Ai - (0x11442, 0x11444,), # Newa Sign Virama ..Newa Sign Anusvara - (0x11446, 0x11446,), # Newa Sign Nukta - (0x114b3, 0x114b8,), # Tirhuta Vowel Sign U ..Tirhuta Vowel Sign Vocal - (0x114ba, 0x114ba,), # Tirhuta Vowel Sign Short E - (0x114bf, 0x114c0,), # Tirhuta Sign Candrabindu..Tirhuta Sign Anusvara - (0x114c2, 0x114c3,), # Tirhuta Sign Virama ..Tirhuta Sign Nukta - (0x115b2, 0x115b5,), # Siddham Vowel Sign U ..Siddham Vowel Sign Vocal - (0x115bc, 0x115bd,), # Siddham Sign Candrabindu..Siddham Sign Anusvara - (0x115bf, 0x115c0,), # Siddham Sign Virama ..Siddham Sign Nukta + (0x11435, 0x11446,), # Newa Vowel Sign Aa ..Newa Sign Nukta + (0x114b0, 0x114c3,), # Tirhuta Vowel Sign Aa ..Tirhuta Sign Nukta + (0x115af, 0x115b5,), # Siddham Vowel Sign Aa ..Siddham Vowel Sign Vocal + (0x115b8, 0x115c0,), # Siddham Vowel Sign E ..Siddham Sign Nukta (0x115dc, 0x115dd,), # Siddham Vowel Sign Alter..Siddham Vowel Sign Alter - (0x11633, 0x1163a,), # Modi Vowel Sign U ..Modi Vowel Sign Ai - (0x1163d, 0x1163d,), # Modi Sign Anusvara - (0x1163f, 0x11640,), # Modi Sign Virama ..Modi Sign Ardhacandra - (0x116ab, 0x116ab,), # Takri Sign Anusvara - (0x116ad, 0x116ad,), # Takri Vowel Sign Aa - (0x116b0, 0x116b5,), # Takri Vowel Sign U ..Takri Vowel Sign Au - (0x116b7, 0x116b7,), # Takri Sign Nukta - (0x1171d, 0x1171f,), # Ahom Consonant Sign Medi..Ahom Consonant Sign Medi - (0x11722, 0x11725,), # Ahom Vowel Sign I ..Ahom Vowel Sign Uu - (0x11727, 0x1172b,), # Ahom Vowel Sign Aw ..Ahom Sign Killer - (0x11a01, 0x11a06,), # Zanabazar Square Vowel S..Zanabazar Square Vowel S - (0x11a09, 0x11a0a,), # Zanabazar Square Vowel S..Zanabazar Square Vowel L - (0x11a33, 0x11a38,), # Zanabazar Square Final C..Zanabazar Square Sign An + (0x11630, 0x11640,), # Modi Vowel Sign Aa ..Modi Sign Ardhacandra + (0x116ab, 0x116b7,), # Takri Sign Anusvara ..Takri Sign Nukta + (0x1171d, 0x1172b,), # Ahom Consonant Sign Medi..Ahom Sign Killer + (0x11a01, 0x11a0a,), # Zanabazar Square Vowel S..Zanabazar Square Vowel L + (0x11a33, 0x11a39,), # Zanabazar Square Final C..Zanabazar Square Sign Vi (0x11a3b, 0x11a3e,), # Zanabazar Square Cluster..Zanabazar Square Cluster (0x11a47, 0x11a47,), # Zanabazar Square Subjoiner - (0x11a51, 0x11a56,), # Soyombo Vowel Sign I ..Soyombo Vowel Sign Oe - (0x11a59, 0x11a5b,), # Soyombo Vowel Sign Vocal..Soyombo Vowel Length Mar - (0x11a8a, 0x11a96,), # Soyombo Final Consonant ..Soyombo Sign Anusvara - (0x11a98, 0x11a99,), # Soyombo Gemination Mark ..Soyombo Subjoiner - (0x11c30, 0x11c36,), # Bhaiksuki Vowel Sign I ..Bhaiksuki Vowel Sign Voc - (0x11c38, 0x11c3d,), # Bhaiksuki Vowel Sign E ..Bhaiksuki Sign Anusvara - (0x11c3f, 0x11c3f,), # Bhaiksuki Sign Virama + (0x11a51, 0x11a5b,), # Soyombo Vowel Sign I ..Soyombo Vowel Length Mar + (0x11a8a, 0x11a99,), # Soyombo Final Consonant ..Soyombo Subjoiner + (0x11c2f, 0x11c36,), # Bhaiksuki Vowel Sign Aa ..Bhaiksuki Vowel Sign Voc + (0x11c38, 0x11c3f,), # Bhaiksuki Vowel Sign E ..Bhaiksuki Sign Virama (0x11c92, 0x11ca7,), # Marchen Subjoined Letter..Marchen Subjoined Letter - (0x11caa, 0x11cb0,), # Marchen Subjoined Letter..Marchen Vowel Sign Aa - (0x11cb2, 0x11cb3,), # Marchen Vowel Sign U ..Marchen Vowel Sign E - (0x11cb5, 0x11cb6,), # Marchen Sign Anusvara ..Marchen Sign Candrabindu + (0x11ca9, 0x11cb6,), # Marchen Subjoined Letter..Marchen Sign Candrabindu (0x11d31, 0x11d36,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign (0x11d3a, 0x11d3a,), # Masaram Gondi Vowel Sign E (0x11d3c, 0x11d3d,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign @@ -2601,10 +2587,12 @@ ZERO_WIDTH = { (0x11d47, 0x11d47,), # Masaram Gondi Ra-kara (0x16af0, 0x16af4,), # Bassa Vah Combining High..Bassa Vah Combining High (0x16b30, 0x16b36,), # Pahawh Hmong Mark Cim Tu..Pahawh Hmong Mark Cim Ta + (0x16f51, 0x16f7e,), # Miao Sign Aspiration ..Miao Vowel Sign Ng (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below (0x1bc9d, 0x1bc9e,), # Duployan Thick Letter Se..Duployan Double Mark - (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining - (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1bca0, 0x1bca3,), # Shorthand Format Letter ..Shorthand Format Up Step + (0x1d165, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d16d, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical @@ -2621,12 +2609,17 @@ ZERO_WIDTH = { (0x1e026, 0x1e02a,), # Combining Glagolitic Let..Combining Glagolitic Let (0x1e8d0, 0x1e8d6,), # Mende Kikakui Combining ..Mende Kikakui Combining (0x1e944, 0x1e94a,), # Adlam Alif Lengthener ..Adlam Nukta + (0x1f3fb, 0x1f3ff,), # Emoji Modifier Fitzpatri..Emoji Modifier Fitzpatri + (0xe0001, 0xe0001,), # Language Tag + (0xe0020, 0xe007f,), # Tag Space ..Cancel Tag (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 ), '11.0.0': ( # Source: DerivedGeneralCategory-11.0.0.txt # Date: 2018-02-21, 05:34:04 GMT # + (0x00000, 0x00000,), # (nil) + (0x000ad, 0x000ad,), # Soft Hyphen (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg @@ -2634,13 +2627,16 @@ ZERO_WIDTH = { (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot (0x005c7, 0x005c7,), # Hebrew Point Qamats Qatan + (0x00600, 0x00605,), # Arabic Number Sign ..Arabic Number Mark Above (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0061c, 0x0061c,), # Arabic Letter Mark (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below (0x00670, 0x00670,), # Arabic Letter Superscript Alef - (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006d6, 0x006dd,), # Arabic Small High Ligatu..Arabic End Of Ayah (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x0070f, 0x0070f,), # Syriac Abbreviation Mark (0x00711, 0x00711,), # Syriac Letter Superscript Alaph (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun @@ -2651,66 +2647,72 @@ ZERO_WIDTH = { (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark - (0x008d3, 0x008e1,), # Arabic Small Low Waw ..Arabic Small High Sign S - (0x008e3, 0x00902,), # Arabic Turned Damma Belo..Devanagari Sign Anusvara - (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe - (0x0093c, 0x0093c,), # Devanagari Sign Nukta - (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai - (0x0094d, 0x0094d,), # Devanagari Sign Virama + (0x008d3, 0x00903,), # Arabic Small Low Waw ..Devanagari Sign Visarga + (0x0093a, 0x0093c,), # Devanagari Vowel Sign Oe..Devanagari Sign Nukta + (0x0093e, 0x0094f,), # Devanagari Vowel Sign Aa..Devanagari Vowel Sign Aw (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo - (0x00981, 0x00981,), # Bengali Sign Candrabindu + (0x00981, 0x00983,), # Bengali Sign Candrabindu..Bengali Sign Visarga (0x009bc, 0x009bc,), # Bengali Sign Nukta - (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal - (0x009cd, 0x009cd,), # Bengali Sign Virama + (0x009be, 0x009c4,), # Bengali Vowel Sign Aa ..Bengali Vowel Sign Vocal + (0x009c7, 0x009c8,), # Bengali Vowel Sign E ..Bengali Vowel Sign Ai + (0x009cb, 0x009cd,), # Bengali Vowel Sign O ..Bengali Sign Virama + (0x009d7, 0x009d7,), # Bengali Au Length Mark (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal (0x009fe, 0x009fe,), # Bengali Sandhi Mark - (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a01, 0x00a03,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Visarga (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta - (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a3e, 0x00a42,), # Gurmukhi Vowel Sign Aa ..Gurmukhi Vowel Sign Uu (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash - (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00a81, 0x00a83,), # Gujarati Sign Candrabind..Gujarati Sign Visarga (0x00abc, 0x00abc,), # Gujarati Sign Nukta - (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand - (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai - (0x00acd, 0x00acd,), # Gujarati Sign Virama + (0x00abe, 0x00ac5,), # Gujarati Vowel Sign Aa ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac9,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Cand + (0x00acb, 0x00acd,), # Gujarati Vowel Sign O ..Gujarati Sign Virama (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca (0x00afa, 0x00aff,), # Gujarati Sign Sukun ..Gujarati Sign Two-circle - (0x00b01, 0x00b01,), # Oriya Sign Candrabindu + (0x00b01, 0x00b03,), # Oriya Sign Candrabindu ..Oriya Sign Visarga (0x00b3c, 0x00b3c,), # Oriya Sign Nukta - (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I - (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic - (0x00b4d, 0x00b4d,), # Oriya Sign Virama - (0x00b56, 0x00b56,), # Oriya Ai Length Mark + (0x00b3e, 0x00b44,), # Oriya Vowel Sign Aa ..Oriya Vowel Sign Vocalic + (0x00b47, 0x00b48,), # Oriya Vowel Sign E ..Oriya Vowel Sign Ai + (0x00b4b, 0x00b4d,), # Oriya Vowel Sign O ..Oriya Sign Virama + (0x00b56, 0x00b57,), # Oriya Ai Length Mark ..Oriya Au Length Mark (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic (0x00b82, 0x00b82,), # Tamil Sign Anusvara - (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii - (0x00bcd, 0x00bcd,), # Tamil Sign Virama - (0x00c00, 0x00c00,), # Telugu Sign Combining Candrabindu Above - (0x00c04, 0x00c04,), # Telugu Sign Combining Anusvara Above - (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00bbe, 0x00bc2,), # Tamil Vowel Sign Aa ..Tamil Vowel Sign Uu + (0x00bc6, 0x00bc8,), # Tamil Vowel Sign E ..Tamil Vowel Sign Ai + (0x00bca, 0x00bcd,), # Tamil Vowel Sign O ..Tamil Sign Virama + (0x00bd7, 0x00bd7,), # Tamil Au Length Mark + (0x00c00, 0x00c04,), # Telugu Sign Combining Ca..Telugu Sign Combining An + (0x00c3e, 0x00c44,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Vocali (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali - (0x00c81, 0x00c81,), # Kannada Sign Candrabindu + (0x00c81, 0x00c83,), # Kannada Sign Candrabindu..Kannada Sign Visarga (0x00cbc, 0x00cbc,), # Kannada Sign Nukta - (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I - (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E - (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00cbe, 0x00cc4,), # Kannada Vowel Sign Aa ..Kannada Vowel Sign Vocal + (0x00cc6, 0x00cc8,), # Kannada Vowel Sign E ..Kannada Vowel Sign Ai + (0x00cca, 0x00ccd,), # Kannada Vowel Sign O ..Kannada Sign Virama + (0x00cd5, 0x00cd6,), # Kannada Length Mark ..Kannada Ai Length Mark (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal - (0x00d00, 0x00d01,), # Malayalam Sign Combining..Malayalam Sign Candrabin + (0x00d00, 0x00d03,), # Malayalam Sign Combining..Malayalam Sign Visarga (0x00d3b, 0x00d3c,), # Malayalam Sign Vertical ..Malayalam Sign Circular - (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc - (0x00d4d, 0x00d4d,), # Malayalam Sign Virama + (0x00d3e, 0x00d44,), # Malayalam Vowel Sign Aa ..Malayalam Vowel Sign Voc + (0x00d46, 0x00d48,), # Malayalam Vowel Sign E ..Malayalam Vowel Sign Ai + (0x00d4a, 0x00d4d,), # Malayalam Vowel Sign O ..Malayalam Sign Virama + (0x00d57, 0x00d57,), # Malayalam Au Length Mark (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00d82, 0x00d83,), # Sinhala Sign Anusvaraya ..Sinhala Sign Visargaya (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna - (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dcf, 0x00dd4,), # Sinhala Vowel Sign Aela-..Sinhala Vowel Sign Ketti (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga Paa-pilla + (0x00dd8, 0x00ddf,), # Sinhala Vowel Sign Gaett..Sinhala Vowel Sign Gayan + (0x00df2, 0x00df3,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga (0x00e31, 0x00e31,), # Thai Character Mai Han-akat (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan @@ -2722,79 +2724,61 @@ ZERO_WIDTH = { (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung Nyi Zla (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung Sgor Rtags (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru - (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga - (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f3e, 0x00f3f,), # Tibetan Sign Yar Tshes ..Tibetan Sign Mar Tshes + (0x00f71, 0x00f84,), # Tibetan Vowel Sign Aa ..Tibetan Mark Halanta (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gdan - (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu - (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below - (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat - (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M - (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0102b, 0x0103e,), # Myanmar Vowel Sign Tall ..Myanmar Consonant Sign M + (0x01056, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01062, 0x01064,), # Myanmar Vowel Sign Sgaw ..Myanmar Tone Mark Sgaw K + (0x01067, 0x0106d,), # Myanmar Vowel Sign Weste..Myanmar Sign Western Pwo (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah - (0x01082, 0x01082,), # Myanmar Consonant Sign Shan Medial Wa - (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan - (0x0108d, 0x0108d,), # Myanmar Sign Shan Council Emphatic Tone - (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton Ai + (0x01082, 0x0108d,), # Myanmar Consonant Sign S..Myanmar Sign Shan Counci + (0x0108f, 0x0108f,), # Myanmar Sign Rumai Palaung Tone-5 + (0x0109a, 0x0109d,), # Myanmar Sign Khamti Tone..Myanmar Vowel Sign Aiton (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U - (0x017b4, 0x017b5,), # Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa - (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua - (0x017c6, 0x017c6,), # Khmer Sign Nikahit - (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017b4, 0x017d3,), # Khmer Vowel Inherent Aq ..Khmer Sign Bathamasat (0x017dd, 0x017dd,), # Khmer Sign Atthacan - (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x0180b, 0x0180e,), # Mongolian Free Variation..Mongolian Vowel Separato (0x01885, 0x01886,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal (0x018a9, 0x018a9,), # Mongolian Letter Ali Gali Dagalga - (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U - (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O - (0x01932, 0x01932,), # Limbu Small Letter Anusvara - (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i - (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U - (0x01a1b, 0x01a1b,), # Buginese Vowel Sign Ae - (0x01a56, 0x01a56,), # Tai Tham Consonant Sign Medial La - (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign - (0x01a60, 0x01a60,), # Tai Tham Sign Sakot - (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai Sat - (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B - (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01920, 0x0192b,), # Limbu Vowel Sign A ..Limbu Subjoined Letter W + (0x01930, 0x0193b,), # Limbu Small Letter Ka ..Limbu Sign Sa-i + (0x01a17, 0x01a1b,), # Buginese Vowel Sign I ..Buginese Vowel Sign Ae + (0x01a55, 0x01a5e,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a60, 0x01a7c,), # Tai Tham Sign Sakot ..Tai Tham Sign Khuen-lue (0x01a7f, 0x01a7f,), # Tai Tham Combining Cryptogrammic Dot (0x01ab0, 0x01abe,), # Combining Doubled Circum..Combining Parentheses Ov - (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang - (0x01b34, 0x01b34,), # Balinese Sign Rerekan - (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R - (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La Lenga - (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepet + (0x01b00, 0x01b04,), # Balinese Sign Ulu Ricem ..Balinese Sign Bisah + (0x01b34, 0x01b44,), # Balinese Sign Rerekan ..Balinese Adeg Adeg (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol - (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar - (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan - (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan - (0x01bab, 0x01bad,), # Sundanese Sign Virama ..Sundanese Consonant Sign - (0x01be6, 0x01be6,), # Batak Sign Tompi - (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee - (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O - (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H - (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T - (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01b80, 0x01b82,), # Sundanese Sign Panyecek ..Sundanese Sign Pangwisad + (0x01ba1, 0x01bad,), # Sundanese Consonant Sign..Sundanese Consonant Sign + (0x01be6, 0x01bf3,), # Batak Sign Tompi ..Batak Panongonan + (0x01c24, 0x01c37,), # Lepcha Subjoined Letter ..Lepcha Sign Nukta (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha - (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash - (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01cd4, 0x01ce8,), # Vedic Sign Yajurvedic Mi..Vedic Sign Visarga Anuda (0x01ced, 0x01ced,), # Vedic Sign Tiryak - (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above - (0x01cf8, 0x01cf9,), # Vedic Tone Ring Above ..Vedic Tone Double Ring A + (0x01cf2, 0x01cf4,), # Vedic Sign Ardhavisarga ..Vedic Tone Candra Above + (0x01cf7, 0x01cf9,), # Vedic Sign Atikrama ..Vedic Tone Double Ring A (0x01dc0, 0x01df9,), # Combining Dotted Grave A..Combining Wide Inverted (0x01dfb, 0x01dff,), # Combining Deletion Mark ..Combining Right Arrowhea + (0x0200b, 0x0200f,), # Zero Width Space ..Right-to-left Mark + (0x02028, 0x0202e,), # Line Separator ..Right-to-left Override + (0x02060, 0x02064,), # Word Joiner ..Invisible Plus + (0x02066, 0x0206f,), # Left-to-right Isolate ..Nominal Digit Shapes (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joiner (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette - (0x0302a, 0x0302d,), # Ideographic Level Tone M..Ideographic Entering Ton + (0x0302a, 0x0302f,), # Ideographic Level Tone M..Hangul Double Dot Tone M (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer @@ -2803,36 +2787,34 @@ ZERO_WIDTH = { (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisvara (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasanta (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusvara - (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign - (0x0a8c4, 0x0a8c5,), # Saurashtra Sign Virama ..Saurashtra Sign Candrabi + (0x0a823, 0x0a827,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a880, 0x0a881,), # Saurashtra Sign Anusvara..Saurashtra Sign Visarga + (0x0a8b4, 0x0a8c5,), # Saurashtra Consonant Sig..Saurashtra Sign Candrabi (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig (0x0a8ff, 0x0a8ff,), # Devanagari Vowel Sign Ay (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop - (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R - (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar - (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu - (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku - (0x0a9bc, 0x0a9bc,), # Javanese Vowel Sign Pepet + (0x0a947, 0x0a953,), # Rejang Vowel Sign I ..Rejang Virama + (0x0a980, 0x0a983,), # Javanese Sign Panyangga ..Javanese Sign Wignyan + (0x0a9b3, 0x0a9c0,), # Javanese Sign Cecak Telu..Javanese Pangkon (0x0a9e5, 0x0a9e5,), # Myanmar Sign Shan Saw - (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe - (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue - (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0aa29, 0x0aa36,), # Cham Vowel Sign Aa ..Cham Consonant Sign Wa (0x0aa43, 0x0aa43,), # Cham Consonant Sign Final Ng - (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Final M - (0x0aa7c, 0x0aa7c,), # Myanmar Sign Tai Laing Tone-2 + (0x0aa4c, 0x0aa4d,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa7b, 0x0aa7d,), # Myanmar Sign Pao Karen T..Myanmar Sign Tai Laing T (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho - (0x0aaec, 0x0aaed,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign - (0x0aaf6, 0x0aaf6,), # Meetei Mayek Virama - (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign Anap - (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign Unap - (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek + (0x0aaeb, 0x0aaef,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf5, 0x0aaf6,), # Meetei Mayek Vowel Sign ..Meetei Mayek Virama + (0x0abe3, 0x0abea,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abec, 0x0abed,), # Meetei Mayek Lum Iyek ..Meetei Mayek Apun Iyek (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spanish Varika (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 (0x0fe20, 0x0fe2f,), # Combining Ligature Left ..Combining Cyrillic Titlo + (0x0feff, 0x0feff,), # Zero Width No-break Space + (0x0fff9, 0x0fffb,), # Interlinear Annotation A..Interlinear Annotation T (0x101fd, 0x101fd,), # Phaistos Disc Sign Combining Oblique Stroke (0x102e0, 0x102e0,), # Coptic Epact Thousands Mark (0x10376, 0x1037a,), # Combining Old Permic Let..Combining Old Permic Let @@ -2844,83 +2826,68 @@ ZERO_WIDTH = { (0x10ae5, 0x10ae6,), # Manichaean Abbreviation ..Manichaean Abbreviation (0x10d24, 0x10d27,), # Hanifi Rohingya Sign Har..Hanifi Rohingya Sign Tas (0x10f46, 0x10f50,), # Sogdian Combining Dot Be..Sogdian Combining Stroke - (0x11001, 0x11001,), # Brahmi Sign Anusvara + (0x11000, 0x11002,), # Brahmi Sign Candrabindu ..Brahmi Sign Visarga (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama - (0x1107f, 0x11081,), # Brahmi Number Joiner ..Kaithi Sign Anusvara - (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai - (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x1107f, 0x11082,), # Brahmi Number Joiner ..Kaithi Sign Visarga + (0x110b0, 0x110ba,), # Kaithi Vowel Sign Aa ..Kaithi Sign Nukta + (0x110bd, 0x110bd,), # Kaithi Number Sign + (0x110cd, 0x110cd,), # Kaithi Number Sign Above (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga - (0x11127, 0x1112b,), # Chakma Vowel Sign A ..Chakma Vowel Sign Uu - (0x1112d, 0x11134,), # Chakma Vowel Sign Ai ..Chakma Maayyaa + (0x11127, 0x11134,), # Chakma Vowel Sign A ..Chakma Maayyaa + (0x11145, 0x11146,), # Chakma Vowel Sign Aa ..Chakma Vowel Sign Ei (0x11173, 0x11173,), # Mahajani Sign Nukta - (0x11180, 0x11181,), # Sharada Sign Candrabindu..Sharada Sign Anusvara - (0x111b6, 0x111be,), # Sharada Vowel Sign U ..Sharada Vowel Sign O + (0x11180, 0x11182,), # Sharada Sign Candrabindu..Sharada Sign Visarga + (0x111b3, 0x111c0,), # Sharada Vowel Sign Aa ..Sharada Sign Virama (0x111c9, 0x111cc,), # Sharada Sandhi Mark ..Sharada Extra Short Vowe - (0x1122f, 0x11231,), # Khojki Vowel Sign U ..Khojki Vowel Sign Ai - (0x11234, 0x11234,), # Khojki Sign Anusvara - (0x11236, 0x11237,), # Khojki Sign Nukta ..Khojki Sign Shadda + (0x1122c, 0x11237,), # Khojki Vowel Sign Aa ..Khojki Sign Shadda (0x1123e, 0x1123e,), # Khojki Sign Sukun - (0x112df, 0x112df,), # Khudawadi Sign Anusvara - (0x112e3, 0x112ea,), # Khudawadi Vowel Sign U ..Khudawadi Sign Virama - (0x11300, 0x11301,), # Grantha Sign Combining A..Grantha Sign Candrabindu + (0x112df, 0x112ea,), # Khudawadi Sign Anusvara ..Khudawadi Sign Virama + (0x11300, 0x11303,), # Grantha Sign Combining A..Grantha Sign Visarga (0x1133b, 0x1133c,), # Combining Bindu Below ..Grantha Sign Nukta - (0x11340, 0x11340,), # Grantha Vowel Sign Ii + (0x1133e, 0x11344,), # Grantha Vowel Sign Aa ..Grantha Vowel Sign Vocal + (0x11347, 0x11348,), # Grantha Vowel Sign Ee ..Grantha Vowel Sign Ai + (0x1134b, 0x1134d,), # Grantha Vowel Sign Oo ..Grantha Sign Virama + (0x11357, 0x11357,), # Grantha Au Length Mark + (0x11362, 0x11363,), # Grantha Vowel Sign Vocal..Grantha Vowel Sign Vocal (0x11366, 0x1136c,), # Combining Grantha Digit ..Combining Grantha Digit (0x11370, 0x11374,), # Combining Grantha Letter..Combining Grantha Letter - (0x11438, 0x1143f,), # Newa Vowel Sign U ..Newa Vowel Sign Ai - (0x11442, 0x11444,), # Newa Sign Virama ..Newa Sign Anusvara - (0x11446, 0x11446,), # Newa Sign Nukta + (0x11435, 0x11446,), # Newa Vowel Sign Aa ..Newa Sign Nukta (0x1145e, 0x1145e,), # Newa Sandhi Mark - (0x114b3, 0x114b8,), # Tirhuta Vowel Sign U ..Tirhuta Vowel Sign Vocal - (0x114ba, 0x114ba,), # Tirhuta Vowel Sign Short E - (0x114bf, 0x114c0,), # Tirhuta Sign Candrabindu..Tirhuta Sign Anusvara - (0x114c2, 0x114c3,), # Tirhuta Sign Virama ..Tirhuta Sign Nukta - (0x115b2, 0x115b5,), # Siddham Vowel Sign U ..Siddham Vowel Sign Vocal - (0x115bc, 0x115bd,), # Siddham Sign Candrabindu..Siddham Sign Anusvara - (0x115bf, 0x115c0,), # Siddham Sign Virama ..Siddham Sign Nukta + (0x114b0, 0x114c3,), # Tirhuta Vowel Sign Aa ..Tirhuta Sign Nukta + (0x115af, 0x115b5,), # Siddham Vowel Sign Aa ..Siddham Vowel Sign Vocal + (0x115b8, 0x115c0,), # Siddham Vowel Sign E ..Siddham Sign Nukta (0x115dc, 0x115dd,), # Siddham Vowel Sign Alter..Siddham Vowel Sign Alter - (0x11633, 0x1163a,), # Modi Vowel Sign U ..Modi Vowel Sign Ai - (0x1163d, 0x1163d,), # Modi Sign Anusvara - (0x1163f, 0x11640,), # Modi Sign Virama ..Modi Sign Ardhacandra - (0x116ab, 0x116ab,), # Takri Sign Anusvara - (0x116ad, 0x116ad,), # Takri Vowel Sign Aa - (0x116b0, 0x116b5,), # Takri Vowel Sign U ..Takri Vowel Sign Au - (0x116b7, 0x116b7,), # Takri Sign Nukta - (0x1171d, 0x1171f,), # Ahom Consonant Sign Medi..Ahom Consonant Sign Medi - (0x11722, 0x11725,), # Ahom Vowel Sign I ..Ahom Vowel Sign Uu - (0x11727, 0x1172b,), # Ahom Vowel Sign Aw ..Ahom Sign Killer - (0x1182f, 0x11837,), # Dogra Vowel Sign U ..Dogra Sign Anusvara - (0x11839, 0x1183a,), # Dogra Sign Virama ..Dogra Sign Nukta + (0x11630, 0x11640,), # Modi Vowel Sign Aa ..Modi Sign Ardhacandra + (0x116ab, 0x116b7,), # Takri Sign Anusvara ..Takri Sign Nukta + (0x1171d, 0x1172b,), # Ahom Consonant Sign Medi..Ahom Sign Killer + (0x1182c, 0x1183a,), # Dogra Vowel Sign Aa ..Dogra Sign Nukta (0x11a01, 0x11a0a,), # Zanabazar Square Vowel S..Zanabazar Square Vowel L - (0x11a33, 0x11a38,), # Zanabazar Square Final C..Zanabazar Square Sign An + (0x11a33, 0x11a39,), # Zanabazar Square Final C..Zanabazar Square Sign Vi (0x11a3b, 0x11a3e,), # Zanabazar Square Cluster..Zanabazar Square Cluster (0x11a47, 0x11a47,), # Zanabazar Square Subjoiner - (0x11a51, 0x11a56,), # Soyombo Vowel Sign I ..Soyombo Vowel Sign Oe - (0x11a59, 0x11a5b,), # Soyombo Vowel Sign Vocal..Soyombo Vowel Length Mar - (0x11a8a, 0x11a96,), # Soyombo Final Consonant ..Soyombo Sign Anusvara - (0x11a98, 0x11a99,), # Soyombo Gemination Mark ..Soyombo Subjoiner - (0x11c30, 0x11c36,), # Bhaiksuki Vowel Sign I ..Bhaiksuki Vowel Sign Voc - (0x11c38, 0x11c3d,), # Bhaiksuki Vowel Sign E ..Bhaiksuki Sign Anusvara - (0x11c3f, 0x11c3f,), # Bhaiksuki Sign Virama + (0x11a51, 0x11a5b,), # Soyombo Vowel Sign I ..Soyombo Vowel Length Mar + (0x11a8a, 0x11a99,), # Soyombo Final Consonant ..Soyombo Subjoiner + (0x11c2f, 0x11c36,), # Bhaiksuki Vowel Sign Aa ..Bhaiksuki Vowel Sign Voc + (0x11c38, 0x11c3f,), # Bhaiksuki Vowel Sign E ..Bhaiksuki Sign Virama (0x11c92, 0x11ca7,), # Marchen Subjoined Letter..Marchen Subjoined Letter - (0x11caa, 0x11cb0,), # Marchen Subjoined Letter..Marchen Vowel Sign Aa - (0x11cb2, 0x11cb3,), # Marchen Vowel Sign U ..Marchen Vowel Sign E - (0x11cb5, 0x11cb6,), # Marchen Sign Anusvara ..Marchen Sign Candrabindu + (0x11ca9, 0x11cb6,), # Marchen Subjoined Letter..Marchen Sign Candrabindu (0x11d31, 0x11d36,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign (0x11d3a, 0x11d3a,), # Masaram Gondi Vowel Sign E (0x11d3c, 0x11d3d,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign (0x11d3f, 0x11d45,), # Masaram Gondi Vowel Sign..Masaram Gondi Virama (0x11d47, 0x11d47,), # Masaram Gondi Ra-kara + (0x11d8a, 0x11d8e,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Vowel Sign (0x11d90, 0x11d91,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Vowel Sign - (0x11d95, 0x11d95,), # Gunjala Gondi Sign Anusvara - (0x11d97, 0x11d97,), # Gunjala Gondi Virama - (0x11ef3, 0x11ef4,), # Makasar Vowel Sign I ..Makasar Vowel Sign U + (0x11d93, 0x11d97,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Virama + (0x11ef3, 0x11ef6,), # Makasar Vowel Sign I ..Makasar Vowel Sign O (0x16af0, 0x16af4,), # Bassa Vah Combining High..Bassa Vah Combining High (0x16b30, 0x16b36,), # Pahawh Hmong Mark Cim Tu..Pahawh Hmong Mark Cim Ta + (0x16f51, 0x16f7e,), # Miao Sign Aspiration ..Miao Vowel Sign Ng (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below (0x1bc9d, 0x1bc9e,), # Duployan Thick Letter Se..Duployan Double Mark - (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining - (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1bca0, 0x1bca3,), # Shorthand Format Letter ..Shorthand Format Up Step + (0x1d165, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d16d, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical @@ -2937,12 +2904,17 @@ ZERO_WIDTH = { (0x1e026, 0x1e02a,), # Combining Glagolitic Let..Combining Glagolitic Let (0x1e8d0, 0x1e8d6,), # Mende Kikakui Combining ..Mende Kikakui Combining (0x1e944, 0x1e94a,), # Adlam Alif Lengthener ..Adlam Nukta + (0x1f3fb, 0x1f3ff,), # Emoji Modifier Fitzpatri..Emoji Modifier Fitzpatri + (0xe0001, 0xe0001,), # Language Tag + (0xe0020, 0xe007f,), # Tag Space ..Cancel Tag (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 ), '12.0.0': ( # Source: DerivedGeneralCategory-12.0.0.txt # Date: 2019-01-22, 08:18:28 GMT # + (0x00000, 0x00000,), # (nil) + (0x000ad, 0x000ad,), # Soft Hyphen (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg @@ -2950,13 +2922,16 @@ ZERO_WIDTH = { (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot (0x005c7, 0x005c7,), # Hebrew Point Qamats Qatan + (0x00600, 0x00605,), # Arabic Number Sign ..Arabic Number Mark Above (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0061c, 0x0061c,), # Arabic Letter Mark (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below (0x00670, 0x00670,), # Arabic Letter Superscript Alef - (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006d6, 0x006dd,), # Arabic Small High Ligatu..Arabic End Of Ayah (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x0070f, 0x0070f,), # Syriac Abbreviation Mark (0x00711, 0x00711,), # Syriac Letter Superscript Alaph (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun @@ -2967,66 +2942,72 @@ ZERO_WIDTH = { (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark - (0x008d3, 0x008e1,), # Arabic Small Low Waw ..Arabic Small High Sign S - (0x008e3, 0x00902,), # Arabic Turned Damma Belo..Devanagari Sign Anusvara - (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe - (0x0093c, 0x0093c,), # Devanagari Sign Nukta - (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai - (0x0094d, 0x0094d,), # Devanagari Sign Virama + (0x008d3, 0x00903,), # Arabic Small Low Waw ..Devanagari Sign Visarga + (0x0093a, 0x0093c,), # Devanagari Vowel Sign Oe..Devanagari Sign Nukta + (0x0093e, 0x0094f,), # Devanagari Vowel Sign Aa..Devanagari Vowel Sign Aw (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo - (0x00981, 0x00981,), # Bengali Sign Candrabindu + (0x00981, 0x00983,), # Bengali Sign Candrabindu..Bengali Sign Visarga (0x009bc, 0x009bc,), # Bengali Sign Nukta - (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal - (0x009cd, 0x009cd,), # Bengali Sign Virama + (0x009be, 0x009c4,), # Bengali Vowel Sign Aa ..Bengali Vowel Sign Vocal + (0x009c7, 0x009c8,), # Bengali Vowel Sign E ..Bengali Vowel Sign Ai + (0x009cb, 0x009cd,), # Bengali Vowel Sign O ..Bengali Sign Virama + (0x009d7, 0x009d7,), # Bengali Au Length Mark (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal (0x009fe, 0x009fe,), # Bengali Sandhi Mark - (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a01, 0x00a03,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Visarga (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta - (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a3e, 0x00a42,), # Gurmukhi Vowel Sign Aa ..Gurmukhi Vowel Sign Uu (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash - (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00a81, 0x00a83,), # Gujarati Sign Candrabind..Gujarati Sign Visarga (0x00abc, 0x00abc,), # Gujarati Sign Nukta - (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand - (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai - (0x00acd, 0x00acd,), # Gujarati Sign Virama + (0x00abe, 0x00ac5,), # Gujarati Vowel Sign Aa ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac9,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Cand + (0x00acb, 0x00acd,), # Gujarati Vowel Sign O ..Gujarati Sign Virama (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca (0x00afa, 0x00aff,), # Gujarati Sign Sukun ..Gujarati Sign Two-circle - (0x00b01, 0x00b01,), # Oriya Sign Candrabindu + (0x00b01, 0x00b03,), # Oriya Sign Candrabindu ..Oriya Sign Visarga (0x00b3c, 0x00b3c,), # Oriya Sign Nukta - (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I - (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic - (0x00b4d, 0x00b4d,), # Oriya Sign Virama - (0x00b56, 0x00b56,), # Oriya Ai Length Mark + (0x00b3e, 0x00b44,), # Oriya Vowel Sign Aa ..Oriya Vowel Sign Vocalic + (0x00b47, 0x00b48,), # Oriya Vowel Sign E ..Oriya Vowel Sign Ai + (0x00b4b, 0x00b4d,), # Oriya Vowel Sign O ..Oriya Sign Virama + (0x00b56, 0x00b57,), # Oriya Ai Length Mark ..Oriya Au Length Mark (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic (0x00b82, 0x00b82,), # Tamil Sign Anusvara - (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii - (0x00bcd, 0x00bcd,), # Tamil Sign Virama - (0x00c00, 0x00c00,), # Telugu Sign Combining Candrabindu Above - (0x00c04, 0x00c04,), # Telugu Sign Combining Anusvara Above - (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00bbe, 0x00bc2,), # Tamil Vowel Sign Aa ..Tamil Vowel Sign Uu + (0x00bc6, 0x00bc8,), # Tamil Vowel Sign E ..Tamil Vowel Sign Ai + (0x00bca, 0x00bcd,), # Tamil Vowel Sign O ..Tamil Sign Virama + (0x00bd7, 0x00bd7,), # Tamil Au Length Mark + (0x00c00, 0x00c04,), # Telugu Sign Combining Ca..Telugu Sign Combining An + (0x00c3e, 0x00c44,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Vocali (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali - (0x00c81, 0x00c81,), # Kannada Sign Candrabindu + (0x00c81, 0x00c83,), # Kannada Sign Candrabindu..Kannada Sign Visarga (0x00cbc, 0x00cbc,), # Kannada Sign Nukta - (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I - (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E - (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00cbe, 0x00cc4,), # Kannada Vowel Sign Aa ..Kannada Vowel Sign Vocal + (0x00cc6, 0x00cc8,), # Kannada Vowel Sign E ..Kannada Vowel Sign Ai + (0x00cca, 0x00ccd,), # Kannada Vowel Sign O ..Kannada Sign Virama + (0x00cd5, 0x00cd6,), # Kannada Length Mark ..Kannada Ai Length Mark (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal - (0x00d00, 0x00d01,), # Malayalam Sign Combining..Malayalam Sign Candrabin + (0x00d00, 0x00d03,), # Malayalam Sign Combining..Malayalam Sign Visarga (0x00d3b, 0x00d3c,), # Malayalam Sign Vertical ..Malayalam Sign Circular - (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc - (0x00d4d, 0x00d4d,), # Malayalam Sign Virama + (0x00d3e, 0x00d44,), # Malayalam Vowel Sign Aa ..Malayalam Vowel Sign Voc + (0x00d46, 0x00d48,), # Malayalam Vowel Sign E ..Malayalam Vowel Sign Ai + (0x00d4a, 0x00d4d,), # Malayalam Vowel Sign O ..Malayalam Sign Virama + (0x00d57, 0x00d57,), # Malayalam Au Length Mark (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00d82, 0x00d83,), # Sinhala Sign Anusvaraya ..Sinhala Sign Visargaya (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna - (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dcf, 0x00dd4,), # Sinhala Vowel Sign Aela-..Sinhala Vowel Sign Ketti (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga Paa-pilla + (0x00dd8, 0x00ddf,), # Sinhala Vowel Sign Gaett..Sinhala Vowel Sign Gayan + (0x00df2, 0x00df3,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga (0x00e31, 0x00e31,), # Thai Character Mai Han-akat (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan @@ -3037,79 +3018,61 @@ ZERO_WIDTH = { (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung Nyi Zla (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung Sgor Rtags (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru - (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga - (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f3e, 0x00f3f,), # Tibetan Sign Yar Tshes ..Tibetan Sign Mar Tshes + (0x00f71, 0x00f84,), # Tibetan Vowel Sign Aa ..Tibetan Mark Halanta (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gdan - (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu - (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below - (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat - (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M - (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0102b, 0x0103e,), # Myanmar Vowel Sign Tall ..Myanmar Consonant Sign M + (0x01056, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01062, 0x01064,), # Myanmar Vowel Sign Sgaw ..Myanmar Tone Mark Sgaw K + (0x01067, 0x0106d,), # Myanmar Vowel Sign Weste..Myanmar Sign Western Pwo (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah - (0x01082, 0x01082,), # Myanmar Consonant Sign Shan Medial Wa - (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan - (0x0108d, 0x0108d,), # Myanmar Sign Shan Council Emphatic Tone - (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton Ai + (0x01082, 0x0108d,), # Myanmar Consonant Sign S..Myanmar Sign Shan Counci + (0x0108f, 0x0108f,), # Myanmar Sign Rumai Palaung Tone-5 + (0x0109a, 0x0109d,), # Myanmar Sign Khamti Tone..Myanmar Vowel Sign Aiton (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U - (0x017b4, 0x017b5,), # Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa - (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua - (0x017c6, 0x017c6,), # Khmer Sign Nikahit - (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017b4, 0x017d3,), # Khmer Vowel Inherent Aq ..Khmer Sign Bathamasat (0x017dd, 0x017dd,), # Khmer Sign Atthacan - (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x0180b, 0x0180e,), # Mongolian Free Variation..Mongolian Vowel Separato (0x01885, 0x01886,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal (0x018a9, 0x018a9,), # Mongolian Letter Ali Gali Dagalga - (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U - (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O - (0x01932, 0x01932,), # Limbu Small Letter Anusvara - (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i - (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U - (0x01a1b, 0x01a1b,), # Buginese Vowel Sign Ae - (0x01a56, 0x01a56,), # Tai Tham Consonant Sign Medial La - (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign - (0x01a60, 0x01a60,), # Tai Tham Sign Sakot - (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai Sat - (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B - (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01920, 0x0192b,), # Limbu Vowel Sign A ..Limbu Subjoined Letter W + (0x01930, 0x0193b,), # Limbu Small Letter Ka ..Limbu Sign Sa-i + (0x01a17, 0x01a1b,), # Buginese Vowel Sign I ..Buginese Vowel Sign Ae + (0x01a55, 0x01a5e,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a60, 0x01a7c,), # Tai Tham Sign Sakot ..Tai Tham Sign Khuen-lue (0x01a7f, 0x01a7f,), # Tai Tham Combining Cryptogrammic Dot (0x01ab0, 0x01abe,), # Combining Doubled Circum..Combining Parentheses Ov - (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang - (0x01b34, 0x01b34,), # Balinese Sign Rerekan - (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R - (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La Lenga - (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepet + (0x01b00, 0x01b04,), # Balinese Sign Ulu Ricem ..Balinese Sign Bisah + (0x01b34, 0x01b44,), # Balinese Sign Rerekan ..Balinese Adeg Adeg (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol - (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar - (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan - (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan - (0x01bab, 0x01bad,), # Sundanese Sign Virama ..Sundanese Consonant Sign - (0x01be6, 0x01be6,), # Batak Sign Tompi - (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee - (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O - (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H - (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T - (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01b80, 0x01b82,), # Sundanese Sign Panyecek ..Sundanese Sign Pangwisad + (0x01ba1, 0x01bad,), # Sundanese Consonant Sign..Sundanese Consonant Sign + (0x01be6, 0x01bf3,), # Batak Sign Tompi ..Batak Panongonan + (0x01c24, 0x01c37,), # Lepcha Subjoined Letter ..Lepcha Sign Nukta (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha - (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash - (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01cd4, 0x01ce8,), # Vedic Sign Yajurvedic Mi..Vedic Sign Visarga Anuda (0x01ced, 0x01ced,), # Vedic Sign Tiryak (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above - (0x01cf8, 0x01cf9,), # Vedic Tone Ring Above ..Vedic Tone Double Ring A + (0x01cf7, 0x01cf9,), # Vedic Sign Atikrama ..Vedic Tone Double Ring A (0x01dc0, 0x01df9,), # Combining Dotted Grave A..Combining Wide Inverted (0x01dfb, 0x01dff,), # Combining Deletion Mark ..Combining Right Arrowhea + (0x0200b, 0x0200f,), # Zero Width Space ..Right-to-left Mark + (0x02028, 0x0202e,), # Line Separator ..Right-to-left Override + (0x02060, 0x02064,), # Word Joiner ..Invisible Plus + (0x02066, 0x0206f,), # Left-to-right Isolate ..Nominal Digit Shapes (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joiner (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette - (0x0302a, 0x0302d,), # Ideographic Level Tone M..Ideographic Entering Ton + (0x0302a, 0x0302f,), # Ideographic Level Tone M..Hangul Double Dot Tone M (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer @@ -3118,36 +3081,34 @@ ZERO_WIDTH = { (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisvara (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasanta (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusvara - (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign - (0x0a8c4, 0x0a8c5,), # Saurashtra Sign Virama ..Saurashtra Sign Candrabi + (0x0a823, 0x0a827,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a880, 0x0a881,), # Saurashtra Sign Anusvara..Saurashtra Sign Visarga + (0x0a8b4, 0x0a8c5,), # Saurashtra Consonant Sig..Saurashtra Sign Candrabi (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig (0x0a8ff, 0x0a8ff,), # Devanagari Vowel Sign Ay (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop - (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R - (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar - (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu - (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku - (0x0a9bc, 0x0a9bd,), # Javanese Vowel Sign Pepe..Javanese Consonant Sign + (0x0a947, 0x0a953,), # Rejang Vowel Sign I ..Rejang Virama + (0x0a980, 0x0a983,), # Javanese Sign Panyangga ..Javanese Sign Wignyan + (0x0a9b3, 0x0a9c0,), # Javanese Sign Cecak Telu..Javanese Pangkon (0x0a9e5, 0x0a9e5,), # Myanmar Sign Shan Saw - (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe - (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue - (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0aa29, 0x0aa36,), # Cham Vowel Sign Aa ..Cham Consonant Sign Wa (0x0aa43, 0x0aa43,), # Cham Consonant Sign Final Ng - (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Final M - (0x0aa7c, 0x0aa7c,), # Myanmar Sign Tai Laing Tone-2 + (0x0aa4c, 0x0aa4d,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa7b, 0x0aa7d,), # Myanmar Sign Pao Karen T..Myanmar Sign Tai Laing T (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho - (0x0aaec, 0x0aaed,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign - (0x0aaf6, 0x0aaf6,), # Meetei Mayek Virama - (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign Anap - (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign Unap - (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek + (0x0aaeb, 0x0aaef,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf5, 0x0aaf6,), # Meetei Mayek Vowel Sign ..Meetei Mayek Virama + (0x0abe3, 0x0abea,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abec, 0x0abed,), # Meetei Mayek Lum Iyek ..Meetei Mayek Apun Iyek (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spanish Varika (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 (0x0fe20, 0x0fe2f,), # Combining Ligature Left ..Combining Cyrillic Titlo + (0x0feff, 0x0feff,), # Zero Width No-break Space + (0x0fff9, 0x0fffb,), # Interlinear Annotation A..Interlinear Annotation T (0x101fd, 0x101fd,), # Phaistos Disc Sign Combining Oblique Stroke (0x102e0, 0x102e0,), # Coptic Epact Thousands Mark (0x10376, 0x1037a,), # Combining Old Permic Let..Combining Old Permic Let @@ -3159,87 +3120,73 @@ ZERO_WIDTH = { (0x10ae5, 0x10ae6,), # Manichaean Abbreviation ..Manichaean Abbreviation (0x10d24, 0x10d27,), # Hanifi Rohingya Sign Har..Hanifi Rohingya Sign Tas (0x10f46, 0x10f50,), # Sogdian Combining Dot Be..Sogdian Combining Stroke - (0x11001, 0x11001,), # Brahmi Sign Anusvara + (0x11000, 0x11002,), # Brahmi Sign Candrabindu ..Brahmi Sign Visarga (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama - (0x1107f, 0x11081,), # Brahmi Number Joiner ..Kaithi Sign Anusvara - (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai - (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x1107f, 0x11082,), # Brahmi Number Joiner ..Kaithi Sign Visarga + (0x110b0, 0x110ba,), # Kaithi Vowel Sign Aa ..Kaithi Sign Nukta + (0x110bd, 0x110bd,), # Kaithi Number Sign + (0x110cd, 0x110cd,), # Kaithi Number Sign Above (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga - (0x11127, 0x1112b,), # Chakma Vowel Sign A ..Chakma Vowel Sign Uu - (0x1112d, 0x11134,), # Chakma Vowel Sign Ai ..Chakma Maayyaa + (0x11127, 0x11134,), # Chakma Vowel Sign A ..Chakma Maayyaa + (0x11145, 0x11146,), # Chakma Vowel Sign Aa ..Chakma Vowel Sign Ei (0x11173, 0x11173,), # Mahajani Sign Nukta - (0x11180, 0x11181,), # Sharada Sign Candrabindu..Sharada Sign Anusvara - (0x111b6, 0x111be,), # Sharada Vowel Sign U ..Sharada Vowel Sign O + (0x11180, 0x11182,), # Sharada Sign Candrabindu..Sharada Sign Visarga + (0x111b3, 0x111c0,), # Sharada Vowel Sign Aa ..Sharada Sign Virama (0x111c9, 0x111cc,), # Sharada Sandhi Mark ..Sharada Extra Short Vowe - (0x1122f, 0x11231,), # Khojki Vowel Sign U ..Khojki Vowel Sign Ai - (0x11234, 0x11234,), # Khojki Sign Anusvara - (0x11236, 0x11237,), # Khojki Sign Nukta ..Khojki Sign Shadda + (0x1122c, 0x11237,), # Khojki Vowel Sign Aa ..Khojki Sign Shadda (0x1123e, 0x1123e,), # Khojki Sign Sukun - (0x112df, 0x112df,), # Khudawadi Sign Anusvara - (0x112e3, 0x112ea,), # Khudawadi Vowel Sign U ..Khudawadi Sign Virama - (0x11300, 0x11301,), # Grantha Sign Combining A..Grantha Sign Candrabindu + (0x112df, 0x112ea,), # Khudawadi Sign Anusvara ..Khudawadi Sign Virama + (0x11300, 0x11303,), # Grantha Sign Combining A..Grantha Sign Visarga (0x1133b, 0x1133c,), # Combining Bindu Below ..Grantha Sign Nukta - (0x11340, 0x11340,), # Grantha Vowel Sign Ii + (0x1133e, 0x11344,), # Grantha Vowel Sign Aa ..Grantha Vowel Sign Vocal + (0x11347, 0x11348,), # Grantha Vowel Sign Ee ..Grantha Vowel Sign Ai + (0x1134b, 0x1134d,), # Grantha Vowel Sign Oo ..Grantha Sign Virama + (0x11357, 0x11357,), # Grantha Au Length Mark + (0x11362, 0x11363,), # Grantha Vowel Sign Vocal..Grantha Vowel Sign Vocal (0x11366, 0x1136c,), # Combining Grantha Digit ..Combining Grantha Digit (0x11370, 0x11374,), # Combining Grantha Letter..Combining Grantha Letter - (0x11438, 0x1143f,), # Newa Vowel Sign U ..Newa Vowel Sign Ai - (0x11442, 0x11444,), # Newa Sign Virama ..Newa Sign Anusvara - (0x11446, 0x11446,), # Newa Sign Nukta + (0x11435, 0x11446,), # Newa Vowel Sign Aa ..Newa Sign Nukta (0x1145e, 0x1145e,), # Newa Sandhi Mark - (0x114b3, 0x114b8,), # Tirhuta Vowel Sign U ..Tirhuta Vowel Sign Vocal - (0x114ba, 0x114ba,), # Tirhuta Vowel Sign Short E - (0x114bf, 0x114c0,), # Tirhuta Sign Candrabindu..Tirhuta Sign Anusvara - (0x114c2, 0x114c3,), # Tirhuta Sign Virama ..Tirhuta Sign Nukta - (0x115b2, 0x115b5,), # Siddham Vowel Sign U ..Siddham Vowel Sign Vocal - (0x115bc, 0x115bd,), # Siddham Sign Candrabindu..Siddham Sign Anusvara - (0x115bf, 0x115c0,), # Siddham Sign Virama ..Siddham Sign Nukta + (0x114b0, 0x114c3,), # Tirhuta Vowel Sign Aa ..Tirhuta Sign Nukta + (0x115af, 0x115b5,), # Siddham Vowel Sign Aa ..Siddham Vowel Sign Vocal + (0x115b8, 0x115c0,), # Siddham Vowel Sign E ..Siddham Sign Nukta (0x115dc, 0x115dd,), # Siddham Vowel Sign Alter..Siddham Vowel Sign Alter - (0x11633, 0x1163a,), # Modi Vowel Sign U ..Modi Vowel Sign Ai - (0x1163d, 0x1163d,), # Modi Sign Anusvara - (0x1163f, 0x11640,), # Modi Sign Virama ..Modi Sign Ardhacandra - (0x116ab, 0x116ab,), # Takri Sign Anusvara - (0x116ad, 0x116ad,), # Takri Vowel Sign Aa - (0x116b0, 0x116b5,), # Takri Vowel Sign U ..Takri Vowel Sign Au - (0x116b7, 0x116b7,), # Takri Sign Nukta - (0x1171d, 0x1171f,), # Ahom Consonant Sign Medi..Ahom Consonant Sign Medi - (0x11722, 0x11725,), # Ahom Vowel Sign I ..Ahom Vowel Sign Uu - (0x11727, 0x1172b,), # Ahom Vowel Sign Aw ..Ahom Sign Killer - (0x1182f, 0x11837,), # Dogra Vowel Sign U ..Dogra Sign Anusvara - (0x11839, 0x1183a,), # Dogra Sign Virama ..Dogra Sign Nukta - (0x119d4, 0x119d7,), # Nandinagari Vowel Sign U..Nandinagari Vowel Sign V - (0x119da, 0x119db,), # Nandinagari Vowel Sign E..Nandinagari Vowel Sign A - (0x119e0, 0x119e0,), # Nandinagari Sign Virama + (0x11630, 0x11640,), # Modi Vowel Sign Aa ..Modi Sign Ardhacandra + (0x116ab, 0x116b7,), # Takri Sign Anusvara ..Takri Sign Nukta + (0x1171d, 0x1172b,), # Ahom Consonant Sign Medi..Ahom Sign Killer + (0x1182c, 0x1183a,), # Dogra Vowel Sign Aa ..Dogra Sign Nukta + (0x119d1, 0x119d7,), # Nandinagari Vowel Sign A..Nandinagari Vowel Sign V + (0x119da, 0x119e0,), # Nandinagari Vowel Sign E..Nandinagari Sign Virama + (0x119e4, 0x119e4,), # Nandinagari Vowel Sign Prishthamatra E (0x11a01, 0x11a0a,), # Zanabazar Square Vowel S..Zanabazar Square Vowel L - (0x11a33, 0x11a38,), # Zanabazar Square Final C..Zanabazar Square Sign An + (0x11a33, 0x11a39,), # Zanabazar Square Final C..Zanabazar Square Sign Vi (0x11a3b, 0x11a3e,), # Zanabazar Square Cluster..Zanabazar Square Cluster (0x11a47, 0x11a47,), # Zanabazar Square Subjoiner - (0x11a51, 0x11a56,), # Soyombo Vowel Sign I ..Soyombo Vowel Sign Oe - (0x11a59, 0x11a5b,), # Soyombo Vowel Sign Vocal..Soyombo Vowel Length Mar - (0x11a8a, 0x11a96,), # Soyombo Final Consonant ..Soyombo Sign Anusvara - (0x11a98, 0x11a99,), # Soyombo Gemination Mark ..Soyombo Subjoiner - (0x11c30, 0x11c36,), # Bhaiksuki Vowel Sign I ..Bhaiksuki Vowel Sign Voc - (0x11c38, 0x11c3d,), # Bhaiksuki Vowel Sign E ..Bhaiksuki Sign Anusvara - (0x11c3f, 0x11c3f,), # Bhaiksuki Sign Virama + (0x11a51, 0x11a5b,), # Soyombo Vowel Sign I ..Soyombo Vowel Length Mar + (0x11a8a, 0x11a99,), # Soyombo Final Consonant ..Soyombo Subjoiner + (0x11c2f, 0x11c36,), # Bhaiksuki Vowel Sign Aa ..Bhaiksuki Vowel Sign Voc + (0x11c38, 0x11c3f,), # Bhaiksuki Vowel Sign E ..Bhaiksuki Sign Virama (0x11c92, 0x11ca7,), # Marchen Subjoined Letter..Marchen Subjoined Letter - (0x11caa, 0x11cb0,), # Marchen Subjoined Letter..Marchen Vowel Sign Aa - (0x11cb2, 0x11cb3,), # Marchen Vowel Sign U ..Marchen Vowel Sign E - (0x11cb5, 0x11cb6,), # Marchen Sign Anusvara ..Marchen Sign Candrabindu + (0x11ca9, 0x11cb6,), # Marchen Subjoined Letter..Marchen Sign Candrabindu (0x11d31, 0x11d36,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign (0x11d3a, 0x11d3a,), # Masaram Gondi Vowel Sign E (0x11d3c, 0x11d3d,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign (0x11d3f, 0x11d45,), # Masaram Gondi Vowel Sign..Masaram Gondi Virama (0x11d47, 0x11d47,), # Masaram Gondi Ra-kara + (0x11d8a, 0x11d8e,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Vowel Sign (0x11d90, 0x11d91,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Vowel Sign - (0x11d95, 0x11d95,), # Gunjala Gondi Sign Anusvara - (0x11d97, 0x11d97,), # Gunjala Gondi Virama - (0x11ef3, 0x11ef4,), # Makasar Vowel Sign I ..Makasar Vowel Sign U + (0x11d93, 0x11d97,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Virama + (0x11ef3, 0x11ef6,), # Makasar Vowel Sign I ..Makasar Vowel Sign O + (0x13430, 0x13438,), # Egyptian Hieroglyph Vert..Egyptian Hieroglyph End (0x16af0, 0x16af4,), # Bassa Vah Combining High..Bassa Vah Combining High (0x16b30, 0x16b36,), # Pahawh Hmong Mark Cim Tu..Pahawh Hmong Mark Cim Ta (0x16f4f, 0x16f4f,), # Miao Sign Consonant Modifier Bar + (0x16f51, 0x16f87,), # Miao Sign Aspiration ..Miao Vowel Sign Ui (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below (0x1bc9d, 0x1bc9e,), # Duployan Thick Letter Se..Duployan Double Mark - (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining - (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1bca0, 0x1bca3,), # Shorthand Format Letter ..Shorthand Format Up Step + (0x1d165, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d16d, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical @@ -3258,12 +3205,17 @@ ZERO_WIDTH = { (0x1e2ec, 0x1e2ef,), # Wancho Tone Tup ..Wancho Tone Koini (0x1e8d0, 0x1e8d6,), # Mende Kikakui Combining ..Mende Kikakui Combining (0x1e944, 0x1e94a,), # Adlam Alif Lengthener ..Adlam Nukta + (0x1f3fb, 0x1f3ff,), # Emoji Modifier Fitzpatri..Emoji Modifier Fitzpatri + (0xe0001, 0xe0001,), # Language Tag + (0xe0020, 0xe007f,), # Tag Space ..Cancel Tag (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 ), '12.1.0': ( # Source: DerivedGeneralCategory-12.1.0.txt # Date: 2019-03-10, 10:53:08 GMT # + (0x00000, 0x00000,), # (nil) + (0x000ad, 0x000ad,), # Soft Hyphen (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg @@ -3271,13 +3223,16 @@ ZERO_WIDTH = { (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot (0x005c7, 0x005c7,), # Hebrew Point Qamats Qatan + (0x00600, 0x00605,), # Arabic Number Sign ..Arabic Number Mark Above (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0061c, 0x0061c,), # Arabic Letter Mark (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below (0x00670, 0x00670,), # Arabic Letter Superscript Alef - (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006d6, 0x006dd,), # Arabic Small High Ligatu..Arabic End Of Ayah (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x0070f, 0x0070f,), # Syriac Abbreviation Mark (0x00711, 0x00711,), # Syriac Letter Superscript Alaph (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun @@ -3288,66 +3243,72 @@ ZERO_WIDTH = { (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark - (0x008d3, 0x008e1,), # Arabic Small Low Waw ..Arabic Small High Sign S - (0x008e3, 0x00902,), # Arabic Turned Damma Belo..Devanagari Sign Anusvara - (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe - (0x0093c, 0x0093c,), # Devanagari Sign Nukta - (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai - (0x0094d, 0x0094d,), # Devanagari Sign Virama + (0x008d3, 0x00903,), # Arabic Small Low Waw ..Devanagari Sign Visarga + (0x0093a, 0x0093c,), # Devanagari Vowel Sign Oe..Devanagari Sign Nukta + (0x0093e, 0x0094f,), # Devanagari Vowel Sign Aa..Devanagari Vowel Sign Aw (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo - (0x00981, 0x00981,), # Bengali Sign Candrabindu + (0x00981, 0x00983,), # Bengali Sign Candrabindu..Bengali Sign Visarga (0x009bc, 0x009bc,), # Bengali Sign Nukta - (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal - (0x009cd, 0x009cd,), # Bengali Sign Virama + (0x009be, 0x009c4,), # Bengali Vowel Sign Aa ..Bengali Vowel Sign Vocal + (0x009c7, 0x009c8,), # Bengali Vowel Sign E ..Bengali Vowel Sign Ai + (0x009cb, 0x009cd,), # Bengali Vowel Sign O ..Bengali Sign Virama + (0x009d7, 0x009d7,), # Bengali Au Length Mark (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal (0x009fe, 0x009fe,), # Bengali Sandhi Mark - (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a01, 0x00a03,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Visarga (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta - (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a3e, 0x00a42,), # Gurmukhi Vowel Sign Aa ..Gurmukhi Vowel Sign Uu (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash - (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00a81, 0x00a83,), # Gujarati Sign Candrabind..Gujarati Sign Visarga (0x00abc, 0x00abc,), # Gujarati Sign Nukta - (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand - (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai - (0x00acd, 0x00acd,), # Gujarati Sign Virama + (0x00abe, 0x00ac5,), # Gujarati Vowel Sign Aa ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac9,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Cand + (0x00acb, 0x00acd,), # Gujarati Vowel Sign O ..Gujarati Sign Virama (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca (0x00afa, 0x00aff,), # Gujarati Sign Sukun ..Gujarati Sign Two-circle - (0x00b01, 0x00b01,), # Oriya Sign Candrabindu + (0x00b01, 0x00b03,), # Oriya Sign Candrabindu ..Oriya Sign Visarga (0x00b3c, 0x00b3c,), # Oriya Sign Nukta - (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I - (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic - (0x00b4d, 0x00b4d,), # Oriya Sign Virama - (0x00b56, 0x00b56,), # Oriya Ai Length Mark + (0x00b3e, 0x00b44,), # Oriya Vowel Sign Aa ..Oriya Vowel Sign Vocalic + (0x00b47, 0x00b48,), # Oriya Vowel Sign E ..Oriya Vowel Sign Ai + (0x00b4b, 0x00b4d,), # Oriya Vowel Sign O ..Oriya Sign Virama + (0x00b56, 0x00b57,), # Oriya Ai Length Mark ..Oriya Au Length Mark (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic (0x00b82, 0x00b82,), # Tamil Sign Anusvara - (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii - (0x00bcd, 0x00bcd,), # Tamil Sign Virama - (0x00c00, 0x00c00,), # Telugu Sign Combining Candrabindu Above - (0x00c04, 0x00c04,), # Telugu Sign Combining Anusvara Above - (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00bbe, 0x00bc2,), # Tamil Vowel Sign Aa ..Tamil Vowel Sign Uu + (0x00bc6, 0x00bc8,), # Tamil Vowel Sign E ..Tamil Vowel Sign Ai + (0x00bca, 0x00bcd,), # Tamil Vowel Sign O ..Tamil Sign Virama + (0x00bd7, 0x00bd7,), # Tamil Au Length Mark + (0x00c00, 0x00c04,), # Telugu Sign Combining Ca..Telugu Sign Combining An + (0x00c3e, 0x00c44,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Vocali (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali - (0x00c81, 0x00c81,), # Kannada Sign Candrabindu + (0x00c81, 0x00c83,), # Kannada Sign Candrabindu..Kannada Sign Visarga (0x00cbc, 0x00cbc,), # Kannada Sign Nukta - (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I - (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E - (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00cbe, 0x00cc4,), # Kannada Vowel Sign Aa ..Kannada Vowel Sign Vocal + (0x00cc6, 0x00cc8,), # Kannada Vowel Sign E ..Kannada Vowel Sign Ai + (0x00cca, 0x00ccd,), # Kannada Vowel Sign O ..Kannada Sign Virama + (0x00cd5, 0x00cd6,), # Kannada Length Mark ..Kannada Ai Length Mark (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal - (0x00d00, 0x00d01,), # Malayalam Sign Combining..Malayalam Sign Candrabin + (0x00d00, 0x00d03,), # Malayalam Sign Combining..Malayalam Sign Visarga (0x00d3b, 0x00d3c,), # Malayalam Sign Vertical ..Malayalam Sign Circular - (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc - (0x00d4d, 0x00d4d,), # Malayalam Sign Virama + (0x00d3e, 0x00d44,), # Malayalam Vowel Sign Aa ..Malayalam Vowel Sign Voc + (0x00d46, 0x00d48,), # Malayalam Vowel Sign E ..Malayalam Vowel Sign Ai + (0x00d4a, 0x00d4d,), # Malayalam Vowel Sign O ..Malayalam Sign Virama + (0x00d57, 0x00d57,), # Malayalam Au Length Mark (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00d82, 0x00d83,), # Sinhala Sign Anusvaraya ..Sinhala Sign Visargaya (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna - (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dcf, 0x00dd4,), # Sinhala Vowel Sign Aela-..Sinhala Vowel Sign Ketti (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga Paa-pilla + (0x00dd8, 0x00ddf,), # Sinhala Vowel Sign Gaett..Sinhala Vowel Sign Gayan + (0x00df2, 0x00df3,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga (0x00e31, 0x00e31,), # Thai Character Mai Han-akat (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan @@ -3358,79 +3319,61 @@ ZERO_WIDTH = { (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung Nyi Zla (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung Sgor Rtags (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru - (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga - (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f3e, 0x00f3f,), # Tibetan Sign Yar Tshes ..Tibetan Sign Mar Tshes + (0x00f71, 0x00f84,), # Tibetan Vowel Sign Aa ..Tibetan Mark Halanta (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gdan - (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu - (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below - (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat - (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M - (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0102b, 0x0103e,), # Myanmar Vowel Sign Tall ..Myanmar Consonant Sign M + (0x01056, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01062, 0x01064,), # Myanmar Vowel Sign Sgaw ..Myanmar Tone Mark Sgaw K + (0x01067, 0x0106d,), # Myanmar Vowel Sign Weste..Myanmar Sign Western Pwo (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah - (0x01082, 0x01082,), # Myanmar Consonant Sign Shan Medial Wa - (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan - (0x0108d, 0x0108d,), # Myanmar Sign Shan Council Emphatic Tone - (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton Ai + (0x01082, 0x0108d,), # Myanmar Consonant Sign S..Myanmar Sign Shan Counci + (0x0108f, 0x0108f,), # Myanmar Sign Rumai Palaung Tone-5 + (0x0109a, 0x0109d,), # Myanmar Sign Khamti Tone..Myanmar Vowel Sign Aiton (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U - (0x017b4, 0x017b5,), # Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa - (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua - (0x017c6, 0x017c6,), # Khmer Sign Nikahit - (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017b4, 0x017d3,), # Khmer Vowel Inherent Aq ..Khmer Sign Bathamasat (0x017dd, 0x017dd,), # Khmer Sign Atthacan - (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x0180b, 0x0180e,), # Mongolian Free Variation..Mongolian Vowel Separato (0x01885, 0x01886,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal (0x018a9, 0x018a9,), # Mongolian Letter Ali Gali Dagalga - (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U - (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O - (0x01932, 0x01932,), # Limbu Small Letter Anusvara - (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i - (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U - (0x01a1b, 0x01a1b,), # Buginese Vowel Sign Ae - (0x01a56, 0x01a56,), # Tai Tham Consonant Sign Medial La - (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign - (0x01a60, 0x01a60,), # Tai Tham Sign Sakot - (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai Sat - (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B - (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01920, 0x0192b,), # Limbu Vowel Sign A ..Limbu Subjoined Letter W + (0x01930, 0x0193b,), # Limbu Small Letter Ka ..Limbu Sign Sa-i + (0x01a17, 0x01a1b,), # Buginese Vowel Sign I ..Buginese Vowel Sign Ae + (0x01a55, 0x01a5e,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a60, 0x01a7c,), # Tai Tham Sign Sakot ..Tai Tham Sign Khuen-lue (0x01a7f, 0x01a7f,), # Tai Tham Combining Cryptogrammic Dot (0x01ab0, 0x01abe,), # Combining Doubled Circum..Combining Parentheses Ov - (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang - (0x01b34, 0x01b34,), # Balinese Sign Rerekan - (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R - (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La Lenga - (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepet + (0x01b00, 0x01b04,), # Balinese Sign Ulu Ricem ..Balinese Sign Bisah + (0x01b34, 0x01b44,), # Balinese Sign Rerekan ..Balinese Adeg Adeg (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol - (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar - (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan - (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan - (0x01bab, 0x01bad,), # Sundanese Sign Virama ..Sundanese Consonant Sign - (0x01be6, 0x01be6,), # Batak Sign Tompi - (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee - (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O - (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H - (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T - (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01b80, 0x01b82,), # Sundanese Sign Panyecek ..Sundanese Sign Pangwisad + (0x01ba1, 0x01bad,), # Sundanese Consonant Sign..Sundanese Consonant Sign + (0x01be6, 0x01bf3,), # Batak Sign Tompi ..Batak Panongonan + (0x01c24, 0x01c37,), # Lepcha Subjoined Letter ..Lepcha Sign Nukta (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha - (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash - (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01cd4, 0x01ce8,), # Vedic Sign Yajurvedic Mi..Vedic Sign Visarga Anuda (0x01ced, 0x01ced,), # Vedic Sign Tiryak (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above - (0x01cf8, 0x01cf9,), # Vedic Tone Ring Above ..Vedic Tone Double Ring A + (0x01cf7, 0x01cf9,), # Vedic Sign Atikrama ..Vedic Tone Double Ring A (0x01dc0, 0x01df9,), # Combining Dotted Grave A..Combining Wide Inverted (0x01dfb, 0x01dff,), # Combining Deletion Mark ..Combining Right Arrowhea + (0x0200b, 0x0200f,), # Zero Width Space ..Right-to-left Mark + (0x02028, 0x0202e,), # Line Separator ..Right-to-left Override + (0x02060, 0x02064,), # Word Joiner ..Invisible Plus + (0x02066, 0x0206f,), # Left-to-right Isolate ..Nominal Digit Shapes (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joiner (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette - (0x0302a, 0x0302d,), # Ideographic Level Tone M..Ideographic Entering Ton + (0x0302a, 0x0302f,), # Ideographic Level Tone M..Hangul Double Dot Tone M (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer @@ -3439,36 +3382,34 @@ ZERO_WIDTH = { (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisvara (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasanta (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusvara - (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign - (0x0a8c4, 0x0a8c5,), # Saurashtra Sign Virama ..Saurashtra Sign Candrabi + (0x0a823, 0x0a827,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a880, 0x0a881,), # Saurashtra Sign Anusvara..Saurashtra Sign Visarga + (0x0a8b4, 0x0a8c5,), # Saurashtra Consonant Sig..Saurashtra Sign Candrabi (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig (0x0a8ff, 0x0a8ff,), # Devanagari Vowel Sign Ay (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop - (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R - (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar - (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu - (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku - (0x0a9bc, 0x0a9bd,), # Javanese Vowel Sign Pepe..Javanese Consonant Sign + (0x0a947, 0x0a953,), # Rejang Vowel Sign I ..Rejang Virama + (0x0a980, 0x0a983,), # Javanese Sign Panyangga ..Javanese Sign Wignyan + (0x0a9b3, 0x0a9c0,), # Javanese Sign Cecak Telu..Javanese Pangkon (0x0a9e5, 0x0a9e5,), # Myanmar Sign Shan Saw - (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe - (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue - (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0aa29, 0x0aa36,), # Cham Vowel Sign Aa ..Cham Consonant Sign Wa (0x0aa43, 0x0aa43,), # Cham Consonant Sign Final Ng - (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Final M - (0x0aa7c, 0x0aa7c,), # Myanmar Sign Tai Laing Tone-2 + (0x0aa4c, 0x0aa4d,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa7b, 0x0aa7d,), # Myanmar Sign Pao Karen T..Myanmar Sign Tai Laing T (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho - (0x0aaec, 0x0aaed,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign - (0x0aaf6, 0x0aaf6,), # Meetei Mayek Virama - (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign Anap - (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign Unap - (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek + (0x0aaeb, 0x0aaef,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf5, 0x0aaf6,), # Meetei Mayek Vowel Sign ..Meetei Mayek Virama + (0x0abe3, 0x0abea,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abec, 0x0abed,), # Meetei Mayek Lum Iyek ..Meetei Mayek Apun Iyek (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spanish Varika (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 (0x0fe20, 0x0fe2f,), # Combining Ligature Left ..Combining Cyrillic Titlo + (0x0feff, 0x0feff,), # Zero Width No-break Space + (0x0fff9, 0x0fffb,), # Interlinear Annotation A..Interlinear Annotation T (0x101fd, 0x101fd,), # Phaistos Disc Sign Combining Oblique Stroke (0x102e0, 0x102e0,), # Coptic Epact Thousands Mark (0x10376, 0x1037a,), # Combining Old Permic Let..Combining Old Permic Let @@ -3480,87 +3421,73 @@ ZERO_WIDTH = { (0x10ae5, 0x10ae6,), # Manichaean Abbreviation ..Manichaean Abbreviation (0x10d24, 0x10d27,), # Hanifi Rohingya Sign Har..Hanifi Rohingya Sign Tas (0x10f46, 0x10f50,), # Sogdian Combining Dot Be..Sogdian Combining Stroke - (0x11001, 0x11001,), # Brahmi Sign Anusvara + (0x11000, 0x11002,), # Brahmi Sign Candrabindu ..Brahmi Sign Visarga (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama - (0x1107f, 0x11081,), # Brahmi Number Joiner ..Kaithi Sign Anusvara - (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai - (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x1107f, 0x11082,), # Brahmi Number Joiner ..Kaithi Sign Visarga + (0x110b0, 0x110ba,), # Kaithi Vowel Sign Aa ..Kaithi Sign Nukta + (0x110bd, 0x110bd,), # Kaithi Number Sign + (0x110cd, 0x110cd,), # Kaithi Number Sign Above (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga - (0x11127, 0x1112b,), # Chakma Vowel Sign A ..Chakma Vowel Sign Uu - (0x1112d, 0x11134,), # Chakma Vowel Sign Ai ..Chakma Maayyaa + (0x11127, 0x11134,), # Chakma Vowel Sign A ..Chakma Maayyaa + (0x11145, 0x11146,), # Chakma Vowel Sign Aa ..Chakma Vowel Sign Ei (0x11173, 0x11173,), # Mahajani Sign Nukta - (0x11180, 0x11181,), # Sharada Sign Candrabindu..Sharada Sign Anusvara - (0x111b6, 0x111be,), # Sharada Vowel Sign U ..Sharada Vowel Sign O + (0x11180, 0x11182,), # Sharada Sign Candrabindu..Sharada Sign Visarga + (0x111b3, 0x111c0,), # Sharada Vowel Sign Aa ..Sharada Sign Virama (0x111c9, 0x111cc,), # Sharada Sandhi Mark ..Sharada Extra Short Vowe - (0x1122f, 0x11231,), # Khojki Vowel Sign U ..Khojki Vowel Sign Ai - (0x11234, 0x11234,), # Khojki Sign Anusvara - (0x11236, 0x11237,), # Khojki Sign Nukta ..Khojki Sign Shadda + (0x1122c, 0x11237,), # Khojki Vowel Sign Aa ..Khojki Sign Shadda (0x1123e, 0x1123e,), # Khojki Sign Sukun - (0x112df, 0x112df,), # Khudawadi Sign Anusvara - (0x112e3, 0x112ea,), # Khudawadi Vowel Sign U ..Khudawadi Sign Virama - (0x11300, 0x11301,), # Grantha Sign Combining A..Grantha Sign Candrabindu + (0x112df, 0x112ea,), # Khudawadi Sign Anusvara ..Khudawadi Sign Virama + (0x11300, 0x11303,), # Grantha Sign Combining A..Grantha Sign Visarga (0x1133b, 0x1133c,), # Combining Bindu Below ..Grantha Sign Nukta - (0x11340, 0x11340,), # Grantha Vowel Sign Ii + (0x1133e, 0x11344,), # Grantha Vowel Sign Aa ..Grantha Vowel Sign Vocal + (0x11347, 0x11348,), # Grantha Vowel Sign Ee ..Grantha Vowel Sign Ai + (0x1134b, 0x1134d,), # Grantha Vowel Sign Oo ..Grantha Sign Virama + (0x11357, 0x11357,), # Grantha Au Length Mark + (0x11362, 0x11363,), # Grantha Vowel Sign Vocal..Grantha Vowel Sign Vocal (0x11366, 0x1136c,), # Combining Grantha Digit ..Combining Grantha Digit (0x11370, 0x11374,), # Combining Grantha Letter..Combining Grantha Letter - (0x11438, 0x1143f,), # Newa Vowel Sign U ..Newa Vowel Sign Ai - (0x11442, 0x11444,), # Newa Sign Virama ..Newa Sign Anusvara - (0x11446, 0x11446,), # Newa Sign Nukta + (0x11435, 0x11446,), # Newa Vowel Sign Aa ..Newa Sign Nukta (0x1145e, 0x1145e,), # Newa Sandhi Mark - (0x114b3, 0x114b8,), # Tirhuta Vowel Sign U ..Tirhuta Vowel Sign Vocal - (0x114ba, 0x114ba,), # Tirhuta Vowel Sign Short E - (0x114bf, 0x114c0,), # Tirhuta Sign Candrabindu..Tirhuta Sign Anusvara - (0x114c2, 0x114c3,), # Tirhuta Sign Virama ..Tirhuta Sign Nukta - (0x115b2, 0x115b5,), # Siddham Vowel Sign U ..Siddham Vowel Sign Vocal - (0x115bc, 0x115bd,), # Siddham Sign Candrabindu..Siddham Sign Anusvara - (0x115bf, 0x115c0,), # Siddham Sign Virama ..Siddham Sign Nukta + (0x114b0, 0x114c3,), # Tirhuta Vowel Sign Aa ..Tirhuta Sign Nukta + (0x115af, 0x115b5,), # Siddham Vowel Sign Aa ..Siddham Vowel Sign Vocal + (0x115b8, 0x115c0,), # Siddham Vowel Sign E ..Siddham Sign Nukta (0x115dc, 0x115dd,), # Siddham Vowel Sign Alter..Siddham Vowel Sign Alter - (0x11633, 0x1163a,), # Modi Vowel Sign U ..Modi Vowel Sign Ai - (0x1163d, 0x1163d,), # Modi Sign Anusvara - (0x1163f, 0x11640,), # Modi Sign Virama ..Modi Sign Ardhacandra - (0x116ab, 0x116ab,), # Takri Sign Anusvara - (0x116ad, 0x116ad,), # Takri Vowel Sign Aa - (0x116b0, 0x116b5,), # Takri Vowel Sign U ..Takri Vowel Sign Au - (0x116b7, 0x116b7,), # Takri Sign Nukta - (0x1171d, 0x1171f,), # Ahom Consonant Sign Medi..Ahom Consonant Sign Medi - (0x11722, 0x11725,), # Ahom Vowel Sign I ..Ahom Vowel Sign Uu - (0x11727, 0x1172b,), # Ahom Vowel Sign Aw ..Ahom Sign Killer - (0x1182f, 0x11837,), # Dogra Vowel Sign U ..Dogra Sign Anusvara - (0x11839, 0x1183a,), # Dogra Sign Virama ..Dogra Sign Nukta - (0x119d4, 0x119d7,), # Nandinagari Vowel Sign U..Nandinagari Vowel Sign V - (0x119da, 0x119db,), # Nandinagari Vowel Sign E..Nandinagari Vowel Sign A - (0x119e0, 0x119e0,), # Nandinagari Sign Virama + (0x11630, 0x11640,), # Modi Vowel Sign Aa ..Modi Sign Ardhacandra + (0x116ab, 0x116b7,), # Takri Sign Anusvara ..Takri Sign Nukta + (0x1171d, 0x1172b,), # Ahom Consonant Sign Medi..Ahom Sign Killer + (0x1182c, 0x1183a,), # Dogra Vowel Sign Aa ..Dogra Sign Nukta + (0x119d1, 0x119d7,), # Nandinagari Vowel Sign A..Nandinagari Vowel Sign V + (0x119da, 0x119e0,), # Nandinagari Vowel Sign E..Nandinagari Sign Virama + (0x119e4, 0x119e4,), # Nandinagari Vowel Sign Prishthamatra E (0x11a01, 0x11a0a,), # Zanabazar Square Vowel S..Zanabazar Square Vowel L - (0x11a33, 0x11a38,), # Zanabazar Square Final C..Zanabazar Square Sign An + (0x11a33, 0x11a39,), # Zanabazar Square Final C..Zanabazar Square Sign Vi (0x11a3b, 0x11a3e,), # Zanabazar Square Cluster..Zanabazar Square Cluster (0x11a47, 0x11a47,), # Zanabazar Square Subjoiner - (0x11a51, 0x11a56,), # Soyombo Vowel Sign I ..Soyombo Vowel Sign Oe - (0x11a59, 0x11a5b,), # Soyombo Vowel Sign Vocal..Soyombo Vowel Length Mar - (0x11a8a, 0x11a96,), # Soyombo Final Consonant ..Soyombo Sign Anusvara - (0x11a98, 0x11a99,), # Soyombo Gemination Mark ..Soyombo Subjoiner - (0x11c30, 0x11c36,), # Bhaiksuki Vowel Sign I ..Bhaiksuki Vowel Sign Voc - (0x11c38, 0x11c3d,), # Bhaiksuki Vowel Sign E ..Bhaiksuki Sign Anusvara - (0x11c3f, 0x11c3f,), # Bhaiksuki Sign Virama + (0x11a51, 0x11a5b,), # Soyombo Vowel Sign I ..Soyombo Vowel Length Mar + (0x11a8a, 0x11a99,), # Soyombo Final Consonant ..Soyombo Subjoiner + (0x11c2f, 0x11c36,), # Bhaiksuki Vowel Sign Aa ..Bhaiksuki Vowel Sign Voc + (0x11c38, 0x11c3f,), # Bhaiksuki Vowel Sign E ..Bhaiksuki Sign Virama (0x11c92, 0x11ca7,), # Marchen Subjoined Letter..Marchen Subjoined Letter - (0x11caa, 0x11cb0,), # Marchen Subjoined Letter..Marchen Vowel Sign Aa - (0x11cb2, 0x11cb3,), # Marchen Vowel Sign U ..Marchen Vowel Sign E - (0x11cb5, 0x11cb6,), # Marchen Sign Anusvara ..Marchen Sign Candrabindu + (0x11ca9, 0x11cb6,), # Marchen Subjoined Letter..Marchen Sign Candrabindu (0x11d31, 0x11d36,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign (0x11d3a, 0x11d3a,), # Masaram Gondi Vowel Sign E (0x11d3c, 0x11d3d,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign (0x11d3f, 0x11d45,), # Masaram Gondi Vowel Sign..Masaram Gondi Virama (0x11d47, 0x11d47,), # Masaram Gondi Ra-kara + (0x11d8a, 0x11d8e,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Vowel Sign (0x11d90, 0x11d91,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Vowel Sign - (0x11d95, 0x11d95,), # Gunjala Gondi Sign Anusvara - (0x11d97, 0x11d97,), # Gunjala Gondi Virama - (0x11ef3, 0x11ef4,), # Makasar Vowel Sign I ..Makasar Vowel Sign U + (0x11d93, 0x11d97,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Virama + (0x11ef3, 0x11ef6,), # Makasar Vowel Sign I ..Makasar Vowel Sign O + (0x13430, 0x13438,), # Egyptian Hieroglyph Vert..Egyptian Hieroglyph End (0x16af0, 0x16af4,), # Bassa Vah Combining High..Bassa Vah Combining High (0x16b30, 0x16b36,), # Pahawh Hmong Mark Cim Tu..Pahawh Hmong Mark Cim Ta (0x16f4f, 0x16f4f,), # Miao Sign Consonant Modifier Bar + (0x16f51, 0x16f87,), # Miao Sign Aspiration ..Miao Vowel Sign Ui (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below (0x1bc9d, 0x1bc9e,), # Duployan Thick Letter Se..Duployan Double Mark - (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining - (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1bca0, 0x1bca3,), # Shorthand Format Letter ..Shorthand Format Up Step + (0x1d165, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d16d, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical @@ -3579,12 +3506,17 @@ ZERO_WIDTH = { (0x1e2ec, 0x1e2ef,), # Wancho Tone Tup ..Wancho Tone Koini (0x1e8d0, 0x1e8d6,), # Mende Kikakui Combining ..Mende Kikakui Combining (0x1e944, 0x1e94a,), # Adlam Alif Lengthener ..Adlam Nukta + (0x1f3fb, 0x1f3ff,), # Emoji Modifier Fitzpatri..Emoji Modifier Fitzpatri + (0xe0001, 0xe0001,), # Language Tag + (0xe0020, 0xe007f,), # Tag Space ..Cancel Tag (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 ), '13.0.0': ( # Source: DerivedGeneralCategory-13.0.0.txt # Date: 2019-10-21, 14:30:32 GMT # + (0x00000, 0x00000,), # (nil) + (0x000ad, 0x000ad,), # Soft Hyphen (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg @@ -3592,13 +3524,16 @@ ZERO_WIDTH = { (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot (0x005c7, 0x005c7,), # Hebrew Point Qamats Qatan + (0x00600, 0x00605,), # Arabic Number Sign ..Arabic Number Mark Above (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0061c, 0x0061c,), # Arabic Letter Mark (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below (0x00670, 0x00670,), # Arabic Letter Superscript Alef - (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006d6, 0x006dd,), # Arabic Small High Ligatu..Arabic End Of Ayah (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x0070f, 0x0070f,), # Syriac Abbreviation Mark (0x00711, 0x00711,), # Syriac Letter Superscript Alaph (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun @@ -3609,67 +3544,72 @@ ZERO_WIDTH = { (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark - (0x008d3, 0x008e1,), # Arabic Small Low Waw ..Arabic Small High Sign S - (0x008e3, 0x00902,), # Arabic Turned Damma Belo..Devanagari Sign Anusvara - (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe - (0x0093c, 0x0093c,), # Devanagari Sign Nukta - (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai - (0x0094d, 0x0094d,), # Devanagari Sign Virama + (0x008d3, 0x00903,), # Arabic Small Low Waw ..Devanagari Sign Visarga + (0x0093a, 0x0093c,), # Devanagari Vowel Sign Oe..Devanagari Sign Nukta + (0x0093e, 0x0094f,), # Devanagari Vowel Sign Aa..Devanagari Vowel Sign Aw (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo - (0x00981, 0x00981,), # Bengali Sign Candrabindu + (0x00981, 0x00983,), # Bengali Sign Candrabindu..Bengali Sign Visarga (0x009bc, 0x009bc,), # Bengali Sign Nukta - (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal - (0x009cd, 0x009cd,), # Bengali Sign Virama + (0x009be, 0x009c4,), # Bengali Vowel Sign Aa ..Bengali Vowel Sign Vocal + (0x009c7, 0x009c8,), # Bengali Vowel Sign E ..Bengali Vowel Sign Ai + (0x009cb, 0x009cd,), # Bengali Vowel Sign O ..Bengali Sign Virama + (0x009d7, 0x009d7,), # Bengali Au Length Mark (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal (0x009fe, 0x009fe,), # Bengali Sandhi Mark - (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a01, 0x00a03,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Visarga (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta - (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a3e, 0x00a42,), # Gurmukhi Vowel Sign Aa ..Gurmukhi Vowel Sign Uu (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash - (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00a81, 0x00a83,), # Gujarati Sign Candrabind..Gujarati Sign Visarga (0x00abc, 0x00abc,), # Gujarati Sign Nukta - (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand - (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai - (0x00acd, 0x00acd,), # Gujarati Sign Virama + (0x00abe, 0x00ac5,), # Gujarati Vowel Sign Aa ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac9,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Cand + (0x00acb, 0x00acd,), # Gujarati Vowel Sign O ..Gujarati Sign Virama (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca (0x00afa, 0x00aff,), # Gujarati Sign Sukun ..Gujarati Sign Two-circle - (0x00b01, 0x00b01,), # Oriya Sign Candrabindu + (0x00b01, 0x00b03,), # Oriya Sign Candrabindu ..Oriya Sign Visarga (0x00b3c, 0x00b3c,), # Oriya Sign Nukta - (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I - (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic - (0x00b4d, 0x00b4d,), # Oriya Sign Virama - (0x00b55, 0x00b56,), # Oriya Sign Overline ..Oriya Ai Length Mark + (0x00b3e, 0x00b44,), # Oriya Vowel Sign Aa ..Oriya Vowel Sign Vocalic + (0x00b47, 0x00b48,), # Oriya Vowel Sign E ..Oriya Vowel Sign Ai + (0x00b4b, 0x00b4d,), # Oriya Vowel Sign O ..Oriya Sign Virama + (0x00b55, 0x00b57,), # Oriya Sign Overline ..Oriya Au Length Mark (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic (0x00b82, 0x00b82,), # Tamil Sign Anusvara - (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii - (0x00bcd, 0x00bcd,), # Tamil Sign Virama - (0x00c00, 0x00c00,), # Telugu Sign Combining Candrabindu Above - (0x00c04, 0x00c04,), # Telugu Sign Combining Anusvara Above - (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00bbe, 0x00bc2,), # Tamil Vowel Sign Aa ..Tamil Vowel Sign Uu + (0x00bc6, 0x00bc8,), # Tamil Vowel Sign E ..Tamil Vowel Sign Ai + (0x00bca, 0x00bcd,), # Tamil Vowel Sign O ..Tamil Sign Virama + (0x00bd7, 0x00bd7,), # Tamil Au Length Mark + (0x00c00, 0x00c04,), # Telugu Sign Combining Ca..Telugu Sign Combining An + (0x00c3e, 0x00c44,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Vocali (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali - (0x00c81, 0x00c81,), # Kannada Sign Candrabindu + (0x00c81, 0x00c83,), # Kannada Sign Candrabindu..Kannada Sign Visarga (0x00cbc, 0x00cbc,), # Kannada Sign Nukta - (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I - (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E - (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00cbe, 0x00cc4,), # Kannada Vowel Sign Aa ..Kannada Vowel Sign Vocal + (0x00cc6, 0x00cc8,), # Kannada Vowel Sign E ..Kannada Vowel Sign Ai + (0x00cca, 0x00ccd,), # Kannada Vowel Sign O ..Kannada Sign Virama + (0x00cd5, 0x00cd6,), # Kannada Length Mark ..Kannada Ai Length Mark (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal - (0x00d00, 0x00d01,), # Malayalam Sign Combining..Malayalam Sign Candrabin + (0x00d00, 0x00d03,), # Malayalam Sign Combining..Malayalam Sign Visarga (0x00d3b, 0x00d3c,), # Malayalam Sign Vertical ..Malayalam Sign Circular - (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc - (0x00d4d, 0x00d4d,), # Malayalam Sign Virama + (0x00d3e, 0x00d44,), # Malayalam Vowel Sign Aa ..Malayalam Vowel Sign Voc + (0x00d46, 0x00d48,), # Malayalam Vowel Sign E ..Malayalam Vowel Sign Ai + (0x00d4a, 0x00d4d,), # Malayalam Vowel Sign O ..Malayalam Sign Virama + (0x00d57, 0x00d57,), # Malayalam Au Length Mark (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc - (0x00d81, 0x00d81,), # Sinhala Sign Candrabindu + (0x00d81, 0x00d83,), # Sinhala Sign Candrabindu..Sinhala Sign Visargaya (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna - (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dcf, 0x00dd4,), # Sinhala Vowel Sign Aela-..Sinhala Vowel Sign Ketti (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga Paa-pilla + (0x00dd8, 0x00ddf,), # Sinhala Vowel Sign Gaett..Sinhala Vowel Sign Gayan + (0x00df2, 0x00df3,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga (0x00e31, 0x00e31,), # Thai Character Mai Han-akat (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan @@ -3680,79 +3620,61 @@ ZERO_WIDTH = { (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung Nyi Zla (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung Sgor Rtags (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru - (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga - (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f3e, 0x00f3f,), # Tibetan Sign Yar Tshes ..Tibetan Sign Mar Tshes + (0x00f71, 0x00f84,), # Tibetan Vowel Sign Aa ..Tibetan Mark Halanta (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gdan - (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu - (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below - (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat - (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M - (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0102b, 0x0103e,), # Myanmar Vowel Sign Tall ..Myanmar Consonant Sign M + (0x01056, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01062, 0x01064,), # Myanmar Vowel Sign Sgaw ..Myanmar Tone Mark Sgaw K + (0x01067, 0x0106d,), # Myanmar Vowel Sign Weste..Myanmar Sign Western Pwo (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah - (0x01082, 0x01082,), # Myanmar Consonant Sign Shan Medial Wa - (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan - (0x0108d, 0x0108d,), # Myanmar Sign Shan Council Emphatic Tone - (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton Ai + (0x01082, 0x0108d,), # Myanmar Consonant Sign S..Myanmar Sign Shan Counci + (0x0108f, 0x0108f,), # Myanmar Sign Rumai Palaung Tone-5 + (0x0109a, 0x0109d,), # Myanmar Sign Khamti Tone..Myanmar Vowel Sign Aiton (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U - (0x017b4, 0x017b5,), # Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa - (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua - (0x017c6, 0x017c6,), # Khmer Sign Nikahit - (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017b4, 0x017d3,), # Khmer Vowel Inherent Aq ..Khmer Sign Bathamasat (0x017dd, 0x017dd,), # Khmer Sign Atthacan - (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x0180b, 0x0180e,), # Mongolian Free Variation..Mongolian Vowel Separato (0x01885, 0x01886,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal (0x018a9, 0x018a9,), # Mongolian Letter Ali Gali Dagalga - (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U - (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O - (0x01932, 0x01932,), # Limbu Small Letter Anusvara - (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i - (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U - (0x01a1b, 0x01a1b,), # Buginese Vowel Sign Ae - (0x01a56, 0x01a56,), # Tai Tham Consonant Sign Medial La - (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign - (0x01a60, 0x01a60,), # Tai Tham Sign Sakot - (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai Sat - (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B - (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01920, 0x0192b,), # Limbu Vowel Sign A ..Limbu Subjoined Letter W + (0x01930, 0x0193b,), # Limbu Small Letter Ka ..Limbu Sign Sa-i + (0x01a17, 0x01a1b,), # Buginese Vowel Sign I ..Buginese Vowel Sign Ae + (0x01a55, 0x01a5e,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a60, 0x01a7c,), # Tai Tham Sign Sakot ..Tai Tham Sign Khuen-lue (0x01a7f, 0x01a7f,), # Tai Tham Combining Cryptogrammic Dot (0x01ab0, 0x01ac0,), # Combining Doubled Circum..Combining Latin Small Le - (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang - (0x01b34, 0x01b34,), # Balinese Sign Rerekan - (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R - (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La Lenga - (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepet + (0x01b00, 0x01b04,), # Balinese Sign Ulu Ricem ..Balinese Sign Bisah + (0x01b34, 0x01b44,), # Balinese Sign Rerekan ..Balinese Adeg Adeg (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol - (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar - (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan - (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan - (0x01bab, 0x01bad,), # Sundanese Sign Virama ..Sundanese Consonant Sign - (0x01be6, 0x01be6,), # Batak Sign Tompi - (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee - (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O - (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H - (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T - (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01b80, 0x01b82,), # Sundanese Sign Panyecek ..Sundanese Sign Pangwisad + (0x01ba1, 0x01bad,), # Sundanese Consonant Sign..Sundanese Consonant Sign + (0x01be6, 0x01bf3,), # Batak Sign Tompi ..Batak Panongonan + (0x01c24, 0x01c37,), # Lepcha Subjoined Letter ..Lepcha Sign Nukta (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha - (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash - (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01cd4, 0x01ce8,), # Vedic Sign Yajurvedic Mi..Vedic Sign Visarga Anuda (0x01ced, 0x01ced,), # Vedic Sign Tiryak (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above - (0x01cf8, 0x01cf9,), # Vedic Tone Ring Above ..Vedic Tone Double Ring A + (0x01cf7, 0x01cf9,), # Vedic Sign Atikrama ..Vedic Tone Double Ring A (0x01dc0, 0x01df9,), # Combining Dotted Grave A..Combining Wide Inverted (0x01dfb, 0x01dff,), # Combining Deletion Mark ..Combining Right Arrowhea + (0x0200b, 0x0200f,), # Zero Width Space ..Right-to-left Mark + (0x02028, 0x0202e,), # Line Separator ..Right-to-left Override + (0x02060, 0x02064,), # Word Joiner ..Invisible Plus + (0x02066, 0x0206f,), # Left-to-right Isolate ..Nominal Digit Shapes (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joiner (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette - (0x0302a, 0x0302d,), # Ideographic Level Tone M..Ideographic Entering Ton + (0x0302a, 0x0302f,), # Ideographic Level Tone M..Hangul Double Dot Tone M (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer @@ -3761,37 +3683,35 @@ ZERO_WIDTH = { (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisvara (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasanta (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusvara - (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a823, 0x0a827,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign (0x0a82c, 0x0a82c,), # Syloti Nagri Sign Alternate Hasanta - (0x0a8c4, 0x0a8c5,), # Saurashtra Sign Virama ..Saurashtra Sign Candrabi + (0x0a880, 0x0a881,), # Saurashtra Sign Anusvara..Saurashtra Sign Visarga + (0x0a8b4, 0x0a8c5,), # Saurashtra Consonant Sig..Saurashtra Sign Candrabi (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig (0x0a8ff, 0x0a8ff,), # Devanagari Vowel Sign Ay (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop - (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R - (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar - (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu - (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku - (0x0a9bc, 0x0a9bd,), # Javanese Vowel Sign Pepe..Javanese Consonant Sign + (0x0a947, 0x0a953,), # Rejang Vowel Sign I ..Rejang Virama + (0x0a980, 0x0a983,), # Javanese Sign Panyangga ..Javanese Sign Wignyan + (0x0a9b3, 0x0a9c0,), # Javanese Sign Cecak Telu..Javanese Pangkon (0x0a9e5, 0x0a9e5,), # Myanmar Sign Shan Saw - (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe - (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue - (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0aa29, 0x0aa36,), # Cham Vowel Sign Aa ..Cham Consonant Sign Wa (0x0aa43, 0x0aa43,), # Cham Consonant Sign Final Ng - (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Final M - (0x0aa7c, 0x0aa7c,), # Myanmar Sign Tai Laing Tone-2 + (0x0aa4c, 0x0aa4d,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa7b, 0x0aa7d,), # Myanmar Sign Pao Karen T..Myanmar Sign Tai Laing T (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho - (0x0aaec, 0x0aaed,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign - (0x0aaf6, 0x0aaf6,), # Meetei Mayek Virama - (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign Anap - (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign Unap - (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek + (0x0aaeb, 0x0aaef,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf5, 0x0aaf6,), # Meetei Mayek Vowel Sign ..Meetei Mayek Virama + (0x0abe3, 0x0abea,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abec, 0x0abed,), # Meetei Mayek Lum Iyek ..Meetei Mayek Apun Iyek (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spanish Varika (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 (0x0fe20, 0x0fe2f,), # Combining Ligature Left ..Combining Cyrillic Titlo + (0x0feff, 0x0feff,), # Zero Width No-break Space + (0x0fff9, 0x0fffb,), # Interlinear Annotation A..Interlinear Annotation T (0x101fd, 0x101fd,), # Phaistos Disc Sign Combining Oblique Stroke (0x102e0, 0x102e0,), # Coptic Epact Thousands Mark (0x10376, 0x1037a,), # Combining Old Permic Let..Combining Old Permic Let @@ -3804,92 +3724,81 @@ ZERO_WIDTH = { (0x10d24, 0x10d27,), # Hanifi Rohingya Sign Har..Hanifi Rohingya Sign Tas (0x10eab, 0x10eac,), # Yezidi Combining Hamza M..Yezidi Combining Madda M (0x10f46, 0x10f50,), # Sogdian Combining Dot Be..Sogdian Combining Stroke - (0x11001, 0x11001,), # Brahmi Sign Anusvara + (0x11000, 0x11002,), # Brahmi Sign Candrabindu ..Brahmi Sign Visarga (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama - (0x1107f, 0x11081,), # Brahmi Number Joiner ..Kaithi Sign Anusvara - (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai - (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x1107f, 0x11082,), # Brahmi Number Joiner ..Kaithi Sign Visarga + (0x110b0, 0x110ba,), # Kaithi Vowel Sign Aa ..Kaithi Sign Nukta + (0x110bd, 0x110bd,), # Kaithi Number Sign + (0x110cd, 0x110cd,), # Kaithi Number Sign Above (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga - (0x11127, 0x1112b,), # Chakma Vowel Sign A ..Chakma Vowel Sign Uu - (0x1112d, 0x11134,), # Chakma Vowel Sign Ai ..Chakma Maayyaa + (0x11127, 0x11134,), # Chakma Vowel Sign A ..Chakma Maayyaa + (0x11145, 0x11146,), # Chakma Vowel Sign Aa ..Chakma Vowel Sign Ei (0x11173, 0x11173,), # Mahajani Sign Nukta - (0x11180, 0x11181,), # Sharada Sign Candrabindu..Sharada Sign Anusvara - (0x111b6, 0x111be,), # Sharada Vowel Sign U ..Sharada Vowel Sign O + (0x11180, 0x11182,), # Sharada Sign Candrabindu..Sharada Sign Visarga + (0x111b3, 0x111c0,), # Sharada Vowel Sign Aa ..Sharada Sign Virama (0x111c9, 0x111cc,), # Sharada Sandhi Mark ..Sharada Extra Short Vowe - (0x111cf, 0x111cf,), # Sharada Sign Inverted Candrabindu - (0x1122f, 0x11231,), # Khojki Vowel Sign U ..Khojki Vowel Sign Ai - (0x11234, 0x11234,), # Khojki Sign Anusvara - (0x11236, 0x11237,), # Khojki Sign Nukta ..Khojki Sign Shadda + (0x111ce, 0x111cf,), # Sharada Vowel Sign Prish..Sharada Sign Inverted Ca + (0x1122c, 0x11237,), # Khojki Vowel Sign Aa ..Khojki Sign Shadda (0x1123e, 0x1123e,), # Khojki Sign Sukun - (0x112df, 0x112df,), # Khudawadi Sign Anusvara - (0x112e3, 0x112ea,), # Khudawadi Vowel Sign U ..Khudawadi Sign Virama - (0x11300, 0x11301,), # Grantha Sign Combining A..Grantha Sign Candrabindu + (0x112df, 0x112ea,), # Khudawadi Sign Anusvara ..Khudawadi Sign Virama + (0x11300, 0x11303,), # Grantha Sign Combining A..Grantha Sign Visarga (0x1133b, 0x1133c,), # Combining Bindu Below ..Grantha Sign Nukta - (0x11340, 0x11340,), # Grantha Vowel Sign Ii + (0x1133e, 0x11344,), # Grantha Vowel Sign Aa ..Grantha Vowel Sign Vocal + (0x11347, 0x11348,), # Grantha Vowel Sign Ee ..Grantha Vowel Sign Ai + (0x1134b, 0x1134d,), # Grantha Vowel Sign Oo ..Grantha Sign Virama + (0x11357, 0x11357,), # Grantha Au Length Mark + (0x11362, 0x11363,), # Grantha Vowel Sign Vocal..Grantha Vowel Sign Vocal (0x11366, 0x1136c,), # Combining Grantha Digit ..Combining Grantha Digit (0x11370, 0x11374,), # Combining Grantha Letter..Combining Grantha Letter - (0x11438, 0x1143f,), # Newa Vowel Sign U ..Newa Vowel Sign Ai - (0x11442, 0x11444,), # Newa Sign Virama ..Newa Sign Anusvara - (0x11446, 0x11446,), # Newa Sign Nukta + (0x11435, 0x11446,), # Newa Vowel Sign Aa ..Newa Sign Nukta (0x1145e, 0x1145e,), # Newa Sandhi Mark - (0x114b3, 0x114b8,), # Tirhuta Vowel Sign U ..Tirhuta Vowel Sign Vocal - (0x114ba, 0x114ba,), # Tirhuta Vowel Sign Short E - (0x114bf, 0x114c0,), # Tirhuta Sign Candrabindu..Tirhuta Sign Anusvara - (0x114c2, 0x114c3,), # Tirhuta Sign Virama ..Tirhuta Sign Nukta - (0x115b2, 0x115b5,), # Siddham Vowel Sign U ..Siddham Vowel Sign Vocal - (0x115bc, 0x115bd,), # Siddham Sign Candrabindu..Siddham Sign Anusvara - (0x115bf, 0x115c0,), # Siddham Sign Virama ..Siddham Sign Nukta + (0x114b0, 0x114c3,), # Tirhuta Vowel Sign Aa ..Tirhuta Sign Nukta + (0x115af, 0x115b5,), # Siddham Vowel Sign Aa ..Siddham Vowel Sign Vocal + (0x115b8, 0x115c0,), # Siddham Vowel Sign E ..Siddham Sign Nukta (0x115dc, 0x115dd,), # Siddham Vowel Sign Alter..Siddham Vowel Sign Alter - (0x11633, 0x1163a,), # Modi Vowel Sign U ..Modi Vowel Sign Ai - (0x1163d, 0x1163d,), # Modi Sign Anusvara - (0x1163f, 0x11640,), # Modi Sign Virama ..Modi Sign Ardhacandra - (0x116ab, 0x116ab,), # Takri Sign Anusvara - (0x116ad, 0x116ad,), # Takri Vowel Sign Aa - (0x116b0, 0x116b5,), # Takri Vowel Sign U ..Takri Vowel Sign Au - (0x116b7, 0x116b7,), # Takri Sign Nukta - (0x1171d, 0x1171f,), # Ahom Consonant Sign Medi..Ahom Consonant Sign Medi - (0x11722, 0x11725,), # Ahom Vowel Sign I ..Ahom Vowel Sign Uu - (0x11727, 0x1172b,), # Ahom Vowel Sign Aw ..Ahom Sign Killer - (0x1182f, 0x11837,), # Dogra Vowel Sign U ..Dogra Sign Anusvara - (0x11839, 0x1183a,), # Dogra Sign Virama ..Dogra Sign Nukta - (0x1193b, 0x1193c,), # Dives Akuru Sign Anusvar..Dives Akuru Sign Candrab - (0x1193e, 0x1193e,), # Dives Akuru Virama - (0x11943, 0x11943,), # Dives Akuru Sign Nukta - (0x119d4, 0x119d7,), # Nandinagari Vowel Sign U..Nandinagari Vowel Sign V - (0x119da, 0x119db,), # Nandinagari Vowel Sign E..Nandinagari Vowel Sign A - (0x119e0, 0x119e0,), # Nandinagari Sign Virama + (0x11630, 0x11640,), # Modi Vowel Sign Aa ..Modi Sign Ardhacandra + (0x116ab, 0x116b7,), # Takri Sign Anusvara ..Takri Sign Nukta + (0x1171d, 0x1172b,), # Ahom Consonant Sign Medi..Ahom Sign Killer + (0x1182c, 0x1183a,), # Dogra Vowel Sign Aa ..Dogra Sign Nukta + (0x11930, 0x11935,), # Dives Akuru Vowel Sign A..Dives Akuru Vowel Sign E + (0x11937, 0x11938,), # Dives Akuru Vowel Sign A..Dives Akuru Vowel Sign O + (0x1193b, 0x1193e,), # Dives Akuru Sign Anusvar..Dives Akuru Virama + (0x11940, 0x11940,), # Dives Akuru Medial Ya + (0x11942, 0x11943,), # Dives Akuru Medial Ra ..Dives Akuru Sign Nukta + (0x119d1, 0x119d7,), # Nandinagari Vowel Sign A..Nandinagari Vowel Sign V + (0x119da, 0x119e0,), # Nandinagari Vowel Sign E..Nandinagari Sign Virama + (0x119e4, 0x119e4,), # Nandinagari Vowel Sign Prishthamatra E (0x11a01, 0x11a0a,), # Zanabazar Square Vowel S..Zanabazar Square Vowel L - (0x11a33, 0x11a38,), # Zanabazar Square Final C..Zanabazar Square Sign An + (0x11a33, 0x11a39,), # Zanabazar Square Final C..Zanabazar Square Sign Vi (0x11a3b, 0x11a3e,), # Zanabazar Square Cluster..Zanabazar Square Cluster (0x11a47, 0x11a47,), # Zanabazar Square Subjoiner - (0x11a51, 0x11a56,), # Soyombo Vowel Sign I ..Soyombo Vowel Sign Oe - (0x11a59, 0x11a5b,), # Soyombo Vowel Sign Vocal..Soyombo Vowel Length Mar - (0x11a8a, 0x11a96,), # Soyombo Final Consonant ..Soyombo Sign Anusvara - (0x11a98, 0x11a99,), # Soyombo Gemination Mark ..Soyombo Subjoiner - (0x11c30, 0x11c36,), # Bhaiksuki Vowel Sign I ..Bhaiksuki Vowel Sign Voc - (0x11c38, 0x11c3d,), # Bhaiksuki Vowel Sign E ..Bhaiksuki Sign Anusvara - (0x11c3f, 0x11c3f,), # Bhaiksuki Sign Virama + (0x11a51, 0x11a5b,), # Soyombo Vowel Sign I ..Soyombo Vowel Length Mar + (0x11a8a, 0x11a99,), # Soyombo Final Consonant ..Soyombo Subjoiner + (0x11c2f, 0x11c36,), # Bhaiksuki Vowel Sign Aa ..Bhaiksuki Vowel Sign Voc + (0x11c38, 0x11c3f,), # Bhaiksuki Vowel Sign E ..Bhaiksuki Sign Virama (0x11c92, 0x11ca7,), # Marchen Subjoined Letter..Marchen Subjoined Letter - (0x11caa, 0x11cb0,), # Marchen Subjoined Letter..Marchen Vowel Sign Aa - (0x11cb2, 0x11cb3,), # Marchen Vowel Sign U ..Marchen Vowel Sign E - (0x11cb5, 0x11cb6,), # Marchen Sign Anusvara ..Marchen Sign Candrabindu + (0x11ca9, 0x11cb6,), # Marchen Subjoined Letter..Marchen Sign Candrabindu (0x11d31, 0x11d36,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign (0x11d3a, 0x11d3a,), # Masaram Gondi Vowel Sign E (0x11d3c, 0x11d3d,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign (0x11d3f, 0x11d45,), # Masaram Gondi Vowel Sign..Masaram Gondi Virama (0x11d47, 0x11d47,), # Masaram Gondi Ra-kara + (0x11d8a, 0x11d8e,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Vowel Sign (0x11d90, 0x11d91,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Vowel Sign - (0x11d95, 0x11d95,), # Gunjala Gondi Sign Anusvara - (0x11d97, 0x11d97,), # Gunjala Gondi Virama - (0x11ef3, 0x11ef4,), # Makasar Vowel Sign I ..Makasar Vowel Sign U + (0x11d93, 0x11d97,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Virama + (0x11ef3, 0x11ef6,), # Makasar Vowel Sign I ..Makasar Vowel Sign O + (0x13430, 0x13438,), # Egyptian Hieroglyph Vert..Egyptian Hieroglyph End (0x16af0, 0x16af4,), # Bassa Vah Combining High..Bassa Vah Combining High (0x16b30, 0x16b36,), # Pahawh Hmong Mark Cim Tu..Pahawh Hmong Mark Cim Ta (0x16f4f, 0x16f4f,), # Miao Sign Consonant Modifier Bar + (0x16f51, 0x16f87,), # Miao Sign Aspiration ..Miao Vowel Sign Ui (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below (0x16fe4, 0x16fe4,), # Khitan Small Script Filler + (0x16ff0, 0x16ff1,), # Vietnamese Alternate Rea..Vietnamese Alternate Rea (0x1bc9d, 0x1bc9e,), # Duployan Thick Letter Se..Duployan Double Mark - (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining - (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1bca0, 0x1bca3,), # Shorthand Format Letter ..Shorthand Format Up Step + (0x1d165, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d16d, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical @@ -3908,12 +3817,17 @@ ZERO_WIDTH = { (0x1e2ec, 0x1e2ef,), # Wancho Tone Tup ..Wancho Tone Koini (0x1e8d0, 0x1e8d6,), # Mende Kikakui Combining ..Mende Kikakui Combining (0x1e944, 0x1e94a,), # Adlam Alif Lengthener ..Adlam Nukta + (0x1f3fb, 0x1f3ff,), # Emoji Modifier Fitzpatri..Emoji Modifier Fitzpatri + (0xe0001, 0xe0001,), # Language Tag + (0xe0020, 0xe007f,), # Tag Space ..Cancel Tag (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 ), '14.0.0': ( # Source: DerivedGeneralCategory-14.0.0.txt # Date: 2021-07-10, 00:35:08 GMT # + (0x00000, 0x00000,), # (nil) + (0x000ad, 0x000ad,), # Soft Hyphen (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg @@ -3921,13 +3835,16 @@ ZERO_WIDTH = { (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot (0x005c7, 0x005c7,), # Hebrew Point Qamats Qatan + (0x00600, 0x00605,), # Arabic Number Sign ..Arabic Number Mark Above (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0061c, 0x0061c,), # Arabic Letter Mark (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below (0x00670, 0x00670,), # Arabic Letter Superscript Alef - (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006d6, 0x006dd,), # Arabic Small High Ligatu..Arabic End Of Ayah (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x0070f, 0x0070f,), # Syriac Abbreviation Mark (0x00711, 0x00711,), # Syriac Letter Superscript Alaph (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun @@ -3938,69 +3855,75 @@ ZERO_WIDTH = { (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark + (0x00890, 0x00891,), # Arabic Pound Mark Above ..Arabic Piastre Mark Abov (0x00898, 0x0089f,), # Arabic Small High Word A..Arabic Half Madda Over M - (0x008ca, 0x008e1,), # Arabic Small High Farsi ..Arabic Small High Sign S - (0x008e3, 0x00902,), # Arabic Turned Damma Belo..Devanagari Sign Anusvara - (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe - (0x0093c, 0x0093c,), # Devanagari Sign Nukta - (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai - (0x0094d, 0x0094d,), # Devanagari Sign Virama + (0x008ca, 0x00903,), # Arabic Small High Farsi ..Devanagari Sign Visarga + (0x0093a, 0x0093c,), # Devanagari Vowel Sign Oe..Devanagari Sign Nukta + (0x0093e, 0x0094f,), # Devanagari Vowel Sign Aa..Devanagari Vowel Sign Aw (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo - (0x00981, 0x00981,), # Bengali Sign Candrabindu + (0x00981, 0x00983,), # Bengali Sign Candrabindu..Bengali Sign Visarga (0x009bc, 0x009bc,), # Bengali Sign Nukta - (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal - (0x009cd, 0x009cd,), # Bengali Sign Virama + (0x009be, 0x009c4,), # Bengali Vowel Sign Aa ..Bengali Vowel Sign Vocal + (0x009c7, 0x009c8,), # Bengali Vowel Sign E ..Bengali Vowel Sign Ai + (0x009cb, 0x009cd,), # Bengali Vowel Sign O ..Bengali Sign Virama + (0x009d7, 0x009d7,), # Bengali Au Length Mark (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal (0x009fe, 0x009fe,), # Bengali Sandhi Mark - (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a01, 0x00a03,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Visarga (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta - (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a3e, 0x00a42,), # Gurmukhi Vowel Sign Aa ..Gurmukhi Vowel Sign Uu (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash - (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00a81, 0x00a83,), # Gujarati Sign Candrabind..Gujarati Sign Visarga (0x00abc, 0x00abc,), # Gujarati Sign Nukta - (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand - (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai - (0x00acd, 0x00acd,), # Gujarati Sign Virama + (0x00abe, 0x00ac5,), # Gujarati Vowel Sign Aa ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac9,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Cand + (0x00acb, 0x00acd,), # Gujarati Vowel Sign O ..Gujarati Sign Virama (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca (0x00afa, 0x00aff,), # Gujarati Sign Sukun ..Gujarati Sign Two-circle - (0x00b01, 0x00b01,), # Oriya Sign Candrabindu + (0x00b01, 0x00b03,), # Oriya Sign Candrabindu ..Oriya Sign Visarga (0x00b3c, 0x00b3c,), # Oriya Sign Nukta - (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I - (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic - (0x00b4d, 0x00b4d,), # Oriya Sign Virama - (0x00b55, 0x00b56,), # Oriya Sign Overline ..Oriya Ai Length Mark + (0x00b3e, 0x00b44,), # Oriya Vowel Sign Aa ..Oriya Vowel Sign Vocalic + (0x00b47, 0x00b48,), # Oriya Vowel Sign E ..Oriya Vowel Sign Ai + (0x00b4b, 0x00b4d,), # Oriya Vowel Sign O ..Oriya Sign Virama + (0x00b55, 0x00b57,), # Oriya Sign Overline ..Oriya Au Length Mark (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic (0x00b82, 0x00b82,), # Tamil Sign Anusvara - (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii - (0x00bcd, 0x00bcd,), # Tamil Sign Virama - (0x00c00, 0x00c00,), # Telugu Sign Combining Candrabindu Above - (0x00c04, 0x00c04,), # Telugu Sign Combining Anusvara Above + (0x00bbe, 0x00bc2,), # Tamil Vowel Sign Aa ..Tamil Vowel Sign Uu + (0x00bc6, 0x00bc8,), # Tamil Vowel Sign E ..Tamil Vowel Sign Ai + (0x00bca, 0x00bcd,), # Tamil Vowel Sign O ..Tamil Sign Virama + (0x00bd7, 0x00bd7,), # Tamil Au Length Mark + (0x00c00, 0x00c04,), # Telugu Sign Combining Ca..Telugu Sign Combining An (0x00c3c, 0x00c3c,), # Telugu Sign Nukta - (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00c3e, 0x00c44,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Vocali (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali - (0x00c81, 0x00c81,), # Kannada Sign Candrabindu + (0x00c81, 0x00c83,), # Kannada Sign Candrabindu..Kannada Sign Visarga (0x00cbc, 0x00cbc,), # Kannada Sign Nukta - (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I - (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E - (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00cbe, 0x00cc4,), # Kannada Vowel Sign Aa ..Kannada Vowel Sign Vocal + (0x00cc6, 0x00cc8,), # Kannada Vowel Sign E ..Kannada Vowel Sign Ai + (0x00cca, 0x00ccd,), # Kannada Vowel Sign O ..Kannada Sign Virama + (0x00cd5, 0x00cd6,), # Kannada Length Mark ..Kannada Ai Length Mark (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal - (0x00d00, 0x00d01,), # Malayalam Sign Combining..Malayalam Sign Candrabin + (0x00d00, 0x00d03,), # Malayalam Sign Combining..Malayalam Sign Visarga (0x00d3b, 0x00d3c,), # Malayalam Sign Vertical ..Malayalam Sign Circular - (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc - (0x00d4d, 0x00d4d,), # Malayalam Sign Virama + (0x00d3e, 0x00d44,), # Malayalam Vowel Sign Aa ..Malayalam Vowel Sign Voc + (0x00d46, 0x00d48,), # Malayalam Vowel Sign E ..Malayalam Vowel Sign Ai + (0x00d4a, 0x00d4d,), # Malayalam Vowel Sign O ..Malayalam Sign Virama + (0x00d57, 0x00d57,), # Malayalam Au Length Mark (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc - (0x00d81, 0x00d81,), # Sinhala Sign Candrabindu + (0x00d81, 0x00d83,), # Sinhala Sign Candrabindu..Sinhala Sign Visargaya (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna - (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dcf, 0x00dd4,), # Sinhala Vowel Sign Aela-..Sinhala Vowel Sign Ketti (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga Paa-pilla + (0x00dd8, 0x00ddf,), # Sinhala Vowel Sign Gaett..Sinhala Vowel Sign Gayan + (0x00df2, 0x00df3,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga (0x00e31, 0x00e31,), # Thai Character Mai Han-akat (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan @@ -4011,79 +3934,60 @@ ZERO_WIDTH = { (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung Nyi Zla (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung Sgor Rtags (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru - (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga - (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f3e, 0x00f3f,), # Tibetan Sign Yar Tshes ..Tibetan Sign Mar Tshes + (0x00f71, 0x00f84,), # Tibetan Vowel Sign Aa ..Tibetan Mark Halanta (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gdan - (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu - (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below - (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat - (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M - (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0102b, 0x0103e,), # Myanmar Vowel Sign Tall ..Myanmar Consonant Sign M + (0x01056, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01062, 0x01064,), # Myanmar Vowel Sign Sgaw ..Myanmar Tone Mark Sgaw K + (0x01067, 0x0106d,), # Myanmar Vowel Sign Weste..Myanmar Sign Western Pwo (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah - (0x01082, 0x01082,), # Myanmar Consonant Sign Shan Medial Wa - (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan - (0x0108d, 0x0108d,), # Myanmar Sign Shan Council Emphatic Tone - (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton Ai + (0x01082, 0x0108d,), # Myanmar Consonant Sign S..Myanmar Sign Shan Counci + (0x0108f, 0x0108f,), # Myanmar Sign Rumai Palaung Tone-5 + (0x0109a, 0x0109d,), # Myanmar Sign Khamti Tone..Myanmar Vowel Sign Aiton (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin - (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama - (0x01732, 0x01733,), # Hanunoo Vowel Sign I ..Hanunoo Vowel Sign U + (0x01712, 0x01715,), # Tagalog Vowel Sign I ..Tagalog Sign Pamudpod + (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U - (0x017b4, 0x017b5,), # Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa - (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua - (0x017c6, 0x017c6,), # Khmer Sign Nikahit - (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017b4, 0x017d3,), # Khmer Vowel Inherent Aq ..Khmer Sign Bathamasat (0x017dd, 0x017dd,), # Khmer Sign Atthacan - (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation - (0x0180f, 0x0180f,), # Mongolian Free Variation Selector Four + (0x0180b, 0x0180f,), # Mongolian Free Variation..Mongolian Free Variation (0x01885, 0x01886,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal (0x018a9, 0x018a9,), # Mongolian Letter Ali Gali Dagalga - (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U - (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O - (0x01932, 0x01932,), # Limbu Small Letter Anusvara - (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i - (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U - (0x01a1b, 0x01a1b,), # Buginese Vowel Sign Ae - (0x01a56, 0x01a56,), # Tai Tham Consonant Sign Medial La - (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign - (0x01a60, 0x01a60,), # Tai Tham Sign Sakot - (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai Sat - (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B - (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01920, 0x0192b,), # Limbu Vowel Sign A ..Limbu Subjoined Letter W + (0x01930, 0x0193b,), # Limbu Small Letter Ka ..Limbu Sign Sa-i + (0x01a17, 0x01a1b,), # Buginese Vowel Sign I ..Buginese Vowel Sign Ae + (0x01a55, 0x01a5e,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a60, 0x01a7c,), # Tai Tham Sign Sakot ..Tai Tham Sign Khuen-lue (0x01a7f, 0x01a7f,), # Tai Tham Combining Cryptogrammic Dot (0x01ab0, 0x01ace,), # Combining Doubled Circum..Combining Latin Small Le - (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang - (0x01b34, 0x01b34,), # Balinese Sign Rerekan - (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R - (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La Lenga - (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepet + (0x01b00, 0x01b04,), # Balinese Sign Ulu Ricem ..Balinese Sign Bisah + (0x01b34, 0x01b44,), # Balinese Sign Rerekan ..Balinese Adeg Adeg (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol - (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar - (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan - (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan - (0x01bab, 0x01bad,), # Sundanese Sign Virama ..Sundanese Consonant Sign - (0x01be6, 0x01be6,), # Batak Sign Tompi - (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee - (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O - (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H - (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T - (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01b80, 0x01b82,), # Sundanese Sign Panyecek ..Sundanese Sign Pangwisad + (0x01ba1, 0x01bad,), # Sundanese Consonant Sign..Sundanese Consonant Sign + (0x01be6, 0x01bf3,), # Batak Sign Tompi ..Batak Panongonan + (0x01c24, 0x01c37,), # Lepcha Subjoined Letter ..Lepcha Sign Nukta (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha - (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash - (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01cd4, 0x01ce8,), # Vedic Sign Yajurvedic Mi..Vedic Sign Visarga Anuda (0x01ced, 0x01ced,), # Vedic Sign Tiryak (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above - (0x01cf8, 0x01cf9,), # Vedic Tone Ring Above ..Vedic Tone Double Ring A + (0x01cf7, 0x01cf9,), # Vedic Sign Atikrama ..Vedic Tone Double Ring A (0x01dc0, 0x01dff,), # Combining Dotted Grave A..Combining Right Arrowhea + (0x0200b, 0x0200f,), # Zero Width Space ..Right-to-left Mark + (0x02028, 0x0202e,), # Line Separator ..Right-to-left Override + (0x02060, 0x02064,), # Word Joiner ..Invisible Plus + (0x02066, 0x0206f,), # Left-to-right Isolate ..Nominal Digit Shapes (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joiner (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette - (0x0302a, 0x0302d,), # Ideographic Level Tone M..Ideographic Entering Ton + (0x0302a, 0x0302f,), # Ideographic Level Tone M..Hangul Double Dot Tone M (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer @@ -4092,37 +3996,35 @@ ZERO_WIDTH = { (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisvara (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasanta (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusvara - (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a823, 0x0a827,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign (0x0a82c, 0x0a82c,), # Syloti Nagri Sign Alternate Hasanta - (0x0a8c4, 0x0a8c5,), # Saurashtra Sign Virama ..Saurashtra Sign Candrabi + (0x0a880, 0x0a881,), # Saurashtra Sign Anusvara..Saurashtra Sign Visarga + (0x0a8b4, 0x0a8c5,), # Saurashtra Consonant Sig..Saurashtra Sign Candrabi (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig (0x0a8ff, 0x0a8ff,), # Devanagari Vowel Sign Ay (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop - (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R - (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar - (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu - (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku - (0x0a9bc, 0x0a9bd,), # Javanese Vowel Sign Pepe..Javanese Consonant Sign + (0x0a947, 0x0a953,), # Rejang Vowel Sign I ..Rejang Virama + (0x0a980, 0x0a983,), # Javanese Sign Panyangga ..Javanese Sign Wignyan + (0x0a9b3, 0x0a9c0,), # Javanese Sign Cecak Telu..Javanese Pangkon (0x0a9e5, 0x0a9e5,), # Myanmar Sign Shan Saw - (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe - (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue - (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0aa29, 0x0aa36,), # Cham Vowel Sign Aa ..Cham Consonant Sign Wa (0x0aa43, 0x0aa43,), # Cham Consonant Sign Final Ng - (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Final M - (0x0aa7c, 0x0aa7c,), # Myanmar Sign Tai Laing Tone-2 + (0x0aa4c, 0x0aa4d,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa7b, 0x0aa7d,), # Myanmar Sign Pao Karen T..Myanmar Sign Tai Laing T (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho - (0x0aaec, 0x0aaed,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign - (0x0aaf6, 0x0aaf6,), # Meetei Mayek Virama - (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign Anap - (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign Unap - (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek + (0x0aaeb, 0x0aaef,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf5, 0x0aaf6,), # Meetei Mayek Vowel Sign ..Meetei Mayek Virama + (0x0abe3, 0x0abea,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abec, 0x0abed,), # Meetei Mayek Lum Iyek ..Meetei Mayek Apun Iyek (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spanish Varika (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 (0x0fe20, 0x0fe2f,), # Combining Ligature Left ..Combining Cyrillic Titlo + (0x0feff, 0x0feff,), # Zero Width No-break Space + (0x0fff9, 0x0fffb,), # Interlinear Annotation A..Interlinear Annotation T (0x101fd, 0x101fd,), # Phaistos Disc Sign Combining Oblique Stroke (0x102e0, 0x102e0,), # Coptic Epact Thousands Mark (0x10376, 0x1037a,), # Combining Old Permic Let..Combining Old Permic Let @@ -4136,97 +4038,86 @@ ZERO_WIDTH = { (0x10eab, 0x10eac,), # Yezidi Combining Hamza M..Yezidi Combining Madda M (0x10f46, 0x10f50,), # Sogdian Combining Dot Be..Sogdian Combining Stroke (0x10f82, 0x10f85,), # Old Uyghur Combining Dot..Old Uyghur Combining Two - (0x11001, 0x11001,), # Brahmi Sign Anusvara + (0x11000, 0x11002,), # Brahmi Sign Candrabindu ..Brahmi Sign Visarga (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama (0x11070, 0x11070,), # Brahmi Sign Old Tamil Virama (0x11073, 0x11074,), # Brahmi Vowel Sign Old Ta..Brahmi Vowel Sign Old Ta - (0x1107f, 0x11081,), # Brahmi Number Joiner ..Kaithi Sign Anusvara - (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai - (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x1107f, 0x11082,), # Brahmi Number Joiner ..Kaithi Sign Visarga + (0x110b0, 0x110ba,), # Kaithi Vowel Sign Aa ..Kaithi Sign Nukta + (0x110bd, 0x110bd,), # Kaithi Number Sign (0x110c2, 0x110c2,), # Kaithi Vowel Sign Vocalic R + (0x110cd, 0x110cd,), # Kaithi Number Sign Above (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga - (0x11127, 0x1112b,), # Chakma Vowel Sign A ..Chakma Vowel Sign Uu - (0x1112d, 0x11134,), # Chakma Vowel Sign Ai ..Chakma Maayyaa + (0x11127, 0x11134,), # Chakma Vowel Sign A ..Chakma Maayyaa + (0x11145, 0x11146,), # Chakma Vowel Sign Aa ..Chakma Vowel Sign Ei (0x11173, 0x11173,), # Mahajani Sign Nukta - (0x11180, 0x11181,), # Sharada Sign Candrabindu..Sharada Sign Anusvara - (0x111b6, 0x111be,), # Sharada Vowel Sign U ..Sharada Vowel Sign O + (0x11180, 0x11182,), # Sharada Sign Candrabindu..Sharada Sign Visarga + (0x111b3, 0x111c0,), # Sharada Vowel Sign Aa ..Sharada Sign Virama (0x111c9, 0x111cc,), # Sharada Sandhi Mark ..Sharada Extra Short Vowe - (0x111cf, 0x111cf,), # Sharada Sign Inverted Candrabindu - (0x1122f, 0x11231,), # Khojki Vowel Sign U ..Khojki Vowel Sign Ai - (0x11234, 0x11234,), # Khojki Sign Anusvara - (0x11236, 0x11237,), # Khojki Sign Nukta ..Khojki Sign Shadda + (0x111ce, 0x111cf,), # Sharada Vowel Sign Prish..Sharada Sign Inverted Ca + (0x1122c, 0x11237,), # Khojki Vowel Sign Aa ..Khojki Sign Shadda (0x1123e, 0x1123e,), # Khojki Sign Sukun - (0x112df, 0x112df,), # Khudawadi Sign Anusvara - (0x112e3, 0x112ea,), # Khudawadi Vowel Sign U ..Khudawadi Sign Virama - (0x11300, 0x11301,), # Grantha Sign Combining A..Grantha Sign Candrabindu + (0x112df, 0x112ea,), # Khudawadi Sign Anusvara ..Khudawadi Sign Virama + (0x11300, 0x11303,), # Grantha Sign Combining A..Grantha Sign Visarga (0x1133b, 0x1133c,), # Combining Bindu Below ..Grantha Sign Nukta - (0x11340, 0x11340,), # Grantha Vowel Sign Ii + (0x1133e, 0x11344,), # Grantha Vowel Sign Aa ..Grantha Vowel Sign Vocal + (0x11347, 0x11348,), # Grantha Vowel Sign Ee ..Grantha Vowel Sign Ai + (0x1134b, 0x1134d,), # Grantha Vowel Sign Oo ..Grantha Sign Virama + (0x11357, 0x11357,), # Grantha Au Length Mark + (0x11362, 0x11363,), # Grantha Vowel Sign Vocal..Grantha Vowel Sign Vocal (0x11366, 0x1136c,), # Combining Grantha Digit ..Combining Grantha Digit (0x11370, 0x11374,), # Combining Grantha Letter..Combining Grantha Letter - (0x11438, 0x1143f,), # Newa Vowel Sign U ..Newa Vowel Sign Ai - (0x11442, 0x11444,), # Newa Sign Virama ..Newa Sign Anusvara - (0x11446, 0x11446,), # Newa Sign Nukta + (0x11435, 0x11446,), # Newa Vowel Sign Aa ..Newa Sign Nukta (0x1145e, 0x1145e,), # Newa Sandhi Mark - (0x114b3, 0x114b8,), # Tirhuta Vowel Sign U ..Tirhuta Vowel Sign Vocal - (0x114ba, 0x114ba,), # Tirhuta Vowel Sign Short E - (0x114bf, 0x114c0,), # Tirhuta Sign Candrabindu..Tirhuta Sign Anusvara - (0x114c2, 0x114c3,), # Tirhuta Sign Virama ..Tirhuta Sign Nukta - (0x115b2, 0x115b5,), # Siddham Vowel Sign U ..Siddham Vowel Sign Vocal - (0x115bc, 0x115bd,), # Siddham Sign Candrabindu..Siddham Sign Anusvara - (0x115bf, 0x115c0,), # Siddham Sign Virama ..Siddham Sign Nukta + (0x114b0, 0x114c3,), # Tirhuta Vowel Sign Aa ..Tirhuta Sign Nukta + (0x115af, 0x115b5,), # Siddham Vowel Sign Aa ..Siddham Vowel Sign Vocal + (0x115b8, 0x115c0,), # Siddham Vowel Sign E ..Siddham Sign Nukta (0x115dc, 0x115dd,), # Siddham Vowel Sign Alter..Siddham Vowel Sign Alter - (0x11633, 0x1163a,), # Modi Vowel Sign U ..Modi Vowel Sign Ai - (0x1163d, 0x1163d,), # Modi Sign Anusvara - (0x1163f, 0x11640,), # Modi Sign Virama ..Modi Sign Ardhacandra - (0x116ab, 0x116ab,), # Takri Sign Anusvara - (0x116ad, 0x116ad,), # Takri Vowel Sign Aa - (0x116b0, 0x116b5,), # Takri Vowel Sign U ..Takri Vowel Sign Au - (0x116b7, 0x116b7,), # Takri Sign Nukta - (0x1171d, 0x1171f,), # Ahom Consonant Sign Medi..Ahom Consonant Sign Medi - (0x11722, 0x11725,), # Ahom Vowel Sign I ..Ahom Vowel Sign Uu - (0x11727, 0x1172b,), # Ahom Vowel Sign Aw ..Ahom Sign Killer - (0x1182f, 0x11837,), # Dogra Vowel Sign U ..Dogra Sign Anusvara - (0x11839, 0x1183a,), # Dogra Sign Virama ..Dogra Sign Nukta - (0x1193b, 0x1193c,), # Dives Akuru Sign Anusvar..Dives Akuru Sign Candrab - (0x1193e, 0x1193e,), # Dives Akuru Virama - (0x11943, 0x11943,), # Dives Akuru Sign Nukta - (0x119d4, 0x119d7,), # Nandinagari Vowel Sign U..Nandinagari Vowel Sign V - (0x119da, 0x119db,), # Nandinagari Vowel Sign E..Nandinagari Vowel Sign A - (0x119e0, 0x119e0,), # Nandinagari Sign Virama + (0x11630, 0x11640,), # Modi Vowel Sign Aa ..Modi Sign Ardhacandra + (0x116ab, 0x116b7,), # Takri Sign Anusvara ..Takri Sign Nukta + (0x1171d, 0x1172b,), # Ahom Consonant Sign Medi..Ahom Sign Killer + (0x1182c, 0x1183a,), # Dogra Vowel Sign Aa ..Dogra Sign Nukta + (0x11930, 0x11935,), # Dives Akuru Vowel Sign A..Dives Akuru Vowel Sign E + (0x11937, 0x11938,), # Dives Akuru Vowel Sign A..Dives Akuru Vowel Sign O + (0x1193b, 0x1193e,), # Dives Akuru Sign Anusvar..Dives Akuru Virama + (0x11940, 0x11940,), # Dives Akuru Medial Ya + (0x11942, 0x11943,), # Dives Akuru Medial Ra ..Dives Akuru Sign Nukta + (0x119d1, 0x119d7,), # Nandinagari Vowel Sign A..Nandinagari Vowel Sign V + (0x119da, 0x119e0,), # Nandinagari Vowel Sign E..Nandinagari Sign Virama + (0x119e4, 0x119e4,), # Nandinagari Vowel Sign Prishthamatra E (0x11a01, 0x11a0a,), # Zanabazar Square Vowel S..Zanabazar Square Vowel L - (0x11a33, 0x11a38,), # Zanabazar Square Final C..Zanabazar Square Sign An + (0x11a33, 0x11a39,), # Zanabazar Square Final C..Zanabazar Square Sign Vi (0x11a3b, 0x11a3e,), # Zanabazar Square Cluster..Zanabazar Square Cluster (0x11a47, 0x11a47,), # Zanabazar Square Subjoiner - (0x11a51, 0x11a56,), # Soyombo Vowel Sign I ..Soyombo Vowel Sign Oe - (0x11a59, 0x11a5b,), # Soyombo Vowel Sign Vocal..Soyombo Vowel Length Mar - (0x11a8a, 0x11a96,), # Soyombo Final Consonant ..Soyombo Sign Anusvara - (0x11a98, 0x11a99,), # Soyombo Gemination Mark ..Soyombo Subjoiner - (0x11c30, 0x11c36,), # Bhaiksuki Vowel Sign I ..Bhaiksuki Vowel Sign Voc - (0x11c38, 0x11c3d,), # Bhaiksuki Vowel Sign E ..Bhaiksuki Sign Anusvara - (0x11c3f, 0x11c3f,), # Bhaiksuki Sign Virama + (0x11a51, 0x11a5b,), # Soyombo Vowel Sign I ..Soyombo Vowel Length Mar + (0x11a8a, 0x11a99,), # Soyombo Final Consonant ..Soyombo Subjoiner + (0x11c2f, 0x11c36,), # Bhaiksuki Vowel Sign Aa ..Bhaiksuki Vowel Sign Voc + (0x11c38, 0x11c3f,), # Bhaiksuki Vowel Sign E ..Bhaiksuki Sign Virama (0x11c92, 0x11ca7,), # Marchen Subjoined Letter..Marchen Subjoined Letter - (0x11caa, 0x11cb0,), # Marchen Subjoined Letter..Marchen Vowel Sign Aa - (0x11cb2, 0x11cb3,), # Marchen Vowel Sign U ..Marchen Vowel Sign E - (0x11cb5, 0x11cb6,), # Marchen Sign Anusvara ..Marchen Sign Candrabindu + (0x11ca9, 0x11cb6,), # Marchen Subjoined Letter..Marchen Sign Candrabindu (0x11d31, 0x11d36,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign (0x11d3a, 0x11d3a,), # Masaram Gondi Vowel Sign E (0x11d3c, 0x11d3d,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign (0x11d3f, 0x11d45,), # Masaram Gondi Vowel Sign..Masaram Gondi Virama (0x11d47, 0x11d47,), # Masaram Gondi Ra-kara + (0x11d8a, 0x11d8e,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Vowel Sign (0x11d90, 0x11d91,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Vowel Sign - (0x11d95, 0x11d95,), # Gunjala Gondi Sign Anusvara - (0x11d97, 0x11d97,), # Gunjala Gondi Virama - (0x11ef3, 0x11ef4,), # Makasar Vowel Sign I ..Makasar Vowel Sign U + (0x11d93, 0x11d97,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Virama + (0x11ef3, 0x11ef6,), # Makasar Vowel Sign I ..Makasar Vowel Sign O + (0x13430, 0x13438,), # Egyptian Hieroglyph Vert..Egyptian Hieroglyph End (0x16af0, 0x16af4,), # Bassa Vah Combining High..Bassa Vah Combining High (0x16b30, 0x16b36,), # Pahawh Hmong Mark Cim Tu..Pahawh Hmong Mark Cim Ta (0x16f4f, 0x16f4f,), # Miao Sign Consonant Modifier Bar + (0x16f51, 0x16f87,), # Miao Sign Aspiration ..Miao Vowel Sign Ui (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below (0x16fe4, 0x16fe4,), # Khitan Small Script Filler + (0x16ff0, 0x16ff1,), # Vietnamese Alternate Rea..Vietnamese Alternate Rea (0x1bc9d, 0x1bc9e,), # Duployan Thick Letter Se..Duployan Double Mark + (0x1bca0, 0x1bca3,), # Shorthand Format Letter ..Shorthand Format Up Step (0x1cf00, 0x1cf2d,), # Znamenny Combining Mark ..Znamenny Combining Mark (0x1cf30, 0x1cf46,), # Znamenny Combining Tonal..Znamenny Priznak Modifie - (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining - (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d165, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d16d, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical @@ -4246,12 +4137,17 @@ ZERO_WIDTH = { (0x1e2ec, 0x1e2ef,), # Wancho Tone Tup ..Wancho Tone Koini (0x1e8d0, 0x1e8d6,), # Mende Kikakui Combining ..Mende Kikakui Combining (0x1e944, 0x1e94a,), # Adlam Alif Lengthener ..Adlam Nukta + (0x1f3fb, 0x1f3ff,), # Emoji Modifier Fitzpatri..Emoji Modifier Fitzpatri + (0xe0001, 0xe0001,), # Language Tag + (0xe0020, 0xe007f,), # Tag Space ..Cancel Tag (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 ), '15.0.0': ( # Source: DerivedGeneralCategory-15.0.0.txt # Date: 2022-04-26, 23:14:35 GMT # + (0x00000, 0x00000,), # (nil) + (0x000ad, 0x000ad,), # Soft Hyphen (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg @@ -4259,13 +4155,16 @@ ZERO_WIDTH = { (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot (0x005c7, 0x005c7,), # Hebrew Point Qamats Qatan + (0x00600, 0x00605,), # Arabic Number Sign ..Arabic Number Mark Above (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0061c, 0x0061c,), # Arabic Letter Mark (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below (0x00670, 0x00670,), # Arabic Letter Superscript Alef - (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006d6, 0x006dd,), # Arabic Small High Ligatu..Arabic End Of Ayah (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x0070f, 0x0070f,), # Syriac Abbreviation Mark (0x00711, 0x00711,), # Syriac Letter Superscript Alaph (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun @@ -4276,152 +4175,470 @@ ZERO_WIDTH = { (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark + (0x00890, 0x00891,), # Arabic Pound Mark Above ..Arabic Piastre Mark Abov (0x00898, 0x0089f,), # Arabic Small High Word A..Arabic Half Madda Over M - (0x008ca, 0x008e1,), # Arabic Small High Farsi ..Arabic Small High Sign S - (0x008e3, 0x00902,), # Arabic Turned Damma Belo..Devanagari Sign Anusvara - (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe - (0x0093c, 0x0093c,), # Devanagari Sign Nukta - (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai - (0x0094d, 0x0094d,), # Devanagari Sign Virama + (0x008ca, 0x00903,), # Arabic Small High Farsi ..Devanagari Sign Visarga + (0x0093a, 0x0093c,), # Devanagari Vowel Sign Oe..Devanagari Sign Nukta + (0x0093e, 0x0094f,), # Devanagari Vowel Sign Aa..Devanagari Vowel Sign Aw (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo - (0x00981, 0x00981,), # Bengali Sign Candrabindu + (0x00981, 0x00983,), # Bengali Sign Candrabindu..Bengali Sign Visarga (0x009bc, 0x009bc,), # Bengali Sign Nukta - (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal - (0x009cd, 0x009cd,), # Bengali Sign Virama + (0x009be, 0x009c4,), # Bengali Vowel Sign Aa ..Bengali Vowel Sign Vocal + (0x009c7, 0x009c8,), # Bengali Vowel Sign E ..Bengali Vowel Sign Ai + (0x009cb, 0x009cd,), # Bengali Vowel Sign O ..Bengali Sign Virama + (0x009d7, 0x009d7,), # Bengali Au Length Mark (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal (0x009fe, 0x009fe,), # Bengali Sandhi Mark - (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a01, 0x00a03,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Visarga (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta - (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a3e, 0x00a42,), # Gurmukhi Vowel Sign Aa ..Gurmukhi Vowel Sign Uu (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash - (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00a81, 0x00a83,), # Gujarati Sign Candrabind..Gujarati Sign Visarga (0x00abc, 0x00abc,), # Gujarati Sign Nukta - (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand - (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai - (0x00acd, 0x00acd,), # Gujarati Sign Virama + (0x00abe, 0x00ac5,), # Gujarati Vowel Sign Aa ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac9,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Cand + (0x00acb, 0x00acd,), # Gujarati Vowel Sign O ..Gujarati Sign Virama (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca (0x00afa, 0x00aff,), # Gujarati Sign Sukun ..Gujarati Sign Two-circle - (0x00b01, 0x00b01,), # Oriya Sign Candrabindu + (0x00b01, 0x00b03,), # Oriya Sign Candrabindu ..Oriya Sign Visarga (0x00b3c, 0x00b3c,), # Oriya Sign Nukta - (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I - (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic - (0x00b4d, 0x00b4d,), # Oriya Sign Virama - (0x00b55, 0x00b56,), # Oriya Sign Overline ..Oriya Ai Length Mark + (0x00b3e, 0x00b44,), # Oriya Vowel Sign Aa ..Oriya Vowel Sign Vocalic + (0x00b47, 0x00b48,), # Oriya Vowel Sign E ..Oriya Vowel Sign Ai + (0x00b4b, 0x00b4d,), # Oriya Vowel Sign O ..Oriya Sign Virama + (0x00b55, 0x00b57,), # Oriya Sign Overline ..Oriya Au Length Mark (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic (0x00b82, 0x00b82,), # Tamil Sign Anusvara - (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii - (0x00bcd, 0x00bcd,), # Tamil Sign Virama - (0x00c00, 0x00c00,), # Telugu Sign Combining Candrabindu Above - (0x00c04, 0x00c04,), # Telugu Sign Combining Anusvara Above + (0x00bbe, 0x00bc2,), # Tamil Vowel Sign Aa ..Tamil Vowel Sign Uu + (0x00bc6, 0x00bc8,), # Tamil Vowel Sign E ..Tamil Vowel Sign Ai + (0x00bca, 0x00bcd,), # Tamil Vowel Sign O ..Tamil Sign Virama + (0x00bd7, 0x00bd7,), # Tamil Au Length Mark + (0x00c00, 0x00c04,), # Telugu Sign Combining Ca..Telugu Sign Combining An (0x00c3c, 0x00c3c,), # Telugu Sign Nukta - (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00c3e, 0x00c44,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Vocali (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali - (0x00c81, 0x00c81,), # Kannada Sign Candrabindu + (0x00c81, 0x00c83,), # Kannada Sign Candrabindu..Kannada Sign Visarga (0x00cbc, 0x00cbc,), # Kannada Sign Nukta - (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I - (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E - (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00cbe, 0x00cc4,), # Kannada Vowel Sign Aa ..Kannada Vowel Sign Vocal + (0x00cc6, 0x00cc8,), # Kannada Vowel Sign E ..Kannada Vowel Sign Ai + (0x00cca, 0x00ccd,), # Kannada Vowel Sign O ..Kannada Sign Virama + (0x00cd5, 0x00cd6,), # Kannada Length Mark ..Kannada Ai Length Mark (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal - (0x00d00, 0x00d01,), # Malayalam Sign Combining..Malayalam Sign Candrabin + (0x00cf3, 0x00cf3,), # Kannada Sign Combining Anusvara Above Right + (0x00d00, 0x00d03,), # Malayalam Sign Combining..Malayalam Sign Visarga (0x00d3b, 0x00d3c,), # Malayalam Sign Vertical ..Malayalam Sign Circular - (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc - (0x00d4d, 0x00d4d,), # Malayalam Sign Virama + (0x00d3e, 0x00d44,), # Malayalam Vowel Sign Aa ..Malayalam Vowel Sign Voc + (0x00d46, 0x00d48,), # Malayalam Vowel Sign E ..Malayalam Vowel Sign Ai + (0x00d4a, 0x00d4d,), # Malayalam Vowel Sign O ..Malayalam Sign Virama + (0x00d57, 0x00d57,), # Malayalam Au Length Mark (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc - (0x00d81, 0x00d81,), # Sinhala Sign Candrabindu + (0x00d81, 0x00d83,), # Sinhala Sign Candrabindu..Sinhala Sign Visargaya (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna - (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dcf, 0x00dd4,), # Sinhala Vowel Sign Aela-..Sinhala Vowel Sign Ketti (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga Paa-pilla + (0x00dd8, 0x00ddf,), # Sinhala Vowel Sign Gaett..Sinhala Vowel Sign Gayan + (0x00df2, 0x00df3,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga (0x00e31, 0x00e31,), # Thai Character Mai Han-akat (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan (0x00eb1, 0x00eb1,), # Lao Vowel Sign Mai Kan (0x00eb4, 0x00ebc,), # Lao Vowel Sign I ..Lao Semivowel Sign Lo - (0x00ec8, 0x00ece,), # Lao Tone Mai Ek ..(nil) + (0x00ec8, 0x00ece,), # Lao Tone Mai Ek ..Lao Yamakkan (0x00f18, 0x00f19,), # Tibetan Astrological Sig..Tibetan Astrological Sig (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung Nyi Zla (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung Sgor Rtags (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru - (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga - (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f3e, 0x00f3f,), # Tibetan Sign Yar Tshes ..Tibetan Sign Mar Tshes + (0x00f71, 0x00f84,), # Tibetan Vowel Sign Aa ..Tibetan Mark Halanta (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gdan - (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu - (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below - (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat - (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M - (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0102b, 0x0103e,), # Myanmar Vowel Sign Tall ..Myanmar Consonant Sign M + (0x01056, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01062, 0x01064,), # Myanmar Vowel Sign Sgaw ..Myanmar Tone Mark Sgaw K + (0x01067, 0x0106d,), # Myanmar Vowel Sign Weste..Myanmar Sign Western Pwo (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah - (0x01082, 0x01082,), # Myanmar Consonant Sign Shan Medial Wa - (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan - (0x0108d, 0x0108d,), # Myanmar Sign Shan Council Emphatic Tone - (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton Ai + (0x01082, 0x0108d,), # Myanmar Consonant Sign S..Myanmar Sign Shan Counci + (0x0108f, 0x0108f,), # Myanmar Sign Rumai Palaung Tone-5 + (0x0109a, 0x0109d,), # Myanmar Sign Khamti Tone..Myanmar Vowel Sign Aiton (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin - (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama - (0x01732, 0x01733,), # Hanunoo Vowel Sign I ..Hanunoo Vowel Sign U + (0x01712, 0x01715,), # Tagalog Vowel Sign I ..Tagalog Sign Pamudpod + (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U - (0x017b4, 0x017b5,), # Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa - (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua - (0x017c6, 0x017c6,), # Khmer Sign Nikahit - (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017b4, 0x017d3,), # Khmer Vowel Inherent Aq ..Khmer Sign Bathamasat (0x017dd, 0x017dd,), # Khmer Sign Atthacan - (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation - (0x0180f, 0x0180f,), # Mongolian Free Variation Selector Four + (0x0180b, 0x0180f,), # Mongolian Free Variation..Mongolian Free Variation (0x01885, 0x01886,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal (0x018a9, 0x018a9,), # Mongolian Letter Ali Gali Dagalga - (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U - (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O - (0x01932, 0x01932,), # Limbu Small Letter Anusvara - (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i - (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U - (0x01a1b, 0x01a1b,), # Buginese Vowel Sign Ae - (0x01a56, 0x01a56,), # Tai Tham Consonant Sign Medial La - (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign - (0x01a60, 0x01a60,), # Tai Tham Sign Sakot - (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai Sat - (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B - (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01920, 0x0192b,), # Limbu Vowel Sign A ..Limbu Subjoined Letter W + (0x01930, 0x0193b,), # Limbu Small Letter Ka ..Limbu Sign Sa-i + (0x01a17, 0x01a1b,), # Buginese Vowel Sign I ..Buginese Vowel Sign Ae + (0x01a55, 0x01a5e,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a60, 0x01a7c,), # Tai Tham Sign Sakot ..Tai Tham Sign Khuen-lue (0x01a7f, 0x01a7f,), # Tai Tham Combining Cryptogrammic Dot (0x01ab0, 0x01ace,), # Combining Doubled Circum..Combining Latin Small Le - (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang - (0x01b34, 0x01b34,), # Balinese Sign Rerekan - (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R - (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La Lenga - (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepet + (0x01b00, 0x01b04,), # Balinese Sign Ulu Ricem ..Balinese Sign Bisah + (0x01b34, 0x01b44,), # Balinese Sign Rerekan ..Balinese Adeg Adeg (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol - (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar - (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan - (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan - (0x01bab, 0x01bad,), # Sundanese Sign Virama ..Sundanese Consonant Sign - (0x01be6, 0x01be6,), # Batak Sign Tompi - (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee - (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O - (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H - (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T - (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01b80, 0x01b82,), # Sundanese Sign Panyecek ..Sundanese Sign Pangwisad + (0x01ba1, 0x01bad,), # Sundanese Consonant Sign..Sundanese Consonant Sign + (0x01be6, 0x01bf3,), # Batak Sign Tompi ..Batak Panongonan + (0x01c24, 0x01c37,), # Lepcha Subjoined Letter ..Lepcha Sign Nukta (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha - (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash - (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01cd4, 0x01ce8,), # Vedic Sign Yajurvedic Mi..Vedic Sign Visarga Anuda (0x01ced, 0x01ced,), # Vedic Sign Tiryak (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above - (0x01cf8, 0x01cf9,), # Vedic Tone Ring Above ..Vedic Tone Double Ring A + (0x01cf7, 0x01cf9,), # Vedic Sign Atikrama ..Vedic Tone Double Ring A + (0x01dc0, 0x01dff,), # Combining Dotted Grave A..Combining Right Arrowhea + (0x0200b, 0x0200f,), # Zero Width Space ..Right-to-left Mark + (0x02028, 0x0202e,), # Line Separator ..Right-to-left Override + (0x02060, 0x02064,), # Word Joiner ..Invisible Plus + (0x02066, 0x0206f,), # Left-to-right Isolate ..Nominal Digit Shapes + (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above + (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu + (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joiner + (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0302a, 0x0302f,), # Ideographic Level Tone M..Hangul Double Dot Tone M + (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag + (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous + (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer + (0x0a69e, 0x0a69f,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0a6f0, 0x0a6f1,), # Bamum Combining Mark Koq..Bamum Combining Mark Tuk + (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisvara + (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasanta + (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusvara + (0x0a823, 0x0a827,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a82c, 0x0a82c,), # Syloti Nagri Sign Alternate Hasanta + (0x0a880, 0x0a881,), # Saurashtra Sign Anusvara..Saurashtra Sign Visarga + (0x0a8b4, 0x0a8c5,), # Saurashtra Consonant Sig..Saurashtra Sign Candrabi + (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig + (0x0a8ff, 0x0a8ff,), # Devanagari Vowel Sign Ay + (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop + (0x0a947, 0x0a953,), # Rejang Vowel Sign I ..Rejang Virama + (0x0a980, 0x0a983,), # Javanese Sign Panyangga ..Javanese Sign Wignyan + (0x0a9b3, 0x0a9c0,), # Javanese Sign Cecak Telu..Javanese Pangkon + (0x0a9e5, 0x0a9e5,), # Myanmar Sign Shan Saw + (0x0aa29, 0x0aa36,), # Cham Vowel Sign Aa ..Cham Consonant Sign Wa + (0x0aa43, 0x0aa43,), # Cham Consonant Sign Final Ng + (0x0aa4c, 0x0aa4d,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa7b, 0x0aa7d,), # Myanmar Sign Pao Karen T..Myanmar Sign Tai Laing T + (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang + (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U + (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia + (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek + (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho + (0x0aaeb, 0x0aaef,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf5, 0x0aaf6,), # Meetei Mayek Vowel Sign ..Meetei Mayek Virama + (0x0abe3, 0x0abea,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abec, 0x0abed,), # Meetei Mayek Lum Iyek ..Meetei Mayek Apun Iyek + (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spanish Varika + (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 + (0x0fe20, 0x0fe2f,), # Combining Ligature Left ..Combining Cyrillic Titlo + (0x0feff, 0x0feff,), # Zero Width No-break Space + (0x0fff9, 0x0fffb,), # Interlinear Annotation A..Interlinear Annotation T + (0x101fd, 0x101fd,), # Phaistos Disc Sign Combining Oblique Stroke + (0x102e0, 0x102e0,), # Coptic Epact Thousands Mark + (0x10376, 0x1037a,), # Combining Old Permic Let..Combining Old Permic Let + (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo + (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O + (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga + (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo + (0x10a3f, 0x10a3f,), # Kharoshthi Virama + (0x10ae5, 0x10ae6,), # Manichaean Abbreviation ..Manichaean Abbreviation + (0x10d24, 0x10d27,), # Hanifi Rohingya Sign Har..Hanifi Rohingya Sign Tas + (0x10eab, 0x10eac,), # Yezidi Combining Hamza M..Yezidi Combining Madda M + (0x10efd, 0x10eff,), # Arabic Small Low Word Sa..Arabic Small Low Word Ma + (0x10f46, 0x10f50,), # Sogdian Combining Dot Be..Sogdian Combining Stroke + (0x10f82, 0x10f85,), # Old Uyghur Combining Dot..Old Uyghur Combining Two + (0x11000, 0x11002,), # Brahmi Sign Candrabindu ..Brahmi Sign Visarga + (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama + (0x11070, 0x11070,), # Brahmi Sign Old Tamil Virama + (0x11073, 0x11074,), # Brahmi Vowel Sign Old Ta..Brahmi Vowel Sign Old Ta + (0x1107f, 0x11082,), # Brahmi Number Joiner ..Kaithi Sign Visarga + (0x110b0, 0x110ba,), # Kaithi Vowel Sign Aa ..Kaithi Sign Nukta + (0x110bd, 0x110bd,), # Kaithi Number Sign + (0x110c2, 0x110c2,), # Kaithi Vowel Sign Vocalic R + (0x110cd, 0x110cd,), # Kaithi Number Sign Above + (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga + (0x11127, 0x11134,), # Chakma Vowel Sign A ..Chakma Maayyaa + (0x11145, 0x11146,), # Chakma Vowel Sign Aa ..Chakma Vowel Sign Ei + (0x11173, 0x11173,), # Mahajani Sign Nukta + (0x11180, 0x11182,), # Sharada Sign Candrabindu..Sharada Sign Visarga + (0x111b3, 0x111c0,), # Sharada Vowel Sign Aa ..Sharada Sign Virama + (0x111c9, 0x111cc,), # Sharada Sandhi Mark ..Sharada Extra Short Vowe + (0x111ce, 0x111cf,), # Sharada Vowel Sign Prish..Sharada Sign Inverted Ca + (0x1122c, 0x11237,), # Khojki Vowel Sign Aa ..Khojki Sign Shadda + (0x1123e, 0x1123e,), # Khojki Sign Sukun + (0x11241, 0x11241,), # Khojki Vowel Sign Vocalic R + (0x112df, 0x112ea,), # Khudawadi Sign Anusvara ..Khudawadi Sign Virama + (0x11300, 0x11303,), # Grantha Sign Combining A..Grantha Sign Visarga + (0x1133b, 0x1133c,), # Combining Bindu Below ..Grantha Sign Nukta + (0x1133e, 0x11344,), # Grantha Vowel Sign Aa ..Grantha Vowel Sign Vocal + (0x11347, 0x11348,), # Grantha Vowel Sign Ee ..Grantha Vowel Sign Ai + (0x1134b, 0x1134d,), # Grantha Vowel Sign Oo ..Grantha Sign Virama + (0x11357, 0x11357,), # Grantha Au Length Mark + (0x11362, 0x11363,), # Grantha Vowel Sign Vocal..Grantha Vowel Sign Vocal + (0x11366, 0x1136c,), # Combining Grantha Digit ..Combining Grantha Digit + (0x11370, 0x11374,), # Combining Grantha Letter..Combining Grantha Letter + (0x11435, 0x11446,), # Newa Vowel Sign Aa ..Newa Sign Nukta + (0x1145e, 0x1145e,), # Newa Sandhi Mark + (0x114b0, 0x114c3,), # Tirhuta Vowel Sign Aa ..Tirhuta Sign Nukta + (0x115af, 0x115b5,), # Siddham Vowel Sign Aa ..Siddham Vowel Sign Vocal + (0x115b8, 0x115c0,), # Siddham Vowel Sign E ..Siddham Sign Nukta + (0x115dc, 0x115dd,), # Siddham Vowel Sign Alter..Siddham Vowel Sign Alter + (0x11630, 0x11640,), # Modi Vowel Sign Aa ..Modi Sign Ardhacandra + (0x116ab, 0x116b7,), # Takri Sign Anusvara ..Takri Sign Nukta + (0x1171d, 0x1172b,), # Ahom Consonant Sign Medi..Ahom Sign Killer + (0x1182c, 0x1183a,), # Dogra Vowel Sign Aa ..Dogra Sign Nukta + (0x11930, 0x11935,), # Dives Akuru Vowel Sign A..Dives Akuru Vowel Sign E + (0x11937, 0x11938,), # Dives Akuru Vowel Sign A..Dives Akuru Vowel Sign O + (0x1193b, 0x1193e,), # Dives Akuru Sign Anusvar..Dives Akuru Virama + (0x11940, 0x11940,), # Dives Akuru Medial Ya + (0x11942, 0x11943,), # Dives Akuru Medial Ra ..Dives Akuru Sign Nukta + (0x119d1, 0x119d7,), # Nandinagari Vowel Sign A..Nandinagari Vowel Sign V + (0x119da, 0x119e0,), # Nandinagari Vowel Sign E..Nandinagari Sign Virama + (0x119e4, 0x119e4,), # Nandinagari Vowel Sign Prishthamatra E + (0x11a01, 0x11a0a,), # Zanabazar Square Vowel S..Zanabazar Square Vowel L + (0x11a33, 0x11a39,), # Zanabazar Square Final C..Zanabazar Square Sign Vi + (0x11a3b, 0x11a3e,), # Zanabazar Square Cluster..Zanabazar Square Cluster + (0x11a47, 0x11a47,), # Zanabazar Square Subjoiner + (0x11a51, 0x11a5b,), # Soyombo Vowel Sign I ..Soyombo Vowel Length Mar + (0x11a8a, 0x11a99,), # Soyombo Final Consonant ..Soyombo Subjoiner + (0x11c2f, 0x11c36,), # Bhaiksuki Vowel Sign Aa ..Bhaiksuki Vowel Sign Voc + (0x11c38, 0x11c3f,), # Bhaiksuki Vowel Sign E ..Bhaiksuki Sign Virama + (0x11c92, 0x11ca7,), # Marchen Subjoined Letter..Marchen Subjoined Letter + (0x11ca9, 0x11cb6,), # Marchen Subjoined Letter..Marchen Sign Candrabindu + (0x11d31, 0x11d36,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign + (0x11d3a, 0x11d3a,), # Masaram Gondi Vowel Sign E + (0x11d3c, 0x11d3d,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign + (0x11d3f, 0x11d45,), # Masaram Gondi Vowel Sign..Masaram Gondi Virama + (0x11d47, 0x11d47,), # Masaram Gondi Ra-kara + (0x11d8a, 0x11d8e,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Vowel Sign + (0x11d90, 0x11d91,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Vowel Sign + (0x11d93, 0x11d97,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Virama + (0x11ef3, 0x11ef6,), # Makasar Vowel Sign I ..Makasar Vowel Sign O + (0x11f00, 0x11f01,), # Kawi Sign Candrabindu ..Kawi Sign Anusvara + (0x11f03, 0x11f03,), # Kawi Sign Visarga + (0x11f34, 0x11f3a,), # Kawi Vowel Sign Aa ..Kawi Vowel Sign Vocalic + (0x11f3e, 0x11f42,), # Kawi Vowel Sign E ..Kawi Conjoiner + (0x13430, 0x13440,), # Egyptian Hieroglyph Vert..Egyptian Hieroglyph Mirr + (0x13447, 0x13455,), # Egyptian Hieroglyph Modi..Egyptian Hieroglyph Modi + (0x16af0, 0x16af4,), # Bassa Vah Combining High..Bassa Vah Combining High + (0x16b30, 0x16b36,), # Pahawh Hmong Mark Cim Tu..Pahawh Hmong Mark Cim Ta + (0x16f4f, 0x16f4f,), # Miao Sign Consonant Modifier Bar + (0x16f51, 0x16f87,), # Miao Sign Aspiration ..Miao Vowel Sign Ui + (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below + (0x16fe4, 0x16fe4,), # Khitan Small Script Filler + (0x16ff0, 0x16ff1,), # Vietnamese Alternate Rea..Vietnamese Alternate Rea + (0x1bc9d, 0x1bc9e,), # Duployan Thick Letter Se..Duployan Double Mark + (0x1bca0, 0x1bca3,), # Shorthand Format Letter ..Shorthand Format Up Step + (0x1cf00, 0x1cf2d,), # Znamenny Combining Mark ..Znamenny Combining Mark + (0x1cf30, 0x1cf46,), # Znamenny Combining Tonal..Znamenny Priznak Modifie + (0x1d165, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d16d, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0x1da00, 0x1da36,), # Signwriting Head Rim ..Signwriting Air Sucking + (0x1da3b, 0x1da6c,), # Signwriting Mouth Closed..Signwriting Excitement + (0x1da75, 0x1da75,), # Signwriting Upper Body Tilting From Hip Joints + (0x1da84, 0x1da84,), # Signwriting Location Head Neck + (0x1da9b, 0x1da9f,), # Signwriting Fill Modifie..Signwriting Fill Modifie + (0x1daa1, 0x1daaf,), # Signwriting Rotation Mod..Signwriting Rotation Mod + (0x1e000, 0x1e006,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e008, 0x1e018,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e01b, 0x1e021,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e023, 0x1e024,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e026, 0x1e02a,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e08f, 0x1e08f,), # Combining Cyrillic Small Letter Byelorussian-ukr + (0x1e130, 0x1e136,), # Nyiakeng Puachue Hmong T..Nyiakeng Puachue Hmong T + (0x1e2ae, 0x1e2ae,), # Toto Sign Rising Tone + (0x1e2ec, 0x1e2ef,), # Wancho Tone Tup ..Wancho Tone Koini + (0x1e4ec, 0x1e4ef,), # Nag Mundari Sign Muhor ..Nag Mundari Sign Sutuh + (0x1e8d0, 0x1e8d6,), # Mende Kikakui Combining ..Mende Kikakui Combining + (0x1e944, 0x1e94a,), # Adlam Alif Lengthener ..Adlam Nukta + (0x1f3fb, 0x1f3ff,), # Emoji Modifier Fitzpatri..Emoji Modifier Fitzpatri + (0xe0001, 0xe0001,), # Language Tag + (0xe0020, 0xe007f,), # Tag Space ..Cancel Tag + (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 + ), + '15.1.0': ( + # Source: DerivedGeneralCategory-15.1.0.txt + # Date: 2023-07-28, 23:34:02 GMT + # + (0x00000, 0x00000,), # (nil) + (0x000ad, 0x000ad,), # Soft Hyphen + (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le + (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli + (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg + (0x005bf, 0x005bf,), # Hebrew Point Rafe + (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot + (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot + (0x005c7, 0x005c7,), # Hebrew Point Qamats Qatan + (0x00600, 0x00605,), # Arabic Number Sign ..Arabic Number Mark Above + (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0061c, 0x0061c,), # Arabic Letter Mark + (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below + (0x00670, 0x00670,), # Arabic Letter Superscript Alef + (0x006d6, 0x006dd,), # Arabic Small High Ligatu..Arabic End Of Ayah + (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda + (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon + (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x0070f, 0x0070f,), # Syriac Abbreviation Mark + (0x00711, 0x00711,), # Syriac Letter Superscript Alaph + (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh + (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun + (0x007eb, 0x007f3,), # Nko Combining Short High..Nko Combining Double Dot + (0x007fd, 0x007fd,), # Nko Dantayalan + (0x00816, 0x00819,), # Samaritan Mark In ..Samaritan Mark Dagesh + (0x0081b, 0x00823,), # Samaritan Mark Epentheti..Samaritan Vowel Sign A + (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U + (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa + (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark + (0x00890, 0x00891,), # Arabic Pound Mark Above ..Arabic Piastre Mark Abov + (0x00898, 0x0089f,), # Arabic Small High Word A..Arabic Half Madda Over M + (0x008ca, 0x00903,), # Arabic Small High Farsi ..Devanagari Sign Visarga + (0x0093a, 0x0093c,), # Devanagari Vowel Sign Oe..Devanagari Sign Nukta + (0x0093e, 0x0094f,), # Devanagari Vowel Sign Aa..Devanagari Vowel Sign Aw + (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu + (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo + (0x00981, 0x00983,), # Bengali Sign Candrabindu..Bengali Sign Visarga + (0x009bc, 0x009bc,), # Bengali Sign Nukta + (0x009be, 0x009c4,), # Bengali Vowel Sign Aa ..Bengali Vowel Sign Vocal + (0x009c7, 0x009c8,), # Bengali Vowel Sign E ..Bengali Vowel Sign Ai + (0x009cb, 0x009cd,), # Bengali Vowel Sign O ..Bengali Sign Virama + (0x009d7, 0x009d7,), # Bengali Au Length Mark + (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal + (0x009fe, 0x009fe,), # Bengali Sandhi Mark + (0x00a01, 0x00a03,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Visarga + (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta + (0x00a3e, 0x00a42,), # Gurmukhi Vowel Sign Aa ..Gurmukhi Vowel Sign Uu + (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai + (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama + (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat + (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak + (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash + (0x00a81, 0x00a83,), # Gujarati Sign Candrabind..Gujarati Sign Visarga + (0x00abc, 0x00abc,), # Gujarati Sign Nukta + (0x00abe, 0x00ac5,), # Gujarati Vowel Sign Aa ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac9,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Cand + (0x00acb, 0x00acd,), # Gujarati Vowel Sign O ..Gujarati Sign Virama + (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca + (0x00afa, 0x00aff,), # Gujarati Sign Sukun ..Gujarati Sign Two-circle + (0x00b01, 0x00b03,), # Oriya Sign Candrabindu ..Oriya Sign Visarga + (0x00b3c, 0x00b3c,), # Oriya Sign Nukta + (0x00b3e, 0x00b44,), # Oriya Vowel Sign Aa ..Oriya Vowel Sign Vocalic + (0x00b47, 0x00b48,), # Oriya Vowel Sign E ..Oriya Vowel Sign Ai + (0x00b4b, 0x00b4d,), # Oriya Vowel Sign O ..Oriya Sign Virama + (0x00b55, 0x00b57,), # Oriya Sign Overline ..Oriya Au Length Mark + (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic + (0x00b82, 0x00b82,), # Tamil Sign Anusvara + (0x00bbe, 0x00bc2,), # Tamil Vowel Sign Aa ..Tamil Vowel Sign Uu + (0x00bc6, 0x00bc8,), # Tamil Vowel Sign E ..Tamil Vowel Sign Ai + (0x00bca, 0x00bcd,), # Tamil Vowel Sign O ..Tamil Sign Virama + (0x00bd7, 0x00bd7,), # Tamil Au Length Mark + (0x00c00, 0x00c04,), # Telugu Sign Combining Ca..Telugu Sign Combining An + (0x00c3c, 0x00c3c,), # Telugu Sign Nukta + (0x00c3e, 0x00c44,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Vocali + (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai + (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama + (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark + (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali + (0x00c81, 0x00c83,), # Kannada Sign Candrabindu..Kannada Sign Visarga + (0x00cbc, 0x00cbc,), # Kannada Sign Nukta + (0x00cbe, 0x00cc4,), # Kannada Vowel Sign Aa ..Kannada Vowel Sign Vocal + (0x00cc6, 0x00cc8,), # Kannada Vowel Sign E ..Kannada Vowel Sign Ai + (0x00cca, 0x00ccd,), # Kannada Vowel Sign O ..Kannada Sign Virama + (0x00cd5, 0x00cd6,), # Kannada Length Mark ..Kannada Ai Length Mark + (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal + (0x00cf3, 0x00cf3,), # Kannada Sign Combining Anusvara Above Right + (0x00d00, 0x00d03,), # Malayalam Sign Combining..Malayalam Sign Visarga + (0x00d3b, 0x00d3c,), # Malayalam Sign Vertical ..Malayalam Sign Circular + (0x00d3e, 0x00d44,), # Malayalam Vowel Sign Aa ..Malayalam Vowel Sign Voc + (0x00d46, 0x00d48,), # Malayalam Vowel Sign E ..Malayalam Vowel Sign Ai + (0x00d4a, 0x00d4d,), # Malayalam Vowel Sign O ..Malayalam Sign Virama + (0x00d57, 0x00d57,), # Malayalam Au Length Mark + (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00d81, 0x00d83,), # Sinhala Sign Candrabindu..Sinhala Sign Visargaya + (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna + (0x00dcf, 0x00dd4,), # Sinhala Vowel Sign Aela-..Sinhala Vowel Sign Ketti + (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga Paa-pilla + (0x00dd8, 0x00ddf,), # Sinhala Vowel Sign Gaett..Sinhala Vowel Sign Gayan + (0x00df2, 0x00df3,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga + (0x00e31, 0x00e31,), # Thai Character Mai Han-akat + (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu + (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan + (0x00eb1, 0x00eb1,), # Lao Vowel Sign Mai Kan + (0x00eb4, 0x00ebc,), # Lao Vowel Sign I ..Lao Semivowel Sign Lo + (0x00ec8, 0x00ece,), # Lao Tone Mai Ek ..Lao Yamakkan + (0x00f18, 0x00f19,), # Tibetan Astrological Sig..Tibetan Astrological Sig + (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung Nyi Zla + (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung Sgor Rtags + (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru + (0x00f3e, 0x00f3f,), # Tibetan Sign Yar Tshes ..Tibetan Sign Mar Tshes + (0x00f71, 0x00f84,), # Tibetan Vowel Sign Aa ..Tibetan Mark Halanta + (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags + (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter + (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter + (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gdan + (0x0102b, 0x0103e,), # Myanmar Vowel Sign Tall ..Myanmar Consonant Sign M + (0x01056, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01062, 0x01064,), # Myanmar Vowel Sign Sgaw ..Myanmar Tone Mark Sgaw K + (0x01067, 0x0106d,), # Myanmar Vowel Sign Weste..Myanmar Sign Western Pwo + (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah + (0x01082, 0x0108d,), # Myanmar Consonant Sign S..Myanmar Sign Shan Counci + (0x0108f, 0x0108f,), # Myanmar Sign Rumai Palaung Tone-5 + (0x0109a, 0x0109d,), # Myanmar Sign Khamti Tone..Myanmar Vowel Sign Aiton + (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin + (0x01712, 0x01715,), # Tagalog Vowel Sign I ..Tagalog Sign Pamudpod + (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod + (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U + (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U + (0x017b4, 0x017d3,), # Khmer Vowel Inherent Aq ..Khmer Sign Bathamasat + (0x017dd, 0x017dd,), # Khmer Sign Atthacan + (0x0180b, 0x0180f,), # Mongolian Free Variation..Mongolian Free Variation + (0x01885, 0x01886,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal + (0x018a9, 0x018a9,), # Mongolian Letter Ali Gali Dagalga + (0x01920, 0x0192b,), # Limbu Vowel Sign A ..Limbu Subjoined Letter W + (0x01930, 0x0193b,), # Limbu Small Letter Ka ..Limbu Sign Sa-i + (0x01a17, 0x01a1b,), # Buginese Vowel Sign I ..Buginese Vowel Sign Ae + (0x01a55, 0x01a5e,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a60, 0x01a7c,), # Tai Tham Sign Sakot ..Tai Tham Sign Khuen-lue + (0x01a7f, 0x01a7f,), # Tai Tham Combining Cryptogrammic Dot + (0x01ab0, 0x01ace,), # Combining Doubled Circum..Combining Latin Small Le + (0x01b00, 0x01b04,), # Balinese Sign Ulu Ricem ..Balinese Sign Bisah + (0x01b34, 0x01b44,), # Balinese Sign Rerekan ..Balinese Adeg Adeg + (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol + (0x01b80, 0x01b82,), # Sundanese Sign Panyecek ..Sundanese Sign Pangwisad + (0x01ba1, 0x01bad,), # Sundanese Consonant Sign..Sundanese Consonant Sign + (0x01be6, 0x01bf3,), # Batak Sign Tompi ..Batak Panongonan + (0x01c24, 0x01c37,), # Lepcha Subjoined Letter ..Lepcha Sign Nukta + (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha + (0x01cd4, 0x01ce8,), # Vedic Sign Yajurvedic Mi..Vedic Sign Visarga Anuda + (0x01ced, 0x01ced,), # Vedic Sign Tiryak + (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above + (0x01cf7, 0x01cf9,), # Vedic Sign Atikrama ..Vedic Tone Double Ring A (0x01dc0, 0x01dff,), # Combining Dotted Grave A..Combining Right Arrowhea + (0x0200b, 0x0200f,), # Zero Width Space ..Right-to-left Mark + (0x02028, 0x0202e,), # Line Separator ..Right-to-left Override + (0x02060, 0x02064,), # Word Joiner ..Invisible Plus + (0x02066, 0x0206f,), # Left-to-right Isolate ..Nominal Digit Shapes (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joiner (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette - (0x0302a, 0x0302d,), # Ideographic Level Tone M..Ideographic Entering Ton + (0x0302a, 0x0302f,), # Ideographic Level Tone M..Hangul Double Dot Tone M (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer @@ -4430,37 +4647,35 @@ ZERO_WIDTH = { (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisvara (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasanta (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusvara - (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a823, 0x0a827,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign (0x0a82c, 0x0a82c,), # Syloti Nagri Sign Alternate Hasanta - (0x0a8c4, 0x0a8c5,), # Saurashtra Sign Virama ..Saurashtra Sign Candrabi + (0x0a880, 0x0a881,), # Saurashtra Sign Anusvara..Saurashtra Sign Visarga + (0x0a8b4, 0x0a8c5,), # Saurashtra Consonant Sig..Saurashtra Sign Candrabi (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig (0x0a8ff, 0x0a8ff,), # Devanagari Vowel Sign Ay (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop - (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R - (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar - (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu - (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku - (0x0a9bc, 0x0a9bd,), # Javanese Vowel Sign Pepe..Javanese Consonant Sign + (0x0a947, 0x0a953,), # Rejang Vowel Sign I ..Rejang Virama + (0x0a980, 0x0a983,), # Javanese Sign Panyangga ..Javanese Sign Wignyan + (0x0a9b3, 0x0a9c0,), # Javanese Sign Cecak Telu..Javanese Pangkon (0x0a9e5, 0x0a9e5,), # Myanmar Sign Shan Saw - (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe - (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue - (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0aa29, 0x0aa36,), # Cham Vowel Sign Aa ..Cham Consonant Sign Wa (0x0aa43, 0x0aa43,), # Cham Consonant Sign Final Ng - (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Final M - (0x0aa7c, 0x0aa7c,), # Myanmar Sign Tai Laing Tone-2 + (0x0aa4c, 0x0aa4d,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa7b, 0x0aa7d,), # Myanmar Sign Pao Karen T..Myanmar Sign Tai Laing T (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho - (0x0aaec, 0x0aaed,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign - (0x0aaf6, 0x0aaf6,), # Meetei Mayek Virama - (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign Anap - (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign Unap - (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek + (0x0aaeb, 0x0aaef,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf5, 0x0aaf6,), # Meetei Mayek Vowel Sign ..Meetei Mayek Virama + (0x0abe3, 0x0abea,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abec, 0x0abed,), # Meetei Mayek Lum Iyek ..Meetei Mayek Apun Iyek (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spanish Varika (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 (0x0fe20, 0x0fe2f,), # Combining Ligature Left ..Combining Cyrillic Titlo + (0x0feff, 0x0feff,), # Zero Width No-break Space + (0x0fff9, 0x0fffb,), # Interlinear Annotation A..Interlinear Annotation T (0x101fd, 0x101fd,), # Phaistos Disc Sign Combining Oblique Stroke (0x102e0, 0x102e0,), # Coptic Epact Thousands Mark (0x10376, 0x1037a,), # Combining Old Permic Let..Combining Old Permic Let @@ -4472,107 +4687,95 @@ ZERO_WIDTH = { (0x10ae5, 0x10ae6,), # Manichaean Abbreviation ..Manichaean Abbreviation (0x10d24, 0x10d27,), # Hanifi Rohingya Sign Har..Hanifi Rohingya Sign Tas (0x10eab, 0x10eac,), # Yezidi Combining Hamza M..Yezidi Combining Madda M - (0x10efd, 0x10eff,), # (nil) + (0x10efd, 0x10eff,), # Arabic Small Low Word Sa..Arabic Small Low Word Ma (0x10f46, 0x10f50,), # Sogdian Combining Dot Be..Sogdian Combining Stroke (0x10f82, 0x10f85,), # Old Uyghur Combining Dot..Old Uyghur Combining Two - (0x11001, 0x11001,), # Brahmi Sign Anusvara + (0x11000, 0x11002,), # Brahmi Sign Candrabindu ..Brahmi Sign Visarga (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama (0x11070, 0x11070,), # Brahmi Sign Old Tamil Virama (0x11073, 0x11074,), # Brahmi Vowel Sign Old Ta..Brahmi Vowel Sign Old Ta - (0x1107f, 0x11081,), # Brahmi Number Joiner ..Kaithi Sign Anusvara - (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai - (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x1107f, 0x11082,), # Brahmi Number Joiner ..Kaithi Sign Visarga + (0x110b0, 0x110ba,), # Kaithi Vowel Sign Aa ..Kaithi Sign Nukta + (0x110bd, 0x110bd,), # Kaithi Number Sign (0x110c2, 0x110c2,), # Kaithi Vowel Sign Vocalic R + (0x110cd, 0x110cd,), # Kaithi Number Sign Above (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga - (0x11127, 0x1112b,), # Chakma Vowel Sign A ..Chakma Vowel Sign Uu - (0x1112d, 0x11134,), # Chakma Vowel Sign Ai ..Chakma Maayyaa + (0x11127, 0x11134,), # Chakma Vowel Sign A ..Chakma Maayyaa + (0x11145, 0x11146,), # Chakma Vowel Sign Aa ..Chakma Vowel Sign Ei (0x11173, 0x11173,), # Mahajani Sign Nukta - (0x11180, 0x11181,), # Sharada Sign Candrabindu..Sharada Sign Anusvara - (0x111b6, 0x111be,), # Sharada Vowel Sign U ..Sharada Vowel Sign O + (0x11180, 0x11182,), # Sharada Sign Candrabindu..Sharada Sign Visarga + (0x111b3, 0x111c0,), # Sharada Vowel Sign Aa ..Sharada Sign Virama (0x111c9, 0x111cc,), # Sharada Sandhi Mark ..Sharada Extra Short Vowe - (0x111cf, 0x111cf,), # Sharada Sign Inverted Candrabindu - (0x1122f, 0x11231,), # Khojki Vowel Sign U ..Khojki Vowel Sign Ai - (0x11234, 0x11234,), # Khojki Sign Anusvara - (0x11236, 0x11237,), # Khojki Sign Nukta ..Khojki Sign Shadda + (0x111ce, 0x111cf,), # Sharada Vowel Sign Prish..Sharada Sign Inverted Ca + (0x1122c, 0x11237,), # Khojki Vowel Sign Aa ..Khojki Sign Shadda (0x1123e, 0x1123e,), # Khojki Sign Sukun - (0x11241, 0x11241,), # (nil) - (0x112df, 0x112df,), # Khudawadi Sign Anusvara - (0x112e3, 0x112ea,), # Khudawadi Vowel Sign U ..Khudawadi Sign Virama - (0x11300, 0x11301,), # Grantha Sign Combining A..Grantha Sign Candrabindu + (0x11241, 0x11241,), # Khojki Vowel Sign Vocalic R + (0x112df, 0x112ea,), # Khudawadi Sign Anusvara ..Khudawadi Sign Virama + (0x11300, 0x11303,), # Grantha Sign Combining A..Grantha Sign Visarga (0x1133b, 0x1133c,), # Combining Bindu Below ..Grantha Sign Nukta - (0x11340, 0x11340,), # Grantha Vowel Sign Ii + (0x1133e, 0x11344,), # Grantha Vowel Sign Aa ..Grantha Vowel Sign Vocal + (0x11347, 0x11348,), # Grantha Vowel Sign Ee ..Grantha Vowel Sign Ai + (0x1134b, 0x1134d,), # Grantha Vowel Sign Oo ..Grantha Sign Virama + (0x11357, 0x11357,), # Grantha Au Length Mark + (0x11362, 0x11363,), # Grantha Vowel Sign Vocal..Grantha Vowel Sign Vocal (0x11366, 0x1136c,), # Combining Grantha Digit ..Combining Grantha Digit (0x11370, 0x11374,), # Combining Grantha Letter..Combining Grantha Letter - (0x11438, 0x1143f,), # Newa Vowel Sign U ..Newa Vowel Sign Ai - (0x11442, 0x11444,), # Newa Sign Virama ..Newa Sign Anusvara - (0x11446, 0x11446,), # Newa Sign Nukta + (0x11435, 0x11446,), # Newa Vowel Sign Aa ..Newa Sign Nukta (0x1145e, 0x1145e,), # Newa Sandhi Mark - (0x114b3, 0x114b8,), # Tirhuta Vowel Sign U ..Tirhuta Vowel Sign Vocal - (0x114ba, 0x114ba,), # Tirhuta Vowel Sign Short E - (0x114bf, 0x114c0,), # Tirhuta Sign Candrabindu..Tirhuta Sign Anusvara - (0x114c2, 0x114c3,), # Tirhuta Sign Virama ..Tirhuta Sign Nukta - (0x115b2, 0x115b5,), # Siddham Vowel Sign U ..Siddham Vowel Sign Vocal - (0x115bc, 0x115bd,), # Siddham Sign Candrabindu..Siddham Sign Anusvara - (0x115bf, 0x115c0,), # Siddham Sign Virama ..Siddham Sign Nukta + (0x114b0, 0x114c3,), # Tirhuta Vowel Sign Aa ..Tirhuta Sign Nukta + (0x115af, 0x115b5,), # Siddham Vowel Sign Aa ..Siddham Vowel Sign Vocal + (0x115b8, 0x115c0,), # Siddham Vowel Sign E ..Siddham Sign Nukta (0x115dc, 0x115dd,), # Siddham Vowel Sign Alter..Siddham Vowel Sign Alter - (0x11633, 0x1163a,), # Modi Vowel Sign U ..Modi Vowel Sign Ai - (0x1163d, 0x1163d,), # Modi Sign Anusvara - (0x1163f, 0x11640,), # Modi Sign Virama ..Modi Sign Ardhacandra - (0x116ab, 0x116ab,), # Takri Sign Anusvara - (0x116ad, 0x116ad,), # Takri Vowel Sign Aa - (0x116b0, 0x116b5,), # Takri Vowel Sign U ..Takri Vowel Sign Au - (0x116b7, 0x116b7,), # Takri Sign Nukta - (0x1171d, 0x1171f,), # Ahom Consonant Sign Medi..Ahom Consonant Sign Medi - (0x11722, 0x11725,), # Ahom Vowel Sign I ..Ahom Vowel Sign Uu - (0x11727, 0x1172b,), # Ahom Vowel Sign Aw ..Ahom Sign Killer - (0x1182f, 0x11837,), # Dogra Vowel Sign U ..Dogra Sign Anusvara - (0x11839, 0x1183a,), # Dogra Sign Virama ..Dogra Sign Nukta - (0x1193b, 0x1193c,), # Dives Akuru Sign Anusvar..Dives Akuru Sign Candrab - (0x1193e, 0x1193e,), # Dives Akuru Virama - (0x11943, 0x11943,), # Dives Akuru Sign Nukta - (0x119d4, 0x119d7,), # Nandinagari Vowel Sign U..Nandinagari Vowel Sign V - (0x119da, 0x119db,), # Nandinagari Vowel Sign E..Nandinagari Vowel Sign A - (0x119e0, 0x119e0,), # Nandinagari Sign Virama + (0x11630, 0x11640,), # Modi Vowel Sign Aa ..Modi Sign Ardhacandra + (0x116ab, 0x116b7,), # Takri Sign Anusvara ..Takri Sign Nukta + (0x1171d, 0x1172b,), # Ahom Consonant Sign Medi..Ahom Sign Killer + (0x1182c, 0x1183a,), # Dogra Vowel Sign Aa ..Dogra Sign Nukta + (0x11930, 0x11935,), # Dives Akuru Vowel Sign A..Dives Akuru Vowel Sign E + (0x11937, 0x11938,), # Dives Akuru Vowel Sign A..Dives Akuru Vowel Sign O + (0x1193b, 0x1193e,), # Dives Akuru Sign Anusvar..Dives Akuru Virama + (0x11940, 0x11940,), # Dives Akuru Medial Ya + (0x11942, 0x11943,), # Dives Akuru Medial Ra ..Dives Akuru Sign Nukta + (0x119d1, 0x119d7,), # Nandinagari Vowel Sign A..Nandinagari Vowel Sign V + (0x119da, 0x119e0,), # Nandinagari Vowel Sign E..Nandinagari Sign Virama + (0x119e4, 0x119e4,), # Nandinagari Vowel Sign Prishthamatra E (0x11a01, 0x11a0a,), # Zanabazar Square Vowel S..Zanabazar Square Vowel L - (0x11a33, 0x11a38,), # Zanabazar Square Final C..Zanabazar Square Sign An + (0x11a33, 0x11a39,), # Zanabazar Square Final C..Zanabazar Square Sign Vi (0x11a3b, 0x11a3e,), # Zanabazar Square Cluster..Zanabazar Square Cluster (0x11a47, 0x11a47,), # Zanabazar Square Subjoiner - (0x11a51, 0x11a56,), # Soyombo Vowel Sign I ..Soyombo Vowel Sign Oe - (0x11a59, 0x11a5b,), # Soyombo Vowel Sign Vocal..Soyombo Vowel Length Mar - (0x11a8a, 0x11a96,), # Soyombo Final Consonant ..Soyombo Sign Anusvara - (0x11a98, 0x11a99,), # Soyombo Gemination Mark ..Soyombo Subjoiner - (0x11c30, 0x11c36,), # Bhaiksuki Vowel Sign I ..Bhaiksuki Vowel Sign Voc - (0x11c38, 0x11c3d,), # Bhaiksuki Vowel Sign E ..Bhaiksuki Sign Anusvara - (0x11c3f, 0x11c3f,), # Bhaiksuki Sign Virama + (0x11a51, 0x11a5b,), # Soyombo Vowel Sign I ..Soyombo Vowel Length Mar + (0x11a8a, 0x11a99,), # Soyombo Final Consonant ..Soyombo Subjoiner + (0x11c2f, 0x11c36,), # Bhaiksuki Vowel Sign Aa ..Bhaiksuki Vowel Sign Voc + (0x11c38, 0x11c3f,), # Bhaiksuki Vowel Sign E ..Bhaiksuki Sign Virama (0x11c92, 0x11ca7,), # Marchen Subjoined Letter..Marchen Subjoined Letter - (0x11caa, 0x11cb0,), # Marchen Subjoined Letter..Marchen Vowel Sign Aa - (0x11cb2, 0x11cb3,), # Marchen Vowel Sign U ..Marchen Vowel Sign E - (0x11cb5, 0x11cb6,), # Marchen Sign Anusvara ..Marchen Sign Candrabindu + (0x11ca9, 0x11cb6,), # Marchen Subjoined Letter..Marchen Sign Candrabindu (0x11d31, 0x11d36,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign (0x11d3a, 0x11d3a,), # Masaram Gondi Vowel Sign E (0x11d3c, 0x11d3d,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign (0x11d3f, 0x11d45,), # Masaram Gondi Vowel Sign..Masaram Gondi Virama (0x11d47, 0x11d47,), # Masaram Gondi Ra-kara + (0x11d8a, 0x11d8e,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Vowel Sign (0x11d90, 0x11d91,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Vowel Sign - (0x11d95, 0x11d95,), # Gunjala Gondi Sign Anusvara - (0x11d97, 0x11d97,), # Gunjala Gondi Virama - (0x11ef3, 0x11ef4,), # Makasar Vowel Sign I ..Makasar Vowel Sign U - (0x11f00, 0x11f01,), # (nil) - (0x11f36, 0x11f3a,), # (nil) - (0x11f40, 0x11f40,), # (nil) - (0x11f42, 0x11f42,), # (nil) - (0x13440, 0x13440,), # (nil) - (0x13447, 0x13455,), # (nil) + (0x11d93, 0x11d97,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Virama + (0x11ef3, 0x11ef6,), # Makasar Vowel Sign I ..Makasar Vowel Sign O + (0x11f00, 0x11f01,), # Kawi Sign Candrabindu ..Kawi Sign Anusvara + (0x11f03, 0x11f03,), # Kawi Sign Visarga + (0x11f34, 0x11f3a,), # Kawi Vowel Sign Aa ..Kawi Vowel Sign Vocalic + (0x11f3e, 0x11f42,), # Kawi Vowel Sign E ..Kawi Conjoiner + (0x13430, 0x13440,), # Egyptian Hieroglyph Vert..Egyptian Hieroglyph Mirr + (0x13447, 0x13455,), # Egyptian Hieroglyph Modi..Egyptian Hieroglyph Modi (0x16af0, 0x16af4,), # Bassa Vah Combining High..Bassa Vah Combining High (0x16b30, 0x16b36,), # Pahawh Hmong Mark Cim Tu..Pahawh Hmong Mark Cim Ta (0x16f4f, 0x16f4f,), # Miao Sign Consonant Modifier Bar + (0x16f51, 0x16f87,), # Miao Sign Aspiration ..Miao Vowel Sign Ui (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below (0x16fe4, 0x16fe4,), # Khitan Small Script Filler + (0x16ff0, 0x16ff1,), # Vietnamese Alternate Rea..Vietnamese Alternate Rea (0x1bc9d, 0x1bc9e,), # Duployan Thick Letter Se..Duployan Double Mark + (0x1bca0, 0x1bca3,), # Shorthand Format Letter ..Shorthand Format Up Step (0x1cf00, 0x1cf2d,), # Znamenny Combining Mark ..Znamenny Combining Mark (0x1cf30, 0x1cf46,), # Znamenny Combining Tonal..Znamenny Priznak Modifie - (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining - (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d165, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d16d, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical @@ -4587,13 +4790,16 @@ ZERO_WIDTH = { (0x1e01b, 0x1e021,), # Combining Glagolitic Let..Combining Glagolitic Let (0x1e023, 0x1e024,), # Combining Glagolitic Let..Combining Glagolitic Let (0x1e026, 0x1e02a,), # Combining Glagolitic Let..Combining Glagolitic Let - (0x1e08f, 0x1e08f,), # (nil) + (0x1e08f, 0x1e08f,), # Combining Cyrillic Small Letter Byelorussian-ukr (0x1e130, 0x1e136,), # Nyiakeng Puachue Hmong T..Nyiakeng Puachue Hmong T (0x1e2ae, 0x1e2ae,), # Toto Sign Rising Tone (0x1e2ec, 0x1e2ef,), # Wancho Tone Tup ..Wancho Tone Koini - (0x1e4ec, 0x1e4ef,), # (nil) + (0x1e4ec, 0x1e4ef,), # Nag Mundari Sign Muhor ..Nag Mundari Sign Sutuh (0x1e8d0, 0x1e8d6,), # Mende Kikakui Combining ..Mende Kikakui Combining (0x1e944, 0x1e94a,), # Adlam Alif Lengthener ..Adlam Nukta + (0x1f3fb, 0x1f3ff,), # Emoji Modifier Fitzpatri..Emoji Modifier Fitzpatri + (0xe0001, 0xe0001,), # Language Tag + (0xe0020, 0xe007f,), # Tag Space ..Cancel Tag (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 ), } diff --git a/contrib/python/wcwidth/py2/wcwidth/unicode_versions.py b/contrib/python/wcwidth/py2/wcwidth/unicode_versions.py index cd33688b2e..4e9ccbf7a7 100644 --- a/contrib/python/wcwidth/py2/wcwidth/unicode_versions.py +++ b/contrib/python/wcwidth/py2/wcwidth/unicode_versions.py @@ -1,7 +1,7 @@ """ Exports function list_versions() for unicode version level support. -This code generated by wcwidth/bin/update-tables.py on 2023-01-14 00:53:07 UTC. +This code generated by wcwidth/bin/update-tables.py on 2023-09-14 15:45:33 UTC. """ @@ -34,4 +34,5 @@ def list_versions(): "13.0.0", "14.0.0", "15.0.0", + "15.1.0", ) diff --git a/contrib/python/wcwidth/py2/wcwidth/wcwidth.py b/contrib/python/wcwidth/py2/wcwidth/wcwidth.py index 6162cddffb..59eb5c0806 100644 --- a/contrib/python/wcwidth/py2/wcwidth/wcwidth.py +++ b/contrib/python/wcwidth/py2/wcwidth/wcwidth.py @@ -68,6 +68,7 @@ import sys import warnings # local +from .table_vs16 import VS16_NARROW_TO_WIDE from .table_wide import WIDE_EASTASIAN from .table_zero import ZERO_WIDTH from .unicode_versions import list_versions @@ -81,34 +82,7 @@ except ImportError: from backports.functools_lru_cache import lru_cache # global cache -_UNICODE_CMPTABLE = None -_PY3 = (sys.version_info[0] >= 3) - - -# NOTE: created by hand, there isn't anything identifiable other than -# general Cf category code to identify these, and some characters in Cf -# category code are of non-zero width. -# Also includes some Cc, Mn, Zl, and Zp characters -ZERO_WIDTH_CF = set([ - 0, # Null (Cc) - 0x034F, # Combining grapheme joiner (Mn) - 0x200B, # Zero width space - 0x200C, # Zero width non-joiner - 0x200D, # Zero width joiner - 0x200E, # Left-to-right mark - 0x200F, # Right-to-left mark - 0x2028, # Line separator (Zl) - 0x2029, # Paragraph separator (Zp) - 0x202A, # Left-to-right embedding - 0x202B, # Right-to-left embedding - 0x202C, # Pop directional formatting - 0x202D, # Left-to-right override - 0x202E, # Right-to-left override - 0x2060, # Word joiner - 0x2061, # Function application - 0x2062, # Invisible times - 0x2063, # Invisible separator -]) +_PY3 = sys.version_info[0] >= 3 def _bisearch(ucs, table): @@ -145,8 +119,8 @@ def wcwidth(wc, unicode_version='auto'): :param str wc: A single Unicode character. :param str unicode_version: A Unicode version number, such as - ``'6.0.0'``, the list of available version levels may be - listed by pairing function :func:`list_versions`. + ``'6.0.0'``. A list of version levels suported by wcwidth + is returned by :func:`list_versions`. Any version string may be specified without error -- the nearest matching version is selected. When ``latest`` (default), the @@ -159,66 +133,27 @@ def wcwidth(wc, unicode_version='auto'): character occupies on a graphic terminal (1 or 2) is returned. :rtype: int - The following have a column width of -1: - - - C0 control characters (U+001 through U+01F). - - - C1 control characters and DEL (U+07F through U+0A0). - - The following have a column width of 0: - - - Non-spacing and enclosing combining characters (general - category code Mn or Me in the Unicode database). - - - NULL (``U+0000``). - - - COMBINING GRAPHEME JOINER (``U+034F``). - - - ZERO WIDTH SPACE (``U+200B``) *through* - RIGHT-TO-LEFT MARK (``U+200F``). - - - LINE SEPARATOR (``U+2028``) *and* - PARAGRAPH SEPARATOR (``U+2029``). - - - LEFT-TO-RIGHT EMBEDDING (``U+202A``) *through* - RIGHT-TO-LEFT OVERRIDE (``U+202E``). - - - WORD JOINER (``U+2060``) *through* - INVISIBLE SEPARATOR (``U+2063``). - - The following have a column width of 1: - - - SOFT HYPHEN (``U+00AD``). - - - All remaining characters, including all printable ISO 8859-1 - and WGL4 characters, Unicode control characters, etc. - - The following have a column width of 2: - - - Spacing characters in the East Asian Wide (W) or East Asian - Full-width (F) category as defined in Unicode Technical - Report #11 have a column width of 2. - - - Some kinds of Emoji or symbols. + See :ref:`Specification` for details of cell measurement. """ - # NOTE: created by hand, there isn't anything identifiable other than - # general Cf category code to identify these, and some characters in Cf - # category code are of non-zero width. - ucs = ord(wc) - if ucs in ZERO_WIDTH_CF: - return 0 + ucs = ord(wc) if wc else 0 + + # small optimization: early return of 1 for printable ASCII, this provides + # approximately 40% performance improvement for mostly-ascii documents, with + # less than 1% impact to others. + if 32 <= ucs < 0x7f: + return 1 - # C0/C1 control characters - if ucs < 32 or 0x07F <= ucs < 0x0A0: + # C0/C1 control characters are -1 for compatibility with POSIX-like calls + if ucs and ucs < 32 or 0x07F <= ucs < 0x0A0: return -1 _unicode_version = _wcmatch_version(unicode_version) - # combining characters with zero width + # Zero width if _bisearch(ucs, ZERO_WIDTH[_unicode_version]): return 0 - # "Wide AastAsian" (and emojis) + # 1 or 2 width return 1 + _bisearch(ucs, WIDE_EASTASIAN[_unicode_version]) @@ -234,21 +169,46 @@ def wcswidth(pwcs, n=None, unicode_version='auto'): the Environment Variable, ``UNICODE_VERSION`` if defined, or the latest available unicode version, otherwise. :rtype: int - :returns: The width, in cells, necessary to display the first ``n`` - characters of the unicode string ``pwcs``. Returns ``-1`` if - a non-printable character is encountered. - """ - # pylint: disable=C0103 - # Invalid argument name "n" + :returns: The width, in cells, needed to display the first ``n`` characters + of the unicode string ``pwcs``. Returns ``-1`` for C0 and C1 control + characters! + See :ref:`Specification` for details of cell measurement. + """ + # this 'n' argument is a holdover for POSIX function + _unicode_version = None end = len(pwcs) if n is None else n - idx = slice(0, end) width = 0 - for char in pwcs[idx]: + idx = 0 + last_measured_char = None + while idx < end: + char = pwcs[idx] + if char == u'\u200D': + # Zero Width Joiner, do not measure this or next character + idx += 2 + continue + if char == u'\uFE0F' and last_measured_char: + # on variation selector 16 (VS16) following another character, + # conditionally add '1' to the measured width if that character is + # known to be converted from narrow to wide by the VS16 character. + if _unicode_version is None: + _unicode_version = _wcversion_value(_wcmatch_version(unicode_version)) + if _unicode_version >= (9, 0, 0): + width += _bisearch(ord(last_measured_char), VS16_NARROW_TO_WIDE["9.0.0"]) + last_measured_char = None + idx += 1 + continue + # measure character at current index wcw = wcwidth(char, unicode_version) if wcw < 0: - return -1 + # early return -1 on C0 and C1 control characters + return wcw + if wcw > 0: + # track last character measured to contain a cell, so that + # subsequent VS-16 modifiers may be understood + last_measured_char = char width += wcw + idx += 1 return width @@ -292,14 +252,18 @@ def _wcmatch_version(given_version): """ # Design note: the choice to return the same type that is given certainly # complicates it for python 2 str-type, but allows us to define an api that - # to use 'string-type', for unicode version level definitions, so all of our - # example code works with all versions of python. That, along with the - # string-to-numeric and comparisons of earliest, latest, matching, or - # nearest, greatly complicates this function. + # uses 'string-type' for unicode version level definitions, so all of our + # example code works with all versions of python. + # + # That, along with the string-to-numeric and comparisons of earliest, + # latest, matching, or nearest, greatly complicates this function. + # Performance is somewhat curbed by memoization. _return_str = not _PY3 and isinstance(given_version, str) if _return_str: - unicode_versions = [ucs.encode() for ucs in list_versions()] + # avoid list-comprehension to work around a coverage issue: + # https://github.com/nedbat/coveragepy/issues/753 + unicode_versions = list(map(lambda ucs: ucs.encode(), list_versions())) else: unicode_versions = list_versions() latest_version = unicode_versions[-1] @@ -375,4 +339,4 @@ def _wcmatch_version(given_version): # is, 4.1 is returned for given 4.9.9, where 4.1 and 5.0 are available. if cmp_next_version > cmp_given: return unicode_version - assert False, ("Code path unreachable", given_version, unicode_versions) + assert False, ("Code path unreachable", given_version, unicode_versions) # pragma: no cover diff --git a/contrib/python/wcwidth/py2/ya.make b/contrib/python/wcwidth/py2/ya.make index fd199c6a95..8453f5ee2f 100644 --- a/contrib/python/wcwidth/py2/ya.make +++ b/contrib/python/wcwidth/py2/ya.make @@ -2,7 +2,7 @@ PY2_LIBRARY() -VERSION(0.2.6) +VERSION(0.2.12) LICENSE(MIT) @@ -15,6 +15,7 @@ NO_LINT() PY_SRCS( TOP_LEVEL wcwidth/__init__.py + wcwidth/table_vs16.py wcwidth/table_wide.py wcwidth/table_zero.py wcwidth/unicode_versions.py diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/config.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/config.hpp index 68d0557fb4..cf7584a790 100644 --- a/contrib/restricted/boost/filesystem/include/boost/filesystem/config.hpp +++ b/contrib/restricted/boost/filesystem/include/boost/filesystem/config.hpp @@ -1,7 +1,7 @@ // boost/filesystem/v3/config.hpp ----------------------------------------------------// // Copyright Beman Dawes 2003 -// Copyright Andrey Semashev 2021 +// Copyright Andrey Semashev 2021-2023 // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt @@ -67,6 +67,15 @@ #error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support #endif +// Deprecated symbols markup -----------------------------------------------------------// + +#if !defined(BOOST_FILESYSTEM_ALLOW_DEPRECATED) +#define BOOST_FILESYSTEM_DETAIL_DEPRECATED(msg) BOOST_DEPRECATED(msg) +#else +#define BOOST_FILESYSTEM_DETAIL_DEPRECATED(msg) +#endif + + // This header implements separate compilation features as described in // http://www.boost.org/more/separate_compilation.html @@ -122,4 +131,22 @@ #include <boost/config/auto_link.hpp> #endif // auto-linking disabled +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) ||\ + (defined(BOOST_LIBSTDCXX_VERSION) && (BOOST_LIBSTDCXX_VERSION < 50000)) ||\ + (defined(BOOST_MSSTL_VERSION) && (BOOST_MSSTL_VERSION < 100)) +// Indicates that the standard library fstream types do not support move constructor/assignment. +#define BOOST_FILESYSTEM_DETAIL_NO_CXX11_MOVABLE_FSTREAMS +#endif + +#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) && \ + (\ + (defined(BOOST_DINKUMWARE_STDLIB) && defined(_HAS_CXX23) && (_HAS_CXX23 != 0) && defined(_MSVC_STL_UPDATE) && (_MSVC_STL_UPDATE < 202208L)) || \ + (defined(BOOST_LIBSTDCXX_VERSION) && (BOOST_LIBSTDCXX_VERSION < 110400 || (BOOST_LIBSTDCXX_VERSION >= 120000 && BOOST_LIBSTDCXX_VERSION < 120200)) && (BOOST_CXX_VERSION > 202002L))\ + ) +// Indicates that std::string_view has implicit constructor from ranges that was present in an early C++23 draft (N4892). +// This was later rectified by marking the constructor explicit (https://wg21.link/p2499). Unfortunately, some compilers +// were released with the constructor being implicit. +#define BOOST_FILESYSTEM_DETAIL_CXX23_STRING_VIEW_HAS_IMPLICIT_RANGE_CTOR +#endif + #endif // BOOST_FILESYSTEM_CONFIG_HPP diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/header.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/header.hpp index 10f49a658e..f98b0aba95 100644 --- a/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/header.hpp +++ b/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/header.hpp @@ -28,6 +28,10 @@ #pragma warning(disable: 4503) // 'X': This function or variable may be unsafe. Consider using Y instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. #pragma warning(disable: 4996) +// qualifier applied to function type has no meaning; ignored +#pragma warning(disable: 4180) +// qualifier applied to reference type; ignored +#pragma warning(disable: 4181) #elif (defined(__GNUC__) && !(defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)) \ && (__GNUC__ * 100 + __GNUC_MINOR__) >= 406) || defined(__clang__) @@ -40,6 +44,11 @@ // unused function 'foo' #pragma GCC diagnostic ignored "-Wunused-function" +#if defined(__clang__) +// template argument uses unnamed type +#pragma clang diagnostic ignored "-Wunnamed-type-template-args" +#endif // defined(__clang__) + #endif #endif // !defined(BOOST_FILESYSTEM_ENABLE_WARNINGS) diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/path_traits.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/path_traits.hpp new file mode 100644 index 0000000000..562b96764e --- /dev/null +++ b/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/path_traits.hpp @@ -0,0 +1,737 @@ +// filesystem path_traits.hpp --------------------------------------------------------// + +// Copyright Beman Dawes 2009 +// Copyright Andrey Semashev 2022 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +#ifndef BOOST_FILESYSTEM_DETAIL_PATH_TRAITS_HPP +#define BOOST_FILESYSTEM_DETAIL_PATH_TRAITS_HPP + +#include <boost/filesystem/config.hpp> +#include <cstddef> +#include <cstring> // for strlen +#include <cwchar> // for mbstate_t, wcslen +#include <locale> +#include <string> +#include <iterator> +#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) +#include <string_view> +#endif +#include <boost/assert.hpp> +#include <boost/system/error_category.hpp> +#include <boost/iterator/is_iterator.hpp> +#include <boost/type_traits/declval.hpp> +#include <boost/type_traits/remove_cv.hpp> +#include <boost/type_traits/integral_constant.hpp> +#include <boost/type_traits/conjunction.hpp> +#if defined(BOOST_FILESYSTEM_DETAIL_CXX23_STRING_VIEW_HAS_IMPLICIT_RANGE_CTOR) +#include <boost/type_traits/disjunction.hpp> +#include <boost/core/enable_if.hpp> +#endif +#if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) && BOOST_FILESYSTEM_VERSION < 4 +#include <vector> +#include <list> +#endif + +#include <boost/filesystem/detail/header.hpp> // must be the last #include + +namespace boost { + +template< typename, typename > class basic_string_view; + +namespace container { +template< typename, typename, typename > class basic_string; +} // namespace container + +namespace filesystem { + +BOOST_FILESYSTEM_DECL system::error_category const& codecvt_error_category() BOOST_NOEXCEPT; + +class directory_entry; + +namespace detail { +namespace path_traits { + +#if defined(BOOST_WINDOWS_API) +typedef wchar_t path_native_char_type; +#define BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE false +#define BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE true +#else +typedef char path_native_char_type; +#define BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE true +#define BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE false +#endif + +typedef std::codecvt< wchar_t, char, std::mbstate_t > codecvt_type; + +struct unknown_type_tag {}; +struct ntcts_type_tag {}; +struct char_ptr_tag : ntcts_type_tag {}; +struct char_array_tag : ntcts_type_tag {}; +struct string_class_tag {}; +struct std_string_tag : string_class_tag {}; +struct boost_container_string_tag : string_class_tag {}; +struct std_string_view_tag : string_class_tag {}; +struct boost_string_view_tag : string_class_tag {}; +struct range_type_tag {}; +struct directory_entry_tag {}; + +//! The traits define a number of properties of a path source +template< typename T > +struct path_source_traits +{ + //! The kind of the path source. Useful for dispatching. + typedef unknown_type_tag tag_type; + //! Character type that the source contains + typedef void char_type; + //! Indicates whether the source is natively supported by \c path::string_type as arguments for constructors/assignment/appending + static BOOST_CONSTEXPR_OR_CONST bool is_native = false; +}; + +template< > +struct path_source_traits< char* > +{ + typedef char_ptr_tag tag_type; + typedef char char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE; +}; + +template< > +struct path_source_traits< const char* > +{ + typedef char_ptr_tag tag_type; + typedef char char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE; +}; + +template< > +struct path_source_traits< wchar_t* > +{ + typedef char_ptr_tag tag_type; + typedef wchar_t char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE; +}; + +template< > +struct path_source_traits< const wchar_t* > +{ + typedef char_ptr_tag tag_type; + typedef wchar_t char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE; +}; + +template< > +struct path_source_traits< char[] > +{ + typedef char_array_tag tag_type; + typedef char char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE; +}; + +template< > +struct path_source_traits< const char[] > +{ + typedef char_array_tag tag_type; + typedef char char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE; +}; + +template< > +struct path_source_traits< wchar_t[] > +{ + typedef char_array_tag tag_type; + typedef wchar_t char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE; +}; + +template< > +struct path_source_traits< const wchar_t[] > +{ + typedef char_array_tag tag_type; + typedef wchar_t char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE; +}; + +template< std::size_t N > +struct path_source_traits< char[N] > +{ + typedef char_array_tag tag_type; + typedef char char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE; +}; + +template< std::size_t N > +struct path_source_traits< const char[N] > +{ + typedef char_array_tag tag_type; + typedef char char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE; +}; + +template< std::size_t N > +struct path_source_traits< wchar_t[N] > +{ + typedef char_array_tag tag_type; + typedef wchar_t char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE; +}; + +template< std::size_t N > +struct path_source_traits< const wchar_t[N] > +{ + typedef char_array_tag tag_type; + typedef wchar_t char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE; +}; + +template< > +struct path_source_traits< std::string > +{ + typedef std_string_tag tag_type; + typedef char char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE; +}; + +template< > +struct path_source_traits< std::wstring > +{ + typedef std_string_tag tag_type; + typedef wchar_t char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE; +}; + +template< > +struct path_source_traits< boost::container::basic_string< char, std::char_traits< char >, void > > +{ + typedef boost_container_string_tag tag_type; + typedef char char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = false; +}; + +template< > +struct path_source_traits< boost::container::basic_string< wchar_t, std::char_traits< wchar_t >, void > > +{ + typedef boost_container_string_tag tag_type; + typedef wchar_t char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = false; +}; + +#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) + +template< > +struct path_source_traits< std::string_view > +{ + typedef std_string_view_tag tag_type; + typedef char char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE; +}; + +template< > +struct path_source_traits< std::wstring_view > +{ + typedef std_string_view_tag tag_type; + typedef wchar_t char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE; +}; + +#endif // !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) + +template< > +struct path_source_traits< boost::basic_string_view< char, std::char_traits< char > > > +{ + typedef boost_string_view_tag tag_type; + typedef char char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = false; +}; + +template< > +struct path_source_traits< boost::basic_string_view< wchar_t, std::char_traits< wchar_t > > > +{ + typedef boost_string_view_tag tag_type; + typedef wchar_t char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = false; +}; + +#if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) && BOOST_FILESYSTEM_VERSION < 4 +template< > +struct +BOOST_FILESYSTEM_DETAIL_DEPRECATED("Boost.Filesystem path construction/assignment/appending from containers is deprecated, use strings or iterators instead.") +path_source_traits< std::vector< char > > +{ + // Since C++11 this could be string_class_tag as std::vector gained data() member + typedef range_type_tag tag_type; + typedef char char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = false; +}; + +template< > +struct +BOOST_FILESYSTEM_DETAIL_DEPRECATED("Boost.Filesystem path construction/assignment/appending from containers is deprecated, use strings or iterators instead.") +path_source_traits< std::vector< wchar_t > > +{ + // Since C++11 this could be string_class_tag as std::vector gained data() member + typedef range_type_tag tag_type; + typedef wchar_t char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = false; +}; + +template< > +struct +BOOST_FILESYSTEM_DETAIL_DEPRECATED("Boost.Filesystem path construction/assignment/appending from containers is deprecated, use strings or iterators instead.") +path_source_traits< std::list< char > > +{ + typedef range_type_tag tag_type; + typedef char char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = false; +}; + +template< > +struct +BOOST_FILESYSTEM_DETAIL_DEPRECATED("Boost.Filesystem path construction/assignment/appending from containers is deprecated, use strings or iterators instead.") +path_source_traits< std::list< wchar_t > > +{ + typedef range_type_tag tag_type; + typedef wchar_t char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = false; +}; +#endif // !defined(BOOST_FILESYSTEM_NO_DEPRECATED) && BOOST_FILESYSTEM_VERSION < 4 + +template< > +struct path_source_traits< directory_entry > +{ + typedef directory_entry_tag tag_type; + typedef path_native_char_type char_type; + static BOOST_CONSTEXPR_OR_CONST bool is_native = false; +}; + +#undef BOOST_FILESYSTEM_DETAIL_IS_CHAR_NATIVE +#undef BOOST_FILESYSTEM_DETAIL_IS_WCHAR_T_NATIVE + + +//! The trait tests if the type is a known path Source tag +template< typename Tag > +struct is_known_path_source_tag : + public boost::true_type +{ +}; + +template< > +struct is_known_path_source_tag< unknown_type_tag > : + public boost::false_type +{ +}; + +//! The trait tests if the type is compatible with path Source requirements +template< typename T > +struct is_path_source : + public is_known_path_source_tag< typename path_source_traits< T >::tag_type >::type +{ +}; + + +//! The trait indicates whether the type is a path Source that is natively supported by path::string_type as the source for construction/assignment/appending +template< typename T > +struct is_native_path_source : + public boost::integral_constant< bool, path_source_traits< T >::is_native > +{ +}; + + +//! The trait indicates whether the type is one of the supported path character types +template< typename T > +struct is_path_char_type : + public boost::false_type +{ +}; + +template< > +struct is_path_char_type< char > : + public boost::true_type +{ +}; + +template< > +struct is_path_char_type< wchar_t > : + public boost::true_type +{ +}; + + +template< typename Iterator > +struct is_iterator_to_path_chars : + public is_path_char_type< typename std::iterator_traits< Iterator >::value_type >::type +{ +}; + +//! The trait indicates whether the type is an iterator over a sequence of path characters +template< typename Iterator > +struct is_path_source_iterator : + public boost::conjunction< + boost::iterators::is_iterator< Iterator >, + is_iterator_to_path_chars< Iterator > + >::type +{ +}; + + +//! The trait indicates whether the type is a pointer to a sequence of native path characters +template< typename T > +struct is_native_char_ptr : + public boost::false_type +{ +}; + +template< > +struct is_native_char_ptr< path_native_char_type* > : + public boost::true_type +{ +}; + +template< > +struct is_native_char_ptr< const path_native_char_type* > : + public boost::true_type +{ +}; + + +//! Converts character encoding using the supplied codecvt facet. If \a cvt is \c NULL then \c path::codecvt() will be used. +BOOST_FILESYSTEM_DECL +void convert(const char* from, const char* from_end, std::wstring& to, const codecvt_type* cvt = NULL); + +//! \overload convert +BOOST_FILESYSTEM_DECL +void convert(const wchar_t* from, const wchar_t* from_end, std::string& to, const codecvt_type* cvt = NULL); + + +// Source dispatch -----------------------------------------------------------------// + +template< typename Source, typename Callback > +typename Callback::result_type dispatch(Source const& source, Callback cb, const codecvt_type* cvt = NULL); + +template< typename Callback > +BOOST_FORCEINLINE typename Callback::result_type dispatch(const char* source, Callback cb, const codecvt_type* cvt, ntcts_type_tag) +{ + return cb(source, source + std::strlen(source), cvt); +} + +template< typename Callback > +BOOST_FORCEINLINE typename Callback::result_type dispatch(const wchar_t* source, Callback cb, const codecvt_type* cvt, ntcts_type_tag) +{ + return cb(source, source + std::wcslen(source), cvt); +} + +template< typename Source, typename Callback > +BOOST_FORCEINLINE typename Callback::result_type dispatch(Source const& source, Callback cb, const codecvt_type* cvt, string_class_tag) +{ + return cb(source.data(), source.data() + source.size(), cvt); +} + +template< typename Source, typename Callback > +BOOST_FORCEINLINE typename Callback::result_type dispatch(Source const& source, Callback cb, const codecvt_type* cvt, range_type_tag) +{ + std::basic_string< typename Source::value_type > src(source.begin(), source.end()); + return cb(src.data(), src.data() + src.size(), cvt); +} + +#if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) && BOOST_FILESYSTEM_VERSION < 4 + +template< typename Callback > +BOOST_FORCEINLINE typename Callback::result_type dispatch(std::vector< char > const& source, Callback cb, const codecvt_type* cvt, range_type_tag) +{ + const char* data = NULL, *data_end = NULL; + if (!source.empty()) + { + data = &source[0]; + data_end = data + source.size(); + } + return cb(data, data_end, cvt); +} + +template< typename Callback > +BOOST_FORCEINLINE typename Callback::result_type dispatch(std::vector< wchar_t > const& source, Callback cb, const codecvt_type* cvt, range_type_tag) +{ + const wchar_t* data = NULL, *data_end = NULL; + if (!source.empty()) + { + data = &source[0]; + data_end = data + source.size(); + } + return cb(data, data_end, cvt); +} + +#endif // !defined(BOOST_FILESYSTEM_NO_DEPRECATED) && BOOST_FILESYSTEM_VERSION < 4 + +// Defined in directory.hpp to avoid circular header dependencies +template< typename Callback > +typename Callback::result_type dispatch(directory_entry const& de, Callback cb, const codecvt_type* cvt, directory_entry_tag); + +template< typename Source, typename Callback > +BOOST_FORCEINLINE typename Callback::result_type dispatch(Source const& source, Callback cb, const codecvt_type* cvt) +{ + return path_traits::dispatch(source, cb, cvt, + typename path_traits::path_source_traits< typename boost::remove_cv< Source >::type >::tag_type()); +} + + +typedef char yes_type; +struct no_type { char buf[2]; }; + +#if !defined(BOOST_FILESYSTEM_DETAIL_CXX23_STRING_VIEW_HAS_IMPLICIT_RANGE_CTOR) + +namespace is_convertible_to_path_source_impl { + +yes_type check(const char*); +yes_type check(const wchar_t*); +yes_type check(std::string const&); +yes_type check(std::wstring const&); +yes_type check(boost::container::basic_string< char, std::char_traits< char >, void > const&); +yes_type check(boost::container::basic_string< wchar_t, std::char_traits< wchar_t >, void > const&); +#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) +yes_type check(std::string_view const&); +yes_type check(std::wstring_view const&); +#endif +yes_type check(boost::basic_string_view< char, std::char_traits< char > > const&); +yes_type check(boost::basic_string_view< wchar_t, std::char_traits< wchar_t > > const&); +#if !defined(BOOST_NO_CXX11_NULLPTR) +no_type check(std::nullptr_t); +#endif +no_type check(...); + +} // namespace is_convertible_to_path_source_impl + +//! The type trait indicates whether the type has a conversion path to one of the path source types +template< typename T > +struct is_convertible_to_path_source : + public boost::integral_constant< + bool, + sizeof(is_convertible_to_path_source_impl::check(boost::declval< T const& >())) == sizeof(yes_type) + > +{ +}; + +#else // !defined(BOOST_FILESYSTEM_DETAIL_CXX23_STRING_VIEW_HAS_IMPLICIT_RANGE_CTOR) + +// Note: We use separate checks for convertibility to std::string_view and other types to avoid ambiguity with an implicit range constructor +// of std::string_view in the early C++23 draft (N4892). If a user's type is convertible to e.g. std::string and also satisfies +// ranges::contiguous_range and ranges::sized_range concepts then the conversion is ambiguous: the type is convertible to std::string +// through the conversion operator in the user's class and is also convertible to std::string_view through the implicit conversion +// constructor in std::string_view. The solution is to check convertibility to std::string_view separately first. + +namespace is_convertible_to_std_string_view_impl { + +yes_type check(std::string_view const&); +yes_type check(std::wstring_view const&); +#if !defined(BOOST_NO_CXX11_NULLPTR) +no_type check(std::nullptr_t); +#endif +no_type check(...); + +} // namespace is_convertible_to_std_string_view_impl + +template< typename T > +struct is_convertible_to_std_string_view : + public boost::integral_constant< + bool, + sizeof(is_convertible_to_std_string_view_impl::check(boost::declval< T const& >())) == sizeof(yes_type) + > +{ +}; + +namespace is_convertible_to_path_source_non_std_string_view_impl { + +yes_type check(const char*); +yes_type check(const wchar_t*); +yes_type check(std::string const&); +yes_type check(std::wstring const&); +yes_type check(boost::container::basic_string< char, std::char_traits< char >, void > const&); +yes_type check(boost::container::basic_string< wchar_t, std::char_traits< wchar_t >, void > const&); +yes_type check(boost::basic_string_view< char, std::char_traits< char > > const&); +yes_type check(boost::basic_string_view< wchar_t, std::char_traits< wchar_t > > const&); +#if !defined(BOOST_NO_CXX11_NULLPTR) +no_type check(std::nullptr_t); +#endif +no_type check(...); + +} // namespace is_convertible_to_path_source_non_std_string_view_impl + +template< typename T > +struct is_convertible_to_path_source_non_std_string_view : + public boost::integral_constant< + bool, + sizeof(is_convertible_to_path_source_non_std_string_view_impl::check(boost::declval< T const& >())) == sizeof(yes_type) + > +{ +}; + +//! The type trait indicates whether the type has a conversion path to one of the path source types +template< typename T > +struct is_convertible_to_path_source : + public boost::disjunction< + is_convertible_to_std_string_view< T >, + is_convertible_to_path_source_non_std_string_view< T > + >::type +{ +}; + +#endif // !defined(BOOST_FILESYSTEM_DETAIL_CXX23_STRING_VIEW_HAS_IMPLICIT_RANGE_CTOR) + +//! The type trait makes \a T dependent on the second template argument. Used to delay type resolution and name binding. +template< typename T, typename > +struct make_dependent +{ + typedef T type; +}; + +template< typename Source, typename Callback > +BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(const char* source, Callback cb, const codecvt_type* cvt) +{ + typedef typename path_traits::make_dependent< const char*, Source >::type source_t; + return path_traits::dispatch(static_cast< source_t >(source), cb, cvt); +} + +template< typename Source, typename Callback > +BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(const wchar_t* source, Callback cb, const codecvt_type* cvt) +{ + typedef typename path_traits::make_dependent< const wchar_t*, Source >::type source_t; + return path_traits::dispatch(static_cast< source_t >(source), cb, cvt); +} + +template< typename Source, typename Callback > +BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(std::string const& source, Callback cb, const codecvt_type* cvt) +{ + typedef typename path_traits::make_dependent< std::string, Source >::type source_t; + return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt); +} + +template< typename Source, typename Callback > +BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(std::wstring const& source, Callback cb, const codecvt_type* cvt) +{ + typedef typename path_traits::make_dependent< std::wstring, Source >::type source_t; + return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt); +} + +template< typename Source, typename Callback > +BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl +( + boost::container::basic_string< char, std::char_traits< char >, void > const& source, + Callback cb, + const codecvt_type* cvt +) +{ + typedef typename path_traits::make_dependent< boost::container::basic_string< char, std::char_traits< char >, void >, Source >::type source_t; + return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt); +} + +template< typename Source, typename Callback > +BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl +( + boost::container::basic_string< wchar_t, std::char_traits< wchar_t >, void > const& source, + Callback cb, + const codecvt_type* cvt +) +{ + typedef typename path_traits::make_dependent< boost::container::basic_string< wchar_t, std::char_traits< wchar_t >, void >, Source >::type source_t; + return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt); +} + +template< typename Source, typename Callback > +BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl +( + boost::basic_string_view< char, std::char_traits< char > > const& source, + Callback cb, + const codecvt_type* cvt +) +{ + typedef typename path_traits::make_dependent< boost::basic_string_view< char, std::char_traits< char > >, Source >::type source_t; + return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt); +} + +template< typename Source, typename Callback > +BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl +( + boost::basic_string_view< wchar_t, std::char_traits< wchar_t > > const& source, + Callback cb, + const codecvt_type* cvt +) +{ + typedef typename path_traits::make_dependent< boost::basic_string_view< wchar_t, std::char_traits< wchar_t > >, Source >::type source_t; + return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt); +} + +#if !defined(BOOST_FILESYSTEM_DETAIL_CXX23_STRING_VIEW_HAS_IMPLICIT_RANGE_CTOR) + +#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) + +template< typename Source, typename Callback > +BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(std::string_view const& source, Callback cb, const codecvt_type* cvt) +{ + typedef typename path_traits::make_dependent< std::string_view, Source >::type source_t; + return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt); +} + +template< typename Source, typename Callback > +BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(std::wstring_view const& source, Callback cb, const codecvt_type* cvt) +{ + typedef typename path_traits::make_dependent< std::wstring_view, Source >::type source_t; + return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt); +} + +#endif // !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) + +template< typename Source, typename Callback > +BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible(Source const& source, Callback cb, const codecvt_type* cvt = NULL) +{ + typedef typename boost::remove_cv< Source >::type source_t; + return path_traits::dispatch_convertible_impl< source_t >(source, cb, cvt); +} + +#else // !defined(BOOST_FILESYSTEM_DETAIL_CXX23_STRING_VIEW_HAS_IMPLICIT_RANGE_CTOR) + +template< typename Source, typename Callback > +BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_sv_impl(std::string_view const& source, Callback cb, const codecvt_type* cvt) +{ + typedef typename path_traits::make_dependent< std::string_view, Source >::type source_t; + return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt); +} + +template< typename Source, typename Callback > +BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_sv_impl(std::wstring_view const& source, Callback cb, const codecvt_type* cvt) +{ + typedef typename path_traits::make_dependent< std::wstring_view, Source >::type source_t; + return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt); +} + +template< typename Source, typename Callback > +BOOST_FORCEINLINE typename boost::disable_if_c< + is_convertible_to_std_string_view< typename boost::remove_cv< Source >::type >::value, + typename Callback::result_type +>::type dispatch_convertible(Source const& source, Callback cb, const codecvt_type* cvt = NULL) +{ + typedef typename boost::remove_cv< Source >::type source_t; + return path_traits::dispatch_convertible_impl< source_t >(source, cb, cvt); +} + +template< typename Source, typename Callback > +BOOST_FORCEINLINE typename boost::enable_if_c< + is_convertible_to_std_string_view< typename boost::remove_cv< Source >::type >::value, + typename Callback::result_type +>::type dispatch_convertible(Source const& source, Callback cb, const codecvt_type* cvt = NULL) +{ + typedef typename boost::remove_cv< Source >::type source_t; + return path_traits::dispatch_convertible_sv_impl< source_t >(source, cb, cvt); +} + +#endif // !defined(BOOST_FILESYSTEM_DETAIL_CXX23_STRING_VIEW_HAS_IMPLICIT_RANGE_CTOR) + +} // namespace path_traits +} // namespace detail +} // namespace filesystem +} // namespace boost + +#include <boost/filesystem/detail/footer.hpp> + +#endif // BOOST_FILESYSTEM_DETAIL_PATH_TRAITS_HPP diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/directory.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/directory.hpp index 68b13638e1..2afcfb6735 100644 --- a/contrib/restricted/boost/filesystem/include/boost/filesystem/directory.hpp +++ b/contrib/restricted/boost/filesystem/include/boost/filesystem/directory.hpp @@ -4,7 +4,7 @@ // Copyright Jan Langer 2002 // Copyright Dietmar Kuehl 2001 // Copyright Vladimir Prus 2002 -// Copyright Andrey Semashev 2019 +// Copyright Andrey Semashev 2019, 2022 // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt @@ -19,11 +19,11 @@ #include <boost/filesystem/config.hpp> #include <boost/filesystem/path.hpp> #include <boost/filesystem/file_status.hpp> +#include <boost/filesystem/detail/path_traits.hpp> #include <cstddef> #include <string> #include <vector> -#include <utility> // std::move #include <boost/assert.hpp> #include <boost/core/scoped_enum.hpp> @@ -41,6 +41,17 @@ namespace boost { namespace filesystem { +class directory_iterator; + +namespace detail { + +struct directory_iterator_params; + +BOOST_FILESYSTEM_DECL void directory_iterator_construct(directory_iterator& it, path const& p, unsigned int opts, directory_iterator_params* params, system::error_code* ec); +BOOST_FILESYSTEM_DECL void directory_iterator_increment(directory_iterator& it, system::error_code* ec); + +} // namespace detail + //--------------------------------------------------------------------------------------// // // // directory_entry // @@ -53,20 +64,30 @@ namespace filesystem { class directory_entry { + friend BOOST_FILESYSTEM_DECL void detail::directory_iterator_construct(directory_iterator& it, path const& p, unsigned int opts, detail::directory_iterator_params* params, system::error_code* ec); + friend BOOST_FILESYSTEM_DECL void detail::directory_iterator_increment(directory_iterator& it, system::error_code* ec); + public: typedef boost::filesystem::path::value_type value_type; // enables class path ctor taking directory_entry directory_entry() BOOST_NOEXCEPT {} - explicit directory_entry(boost::filesystem::path const& p) : - m_path(p), m_status(file_status()), m_symlink_status(file_status()) + explicit directory_entry(boost::filesystem::path const& p); + +#if BOOST_FILESYSTEM_VERSION >= 4 + directory_entry(boost::filesystem::path const& p, system::error_code& ec) : + m_path(p) { + refresh_impl(&ec); + if (ec) + m_path.clear(); } - +#else directory_entry(boost::filesystem::path const& p, file_status st, file_status symlink_st = file_status()) : m_path(p), m_status(st), m_symlink_status(symlink_st) { } +#endif directory_entry(directory_entry const& rhs) : m_path(rhs.m_path), m_status(rhs.m_status), m_symlink_status(rhs.m_symlink_status) @@ -87,69 +108,349 @@ public: #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) directory_entry(directory_entry&& rhs) BOOST_NOEXCEPT : - m_path(std::move(rhs.m_path)), - m_status(std::move(rhs.m_status)), - m_symlink_status(std::move(rhs.m_symlink_status)) + m_path(static_cast< boost::filesystem::path&& >(rhs.m_path)), + m_status(static_cast< file_status&& >(rhs.m_status)), + m_symlink_status(static_cast< file_status&& >(rhs.m_symlink_status)) { } directory_entry& operator=(directory_entry&& rhs) BOOST_NOEXCEPT { - m_path = std::move(rhs.m_path); - m_status = std::move(rhs.m_status); - m_symlink_status = std::move(rhs.m_symlink_status); + m_path = static_cast< boost::filesystem::path&& >(rhs.m_path); + m_status = static_cast< file_status&& >(rhs.m_status); + m_symlink_status = static_cast< file_status&& >(rhs.m_symlink_status); return *this; } + + void assign(boost::filesystem::path&& p); + +#if BOOST_FILESYSTEM_VERSION >= 4 + void assign(boost::filesystem::path&& p, system::error_code& ec) + { + m_path = static_cast< boost::filesystem::path&& >(p); + refresh_impl(&ec); + } +#else + void assign(boost::filesystem::path&& p, file_status st, file_status symlink_st = file_status()) + { + assign_with_status(static_cast< boost::filesystem::path&& >(p), st, symlink_st); + } #endif +#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - void assign(boost::filesystem::path const& p, file_status st = file_status(), file_status symlink_st = file_status()) + void assign(boost::filesystem::path const& p); + +#if BOOST_FILESYSTEM_VERSION >= 4 + void assign(boost::filesystem::path const& p, system::error_code& ec) { m_path = p; - m_status = st; - m_symlink_status = symlink_st; + refresh_impl(&ec); + } +#else + void assign(boost::filesystem::path const& p, file_status st, file_status symlink_st = file_status()) + { + assign_with_status(p, st, symlink_st); } +#endif + + void replace_filename(boost::filesystem::path const& p); - void replace_filename(boost::filesystem::path const& p, file_status st = file_status(), file_status symlink_st = file_status()) +#if BOOST_FILESYSTEM_VERSION >= 4 + void replace_filename(boost::filesystem::path const& p, system::error_code& ec) { - m_path.remove_filename(); - m_path /= p; - m_status = st; - m_symlink_status = symlink_st; + m_path.replace_filename(p); + refresh_impl(&ec); + } +#else + void replace_filename(boost::filesystem::path const& p, file_status st, file_status symlink_st = file_status()) + { + replace_filename_with_status(p, st, symlink_st); } -#ifndef BOOST_FILESYSTEM_NO_DEPRECATED + BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use directory_entry::replace_filename() instead") void replace_leaf(boost::filesystem::path const& p, file_status st, file_status symlink_st) { - replace_filename(p, st, symlink_st); + replace_filename_with_status(p, st, symlink_st); } #endif - boost::filesystem::path const& path() const BOOST_NOEXCEPT + boost::filesystem::path const& path() const BOOST_NOEXCEPT { return m_path; } + operator boost::filesystem::path const&() const BOOST_NOEXCEPT { return m_path; } + + void refresh() { refresh_impl(); } + void refresh(system::error_code& ec) BOOST_NOEXCEPT { refresh_impl(&ec); } + + file_status status() const { - return m_path; + if (!filesystem::status_known(m_status)) + refresh_impl(); + return m_status; + } + + file_status status(system::error_code& ec) const BOOST_NOEXCEPT + { + if (!filesystem::status_known(m_status)) + refresh_impl(&ec); + return m_status; + } + + file_status symlink_status() const + { + if (!filesystem::status_known(m_symlink_status)) + refresh_impl(); + return m_symlink_status; + } + + file_status symlink_status(system::error_code& ec) const BOOST_NOEXCEPT + { + if (!filesystem::status_known(m_symlink_status)) + refresh_impl(&ec); + return m_symlink_status; + } + + filesystem::file_type file_type() const + { + if (!filesystem::type_present(m_status)) + refresh_impl(); + return m_status.type(); + } + + filesystem::file_type file_type(system::error_code& ec) const BOOST_NOEXCEPT + { + if (!filesystem::type_present(m_status)) + refresh_impl(&ec); + return m_status.type(); + } + + filesystem::file_type symlink_file_type() const + { + if (!filesystem::type_present(m_symlink_status)) + refresh_impl(); + return m_symlink_status.type(); + } + + filesystem::file_type symlink_file_type(system::error_code& ec) const BOOST_NOEXCEPT + { + if (!filesystem::type_present(m_symlink_status)) + refresh_impl(&ec); + return m_symlink_status.type(); + } + + bool exists() const + { + filesystem::file_type ft = this->file_type(); + return ft != filesystem::status_error && ft != filesystem::file_not_found; + } + + bool exists(system::error_code& ec) const BOOST_NOEXCEPT + { + filesystem::file_type ft = this->file_type(ec); + return ft != filesystem::status_error && ft != filesystem::file_not_found; + } + + bool is_regular_file() const + { + return this->file_type() == filesystem::regular_file; + } + + bool is_regular_file(system::error_code& ec) const BOOST_NOEXCEPT + { + return this->file_type(ec) == filesystem::regular_file; + } + + bool is_directory() const + { + return this->file_type() == filesystem::directory_file; + } + + bool is_directory(system::error_code& ec) const BOOST_NOEXCEPT + { + return this->file_type(ec) == filesystem::directory_file; + } + + bool is_symlink() const + { + return this->symlink_file_type() == filesystem::symlink_file; + } + + bool is_symlink(system::error_code& ec) const BOOST_NOEXCEPT + { + return this->symlink_file_type(ec) == filesystem::symlink_file; } - operator boost::filesystem::path const&() const BOOST_NOEXCEPT { return m_path; } - file_status status() const { return get_status(); } - file_status status(system::error_code& ec) const BOOST_NOEXCEPT { return get_status(&ec); } - file_status symlink_status() const { return get_symlink_status(); } - file_status symlink_status(system::error_code& ec) const BOOST_NOEXCEPT { return get_symlink_status(&ec); } - - bool operator==(directory_entry const& rhs) const BOOST_NOEXCEPT { return m_path == rhs.m_path; } - bool operator!=(directory_entry const& rhs) const BOOST_NOEXCEPT { return m_path != rhs.m_path; } - bool operator<(directory_entry const& rhs) const BOOST_NOEXCEPT { return m_path < rhs.m_path; } - bool operator<=(directory_entry const& rhs) const BOOST_NOEXCEPT { return m_path <= rhs.m_path; } - bool operator>(directory_entry const& rhs) const BOOST_NOEXCEPT { return m_path > rhs.m_path; } - bool operator>=(directory_entry const& rhs) const BOOST_NOEXCEPT { return m_path >= rhs.m_path; } + + bool is_block_file() const + { + return this->file_type() == filesystem::block_file; + } + + bool is_block_file(system::error_code& ec) const BOOST_NOEXCEPT + { + return this->file_type(ec) == filesystem::block_file; + } + + bool is_character_file() const + { + return this->file_type() == filesystem::character_file; + } + + bool is_character_file(system::error_code& ec) const BOOST_NOEXCEPT + { + return this->file_type(ec) == filesystem::character_file; + } + + bool is_fifo() const + { + return this->file_type() == filesystem::fifo_file; + } + + bool is_fifo(system::error_code& ec) const BOOST_NOEXCEPT + { + return this->file_type(ec) == filesystem::fifo_file; + } + + bool is_socket() const + { + return this->file_type() == filesystem::socket_file; + } + + bool is_socket(system::error_code& ec) const BOOST_NOEXCEPT + { + return this->file_type(ec) == filesystem::socket_file; + } + + bool is_reparse_file() const + { + return this->symlink_file_type() == filesystem::reparse_file; + } + + bool is_reparse_file(system::error_code& ec) const BOOST_NOEXCEPT + { + return this->symlink_file_type(ec) == filesystem::reparse_file; + } + + bool is_other() const + { + filesystem::file_type ft = this->file_type(); + return ft != filesystem::status_error && ft != filesystem::file_not_found && + ft != filesystem::regular_file && ft != filesystem::directory_file; + } + + bool is_other(system::error_code& ec) const BOOST_NOEXCEPT + { + filesystem::file_type ft = this->file_type(ec); + return ft != filesystem::status_error && ft != filesystem::file_not_found && + ft != filesystem::regular_file && ft != filesystem::directory_file; + } + + bool operator==(directory_entry const& rhs) const { return m_path == rhs.m_path; } + bool operator!=(directory_entry const& rhs) const { return m_path != rhs.m_path; } + bool operator<(directory_entry const& rhs) const { return m_path < rhs.m_path; } + bool operator<=(directory_entry const& rhs) const { return m_path <= rhs.m_path; } + bool operator>(directory_entry const& rhs) const { return m_path > rhs.m_path; } + bool operator>=(directory_entry const& rhs) const { return m_path >= rhs.m_path; } private: - BOOST_FILESYSTEM_DECL file_status get_status(system::error_code* ec = NULL) const; - BOOST_FILESYSTEM_DECL file_status get_symlink_status(system::error_code* ec = NULL) const; + BOOST_FILESYSTEM_DECL void refresh_impl(system::error_code* ec = NULL) const; + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + void assign_with_status(boost::filesystem::path&& p, file_status st, file_status symlink_st) + { + m_path = static_cast< boost::filesystem::path&& >(p); + m_status = static_cast< file_status&& >(st); + m_symlink_status = static_cast< file_status&& >(symlink_st); + } +#endif + + void assign_with_status(boost::filesystem::path const& p, file_status st, file_status symlink_st) + { + m_path = p; +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + m_status = static_cast< file_status&& >(st); + m_symlink_status = static_cast< file_status&& >(symlink_st); +#else + m_status = st; + m_symlink_status = symlink_st; +#endif + } + + void replace_filename_with_status(boost::filesystem::path const& p, file_status st, file_status symlink_st) + { + m_path.replace_filename(p); +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + m_status = static_cast< file_status&& >(st); + m_symlink_status = static_cast< file_status&& >(symlink_st); +#else + m_status = st; + m_symlink_status = symlink_st; +#endif + } private: boost::filesystem::path m_path; mutable file_status m_status; // stat()-like mutable file_status m_symlink_status; // lstat()-like -}; // directory_entry +}; + +#if !defined(BOOST_FILESYSTEM_SOURCE) + +inline directory_entry::directory_entry(boost::filesystem::path const& p) : + m_path(p) +{ +#if BOOST_FILESYSTEM_VERSION >= 4 + refresh_impl(); +#endif +} + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +inline void directory_entry::assign(boost::filesystem::path&& p) +{ + m_path = static_cast< boost::filesystem::path&& >(p); +#if BOOST_FILESYSTEM_VERSION >= 4 + refresh_impl(); +#else + m_status = file_status(); + m_symlink_status = file_status(); +#endif +} +#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + +inline void directory_entry::assign(boost::filesystem::path const& p) +{ + m_path = p; +#if BOOST_FILESYSTEM_VERSION >= 4 + refresh_impl(); +#else + m_status = file_status(); + m_symlink_status = file_status(); +#endif +} + +inline void directory_entry::replace_filename(boost::filesystem::path const& p) +{ + m_path.replace_filename(p); +#if BOOST_FILESYSTEM_VERSION >= 4 + refresh_impl(); +#else + m_status = file_status(); + m_symlink_status = file_status(); +#endif +} + +#endif // !defined(BOOST_FILESYSTEM_SOURCE) + +namespace detail { +namespace path_traits { + +// Dispatch function for integration with path class +template< typename Callback > +BOOST_FORCEINLINE typename Callback::result_type dispatch(directory_entry const& de, Callback cb, const codecvt_type* cvt, directory_entry_tag) +{ + boost::filesystem::path::string_type const& source = de.path().native(); + return cb(source.data(), source.data() + source.size(), cvt); +} + +} // namespace path_traits +} // namespace detail //--------------------------------------------------------------------------------------// // // @@ -167,70 +468,147 @@ inline file_status status(directory_entry const& e) { return e.status(); } + inline file_status status(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT { return e.status(ec); } + +inline file_status symlink_status(directory_entry const& e) +{ + return e.symlink_status(); +} + +inline file_status symlink_status(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT +{ + return e.symlink_status(ec); +} + inline bool type_present(directory_entry const& e) { - return filesystem::type_present(e.status()); + return e.file_type() != filesystem::status_error; } + inline bool type_present(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT { - return filesystem::type_present(e.status(ec)); + return e.file_type(ec) != filesystem::status_error; } + inline bool status_known(directory_entry const& e) { return filesystem::status_known(e.status()); } + inline bool status_known(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT { return filesystem::status_known(e.status(ec)); } + inline bool exists(directory_entry const& e) { - return filesystem::exists(e.status()); + return e.exists(); } + inline bool exists(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT { - return filesystem::exists(e.status(ec)); + return e.exists(ec); } + inline bool is_regular_file(directory_entry const& e) { - return filesystem::is_regular_file(e.status()); + return e.is_regular_file(); } + inline bool is_regular_file(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT { - return filesystem::is_regular_file(e.status(ec)); + return e.is_regular_file(ec); } + inline bool is_directory(directory_entry const& e) { - return filesystem::is_directory(e.status()); + return e.is_directory(); } + inline bool is_directory(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT { - return filesystem::is_directory(e.status(ec)); + return e.is_directory(ec); } + inline bool is_symlink(directory_entry const& e) { - return filesystem::is_symlink(e.symlink_status()); + return e.is_symlink(); } + inline bool is_symlink(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT { - return filesystem::is_symlink(e.symlink_status(ec)); + return e.is_symlink(ec); +} + +inline bool is_block_file(directory_entry const& e) +{ + return e.is_block_file(); +} + +inline bool is_block_file(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT +{ + return e.is_block_file(ec); +} + +inline bool is_character_file(directory_entry const& e) +{ + return e.is_character_file(); +} + +inline bool is_character_file(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT +{ + return e.is_character_file(ec); } + +inline bool is_fifo(directory_entry const& e) +{ + return e.is_fifo(); +} + +inline bool is_fifo(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT +{ + return e.is_fifo(ec); +} + +inline bool is_socket(directory_entry const& e) +{ + return e.is_socket(); +} + +inline bool is_socket(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT +{ + return e.is_socket(ec); +} + +inline bool is_reparse_file(directory_entry const& e) +{ + return e.is_reparse_file(); +} + +inline bool is_reparse_file(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT +{ + return e.is_reparse_file(ec); +} + inline bool is_other(directory_entry const& e) { - return filesystem::is_other(e.status()); + return e.is_other(); } + inline bool is_other(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT { - return filesystem::is_other(e.status(ec)); + return e.is_other(ec); } + #ifndef BOOST_FILESYSTEM_NO_DEPRECATED +BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use is_regular_file() instead") inline bool is_regular(directory_entry const& e) { - return filesystem::is_regular(e.status()); + return filesystem::is_regular_file(e); } #endif @@ -243,20 +621,18 @@ inline bool is_regular(directory_entry const& e) BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(directory_options, unsigned int) { none = 0u, - skip_permission_denied = 1u, // if a directory cannot be opened because of insufficient permissions, pretend that the directory is empty - follow_directory_symlink = 1u << 1, // recursive_directory_iterator: follow directory symlinks - skip_dangling_symlinks = 1u << 2, // non-standard extension for recursive_directory_iterator: don't follow dangling directory symlinks, - pop_on_error = 1u << 3, // non-standard extension for recursive_directory_iterator: instead of producing an end iterator on errors, - // repeatedly invoke pop() until it succeeds or the iterator becomes equal to end iterator - _detail_no_follow = 1u << 4, // internal use only - _detail_no_push = 1u << 5 // internal use only + skip_permission_denied = 1u, // if a directory cannot be opened because of insufficient permissions, pretend that the directory is empty + follow_directory_symlink = 1u << 1u, // recursive_directory_iterator: follow directory symlinks + skip_dangling_symlinks = 1u << 2u, // non-standard extension for recursive_directory_iterator: don't follow dangling directory symlinks, + pop_on_error = 1u << 3u, // non-standard extension for recursive_directory_iterator: instead of producing an end iterator on errors, + // repeatedly invoke pop() until it succeeds or the iterator becomes equal to end iterator + _detail_no_follow = 1u << 4u, // internal use only + _detail_no_push = 1u << 5u // internal use only } BOOST_SCOPED_ENUM_DECLARE_END(directory_options) BOOST_BITMASK(BOOST_SCOPED_ENUM_NATIVE(directory_options)) -class directory_iterator; - namespace detail { struct dir_itr_imp : @@ -286,11 +662,6 @@ struct dir_itr_imp : BOOST_FILESYSTEM_DECL static void operator delete(void* p) BOOST_NOEXCEPT; }; -struct directory_iterator_params; - -BOOST_FILESYSTEM_DECL void directory_iterator_construct(directory_iterator& it, path const& p, unsigned int opts, directory_iterator_params* params, system::error_code* ec); -BOOST_FILESYSTEM_DECL void directory_iterator_increment(directory_iterator& it, system::error_code* ec); - } // namespace detail //--------------------------------------------------------------------------------------// @@ -336,13 +707,13 @@ public: #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) directory_iterator(directory_iterator&& that) BOOST_NOEXCEPT : - m_imp(std::move(that.m_imp)) + m_imp(static_cast< boost::intrusive_ptr< detail::dir_itr_imp >&& >(that.m_imp)) { } directory_iterator& operator=(directory_iterator&& that) BOOST_NOEXCEPT { - m_imp = std::move(that.m_imp); + m_imp = static_cast< boost::intrusive_ptr< detail::dir_itr_imp >&& >(that.m_imp); return *this; } #endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) @@ -540,11 +911,13 @@ public: #if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) // Deprecated constructors + BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use directory_options instead of symlink_option") recursive_directory_iterator(path const& dir_path, BOOST_SCOPED_ENUM_NATIVE(symlink_option) opts) { detail::recursive_directory_iterator_construct(*this, dir_path, static_cast< unsigned int >(opts), NULL); } + BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use directory_options instead of symlink_option") recursive_directory_iterator(path const& dir_path, BOOST_SCOPED_ENUM_NATIVE(symlink_option) opts, system::error_code& ec) BOOST_NOEXCEPT { detail::recursive_directory_iterator_construct(*this, dir_path, static_cast< unsigned int >(opts), &ec); @@ -556,13 +929,13 @@ public: #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) recursive_directory_iterator(recursive_directory_iterator&& that) BOOST_NOEXCEPT : - m_imp(std::move(that.m_imp)) + m_imp(static_cast< boost::intrusive_ptr< detail::recur_dir_itr_imp >&& >(that.m_imp)) { } recursive_directory_iterator& operator=(recursive_directory_iterator&& that) BOOST_NOEXCEPT { - m_imp = std::move(that.m_imp); + m_imp = static_cast< boost::intrusive_ptr< detail::recur_dir_itr_imp >&& >(that.m_imp); return *this; } #endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) @@ -586,6 +959,7 @@ public: } #ifndef BOOST_FILESYSTEM_NO_DEPRECATED + BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use recursive_directory_iterator::depth() instead") int level() const BOOST_NOEXCEPT { return depth(); @@ -614,6 +988,7 @@ public: } #ifndef BOOST_FILESYSTEM_NO_DEPRECATED + BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use recursive_directory_iterator::disable_recursion_pending() instead") void no_push(bool value = true) BOOST_NOEXCEPT { disable_recursion_pending(value); @@ -664,6 +1039,7 @@ private: }; #if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) +BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use recursive_directory_iterator instead") typedef recursive_directory_iterator wrecursive_directory_iterator; #endif diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/file_status.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/file_status.hpp index 90eca99e84..fb36240127 100644 --- a/contrib/restricted/boost/filesystem/include/boost/filesystem/file_status.hpp +++ b/contrib/restricted/boost/filesystem/include/boost/filesystem/file_status.hpp @@ -155,13 +155,13 @@ public: // Note: std::move is not constexpr in C++11, that's why we're not using it here BOOST_CONSTEXPR file_status(file_status&& rhs) BOOST_NOEXCEPT : m_value(static_cast< file_type&& >(rhs.m_value)), - m_perms(static_cast< enum perms&& >(rhs.m_perms)) + m_perms(static_cast< perms&& >(rhs.m_perms)) { } BOOST_CXX14_CONSTEXPR file_status& operator=(file_status&& rhs) BOOST_NOEXCEPT { m_value = static_cast< file_type&& >(rhs.m_value); - m_perms = static_cast< enum perms&& >(rhs.m_perms); + m_perms = static_cast< perms&& >(rhs.m_perms); return *this; } #endif @@ -174,28 +174,28 @@ public: BOOST_CXX14_CONSTEXPR void type(file_type v) BOOST_NOEXCEPT { m_value = v; } BOOST_CXX14_CONSTEXPR void permissions(perms prms) BOOST_NOEXCEPT { m_perms = prms; } - BOOST_CONSTEXPR bool operator==(const file_status& rhs) const BOOST_NOEXCEPT + BOOST_CONSTEXPR bool operator==(file_status const& rhs) const BOOST_NOEXCEPT { return type() == rhs.type() && permissions() == rhs.permissions(); } - BOOST_CONSTEXPR bool operator!=(const file_status& rhs) const BOOST_NOEXCEPT + BOOST_CONSTEXPR bool operator!=(file_status const& rhs) const BOOST_NOEXCEPT { return !(*this == rhs); } private: file_type m_value; - enum perms m_perms; + perms m_perms; }; inline BOOST_CONSTEXPR bool type_present(file_status f) BOOST_NOEXCEPT { - return f.type() != status_error; + return f.type() != filesystem::status_error; } inline BOOST_CONSTEXPR bool permissions_present(file_status f) BOOST_NOEXCEPT { - return f.permissions() != perms_not_known; + return f.permissions() != filesystem::perms_not_known; } inline BOOST_CONSTEXPR bool status_known(file_status f) BOOST_NOEXCEPT @@ -205,22 +205,47 @@ inline BOOST_CONSTEXPR bool status_known(file_status f) BOOST_NOEXCEPT inline BOOST_CONSTEXPR bool exists(file_status f) BOOST_NOEXCEPT { - return f.type() != status_error && f.type() != file_not_found; + return f.type() != filesystem::status_error && f.type() != filesystem::file_not_found; } inline BOOST_CONSTEXPR bool is_regular_file(file_status f) BOOST_NOEXCEPT { - return f.type() == regular_file; + return f.type() == filesystem::regular_file; } inline BOOST_CONSTEXPR bool is_directory(file_status f) BOOST_NOEXCEPT { - return f.type() == directory_file; + return f.type() == filesystem::directory_file; } inline BOOST_CONSTEXPR bool is_symlink(file_status f) BOOST_NOEXCEPT { - return f.type() == symlink_file; + return f.type() == filesystem::symlink_file; +} + +inline BOOST_CONSTEXPR bool is_block_file(file_status f) BOOST_NOEXCEPT +{ + return f.type() == filesystem::block_file; +} + +inline BOOST_CONSTEXPR bool is_character_file(file_status f) BOOST_NOEXCEPT +{ + return f.type() == filesystem::character_file; +} + +inline BOOST_CONSTEXPR bool is_fifo(file_status f) BOOST_NOEXCEPT +{ + return f.type() == filesystem::fifo_file; +} + +inline BOOST_CONSTEXPR bool is_socket(file_status f) BOOST_NOEXCEPT +{ + return f.type() == filesystem::socket_file; +} + +inline BOOST_CONSTEXPR bool is_reparse_file(file_status f) BOOST_NOEXCEPT +{ + return f.type() == filesystem::reparse_file; } inline BOOST_CONSTEXPR bool is_other(file_status f) BOOST_NOEXCEPT @@ -229,6 +254,7 @@ inline BOOST_CONSTEXPR bool is_other(file_status f) BOOST_NOEXCEPT } #ifndef BOOST_FILESYSTEM_NO_DEPRECATED +BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use is_regular_file() instead") inline bool is_regular(file_status f) BOOST_NOEXCEPT { return filesystem::is_regular_file(f); diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/operations.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/operations.hpp index 856de7c1a5..0b7f736878 100644 --- a/contrib/restricted/boost/filesystem/include/boost/filesystem/operations.hpp +++ b/contrib/restricted/boost/filesystem/include/boost/filesystem/operations.hpp @@ -176,7 +176,7 @@ inline file_status status(path const& p) return detail::status(p); } -inline file_status status(path const& p, system::error_code& ec) +inline file_status status(path const& p, system::error_code& ec) BOOST_NOEXCEPT { return detail::status(p, &ec); } @@ -186,70 +186,122 @@ inline file_status symlink_status(path const& p) return detail::symlink_status(p); } -inline file_status symlink_status(path const& p, system::error_code& ec) +inline file_status symlink_status(path const& p, system::error_code& ec) BOOST_NOEXCEPT { return detail::symlink_status(p, &ec); } inline bool exists(path const& p) { - return exists(detail::status(p)); + return filesystem::exists(detail::status(p)); } -inline bool exists(path const& p, system::error_code& ec) +inline bool exists(path const& p, system::error_code& ec) BOOST_NOEXCEPT { - return exists(detail::status(p, &ec)); + return filesystem::exists(detail::status(p, &ec)); +} + +inline bool is_regular_file(path const& p) +{ + return filesystem::is_regular_file(detail::status(p)); +} + +inline bool is_regular_file(path const& p, system::error_code& ec) BOOST_NOEXCEPT +{ + return filesystem::is_regular_file(detail::status(p, &ec)); } inline bool is_directory(path const& p) { - return is_directory(detail::status(p)); + return filesystem::is_directory(detail::status(p)); } -inline bool is_directory(path const& p, system::error_code& ec) +inline bool is_directory(path const& p, system::error_code& ec) BOOST_NOEXCEPT { - return is_directory(detail::status(p, &ec)); + return filesystem::is_directory(detail::status(p, &ec)); } -inline bool is_regular_file(path const& p) +inline bool is_symlink(path const& p) { - return is_regular_file(detail::status(p)); + return filesystem::is_symlink(detail::symlink_status(p)); } -inline bool is_regular_file(path const& p, system::error_code& ec) +inline bool is_symlink(path const& p, system::error_code& ec) BOOST_NOEXCEPT { - return is_regular_file(detail::status(p, &ec)); + return filesystem::is_symlink(detail::symlink_status(p, &ec)); } -inline bool is_other(path const& p) +inline bool is_block_file(path const& p) { - return is_other(detail::status(p)); + return filesystem::is_block_file(detail::status(p)); } -inline bool is_other(path const& p, system::error_code& ec) +inline bool is_block_file(path const& p, system::error_code& ec) BOOST_NOEXCEPT { - return is_other(detail::status(p, &ec)); + return filesystem::is_block_file(detail::status(p, &ec)); } -inline bool is_symlink(path const& p) +inline bool is_character_file(path const& p) +{ + return filesystem::is_character_file(detail::status(p)); +} + +inline bool is_character_file(path const& p, system::error_code& ec) BOOST_NOEXCEPT +{ + return filesystem::is_character_file(detail::status(p, &ec)); +} + +inline bool is_fifo(path const& p) +{ + return filesystem::is_fifo(detail::status(p)); +} + +inline bool is_fifo(path const& p, system::error_code& ec) BOOST_NOEXCEPT +{ + return filesystem::is_fifo(detail::status(p, &ec)); +} + +inline bool is_socket(path const& p) +{ + return filesystem::is_socket(detail::status(p)); +} + +inline bool is_socket(path const& p, system::error_code& ec) BOOST_NOEXCEPT +{ + return filesystem::is_socket(detail::status(p, &ec)); +} + +inline bool is_reparse_file(path const& p) +{ + return filesystem::is_reparse_file(detail::symlink_status(p)); +} + +inline bool is_reparse_file(path const& p, system::error_code& ec) BOOST_NOEXCEPT +{ + return filesystem::is_reparse_file(detail::symlink_status(p, &ec)); +} + +inline bool is_other(path const& p) { - return is_symlink(detail::symlink_status(p)); + return filesystem::is_other(detail::status(p)); } -inline bool is_symlink(path const& p, system::error_code& ec) +inline bool is_other(path const& p, system::error_code& ec) BOOST_NOEXCEPT { - return is_symlink(detail::symlink_status(p, &ec)); + return filesystem::is_other(detail::status(p, &ec)); } #ifndef BOOST_FILESYSTEM_NO_DEPRECATED +BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use is_regular_file() instead") inline bool is_regular(path const& p) { - return is_regular(detail::status(p)); + return filesystem::is_regular_file(p); } -inline bool is_regular(path const& p, system::error_code& ec) +BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use is_regular_file() instead") +inline bool is_regular(path const& p, system::error_code& ec) BOOST_NOEXCEPT { - return is_regular(detail::status(p, &ec)); + return filesystem::is_regular_file(p, ec); } #endif @@ -347,11 +399,13 @@ inline path canonical(path const& p, path const& base, system::error_code& ec) } #ifndef BOOST_FILESYSTEM_NO_DEPRECATED +BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use absolute() instead") inline path complete(path const& p) { return absolute(p, initial_path()); } +BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use absolute() instead") inline path complete(path const& p, path const& base) { return absolute(p, base); @@ -379,11 +433,13 @@ inline void copy(path const& from, path const& to, BOOST_SCOPED_ENUM_NATIVE(copy } #if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) +BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use create_directory() instead") inline void copy_directory(path const& from, path const& to) { detail::copy_directory(from, to); } +BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use create_directory() instead") inline void copy_directory(path const& from, path const& to, system::error_code& ec) BOOST_NOEXCEPT { detail::copy_directory(from, to, &ec); @@ -413,12 +469,14 @@ inline bool copy_file(path const& from, path const& to, // See ticket #2925 } #if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) +BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use copy_options instead of copy_option") inline bool copy_file(path const& from, path const& to, // See ticket #2925 BOOST_SCOPED_ENUM_NATIVE(copy_option) options) { return detail::copy_file(from, to, static_cast< unsigned int >(options)); } +BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use copy_options instead of copy_option") inline bool copy_file(path const& from, path const& to, // See ticket #2925 BOOST_SCOPED_ENUM_NATIVE(copy_option) options, system::error_code& ec) BOOST_NOEXCEPT { @@ -646,6 +704,7 @@ inline space_info space(path const& p, system::error_code& ec) BOOST_NOEXCEPT } #ifndef BOOST_FILESYSTEM_NO_DEPRECATED +BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use is_symlink(symlink_status(path)) instead") inline bool symbolic_link_exists(path const& p) { return is_symlink(filesystem::symlink_status(p)); diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/path.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/path.hpp index 0554c987a1..729e188125 100644 --- a/contrib/restricted/boost/filesystem/include/boost/filesystem/path.hpp +++ b/contrib/restricted/boost/filesystem/include/boost/filesystem/path.hpp @@ -2,7 +2,7 @@ // Copyright Vladimir Prus 2002 // Copyright Beman Dawes 2002-2005, 2009 -// Copyright Andrey Semashev 2021 +// Copyright Andrey Semashev 2021-2023 // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt @@ -18,25 +18,25 @@ #include <boost/assert.hpp> #include <boost/filesystem/config.hpp> -#include <boost/filesystem/path_traits.hpp> // includes <cwchar> +#include <boost/filesystem/detail/path_traits.hpp> #include <boost/iterator/iterator_facade.hpp> #include <boost/iterator/iterator_categories.hpp> #include <boost/core/enable_if.hpp> #include <boost/io/quoted.hpp> #include <boost/functional/hash_fwd.hpp> -#include <boost/type_traits/integral_constant.hpp> +#include <boost/type_traits/negation.hpp> +#include <boost/type_traits/conjunction.hpp> +#include <boost/type_traits/disjunction.hpp> #include <boost/type_traits/is_same.hpp> -#include <boost/type_traits/is_integral.hpp> -#include <boost/type_traits/remove_reference.hpp> #include <boost/type_traits/remove_cv.hpp> -#include <boost/type_traits/decay.hpp> #include <cstddef> -#include <cwchar> // for mbstate_t -#include <string> #include <iosfwd> -#include <iterator> #include <locale> -#include <utility> +#include <string> +#include <iterator> +#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) +#include <string_view> +#endif #include <boost/filesystem/detail/header.hpp> // must be the last #include @@ -69,59 +69,82 @@ BOOST_CONSTEXPR_OR_CONST typename path_constants< Char, Separator, PreferredSepa path_constants< Char, Separator, PreferredSeparator, Dot >::dot; #endif -// A struct that denotes a contiguous range of characters in a string. A lightweight alternative to string_view. -struct substring +class path_iterator; +class path_reverse_iterator; + +} // namespace path_detail + +namespace detail { + +struct path_algorithms { - std::size_t pos; - std::size_t size; -}; + // A struct that denotes a contiguous range of characters in a string. A lightweight alternative to string_view. + struct substring + { + std::size_t pos; + std::size_t size; + }; -template< typename T > -struct is_native_char_ptr_impl : public boost::false_type {}; + typedef path_traits::path_native_char_type value_type; + typedef std::basic_string< value_type > string_type; -#if defined(BOOST_WINDOWS_API) -template< > -struct is_native_char_ptr_impl< wchar_t* > : public boost::true_type {}; -template< > -struct is_native_char_ptr_impl< const wchar_t* > : public boost::true_type {}; -#else // defined(BOOST_WINDOWS_API) -template< > -struct is_native_char_ptr_impl< char* > : public boost::true_type {}; -template< > -struct is_native_char_ptr_impl< const char* > : public boost::true_type {}; -#endif // defined(BOOST_WINDOWS_API) + static bool has_filename_v3(path const& p); + static bool has_filename_v4(path const& p); + BOOST_FILESYSTEM_DECL static path filename_v3(path const& p); + static path filename_v4(path const& p); -template< typename T > -struct is_native_char_ptr : public is_native_char_ptr_impl< typename boost::remove_cv< typename boost::remove_reference< T >::type >::type > {}; + BOOST_FILESYSTEM_DECL static path stem_v3(path const& p); + BOOST_FILESYSTEM_DECL static path stem_v4(path const& p); + BOOST_FILESYSTEM_DECL static path extension_v3(path const& p); + static path extension_v4(path const& p); -template< typename T > -struct is_native_pathable_impl : public boost::false_type {}; + BOOST_FILESYSTEM_DECL static void remove_filename_v3(path& p); + BOOST_FILESYSTEM_DECL static void remove_filename_v4(path& p); -template< typename T > -struct is_native_pathable_impl< T* > : public is_native_char_ptr_impl< T* > {}; + BOOST_FILESYSTEM_DECL static void replace_extension_v3(path& p, path const& new_extension); + BOOST_FILESYSTEM_DECL static void replace_extension_v4(path& p, path const& new_extension); -#if defined(BOOST_WINDOWS_API) -template< > -struct is_native_pathable_impl< const wchar_t[] > : public boost::true_type {}; -template< std::size_t N > -struct is_native_pathable_impl< const wchar_t[N] > : public boost::true_type {}; -template< > -struct is_native_pathable_impl< std::basic_string< wchar_t > > : public boost::true_type {}; -#else // defined(BOOST_WINDOWS_API) -template< > -struct is_native_pathable_impl< const char[] > : public boost::true_type {}; -template< std::size_t N > -struct is_native_pathable_impl< const char[N] > : public boost::true_type {}; -template< > -struct is_native_pathable_impl< std::basic_string< char > > : public boost::true_type {}; -#endif // defined(BOOST_WINDOWS_API) -template< > -struct is_native_pathable_impl< filesystem::path > : public boost::true_type {}; + BOOST_FILESYSTEM_DECL static path lexically_normal_v3(path const& p); + BOOST_FILESYSTEM_DECL static path lexically_normal_v4(path const& p); -template< typename T > -struct is_native_pathable : public is_native_pathable_impl< typename boost::remove_cv< typename boost::remove_reference< T >::type >::type > {}; + BOOST_FILESYSTEM_DECL static int compare_v3(path const& left, path const& right); + BOOST_FILESYSTEM_DECL static int compare_v4(path const& left, path const& right); -} // namespace path_detail + BOOST_FILESYSTEM_DECL static void append_v3(path& p, const value_type* b, const value_type* e); + BOOST_FILESYSTEM_DECL static void append_v4(path& p, const value_type* b, const value_type* e); + static void append_v4(path& left, path const& right); + + // Returns: If separator is to be appended, m_pathname.size() before append. Otherwise 0. + // Note: An append is never performed if size()==0, so a returned 0 is unambiguous. + BOOST_FILESYSTEM_DECL static string_type::size_type append_separator_if_needed(path& p); + BOOST_FILESYSTEM_DECL static void erase_redundant_separator(path& p, string_type::size_type sep_pos); + + BOOST_FILESYSTEM_DECL static string_type::size_type find_root_name_size(path const& p); + BOOST_FILESYSTEM_DECL static string_type::size_type find_root_path_size(path const& p); + BOOST_FILESYSTEM_DECL static substring find_root_directory(path const& p); + BOOST_FILESYSTEM_DECL static substring find_relative_path(path const& p); + BOOST_FILESYSTEM_DECL static string_type::size_type find_parent_path_size(path const& p); + BOOST_FILESYSTEM_DECL static string_type::size_type find_filename_v4_size(path const& p); + BOOST_FILESYSTEM_DECL static string_type::size_type find_extension_v4_size(path const& p); + + BOOST_FILESYSTEM_DECL static int lex_compare_v3 + ( + path_detail::path_iterator first1, path_detail::path_iterator const& last1, + path_detail::path_iterator first2, path_detail::path_iterator const& last2 + ); + BOOST_FILESYSTEM_DECL static int lex_compare_v4 + ( + path_detail::path_iterator first1, path_detail::path_iterator const& last1, + path_detail::path_iterator first2, path_detail::path_iterator const& last2 + ); + + BOOST_FILESYSTEM_DECL static void increment_v3(path_detail::path_iterator& it); + BOOST_FILESYSTEM_DECL static void increment_v4(path_detail::path_iterator& it); + BOOST_FILESYSTEM_DECL static void decrement_v3(path_detail::path_iterator& it); + BOOST_FILESYSTEM_DECL static void decrement_v4(path_detail::path_iterator& it); +}; + +} // namespace detail //------------------------------------------------------------------------------------// // // @@ -132,19 +155,23 @@ struct is_native_pathable : public is_native_pathable_impl< typename boost::remo class path : public filesystem::path_detail::path_constants< #ifdef BOOST_WINDOWS_API - wchar_t, L'/', L'\\', L'.' + detail::path_traits::path_native_char_type, L'/', L'\\', L'.' #else - char, '/', '/', '.' + detail::path_traits::path_native_char_type, '/', '/', '.' #endif > { + friend class path_detail::path_iterator; + friend class path_detail::path_reverse_iterator; + friend struct detail::path_algorithms; + public: // value_type is the character type used by the operating system API to // represent paths. - typedef path_constants_base::value_type value_type; - typedef std::basic_string< value_type > string_type; - typedef std::codecvt< wchar_t, char, std::mbstate_t > codecvt_type; + typedef detail::path_algorithms::value_type value_type; + typedef detail::path_algorithms::string_type string_type; + typedef detail::path_traits::codecvt_type codecvt_type; // ----- character encoding conversions ----- @@ -201,131 +228,302 @@ public: // that actually depend on locale(""). It further ensures that exceptions thrown // as a result of such failues occur after main() has started, so can be caught. +private: + //! Assignment operation + class assign_op + { + private: + path& m_self; + + public: + typedef void result_type; + + explicit assign_op(path& self) BOOST_NOEXCEPT : m_self(self) {} + + result_type operator() (const value_type* source, const value_type* source_end, const codecvt_type* = NULL) const + { + m_self.m_pathname.assign(source, source_end); + } + + template< typename OtherChar > + result_type operator() (const OtherChar* source, const OtherChar* source_end, const codecvt_type* cvt = NULL) const + { + m_self.m_pathname.clear(); + detail::path_traits::convert(source, source_end, m_self.m_pathname, cvt); + } + }; + + //! Concatenation operation + class concat_op + { + private: + path& m_self; + + public: + typedef void result_type; + + explicit concat_op(path& self) BOOST_NOEXCEPT : m_self(self) {} + + result_type operator() (const value_type* source, const value_type* source_end, const codecvt_type* = NULL) const + { + m_self.m_pathname.append(source, source_end); + } + + template< typename OtherChar > + result_type operator() (const OtherChar* source, const OtherChar* source_end, const codecvt_type* cvt = NULL) const + { + detail::path_traits::convert(source, source_end, m_self.m_pathname, cvt); + } + }; + + //! Path appending operation + class append_op + { + private: + path& m_self; + + public: + typedef void result_type; + + explicit append_op(path& self) BOOST_NOEXCEPT : m_self(self) {} + + BOOST_FORCEINLINE result_type operator() (const value_type* source, const value_type* source_end, const codecvt_type* = NULL) const + { + m_self.append(source, source_end); + } + + template< typename OtherChar > + BOOST_FORCEINLINE result_type operator() (const OtherChar* source, const OtherChar* source_end, const codecvt_type* cvt = NULL) const + { + string_type src; + detail::path_traits::convert(source, source_end, src, cvt); + m_self.append(src.data(), src.data() + src.size()); + } + }; + + //! Path comparison operation + class compare_op + { + private: + path const& m_self; + + public: + typedef int result_type; + + explicit compare_op(path const& self) BOOST_NOEXCEPT : m_self(self) {} + + result_type operator() (const value_type* source, const value_type* source_end, const codecvt_type* = NULL) const; + + template< typename OtherChar > + result_type operator() (const OtherChar* source, const OtherChar* source_end, const codecvt_type* cvt = NULL) const; + }; + +public: + typedef path_detail::path_iterator iterator; + typedef iterator const_iterator; + typedef path_detail::path_reverse_iterator reverse_iterator; + typedef reverse_iterator const_reverse_iterator; + +public: // ----- constructors ----- path() BOOST_NOEXCEPT {} path(path const& p) : m_pathname(p.m_pathname) {} + path(path const& p, codecvt_type const&) : m_pathname(p.m_pathname) {} - template< class Source > + path(const value_type* s) : m_pathname(s) {} + path(const value_type* s, codecvt_type const&) : m_pathname(s) {} + path(string_type const& s) : m_pathname(s) {} + path(string_type const& s, codecvt_type const&) : m_pathname(s) {} +#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) + path(std::basic_string_view< value_type > const& s) : m_pathname(s) {} + path(std::basic_string_view< value_type > const& s, codecvt_type const&) : m_pathname(s) {} +#endif + +#if !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) + template< + typename Source, + typename = typename boost::enable_if_c< + boost::conjunction< + detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >, + boost::negation< detail::path_traits::is_native_path_source< typename boost::remove_cv< Source >::type > > + >::value + >::type + > + path(Source const& source) +#else + template< typename Source > path(Source const& source, typename boost::enable_if_c< - path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value + boost::conjunction< + detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >, + boost::negation< detail::path_traits::is_native_path_source< typename boost::remove_cv< Source >::type > > + >::value >::type* = NULL) +#endif { - path_traits::dispatch(source, m_pathname); + assign(source); } - path(const value_type* s) : m_pathname(s) {} - path(string_type const& s) : m_pathname(s) {} +#if !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) + template< + typename Source, + typename = typename boost::enable_if_c< + boost::conjunction< + detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >, + boost::negation< detail::path_traits::is_native_path_source< typename boost::remove_cv< Source >::type > > + >::value + >::type + > + explicit path(Source const& source, codecvt_type const& cvt) +#else + template< typename Source > + explicit path(Source const& source, codecvt_type const& cvt, typename boost::enable_if_c< + boost::conjunction< + detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >, + boost::negation< detail::path_traits::is_native_path_source< typename boost::remove_cv< Source >::type > > + >::value + >::type* = NULL) +#endif + { + assign(source, cvt); + } // As of October 2015 the interaction between noexcept and =default is so troublesome // for VC++, GCC, and probably other compilers, that =default is not used with noexcept // functions. GCC is not even consistent for the same release on different platforms. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - path(path&& p) BOOST_NOEXCEPT : m_pathname(std::move(p.m_pathname)) + path(path&& p) BOOST_NOEXCEPT : m_pathname(static_cast< string_type&& >(p.m_pathname)) { } - path(path&& p, codecvt_type const&) BOOST_NOEXCEPT : m_pathname(std::move(p.m_pathname)) + path(path&& p, codecvt_type const&) BOOST_NOEXCEPT : m_pathname(static_cast< string_type&& >(p.m_pathname)) { } path& operator=(path&& p) BOOST_NOEXCEPT { - m_pathname = std::move(p.m_pathname); + m_pathname = static_cast< string_type&& >(p.m_pathname); return *this; } path& assign(path&& p) BOOST_NOEXCEPT { - m_pathname = std::move(p.m_pathname); + m_pathname = static_cast< string_type&& >(p.m_pathname); return *this; } path& assign(path&& p, codecvt_type const&) BOOST_NOEXCEPT { - m_pathname = std::move(p.m_pathname); + m_pathname = static_cast< string_type&& >(p.m_pathname); return *this; } - path(string_type&& s) BOOST_NOEXCEPT : m_pathname(std::move(s)) + path(string_type&& s) BOOST_NOEXCEPT : m_pathname(static_cast< string_type&& >(s)) { } - path(string_type&& s, codecvt_type const&) BOOST_NOEXCEPT : m_pathname(std::move(s)) + path(string_type&& s, codecvt_type const&) BOOST_NOEXCEPT : m_pathname(static_cast< string_type&& >(s)) { } path& operator=(string_type&& p) BOOST_NOEXCEPT { - m_pathname = std::move(p); + m_pathname = static_cast< string_type&& >(p); return *this; } path& assign(string_type&& p) BOOST_NOEXCEPT { - m_pathname = std::move(p); + m_pathname = static_cast< string_type&& >(p); return *this; } path& assign(string_type&& p, codecvt_type const&) BOOST_NOEXCEPT { - m_pathname = std::move(p); + m_pathname = static_cast< string_type&& >(p); return *this; } #endif - path(path const& p, codecvt_type const&) : m_pathname(p.m_pathname) {} - path(const value_type* s, codecvt_type const&) : m_pathname(s) {} - path(string_type const& s, codecvt_type const&) : m_pathname(s) {} - - template< class Source > - path(Source const& source, codecvt_type const& cvt, typename boost::enable_if_c< - path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value - >::type* = NULL) - { - path_traits::dispatch(source, m_pathname, cvt); - } - path(const value_type* begin, const value_type* end) : m_pathname(begin, end) {} + path(const value_type* begin, const value_type* end, codecvt_type const&) : m_pathname(begin, end) {} - template< class InputIterator > - path(InputIterator begin, InputIterator end, typename boost::disable_if< path_detail::is_native_char_ptr< InputIterator > >::type* = NULL) +#if !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) + template< + typename InputIterator, + typename = typename boost::enable_if_c< + boost::conjunction< + detail::path_traits::is_path_source_iterator< InputIterator >, + boost::negation< detail::path_traits::is_native_char_ptr< InputIterator > > + >::value + >::type + > + path(InputIterator begin, InputIterator end) +#else + template< typename InputIterator > + path(InputIterator begin, InputIterator end, typename boost::enable_if_c< + boost::conjunction< + detail::path_traits::is_path_source_iterator< InputIterator >, + boost::negation< detail::path_traits::is_native_char_ptr< InputIterator > > + >::value + >::type* = NULL) +#endif { if (begin != end) { - // convert requires contiguous string, so copy - std::basic_string< typename std::iterator_traits< InputIterator >::value_type > seq(begin, end); - path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), m_pathname); + typedef std::basic_string< typename std::iterator_traits< InputIterator >::value_type > source_t; + source_t source(begin, end); +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + assign(static_cast< source_t&& >(source)); +#else + assign(source); +#endif } } - path(const value_type* begin, const value_type* end, codecvt_type const&) : m_pathname(begin, end) {} - - template< class InputIterator > - path(InputIterator begin, InputIterator end, codecvt_type const& cvt, typename boost::disable_if< path_detail::is_native_char_ptr< InputIterator > >::type* = NULL) +#if !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) + template< + typename InputIterator, + typename = typename boost::enable_if_c< + boost::conjunction< + detail::path_traits::is_path_source_iterator< InputIterator >, + boost::negation< detail::path_traits::is_native_char_ptr< InputIterator > > + >::value + >::type + > + path(InputIterator begin, InputIterator end, codecvt_type const& cvt) +#else + template< typename InputIterator > + path(InputIterator begin, InputIterator end, codecvt_type const& cvt, typename boost::enable_if_c< + boost::conjunction< + detail::path_traits::is_path_source_iterator< InputIterator >, + boost::negation< detail::path_traits::is_native_char_ptr< InputIterator > > + >::value + >::type* = NULL) +#endif { if (begin != end) { - // convert requires contiguous string, so copy - std::basic_string< typename std::iterator_traits< InputIterator >::value_type > seq(begin, end); - path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), m_pathname, cvt); + typedef std::basic_string< typename std::iterator_traits< InputIterator >::value_type > source_t; + source_t source(begin, end); +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + assign(static_cast< source_t&& >(source), cvt); +#else + assign(source, cvt); +#endif } } +#if !defined(BOOST_NO_CXX11_NULLPTR) + BOOST_DELETED_FUNCTION(path(std::nullptr_t)) + BOOST_DELETED_FUNCTION(path& operator= (std::nullptr_t)) +#endif + +public: // ----- assignments ----- // We need to explicitly define copy assignment as otherwise it will be implicitly defined as deleted because there is move assignment - path& operator=(path const& p) - { - return assign(p); - } - - path& operator=(string_type const& s) - { - return assign(s); - } - - path& operator=(const value_type* ptr) - { - return assign(ptr); - } + path& operator=(path const& p); - template< class Source > + template< typename Source > typename boost::enable_if_c< - path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value, + boost::disjunction< + detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >, + detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type > + >::value, path& >::type operator=(Source const& source) { @@ -338,26 +536,26 @@ public: return *this; } - path& assign(string_type const& s) - { - m_pathname = s; - return *this; - } - - path& assign(const value_type* ptr) + template< typename Source > + typename boost::enable_if_c< + detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >::value, + path& + >::type assign(Source const& source) { - m_pathname = ptr; + detail::path_traits::dispatch(source, assign_op(*this)); return *this; } - template< class Source > + template< typename Source > typename boost::enable_if_c< - path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value, + boost::conjunction< + detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >, + boost::negation< detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type > > + >::value, path& >::type assign(Source const& source) { - m_pathname.clear(); - path_traits::dispatch(source, m_pathname); + detail::path_traits::dispatch_convertible(source, assign_op(*this)); return *this; } @@ -367,26 +565,26 @@ public: return *this; } - path& assign(string_type const& s, codecvt_type const&) - { - m_pathname = s; - return *this; - } - - path& assign(const value_type* ptr, codecvt_type const&) + template< typename Source > + typename boost::enable_if_c< + detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >::value, + path& + >::type assign(Source const& source, codecvt_type const& cvt) { - m_pathname = ptr; + detail::path_traits::dispatch(source, assign_op(*this), &cvt); return *this; } - template< class Source > + template< typename Source > typename boost::enable_if_c< - path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value, + boost::conjunction< + detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >, + boost::negation< detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type > > + >::value, path& >::type assign(Source const& source, codecvt_type const& cvt) { - m_pathname.clear(); - path_traits::dispatch(source, m_pathname, cvt); + detail::path_traits::dispatch_convertible(source, assign_op(*this), &cvt); return *this; } @@ -396,15 +594,25 @@ public: return *this; } - template< class InputIterator > - typename boost::disable_if< path_detail::is_native_char_ptr< InputIterator >, path& >::type - assign(InputIterator begin, InputIterator end) + template< typename InputIterator > + typename boost::enable_if_c< + boost::conjunction< + detail::path_traits::is_path_source_iterator< InputIterator >, + boost::negation< detail::path_traits::is_native_char_ptr< InputIterator > > + >::value, + path& + >::type assign(InputIterator begin, InputIterator end) { m_pathname.clear(); if (begin != end) { - std::basic_string< typename std::iterator_traits< InputIterator >::value_type > seq(begin, end); - path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), m_pathname); + typedef std::basic_string< typename std::iterator_traits< InputIterator >::value_type > source_t; + source_t source(begin, end); +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + assign(static_cast< source_t&& >(source)); +#else + assign(source); +#endif } return *this; } @@ -415,39 +623,36 @@ public: return *this; } - template< class InputIterator > - typename boost::disable_if< path_detail::is_native_char_ptr< InputIterator >, path& >::type - assign(InputIterator begin, InputIterator end, codecvt_type const& cvt) + template< typename InputIterator > + typename boost::enable_if_c< + boost::conjunction< + detail::path_traits::is_path_source_iterator< InputIterator >, + boost::negation< detail::path_traits::is_native_char_ptr< InputIterator > > + >::value, + path& + >::type assign(InputIterator begin, InputIterator end, codecvt_type const& cvt) { m_pathname.clear(); if (begin != end) { - std::basic_string< typename std::iterator_traits< InputIterator >::value_type > seq(begin, end); - path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), m_pathname, cvt); + typedef std::basic_string< typename std::iterator_traits< InputIterator >::value_type > source_t; + source_t source(begin, end); +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + assign(static_cast< source_t&& >(source), cvt); +#else + assign(source, cvt); +#endif } return *this; } // ----- concatenation ----- - path& operator+=(path const& p) - { - return concat(p); - } - - path& operator+=(const value_type* ptr) - { - return concat(ptr); - } + path& operator+=(path const& p); - path& operator+=(string_type const& s) - { - return concat(s); - } - - template< class Source > + template< typename Source > typename boost::enable_if_c< - path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value, + detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >::value, path& >::type operator+=(Source const& source) { @@ -460,69 +665,74 @@ public: return *this; } - template< class CharT > - typename boost::enable_if< boost::is_integral< CharT >, path& >::type - operator+=(CharT c) + template< typename CharT > + typename boost::enable_if_c< + detail::path_traits::is_path_char_type< CharT >::value, + path& + >::type operator+=(CharT c) { CharT tmp[2]; tmp[0] = c; tmp[1] = static_cast< CharT >(0); - return concat(tmp); - } - - path& concat(path const& p) - { - m_pathname += p.m_pathname; + concat_op(*this)(tmp, tmp + 1); return *this; } - path& concat(const value_type* ptr) + path& concat(path const& p) { - m_pathname += ptr; + m_pathname.append(p.m_pathname); return *this; } - path& concat(string_type const& s) + template< typename Source > + typename boost::enable_if_c< + detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >::value, + path& + >::type concat(Source const& source) { - m_pathname += s; + detail::path_traits::dispatch(source, concat_op(*this)); return *this; } - template< class Source > + template< typename Source > typename boost::enable_if_c< - path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value, + boost::conjunction< + detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >, + boost::negation< detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type > > + >::value, path& >::type concat(Source const& source) { - path_traits::dispatch(source, m_pathname); + detail::path_traits::dispatch_convertible(source, concat_op(*this)); return *this; } path& concat(path const& p, codecvt_type const&) { - m_pathname += p.m_pathname; + m_pathname.append(p.m_pathname); return *this; } - path& concat(const value_type* ptr, codecvt_type const&) - { - m_pathname += ptr; - return *this; - } - - path& concat(string_type const& s, codecvt_type const&) + template< typename Source > + typename boost::enable_if_c< + detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >::value, + path& + >::type concat(Source const& source, codecvt_type const& cvt) { - m_pathname += s; + detail::path_traits::dispatch(source, concat_op(*this), &cvt); return *this; } - template< class Source > + template< typename Source > typename boost::enable_if_c< - path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value, + boost::conjunction< + detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >, + boost::negation< detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type > > + >::value, path& >::type concat(Source const& source, codecvt_type const& cvt) { - path_traits::dispatch(source, m_pathname, cvt); + detail::path_traits::dispatch_convertible(source, concat_op(*this), &cvt); return *this; } @@ -532,14 +742,19 @@ public: return *this; } - template< class InputIterator > - typename boost::disable_if< path_detail::is_native_char_ptr< InputIterator >, path& >::type - concat(InputIterator begin, InputIterator end) + template< typename InputIterator > + typename boost::enable_if_c< + boost::conjunction< + detail::path_traits::is_path_source_iterator< InputIterator >, + boost::negation< detail::path_traits::is_native_char_ptr< InputIterator > > + >::value, + path& + >::type concat(InputIterator begin, InputIterator end) { if (begin != end) { - std::basic_string< typename std::iterator_traits< InputIterator >::value_type > seq(begin, end); - path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), m_pathname); + std::basic_string< typename std::iterator_traits< InputIterator >::value_type > source(begin, end); + detail::path_traits::dispatch(source, concat_op(*this)); } return *this; } @@ -550,14 +765,19 @@ public: return *this; } - template< class InputIterator > - typename boost::disable_if< path_detail::is_native_char_ptr< InputIterator >, path& >::type - concat(InputIterator begin, InputIterator end, codecvt_type const& cvt) + template< typename InputIterator > + typename boost::enable_if_c< + boost::conjunction< + detail::path_traits::is_path_source_iterator< InputIterator >, + boost::negation< detail::path_traits::is_native_char_ptr< InputIterator > > + >::value, + path& + >::type concat(InputIterator begin, InputIterator end, codecvt_type const& cvt) { if (begin != end) { - std::basic_string< typename std::iterator_traits< InputIterator >::value_type > seq(begin, end); - path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), m_pathname, cvt); + std::basic_string< typename std::iterator_traits< InputIterator >::value_type > source(begin, end); + detail::path_traits::dispatch(source, concat_op(*this), &cvt); } return *this; } @@ -567,124 +787,97 @@ public: // if a separator is added, it is the preferred separator for the platform; // slash for POSIX, backslash for Windows - path& operator/=(path const& p) - { - return append(p); - } + path& operator/=(path const& p); - path& operator/=(const value_type* ptr) - { - return append(ptr); - } - - path& operator/=(string_type const& s) - { - return append(s); - } - - template< class Source > + template< typename Source > BOOST_FORCEINLINE typename boost::enable_if_c< - path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value, + detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >::value, path& >::type operator/=(Source const& source) { return append(source); } - BOOST_FORCEINLINE path& append(path const& p) - { - BOOST_FILESYSTEM_VERSIONED_SYM(append)(p); - return *this; - } - - BOOST_FORCEINLINE path& append(string_type const& p) - { - BOOST_FILESYSTEM_VERSIONED_SYM(append)(p.c_str(), p.c_str() + p.size()); - return *this; - } + path& append(path const& p); - BOOST_FORCEINLINE path& append(const value_type* ptr) + template< typename Source > + BOOST_FORCEINLINE typename boost::enable_if_c< + detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >::value, + path& + >::type append(Source const& source) { - BOOST_FILESYSTEM_VERSIONED_SYM(append)(ptr, ptr + string_type::traits_type::length(ptr)); + detail::path_traits::dispatch(source, append_op(*this)); return *this; } - template< class Source > - typename boost::enable_if_c< - path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value, + template< typename Source > + BOOST_FORCEINLINE typename boost::enable_if_c< + boost::conjunction< + detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >, + boost::negation< detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type > > + >::value, path& >::type append(Source const& source) { - path p; - path_traits::dispatch(source, p.m_pathname); - return append(p); - } - - BOOST_FORCEINLINE path& append(path const& p, codecvt_type const&) - { - BOOST_FILESYSTEM_VERSIONED_SYM(append)(p); + detail::path_traits::dispatch_convertible(source, append_op(*this)); return *this; } - BOOST_FORCEINLINE path& append(string_type const& p, codecvt_type const&) - { - BOOST_FILESYSTEM_VERSIONED_SYM(append)(p.c_str(), p.c_str() + p.size()); - return *this; - } + path& append(path const& p, codecvt_type const&); - BOOST_FORCEINLINE path& append(const value_type* ptr, codecvt_type const&) + template< typename Source > + BOOST_FORCEINLINE typename boost::enable_if_c< + detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >::value, + path& + >::type append(Source const& source, codecvt_type const& cvt) { - BOOST_FILESYSTEM_VERSIONED_SYM(append)(ptr, ptr + string_type::traits_type::length(ptr)); + detail::path_traits::dispatch(source, append_op(*this), &cvt); return *this; } - template< class Source > - typename boost::enable_if_c< - path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value, + template< typename Source > + BOOST_FORCEINLINE typename boost::enable_if_c< + boost::conjunction< + detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >, + boost::negation< detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type > > + >::value, path& >::type append(Source const& source, codecvt_type const& cvt) { - path p; - path_traits::dispatch(source, p.m_pathname, cvt); - return append(p); - } - - BOOST_FORCEINLINE path& append(const value_type* begin, const value_type* end) - { - BOOST_FILESYSTEM_VERSIONED_SYM(append)(begin, end); + detail::path_traits::dispatch_convertible(source, append_op(*this), &cvt); return *this; } - template< class InputIterator > - typename boost::disable_if< path_detail::is_native_char_ptr< InputIterator >, path& >::type - append(InputIterator begin, InputIterator end) - { - path p; - if (begin != end) - { - std::basic_string< typename std::iterator_traits< InputIterator >::value_type > seq(begin, end); - path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), p.m_pathname); - } - return append(p); - } + path& append(const value_type* begin, const value_type* end); - BOOST_FORCEINLINE path& append(const value_type* begin, const value_type* end, codecvt_type const&) + template< typename InputIterator > + BOOST_FORCEINLINE typename boost::enable_if_c< + boost::conjunction< + detail::path_traits::is_path_source_iterator< InputIterator >, + boost::negation< detail::path_traits::is_native_char_ptr< InputIterator > > + >::value, + path& + >::type append(InputIterator begin, InputIterator end) { - BOOST_FILESYSTEM_VERSIONED_SYM(append)(begin, end); + std::basic_string< typename std::iterator_traits< InputIterator >::value_type > source(begin, end); + detail::path_traits::dispatch(source, append_op(*this)); return *this; } - template< class InputIterator > - typename boost::disable_if< path_detail::is_native_char_ptr< InputIterator >, path& >::type - append(InputIterator begin, InputIterator end, const codecvt_type& cvt) + path& append(const value_type* begin, const value_type* end, codecvt_type const&); + + template< typename InputIterator > + BOOST_FORCEINLINE typename boost::enable_if_c< + boost::conjunction< + detail::path_traits::is_path_source_iterator< InputIterator >, + boost::negation< detail::path_traits::is_native_char_ptr< InputIterator > > + >::value, + path& + >::type append(InputIterator begin, InputIterator end, const codecvt_type& cvt) { - path p; - if (begin != end) - { - std::basic_string< typename std::iterator_traits< InputIterator >::value_type > seq(begin, end); - path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), p.m_pathname, cvt); - } - return append(p); + std::basic_string< typename std::iterator_traits< InputIterator >::value_type > source(begin, end); + detail::path_traits::dispatch(source, append_op(*this), &cvt); + return *this; } // ----- modifiers ----- @@ -699,13 +892,12 @@ public: #else // BOOST_WINDOWS_API BOOST_FILESYSTEM_DECL path& make_preferred(); // change slashes to backslashes #endif - BOOST_FILESYSTEM_DECL path& remove_filename(); + path& remove_filename(); + BOOST_FILESYSTEM_DECL path& remove_filename_and_trailing_separators(); BOOST_FILESYSTEM_DECL path& remove_trailing_separator(); - BOOST_FORCEINLINE path& replace_extension(path const& new_extension = path()) - { - BOOST_FILESYSTEM_VERSIONED_SYM(replace_extension)(new_extension); - return *this; - } + BOOST_FILESYSTEM_DECL path& replace_filename(path const& replacement); + path& replace_extension(path const& new_extension = path()); + void swap(path& rhs) BOOST_NOEXCEPT { m_pathname.swap(rhs.m_pathname); } // ----- observers ----- @@ -733,10 +925,10 @@ public: const value_type* c_str() const BOOST_NOEXCEPT { return m_pathname.c_str(); } string_type::size_type size() const BOOST_NOEXCEPT { return m_pathname.size(); } - template< class String > + template< typename String > String string() const; - template< class String > + template< typename String > String string(codecvt_type const& cvt) const; #ifdef BOOST_WINDOWS_API @@ -744,14 +936,14 @@ public: { std::string tmp; if (!m_pathname.empty()) - path_traits::convert(m_pathname.c_str(), m_pathname.c_str() + m_pathname.size(), tmp); + detail::path_traits::convert(m_pathname.data(), m_pathname.data() + m_pathname.size(), tmp); return tmp; } std::string string(codecvt_type const& cvt) const { std::string tmp; if (!m_pathname.empty()) - path_traits::convert(m_pathname.c_str(), m_pathname.c_str() + m_pathname.size(), tmp, cvt); + detail::path_traits::convert(m_pathname.data(), m_pathname.data() + m_pathname.size(), tmp, &cvt); return tmp; } @@ -767,14 +959,14 @@ public: { std::wstring tmp; if (!m_pathname.empty()) - path_traits::convert(m_pathname.c_str(), m_pathname.c_str() + m_pathname.size(), tmp); + detail::path_traits::convert(m_pathname.data(), m_pathname.data() + m_pathname.size(), tmp); return tmp; } std::wstring wstring(codecvt_type const& cvt) const { std::wstring tmp; if (!m_pathname.empty()) - path_traits::convert(m_pathname.c_str(), m_pathname.c_str() + m_pathname.size(), tmp, cvt); + detail::path_traits::convert(m_pathname.data(), m_pathname.data() + m_pathname.size(), tmp, &cvt); return tmp; } #endif @@ -787,13 +979,13 @@ public: #ifdef BOOST_WINDOWS_API BOOST_FILESYSTEM_DECL path generic_path() const; #else - path generic_path() const { return path(*this); } + path generic_path() const; #endif - template< class String > + template< typename String > String generic_string() const; - template< class String > + template< typename String > String generic_string(codecvt_type const& cvt) const; #ifdef BOOST_WINDOWS_API @@ -811,51 +1003,88 @@ public: // ----- compare ----- - BOOST_FORCEINLINE int compare(path const& p) const BOOST_NOEXCEPT // generic, lexicographical + int compare(path const& p) const; // generic, lexicographical + + template< typename Source > + BOOST_FORCEINLINE typename boost::enable_if_c< + detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >::value, + int + >::type compare(Source const& source) const + { + return detail::path_traits::dispatch(source, compare_op(*this)); + } + + template< typename Source > + BOOST_FORCEINLINE typename boost::enable_if_c< + boost::conjunction< + detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >, + boost::negation< detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type > > + >::value, + int + >::type compare(Source const& source) const { - return BOOST_FILESYSTEM_VERSIONED_SYM(compare)(p); + return detail::path_traits::dispatch_convertible(source, compare_op(*this)); + } + + template< typename Source > + BOOST_FORCEINLINE typename boost::enable_if_c< + detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >::value, + int + >::type compare(Source const& source, codecvt_type const& cvt) const + { + return detail::path_traits::dispatch(source, compare_op(*this), &cvt); + } + + template< typename Source > + BOOST_FORCEINLINE typename boost::enable_if_c< + boost::conjunction< + detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >, + boost::negation< detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type > > + >::value, + int + >::type compare(Source const& source, codecvt_type const& cvt) const + { + return detail::path_traits::dispatch_convertible(source, compare_op(*this), &cvt); } - int compare(std::string const& s) const { return compare(path(s)); } - int compare(const value_type* s) const { return compare(path(s)); } // ----- decomposition ----- - path root_path() const { return path(m_pathname.c_str(), m_pathname.c_str() + find_root_path_size()); } + path root_path() const { return path(m_pathname.c_str(), m_pathname.c_str() + detail::path_algorithms::find_root_path_size(*this)); } // returns 0 or 1 element path even on POSIX, root_name() is non-empty() for network paths - path root_name() const { return path(m_pathname.c_str(), m_pathname.c_str() + find_root_name_size()); } + path root_name() const { return path(m_pathname.c_str(), m_pathname.c_str() + detail::path_algorithms::find_root_name_size(*this)); } // returns 0 or 1 element path path root_directory() const { - path_detail::substring root_dir = find_root_directory(); + detail::path_algorithms::substring root_dir = detail::path_algorithms::find_root_directory(*this); const value_type* p = m_pathname.c_str() + root_dir.pos; return path(p, p + root_dir.size); } path relative_path() const { - path_detail::substring root_dir = find_relative_path(); - const value_type* p = m_pathname.c_str() + root_dir.pos; - return path(p, p + root_dir.size); + detail::path_algorithms::substring rel_path = detail::path_algorithms::find_relative_path(*this); + const value_type* p = m_pathname.c_str() + rel_path.pos; + return path(p, p + rel_path.size); } - path parent_path() const { return path(m_pathname.c_str(), m_pathname.c_str() + find_parent_path_size()); } + path parent_path() const { return path(m_pathname.c_str(), m_pathname.c_str() + detail::path_algorithms::find_parent_path_size(*this)); } - BOOST_FORCEINLINE path filename() const { return BOOST_FILESYSTEM_VERSIONED_SYM(filename)(); } // returns 0 or 1 element path - BOOST_FORCEINLINE path stem() const { return BOOST_FILESYSTEM_VERSIONED_SYM(stem)(); } // returns 0 or 1 element path - BOOST_FORCEINLINE path extension() const { return BOOST_FILESYSTEM_VERSIONED_SYM(extension)(); } // returns 0 or 1 element path + path filename() const; // returns 0 or 1 element path + path stem() const; // returns 0 or 1 element path + path extension() const; // returns 0 or 1 element path // ----- query ----- bool empty() const BOOST_NOEXCEPT { return m_pathname.empty(); } bool filename_is_dot() const; bool filename_is_dot_dot() const; - bool has_root_path() const { return find_root_path_size() > 0; } - bool has_root_name() const { return find_root_name_size() > 0; } - bool has_root_directory() const { return find_root_directory().size > 0; } - bool has_relative_path() const { return find_relative_path().size > 0; } - bool has_parent_path() const { return find_parent_path_size() > 0; } - BOOST_FORCEINLINE bool has_filename() const { return BOOST_FILESYSTEM_VERSIONED_SYM(has_filename)(); } + bool has_root_path() const { return detail::path_algorithms::find_root_path_size(*this) > 0; } + bool has_root_name() const { return detail::path_algorithms::find_root_name_size(*this) > 0; } + bool has_root_directory() const { return detail::path_algorithms::find_root_directory(*this).size > 0; } + bool has_relative_path() const { return detail::path_algorithms::find_relative_path(*this).size > 0; } + bool has_parent_path() const { return detail::path_algorithms::find_parent_path_size(*this) > 0; } + bool has_filename() const; bool has_stem() const { return !stem().empty(); } bool has_extension() const { return !extension().empty(); } bool is_relative() const { return !is_absolute(); } @@ -871,22 +1100,12 @@ public: // ----- lexical operations ----- - BOOST_FORCEINLINE path lexically_normal() const { return BOOST_FILESYSTEM_VERSIONED_SYM(lexically_normal)(); } + path lexically_normal() const; BOOST_FILESYSTEM_DECL path lexically_relative(path const& base) const; - path lexically_proximate(path const& base) const - { - path tmp(lexically_relative(base)); - return tmp.empty() ? *this : tmp; - } + path lexically_proximate(path const& base) const; // ----- iterators ----- - class iterator; - friend class iterator; - typedef iterator const_iterator; - class reverse_iterator; - typedef reverse_iterator const_reverse_iterator; - BOOST_FILESYSTEM_DECL iterator begin() const; BOOST_FILESYSTEM_DECL iterator end() const; reverse_iterator rbegin() const; @@ -901,29 +1120,37 @@ public: #if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) // recently deprecated functions supplied by default - path& normalize() - { - path tmp(lexically_normal()); - m_pathname.swap(tmp.m_pathname); - return *this; - } + path& normalize(); + BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use path::remove_filename() instead") path& remove_leaf() { return remove_filename(); } + BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use path::filename() instead") path leaf() const { return filename(); } + BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use path::parent_path() instead") path branch_path() const { return parent_path(); } + BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use path::generic_path() instead") path generic() const { return generic_path(); } + BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use !path::empty() instead") bool has_leaf() const { return !m_pathname.empty(); } - bool has_branch_path() const { return !parent_path().empty(); } + BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use path::has_parent_path() instead") + bool has_branch_path() const { return has_parent_path(); } + BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use path::is_absolute() instead") bool is_complete() const { return is_absolute(); } #endif #if defined(BOOST_FILESYSTEM_DEPRECATED) // deprecated functions with enough signature or semantic changes that they are // not supplied by default + BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use path::string() instead") std::string file_string() const { return string(); } + BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use path::string() instead") std::string directory_string() const { return string(); } + BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use path::string() instead") std::string native_file_string() const { return string(); } + BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use path::string() instead") std::string native_directory_string() const { return string(); } + BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use path::native() instead") string_type external_file_string() const { return native(); } + BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use path::native() instead") string_type external_directory_string() const { return native(); } #endif @@ -931,55 +1158,6 @@ public: // class path private members // //--------------------------------------------------------------------------------------// private: - bool has_filename_v3() const { return !m_pathname.empty(); } - bool has_filename_v4() const { return find_filename_v4_size() > 0; } - BOOST_FILESYSTEM_DECL path filename_v3() const; - path filename_v4() const - { - string_type::size_type filename_size = find_filename_v4_size(); - string_type::size_type pos = m_pathname.size() - filename_size; - const value_type* p = m_pathname.c_str() + pos; - return path(p, p + filename_size); - } - BOOST_FILESYSTEM_DECL path stem_v3() const; - BOOST_FILESYSTEM_DECL path stem_v4() const; - BOOST_FILESYSTEM_DECL path extension_v3() const; - path extension_v4() const - { - string_type::size_type extension_size = find_extension_v4_size(); - string_type::size_type pos = m_pathname.size() - extension_size; - const value_type* p = m_pathname.c_str() + pos; - return path(p, p + extension_size); - } - - BOOST_FILESYSTEM_DECL void replace_extension_v3(path const& new_extension); - BOOST_FILESYSTEM_DECL void replace_extension_v4(path const& new_extension); - - BOOST_FILESYSTEM_DECL path lexically_normal_v3() const; - BOOST_FILESYSTEM_DECL path lexically_normal_v4() const; - - BOOST_FILESYSTEM_DECL int compare_v3(path const& p) const BOOST_NOEXCEPT; - BOOST_FILESYSTEM_DECL int compare_v4(path const& p) const BOOST_NOEXCEPT; - - BOOST_FILESYSTEM_DECL void append_v3(const value_type* b, const value_type* e); - BOOST_FILESYSTEM_DECL void append_v4(const value_type* b, const value_type* e); - BOOST_FILESYSTEM_DECL void append_v3(path const& p); - BOOST_FILESYSTEM_DECL void append_v4(path const& p); - - // Returns: If separator is to be appended, m_pathname.size() before append. Otherwise 0. - // Note: An append is never performed if size()==0, so a returned 0 is unambiguous. - BOOST_FILESYSTEM_DECL string_type::size_type append_separator_if_needed(); - BOOST_FILESYSTEM_DECL void erase_redundant_separator(string_type::size_type sep_pos); - - BOOST_FILESYSTEM_DECL string_type::size_type find_root_name_size() const; - BOOST_FILESYSTEM_DECL string_type::size_type find_root_path_size() const; - BOOST_FILESYSTEM_DECL path_detail::substring find_root_directory() const; - BOOST_FILESYSTEM_DECL path_detail::substring find_relative_path() const; - BOOST_FILESYSTEM_DECL string_type::size_type find_parent_path_size() const; - BOOST_FILESYSTEM_DECL string_type::size_type find_filename_v4_size() const; - BOOST_FILESYSTEM_DECL string_type::size_type find_extension_v4_size() const; - -private: /* * m_pathname has the type, encoding, and format required by the native * operating system. Thus for POSIX and Windows there is no conversion for @@ -993,8 +1171,6 @@ private: }; namespace detail { -BOOST_FILESYSTEM_DECL int lex_compare_v3(path::iterator first1, path::iterator last1, path::iterator first2, path::iterator last2); -BOOST_FILESYSTEM_DECL int lex_compare_v4(path::iterator first1, path::iterator last1, path::iterator first2, path::iterator last2); BOOST_FILESYSTEM_DECL path const& dot_path(); BOOST_FILESYSTEM_DECL path const& dot_dot_path(); } // namespace detail @@ -1003,13 +1179,15 @@ BOOST_FILESYSTEM_DECL path const& dot_dot_path(); typedef path wpath; #endif +namespace path_detail { + //------------------------------------------------------------------------------------// // class path::iterator // //------------------------------------------------------------------------------------// -class path::iterator : +class path_iterator : public boost::iterator_facade< - path::iterator, + path_iterator, const path, boost::bidirectional_traversal_tag > @@ -1017,24 +1195,18 @@ class path::iterator : private: friend class boost::iterator_core_access; friend class boost::filesystem::path; - friend class boost::filesystem::path::reverse_iterator; - friend BOOST_FILESYSTEM_DECL int detail::lex_compare_v3(path::iterator first1, path::iterator last1, path::iterator first2, path::iterator last2); + friend class path_reverse_iterator; + friend struct boost::filesystem::detail::path_algorithms; path const& dereference() const { return m_element; } - bool equal(iterator const& rhs) const + bool equal(path_iterator const& rhs) const BOOST_NOEXCEPT { return m_path_ptr == rhs.m_path_ptr && m_pos == rhs.m_pos; } - BOOST_FORCEINLINE void increment() { BOOST_FILESYSTEM_VERSIONED_SYM(increment)(); } - BOOST_FORCEINLINE void decrement() { BOOST_FILESYSTEM_VERSIONED_SYM(decrement)(); } - -private: - BOOST_FILESYSTEM_DECL void increment_v3(); - BOOST_FILESYSTEM_DECL void increment_v4(); - BOOST_FILESYSTEM_DECL void decrement_v3(); - BOOST_FILESYSTEM_DECL void decrement_v4(); + void increment(); + void decrement(); private: // current element @@ -1046,22 +1218,22 @@ private: // position of the last separator in the path. // end() iterator is indicated by // m_pos == m_path_ptr->m_pathname.size() - string_type::size_type m_pos; + path::string_type::size_type m_pos; }; //------------------------------------------------------------------------------------// // class path::reverse_iterator // //------------------------------------------------------------------------------------// -class path::reverse_iterator : +class path_reverse_iterator : public boost::iterator_facade< - path::reverse_iterator, + path_reverse_iterator, const path, boost::bidirectional_traversal_tag > { public: - explicit reverse_iterator(iterator itr) : + explicit path_reverse_iterator(path_iterator itr) : m_itr(itr) { if (itr != itr.m_path_ptr->begin()) @@ -1073,14 +1245,14 @@ private: friend class boost::filesystem::path; path const& dereference() const { return m_element; } - bool equal(reverse_iterator const& rhs) const { return m_itr == rhs.m_itr; } + bool equal(path_reverse_iterator const& rhs) const BOOST_NOEXCEPT { return m_itr == rhs.m_itr; } void increment() { --m_itr; if (m_itr != m_itr.m_path_ptr->begin()) { - iterator tmp = m_itr; + path_iterator tmp = m_itr; m_element = *--tmp; } } @@ -1092,99 +1264,209 @@ private: } private: - iterator m_itr; + path_iterator m_itr; path m_element; }; +// std::lexicographical_compare would infinitely recurse because path iterators +// yield paths, so provide a path aware version +bool lexicographical_compare(path_iterator first1, path_iterator const& last1, path_iterator first2, path_iterator const& last2); + +} // namespace path_detail + +using path_detail::lexicographical_compare; + //------------------------------------------------------------------------------------// // // // non-member functions // // // //------------------------------------------------------------------------------------// -// std::lexicographical_compare would infinitely recurse because path iterators -// yield paths, so provide a path aware version -inline bool lexicographical_compare(path::iterator first1, path::iterator last1, path::iterator first2, path::iterator last2) +BOOST_FORCEINLINE bool operator==(path const& lhs, path const& rhs) { - return BOOST_FILESYSTEM_VERSIONED_SYM(detail::lex_compare)(first1, last1, first2, last2) < 0; + return lhs.compare(rhs) == 0; } -inline bool operator==(path const& lhs, path const& rhs) +template< typename Path, typename Source > +BOOST_FORCEINLINE typename boost::enable_if_c< + boost::conjunction< + boost::is_same< Path, path >, + detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type > + >::value, + bool +>::type operator==(Path const& lhs, Source const& rhs) { return lhs.compare(rhs) == 0; } -inline bool operator==(path const& lhs, path::string_type const& rhs) +template< typename Source, typename Path > +BOOST_FORCEINLINE typename boost::enable_if_c< + boost::conjunction< + boost::is_same< Path, path >, + detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type > + >::value, + bool +>::type operator==(Source const& lhs, Path const& rhs) { - return lhs.compare(rhs) == 0; + return rhs.compare(lhs) == 0; } -inline bool operator==(path::string_type const& lhs, path const& rhs) +BOOST_FORCEINLINE bool operator!=(path const& lhs, path const& rhs) { - return rhs.compare(lhs) == 0; + return lhs.compare(rhs) != 0; } -inline bool operator==(path const& lhs, const path::value_type* rhs) +template< typename Path, typename Source > +BOOST_FORCEINLINE typename boost::enable_if_c< + boost::conjunction< + boost::is_same< Path, path >, + detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type > + >::value, + bool +>::type operator!=(Path const& lhs, Source const& rhs) { - return lhs.compare(rhs) == 0; + return lhs.compare(rhs) != 0; } -inline bool operator==(const path::value_type* lhs, path const& rhs) +template< typename Source, typename Path > +BOOST_FORCEINLINE typename boost::enable_if_c< + boost::conjunction< + boost::is_same< Path, path >, + detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type > + >::value, + bool +>::type operator!=(Source const& lhs, Path const& rhs) { - return rhs.compare(lhs) == 0; + return rhs.compare(lhs) != 0; } -inline bool operator!=(path const& lhs, path const& rhs) +BOOST_FORCEINLINE bool operator<(path const& lhs, path const& rhs) { - return lhs.compare(rhs) != 0; + return lhs.compare(rhs) < 0; } -inline bool operator!=(path const& lhs, path::string_type const& rhs) +template< typename Path, typename Source > +BOOST_FORCEINLINE typename boost::enable_if_c< + boost::conjunction< + boost::is_same< Path, path >, + detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type > + >::value, + bool +>::type operator<(Path const& lhs, Source const& rhs) { - return lhs.compare(rhs) != 0; + return lhs.compare(rhs) < 0; } -inline bool operator!=(path::string_type const& lhs, path const& rhs) +template< typename Source, typename Path > +BOOST_FORCEINLINE typename boost::enable_if_c< + boost::conjunction< + boost::is_same< Path, path >, + detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type > + >::value, + bool +>::type operator<(Source const& lhs, Path const& rhs) { - return rhs.compare(lhs) != 0; + return rhs.compare(lhs) > 0; } -inline bool operator!=(path const& lhs, const path::value_type* rhs) +BOOST_FORCEINLINE bool operator<=(path const& lhs, path const& rhs) { - return lhs.compare(rhs) != 0; + return lhs.compare(rhs) <= 0; } -inline bool operator!=(const path::value_type* lhs, path const& rhs) +template< typename Path, typename Source > +BOOST_FORCEINLINE typename boost::enable_if_c< + boost::conjunction< + boost::is_same< Path, path >, + detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type > + >::value, + bool +>::type operator<=(Path const& lhs, Source const& rhs) { - return rhs.compare(lhs) != 0; + return lhs.compare(rhs) <= 0; } -// TODO: why do == and != have additional overloads, but the others don't? +template< typename Source, typename Path > +BOOST_FORCEINLINE typename boost::enable_if_c< + boost::conjunction< + boost::is_same< Path, path >, + detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type > + >::value, + bool +>::type operator<=(Source const& lhs, Path const& rhs) +{ + return rhs.compare(lhs) >= 0; +} -inline bool operator<(path const& lhs, path const& rhs) +BOOST_FORCEINLINE bool operator>(path const& lhs, path const& rhs) { - return lhs.compare(rhs) < 0; + return lhs.compare(rhs) > 0; } -inline bool operator<=(path const& lhs, path const& rhs) + +template< typename Path, typename Source > +BOOST_FORCEINLINE typename boost::enable_if_c< + boost::conjunction< + boost::is_same< Path, path >, + detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type > + >::value, + bool +>::type operator>(Path const& lhs, Source const& rhs) +{ + return lhs.compare(rhs) > 0; +} + +template< typename Source, typename Path > +BOOST_FORCEINLINE typename boost::enable_if_c< + boost::conjunction< + boost::is_same< Path, path >, + detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type > + >::value, + bool +>::type operator>(Source const& lhs, Path const& rhs) +{ + return rhs.compare(lhs) < 0; +} + +BOOST_FORCEINLINE bool operator>=(path const& lhs, path const& rhs) { - return !(rhs < lhs); + return lhs.compare(rhs) >= 0; } -inline bool operator>(path const& lhs, path const& rhs) + +template< typename Path, typename Source > +BOOST_FORCEINLINE typename boost::enable_if_c< + boost::conjunction< + boost::is_same< Path, path >, + detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type > + >::value, + bool +>::type operator>=(Path const& lhs, Source const& rhs) { - return rhs < lhs; + return lhs.compare(rhs) >= 0; } -inline bool operator>=(path const& lhs, path const& rhs) + +template< typename Source, typename Path > +BOOST_FORCEINLINE typename boost::enable_if_c< + boost::conjunction< + boost::is_same< Path, path >, + detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type > + >::value, + bool +>::type operator>=(Source const& lhs, Path const& rhs) { - return !(lhs < rhs); + return rhs.compare(lhs) <= 0; } + // Note: Declared as a template to delay binding to Boost.ContainerHash functions and make the dependency optional -template< typename T > -inline typename boost::enable_if< boost::is_same< T, path >, std::size_t >::type hash_value(T const& p) BOOST_NOEXCEPT +template< typename Path > +inline typename boost::enable_if_c< + boost::is_same< Path, path >::value, + std::size_t +>::type hash_value(Path const& p) BOOST_NOEXCEPT { #ifdef BOOST_WINDOWS_API std::size_t seed = 0u; - for (typename T::value_type const* it = p.c_str(); *it; ++it) + for (typename Path::value_type const* it = p.c_str(); *it; ++it) hash_combine(seed, *it == L'/' ? L'\\' : *it); return seed; #else // BOOST_POSIX_API @@ -1197,33 +1479,34 @@ inline void swap(path& lhs, path& rhs) BOOST_NOEXCEPT lhs.swap(rhs); } -inline path operator/(path const& lhs, path const& rhs) +BOOST_FORCEINLINE path operator/(path lhs, path const& rhs) { - path p = lhs; - p /= rhs; - return p; + lhs.append(rhs); + return lhs; } -#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) -inline path operator/(path&& lhs, path const& rhs) +template< typename Source > +BOOST_FORCEINLINE typename boost::enable_if_c< + detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >::value, + path +>::type operator/(path lhs, Source const& rhs) { - lhs /= rhs; - return std::move(lhs); + lhs.append(rhs); + return lhs; } -#endif // inserters and extractors // use boost::io::quoted() to handle spaces in paths // use '&' as escape character to ease use for Windows paths -template< class Char, class Traits > +template< typename Char, typename Traits > inline std::basic_ostream< Char, Traits >& operator<<(std::basic_ostream< Char, Traits >& os, path const& p) { return os << boost::io::quoted(p.template string< std::basic_string< Char > >(), static_cast< Char >('&')); } -template< class Char, class Traits > +template< typename Char, typename Traits > inline std::basic_istream< Char, Traits >& operator>>(std::basic_istream< Char, Traits >& is, path& p) { @@ -1275,10 +1558,96 @@ inline bool is_element_separator(path::value_type c) BOOST_NOEXCEPT // class path miscellaneous function implementations // //------------------------------------------------------------------------------------// +namespace detail { + +inline bool path_algorithms::has_filename_v3(path const& p) +{ + return !p.m_pathname.empty(); +} + +inline bool path_algorithms::has_filename_v4(path const& p) +{ + return path_algorithms::find_filename_v4_size(p) > 0; +} + +inline path path_algorithms::filename_v4(path const& p) +{ + string_type::size_type filename_size = path_algorithms::find_filename_v4_size(p); + string_type::size_type pos = p.m_pathname.size() - filename_size; + const value_type* ptr = p.m_pathname.c_str() + pos; + return path(ptr, ptr + filename_size); +} + +inline path path_algorithms::extension_v4(path const& p) +{ + string_type::size_type extension_size = path_algorithms::find_extension_v4_size(p); + string_type::size_type pos = p.m_pathname.size() - extension_size; + const value_type* ptr = p.m_pathname.c_str() + pos; + return path(ptr, ptr + extension_size); +} + +inline void path_algorithms::append_v4(path& left, path const& right) +{ + path_algorithms::append_v4(left, right.m_pathname.c_str(), right.m_pathname.c_str() + right.m_pathname.size()); +} + +} // namespace detail + +// Note: Because of the range constructor in C++23 std::string_view that involves a check for contiguous_range concept, +// any non-template function call that requires a check whether the source argument (which may be fs::path) +// is convertible to std::string_view must be made after fs::path::iterator is defined. This includes overload +// resolution and SFINAE checks. Otherwise, the concept check result formally changes between fs::path::iterator +// is not defined and defined, which causes compilation errors with gcc 11 and later. +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106808 + +BOOST_FORCEINLINE path::compare_op::result_type path::compare_op::operator() (const value_type* source, const value_type* source_end, const codecvt_type*) const +{ + path src; + src.m_pathname.assign(source, source_end); + return m_self.compare(src); +} + +template< typename OtherChar > +BOOST_FORCEINLINE path::compare_op::result_type path::compare_op::operator() (const OtherChar* source, const OtherChar* source_end, const codecvt_type* cvt) const +{ + path src; + detail::path_traits::convert(source, source_end, src.m_pathname, cvt); + return m_self.compare(src); +} + +inline path& path::operator=(path const& p) +{ + return assign(p); +} + +inline path& path::operator+=(path const& p) +{ + return concat(p); +} + +BOOST_FORCEINLINE path& path::operator/=(path const& p) +{ + return append(p); +} + +#if !defined(BOOST_WINDOWS_API) +inline path path::generic_path() const +{ + return path(*this); +} +#endif + +inline path path::lexically_proximate(path const& base) const +{ + path tmp(lexically_relative(base)); + return tmp.empty() ? *this : tmp; +} + inline path::reverse_iterator path::rbegin() const { return reverse_iterator(end()); } + inline path::reverse_iterator path::rend() const { return reverse_iterator(begin()); @@ -1299,92 +1668,164 @@ inline bool path::filename_is_dot_dot() const // to deal with "c:.." edge case on Windows when ':' acts as a separator } +#if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) + +BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use path::lexically_normal() instead") +BOOST_FORCEINLINE path& path::normalize() +{ + path tmp(lexically_normal()); + m_pathname.swap(tmp.m_pathname); + return *this; +} + +#endif // !defined(BOOST_FILESYSTEM_NO_DEPRECATED) + +// The following functions are defined differently, depending on Boost.Filesystem version in use. +// To avoid ODR violation, these functions are not defined when the library itself is built. +// This makes sure they are not compiled when the library is built, and the only version there is +// is the one in user's code. Users are supposed to consistently use the same Boost.Filesystem version +// in all their translation units. +#if !defined(BOOST_FILESYSTEM_SOURCE) + +BOOST_FORCEINLINE path& path::append(path const& p) +{ + BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::append)(*this, p.m_pathname.data(), p.m_pathname.data() + p.m_pathname.size()); + return *this; +} + +BOOST_FORCEINLINE path& path::append(path const& p, codecvt_type const&) +{ + BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::append)(*this, p.m_pathname.data(), p.m_pathname.data() + p.m_pathname.size()); + return *this; +} + +BOOST_FORCEINLINE path& path::append(const value_type* begin, const value_type* end) +{ + BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::append)(*this, begin, end); + return *this; +} + +BOOST_FORCEINLINE path& path::append(const value_type* begin, const value_type* end, codecvt_type const&) +{ + BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::append)(*this, begin, end); + return *this; +} + +BOOST_FORCEINLINE path& path::remove_filename() +{ + BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::remove_filename)(*this); + return *this; +} + +BOOST_FORCEINLINE path& path::replace_extension(path const& new_extension) +{ + BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::replace_extension)(*this, new_extension); + return *this; +} + +BOOST_FORCEINLINE int path::compare(path const& p) const +{ + return BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::compare)(*this, p); +} + +BOOST_FORCEINLINE path path::filename() const +{ + return BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::filename)(*this); +} + +BOOST_FORCEINLINE path path::stem() const +{ + return BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::stem)(*this); +} + +BOOST_FORCEINLINE path path::extension() const +{ + return BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::extension)(*this); +} + +BOOST_FORCEINLINE bool path::has_filename() const +{ + return BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::has_filename)(*this); +} + +BOOST_FORCEINLINE path path::lexically_normal() const +{ + return BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::lexically_normal)(*this); +} + +namespace path_detail { + +BOOST_FORCEINLINE void path_iterator::increment() +{ + BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::increment)(*this); +} + +BOOST_FORCEINLINE void path_iterator::decrement() +{ + BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::decrement)(*this); +} + +BOOST_FORCEINLINE bool lexicographical_compare(path_iterator first1, path_iterator const& last1, path_iterator first2, path_iterator const& last2) +{ + return BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::lex_compare)(first1, last1, first2, last2) < 0; +} + +} // namespace path_detail + +#endif // !defined(BOOST_FILESYSTEM_SOURCE) + //--------------------------------------------------------------------------------------// // class path member template specializations // //--------------------------------------------------------------------------------------// -template<> +template< > inline std::string path::string< std::string >() const { return string(); } -template<> +template< > inline std::wstring path::string< std::wstring >() const { return wstring(); } -template<> -inline std::string path::string< std::string >(const codecvt_type& cvt) const +template< > +inline std::string path::string< std::string >(codecvt_type const& cvt) const { return string(cvt); } -template<> -inline std::wstring path::string< std::wstring >(const codecvt_type& cvt) const +template< > +inline std::wstring path::string< std::wstring >(codecvt_type const& cvt) const { return wstring(cvt); } -template<> +template< > inline std::string path::generic_string< std::string >() const { return generic_string(); } -template<> +template< > inline std::wstring path::generic_string< std::wstring >() const { return generic_wstring(); } -template<> +template< > inline std::string path::generic_string< std::string >(codecvt_type const& cvt) const { return generic_string(cvt); } -template<> +template< > inline std::wstring path::generic_string< std::wstring >(codecvt_type const& cvt) const { return generic_wstring(cvt); } -//--------------------------------------------------------------------------------------// -// path_traits convert function implementations // -// requiring path::codecvt() be visable // -//--------------------------------------------------------------------------------------// - -namespace path_traits { // without codecvt - -inline void convert(const char* from, - const char* from_end, // NULL for null terminated MBCS - std::wstring& to) -{ - convert(from, from_end, to, path::codecvt()); -} - -inline void convert(const wchar_t* from, - const wchar_t* from_end, // NULL for null terminated MBCS - std::string& to) -{ - convert(from, from_end, to, path::codecvt()); -} - -inline void convert(const char* from, std::wstring& to) -{ - BOOST_ASSERT(!!from); - convert(from, NULL, to, path::codecvt()); -} - -inline void convert(const wchar_t* from, std::string& to) -{ - BOOST_ASSERT(!!from); - convert(from, NULL, to, path::codecvt()); -} - -} // namespace path_traits } // namespace filesystem } // namespace boost diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/path_traits.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/path_traits.hpp deleted file mode 100644 index e4f9b52c0d..0000000000 --- a/contrib/restricted/boost/filesystem/include/boost/filesystem/path_traits.hpp +++ /dev/null @@ -1,384 +0,0 @@ -// filesystem path_traits.hpp --------------------------------------------------------// - -// Copyright Beman Dawes 2009 - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// Library home page: http://www.boost.org/libs/filesystem - -#ifndef BOOST_FILESYSTEM_PATH_TRAITS_HPP -#define BOOST_FILESYSTEM_PATH_TRAITS_HPP - -#include <boost/filesystem/config.hpp> -#include <boost/system/error_category.hpp> -#include <boost/type_traits/is_array.hpp> -#include <boost/type_traits/decay.hpp> -#include <boost/core/enable_if.hpp> -#include <cstddef> -#include <cwchar> // for mbstate_t -#include <string> -#include <vector> -#include <list> -#include <iterator> -#include <locale> -#include <boost/assert.hpp> - -#include <boost/filesystem/detail/header.hpp> // must be the last #include - -namespace boost { -namespace filesystem { - -BOOST_FILESYSTEM_DECL system::error_category const& codecvt_error_category() BOOST_NOEXCEPT; -// uses std::codecvt_base::result used for error codes: -// -// ok: Conversion successful. -// partial: Not all source characters converted; one or more additional source -// characters are needed to produce the final target character, or the -// size of the target intermediate buffer was too small to hold the result. -// error: A character in the source could not be converted to the target encoding. -// noconv: The source and target characters have the same type and encoding, so no -// conversion was necessary. - -class directory_entry; - -namespace path_traits { - -typedef std::codecvt< wchar_t, char, std::mbstate_t > codecvt_type; - -// is_pathable type trait; allows disabling over-agressive class path member templates - -template< class T > -struct is_pathable -{ - static const bool value = false; -}; - -template<> -struct is_pathable< char* > -{ - static const bool value = true; -}; - -template<> -struct is_pathable< const char* > -{ - static const bool value = true; -}; - -template<> -struct is_pathable< wchar_t* > -{ - static const bool value = true; -}; - -template<> -struct is_pathable< const wchar_t* > -{ - static const bool value = true; -}; - -template<> -struct is_pathable< std::string > -{ - static const bool value = true; -}; - -template<> -struct is_pathable< std::wstring > -{ - static const bool value = true; -}; - -template<> -struct is_pathable< std::vector< char > > -{ - static const bool value = true; -}; - -template<> -struct is_pathable< std::vector< wchar_t > > -{ - static const bool value = true; -}; - -template<> -struct is_pathable< std::list< char > > -{ - static const bool value = true; -}; - -template<> -struct is_pathable< std::list< wchar_t > > -{ - static const bool value = true; -}; - -template<> -struct is_pathable< directory_entry > -{ - static const bool value = true; -}; - -// Pathable empty - -template< class Container > -inline - // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for - // conforming compilers. Replace by plain "bool" at some future date (2012?) - typename boost::disable_if< boost::is_array< Container >, bool >::type - empty(Container const& c) -{ - return c.begin() == c.end(); -} - -template< class T > -inline bool empty(T* const& c_str) -{ - BOOST_ASSERT(c_str); - return !*c_str; -} - -template< typename T, std::size_t N > -inline bool empty(T (&x)[N]) -{ - return !x[0]; -} - -// value types differ ---------------------------------------------------------------// -// -// A from_end argument of NULL is less efficient than a known end, so use only if needed - -// with codecvt - -BOOST_FILESYSTEM_DECL -void convert(const char* from, - const char* from_end, // NULL for null terminated MBCS - std::wstring& to, codecvt_type const& cvt); - -BOOST_FILESYSTEM_DECL -void convert(const wchar_t* from, - const wchar_t* from_end, // NULL for null terminated MBCS - std::string& to, codecvt_type const& cvt); - -inline void convert(const char* from, std::wstring& to, codecvt_type const& cvt) -{ - BOOST_ASSERT(from); - convert(from, NULL, to, cvt); -} - -inline void convert(const wchar_t* from, std::string& to, codecvt_type const& cvt) -{ - BOOST_ASSERT(from); - convert(from, NULL, to, cvt); -} - -// without codecvt - -inline void convert(const char* from, - const char* from_end, // NULL for null terminated MBCS - std::wstring& to); - -inline void convert(const wchar_t* from, - const wchar_t* from_end, // NULL for null terminated MBCS - std::string& to); - -inline void convert(const char* from, std::wstring& to); - -inline void convert(const wchar_t* from, std::string& to); - -// value types same -----------------------------------------------------------------// - -// char with codecvt - -inline void convert(const char* from, const char* from_end, std::string& to, codecvt_type const&) -{ - BOOST_ASSERT(from); - BOOST_ASSERT(from_end); - to.append(from, from_end); -} - -inline void convert(const char* from, std::string& to, codecvt_type const&) -{ - BOOST_ASSERT(from); - to += from; -} - -// wchar_t with codecvt - -inline void convert(const wchar_t* from, const wchar_t* from_end, std::wstring& to, codecvt_type const&) -{ - BOOST_ASSERT(from); - BOOST_ASSERT(from_end); - to.append(from, from_end); -} - -inline void convert(const wchar_t* from, std::wstring& to, codecvt_type const&) -{ - BOOST_ASSERT(from); - to += from; -} - -// char without codecvt - -inline void convert(const char* from, const char* from_end, std::string& to) -{ - BOOST_ASSERT(from); - BOOST_ASSERT(from_end); - to.append(from, from_end); -} - -inline void convert(const char* from, std::string& to) -{ - BOOST_ASSERT(from); - to += from; -} - -// wchar_t without codecvt - -inline void convert(const wchar_t* from, const wchar_t* from_end, std::wstring& to) -{ - BOOST_ASSERT(from); - BOOST_ASSERT(from_end); - to.append(from, from_end); -} - -inline void convert(const wchar_t* from, std::wstring& to) -{ - BOOST_ASSERT(from); - to += from; -} - -// Source dispatch -----------------------------------------------------------------// - -// contiguous containers with codecvt -template< class U > -inline void dispatch(std::string const& c, U& to, codecvt_type const& cvt) -{ - if (!c.empty()) - convert(&*c.begin(), &*c.begin() + c.size(), to, cvt); -} -template< class U > -inline void dispatch(std::wstring const& c, U& to, codecvt_type const& cvt) -{ - if (!c.empty()) - convert(&*c.begin(), &*c.begin() + c.size(), to, cvt); -} -template< class U > -inline void dispatch(std::vector< char > const& c, U& to, codecvt_type const& cvt) -{ - if (!c.empty()) - convert(&*c.begin(), &*c.begin() + c.size(), to, cvt); -} -template< class U > -inline void dispatch(std::vector< wchar_t > const& c, U& to, codecvt_type const& cvt) -{ - if (!c.empty()) - convert(&*c.begin(), &*c.begin() + c.size(), to, cvt); -} - -// contiguous containers without codecvt -template< class U > -inline void dispatch(std::string const& c, U& to) -{ - if (!c.empty()) - convert(&*c.begin(), &*c.begin() + c.size(), to); -} -template< class U > -inline void dispatch(std::wstring const& c, U& to) -{ - if (!c.empty()) - convert(&*c.begin(), &*c.begin() + c.size(), to); -} -template< class U > -inline void dispatch(std::vector< char > const& c, U& to) -{ - if (!c.empty()) - convert(&*c.begin(), &*c.begin() + c.size(), to); -} -template< class U > -inline void dispatch(std::vector< wchar_t > const& c, U& to) -{ - if (!c.empty()) - convert(&*c.begin(), &*c.begin() + c.size(), to); -} - -// non-contiguous containers with codecvt -template< class Container, class U > -inline - // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for - // conforming compilers. Replace by plain "void" at some future date (2012?) - typename boost::disable_if< boost::is_array< Container >, void >::type - dispatch(Container const& c, U& to, codecvt_type const& cvt) -{ - if (!c.empty()) - { - std::basic_string< typename Container::value_type > s(c.begin(), c.end()); - convert(s.c_str(), s.c_str() + s.size(), to, cvt); - } -} - -// c_str -template< class T, class U > -inline void dispatch(T* const& c_str, U& to, codecvt_type const& cvt) -{ - // std::cout << "dispatch() const T *\n"; - BOOST_ASSERT(c_str); - convert(c_str, to, cvt); -} - -// Note: there is no dispatch on C-style arrays because the array may -// contain a string smaller than the array size. - -BOOST_FILESYSTEM_DECL -void dispatch(directory_entry const& de, -#ifdef BOOST_WINDOWS_API - std::wstring& to, -#else - std::string& to, -#endif - codecvt_type const&); - -// non-contiguous containers without codecvt -template< class Container, class U > -inline - // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for - // conforming compilers. Replace by plain "void" at some future date (2012?) - typename boost::disable_if< boost::is_array< Container >, void >::type - dispatch(Container const& c, U& to) -{ - if (!c.empty()) - { - std::basic_string< typename Container::value_type > seq(c.begin(), c.end()); - convert(seq.c_str(), seq.c_str() + seq.size(), to); - } -} - -// c_str -template< class T, class U > -inline void dispatch(T* const& c_str, U& to) -{ - // std::cout << "dispatch() const T *\n"; - BOOST_ASSERT(c_str); - convert(c_str, to); -} - -// Note: there is no dispatch on C-style arrays because the array may -// contain a string smaller than the array size. - -BOOST_FILESYSTEM_DECL -void dispatch(directory_entry const& de, -#ifdef BOOST_WINDOWS_API - std::wstring& to -#else - std::string& to -#endif -); - -} // namespace path_traits -} // namespace filesystem -} // namespace boost - -#include <boost/filesystem/detail/footer.hpp> - -#endif // BOOST_FILESYSTEM_PATH_TRAITS_HPP diff --git a/contrib/restricted/boost/filesystem/src/codecvt_error_category.cpp b/contrib/restricted/boost/filesystem/src/codecvt_error_category.cpp index 72db677a09..a8d2a42732 100644 --- a/contrib/restricted/boost/filesystem/src/codecvt_error_category.cpp +++ b/contrib/restricted/boost/filesystem/src/codecvt_error_category.cpp @@ -15,7 +15,7 @@ #include <boost/config/warning_disable.hpp> #include <boost/filesystem/config.hpp> -#include <boost/filesystem/path_traits.hpp> +#include <boost/filesystem/detail/path_traits.hpp> #include <boost/system/error_category.hpp> #include <locale> #include <string> diff --git a/contrib/restricted/boost/filesystem/src/directory.cpp b/contrib/restricted/boost/filesystem/src/directory.cpp index 6a3e1dc731..f769f8fc18 100644 --- a/contrib/restricted/boost/filesystem/src/directory.cpp +++ b/contrib/restricted/boost/filesystem/src/directory.cpp @@ -74,15 +74,6 @@ #include <boost/filesystem/detail/header.hpp> // must be the last #include -// BOOST_FILESYSTEM_STATUS_CACHE enables file_status cache in -// dir_itr_increment. The config tests are placed here because some of the -// macros being tested come from dirent.h. -// -// TODO: find out what macros indicate dirent::d_type present in more libraries -#if defined(BOOST_WINDOWS_API) || defined(_DIRENT_HAVE_D_TYPE) // defined by GNU C library if d_type present -#define BOOST_FILESYSTEM_STATUS_CACHE -#endif - namespace fs = boost::filesystem; using boost::system::error_code; using boost::system::system_category; @@ -96,76 +87,34 @@ namespace filesystem { // // //--------------------------------------------------------------------------------------// -BOOST_FILESYSTEM_DECL -file_status directory_entry::get_status(system::error_code* ec) const +BOOST_FILESYSTEM_DECL void directory_entry::refresh_impl(system::error_code* ec) const { - if (!status_known(m_status)) + system::error_code local_ec; + m_symlink_status = detail::symlink_status(m_path, &local_ec); + + if (!filesystem::is_symlink(m_symlink_status)) { - // optimization: if the symlink status is known, and it isn't a symlink, - // then status and symlink_status are identical so just copy the - // symlink status to the regular status. - if (status_known(m_symlink_status) && !is_symlink(m_symlink_status)) - { - m_status = m_symlink_status; - if (ec) - ec->clear(); - } - else + // Also works if symlink_status fails - set m_status to status_error as well + m_status = m_symlink_status; + + if (BOOST_UNLIKELY(!!local_ec)) { - m_status = detail::status(m_path, ec); + if (!ec) + BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::directory_entry::refresh", m_path, local_ec)); + + *ec = local_ec; + return; } + + if (ec) + ec->clear(); } - else if (ec) + else { - ec->clear(); + m_status = detail::status(m_path, ec); } - - return m_status; } -BOOST_FILESYSTEM_DECL -file_status directory_entry::get_symlink_status(system::error_code* ec) const -{ - if (!status_known(m_symlink_status)) - m_symlink_status = detail::symlink_status(m_path, ec); - else if (ec) - ec->clear(); - - return m_symlink_status; -} - -// dispatch directory_entry supplied here rather than in -// <boost/filesystem/path_traits.hpp>, thus avoiding header circularity. -// test cases are in operations_unit_test.cpp - -namespace path_traits { - -BOOST_FILESYSTEM_DECL -void dispatch(directory_entry const& de, -#ifdef BOOST_WINDOWS_API - std::wstring& to, -#else - std::string& to, -#endif - codecvt_type const&) -{ - to = de.path().native(); -} - -BOOST_FILESYSTEM_DECL -void dispatch(directory_entry const& de, -#ifdef BOOST_WINDOWS_API - std::wstring& to -#else - std::string& to -#endif -) -{ - to = de.path().native(); -} - -} // namespace path_traits - //--------------------------------------------------------------------------------------// // // // directory_iterator // @@ -353,24 +302,43 @@ error_code dir_itr_increment(dir_itr_imp& imp, fs::path& filename, fs::file_stat filename = result->d_name; -#ifdef BOOST_FILESYSTEM_STATUS_CACHE +#if defined(BOOST_FILESYSTEM_HAS_DIRENT_D_TYPE) if (result->d_type == DT_UNKNOWN) // filesystem does not supply d_type value { sf = symlink_sf = fs::file_status(fs::status_error); } else // filesystem supplies d_type value { - if (result->d_type == DT_DIR) - sf = symlink_sf = fs::file_status(fs::directory_file); - else if (result->d_type == DT_REG) + if (result->d_type == DT_REG) sf = symlink_sf = fs::file_status(fs::regular_file); + else if (result->d_type == DT_DIR) + sf = symlink_sf = fs::file_status(fs::directory_file); else if (result->d_type == DT_LNK) { sf = fs::file_status(fs::status_error); symlink_sf = fs::file_status(fs::symlink_file); } else - sf = symlink_sf = fs::file_status(fs::status_error); + { + switch (result->d_type) + { + case DT_SOCK: + sf = symlink_sf = fs::file_status(fs::socket_file); + break; + case DT_FIFO: + sf = symlink_sf = fs::file_status(fs::fifo_file); + break; + case DT_BLK: + sf = symlink_sf = fs::file_status(fs::block_file); + break; + case DT_CHR: + sf = symlink_sf = fs::file_status(fs::character_file); + break; + default: + sf = symlink_sf = fs::file_status(fs::status_error); + break; + } + } } #else sf = symlink_sf = fs::file_status(fs::status_error); @@ -599,9 +567,12 @@ extra_data_format g_extra_data_format = file_directory_information_format; * \brief Extra buffer size for GetFileInformationByHandleEx-based or NtQueryDirectoryFile-based directory iterator. * * Must be large enough to accommodate at least one FILE_DIRECTORY_INFORMATION or *_DIR_INFO struct and one filename. - * NTFS, VFAT, exFAT support filenames up to 255 UTF-16/UCS-2 characters. ReFS supports filenames up to 32768 UTF-16 characters. + * NTFS, VFAT, exFAT and ReFS support filenames up to 255 UTF-16/UCS-2 characters. (For ReFS, there is no information + * on the on-disk format, and it is possible that it supports longer filenames, up to 32768 UTF-16/UCS-2 characters.) + * The buffer cannot be larger than 64k, because up to Windows 8.1, NtQueryDirectoryFile and GetFileInformationByHandleEx + * fail with ERROR_INVALID_PARAMETER when trying to retrieve the filenames from a network share. */ -BOOST_CONSTEXPR_OR_CONST std::size_t dir_itr_extra_size = sizeof(file_id_extd_dir_info) + 65536u; +BOOST_CONSTEXPR_OR_CONST std::size_t dir_itr_extra_size = 65536u; inline system::error_code dir_itr_close(dir_itr_imp& imp) BOOST_NOEXCEPT { @@ -763,6 +734,28 @@ done: return error_code(); } +//! Returns \c true if the error code indicates that the OS or the filesystem does not support a particular directory info class +inline bool is_dir_info_class_not_supported(DWORD error) +{ + // Some mounted filesystems may not support FILE_ID_128 identifiers, which will cause + // GetFileInformationByHandleEx(FileIdExtdDirectoryRestartInfo) return ERROR_INVALID_PARAMETER, + // even though in general the operation is supported by the kernel. SMBv1 returns a special error + // code ERROR_INVALID_LEVEL in this case. + // Some other filesystems also don't implement other info classes and return ERROR_INVALID_PARAMETER + // (e.g. see https://github.com/boostorg/filesystem/issues/266), ERROR_GEN_FAILURE, ERROR_INVALID_FUNCTION + // or ERROR_INTERNAL_ERROR (https://github.com/boostorg/filesystem/issues/286). Treat these error codes + // as "non-permanent", even though ERROR_INVALID_PARAMETER is also returned if GetFileInformationByHandleEx + // in general does not support a certain info class. Worst case, we will make extra syscalls on directory + // iterator construction. + // Also note that Wine returns ERROR_CALL_NOT_IMPLEMENTED for unimplemented info classes, and + // up until 7.21 it didn't implement FileIdExtdDirectoryRestartInfo and FileFullDirectoryRestartInfo. + // (https://bugs.winehq.org/show_bug.cgi?id=53590) + return error == ERROR_NOT_SUPPORTED || error == ERROR_INVALID_PARAMETER || + error == ERROR_INVALID_LEVEL || error == ERROR_CALL_NOT_IMPLEMENTED || + error == ERROR_GEN_FAILURE || error == ERROR_INVALID_FUNCTION || + error == ERROR_INTERNAL_ERROR; +} + error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs::path const& dir, unsigned int opts, directory_iterator_params* params, fs::path& first_filename, fs::file_status& sf, fs::file_status& symlink_sf) { boost::intrusive_ptr< detail::dir_itr_imp > pimpl(new (dir_itr_extra_size) detail::dir_itr_imp()); @@ -828,9 +821,14 @@ error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs:: if (BOOST_UNLIKELY((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0u)) return make_error_code(system::errc::not_a_directory); - if ((opts & static_cast< unsigned int >(directory_options::_detail_no_follow)) != 0u) + if ((opts & static_cast< unsigned int >(directory_options::_detail_no_follow)) != 0u && (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0u) { - if ((info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0u && is_reparse_point_a_symlink_ioctl(h.handle)) + error_code ec; + const ULONG reparse_point_tag = detail::get_reparse_point_tag_ioctl(h.handle, dir, &ec); + if (BOOST_UNLIKELY(!!ec)) + return ec; + + if (detail::is_reparse_point_tag_a_symlink(reparse_point_tag)) return make_error_code(system::errc::too_many_symbolic_link_levels); } } @@ -845,14 +843,10 @@ error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs:: { DWORD error = ::GetLastError(); - if (error == ERROR_NOT_SUPPORTED || error == ERROR_INVALID_PARAMETER) + if (is_dir_info_class_not_supported(error)) { // Fall back to file_full_dir_info_format. - // Note that some mounted filesystems may not support FILE_ID_128 identifiers, which will cause - // GetFileInformationByHandleEx(FileIdExtdDirectoryRestartInfo) return ERROR_INVALID_PARAMETER, - // even though in general the operation is supported by the kernel. So don't downgrade to - // FileFullDirectoryRestartInfo permanently in this case - only for this particular iterator. - if (error == ERROR_NOT_SUPPORTED) + if (error == ERROR_NOT_SUPPORTED || error == ERROR_CALL_NOT_IMPLEMENTED) filesystem::detail::atomic_store_relaxed(g_extra_data_format, file_full_dir_info_format); goto fallback_to_file_full_dir_info_format; } @@ -879,11 +873,12 @@ error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs:: { DWORD error = ::GetLastError(); - if (error == ERROR_NOT_SUPPORTED || error == ERROR_INVALID_PARAMETER) + if (is_dir_info_class_not_supported(error)) { // Fall back to file_id_both_dir_info - filesystem::detail::atomic_store_relaxed(g_extra_data_format, file_id_both_dir_info_format); - goto fallback_to_file_id_both_dir_info; + if (error == ERROR_NOT_SUPPORTED || error == ERROR_CALL_NOT_IMPLEMENTED) + filesystem::detail::atomic_store_relaxed(g_extra_data_format, file_id_both_dir_info_format); + goto fallback_to_file_id_both_dir_info_format; } if (error == ERROR_NO_MORE_FILES || error == ERROR_FILE_NOT_FOUND) @@ -902,12 +897,20 @@ error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs:: break; case file_id_both_dir_info_format: - fallback_to_file_id_both_dir_info: + fallback_to_file_id_both_dir_info_format: { if (!get_file_information_by_handle_ex(iterator_handle, file_id_both_directory_restart_info_class, extra_data, dir_itr_extra_size)) { DWORD error = ::GetLastError(); + if (is_dir_info_class_not_supported(error)) + { + // Fall back to file_directory_information + if (error == ERROR_NOT_SUPPORTED || error == ERROR_CALL_NOT_IMPLEMENTED) + filesystem::detail::atomic_store_relaxed(g_extra_data_format, file_directory_information_format); + goto fallback_to_file_directory_information_format; + } + if (error == ERROR_NO_MORE_FILES || error == ERROR_FILE_NOT_FOUND) goto done; @@ -924,6 +927,7 @@ error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs:: break; default: + fallback_to_file_directory_information_format: { NtQueryDirectoryFile_t* nt_query_directory_file = filesystem::detail::atomic_load_relaxed(boost::filesystem::detail::nt_query_directory_file_api); if (BOOST_UNLIKELY(!nt_query_directory_file)) @@ -1120,7 +1124,18 @@ void directory_iterator_construct(directory_iterator& it, path const& p, unsigne && (filename_str[1] == static_cast< path::string_type::value_type >('\0') || (filename_str[1] == path::dot && filename_str[2] == static_cast< path::string_type::value_type >('\0'))))) { - imp->dir_entry.assign(p / filename, file_stat, symlink_file_stat); + path full_path(p); + path_algorithms::append_v4(full_path, filename); + imp->dir_entry.assign_with_status + ( +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + static_cast< path&& >(full_path), +#else + full_path, +#endif + file_stat, + symlink_file_stat + ); it.m_imp.swap(imp); return; } @@ -1180,7 +1195,7 @@ void directory_iterator_increment(directory_iterator& it, system::error_code* ec && (filename_str[1] == static_cast< path::string_type::value_type >('\0') || (filename_str[1] == path::dot && filename_str[2] == static_cast< path::string_type::value_type >('\0'))))) { - it.m_imp->dir_entry.replace_filename(filename, file_stat, symlink_file_stat); + it.m_imp->dir_entry.replace_filename_with_status(filename, file_stat, symlink_file_stat); return; } } @@ -1344,14 +1359,14 @@ inline push_directory_result recursive_directory_iterator_push_directory(detail: return result; } - file_status symlink_stat; + file_type symlink_ft = status_error; // If we are not recursing into symlinks, we are going to have to know if the // stack top is a symlink, so get symlink_status and verify no error occurred. if ((imp->m_options & static_cast< unsigned int >(directory_options::follow_directory_symlink)) == 0u || (imp->m_options & static_cast< unsigned int >(directory_options::skip_dangling_symlinks)) != 0u) { - symlink_stat = imp->m_stack.back()->symlink_status(ec); + symlink_ft = imp->m_stack.back()->symlink_file_type(ec); if (ec) return result; } @@ -1364,12 +1379,12 @@ inline push_directory_result recursive_directory_iterator_push_directory(detail: // The predicate code has since been rewritten to pass error_code arguments, // per ticket #5653. - if ((imp->m_options & static_cast< unsigned int >(directory_options::follow_directory_symlink)) != 0u || !fs::is_symlink(symlink_stat)) + if ((imp->m_options & static_cast< unsigned int >(directory_options::follow_directory_symlink)) != 0u || symlink_ft != symlink_file) { - file_status stat = imp->m_stack.back()->status(ec); + file_type ft = imp->m_stack.back()->file_type(ec); if (BOOST_UNLIKELY(!!ec)) { - if (ec == make_error_condition(system::errc::no_such_file_or_directory) && fs::is_symlink(symlink_stat) && + if (ec == make_error_condition(system::errc::no_such_file_or_directory) && symlink_ft == symlink_file && (imp->m_options & static_cast< unsigned int >(directory_options::follow_directory_symlink | directory_options::skip_dangling_symlinks)) == static_cast< unsigned int >(directory_options::follow_directory_symlink | directory_options::skip_dangling_symlinks)) { // Skip dangling symlink and continue iteration on the current depth level @@ -1379,7 +1394,7 @@ inline push_directory_result recursive_directory_iterator_push_directory(detail: return result; } - if (!fs::is_directory(stat)) + if (ft != directory_file) return result; if (BOOST_UNLIKELY((imp->m_stack.size() - 1u) >= static_cast< std::size_t >((std::numeric_limits< int >::max)()))) diff --git a/contrib/restricted/boost/filesystem/src/operations.cpp b/contrib/restricted/boost/filesystem/src/operations.cpp index dd636e9063..c7808d5941 100644 --- a/contrib/restricted/boost/filesystem/src/operations.cpp +++ b/contrib/restricted/boost/filesystem/src/operations.cpp @@ -70,7 +70,7 @@ #include <unistd.h> #include <fcntl.h> -#if _POSIX_C_SOURCE < 200809L +#if !defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS) #include <utime.h> #endif #include <limits.h> @@ -1116,7 +1116,7 @@ uintmax_t remove_all_impl count += fs::detail::remove_all_impl ( #if defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) && defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS) - itr->path().filename(), + path_algorithms::filename_v4(itr->path()), #else itr->path(), #endif @@ -1511,50 +1511,36 @@ boost::winapi::NTSTATUS_ nt_create_file_handle_at(HANDLE& out, HANDLE basedir_ha #endif // !defined(UNDER_CE) -bool is_reparse_point_a_symlink_ioctl(HANDLE h) +ULONG get_reparse_point_tag_ioctl(HANDLE h, path const& p, error_code* ec) { - boost::scoped_ptr< reparse_data_buffer_with_storage > buf(new reparse_data_buffer_with_storage); + boost::scoped_ptr< reparse_data_buffer_with_storage > buf(new (std::nothrow) reparse_data_buffer_with_storage); + if (BOOST_UNLIKELY(!buf.get())) + { + if (!ec) + BOOST_FILESYSTEM_THROW(filesystem_error("Cannot allocate memory to query reparse point", p, make_error_code(system::errc::not_enough_memory))); + + *ec = make_error_code(system::errc::not_enough_memory); + return 0u; + } // Query the reparse data DWORD dwRetLen = 0u; BOOL result = ::DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, NULL, 0, buf.get(), sizeof(*buf), &dwRetLen, NULL); if (BOOST_UNLIKELY(!result)) - return false; - - return is_reparse_point_tag_a_symlink(buf->rdb.ReparseTag); -} - -namespace { - -inline bool is_reparse_point_a_symlink(path const& p) -{ - handle_wrapper h(create_file_handle( - p, - FILE_READ_ATTRIBUTES, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT)); - if (BOOST_UNLIKELY(h.handle == INVALID_HANDLE_VALUE)) - return false; - - GetFileInformationByHandleEx_t* get_file_information_by_handle_ex = filesystem::detail::atomic_load_relaxed(get_file_information_by_handle_ex_api); - if (BOOST_LIKELY(get_file_information_by_handle_ex != NULL)) { - file_attribute_tag_info info; - BOOL result = get_file_information_by_handle_ex(h.handle, file_attribute_tag_info_class, &info, sizeof(info)); - if (BOOST_UNLIKELY(!result)) - return false; - - if ((info.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0u) - return false; + DWORD err = ::GetLastError(); + if (!ec) + BOOST_FILESYSTEM_THROW(filesystem_error("Failed to query reparse point", p, error_code(err, system_category()))); - return is_reparse_point_tag_a_symlink(info.ReparseTag); + ec->assign(err, system_category()); + return 0u; } - return is_reparse_point_a_symlink_ioctl(h.handle); + return buf->rdb.ReparseTag; } +namespace { + inline std::size_t get_full_path_name(path const& src, std::size_t len, wchar_t* buf, wchar_t** p) { return static_cast< std::size_t >(::GetFullPathNameW(src.c_str(), static_cast< DWORD >(len), buf, p)); @@ -1590,6 +1576,7 @@ fs::file_status status_by_handle(HANDLE h, path const& p, error_code* ec) { fs::file_type ftype; DWORD attrs; + ULONG reparse_tag = 0u; GetFileInformationByHandleEx_t* get_file_information_by_handle_ex = filesystem::detail::atomic_load_relaxed(get_file_information_by_handle_ex_api); if (BOOST_LIKELY(get_file_information_by_handle_ex != NULL)) { @@ -1609,12 +1596,7 @@ fs::file_status status_by_handle(HANDLE h, path const& p, error_code* ec) } attrs = info.FileAttributes; - - if (attrs & FILE_ATTRIBUTE_REPARSE_POINT) - { - ftype = is_reparse_point_tag_a_symlink(info.ReparseTag) ? fs::symlink_file : fs::reparse_file; - goto done; - } + reparse_tag = info.ReparseTag; } else { @@ -1626,25 +1608,48 @@ fs::file_status status_by_handle(HANDLE h, path const& p, error_code* ec) attrs = info.dwFileAttributes; - if (attrs & FILE_ATTRIBUTE_REPARSE_POINT) + if ((attrs & FILE_ATTRIBUTE_REPARSE_POINT) != 0u) { - ftype = is_reparse_point_a_symlink_ioctl(h) ? fs::symlink_file : fs::reparse_file; - goto done; + reparse_tag = get_reparse_point_tag_ioctl(h, p, ec); + if (ec) + { + if (BOOST_UNLIKELY(!!ec)) + return fs::file_status(fs::status_error); + } } } - ftype = (attrs & FILE_ATTRIBUTE_DIRECTORY) ? fs::directory_file : fs::regular_file; + if ((attrs & FILE_ATTRIBUTE_REPARSE_POINT) != 0u) + { + if (reparse_tag == IO_REPARSE_TAG_DEDUP) + ftype = fs::regular_file; + else if (is_reparse_point_tag_a_symlink(reparse_tag)) + ftype = fs::symlink_file; + else + ftype = fs::reparse_file; + } + else if ((attrs & FILE_ATTRIBUTE_DIRECTORY) != 0u) + { + ftype = fs::directory_file; + } + else + { + ftype = fs::regular_file; + } -done: return fs::file_status(ftype, make_permissions(p, attrs)); } //! symlink_status() implementation fs::file_status symlink_status_impl(path const& p, error_code* ec) { + // Normally, we only need FILE_READ_ATTRIBUTES access mode. But SMBv1 reports incorrect + // file attributes in GetFileInformationByHandleEx in this case (e.g. it reports FILE_ATTRIBUTE_NORMAL + // for a directory in a SMBv1 share), so we add FILE_READ_EA as a workaround. + // https://github.com/boostorg/filesystem/issues/282 handle_wrapper h(create_file_handle( p.c_str(), - FILE_READ_ATTRIBUTES, // dwDesiredAccess; attributes only + FILE_READ_ATTRIBUTES | FILE_READ_EA, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, // lpSecurityAttributes OPEN_EXISTING, @@ -1688,7 +1693,7 @@ fs::file_status status_impl(path const& p, error_code* ec) // Resolve the symlink handle_wrapper h(create_file_handle( p.c_str(), - FILE_READ_ATTRIBUTES, // dwDesiredAccess; attributes only + FILE_READ_ATTRIBUTES | FILE_READ_EA, // see the comment in symlink_status_impl re. access mode FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, // lpSecurityAttributes OPEN_EXISTING, @@ -1775,7 +1780,7 @@ DWORD remove_nt6_by_handle(HANDLE handle, remove_impl_type impl) break; err = ::GetLastError(); - if (BOOST_UNLIKELY(err == ERROR_INVALID_PARAMETER || err == ERROR_INVALID_FUNCTION || err == ERROR_NOT_SUPPORTED)) + if (BOOST_UNLIKELY(err == ERROR_INVALID_PARAMETER || err == ERROR_INVALID_FUNCTION || err == ERROR_NOT_SUPPORTED || err == ERROR_CALL_NOT_IMPLEMENTED)) { // Downgrade to the older implementation impl = remove_disp_ex_flag_posix_semantics; @@ -1833,7 +1838,7 @@ DWORD remove_nt6_by_handle(HANDLE handle, remove_impl_type impl) break; } - else if (BOOST_UNLIKELY(err == ERROR_INVALID_PARAMETER || err == ERROR_INVALID_FUNCTION || err == ERROR_NOT_SUPPORTED)) + else if (BOOST_UNLIKELY(err == ERROR_INVALID_PARAMETER || err == ERROR_INVALID_FUNCTION || err == ERROR_NOT_SUPPORTED || err == ERROR_CALL_NOT_IMPLEMENTED)) { // Downgrade to the older implementation impl = remove_disp; @@ -1902,7 +1907,7 @@ inline bool remove_nt6_impl(path const& p, remove_impl_type impl, error_code* ec { handle_wrapper h(create_file_handle( p, - DELETE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, + DELETE | FILE_READ_ATTRIBUTES | FILE_READ_EA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, @@ -1999,12 +2004,12 @@ uintmax_t remove_all_nt6_by_handle(HANDLE h, path const& p, error_code* ec) ( hh.handle, h, - nested_path.filename(), + path_algorithms::filename_v4(nested_path), 0u, // FileAttributes - FILE_LIST_DIRECTORY | DELETE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE, + FILE_LIST_DIRECTORY | DELETE | FILE_READ_ATTRIBUTES | FILE_READ_EA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | SYNCHRONIZE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN, - FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT + FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT ); if (!NT_SUCCESS(status)) @@ -2027,7 +2032,7 @@ uintmax_t remove_all_nt6_by_handle(HANDLE h, path const& p, error_code* ec) { hh.handle = create_file_handle( nested_path, - FILE_LIST_DIRECTORY | DELETE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE, + FILE_LIST_DIRECTORY | DELETE | FILE_READ_ATTRIBUTES | FILE_READ_EA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | SYNCHRONIZE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, @@ -2144,7 +2149,7 @@ inline uintmax_t remove_all_impl(path const& p, error_code* ec) { handle_wrapper h(create_file_handle( p, - FILE_LIST_DIRECTORY | DELETE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE, + FILE_LIST_DIRECTORY | DELETE | FILE_READ_ATTRIBUTES | FILE_READ_EA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | SYNCHRONIZE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, @@ -2385,12 +2390,12 @@ path absolute(path const& p, path const& base, system::error_code* ec) else { res.concat(abs_base.root_directory()); - res /= abs_base.relative_path(); + path_algorithms::append_v4(res, abs_base.relative_path()); } path p_relative_path(p.relative_path()); if (!p_relative_path.empty()) - res /= p_relative_path; + path_algorithms::append_v4(res, p_relative_path); return res; } @@ -2437,14 +2442,14 @@ path canonical(path const& p, path const& base, system::error_code* ec) path result; while (true) { - for (path::iterator itr(source.begin()), end(source.end()); itr != end; ++itr) + for (path::iterator itr(source.begin()), end(source.end()); itr != end; path_algorithms::increment_v4(itr)) { - if (*itr == dot_p) + if (path_algorithms::compare_v4(*itr, dot_p) == 0) continue; - if (*itr == dot_dot_p) + if (path_algorithms::compare_v4(*itr, dot_dot_p) == 0) { - if (result != root) - result.remove_filename(); + if (path_algorithms::compare_v4(result, root) != 0) + result.remove_filename_and_trailing_separators(); continue; } @@ -2459,7 +2464,7 @@ path canonical(path const& p, path const& base, system::error_code* ec) continue; } - result /= *itr; + path_algorithms::append_v4(result, *itr); // If we don't have an absolute path yet then don't check symlink status. // This avoids checking "C:" which is "the current directory on drive C" @@ -2484,14 +2489,14 @@ path canonical(path const& p, path const& base, system::error_code* ec) path link(detail::read_symlink(result, ec)); if (ec && *ec) goto return_empty_path; - result.remove_filename(); + result.remove_filename_and_trailing_separators(); if (link.is_absolute()) { - for (++itr; itr != end; ++itr) + for (path_algorithms::increment_v4(itr); itr != end; path_algorithms::increment_v4(itr)) { - if (*itr != dot_p) - link /= *itr; + if (path_algorithms::compare_v4(*itr, dot_p) != 0) + path_algorithms::append_v4(link, *itr); } source = link; root = source.root_path(); @@ -2499,15 +2504,15 @@ path canonical(path const& p, path const& base, system::error_code* ec) else // link is relative { link.remove_trailing_separator(); - if (link == dot_p) + if (path_algorithms::compare_v4(link, dot_p) == 0) continue; path new_source(result); - new_source /= link; - for (++itr; itr != end; ++itr) + path_algorithms::append_v4(new_source, link); + for (path_algorithms::increment_v4(itr); itr != end; path_algorithms::increment_v4(itr)) { - if (*itr != dot_p) - new_source /= *itr; + if (path_algorithms::compare_v4(*itr, dot_p) != 0) + path_algorithms::append_v4(new_source, *itr); } source = new_source; } @@ -2603,10 +2608,10 @@ void copy(path const& from, path const& to, unsigned int options, system::error_ relative_from = detail::relative(abs_from, abs_to, ec); if (ec && *ec) return; - if (relative_from != dot_path()) - relative_from /= from.filename(); + if (path_algorithms::compare_v4(relative_from, dot_path()) != 0) + path_algorithms::append_v4(relative_from, path_algorithms::filename_v4(from)); else - relative_from = from.filename(); + relative_from = path_algorithms::filename_v4(from); pfrom = &relative_from; } detail::create_symlink(*pfrom, to, ec); @@ -2642,7 +2647,11 @@ void copy(path const& from, path const& to, unsigned int options, system::error_ } if (is_directory(to_stat)) - detail::copy_file(from, to / from.filename(), options, ec); + { + path target(to); + path_algorithms::append_v4(target, path_algorithms::filename_v4(from)); + detail::copy_file(from, target, options, ec); + } else detail::copy_file(from, to, options, ec); } @@ -2697,8 +2706,12 @@ void copy(path const& from, path const& to, unsigned int options, system::error_ while (itr != end_dit) { path const& p = itr->path(); - // Set _detail_recursing flag so that we don't recurse more than for one level deeper into the directory if options are copy_options::none - detail::copy(p, to / p.filename(), options | static_cast< unsigned int >(copy_options::_detail_recursing), ec); + { + path target(to); + path_algorithms::append_v4(target, path_algorithms::filename_v4(p)); + // Set _detail_recursing flag so that we don't recurse more than for one level deeper into the directory if options are copy_options::none + detail::copy(p, target, options | static_cast< unsigned int >(copy_options::_detail_recursing), ec); + } if (ec && *ec) return; @@ -2953,7 +2966,14 @@ bool copy_file(path const& from, path const& to, unsigned int options, error_cod // Create handle_wrappers here so that CloseHandle calls don't clobber error code returned by GetLastError handle_wrapper hw_from, hw_to; - hw_from.handle = create_file_handle(from.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS); + // See the comment in last_write_time regarding access rights used here for GetFileTime. + hw_from.handle = create_file_handle( + from.c_str(), + FILE_READ_ATTRIBUTES | FILE_READ_EA, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS); FILETIME lwt_from; if (hw_from.handle == INVALID_HANDLE_VALUE) @@ -2967,7 +2987,13 @@ bool copy_file(path const& from, path const& to, unsigned int options, error_cod if (!::GetFileTime(hw_from.handle, NULL, NULL, &lwt_from)) goto fail_last_error; - hw_to.handle = create_file_handle(to.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS); + hw_to.handle = create_file_handle( + to.c_str(), + FILE_READ_ATTRIBUTES | FILE_READ_EA, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS); if (hw_to.handle != INVALID_HANDLE_VALUE) { @@ -3088,9 +3114,9 @@ bool create_directories(path const& p, system::error_code* ec) error_code local_ec; // Find the initial part of the path that exists - for (path fname = parent.filename(); parent.has_relative_path(); fname = parent.filename()) + for (path fname = path_algorithms::filename_v4(parent); parent.has_relative_path(); fname = path_algorithms::filename_v4(parent)) { - if (!fname.empty() && fname != dot_p && fname != dot_dot_p) + if (!fname.empty() && path_algorithms::compare_v4(fname, dot_p) != 0 && path_algorithms::compare_v4(fname, dot_dot_p) != 0) { file_status existing_status = detail::status_impl(parent, &local_ec); @@ -3107,19 +3133,19 @@ bool create_directories(path const& p, system::error_code* ec) } } - --it; - parent.remove_filename(); + path_algorithms::decrement_v4(it); + parent.remove_filename_and_trailing_separators(); } // Create missing directories bool created = false; - for (; it != e; ++it) + for (; it != e; path_algorithms::increment_v4(it)) { path const& fname = *it; - parent /= fname; - if (!fname.empty() && fname != dot_p && fname != dot_dot_p) + path_algorithms::append_v4(parent, fname); + if (!fname.empty() && path_algorithms::compare_v4(fname, dot_p) != 0 && path_algorithms::compare_v4(fname, dot_dot_p) != 0) { - created = create_directory(parent, NULL, &local_ec); + created = detail::create_directory(parent, NULL, &local_ec); if (BOOST_UNLIKELY(!!local_ec)) { if (!ec) @@ -3749,9 +3775,10 @@ std::time_t creation_time(path const& p, system::error_code* ec) #else // defined(BOOST_POSIX_API) + // See the comment in last_write_time regarding access rights used here for GetFileTime. handle_wrapper hw(create_file_handle( p.c_str(), - FILE_READ_ATTRIBUTES, + FILE_READ_ATTRIBUTES | FILE_READ_EA, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, @@ -3765,7 +3792,6 @@ std::time_t creation_time(path const& p, system::error_code* ec) } FILETIME ct; - if (BOOST_UNLIKELY(!::GetFileTime(hw.handle, &ct, NULL, NULL))) goto fail; @@ -3807,9 +3833,12 @@ std::time_t last_write_time(path const& p, system::error_code* ec) #else // defined(BOOST_POSIX_API) + // GetFileTime is documented to require GENERIC_READ access right, but this causes problems if the file + // is opened by another process without FILE_SHARE_READ. In practice, FILE_READ_ATTRIBUTES works, and + // FILE_READ_EA is also added for good measure, in case if it matters for SMBv1. handle_wrapper hw(create_file_handle( p.c_str(), - FILE_READ_ATTRIBUTES, + FILE_READ_ATTRIBUTES | FILE_READ_EA, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, @@ -3823,7 +3852,6 @@ std::time_t last_write_time(path const& p, system::error_code* ec) } FILETIME lwt; - if (BOOST_UNLIKELY(!::GetFileTime(hw.handle, NULL, NULL, &lwt))) goto fail; @@ -4055,9 +4083,8 @@ path read_symlink(path const& p, system::error_code* ec) DWORD error; if (BOOST_UNLIKELY(h.handle == INVALID_HANDLE_VALUE)) { + return_last_error: error = ::GetLastError(); - - return_error: emit_error(error, p, ec, "boost::filesystem::read_symlink"); return symlink_path; } @@ -4065,10 +4092,7 @@ path read_symlink(path const& p, system::error_code* ec) boost::scoped_ptr< reparse_data_buffer_with_storage > buf(new reparse_data_buffer_with_storage); DWORD sz = 0u; if (BOOST_UNLIKELY(!::DeviceIoControl(h.handle, FSCTL_GET_REPARSE_POINT, NULL, 0, buf.get(), sizeof(*buf), &sz, NULL))) - { - error = ::GetLastError(); - goto return_error; - } + goto return_last_error; const wchar_t* buffer; std::size_t offset, len; @@ -4310,11 +4334,8 @@ path temp_directory_path(system::error_code* ec) #else // Windows #if !defined(UNDER_CE) - const wchar_t* tmp_env = L"TMP"; - const wchar_t* temp_env = L"TEMP"; - const wchar_t* localappdata_env = L"LOCALAPPDATA"; - const wchar_t* userprofile_env = L"USERPROFILE"; - const wchar_t* env_list[] = { tmp_env, temp_env, localappdata_env, userprofile_env }; + static const wchar_t* env_list[] = { L"TMP", L"TEMP", L"LOCALAPPDATA", L"USERPROFILE" }; + static const wchar_t temp_dir[] = L"Temp"; path p; for (unsigned int i = 0; i < sizeof(env_list) / sizeof(*env_list); ++i) @@ -4324,7 +4345,7 @@ path temp_directory_path(system::error_code* ec) { p = env; if (i >= 2) - p /= L"Temp"; + path_algorithms::append_v4(p, temp_dir, temp_dir + (sizeof(temp_dir) / sizeof(*temp_dir) - 1u)); error_code lcl_ec; if (exists(p, lcl_ec) && !lcl_ec && is_directory(p, lcl_ec) && !lcl_ec) break; @@ -4349,7 +4370,7 @@ path temp_directory_path(system::error_code* ec) goto getwindir_error; p = buf.get(); // do not depend on initial buf size, see ticket #10388 - p /= L"Temp"; + path_algorithms::append_v4(p, temp_dir, temp_dir + (sizeof(temp_dir) / sizeof(*temp_dir) - 1u)); } return p; @@ -4395,7 +4416,12 @@ path system_complete(path const& p, system::error_code* ec) { #ifdef BOOST_POSIX_API - return (p.empty() || p.is_absolute()) ? p : current_path() / p; + if (p.empty() || p.is_absolute()) + return p; + + path res(current_path()); + path_algorithms::append_v4(res, p); + return res; #else if (p.empty()) @@ -4432,9 +4458,9 @@ path weakly_canonical(path const& p, path const& base, system::error_code* ec) path::iterator itr(p_end); path head(p); - for (; !head.empty(); --itr) + for (; !head.empty(); path_algorithms::decrement_v4(itr)) { - file_status head_status = detail::status_impl(head, &local_ec); + file_status head_status(detail::status_impl(head, &local_ec)); if (BOOST_UNLIKELY(head_status.type() == fs::status_error)) { if (!ec) @@ -4447,35 +4473,86 @@ path weakly_canonical(path const& p, path const& base, system::error_code* ec) if (head_status.type() != fs::file_not_found) break; - head.remove_filename(); + head.remove_filename_and_trailing_separators(); } + if (head.empty()) + return path_algorithms::lexically_normal_v4(p); + + path const& dot_p = dot_path(); + path const& dot_dot_p = dot_dot_path(); + #else - // On Windows, filesystem APIs such as GetFileAttributesW perform lexical path normalization internally. - // As a result, a path like "c:\a\.." can be reported as present even if "c:\a" is not. This would break - // canonical, as symlink_status that it calls internally would report an error that the file at the intermediate - // path does not exist. To avoid this, scan the initial path in the forward direction. - // Also, operate on paths with preferred separators. This can be important on Windows since GetFileAttributesW, - // which is called in status() may return "file not found" for paths to network shares and mounted cloud - // storages that have forward slashes as separators. + // On Windows, filesystem APIs such as GetFileAttributesW and CreateFileW perform lexical path normalization + // internally. As a result, a path like "c:\a\.." can be reported as present even if "c:\a" is not. This would + // break canonical, as symlink_status that it calls internally would report an error that the file at the + // intermediate path does not exist. To avoid this, scan the initial path in the forward direction. + // Also, operate on paths with preferred separators. This can be important on Windows since GetFileAttributesW + // or CreateFileW, which is called in status() may return "file not found" for paths to network shares and + // mounted cloud storages that have forward slashes as separators. + // Also, avoid querying status of the root name such as \\?\c: as CreateFileW returns ERROR_INVALID_FUNCTION for + // such path. Querying the status of a root name such as c: is also not right as this path refers to the current + // directory on drive C:, which is not what we want to test for existence anyway. path::iterator itr(p.begin()); path head; - for (; itr != p_end; ++itr) + if (p.has_root_name()) { - path const& p_elem = *itr; - if (p_elem.size() == 1u && detail::is_directory_separator(p_elem.native()[0])) + BOOST_ASSERT(itr != p_end); + head = *itr; + path_algorithms::increment_v4(itr); + } + + if (p.has_root_directory()) + { + BOOST_ASSERT(itr != p_end); + // Convert generic separator returned by the iterator for the root directory to + // the preferred separator. + head += path::preferred_separator; + path_algorithms::increment_v4(itr); + } + + if (!head.empty()) + { + file_status head_status(detail::status_impl(head, &local_ec)); + if (BOOST_UNLIKELY(head_status.type() == fs::status_error)) { - // Convert generic separator returned by the iterator for the root directory to - // the preferred separator. - head += path::preferred_separator; + if (!ec) + BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::weakly_canonical", head, local_ec)); + + *ec = local_ec; + return path(); } - else + + if (head_status.type() == fs::file_not_found) { - head /= p_elem; + // If the root path does not exist then no path element exists + return path_algorithms::lexically_normal_v4(p); } + } + + path const& dot_p = dot_path(); + path const& dot_dot_p = dot_dot_path(); + for (; itr != p_end; path_algorithms::increment_v4(itr)) + { + path const& p_elem = *itr; + + // Avoid querying status of paths containing dot and dot-dot elements, as this will break + // if the root name starts with "\\?\". + if (path_algorithms::compare_v4(p_elem, dot_p) == 0) + continue; + + if (path_algorithms::compare_v4(p_elem, dot_dot_p) == 0) + { + if (head.has_relative_path()) + head.remove_filename_and_trailing_separators(); - file_status head_status = detail::status_impl(head, &local_ec); + continue; + } + + path_algorithms::append_v4(head, p_elem); + + file_status head_status(detail::status_impl(head, &local_ec)); if (BOOST_UNLIKELY(head_status.type() == fs::status_error)) { if (!ec) @@ -4487,38 +4564,27 @@ path weakly_canonical(path const& p, path const& base, system::error_code* ec) if (head_status.type() == fs::file_not_found) { - head.remove_filename(); + head.remove_filename_and_trailing_separators(); break; } } + if (head.empty()) + return path_algorithms::lexically_normal_v4(p); + #endif - path const& dot_p = dot_path(); - path const& dot_dot_p = dot_dot_path(); path tail; bool tail_has_dots = false; - for (; itr != p_end; ++itr) + for (; itr != p_end; path_algorithms::increment_v4(itr)) { path const& tail_elem = *itr; -#if defined(BOOST_WINDOWS_API) - if (tail_elem.size() == 1u && detail::is_directory_separator(tail_elem.native()[0])) - { - // Convert generic separator returned by the iterator for the root directory to - // the preferred separator. - tail += path::preferred_separator; - continue; - } -#endif - tail /= tail_elem; + path_algorithms::append_v4(tail, tail_elem); // for a later optimization, track if any dot or dot-dot elements are present - if (!tail_has_dots && (tail_elem == dot_p || tail_elem == dot_dot_p)) + if (!tail_has_dots && (path_algorithms::compare_v4(tail_elem, dot_p) == 0 || path_algorithms::compare_v4(tail_elem, dot_dot_p) == 0)) tail_has_dots = true; } - if (head.empty()) - return p.lexically_normal(); - head = detail::canonical(head, base, &local_ec); if (BOOST_UNLIKELY(!!local_ec)) { @@ -4531,11 +4597,11 @@ path weakly_canonical(path const& p, path const& base, system::error_code* ec) if (BOOST_LIKELY(!tail.empty())) { - head /= tail; + path_algorithms::append_v4(head, tail); // optimization: only normalize if tail had dot or dot-dot element if (tail_has_dots) - return head.lexically_normal(); + return path_algorithms::lexically_normal_v4(head); } return head; diff --git a/contrib/restricted/boost/filesystem/src/path.cpp b/contrib/restricted/boost/filesystem/src/path.cpp index 27b32e57c5..1d9748cac7 100644 --- a/contrib/restricted/boost/filesystem/src/path.cpp +++ b/contrib/restricted/boost/filesystem/src/path.cpp @@ -1,7 +1,7 @@ // filesystem path.cpp ------------------------------------------------------------- // // Copyright Beman Dawes 2008 -// Copyright Andrey Semashev 2021 +// Copyright Andrey Semashev 2021-2023 // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt @@ -12,7 +12,7 @@ #include <boost/filesystem/config.hpp> #include <boost/filesystem/path.hpp> -#include <boost/filesystem/path_traits.hpp> // codecvt_error_category() +#include <boost/filesystem/detail/path_traits.hpp> // codecvt_error_category() #include <boost/scoped_array.hpp> #include <boost/system/error_category.hpp> // for BOOST_SYSTEM_HAS_CONSTEXPR #include <boost/assert.hpp> @@ -60,7 +60,6 @@ namespace { typedef path::value_type value_type; typedef path::string_type string_type; typedef string_type::size_type size_type; -using boost::filesystem::path_detail::substring; #ifdef BOOST_WINDOWS_API @@ -151,110 +150,247 @@ inline void first_element(string_type const& src, size_type& element_pos, size_t namespace boost { namespace filesystem { +namespace detail { -BOOST_FILESYSTEM_DECL void path::append_v3(path const& p) +// C++14 provides a mismatch algorithm with four iterator arguments(), but earlier +// standard libraries didn't, so provide this needed functionality. +inline std::pair< path::iterator, path::iterator > mismatch(path::iterator it1, path::iterator it1end, path::iterator it2, path::iterator it2end) { - if (!p.empty()) + for (; it1 != it1end && it2 != it2end && path_algorithms::compare_v4(*it1, *it2) == 0;) { - if (BOOST_LIKELY(this != &p)) - { - if (!detail::is_directory_separator(*p.m_pathname.begin())) - append_separator_if_needed(); - m_pathname += p.m_pathname; - } - else - { - // self-append - path rhs(p); - append_v3(rhs); - } + path_algorithms::increment_v4(it1); + path_algorithms::increment_v4(it2); } + return std::make_pair(it1, it2); } -BOOST_FILESYSTEM_DECL void path::append_v3(const value_type* begin, const value_type* end) +// normal --------------------------------------------------------------------------// + +BOOST_FILESYSTEM_DECL path path_algorithms::lexically_normal_v3(path const& p) { - if (begin != end) + const value_type* const pathname = p.m_pathname.c_str(); + const size_type pathname_size = p.m_pathname.size(); + size_type root_name_size = 0; + size_type root_dir_pos = find_root_directory_start(pathname, pathname_size, root_name_size); + path normal(pathname, pathname + root_name_size); + +#if defined(BOOST_WINDOWS_API) + for (size_type i = 0; i < root_name_size; ++i) + { + if (normal.m_pathname[i] == path::separator) + normal.m_pathname[i] = path::preferred_separator; + } +#endif + + size_type root_path_size = root_name_size; + if (root_dir_pos < pathname_size) { - if (BOOST_LIKELY(begin < m_pathname.data() || begin >= (m_pathname.data() + m_pathname.size()))) + root_path_size = root_dir_pos + 1; + normal.m_pathname.push_back(path::preferred_separator); + } + + size_type i = root_path_size; + + // Skip redundant directory separators after the root directory + while (i < pathname_size && detail::is_directory_separator(pathname[i])) + ++i; + + if (i < pathname_size) + { + bool last_element_was_dot = false; + while (true) { - if (!detail::is_directory_separator(*begin)) - append_separator_if_needed(); - m_pathname.append(begin, end); + { + const size_type start_pos = i; + + // Find next separator + i += find_separator(pathname + i, pathname_size - i); + + const size_type size = i - start_pos; + + // Skip dot elements + if (size == 1u && pathname[start_pos] == path::dot) + { + last_element_was_dot = true; + goto skip_append; + } + + last_element_was_dot = false; + + // Process dot dot elements + if (size == 2u && pathname[start_pos] == path::dot && pathname[start_pos + 1] == path::dot && normal.m_pathname.size() > root_path_size) + { + // Don't remove previous dot dot elements + const size_type normal_size = normal.m_pathname.size(); + size_type filename_size = find_filename_size(normal.m_pathname, root_path_size, normal_size); + size_type pos = normal_size - filename_size; + if (filename_size != 2u || normal.m_pathname[pos] != path::dot || normal.m_pathname[pos + 1] != path::dot) + { + if (pos > root_path_size && detail::is_directory_separator(normal.m_pathname[pos - 1])) + --pos; + normal.m_pathname.erase(normal.m_pathname.begin() + pos , normal.m_pathname.end()); + goto skip_append; + } + } + + // Append the element + path_algorithms::append_separator_if_needed(normal); + normal.m_pathname.append(pathname + start_pos, size); + } + + skip_append: + if (i == pathname_size) + break; + + // Skip directory separators, including duplicates + while (i < pathname_size && detail::is_directory_separator(pathname[i])) + ++i; + + if (i == pathname_size) + { + // If a path ends with a separator, add a trailing dot element + goto append_trailing_dot; + } } - else + + if (normal.empty() || last_element_was_dot) { - // overlapping source - path rhs(begin, end); - append_v3(rhs); + append_trailing_dot: + path_algorithms::append_separator_if_needed(normal); + normal.m_pathname.push_back(path::dot); } } + + return normal; } -BOOST_FILESYSTEM_DECL void path::append_v4(path const& p) +BOOST_FILESYSTEM_DECL path path_algorithms::lexically_normal_v4(path const& p) { - if (!p.empty()) - { - if (BOOST_LIKELY(this != &p)) - { - const size_type that_size = p.m_pathname.size(); - size_type that_root_name_size = 0; - size_type that_root_dir_pos = find_root_directory_start(p.m_pathname.c_str(), that_size, that_root_name_size); + const value_type* const pathname = p.m_pathname.c_str(); + const size_type pathname_size = p.m_pathname.size(); + size_type root_name_size = 0; + size_type root_dir_pos = find_root_directory_start(pathname, pathname_size, root_name_size); + path normal(pathname, pathname + root_name_size); - // if (p.is_absolute()) - if - ( -#if defined(BOOST_WINDOWS_API) && !defined(UNDER_CE) - that_root_name_size > 0 && +#if defined(BOOST_WINDOWS_API) + for (size_type i = 0; i < root_name_size; ++i) + { + if (normal.m_pathname[i] == path::separator) + normal.m_pathname[i] = path::preferred_separator; + } #endif - that_root_dir_pos < that_size - ) + + size_type root_path_size = root_name_size; + if (root_dir_pos < pathname_size) + { + root_path_size = root_dir_pos + 1; + normal.m_pathname.push_back(path::preferred_separator); + } + + size_type i = root_path_size; + + // Skip redundant directory separators after the root directory + while (i < pathname_size && detail::is_directory_separator(pathname[i])) + ++i; + + if (i < pathname_size) + { + while (true) + { + bool last_element_was_dot = false; { - return_assign: - assign(p); - return; - } + const size_type start_pos = i; - size_type this_root_name_size = 0; - find_root_directory_start(m_pathname.c_str(), m_pathname.size(), this_root_name_size); + // Find next separator + i += find_separator(pathname + i, pathname_size - i); - if - ( - that_root_name_size > 0 && - (that_root_name_size != this_root_name_size || std::memcmp(m_pathname.c_str(), p.m_pathname.c_str(), this_root_name_size * sizeof(value_type)) != 0) - ) + const size_type size = i - start_pos; + + // Skip dot elements + if (size == 1u && pathname[start_pos] == path::dot) + { + last_element_was_dot = true; + goto skip_append; + } + + // Process dot dot elements + if (size == 2u && pathname[start_pos] == path::dot && pathname[start_pos + 1] == path::dot && normal.m_pathname.size() > root_path_size) + { + // Don't remove previous dot dot elements + const size_type normal_size = normal.m_pathname.size(); + size_type filename_size = find_filename_size(normal.m_pathname, root_path_size, normal_size); + size_type pos = normal_size - filename_size; + if (filename_size != 2u || normal.m_pathname[pos] != path::dot || normal.m_pathname[pos + 1] != path::dot) + { + if (pos > root_path_size && detail::is_directory_separator(normal.m_pathname[pos - 1])) + --pos; + normal.m_pathname.erase(normal.m_pathname.begin() + pos, normal.m_pathname.end()); + goto skip_append; + } + } + + // Append the element + path_algorithms::append_separator_if_needed(normal); + normal.m_pathname.append(pathname + start_pos, size); + } + + skip_append: + if (i == pathname_size) { - goto return_assign; + // If a path ends with a trailing dot after a directory element, add a trailing separator + if (last_element_was_dot && !normal.empty() && !normal.filename_is_dot_dot()) + path_algorithms::append_separator_if_needed(normal); + + break; } - if (that_root_dir_pos < that_size) + // Skip directory separators, including duplicates + while (i < pathname_size && detail::is_directory_separator(pathname[i])) + ++i; + + if (i == pathname_size) { - // Remove root directory (if any) and relative path to replace with those from p - m_pathname.erase(m_pathname.begin() + this_root_name_size, m_pathname.end()); + // If a path ends with a separator, add a trailing separator + if (!normal.empty() && !normal.filename_is_dot_dot()) + path_algorithms::append_separator_if_needed(normal); + break; } + } - const value_type* const that_path = p.m_pathname.c_str() + that_root_name_size; - if (!detail::is_directory_separator(*that_path)) - append_separator_if_needed(); - m_pathname.append(that_path, that_size - that_root_name_size); + // If the original path was not empty and normalized ended up being empty, make it a dot + if (normal.empty()) + normal.m_pathname.push_back(path::dot); + } + + return normal; +} + +// append --------------------------------------------------------------------------// + +BOOST_FILESYSTEM_DECL void path_algorithms::append_v3(path& p, const value_type* begin, const value_type* end) +{ + if (begin != end) + { + if (BOOST_LIKELY(begin < p.m_pathname.data() || begin >= (p.m_pathname.data() + p.m_pathname.size()))) + { + if (!detail::is_directory_separator(*begin)) + path_algorithms::append_separator_if_needed(p); + p.m_pathname.append(begin, end); } else { - // self-append - path rhs(p); - append_v4(rhs); + // overlapping source + string_type rhs(begin, end); + path_algorithms::append_v3(p, rhs.data(), rhs.data() + rhs.size()); } } - else if (has_filename_v4()) - { - m_pathname.push_back(preferred_separator); - } } -BOOST_FILESYSTEM_DECL void path::append_v4(const value_type* begin, const value_type* end) +BOOST_FILESYSTEM_DECL void path_algorithms::append_v4(path& p, const value_type* begin, const value_type* end) { if (begin != end) { - if (BOOST_LIKELY(begin < m_pathname.data() || begin >= (m_pathname.data() + m_pathname.size()))) + if (BOOST_LIKELY(begin < p.m_pathname.data() || begin >= (p.m_pathname.data() + p.m_pathname.size()))) { const size_type that_size = end - begin; size_type that_root_name_size = 0; @@ -270,17 +406,17 @@ BOOST_FILESYSTEM_DECL void path::append_v4(const value_type* begin, const value_ ) { return_assign: - assign(begin, end); + p.assign(begin, end); return; } size_type this_root_name_size = 0; - find_root_directory_start(m_pathname.c_str(), m_pathname.size(), this_root_name_size); + find_root_directory_start(p.m_pathname.c_str(), p.m_pathname.size(), this_root_name_size); if ( that_root_name_size > 0 && - (that_root_name_size != this_root_name_size || std::memcmp(m_pathname.c_str(), begin, this_root_name_size * sizeof(value_type)) != 0) + (that_root_name_size != this_root_name_size || std::memcmp(p.m_pathname.c_str(), begin, this_root_name_size * sizeof(value_type)) != 0) ) { goto return_assign; @@ -289,197 +425,219 @@ BOOST_FILESYSTEM_DECL void path::append_v4(const value_type* begin, const value_ if (that_root_dir_pos < that_size) { // Remove root directory (if any) and relative path to replace with those from p - m_pathname.erase(m_pathname.begin() + this_root_name_size, m_pathname.end()); + p.m_pathname.erase(p.m_pathname.begin() + this_root_name_size, p.m_pathname.end()); } const value_type* const that_path = begin + that_root_name_size; if (!detail::is_directory_separator(*that_path)) - append_separator_if_needed(); - m_pathname.append(that_path, end); + path_algorithms::append_separator_if_needed(p); + p.m_pathname.append(that_path, end); } else { // overlapping source - path rhs(begin, end); - append_v4(rhs); + string_type rhs(begin, end); + path_algorithms::append_v4(p, rhs.data(), rhs.data() + rhs.size()); } } - else if (has_filename_v4()) + else if (path_algorithms::has_filename_v4(p)) { - m_pathname.push_back(preferred_separator); + p.m_pathname.push_back(path::preferred_separator); } } -#ifdef BOOST_WINDOWS_API +// compare -------------------------------------------------------------------------// -BOOST_FILESYSTEM_DECL path path::generic_path() const +BOOST_FILESYSTEM_DECL int path_algorithms::lex_compare_v3 +( + path_detail::path_iterator first1, path_detail::path_iterator const& last1, + path_detail::path_iterator first2, path_detail::path_iterator const& last2 +) { - path tmp(*this); - std::replace(tmp.m_pathname.begin(), tmp.m_pathname.end(), L'\\', L'/'); - return tmp; + for (; first1 != last1 && first2 != last2;) + { + if (first1->native() < first2->native()) + return -1; + if (first2->native() < first1->native()) + return 1; + BOOST_ASSERT(first2->native() == first1->native()); + path_algorithms::increment_v3(first1); + path_algorithms::increment_v3(first2); + } + if (first1 == last1 && first2 == last2) + return 0; + return first1 == last1 ? -1 : 1; } -#endif // BOOST_WINDOWS_API +BOOST_FILESYSTEM_DECL int path_algorithms::lex_compare_v4 +( + path_detail::path_iterator first1, path_detail::path_iterator const& last1, + path_detail::path_iterator first2, path_detail::path_iterator const& last2 +) +{ + for (; first1 != last1 && first2 != last2;) + { + if (first1->native() < first2->native()) + return -1; + if (first2->native() < first1->native()) + return 1; + BOOST_ASSERT(first2->native() == first1->native()); + path_algorithms::increment_v4(first1); + path_algorithms::increment_v4(first2); + } + if (first1 == last1 && first2 == last2) + return 0; + return first1 == last1 ? -1 : 1; +} -BOOST_FILESYSTEM_DECL int path::compare_v3(path const& p) const BOOST_NOEXCEPT +BOOST_FILESYSTEM_DECL int path_algorithms::compare_v3(path const& left, path const& right) { - return detail::lex_compare_v3(begin(), end(), p.begin(), p.end()); + return path_algorithms::lex_compare_v3(left.begin(), left.end(), right.begin(), right.end()); } -BOOST_FILESYSTEM_DECL int path::compare_v4(path const& p) const BOOST_NOEXCEPT +BOOST_FILESYSTEM_DECL int path_algorithms::compare_v4(path const& left, path const& right) { - return detail::lex_compare_v4(begin(), end(), p.begin(), p.end()); + return path_algorithms::lex_compare_v4(left.begin(), left.end(), right.begin(), right.end()); } -// append_separator_if_needed ----------------------------------------------------// +// append_separator_if_needed ------------------------------------------------------// -BOOST_FILESYSTEM_DECL path::string_type::size_type path::append_separator_if_needed() +BOOST_FILESYSTEM_DECL path_algorithms::string_type::size_type path_algorithms::append_separator_if_needed(path& p) { - if (!m_pathname.empty() && + if (!p.m_pathname.empty() && #ifdef BOOST_WINDOWS_API - *(m_pathname.end() - 1) != colon && + *(p.m_pathname.end() - 1) != colon && #endif - !detail::is_directory_separator(*(m_pathname.end() - 1))) + !detail::is_directory_separator(*(p.m_pathname.end() - 1))) { - string_type::size_type tmp(m_pathname.size()); - m_pathname += preferred_separator; + string_type::size_type tmp(p.m_pathname.size()); + p.m_pathname.push_back(path::preferred_separator); return tmp; } return 0; } -// erase_redundant_separator -----------------------------------------------------// +// erase_redundant_separator -------------------------------------------------------// -BOOST_FILESYSTEM_DECL void path::erase_redundant_separator(string_type::size_type sep_pos) +BOOST_FILESYSTEM_DECL void path_algorithms::erase_redundant_separator(path& p, string_type::size_type sep_pos) { - if (sep_pos // a separator was added - && sep_pos < m_pathname.size() // and something was appended - && (m_pathname[sep_pos + 1] == separator // and it was also separator + if (sep_pos // a separator was added + && sep_pos < p.m_pathname.size() // and something was appended + && (p.m_pathname[sep_pos + 1] == path::separator // and it was also separator #ifdef BOOST_WINDOWS_API - || m_pathname[sep_pos + 1] == preferred_separator // or preferred_separator + || p.m_pathname[sep_pos + 1] == path::preferred_separator // or preferred_separator #endif )) { - m_pathname.erase(m_pathname.begin() + sep_pos); // erase the added separator + p.m_pathname.erase(p.m_pathname.begin() + sep_pos); // erase the added separator } } // modifiers -----------------------------------------------------------------------// -#ifdef BOOST_WINDOWS_API -BOOST_FILESYSTEM_DECL path& path::make_preferred() +BOOST_FILESYSTEM_DECL void path_algorithms::remove_filename_v3(path& p) { - std::replace(m_pathname.begin(), m_pathname.end(), L'/', L'\\'); - return *this; + p.remove_filename_and_trailing_separators(); } -#endif -BOOST_FILESYSTEM_DECL path& path::remove_filename() +BOOST_FILESYSTEM_DECL void path_algorithms::remove_filename_v4(path& p) { - size_type end_pos = find_parent_path_size(); - m_pathname.erase(m_pathname.begin() + end_pos, m_pathname.end()); - return *this; + size_type filename_size = path_algorithms::find_filename_v4_size(p); + p.m_pathname.erase(p.m_pathname.begin() + (p.m_pathname.size() - filename_size), p.m_pathname.end()); } -BOOST_FILESYSTEM_DECL path& path::remove_trailing_separator() -{ - if (!m_pathname.empty() && detail::is_directory_separator(m_pathname[m_pathname.size() - 1])) - m_pathname.erase(m_pathname.end() - 1); - return *this; -} - -BOOST_FILESYSTEM_DECL void path::replace_extension_v3(path const& new_extension) +BOOST_FILESYSTEM_DECL void path_algorithms::replace_extension_v3(path& p, path const& new_extension) { // erase existing extension, including the dot, if any - size_type ext_pos = m_pathname.size() - extension_v3().m_pathname.size(); - m_pathname.erase(m_pathname.begin() + ext_pos, m_pathname.end()); + size_type ext_pos = p.m_pathname.size() - path_algorithms::extension_v3(p).m_pathname.size(); + p.m_pathname.erase(p.m_pathname.begin() + ext_pos, p.m_pathname.end()); if (!new_extension.empty()) { // append new_extension, adding the dot if necessary - if (new_extension.m_pathname[0] != dot) - m_pathname.push_back(dot); - m_pathname.append(new_extension.m_pathname); + if (new_extension.m_pathname[0] != path::dot) + p.m_pathname.push_back(path::dot); + p.m_pathname.append(new_extension.m_pathname); } } -BOOST_FILESYSTEM_DECL void path::replace_extension_v4(path const& new_extension) +BOOST_FILESYSTEM_DECL void path_algorithms::replace_extension_v4(path& p, path const& new_extension) { // erase existing extension, including the dot, if any - size_type ext_pos = m_pathname.size() - find_extension_v4_size(); - m_pathname.erase(m_pathname.begin() + ext_pos, m_pathname.end()); + size_type ext_pos = p.m_pathname.size() - path_algorithms::find_extension_v4_size(p); + p.m_pathname.erase(p.m_pathname.begin() + ext_pos, p.m_pathname.end()); if (!new_extension.empty()) { // append new_extension, adding the dot if necessary - if (new_extension.m_pathname[0] != dot) - m_pathname.push_back(dot); - m_pathname.append(new_extension.m_pathname); + if (new_extension.m_pathname[0] != path::dot) + p.m_pathname.push_back(path::dot); + p.m_pathname.append(new_extension.m_pathname); } } // decomposition -------------------------------------------------------------------// -BOOST_FILESYSTEM_DECL size_type path::find_root_name_size() const +BOOST_FILESYSTEM_DECL size_type path_algorithms::find_root_name_size(path const& p) { size_type root_name_size = 0; - find_root_directory_start(m_pathname.c_str(), m_pathname.size(), root_name_size); + find_root_directory_start(p.m_pathname.c_str(), p.m_pathname.size(), root_name_size); return root_name_size; } -BOOST_FILESYSTEM_DECL size_type path::find_root_path_size() const +BOOST_FILESYSTEM_DECL size_type path_algorithms::find_root_path_size(path const& p) { size_type root_name_size = 0; - size_type root_dir_pos = find_root_directory_start(m_pathname.c_str(), m_pathname.size(), root_name_size); + size_type root_dir_pos = find_root_directory_start(p.m_pathname.c_str(), p.m_pathname.size(), root_name_size); size_type size = root_name_size; - if (root_dir_pos < m_pathname.size()) + if (root_dir_pos < p.m_pathname.size()) size = root_dir_pos + 1; return size; } -BOOST_FILESYSTEM_DECL substring path::find_root_directory() const +BOOST_FILESYSTEM_DECL path_algorithms::substring path_algorithms::find_root_directory(path const& p) { substring root_dir; size_type root_name_size = 0; - root_dir.pos = find_root_directory_start(m_pathname.c_str(), m_pathname.size(), root_name_size); - root_dir.size = static_cast< std::size_t >(root_dir.pos < m_pathname.size()); + root_dir.pos = find_root_directory_start(p.m_pathname.c_str(), p.m_pathname.size(), root_name_size); + root_dir.size = static_cast< std::size_t >(root_dir.pos < p.m_pathname.size()); return root_dir; } -BOOST_FILESYSTEM_DECL substring path::find_relative_path() const +BOOST_FILESYSTEM_DECL path_algorithms::substring path_algorithms::find_relative_path(path const& p) { size_type root_name_size = 0; - size_type root_dir_pos = find_root_directory_start(m_pathname.c_str(), m_pathname.size(), root_name_size); + size_type root_dir_pos = find_root_directory_start(p.m_pathname.c_str(), p.m_pathname.size(), root_name_size); // Skip root name, root directory and any duplicate separators size_type size = root_name_size; - if (root_dir_pos < m_pathname.size()) + if (root_dir_pos < p.m_pathname.size()) { size = root_dir_pos + 1; - for (size_type n = m_pathname.size(); size < n; ++size) + for (size_type n = p.m_pathname.size(); size < n; ++size) { - if (!detail::is_directory_separator(m_pathname[size])) + if (!detail::is_directory_separator(p.m_pathname[size])) break; } } substring rel_path; rel_path.pos = size; - rel_path.size = m_pathname.size() - size; + rel_path.size = p.m_pathname.size() - size; return rel_path; } -BOOST_FILESYSTEM_DECL string_type::size_type path::find_parent_path_size() const +BOOST_FILESYSTEM_DECL path_algorithms::string_type::size_type path_algorithms::find_parent_path_size(path const& p) { - const size_type size = m_pathname.size(); + const size_type size = p.m_pathname.size(); size_type root_name_size = 0; - size_type root_dir_pos = find_root_directory_start(m_pathname.c_str(), size, root_name_size); + size_type root_dir_pos = find_root_directory_start(p.m_pathname.c_str(), size, root_name_size); - size_type filename_size = find_filename_size(m_pathname, root_name_size, size); + size_type filename_size = find_filename_size(p.m_pathname, root_name_size, size); size_type end_pos = size - filename_size; while (true) { @@ -493,7 +651,7 @@ BOOST_FILESYSTEM_DECL string_type::size_type path::find_parent_path_size() const --end_pos; - if (!detail::is_directory_separator(m_pathname[end_pos])) + if (!detail::is_directory_separator(p.m_pathname[end_pos])) { ++end_pos; break; @@ -510,13 +668,13 @@ BOOST_FILESYSTEM_DECL string_type::size_type path::find_parent_path_size() const return end_pos; } -BOOST_FILESYSTEM_DECL path path::filename_v3() const +BOOST_FILESYSTEM_DECL path path_algorithms::filename_v3(path const& p) { - const size_type size = m_pathname.size(); + const size_type size = p.m_pathname.size(); size_type root_name_size = 0; - size_type root_dir_pos = find_root_directory_start(m_pathname.c_str(), size, root_name_size); + size_type root_dir_pos = find_root_directory_start(p.m_pathname.c_str(), size, root_name_size); size_type filename_size, pos; - if (root_dir_pos < size && detail::is_directory_separator(m_pathname[size - 1]) && is_root_separator(m_pathname, root_dir_pos, size - 1)) + if (root_dir_pos < size && detail::is_directory_separator(p.m_pathname[size - 1]) && is_root_separator(p.m_pathname, root_dir_pos, size - 1)) { // Return root directory pos = root_dir_pos; @@ -530,77 +688,77 @@ BOOST_FILESYSTEM_DECL path path::filename_v3() const } else { - filename_size = find_filename_size(m_pathname, root_name_size, size); + filename_size = find_filename_size(p.m_pathname, root_name_size, size); pos = size - filename_size; - if (filename_size == 0u && pos > root_name_size && detail::is_directory_separator(m_pathname[pos - 1]) && !is_root_separator(m_pathname, root_dir_pos, pos - 1)) + if (filename_size == 0u && pos > root_name_size && detail::is_directory_separator(p.m_pathname[pos - 1]) && !is_root_separator(p.m_pathname, root_dir_pos, pos - 1)) return detail::dot_path(); } - const value_type* p = m_pathname.c_str() + pos; - return path(p, p + filename_size); + const value_type* ptr = p.m_pathname.c_str() + pos; + return path(ptr, ptr + filename_size); } -BOOST_FILESYSTEM_DECL string_type::size_type path::find_filename_v4_size() const +BOOST_FILESYSTEM_DECL path_algorithms::string_type::size_type path_algorithms::find_filename_v4_size(path const& p) { - const size_type size = m_pathname.size(); + const size_type size = p.m_pathname.size(); size_type root_name_size = 0; - find_root_directory_start(m_pathname.c_str(), size, root_name_size); - return find_filename_size(m_pathname, root_name_size, size); + find_root_directory_start(p.m_pathname.c_str(), size, root_name_size); + return find_filename_size(p.m_pathname, root_name_size, size); } -BOOST_FILESYSTEM_DECL path path::stem_v3() const +BOOST_FILESYSTEM_DECL path path_algorithms::stem_v3(path const& p) { - path name(filename_v3()); - if (name != detail::dot_path() && name != detail::dot_dot_path()) + path name(path_algorithms::filename_v3(p)); + if (path_algorithms::compare_v4(name, detail::dot_path()) != 0 && path_algorithms::compare_v4(name, detail::dot_dot_path()) != 0) { - size_type pos = name.m_pathname.rfind(dot); + size_type pos = name.m_pathname.rfind(path::dot); if (pos != string_type::npos) name.m_pathname.erase(name.m_pathname.begin() + pos, name.m_pathname.end()); } return name; } -BOOST_FILESYSTEM_DECL path path::stem_v4() const +BOOST_FILESYSTEM_DECL path path_algorithms::stem_v4(path const& p) { - path name(filename_v4()); - if (name != detail::dot_path() && name != detail::dot_dot_path()) + path name(path_algorithms::filename_v4(p)); + if (path_algorithms::compare_v4(name, detail::dot_path()) != 0 && path_algorithms::compare_v4(name, detail::dot_dot_path()) != 0) { - size_type pos = name.m_pathname.rfind(dot); + size_type pos = name.m_pathname.rfind(path::dot); if (pos != 0 && pos != string_type::npos) name.m_pathname.erase(name.m_pathname.begin() + pos, name.m_pathname.end()); } return name; } -BOOST_FILESYSTEM_DECL path path::extension_v3() const +BOOST_FILESYSTEM_DECL path path_algorithms::extension_v3(path const& p) { - path name(filename_v3()); - if (name == detail::dot_path() || name == detail::dot_dot_path()) + path name(path_algorithms::filename_v3(p)); + if (path_algorithms::compare_v4(name, detail::dot_path()) == 0 || path_algorithms::compare_v4(name, detail::dot_dot_path()) == 0) return path(); - size_type pos(name.m_pathname.rfind(dot)); + size_type pos(name.m_pathname.rfind(path::dot)); return pos == string_type::npos ? path() : path(name.m_pathname.c_str() + pos); } -BOOST_FILESYSTEM_DECL string_type::size_type path::find_extension_v4_size() const +BOOST_FILESYSTEM_DECL path_algorithms::string_type::size_type path_algorithms::find_extension_v4_size(path const& p) { - const size_type size = m_pathname.size(); + const size_type size = p.m_pathname.size(); size_type root_name_size = 0; - find_root_directory_start(m_pathname.c_str(), size, root_name_size); - size_type filename_size = find_filename_size(m_pathname, root_name_size, size); + find_root_directory_start(p.m_pathname.c_str(), size, root_name_size); + size_type filename_size = find_filename_size(p.m_pathname, root_name_size, size); size_type filename_pos = size - filename_size; if ( filename_size > 0u && // Check for "." and ".." filenames - !(m_pathname[filename_pos] == dot && - (filename_size == 1u || (filename_size == 2u && m_pathname[filename_pos + 1u] == dot))) + !(p.m_pathname[filename_pos] == path::dot && + (filename_size == 1u || (filename_size == 2u && p.m_pathname[filename_pos + 1u] == path::dot))) ) { size_type ext_pos = size; while (ext_pos > filename_pos) { --ext_pos; - if (m_pathname[ext_pos] == dot) + if (p.m_pathname[ext_pos] == path::dot) break; } @@ -611,21 +769,30 @@ BOOST_FILESYSTEM_DECL string_type::size_type path::find_extension_v4_size() cons return 0u; } -// lexical operations --------------------------------------------------------------// +} // namespace detail -namespace detail { -// C++14 provides a mismatch algorithm with four iterator arguments(), but earlier -// standard libraries didn't, so provide this needed functionality. -inline std::pair< path::iterator, path::iterator > mismatch(path::iterator it1, path::iterator it1end, path::iterator it2, path::iterator it2end) +BOOST_FILESYSTEM_DECL path& path::remove_filename_and_trailing_separators() { - for (; it1 != it1end && it2 != it2end && *it1 == *it2;) - { - ++it1; - ++it2; - } - return std::make_pair(it1, it2); + size_type end_pos = detail::path_algorithms::find_parent_path_size(*this); + m_pathname.erase(m_pathname.begin() + end_pos, m_pathname.end()); + return *this; } -} // namespace detail + +BOOST_FILESYSTEM_DECL path& path::remove_trailing_separator() +{ + if (!m_pathname.empty() && detail::is_directory_separator(m_pathname[m_pathname.size() - 1])) + m_pathname.erase(m_pathname.end() - 1); + return *this; +} + +BOOST_FILESYSTEM_DECL path& path::replace_filename(path const& replacement) +{ + detail::path_algorithms::remove_filename_v4(*this); + detail::path_algorithms::append_v4(*this, replacement.m_pathname.data(), replacement.m_pathname.data() + replacement.m_pathname.size()); + return *this; +} + +// lexical operations --------------------------------------------------------------// BOOST_FILESYSTEM_DECL path path::lexically_relative(path const& base) const { @@ -637,12 +804,12 @@ BOOST_FILESYSTEM_DECL path path::lexically_relative(path const& base) const return detail::dot_path(); std::ptrdiff_t n = 0; - for (; mm.second != base_e; ++mm.second) + for (; mm.second != base_e; detail::path_algorithms::increment_v4(mm.second)) { path const& p = *mm.second; - if (p == detail::dot_dot_path()) + if (detail::path_algorithms::compare_v4(p, detail::dot_dot_path()) == 0) --n; - else if (!p.empty() && p != detail::dot_path()) + else if (!p.empty() && detail::path_algorithms::compare_v4(p, detail::dot_path()) != 0) ++n; } if (n < 0) @@ -652,213 +819,29 @@ BOOST_FILESYSTEM_DECL path path::lexically_relative(path const& base) const path tmp; for (; n > 0; --n) - tmp /= detail::dot_dot_path(); - for (; mm.first != e; ++mm.first) - tmp /= *mm.first; + detail::path_algorithms::append_v4(tmp, detail::dot_dot_path()); + for (; mm.first != e; detail::path_algorithms::increment_v4(mm.first)) + detail::path_algorithms::append_v4(tmp, *mm.first); return tmp; } -// normal --------------------------------------------------------------------------// - -BOOST_FILESYSTEM_DECL path path::lexically_normal_v3() const -{ - const value_type* const pathname = m_pathname.c_str(); - const size_type pathname_size = m_pathname.size(); - size_type root_name_size = 0; - size_type root_dir_pos = find_root_directory_start(pathname, pathname_size, root_name_size); - path normal(pathname, pathname + root_name_size); - #if defined(BOOST_WINDOWS_API) - for (size_type i = 0; i < root_name_size; ++i) - { - if (normal.m_pathname[i] == path::separator) - normal.m_pathname[i] = path::preferred_separator; - } -#endif - - size_type root_path_size = root_name_size; - if (root_dir_pos < pathname_size) - { - root_path_size = root_dir_pos + 1; - normal.m_pathname.push_back(preferred_separator); - } - - size_type i = root_path_size; - - // Skip redundant directory separators after the root directory - while (i < pathname_size && detail::is_directory_separator(pathname[i])) - ++i; - - if (i < pathname_size) - { - bool last_element_was_dot = false; - while (true) - { - { - const size_type start_pos = i; - - // Find next separator - i += find_separator(pathname + i, pathname_size - i); - - const size_type size = i - start_pos; - - // Skip dot elements - if (size == 1u && pathname[start_pos] == dot) - { - last_element_was_dot = true; - goto skip_append; - } - - last_element_was_dot = false; - - // Process dot dot elements - if (size == 2u && pathname[start_pos] == dot && pathname[start_pos + 1] == dot && normal.m_pathname.size() > root_path_size) - { - // Don't remove previous dot dot elements - const size_type normal_size = normal.m_pathname.size(); - size_type filename_size = find_filename_size(normal.m_pathname, root_path_size, normal_size); - size_type pos = normal_size - filename_size; - if (filename_size != 2u || normal.m_pathname[pos] != dot || normal.m_pathname[pos + 1] != dot) - { - if (pos > root_path_size && detail::is_directory_separator(normal.m_pathname[pos - 1])) - --pos; - normal.m_pathname.erase(normal.m_pathname.begin() + pos , normal.m_pathname.end()); - goto skip_append; - } - } - - // Append the element - normal.append_separator_if_needed(); - normal.m_pathname.append(pathname + start_pos, size); - } - - skip_append: - if (i == pathname_size) - break; - - // Skip directory separators, including duplicates - while (i < pathname_size && detail::is_directory_separator(pathname[i])) - ++i; - if (i == pathname_size) - { - // If a path ends with a separator, add a trailing dot element - goto append_trailing_dot; - } - } - - if (normal.empty() || last_element_was_dot) - { - append_trailing_dot: - normal.append_separator_if_needed(); - normal.m_pathname.push_back(dot); - } - } - - return normal; +BOOST_FILESYSTEM_DECL path path::generic_path() const +{ + path tmp(*this); + std::replace(tmp.m_pathname.begin(), tmp.m_pathname.end(), L'\\', L'/'); + return tmp; } -BOOST_FILESYSTEM_DECL path path::lexically_normal_v4() const +BOOST_FILESYSTEM_DECL path& path::make_preferred() { - const value_type* const pathname = m_pathname.c_str(); - const size_type pathname_size = m_pathname.size(); - size_type root_name_size = 0; - size_type root_dir_pos = find_root_directory_start(pathname, pathname_size, root_name_size); - path normal(pathname, pathname + root_name_size); - -#if defined(BOOST_WINDOWS_API) - for (size_type i = 0; i < root_name_size; ++i) - { - if (normal.m_pathname[i] == path::separator) - normal.m_pathname[i] = path::preferred_separator; - } -#endif - - size_type root_path_size = root_name_size; - if (root_dir_pos < pathname_size) - { - root_path_size = root_dir_pos + 1; - normal.m_pathname.push_back(preferred_separator); - } - - size_type i = root_path_size; - - // Skip redundant directory separators after the root directory - while (i < pathname_size && detail::is_directory_separator(pathname[i])) - ++i; - - if (i < pathname_size) - { - while (true) - { - bool last_element_was_dot = false; - { - const size_type start_pos = i; - - // Find next separator - i += find_separator(pathname + i, pathname_size - i); - - const size_type size = i - start_pos; - - // Skip dot elements - if (size == 1u && pathname[start_pos] == dot) - { - last_element_was_dot = true; - goto skip_append; - } - - // Process dot dot elements - if (size == 2u && pathname[start_pos] == dot && pathname[start_pos + 1] == dot && normal.m_pathname.size() > root_path_size) - { - // Don't remove previous dot dot elements - const size_type normal_size = normal.m_pathname.size(); - size_type filename_size = find_filename_size(normal.m_pathname, root_path_size, normal_size); - size_type pos = normal_size - filename_size; - if (filename_size != 2u || normal.m_pathname[pos] != dot || normal.m_pathname[pos + 1] != dot) - { - if (pos > root_path_size && detail::is_directory_separator(normal.m_pathname[pos - 1])) - --pos; - normal.m_pathname.erase(normal.m_pathname.begin() + pos, normal.m_pathname.end()); - goto skip_append; - } - } - - // Append the element - normal.append_separator_if_needed(); - normal.m_pathname.append(pathname + start_pos, size); - } - - skip_append: - if (i == pathname_size) - { - // If a path ends with a trailing dot after a directory element, add a trailing separator - if (last_element_was_dot && !normal.empty() && !normal.filename_is_dot_dot()) - normal.append_separator_if_needed(); - - break; - } - - // Skip directory separators, including duplicates - while (i < pathname_size && detail::is_directory_separator(pathname[i])) - ++i; - - if (i == pathname_size) - { - // If a path ends with a separator, add a trailing separator - if (!normal.empty() && !normal.filename_is_dot_dot()) - normal.append_separator_if_needed(); - break; - } - } - - // If the original path was not empty and normalized ended up being empty, make it a dot - if (normal.empty()) - normal.m_pathname.push_back(dot); - } - - return normal; + std::replace(m_pathname.begin(), m_pathname.end(), L'/', L'\\'); + return *this; } +#endif // defined(BOOST_WINDOWS_API) + } // namespace filesystem } // namespace boost @@ -1001,7 +984,13 @@ find_next_separator: return pos; } -// first_element --------------------------------------------------------------------// +//--------------------------------------------------------------------------------------// +// // +// class path::iterator implementation // +// // +//--------------------------------------------------------------------------------------// + +// first_element ----------------------------------------------------------------------// // sets pos and len of first element, excluding extra separators // if src.empty(), sets pos,len, to 0,0. @@ -1043,225 +1032,153 @@ namespace boost { namespace filesystem { namespace detail { -BOOST_FILESYSTEM_DECL -int lex_compare_v3(path::iterator first1, path::iterator last1, path::iterator first2, path::iterator last2) -{ - for (; first1 != last1 && first2 != last2;) - { - if (first1->native() < first2->native()) - return -1; - if (first2->native() < first1->native()) - return 1; - BOOST_ASSERT(first2->native() == first1->native()); - first1.increment_v3(); - first2.increment_v3(); - } - if (first1 == last1 && first2 == last2) - return 0; - return first1 == last1 ? -1 : 1; -} - -BOOST_FILESYSTEM_DECL -int lex_compare_v4(path::iterator first1, path::iterator last1, path::iterator first2, path::iterator last2) -{ - for (; first1 != last1 && first2 != last2;) - { - if (first1->native() < first2->native()) - return -1; - if (first2->native() < first1->native()) - return 1; - BOOST_ASSERT(first2->native() == first1->native()); - ++first1; - ++first2; - } - if (first1 == last1 && first2 == last2) - return 0; - return first1 == last1 ? -1 : 1; -} - -} // namespace detail - -//--------------------------------------------------------------------------------------// -// // -// class path::iterator implementation // -// // -//--------------------------------------------------------------------------------------// - -BOOST_FILESYSTEM_DECL path::iterator path::begin() const +BOOST_FILESYSTEM_DECL void path_algorithms::increment_v3(path_detail::path_iterator& it) { - iterator itr; - itr.m_path_ptr = this; - - size_type element_size; - first_element(m_pathname, itr.m_pos, element_size); - - if (element_size > 0) - { - itr.m_element = m_pathname.substr(itr.m_pos, element_size); -#ifdef BOOST_WINDOWS_API - if (itr.m_element.m_pathname.size() == 1u && itr.m_element.m_pathname[0] == preferred_separator) - itr.m_element.m_pathname[0] = separator; -#endif - } - - return itr; -} - -BOOST_FILESYSTEM_DECL path::iterator path::end() const -{ - iterator itr; - itr.m_path_ptr = this; - itr.m_pos = m_pathname.size(); - return itr; -} - -BOOST_FILESYSTEM_DECL void path::iterator::increment_v3() -{ - const size_type size = m_path_ptr->m_pathname.size(); - BOOST_ASSERT_MSG(m_pos < size, "path::iterator increment past end()"); + const size_type size = it.m_path_ptr->m_pathname.size(); + BOOST_ASSERT_MSG(it.m_pos < size, "path::iterator increment past end()"); // increment to position past current element; if current element is implicit dot, // this will cause m_pos to represent the end iterator - m_pos += m_element.m_pathname.size(); + it.m_pos += it.m_element.m_pathname.size(); // if the end is reached, we are done - if (m_pos >= size) + if (it.m_pos >= size) { - BOOST_ASSERT_MSG(m_pos == size, "path::iterator increment after the referenced path was modified"); - m_element.clear(); // aids debugging + BOOST_ASSERT_MSG(it.m_pos == size, "path::iterator increment after the referenced path was modified"); + it.m_element.clear(); // aids debugging return; } // process separator (Windows drive spec is only case not a separator) - if (detail::is_directory_separator(m_path_ptr->m_pathname[m_pos])) + if (detail::is_directory_separator(it.m_path_ptr->m_pathname[it.m_pos])) { size_type root_name_size = 0; - size_type root_dir_pos = find_root_directory_start(m_path_ptr->m_pathname.c_str(), size, root_name_size); + size_type root_dir_pos = find_root_directory_start(it.m_path_ptr->m_pathname.c_str(), size, root_name_size); // detect root directory and set iterator value to the separator if it is - if (m_pos == root_dir_pos && m_element.m_pathname.size() == root_name_size) + if (it.m_pos == root_dir_pos && it.m_element.m_pathname.size() == root_name_size) { - m_element.m_pathname = separator; // generic format; see docs + it.m_element.m_pathname = path::separator; // generic format; see docs return; } // skip separators until m_pos points to the start of the next element - while (m_pos != size && detail::is_directory_separator(m_path_ptr->m_pathname[m_pos])) + while (it.m_pos != size && detail::is_directory_separator(it.m_path_ptr->m_pathname[it.m_pos])) { - ++m_pos; + ++it.m_pos; } // detect trailing separator, and treat it as ".", per POSIX spec - if (m_pos == size && - !is_root_separator(m_path_ptr->m_pathname, root_dir_pos, m_pos - 1)) + if (it.m_pos == size && + !is_root_separator(it.m_path_ptr->m_pathname, root_dir_pos, it.m_pos - 1)) { - --m_pos; - m_element = detail::dot_path(); + --it.m_pos; + it.m_element = detail::dot_path(); return; } } // get m_element - size_type end_pos = m_path_ptr->m_pathname.find_first_of(separators, m_pos); + size_type end_pos = it.m_path_ptr->m_pathname.find_first_of(separators, it.m_pos); if (end_pos == string_type::npos) end_pos = size; - const path::value_type* p = m_path_ptr->m_pathname.c_str(); - m_element.m_pathname.assign(p + m_pos, p + end_pos); + const path::value_type* p = it.m_path_ptr->m_pathname.c_str(); + it.m_element.m_pathname.assign(p + it.m_pos, p + end_pos); } -BOOST_FILESYSTEM_DECL void path::iterator::increment_v4() +BOOST_FILESYSTEM_DECL void path_algorithms::increment_v4(path_detail::path_iterator& it) { - const size_type size = m_path_ptr->m_pathname.size(); - BOOST_ASSERT_MSG(m_pos <= size, "path::iterator increment past end()"); + const size_type size = it.m_path_ptr->m_pathname.size(); + BOOST_ASSERT_MSG(it.m_pos <= size, "path::iterator increment past end()"); - if (m_element.m_pathname.empty() && (m_pos + 1) == size && detail::is_directory_separator(m_path_ptr->m_pathname[m_pos])) + if (it.m_element.m_pathname.empty() && (it.m_pos + 1) == size && detail::is_directory_separator(it.m_path_ptr->m_pathname[it.m_pos])) { // The iterator was pointing to the last empty element of the path; set to end. - m_pos = size; + it.m_pos = size; return; } // increment to position past current element; if current element is implicit dot, // this will cause m_pos to represent the end iterator - m_pos += m_element.m_pathname.size(); + it.m_pos += it.m_element.m_pathname.size(); // if the end is reached, we are done - if (m_pos >= size) + if (it.m_pos >= size) { - BOOST_ASSERT_MSG(m_pos == size, "path::iterator increment after the referenced path was modified"); - m_element.clear(); // aids debugging + BOOST_ASSERT_MSG(it.m_pos == size, "path::iterator increment after the referenced path was modified"); + it.m_element.clear(); // aids debugging return; } // process separator (Windows drive spec is only case not a separator) - if (detail::is_directory_separator(m_path_ptr->m_pathname[m_pos])) + if (detail::is_directory_separator(it.m_path_ptr->m_pathname[it.m_pos])) { size_type root_name_size = 0; - size_type root_dir_pos = find_root_directory_start(m_path_ptr->m_pathname.c_str(), size, root_name_size); + size_type root_dir_pos = find_root_directory_start(it.m_path_ptr->m_pathname.c_str(), size, root_name_size); // detect root directory and set iterator value to the separator if it is - if (m_pos == root_dir_pos && m_element.m_pathname.size() == root_name_size) + if (it.m_pos == root_dir_pos && it.m_element.m_pathname.size() == root_name_size) { - m_element.m_pathname = separator; // generic format; see docs + it.m_element.m_pathname = path::separator; // generic format; see docs return; } // skip separators until m_pos points to the start of the next element - while (m_pos != size && detail::is_directory_separator(m_path_ptr->m_pathname[m_pos])) + while (it.m_pos != size && detail::is_directory_separator(it.m_path_ptr->m_pathname[it.m_pos])) { - ++m_pos; + ++it.m_pos; } // detect trailing separator - if (m_pos == size && - !is_root_separator(m_path_ptr->m_pathname, root_dir_pos, m_pos - 1)) + if (it.m_pos == size && + !is_root_separator(it.m_path_ptr->m_pathname, root_dir_pos, it.m_pos - 1)) { - --m_pos; - m_element.m_pathname.clear(); + --it.m_pos; + it.m_element.m_pathname.clear(); return; } } // get m_element - size_type end_pos = m_path_ptr->m_pathname.find_first_of(separators, m_pos); + size_type end_pos = it.m_path_ptr->m_pathname.find_first_of(separators, it.m_pos); if (end_pos == string_type::npos) end_pos = size; - const path::value_type* p = m_path_ptr->m_pathname.c_str(); - m_element.m_pathname.assign(p + m_pos, p + end_pos); + const path::value_type* p = it.m_path_ptr->m_pathname.c_str(); + it.m_element.m_pathname.assign(p + it.m_pos, p + end_pos); } -BOOST_FILESYSTEM_DECL void path::iterator::decrement_v3() +BOOST_FILESYSTEM_DECL void path_algorithms::decrement_v3(path_detail::path_iterator& it) { - const size_type size = m_path_ptr->m_pathname.size(); - BOOST_ASSERT_MSG(m_pos > 0, "path::iterator decrement past begin()"); - BOOST_ASSERT_MSG(m_pos <= size, "path::iterator decrement after the referenced path was modified"); + const size_type size = it.m_path_ptr->m_pathname.size(); + BOOST_ASSERT_MSG(it.m_pos > 0, "path::iterator decrement past begin()"); + BOOST_ASSERT_MSG(it.m_pos <= size, "path::iterator decrement after the referenced path was modified"); size_type root_name_size = 0; - size_type root_dir_pos = find_root_directory_start(m_path_ptr->m_pathname.c_str(), size, root_name_size); + size_type root_dir_pos = find_root_directory_start(it.m_path_ptr->m_pathname.c_str(), size, root_name_size); - if (root_dir_pos < size && m_pos == root_dir_pos) + if (root_dir_pos < size && it.m_pos == root_dir_pos) { // Was pointing at root directory, decrement to root name set_to_root_name: - m_pos = 0u; - const path::value_type* p = m_path_ptr->m_pathname.c_str(); - m_element.m_pathname.assign(p, p + root_name_size); + it.m_pos = 0u; + const path::value_type* p = it.m_path_ptr->m_pathname.c_str(); + it.m_element.m_pathname.assign(p, p + root_name_size); return; } // if at end and there was a trailing non-root '/', return "." - if (m_pos == size && + if (it.m_pos == size && size > 1 && - detail::is_directory_separator(m_path_ptr->m_pathname[m_pos - 1]) && - !is_root_separator(m_path_ptr->m_pathname, root_dir_pos, m_pos - 1)) + detail::is_directory_separator(it.m_path_ptr->m_pathname[it.m_pos - 1]) && + !is_root_separator(it.m_path_ptr->m_pathname, root_dir_pos, it.m_pos - 1)) { - --m_pos; - m_element = detail::dot_path(); + --it.m_pos; + it.m_element = detail::dot_path(); return; } // skip separators unless root directory - size_type end_pos = m_pos; + size_type end_pos = it.m_pos; while (end_pos > root_name_size) { --end_pos; @@ -1269,12 +1186,12 @@ BOOST_FILESYSTEM_DECL void path::iterator::decrement_v3() if (end_pos == root_dir_pos) { // Decremented to the root directory - m_pos = end_pos; - m_element.m_pathname = separator; // generic format; see docs + it.m_pos = end_pos; + it.m_element.m_pathname = path::separator; // generic format; see docs return; } - if (!detail::is_directory_separator(m_path_ptr->m_pathname[end_pos])) + if (!detail::is_directory_separator(it.m_path_ptr->m_pathname[end_pos])) { ++end_pos; break; @@ -1284,44 +1201,44 @@ BOOST_FILESYSTEM_DECL void path::iterator::decrement_v3() if (end_pos <= root_name_size) goto set_to_root_name; - size_type filename_size = find_filename_size(m_path_ptr->m_pathname, root_name_size, end_pos); - m_pos = end_pos - filename_size; - const path::value_type* p = m_path_ptr->m_pathname.c_str(); - m_element.m_pathname.assign(p + m_pos, p + end_pos); + size_type filename_size = find_filename_size(it.m_path_ptr->m_pathname, root_name_size, end_pos); + it.m_pos = end_pos - filename_size; + const path::value_type* p = it.m_path_ptr->m_pathname.c_str(); + it.m_element.m_pathname.assign(p + it.m_pos, p + end_pos); } -BOOST_FILESYSTEM_DECL void path::iterator::decrement_v4() +BOOST_FILESYSTEM_DECL void path_algorithms::decrement_v4(path_detail::path_iterator& it) { - const size_type size = m_path_ptr->m_pathname.size(); - BOOST_ASSERT_MSG(m_pos > 0, "path::iterator decrement past begin()"); - BOOST_ASSERT_MSG(m_pos <= size, "path::iterator decrement after the referenced path was modified"); + const size_type size = it.m_path_ptr->m_pathname.size(); + BOOST_ASSERT_MSG(it.m_pos > 0, "path::iterator decrement past begin()"); + BOOST_ASSERT_MSG(it.m_pos <= size, "path::iterator decrement after the referenced path was modified"); size_type root_name_size = 0; - size_type root_dir_pos = find_root_directory_start(m_path_ptr->m_pathname.c_str(), size, root_name_size); + size_type root_dir_pos = find_root_directory_start(it.m_path_ptr->m_pathname.c_str(), size, root_name_size); - if (root_dir_pos < size && m_pos == root_dir_pos) + if (root_dir_pos < size && it.m_pos == root_dir_pos) { // Was pointing at root directory, decrement to root name set_to_root_name: - m_pos = 0u; - const path::value_type* p = m_path_ptr->m_pathname.c_str(); - m_element.m_pathname.assign(p, p + root_name_size); + it.m_pos = 0u; + const path::value_type* p = it.m_path_ptr->m_pathname.c_str(); + it.m_element.m_pathname.assign(p, p + root_name_size); return; } // if at end and there was a trailing '/', return "" - if (m_pos == size && + if (it.m_pos == size && size > 1 && - detail::is_directory_separator(m_path_ptr->m_pathname[m_pos - 1]) && - !is_root_separator(m_path_ptr->m_pathname, root_dir_pos, m_pos - 1)) + detail::is_directory_separator(it.m_path_ptr->m_pathname[it.m_pos - 1]) && + !is_root_separator(it.m_path_ptr->m_pathname, root_dir_pos, it.m_pos - 1)) { - --m_pos; - m_element.m_pathname.clear(); + --it.m_pos; + it.m_element.m_pathname.clear(); return; } // skip separators unless root directory - size_type end_pos = m_pos; + size_type end_pos = it.m_pos; while (end_pos > root_name_size) { --end_pos; @@ -1329,12 +1246,12 @@ BOOST_FILESYSTEM_DECL void path::iterator::decrement_v4() if (end_pos == root_dir_pos) { // Decremented to the root directory - m_pos = end_pos; - m_element.m_pathname = separator; // generic format; see docs + it.m_pos = end_pos; + it.m_element.m_pathname = path::separator; // generic format; see docs return; } - if (!detail::is_directory_separator(m_path_ptr->m_pathname[end_pos])) + if (!detail::is_directory_separator(it.m_path_ptr->m_pathname[end_pos])) { ++end_pos; break; @@ -1344,10 +1261,42 @@ BOOST_FILESYSTEM_DECL void path::iterator::decrement_v4() if (end_pos <= root_name_size) goto set_to_root_name; - size_type filename_size = find_filename_size(m_path_ptr->m_pathname, root_name_size, end_pos); - m_pos = end_pos - filename_size; - const path::value_type* p = m_path_ptr->m_pathname.c_str(); - m_element.m_pathname.assign(p + m_pos, p + end_pos); + size_type filename_size = find_filename_size(it.m_path_ptr->m_pathname, root_name_size, end_pos); + it.m_pos = end_pos - filename_size; + const path::value_type* p = it.m_path_ptr->m_pathname.c_str(); + it.m_element.m_pathname.assign(p + it.m_pos, p + end_pos); +} + +} // namespace detail + +// path iterators ------------------------------------------------------------------// + +BOOST_FILESYSTEM_DECL path::iterator path::begin() const +{ + iterator itr; + itr.m_path_ptr = this; + + size_type element_size; + first_element(m_pathname, itr.m_pos, element_size); + + if (element_size > 0) + { + itr.m_element = m_pathname.substr(itr.m_pos, element_size); +#ifdef BOOST_WINDOWS_API + if (itr.m_element.m_pathname.size() == 1u && itr.m_element.m_pathname[0] == path::preferred_separator) + itr.m_element.m_pathname[0] = path::separator; +#endif + } + + return itr; +} + +BOOST_FILESYSTEM_DECL path::iterator path::end() const +{ + iterator itr; + itr.m_path_ptr = this; + itr.m_pos = m_pathname.size(); + return itr; } } // namespace filesystem diff --git a/contrib/restricted/boost/filesystem/src/path_traits.cpp b/contrib/restricted/boost/filesystem/src/path_traits.cpp index aa4b8815f7..baed387b4d 100644 --- a/contrib/restricted/boost/filesystem/src/path_traits.cpp +++ b/contrib/restricted/boost/filesystem/src/path_traits.cpp @@ -12,19 +12,19 @@ #include "platform_config.hpp" #include <boost/filesystem/config.hpp> -#include <boost/filesystem/path_traits.hpp> +#include <boost/filesystem/detail/path_traits.hpp> +#include <boost/filesystem/path.hpp> #include <boost/system/system_error.hpp> #include <boost/smart_ptr/scoped_array.hpp> #include <boost/assert.hpp> #include <string> #include <locale> // for codecvt_base::result -#include <cstring> // for strlen -#include <cwchar> // for wcslen +#include <cwchar> // for mbstate_t #include <cstddef> #include <boost/filesystem/detail/header.hpp> // must be the last #include -namespace pt = boost::filesystem::path_traits; +namespace pt = boost::filesystem::detail::path_traits; namespace fs = boost::filesystem; namespace bs = boost::system; @@ -51,12 +51,7 @@ BOOST_CONSTEXPR_OR_CONST std::size_t default_codecvt_buf_size = BOOST_FILESYSTEM // convert_aux const char* to wstring // //--------------------------------------------------------------------------------------// -void convert_aux( - const char* from, - const char* from_end, - wchar_t* to, wchar_t* to_end, - std::wstring& target, - pt::codecvt_type const& cvt) +void convert_aux(const char* from, const char* from_end, wchar_t* to, wchar_t* to_end, std::wstring& target, pt::codecvt_type const& cvt) { //std::cout << std::hex // << " from=" << std::size_t(from) @@ -83,12 +78,7 @@ void convert_aux( // convert_aux const wchar_t* to string // //--------------------------------------------------------------------------------------// -void convert_aux( - const wchar_t* from, - const wchar_t* from_end, - char* to, char* to_end, - std::string& target, - pt::codecvt_type const& cvt) +void convert_aux(const wchar_t* from, const wchar_t* from_end, char* to, char* to_end, std::string& target, pt::codecvt_type const& cvt) { //std::cout << std::hex // << " from=" << std::size_t(from) @@ -119,6 +109,7 @@ void convert_aux( namespace boost { namespace filesystem { +namespace detail { namespace path_traits { //--------------------------------------------------------------------------------------// @@ -126,32 +117,29 @@ namespace path_traits { //--------------------------------------------------------------------------------------// BOOST_FILESYSTEM_DECL -void convert(const char* from, - const char* from_end, // 0 for null terminated MBCS - std::wstring& to, codecvt_type const& cvt) +void convert(const char* from, const char* from_end, std::wstring& to, const codecvt_type* cvt) { - BOOST_ASSERT(from); - - if (!from_end) // null terminated - { - from_end = from + std::strlen(from); - } - if (from == from_end) return; + BOOST_ASSERT(from != NULL); + BOOST_ASSERT(from_end != NULL); + + if (!cvt) + cvt = &fs::path::codecvt(); + std::size_t buf_size = (from_end - from) * 3; // perhaps too large, but that's OK // dynamically allocate a buffer only if source is unusually large if (buf_size > default_codecvt_buf_size) { boost::scoped_array< wchar_t > buf(new wchar_t[buf_size]); - convert_aux(from, from_end, buf.get(), buf.get() + buf_size, to, cvt); + convert_aux(from, from_end, buf.get(), buf.get() + buf_size, to, *cvt); } else { wchar_t buf[default_codecvt_buf_size]; - convert_aux(from, from_end, buf, buf + default_codecvt_buf_size, to, cvt); + convert_aux(from, from_end, buf, buf + default_codecvt_buf_size, to, *cvt); } } @@ -160,20 +148,17 @@ void convert(const char* from, //--------------------------------------------------------------------------------------// BOOST_FILESYSTEM_DECL -void convert(const wchar_t* from, - const wchar_t* from_end, // 0 for null terminated MBCS - std::string& to, codecvt_type const& cvt) +void convert(const wchar_t* from, const wchar_t* from_end, std::string& to, const codecvt_type* cvt) { - BOOST_ASSERT(from); - - if (!from_end) // null terminated - { - from_end = from + std::wcslen(from); - } - if (from == from_end) return; + BOOST_ASSERT(from != NULL); + BOOST_ASSERT(from_end != NULL); + + if (!cvt) + cvt = &fs::path::codecvt(); + // The codecvt length functions may not be implemented, and I don't really // understand them either. Thus this code is just a guess; if it turns // out the buffer is too small then an error will be reported and the code @@ -185,16 +170,17 @@ void convert(const wchar_t* from, if (buf_size > default_codecvt_buf_size) { boost::scoped_array< char > buf(new char[buf_size]); - convert_aux(from, from_end, buf.get(), buf.get() + buf_size, to, cvt); + convert_aux(from, from_end, buf.get(), buf.get() + buf_size, to, *cvt); } else { char buf[default_codecvt_buf_size]; - convert_aux(from, from_end, buf, buf + default_codecvt_buf_size, to, cvt); + convert_aux(from, from_end, buf, buf + default_codecvt_buf_size, to, *cvt); } } } // namespace path_traits +} // namespace detail } // namespace filesystem } // namespace boost diff --git a/contrib/restricted/boost/filesystem/src/windows_tools.hpp b/contrib/restricted/boost/filesystem/src/windows_tools.hpp index 8a2de7f0c9..ca62bfbf7e 100644 --- a/contrib/restricted/boost/filesystem/src/windows_tools.hpp +++ b/contrib/restricted/boost/filesystem/src/windows_tools.hpp @@ -1,7 +1,8 @@ // windows_tools.hpp -----------------------------------------------------------------// -// Copyright 2002-2009, 2014 Beman Dawes // Copyright 2001 Dietmar Kuehl +// Copyright 2002-2009, 2014 Beman Dawes +// Copyright 2021-2022 Andrey Semashev // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt @@ -23,6 +24,10 @@ #include <boost/filesystem/detail/header.hpp> // must be the last #include +#ifndef IO_REPARSE_TAG_DEDUP +#define IO_REPARSE_TAG_DEDUP (0x80000013L) +#endif + #ifndef IO_REPARSE_TAG_MOUNT_POINT #define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) #endif @@ -57,14 +62,14 @@ inline boost::filesystem::perms make_permissions(boost::filesystem::path const& boost::filesystem::perms prms = boost::filesystem::owner_read | boost::filesystem::group_read | boost::filesystem::others_read; if ((attr & FILE_ATTRIBUTE_READONLY) == 0u) prms |= boost::filesystem::owner_write | boost::filesystem::group_write | boost::filesystem::others_write; - boost::filesystem::path ext = p.extension(); + boost::filesystem::path ext = detail::path_algorithms::extension_v4(p); wchar_t const* q = ext.c_str(); if (equal_extension(q, L".exe", L".EXE") || equal_extension(q, L".com", L".COM") || equal_extension(q, L".bat", L".BAT") || equal_extension(q, L".cmd", L".CMD")) prms |= boost::filesystem::owner_exe | boost::filesystem::group_exe | boost::filesystem::others_exe; return prms; } -bool is_reparse_point_a_symlink_ioctl(HANDLE h); +ULONG get_reparse_point_tag_ioctl(HANDLE h, boost::filesystem::path const& p, boost::system::error_code* ec); inline bool is_reparse_point_tag_a_symlink(ULONG reparse_point_tag) { @@ -156,6 +161,9 @@ struct object_attributes #ifndef FILE_DIRECTORY_FILE #define FILE_DIRECTORY_FILE 0x00000001 #endif +#ifndef FILE_SYNCHRONOUS_IO_NONALERT +#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020 +#endif #ifndef FILE_OPEN_FOR_BACKUP_INTENT #define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000 #endif diff --git a/contrib/restricted/boost/filesystem/ya.make b/contrib/restricted/boost/filesystem/ya.make index fb19913ed1..bd15cb93a5 100644 --- a/contrib/restricted/boost/filesystem/ya.make +++ b/contrib/restricted/boost/filesystem/ya.make @@ -1,4 +1,4 @@ -# Generated by devtools/yamaker from nixpkgs 22.05. +# Generated by devtools/yamaker from nixpkgs 22.11. LIBRARY() @@ -6,9 +6,9 @@ LICENSE(BSL-1.0) LICENSE_TEXTS(.yandex_meta/licenses.list.txt) -VERSION(1.80.0) +VERSION(1.83.0) -ORIGINAL_SOURCE(https://github.com/boostorg/filesystem/archive/boost-1.80.0.tar.gz) +ORIGINAL_SOURCE(https://github.com/boostorg/filesystem/archive/boost-1.83.0.tar.gz) PEERDIR( contrib/restricted/boost/assert diff --git a/contrib/tools/python3/patches/all-changes.patch b/contrib/tools/python3/patches/all-changes.patch new file mode 100644 index 0000000000..69dac70067 --- /dev/null +++ b/contrib/tools/python3/patches/all-changes.patch @@ -0,0 +1,386 @@ +--- contrib/tools/python3/src/Modules/posixmodule.c (index) ++++ contrib/tools/python3/src/Modules/posixmodule.c (working tree) +@@ -288,6 +288,7 @@ corresponding Unix manual entries for more information on calls."); + #endif + #ifdef HAVE_GETRANDOM_SYSCALL + # include <sys/syscall.h> ++# include <sys/random.h> + #endif + + #if defined(MS_WINDOWS) +--- contrib/tools/python3/src/Lib/ctypes/__init__.py (index) ++++ contrib/tools/python3/src/Lib/ctypes/__init__.py (working tree) +@@ -11,6 +11,7 @@ from _ctypes import CFuncPtr as _CFuncPtr + from _ctypes import __version__ as _ctypes_version + from _ctypes import RTLD_LOCAL, RTLD_GLOBAL + from _ctypes import ArgumentError ++from .util import find_library as _find_library + + from struct import calcsize as _calcsize + +@@ -372,8 +373,15 @@ class CDLL(object): + _restype_ = self._func_restype_ + self._FuncPtr = _FuncPtr + ++ self._builtin = {} ++ + if handle is None: +- self._handle = _dlopen(self._name, mode) ++ if isinstance(self._name, dict): ++ self._builtin = self._name['symbols'] ++ self._name = self._name['name'] ++ self._handle = 0 ++ else: ++ self._handle = _dlopen(self._name, mode) + else: + self._handle = handle + +@@ -391,7 +399,13 @@ class CDLL(object): + return func + + def __getitem__(self, name_or_ordinal): +- func = self._FuncPtr((name_or_ordinal, self)) ++ if self._builtin: ++ if name_or_ordinal not in self._builtin: ++ raise AttributeError("function %r not found" % name_or_ordinal) ++ func = self._FuncPtr(self._builtin[name_or_ordinal]) ++ else: ++ func = self._FuncPtr((name_or_ordinal, self)) ++ + if not isinstance(name_or_ordinal, int): + func.__name__ = name_or_ordinal + return func +@@ -458,12 +472,20 @@ class LibraryLoader(object): + cdll = LibraryLoader(CDLL) + pydll = LibraryLoader(PyDLL) + +-if _os.name == "nt": +- pythonapi = PyDLL("python dll", None, _sys.dllhandle) +-elif _sys.platform == "cygwin": +- pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2]) +-else: ++#if _os.name == "nt": ++# pythonapi = PyDLL("python dll", None, _sys.dllhandle) ++#elif _sys.platform == "cygwin": ++# pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2]) ++#else: ++# pythonapi = PyDLL(None) ++ ++try: + pythonapi = PyDLL(None) ++except: ++ try: ++ pythonapi = PyDLL(_find_library('python')) ++ except: ++ pythonapi = PyDLL(dict(name='python', symbols={})) + + + if _os.name == "nt": +--- contrib/tools/python3/src/Lib/ctypes/util.py (index) ++++ contrib/tools/python3/src/Lib/ctypes/util.py (working tree) +@@ -329,6 +329,16 @@ elif os.name == "posix": + return _findSoname_ldconfig(name) or \ + _get_soname(_findLib_gcc(name)) or _get_soname(_findLib_ld(name)) + ++try: ++ from library.python.symbols.module import find_library as _find_library ++except ImportError: ++ pass ++else: ++ _next_find_library = find_library ++ ++ def find_library(name): ++ return _find_library(name, _next_find_library) ++ + ################################################################ + # test code + +--- contrib/tools/python3/src/Lib/doctest.py (index) ++++ contrib/tools/python3/src/Lib/doctest.py (working tree) +@@ -957,7 +957,7 @@ class DocTestFinder: + return module.__dict__ is object.__globals__ + elif (inspect.ismethoddescriptor(object) or + inspect.ismethodwrapper(object)): +- if hasattr(object, '__objclass__'): ++ if hasattr(object, '__objclass__') and hasattr(object.__objclass__, '__module__'): + obj_mod = object.__objclass__.__module__ + elif hasattr(object, '__module__'): + obj_mod = object.__module__ +@@ -965,7 +965,10 @@ class DocTestFinder: + return True # [XX] no easy way to tell otherwise + return module.__name__ == obj_mod + elif inspect.isclass(object): +- return module.__name__ == object.__module__ ++ try: ++ return module.__name__ == object.__module__ ++ except: ++ return True + elif hasattr(object, '__module__'): + return module.__name__ == object.__module__ + elif isinstance(object, property): +--- contrib/tools/python3/src/Lib/multiprocessing/popen_spawn_win32.py (index) ++++ contrib/tools/python3/src/Lib/multiprocessing/popen_spawn_win32.py (working tree) +@@ -65,5 +65,6 @@ class Popen(object): + env["__PYVENV_LAUNCHER__"] = sys.executable + else: +- env = None ++ env = os.environ.copy() ++ env['Y_PYTHON_ENTRY_POINT'] = ':main' + + cmd = ' '.join('"%s"' % x for x in cmd) +--- contrib/tools/python3/src/Lib/multiprocessing/spawn.py (index) ++++ contrib/tools/python3/src/Lib/multiprocessing/spawn.py (working tree) +@@ -82,7 +82,7 @@ def get_command_line(**kwds): + ''' + Returns prefix of command line used for spawning a child process + ''' +- if getattr(sys, 'frozen', False): ++ if False and getattr(sys, 'frozen', False): + return ([sys.executable, '--multiprocessing-fork'] + + ['%s=%r' % item for item in kwds.items()]) + else: +--- contrib/tools/python3/src/Lib/multiprocessing/util.py (index) ++++ contrib/tools/python3/src/Lib/multiprocessing/util.py (working tree) +@@ -383,8 +383,11 @@ class ForkAwareThreadLock(object): + + + class ForkAwareLocal(threading.local): +- def __init__(self): +- register_after_fork(self, lambda obj : obj.__dict__.clear()) ++ def __new__(cls): ++ self = threading.local.__new__(cls) ++ register_after_fork(self, lambda obj: obj.__dict__.clear()) ++ return self ++ + def __reduce__(self): + return type(self), () + +@@ -444,14 +447,26 @@ def _flush_std_streams(): + # Start a program with only specified fds kept open + # + ++ ++def _env_list(): ++ # Based on fork_exec in subprocess.py. ++ env = os.environ.copy() ++ env['Y_PYTHON_ENTRY_POINT'] = ':main' ++ env_list = [] ++ for k, v in env.items(): ++ if '=' not in k: ++ env_list.append(os.fsencode(k) + b'=' + os.fsencode(v)) ++ return env_list ++ ++ + def spawnv_passfds(path, args, passfds): + import _posixsubprocess + import subprocess + passfds = tuple(sorted(map(int, passfds))) + errpipe_read, errpipe_write = os.pipe() + try: + return _posixsubprocess.fork_exec( +- args, [path], True, passfds, None, None, ++ args, [path], True, passfds, None, _env_list(), + -1, -1, -1, -1, -1, -1, errpipe_read, errpipe_write, + False, False, -1, None, None, None, -1, None, + subprocess._USE_VFORK) +--- contrib/tools/python3/src/Modules/_ctypes/_ctypes.c (index) ++++ contrib/tools/python3/src/Modules/_ctypes/_ctypes.c (working tree) +@@ -109,6 +109,7 @@ bytes(cdata) + // windows.h must be included before pycore internal headers + #ifdef MS_WIN32 + # include <windows.h> ++# include <Unknwn.h> + #endif + + #include "pycore_call.h" // _PyObject_CallNoArgs() +--- contrib/tools/python3/src/Modules/_ctypes/callbacks.c (index) ++++ contrib/tools/python3/src/Modules/_ctypes/callbacks.c (working tree) +@@ -7,6 +7,7 @@ + // windows.h must be included before pycore internal headers + #ifdef MS_WIN32 + # include <windows.h> ++# include <Unknwn.h> + #endif + + #include "pycore_call.h" // _PyObject_CallNoArgs() +--- contrib/tools/python3/src/Modules/_ctypes/callproc.c (index) ++++ contrib/tools/python3/src/Modules/_ctypes/callproc.c (working tree) +@@ -63,6 +63,7 @@ + + #ifdef MS_WIN32 + #include <windows.h> ++#include <Unknwn.h> + #include <tchar.h> + #else + #include "ctypes_dlfcn.h" +--- contrib/tools/python3/src/Modules/_ctypes/cfield.c (index) ++++ contrib/tools/python3/src/Modules/_ctypes/cfield.c (working tree) +@@ -6,6 +6,7 @@ + // windows.h must be included before pycore internal headers + #ifdef MS_WIN32 + # include <windows.h> ++# include <Unknwn.h> + #endif + + #include "pycore_bitutils.h" // _Py_bswap32() +--- contrib/tools/python3/src/Modules/_ctypes/stgdict.c (index) ++++ contrib/tools/python3/src/Modules/_ctypes/stgdict.c (working tree) +@@ -7,6 +7,7 @@ + // windows.h must be included before pycore internal headers + #ifdef MS_WIN32 + # include <windows.h> ++# include <Unknwn.h> + #endif + + #include "pycore_call.h" // _PyObject_CallNoArgs() +--- contrib/tools/python3/src/Modules/_decimal/libmpdec/io.c (index) ++++ contrib/tools/python3/src/Modules/_decimal/libmpdec/io.c (working tree) +@@ -37,7 +37,7 @@ + #include <stdlib.h> + #include <string.h> + +-#include "io.h" ++#include "mpd_io.h" + #include "typearith.h" + + +--- contrib/tools/python3/src/Modules/_decimal/libmpdec/mpdecimal.h (index) ++++ contrib/tools/python3/src/Modules/_decimal/libmpdec/mpdecimal.h (working tree) +@@ -96,17 +96,17 @@ const char *mpd_version(void); + /* Configuration */ + /******************************************************************************/ + +-#if defined(UNIVERSAL) ++#if 1 + #if defined(CONFIG_64) || defined(CONFIG_32) + #error "cannot use CONFIG_64 or CONFIG_32 with UNIVERSAL." + #endif +- #if defined(__ppc__) +- #define CONFIG_32 +- #define ANSI +- #elif defined(__ppc64__) ++ #if defined(__powerpc64__) || defined(_M_AMD64) || defined(__aarch64__) + #define CONFIG_64 + #define ANSI +- #elif defined(__i386__) ++ #elif defined(__powerpc__) ++ #define CONFIG_32 ++ #define ANSI ++ #elif defined(__i386__) || defined(_M_IX86) + #define CONFIG_32 + #define ANSI + #elif defined(__x86_64__) +--- contrib/tools/python3/src/Modules/_ssl.c (index) ++++ contrib/tools/python3/src/Modules/_ssl.c (working tree) +@@ -28,6 +28,10 @@ + /* Include symbols from _socket module */ + #include "socketmodule.h" + ++#ifdef _MSC_VER ++#include <wincrypt.h> ++#endif ++ + #include "_ssl.h" + + /* Redefined below for Windows debug builds after important #includes */ +--- contrib/tools/python3/src/Modules/_winapi.c (index) ++++ contrib/tools/python3/src/Modules/_winapi.c (working tree) +@@ -41,6 +41,7 @@ + + #define WINDOWS_LEAN_AND_MEAN + #include "windows.h" ++#include <winioctl.h> + #include <crtdbg.h> + #include "winreparse.h" + +--- contrib/tools/python3/src/Modules/getpath.c (index) ++++ contrib/tools/python3/src/Modules/getpath.c (working tree) +@@ -1,3 +1,4 @@ ++#define PYTHONPATH ":" + /* Return the initial module search path. */ + + #include "Python.h" +--- contrib/tools/python3/src/Modules/main.c (index) ++++ contrib/tools/python3/src/Modules/main.c (working tree) +@@ -51,6 +51,7 @@ pymain_init(const _PyArgv *args) + + PyConfig config; + PyConfig_InitPythonConfig(&config); ++ config.pathconfig_warnings = 0; /* Suppress errors from getpath.c */ + + /* pass NULL as the config: config is read from command line arguments, + environment variables, configuration files */ +--- contrib/tools/python3/src/Modules/posixmodule.c (index) ++++ contrib/tools/python3/src/Modules/posixmodule.c (working tree) +@@ -25,2 +25,3 @@ extern char *ctermid_r(char *); + # include <windows.h> ++# include <winioctl.h> + # include <pathcch.h> +--- contrib/tools/python3/src/PC/pyconfig.h (index) ++++ contrib/tools/python3/src/PC/pyconfig.h (working tree) +@@ -306,10 +306,6 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ + # endif + #endif + +-#ifdef _DEBUG +-# define Py_DEBUG +-#endif +- + + #ifdef MS_WIN32 + +@@ -460,7 +456,9 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ + /* #define WITH_READLINE 1 */ + + /* Use Python's own small-block memory-allocator. */ ++#ifndef address_sanitizer_enabled + #define WITH_PYMALLOC 1 ++#endif + + /* Define if you want to compile in object freelists optimization */ + #define WITH_FREELISTS 1 +--- contrib/tools/python3/src/Python/initconfig.c (index) ++++ contrib/tools/python3/src/Python/initconfig.c (working tree) +@@ -163,7 +163,7 @@ int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */ + int Py_OptimizeFlag = 0; /* Needed by compile.c */ + int Py_NoSiteFlag = 0; /* Suppress 'import site' */ + int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */ +-int Py_FrozenFlag = 0; /* Needed by getpath.c */ ++int Py_FrozenFlag = 1; /* Needed by getpath.c */ + int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */ + int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */ + int Py_NoUserSiteDirectory = 0; /* for -s and site.py */ +--- contrib/tools/python3/src/Python/pylifecycle.c (index) ++++ contrib/tools/python3/src/Python/pylifecycle.c (working tree) +@@ -230,6 +230,14 @@ init_importlib_external(PyThreadState *tstate) + return _PyStatus_ERR("external importer setup failed"); + } + Py_DECREF(value); ++ ++ value = PyImport_ImportModule("__res"); ++ if (value == NULL) { ++ PyErr_Print(); ++ return _PyStatus_ERR("can't import __res"); ++ } ++ Py_DECREF(value); ++ + return _PyImportZip_Init(tstate); + } + +--- contrib/tools/python3/src/Python/sysmodule.c (index) ++++ contrib/tools/python3/src/Python/sysmodule.c (working tree) +@@ -1500,12 +1500,12 @@ sys_getwindowsversion_impl(PyObject *module) + hKernel32 = GetModuleHandleW(L"kernel32.dll"); + Py_END_ALLOW_THREADS + if (hKernel32 && GetModuleFileNameW(hKernel32, kernel32_path, MAX_PATH) && +- (verblock_size = GetFileVersionInfoSizeW(kernel32_path, NULL)) && ++ (verblock_size = GetFileVersionInfoSizeExW(0, kernel32_path, NULL)) && + (verblock = PyMem_RawMalloc(verblock_size))) { + VS_FIXEDFILEINFO *ffi; + UINT ffi_len; + +- if (GetFileVersionInfoW(kernel32_path, 0, verblock_size, verblock) && ++ if (GetFileVersionInfoExW(0, kernel32_path, 0, verblock_size, verblock) && + VerQueryValueW(verblock, L"", (LPVOID)&ffi, &ffi_len)) { + realMajor = HIWORD(ffi->dwProductVersionMS); + realMinor = LOWORD(ffi->dwProductVersionMS); diff --git a/contrib/tools/python3/src/Modules/main.c b/contrib/tools/python3/src/Modules/main.c index a78e3564a5..5d0094b67d 100644 --- a/contrib/tools/python3/src/Modules/main.c +++ b/contrib/tools/python3/src/Modules/main.c @@ -571,7 +571,7 @@ pymain_run_python(int *exitcode) goto error; } } - else if (!config->safe_path && 0) { // Do not add current directory. + else if (!config->safe_path) { PyObject *path0 = NULL; int res = _PyPathConfig_ComputeSysPath0(&config->argv, &path0); if (res < 0) { diff --git a/library/cpp/getopt/small/last_getopt_opt.h b/library/cpp/getopt/small/last_getopt_opt.h index 625f4237dc..5b035dbe6d 100644 --- a/library/cpp/getopt/small/last_getopt_opt.h +++ b/library/cpp/getopt/small/last_getopt_opt.h @@ -670,7 +670,12 @@ namespace NLastGetopt { // Similar to store_true in Python's argparse TOpt& StoreTrue(bool* target) { - return NoArgument().SetFlag(target); + return NoArgument().StoreResult(target, true); + } + + // Similar to store_false in Python's argparse + TOpt& StoreFalse(bool* target) { + return NoArgument().StoreResult(target, false); } template <typename TpVal, typename T, typename TpFunc> diff --git a/library/cpp/ipmath/ipmath.cpp b/library/cpp/ipmath/ipmath.cpp index 53f19dbb01..b2dffcfcfd 100644 --- a/library/cpp/ipmath/ipmath.cpp +++ b/library/cpp/ipmath/ipmath.cpp @@ -139,7 +139,7 @@ TIpAddressRange::TIpAddressRangeBuilder& TIpAddressRange::TIpAddressRangeBuilder return *this; } -TIpAddressRange::TIpAddressRangeBuilder& TIpAddressRange::TIpAddressRangeBuilder::WithPrefix(ui8 len) { +TIpAddressRange::TIpAddressRangeBuilder& TIpAddressRange::TIpAddressRangeBuilder::WithPrefixImpl(ui8 len, bool checkLowerBound) { Y_ENSURE_EX(IsValid(Start_), TInvalidIpRangeException() << "Start value must be set before prefix"); const auto type = Start_.Type(); const auto maxLen = MaxPrefixLenForType(type); @@ -147,14 +147,25 @@ TIpAddressRange::TIpAddressRangeBuilder& TIpAddressRange::TIpAddressRangeBuilder << maxLen << ", but requested " << (ui32)len); const auto lowerBound = LowerBoundForPrefix(Start_, len); - Y_ENSURE_EX(Start_ == lowerBound, TInvalidIpRangeException() << "Cannot create IP range from start address " - << Start_ << " with prefix length " << (ui32)len); + if (checkLowerBound) { + Y_ENSURE_EX(Start_ == lowerBound, TInvalidIpRangeException() << "Cannot create IP range from start address " + << Start_ << " with prefix length " << (ui32)len); + } + Start_ = lowerBound; End_ = UpperBoundForPrefix(Start_, len); return *this; } +TIpAddressRange::TIpAddressRangeBuilder& TIpAddressRange::TIpAddressRangeBuilder::WithPrefix(ui8 len) { + return WithPrefixImpl(len, true); +} + +TIpAddressRange::TIpAddressRangeBuilder& TIpAddressRange::TIpAddressRangeBuilder::WithMaskedPrefix(ui8 len) { + return WithPrefixImpl(len, false); +} + void TIpAddressRange::Init(TIpv6Address from, TIpv6Address to) { Start_ = from; End_ = to; @@ -230,7 +241,7 @@ TIpAddressRange TIpAddressRange::FromCidrString(const TStringBuf str) { ythrow TInvalidIpRangeException() << "Cannot parse " << str << " as a CIDR string"; } -TMaybe<TIpAddressRange> TIpAddressRange::TryFromCidrString(const TStringBuf str) { +TMaybe<TIpAddressRange> TIpAddressRange::TryFromCidrStringImpl(const TStringBuf str, bool compact) { auto idx = str.rfind('/'); if (idx == TStringBuf::npos) { return Nothing(); @@ -246,8 +257,25 @@ TMaybe<TIpAddressRange> TIpAddressRange::TryFromCidrString(const TStringBuf str) return Nothing(); } - return TIpAddressRange::From(address) - .WithPrefix(prefixLen); + return compact ? + TIpAddressRange::From(address).WithMaskedPrefix(prefixLen) : + TIpAddressRange::From(address).WithPrefix(prefixLen); +} + +TMaybe<TIpAddressRange> TIpAddressRange::TryFromCidrString(const TStringBuf str) { + return TryFromCidrStringImpl(str, false); +} + +TIpAddressRange TIpAddressRange::FromCompactString(const TStringBuf str) { + if (auto result = TryFromCompactString(str)) { + return *result; + } + + ythrow TInvalidIpRangeException() << "Cannot parse " << str << " as a CIDR string"; +} + +TMaybe<TIpAddressRange> TIpAddressRange::TryFromCompactString(const TStringBuf str) { + return TryFromCidrStringImpl(str, true); } TIpAddressRange TIpAddressRange::FromRangeString(const TStringBuf str) { diff --git a/library/cpp/ipmath/ipmath.h b/library/cpp/ipmath/ipmath.h index f1c15e341e..8c24bd471c 100644 --- a/library/cpp/ipmath/ipmath.h +++ b/library/cpp/ipmath/ipmath.h @@ -26,7 +26,7 @@ public: static TIpAddressRangeBuilder From(const TStringBuf from); /** - * Parses a string tormatted in Classless Iter-Domain Routing (CIDR) notation. + * Parses a string formatted in Classless Inter-Domain Routing (CIDR) notation. * @param str a CIDR-formatted string, e.g. "192.168.0.0/16" * @return a new TIpAddressRange * @throws TInvalidIpRangeException if the string cannot be parsed. @@ -35,6 +35,15 @@ public: static TMaybe<TIpAddressRange> TryFromCidrString(const TStringBuf str); /** + * Parses a string formatted in compact Classless Inter-Domain Routing (CIDR) notation with node address. + * @param str a CIDR-formatted string with node address, e.g. "192.168.1.24/16" + * @return a new TIpAddressRange + * @throws TInvalidIpRangeException if the string cannot be parsed. + */ + static TIpAddressRange FromCompactString(const TStringBuf str); + static TMaybe<TIpAddressRange> TryFromCompactString(const TStringBuf str); + + /** * Parses a string formatted as two dash-separated addresses. * @param str a CIDR-formatted string, e.g. "192.168.0.0-192.168.0.2" * @return a new TIpAddressRange @@ -99,6 +108,8 @@ public: private: void Init(TIpv6Address, TIpv6Address); + static TMaybe<TIpAddressRange> TryFromCidrStringImpl(const TStringBuf str, bool compact); + TIpv6Address Start_; TIpv6Address End_; }; @@ -129,8 +140,11 @@ public: TIpAddressRangeBuilder& To(TIpv6Address); TIpAddressRangeBuilder& WithPrefix(ui8 len); + TIpAddressRangeBuilder& WithMaskedPrefix(ui8 len); private: + TIpAddressRangeBuilder& WithPrefixImpl(ui8 len, bool checkLowerBound); + TIpv6Address Start_; TIpv6Address End_; }; diff --git a/library/cpp/ipmath/ipmath_ut.cpp b/library/cpp/ipmath/ipmath_ut.cpp index 179f232503..8179c1bd67 100644 --- a/library/cpp/ipmath/ipmath_ut.cpp +++ b/library/cpp/ipmath/ipmath_ut.cpp @@ -35,6 +35,7 @@ public: UNIT_TEST(IpRangeFromIpv6); UNIT_TEST(FullIpRange); UNIT_TEST(IpRangeFromCidr); + UNIT_TEST(IpRangeFromCompact); UNIT_TEST(IpRangeFromIpv4Builder); UNIT_TEST(IpRangeFromInvalidIpv4); UNIT_TEST(IpRangeFromInvalidIpv6); @@ -145,6 +146,15 @@ public: ASSERT_THROW(TIpAddressRange::FromCidrString("::/150"), TInvalidIpRangeException); } + void IpRangeFromCompact() { + // FromCidrString disallows node addresses + EXPECT_THROW(TIpAddressRange::FromCidrString("10.10.36.12/12"), TInvalidIpRangeException); + + // FromCompactString allows to use node address instead of network address (suffix of zeroes is not required) + ASSERT_THAT(TIpAddressRange::FromCompactString("10.10.36.12/12"), Eq(TIpAddressRange::FromCidrString("10.0.0.0/12"))); + ASSERT_THAT(TIpAddressRange::FromCompactString("abcd:ef01:2345::/24"), Eq(TIpAddressRange::FromCidrString("abcd:ef00::/24"))); + } + void RangeFromRangeString() { { auto range = TIpAddressRange::FromRangeString("10.0.0.0-10.0.0.3"); diff --git a/library/cpp/protobuf/json/json2proto.cpp b/library/cpp/protobuf/json/json2proto.cpp index 83b7891b9c..f0ca3adf42 100644 --- a/library/cpp/protobuf/json/json2proto.cpp +++ b/library/cpp/protobuf/json/json2proto.cpp @@ -367,7 +367,7 @@ Json2RepeatedFieldValue(const NJson::TJsonValue& jsonValue, const google::protobuf::FieldDescriptor& field, const NProtobufJson::TJson2ProtoConfig& config, const google::protobuf::Reflection* reflection, - const TMaybe<TString>& key = {}) { + const TString* key = nullptr) { using namespace google::protobuf; switch (field.cpp_type()) { @@ -392,12 +392,12 @@ Json2RepeatedFieldValue(const NJson::TJsonValue& jsonValue, case FieldDescriptor::CPPTYPE_MESSAGE: { Message* innerProto = reflection->AddMessage(&proto, &field); Y_ASSERT(!!innerProto); - if (key.Defined()) { - const FieldDescriptor* keyField = innerProto->GetDescriptor()->FindFieldByName("key"); + if (key) { + const FieldDescriptor* keyField = innerProto->GetDescriptor()->map_key(); Y_ENSURE(keyField, "Map entry key field not found: " << field.name()); SetKey(*innerProto, *keyField, *key); - const FieldDescriptor* valueField = innerProto->GetDescriptor()->FindFieldByName("value"); + const FieldDescriptor* valueField = innerProto->GetDescriptor()->map_value(); Y_ENSURE(valueField, "Map entry value field not found."); Json2SingleField(jsonValue, *innerProto, *valueField, config, /*isMapValue=*/true); } else { @@ -457,7 +457,7 @@ Json2RepeatedField(const NJson::TJsonValue& json, if (config.UnknownFieldsCollector) { config.UnknownFieldsCollector->OnEnterMapItem(key); } - Json2RepeatedFieldValue(jsonValue, proto, field, config, reflection, key); + Json2RepeatedFieldValue(jsonValue, proto, field, config, reflection, &key); if (config.UnknownFieldsCollector) { config.UnknownFieldsCollector->OnLeaveMapItem(); } diff --git a/library/cpp/protobuf/json/proto2json_printer.cpp b/library/cpp/protobuf/json/proto2json_printer.cpp index aa0823de0e..b2426f395a 100644 --- a/library/cpp/protobuf/json/proto2json_printer.cpp +++ b/library/cpp/protobuf/json/proto2json_printer.cpp @@ -408,10 +408,10 @@ namespace NProtobufJson { void TProto2JsonPrinter::PrintKeyValue(const NProtoBuf::Message& proto, IJsonOutput& json) { - const FieldDescriptor* keyField = proto.GetDescriptor()->FindFieldByName("key"); + const FieldDescriptor* keyField = proto.GetDescriptor()->map_key(); Y_ABORT_UNLESS(keyField, "Map entry key field not found."); TString key = MakeKey(proto, *keyField); - const FieldDescriptor* valueField = proto.GetDescriptor()->FindFieldByName("value"); + const FieldDescriptor* valueField = proto.GetDescriptor()->map_value(); Y_ABORT_UNLESS(valueField, "Map entry value field not found."); PrintSingleField(proto, *valueField, json, key, true); } diff --git a/library/cpp/sanitizer/include/ya.make b/library/cpp/sanitizer/include/ya.make index 444a570333..8fb803a814 100644 --- a/library/cpp/sanitizer/include/ya.make +++ b/library/cpp/sanitizer/include/ya.make @@ -4,7 +4,9 @@ NO_SANITIZE() NO_RUNTIME() -ADDINCL(GLOBAL contrib/libs/clang${CLANG_VER}-rt/include) +IF (USE_ARCADIA_COMPILER_RUNTIME) + ADDINCL(GLOBAL contrib/libs/clang${CLANG_VER}-rt/include) +ENDIF() END() diff --git a/library/cpp/threading/future/core/future-inl.h b/library/cpp/threading/future/core/future-inl.h index a98175af2d..db58b3156c 100644 --- a/library/cpp/threading/future/core/future-inl.h +++ b/library/cpp/threading/future/core/future-inl.h @@ -729,16 +729,16 @@ namespace NThreading { } template <typename R> - inline TFuture<R> TFuture<void>::Return(const R& value) const { - auto promise = NewPromise<R>(); - Subscribe([=](const TFuture<void>& future) mutable { + inline TFuture<std::remove_cvref_t<R>> TFuture<void>::Return(R&& value) const { + auto promise = NewPromise<std::remove_cvref_t<R>>(); + Subscribe([promise, value = std::forward<R>(value)](const TFuture<void>& future) mutable { try { future.TryRethrow(); } catch (...) { promise.SetException(std::current_exception()); return; } - promise.SetValue(value); + promise.SetValue(std::move(value)); }); return promise; } diff --git a/library/cpp/threading/future/core/future.h b/library/cpp/threading/future/core/future.h index c803b28b75..598336282a 100644 --- a/library/cpp/threading/future/core/future.h +++ b/library/cpp/threading/future/core/future.h @@ -169,7 +169,7 @@ namespace NThreading { TFuture<TFutureType<TFutureCallResult<F, void>>> Apply(F&& func) const; template <typename R> - TFuture<R> Return(const R& value) const; + TFuture<std::remove_cvref_t<R>> Return(R&& value) const; TFuture<void> IgnoreResult() const { return *this; diff --git a/library/cpp/threading/future/future_ut.cpp b/library/cpp/threading/future/future_ut.cpp index 05950a568d..26f8fa9e9c 100644 --- a/library/cpp/threading/future/future_ut.cpp +++ b/library/cpp/threading/future/future_ut.cpp @@ -635,6 +635,28 @@ namespace { TestApplyLvalueCopyImpl<void>(); TestApplyLvalueCopyImpl<int>(); } + + Y_UNIT_TEST(ReturnForwardingTypeDeduction) { + const TString e = TString(80, 'a'); + TString l = TString(80, 'a'); + + TFuture<TString> futureL = MakeFuture().Return(l); + UNIT_ASSERT_VALUES_EQUAL(futureL.GetValue(), e); + UNIT_ASSERT_VALUES_EQUAL(l, e); + + TFuture<TString> futureR = MakeFuture().Return(std::move(l)); + UNIT_ASSERT_VALUES_EQUAL(futureR.GetValue(), e); + } + + Y_UNIT_TEST(ReturnForwardingCopiesCount) { + size_t numCopies = 0; + TCopyCounter copyCounter(&numCopies); + + auto returnedCounter = MakeFuture().Return(std::move(copyCounter)).ExtractValueSync(); + Y_DO_NOT_OPTIMIZE_AWAY(returnedCounter); + + UNIT_ASSERT_VALUES_EQUAL(numCopies, 0); + } } } diff --git a/library/cpp/tld/tlds-alpha-by-domain.txt b/library/cpp/tld/tlds-alpha-by-domain.txt index 361254bc21..52c974e44a 100644 --- a/library/cpp/tld/tlds-alpha-by-domain.txt +++ b/library/cpp/tld/tlds-alpha-by-domain.txt @@ -1,7 +1,6 @@ -# Version 2022032102, Last Updated Tue Mar 22 07:07:01 2022 UTC +# Version 2023122500, Last Updated Mon Dec 25 07:07:01 2023 UTC AAA AARP -ABARTH ABB ABBOTT ABBVIE @@ -17,7 +16,6 @@ ACCOUNTANTS ACO ACTOR AD -ADAC ADS ADULT AE @@ -37,7 +35,6 @@ AIRFORCE AIRTEL AKDN AL -ALFAROMEO ALIBABA ALIPAY ALLFINANZ @@ -176,7 +173,6 @@ BROTHER BRUSSELS BS BT -BUGATTI BUILD BUILDERS BUSINESS @@ -196,7 +192,6 @@ CALVINKLEIN CAM CAMERA CAMP -CANCERRESEARCH CANON CAPETOWN CAPITAL @@ -218,7 +213,6 @@ CATHOLIC CBA CBN CBRE -CBS CC CD CENTER @@ -247,7 +241,6 @@ CITADEL CITI CITIC CITY -CITYEATS CK CL CLAIMS @@ -281,7 +274,6 @@ CONSULTING CONTACT CONTRACTORS COOKING -COOKINGCHANNEL COOL COOP CORSICA @@ -387,7 +379,6 @@ ES ESQ ESTATE ET -ETISALAT EU EUROVISION EUS @@ -413,7 +404,6 @@ FEEDBACK FERRARI FERRERO FI -FIAT FIDELITY FIDO FILM @@ -439,7 +429,6 @@ FM FO FOO FOOD -FOODNETWORK FOOTBALL FORD FOREX @@ -452,7 +441,6 @@ FREE FRESENIUS FRL FROGANS -FRONTDOOR FRONTIER FTR FUJITSU @@ -545,7 +533,6 @@ HELP HELSINKI HERE HERMES -HGTV HIPHOP HISAMITSU HITACHI @@ -567,7 +554,6 @@ HOSPITAL HOST HOSTING HOT -HOTELES HOTELS HOTMAIL HOUSE @@ -653,8 +639,8 @@ KG KH KI KIA +KIDS KIM -KINDER KINDLE KITCHEN KIWI @@ -679,7 +665,6 @@ LACAIXA LAMBORGHINI LAMER LANCASTER -LANCIA LAND LANDROVER LANXESS @@ -710,7 +695,6 @@ LILLY LIMITED LIMO LINCOLN -LINDE LINK LIPSY LIVE @@ -722,7 +706,6 @@ LOAN LOANS LOCKER LOCUS -LOFT LOL LONDON LOTTE @@ -742,7 +725,6 @@ LUXURY LV LY MA -MACYS MADRID MAIF MAISON @@ -756,7 +738,6 @@ MARKETING MARKETS MARRIOTT MARSHALLS -MASERATI MATTEL MBA MC @@ -816,7 +797,6 @@ MTR MU MUSEUM MUSIC -MUTUAL MV MW MX @@ -857,7 +837,6 @@ NISSAY NL NO NOKIA -NORTHWESTERNMUTUAL NORTON NOW NOWRUZ @@ -903,7 +882,6 @@ PARS PARTNERS PARTS PARTY -PASSAGENS PAY PCCW PE @@ -1004,7 +982,6 @@ RIL RIO RIP RO -ROCHER ROCKS RODEO ROGERS @@ -1039,7 +1016,6 @@ SB SBI SBS SC -SCA SCB SCHAEFFLER SCHMIDT @@ -1059,7 +1035,6 @@ SEEK SELECT SENER SERVICES -SES SEVEN SEW SEX @@ -1078,7 +1053,6 @@ SHOP SHOPPING SHOUJI SHOW -SHOWTIME SI SILK SINA @@ -1176,7 +1150,6 @@ THEATRE TIAA TICKETS TIENDA -TIFFANY TIPS TIRES TIROL @@ -1206,7 +1179,6 @@ TRADE TRADING TRAINING TRAVEL -TRAVELCHANNEL TRAVELERS TRAVELERSINSURANCE TRUST @@ -1261,14 +1233,12 @@ VIVO VLAANDEREN VN VODKA -VOLKSWAGEN VOLVO VOTE VOTING VOTO VOYAGE VU -VUELOS WALES WALMART WALTER @@ -1386,7 +1356,6 @@ XN--J1AEF XN--J1AMH XN--J6W193G XN--JLQ480N2RG -XN--JLQ61U9W7B XN--JVR189M XN--KCRX77D1X4A XN--KPRW13D @@ -1398,7 +1367,6 @@ XN--MGB9AWBF XN--MGBA3A3EJT XN--MGBA3A4F16A XN--MGBA7C0BBN0A -XN--MGBAAKC7DVF XN--MGBAAM7A8H XN--MGBAB2BD XN--MGBAH1A3HJKRD diff --git a/library/python/cyson/cyson/unsigned_long.cpp b/library/python/cyson/cyson/unsigned_long.cpp index f20b3f106e..bbc25bef9c 100644 --- a/library/python/cyson/cyson/unsigned_long.cpp +++ b/library/python/cyson/cyson/unsigned_long.cpp @@ -21,12 +21,22 @@ #define Py_TPFLAGS_CHECKTYPES 0 #endif +#if PY_VERSION_HEX < 0x030c0000 +#define GetSize(obj) Py_SIZE(obj) +#define IsNegative(obj) GetSize(obj) < 0 +#define IsPositive(obj) GetSize(obj) >= 0 +#else +#define GetSize(obj) (((PyLongObject*)obj)->long_value.lv_tag >> _PyLong_NON_SIZE_BITS) +#define IsNegative(obj) ((((PyLongObject*)obj)->long_value.lv_tag & _PyLong_SIGN_MASK) & 2) +#define IsPositive(obj) !IsNegative(obj) +#endif + namespace NCYson { static NPrivate::TPyObjectPtr PyUnsignedLong_ReprPtr; static void SetNegativeValueError(PyObject* obj, PyTypeObject* type) { assert(PyLong_Check(obj)); - assert(Py_SIZE(obj) < 0); + assert(IsNegative(obj)); PyObject* repr = ConvertPyLongToPyBytes(obj); @@ -58,12 +68,12 @@ namespace NCYson { assert(PyLong_Check(obj)); - size = Py_SIZE(obj); - if (size < 0) { + if (IsNegative(obj)) { SetNegativeValueError((PyObject*)obj, &PyUnsignedLong_Type); return nullptr; } + size = GetSize(obj); result = PyLong_Type.tp_alloc(&PyUnsignedLong_Type, size); if (Y_UNLIKELY(!result)) { return nullptr; @@ -73,8 +83,15 @@ namespace NCYson { Py_SET_SIZE(result, size); +#if PY_VERSION_HEX >= 0x030c0000 + ((PyLongObject*)result)->long_value.lv_tag = obj->long_value.lv_tag; +#endif for (index = 0; index < size; ++index) { +#if PY_VERSION_HEX < 0x030c0000 ((PyLongObject*)result)->ob_digit[index] = obj->ob_digit[index]; +#else + ((PyLongObject*)result)->long_value.ob_digit[index] = obj->long_value.ob_digit[index]; +#endif } return result; @@ -106,7 +123,7 @@ namespace NCYson { assert(IsExactPyUInt(result)); - if (Py_SIZE(result) < 0) { + if (IsNegative(result)) { SetNegativeValueError(result, type); Py_DECREF(result); return nullptr; @@ -135,7 +152,7 @@ namespace NCYson { #define UNSIGNED_LONG_OPERATION(SLOT, ...) \ static PyObject* unsigned_long_##SLOT(Y_MAP_ARGS_WITH_LAST(PYOBJECT_ARG, PYOBJECT_ARG_LAST, __VA_ARGS__)) { \ PyObject* result = PyLong_Type.tp_as_number->nb_##SLOT(__VA_ARGS__); \ - if (result && PyLong_CheckExact(result) && (Py_SIZE(result) >= 0)) { \ + if (result && PyLong_CheckExact(result) && (IsPositive(result))) { \ PyObject* tmp = result; \ result = ConstructPyUIntFromPyLong((PyLongObject*)tmp); \ Py_DECREF(tmp); \ @@ -288,5 +305,8 @@ namespace NCYson { #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 0, /*tp_print*/ #endif +#if PY_VERSION_HEX >= 0x030c0000 + 0, /*tp_watched*/ +#endif }; } diff --git a/library/python/cyson/ut/test_unsigned_long.py b/library/python/cyson/ut/test_unsigned_long.py index 3cd4ffe440..f5d6a1e2e6 100644 --- a/library/python/cyson/ut/test_unsigned_long.py +++ b/library/python/cyson/ut/test_unsigned_long.py @@ -27,6 +27,8 @@ UN = UInt(N) def test_uint64_initialization(): assert UInt(2**63 - 1) == 2**63 - 1 assert UInt() == UInt(0) == 0 + assert UInt(1) == 1 + assert UInt(2) == 2 assert UInt(long(78)) == 78 assert UInt(23.57) == 23 assert UInt('111') == 111 diff --git a/util/system/yassert.h b/util/system/yassert.h index 8411254693..8fb5b6bd82 100644 --- a/util/system/yassert.h +++ b/util/system/yassert.h @@ -86,6 +86,7 @@ namespace NPrivate { } \ } while (false) +#define Y_ABORT_IF(expr, ...) Y_ABORT_UNLESS(!(expr), __VA_ARGS__) #define Y_ABORT(...) Y_ABORT_UNLESS(false, __VA_ARGS__) #ifndef NDEBUG diff --git a/yt/yt/client/api/admin_client.h b/yt/yt/client/api/admin_client.h index 2a4b08c0e3..500033b8ea 100644 --- a/yt/yt/client/api/admin_client.h +++ b/yt/yt/client/api/admin_client.h @@ -289,6 +289,7 @@ struct IAdminClient virtual TFuture<TDestroyChunkLocationsResult> DestroyChunkLocations( const TString& nodeAddress, + bool recoverUnlinkedDisks, const std::vector<TGuid>& locationUuids, const TDestroyChunkLocationsOptions& options = {}) = 0; diff --git a/yt/yt/client/api/delegating_client.cpp b/yt/yt/client/api/delegating_client.cpp index c878d878ad..ac0bec3f0a 100644 --- a/yt/yt/client/api/delegating_client.cpp +++ b/yt/yt/client/api/delegating_client.cpp @@ -885,10 +885,11 @@ TFuture<TDisableChunkLocationsResult> TDelegatingClient::DisableChunkLocations( TFuture<TDestroyChunkLocationsResult> TDelegatingClient::DestroyChunkLocations( const TString& nodeAddress, + bool recoverUnlinkedDisks, const std::vector<TGuid>& locationUuids, const TDestroyChunkLocationsOptions& options) { - return Underlying_->DestroyChunkLocations(nodeAddress, locationUuids, options); + return Underlying_->DestroyChunkLocations(nodeAddress, recoverUnlinkedDisks, locationUuids, options); } TFuture<TResurrectChunkLocationsResult> TDelegatingClient::ResurrectChunkLocations( diff --git a/yt/yt/client/api/delegating_client.h b/yt/yt/client/api/delegating_client.h index 15abcbedec..a8df97651a 100644 --- a/yt/yt/client/api/delegating_client.h +++ b/yt/yt/client/api/delegating_client.h @@ -553,6 +553,7 @@ public: TFuture<TDestroyChunkLocationsResult> DestroyChunkLocations( const TString& nodeAddress, + bool recoverUnlinkedDisks, const std::vector<TGuid>& locationUuids, const TDestroyChunkLocationsOptions& options = {}) override; diff --git a/yt/yt/client/api/journal_client.h b/yt/yt/client/api/journal_client.h index 0feb298e1d..f1d68f24e7 100644 --- a/yt/yt/client/api/journal_client.h +++ b/yt/yt/client/api/journal_client.h @@ -17,6 +17,19 @@ struct TJournalReaderOptions TJournalReaderConfigPtr Config; }; +//////////////////////////////////////////////////////////////////////////////// + +struct IJournalWritesObserver + : public TRefCounted +{ + virtual void RegisterPayloadWrite(int payloadBytes) = 0; + virtual void RegisterJournalWrite(int journalBytes, int mediumBytes) = 0; +}; + +DEFINE_REFCOUNTED_TYPE(IJournalWritesObserver) + +//////////////////////////////////////////////////////////////////////////////// + struct TJournalWriterPerformanceCounters { TJournalWriterPerformanceCounters() = default; @@ -40,6 +53,8 @@ struct TJournalWriterPerformanceCounters NProfiling::TCounter MediumWrittenBytes; NProfiling::TCounter IORequestCount; NProfiling::TCounter JournalWrittenBytes; + + IJournalWritesObserverPtr JournalWritesObserver; }; struct TJournalWriterOptions diff --git a/yt/yt/client/api/public.h b/yt/yt/client/api/public.h index c671dea611..7e6c250481 100644 --- a/yt/yt/client/api/public.h +++ b/yt/yt/client/api/public.h @@ -110,6 +110,8 @@ DECLARE_REFCOUNTED_TYPE(ITypeErasedRowset) DECLARE_REFCOUNTED_STRUCT(IPersistentQueueRowset) DECLARE_REFCOUNTED_STRUCT(TSkynetSharePartsLocations) +DECLARE_REFCOUNTED_STRUCT(IJournalWritesObserver) + struct TConnectionOptions; using TClientOptions = NAuth::TAuthenticationOptions; diff --git a/yt/yt/client/api/rpc_proxy/client_impl.cpp b/yt/yt/client/api/rpc_proxy/client_impl.cpp index 8d0a7530e2..e62188c044 100644 --- a/yt/yt/client/api/rpc_proxy/client_impl.cpp +++ b/yt/yt/client/api/rpc_proxy/client_impl.cpp @@ -1953,12 +1953,14 @@ TFuture<TDisableChunkLocationsResult> TClient::DisableChunkLocations( TFuture<TDestroyChunkLocationsResult> TClient::DestroyChunkLocations( const TString& nodeAddress, + bool recoverUnlinkedDisks, const std::vector<TGuid>& locationUuids, const TDestroyChunkLocationsOptions& /*options*/) { auto proxy = CreateApiServiceProxy(); auto req = proxy.DestroyChunkLocations(); + req->set_recover_unlinked_disks(recoverUnlinkedDisks); ToProto(req->mutable_node_address(), nodeAddress); ToProto(req->mutable_location_uuids(), locationUuids); diff --git a/yt/yt/client/api/rpc_proxy/client_impl.h b/yt/yt/client/api/rpc_proxy/client_impl.h index 77c1b429f8..28cd077ce9 100644 --- a/yt/yt/client/api/rpc_proxy/client_impl.h +++ b/yt/yt/client/api/rpc_proxy/client_impl.h @@ -414,6 +414,7 @@ public: TFuture<TDestroyChunkLocationsResult> DestroyChunkLocations( const TString& nodeAddress, + bool recoverUnlinkedDisks, const std::vector<TGuid>& locationUuids, const TDestroyChunkLocationsOptions& options) override; diff --git a/yt/yt/client/chaos_client/replication_card.cpp b/yt/yt/client/chaos_client/replication_card.cpp index 6e32041b2e..e94771bba5 100644 --- a/yt/yt/client/chaos_client/replication_card.cpp +++ b/yt/yt/client/chaos_client/replication_card.cpp @@ -15,6 +15,53 @@ using namespace NTableClient; using namespace NTabletClient; using namespace NTransactionClient; +namespace NDetail { + +void FormatProgressWithProjection( + TStringBuilderBase* builder, + const TReplicationProgress& replicationProgress, + TReplicationProgressProjection replicationProgressProjection) +{ + const auto& segments = replicationProgress.Segments; + if (segments.empty()) { + builder->AppendString("[]"); + return; + } + + auto it = std::upper_bound( + segments.begin(), + segments.end(), + replicationProgressProjection.From, + [] (const auto& lhs, const auto& rhs) { + return CompareRows(lhs, rhs.LowerKey) <= 0; + }); + + bool comma = false; + builder->AppendChar('['); + + if (it != segments.begin()) { + builder->AppendFormat("<%v, %x>", segments[0].LowerKey, segments[0].Timestamp); + if (it != std::next(segments.begin())) { + builder->AppendString(", ..."); + } + comma = true; + } + + for (; it != segments.end() && it->LowerKey <= replicationProgressProjection.To; ++it) { + builder->AppendFormat("%v<%v, %x>", comma ? ", " : "", it->LowerKey, it->Timestamp); + comma = true; + } + + if (it != segments.end()) { + builder->AppendString(", ..."); + } + + builder->AppendChar(']'); +} + +} // namespace NDetail + + //////////////////////////////////////////////////////////////////////////////// TReplicationCardFetchOptions::operator size_t() const @@ -40,13 +87,24 @@ TString ToString(const TReplicationCardFetchOptions& options) //////////////////////////////////////////////////////////////////////////////// -void FormatValue(TStringBuilderBase* builder, const TReplicationProgress& replicationProgress, TStringBuf /*spec*/) +void FormatValue( + TStringBuilderBase* builder, + const TReplicationProgress& replicationProgress, + TStringBuf /*spec*/, + std::optional<TReplicationProgressProjection> replicationProgressProjection) { - builder->AppendFormat("{Segments: %v, UpperKey: %v}", - MakeFormattableView(replicationProgress.Segments, [] (auto* builder, const auto& segment) { + builder->AppendString("{Segments: "); + const auto& segments = replicationProgress.Segments; + if (!replicationProgressProjection) { + builder->AppendFormat("%v", MakeFormattableView(segments, [] (auto* builder, const auto& segment) { builder->AppendFormat("<%v, %x>", segment.LowerKey, segment.Timestamp); - }), - replicationProgress.UpperKey); + })); + } else { + NDetail::FormatProgressWithProjection(builder, replicationProgress, *replicationProgressProjection); + } + + builder->AppendFormat(", UpperKey: %v}", replicationProgress.UpperKey); + } TString ToString(const TReplicationProgress& replicationProgress) @@ -68,16 +126,22 @@ TString ToString(const TReplicaHistoryItem& replicaHistoryItem) return ToStringViaBuilder(replicaHistoryItem); } -void FormatValue(TStringBuilderBase* builder, const TReplicaInfo& replicaInfo, TStringBuf /*spec*/) +void FormatValue( + TStringBuilderBase* builder, + const TReplicaInfo& replicaInfo, + TStringBuf /*spec*/, + std::optional<TReplicationProgressProjection> replicationProgressProjection) { - builder->AppendFormat("{ClusterName: %v, ReplicaPath: %v, ContentType: %v, Mode: %v, State: %v, Progress: %v, History: %v}", + builder->AppendFormat("{ClusterName: %v, ReplicaPath: %v, ContentType: %v, Mode: %v, State: %v, Progress: ", replicaInfo.ClusterName, replicaInfo.ReplicaPath, replicaInfo.ContentType, replicaInfo.Mode, - replicaInfo.State, - replicaInfo.ReplicationProgress, - replicaInfo.History); + replicaInfo.State); + + FormatValue(builder, replicaInfo.ReplicationProgress, TStringBuf(), replicationProgressProjection); + + builder->AppendFormat(", History: %v}", replicaInfo.History); } TString ToString(const TReplicaInfo& replicaInfo) @@ -85,11 +149,21 @@ TString ToString(const TReplicaInfo& replicaInfo) return ToStringViaBuilder(replicaInfo); } -void FormatValue(TStringBuilderBase* builder, const TReplicationCard& replicationCard, TStringBuf /*spec*/) +void FormatValue( + TStringBuilderBase* builder, + const TReplicationCard& replicationCard, + TStringBuf /*spec*/, + std::optional<TReplicationProgressProjection> replicationProgressProjection) { builder->AppendFormat("{Era: %v, Replicas: %v, CoordinatorCellIds: %v, TableId: %v, TablePath: %v, TableClusterName: %v, CurrentTimestamp: %v, CollocationId: %v}", replicationCard.Era, - replicationCard.Replicas, + MakeFormattableView( + replicationCard.Replicas, + [&] (TStringBuilderBase* builder, std::pair<const NYT::TGuid, NYT::NChaosClient::TReplicaInfo> replica) { + FormatValue(builder, replica.first, TStringBuf()); + builder->AppendString(": "); + FormatValue(builder, replica.second, TStringBuf(), replicationProgressProjection); + }), replicationCard.CoordinatorCellIds, replicationCard.TableId, replicationCard.TablePath, @@ -98,9 +172,13 @@ void FormatValue(TStringBuilderBase* builder, const TReplicationCard& replicatio replicationCard.ReplicationCardCollocationId); } -TString ToString(const TReplicationCard& replicationCard) +TString ToString( + const TReplicationCard& replicationCard, + std::optional<TReplicationProgressProjection> replicationProgressProjection) { - return ToStringViaBuilder(replicationCard); + TStringBuilder builder; + FormatValue(&builder, replicationCard, {}, replicationProgressProjection); + return builder.Flush(); } //////////////////////////////////////////////////////////////////////////////// diff --git a/yt/yt/client/chaos_client/replication_card.h b/yt/yt/client/chaos_client/replication_card.h index 364f4f6dd6..992815a7d2 100644 --- a/yt/yt/client/chaos_client/replication_card.h +++ b/yt/yt/client/chaos_client/replication_card.h @@ -53,6 +53,12 @@ struct TReplicaInfo int FindHistoryItemIndex(NTransactionClient::TTimestamp timestamp) const; }; +struct TReplicationProgressProjection +{ + NTableClient::TUnversionedRow From; + NTableClient::TUnversionedRow To; +}; + struct TReplicationCard : public TRefCounted { @@ -91,17 +97,31 @@ TString ToString(const TReplicationCardFetchOptions& options); /////////////////////////////////////////////////////////////////////////////// -void FormatValue(TStringBuilderBase* builder, const TReplicationProgress& replicationProgress, TStringBuf /*spec*/); +void FormatValue( + TStringBuilderBase* builder, + const TReplicationProgress& replicationProgress, + TStringBuf /*spec*/, + std::optional<TReplicationProgressProjection> replicationProgressProjection = std::nullopt); TString ToString(const TReplicationProgress& replicationProgress); void FormatValue(TStringBuilderBase* builder, const TReplicaHistoryItem& replicaHistoryItem, TStringBuf /*spec*/); TString ToString(const TReplicaHistoryItem& replicaHistoryItem); -void FormatValue(TStringBuilderBase* builder, const TReplicaInfo& replicaInfo, TStringBuf /*spec*/); +void FormatValue( + TStringBuilderBase* builder, + const TReplicaInfo& replicaInfo, + TStringBuf /*spec*/, + std::optional<TReplicationProgressProjection> replicationProgressProjection = std::nullopt); TString ToString(const TReplicaInfo& replicaInfo); -void FormatValue(TStringBuilderBase* builder, const TReplicationCard& replicationCard, TStringBuf /*spec*/); -TString ToString(const TReplicationCard& replicationCard); +void FormatValue( + TStringBuilderBase* builder, + const TReplicationCard& replicationCard, + TStringBuf /*spec*/, + std::optional<TReplicationProgressProjection> replicationProgressProjection = std::nullopt); +TString ToString( + const TReplicationCard& replicationCard, + std::optional<TReplicationProgressProjection> replicationProgressProjection = std::nullopt); //////////////////////////////////////////////////////////////////////////////// diff --git a/yt/yt/client/driver/admin_commands.cpp b/yt/yt/client/driver/admin_commands.cpp index d7b097c910..7518352825 100644 --- a/yt/yt/client/driver/admin_commands.cpp +++ b/yt/yt/client/driver/admin_commands.cpp @@ -497,13 +497,19 @@ void TDisableChunkLocationsCommand::DoExecute(ICommandContextPtr context) void TDestroyChunkLocationsCommand::Register(TRegistrar registrar) { registrar.Parameter("node_address", &TThis::NodeAddress_); + registrar.Parameter("recover_unlinked_disks", &TThis::RecoverUnlinkedDisks_) + .Default(false); registrar.Parameter("location_uuids", &TThis::LocationUuids_) .Default(); } void TDestroyChunkLocationsCommand::DoExecute(ICommandContextPtr context) { - auto result = WaitFor(context->GetClient()->DestroyChunkLocations(NodeAddress_, LocationUuids_, Options)) + auto result = WaitFor(context->GetClient()->DestroyChunkLocations( + NodeAddress_, + RecoverUnlinkedDisks_, + LocationUuids_, + Options)) .ValueOrThrow(); context->ProduceOutputValue(BuildYsonStringFluently() diff --git a/yt/yt/client/driver/admin_commands.h b/yt/yt/client/driver/admin_commands.h index 79793930f8..4a52a34bbf 100644 --- a/yt/yt/client/driver/admin_commands.h +++ b/yt/yt/client/driver/admin_commands.h @@ -310,6 +310,7 @@ public: private: TString NodeAddress_; + bool RecoverUnlinkedDisks_; std::vector<TGuid> LocationUuids_; void DoExecute(ICommandContextPtr context) override; diff --git a/yt/yt/client/driver/queue_commands.cpp b/yt/yt/client/driver/queue_commands.cpp index 2d82e0d22c..e2aaf35e7c 100644 --- a/yt/yt/client/driver/queue_commands.cpp +++ b/yt/yt/client/driver/queue_commands.cpp @@ -233,8 +233,7 @@ void TAdvanceConsumerCommand::DoExecute(ICommandContextPtr context) { auto transaction = GetTransaction(context); - WaitFor(transaction->AdvanceConsumer(ConsumerPath, QueuePath, PartitionIndex, OldOffset, NewOffset, /*options*/ {})) - .ThrowOnError(); + transaction->AdvanceConsumer(ConsumerPath, QueuePath, PartitionIndex, OldOffset, NewOffset); if (ShouldCommitTransaction()) { WaitFor(transaction->Commit()) diff --git a/yt/yt/client/federated/client.cpp b/yt/yt/client/federated/client.cpp index 3e2bf635ad..992331b41e 100644 --- a/yt/yt/client/federated/client.cpp +++ b/yt/yt/client/federated/client.cpp @@ -402,7 +402,7 @@ public: UNIMPLEMENTED_METHOD(TFuture<TMaintenanceId>, AddMaintenance, (EMaintenanceComponent, const TString&, EMaintenanceType, const TString&, const TAddMaintenanceOptions&)); UNIMPLEMENTED_METHOD(TFuture<TMaintenanceCounts>, RemoveMaintenance, (EMaintenanceComponent, const TString&, const TMaintenanceFilter&, const TRemoveMaintenanceOptions&)); UNIMPLEMENTED_METHOD(TFuture<TDisableChunkLocationsResult>, DisableChunkLocations, (const TString&, const std::vector<TGuid>&, const TDisableChunkLocationsOptions&)); - UNIMPLEMENTED_METHOD(TFuture<TDestroyChunkLocationsResult>, DestroyChunkLocations, (const TString&, const std::vector<TGuid>&, const TDestroyChunkLocationsOptions&)); + UNIMPLEMENTED_METHOD(TFuture<TDestroyChunkLocationsResult>, DestroyChunkLocations, (const TString&, bool, const std::vector<TGuid>&, const TDestroyChunkLocationsOptions&)); UNIMPLEMENTED_METHOD(TFuture<TResurrectChunkLocationsResult>, ResurrectChunkLocations, (const TString&, const std::vector<TGuid>&, const TResurrectChunkLocationsOptions&)); UNIMPLEMENTED_METHOD(TFuture<TRequestRestartResult>, RequestRestart, (const TString&, const TRequestRestartOptions&)); UNIMPLEMENTED_METHOD(TFuture<void>, SetUserPassword, (const TString&, const TString&, const TString&, const TSetUserPasswordOptions&)); diff --git a/yt/yt/client/hedging/counter.h b/yt/yt/client/hedging/counter.h index 1502df2475..b0633cf73a 100644 --- a/yt/yt/client/hedging/counter.h +++ b/yt/yt/client/hedging/counter.h @@ -1,9 +1,9 @@ #pragma once -#include <yt/yt/core/misc/ref_counted.h> - #include <yt/yt/library/profiling/sensor.h> +#include <library/cpp/yt/memory/ref_counted.h> + #include <util/generic/hash.h> #include <util/generic/string.h> #include <util/generic/vector.h> diff --git a/yt/yt/client/hedging/hedging.cpp b/yt/yt/client/hedging/hedging.cpp index b76b740345..c0866b962e 100644 --- a/yt/yt/client/hedging/hedging.cpp +++ b/yt/yt/client/hedging/hedging.cpp @@ -195,7 +195,7 @@ public: UNSUPPORTED_METHOD(TFuture<TMaintenanceId>, AddMaintenance, (EMaintenanceComponent, const TString&, EMaintenanceType, const TString&, const TAddMaintenanceOptions&)); UNSUPPORTED_METHOD(TFuture<TMaintenanceCounts>, RemoveMaintenance, (EMaintenanceComponent, const TString&, const TMaintenanceFilter&, const TRemoveMaintenanceOptions&)); UNSUPPORTED_METHOD(TFuture<TDisableChunkLocationsResult>, DisableChunkLocations, (const TString&, const std::vector<TGuid>&, const TDisableChunkLocationsOptions&)); - UNSUPPORTED_METHOD(TFuture<TDestroyChunkLocationsResult>, DestroyChunkLocations, (const TString&, const std::vector<TGuid>&, const TDestroyChunkLocationsOptions&)); + UNSUPPORTED_METHOD(TFuture<TDestroyChunkLocationsResult>, DestroyChunkLocations, (const TString&, bool, const std::vector<TGuid>&, const TDestroyChunkLocationsOptions&)); UNSUPPORTED_METHOD(TFuture<TResurrectChunkLocationsResult>, ResurrectChunkLocations, (const TString&, const std::vector<TGuid>&, const TResurrectChunkLocationsOptions&)); UNSUPPORTED_METHOD(TFuture<TRequestRestartResult>, RequestRestart, (const TString&, const TRequestRestartOptions&)); UNSUPPORTED_METHOD(TFuture<TPullRowsResult>, PullRows, (const NYPath::TYPath&, const TPullRowsOptions&)); diff --git a/yt/yt/client/queue_client/public.h b/yt/yt/client/queue_client/public.h index df1761c324..eb5cf3f289 100644 --- a/yt/yt/client/queue_client/public.h +++ b/yt/yt/client/queue_client/public.h @@ -2,7 +2,8 @@ #include <yt/yt/core/misc/common.h> #include <yt/yt/core/misc/error_code.h> -#include <yt/yt/core/misc/ref_counted.h> + +#include <library/cpp/yt/memory/ref_counted.h> namespace NYT::NQueueClient { diff --git a/yt/yt/client/scheduler/public.h b/yt/yt/client/scheduler/public.h index 7de0092bbc..d6f3da28f9 100644 --- a/yt/yt/client/scheduler/public.h +++ b/yt/yt/client/scheduler/public.h @@ -128,6 +128,8 @@ DEFINE_ENUM(EAbortReason, ((Abandoned) ( 49)) // TODO(ignat): is it actually a scheduling type of abortion? ((JobSettlementTimedOut) ( 50)) + ((NonexistentPoolTree) ( 51)) + ((WrongSchedulingSegmentModule) ( 52)) ((SchedulingFirst) (100)) ((SchedulingTimeout) (101)) ((SchedulingResourceOvercommit) (102)) diff --git a/yt/yt/client/table_client/logical_type.h b/yt/yt/client/table_client/logical_type.h index 807b851e0c..686d449dc0 100644 --- a/yt/yt/client/table_client/logical_type.h +++ b/yt/yt/client/table_client/logical_type.h @@ -7,7 +7,7 @@ #include <yt/yt/core/yson/public.h> #include <yt/yt/core/ytree/public.h> -#include <yt/yt/core/misc/ref_counted.h> +#include <library/cpp/yt/memory/ref_counted.h> #include <library/cpp/yt/misc/enum.h> diff --git a/yt/yt/client/unittests/mock/client.h b/yt/yt/client/unittests/mock/client.h index 49c221d8ad..87d4752c03 100644 --- a/yt/yt/client/unittests/mock/client.h +++ b/yt/yt/client/unittests/mock/client.h @@ -553,6 +553,7 @@ public: MOCK_METHOD(TFuture<TDestroyChunkLocationsResult>, DestroyChunkLocations, ( const TString& nodeAddress, + bool recoverUnlinkedDisks, const std::vector<TGuid>& locationUuids, const TDestroyChunkLocationsOptions& options), (override)); diff --git a/yt/yt/client/unittests/replication_progress_ut.cpp b/yt/yt/client/unittests/replication_progress_ut.cpp index 0c00a02d69..e82b1e62a3 100644 --- a/yt/yt/client/unittests/replication_progress_ut.cpp +++ b/yt/yt/client/unittests/replication_progress_ut.cpp @@ -406,5 +406,136 @@ INSTANTIATE_TEST_SUITE_P( //////////////////////////////////////////////////////////////////////////////// +class TReplicationProgressSerialization + : public ::testing::Test + , public ::testing::WithParamInterface<std::tuple< + const char*, + const char*>> +{ }; + +TEST_P(TReplicationProgressSerialization, Simple) +{ + const auto& params = GetParam(); + auto progress = ConvertTo<TReplicationProgress>(TYsonStringBuf(std::get<0>(params))); + auto expected = TString(std::get<1>(params)); + + auto result = ToString(progress); + + EXPECT_EQ(result, expected) + << "progresses: " << std::get<0>(params) << std::endl + << "expected: " << expected << std::endl + << "actual: " << result << std::endl; +} + +INSTANTIATE_TEST_SUITE_P( + TReplicationProgressSerialization, + TReplicationProgressSerialization, + ::testing::Values( + std::make_tuple( + "{segments=[{lower_key=[];timestamp=1}];upper_key=[<type=max>#]}", + "{Segments: [<[], 1>], UpperKey: [0#<Max>]}"), + std::make_tuple( + "{segments=[{lower_key=[];timestamp=1};{lower_key=[1];timestamp=2}];upper_key=[<type=max>#]}", + "{Segments: [<[], 1>, <[0#1], 2>], UpperKey: [0#<Max>]}"), + std::make_tuple( + "{segments=[{lower_key=[];timestamp=1};{lower_key=[1];timestamp=2};{lower_key=[2];timestamp=3}];upper_key=[<type=max>#]}", + "{Segments: [<[], 1>, <[0#1], 2>, <[0#2], 3>], UpperKey: [0#<Max>]}"), + std::make_tuple( + "{segments=[{lower_key=[];timestamp=1};{lower_key=[1];timestamp=2};{lower_key=[2];timestamp=3};{lower_key=[3];timestamp=4};{lower_key=[4];timestamp=5};" + "{lower_key=[5];timestamp=6};{lower_key=[6];timestamp=7};{lower_key=[7];timestamp=8};{lower_key=[8];timestamp=9}];upper_key=[<type=max>#]}", + "{Segments: [<[], 1>, <[0#1], 2>, <[0#2], 3>, <[0#3], 4>, <[0#4], 5>, <[0#5], 6>, <[0#6], 7>, <[0#7], 8>, <[0#8], 9>], UpperKey: [0#<Max>]}") +)); + +//////////////////////////////////////////////////////////////////////////////// + +class TReplicationProgressProjectedSerialization + : public ::testing::Test + , public ::testing::WithParamInterface<std::tuple< + const char*, + const char*, + const char*, + const char*>> +{ }; + +TEST_P(TReplicationProgressProjectedSerialization, Simple) +{ + const auto& params = GetParam(); + auto progress = ConvertTo<TReplicationProgress>(TYsonStringBuf(std::get<0>(params))); + auto from = ConvertTo<TUnversionedOwningRow>(TYsonStringBuf(std::get<1>(params))); + auto to = ConvertTo<TUnversionedOwningRow>(TYsonStringBuf(std::get<2>(params))); + auto expected = TString(std::get<3>(params)); + + TStringBuilder builder; + FormatValue(&builder, progress, {}, {{from, to}}); + auto result = builder.Flush(); + + EXPECT_EQ(result, expected) + << "progresses: " << std::get<0>(params) << std::endl + << "from: " << std::get<1>(params) << std::endl + << "to: " << std::get<2>(params) << std::endl + << "expected: " << expected << std::endl + << "actual: " << result << std::endl; +} + +INSTANTIATE_TEST_SUITE_P( + TReplicationProgressProjectedSerialization, + TReplicationProgressProjectedSerialization, + ::testing::Values( + std::make_tuple( + "{segments=[{lower_key=[];timestamp=1}];upper_key=[<type=max>#]}", + "[0]", + "[1]", + "{Segments: [<[], 1>], UpperKey: [0#<Max>]}"), + std::make_tuple( + "{segments=[{lower_key=[];timestamp=1}];upper_key=[<type=max>#]}", + "[0]", + "[<type=max>#]", + "{Segments: [<[], 1>], UpperKey: [0#<Max>]}"), + std::make_tuple( + "{segments=[{lower_key=[];timestamp=1};{lower_key=[1];timestamp=2}];upper_key=[<type=max>#]}", + "[0]", + "[1]", + "{Segments: [<[], 1>, <[0#1], 2>], UpperKey: [0#<Max>]}"), + std::make_tuple( + "{segments=[{lower_key=[];timestamp=1};{lower_key=[1];timestamp=2}];upper_key=[<type=max>#]}", + "[1]", + "[2]", + "{Segments: [<[], 1>, <[0#1], 2>], UpperKey: [0#<Max>]}"), + std::make_tuple( + "{segments=[{lower_key=[];timestamp=1};{lower_key=[1];timestamp=2}];upper_key=[<type=max>#]}", + "[1]", + "[<type=max>#]", + "{Segments: [<[], 1>, <[0#1], 2>], UpperKey: [0#<Max>]}"), + std::make_tuple( + "{segments=[{lower_key=[];timestamp=1};{lower_key=[1];timestamp=2};{lower_key=[2];timestamp=3}];upper_key=[<type=max>#]}", + "[]", + "[1]", + "{Segments: [<[], 1>, <[0#1], 2>, ...], UpperKey: [0#<Max>]}"), + std::make_tuple( + "{segments=[{lower_key=[];timestamp=1};{lower_key=[1];timestamp=2};{lower_key=[2];timestamp=3}];upper_key=[<type=max>#]}", + "[1]", + "[2]", + "{Segments: [<[], 1>, <[0#1], 2>, <[0#2], 3>], UpperKey: [0#<Max>]}"), + std::make_tuple( + "{segments=[{lower_key=[];timestamp=1};{lower_key=[1];timestamp=2};{lower_key=[2];timestamp=3}];upper_key=[<type=max>#]}", + "[2]", + "[3]", + "{Segments: [<[], 1>, ..., <[0#2], 3>], UpperKey: [0#<Max>]}"), + std::make_tuple( + "{segments=[{lower_key=[];timestamp=1};{lower_key=[1];timestamp=2};{lower_key=[2];timestamp=3}];upper_key=[<type=max>#]}", + "[2]", + "[<type=max>#]", + "{Segments: [<[], 1>, ..., <[0#2], 3>], UpperKey: [0#<Max>]}"), + std::make_tuple( + "{segments=[{lower_key=[];timestamp=1};{lower_key=[1];timestamp=2};{lower_key=[2];timestamp=3};{lower_key=[3];timestamp=4};{lower_key=[4];timestamp=5};" + "{lower_key=[5];timestamp=6};{lower_key=[6];timestamp=7};{lower_key=[7];timestamp=8};{lower_key=[8];timestamp=9}];upper_key=[<type=max>#]}", + "[5]", + "[6]", + "{Segments: [<[], 1>, ..., <[0#5], 6>, <[0#6], 7>, ...], UpperKey: [0#<Max>]}") +)); + + +//////////////////////////////////////////////////////////////////////////////// + } // namespace } // namespace NYT::NChaosClient diff --git a/yt/yt/core/actions/future.h b/yt/yt/core/actions/future.h index 35f7ed0524..fc993062c8 100644 --- a/yt/yt/core/actions/future.h +++ b/yt/yt/core/actions/future.h @@ -472,7 +472,7 @@ public: * If the value is set before the call to #handlered, then * #handler is discarded. */ - bool OnCanceled(TCallback<void (const TError&)> handler) const; + bool OnCanceled(TCallback<void(const TError&)> handler) const; //! Converts promise into future. operator TFuture<T>() const; diff --git a/yt/yt/core/concurrency/execution_stack.cpp b/yt/yt/core/concurrency/execution_stack.cpp index 15e3b7ec57..3fcf1a11d4 100644 --- a/yt/yt/core/concurrency/execution_stack.cpp +++ b/yt/yt/core/concurrency/execution_stack.cpp @@ -1,8 +1,6 @@ #include "execution_stack.h" #include "private.h" -#include <yt/yt/core/misc/ref_tracked.h> - #if defined(_unix_) # include <sys/mman.h> # include <limits.h> @@ -16,6 +14,7 @@ #include <yt/yt/core/misc/object_pool.h> #include <library/cpp/yt/memory/ref.h> +#include <library/cpp/yt/memory/ref_tracked.h> #include <library/cpp/yt/misc/tls.h> diff --git a/yt/yt/core/concurrency/new_fair_share_thread_pool.cpp b/yt/yt/core/concurrency/new_fair_share_thread_pool.cpp index 2ebe055242..e5bcbc9775 100644 --- a/yt/yt/core/concurrency/new_fair_share_thread_pool.cpp +++ b/yt/yt/core/concurrency/new_fair_share_thread_pool.cpp @@ -16,6 +16,8 @@ #include <yt/yt/library/profiling/sensor.h> +#include <library/cpp/yt/containers/intrusive_linked_list.h> + #include <library/cpp/yt/memory/public.h> #include <library/cpp/yt/misc/tls.h> @@ -34,6 +36,7 @@ inline const NLogging::TLogger Logger("FairShareThreadPool"); namespace { +DECLARE_REFCOUNTED_CLASS(TBucketMapping) DECLARE_REFCOUNTED_CLASS(TTwoLevelFairShareQueue) DECLARE_REFCOUNTED_CLASS(TBucket) @@ -243,7 +246,7 @@ bool operator < (const TEnqueuedTime& lhs, const TEnqueuedTime& rhs) //////////////////////////////////////////////////////////////////////////////// // Data for scheduling on the first level. -struct TExecutionPool +struct TExecutionPool final : public THeapItemBase<TExecutionPool> { const TString PoolName; @@ -256,8 +259,6 @@ struct TExecutionPool const TEventTimer ExecTimeCounter; const TEventTimer TotalTimeCounter; const NProfiling::TTimeCounter CumulativeTimeCounter; - // Execution pool is retained for some after last usage to flush profiling counters. - TCpuInstant LastUsageTime = 0; // Action count is used to decide whether to reset excess time or not. size_t ActionCountInQueue = 0; @@ -265,11 +266,14 @@ struct TExecutionPool TCpuDuration NextUpdateWeightInstant = 0; double InverseWeight = 1.0; TCpuDuration ExcessTime = 0; - int BucketRefs = 0; TPriorityQueue<TBucket> ActiveBucketsHeap; TCpuDuration LastBucketExcessTime = 0; + TIntrusiveLinkedListNode<TExecutionPool> LinkedListNode; + // Execution pool is retained for some after last usage to flush profiling counters. + TCpuInstant LastUsageTime = 0; + TExecutionPool(TString poolName, const TProfiler& profiler) : PoolName(std::move(poolName)) , BucketCounter(profiler.Summary("/buckets")) @@ -287,6 +291,8 @@ bool operator < (const TExecutionPool& lhs, const TExecutionPool& rhs) return lhs.ExcessTime < rhs.ExcessTime; } +using TExecutionPoolPtr = ::NYT::TIntrusivePtr<TExecutionPool>; + //////////////////////////////////////////////////////////////////////////////// // Data for scheduling on the second level. @@ -296,7 +302,7 @@ struct TBucketBase const TString PoolName; TRingQueue<TAction> ActionQueue; - TExecutionPool* Pool = nullptr; + TExecutionPoolPtr Pool = nullptr; TCpuDuration ExcessTime = 0; @@ -321,7 +327,7 @@ class TBucket , public TBucketBase { public: - TBucket(TString bucketName, TString poolName, TTwoLevelFairShareQueuePtr parent) + TBucket(TString bucketName, TString poolName, TBucketMappingPtr parent) : TBucketBase(std::move(bucketName), std::move(poolName)) , Parent_(std::move(parent)) { } @@ -363,50 +369,51 @@ public: { } private: - const TTwoLevelFairShareQueuePtr Parent_; + const TBucketMappingPtr Parent_; }; DEFINE_REFCOUNTED_TYPE(TBucket) //////////////////////////////////////////////////////////////////////////////// -DEFINE_ENUM(ERequest, - (None) - (EndExecute) - (FetchNext) -); - -class TTwoLevelFairShareQueue +class TBucketMapping : public TRefCounted - , protected TNotifyManager { public: - using TWaitTimeObserver = ITwoLevelFairShareThreadPool::TWaitTimeObserver; + struct TExecutionPoolToListNode + { + auto operator() (TExecutionPool* pool) const + { + return &pool->LinkedListNode; + } + }; - TTwoLevelFairShareQueue( - TIntrusivePtr<NThreading::TEventCount> callbackEventCount, - const TString& threadNamePrefix, - const TNewTwoLevelFairShareThreadPoolOptions& options) - : TNotifyManager(std::move(callbackEventCount), GetThreadTags(threadNamePrefix), options.PollingPeriod) - , ThreadNamePrefix_(threadNamePrefix) - , Profiler_(TProfiler{"/fair_share_queue"} - .WithHot()) - , CumulativeSchedulingTimeCounter_(Profiler_.TimeCounter("/time/scheduling_cumulative")) - , PoolWeightProvider_(options.PoolWeightProvider) - , PoolRetentionTime_(options.PoolRetentionTime) - , VerboseLogging_(options.VerboseLogging) + using TPoolQueue = TIntrusiveLinkedList<TExecutionPool, TExecutionPoolToListNode>; + + explicit TBucketMapping(TDuration poolRetentionTime) + : PoolRetentionTime_(poolRetentionTime) { } - ~TTwoLevelFairShareQueue() + ~TBucketMapping() { - Shutdown(); - } + auto guard = Guard(MappingLock_); - void Configure(int threadCount) - { - ThreadCount_.store(threadCount); + while (RetainPoolQueue_.GetSize() > 0) { + auto* frontPool = RetainPoolQueue_.GetFront(); + + auto poolIt = PoolMapping_.find(frontPool->PoolName); + YT_ASSERT(poolIt != PoolMapping_.end() && poolIt->second == frontPool); + PoolMapping_.erase(poolIt); + + RetainPoolQueue_.PopFront(); + NYT::DestroyRefCounted(frontPool); + } } + virtual TProfiler GetPoolProfiler(const TString& poolName) = 0; + + virtual void Invoke(TClosure callback, TBucket* bucket) = 0; + // GetInvoker is protected by mapping lock (can be sharded). IInvokerPtr GetInvoker(const TString& poolName, const TString& bucketName) { @@ -419,6 +426,7 @@ public: if (!bucket) { bucket = New<TBucket>(bucketName, poolName, MakeStrong(this)); bucketIt->second = bucket.Get(); + bucket->Pool = GetOrRegisterPool(bucket->PoolName); } return bucket; @@ -427,25 +435,191 @@ public: // GetInvoker is protected by mapping lock (can be sharded). void RemoveBucket(TBucket* bucket) { - { - auto guard = Guard(MappingLock_); - auto bucketIt = BucketMapping_.find(std::make_pair(bucket->PoolName, bucket->BucketName)); + auto guard = Guard(MappingLock_); + auto bucketIt = BucketMapping_.find(std::make_pair(bucket->PoolName, bucket->BucketName)); + + if (bucketIt != BucketMapping_.end() && bucketIt->second == bucket) { + BucketMapping_.erase(bucketIt); + } + + // Detach under lock. + auto* poolDangerousPtr = bucket->Pool.Release(); - if (bucketIt != BucketMapping_.end() && bucketIt->second == bucket) { - BucketMapping_.erase(bucketIt); + // Do not want use NewWithDeleter and keep pointer to TTwoLevelFairShareQueue in each execution pool. + if (NYT::GetRefCounter(poolDangerousPtr)->Unref(1)) { + auto poolsToRemove = DetachPool(poolDangerousPtr); + guard.Release(); + + while (poolsToRemove.GetSize() > 0) { + auto* frontPool = poolsToRemove.GetFront(); + poolsToRemove.PopFront(); + NYT::DestroyRefCounted(frontPool); } } + } + + TExecutionPoolPtr GetOrRegisterPool(TString poolName) + { + VERIFY_SPINLOCK_AFFINITY(MappingLock_); + + auto [mappingIt, inserted] = PoolMapping_.emplace(poolName, nullptr); + if (!inserted) { + YT_ASSERT(mappingIt->second->PoolName == poolName); + + auto* pool = mappingIt->second; + // If RetainPoolQueue_ contains only one element its LinkedListNode will be null. + // Determine that pool is in RetainPoolQueue_ by checking its ref count. + if (NYT::GetRefCounter(pool)->GetRefCount() == 0) { + RetainPoolQueue_.Remove(pool); + pool->LinkedListNode = {}; + + YT_LOG_TRACE("Restoring pool (PoolName: %v)", pool->PoolName); + } + + YT_LOG_TRACE("Reusing pool (PoolName: %v)", pool->PoolName); - // Using non atomic Pool pointer is safe because it is set once and RemoveBucket cannot be - // concurrently executed with ConsumeInvokeQueue. - // Pool is nullptr when bucket was created but no actions were invoked. - if (auto* pool = bucket->Pool) { - UnlinkBucketQueue_.Enqueue(pool); + return pool; + } else { + YT_LOG_TRACE("Creating pool (PoolName: %v)", poolName); + auto pool = New<TExecutionPool>(poolName, GetPoolProfiler(poolName)); + mappingIt->second = pool.Get(); + + return pool; } } + TPoolQueue DetachPool(TExecutionPool* pool) + { + VERIFY_SPINLOCK_AFFINITY(MappingLock_); + + YT_LOG_TRACE("Removing pool (PoolName: %v)", pool->PoolName); + + auto currentInstant = GetCpuInstant(); + pool->LastUsageTime = currentInstant; + + // Items in RetainPoolQueue_ are ordered by LastUsageTime. + // When pool is used again it is removed from RetainPoolQueue_. + RetainPoolQueue_.PushBack(pool); + return ProceedRetainQueue(currentInstant); + } + + TPoolQueue ProceedRetainQueue(TCpuInstant currentInstant) + { + VERIFY_SPINLOCK_AFFINITY(MappingLock_); + + YT_LOG_TRACE("ProceedRetainQueue (Size: %v)", RetainPoolQueue_.GetSize()); + + TPoolQueue poolsToRemove; + + while (RetainPoolQueue_.GetSize() > 0) { + auto* frontPool = RetainPoolQueue_.GetFront(); + + auto lastUsageTime = frontPool->LastUsageTime; + if (CpuDurationToDuration(currentInstant - lastUsageTime) < PoolRetentionTime_) { + break; + } + + YT_LOG_TRACE("Destroing pool (PoolName: %v)", frontPool->PoolName); + + auto poolIt = PoolMapping_.find(frontPool->PoolName); + YT_ASSERT(poolIt != PoolMapping_.end() && poolIt->second == frontPool); + PoolMapping_.erase(poolIt); + + RetainPoolQueue_.PopFront(); + poolsToRemove.PushBack(frontPool); + } + + return poolsToRemove; + } + + void MaybeProceedRetainQueue(TCpuInstant currentInstant) + { + if (!MappingLock_.TryAcquire()) { + return; + } + + auto finally = Finally([&] { + MappingLock_.Release(); + }); + + auto poolsToRemove = ProceedRetainQueue(currentInstant); + MappingLock_.Release(); + finally.Release(); + + while (poolsToRemove.GetSize() > 0) { + auto* frontPool = poolsToRemove.GetFront(); + poolsToRemove.PopFront(); + NYT::DestroyRefCounted(frontPool); + } + } + +private: + const TDuration PoolRetentionTime_; + + YT_DECLARE_SPIN_LOCK(NThreading::TSpinLock, MappingLock_); + THashMap<std::pair<TString, TString>, TBucket*> BucketMapping_; + THashMap<TString, TExecutionPool*> PoolMapping_; + + TPoolQueue RetainPoolQueue_; +}; + +DEFINE_REFCOUNTED_TYPE(TBucketMapping) + +//////////////////////////////////////////////////////////////////////////////// + +void TBucket::Invoke(TClosure callback) +{ + Parent_->Invoke(std::move(callback), this); +} + +TBucket::~TBucket() +{ + Parent_->RemoveBucket(this); +} + +//////////////////////////////////////////////////////////////////////////////// + +DEFINE_ENUM(ERequest, + (None) + (EndExecute) + (FetchNext) +); + +class TTwoLevelFairShareQueue + : protected TNotifyManager + , public TBucketMapping +{ +public: + using TWaitTimeObserver = ITwoLevelFairShareThreadPool::TWaitTimeObserver; + + TTwoLevelFairShareQueue( + TIntrusivePtr<NThreading::TEventCount> callbackEventCount, + const TString& threadNamePrefix, + const TNewTwoLevelFairShareThreadPoolOptions& options) + : TNotifyManager(std::move(callbackEventCount), GetThreadTags(threadNamePrefix), options.PollingPeriod) + , TBucketMapping(options.PoolRetentionTime) + , ThreadNamePrefix_(threadNamePrefix) + , Profiler_(TProfiler{"/fair_share_queue"} + .WithHot()) + , CumulativeSchedulingTimeCounter_(Profiler_ + .WithTags(GetThreadTags(ThreadNamePrefix_)) + .TimeCounter("/time/scheduling_cumulative")) + , PoolWeightProvider_(options.PoolWeightProvider) + , VerboseLogging_(options.VerboseLogging) + { } + + ~TTwoLevelFairShareQueue() + { + Shutdown(); + } + + void Configure(int threadCount) + { + ThreadCount_.store(threadCount); + } + // Invoke is lock free. - void Invoke(TClosure callback, TBucket* bucket) + void Invoke(TClosure callback, TBucket* bucket) override { if (Stopped_.load()) { return; @@ -573,14 +747,8 @@ private: const TProfiler Profiler_; const NProfiling::TTimeCounter CumulativeSchedulingTimeCounter_; const IPoolWeightProviderPtr PoolWeightProvider_; - const TDuration PoolRetentionTime_; const bool VerboseLogging_; - // TODO(lukyan): Sharded mapping. - YT_DECLARE_SPIN_LOCK(NThreading::TSpinLock, MappingLock_); - THashMap<std::pair<TString, TString>, TBucket*> BucketMapping_; - TMpscStack<TExecutionPool*> UnlinkBucketQueue_; - std::atomic<bool> Stopped_ = false; TMpscStack<TAction> InvokeQueue_; char Padding0_[CacheLineSize - sizeof(TMpscStack<TAction>)]; @@ -591,7 +759,6 @@ private: std::array<TThreadState, TThreadPoolBase::MaxThreadCount> ThreadStates_; - THashMap<TString, std::unique_ptr<TExecutionPool>> PoolMapping_; TPriorityQueue<TExecutionPool> ActivePoolsHeap_; TCpuDuration LastPoolExcessTime_ = 0; TPriorityQueue<TEnqueuedTime> WaitHeap_; @@ -604,21 +771,9 @@ private: std::atomic<bool> IsWaitTimeObserverSet_; TWaitTimeObserver WaitTimeObserver_; - TExecutionPool* GetOrRegisterPool(TString poolName) + TProfiler GetPoolProfiler(const TString& poolName) override { - VERIFY_SPINLOCK_AFFINITY(MainLock_); - - auto [mappingIt, inserted] = PoolMapping_.emplace(poolName, nullptr); - if (!inserted) { - YT_ASSERT(mappingIt->second->PoolName == poolName); - } else { - YT_LOG_TRACE("Creating pool (PoolName: %v)", poolName); - mappingIt->second = std::make_unique<TExecutionPool>( - poolName, - Profiler_.WithTags(GetBucketTags(ThreadNamePrefix_, poolName))); - } - - return mappingIt->second.get(); + return Profiler_.WithTags(GetBucketTags(ThreadNamePrefix_, poolName)); } Y_NO_INLINE void ConsumeInvokeQueue() @@ -631,12 +786,10 @@ private: InvokeQueue_.DequeueAll(true, [&] (auto& action) { auto* bucket = action.BucketHolder.Get(); - if (bucket->Pool == nullptr) { - bucket->Pool = GetOrRegisterPool(bucket->PoolName); - bucket->Pool->BucketRefs++; - } + auto* pool = bucket->Pool.Get(); + + YT_VERIFY(!pool->LinkedListNode.Next && !pool->LinkedListNode.Prev); - auto* pool = bucket->Pool; if (!pool->GetPositionInHeap()) { // ExcessTime can be greater than last pool excess time // if the pool is "currently executed" and reschedules action. @@ -690,25 +843,6 @@ private: }); } - Y_NO_INLINE void ProcessUnlinkedBuckets(TCpuInstant currentInstant) - { - UnlinkBucketQueue_.FilterElements([&] (TExecutionPool* pool) { - YT_ASSERT(pool->BucketRefs > 0); - if (pool->BucketRefs == 1) { - auto lastUsageTime = pool->LastUsageTime; - if (CpuDurationToDuration(currentInstant - lastUsageTime) < PoolRetentionTime_) { - return true; - } - auto poolIt = PoolMapping_.find(pool->PoolName); - YT_ASSERT(poolIt != PoolMapping_.end() && poolIt->second.get() == pool); - PoolMapping_.erase(poolIt); - } else { - --pool->BucketRefs; - } - return false; - }); - } - void ServeBeginExecute(TThreadState* threadState, TCpuInstant currentInstant, TAction action) { VERIFY_SPINLOCK_AFFINITY(MainLock_); @@ -722,7 +856,7 @@ private: threadState->Action = std::move(action); } - void ServeEndExecute(TThreadState* threadState, TCpuInstant cpuInstant) + void ServeEndExecute(TThreadState* threadState, TCpuInstant /*cpuInstant*/) { VERIFY_SPINLOCK_AFFINITY(MainLock_); @@ -741,8 +875,6 @@ private: auto& pool = *bucket->Pool; YT_ASSERT(pool.PoolName == bucket->PoolName); - pool.LastUsageTime = cpuInstant; - // LastActionsInQueue is used to update SizeCounter outside lock. threadState->LastActionsInQueue = --pool.ActionCountInQueue; @@ -755,7 +887,7 @@ private: { VERIFY_SPINLOCK_AFFINITY(MainLock_); - auto* pool = bucket->Pool; + auto* pool = bucket->Pool.Get(); if (PoolWeightProvider_ && pool->NextUpdateWeightInstant < currentInstant) { pool->NextUpdateWeightInstant = currentInstant + DurationToCpuDuration(TDuration::Seconds(1)); @@ -887,8 +1019,6 @@ private: ConsumeInvokeQueue(); - ProcessUnlinkedBuckets(currentInstant); - int fetchedActions = 0; int otherActionCount = 0; @@ -974,7 +1104,7 @@ private: auto finally = Finally([&] { auto bucketToUndef = std::move(threadState.BucketToUnref); if (bucketToUndef) { - auto* pool = bucketToUndef->Pool; + auto* pool = bucketToUndef->Pool.Get(); pool->SizeCounter.Record(threadState.LastActionsInQueue); pool->DequeuedCounter.Increment(1); pool->ExecTimeCounter.Record(threadState.TimeFromStart); @@ -991,6 +1121,10 @@ private: } CumulativeSchedulingTimeCounter_.Add(CpuDurationToDuration(GetCpuInstant() - cpuInstant)); + + if (!fetchNext) { + MaybeProceedRetainQueue(cpuInstant); + } }); auto& request = threadState.Request; @@ -1043,18 +1177,6 @@ DEFINE_REFCOUNTED_TYPE(TTwoLevelFairShareQueue) //////////////////////////////////////////////////////////////////////////////// -void TBucket::Invoke(TClosure callback) -{ - Parent_->Invoke(std::move(callback), this); -} - -TBucket::~TBucket() -{ - Parent_->RemoveBucket(this); -} - -//////////////////////////////////////////////////////////////////////////////// - class TFairShareThread : public TSchedulerThread { diff --git a/yt/yt/core/concurrency/thread_pool_poller.cpp b/yt/yt/core/concurrency/thread_pool_poller.cpp index f486003cc1..f93d507673 100644 --- a/yt/yt/core/concurrency/thread_pool_poller.cpp +++ b/yt/yt/core/concurrency/thread_pool_poller.cpp @@ -10,12 +10,13 @@ #include <yt/yt/core/misc/collection_helpers.h> #include <yt/yt/core/misc/proc.h> #include <yt/yt/core/misc/mpsc_stack.h> -#include <yt/yt/core/misc/ref_tracked.h> #include <yt/yt/core/profiling/tscp.h> #include <library/cpp/yt/threading/notification_handle.h> +#include <library/cpp/yt/memory/ref_tracked.h> + #include <util/system/thread.h> #include <util/thread/lfqueue.h> diff --git a/yt/yt/core/concurrency/throughput_throttler.cpp b/yt/yt/core/concurrency/throughput_throttler.cpp index f598f5190d..bdfe1d1724 100644 --- a/yt/yt/core/concurrency/throughput_throttler.cpp +++ b/yt/yt/core/concurrency/throughput_throttler.cpp @@ -477,7 +477,7 @@ IReconfigurableThroughputThrottlerPtr CreateNamedReconfigurableThroughputThrottl //////////////////////////////////////////////////////////////////////////////// class TUnlimitedThroughputThrottler - : public IThroughputThrottler + : public IReconfigurableThroughputThrottler { public: explicit TUnlimitedThroughputThrottler( @@ -552,17 +552,37 @@ public: YT_UNIMPLEMENTED(); } + void Reconfigure(TThroughputThrottlerConfigPtr /*config*/) override + { + VERIFY_THREAD_AFFINITY_ANY(); + } + + void SetLimit(std::optional<double> /*limit*/) override + { + VERIFY_THREAD_AFFINITY_ANY(); + } + + TFuture<void> GetAvailableFuture() override + { + YT_UNIMPLEMENTED(); + } + + TThroughputThrottlerConfigPtr GetConfig() const override + { + YT_UNIMPLEMENTED(); + } + private: NProfiling::TCounter ValueCounter_; NProfiling::TCounter ReleaseCounter_; }; -IThroughputThrottlerPtr GetUnlimitedThrottler() +IReconfigurableThroughputThrottlerPtr GetUnlimitedThrottler() { return LeakyRefCountedSingleton<TUnlimitedThroughputThrottler>(); } -IThroughputThrottlerPtr CreateNamedUnlimitedThroughputThrottler( +IReconfigurableThroughputThrottlerPtr CreateNamedUnlimitedThroughputThrottler( const TString& name, NProfiling::TProfiler profiler) { diff --git a/yt/yt/core/concurrency/throughput_throttler.h b/yt/yt/core/concurrency/throughput_throttler.h index c4dd476a97..df03931b16 100644 --- a/yt/yt/core/concurrency/throughput_throttler.h +++ b/yt/yt/core/concurrency/throughput_throttler.h @@ -129,10 +129,10 @@ IReconfigurableThroughputThrottlerPtr CreateNamedReconfigurableThroughputThrottl NProfiling::TProfiler profiler = {}); //! Returns a throttler that imposes no throughput limit. -IThroughputThrottlerPtr GetUnlimitedThrottler(); +IReconfigurableThroughputThrottlerPtr GetUnlimitedThrottler(); //! Returns a throttler that imposes no throughput limit and profiles throughput. -IThroughputThrottlerPtr CreateNamedUnlimitedThroughputThrottler( +IReconfigurableThroughputThrottlerPtr CreateNamedUnlimitedThroughputThrottler( const TString& name, NProfiling::TProfiler profiler = {}); diff --git a/yt/yt/core/crypto/public.h b/yt/yt/core/crypto/public.h index 2b524c79ef..8e658bd6cf 100644 --- a/yt/yt/core/crypto/public.h +++ b/yt/yt/core/crypto/public.h @@ -2,7 +2,7 @@ #include <yt/yt/core/misc/public.h> -#include <yt/yt/core/misc/intrusive_ptr.h> +#include <library/cpp/yt/memory/intrusive_ptr.h> namespace NYT::NCrypto { diff --git a/yt/yt/core/crypto/tls.cpp b/yt/yt/core/crypto/tls.cpp index 26c89a0823..793b0571a1 100644 --- a/yt/yt/core/crypto/tls.cpp +++ b/yt/yt/core/crypto/tls.cpp @@ -279,7 +279,7 @@ public: .Run(); } - void SubscribePeerDisconnect(TCallback<void ()> cb) override + void SubscribePeerDisconnect(TCallback<void()> cb) override { return Underlying_->SubscribePeerDisconnect(std::move(cb)); } diff --git a/yt/yt/core/logging/log_manager.cpp b/yt/yt/core/logging/log_manager.cpp index b95beb20fb..021f7fc9aa 100644 --- a/yt/yt/core/logging/log_manager.cpp +++ b/yt/yt/core/logging/log_manager.cpp @@ -137,11 +137,6 @@ public: YT_ASSERT(rv >= static_cast<ssize_t>(sizeof(struct inotify_event))); struct inotify_event* event = (struct inotify_event*)buffer; - if (event->mask & IN_ATTRIB) { - YT_LOG_TRACE( - "Watch %v has triggered metadata change (IN_ATTRIB)", - event->wd); - } if (event->mask & IN_DELETE_SELF) { YT_LOG_TRACE( "Watch %v has triggered a deletion (IN_DELETE_SELF)", @@ -201,9 +196,10 @@ public: void Run() { - Callback_(); - // Reinitialize watch to hook to the newly created file. + // Unregister before create a new file. DropWatch(); + Callback_(); + // Register the newly created file. CreateWatch(); } @@ -215,7 +211,7 @@ private: WD_ = inotify_add_watch( FD_, Path_.c_str(), - IN_ATTRIB | IN_DELETE_SELF | IN_MOVE_SELF); + IN_DELETE_SELF | IN_MOVE_SELF); if (WD_ < 0) { YT_LOG_ERROR(TError::FromSystem(errno), "Error registering watch for %v", @@ -892,6 +888,7 @@ private: KeyToCachedWriter_.clear(); WDToNotificationWatch_.clear(); NotificationWatches_.clear(); + InvalidNotificationWatches_.clear(); for (const auto& [name, writerConfig] : config->Writers) { auto typedWriterConfig = ConvertTo<TLogWriterConfigPtr>(writerConfig); @@ -910,12 +907,10 @@ private: if (auto fileWriter = DynamicPointerCast<IFileLogWriter>(writer)) { auto watch = CreateNotificationWatch(config, fileWriter); - if (watch && watch->IsValid()) { - // Watch can fail to initialize if the writer is disabled - // e.g. due to the lack of space. - EmplaceOrCrash(WDToNotificationWatch_, watch->GetWD(), watch.get()); + if (watch) { + RegisterNotificatonWatch(watch.get()); + NotificationWatches_.push_back(std::move(watch)); } - NotificationWatches_.push_back(std::move(watch)); } } for (const auto& [_, category] : NameToCategory_) { @@ -992,6 +987,17 @@ private: } } + void RegisterNotificatonWatch(TNotificationWatch* watch) + { + if (watch->IsValid()) { + // Watch can fail to initialize if the writer is disabled + // e.g. due to the lack of space. + EmplaceOrCrash(WDToNotificationWatch_, watch->GetWD(), watch); + } else { + InvalidNotificationWatches_.push_back(watch); + } + } + void WatchWriters() { VERIFY_THREAD_AFFINITY(LoggingThread); @@ -1016,15 +1022,20 @@ private: if (watch->GetWD() != currentWD) { WDToNotificationWatch_.erase(it); - if (watch->GetWD() >= 0) { - // Watch can fail to initialize if the writer is disabled - // e.g. due to the lack of space. - EmplaceOrCrash(WDToNotificationWatch_, watch->GetWD(), watch); - } + RegisterNotificatonWatch(watch); } previousWD = currentWD; } + // Handle invalid watches, try to register they again. + { + std::vector<TNotificationWatch*> invalidNotificationWatches; + invalidNotificationWatches.swap(InvalidNotificationWatches_); + for (auto* watch : invalidNotificationWatches) { + watch->Run(); + RegisterNotificatonWatch(watch); + } + } } void PushEvent(TLoggerQueueItem&& event) @@ -1453,6 +1464,7 @@ private: std::unique_ptr<TNotificationHandle> NotificationHandle_; std::vector<std::unique_ptr<TNotificationWatch>> NotificationWatches_; THashMap<int, TNotificationWatch*> WDToNotificationWatch_; + std::vector<TNotificationWatch*> InvalidNotificationWatches_; THashMap<TString, TLoggingAnchor*> AnchorMap_; std::atomic<TLoggingAnchor*> FirstAnchor_ = nullptr; diff --git a/yt/yt/core/misc/atomic_ptr.h b/yt/yt/core/misc/atomic_ptr.h index 89104ad7bb..4cd9375bbd 100644 --- a/yt/yt/core/misc/atomic_ptr.h +++ b/yt/yt/core/misc/atomic_ptr.h @@ -1,7 +1,8 @@ #pragma once #include "hazard_ptr.h" -#include "intrusive_ptr.h" + +#include <library/cpp/yt/memory/intrusive_ptr.h> namespace NYT { diff --git a/yt/yt/core/misc/fs.cpp b/yt/yt/core/misc/fs.cpp index 440956f273..a6e0de19b6 100644 --- a/yt/yt/core/misc/fs.cpp +++ b/yt/yt/core/misc/fs.cpp @@ -2,7 +2,6 @@ #include "finally.h" #include <yt/yt/core/logging/log.h> -#include <yt/yt/core/misc/ref_counted.h> #include <yt/yt/core/misc/proc.h> diff --git a/yt/yt/core/misc/intrusive_ptr.h b/yt/yt/core/misc/intrusive_ptr.h deleted file mode 100644 index 0a9b9ab14d..0000000000 --- a/yt/yt/core/misc/intrusive_ptr.h +++ /dev/null @@ -1 +0,0 @@ -#include <library/cpp/yt/memory/intrusive_ptr.h> diff --git a/yt/yt/core/misc/ref_counted.h b/yt/yt/core/misc/ref_counted.h deleted file mode 100644 index 9d5675f4ff..0000000000 --- a/yt/yt/core/misc/ref_counted.h +++ /dev/null @@ -1 +0,0 @@ -#include <library/cpp/yt/memory/ref_counted.h> diff --git a/yt/yt/core/misc/ref_tracked.cpp b/yt/yt/core/misc/ref_tracked.cpp index 3d7551a8f6..b3a7b0a159 100644 --- a/yt/yt/core/misc/ref_tracked.cpp +++ b/yt/yt/core/misc/ref_tracked.cpp @@ -1,6 +1,7 @@ -#include "ref_tracked.h" #include "ref_counted_tracker.h" +#include <library/cpp/yt/memory/ref_tracked.h> + namespace NYT { //////////////////////////////////////////////////////////////////////////////// diff --git a/yt/yt/core/misc/ref_tracked.h b/yt/yt/core/misc/ref_tracked.h deleted file mode 100644 index 4d94188f9a..0000000000 --- a/yt/yt/core/misc/ref_tracked.h +++ /dev/null @@ -1 +0,0 @@ -#include <library/cpp/yt/memory/ref_tracked.h> diff --git a/yt/yt/core/misc/signal_registry.cpp b/yt/yt/core/misc/signal_registry.cpp index 27fe3b250d..05b87590d5 100644 --- a/yt/yt/core/misc/signal_registry.cpp +++ b/yt/yt/core/misc/signal_registry.cpp @@ -4,13 +4,15 @@ #include <library/cpp/yt/system/thread_id.h> +#include <util/generic/algorithm.h> + #include <signal.h> namespace NYT { //////////////////////////////////////////////////////////////////////////////// -std::vector<int> CrashSignals = { +constexpr std::initializer_list<int> CrashSignals{ SIGSEGV, SIGILL, SIGFPE, @@ -20,8 +22,6 @@ std::vector<int> CrashSignals = { #endif }; -//////////////////////////////////////////////////////////////////////////////// - // This variable is used for protecting signal handlers for crash signals from // dumping stuff while another thread is already doing that. Our policy is to let // the first thread dump stuff and make other threads wait. @@ -43,19 +43,22 @@ void TSignalRegistry::SetupSignal(int signal, int flags) YT_VERIFY(signal != SIGALRM); if (!OverrideNonDefaultSignalHandlers_) { - struct sigaction oldact; - YT_VERIFY(sigaction(signal, NULL, &oldact) == 0); - if (reinterpret_cast<void*>(oldact.sa_sigaction) != SIG_DFL) { + struct sigaction sa; + YT_VERIFY(sigaction(signal, nullptr, &sa) == 0); + if (reinterpret_cast<void*>(sa.sa_sigaction) != SIG_DFL) { return; } } - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sigemptyset(&sa.sa_mask); - sa.sa_flags = flags | SA_SIGINFO; - sa.sa_sigaction = &Handle; - YT_VERIFY(sigaction(signal, &sa, NULL) == 0); + { + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sigemptyset(&sa.sa_mask); + sa.sa_flags = flags | SA_SIGINFO | SA_ONSTACK; + sa.sa_sigaction = &Handle; + YT_VERIFY(sigaction(signal, &sa, nullptr) == 0); + } + Signals_[signal].SetUp = true; }); #else @@ -84,7 +87,7 @@ void TSignalRegistry::PushCallback(int signal, TSignalRegistry::TSignalHandler c #ifdef _unix_ void TSignalRegistry::PushCallback(int signal, std::function<void(int)> callback) { - PushCallback(signal, [callback = std::move(callback)] (int signal, siginfo_t* /* siginfo */, void* /* ucontext */) { + PushCallback(signal, [callback = std::move(callback)] (int signal, siginfo_t* /*siginfo*/, void* /*ucontext*/) { callback(signal); }); } @@ -93,11 +96,11 @@ void TSignalRegistry::PushCallback(int signal, std::function<void(int)> callback void TSignalRegistry::PushCallback(int signal, std::function<void(void)> callback) { #ifdef _unix_ - PushCallback(signal, [callback = std::move(callback)] (int /* signal */, siginfo_t* /* siginfo */, void* /* ucontext */) { + PushCallback(signal, [callback = std::move(callback)] (int /*signal*/, siginfo_t* /*siginfo*/, void* /*ucontext*/) { callback(); }); #else - PushCallback(signal, [callback = std::move(callback)] (int /* signal */) { + PushCallback(signal, [callback = std::move(callback)] (int /*signal*/) { callback(); }); #endif @@ -107,11 +110,13 @@ void TSignalRegistry::PushDefaultSignalHandler(int signal) { PushCallback(signal, [] (int signal) { #ifdef _unix_ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sigemptyset(&sa.sa_mask); - sa.sa_handler = SIG_DFL; - YT_VERIFY(sigaction(signal, &sa, nullptr) == 0); + { + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sigemptyset(&sa.sa_mask); + sa.sa_handler = SIG_DFL; + YT_VERIFY(sigaction(signal, &sa, nullptr) == 0); + } YT_VERIFY(raise(signal) == 0); #else @@ -130,13 +135,12 @@ void TSignalRegistry::Handle(int signal) auto* self = Get(); if (self->EnableCrashSignalProtection_ && - std::find(CrashSignals.begin(), CrashSignals.end(), signal) != CrashSignals.end()) { + Find(CrashSignals, signal) != CrashSignals.end()) + { // For crash signals we try pretty hard to prevent simultaneous execution of // several crash handlers. - auto currentThreadId = GetSequentialThreadId(); auto expectedCrashingThreadId = InvalidSequentialThreadId; - if (!CrashingThreadId.compare_exchange_strong(expectedCrashingThreadId, currentThreadId)) { // We've already entered the signal handler. What should we do? if (currentThreadId == expectedCrashingThreadId) { diff --git a/yt/yt/core/misc/signal_registry.h b/yt/yt/core/misc/signal_registry.h index c0fe057289..23dbdeb950 100644 --- a/yt/yt/core/misc/signal_registry.h +++ b/yt/yt/core/misc/signal_registry.h @@ -16,35 +16,35 @@ constexpr int AllCrashSignals = -1; class TSignalRegistry { public: - //! Flag enabling mechanism which protects multiple crash signal handlers from simultaneous + //! Enables a mechanism which protects multiple crash signal handlers from simultaneous //! execution. DEFINE_BYVAL_RW_PROPERTY(bool, EnableCrashSignalProtection, true); - //! Flag preventing us to override user custom signal handlers. + //! Prevents from overriding user custom signal handlers. DEFINE_BYVAL_RW_PROPERTY(bool, OverrideNonDefaultSignalHandlers, true); +public: #ifdef _unix_ using TSignalHandler = std::function<void(int, siginfo_t*, void*)>; #else using TSignalHandler = std::function<void(int)>; #endif -public: static TSignalRegistry* Get(); - //! Setup our handler that invokes registered callbacks in order. + //! Sets up our handler that invokes registered callbacks in order. //! Flags has same meaning as sa_flags in sigaction(2). Use this method if you need certain flags. //! By default any signal touched by PushCallback(...) will be set up with default flags. void SetupSignal(int signal, int flags = 0); - //! Add simple callback which should be called for signal. Different signatures are supported for convenience. + //! Adds a simple callback which should be called for signal. Different signatures are supported for convenience. void PushCallback(int signal, std::function<void(void)> callback); #ifdef _unix_ void PushCallback(int signal, std::function<void(int)> callback); #endif void PushCallback(int signal, TSignalHandler callback); - //! Add default signal handler which is called after invoking our custom handlers. + //! Adds the default signal handler which is called after invoking our custom handlers. //! NB: this handler restores default signal handler as a side-effect. Use it only //! when default handler terminates the program. void PushDefaultSignalHandler(int signal); diff --git a/yt/yt/core/misc/unittests/ref_counted_tracker_ut.cpp b/yt/yt/core/misc/unittests/ref_counted_tracker_ut.cpp index 538f03989f..faf1352a5b 100644 --- a/yt/yt/core/misc/unittests/ref_counted_tracker_ut.cpp +++ b/yt/yt/core/misc/unittests/ref_counted_tracker_ut.cpp @@ -6,15 +6,15 @@ #include <yt/yt/core/misc/blob.h> #include <yt/yt/core/misc/protobuf_helpers.h> -#include <yt/yt/core/misc/ref_counted.h> #include <yt/yt/core/misc/ref_counted_tracker.h> -#include <yt/yt/core/misc/ref_tracked.h> #include <yt/yt/core/actions/future.h> #include <yt/yt/core/concurrency/action_queue.h> #include <library/cpp/yt/memory/new.h> +#include <library/cpp/yt/memory/ref_tracked.h> +#include <library/cpp/yt/memory/ref_counted.h> namespace NYT { namespace { diff --git a/yt/yt/core/net/connection.h b/yt/yt/core/net/connection.h index e52de86abb..8512e5bc7e 100644 --- a/yt/yt/core/net/connection.h +++ b/yt/yt/core/net/connection.h @@ -4,11 +4,12 @@ #include <yt/yt/core/concurrency/async_stream.h> -#include <yt/yt/core/misc/ref_counted.h> #include <yt/yt/core/misc/proc.h> #include <yt/yt/core/net/address.h> +#include <library/cpp/yt/memory/ref_counted.h> + namespace NYT::NNet { //////////////////////////////////////////////////////////////////////////////// diff --git a/yt/yt/core/net/packet_connection.h b/yt/yt/core/net/packet_connection.h index 36c21175c1..a4450df1e3 100644 --- a/yt/yt/core/net/packet_connection.h +++ b/yt/yt/core/net/packet_connection.h @@ -2,10 +2,10 @@ #include "public.h" -#include <yt/yt/core/misc/ref_counted.h> - #include <yt/yt/core/net/address.h> +#include <library/cpp/yt/memory/ref_counted.h> + namespace NYT::NNet { //////////////////////////////////////////////////////////////////////////////// diff --git a/yt/yt/core/net/public.h b/yt/yt/core/net/public.h index bb1b74c615..05d3ec03de 100644 --- a/yt/yt/core/net/public.h +++ b/yt/yt/core/net/public.h @@ -2,7 +2,7 @@ #include <yt/yt/core/misc/public.h> -#include <yt/yt/core/misc/intrusive_ptr.h> +#include <library/cpp/yt/memory/intrusive_ptr.h> namespace NYT::NNet { diff --git a/yt/yt/core/rpc/config.cpp b/yt/yt/core/rpc/config.cpp index 14143a6585..ec29c3b88c 100644 --- a/yt/yt/core/rpc/config.cpp +++ b/yt/yt/core/rpc/config.cpp @@ -38,6 +38,20 @@ void TServiceCommonConfig::Register(TRegistrar registrar) //////////////////////////////////////////////////////////////////////////////// +void TServiceCommonDynamicConfig::Register(TRegistrar registrar) +{ + registrar.Parameter("enable_per_user_profiling", &TThis::EnablePerUserProfiling) + .Default(); + registrar.Parameter("histogram_timer_profiling", &TThis::HistogramTimerProfiling) + .Default(); + registrar.Parameter("code_counting", &TThis::EnableErrorCodeCounting) + .Default(); + registrar.Parameter("tracing_mode", &TThis::TracingMode) + .Default(); +} + +//////////////////////////////////////////////////////////////////////////////// + void TServerConfig::Register(TRegistrar registrar) { registrar.Parameter("services", &TThis::Services) @@ -46,6 +60,14 @@ void TServerConfig::Register(TRegistrar registrar) //////////////////////////////////////////////////////////////////////////////// +void TServerDynamicConfig::Register(TRegistrar registrar) +{ + registrar.Parameter("services", &TThis::Services) + .Default(); +} + +//////////////////////////////////////////////////////////////////////////////// + void TServiceConfig::Register(TRegistrar registrar) { registrar.Parameter("enable_per_user_profiling", &TThis::EnablePerUserProfiling) diff --git a/yt/yt/core/rpc/config.h b/yt/yt/core/rpc/config.h index be8c1fdec5..9cdf971d18 100644 --- a/yt/yt/core/rpc/config.h +++ b/yt/yt/core/rpc/config.h @@ -90,6 +90,40 @@ DEFINE_REFCOUNTED_TYPE(TServerConfig) //////////////////////////////////////////////////////////////////////////////// +// Common options shared between all services in one server. +class TServiceCommonDynamicConfig + : public NYTree::TYsonStruct +{ +public: + std::optional<bool> EnablePerUserProfiling; + std::optional<THistogramConfigPtr> HistogramTimerProfiling; + std::optional<bool> EnableErrorCodeCounting; + std::optional<ERequestTracingMode> TracingMode; + + REGISTER_YSON_STRUCT(TServiceCommonDynamicConfig); + + static void Register(TRegistrar registrar); +}; + +DEFINE_REFCOUNTED_TYPE(TServiceCommonDynamicConfig) + +//////////////////////////////////////////////////////////////////////////////// + +class TServerDynamicConfig + : public TServiceCommonDynamicConfig +{ +public: + THashMap<TString, NYTree::INodePtr> Services; + + REGISTER_YSON_STRUCT(TServerDynamicConfig); + + static void Register(TRegistrar registrar); +}; + +DEFINE_REFCOUNTED_TYPE(TServerDynamicConfig) + +//////////////////////////////////////////////////////////////////////////////// + class TServiceConfig : public NYTree::TYsonStruct { diff --git a/yt/yt/core/rpc/public.h b/yt/yt/core/rpc/public.h index af88870ad9..5548fa0f22 100644 --- a/yt/yt/core/rpc/public.h +++ b/yt/yt/core/rpc/public.h @@ -107,6 +107,8 @@ DECLARE_REFCOUNTED_CLASS(THistogramExponentialBounds) DECLARE_REFCOUNTED_CLASS(THistogramConfig) DECLARE_REFCOUNTED_CLASS(TServerConfig) DECLARE_REFCOUNTED_CLASS(TServiceCommonConfig) +DECLARE_REFCOUNTED_CLASS(TServerDynamicConfig) +DECLARE_REFCOUNTED_CLASS(TServiceCommonDynamicConfig) DECLARE_REFCOUNTED_CLASS(TServiceConfig) DECLARE_REFCOUNTED_CLASS(TMethodConfig) DECLARE_REFCOUNTED_CLASS(TRetryingChannelConfig) diff --git a/yt/yt/core/rpc/server.h b/yt/yt/core/rpc/server.h index fe4c88a478..e48bf2ef5c 100644 --- a/yt/yt/core/rpc/server.h +++ b/yt/yt/core/rpc/server.h @@ -31,7 +31,9 @@ struct IServer virtual IServicePtr GetServiceOrThrow(const TServiceId& serviceId) const = 0; //! Reconfigures the server on-the-fly. - virtual void Configure(TServerConfigPtr config) = 0; + virtual void Configure(const TServerConfigPtr& config) = 0; + + virtual void OnDynamicConfigChanged(const TServerDynamicConfigPtr& config) = 0; //! Starts the server. /*! diff --git a/yt/yt/core/rpc/server_detail.cpp b/yt/yt/core/rpc/server_detail.cpp index 0f80a07b6b..82ba43afe4 100644 --- a/yt/yt/core/rpc/server_detail.cpp +++ b/yt/yt/core/rpc/server_detail.cpp @@ -768,12 +768,12 @@ void TServerBase::RegisterService(IServicePtr service) auto guard = WriterGuard(ServicesLock_); auto& serviceMap = RealmIdToServiceMap_[serviceId.RealmId]; YT_VERIFY(serviceMap.emplace(serviceId.ServiceName, service).second); - if (Config_) { - auto it = Config_->Services.find(serviceId.ServiceName); - if (it != Config_->Services.end()) { - service->Configure(Config_, it->second); + if (AppliedConfig_) { + auto it = AppliedConfig_->Services.find(serviceId.ServiceName); + if (it != AppliedConfig_->Services.end()) { + service->Configure(AppliedConfig_, it->second); } else { - service->Configure(Config_, nullptr); + service->Configure(AppliedConfig_, nullptr); } } DoRegisterService(service); @@ -866,26 +866,54 @@ IServicePtr TServerBase::GetServiceOrThrow(const TServiceId& serviceId) const return serviceIt->second; } -void TServerBase::Configure(TServerConfigPtr config) +void TServerBase::ApplyConfig() { - auto guard = WriterGuard(ServicesLock_); + VERIFY_SPINLOCK_AFFINITY(ServicesLock_); - // Future services will be configured appropriately. - Config_ = config; + auto newAppliedConfig = New<TServerConfig>(); + newAppliedConfig->EnableErrorCodeCounting = DynamicConfig_->EnableErrorCodeCounting.value_or(StaticConfig_->EnableErrorCodeCounting); + newAppliedConfig->EnablePerUserProfiling = DynamicConfig_->EnablePerUserProfiling.value_or(StaticConfig_->EnablePerUserProfiling); + newAppliedConfig->HistogramTimerProfiling = DynamicConfig_->HistogramTimerProfiling.value_or(StaticConfig_->HistogramTimerProfiling); + newAppliedConfig->Services = StaticConfig_->Services; + + for (const auto& [name, node] : DynamicConfig_->Services) { + newAppliedConfig->Services[name] = node; + } + + AppliedConfig_ = newAppliedConfig; // Apply configuration to all existing services. for (const auto& [realmId, serviceMap] : RealmIdToServiceMap_) { for (const auto& [serviceName, service] : serviceMap) { - auto it = config->Services.find(serviceName); - if (it != config->Services.end()) { - service->Configure(config, it->second); + auto it = AppliedConfig_->Services.find(serviceName); + if (it != AppliedConfig_->Services.end()) { + service->Configure(AppliedConfig_, it->second); } else { - service->Configure(config, nullptr); + service->Configure(AppliedConfig_, nullptr); } } } } +void TServerBase::Configure(const TServerConfigPtr& config) +{ + auto guard = WriterGuard(ServicesLock_); + + // Future services will be configured appropriately. + StaticConfig_ = config; + + ApplyConfig(); +} + +void TServerBase::OnDynamicConfigChanged(const TServerDynamicConfigPtr& config) +{ + auto guard = WriterGuard(ServicesLock_); + + DynamicConfig_ = config; + + ApplyConfig(); +} + void TServerBase::Start() { YT_VERIFY(!Started_); diff --git a/yt/yt/core/rpc/server_detail.h b/yt/yt/core/rpc/server_detail.h index 0a2647b643..aceba1f14e 100644 --- a/yt/yt/core/rpc/server_detail.h +++ b/yt/yt/core/rpc/server_detail.h @@ -3,6 +3,7 @@ #include "authentication_identity.h" #include "server.h" #include "service.h" +#include "config.h" #include <yt/yt/core/logging/log.h> @@ -269,7 +270,8 @@ public: IServicePtr FindService(const TServiceId& serviceId) const override; IServicePtr GetServiceOrThrow(const TServiceId& serviceId) const override; - void Configure(TServerConfigPtr config) override; + void Configure(const TServerConfigPtr& config) override; + void OnDynamicConfigChanged(const TServerDynamicConfigPtr& config) override; void Start() override; TFuture<void> Stop(bool graceful) override; @@ -280,7 +282,9 @@ protected: std::atomic<bool> Started_ = false; YT_DECLARE_SPIN_LOCK(NThreading::TReaderWriterSpinLock, ServicesLock_); - TServerConfigPtr Config_; + TServerConfigPtr StaticConfig_; + TServerDynamicConfigPtr DynamicConfig_ = New<TServerDynamicConfig>(); + TServerConfigPtr AppliedConfig_; //! Service name to service. using TServiceMap = THashMap<TString, IServicePtr>; @@ -288,6 +292,8 @@ protected: explicit TServerBase(NLogging::TLogger logger); + void ApplyConfig(); + virtual void DoStart(); virtual TFuture<void> DoStop(bool graceful); diff --git a/yt/yt/core/rpc/service_detail.cpp b/yt/yt/core/rpc/service_detail.cpp index 2fd6f483ad..46567c3fcd 100644 --- a/yt/yt/core/rpc/service_detail.cpp +++ b/yt/yt/core/rpc/service_detail.cpp @@ -2451,6 +2451,7 @@ void TServiceBase::DoConfigure( auto methodConfig = methodIt ? methodIt->second : New<TMethodConfig>(); const auto& descriptor = runtimeInfo->Descriptor; + runtimeInfo->Heavy.store(methodConfig->Heavy.value_or(descriptor.Options.Heavy)); runtimeInfo->QueueSizeLimit.store(methodConfig->QueueSizeLimit.value_or(descriptor.QueueSizeLimit)); runtimeInfo->ConcurrencyLimit.Reconfigure(methodConfig->ConcurrencyLimit.value_or(descriptor.ConcurrencyLimit)); diff --git a/yt/yt/core/threading/thread.cpp b/yt/yt/core/threading/thread.cpp index cc8f9cfae7..4b04e154bd 100644 --- a/yt/yt/core/threading/thread.cpp +++ b/yt/yt/core/threading/thread.cpp @@ -8,10 +8,14 @@ #include <library/cpp/yt/misc/tls.h> +#include <util/generic/size_literals.h> + #ifdef _linux_ #include <sched.h> #endif +#include <signal.h> + namespace NYT::NThreading { //////////////////////////////////////////////////////////////////////////////// @@ -203,6 +207,7 @@ void TThread::ThreadMainTrampoline() CurrentUniqueThreadId = UniqueThreadId_; SetThreadPriority(); + ConfigureSignalHandlerStack(); StartedEvent_.NotifyAll(); @@ -275,6 +280,30 @@ void TThread::SetThreadPriority() #endif } +void TThread::ConfigureSignalHandlerStack() +{ +#if !defined(_asan_enabled_) && !defined(_msan_enabled_) && \ + (_XOPEN_SOURCE >= 500 || \ + /* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200809L || \ + /* glibc <= 2.19: */ _BSD_SOURCE) + YT_THREAD_LOCAL(bool) Configured; + if (std::exchange(Configured, true)) { + return; + } + + // The size of of the custom stack to be provided for signal handlers. + constexpr size_t SignalHandlerStackSize = 16_KB; + YT_THREAD_LOCAL(std::array<char, SignalHandlerStackSize>) Stack; + + stack_t stack{ + .ss_sp = GetTlsRef(Stack).data(), + .ss_flags = 0, + .ss_size = GetTlsRef(Stack).size(), + }; + YT_VERIFY(sigaltstack(&stack, nullptr) == 0); +#endif +} + //////////////////////////////////////////////////////////////////////////////// } // namespace NYT::NThreading diff --git a/yt/yt/core/threading/thread.h b/yt/yt/core/threading/thread.h index bc54afdc07..2599f18db2 100644 --- a/yt/yt/core/threading/thread.h +++ b/yt/yt/core/threading/thread.h @@ -72,6 +72,7 @@ private: ::TThread UnderlyingThread_; void SetThreadPriority(); + void ConfigureSignalHandlerStack(); bool StartSlow(); diff --git a/yt/yt/core/yson/protobuf_interop.cpp b/yt/yt/core/yson/protobuf_interop.cpp index a72a630f04..400d4a8f73 100644 --- a/yt/yt/core/yson/protobuf_interop.cpp +++ b/yt/yt/core/yson/protobuf_interop.cpp @@ -1007,22 +1007,20 @@ protected: } switch (config->Utf8Check) { case EUtf8Check::Disable: - break; + return; case EUtf8Check::LogOnFail: - YT_LOG_WARNING("Field %v accepts only valid UTF-8 sequence, but got (%Qv)", + YT_LOG_WARNING("String field got non UTF-8 value (Path: %v, Value: %v)", YPathStack_.GetHumanReadablePath(), data); - break; + return; case EUtf8Check::ThrowOnFail: - THROW_ERROR_EXCEPTION("Field %v accepts only valid UTF-8 sequence, but got (%Qv)", + THROW_ERROR_EXCEPTION("String field got non UTF-8 value (Path: %v, Value: %v)", YPathStack_.GetHumanReadablePath(), data) << TErrorAttribute("ypath", YPathStack_.GetPath()) << TErrorAttribute("proto_field", fieldFullName); - break; } } - }; //////////////////////////////////////////////////////////////////////////////// diff --git a/yt/yt/core/yson/unittests/protobuf_yson_ut.cpp b/yt/yt/core/yson/unittests/protobuf_yson_ut.cpp index f995f3f459..87c15c9600 100644 --- a/yt/yt/core/yson/unittests/protobuf_yson_ut.cpp +++ b/yt/yt/core/yson/unittests/protobuf_yson_ut.cpp @@ -1033,7 +1033,7 @@ TEST(TYsonToProtobufTest, ValidUtf8StringCheck) .EndMap(); }; if (option == EUtf8Check::ThrowOnFail) { - EXPECT_THROW_WITH_SUBSTRING(check(), "valid UTF-8"); + EXPECT_THROW_WITH_SUBSTRING(check(), "String field got non UTF-8 value"); } else { EXPECT_NO_THROW(check()); } @@ -1045,7 +1045,7 @@ TEST(TYsonToProtobufTest, ValidUtf8StringCheck) TYsonWriter ysonWriter(&newYsonOutputStream, EYsonFormat::Pretty); if (option == EUtf8Check::ThrowOnFail) { EXPECT_THROW_WITH_SUBSTRING( - WriteProtobufMessage(&ysonWriter, message), "valid UTF-8"); + WriteProtobufMessage(&ysonWriter, message), "String field got non UTF-8 value"); } else { EXPECT_NO_THROW(WriteProtobufMessage(&ysonWriter, message)); } diff --git a/yt/yt/library/column_converters/column_converter.cpp b/yt/yt/library/column_converters/column_converter.cpp index 7442ea0fd4..04239c0344 100644 --- a/yt/yt/library/column_converters/column_converter.cpp +++ b/yt/yt/library/column_converters/column_converter.cpp @@ -64,7 +64,7 @@ IColumnConverterPtr CreateColumnConvert( TConvertedColumnRange TColumnConverters::ConvertRowsToColumns( TRange<TUnversionedRow> rows, - const std::vector<TColumnSchema>& columnSchema) + const THashMap<int, TColumnSchema>& columnSchema) { TConvertedColumnRange convertedColumnsRange; if (rows.size() == 0) { @@ -79,6 +79,10 @@ TConvertedColumnRange TColumnConverters::ConvertRowsToColumns( for (const auto* item = firstRow.Begin(); item != firstRow.End(); ++item) { IdsToIndexes_[item->Id] = std::ssize(ColumnIds_); ColumnIds_.push_back(item->Id); + auto iterSchema = columnSchema.find(item->Id); + if (iterSchema == columnSchema.end()) { + THROW_ERROR_EXCEPTION("Column with Id %v has no schema", item->Id); + } } } IsFirstBatch_ = false; @@ -90,15 +94,18 @@ TConvertedColumnRange TColumnConverters::ConvertRowsToColumns( TUnversionedRowValues rowValues(ColumnIds_.size(), nullptr); for (const auto* item = row.Begin(); item != row.End(); ++item) { auto iter = IdsToIndexes_.find(item->Id); - YT_VERIFY(iter != IdsToIndexes_.end()); + if(iter == IdsToIndexes_.end()) { + THROW_ERROR_EXCEPTION("Column with Id %v has no schema", item->Id); + } rowValues[iter->second] = item; } rowsValues.push_back(std::move(rowValues)); } for (int offset = 0; offset < std::ssize(ColumnIds_); offset++) { - YT_VERIFY(ColumnIds_[offset] >= 0 && ColumnIds_[offset] < std::ssize(columnSchema)); - auto converter = CreateColumnConvert(columnSchema[ColumnIds_[offset]], ColumnIds_[offset], offset); + auto iterSchema = columnSchema.find(ColumnIds_[offset]); + YT_VERIFY(iterSchema != columnSchema.end()); + auto converter = CreateColumnConvert(iterSchema->second, ColumnIds_[offset], offset); auto columns = converter->Convert(rowsValues); convertedColumnsRange.push_back(columns); } diff --git a/yt/yt/library/column_converters/column_converter.h b/yt/yt/library/column_converters/column_converter.h index 46515d8eb4..12d9e2a04c 100644 --- a/yt/yt/library/column_converters/column_converter.h +++ b/yt/yt/library/column_converters/column_converter.h @@ -50,7 +50,7 @@ class TColumnConverters public: TConvertedColumnRange ConvertRowsToColumns( TRange<NTableClient::TUnversionedRow> rows, - const std::vector<NTableClient::TColumnSchema>& columnSchema); + const THashMap<int, NTableClient::TColumnSchema>& columnSchema); private: THashMap<int, int> IdsToIndexes_; std::vector<int> ColumnIds_; diff --git a/yt/yt/library/formats/arrow_writer.cpp b/yt/yt/library/formats/arrow_writer.cpp index d83cb97358..452254f738 100644 --- a/yt/yt/library/formats/arrow_writer.cpp +++ b/yt/yt/library/formats/arrow_writer.cpp @@ -906,17 +906,27 @@ public: { YT_VERIFY(tableSchemas.size() > 0); - auto tableSchema = tableSchemas[0]; - - for (const auto& columnSchema : tableSchema->Columns()) { - NameTable_->GetIdOrRegisterName(columnSchema.Name()); - } - - auto columnCount = NameTable_->GetSize(); - SchemaExistenceFlags_.resize(columnCount, true); - - for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) { - ColumnSchemas_.push_back(GetColumnSchema(tableSchema, columnIndex)); + ColumnConverters_.resize(tableSchemas.size()); + TableNumbers_ = tableSchemas.size(); + ColumnSchemas_.resize(tableSchemas.size()); + + for (int tableIndex = 0; tableIndex < std::ssize(tableSchemas); ++tableIndex) { + for (const auto& columnSchema : tableSchemas[tableIndex]->Columns()) { + auto columnId = NameTable_->GetIdOrRegisterName(columnSchema.Name()); + ColumnSchemas_[tableIndex][columnId] = columnSchema; + } + if (CheckColumnInNameTable(GetRangeIndexColumnId())) { + ColumnSchemas_[tableIndex][GetRangeIndexColumnId()] = GetSystemColumnSchema(NameTable_->GetName(GetRangeIndexColumnId()), GetRangeIndexColumnId()); + } + if (CheckColumnInNameTable(GetRowIndexColumnId())) { + ColumnSchemas_[tableIndex][GetRowIndexColumnId()] = GetSystemColumnSchema(NameTable_->GetName(GetRowIndexColumnId()), GetRowIndexColumnId()); + } + if (CheckColumnInNameTable(GetTableIndexColumnId())) { + ColumnSchemas_[tableIndex][GetTableIndexColumnId()] = GetSystemColumnSchema(NameTable_->GetName(GetTableIndexColumnId()), GetTableIndexColumnId()); + } + if (CheckColumnInNameTable(GetTabletIndexColumnId())) { + ColumnSchemas_[tableIndex][GetTabletIndexColumnId()] = GetSystemColumnSchema(NameTable_->GetName(GetTabletIndexColumnId()), GetTabletIndexColumnId()); + } } } @@ -935,20 +945,56 @@ private: output->Write(&zero, sizeof(zero)); } - void DoWrite(TRange<TUnversionedRow> rows) override + bool CheckColumnInNameTable(int columnIndex) const { - Reset(); - - auto convertedColumns = ColumnConverters_.ConvertRowsToColumns(rows, ColumnSchemas_); + return columnIndex >= 0 && columnIndex < NameTable_->GetSize(); + } + void WriteRowsForSingleTable(TRange<TUnversionedRow> rows, i32 tableIndex) + { + Reset(); + auto convertedColumns = ColumnConverters_[tableIndex].ConvertRowsToColumns(rows, ColumnSchemas_[tableIndex]); std::vector<const TBatchColumn*> rootColumns; rootColumns.reserve( std::ssize(convertedColumns)); for (ssize_t columnIndex = 0; columnIndex < std::ssize(convertedColumns); columnIndex++) { rootColumns.push_back(convertedColumns[columnIndex].RootColumn); } RowCount_ = rows.size(); - PrepareColumns(rootColumns); - Encode(); + PrepareColumns(rootColumns, tableIndex); + Encode(tableIndex); + } + + void DoWrite(TRange<TUnversionedRow> rows) override + { + Reset(); + + ssize_t sameTableRangeBeginRowIndex = 0; + i32 tableIndex = 0; + + for (ssize_t rowIndex = 0; rowIndex < std::ssize(rows); rowIndex++) { + i32 currentTableIndex = -1; + if(TableNumbers_ > 1) { + const auto& elems = rows[rowIndex].Elements(); + for (ssize_t columnIndex = std::ssize(elems) - 1; columnIndex >= 0; --columnIndex) { + if (elems[columnIndex].Id == GetTableIndexColumnId()) { + currentTableIndex = elems[columnIndex].Data.Int64; + break; + } + } + } else { + currentTableIndex = 0; + } + YT_VERIFY(currentTableIndex < TableNumbers_ && currentTableIndex >= 0); + if (tableIndex != currentTableIndex && rowIndex != 0) { + auto currentRows = rows.Slice(sameTableRangeBeginRowIndex, rowIndex); + WriteRowsForSingleTable(currentRows, tableIndex); + sameTableRangeBeginRowIndex = rowIndex; + } + tableIndex = currentTableIndex; + } + + auto currentRows = rows.Slice(sameTableRangeBeginRowIndex, rows.size()); + WriteRowsForSingleTable(currentRows, tableIndex); } void DoWriteBatch(NTableClient::IUnversionedRowBatchPtr rowBatch) override @@ -959,22 +1005,24 @@ private: DoWrite(rowBatch->MaterializeRows()); } else { YT_LOG_DEBUG("Encoding columnar batch (RowCount: %v)", rowBatch->GetRowCount()); + YT_VERIFY(TableNumbers_ == 1); Reset(); RowCount_ = rowBatch->GetRowCount(); - PrepareColumns(columnarBatch->MaterializeColumns()); - Encode(); + PrepareColumns(columnarBatch->MaterializeColumns(), 0); + Encode(0); } } - void Encode() + void Encode(i32 tableIndex) { auto output = GetOutputStream(); - if (IsSchemaMessageNeeded()) { + if (tableIndex != PrevTableIndex_ || IsSchemaMessageNeeded()) { + PrevTableIndex_ = tableIndex; if (!IsFirstBatch_) { RegisterEosMarker(); } ResetArrowDictionaries(); - PrepareSchema(); + PrepareSchema(tableIndex); } IsFirstBatch_ = false; PrepareDictionaryBatches(); @@ -985,13 +1033,14 @@ private: } private: + i32 TableNumbers_ = 0; bool IsFirstBatch_ = true; + i64 PrevTableIndex_ = 0; i64 RowCount_ = 0; std::vector<TTypedBatchColumn> TypedColumns_; - std::vector<TColumnSchema> ColumnSchemas_; + std::vector<THashMap<int, TColumnSchema>> ColumnSchemas_; std::vector<IUnversionedColumnarRowBatch::TDictionaryId> ArrowDictionaryIds_; - std::vector<bool> SchemaExistenceFlags_; - NColumnConverters::TColumnConverters ColumnConverters_; + std::vector<NColumnConverters::TColumnConverters> ColumnConverters_; struct TMessage { @@ -1002,7 +1051,7 @@ private: std::vector<TMessage> Messages_; - bool CheckIfSystemColumnEnable(int columnIndex) + bool CheckIfSystemColumnEnable(int columnIndex) const { return ControlAttributesConfig_->EnableTableIndex && IsTableIndexColumnId(columnIndex) || ControlAttributesConfig_->EnableRangeIndex && IsRangeIndexColumnId(columnIndex) || @@ -1010,34 +1059,30 @@ private: ControlAttributesConfig_->EnableTabletIndex && IsTabletIndexColumnId(columnIndex); } - TColumnSchema GetColumnSchema(NTableClient::TTableSchemaPtr& tableSchema, int columnIndex) + bool IsColumnNeedsToAdd(int columnIndex) const { - YT_VERIFY(columnIndex >= 0); - SchemaExistenceFlags_[columnIndex] = true; - auto name = NameTable_->GetName(columnIndex); - auto columnSchema = tableSchema->FindColumn(name); - if (!columnSchema) { - if (IsSystemColumnId(columnIndex)) { - if (CheckIfSystemColumnEnable(columnIndex)) { - return TColumnSchema(TString(name), EValueType::Int64); - } - SchemaExistenceFlags_[columnIndex] = false; - return TColumnSchema(TString(name), EValueType::Null); - } - THROW_ERROR_EXCEPTION("Column %Qv has no schema", name); + return !IsSystemColumnId(columnIndex) + || (CheckIfSystemColumnEnable(columnIndex) && !IsTableIndexColumnId(columnIndex)); + } + + TColumnSchema GetSystemColumnSchema(TStringBuf name, int columnIndex) + { + if (CheckIfSystemColumnEnable(columnIndex) && !IsTableIndexColumnId(columnIndex)) { + return TColumnSchema(TString(name), EValueType::Int64); } - return *columnSchema; + return TColumnSchema(TString(name), EValueType::Null); } - void PrepareColumns(const TRange<const TBatchColumn*>& batchColumns) + void PrepareColumns(const TRange<const TBatchColumn*>& batchColumns, int tableIndex) { TypedColumns_.reserve(batchColumns.Size()); for (const auto* column : batchColumns) { - if (SchemaExistenceFlags_[column->Id]) { - YT_VERIFY(column->Id >= 0 && column->Id < std::ssize(ColumnSchemas_)); + if(IsColumnNeedsToAdd(column->Id)) { + auto iterSchema = ColumnSchemas_[tableIndex].find(column->Id); + YT_VERIFY(iterSchema != ColumnSchemas_[tableIndex].end()); TypedColumns_.push_back(TTypedBatchColumn{ column, - ColumnSchemas_[column->Id].LogicalType() + iterSchema->second.LogicalType() }); } } @@ -1093,7 +1138,7 @@ private: std::move(bodyWriter)}); } - void PrepareSchema() + void PrepareSchema(i32 tableIndex) { flatbuffers::FlatBufferBuilder flatbufBuilder; @@ -1101,8 +1146,9 @@ private: std::vector<flatbuffers::Offset<org::apache::arrow::flatbuf::Field>> fieldOffsets; for (int columnIndex = 0; columnIndex < std::ssize(TypedColumns_); columnIndex++) { const auto& typedColumn = TypedColumns_[columnIndex]; - YT_VERIFY(typedColumn.Column->Id >= 0 && typedColumn.Column->Id < std::ssize(ColumnSchemas_)); - auto columnSchema = ColumnSchemas_[typedColumn.Column->Id]; + auto iterSchema = ColumnSchemas_[tableIndex].find(typedColumn.Column->Id); + YT_VERIFY(iterSchema != ColumnSchemas_[tableIndex].end()); + auto columnSchema = iterSchema->second; auto nameOffset = SerializeString(&flatbufBuilder, columnSchema.Name()); auto [typeType, typeOffset] = SerializeColumnType(&flatbufBuilder, columnSchema); @@ -1130,10 +1176,22 @@ private: auto fieldsOffset = flatbufBuilder.CreateVector(fieldOffsets); + std::vector<flatbuffers::Offset<org::apache::arrow::flatbuf::KeyValue>> customMetadata; + + if (TableNumbers_ > 1) { + auto keyValueOffsett = org::apache::arrow::flatbuf::CreateKeyValue( + flatbufBuilder, + flatbufBuilder.CreateString("TableId"), + flatbufBuilder.CreateString(std::to_string(tableIndex)) + ); + customMetadata.push_back(keyValueOffsett); + } + auto schemaOffset = org::apache::arrow::flatbuf::CreateSchema( flatbufBuilder, org::apache::arrow::flatbuf::Endianness_Little, - fieldsOffset); + fieldsOffset, + flatbufBuilder.CreateVector(customMetadata)); auto messageOffset = org::apache::arrow::flatbuf::CreateMessage( flatbufBuilder, diff --git a/yt/yt/library/numeric/piecewise_linear_function.h b/yt/yt/library/numeric/piecewise_linear_function.h index 254f4de0d7..f305307760 100644 --- a/yt/yt/library/numeric/piecewise_linear_function.h +++ b/yt/yt/library/numeric/piecewise_linear_function.h @@ -382,8 +382,6 @@ public: public: TLeftToRightTraverser(const TPiecewiseLinearFunction& function, int segmentIndex = 0); - TLeftToRightTraverser(const TLeftToRightTraverser& other) = default; - // See: |TPiecewiseLinearFunction::LeftSegmentAt|. // If |y > x|, |LeftSegmentAt(x)| cannot be called after |LeftSegmentAt(y)|. // If |y >= x|, |LeftSegmentAt(x)| cannot be called after |SegmentAt(y)| or |RightSegmentAt(y)|. diff --git a/yt/yt/library/profiling/solomon/public.h b/yt/yt/library/profiling/solomon/public.h index 6942e8dba7..02bf5ad2c9 100644 --- a/yt/yt/library/profiling/solomon/public.h +++ b/yt/yt/library/profiling/solomon/public.h @@ -1,6 +1,6 @@ #pragma once -#include <yt/yt/core/misc/ref_counted.h> +#include <library/cpp/yt/memory/ref_counted.h> namespace NYT::NProfiling { diff --git a/yt/yt/library/profiling/solomon/sensor_set.h b/yt/yt/library/profiling/solomon/sensor_set.h index fb71767bdd..a873254e06 100644 --- a/yt/yt/library/profiling/solomon/sensor_set.h +++ b/yt/yt/library/profiling/solomon/sensor_set.h @@ -9,11 +9,12 @@ #include <yt/yt/core/profiling/public.h> -#include <yt/yt/core/misc/intrusive_ptr.h> #include <yt/yt/core/misc/error.h> #include <yt/yt/core/ytree/fluent.h> +#include <library/cpp/yt/memory/intrusive_ptr.h> + namespace NYT::NProfiling { //////////////////////////////////////////////////////////////////////////////// diff --git a/yt/yt/library/profiling/unittests/solomon_ut.cpp b/yt/yt/library/profiling/unittests/solomon_ut.cpp index 2efaf3e3cc..ecfc27d6ff 100644 --- a/yt/yt/library/profiling/unittests/solomon_ut.cpp +++ b/yt/yt/library/profiling/unittests/solomon_ut.cpp @@ -1,4 +1,3 @@ -#include "yt/yt/core/misc/ref_counted.h" #include <gtest/gtest.h> #include <gmock/gmock.h> @@ -9,6 +8,8 @@ #include <yt/yt/library/profiling/solomon/registry.h> #include <yt/yt/library/profiling/solomon/remote.h> +#include <library/cpp/yt/memory/ref_counted.h> + #include <util/string/join.h> namespace NYT::NProfiling { diff --git a/yt/yt/library/program/ya.make b/yt/yt/library/program/ya.make index 1d044b5a8d..02da9f2e57 100644 --- a/yt/yt/library/program/ya.make +++ b/yt/yt/library/program/ya.make @@ -24,6 +24,7 @@ PEERDIR( library/cpp/yt/mlock library/cpp/yt/stockpile library/cpp/yt/string + library/cpp/getopt/small ) END() diff --git a/yt/yt/library/syncmap/map.h b/yt/yt/library/syncmap/map.h index 8e442accef..ed1e296f86 100644 --- a/yt/yt/library/syncmap/map.h +++ b/yt/yt/library/syncmap/map.h @@ -2,10 +2,11 @@ #include <yt/yt/core/misc/finally.h> #include <yt/yt/core/misc/hazard_ptr.h> -#include <yt/yt/core/misc/ref_counted.h> #include <library/cpp/yt/threading/spin_lock.h> +#include <library/cpp/yt/memory/ref_counted.h> + #include <util/generic/hash.h> #include <util/generic/noncopyable.h> diff --git a/yt/yt/library/tracing/public.h b/yt/yt/library/tracing/public.h index ae473bb33b..1c20b9c7dc 100644 --- a/yt/yt/library/tracing/public.h +++ b/yt/yt/library/tracing/public.h @@ -1,6 +1,6 @@ #pragma once -#include <yt/yt/core/misc/ref_counted.h> +#include <library/cpp/yt/memory/ref_counted.h> namespace NYT::NTracing { diff --git a/yt/yt/library/tracing/tracer.h b/yt/yt/library/tracing/tracer.h index 8b53efd997..bd2e180735 100644 --- a/yt/yt/library/tracing/tracer.h +++ b/yt/yt/library/tracing/tracer.h @@ -2,10 +2,10 @@ #include "public.h" -#include <yt/yt/core/misc/ref_counted.h> - #include <yt/yt/core/tracing/public.h> +#include <library/cpp/yt/memory/ref_counted.h> + namespace NYT::NTracing { //////////////////////////////////////////////////////////////////////////////// diff --git a/yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto b/yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto index 297ee2ae7d..0e8b3fe47a 100644 --- a/yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto +++ b/yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto @@ -1930,6 +1930,7 @@ message TReqDestroyChunkLocations { required string node_address = 1; repeated NYT.NProto.TGuid location_uuids = 2; + optional bool recover_unlinked_disks = 3 [default = false]; } message TRspDestroyChunkLocations |