diff --git a/.appveyor.yml b/.appveyor.yml
new file mode 100644
index 000000000..706f006be
--- /dev/null
+++ b/.appveyor.yml
@@ -0,0 +1,49 @@
+version: "{build}"
+skip_branch_with_pr: true
+skip_tags: true
+build: off
+
+os: Visual Studio 2019
+
+environment:
+ matrix:
+ # Build Node.js
+ - nodejs_version: stable
+ - nodejs_version: 22
+ - nodejs_version: 20
+
+ # Build plain C++
+ - nodejs_version: none
+
+platform:
+ - x64
+
+for:
+- matrix:
+ except:
+ - nodejs_version: none
+ install:
+ - ps: Install-Product node $env:nodejs_version $env:platform
+ - npm -g i npm@latest
+ build_script:
+ - appveyor-retry call npm install --build-from-source
+ test_script:
+ - npm test
+
+- matrix:
+ only:
+ - nodejs_version: none
+ build_script:
+ - SET arch=%platform%
+ - IF "%platform%"=="x86" SET arch=Win32
+
+ - cmake -A%arch% -S. -Bbuild -DCMAKE_INSTALL_PREFIX:PATH=. -DENABLE_GTEST:BOOL=ON -DENABLE_BENCHMARK:BOOL=ON -DCMAKE_BUILD_TYPE=Release
+ - cmake --build build --config Release --target install
+ test_script:
+ - cd build
+ - ctest --verbose -C Release
+ after_build:
+ - 7z a OpenCC.zip build/bin build/include build/lib build/share
+ artifacts:
+ - path: OpenCC.zip
+ name: OpenCC
diff --git a/.bazelversion b/.bazelversion
new file mode 100644
index 000000000..b26a34e47
--- /dev/null
+++ b/.bazelversion
@@ -0,0 +1 @@
+7.2.1
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 000000000..70e3ef3ff
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1 @@
+github: BYVoid
diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml
new file mode 100644
index 000000000..f3aa450d5
--- /dev/null
+++ b/.github/workflows/bazel.yml
@@ -0,0 +1,24 @@
+name: Bazel
+
+on:
+ push:
+ branches: [master]
+ pull_request:
+ branches: [master]
+
+jobs:
+ build-and-test:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [ubuntu-latest, macos-latest, macos-14]
+
+ steps:
+ - uses: actions/checkout@v4
+ - uses: bazelbuild/setup-bazelisk@v3
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.12"
+ - run: bazel build //:opencc
+ - run: bazel test --test_output=all //src/... //data/... //test/... //python/...
diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml
new file mode 100644
index 000000000..32a2f2b45
--- /dev/null
+++ b/.github/workflows/cmake.yml
@@ -0,0 +1,22 @@
+name: CMake
+
+on:
+ push:
+ branches: [master]
+ pull_request:
+ branches: [master]
+
+jobs:
+ build-and-test:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [ubuntu-latest, macos-latest, macos-14]
+ steps:
+ - uses: actions/checkout@v4
+ - name: make build
+ run: make build VERBOSE=1 REL_BUILD_DOCUMENTATION=OFF
+ - name: make test
+ run: make test VERBOSE=1
+ - name: make benchmark
+ run: make benchmark VERBOSE=1
diff --git a/.github/workflows/mingw.yml b/.github/workflows/mingw.yml
new file mode 100644
index 000000000..dd996588c
--- /dev/null
+++ b/.github/workflows/mingw.yml
@@ -0,0 +1,32 @@
+name: mingw-w64
+
+on:
+ push:
+ branches: [master]
+ pull_request:
+ branches: [master]
+
+jobs:
+ build:
+ runs-on: windows-latest
+ defaults:
+ run:
+ shell: msys2 {0}
+ steps:
+ - uses: msys2/setup-msys2@v2
+ - uses: actions/checkout@v4
+ - name: Install dependencies
+ run: pacman -S --noconfirm base-devel mingw-w64-x86_64-toolchain cmake ninja python
+ - name: Build with mingw-w64
+ run: |
+ CC=/mingw64/bin/cc CXX=/mingw64/bin/c++ cmake \
+ -B build -G Ninja \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_INSTALL_PREFIX=/usr \
+ -DENABLE_GTEST=ON \
+ -DBUILD_SHARED_LIBS=OFF
+ cmake --build build
+ - name: Run test
+ run: |
+ cd build
+ ctest
diff --git a/.github/workflows/msvc.yml b/.github/workflows/msvc.yml
new file mode 100644
index 000000000..9daef8d38
--- /dev/null
+++ b/.github/workflows/msvc.yml
@@ -0,0 +1,26 @@
+name: MSVC
+
+on:
+ push:
+ branches: [master]
+ pull_request:
+ branches: [master]
+
+jobs:
+ build-and-test:
+ runs-on: windows-latest
+ strategy:
+ matrix:
+ arch:
+ - amd64
+ - amd64_x86
+ - amd64_arm64
+ steps:
+ - uses: actions/checkout@v4
+ - uses: ilammy/msvc-dev-cmd@v1
+ with:
+ arch: ${{ matrix.arch }}
+ - name: build
+ run: ./build.cmd
+ - name: test
+ run: ./test.cmd
diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml
new file mode 100644
index 000000000..6d568ec06
--- /dev/null
+++ b/.github/workflows/nodejs.yml
@@ -0,0 +1,31 @@
+name: Node.js
+
+on:
+ push:
+ branches: [master]
+ pull_request:
+ branches: [master]
+
+jobs:
+ build-and-test:
+ runs-on: ${{ matrix.os }}
+
+ strategy:
+ matrix:
+ # Bleeding Edge: Latest Node × Latest OS
+ os: [ubuntu-latest, macos-latest]
+ node-version: [latest]
+ # Stable: Node 20, 22 (LTS) on macOS 14 (ARM64)
+ include:
+ - os: macos-14
+ node-version: 22
+ - os: macos-14
+ node-version: 20
+ steps:
+ - uses: actions/checkout@v4
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v4
+ with:
+ node-version: ${{ matrix.node-version }}
+ - run: npm ci
+ - run: npm test
diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml
new file mode 100644
index 000000000..7e32d0a08
--- /dev/null
+++ b/.github/workflows/python.yml
@@ -0,0 +1,69 @@
+name: Python
+
+on:
+ push:
+ branches: [master]
+ pull_request:
+ branches: [master]
+
+jobs:
+ unit-test:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ python-version: [3.8, 3.9, "3.10", "3.11", "3.12"]
+
+ steps:
+ - uses: actions/checkout@v4
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v5
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install flake8 pytest wheel setuptools
+ if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
+ - name: Lint with flake8
+ run: |
+ # stop the build if there are Python syntax errors or undefined names
+ flake8 . --exclude deps --count --select=E9,F63,F7,F82 --show-source --statistics
+ # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
+ flake8 . --exclude deps --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
+ - name: Build and install
+ run: python -m pip install .
+ - name: Test with pytest
+ run: pytest python/
+
+ test-pypi:
+ strategy:
+ matrix:
+ os: [ubuntu-latest, macos-latest, macos-14, windows-latest]
+ runs-on: ${{ matrix.os }}
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Build package and upload from docker (Linux)
+ if: runner.os == 'Linux'
+ run: |
+ docker run --rm -v "${PWD}:/opt/OpenCC" \
+ -e TWINE_USERNAME=__token__ \
+ -e TWINE_PASSWORD=${{ secrets.PYPI_TOKEN }} \
+ ubuntu:22.04 /bin/bash /opt/OpenCC/release-pypi-linux.sh testonly
+
+ - name: Build package and upload (macOS)
+ if: runner.os == 'macOS'
+ run: bash release-pypi-macos.sh testonly
+ env:
+ TWINE_USERNAME: __token__
+ TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
+
+ - name: Build package and upload (Windows)
+ if: runner.os == 'Windows'
+ run: |
+ C:\Miniconda/condabin/conda.bat init powershell
+ ./release-pypi-windows.cmd testonly
+ env:
+ TWINE_USERNAME: __token__
+ TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
diff --git a/.github/workflows/release-pypi.yml b/.github/workflows/release-pypi.yml
new file mode 100644
index 000000000..c95894776
--- /dev/null
+++ b/.github/workflows/release-pypi.yml
@@ -0,0 +1,38 @@
+name: Build and upload python package to PyPI
+
+on:
+ workflow_dispatch
+
+jobs:
+ release-pypi:
+ strategy:
+ matrix:
+ os: [ubuntu-latest, macos-latest, macos-14, windows-latest]
+ runs-on: ${{ matrix.os }}
+
+ steps:
+ - uses: actions/checkout@v1
+
+ - name: Build package and upload from docker (Linux)
+ if: runner.os == 'Linux'
+ run: |
+ docker run --rm -v "${PWD}:/opt/OpenCC" \
+ -e TWINE_USERNAME=__token__ \
+ -e TWINE_PASSWORD=${{ secrets.PYPI_TOKEN }} \
+ ubuntu:22.04 /bin/bash /opt/OpenCC/release-pypi-linux.sh
+
+ - name: Build package and upload (macOS)
+ if: runner.os == 'macOS'
+ run: bash release-pypi-macos.sh
+ env:
+ TWINE_USERNAME: __token__
+ TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
+
+ - name: Build package and upload (Windows)
+ if: runner.os == 'Windows'
+ run: |
+ C:\Miniconda/condabin/conda.bat init powershell
+ ./release-pypi-windows.cmd
+ env:
+ TWINE_USERNAME: __token__
+ TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
diff --git a/.gitignore b/.gitignore
index d04819178..f5164873a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,12 +2,18 @@
*.tgz
.project
.cproject
+/.vscode
+/.mypy_cache
+/bazel-*
/build
/other
/doc/html
+/dist
/opencc.xcodeproj
/test/dict.ocd
/test/dict.txt
/test/dict.bin
/xcode
/node_modules
+/*.egg-info
+/.venv/
diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml
deleted file mode 100644
index 50cffbf8f..000000000
--- a/.idea/codeStyleSettings.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/.npmignore b/.npmignore
index a847eb415..5ab6c90b3 100644
--- a/.npmignore
+++ b/.npmignore
@@ -1,19 +1,44 @@
+.bazelversion
.npmignore
.gitignore
CMakeLists.txt
*.cmake
*.pyc
+*.cmd
+*.tgz
+*.bazel
+/.github
+/.vscode
+/.appveyor.yml
+/.clang-format
+/.travis.yml
+/bazel-*
+/Makefile
+/src/*Test.cpp
+/src/*TestBase.cpp
/doc
/data/scheme
+/deps/google-benchmark
+/deps/googletest*
+/deps/pybind*
+/deps/tclap*
+/bazel-*
/build
/debug
+/dist
/release
/other
/opencc.pc.in
/doc/html
/opencc.xcodeproj
+/python
+/src/benchmark
+/test/benchmark
/test/dict.ocd
/test/dict.txt
/test/dict.bin
+/test/CommandLineConvertTest.cpp
/node_modules
+/xcode
+/*.egg-info
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 85723a294..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,44 +0,0 @@
-language: node_js
-
-cache:
- npm: true
- ccache: true
-
-node_js:
- - stable
- - 7
- - 6
- - 5
- - 4
- - 0
-
-os:
- - linux
- - osx
-
-addons:
- apt:
- sources:
- - ubuntu-toolchain-r-test
- packages:
- - doxygen
- - g++-4.8
-
-# Install scripts. (runs after repo cloning)
-install:
- - if [ $TRAVIS_OS_NAME == "linux" ]; then export CXX=g++-4.8; fi
- # install modules
- - npm install --build-from-source
-
-# Post-install test scripts.
-script:
- - export PATH="/usr/lib/ccache/:$PATH"
- - if [ $TRAVIS_OS_NAME == "linux" ] && [ $TRAVIS_NODE_VERSION == "stable" ]; then
- make test VERBOSE=1;
- make package VERBOSE=1;
- fi
-
- - npm test
-
-after_success:
- - npm run deploy
diff --git a/AUTHORS b/AUTHORS
index 156feefdd..52c080efd 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,5 +1,5 @@
Author:
-BYVoid
+Carbo Kuo
Contributors:
Peng Huang
diff --git a/BUILD.bazel b/BUILD.bazel
new file mode 100644
index 000000000..263edc9b9
--- /dev/null
+++ b/BUILD.bazel
@@ -0,0 +1,29 @@
+load("@rules_cc//cc:defs.bzl", "cc_library")
+load("@rules_python//python:py_library.bzl", "py_library")
+
+package(default_visibility = ["//visibility:public"])
+
+cc_library(
+ name = "opencc",
+ hdrs = [
+ "//src:Export.hpp",
+ "//src:SimpleConverter.hpp",
+ "//src:opencc.h",
+ ],
+ data = [
+ "//data/config",
+ "//data/dictionary:binary_dictionaries",
+ "//data/dictionary:text_dictionaries",
+ ],
+ strip_include_prefix = "src",
+ deps = [
+ "//src:opencc",
+ ],
+)
+
+py_library(
+ name = "py_opencc",
+ deps = [
+ "//python/opencc",
+ ],
+)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2a29415bd..b79e5b5c2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,7 @@
#
# Open Chinese Convert
#
-# Copyright 2010-2015 BYVoid
+# Copyright 2010-2020 Carbo Kuo
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -17,7 +17,7 @@
#
######## Project settings
-cmake_minimum_required(VERSION 2.8)
+cmake_minimum_required(VERSION 3.5)
set (PACKAGE_NAME opencc)
project (${PACKAGE_NAME} CXX)
include (CTest)
@@ -26,13 +26,23 @@ include (CTest)
option(BUILD_DOCUMENTATION "Use Doxygen to create the HTML based API documentation" OFF)
option(BUILD_SHARED_LIBS "Build opencc as shared library" ON)
option(ENABLE_GTEST "Build all tests." OFF)
+option(ENABLE_BENCHMARK "Build benchmark tests." OFF)
+option(ENABLE_DARTS "Build DartsDict (ocd format)." ON)
+option(BUILD_PYTHON "Build python library" OFF)
+option(USE_SYSTEM_DARTS "Use system version of Darts" OFF)
+option(USE_SYSTEM_GOOGLE_BENCHMARK "Use system version of Google Benchmark" OFF)
+option(USE_SYSTEM_GTEST "Use system version of GoogleTest" OFF)
+option(USE_SYSTEM_MARISA "Use system version of Marisa" OFF)
+option(USE_SYSTEM_PYBIND11 "Use system version of pybind11" OFF)
+option(USE_SYSTEM_RAPIDJSON "Use system version of RapidJSON" OFF)
+option(USE_SYSTEM_TCLAP "Use system version of TCLAP" OFF)
######## Package information
-set (PACKAGE_URL https://github.com/BYVoid/Opencc)
-set (PACKAGE_BUGREPORT https://github.com/BYVoid/Opencc/issues)
+set (PACKAGE_URL https://github.com/BYVoid/OpenCC)
+set (PACKAGE_BUGREPORT https://github.com/BYVoid/OpenCC/issues)
set (OPENCC_VERSION_MAJOR 1)
-set (OPENCC_VERSION_MINOR 0)
-set (OPENCC_VERSION_REVISION 5)
+set (OPENCC_VERSION_MINOR 1)
+set (OPENCC_VERSION_REVISION 9)
if (CMAKE_BUILD_TYPE MATCHES Debug)
set (version_suffix .Debug)
@@ -47,7 +57,7 @@ set(CPACK_SOURCE_PACKAGE_FILE_NAME
"${PACKAGE_NAME}-${OPENCC_VERSION_MAJOR}.${OPENCC_VERSION_MINOR}.${OPENCC_VERSION_REVISION}"
)
set(CPACK_SOURCE_IGNORE_FILES
- "/build/;/test/dict.ocd;/test/dict.txt;/test/dict.bin;/other/;/opencc.xcodeproj/;/.git/;.gitignore;~$;.pyc;${CPACK_SOURCE_IGNORE_FILES}"
+ "/build/;/test/dict.ocd;/test/dict.txt;/test/dict.bin;/other/;/opencc.xcodeproj/;/.git/;.gitignore;~$;.pyc;/bazel*;/node_modules;/.github;/.pytest_cache;/.vscode;${CPACK_SOURCE_IGNORE_FILES}"
)
include(CPack)
@@ -58,17 +68,21 @@ include(CPack)
# set(CMAKE_STATIC_LIBRARY_PREFIX ${CMAKE_INSTALL_PREFIX})
#endif (WIN32)
-######## Mac OS X
+######## macOS
-set(CMAKE_MACOSX_RPATH 1)
+if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+ set(CMAKE_MACOSX_RPATH 1)
+ set(CMAKE_CXX_STANDARD 14)
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
+endif()
######## Directory
set (DIR_PREFIX ${CMAKE_INSTALL_PREFIX})
-set (DIR_INCLUDE ${DIR_PREFIX}/include/)
-set (DIR_SHARE ${DIR_PREFIX}/share/)
-set (DIR_ETC ${DIR_PREFIX}/etc/)
-set (DIR_LIBRARY ${DIR_PREFIX}/lib${LIB_SUFFIX}/)
+set (DIR_INCLUDE ${DIR_PREFIX}/include)
+set (DIR_SHARE ${DIR_PREFIX}/share)
+set (DIR_ETC ${DIR_PREFIX}/etc)
+set (DIR_LIBRARY ${DIR_PREFIX}/lib${LIB_SUFFIX})
if (DEFINED SHARE_INSTALL_PREFIX)
set (DIR_SHARE ${SHARE_INSTALL_PREFIX})
@@ -86,11 +100,15 @@ if (DEFINED LIB_INSTALL_DIR)
set (DIR_LIBRARY ${LIB_INSTALL_DIR})
endif (DEFINED LIB_INSTALL_DIR)
-set (DIR_SHARE_OPENCC ${DIR_SHARE}/opencc/)
-set (DIR_SHARE_LOCALE ${DIR_SHARE}/locale/)
+set (DIR_SHARE_OPENCC ${DIR_SHARE}/opencc)
+set (DIR_SHARE_LOCALE ${DIR_SHARE}/locale)
######## Configuration
+include(CMakePackageConfigHelpers)
+
+set(targets_export_name OpenCCTargets)
+
configure_file(
opencc.pc.in
opencc.pc
@@ -99,11 +117,32 @@ configure_file(
install(
FILES
- ${CMAKE_BINARY_DIR}/opencc.pc
+ ${CMAKE_CURRENT_BINARY_DIR}/opencc.pc
DESTINATION
${DIR_LIBRARY}/pkgconfig
)
+write_basic_package_version_file(
+ OpenCCConfigVersion.cmake
+ VERSION ${OPENCC_VERSION}
+ COMPATIBILITY SameMajorVersion
+)
+
+configure_package_config_file(
+ OpenCCConfig.cmake.in
+ ${CMAKE_CURRENT_BINARY_DIR}/OpenCCConfig.cmake
+ INSTALL_DESTINATION ${DIR_LIBRARY}/cmake/opencc
+ PATH_VARS DIR_INCLUDE
+)
+
+install(
+ FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/OpenCCConfig.cmake
+ ${CMAKE_CURRENT_BINARY_DIR}/OpenCCConfigVersion.cmake
+ DESTINATION
+ ${DIR_LIBRARY}/cmake/opencc
+)
+
######## Compiler flags
add_definitions(
@@ -113,9 +152,9 @@ add_definitions(
-DPACKAGE_NAME="${PACKAGE_NAME}"
)
-if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+set(CMAKE_CXX_STANDARD 14) # default C++ version for new target afterward
+if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
add_definitions(
- -std=c++11
-Wall
)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread")
@@ -124,7 +163,6 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
endif ()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
add_definitions(
- -std=c++0x
-Wall
)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread")
@@ -151,6 +189,34 @@ if (ENABLE_GTEST)
)
endif()
+if (ENABLE_BENCHMARK)
+ add_definitions(
+ -DPROJECT_BINARY_DIR="${PROJECT_BINARY_DIR}"
+ -DCMAKE_SOURCE_DIR="${CMAKE_SOURCE_DIR}"
+ )
+endif()
+
+if (ENABLE_DARTS)
+ add_definitions(
+ -DENABLE_DARTS
+ )
+endif()
+
+
+######## Dependencies
+
+if(NOT USE_SYSTEM_MARISA)
+ message(STATUS "Use bundled marisa library.")
+ add_subdirectory(deps/marisa-0.2.6)
+else()
+ find_library(LIBMARISA NAMES marisa)
+ if (LIBMARISA)
+ message(STATUS "libmarisa found: ${LIBMARISA}")
+ else()
+ message(FATAL_ERROR "libmarisa not found.")
+ endif()
+endif()
+
######## Subdirectories
add_subdirectory(src)
@@ -161,6 +227,28 @@ add_subdirectory(test)
######## Testing
if (ENABLE_GTEST)
- add_subdirectory(deps/gtest-1.7.0)
+ if(NOT USE_SYSTEM_GTEST)
+ add_subdirectory(deps/googletest-1.15.0)
+ endif()
+ enable_testing()
+endif()
+
+if (ENABLE_BENCHMARK)
+ set(BENCHMARK_ENABLE_TESTING OFF)
+ if(NOT USE_SYSTEM_GOOGLE_BENCHMARK)
+ add_subdirectory(deps/google-benchmark)
+ endif()
enable_testing()
endif()
+
+######## Python
+
+if (BUILD_PYTHON)
+ if(USE_SYSTEM_PYBIND11)
+ find_package(pybind11 CONFIG)
+ else()
+ add_subdirectory(deps/pybind11-2.13.1)
+ endif()
+ pybind11_add_module(opencc_clib src/py_opencc.cpp)
+ target_link_libraries(opencc_clib PRIVATE libopencc)
+endif()
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 000000000..38ab0ada5
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,9 @@
+graft src
+graft deps
+graft test
+graft data
+graft doc
+include CMakeLists.txt OpenCCConfig.cmake.in opencc.pc.in README* LICENSE*
+global-exclude *~ *.py[cod] *.so
+include python/**/__init__.py
+graft python/tests
diff --git a/MODULE.bazel b/MODULE.bazel
new file mode 100644
index 000000000..b59448e9d
--- /dev/null
+++ b/MODULE.bazel
@@ -0,0 +1,30 @@
+"Open Chinese Convert"
+
+module(
+ name = "opencc",
+ version = "1.1.9",
+ compatibility_level = 1,
+)
+
+bazel_dep(name = "darts-clone", version = "0.32")
+bazel_dep(name = "googletest", version = "1.15.0", dev_dependency = True)
+bazel_dep(name = "marisa-trie", version = "0.2.6")
+bazel_dep(name = "platforms", version = "0.0.10")
+bazel_dep(name = "pybind11_bazel", version = "2.12.0")
+bazel_dep(name = "rapidjson", version = "1.1.0")
+bazel_dep(name = "rules_cc", version = "0.0.9")
+bazel_dep(name = "rules_python", version = "0.34.0")
+bazel_dep(name = "tclap", version = "1.2.5")
+
+
+python = use_extension("@rules_python//python/extensions:python.bzl", "python")
+python.toolchain(
+ python_version = "3.12",
+)
+pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")
+pip.parse(
+ hub_name = "pip",
+ python_version = "3.12",
+ requirements_lock = "//python/tests:requirements_lock.txt",
+)
+use_repo(pip, "pip")
diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock
new file mode 100644
index 000000000..e794d2d28
--- /dev/null
+++ b/MODULE.bazel.lock
@@ -0,0 +1,188 @@
+{
+ "lockFileVersion": 11,
+ "registryFileHashes": {
+ "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497",
+ "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2",
+ "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589",
+ "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0",
+ "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb",
+ "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16",
+ "https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16",
+ "https://bcr.bazel.build/modules/abseil-cpp/20240116.2/source.json": "750d5e29326fb59cbe61116a7b803c8a1d0a7090a9c8ed89888d188e3c473fc7",
+ "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85",
+ "https://bcr.bazel.build/modules/apple_support/1.15.1/source.json": "517f2b77430084c541bc9be2db63fdcbb7102938c5f64c17ee60ffda2e5cf07b",
+ "https://bcr.bazel.build/modules/apple_support/1.5.0/MODULE.bazel": "50341a62efbc483e8a2a6aec30994a58749bd7b885e18dd96aa8c33031e558ef",
+ "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd",
+ "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8",
+ "https://bcr.bazel.build/modules/bazel_features/1.11.0/source.json": "c9320aa53cd1c441d24bd6b716da087ad7e4ff0d9742a9884587596edfe53015",
+ "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/source.json": "082ed5f9837901fada8c68c2f3ddc958bb22b6d654f71dd73f3df30d45d4b749",
+ "https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84",
+ "https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8",
+ "https://bcr.bazel.build/modules/darts-clone/0.32/MODULE.bazel": "bdd235e31dd7f2538ff8b3ab3ef09c831349b141afca587d32b487d75c502361",
+ "https://bcr.bazel.build/modules/darts-clone/0.32/source.json": "c65158c152e276f3c59dc0fc0fa746f1ff601e23b0a09812e024fe563e4dc99c",
+ "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb",
+ "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4",
+ "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6",
+ "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f",
+ "https://bcr.bazel.build/modules/googletest/1.15.0/MODULE.bazel": "c4515ecca65378b9035bb6ccee496c1a362b31311c2380ca7740a73bfdaccb51",
+ "https://bcr.bazel.build/modules/googletest/1.15.0/source.json": "c235880d343a5758da581c839653abeebb5f5cd9d987ff879ca68bf08a59f879",
+ "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902",
+ "https://bcr.bazel.build/modules/marisa-trie/0.2.6/MODULE.bazel": "3a4e187ae58831081fe6b38d3f58f44e9d929164b2c1bc970821f076a023dcb6",
+ "https://bcr.bazel.build/modules/marisa-trie/0.2.6/source.json": "a9670e7b0889be633edb31e9aa4ffffa6a562ead1c576cf8ff17f474e54d2c59",
+ "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5",
+ "https://bcr.bazel.build/modules/platforms/0.0.10/source.json": "f22828ff4cf021a6b577f1bf6341cb9dcd7965092a439f64fc1bb3b7a5ae4bd5",
+ "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee",
+ "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37",
+ "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615",
+ "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814",
+ "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d",
+ "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc",
+ "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7",
+ "https://bcr.bazel.build/modules/protobuf/23.1/MODULE.bazel": "88b393b3eb4101d18129e5db51847cd40a5517a53e81216144a8c32dfeeca52a",
+ "https://bcr.bazel.build/modules/protobuf/24.4/MODULE.bazel": "7bc7ce5f2abf36b3b7b7c8218d3acdebb9426aeb35c2257c96445756f970eb12",
+ "https://bcr.bazel.build/modules/protobuf/24.4/source.json": "ace4b8c65d4cfe64efe544f09fc5e5df77faf3a67fbb29c5341e0d755d9b15d6",
+ "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0",
+ "https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858",
+ "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e",
+ "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34",
+ "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/source.json": "6900fdc8a9e95866b8c0d4ad4aba4d4236317b5c1cd04c502df3f0d33afed680",
+ "https://bcr.bazel.build/modules/rapidjson/1.1.0/MODULE.bazel": "0367b53ebffe290358729893e7c435da379397738e09ae45c845e1e4f59fa3fc",
+ "https://bcr.bazel.build/modules/rapidjson/1.1.0/source.json": "0e1c31420d28513742394cd6ab5c4ed004e097670fc85fcf111cdcab96f381bb",
+ "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206",
+ "https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa",
+ "https://bcr.bazel.build/modules/re2/2024-07-02/source.json": "547d0111a9d4f362db32196fef805abbf3676e8d6afbe44d395d87816c1130ca",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.5/MODULE.bazel": "be41f87587998fe8890cd82ea4e848ed8eb799e053c224f78f3ff7fe1a1d9b74",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.9/source.json": "1f1ba6fea244b616de4a554a0f4983c91a9301640c8fe0dd1d410254115c8430",
+ "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6",
+ "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74",
+ "https://bcr.bazel.build/modules/rules_java/7.1.0/MODULE.bazel": "30d9135a2b6561c761bd67bd4990da591e6bdc128790ce3e7afd6a3558b2fb64",
+ "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe",
+ "https://bcr.bazel.build/modules/rules_java/7.6.1/source.json": "8f3f3076554e1558e8e468b2232991c510ecbcbed9e6f8c06ac31c93bcf38362",
+ "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7",
+ "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909",
+ "https://bcr.bazel.build/modules/rules_jvm_external/5.1/source.json": "5abb45cc9beb27b77aec6a65a11855ef2b55d95dfdc358e9f312b78ae0ba32d5",
+ "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0",
+ "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d",
+ "https://bcr.bazel.build/modules/rules_license/0.0.7/source.json": "355cc5737a0f294e560d52b1b7a6492d4fff2caf0bef1a315df5a298fca2d34a",
+ "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc",
+ "https://bcr.bazel.build/modules/rules_pkg/0.7.0/source.json": "c2557066e0c0342223ba592510ad3d812d4963b9024831f7f66fd0584dd8c66c",
+ "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06",
+ "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7",
+ "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483",
+ "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/source.json": "8d8448e71706df7450ced227ca6b3812407ff5e2ccad74a43a9fbe79c84e34e0",
+ "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f",
+ "https://bcr.bazel.build/modules/rules_python/0.22.1/MODULE.bazel": "26114f0c0b5e93018c0c066d6673f1a2c3737c7e90af95eff30cfee38d0bbac7",
+ "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382",
+ "https://bcr.bazel.build/modules/rules_python/0.29.0/MODULE.bazel": "2ac8cd70524b4b9ec49a0b8284c79e4cd86199296f82f6e0d5da3f783d660c82",
+ "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58",
+ "https://bcr.bazel.build/modules/rules_python/0.33.2/MODULE.bazel": "3e036c4ad8d804a4dad897d333d8dce200d943df4827cb849840055be8d2e937",
+ "https://bcr.bazel.build/modules/rules_python/0.34.0/MODULE.bazel": "1d623d026e075b78c9fde483a889cda7996f5da4f36dffb24c246ab30f06513a",
+ "https://bcr.bazel.build/modules/rules_python/0.34.0/source.json": "113116e287eec64a7d005a9db44865d810499fdc4f621e352aff58214f5ea2d8",
+ "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c",
+ "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8",
+ "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c",
+ "https://bcr.bazel.build/modules/stardoc/0.5.3/source.json": "cd53fe968dc8cd98197c052db3db6d82562960c87b61e7a90ee96f8e4e0dda97",
+ "https://bcr.bazel.build/modules/tclap/1.2.5/MODULE.bazel": "d91b779402516ce378283a867e5af24bcc37a8cf80934bf7f9679d082eaded53",
+ "https://bcr.bazel.build/modules/tclap/1.2.5/source.json": "8e519d780d8bb314bbe87af7aa50f0ba7fe68e2450e6df97f860ed105aecd41e",
+ "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43",
+ "https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/MODULE.bazel": "c0df5e35ad55e264160417fd0875932ee3c9dda63d9fccace35ac62f45e1b6f9",
+ "https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/source.json": "b2150404947339e8b947c6b16baa39fa75657f4ddec5e37272c7b11c7ab533bc",
+ "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0",
+ "https://bcr.bazel.build/modules/zlib/1.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27",
+ "https://bcr.bazel.build/modules/zlib/1.3/MODULE.bazel": "6a9c02f19a24dcedb05572b2381446e27c272cd383aed11d41d99da9e3167a72",
+ "https://bcr.bazel.build/modules/zlib/1.3/source.json": "b6b43d0737af846022636e6e255fd4a96fee0d34f08f3830e6e0bac51465c37c"
+ },
+ "selectedYankedVersions": {},
+ "moduleExtensions": {
+ "@@apple_support~//crosstool:setup.bzl%apple_cc_configure_extension": {
+ "general": {
+ "bzlTransitiveDigest": "ltCGFbl/LQQZXn/LEMXfKX7pGwyqNiOCHcmiQW0tmjM=",
+ "usagesDigest": "RkqDb8JtSSm4rLheCLMw/Dx3QQE7dZbl4taOVEYaQZg=",
+ "recordedFileInputs": {},
+ "recordedDirentsInputs": {},
+ "envVariables": {},
+ "generatedRepoSpecs": {
+ "local_config_apple_cc": {
+ "bzlFile": "@@apple_support~//crosstool:setup.bzl",
+ "ruleClassName": "_apple_cc_autoconf",
+ "attributes": {}
+ },
+ "local_config_apple_cc_toolchains": {
+ "bzlFile": "@@apple_support~//crosstool:setup.bzl",
+ "ruleClassName": "_apple_cc_autoconf_toolchains",
+ "attributes": {}
+ }
+ },
+ "recordedRepoMappingEntries": [
+ [
+ "apple_support~",
+ "bazel_tools",
+ "bazel_tools"
+ ]
+ ]
+ }
+ },
+ "@@platforms//host:extension.bzl%host_platform": {
+ "general": {
+ "bzlTransitiveDigest": "xelQcPZH8+tmuOHVjL9vDxMnnQNMlwj0SlvgoqBkm4U=",
+ "usagesDigest": "V1R2Y2oMxKNfx2WCWpSCaUV1WefW1o8HZGm3v1vHgY4=",
+ "recordedFileInputs": {},
+ "recordedDirentsInputs": {},
+ "envVariables": {},
+ "generatedRepoSpecs": {
+ "host_platform": {
+ "bzlFile": "@@platforms//host:extension.bzl",
+ "ruleClassName": "host_platform_repo",
+ "attributes": {}
+ }
+ },
+ "recordedRepoMappingEntries": []
+ }
+ },
+ "@@pybind11_bazel~//:internal_configure.bzl%internal_configure_extension": {
+ "general": {
+ "bzlTransitiveDigest": "+F47SE20NlARCHVGbd4r7kkjg4OA0eCJcOd5fqKq4fQ=",
+ "usagesDigest": "iH2lKTfsNEpn2MqtGpBNwJrxbb2C7DiYmh/XuKgDtr8=",
+ "recordedFileInputs": {
+ "@@pybind11_bazel~//MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34"
+ },
+ "recordedDirentsInputs": {},
+ "envVariables": {},
+ "generatedRepoSpecs": {
+ "pybind11": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "build_file": "@@pybind11_bazel~//:pybind11-BUILD.bazel",
+ "strip_prefix": "pybind11-2.12.0",
+ "urls": [
+ "https://github.com/pybind/pybind11/archive/v2.12.0.zip"
+ ]
+ }
+ }
+ },
+ "recordedRepoMappingEntries": [
+ [
+ "pybind11_bazel~",
+ "bazel_tools",
+ "bazel_tools"
+ ]
+ ]
+ }
+ }
+ }
+}
diff --git a/Makefile b/Makefile
index 25d7c64fe..db5af82c1 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
#
# Open Chinese Convert
#
-# Copyright 2010-2015 BYVoid
+# Copyright 2010-2020 Carbo Kuo
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -17,14 +17,16 @@
#
PREFIX = /usr
+REL_BUILD_DOCUMENTATION ?= ON
-.PHONY: build clean node test xcode-build
+.PHONY: bazel build clean node test xcode-build
build:
mkdir -p build/rel
(cd build/rel; cmake \
- -DBUILD_DOCUMENTATION:BOOL=ON \
+ -DBUILD_DOCUMENTATION:BOOL=${REL_BUILD_DOCUMENTATION} \
-DENABLE_GTEST:BOOL=OFF \
+ -DENABLE_BENCHMARK:BOOL=OFF \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=${PREFIX} \
../..)
@@ -39,6 +41,7 @@ test:
(cd build/dbg; cmake \
-DBUILD_DOCUMENTATION:BOOL=OFF \
-DENABLE_GTEST:BOOL=ON \
+ -DENABLE_BENCHMARK:BOOL=OFF \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_INSTALL_PREFIX=`pwd`/root \
../..)
@@ -46,6 +49,18 @@ test:
(cd build/dbg; ctest --verbose)
make -C build/dbg install VERBOSE=${VERBOSE}
+benchmark:
+ mkdir -p build/perf
+ (cd build/perf; cmake \
+ -DBUILD_DOCUMENTATION:BOOL=OFF \
+ -DENABLE_GTEST:BOOL=OFF \
+ -DENABLE_BENCHMARK:BOOL=ON \
+ -DCMAKE_BUILD_TYPE=RelWithDebInfo \
+ -DCMAKE_INSTALL_PREFIX=`pwd`/root \
+ ../..)
+ make -C build/perf VERBOSE=${VERBOSE} PREFIX=${PREFIX}
+ (cd build/perf; ctest --verbose)
+
node:
node-gyp configure
node-gyp build
@@ -59,13 +74,38 @@ xcode-build:
-G "Xcode" \
-DBUILD_DOCUMENTATION:BOOL=OFF \
-DENABLE_GTEST:BOOL=ON \
+ -DENABLE_BENCHMARK:BOOL=ON \
..; \
xcodebuild build)
-test-all: test node-test
+python-build:
+ echo "No need to build"
+
+python-install: python-build
+ python -m pip install .
+
+python-dist: python-build
+ python -m build
+
+python-test: python-build
+ cd python; pytest .
+
+test-all: test node-test python-test
+
+format:
+ find "src" "node" "test" -iname "*.hpp" -o -iname "*.cpp" -o -iname "*.cc" \
+ -o -iname "*.c" -o -iname "*.h" \
+ | xargs clang-format -i
clean:
- rm -rf build xcode
+ rm -rf build xcode python/opencc/clib *.egg-info bazel-*
install: build
make -C build/rel install VERBOSE=${VERBOSE} PREFIX=${PREFIX}
+
+bazel:
+ bazel build //:opencc
+ bazel test --test_output=all //src/... //data/... //test/...
+
+bazel-clean:
+ bazel clean --expunge
diff --git a/NEWS.md b/NEWS.md
index b3c2fc6cf..0c2767fbc 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,5 +1,100 @@
# Change History of OpenCC
+## Version 1.1.8
+
+2024年7月27日
+
+* 修正Node新版本編譯的問題([#782](https://github.com/BYVoid/OpenCC/issues/782), [#798](https://github.com/BYVoid/OpenCC/issues/798))。
+* 進一步修正Python包生成腳本([#875](https://github.com/BYVoid/OpenCC/pull/875))。
+* 引入Bazel構建系統以及CI([#879](https://github.com/BYVoid/OpenCC/pull/879))。
+* 引入Github MSVC CI([#880](https://github.com/BYVoid/OpenCC/pull/880))。
+* 爲`opencc`命令行工具添加了字典和配置的路徑`--path`參數。
+* 更新附帶的`googletest`版本到1.15,`pybind11`到2.13.1,`tclap`到1.2.5。
+* 若干轉換字詞修正([#609](https://github.com/BYVoid/OpenCC/pull/609), [#698](https://github.com/BYVoid/OpenCC/pull/698), [#707](https://github.com/BYVoid/OpenCC/pull/707), [#760](https://github.com/BYVoid/OpenCC/pull/760), [#779](https://github.com/BYVoid/OpenCC/pull/779), [#786](https://github.com/BYVoid/OpenCC/pull/786), [#792](https://github.com/BYVoid/OpenCC/pull/792), [#806](https://github.com/BYVoid/OpenCC/pull/806), [#808](https://github.com/BYVoid/OpenCC/pull/808), [#810](https://github.com/BYVoid/OpenCC/pull/810), [#825](https://github.com/BYVoid/OpenCC/pull/825), [#826](https://github.com/BYVoid/OpenCC/pull/826), [#837](https://github.com/BYVoid/OpenCC/pull/837), [#864](https://github.com/BYVoid/OpenCC/pull/864), [#865](https://github.com/BYVoid/OpenCC/pull/865), [#870](https://github.com/BYVoid/OpenCC/pull/870), [#877](https://github.com/BYVoid/OpenCC/pull/877), [#878](https://github.com/BYVoid/OpenCC/pull/878))。
+
+## Version 1.1.7
+
+2023年10月15日
+
+* 添加提交時 python 包重建以驗證包生成 ([#822](https://github.com/BYVoid/OpenCC/pull/822))。
+* 支持Python 3.12 和 Node 20,移除針對Python 3.7和Node 16的構建 ([#820](https://github.com/BYVoid/OpenCC/pull/820))。
+* add mingw-w64 ci ([#802](https://github.com/BYVoid/OpenCC/pull/802))。
+* Add support of CMake config modules ([#763](https://github.com/BYVoid/OpenCC/pull/763))。
+* 若干其他小修復。
+
+## Version 1.1.6
+
+2022年12月08日
+
+* 修復python3.11 macos構建 ([#744](https://github.com/BYVoid/OpenCC/pull/744))。
+* Bump gtest 和 benchmark 以與最新的 github runners 一起工作 ([#747](https://github.com/BYVoid/OpenCC/pull/747))。
+
+## Version 1.1.5
+
+2022年12月03日
+
+* 支持Python 3.11 ([#728](https://github.com/BYVoid/OpenCC/pull/728))。
+* Automatically name SO files ([#708](https://github.com/BYVoid/OpenCC/pull/708))
+* Add support for Apple silicon build tag ([#716](https://github.com/BYVoid/OpenCC/pull/716))
+* 若干其他小修復。
+
+## Version 1.1.4
+
+2022年6月4日
+
+* 支持Python 3.10([#637](https://github.com/BYVoid/OpenCC/issues/637))。
+* 移除針對Python 2.7、3.5、3.6和Node 10的構建([#690](https://github.com/BYVoid/OpenCC/issues/690), [#691](https://github.com/BYVoid/OpenCC/issues/691))。
+* 若干其他小修復。
+
+## Version 1.1.3
+
+2021年9月3日
+
+* 修復部分頭文件不能單獨使用的問題(#550)。
+* 修復引入系統pybind11的方法(#566)。
+* 支持Node.js 16(#597)。
+* 支持Python 3.9(#603)。
+* 修正轉換錯誤。
+* 若干其他小修復。
+
+## Version 1.1.2
+
+2021年3月2日
+
+* 新增香港繁體轉換。
+* 根據《通用漢字規範表》修正大量簡體異體字轉換。調整臺灣標準,避免過度轉換。
+* 修正編譯兼容性問題,包括並行編譯。
+* 修正1.1.0以來引入的性能嚴重下降問題。
+
+## Version 1.1.1
+
+2020年5月22日
+
+* 正式提供[Python](https://pypi.org/project/OpenCC/)接口和TypeScript類型標註。
+* 更新動態鏈接庫`SOVERSION`到`1.1`,由於C++內部接口發生變更。
+* 進一步改進與Windows MSVC的兼容性。
+* 簡化頭文件結構,加快編譯速度。刪除不必要的`using`。
+* 修復部分香港標準字。
+
+## Version 1.1.0
+
+2020年5月10日
+
+* 新辭典格式`ocd2`,基於Marisa Trie 0.2.5。辭典大小大幅減少。`STPhrases.ocd`從4.3MB減少到`STPhrases.ocd2`的924KB。
+* 升級依賴的rapidjson版本到1.1.0,tclap到1.2.2,gtest到1.11.0。
+* 更改「涌/湧」的默認轉換,修正多個詞組轉換。
+* 提供Windows的預編譯版本下載(AppVeyor)。
+* 增加基準測試結果。
+
+## Version 1.0.6
+
+2020年4月13日
+
+* 正式支持日本語新字體轉換。
+* 升級Node.js依賴,改進兼容性。
+* 修復多處多平臺編譯和兼容性問題。
+* 修正大量轉換錯誤。
+
## Version 1.0.5
2017年2月6日
diff --git a/OpenCCConfig.cmake.in b/OpenCCConfig.cmake.in
new file mode 100644
index 000000000..07087bfbd
--- /dev/null
+++ b/OpenCCConfig.cmake.in
@@ -0,0 +1,7 @@
+@PACKAGE_INIT@
+
+include(${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake)
+
+set_and_check(OPENCC_INCLUDE_DIR @PACKAGE_DIR_INCLUDE@/opencc)
+
+check_required_components(OpenCC)
diff --git a/README.md b/README.md
index fb686a83d..a89d616df 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,21 @@
# Open Chinese Convert 開放中文轉換
-[  ](https://bintray.com/byvoid/opencc/OpenCC/_latestVersion)
-[](https://travis-ci.org/BYVoid/OpenCC)
+[](https://github.com/BYVoid/OpenCC/actions/workflows/cmake.yml)
+[](https://github.com/BYVoid/OpenCC/actions/workflows/bazel.yml)
+[](https://github.com/BYVoid/OpenCC/actions/workflows/msvc.yml)
+[](https://github.com/BYVoid/OpenCC/actions/workflows/nodejs.yml)
+[](https://github.com/BYVoid/OpenCC/actions/workflows/python.yml)
[](https://ci.appveyor.com/project/Carbo/OpenCC)
## Introduction 介紹
-Open Chinese Convert (OpenCC, 開放中文轉換) is an opensource project for conversion between Traditional Chinese and Simplified Chinese, supporting character-level conversion, phrase-level conversion, variant conversion and regional idioms among Mainland China, Taiwan and Hong kong.
+
-中文簡繁轉換開源項目,支持詞彙級別的轉換、異體字轉換和地區習慣用詞轉換(中國大陸、臺灣、香港)。
+Open Chinese Convert (OpenCC, 開放中文轉換) is an opensource project for conversions between Traditional Chinese, Simplified Chinese and Japanese Kanji (Shinjitai). It supports character-level and phrase-level conversion, character variant conversion and regional idioms among Mainland China, Taiwan and Hong Kong. This is not translation tool between Mandarin and Cantonese, etc.
+
+中文簡繁轉換開源項目,支持詞彙級別的轉換、異體字轉換和地區習慣用詞轉換(中國大陸、臺灣、香港、日本新字體)。不提供普通話與粵語的轉換。
+
+Discussion (Telegram): https://t.me/open_chinese_convert
### Features 特點
@@ -17,33 +24,118 @@ Open Chinese Convert (OpenCC, 開放中文轉換) is an opensource project for c
* 嚴格審校一簡對多繁詞條,原則爲「能分則不合」。
* 支持中國大陸、臺灣、香港異體字和地區習慣用詞轉換,如「裏」「裡」、「鼠標」「滑鼠」。
* 詞庫和函數庫完全分離,可以自由修改、導入、擴展。
-* 支持C、C++、Python、PHP、Java、Ruby、Node.js and Android。
-* 兼容Windows、Linux、Mac平臺。
-
-### Links 相關鏈接
-
-* Introduction 詳細介紹 https://github.com/BYVoid/OpenCC/wiki/%E7%B7%A3%E7%94%B1
-* OpenCC Online (在線轉換) http://opencc.byvoid.com/
-* 現代漢語常用簡繁一對多字義辨析表 http://ytenx.org/byohlyuk/KienxPyan
## Installation 安裝
-* [Debian](http://packages.qa.debian.org/o/opencc.html)
+### Package Managers 包管理器
+
+* [Debian](https://tracker.debian.org/pkg/opencc)
* [Ubuntu](https://launchpad.net/ubuntu/+source/opencc)
-* [Fedora](https://admin.fedoraproject.org/pkgdb/package/opencc/)
-* [Arch Linux](https://www.archlinux.org/packages/community/x86_64/opencc/)
-* [Mac OS](https://github.com/Homebrew/homebrew-core/blob/master/Formula/opencc.rb)
+* [Fedora](https://packages.fedoraproject.org/pkgs/opencc/opencc/)
+* [Arch Linux](https://archlinux.org/packages/extra/x86_64/opencc/)
+* [macOS](https://formulae.brew.sh/formula/opencc)
+* [Bazel](https://registry.bazel.build/modules/opencc)
* [Node.js](https://npmjs.org/package/opencc)
+* [Python](https://pypi.org/project/OpenCC/)
-## Download 下載
+### Prebuilt 預編譯
-https://bintray.com/byvoid/opencc/OpenCC
+* Windows (x86_64): [Latest build](https://ci.appveyor.com/api/projects/Carbo/opencc/artifacts/OpenCC.zip?branch=master&job=Environment:%20nodejs_version=none;%20Platform:%20x64)
+* Windows (x86): [Latest build](https://ci.appveyor.com/api/projects/Carbo/opencc/artifacts/OpenCC.zip?branch=master&job=Environment:%20nodejs_version=none;%20Platform:%20x86)
## Usage 使用
-### Command Line 命令行
+### Online demo 線上轉換展示
+
+Warning: **This is NOT an API.** You will be banned if you make calls programmatically.
+
+https://opencc.byvoid.com/
+
+### Node.js
+
+[npm](https://www.npmjs.com/opencc) `npm install opencc`
+
+#### JavaScript
+```js
+const OpenCC = require('opencc');
+const converter = new OpenCC('s2t.json');
+converter.convertPromise("汉字").then(converted => {
+ console.log(converted); // 漢字
+});
+```
+
+#### TypeScript
+```ts
+import { OpenCC } from 'opencc';
+async function main() {
+ const converter: OpenCC = new OpenCC('s2t.json');
+ const result: string = await converter.convertPromise('汉字');
+ console.log(result);
+}
+```
+
+See [demo.js](https://github.com/BYVoid/OpenCC/blob/master/node/demo.js) and [ts-demo.ts](https://github.com/BYVoid/OpenCC/blob/master/node/ts-demo.ts).
+
+### Python
+
+`pip install opencc` (Windows, Linux, macOS)
+
+```python
+import opencc
+converter = opencc.OpenCC('s2t.json')
+converter.convert('汉字') # 漢字
+```
+
+### C++
+
+```c++
+#include "opencc.h"
+
+int main() {
+ const opencc::SimpleConverter converter("s2t.json");
+ converter.Convert("汉字"); // 漢字
+ return 0;
+}
+```
+
+[Full example with Bazel](https://github.com/BYVoid/opencc-bazel-example)
-`opencc --help`
+### C
+
+```c
+#include "opencc.h"
+
+int main() {
+ opencc_t opencc = opencc_open("s2t.json");
+ const char* input = "汉字";
+ char* converted = opencc_convert_utf8(opencc, input, strlen(input)); // 漢字
+ opencc_convert_utf8_free(converted);
+ opencc_close(opencc);
+ return 0;
+}
+
+```
+
+Document 文檔: https://byvoid.github.io/OpenCC/
+
+### Command Line
+
+* `opencc --help`
+* `opencc_dict --help`
+* `opencc_phrase_extract --help`
+
+### Others (Unofficial)
+
+* Swift (iOS): [SwiftyOpenCC](https://github.com/XQS6LB3A/SwiftyOpenCC)
+* iOSOpenCC (pod): [iOSOpenCC](https://github.com/swiftdo/OpenCC)
+* Java: [opencc4j](https://github.com/houbb/opencc4j)
+* Android: [android-opencc](https://github.com/qichuan/android-opencc)
+* PHP: [opencc4php](https://github.com/nauxliu/opencc4php)
+* Pure JavaScript: [opencc-js](https://github.com/nk2028/opencc-js)
+* WebAssembly: [wasm-opencc](https://github.com/oyyd/wasm-opencc)
+* Browser Extension: [opencc-extension](https://github.com/tnychn/opencc-extension)
+* Go (Pure): [OpenCC for Go](https://github.com/longbridge/opencc)
+* Dart (native-assets): [opencc-dart](https://github.com/lindeer/opencc-dart)
### Configurations 配置文件
@@ -53,68 +145,97 @@ https://bintray.com/byvoid/opencc/OpenCC
* `t2s.json` Traditional Chinese to Simplified Chinese 繁體到簡體
* `s2tw.json` Simplified Chinese to Traditional Chinese (Taiwan Standard) 簡體到臺灣正體
* `tw2s.json` Traditional Chinese (Taiwan Standard) to Simplified Chinese 臺灣正體到簡體
-* `s2hk.json` Simplified Chinese to Traditional Chinese (Hong Kong Standard) 簡體到香港繁體(香港小學學習字詞表標準)
-* `hk2s.json` Traditional Chinese (Hong Kong Standard) to Simplified Chinese 香港繁體(香港小學學習字詞表標準)到簡體
+* `s2hk.json` Simplified Chinese to Traditional Chinese (Hong Kong variant) 簡體到香港繁體
+* `hk2s.json` Traditional Chinese (Hong Kong variant) to Simplified Chinese 香港繁體到簡體
* `s2twp.json` Simplified Chinese to Traditional Chinese (Taiwan Standard) with Taiwanese idiom 簡體到繁體(臺灣正體標準)並轉換爲臺灣常用詞彙
* `tw2sp.json` Traditional Chinese (Taiwan Standard) to Simplified Chinese with Mainland Chinese idiom 繁體(臺灣正體標準)到簡體並轉換爲中國大陸常用詞彙
* `t2tw.json` Traditional Chinese (OpenCC Standard) to Taiwan Standard 繁體(OpenCC 標準)到臺灣正體
-* `t2hk.json` Traditional Chinese (OpenCC Standard) to Hong Kong Standard 繁體(OpenCC 標準)到香港繁體(香港小學學習字詞表標準)
-
-## Development Documentation 開發文檔
-
-* http://byvoid.github.io/OpenCC/
+* `hk2t.json` Traditional Chinese (Hong Kong variant) to Traditional Chinese 香港繁體到繁體(OpenCC 標準)
+* `t2hk.json` Traditional Chinese (OpenCC Standard) to Hong Kong variant 繁體(OpenCC 標準)到香港繁體
+* `t2jp.json` Traditional Chinese Characters (Kyūjitai) to New Japanese Kanji (Shinjitai) 繁體(OpenCC 標準,舊字體)到日文新字體
+* `jp2t.json` New Japanese Kanji (Shinjitai) to Traditional Chinese Characters (Kyūjitai) 日文新字體到繁體(OpenCC 標準,舊字體)
+* `tw2t.json` Traditional Chinese (Taiwan standard) to Traditional Chinese 臺灣正體到繁體(OpenCC 標準)
## Build 編譯
### Build with CMake
-Linux (gcc 4.6 is required):
+#### Linux & macOS
-```
+g++ 4.6+ or clang 3.2+ is required.
+
+```bash
make
-sudo make install
```
-Mac OS X (clang 3.2 is required):
+#### Windows Visual Studio:
+```bash
+build.cmd
```
-make PREFIX=/usr/local
-sudo make PREFIX=/usr/local install
+
+### Build with Bazel
+
+```bash
+bazel build //:opencc
+bazel test --test_output=all //src/... //data/... //test/...
```
-Windows MSYS:
+### Test 測試
+
+#### Linux & macOS
```
-cmake -H. -Bbuild -G "MSYS Makefiles" -DCMAKE_INSTALL_PREFIX="path/to/install"
-cmake --build build --config Release --target install
+make test
```
-Windows Visual Studio (2013 or higher required):
+#### Windows Visual Studio:
-```
-cmake -H. -Bbuild -G"Visual Studio 12" -DCMAKE_INSTALL_PREFIX="path/to/install"
-cmake --build build --config Release --target install
+```bash
+test.cmd
```
-### iOS
+### Benchmark 基準測試
-See https://github.com/gelosie/OpenCC/tree/master/iOS
+```
+make benchmark
+```
-Or [SwiftyOpenCC](https://github.com/XQS6LB3A/SwiftyOpenCC)
+Example results (from Github CI):
-### Android
+```
+1: ------------------------------------------------------------------
+1: Benchmark Time CPU Iterations
+1: ------------------------------------------------------------------
+1: BM_Initialization/hk2s 1.56 ms 1.56 ms 442
+1: BM_Initialization/hk2t 0.144 ms 0.144 ms 4878
+1: BM_Initialization/jp2t 0.260 ms 0.260 ms 2604
+1: BM_Initialization/s2hk 23.8 ms 23.8 ms 29
+1: BM_Initialization/s2t 25.6 ms 25.6 ms 28
+1: BM_Initialization/s2tw 24.0 ms 23.9 ms 30
+1: BM_Initialization/s2twp 24.6 ms 24.6 ms 28
+1: BM_Initialization/t2hk 0.052 ms 0.052 ms 12897
+1: BM_Initialization/t2jp 0.141 ms 0.141 ms 5012
+1: BM_Initialization/t2s 1.30 ms 1.30 ms 540
+1: BM_Initialization/tw2s 1.39 ms 1.39 ms 529
+1: BM_Initialization/tw2sp 1.69 ms 1.69 ms 426
+1: BM_Initialization/tw2t 0.089 ms 0.089 ms 7707
+1: BM_Convert2M 582 ms 582 ms 1
+1: BM_Convert/100 1.07 ms 1.07 ms 636
+1: BM_Convert/1000 11.0 ms 11.0 ms 67
+1: BM_Convert/10000 113 ms 113 ms 6
+1: BM_Convert/100000 1176 ms 1176 ms 1
+```
-See [android-opencc](https://github.com/qichuan/android-opencc)
+## Projects using OpenCC 使用 OpenCC 的項目
-## Projects using Opencc 使用OpenCC的項目
+Please update if your project is using OpenCC.
* [ibus-pinyin](https://github.com/ibus/ibus-pinyin)
* [fcitx](https://github.com/fcitx/fcitx)
-* [rimeime](http://code.google.com/p/rimeime/)
+* [rimeime](https://rime.im/)
* [libgooglepinyin](http://code.google.com/p/libgooglepinyin/)
* [ibus-libpinyin](https://github.com/libpinyin/ibus-libpinyin)
-* [BYVBlog](https://github.com/byvoid/byvblog)
-* [豆瓣同城微信](http://weixinqiao.com/douban-event/)
* [alfred-chinese-converter](https://github.com/amowu/alfred-chinese-converter)
* [GoldenDict](https://github.com/goldendict/goldendict)
@@ -124,15 +245,22 @@ Apache License 2.0
## Third Party Library 第三方庫
-* [darts-clone](https://code.google.com/p/darts-clone/) BSD License
+* [darts-clone](https://github.com/s-yata/darts-clone) BSD License
+* [marisa-trie](https://github.com/s-yata/marisa-trie) BSD License
* [tclap](http://tclap.sourceforge.net/) MIT License
-* [rapidjson](https://github.com/miloyip/rapidjson) MIT License
+* [rapidjson](https://github.com/Tencent/rapidjson) MIT License
+* [Google Test](https://github.com/google/googletest) BSD License
-All these libraries are statically linked.
+All these libraries are statically linked by default.
## Change History 版本歷史
-https://github.com/BYVoid/OpenCC/blob/master/NEWS.md
+* [NEWS](https://github.com/BYVoid/OpenCC/blob/master/NEWS.md)
+
+### Links 相關鏈接
+
+* Introduction 詳細介紹 https://github.com/BYVoid/OpenCC/wiki/%E7%B7%A3%E7%94%B1
+* 現代漢語常用簡繁一對多字義辨析表 http://ytenx.org/byohlyuk/KienxPyan
## Contributors 貢獻者
@@ -148,6 +276,7 @@ https://github.com/BYVoid/OpenCC/blob/master/NEWS.md
* [Paul Meng](http://home.mno2.org/)
* [Lawrence Lau](https://github.com/ktslwy)
* [瑾昀](https://github.com/kunki)
+* [內木一郎](https://github.com/SyaoranHinata)
* [Marguerite Su](https://www.marguerite.su/)
* [Brian White](http://mscdex.net)
* [Qijiang Fan](https://fqj.me/)
@@ -174,5 +303,8 @@ https://github.com/BYVoid/OpenCC/blob/master/NEWS.md
* [Cychih](https://github.com/pi314)
* [kyleskimo](https://github.com/kyleskimo)
* [Ryuan Choi](https://github.com/bunhere)
+* [Prcuvu](https://github.com/Prcuvu)
+* [Tony Able](https://github.com/TonyAble)
+* [Xiao Liang](https://github.com/yxliang01)
-Please update this list you have contributed OpenCC.
+Please feel free to update this list if you have contributed OpenCC.
diff --git a/appveyor.yml b/appveyor.yml
deleted file mode 100644
index 36eed0126..000000000
--- a/appveyor.yml
+++ /dev/null
@@ -1,40 +0,0 @@
-version: "{build}"
-skip_branch_with_pr: true
-skip_tags: true
-build: off
-
-environment:
- matrix:
- - nodejs_version: stable
- - nodejs_version: 7
- - nodejs_version: 6
- - nodejs_version: 5
-
-platform:
- - x64
- - x86
-
-# Install scripts. (runs after repo cloning)
-install:
- # install Node.js
- - ps: Install-Product node $env:nodejs_version $env:platform
- # Get the latest stable version of npm
- - npm -g i npm@latest
- # install modules
- - appveyor-retry call npm install --build-from-source
-
-# to run your custom scripts instead of automatic tests
-test_script:
- - IF %nodejs_version%==stable cmake -H. -Bbuild -G"Visual Studio 12"
- - IF %nodejs_version%==stable cmake --build build --config Release --target install
- - npm test
-
-# pushing entire folder as a zip archive
-artifacts:
- - path: build/src/tools/Release
- name: OpenCC
- type: zip
-
-# to run your custom scripts instead of provider deployments
-deploy_script:
- - npm run deploy
diff --git a/build.cmd b/build.cmd
new file mode 100644
index 000000000..d627a48d7
--- /dev/null
+++ b/build.cmd
@@ -0,0 +1,2 @@
+cmake -S. -Bbuild -DCMAKE_INSTALL_PREFIX:PATH=.
+cmake --build build --config Release --target install
diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt
index 151677536..e9b921f50 100644
--- a/data/CMakeLists.txt
+++ b/data/CMakeLists.txt
@@ -1,6 +1,8 @@
+find_package(PythonInterp REQUIRED)
+
set(OPENCC_DICT_BIN opencc_dict)
-set(DICT_MERGE_BIN python ${CMAKE_CURRENT_SOURCE_DIR}/scripts/merge.py)
-set(DICT_REVERSE_BIN python ${CMAKE_CURRENT_SOURCE_DIR}/scripts/reverse.py)
+set(DICT_MERGE_BIN "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/merge.py")
+set(DICT_REVERSE_BIN "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/reverse.py")
set(DICT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dictionary)
set(DICT_GENERATED_DIR ${CMAKE_CURRENT_BINARY_DIR})
@@ -12,10 +14,11 @@ set(
TSPhrases
TWVariants
TWVariantsRevPhrases
- JPVariants
HKVariants
- HKVariantsPhrases
HKVariantsRevPhrases
+ JPVariants
+ JPShinjitaiCharacters
+ JPShinjitaiPhrases
)
set(
@@ -24,12 +27,13 @@ set(
TWPhrasesRev
TWVariantsRev
HKVariantsRev
+ JPVariantsRev
)
set(DICTS ${DICTS_RAW} ${DICTS_GENERATED})
foreach(DICT ${DICTS})
- set(DICT_TARGETS ${DICT_TARGETS} ${DICT}.ocd)
+ set(DICT_TARGETS ${DICT_TARGETS} ${DICT}.ocd2)
endforeach(DICT)
add_custom_target(
@@ -85,6 +89,15 @@ set(
${DICT_REVERSE_BIN} ${DICT_HKVariantsRev_GENERATING_INPUT} HKVariantsRev.txt
)
+set(
+ DICT_JPVariantsRev_GENERATING_INPUT
+ ${DICT_DIR}/JPVariants.txt
+)
+set(
+ DICT_JPVariantsRev_GENERATING_COMMAND
+ ${DICT_REVERSE_BIN} ${DICT_JPVariantsRev_GENERATING_INPUT} JPVariantsRev.txt
+)
+
foreach(DICT ${DICTS_GENERATED})
add_custom_command(
OUTPUT
@@ -103,28 +116,40 @@ foreach(DICT ${DICTS_GENERATED})
)
endforeach(DICT)
+add_custom_target(
+ copy_libopencc_to_dir_of_opencc_dict
+ COMMENT
+ "Copying libopencc to directory of opencc_dict"
+ COMMAND
+ ${CMAKE_COMMAND} -E copy "$" "$"
+)
+if (WIN32)
+ set(DICT_WIN32_DEPENDS copy_libopencc_to_dir_of_opencc_dict)
+else()
+ set(DICT_WIN32_DEPENDS)
+endif()
+
foreach(DICT ${DICTS})
add_custom_command(
OUTPUT
- ${DICT}.ocd
+ ${DICT}.ocd2
COMMENT
- "Building ${DICT}.ocd"
- COMMAND
- ${CMAKE_COMMAND} -E copy "$" "$"
+ "Building ${DICT}.ocd2"
COMMAND
${OPENCC_DICT_BIN}
--input ${DICT_${DICT}_INPUT}
- --output ${DICT}.ocd
+ --output ${DICT}.ocd2
--from text
- --to ocd
+ --to ocd2
DEPENDS
+ ${DICT_WIN32_DEPENDS}
${OPENCC_DICT_BIN}
${DICT_${DICT}_INPUT}
)
install(
FILES
- ${DICT_GENERATED_DIR}/${DICT}.ocd
+ ${DICT_GENERATED_DIR}/${DICT}.ocd2
DESTINATION
${DIR_SHARE_OPENCC}
)
@@ -132,21 +157,25 @@ foreach(DICT ${DICTS})
set_directory_properties(
PROPERTIES
ADDITIONAL_MAKE_CLEAN_FILES
- "${DICT_GENERATED_DIR}/${DICT}.ocd"
+ "${DICT_GENERATED_DIR}/${DICT}.ocd2"
)
endforeach(DICT)
set(CONFIG_FILES
+ config/hk2s.json
+ config/hk2t.json
+ config/jp2t.json
+ config/s2hk.json
config/s2t.json
- config/t2s.json
config/s2tw.json
config/s2twp.json
+ config/t2hk.json
+ config/t2jp.json
+ config/t2s.json
+ config/t2tw.json
config/tw2s.json
config/tw2sp.json
- config/t2tw.json
- config/s2hk.json
- config/hk2s.json
- config/t2hk.json
+ config/tw2t.json
)
install(
diff --git a/data/config/BUILD.bazel b/data/config/BUILD.bazel
new file mode 100644
index 000000000..ea3ee617d
--- /dev/null
+++ b/data/config/BUILD.bazel
@@ -0,0 +1,6 @@
+package(default_visibility = ["//visibility:public"])
+
+filegroup(
+ name = "config",
+ srcs = glob(["*.json"]),
+)
diff --git a/data/config/hk2s.json b/data/config/hk2s.json
index ab01ca8b8..cf0e9b975 100644
--- a/data/config/hk2s.json
+++ b/data/config/hk2s.json
@@ -1,32 +1,32 @@
{
- "name": "Traditional Chinese (Hong Kong standard) to Simplified Chinese",
+ "name": "Traditional Chinese (Hong Kong variant) to Simplified Chinese",
"segmentation": {
"type": "mmseg",
"dict": {
- "type": "ocd",
- "file": "TSPhrases.ocd"
+ "type": "ocd2",
+ "file": "TSPhrases.ocd2"
}
},
"conversion_chain": [{
"dict": {
"type": "group",
"dicts": [{
- "type": "ocd",
- "file": "HKVariantsRevPhrases.ocd"
+ "type": "ocd2",
+ "file": "HKVariantsRevPhrases.ocd2"
}, {
- "type": "ocd",
- "file": "HKVariantsRev.ocd"
+ "type": "ocd2",
+ "file": "HKVariantsRev.ocd2"
}]
}
}, {
"dict": {
"type": "group",
"dicts": [{
- "type": "ocd",
- "file": "TSPhrases.ocd"
+ "type": "ocd2",
+ "file": "TSPhrases.ocd2"
}, {
- "type": "ocd",
- "file": "TSCharacters.ocd"
+ "type": "ocd2",
+ "file": "TSCharacters.ocd2"
}]
}
}]
diff --git a/data/config/hk2t.json b/data/config/hk2t.json
new file mode 100644
index 000000000..0d47b9174
--- /dev/null
+++ b/data/config/hk2t.json
@@ -0,0 +1,22 @@
+{
+ "name": "Traditional Chinese (Hong Kong variant) to Traditional Chinese",
+ "segmentation": {
+ "type": "mmseg",
+ "dict": {
+ "type": "ocd2",
+ "file": "HKVariantsRevPhrases.ocd2"
+ }
+ },
+ "conversion_chain": [{
+ "dict": {
+ "type": "group",
+ "dicts": [{
+ "type": "ocd2",
+ "file": "HKVariantsRevPhrases.ocd2"
+ }, {
+ "type": "ocd2",
+ "file": "HKVariantsRev.ocd2"
+ }]
+ }
+ }]
+}
diff --git a/data/config/jp2t.json b/data/config/jp2t.json
new file mode 100644
index 000000000..025d89197
--- /dev/null
+++ b/data/config/jp2t.json
@@ -0,0 +1,25 @@
+{
+ "name": "New Japanese Kanji (Shinjitai) to Traditional Chinese Characters (Kyūjitai)",
+ "segmentation": {
+ "type": "mmseg",
+ "dict": {
+ "type": "ocd2",
+ "file": "JPShinjitaiPhrases.ocd2"
+ }
+ },
+ "conversion_chain": [{
+ "dict": {
+ "type": "group",
+ "dicts": [{
+ "type": "ocd2",
+ "file": "JPShinjitaiPhrases.ocd2"
+ }, {
+ "type": "ocd2",
+ "file": "JPShinjitaiCharacters.ocd2"
+ }, {
+ "type": "ocd2",
+ "file": "JPVariantsRev.ocd2"
+ }]
+ }
+ }]
+}
diff --git a/data/config/s2hk.json b/data/config/s2hk.json
index 948544092..fcaa017ee 100644
--- a/data/config/s2hk.json
+++ b/data/config/s2hk.json
@@ -1,33 +1,27 @@
{
- "name": "Simplified Chinese to Traditional Chinese (Hong Kong standard)",
+ "name": "Simplified Chinese to Traditional Chinese (Hong Kong variant)",
"segmentation": {
"type": "mmseg",
"dict": {
- "type": "ocd",
- "file": "STPhrases.ocd"
+ "type": "ocd2",
+ "file": "STPhrases.ocd2"
}
},
"conversion_chain": [{
"dict": {
"type": "group",
"dicts": [{
- "type": "ocd",
- "file": "STPhrases.ocd"
+ "type": "ocd2",
+ "file": "STPhrases.ocd2"
}, {
- "type": "ocd",
- "file": "STCharacters.ocd"
+ "type": "ocd2",
+ "file": "STCharacters.ocd2"
}]
}
}, {
"dict": {
- "type": "group",
- "dicts": [{
- "type": "ocd",
- "file": "HKVariantsPhrases.ocd"
- }, {
- "type": "ocd",
- "file": "HKVariants.ocd"
- }]
+ "type": "ocd2",
+ "file": "HKVariants.ocd2"
}
}]
}
diff --git a/data/config/s2t.json b/data/config/s2t.json
index de1fad2c9..87516acbd 100644
--- a/data/config/s2t.json
+++ b/data/config/s2t.json
@@ -3,19 +3,19 @@
"segmentation": {
"type": "mmseg",
"dict": {
- "type": "ocd",
- "file": "STPhrases.ocd"
+ "type": "ocd2",
+ "file": "STPhrases.ocd2"
}
},
"conversion_chain": [{
"dict": {
"type": "group",
"dicts": [{
- "type": "ocd",
- "file": "STPhrases.ocd"
+ "type": "ocd2",
+ "file": "STPhrases.ocd2"
}, {
- "type": "ocd",
- "file": "STCharacters.ocd"
+ "type": "ocd2",
+ "file": "STCharacters.ocd2"
}]
}
}]
diff --git a/data/config/s2tw.json b/data/config/s2tw.json
index 5fc6afe14..2a3d7656b 100644
--- a/data/config/s2tw.json
+++ b/data/config/s2tw.json
@@ -3,25 +3,25 @@
"segmentation": {
"type": "mmseg",
"dict": {
- "type": "ocd",
- "file": "STPhrases.ocd"
+ "type": "ocd2",
+ "file": "STPhrases.ocd2"
}
},
"conversion_chain": [{
"dict": {
"type": "group",
"dicts": [{
- "type": "ocd",
- "file": "STPhrases.ocd"
+ "type": "ocd2",
+ "file": "STPhrases.ocd2"
}, {
- "type": "ocd",
- "file": "STCharacters.ocd"
+ "type": "ocd2",
+ "file": "STCharacters.ocd2"
}]
}
}, {
"dict": {
- "type": "ocd",
- "file": "TWVariants.ocd"
+ "type": "ocd2",
+ "file": "TWVariants.ocd2"
}
}]
}
diff --git a/data/config/s2twp.json b/data/config/s2twp.json
index 6a7f881ad..2f36e9352 100644
--- a/data/config/s2twp.json
+++ b/data/config/s2twp.json
@@ -3,30 +3,30 @@
"segmentation": {
"type": "mmseg",
"dict": {
- "type": "ocd",
- "file": "STPhrases.ocd"
+ "type": "ocd2",
+ "file": "STPhrases.ocd2"
}
},
"conversion_chain": [{
"dict": {
"type": "group",
"dicts": [{
- "type": "ocd",
- "file": "STPhrases.ocd"
+ "type": "ocd2",
+ "file": "STPhrases.ocd2"
}, {
- "type": "ocd",
- "file": "STCharacters.ocd"
+ "type": "ocd2",
+ "file": "STCharacters.ocd2"
}]
}
}, {
"dict": {
- "type": "ocd",
- "file": "TWPhrases.ocd"
+ "type": "ocd2",
+ "file": "TWPhrases.ocd2"
}
}, {
"dict": {
- "type": "ocd",
- "file": "TWVariants.ocd"
+ "type": "ocd2",
+ "file": "TWVariants.ocd2"
}
}]
}
diff --git a/data/config/t2hk.json b/data/config/t2hk.json
index d657861f8..519d4a3fd 100644
--- a/data/config/t2hk.json
+++ b/data/config/t2hk.json
@@ -1,16 +1,16 @@
{
- "name": "Traditional Chinese to Traditional Chinese (Hong Kong standard)",
+ "name": "Traditional Chinese to Traditional Chinese (Hong Kong variant)",
"segmentation": {
"type": "mmseg",
"dict": {
- "type": "ocd",
- "file": "HKVariants.ocd"
+ "type": "ocd2",
+ "file": "HKVariants.ocd2"
}
},
"conversion_chain": [{
"dict": {
- "type": "ocd",
- "file": "HKVariants.ocd"
+ "type": "ocd2",
+ "file": "HKVariants.ocd2"
}
}]
}
diff --git a/data/config/t2jp.json b/data/config/t2jp.json
new file mode 100644
index 000000000..7a43217ff
--- /dev/null
+++ b/data/config/t2jp.json
@@ -0,0 +1,16 @@
+{
+ "name": "Traditional Chinese Characters (Kyūjitai) to New Japanese Kanji (Shinjitai)",
+ "segmentation": {
+ "type": "mmseg",
+ "dict": {
+ "type": "ocd2",
+ "file": "JPVariants.ocd2"
+ }
+ },
+ "conversion_chain": [{
+ "dict": {
+ "type": "ocd2",
+ "file": "JPVariants.ocd2"
+ }
+ }]
+}
diff --git a/data/config/t2s.json b/data/config/t2s.json
index 21ba6e406..06cf5f58e 100644
--- a/data/config/t2s.json
+++ b/data/config/t2s.json
@@ -3,19 +3,19 @@
"segmentation": {
"type": "mmseg",
"dict": {
- "type": "ocd",
- "file": "TSPhrases.ocd"
+ "type": "ocd2",
+ "file": "TSPhrases.ocd2"
}
},
"conversion_chain": [{
"dict": {
"type": "group",
"dicts": [{
- "type": "ocd",
- "file": "TSPhrases.ocd"
+ "type": "ocd2",
+ "file": "TSPhrases.ocd2"
}, {
- "type": "ocd",
- "file": "TSCharacters.ocd"
+ "type": "ocd2",
+ "file": "TSCharacters.ocd2"
}]
}
}]
diff --git a/data/config/t2tw.json b/data/config/t2tw.json
index a0c7ae1f1..0394f600d 100644
--- a/data/config/t2tw.json
+++ b/data/config/t2tw.json
@@ -3,14 +3,14 @@
"segmentation": {
"type": "mmseg",
"dict": {
- "type": "ocd",
- "file": "TWVariants.ocd"
+ "type": "ocd2",
+ "file": "TWVariants.ocd2"
}
},
"conversion_chain": [{
"dict": {
- "type": "ocd",
- "file": "TWVariants.ocd"
+ "type": "ocd2",
+ "file": "TWVariants.ocd2"
}
}]
}
diff --git a/data/config/tw2s.json b/data/config/tw2s.json
index 7c772e769..4f554393e 100644
--- a/data/config/tw2s.json
+++ b/data/config/tw2s.json
@@ -3,30 +3,30 @@
"segmentation": {
"type": "mmseg",
"dict": {
- "type": "ocd",
- "file": "TSPhrases.ocd"
+ "type": "ocd2",
+ "file": "TSPhrases.ocd2"
}
},
"conversion_chain": [{
"dict": {
"type": "group",
"dicts": [{
- "type": "ocd",
- "file": "TWVariantsRevPhrases.ocd"
+ "type": "ocd2",
+ "file": "TWVariantsRevPhrases.ocd2"
}, {
- "type": "ocd",
- "file": "TWVariantsRev.ocd"
+ "type": "ocd2",
+ "file": "TWVariantsRev.ocd2"
}]
}
}, {
"dict": {
"type": "group",
"dicts": [{
- "type": "ocd",
- "file": "TSPhrases.ocd"
+ "type": "ocd2",
+ "file": "TSPhrases.ocd2"
}, {
- "type": "ocd",
- "file": "TSCharacters.ocd"
+ "type": "ocd2",
+ "file": "TSCharacters.ocd2"
}]
}
}]
diff --git a/data/config/tw2sp.json b/data/config/tw2sp.json
index 86078fe4d..64eb9d977 100644
--- a/data/config/tw2sp.json
+++ b/data/config/tw2sp.json
@@ -3,35 +3,33 @@
"segmentation": {
"type": "mmseg",
"dict": {
- "type": "ocd",
- "file": "TSPhrases.ocd"
+ "type": "ocd2",
+ "file": "TSPhrases.ocd2"
}
},
"conversion_chain": [{
"dict": {
"type": "group",
"dicts": [{
- "type": "ocd",
- "file": "TWVariantsRevPhrases.ocd"
+ "type": "ocd2",
+ "file": "TWPhrasesRev.ocd2"
}, {
- "type": "ocd",
- "file": "TWVariantsRev.ocd"
+ "type": "ocd2",
+ "file": "TWVariantsRevPhrases.ocd2"
+ }, {
+ "type": "ocd2",
+ "file": "TWVariantsRev.ocd2"
}]
}
- }, {
- "dict": {
- "type": "ocd",
- "file": "TWPhrasesRev.ocd"
- }
}, {
"dict": {
"type": "group",
"dicts": [{
- "type": "ocd",
- "file": "TSPhrases.ocd"
+ "type": "ocd2",
+ "file": "TSPhrases.ocd2"
}, {
- "type": "ocd",
- "file": "TSCharacters.ocd"
+ "type": "ocd2",
+ "file": "TSCharacters.ocd2"
}]
}
}]
diff --git a/data/config/tw2t.json b/data/config/tw2t.json
new file mode 100644
index 000000000..ad5295b65
--- /dev/null
+++ b/data/config/tw2t.json
@@ -0,0 +1,22 @@
+{
+ "name": "Traditional Chinese (Taiwan standard) to Traditional Chinese",
+ "segmentation": {
+ "type": "mmseg",
+ "dict": {
+ "type": "ocd2",
+ "file": "TWVariantsRevPhrases.ocd2"
+ }
+ },
+ "conversion_chain": [{
+ "dict": {
+ "type": "group",
+ "dicts": [{
+ "type": "ocd2",
+ "file": "TWVariantsRevPhrases.ocd2"
+ }, {
+ "type": "ocd2",
+ "file": "TWVariantsRev.ocd2"
+ }]
+ }
+ }]
+}
diff --git a/data/dictionary/BUILD.bazel b/data/dictionary/BUILD.bazel
new file mode 100644
index 000000000..3a1f1aa0a
--- /dev/null
+++ b/data/dictionary/BUILD.bazel
@@ -0,0 +1,79 @@
+package(default_visibility = ["//visibility:public"])
+
+genrule(
+ name = "merge_TWPhrases",
+ srcs = [
+ "TWPhrasesIT.txt",
+ "TWPhrasesName.txt",
+ "TWPhrasesOther.txt",
+ ],
+ outs = ["TWPhrases.txt"],
+ cmd = "$(location //data/scripts:merge) " +
+ "$(SRCS) $(OUTS)",
+ tools = ["//data/scripts:merge"],
+)
+
+[
+ genrule(
+ name = "reverse_" + txt,
+ srcs = [txt + ".txt"],
+ outs = [txt + "Rev.txt"],
+ cmd = "$(location //data/scripts:reverse) " +
+ "$(SRCS) $(OUTS)",
+ tools = ["//data/scripts:reverse"],
+ )
+ for txt in [
+ "TWVariants",
+ "TWPhrases",
+ "HKVariants",
+ "JPVariants",
+ ]
+]
+
+TEXT_DICTS = glob(["*.txt"]) + [
+ "TWPhrases.txt",
+ "TWVariantsRev.txt",
+ "TWPhrasesRev.txt",
+ "HKVariantsRev.txt",
+ "JPVariantsRev.txt",
+]
+
+[
+ genrule(
+ name = "generate_bin_" + txt[:-4],
+ srcs = [txt],
+ outs = [txt.replace(".txt", ".ocd2")],
+ cmd = "$(location //src/tools:dict_converter) " +
+ "--input $(location " + txt + ") " +
+ "--output $(OUTS) " +
+ "--from text " +
+ "--to ocd2",
+ tools = ["//src/tools:dict_converter"],
+ )
+ for txt in TEXT_DICTS
+]
+
+filegroup(
+ name = "text_dictionaries",
+ srcs = TEXT_DICTS,
+)
+
+filegroup(
+ name = "binary_dictionaries",
+ srcs = [txt.replace(".txt", ".ocd2") for txt in TEXT_DICTS],
+)
+
+cc_test(
+ name = "dictionary_test",
+ srcs = ["DictionaryTest.cpp"],
+ data = [
+ ":binary_dictionaries",
+ ":text_dictionaries",
+ ],
+ deps = [
+ "//src:lexicon",
+ "//src:marisa_dict",
+ "//src:utf8_util",
+ "@googletest//:gtest_main",
+ ],
+)
diff --git a/data/dictionary/DictionaryTest.cpp b/data/dictionary/DictionaryTest.cpp
new file mode 100644
index 000000000..7b931c722
--- /dev/null
+++ b/data/dictionary/DictionaryTest.cpp
@@ -0,0 +1,90 @@
+/*
+ * Open Chinese Convert
+ *
+ * Copyright 2024-2024 Carbo Kuo
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "gtest/gtest.h"
+
+#include "src/Lexicon.hpp"
+#include "src/MarisaDict.hpp"
+#include "src/UTF8Util.hpp"
+
+namespace opencc {
+
+const char* RUNFILE_SUFFIX = ".runfiles/_main";
+
+class DictionaryTest : public ::testing::Test,
+ public ::testing::WithParamInterface {
+protected:
+ static void SetUpTestSuite() {
+
+ std::string program_filename = ::testing::internal::GetArgvs().front();
+ size_t suffix_pos = program_filename.find(RUNFILE_SUFFIX);
+ ASSERT_NE(suffix_pos, std::string::npos);
+
+ runfile_dir_ =
+ program_filename.substr(0, suffix_pos + strlen(RUNFILE_SUFFIX));
+ }
+
+ static std::string runfile_dir_;
+};
+
+std::string DictionaryTest::runfile_dir_;
+
+INSTANTIATE_TEST_SUITE_P(
+ , DictionaryTest,
+ ::testing::Values("HKVariants", "HKVariantsRevPhrases",
+ "JPShinjitaiCharacters", "JPShinjitaiPhrases",
+ "JPVariants", "STCharacters", "STPhrases", "TSCharacters",
+ "TSPhrases", "TWPhrasesIT", "TWPhrasesName",
+ "TWPhrasesOther", "TWVariants", "TWVariantsRevPhrases",
+ "TWPhrases", "TWVariantsRev", "TWPhrasesRev",
+ "HKVariantsRev", "JPVariantsRev"),
+ [](const testing::TestParamInfo& info) {
+ return info.param;
+ });
+
+TEST_P(DictionaryTest, UniqueSortedTest) {
+ const std::string dictionaryFileName =
+ runfile_dir_ + "/data/dictionary/" + GetParam() + ".txt";
+ FILE* fp =
+ fopen(UTF8Util::GetPlatformString(dictionaryFileName).c_str(), "rb");
+ ASSERT_NE(fp, nullptr);
+ LexiconPtr lexicon = Lexicon::ParseLexiconFromFile(fp);
+ EXPECT_TRUE(lexicon->IsUnique()) << GetParam() << " has duplicated keys.";
+ EXPECT_TRUE(lexicon->IsSorted()) << GetParam() << " is not sorted.";
+}
+
+TEST_P(DictionaryTest, BinaryTest) {
+ const std::string binaryDictionaryFileName =
+ runfile_dir_ + "/data/dictionary/" + GetParam() + ".ocd2";
+ FILE* fp_bin = fopen(
+ UTF8Util::GetPlatformString(binaryDictionaryFileName).c_str(), "rb");
+ ASSERT_NE(fp_bin, nullptr);
+ MarisaDictPtr dict = MarisaDict::NewFromFile(fp_bin);
+ ASSERT_NE(dict, nullptr);
+
+ const std::string textDictionaryFileName =
+ runfile_dir_ + "/data/dictionary/" + GetParam() + ".txt";
+ FILE* fp_txt =
+ fopen(UTF8Util::GetPlatformString(textDictionaryFileName).c_str(), "rb");
+ ASSERT_NE(fp_txt, nullptr);
+ LexiconPtr txt_lexicon = Lexicon::ParseLexiconFromFile(fp_txt);
+
+ EXPECT_EQ(dict->GetLexicon()->Length(), txt_lexicon->Length());
+}
+
+} // namespace opencc
diff --git a/data/dictionary/HKVariants.txt b/data/dictionary/HKVariants.txt
index 2660bca59..e0f688135 100644
--- a/data/dictionary/HKVariants.txt
+++ b/data/dictionary/HKVariants.txt
@@ -1,18 +1,13 @@
僞 偽
兌 兑
-冑 胄
-冗 宂
-勳 勛
叄 叁
-啓 啟
-嘆 歎
+只 只 衹
+啓 啓 啟
+喫 吃
囪 囱
-妝 粧
+妝 妝 粧
媼 媪
-嫋 裊
-嫺 嫻
嬀 媯
-岩 巖
悅 悦
慍 愠
戶 户
@@ -20,14 +15,13 @@
搵 揾
擡 抬
敓 敚
-敘 敍
+敘 敍 敘
柺 枴
梲 棁
-棱 稜
+棱 稜 棱
榲 榅
檯 枱
氳 氲
-涌 湧
涗 涚
溫 温
溼 濕
@@ -35,15 +29,15 @@
潨 潀
熅 煴
爲 為
-痹 痺
癡 痴
皁 皂
+祕 秘
稅 税
竈 灶
-糉 粽
+糉 粽 糉 糭
縕 緼
-繮 韁
纔 才
+脣 唇
脫 脱
膃 腽
臥 卧
@@ -58,13 +52,12 @@
衛 衞
覈 核
說 説
-贗 贋
踊 踴
轀 輼
醞 醖
鉢 缽
鉤 鈎
銳 鋭
+鍼 針
閱 閲
鰮 鰛
-鱉 鼈
diff --git a/data/dictionary/HKVariantsPhrases.txt b/data/dictionary/HKVariantsPhrases.txt
deleted file mode 100644
index f73f0a27d..000000000
--- a/data/dictionary/HKVariantsPhrases.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-南涌 南涌
-大欖涌 大欖涌
-大涌 大涌
-東涌 東涌
-沙河涌 沙河涌
-沙魚涌 沙魚涌
-河涌 河涌
-泥涌 泥涌
-涌尾 涌尾
-深涌 深涌
-溪涌 溪涌
-葵涌 葵涌
-蠔涌 蠔涌
-西涌 西涌
-鰂魚涌 鰂魚涌
-麻涌 麻涌
-黎涌 黎涌
diff --git a/data/dictionary/HKVariantsRevPhrases.txt b/data/dictionary/HKVariantsRevPhrases.txt
index b8a1dc1dc..3f03fd897 100644
--- a/data/dictionary/HKVariantsRevPhrases.txt
+++ b/data/dictionary/HKVariantsRevPhrases.txt
@@ -1,3 +1,9 @@
+一口吃個 一口喫個
+一口吃成 一口喫成
+一家三口 一家三口
+一家五口 一家五口
+一家六口 一家六口
+一家四口 一家四口
七星巖 七星巖
世胄 世胄
介胄 介冑
@@ -7,10 +13,16 @@
千巖競秀 千巖競秀
千巖萬壑 千巖萬壑
千巖萬谷 千巖萬谷
+口吃 口吃
台山 台山
台州 台州
台州地區 台州地區
台州市 台州市
+吃口 喫口 吃口
+吃口令 吃口令
+吃口飯 喫口飯
+吃吃 喫喫 吃吃
+吃子 喫子 吃子
名胄 名胄
國胄 國胄
圍巖 圍巖
@@ -55,6 +67,7 @@
帝胄 帝胄
幽巖 幽巖
幽棲巖谷 幽棲巖谷
+張口 張口
懸巖 懸巖
懸巖峭壁 懸巖峭壁
懸胄 懸冑
@@ -84,6 +97,7 @@
絕巖 絕巖
緒胄 緒胄
纂胄 纂胄
+胃口 胃口
胄嗣 胄嗣
胄子 胄子
胄序 胄序
@@ -109,17 +123,20 @@
貝胄 貝冑
貴胄 貴胄
賢胄 賢胄
+蹇吃 蹇吃
躬擐甲胄 躬擐甲冑
遐胄 遐胄
遙胄 遙胄
遙遙華胄 遙遙華胄
遠胄 遠胄
遺胄 遺胄
+鄧艾吃 鄧艾吃
重巖疊嶂 重巖疊嶂
金胄 金胄
鎧胄 鎧冑
鑿巖 鑿巖
門胄 門胄
+開口 開口
雲巖區 雲巖區
非層巖 非層巖
韓侂胄 韓侂冑
diff --git a/data/dictionary/JPShinjitaiCharacters.txt b/data/dictionary/JPShinjitaiCharacters.txt
new file mode 100644
index 000000000..30220aa35
--- /dev/null
+++ b/data/dictionary/JPShinjitaiCharacters.txt
@@ -0,0 +1,7 @@
+両 兩 輛
+弁 辨 辯 瓣 辦 弁
+御 御 禦
+欠 缺 欠
+浜 濱 浜
+糸 絲 糸
+芸 藝 芸
diff --git a/data/dictionary/JPShinjitaiPhrases.txt b/data/dictionary/JPShinjitaiPhrases.txt
new file mode 100644
index 000000000..3a85c8867
--- /dev/null
+++ b/data/dictionary/JPShinjitaiPhrases.txt
@@ -0,0 +1,176 @@
+一獲千金 一攫千金
+丁寧 叮嚀
+丁重 鄭重
+三差路 三叉路
+世論 輿論
+亜鈴 啞鈴
+交差 交叉
+供宴 饗宴
+俊馬 駿馬
+保塁 堡壘
+個条書 箇条書
+偏平 扁平
+停泊 碇泊
+優俊 優駿
+先兵 尖兵
+先鋭 尖鋭
+共役 共軛
+冗舌 饒舌
+凶器 兇器
+削岩 鑿岩
+包丁 庖丁
+包帯 繃帯
+区画 區劃
+厳然 儼然
+友宜 友誼
+反乱 叛乱
+収集 蒐集
+叙情 抒情
+台頭 擡頭
+合弁 合辦
+喜遊曲 嬉遊曲
+嘆願 歎願
+回転 廻転
+回遊 回游
+奉持 捧持
+委縮 萎縮
+展転 輾轉
+希少 稀少
+幻惑 眩惑
+広範 廣汎
+広野 曠野
+廃虚 廢墟
+建坪率 建蔽率
+弁当 辨當
+弁膜 瓣膜
+弁護 辯護
+弁髪 辮髮
+弦歌 絃歌
+恩義 恩誼
+意向 意嚮
+慰謝料 慰藉料
+憶断 臆断
+憶病 臆病
+戦没 戰歿
+扇情 煽情
+手帳 手帖
+技量 伎倆
+抜粋 抜萃
+披歴 披瀝
+抵触 牴触
+抽選 抽籤
+拘引 勾引
+拠出 醵出
+拠金 醵金
+掘削 掘鑿
+控除 扣除
+援護 掩護
+放棄 抛棄
+散水 撒水
+敬謙 敬虔
+敷延 敷衍
+断固 断乎
+族生 簇生
+昇叙 陞敘
+暖房 煖房
+暗唱 暗誦
+暗夜 闇夜
+暴露 曝露
+枯渇 涸渇
+格好 恰好
+格幅 恰幅
+棄損 毀損
+模索 摸索
+橋頭保 橋頭堡
+欠缺 欠缺
+死体 屍體
+殿部 臀部
+母指 拇指
+気迫 気魄
+決別 訣別
+決壊 決潰
+沈殿 沈澱
+油送船 油槽船
+波乱 波瀾
+注釈 註釋
+洗浄 洗滌 洗浄
+活発 活潑
+浸透 滲透
+浸食 浸蝕
+消却 銷卻
+混然 渾然
+湾曲 彎曲
+溶接 熔接
+漁労 漁撈
+漂然 飄然
+激高 激昂
+火炎 火焰
+焦燥 焦躁
+班点 斑点
+留飲 溜飲
+略奪 掠奪
+疎通 疏通
+発酵 醱酵
+白亜 白堊
+相克 相剋
+知恵 智慧
+破棄 破毀
+確固 確乎
+禁固 禁錮
+符丁 符牒
+粉装 扮装
+紫班 紫斑
+終息 終熄
+総合 綜合
+編集 編輯
+義援 義捐
+耕運機 耕耘機
+肝心 肝腎
+肩甲骨 肩胛骨
+背徳 悖德
+脈拍 脈搏
+膨張 膨脹
+芳純 芳醇
+英知 叡智
+蒸留 蒸溜
+薫蒸 燻蒸
+薫製 燻製
+衣装 衣裳
+衰退 衰退 衰頽
+裕然 悠然
+補佐 輔佐
+訓戒 訓誡
+試練 試煉
+詭弁 詭辯
+講和 媾和
+象眼 象嵌
+貫録 貫禄
+買弁 買辦
+賛辞 讚辭
+踏襲 蹈襲
+車両 車輛
+転倒 顛倒
+輪郭 輪廓
+退色 褪色
+途絶 杜絶
+連係 連繫
+連合 聯合
+選考 銓衡
+酢酸 醋酸
+野卑 野鄙
+鉱石 礦石
+間欠 間歇
+関数 函數
+防御 防禦
+険阻 嶮岨
+障壁 牆壁
+障害 障礙
+隠滅 湮滅
+集落 聚落
+雇用 雇傭
+風諭 諷喩
+飛語 蜚語
+香典 香奠
+骨格 骨骼
+高進 亢進
+鳥観 鳥瞰
diff --git a/data/dictionary/JPVariants.txt b/data/dictionary/JPVariants.txt
index 5cf425786..0d9a7427d 100644
--- a/data/dictionary/JPVariants.txt
+++ b/data/dictionary/JPVariants.txt
@@ -4,14 +4,16 @@
亞 亜
佛 仏
來 来
-倂 併
假 仮
傳 伝
僞 偽
價 価
儉 倹
兒 児
+內 内
兩 両
+冰 氷
+剎 刹
剩 剰
劍 剣
劑 剤
@@ -19,12 +21,16 @@
勳 勲
勵 励
勸 勧
+勻 匀
區 区
卷 巻
-卽 即
+卻 却
參 参
+吳 呉
+咒 呪
啞 唖
單 単
+噓 嘘
嚙 噛
嚴 厳
囑 嘱
@@ -45,6 +51,7 @@
壽 寿
奧 奥
奬 奨
+妝 粧
孃 嬢
學 学
寢 寝
@@ -56,35 +63,37 @@
專 専
對 対
屆 届
-屛 屏
屬 属
+峯 峰
峽 峡
嶽 岳
巖 巌
巢 巣
帶 帯
-幷 并
+廁 厠
廢 廃
廣 広
廳 庁
彈 弾
彌 弥
彎 弯
+彥 彦
徑 径
從 従
徵 徴
德 徳
恆 恒
+悅 悦
惠 恵
惡 悪
惱 悩
-愼 慎
慘 惨
應 応
懷 懐
戀 恋
戰 戦
戲 戯
+戶 戸
戾 戻
拂 払
拔 抜
@@ -95,31 +104,35 @@
搔 掻
搖 揺
搜 捜
+摑 掴
擇 択
擊 撃
擔 担
據 拠
-擧 挙
擴 拡
攝 摂
攪 撹
收 収
效 効
-敍 叙
敕 勅
+敘 叙
數 数
斷 断
+晉 晋
晚 晩
晝 昼
+暨 曁
曆 暦
曉 暁
曾 曽
會 会
枡 桝
+查 査
條 条
棧 桟
+棱 稜 棱
+榆 楡
榮 栄
-槪 概
樂 楽
樓 楼
樞 枢
@@ -131,6 +144,7 @@
歐 欧
歡 歓
步 歩
+歲 歳
歷 歴
歸 帰
殘 残
@@ -138,6 +152,8 @@
毆 殴
每 毎
氣 気
+污 汚
+沒 没
涉 渉
淚 涙
淨 浄
@@ -145,24 +161,28 @@
渴 渇
溪 渓
溫 温
+溼 湿
滯 滞
滿 満
+潑 溌
潛 潜
-澁 渋
+澀 渋
澤 沢
-濕 湿
濟 済
+濤 涛
濱 浜
濾 沪
瀧 滝
瀨 瀬
灣 湾
+焰 焔
燈 灯
燒 焼
營 営
爐 炉
爭 争
爲 為
+牀 床
犧 犠
狀 状
狹 狭
@@ -171,32 +191,38 @@
獸 獣
獻 献
瓣 弁
-甁 瓶
+產 産
畫 画
當 当
疊 畳
+疎 疏
+痹 痺
瘦 痩
癡 痴
發 発
+皋 皐
盜 盗
盡 尽
-眞 真
-硏 研
碎 砕
+礪 砺
祕 秘
祿 禄
+禦 御
禪 禅
禮 礼
禱 祷
+稅 税
稱 称
稻 稲
穎 頴
穗 穂
穩 穏
穰 穣
+竈 竃
竊 窃
-竝 並
粹 粋
+糉 粽
+絕 絶
絲 糸
經 経
綠 緑
@@ -208,24 +234,38 @@
繡 繍
繩 縄
繪 絵
+繫 繋
繼 継
續 続
+纔 才
纖 繊
缺 欠
罐 缶
+羣 群
+聯 連
+聰 聡
聲 声
聽 聴
肅 粛
+脣 唇
+脫 脱
腦 脳
+腳 脚
膽 胆
臟 臓
臺 台
與 与
+舉 挙
舊 旧
-莊 荘
+舍 舎
+荔 茘
+莊 荘 庄
莖 茎
+菸 煙
+萊 莱
萬 万
蔣 蒋
+蔥 葱
薰 薫
藏 蔵
藝 芸
@@ -239,13 +279,12 @@
蠟 蝋
蠶 蚕
蠻 蛮
-衞 衛
裝 装
-襃 褒
覺 覚
覽 覧
觀 観
觸 触
+說 説
謠 謡
證 証
譯 訳
@@ -255,33 +294,39 @@
讓 譲
豐 豊
豫 予
+貓 猫
貳 弐
賣 売
賴 頼
贊 賛
+贗 贋
踐 践
輕 軽
+輛 輌
轉 転
辨 弁
辭 辞
辯 弁
遞 逓
+遥 遙
遲 遅
邊 辺
-郞 郎
-鄕 郷
+鄉 郷
+酢 醋
醉 酔
醫 医
醬 醤
+醱 醗
釀 醸
釋 釈
+鋪 舗
錄 録
錢 銭
鍊 錬
-鎭 鎮
鐵 鉄
鑄 鋳
鑛 鉱
+閱 閲
關 関
陷 陥
隨 随
@@ -289,11 +334,12 @@
隱 隠
雙 双
雜 雑
+雞 鶏
霸 覇
靈 霊
靜 静
+顏 顔
顯 顕
-飜 翻
餘 余
騷 騒
驅 駆
@@ -302,14 +348,14 @@
髓 髄
體 体
髮 髪
-鬪 闘
-鷄 鶏
+鬥 闘
+鱉 鼈
鷗 鴎
鹼 鹸
鹽 塩
麥 麦
+麪 麺
麴 麹
-麵 麺
黃 黄
黑 黒
默 黙
@@ -320,69 +366,4 @@
齒 歯
齡 齢
龍 竜
-欄 欄
-廊 廊
-朗 朗
-虜 虜
-殺 殺
-類 類
-隆 隆
-塚 塚
-猪 猪
-神 神
-祥 祥
-福 福
-諸 諸
-都 都
-侮 侮
-僧 僧
-免 免
-勉 勉
-勤 勤
-卑 卑
-喝 喝
-嘆 嘆
-器 器
-塀 塀
-墨 墨
-層 層
-悔 悔
-慨 慨
-憎 憎
-懲 懲
-敏 敏
-暑 暑
-梅 梅
-海 海
-渚 渚
-漢 漢
-煮 煮
-琢 琢
-碑 碑
-社 社
-祉 祉
-祈 祈
-祐 祐
-祖 祖
-祝 祝
-禍 禍
-禎 禎
-穀 穀
-突 突
-節 節
-練 練
-繁 繁
-署 署
-者 者
-臭 臭
-著 著
-褐 褐
-視 視
-謁 謁
-謹 謹
-賓 賓
-贈 贈
-逸 逸
-難 難
-響 響
-頻 頻
+龜 亀
diff --git a/data/dictionary/STCharacters.txt b/data/dictionary/STCharacters.txt
index 6d9ff27d2..7347645ad 100644
--- a/data/dictionary/STCharacters.txt
+++ b/data/dictionary/STCharacters.txt
@@ -11,7 +11,6 @@
㔉 劚
㖊 噚
㖞 喎
-㗷 㘔
㘎 㘚
㚯 㜄
㛀 媰
@@ -133,8 +132,8 @@
䴕 鴷
䴖 鶄
䴗 鶪
-䴘 鷈 鷉
-䴙 鷿 鸊
+䴘 鷉
+䴙 鸊
䶮 龑
万 萬 万
与 與
@@ -272,7 +271,7 @@
减 減
凑 湊
凛 凜
-几 幾 几 機
+几 幾 几
凤 鳳
凫 鳧
凭 憑
@@ -367,6 +366,7 @@
叹 嘆 歎
叽 嘰
吁 籲 吁
+吃 喫 吃
合 合 閤
吊 吊 弔
同 同 衕
@@ -375,7 +375,6 @@
吓 嚇
吕 呂
吗 嗎
-吣 唚
吨 噸
听 聽
启 啓
@@ -411,7 +410,7 @@
哜 嚌
哝 噥
哟 喲
-唇 脣
+唇 脣 唇
唛 嘜
唝 嗊
唠 嘮
@@ -451,14 +450,12 @@
圣 聖
圹 壙
场 場
-坂 阪
坏 壞
-坐 坐 座
块 塊
坚 堅
坛 壇 罈
坜 壢
-坝 壩
+坝 壩 垻
坞 塢
坟 墳
坠 墜
@@ -477,7 +474,6 @@
埘 塒
埙 壎 塤
埚 堝
-埯 垵
堑 塹
堕 墮
塆 壪
@@ -534,6 +530,7 @@
学 學
孪 孿
宁 寧 甯
+它 它 牠
宝 寶
实 實
宠 寵
@@ -570,7 +567,6 @@
岖 嶇
岗 崗
岘 峴
-岙 嶴
岚 嵐
岛 島
岩 巖 岩
@@ -613,7 +609,6 @@
帻 幘
帼 幗
幂 冪
-幞 襆
干 幹 乾 干
并 並 併
幸 幸 倖
@@ -645,7 +640,6 @@
归 歸
当 當 噹
录 錄 彔
-彝 彝
彟 彠
彦 彥
彨 彲
@@ -713,7 +707,7 @@
戏 戲
戗 戧
战 戰
-戚 戚 慼 鏚
+戚 戚 慼
戬 戩
戯 戱
户 戶
@@ -737,7 +731,6 @@
抢 搶
护 護
报 報
-抬 擡
抵 抵 牴
担 擔
拐 拐 柺
@@ -804,7 +797,6 @@
擞 擻
攒 攢
敌 敵
-教 教
敚 敓
敛 斂
敩 斆
@@ -814,6 +806,7 @@
斗 鬥 斗
斩 斬
断 斷
+旋 旋 鏇
无 無
旧 舊
时 時
@@ -851,7 +844,7 @@
杩 榪
杯 杯 盃
杰 傑 杰
-松 鬆 松
+松 松 鬆
板 板 闆
极 極 极
构 構
@@ -866,7 +859,6 @@
枭 梟
柜 櫃 柜
柠 檸
-查 查
柽 檉
栀 梔
栅 柵
@@ -880,7 +872,7 @@
栏 欄
树 樹
栖 棲
-栗 慄 栗
+栗 栗 慄
样 樣
核 核 覈
栾 欒
@@ -895,15 +887,14 @@
桨 槳
桩 樁
桪 樳
-梁 樑 梁
+梁 梁 樑
梦 夢
梼 檮
梾 棶
梿 槤
检 檢
棁 梲
-棂 櫺 欞
-棱 棱
+棂 欞
椁 槨
椝 槼
椟 櫝
@@ -951,7 +942,7 @@
毙 斃
毡 氈
毵 毿
-毶 毿 𣯶
+毶 𣯶
氇 氌
气 氣
氢 氫
@@ -959,9 +950,9 @@
氲 氳
汇 匯 彙
汉 漢
-污 污
汤 湯
汹 洶
+沄 澐
沈 沈 瀋
沟 溝
没 沒
@@ -973,6 +964,7 @@
沨 渢
沩 潙
沪 滬
+沾 沾 霑
泛 泛 氾 汎
泞 濘
注 注 註
@@ -1006,7 +998,7 @@
浔 潯
浕 濜
涂 塗 涂
-涌 涌
+涌 湧 涌
涚 涗
涛 濤
涝 澇
@@ -1095,7 +1087,7 @@
焖 燜
焘 燾
煴 熅
-熏 薰 燻
+熏 燻 熏
爱 愛
爷 爺
牍 牘
@@ -1130,6 +1122,7 @@
玙 璵
玚 瑒
玛 瑪
+玩 玩 翫
玮 瑋
环 環
现 現
@@ -1146,6 +1139,7 @@
瑶 瑤
瑷 璦
瑸 璸
+璇 璇 璿
璎 瓔
瓒 瓚
瓮 甕
@@ -1258,7 +1252,6 @@
稣 穌
稳 穩
穑 穡
-穗 穗 繐
穞 穭
穷 窮
窃 竊
@@ -1317,7 +1310,6 @@
糍 餈
系 系 係 繫
紧 緊
-累 累
絷 縶
緼 縕
縆 緪
@@ -1351,7 +1343,7 @@
纺 紡
纻 紵
纼 紖
-纽 紐 鈕
+纽 紐
纾 紓
线 線
绀 紺
@@ -1409,7 +1401,7 @@
维 維
绵 綿
绶 綬
-绷 繃 綳
+绷 繃 綳
绸 綢
绹 綯
绺 綹
@@ -1552,7 +1544,6 @@
芗 薌
芜 蕪
芦 蘆
-芲 芲 菕
芸 芸 蕓
苁 蓯
苇 葦
@@ -1563,7 +1554,6 @@
苎 苧
苏 蘇 甦 囌
苔 苔 薹
-苘 檾
苧 薴
苹 蘋 苹
范 範 范
@@ -1674,7 +1664,7 @@
蝇 蠅
蝈 蟈
蝉 蟬
-蝎 蠍
+蝎 蠍 蝎
蝼 螻
蝾 蠑
螀 螿
@@ -1958,6 +1948,7 @@
趸 躉
跃 躍
跄 蹌
+跖 蹠 跖
跞 躒
践 踐
跶 躂
@@ -1965,7 +1956,6 @@
跸 蹕
跹 躚
跻 躋
-踊 踊
踌 躊
踪 蹤
踬 躓
@@ -2228,7 +2218,7 @@
锌 鋅
锍 鋶
锎 鐦
-锏 鐗 鐧
+锏 鐧
锐 銳
锑 銻
锒 鋃
@@ -2253,7 +2243,7 @@
锥 錐
锦 錦
锧 鑕
-锨 杴 鍁
+锨 鍁
锩 錈
锪 鍃
锫 錇 鉳
@@ -2276,13 +2266,13 @@
锼 鎪
锽 鍠
锾 鍰
-锿 鎄 鑀
+锿 鎄
镀 鍍
镁 鎂
镂 鏤
镃 鎡
镄 鐨
-镅 鎇 鋂
+镅 鎇
镆 鏌
镇 鎮
镈 鎛
@@ -2675,7 +2665,7 @@
鲳 鯧
鲴 鯝
鲵 鯢
-鲶 鮎 鯰
+鲶 鯰
鲷 鯛
鲸 鯨
鲹 鰺
@@ -2686,7 +2676,7 @@
鲾 鰏
鲿 鱨
鳀 鯷
-鳁 鰮 鰛
+鳁 鰮
鳂 鰃
鳃 鰓
鳄 鱷
@@ -2781,7 +2771,7 @@
鹗 鶚
鹘 鶻
鹙 鶖
-鹚 鶿
+鹚 鷀
鹛 鶥
鹜 鶩
鹝 鷊
@@ -2823,9 +2813,7 @@
鼋 黿
鼌 鼂
鼍 鼉
-鼗 鞀
鼹 鼴
-齄 齇
齐 齊
齑 齏
齿 齒
@@ -2856,7 +2844,6 @@
𠇹 俓
𠉂 㒓
𠉗 𠏢
-𠊉 𣍐
𠋆 儭
𠚳 𠠎
𠛅 剾
@@ -2962,7 +2949,7 @@
𤊀 𤒎
𤊰 𤓩
𤋏 熡
-𤎺 㸇
+𤎺 𤓎
𤎻 𤑳
𤙯 𤛮
𤝢 𤢟
@@ -3039,7 +3026,6 @@
𦶟 爇
𦶻 𦾟
𦻕 蘟
-𦼖 檾
𧉐 𧕟
𧉞 䗿
𧌥 𧎈
@@ -3213,7 +3199,6 @@
𩽽 𩶱
𩽾 鮟
𩽿 𩶰
-𩾀 鮕
𩾁 鯄
𩾂 䲖
𩾃 鮸
@@ -3242,7 +3227,6 @@
𪉐 𪃍
𪉑 鷔
𪉒 𪄕
-𪉓 𪈼
𪉔 𪄆
𪉕 𪇳
𪎈 䴬
@@ -3250,7 +3234,6 @@
𪎊 麨
𪎋 䴴
𪎌 麳
-𪎍 𪋿
𪑅 䵳
𪔭 𪔵
𪚏 𪘀
@@ -3879,20 +3862,119 @@
𫠖 𩿅
𫠜 齯
𫢸 僤
+𫧃 𣍐
+𫧮 𪋿
+𫫇 噁
+𫬐 㘔
+𫭟 塸
+𫭢 埨
+𫭼 𡑍
𫮃 墠
𫰛 娙
+𫵷 㠣
𫶇 嵽
𫷷 廞
𫸩 彄
𬀩 暐
+𬀪 晛
+𬂩 梜
+𬃊 櫍
+𬇕 澫
+𬇙 浿
+𬇹 漍
+𬉼 熰
+𬊈 燖
+𬊤 燀
+𬍛 瓅
+𬍡 璗
+𬍤 璕
+𬒈 礐
+𬒗 𥗽
+𬕂 篢
+𬘓 紃
+𬘘 紞
+𬘡 絪
+𬘩 綎
+𬘫 綄
+𬘬 綪
+𬘭 綝
+𬘯 綧
+𬙂 縯
+𬙊 纆
+𬙋 纕
+𬜬 蔄
+𬜯 䓣
+𬞟 蘋
+𬟁 虉
+𬟽 蝀
+𬣙 訏
+𬣞 詝
+𬣡 諓
+𬣳 詪
+𬤇 諲
+𬤊 諟
+𬤝 譓
+𬨂 軝
+𬨎 輶
+𬩽 鄩
+𬪩 醲
+𬬩 釴
𬬭 錀
+𬬮 鋹
+𬬱 釿
+𬬸 鉥
+𬬹 鉮
𬬻 鑪
+𬬿 鉊
+𬭁 鉧
𬭊 𨧀
+𬭎 鋐
+𬭚 錞
𬭛 𨨏
+𬭤 鍭
+𬭩 鎓
+𬭬 鏏
+𬭭 鏚
+𬭯 䥕
𬭳 𨭎
𬭶 𨭆
+𬭸 鏻
+𬭼 鐩
+𬮱 闉
+𬮿 隑
+𬯀 隮
+𬯎 隤
+𬱖 頔
+𬱟 頠
+𬳵 駓
+𬳶 駉
+𬳽 駪
+𬳿 駼
+𬴂 騑
+𬴃 騞
+𬴊 驎
𬶋 鮈
𬶍 鮀
𬶏 鮠
+𬶐 鮡
𬶟 鯻
+𬶠 鰊
+𬶨 鱀
+𬶭 鰶
+𬶮 鱚
+𬷕 鵏
+𬸘 鶠
+𬸚 鸑
+𬸣 鶱
+𬸦 鷟
𬸪 鷭
+𬸯 鷿
+𬹼 齘
+𬺈 齮
+𬺓 齼
+𰬸 繐
+𰰨 菕
+𰶎 譅
+𰾄 鋂
+𰾭 鑀
+𱊜 𪈼
diff --git a/data/dictionary/STPhrases.txt b/data/dictionary/STPhrases.txt
index 28f14fd23..d4add2b11 100644
--- a/data/dictionary/STPhrases.txt
+++ b/data/dictionary/STPhrases.txt
@@ -13,6 +13,7 @@
一党 一黨
一冲性子 一沖性子
一准 一準
+一出 一齣 一出
一出剧 一齣劇
一出去 一出去
一出场 一出場
@@ -55,7 +56,7 @@
一同 一同
一向 一向
一周 一週
-一周天 一週天
+一周天 一周天
一周年 一週年
一周遭 一周遭
一哄 一鬨
@@ -268,7 +269,6 @@
丁一确二 丁一確二
丁丁冬冬 丁丁冬冬
丁丁当当 丁丁當當
-丁丁炒面 丁丁炒面
丁丑 丁丑
丁伯升 丁伯升
丁克 丁克
@@ -280,6 +280,7 @@
丁柏升 丁柏升
丁种 丁種
丁种维生素 丁種維生素
+丁里 丁里
丁铃当啷 丁鈴噹啷
丁零当啷 丁零當啷
丁鸿志 丁鴻志
@@ -295,6 +296,7 @@
七余 七餘
七八下里 七八下裏
七出 七出
+七出戏 七齣戲
七出祁山 七出祁山
七分钟 七分鐘
七划 七劃
@@ -343,6 +345,7 @@
七窍冒烟 七竅冒煙
七窍生烟 七竅生煙
七色板 七色板
+七里 七里
七里河 七里河
七里河区 七里河區
七里香 七里香
@@ -645,7 +648,7 @@
万里同风 萬里同風
万里封侯 萬里封侯
万里无云 萬里無雲
-万里春愁直 萬裏春愁直
+万里春愁直 萬里春愁直
万里晴空 萬里晴空
万里江山 萬里江山
万里迢迢 萬里迢迢
@@ -696,6 +699,7 @@
三冬 三冬
三冬两夏 三冬兩夏
三准 三準
+三出戏 三齣戲
三出祁山 三出祁山
三分钟 三分鐘
三只 三隻
@@ -807,6 +811,7 @@
三连胜 三連勝
三部合唱 三部合唱
三部曲 三部曲
+三里 三里
三里屯 三里屯
三里河 三里河
三针 三針
@@ -954,6 +959,7 @@
下里 下里
下里巴人 下里巴人
下面 下面 下麪
+下面条 下麪條
下面请看 下面請看
下风方向 下風方向
下马杯 下馬杯
@@ -1055,7 +1061,7 @@
不可胜言 不可勝言
不可胜计 不可勝計
不可胜记 不可勝記
-不吃烟火食 不吃煙火食
+不吃烟火食 不喫煙火食
不合 不合
不合体统 不合體統
不合作 不合作
@@ -1132,7 +1138,7 @@
不差毫发 不差毫髮
不干 不幹 不乾
不干不净 不乾不淨
-不干不淨吃了没病 不乾不淨吃了沒病
+不干不淨吃了没病 不乾不淨喫了沒病
不干了 不幹了
不干事 不幹事
不干他 不干他
@@ -1216,6 +1222,10 @@
不敢当 不敢當
不整合 不整合
不斗 不鬥
+不断发展 不斷發展
+不断发现 不斷發現
+不断发生 不斷發生
+不断发酵 不斷發酵
不断电系统 不斷電系統
不早了 不早了
不时之须 不時之須
@@ -1586,6 +1596,7 @@
东欧集团 東歐集團
东海捞针 東海撈針
东涂西抹 東塗西抹
+东涌 東涌
东淨里的砖儿 東淨裏的磚兒
东游 東遊
东窗事发 東窗事發
@@ -2087,6 +2098,7 @@
丹干 丹干
丹徒布衣 丹徒布衣
丹朱 丹朱
+丹棱 丹稜
丹药 丹藥
为中台 爲中颱
为了 爲了
@@ -2195,7 +2207,7 @@
乌兹别克共和国 烏茲別克共和國
乌兹别克斯坦 烏茲別克斯坦
乌兹别克族 烏茲別克族
-乌冬面 烏冬面
+乌冬面 烏冬麪
乌发 烏髮
乌合 烏合
乌合之众 烏合之衆
@@ -2219,7 +2231,7 @@
乌滋别克 烏滋別克
乌滋别克斯坦 烏滋別克斯坦
乌烟瘴气 烏煙瘴氣
-乌狗吃食白狗当灾 烏狗吃食白狗當災
+乌狗吃食白狗当灾 烏狗喫食白狗當災
乌苏 烏蘇
乌苏市 烏蘇市
乌苏拉 烏蘇拉
@@ -2252,8 +2264,11 @@
乐极悲生 樂極悲生
乐极生悲 樂極生悲
乐游原 樂遊原
+乐理 樂理
乐祸幸灾 樂禍幸災
乐透彩 樂透彩
+乐里 樂里
+乐里镇 樂里鎮
乐颠了馅 樂顛了餡
乒乓球台 乒乓球檯
乔修亚 喬修亞
@@ -2294,6 +2309,7 @@
九亿五千万 九億五千萬
九余 九餘
九冬 九冬
+九出戏 九齣戲
九出祁山 九出祁山
九分钟 九分鐘
九划 九劃
@@ -2343,10 +2359,11 @@
也对于 也對於
也念 也念
也斗了胆 也斗了膽
-也舍下 也舍下
+也舍下 也捨下
也须 也須
习于 習於
习惯于 習慣於
+习玩 習翫
习非胜是 習非勝是
乡党 鄉黨
乡党尚齿 鄉黨尚齒
@@ -2405,7 +2422,6 @@
买烟 買菸
买物历 買物歷
买臣复水 買臣覆水
-买进对冲 買進對沖
买闲钱 買閒錢
买面子 買面子
买风云雷雨 買風雲雷雨
@@ -2843,7 +2859,8 @@
于途 於途
于道泉 于道泉
于邑 於邑
-于都县 於都縣
+于都 于都
+于都县 于都縣
于里察 于里察
于野 於野
于阗 于闐
@@ -2868,6 +2885,7 @@
云中白鹤 雲中白鶴
云为 云爲
云乎 云乎
+云乐镇 雲樂鎮
云云 云云
云从龙风从虎 雲從龍風從虎
云仙杂记 雲仙雜記
@@ -2969,14 +2987,14 @@
云海 雲海
云消雨散 雲消雨散
云消雾散 雲消霧散
-云涌 雲涌
+云涌 雲湧
云涛 雲濤
云液 雲液
云淡风轻 雲淡風輕
云游 雲遊
云游四方 雲遊四方
-云溪 云溪
-云溪区 云溪區
+云溪 雲溪
+云溪区 雲溪區
云烟 雲煙
云烟过眼 雲煙過眼
云烟过眼录 雲煙過眼錄
@@ -3423,6 +3441,7 @@
什不闲 什不閒
什么 什麼
什叶派 什葉派
+什里店 什里店
什锦炒面 什錦炒麪
什锦面 什錦麪
什面 什面
@@ -3556,6 +3575,7 @@
代数几何 代數幾何
代数曲线 代數曲線
代数曲面 代數曲面
+代理 代理
代码表 代碼表
代签 代簽
代签人 代簽人
@@ -3664,6 +3684,8 @@
价值逻辑 價值邏輯
价值量 價值量
价单 價單
+价古 价古
+价川 价川
价差 價差
价廉物美 價廉物美
价格 價格
@@ -3724,9 +3746,10 @@
伊犁纵谷 伊犁縱谷
伊莱克斯 伊萊克斯
伊郁 伊鬱
+伊里其 伊里其
伊里奇 伊里奇
伊里布 伊里布
-伊里格瑞 伊裏格瑞
+伊里格瑞 伊里格瑞
伊面 伊麪
伍员鞭尸 伍員鞭屍
伍德合金 伍德合金
@@ -3807,7 +3830,7 @@
会占卜 會占卜
会发 會發
会合 會合
-会合周期 會合周期
+会合周期 會合週期
会合处 會合處
会合点 會合點
会吊 會弔
@@ -3843,8 +3866,8 @@
会计系 會計系
会议记录 會議記錄
会逢其适 會逢其適
-会里 會裏
-会里县 會裏縣
+会里 會里
+会里县 會里縣
会长团 會長團
会面 會面
会面处 會面處
@@ -3892,7 +3915,7 @@
传闻证据 傳聞證據
传颂千古 傳頌千古
伤了 傷了
-伤亡枕借 傷亡枕藉
+伤亡枕藉 傷亡枕藉
伤别 傷別
伤口发炎 傷口發炎
伤寒杆菌 傷寒桿菌
@@ -3902,6 +3925,8 @@
伤痕累累 傷痕累累
伤药 傷藥
伤风克 傷風克
+伦布雪 倫布雪
+伦理 倫理
伦理规范 倫理規範
伪托 僞託
伪药 僞藥
@@ -3941,7 +3966,7 @@
似松实紧 似鬆實緊
佃租制度 佃租制度
但云 但云
-但得一片橘皮吃且莫忘了洞庭湖 但得一片橘皮吃且莫忘了洞庭湖
+但得一片橘皮吃且莫忘了洞庭湖 但得一片橘皮喫且莫忘了洞庭湖
但愿 但願
但愿如此 但願如此
但曲 但曲
@@ -4100,6 +4125,7 @@
余悸 餘悸
余情 餘情
余情未了 餘情未了
+余慈高速 餘慈高速
余户 餘戶
余政宪 余政憲
余数 餘數
@@ -4287,6 +4313,7 @@
佳冬乡 佳冬鄉
佳肴 佳餚
佳致 佳致
+佳荣里 佳榮里
佳里 佳里
佳里鎮 佳里鎮
佳里镇 佳里鎮
@@ -4365,7 +4392,7 @@
侵蚀基准 侵蝕基準
便了 便了
便于 便於
-便吃干 便吃乾
+便吃干 便喫乾
便宜不过当家 便宜不過當家
便当 便當
便当店 便當店
@@ -4442,7 +4469,7 @@
信息系统 信息系統
信托 信託
信托公司 信託公司
-信托贸易 信托貿易
+信托贸易 信託貿易
信据 信據
信步闲游 信步閒遊
信汇 信匯
@@ -4510,8 +4537,8 @@
修曼德 修曼德
修杰楷 修杰楷
修枝 修枝
-修桥舖路 修橋舖路
修桥补路 修橋補路
+修桥铺路 修橋鋪路
修樾 脩樾
修正 修正
修正为 修正爲
@@ -5135,7 +5162,7 @@
光合作用 光合作用
光合细菌 光合細菌
光向 光向
-光周期 光周期
+光周期 光週期
光圈范围 光圈範圍
光复 光復
光复乡 光復鄉
@@ -5483,7 +5510,7 @@
党外 黨外
党外人士 黨外人士
党太尉 党太尉
-党太尉吃匾食 党太尉吃匾食
+党太尉吃匾食 党太尉喫匾食
党委 黨委
党委书记 黨委書記
党委会 黨委會
@@ -5652,6 +5679,7 @@
全面禁止核试验条约 全面禁止核試驗條約
全面规划 全面規劃
全面进行 全面進行
+兩出戏 兩齣戲
八万 八萬
八万一千 八萬一千
八万四千法门 八萬四千法門
@@ -5663,6 +5691,7 @@
八余 八餘
八克 八克
八军团 八軍團
+八出戏 八齣戲
八出祁山 八出祁山
八十天环游地球 八十天環遊地球
八十种好 八十種好
@@ -5782,6 +5811,7 @@
六余 六餘
六冲 六沖
六出奇计 六出奇計
+六出戏 六齣戲
六出祁山 六出祁山
六厂 六廠
六发 六發
@@ -5815,6 +5845,7 @@
六谷 六穀
六通四辟 六通四辟
六道轮回 六道輪迴
+六里 六里
六面 六面
六面体 六面體
六须鲇 六鬚鮎
@@ -5828,6 +5859,8 @@
兰叶撇 蘭葉撇
兰摧玉折 蘭摧玉折
兰摧蕙折 蘭摧蕙折
+兰棱 蘭棱
+兰溪 蘭谿
兰秋 蘭秋
兰艾同烬 蘭艾同燼
兰艾同焚 蘭艾同焚
@@ -6355,6 +6388,7 @@
冲帐 沖帳
冲年 沖年
冲床 衝牀
+冲床工 沖牀工
冲开 衝開
冲弱 沖弱
冲得入 衝得入
@@ -6403,7 +6437,6 @@
冲淡 沖淡
冲澡 沖澡
冲然 衝然
-冲牀工 沖牀工
冲犯 衝犯
冲田 沖田
冲盹 衝盹
@@ -6435,6 +6468,7 @@
冲自己 衝自己
冲至 衝至
冲茶 沖茶
+冲蒌 沖蔞
冲虚 沖虛
冲虚真人 沖虛真人
冲虚真经 沖虛真經
@@ -6921,7 +6955,7 @@
几点几 幾點幾
几点钟 幾點鐘
几版 幾版
-几率 機率
+几率 幾率
几环 幾環
几班 幾班
几番 幾番
@@ -6995,6 +7029,7 @@
几道 幾道
几道菜 幾道菜
几部 幾部
+几里 幾里
几针 幾針
几门 幾門
几间 幾間
@@ -7038,7 +7073,7 @@
凯特布兰琪 凱特布蘭琪
凯迪拉克 凱迪拉克
凯里 凱里
-凯里市 凱裏市
+凯里市 凱里市
凶事 凶事
凶人 兇人
凶仪 兇儀
@@ -7135,7 +7170,7 @@
出不起 出不起
出丑 出醜
出丑扬疾 出醜揚疾
-出丑狼借 出醜狼藉
+出丑狼藉 出醜狼藉
出世 出世
出世作 出世作
出世法 出世法
@@ -7316,7 +7351,7 @@
出宰 出宰
出家 出家
出家人 出家人
-出家人吃八方 出家人吃八方
+出家人吃八方 出家人喫八方
出将入相 出將入相
出小恭 出小恭
出尔反尔 出爾反爾
@@ -7356,7 +7391,7 @@
出恭 出恭
出息 出息
出意外 出意外
-出戏 齣戲
+出戏 出戲 齣戲
出战 出戰
出户 出戶
出手 出手
@@ -7784,7 +7819,7 @@
切当 切當
切菜板 切菜板
切除术 切除術
-切面 切面
+切面 切面 切麵
切骨之仇 切骨之仇
刊了 刊了
刊出 刊出
@@ -8126,7 +8161,7 @@
别当 別當
别得 別得
别忙 別忙
-别念 別念
+别念 別唸
别急 別急
别怪 別怪
别情 別情
@@ -8524,6 +8559,7 @@
制醣 制醣
制钟 制鐘
制钱 制錢
+制锦 製錦
制限 制限
制限选举 制限選舉
制陶 製陶
@@ -8834,6 +8870,7 @@
加拿大铝业集团 加拿大鋁業集團
加挂 加掛
加挂车厢 加掛車廂
+加斗 加斗
加杯 加杯
加杯水 加杯水
加氢精制 加氫精制
@@ -8845,14 +8882,13 @@
加荣耀于 加榮耀於
加药 加藥
加解密系统 加解密系統
-加达里 加達裏
+加达里 加達里
加速踏板 加速踏板
加里 加里
-加里宁 加裏寧
+加里宁 加里寧
加里宁格勒 加里寧格勒
-加里宁格勒州 加裏寧格勒州
-加里曼丹 加裏曼丹
-加里曼丹岛 加裏曼丹島
+加里宁格勒州 加里寧格勒州
+加里曼丹 加里曼丹
加里波的 加里波的
加里波第 加里波第
加里肋亚 加里肋亞
@@ -8882,6 +8918,7 @@
动配合 動配合
助于 助於
助恶 助惡
+助理 助理
助选团 助選團
努瓦克肖特 努瓦克肖特
劫余 劫餘
@@ -8894,6 +8931,7 @@
励志 勵志
励志书 勵志書
劲度系数 勁度係數
+劲松 勁松
劲秋 勁秋
劲舞团 勁舞團
劲骨丰肌 勁骨豐肌
@@ -9006,7 +9044,7 @@
化学工厂 化學工廠
化学弹药 化學彈藥
化学当量 化學當量
-化学战斗部 化學戰斗部
+化学战斗部 化學戰鬥部
化学系 化學系
化学纤维 化學纖維
化工厂 化工廠
@@ -9061,8 +9099,7 @@
北里 北里
北面 北面
北面称臣 北面稱臣
-北马里亚纳 北馬裏亞納
-北马里亚纳群岛 北馬裏亞納羣島
+北马里亚纳 北马里亞納
匙扣 匙扣
匡合 匡合
匡复 匡復
@@ -9481,6 +9518,7 @@
千鬼百怪 千鬼百怪
千鸟 千鳥
千鸟渊国家公墓 千鳥淵國家公墓
+卅里 卅里
升上 升上
升上去 升上去
升上来 升上來
@@ -9620,6 +9658,7 @@
半面 半面
半面之交 半面之交
半面之旧 半面之舊
+卌里 卌里
华东师范 華東師範
华东师范大学 華東師範大學
华严钟 華嚴鐘
@@ -9662,7 +9701,7 @@
单交种 單交種
单价 單價
单位价格 單位價格
-单位信托 單位信托
+单位信托 單位信託
单位切向量 單位切向量
单位制 單位制
单位向量 單位向量
@@ -9771,6 +9810,9 @@
南征北伐 南征北伐
南征北战 南征北戰
南征北讨 南征北討
+南斗 南斗
+南斗六星 南斗六星
+南斗星君 南斗星君
南方周末 南方週末
南无阿弥陀佛 南無阿彌陀佛
南曲 南曲
@@ -9793,6 +9835,7 @@
南汇 南匯
南汇区 南匯區
南洋模范 南洋模範
+南涌 南涌
南游 南遊
南特杰克 南特傑克
南筑 南筑
@@ -10256,7 +10299,6 @@
卷舌元音 捲舌元音
卷舌音 捲舌音
卷舒 卷舒
-卷舖盖 捲舖蓋
卷菸 捲菸
卷落叶 捲落葉
卷衣袖 捲衣袖
@@ -10521,7 +10563,7 @@
去向 去向
去向不明 去向不明
去干 去幹
-去念 去念
+去念 去唸
去恶从善 去惡從善
去搜 去搜
去暗投明 去暗投明
@@ -11030,7 +11072,7 @@
发悲 發悲
发悸 發悸
发情 發情
-发情周期 發情周期
+发情周期 發情週期
发情期 發情期
发想 發想
发愁 發愁
@@ -11087,6 +11129,7 @@
发散 發散
发文 發文
发文者 發文者
+发旋 髮旋
发明 發明
发明人 發明人
发明创造 發明創造
@@ -11265,6 +11308,7 @@
发粉 發粉
发糕 發糕
发紫 發紫
+发絲 髮絲
发红 發紅
发纱 髮紗
发绀 發紺
@@ -11427,6 +11471,7 @@
发长 髮長
发问 發問
发问者 發問者
+发间 髮間
发闷 發悶
发闹 發鬧
发阴天 發陰天
@@ -11449,6 +11494,8 @@
发音方法 發音方法
发音部位 發音部位
发音障碍 發音障礙
+发頂 髮頂
+发須 髮鬚
发须俱 髮鬚俱
发须已 髮鬚已
发须斑 髮鬚斑
@@ -11499,6 +11546,7 @@
取舍之间 取捨之間
取舍难定 取捨難定
取药 取藥
+取阳谷 取陽谷
受不了 受不了
受了 受了
受人之托 受人之託
@@ -11516,6 +11564,7 @@
受托人 受託人
受托者 受託者
受折磨 受折磨
+受理 受理
受用不尽 受用不盡
受聘于 受聘於
受阻于 受阻於
@@ -11577,6 +11626,7 @@
口出恶言 口出惡言
口出秽言 口出穢言
口占 口占
+口吃 口吃
口布 口布
口干 口乾
口干舌燥 口乾舌燥
@@ -11590,7 +11640,7 @@
口服药 口服藥
口杯 口杯
口燥唇干 口燥脣乾
-口燥脣干 口燥脣乾
+口腔里 口腔裏
口腹之欲 口腹之慾
口血未干 口血未乾
口语字词识别 口語字詞識別
@@ -11600,6 +11650,7 @@
口钟 口鐘
古书云 古書云
古云 古云
+古云镇 古雲鎮
古今注 古今注
古典艺术 古典藝術
古切里 古切里
@@ -11706,7 +11757,7 @@
只可在 只可在
只可意会不可言传 只可意會不可言傳
只叹 只嘆
-只吃 只吃
+只吃 只喫
只合 只合
只含 只含
只听 只聽
@@ -12221,14 +12272,14 @@
台子孙 臺子孫
台孙 臺孫
台孩 臺孩
-台安 檯安
-台安县 檯安縣
+台安 臺安 檯安
+台安县 臺安縣
台客 臺客
台客呛辣 臺客嗆辣
台客舞 臺客舞
台尺 臺尺
台山 台山
-台山市 臺山市
+台山市 台山市
台峪 臺峪
台州 台州
台州地区 台州地區
@@ -12693,59 +12744,60 @@
吁气 吁氣
吁求 籲求
吁请 籲請
-吃一顿挨一顿 吃一頓挨一頓
-吃不了 吃不了
-吃不出 吃不出
-吃不出来 吃不出來
-吃了 吃了
-吃了定心丸 吃了定心丸
-吃了秤砣 吃了秤砣
-吃了蜜蜂儿屎似的 吃了蜜蜂兒屎似的
-吃了饭 吃了飯
-吃亏上当 吃虧上當
-吃亏就是占便宜 吃虧就是佔便宜
-吃人一个蛋恩情无法断 吃人一個蛋恩情無法斷
-吃人虫 吃人蟲
-吃伤了 吃傷了
-吃几碗干饭 吃幾碗乾飯
-吃出 吃出
-吃合家欢 吃合家歡
-吃后悔药 吃後悔藥
-吃回头草 吃回頭草
-吃地面 吃地面
-吃姜 吃薑
-吃完面 吃完麪
-吃尽 吃盡
-吃尽当光 吃盡當光
-吃干了 吃乾了
-吃干醋 吃乾醋
-吃得了 吃得了
-吃得出 吃得出
-吃得出来 吃得出來
-吃挂络儿 吃掛絡兒
-吃敲才 吃敲才
-吃板刀面 吃板刀麪
-吃枪药 吃槍藥
-吃烟 吃煙
-吃药 吃藥
-吃药前 吃藥前
-吃药后 吃藥後
-吃药时 吃藥時
-吃豆干 吃豆乾
-吃辣面 吃辣麪
-吃过面 吃過麪
-吃里扒外 吃裏扒外
-吃里爬外 吃裏爬外
-吃钉板 吃釘板
-吃错药 吃錯藥
-吃闲话 吃閒話
-吃闲饭 吃閒飯
-吃面 吃麪
-吃饭傢伙 吃飯傢伙
-吃饭别忘了种谷人 吃飯別忘了種穀人
-吃饭家伙 吃飯家伙
-吃饱了饭撑的 吃飽了飯撐的
-吃饱没事干 吃飽沒事幹
+吃一顿挨一顿 喫一頓挨一頓
+吃不了 喫不了
+吃不出 喫不出
+吃不出来 喫不出來
+吃了 喫了
+吃了定心丸 喫了定心丸
+吃了秤砣 喫了秤砣
+吃了蜜蜂儿屎似的 喫了蜜蜂兒屎似的
+吃了饭 喫了飯
+吃亏上当 喫虧上當
+吃亏就是占便宜 喫虧就是佔便宜
+吃亏的是乖占便宜的是呆 喫虧的是乖占便宜的是呆
+吃人一个蛋恩情无法断 喫人一個蛋恩情無法斷
+吃人虫 喫人蟲
+吃伤了 喫傷了
+吃几碗干饭 喫幾碗乾飯
+吃出 喫出
+吃合家欢 喫合家歡
+吃后悔药 喫後悔藥
+吃回头草 喫回頭草
+吃地面 喫地面
+吃姜 喫薑
+吃完面 喫完麪
+吃尽 喫盡
+吃尽当光 喫盡當光
+吃干了 喫乾了
+吃干醋 喫乾醋
+吃得了 喫得了
+吃得出 喫得出
+吃得出来 喫得出來
+吃挂络儿 喫掛絡兒
+吃敲才 喫敲才
+吃板刀面 喫板刀麪
+吃枪药 喫槍藥
+吃烟 喫煙
+吃药 喫藥
+吃药前 喫藥前
+吃药后 喫藥後
+吃药时 喫藥時
+吃豆干 喫豆乾
+吃辣面 喫辣麪
+吃过面 喫過麪
+吃里扒外 喫裏扒外
+吃里爬外 喫裏爬外
+吃钉板 喫釘板
+吃错药 喫錯藥
+吃闲话 喫閒話
+吃闲饭 喫閒飯
+吃面 喫麪
+吃饭傢伙 喫飯傢伙
+吃饭别忘了种谷人 喫飯別忘了種穀人
+吃饭家伙 喫飯家伙
+吃饱了饭撑的 喫飽了飯撐的
+吃饱没事干 喫飽沒事幹
各不相同 各不相同
各个 各個
各个击破 各個擊破
@@ -12867,8 +12919,8 @@
合口味 合口味
合口呼 合口呼
合叶 合葉
-合吃 合吃
-合吃族 合吃族
+合吃 合喫
+合吃族 合喫族
合合 合合
合同 合同
合同各方 合同各方
@@ -13382,8 +13434,8 @@
同参 同參
同右 同右
同号 同號
-同吃 同吃
-同吃同住 同吃同住
+同吃 同喫
+同吃同住 同喫同住
同名 同名
同名之累 同名之累
同名同姓 同名同姓
@@ -13455,6 +13507,7 @@
同年而语 同年而語
同庆 同慶
同床 同牀
+同床各梦 同牀各夢
同床异梦 同牀異夢
同庚 同庚
同度 同度
@@ -13611,8 +13664,6 @@
同爲 同爲
同父 同父
同父异母 同父異母
-同牀各梦 同牀各夢
-同牀异梦 同牀異夢
同班 同班
同班同学 同班同學
同理 同理
@@ -13738,6 +13789,7 @@
同道者 同道者
同配生殖 同配生殖
同酬 同酬
+同里 同里
同重 同重
同量 同量
同量异位素 同量異位素
@@ -14087,7 +14139,7 @@
后虑 後慮
后蜀 後蜀
后行 後行
-后街 后街
+后街 後街 后街
后裔 後裔
后襟 後襟
后西游记 後西遊記
@@ -14339,6 +14391,7 @@
吞刀刮肠 吞刀刮腸
吞咽 吞嚥
吞并 吞併
+吞武里 吞武里
吞烟 吞煙
吞米桑布札 吞米桑布札
吟叹 吟歎
@@ -14475,6 +14528,7 @@
呆气 呆氣
呆滞 呆滯
呆痴 呆癡
+呆着 待著
呆脑 呆腦
呆致致 呆緻緻
呆话 呆話
@@ -14589,7 +14643,7 @@
周年 週年
周年庆 週年慶
周年纪念 週年紀念
-周年视差 周年視差
+周年视差 週年視差
周幼婷 周幼婷
周幽王 周幽王
周庄 周莊
@@ -14634,8 +14688,8 @@
周晬 周晬
周朝 周朝
周期 週期
-周期函数 周期函數
-周期彗星 周期彗星
+周期函数 週期函數
+周期彗星 週期彗星
周期律 週期律
周期性 週期性
周期数 週期數
@@ -14703,7 +14757,7 @@
周美青 周美青
周考 週考
周而不比 周而不比
-周而复始 周而復始
+周而复始 週而復始
周至 周至
周至县 周至縣
周董 周董
@@ -14724,11 +14778,11 @@
周边 周邊
周边设备 周邊設備
周迅 周迅
-周近 週近
+周近 周近
周遍 周遍
周道 周道
周遭 周遭
-周遭事物 週遭事物
+周遭事物 周遭事物
周遮 周遮
周邦彦 周邦彥
周郎 周郎
@@ -14760,12 +14814,14 @@
命世才 命世才
命中注定 命中註定
命名系统 命名系統
+命理 命理
命运注定 命運註定
命题范围 命題範圍
咀咽 咀嚥
咀嚼出 咀嚼出
和丰 和豐
和了 和了
+和什托洛盖 和什托洛蓋
和光同尘 和光同塵
和克制 和剋制
和合 和合
@@ -14842,6 +14898,7 @@
咸宁 咸寧
咸宁地区 咸寧地區
咸宁市 咸寧市
+咸安 咸安
咸安区 咸安區
咸宜 咸宜
咸度 鹹度
@@ -14988,7 +15045,7 @@
哈里斯 哈里斯
哈里斯堡 哈里斯堡
哈里札德 哈里札德
-哈里森史密特 哈裏森史密特
+哈里森史密特 哈里森史密特
哈里路亚 哈里路亞
哈里逊 哈里遜
哈里逊福特 哈里遜福特
@@ -15054,14 +15111,22 @@
哲学系 哲學系
哲学范畴 哲學範疇
哲布尊丹巴 哲布尊丹巴
+哲理 哲理
+哲里木 哲里木
哺喂 哺餵
哼个 哼個
哼出 哼出
哽咽 哽咽
唁吊 唁弔
+唇似抹朱 脣似抹朱
+唇如涂朱 脣如塗朱
唇干 脣乾
唇彩 脣彩
+唇彩盘 脣彩盤
唇燥舌干 脣燥舌乾
+唇若抹朱 脣若抹朱
+唇若涂朱 脣若塗朱
+唇若涂脂 脣若塗脂
唉叹 唉嘆
唐三彩 唐三彩
唐志中 唐志中
@@ -15149,10 +15214,13 @@
喂它 餵它
喂我 餵我
喂母乳 餵母乳
+喂牛 餵牛
+喂狗 餵狗
喂猪 餵豬
喂眼 喂眼
喂给 餵給
喂羊 餵羊
+喂貓 餵貓
喂过 餵過
喂食 餵食
喂饭 餵飯
@@ -15184,6 +15252,7 @@
善罢干休 善罷干休
善财难舍 善財難捨
喇叭虫 喇叭蟲
+喉咙里 喉嚨裏
喉咽 喉咽
喉头发干 喉頭發乾
喉干舌燥 喉乾舌燥
@@ -15231,7 +15300,6 @@
喧哄 喧鬨
喧哗 喧譁
喧噪 喧噪
-喫亏的是乖占便宜的是呆 喫虧的是乖占便宜的是呆
喷云吐雾 噴雲吐霧
喷云嗳雾 噴雲噯霧
喷出 噴出
@@ -15502,7 +15570,7 @@
回帖 回帖
回带 迴帶
回席 回席
-回应 迴應
+回应 回應
回府 回府
回廊 迴廊
回弹 回彈
@@ -15703,6 +15771,7 @@
回邮信封 回郵信封
回部 回部
回采 回採
+回里 回里
回銮 迴鑾
回销 回銷
回锅 回鍋
@@ -16022,6 +16091,7 @@
图形用户界面 圖形用戶界面
图形界面 圖形界面
图文并茂 圖文並茂
+图昆线 圖崑線
图木舒克 圖木舒克
图木舒克市 圖木舒克市
图板 圖板
@@ -16031,6 +16101,7 @@
图资系统 圖資系統
图里 圖裏
图里亚夫 圖里亞夫
+图里河 圖里河
图鉴 圖鑑
图面 圖面
囿于 囿於
@@ -16130,7 +16201,7 @@
在家千日好出门一时难 在家千日好出門一時難
在家靠父母出外靠朋友 在家靠父母出外靠朋友
在密切注意 在密切注意
-在念 在念
+在念 在唸
在某种程度上 在某種程度上
在核 在覈
在桥梁工地上 在橋梁工地上
@@ -16191,6 +16262,7 @@
地牛发威 地牛發威
地狱谷 地獄谷
地球同步轨道 地球同步軌道
+地理 地理
地理极 地理極
地理资讯系统 地理資訊系統
地瓜叶 地瓜葉
@@ -16272,7 +16344,7 @@
坛场 壇場
坛坛罐罐 罈罈罐罐
坛坫 壇坫
-坛坫周旋 壇坫週旋
+坛坫周旋 壇坫周旋
坛城 壇城
坛女儿红 罈女兒紅
坛好酒 罈好酒
@@ -16394,7 +16466,7 @@
培美曲塞 培美曲塞
培育出 培育出
培育出来 培育出來
-培里克利斯 培裏克利斯
+培里克利斯 培里克利斯
培里克里斯 培里克里斯
基于 基於
基克维特 基克維特
@@ -16424,7 +16496,7 @@
基民党 基民黨
基里兰柯 基里蘭柯
基里巴斯 基里巴斯
-基里巴斯共和国 基裏巴斯共和國
+基里巴斯共和国 基里巴斯共和國
基面 基面
堂分姑娘 堂分姑娘
堂后官 堂後官
@@ -16468,6 +16540,7 @@
塔娜苏冈 塔娜蘇岡
塔娜苏甘 塔娜蘇甘
塔布 塔布
+塔木托格拉克 塔木托格拉克
塔波兰尼克 塔波蘭尼克
塔罗维克 塔羅維克
塔里契亚努 塔里契亞努
@@ -16492,7 +16565,7 @@
塞药 塞藥
塞莉佛维克 塞莉佛維克
塞车症候群 塞車症候羣
-塞韦里诺 塞韋裏諾
+塞韦里诺 塞韋里諾
填个 填個
填了 填了
填发 填發
@@ -16510,6 +16583,7 @@
增量参数 增量參數
墟里 墟里
墨卷 墨卷
+墨发 墨髮
墨斗 墨斗
墨斗鱼 墨斗魚
墨沈 墨沈
@@ -16556,6 +16630,7 @@
处于 處於
处女表演 處女表演
处方药 處方藥
+处理 處理
处理厂 處理廠
处理表 處理表
备尝 備嘗
@@ -16575,7 +16650,6 @@
复习考 複習考
复书 復書
复交 復交
-复亩珍 複畝珍
复仇 復仇
复仇者 復仇者
复仇记 復仇記
@@ -16709,7 +16783,6 @@
复呈 覆呈
复员 復員
复员令 復員令
-复员军人 複員軍人
复命 覆命
复品牌 複品牌
复回 復回
@@ -17039,7 +17112,7 @@
多发病 多發病
多只 多隻
多台 多臺
-多吃多占 多吃多佔
+多吃多占 多喫多佔
多向 多向
多哈回合 多哈回合
多回 多回
@@ -17089,6 +17162,7 @@
多边合作 多邊合作
多采 多采
多采多姿 多采多姿
+多里 多里
多面 多面
多面体 多面體
多面性 多面性
@@ -17154,8 +17228,8 @@
大伙 大夥
大伙人 大夥人
大伙儿 大夥兒
-大余 大餘
-大余县 大餘縣
+大余 大余
+大余县 大余縣
大便干燥 大便乾燥
大修 大修
大修理 大修理
@@ -17241,7 +17315,7 @@
大后年 大後年
大后方 大後方
大周后 大周后
-大周折 大週摺
+大周折 大周折
大咸 大咸
大哗 大譁
大回 大回
@@ -17326,6 +17400,7 @@
大核 大核
大梁 大梁 大樑
大楼监控系统 大樓監控系統
+大榄涌 大欖涌
大欲 大欲
大武仑 大武崙
大气团 大氣團
@@ -17337,6 +17412,7 @@
大汉技术学院 大漢技術學院
大汗淋漓 大汗淋漓
大海捞针 大海撈針
+大涌 大涌
大润发 大潤發
大涨小回 大漲小回
大清一统志 大清一統志
@@ -17380,9 +17456,9 @@
大获 大獲
大获全胜 大獲全勝
大虫 大蟲
-大虫不吃伏肉 大蟲不吃伏肉
+大虫不吃伏肉 大蟲不喫伏肉
大虫口里倒涎 大蟲口裏倒涎
-大虫吃小虫 大蟲吃小蟲
+大虫吃小虫 大蟲喫小蟲
大虫头上做窠 大蟲頭上做窠
大蜡 大蜡
大衍历 大衍曆
@@ -17506,6 +17582,7 @@
天渊之别 天淵之別
天潢贵胄 天潢貴胄
天然纤维 天然纖維
+天璇 天璇
天生干 天生幹
天盟誓表现 天盟誓表現
天纳克 天納克
@@ -17534,6 +17611,7 @@
太初历史 太初歷史
太卜 太卜
太原师范学院 太原師範學院
+太古里 太古里
太后 太后
太咸 太鹹
太好了 太好了
@@ -17541,8 +17619,7 @@
太子舍人 太子舍人
太干 太乾
太平御览 太平御覽
-太平洋周边 太平洋週邊
-太平洋周邊 太平洋周邊
+太平洋周边 太平洋周邊
太平洋联合铁路 太平洋聯合鐵路
太扯了 太扯了
太松 太鬆
@@ -17559,7 +17636,7 @@
太谷 太谷
太谷县 太谷縣
太谷灯 太谷燈
-太阳升 太陽升
+太阳升 太陽昇
太阳历 太陽曆
太阳微系统公司 太陽微系統公司
太阳照在桑干河上 太陽照在桑乾河上
@@ -17568,7 +17645,7 @@
太阳系 太陽系
太阳能板 太陽能板
太阳谷 太陽谷
-太阳黑子周 太陽黑子周
+太阳黑子周 太陽黑子週
太阴历 太陰曆
太麻里 太麻里
太麻里乡 太麻里鄉
@@ -17928,10 +18005,6 @@
奸黠 奸黠
她克制 她剋制
她准知 她準知
-她出 她出
-她出去 她出去
-她出来 她出來
-她念 她念
好一出 好一齣
好不了 好不了
好不容易才 好不容易纔
@@ -18159,7 +18232,6 @@
威克菲尔 威克菲爾
威克菲尔德 威克菲爾德
威奇托 威奇托
-威宁彝族回族苗族自治县 威寧彝族回族苗族自治縣
威尔生氏症 威爾生氏症
威布里吉 威布里吉
威廉亚历山大 威廉亞歷山大
@@ -18434,6 +18506,7 @@
安吉里科 安吉里科
安地卡及巴布达 安地卡及巴布達
安山岩 安山岩
+安岳 安岳
安布罗斯 安布羅斯
安席克 安席克
安扎 安扎
@@ -18461,6 +18534,7 @@
宋三彩 宋三彩
宋亨欣叶纯豪 宋亨欣葉純豪
宋克 宋克
+宋干节 宋干節
宋板 宋板
完了 完了
完全叶 完全葉
@@ -18521,6 +18595,7 @@
定时号志 定時號誌
定时钟 定時鐘
定点厂 定點廠
+定理 定理
定碳杯 定碳杯
定胜败 定勝敗
定范围 定範圍
@@ -18533,7 +18608,7 @@
宜丰县 宜豐縣
宜于 宜於
宜云 宜云
-宝丰 寶丰 寶豐
+宝丰 寶豐
宝丰县 寶豐縣
宝卷 寶卷
宝历 寶曆
@@ -18557,7 +18632,7 @@
实录 實錄
实才 實才
实据 實據
-实时技术 實時技術
+实时 即時
实用价值 實用價值
实症 實症
实质面 實質面
@@ -18568,6 +18643,7 @@
审干 審幹
审曲面势 審曲面勢
审核 審覈
+审理 審理
审级制度 審級制度
审计范围 審計範圍
客串演出 客串演出
@@ -18696,6 +18772,7 @@
密苏里 密蘇里
密苏里州 密蘇里州
密苏里河 密蘇里河
+寇不可玩 寇不可翫
寇仇 寇仇
寇准 寇準
富于 富於
@@ -18732,6 +18809,7 @@
察合台汗国 察合臺汗國
察布查尔 察布查爾
察布查尔县 察布查爾縣
+察干 察干
察核 察覈
察觉出 察覺出
寡占 寡佔
@@ -18745,8 +18823,8 @@
对了槛儿 對了檻兒
对于 對於
对偶多面体 對偶多面體
-对冲 對衝
-对冲基金 對衝基金
+对冲 對沖
+对冲基金 對沖基金
对准 對準
对准目标 對準目標
对准表 對準錶
@@ -18790,7 +18868,6 @@
寻找出来 尋找出來
寻来范畴 尋來範疇
寻求出来 尋求出來
-寻甸回族彝族自治县 尋甸回族彝族自治縣
寻获 尋獲
导出 導出
导出值 導出值
@@ -18922,7 +18999,7 @@
小叶 小葉
小同乡 小同鄉
小后生 小後生
-小周天 小週天
+小周天 小周天
小回 小回
小场面 小場面
小型柜橱 小型櫃櫥
@@ -19085,7 +19162,7 @@
尤克勒斯 尤克勒斯
尤克斯 尤克斯
尤克里斯 尤克里斯
-尤克里里琴 尤克裏裏琴
+尤克里里琴 尤克里里琴
尤基里斯 尤基里斯
尤班克斯 尤班克斯
尤秋兴 尤秋興
@@ -19101,7 +19178,7 @@
就出 就出
就出去 就出去
就出来 就出來
-就吃干 就吃乾
+就吃干 就喫乾
就回 就回
就回去 就回去
就回来 就回來
@@ -19111,7 +19188,7 @@
就干淨 就乾淨
就当 就當
就当作 就當作
-就念 就念
+就念 就唸
就扣 就扣
就拿出 就拿出
就日瞻云 就日瞻雲
@@ -19168,6 +19245,8 @@
尺幅千里 尺幅千里
尺板 尺板
尺板斗食 尺板斗食
+尼乾子 尼乾子
+尼乾陀 尼乾陀
尼亚加拉瀑布 尼亞加拉瀑布
尼克 尼克
尼克劳斯 尼克勞斯
@@ -19276,6 +19355,7 @@
尽本分 盡本分
尽欢 盡歡
尽欢而散 盡歡而散
+尽沾恩露 盡霑恩露
尽然 盡然
尽瘁 盡瘁
尽瘁鞠躬 盡瘁鞠躬
@@ -19390,7 +19470,8 @@
履历表 履歷表
屯扎 屯紮
屯田制 屯田制
-屯里 屯裏
+屯里 屯裏 屯里
+屯里镇 屯里鎮
山中无历日 山中無曆日
山中白云 山中白雲
山仔后 山仔后
@@ -19621,6 +19702,7 @@
左氏春秋 左氏春秋
左邻右舍 左鄰右舍
左邻右里 左鄰右里
+左里 左里
左里克 左里克
左面 左面
巧了 巧了
@@ -19757,9 +19839,9 @@
巴贝西亚原虫病 巴貝西亞原蟲病
巴里 巴里
巴里坤 巴里坤
-巴里坤县 巴裏坤縣
-巴里坤哈萨克自治县 巴裏坤哈薩克自治縣
-巴里坤草原 巴裏坤草原
+巴里坤县 巴里坤縣
+巴里坤哈萨克自治县 巴里坤哈薩克自治縣
+巴里坤草原 巴里坤草原
巴里岛 巴里島
巴里库廷火山 巴里庫廷火山
巴里斯 巴里斯
@@ -19830,6 +19912,7 @@
布列兹涅夫 布列茲涅夫
布列兹涅夫主义 布列茲涅夫主義
布列塔尼 布列塔尼
+布列开 布列開
布利吉 布利吉
布利斯班 布利斯班
布利斯班市 布利斯班市
@@ -19847,8 +19930,8 @@
布吉河 布吉河
布吉纳法索 布吉納法索
布告 佈告
-布告栏 布告欄
-布告牌 布告牌
+布告栏 佈告欄
+布告牌 佈告牌
布哈拉 布哈拉
布哈林 布哈林
布哈林模式 布哈林模式
@@ -19971,7 +20054,6 @@
布气 布氣
布水 布水
布法罗 布法羅
-布洒器 布灑器
布洛克 布洛克
布洛斯顿 布洛斯頓
布洛沙德 布洛沙德
@@ -19990,7 +20072,6 @@
布瑞斯特 布瑞斯特
布瑞特 布瑞特
布瑞顿 布瑞頓
-布用填 布用填
布疋 布疋
布疑阵 佈疑陣
布痕瓦尔德 布痕瓦爾德
@@ -20093,7 +20174,6 @@
布里姬沃特 布里姬沃特
布里斯 布里斯
布里斯托 布里斯托
-布里斯托尔 布裏斯托爾
布里斯托尔海峡 布里斯托爾海峽
布里斯本 布里斯本
布里斯本市 布里斯本市
@@ -20164,8 +20244,8 @@
帅呆了 帥呆了
帆布 帆布
帆布包 帆布包
+帆布床 帆布牀
帆布椅 帆布椅
-帆布牀 帆布牀
帆布袋 帆布袋
帆布鞋 帆布鞋
帆板 帆板
@@ -20195,7 +20275,7 @@
希布伦市 希布倫市
希拉克 希拉剋
希拉里 希拉里
-希拉里克林顿 希拉裏克林頓
+希拉里克林顿 希拉里克林頓
希斯仑 希斯崙
希斯莱杰 希斯萊傑
希斯雷杰 希斯雷傑
@@ -20207,7 +20287,6 @@
帕克 帕克
帕台农 帕臺農
帕台农神庙 帕臺農神廟
-帕拉马里博 帕拉馬裏博
帕特里克 帕特里克
帕特里夏 帕特里夏
帕穆克 帕穆克
@@ -20331,6 +20410,7 @@
干乔 乾喬
干买卖 幹買賣
干了 幹了 乾了
+干了什么 幹了什麼
干了杯 乾了杯
干了这一杯 乾了這一杯
干了这一瓶 乾了這一瓶
@@ -20342,6 +20422,7 @@
干云蔽日 乾雲蔽日
干井 乾井
干些 幹些
+干些什么 幹些什麼
干产 乾產
干亲 乾親
干人 幹人
@@ -20420,11 +20501,13 @@
干土 乾土
干地 乾地
干坏事 幹壞事
+干坐 乾坐
干坐着 乾坐着
干坛子 乾罈子
干坞 乾塢
干城 干城
干堂婶 乾堂嬸
+干塘 乾塘
干大事 幹大事
干头 幹頭
干女 乾女
@@ -20522,6 +20605,7 @@
干支剌 乾支剌
干支支 乾支支
干支沟 干支溝
+干支流 幹支流
干政 干政
干数杯 乾數杯
干料 乾料
@@ -20565,10 +20649,12 @@
干涸 乾涸
干淨 乾淨
干淨俐落 乾淨俐落
-干渠 乾渠
+干渠 幹渠
干渴 乾渴
干湿 乾溼
干湿发 乾溼髮
+干溪 乾溪
+干滩 乾灘
干漆 乾漆
干灯盏 乾燈盞
干点 乾點 幹點
@@ -20622,6 +20708,7 @@
干碍 干礙
干礼 乾禮
干稿 乾稿
+干站 乾站
干站着 乾站着
干笑 乾笑
干等 乾等
@@ -20705,6 +20792,8 @@
干醋 乾醋
干重 乾重
干量 乾量
+干锅 乾鍋
+干镇驿 乾鎮驛
干闼婆 乾闥婆
干阿奶 乾阿奶
干雷 乾雷
@@ -20717,6 +20806,7 @@
干馆 乾館
干馏 乾餾
干馏法 乾餾法
+干驿镇 乾驛鎮
干鱼 乾魚
干鲜 乾鮮
干麻 幹麻
@@ -20748,12 +20838,13 @@
平复帖 平復帖
平复起来 平復起來
平头并进 平頭並進
-平安里 平安裏
+平安里 平安里
平定准噶尔回部得胜图 平定準噶爾回部得勝圖
平平当当 平平當當
平康里 平康里
平方公里 平方公里
平方千米 平方千米
+平日里 平日裏
平易谦冲 平易謙沖
平板 平板
平板仪 平板儀
@@ -21100,6 +21191,7 @@
庄舄越吟 莊舄越吟
庄语 莊語
庄里 莊裏
+庄里镇 莊里鎮 莊裏鎮
庄重 莊重
庄院 莊院
庄骚 莊騷
@@ -21115,6 +21207,7 @@
庇里牛斯 庇里牛斯
庇里牛斯山 庇里牛斯山
床头柜 牀頭櫃
+床头金尽 牀頭金盡
床席 牀蓆
床板 牀板
序升 序升
@@ -21133,7 +21226,7 @@
库尔德工人党 庫爾德工人黨
库尔斯克 庫爾斯克
库工党 庫工黨
-库布里克 庫布裏克
+库布里克 庫布里克
库木吐拉千佛洞 庫木吐拉千佛洞
库瑞克 庫瑞克
库苏古尔湖 庫蘇古爾湖
@@ -21303,6 +21396,7 @@
建造出 建造出
建都于 建都於
廿五万 廿五萬
+廿里 廿里
开不了 開不了
开个 開個
开了 開了
@@ -21434,7 +21528,7 @@
弄盏传杯 弄盞傳杯
弄粉调朱 弄粉調朱
弄脏 弄髒
-弄面吃 弄麪吃
+弄面吃 弄麪喫
弄鬼吊猴 弄鬼弔猴
弈秋 弈秋
弊帚千金 弊帚千金
@@ -21479,16 +21573,16 @@
引致 引致
引蛇出洞 引蛇出洞
弗兰克 弗蘭克
-弗洛里斯岛 弗洛裏斯島
-弗罗里达 弗羅裏達
-弗罗里达州 弗羅裏達州
-弗里得里希 弗裏得裏希
+弗洛里斯岛 弗洛里斯島
+弗罗里达 弗羅里達
+弗罗里达州 弗羅里達州
+弗里得里希 弗里得里希
弗里德里希 弗里德里希
弗里敦 弗里敦
弗里斯兰 弗里斯蘭
弗里曼 弗里曼
-弗雷德里克 弗雷德裏克
-弗雷德里克顿 弗雷德裏克頓
+弗雷德里克 弗雷德里克
+弗雷德里克顿 弗雷德里克頓
弘历 弘曆
弘愿 弘願
张三丰 張三丰
@@ -21504,6 +21598,7 @@
张基郁 張基郁
张堪折辕 張堪折轅
张大千 張大千
+张必 張必
张志 張志
张志和 張志和
张志家 張誌家
@@ -21538,6 +21633,7 @@
张良借箸 張良借箸
张良慕赤松 張良慕赤松
张苙云 張苙雲
+张范街道 張范街道
张荣发 張榮發
张金涂 張金塗
张飞穿针 張飛穿針
@@ -21623,7 +21719,6 @@
弱不胜衣 弱不勝衣
弱于 弱於
弱势团体 弱勢團體
-弱智赖于涵 弱智賴于涵
弱水三千 弱水三千
弱音踏板 弱音踏板
弹不出 彈不出
@@ -21795,6 +21890,7 @@
当可 當可
当合 當合
当周 當週
+当周街道 當周街道
当啷 噹啷
当啷落地 噹啷落地
当回事 當回事
@@ -21941,7 +22037,6 @@
当罏红袖 當罏紅袖
当者披靡 當者披靡
当耳边风 當耳邊風
-当舖 當舖
当艄拿舵 當艄拿舵
当艄顺 當艄順
当花 當花
@@ -22062,6 +22157,7 @@
形同虚设 形同虛設
形同陌路 形同陌路
形名参同 形名參同
+形如斗 形如斗
形孤影只 形孤影隻
形容尽致 形容盡致
形影相吊 形影相弔
@@ -22154,7 +22250,7 @@
彩色缤纷 彩色繽紛
彩虹 彩虹
彩虹仙子 彩虹仙子
-彩虹冰舖 彩虹冰舖
+彩虹冰铺 彩虹冰鋪
彩虹桥 彩虹橋
彩蛋 彩蛋
彩蝶 彩蝶
@@ -22356,12 +22452,12 @@
徐妃半面妆 徐妃半面妝
徐娘 徐娘
徐娘半老 徐娘半老
-徐家汇 徐家彙
+徐家汇 徐家匯
徐州师范大学 徐州師範大學
徐干 徐幹
徐志摩 徐志摩
徐汇 徐匯
-徐汇区 徐彙區
+徐汇区 徐匯區
徐清云 徐清雲
徐赞升 徐讚昇
徐霞客游记 徐霞客遊記
@@ -22562,6 +22658,8 @@
心游 心遊
心满愿足 心滿願足
心物合一 心物合一
+心理 心理
+心理发展 心理發展
心理学系 心理學系
心理系 心理系
心理面 心理面
@@ -22765,7 +22863,7 @@
快出来 快出來
快升 快升
快去快回 快去快回
-快吃干 快吃乾
+快吃干 快喫乾
快向 快向
快回 快回
快回到 快回到
@@ -22787,6 +22885,7 @@
快没了 快沒了
快满了 快滿了
快熟了 快熟了
+快狠准 快狠準
快舍下 快捨下
快赢了 快贏了
快适 快適
@@ -22905,7 +23004,7 @@
思前思后 思前思後
思前想后 思前想後
思前算后 思前算後
-思如泉涌 思如泉涌
+思如泉涌 思如泉湧
思念 思念
思想体系 思想體系
思想准备 思想準備
@@ -22978,6 +23077,7 @@
总杆数 總桿數
总杆赛 總桿賽
总汇 總彙
+总理 總理
总统制 總統制
总统杯 總統盃
总裁制 總裁制
@@ -23005,11 +23105,11 @@
恐韩症 恐韓症
恐高症 恐高症
恐鸡症 恐雞症
+恒大 恒大
+恒指 恒指
恒星周期 恆星週期
恒春野百合 恆春野百合
-恒生指数 恆生指數
-恒生股价指数 恆生股價指數
-恒生银行 恆生銀行
+恒生 恒生
恒言录 恆言錄
恕乏价催 恕乏价催
恙虫 恙蟲
@@ -23506,9 +23606,11 @@
愿谨 願謹
愿闻其详 願聞其詳
慈云 慈雲
+慈余高速 慈餘高速
慈制 慈制
慈安太后 慈安太后
慈悲喜舍 慈悲喜捨
+慈溪 慈谿
慈禧太后 慈禧太后
慌了 慌了
慌了手脚 慌了手腳
@@ -23663,8 +23765,8 @@
戚党 戚黨
戚凯罗 戚凱羅
戚友 戚友
-戚墅堰 慼墅堰
-戚墅堰区 慼墅堰區
+戚墅堰 戚墅堰
+戚墅堰区 戚墅堰區
戚夫人 戚夫人
戚家军 戚家軍
戚容 戚容
@@ -23803,7 +23905,7 @@
手铲 手鏟
手链 手鍊 手鏈
手面 手面
-手面赚吃 手面賺吃
+手面赚吃 手面賺喫
才上到 纔上到
才上去 纔上去
才上来 纔上來
@@ -23951,7 +24053,7 @@
才艺秀 才藝秀
才蔽识浅 才蔽識淺
才藻 才藻
-才行 才行
+才行 纔行 才行
才要 纔要
才讲 纔講
才识 才識
@@ -24213,6 +24315,7 @@
托买 託買
托了 託了
托事 託事
+托云 托雲
托交 託交
托人 託人
托人情 託人情
@@ -24251,8 +24354,10 @@
托尔 托爾
托尔斯泰 托爾斯泰
托尔金 托爾金
+托布力其 托布力其
托幼 托幼
托庇 託庇
+托托镇 托托鎮
托拉 托拉
托拉博拉 托拉博拉
托拉斯 托拉斯
@@ -24264,6 +24369,7 @@
托木尔峰 托木爾峯
托杯 托杯
托架 托架
+托格拉克 托格拉克
托梦 託夢
托比亚斯 托比亞斯
托比麦奎尔 托比麥奎爾
@@ -24313,9 +24419,9 @@
托过 託過
托运 託運
托运行李 托運行李
-托里 托裏
-托里县 托裏縣
-托里拆利 托裏拆利
+托里 托里
+托里县 托里縣
+托里拆利 托里拆利
托鉢 托鉢
托钵人 托鉢人
托钵修会 托鉢修會
@@ -24476,9 +24582,10 @@
扳回 扳回
扳回一城 扳回一城
扶了 扶了
-扶余 扶余
-扶余县 扶余縣
+扶余 扶餘
+扶余县 扶餘縣
扶余国 扶餘國
+扶余市 扶餘市
扶出 扶出
扶出去 扶出去
扶出来 扶出來
@@ -24623,7 +24730,7 @@
抓出 抓出
抓出去 抓出去
抓出来 抓出來
-抓周 抓週
+抓周 抓周
抓回 抓回
抓回去 抓回去
抓回来 抓回來
@@ -24642,6 +24749,7 @@
投出来 投出來
投合 投合
投向 投向
+投喂 投餵
投回 投回
投射出 投射出
投影几何 投影幾何
@@ -24719,10 +24827,10 @@
折变 折變
折叠 摺疊
折叠为 摺疊爲
+折叠床 摺疊牀
折叠式 摺疊式
折叠扇 摺疊扇
折叠椅 摺疊椅
-折叠牀 摺疊牀
折叠起来 摺疊起來
折台 折檯
折合 摺合
@@ -24899,6 +25007,7 @@
护壁板 護壁板
护念 護念
护板 護板
+护理 護理
护理系 護理系
护面 護面
护面具 護面具
@@ -25015,6 +25124,7 @@
抽咽 抽咽
抽回 抽回
抽尽 抽盡
+抽屉里 抽屜裏
抽干 抽乾
抽斗 抽斗
抽油烟机 抽油煙機
@@ -25239,7 +25349,7 @@
招回去 招回去
招回来 招回來
招复 招復
-招待不周 招待不週
+招待不周 招待不周
招术 招術
招致 招致
拜冬 拜冬
@@ -25854,6 +25964,7 @@
据实相告 據實相告
据常 據常
据干而窥井底 據榦而窺井底
+据床指麾 據牀指麾
据悉 據悉
据情办理 據情辦理
据我看 據我看
@@ -25863,7 +25974,6 @@
据有 據有
据此 據此
据点 據點
-据牀指麾 據牀指麾
据理 據理
据理力争 據理力爭
据理而争 據理而爭
@@ -25912,6 +26022,7 @@
掉出来 掉出來
掉发 掉髮
掉回头 掉回頭
+掉海里 掉海裏
掊克 掊克
掊斗折衡 掊斗折衡
掌柜 掌櫃
@@ -26039,6 +26150,7 @@
推杯 推杯
推派出 推派出
推演出来 推演出來
+推理 推理
推算出 推算出
推算出来 推算出來
推舟于陆 推舟於陸
@@ -26112,6 +26224,7 @@
提炼出 提煉出
提甕出汲 提甕出汲
提纯复壮 提純復壯
+提纳里 提納里
提舍尼 提舍尼
插于 插於
插回 插回
@@ -26807,6 +26920,7 @@
救恩计划 救恩計劃
救生艇甲板 救生艇甲板
救药 救藥
+敖力布告 敖力布告
敖游 敖遊
敖荡 敖盪
教个 教個
@@ -26925,9 +27039,11 @@
数据链路连接识别码 數據鏈路連接識別碼
数术 數術
数杯 數杯
+数理 數理
数百万 數百萬
数米志炊 數米志炊
数罪并罚 數罪併罰
+数里 數里
敲丧钟 敲喪鐘
敲了 敲了
敲出 敲出
@@ -26975,6 +27091,7 @@
整杯酒 整杯酒
整柜 整櫃
整根烟 整根菸
+整理 整理
整理出 整理出
整理出来 整理出來
整装待发 整裝待發
@@ -27014,7 +27131,7 @@
文彩 文彩
文征明 文徵明
文心雕龙 文心雕龍
-文思泉涌 文思泉涌
+文思泉涌 文思泉湧
文情并茂 文情並茂
文才 文才
文擅雕龙 文擅雕龍
@@ -27099,6 +27216,7 @@
斗子 斗子
斗室 斗室
斗室生辉 斗室生輝
+斗宿 斗宿
斗富 鬥富
斗小马 斗小馬
斗尾港 斗尾港
@@ -27132,10 +27250,12 @@
斗斛之禄 斗斛之祿
斗方 斗方
斗方名士 斗方名士
+斗星官 斗星官
斗智 鬥智
斗智不斗力 鬥智不鬥力
斗智斗力 鬥智鬥力
斗暴 鬥暴
+斗木獬 斗木獬
斗杓 斗杓
斗杓东指 斗杓東指
斗杓转势 斗杓轉勢
@@ -27147,6 +27267,7 @@
斗武 鬥武
斗殴 鬥毆
斗气 鬥氣
+斗沟子 斗溝子
斗法 鬥法
斗渠 斗渠
斗灯 斗燈
@@ -27211,6 +27332,7 @@
斗趣 鬥趣
斗趣儿 鬥趣兒
斗车 斗車
+斗转 斗轉
斗转参横 斗轉參橫
斗转星移 斗轉星移
斗酒 斗酒
@@ -27315,8 +27437,8 @@
新丰县 新豐縣
新丰酒 新豐酒
新书看板 新書看板
-新余 新餘
-新余市 新餘市
+新余 新余
+新余市 新余市
新修本草 新修本草
新党 新黨
新几內亚 新幾內亞
@@ -27351,8 +27473,8 @@
新婚不如远别 新婚不如遠別
新嫁娘 新嫁娘
新局面 新局面
-新干 新干
-新干县 新干縣
+新干 新幹
+新干县 新幹縣
新干线 新幹線
新庄 新莊
新庄市 新莊市
@@ -27556,6 +27678,7 @@
无尽藏 無盡藏
无尿症 無尿症
无干 無干
+无序 無序
无店面 無店面
无异于 無異於
无形输出 無形輸出
@@ -27671,7 +27794,8 @@
日转千街 日轉千街
日转千阶 日轉千階
日进斗金 日進斗金
-日里 日裏
+日里 日里
+日里雪冷 日里雪冷
日锻月炼 日鍛月煉
日食万钱 日食萬錢
旧公烟 舊公煙
@@ -27713,7 +27837,7 @@
早知今日悔不当初 早知今日悔不當初
早秋 早秋
早自修 早自修
-早起的鸟儿有虫吃 早起的鳥兒有蟲吃
+早起的鸟儿有虫吃 早起的鳥兒有蟲喫
旭日东升 旭日東昇
旭日初升 旭日初昇
旱干 旱乾
@@ -27764,6 +27888,7 @@
昆山 崑山
昆布 昆布
昆曲 崑曲
+昆玉 崑玉
昆腔 崑腔
昆苏 崑蘇
昆虫 昆蟲
@@ -27915,7 +28040,7 @@
春困 春困
春困秋乏 春困秋乏
春夏秋冬 春夏秋冬
-春天里 春天裏
+春天里 春天裏 春天里
春宵一刻值千金 春宵一刻值千金
春心荡漾 春心蕩漾
春日里 春日裏
@@ -28076,7 +28201,6 @@
景胄 景胄
景致 景緻
景谷 景谷
-景谷傣族彝族自治县 景谷傣族彝族自治縣
景谷县 景谷縣
晴了 晴了
晴云秋月 晴雲秋月
@@ -28147,7 +28271,7 @@
暗号 暗號
暗号灯 暗號燈
暗叹 暗歎
-暗吃一惊 暗吃一驚
+暗吃一惊 暗喫一驚
暗合 暗合
暗含 暗含
暗喜 暗喜
@@ -28206,14 +28330,14 @@
暗泣 暗泣
暗流 暗流
暗浅 闇淺
-暗涌 暗涌
+暗涌 暗湧
暗淡 暗淡
暗淡无光 暗淡無光
暗渠 暗渠
暗渡陈仓 暗渡陳倉
暗滩 暗灘
暗潮 暗潮
-暗潮汹涌 暗潮洶涌
+暗潮汹涌 暗潮洶湧
暗澹 暗澹
暗火 闇火
暗灰色 暗灰色
@@ -28496,7 +28620,10 @@
曷极 曷極
曹余章 曹餘章
曹参 曹參
+曹子里 曹子里
+曹范街道 曹范街道
曹郁芬 曹郁芬
+曹里 曹里
曼尼托巴省 曼尼托巴省
曼苏尔 曼蘇爾
曼苏尔.达杜拉 曼蘇爾.達杜拉
@@ -28626,6 +28753,7 @@
有害于 有害於
有尽有让 有儘有讓
有幸 有幸
+有序 有序
有当 有當
有征 有徵
有征无战 有征無戰
@@ -28727,6 +28855,7 @@
服饰周 服飾週
朔云 朔雲
朔党 朔黨
+朔里 朔里
朗朗云天 朗朗雲天
望乡台 望鄉臺
望了望 望了望
@@ -28784,7 +28913,7 @@
木板地 木板地
木板墙 木板牆
木板大鼓 木板大鼓
-木板牀 木板牀
+木板床 木板牀
木板画 木板畫
木柜 木櫃
木梁 木樑
@@ -28792,7 +28921,8 @@
木薯淀粉 木薯澱粉
木蜡 木蠟
木表法 木表法
-木里藏族自治县 木裏藏族自治縣
+木里图 木里圖
+木里藏族自治县 木里藏族自治縣
木钟 木鐘
木铲 木鏟
木雕 木雕
@@ -28826,7 +28956,6 @@
未扣 未扣
未折现 未折現
未易才 未易才
-未松下 未松下
未知万一 未知萬一
未确定 未確定
未竟之志 未竟之志
@@ -28932,7 +29061,9 @@
朱咏薇 朱詠薇
朱哲琴 朱哲琴
朱唇 朱脣
-朱唇皓齿 硃脣皓齒
+朱唇榴齿 朱脣榴齒
+朱唇皓齿 朱脣皓齒
+朱唇粉面 朱脣粉面
朱培庆 朱培慶
朱墨 朱墨
朱墨本 朱墨本
@@ -28998,7 +29129,6 @@
朱淑真 朱淑真
朱温 朱溫
朱漆 朱漆
-朱熔基 朱熔基
朱熹 朱熹
朱理安历 朱理安曆
朱理安历史 朱理安歷史
@@ -29027,10 +29157,6 @@
朱经武 朱經武
朱美 朱美
朱耷 朱耷
-朱脣 朱脣
-朱脣榴齿 朱脣榴齒
-朱脣皓齿 朱脣皓齒
-朱脣粉面 朱脣粉面
朱自清 朱自清
朱舜水 朱舜水
朱色 硃色
@@ -29053,6 +29179,7 @@
朱迪亚 朱迪亞
朱邸 朱邸
朱郁信 朱郁信
+朱里 朱里
朱铭 朱銘
朱镕基 朱鎔基
朱门 朱門
@@ -29095,6 +29222,7 @@
朴实作风 樸實作風
朴实无华 樸實無華
朴宣英 朴宣英
+朴屯 朴屯
朴志胤 朴志胤
朴忠 朴忠
朴念仁 樸念仁
@@ -29264,6 +29392,7 @@
李杰 李傑
李洪志 李洪志
李炳千 李炳千
+李白 李白
李百药 李百藥
李盟干 李盟乾
李秋静 李秋靜
@@ -29321,7 +29450,17 @@
束矢难折 束矢難折
束身修行 束身修行
束身自修 束身自修
+杠一 杠一
+杠七 杠七
+杠三 杠三
杠上 槓上
+杠九 杠九
+杠二 杠二
+杠五 杠五
+杠八 杠八
+杠六 杠六
+杠四 杠四
+杠增一 杠增一
杠头 槓頭
杠子 槓子
杠杆 槓桿
@@ -29354,10 +29493,10 @@
来回票 來回票
来复 來複
来复日 來復日
-来复枪 來複槍
-来复线 來複線
+来复枪 來復槍
+来复线 來復線
来宾致词 來賓致詞
-来念 來念
+来念 來唸
来来回回 來來回回
来杯 來杯
来自于 來自於
@@ -29386,7 +29525,7 @@
杨胜旭 楊勝旭
杨致远 楊致遠
杨苏棣 楊甦棣
-杨采妮 楊採妮
+杨采妮 楊采妮
杨雅筑 楊雅筑
杪秋 杪秋
杭丁顿舞蹈症 杭丁頓舞蹈症
@@ -29542,6 +29681,7 @@
松北区 松北區
松原 松原
松原市 松原市
+松发 鬆發
松口 鬆口
松口气 鬆口氣
松口蘑 松口蘑
@@ -29551,6 +29691,8 @@
松喉 鬆喉
松土 鬆土
松土机 鬆土機
+松坎 松坎
+松坝 松壩
松垮 鬆垮
松大辅 松大輔
松子 松子
@@ -29611,6 +29753,7 @@
松柏长青茶 松柏長青茶
松柔 鬆柔
松树 松樹
+松桃 松桃
松桃县 松桃縣
松桃苗族自治县 松桃苗族自治縣
松毛 松毛
@@ -29622,6 +29765,7 @@
松江区 松江區
松江省 松江省
松江路 松江路
+松河 松河
松油 松油
松油管 鬆油管
松油门 鬆油門
@@ -29631,8 +29775,8 @@
松涛 松濤
松溪 松溪
松溪县 松溪縣
-松滋 鬆滋
-松滋市 鬆滋市
+松滋 松滋
+松滋市 松滋市
松漠 松漠
松潘 松潘
松潘县 松潘縣
@@ -29640,7 +29784,7 @@
松烟墨 松煙墨
松焦油 松焦油
松煤 松煤
-松狮犬 松獅犬
+松狮 鬆獅
松球 松球
松球鱼 松球魚
松瓤 松瓤
@@ -29894,7 +30038,7 @@
林义杰 林義傑
林云 林雲
林云阁 林雲閣
-林俊杰 林俊杰
+林俊杰 林俊傑
林克 林克
林克平大学 林克平大學
林克海德 林克海德
@@ -29958,6 +30102,7 @@
果子药 果子藥
果干 果乾
果杯 果杯
+果松 果松
果核 果核
果穗 果穗
枝不得大于干 枝不得大於榦
@@ -30056,6 +30201,8 @@
查克瑞 查克瑞
查准率 查準率
查出 查出
+查干 查干
+查干湖 查干湖
查扣 查扣
查核 查覈
查获 查獲
@@ -30096,7 +30243,7 @@
査回 查回
査回去 查回去
査回来 查回來
-査找周期 查找周期
+査找周期 查找週期
査报表 查報表
査无实据 查無實據
査获 查獲
@@ -30167,6 +30314,7 @@
标致 標緻
标表 標表
标记识别 標記識別
+标里镇 標里鎮
栈板 棧板
栉发工 櫛髮工
栋折榱崩 棟折榱崩
@@ -30259,7 +30407,7 @@
核当量 核當量
核心 核心
核战 核戰
-核战斗部 核戰斗部
+核战斗部 核戰鬥部
核批 覈批
核技术 核技術
核报 覈報
@@ -30573,6 +30721,7 @@
梳发 梳髮
梳头发 梳頭髮
梳妆台 梳妝檯
+梳理 梳理
梵册贝叶 梵冊貝葉
梵谷 梵谷
检修 檢修
@@ -30812,6 +30961,7 @@
欧胡岛 歐胡島
欧萨苏纳 歐薩蘇納
欧足联杯 歐足聯杯
+欧里 歐里
欧里庇得斯 歐里庇得斯
欧里桑 歐里桑
欧阳修 歐陽修
@@ -30993,7 +31143,7 @@
武器系统 武器系統
武器级别材料 武器級別材料
武坛 武壇
-武大郎吃毒药 武大郎吃毒藥
+武大郎吃毒药 武大郎喫毒藥
武当 武當
武当山 武當山
武当派 武當派
@@ -31254,6 +31404,7 @@
毫发无损 毫髮無損
毫发未伤 毫髮未傷
毫居里 毫居里
+毫无 毫無
毫无二致 毫無二致
毫无价值 毫無價值
毫无准备 毫無準備
@@ -31321,9 +31472,9 @@
气充志骄 氣充志驕
气克斗牛 氣克斗牛
气冲冲 氣沖沖
-气冲斗牛 氣衝斗牛
-气冲牛斗 氣衝牛斗
-气冲霄汉 氣衝霄漢
+气冲斗牛 氣沖斗牛
+气冲牛斗 氣沖牛斗
+气冲霄汉 氣沖霄漢
气出 氣出
气力用尽 氣力用盡
气动控制 氣動控制
@@ -31488,11 +31639,11 @@
求胜心 求勝心
求过于供 求過於供
求道于盲 求道於盲
-汇业 匯業
-汇业财经集团 匯業財經集團
-汇业银行 匯業銀行
-汇丰 匯豐
-汇丰银行 匯豐銀行
+汇业 滙業
+汇业财经集团 滙業財經集團
+汇业银行 滙業銀行
+汇丰 滙豐
+汇丰银行 滙豐銀行
汇付 匯付
汇价 匯價
汇信 匯信
@@ -31621,7 +31772,7 @@
汲于 汲於
汲汲于 汲汲於
汴梁 汴梁
-汹涌 洶涌
+汹涌 洶湧
汽电共生系统 汽電共生系統
汽表 汽表
汽车厂 汽車廠
@@ -31775,12 +31926,13 @@
沙参 沙蔘
沙发 沙發
沙发垫 沙發墊
+沙发床 沙發牀
沙发椅 沙發椅
-沙发牀 沙發牀
沙坑杆 沙坑桿
沙岩 沙岩
沙弥 沙彌
沙弥戒 沙彌戒
+沙河涌 沙河涌
沙洛培克 沙洛培克
沙漠生态系 沙漠生態系
沙茶面 沙茶麪
@@ -31788,6 +31940,7 @@
沙里淘金 沙裏淘金
沙雕 沙雕
沙雕赛 沙雕賽
+沙鱼涌 沙魚涌
沟谷 溝谷
没个出豁 沒個出豁
没个好结果 沒個好結果
@@ -31905,6 +32058,7 @@
河曲智叟 河曲智叟
河梁 河梁
河流汇集 河流匯集
+河涌 河涌
河涸海干 河涸海乾
河系 河系
河落海干 河落海乾
@@ -31944,7 +32098,16 @@
沽名吊誉 沽名吊譽
沽名干誉 沽名干譽
沽酒当炉 沽酒當爐
+沾临高速 霑臨高速
+沾会高速 霑會高速
+沾体 霑體
+沾化 霑化
+沾恩 霑恩
沾染控制 沾染控制
+沾洽 霑洽
+沾益 霑益
+沾衿 霑衿
+沾青线 霑青線
沿才授职 沿才授職
沿门托钵 沿門托鉢
沿门挨户 沿門挨戶
@@ -32002,10 +32165,12 @@
法术 法術
法术无边 法術無邊
法柜奇兵 法櫃奇兵
+法理 法理
法系 法系
法西斯党 法西斯黨
法语系 法語系
法身舍利 法身舍利
+法雨均沾 法雨均霑
法鲁克 法魯克
泛了 泛了
泛亚 泛亞
@@ -32093,7 +32258,7 @@
波棱菜 波棱菜
波洛克 波洛克
波浪周期 波浪週期
-波涌云乱 波涌雲亂
+波涌云乱 波湧雲亂
波状云 波狀雲
波荡 波盪
波诡云谲 波詭雲譎
@@ -32115,6 +32280,7 @@
泥板 泥板
泥板岩 泥板岩
泥涂 泥塗
+泥涌 泥涌
泥灰岩 泥灰岩
泥质岩 泥質岩
泥质页岩 泥質頁岩
@@ -32190,7 +32356,7 @@
注音法 注音法
注音符号 注音符號
泪出痛肠 淚出痛腸
-泪如泉涌 淚如泉涌
+泪如泉涌 淚如泉湧
泪容满面 淚容滿面
泪干 淚乾
泪干肠断 淚乾腸斷
@@ -32494,6 +32660,7 @@
浓雾密布 濃霧密佈
浙江天台县 浙江天台縣
浙江师范大学 浙江師範大學
+浚县 濬縣
浥注 浥注
浦发 浦發
浩克 浩克
@@ -32533,8 +32700,6 @@
浮尸 浮屍
浮托 浮托
浮松 浮鬆
-浮梁 浮樑
-浮梁县 浮樑縣
浮沈 浮沈
浮泛 浮泛
浮游 浮游
@@ -32626,7 +32791,7 @@
涂好 塗好
涂姓 涂姓
涂姓技士 塗姓技士
-涂尔干 涂爾干
+涂尔干 涂爾幹
涂层 塗層
涂居贤 涂居賢
涂山 塗山
@@ -32724,15 +32889,16 @@
涉台 涉臺
涉谷 涉谷
涉足于 涉足於
-涌出 涌出
-涌出去 涌出去
-涌出来 涌出來
-涌升流 涌升流
-涌向 涌向
-涌来 涌來
-涌现 涌現
-涌现出 涌現出
-涌进 涌進
+涌出 湧出
+涌出去 湧出去
+涌出来 湧出來
+涌升流 湧升流
+涌向 湧向
+涌尾 涌尾
+涌来 湧來
+涌现 湧現
+涌现出 湧現出
+涌进 湧進
涛生云灭 濤生雲滅
涡虫 渦蟲
涡虫纲 渦蟲綱
@@ -32844,6 +33010,7 @@
深沟墩台 深溝墩臺
深浅不同 深淺不同
深海烟囱 深海煙囪
+深涌 深涌
深渊里 深淵裏
深秋 深秋
深色系列 深色系列
@@ -32915,6 +33082,7 @@
清水烟 清水煙
清汤挂面 清湯掛麪
清浊同流 清濁同流
+清理 清理
清算斗争 清算鬥爭
清胄 清胄
清芬志 清芬志
@@ -32938,6 +33106,7 @@
渗出来 滲出來
渗出物 滲出物
渗出量 滲出量
+渝筑高速 渝筑高速
渠冲 渠衝
渡了 渡了
渡假胜地 渡假勝地
@@ -32958,6 +33127,7 @@
温度范围 溫度範圍
温度表 溫度表
温得和克 溫得和克
+温根托海 溫根托海
温祥云 溫祥雲
港制 港製
港制品 港製品
@@ -33262,6 +33432,7 @@
溢出来 溢出來
溢恶 溢惡
溥天同庆 溥天同慶
+溪涌 溪涌
溪谷 溪谷
溯游 溯游
溲面 溲麪
@@ -33332,7 +33503,7 @@
满拚自尽 滿拚自盡
满杯 滿杯
满洲里 滿洲里
-满洲里市 滿洲裏市
+满洲里市 滿洲里市
满满当当 滿滿當當
满脸溅朱 滿臉濺朱
满腹才学 滿腹才學
@@ -33478,6 +33649,7 @@
潭里 潭裏
潮力发电 潮力發電
潮烟 潮菸
+澄江 澂江
澄澹精致 澄澹精致
澎湖天后宫 澎湖天后宮
澒蒙 澒濛
@@ -33621,6 +33793,7 @@
灵谷寺 靈谷寺
灵迹 靈蹟
灸术 灸術
+灸阳谷 灸陽谷
灾后 災後
灾害链 災害鏈
灿烂多彩 燦爛多彩
@@ -33710,7 +33883,6 @@
炼贫 鍊貧
炼金 鍊金
炼金术 鍊金術
-炼金术士 煉金術士
炼钢 鍊鋼
炼钢业 鍊鋼業
炼钢厂 鍊鋼廠
@@ -34076,7 +34248,8 @@
熏蒸 燻蒸
熏蒸剂 熏蒸劑
熏蒸室 熏蒸室
-熏衣草 熏衣草
+熏衣 薰衣
+熏衣草 薰衣草
熏赫 燻赫
熏鑪 燻鑪
熏陶 薰陶
@@ -34200,8 +34373,6 @@
爷饭娘羹 爺飯孃羹
爹娘 爹孃
爽荡 爽蕩
-牀头柜 牀頭櫃
-牀头金尽 牀頭金盡
片云遮顶 片雲遮頂
片价 片價
片善小才 片善小才
@@ -34290,6 +34461,7 @@
物欲世界 物慾世界
物欲横流 物慾橫流
物流系统 物流系統
+物理 物理
物理系 物理系
物种 物種
物种来由 物種來由
@@ -34530,7 +34702,7 @@
猝发 猝發
猢狲入布袋 猢猻入布袋
猥当大任 猥當大任
-猪八戒吃人参果 豬八戒吃人參果
+猪八戒吃人参果 豬八戒喫人參果
猪只 豬隻
猪肉干 豬肉乾
猪肝面 豬肝麪
@@ -34634,6 +34806,7 @@
王秋凤 王秋鳳
王者风范 王者風範
王茂松 王茂松
+王范 王范
王蒙 王蒙
王鉴 王鑑
玛斯克 瑪斯克
@@ -34647,6 +34820,7 @@
玩出去 玩出去
玩出来 玩出來
玩团 玩團
+玩忽 翫忽
玩物丧志 玩物喪志
环保斗士 環保鬥士
环安系 環安系
@@ -34811,13 +34985,14 @@
瓦尔达克省 瓦爾達克省
瓦当 瓦當
瓦当文 瓦當文
+瓦拉干 瓦拉干
瓦松 瓦松
瓦特表 瓦特表
瓦瑞泰克 瓦瑞泰克
瓦舍 瓦舍
瓦萨里 瓦薩里
瓦西里 瓦西里
-瓦西里耶维奇 瓦西裏耶維奇
+瓦西里耶维奇 瓦西里耶維奇
瓦解云散 瓦解雲散
瓦达克 瓦達克
瓦里 瓦里
@@ -34851,7 +35026,6 @@
甜水面 甜水麪
甜萝卜 甜蘿蔔
甜面酱 甜麪醬
-甜面醬 甜麪醬
生个 生個
生了 生了
生于 生於
@@ -34868,7 +35042,8 @@
生别死离 生別死離
生力面 生力麪
生华发 生華髮
-生发 生髮
+生发 生髮 生發
+生发中心 生發中心 生髮中心
生发剂 生髮劑
生发水 生髮水
生发药 生髮藥
@@ -34891,7 +35066,7 @@
生态系统 生態系統
生情发意 生情發意
生技医药 生技醫藥
-生旦淨末丑 生旦淨末丑
+生旦净末丑 生旦淨末丑
生栋复屋 生棟覆屋
生死别离 生死別離
生死斗 生死鬥
@@ -34917,6 +35092,7 @@
生物时钟 生物時鐘
生物系 生物系
生物钟 生物鐘
+生理 生理
生理时钟 生理時鐘
生田斗 生田斗
生离死别 生離死別
@@ -34925,6 +35101,7 @@
生词表 生詞表
生迭水准 生迭水準
生锈 生鏽
+生长发育 生長發育
生长板 生長板
生面 生面
生面团 生麪糰
@@ -34966,6 +35143,7 @@
田家庵区 田家庵區
田庄 田莊
田志兴 田志興
+田梁子 田梁子
田父之获 田父之獲
田秋堇 田秋堇
田种玉 田種玉
@@ -35013,7 +35191,6 @@
电子云 電子雲
电子反制 電子反制
电子学系 電子學系
-电子布告栏 電子布告欄
电子店面 電子店面
电子数据交换 電子數據交換
电子杂志 電子雜誌
@@ -35224,6 +35401,7 @@
病愈 病癒
病毒血症 病毒血症
病毒防范 病毒防範
+病理 病理
病症 病症
病舍 病舍
病虫 病蟲
@@ -35258,6 +35436,7 @@
痰症 痰症
痲痹不了 痲痹不了
痲痺不了 痲痺不了
+痴儿 痴兒
痴呆症 癡呆症
痴念 癡念
痴虫 癡蟲
@@ -35355,7 +35534,7 @@
白板天子 白板天子
白板笔 白板筆
白果松 白果松
-白洋淀 白洋澱
+白洋淀 白洋淀
白淨面皮 白淨面皮
白烟 白煙
白皮松 白皮松
@@ -35551,8 +35730,7 @@
皓发 皓髮
皓月千里 皓月千里
皓月当空 皓月當空
-皓齿朱唇 皓齒硃脣
-皓齿朱脣 皓齒朱脣
+皓齿朱唇 皓齒朱脣
皖系军阀 皖系軍閥
皖系战败 皖系戰敗
皙面 皙面
@@ -35662,6 +35840,7 @@
盛极而衰 盛極而衰
盛行于 盛行於
盛赞 盛讚
+盜跖 盜跖
盟旗制度 盟旗制度
目前目后 目前目後
目力表 目力表
@@ -35764,7 +35943,6 @@
相须为命 相須爲命
相须而行 相須而行
盼了 盼了
-盼既示复 盼既示覆
盾板 盾板
省个 省個
省了 省了
@@ -35970,7 +36148,6 @@
短了 短了
短于 短於
短价 短價
-短几 短几
短发 短髮
短发性 短發性
短叹 短嘆
@@ -36384,6 +36561,7 @@
神杯 神杯
神游 神遊
神游太虚 神遊太虛
+神秘 神祕
神经干 神經幹
神经战术 神經戰術
神经症 神經症
@@ -36402,6 +36580,7 @@
神采飘逸 神采飄逸
神采飞扬 神采飛揚
神采骏发 神采駿發
+神里 神里
神雕 神鵰
神雕侠侣 神鵰俠侶
神雕像 神雕像
@@ -36827,6 +37006,7 @@
秒钟 秒鐘
秕谷 秕穀
秘制 祕製
+秘密 祕密
秘录 祕錄
租价 租價
租借 租借
@@ -36919,7 +37099,7 @@
稔恶不悛 稔惡不悛
稠云 稠雲
稳占 穩佔
-稳吃三注 穩吃三注
+稳吃三注 穩喫三注
稳坐钓鱼台 穩坐釣魚臺
稳定物价 穩定物價
稳当 穩當
@@ -36940,6 +37120,7 @@
穆克吉 穆克吉
穆巴拉克 穆巴拉克
穆斯坦西里 穆斯坦西里
+穆棱 穆稜
穆罕默德历 穆罕默德曆
穆罕默德历史 穆罕默德歷史
穗儿 穗兒
@@ -37182,12 +37363,14 @@
竹板书 竹板書
竹板歌 竹板歌
竹林之游 竹林之遊
+竹溪 竹谿
竹笋干 竹筍乾
竹签 竹籤
竹篱茅舍 竹籬茅舍
竹节虫 竹節蟲
竹苞松茂 竹苞松茂
竹野內丰 竹野內豐
+竺乾 竺乾
笃志 篤志
笃志好学 篤志好學
笃志爱古 篤志愛古
@@ -37234,8 +37417,7 @@
符合 符合
符合标准 符合標準
符合美国利益 符合美國利益
-符拉迪沃斯托克 符拉迪沃斯託克
-符拉迪沃斯讬克 符拉迪沃斯託克
+符拉迪沃斯托克 符拉迪沃斯托克
符采 符采
笨蛋挂 笨蛋掛
第一个 第一個
@@ -37329,6 +37511,7 @@
筑城 築城
筑堤 築堤
筑墙 築牆
+筑大高速 筑大高速
筑室 築室
筑室反耕 築室反耕
筑室道谋 築室道謀
@@ -37475,7 +37658,6 @@
算出去 算出去
算出来 算出來
算历 算曆
-算发 算髮
算得了 算得了
算术 算術
算术和 算術和
@@ -37510,6 +37692,7 @@
管干 管幹
管弦 管絃
管弦乐团 管弦樂團
+管理 管理
管理人才 管理人才
管理体制 管理體制
管理系 管理系
@@ -37556,7 +37739,7 @@
米制 米制
米卤蛋 米滷蛋
米厘米突 米釐米突
-米德尔伯里 米德爾伯裏
+米德尔伯里 米德爾伯里
米格式战斗机 米格式戰鬥機
米纳谷 米納谷
米罗的维纳斯雕像 米羅的維納斯雕像
@@ -37586,7 +37769,7 @@
粉签子 粉籤子
粉红色系 粉紅色系
粉面 粉面
-粉面朱脣 粉面硃脣
+粉面朱唇 粉面朱脣
粉面油头 粉面油頭
粉饰门面 粉飾門面
粒变岩 粒變岩
@@ -37804,6 +37987,7 @@
系风捕景 繫風捕景
系馆 系館
系马 繫馬
+紅发 紅髮
素借 素藉
素发 素髮
素志 素志
@@ -37827,10 +38011,10 @@
索托 索托
索杰纳 索傑納
索福克勒斯 索福克勒斯
-索福克里斯 索福克裏斯
+索福克里斯 索福克里斯
索里亚 索里亞
索里士 索里士
-索面 索麪
+索面 索面 索麪
索馬里 索馬里
索马里 索馬里
索马里亚 索馬里亞
@@ -37851,7 +38035,7 @@
紧随其后 緊隨其後
紫云 紫雲
紫云乡 紫雲鄉
-紫云苗族布依族自治县 紫云苗族布依族自治縣
+紫云苗族布依族自治县 紫雲苗族布依族自治縣
紫云英 紫雲英
紫台 紫臺
紫姜 紫薑
@@ -38104,7 +38288,6 @@
纺锤虫 紡錘蟲
纽几内亚 紐幾內亞
纽华克 紐華克
-纽扣 鈕釦
纽瓦克 紐瓦克
纽芬兰与拉布拉多 紐芬蘭與拉布拉多
纽蒙特 紐蒙特
@@ -38168,6 +38351,7 @@
织布机 織布機
织席 織蓆
织当访婢 織當訪婢
+织里 織里
织锦回文 織錦回文
终了 終了
终于 終於
@@ -38225,6 +38409,7 @@
经济计划 經濟計劃
经济部标准检验局 經濟部標準檢驗局
经济面 經濟面
+经理 經理
经营决策资讯系统 經營決策資訊系統
经营范围 經營範圍
经贸关系 經貿關係
@@ -38367,6 +38552,7 @@
绣阁 繡閣
绣面 繡面
绣鞋 繡鞋
+绥棱 綏稜
绦虫 絛蟲
绦虫纲 絛蟲綱
继天立极 繼天立極
@@ -38503,7 +38689,7 @@
缕当 縷當
编个 編個
编了 編了
-编余 編余
+编余 編餘
编余人员 編餘人員
编修 編修
编写出 編寫出
@@ -38639,7 +38825,6 @@
罗西里尼 羅西里尼
罗迪克 羅迪克
罗马建筑 羅馬建築
-罗马里奥 羅馬裏奧
罚不当罪 罰不當罪
罚个 罰個
罚了 罰了
@@ -38762,6 +38947,7 @@
群谋咸同 羣謀咸同
群轻折轴 羣輕折軸
群辟 羣辟
+群里 羣裏
群雕 羣雕
羹里来饭里去 羹裏來飯裏去
羽毛丰满 羽毛豐滿
@@ -39195,6 +39381,7 @@
肿瘤切除术 腫瘤切除術
胁制 脅制
胃出血 胃出血
+胃口 胃口
胃脏 胃臟
胃药 胃藥
胃药片 胃藥片
@@ -39349,8 +39536,8 @@
胡厮哄 胡廝哄
胡厮混 胡廝混
胡厮缠 胡廝纏
-胡吃海喝 胡吃海喝
-胡吃闷睡 胡吃悶睡
+胡吃海喝 胡喫海喝
+胡吃闷睡 胡喫悶睡
胡同 衚衕
胡吣 胡唚
胡吹 胡吹
@@ -39670,12 +39857,6 @@
脚踏板 腳踏板
脚酸 腳痠
脚面 腳面
-脣似抹朱 脣似抹硃
-脣如涂朱 脣如塗朱
-脣彩盘 脣彩盤
-脣若抹朱 脣若抹硃
-脣若涂朱 脣若塗硃
-脣若涂脂 脣若塗脂
脱不了 脫不了
脱不了身 脫不了身
脱了 脫了
@@ -39988,7 +40169,6 @@
舌后 舌後
舌尖后音 舌尖後音
舌干唇焦 舌乾脣焦
-舌干脣焦 舌乾脣焦
舌面 舌面
舌面元音 舌面元音
舌面前音 舌面前音
@@ -40213,6 +40393,9 @@
艾里亚森 艾里亞森
艾里斯 艾里斯
艾里森 艾里森
+艾里西 艾里西
+艾里西湖 艾里西湖
+艾里西湖镇 艾里西湖鎮
艾里赛宫 艾里賽宮
节余 節餘
节制 節制
@@ -40220,6 +40403,7 @@
节奏布鲁斯 節奏布魯斯
节录 節錄
节录自 節錄自
+节日里 節日裏
节欲 節慾
节流踏板 節流踏板
节目表 節目表
@@ -40333,7 +40517,7 @@
苏丽文 蘇麗文
苏乐明 蘇樂明
苏乐桃 蘇樂桃
-苏仙区 甦仙區
+苏仙区 蘇仙區
苏伊士 蘇伊士
苏伊士河 蘇伊士河
苏伊士运河 蘇伊士運河
@@ -40366,8 +40550,9 @@
苏子油 蘇子油
苏宁 蘇寧
苏宁电器 蘇寧電器
-苏家屯 甦家屯
-苏家屯区 甦家屯區
+苏家 蘇家
+苏家屯 蘇家屯
+苏家屯区 蘇家屯區
苏家明 蘇家明
苏富比 蘇富比
苏富比公司 蘇富比公司
@@ -40397,8 +40582,6 @@
苏建忠 蘇建忠
苏建荣 蘇建榮
苏式 蘇式
-苏彝士 蘇彝士
-苏彝士运河 蘇彝士運河
苏德曼 蘇德曼
苏必利尔湖 蘇必利爾湖
苏必略湖 蘇必略湖
@@ -40650,7 +40833,9 @@
范公偁 范公偁
范公堤 范公堤
范冰冰 范冰冰
+范县 范縣
范可钦 范可欽
+范各庄 范各莊
范哈能 范哈能
范嘉骅 范嘉驊
范围 範圍
@@ -40664,15 +40849,18 @@
范围查询 範圍查詢
范围调整 範圍調整
范国铨 范國銓
+范坝 范壩
范增 范增
范士丹 范士丹
范姜 范姜
范字 範字
-范家谦 范家謙
+范家 范家
范宽 范寬
+范寨 范寨
范小姐 范小姐
范尼斯特鲁伊 范尼斯特魯伊
范履霜 范履霜
+范岗 范崗
范式 範式
范张鸡黍 范張雞黍
范德林特 范德林特
@@ -40700,8 +40888,11 @@
范晓萱 范曉萱
范晔 范曄
范本 範本
+范村 范村
+范桥 范橋
范植伟 范植偉
范植谷 范植谷
+范楼 范樓
范欣妤 范欣妤
范正祥 范正祥
范洪森 范洪森
@@ -40720,13 +40911,19 @@
范纲武 范綱武
范织钦 范織欽
范绮馨 范綺馨
+范罗山 范羅山
范范之辈 范範之輩
+范营 范營
范蠡 范蠡
范进 范進
范逸臣 范逸臣
+范里 范里
范金 範金
+范鎮 范鎮
+范镇 范鎮
范阳 范陽
范陈柏 范陳柏
+范集 范集
范雎 范雎
范靖瑶 范靖瑤
茄二十八星瓢虫 茄二十八星瓢蟲
@@ -40979,7 +41176,6 @@
药膏 藥膏
药膛 藥膛
药膳 藥膳
-药舖 藥舖
药茶 藥茶
药草 藥草
药草茶 藥草茶
@@ -41143,7 +41339,7 @@
菲尼克斯 菲尼克斯
菲德烈克 菲德烈克
菲才寡学 菲才寡學
-菲舍尔 菲捨爾
+菲舍尔 菲舍爾
菲茨杰拉德 菲茨傑拉德
菲衣恶食 菲衣惡食
萌发 萌發
@@ -41255,6 +41451,7 @@
葱胡子 蔥鬍子
葱葱郁郁 蔥蔥郁郁
葱郁 蔥鬱
+葵涌 葵涌
蒂森克虏伯 蒂森克虜伯
蒋国梁 蔣國樑
蒋干 蔣幹
@@ -41568,7 +41765,7 @@
虫儿 蟲兒
虫出 蟲出
虫卵 蟲卵
-虫吃牙 蟲吃牙
+虫吃牙 蟲喫牙
虫声 蟲聲
虫媒病毒 蟲媒病毒
虫媒花 蟲媒花
@@ -41626,6 +41823,7 @@
蚕种 蠶種
蚕豆症 蠶豆症
蚜虫 蚜蟲
+蚝涌 蠔涌
蚵仔面线 蚵仔麪線
蛀虫 蛀蟲
蛆虫 蛆蟲
@@ -41661,7 +41859,7 @@
蜂午并起 蜂午並起
蜂后 蜂后
蜂巢式行动电话系统 蜂巢式行動電話系統
-蜂涌而出 蜂涌而出
+蜂涌而出 蜂湧而出
蜂蒙 蜂蒙
蜂蜡 蜂蠟
蜗杆 蝸桿
@@ -41811,7 +42009,7 @@
衅钟 釁鐘
衅面 釁面
行万里路 行萬里路
-行万里路胜读万卷书 行萬裏路勝讀萬捲書
+行万里路胜读万卷书 行萬里路勝讀萬捲書
行万里路读万卷书 行萬里路讀萬卷書
行不苟合 行不苟合
行业别 行業別
@@ -41840,7 +42038,7 @@
行凶者 行兇者
行动党 行動黨
行动计划 行動計劃
-行千里路读万卷书 行千裏路讀萬卷書
+行千里路读万卷书 行千里路讀萬卷書
行卷 行卷
行台 行臺
行合趋同 行合趨同
@@ -41882,6 +42080,7 @@
行雨朝云 行雨朝雲
衍声复词 衍聲複詞
衍极 衍極
+衍生 衍生
衍生出 衍生出
衍生出来 衍生出來
衔哀致诚 銜哀致誠
@@ -42273,6 +42472,7 @@
西岳 西嶽
西征 西征
西文系 西文系
+西斗铺 西斗鋪
西方极乐 西方極樂
西方极乐世界 西方極樂世界
西晒 西曬
@@ -42284,6 +42484,7 @@
西格蒙德 西格蒙德
西欧集团 西歐集團
西洋参 西洋參
+西涌 西涌
西游 西遊
西游补 西遊補
西游记 西遊記
@@ -42469,7 +42670,7 @@
角膜移植术 角膜移植術
角色冲突 角色衝突
角色扮演游戏 角色扮演遊戲
-角落发 角落發
+角落 角落
角落里 角落裏
角谷猜想 角谷猜想
角里 角里
@@ -42596,6 +42797,7 @@
计穷力尽 計窮力盡
计穷力极 計窮力極
计穷虑极 計窮慮極
+计算 計算
计算出 計算出
计算出来 計算出來
计算机制图 計算機製圖
@@ -42999,7 +43201,7 @@
读万卷书 讀萬卷書
读万卷书行万里路 讀萬卷書行萬里路
读不舍手 讀不捨手
-读书三余 讀書三余
+读书三余 讀書三餘
读书种子 讀書種子
读了 讀了
读出 讀出
@@ -43007,8 +43209,8 @@
读后 讀後
读后心得 讀後心得
读后感 讀後感
+读唇术 讀脣術
读心术 讀心術
-读脣术 讀脣術
课余 課餘
课前课后 課前課後
课卷 課卷
@@ -43151,8 +43353,8 @@
谷垣 谷垣
谷垣祯 谷垣禎
谷垣祯一 谷垣禎一
-谷城 谷城
-谷城县 谷城縣
+谷城 穀城
+谷城县 穀城縣
谷壁 谷壁
谷壳 穀殼
谷子 穀子
@@ -43191,6 +43393,14 @@
谷贵饿农谷贱伤农 穀貴餓農穀賤傷農
谷道 穀道
谷都 谷都
+谷里 谷里
+谷里街道 谷里街道
+谷阳 穀陽 谷陽
+谷阳县 穀陽縣 谷陽縣
+谷阳竖 穀陽豎
+谷阳街道 谷陽街道
+谷阳郡 穀陽郡
+谷阳镇 穀陽鎮 谷陽鎮
谷雨 穀雨
谷风 穀風 谷風
谷食 穀食
@@ -43401,6 +43611,8 @@
贵戚 貴戚
贵极人臣 貴極人臣
贵游子弟 貴遊子弟
+贵筑 貴筑
+贵筑县 貴筑縣
贵胄 貴胄
贵贱之别 貴賤之別
贷个 貸個
@@ -43419,10 +43631,10 @@
费尔干纳盆地 費爾幹納盆地
费尔法克斯 費爾法克斯
费尽 費盡
+费尽唇舌 費盡脣舌
费尽心思 費盡心思
费尽心机 費盡心機
费尽精神 費盡精神
-费尽脣舌 費盡脣舌
费杰罗 費傑羅
费洛蒙 費洛蒙
费玛最后定理 費瑪最後定理
@@ -43469,6 +43681,7 @@
资方代表 資方代表
资治通鉴 資治通鑑
资源回收 資源回收
+资溪 資谿
资管系 資管系
资讯学系 資訊學系
资讯系 資訊系
@@ -43802,6 +44015,9 @@
跑回来 跑回來
跑得了和尚跑不了庙 跑得了和尚跑不了廟
跑表 跑表
+跖犬吠尧 跖犬吠堯
+跖狗吠尧 跖狗吠堯
+跖蹻 跖蹻
跗注 跗注
跗面 跗面
跛行症 跛行症
@@ -43912,6 +44128,7 @@
蹭棱子 蹭棱子
蹲了 蹲了
蹲板 蹲板
+蹻跖 蹻跖
躁狂抑郁症 躁狂抑鬱症
躁狂症 躁狂症
躁郁 躁鬱
@@ -44217,6 +44434,7 @@
辩论术 辯論術
辫发 辮髮
辫穗头 辮穗頭
+辰溪 辰谿
辱游 辱游
边修 邊修
边境冲突 邊境衝突
@@ -44347,6 +44565,7 @@
近朱近墨 近朱近墨
近水楼台 近水樓臺
近视眼生了瞎子 近視眼生了瞎子
+返佣 返佣
返台 返臺
返吟复吟 返吟復吟
返回 返回
@@ -44466,7 +44685,7 @@
远志 遠志
远恶 遠惡
远房亲戚 遠房親戚
-远打周折 遠打週折
+远打周折 遠打周折
远期外汇 遠期外匯
远水救不了近火 遠水救不了近火
远游 遠遊
@@ -44792,6 +45011,7 @@
通联记录 通聯記錄
通讯录 通訊錄
通讯系统 通訊系統
+通车里程 通車里程
通过事后 通過事後
通鉴 通鑑
逛了 逛了
@@ -44889,6 +45109,7 @@
道合志同 道合志同
道同志合 道同志合
道听涂说 道聽塗說
+道咸 道咸
道尔顿制 道爾頓制
道尽 道盡
道尽涂殚 道盡塗殫
@@ -44974,7 +45195,7 @@
邢台市 邢臺市
那个 那個
那个人 那個人
-那个猫儿不吃腥 那個貓兒不吃腥
+那个猫儿不吃腥 那個貓兒不喫腥
那个耗子不偷油 那個耗子不偷油
那么 那麼
那么干 那麼幹
@@ -45126,7 +45347,7 @@
部发 部發
部曲 部曲
部胡林 部胡林
-部落发 部落發
+部落 部落
部落同盟 部落同盟
郭勇志 郭勇志
郭台成 郭臺成
@@ -45480,11 +45701,15 @@
里手 裏手
里扣 里扣
里拉 里拉
+里挑一 裏挑一
里斯 里斯
里斯本 里斯本
里昂 里昂
里昂市 里昂市
里昂队 里昂隊
+里望 里望
+里望乡 里望鄉
+里木店 里木店
里根 里根
里欧 里歐
里欧斯 里歐斯
@@ -45500,6 +45725,7 @@
里特维宁科 里特維寧科
里瓦几亚条约 里瓦幾亞條約
里瓦尔多 裏瓦爾多
+里甲 里甲
里社 里社
里科 里科
里程 里程
@@ -45754,6 +45980,7 @@
鉴赏能力 鑑賞能力
鉴频 鑑頻
鉴频器 鑑頻器
+銀发 銀髮
针关 鍼關
针具 針具
针刺 針刺
@@ -45819,6 +46046,7 @@
针锋 針鋒
针锋相对 針鋒相對
针锋相投 針鋒相投
+针阳谷 鍼陽谷
针饵莫减 針餌莫減
针骨 針骨
针鱼 針魚
@@ -45908,6 +46136,7 @@
钟祥县 鍾祥縣
钟祥市 鍾祥市
钟福松 鐘福松
+钟离 鍾離
钟纽 鐘紐
钟罩 鐘罩
钟腰 鐘腰
@@ -46269,16 +46498,18 @@
长卷 長卷
长历 長曆
长发 長髮
+长发屯 長發屯
+长发镇 長發鎮
长叹 長嘆
长吁 長吁
长吁短叹 長吁短嘆
长君之恶 長君之惡
-长坂坡七进七出 長阪坡七進七出
长头布 長頭布
长寿烟 長壽菸
长寿面 長壽麪
长干巷 長干巷
长干曲 長干曲
+长干里 長干里
长征 長征
长征军 長征軍
长恶不悛 長惡不悛
@@ -46306,7 +46537,7 @@
长须 長鬚
长须鲸 長鬚鯨
长风万里 長風萬里
-開發周期 開發周期
+開發周期 開發週期
门前门后 門前門後
门吊儿 門吊兒
门帘 門簾
@@ -46404,9 +46635,10 @@
间奏曲 間奏曲
间接证据 間接證據
间深里 間深裏
+间里 間裏
闵凶 閔凶
闵子里 閔子裏
-闵采尔 閔採爾
+闵采尔 閔采爾
闷出 悶出
闷在心里 悶在心裏
闷板 悶板
@@ -46522,8 +46754,9 @@
阳电极 陽電極
阳秋 陽秋
阳虚发热 陽虛發熱
-阳谷 陽谷
-阳谷县 陽谷縣
+阳谷 陽穀 陽谷
+阳谷县 陽穀縣
+阳谷穴 陽谷穴
阳面 陽面
阴丹布 陰丹布
阴云 陰雲
@@ -46647,6 +46880,7 @@
阿森松岛 阿森松島
阿波罗计划 阿波羅計劃
阿滋海默症 阿滋海默症
+阿热勒托别 阿熱勒托別
阿瓦里德 阿瓦里德
阿秋 阿秋
阿米巴原虫 阿米巴原蟲
@@ -46796,6 +47030,7 @@
陕西师范大学 陝西師範大學
陕飞集团 陝飛集團
陡然升高 陡然升高
+院子里 院子裏
院系 院系
院里 院裏
除不尽 除不盡
@@ -46926,7 +47161,7 @@
雅克萨 雅克薩
雅库次克 雅庫次克
雅游 雅游
-雅筑 雅筑
+雅筑 雅筑 雅築
雅致 雅緻
雅舍 雅舍
雅范 雅範
@@ -47064,6 +47299,7 @@
雨约云期 雨約雲期
雨花台 雨花臺
雨花台区 雨花臺區
+雨露均沾 雨露均霑
雨魄云魂 雨魄雲魂
雩坛 雩壇
雪松 雪松
@@ -47562,7 +47798,7 @@
面霜 面霜
面露不悦 面露不悅
面霸 麪霸
-面青脣白 面青脣白
+面青唇白 面青脣白
面面 面面
面面俱全 面面俱全
面面俱到 面面俱到
@@ -47584,9 +47820,9 @@
面首 面首
面驾 面駕
面黄 面黃
+面黄唇白 面黃脣白
面黄肌瘦 面黃肌瘦
面黄肌闳 面黃肌閎
-面黄脣白 面黃脣白
革出 革出
革出山门 革出山門
革出教门 革出教門
@@ -47832,6 +48068,7 @@
颜面神经 顏面神經
颜面角 顏面角
颜面骨 顏面骨
+额发 額髮
额征 額徵
额我略历 額我略曆
额我略历史 額我略歷史
@@ -47916,7 +48153,7 @@
风药 風藥
风虎云龙 風虎雲龍
风起云布 風起雲布
-风起云涌 風起雲涌
+风起云涌 風起雲湧
风起云蒸 風起雲蒸
风轻云淡 風輕雲淡
风轻云淨 風輕雲淨
@@ -47932,7 +48169,7 @@
风险防范 風險防範
风雨同舟 風雨同舟
风雨欲来 風雨欲來
-风靡云涌 風靡雲涌
+风靡云涌 風靡雲湧
风靡云蒸 風靡雲蒸
风飞云会 風飛雲會
风马云车 風馬雲車
@@ -48114,7 +48351,7 @@
香愿 香願
香斗 香斗
香格里拉 香格里拉
-香格里拉县 香格裏拉縣
+香格里拉县 香格里拉縣
香格里拉怡咖啡 香格里拉怡咖啡
香榭丽舍 香榭麗舍
香榭丽舍大街 香榭麗舍大街
@@ -48347,7 +48584,7 @@
高发 高發
高台 高臺
高台县 高臺縣
-高周波 高周波
+高周波 高週波
高唱入云 高唱入雲
高坛 高壇
高处不胜寒 高處不勝寒
@@ -48494,6 +48731,7 @@
鲇鱼 鮎魚
鲋鱼困涸辙难待西江水 鮒魚困涸轍難待西江水
鲍德里亚 鮑德里亞
+鲗鱼涌 鰂魚涌
鲜于 鮮于
鲜彩 鮮彩
鲜明个性 鮮明個性
@@ -48548,6 +48786,7 @@
鸦片烟 鴉片煙
鸦窝里出凤凰 鴉窩裏出鳳凰
鸭子划水 鴨子划水
+鸭跖草 鴨跖草
鸳鸯折颈 鴛鴦折頸
鸷虫 鷙蟲
鸿志 鴻志
@@ -48646,6 +48885,7 @@
麻栗坡 麻栗坡
麻栗坡县 麻栗坡縣
麻油厂 麻油廠
+麻涌 麻涌
麻痹不了 麻痹不了
麻痺不了 麻痺不了
麻胡 麻胡
@@ -48701,6 +48941,7 @@
黄曲霉毒素 黃麴黴毒素
黄曲霉菌 黃麴黴菌
黄有才 黃有才
+黄松 黃松
黄梁 黃梁
黄梁梦 黃梁夢
黄梁美梦 黃樑美夢
@@ -48749,11 +48990,14 @@
黄鹰抓住了鹞子的脚 黃鷹抓住了鷂子的腳
黉舍 黌舍
黍谷生春 黍谷生春
+黎托 黎托
+黎托街道 黎托街道
黎明前的黑暗 黎明前的黑暗
黎曼几何 黎曼幾何
黎曼几何学 黎曼幾何學
黎曼曲面 黎曼曲面
黎曼面 黎曼面
+黎涌 黎涌
黏了 黏了
黏合 黏合
黏合剂 黏合劑
@@ -48839,6 +49083,7 @@
鼓面 鼓面
鼠得克 鼠得克
鼠曲草 鼠麴草
+鼠标里面 鼠標裏面
鼠疫杆菌 鼠疫桿菌
鼠肝虫臂 鼠肝蟲臂
鼠药 鼠藥
@@ -48904,8 +49149,8 @@
龙嵩叶 龍嵩葉
龙斗虎伤 龍鬥虎傷
龙无云而不行 龍無雲而不行
-龙游 龍遊
-龙游县 龍遊縣
+龙游 龍游
+龙游县 龍游縣
龙游浅水 龍游淺水
龙烟铁矿 龍煙鐵礦
龙眼干 龍眼乾
@@ -48915,8 +49160,8 @@
龙虎并伏 龍虎並伏
龙虎斗 龍虎鬥
龙虾面 龍蝦麪
-龙里 龍裏
-龙里县 龍裏縣
+龙里 龍里
+龙里县 龍里縣
龙钟 龍鍾
龙门吊 龍門吊
龙须 龍鬚
diff --git a/data/dictionary/TSCharacters.txt b/data/dictionary/TSCharacters.txt
index ef0629dc9..a23651457 100644
--- a/data/dictionary/TSCharacters.txt
+++ b/data/dictionary/TSCharacters.txt
@@ -11,7 +11,7 @@
㗿 𪡛
㘉 𠰱
㘓 𪢌
-㘔 㗷
+㘔 𫬐
㘚 㘎
㛝 𫝦
㜄 㚯
@@ -23,6 +23,7 @@
㞞 𪨊
㟺 𪩇
㠏 㟆
+㠣 𫵷
㢗 𪪑
㢝 𢋈
㥮 㤘
@@ -88,6 +89,7 @@
䍽 𦍠
䎙 𫅭
䎱 䎬
+䓣 𬜯
䕤 𫟕
䕳 𦰴
䖅 𫟑
@@ -120,6 +122,7 @@
䥄 𫠀
䥇 䦂
䥑 鿏
+䥕 𬭯
䥗 𫔋
䥩 𨱖
䥯 𫔆
@@ -193,30 +196,15 @@
䵴 𫜙
䶕 𫜨
䶲 𫜳
-万 万
-丑 丑
丟 丢
並 并
-丰 丰
-么 么
乾 干 乾
亂 乱
-了 了
-于 于
-云 云
亙 亘
亞 亚
-仆 仆
-仇 仇
-价 价
-仿 仿
-伙 伙
佇 伫
佈 布
佔 占
-余 余
-佛 佛
-佣 佣
併 并
來 来
侖 仑
@@ -224,13 +212,11 @@
侷 局
俁 俣
係 系
-俊 俊
俓 𠇹
俔 伣
俠 侠
俥 伡
俬 私
-修 修
倀 伥
倆 俩
倈 俫
@@ -238,7 +224,6 @@
個 个
們 们
倖 幸
-借 借
倫 伦
倲 㑈
偉 伟
@@ -265,10 +250,10 @@
僑 侨
僕 仆
僞 伪
+僤 𫢸
僥 侥
僨 偾
僱 雇
-僵 僵
價 价
儀 仪
儁 俊
@@ -292,35 +277,24 @@
儻 傥
儼 俨
兇 凶
-克 克
兌 兑
兒 儿
兗 兖
-党 党
內 内
兩 两
冊 册
冑 胄
冪 幂
-冬 冬
-准 准
凈 净
-凌 凌
凍 冻
凙 𪞝
凜 凛
-几 几
凱 凯
-凶 凶
-出 出
-划 划
別 别
刪 删
-刮 刮
-制 制
剄 刭
則 则
-剋 克
+剋 克 剋
剎 刹
剗 刬
剛 刚
@@ -358,17 +332,10 @@
匯 汇
匱 匮
區 区
-千 千
-升 升
協 协
-卜 卜
-占 占
-卷 卷
卹 恤
卻 却
卽 即
-厂 厂
-厘 厘
厙 厍
厠 厕
厤 历
@@ -378,37 +345,21 @@
參 参
叄 叁
叢 丛
-只 只
-台 台
-叶 叶
-吁 吁
-合 合
-吊 吊
-同 同
-后 后
-向 向
吒 咤
吳 吴
吶 呐
呂 吕
-周 周
-咨 咨
-咸 咸
咼 呙
-咽 咽
-哄 哄
員 员
哯 𠯟
唄 呗
唓 𪠳
-唚 吣
唸 念
問 问
啓 启
啞 哑
啟 启
啢 唡
-喂 喂
喎 㖞
喚 唤
喪 丧
@@ -442,7 +393,7 @@
嘸 呒
嘺 𪡀
嘽 啴
-噁 恶
+噁 恶 𫫇
噅 𠯠
噓 嘘
噚 㖊
@@ -451,7 +402,6 @@
噠 哒
噥 哝
噦 哕
-噪 噪
噯 嗳
噲 哙
噴 喷
@@ -484,9 +434,7 @@
囌 苏
囑 嘱
囒 𪢠
-回 回
囪 囱
-困 困
圇 囵
國 国
圍 围
@@ -495,9 +443,9 @@
圖 图
團 团
圞 𪢮
-坐 坐
-垵 埯
+垻 坝
埡 垭
+埨 𫭢
埬 𪣆
埰 采
執 执
@@ -518,10 +466,12 @@
塢 坞
塤 埙
塵 尘
+塸 𫭟
塹 堑
塿 𪣻
墊 垫
墜 坠
+墠 𫮃
墮 堕
墰 坛
墲 𪢸
@@ -552,8 +502,7 @@
壽 寿
夠 够
夢 梦
-夥 伙
-夸 夸
+夥 伙 夥
夾 夹
奐 奂
奧 奥
@@ -561,13 +510,11 @@
奪 夺
奬 奖
奮 奋
-奸 奸
奼 姹
妝 妆
姍 姗
-姜 姜
姦 奸
-娘 娘
+娙 𫰛
娛 娱
婁 娄
婡 𫝫
@@ -613,7 +560,6 @@
孾 𪧀
孿 孪
宮 宫
-家 家
寀 采
寠 𪧘
寢 寝
@@ -630,8 +576,6 @@
對 对
導 导
尷 尴
-尸 尸
-局 局
屆 届
屍 尸
屓 屃
@@ -642,7 +586,6 @@
屩 𪨗
屬 属
岡 冈
-岩 岩
峯 峰
峴 岘
島 岛
@@ -656,6 +599,7 @@
嵐 岚
嵗 岁
嵼 𡶴
+嵽 𫶇
嵾 㟥
嶁 嵝
嶄 崭
@@ -669,7 +613,6 @@
嶧 峄
嶨 峃
嶮 崄
-嶴 岙
嶸 嵘
嶹 𫝵
嶺 岭
@@ -682,14 +625,10 @@
巖 岩
巗 𪨷
巘 𪩘
-巨 巨
巰 巯
巹 卺
-布 布
-帘 帘
帥 帅
師 师
-席 席
帳 帐
帶 带
幀 帧
@@ -703,15 +642,9 @@
幩 𪩸
幫 帮
幬 帱
-干 干
-幸 幸
幹 干
-幺 幺
幾 几
-广 广
-座 座
庫 库
-庵 庵
廁 厕
廂 厢
廄 厩
@@ -720,6 +653,7 @@
廕 荫
廚 厨
廝 厮
+廞 𫷷
廟 庙
廠 厂
廡 庑
@@ -731,37 +665,31 @@
廳 厅
弒 弑
弔 吊
-弦 弦
弳 弪
張 张
強 强
彃 𪪼
+彄 𫸩
彆 别
彈 弹
彌 弥
彎 弯
彔 录
彙 汇
-彞 彝
彠 彟
彥 彦
-彩 彩
彫 雕
彲 彨
彷 彷 仿
彿 佛
-征 征
後 后
徑 径
從 从
徠 徕
-御 御
復 复
徵 征 徵
徹 彻
徿 𪫌
-志 志
-念 念
恆 恒
恥 耻
悅 悦
@@ -773,7 +701,6 @@
惱 恼
惲 恽
惻 恻
-愈 愈
愛 爱
愜 惬
愨 悫
@@ -781,7 +708,6 @@
愷 恺
愻 𢙏
愾 忾
-愿 愿
慄 栗
態 态
慍 愠
@@ -834,30 +760,18 @@
戀 恋
戇 戆
戔 戋
-戚 戚
戧 戗
戩 戬
戰 战 𢧐
戱 戯
戲 戏
戶 户
-才 才
-扎 扎
-托 托
-扣 扣
-折 折
拋 抛
-拐 拐
-拚 拚
-挂 挂
-挨 挨
挩 捝
挱 挲
-挽 挽
挾 挟
捨 舍
捫 扪
-据 据
捱 挨
捲 卷
掃 扫
@@ -876,7 +790,6 @@
損 损
搖 摇
搗 捣
-搜 搜
搵 揾
搶 抢
摋 𢫬
@@ -915,7 +828,6 @@
據 据
擟 𪭧
擠 挤
-擡 抬
擣 捣 𢭏
擫 𢬍
擬 拟
@@ -956,21 +868,20 @@
斅 𢽾
斆 敩
斕 斓
-斗 斗
斬 斩
斷 断
斸 𣃁
於 于 於
旂 旗
旣 既
-昆 昆
昇 升
時 时
晉 晋
+晛 𬀪
晝 昼
暈 晕
暉 晖
-暗 暗
+暐 𬀩
暘 旸
暢 畅
暫 暂
@@ -985,36 +896,22 @@
曥 𣆐
曨 昽
曬 晒
-曲 曲
書 书
會 会
朥 𦛨
朧 胧
朮 术
-朱 朱
-朴 朴
-杆 杆
-杠 杠
-杯 杯
-杰 杰
東 东
-杴 锨
-松 松
-板 板
-极 极
枴 拐
-柜 柜
柵 栅
柺 拐
査 查
-栗 栗
-核 核
桱 𣐕
桿 杆
-梁 梁
梔 栀
梖 𪱷
梘 枧
+梜 𬂩
條 条
梟 枭
梲 棁
@@ -1025,7 +922,6 @@
棟 栋
棡 㭎
棧 栈
-棱 棱
棲 栖
棶 梾
椏 桠
@@ -1091,9 +987,9 @@
檵 𪲛
檸 柠
檻 槛
-檾 𦼖
櫃 柜
櫅 𪲎
+櫍 𬃊
櫓 橹
櫚 榈
櫛 栉
@@ -1110,7 +1006,6 @@
櫱 蘖
櫳 栊
櫸 榉
-櫺 棂
櫻 樱
欄 栏
欅 榉
@@ -1125,7 +1020,6 @@
欖 榄
欘 𣚚
欞 棂
-欲 欲
欽 钦
歎 叹
歐 欧
@@ -1165,22 +1059,17 @@
汎 泛
汙 污
決 决
-沈 沈 沉
沒 没
沖 冲
況 况
-泛 泛
泝 溯
-注 注
洩 泄
洶 汹
浹 浃
-涂 涂
+浿 𬇙
涇 泾
-涌 涌
涗 涚
涼 凉
-淀 淀
淒 凄
淚 泪
淥 渌
@@ -1195,7 +1084,6 @@
渢 沨
渦 涡
測 测
-游 游
渾 浑
湊 凑
湋 𣲗
@@ -1225,7 +1113,7 @@
滿 满
漁 渔
漊 溇
-漓 漓
+漍 𬇹
漚 沤
漢 汉
漣 涟
@@ -1257,6 +1145,7 @@
澤 泽
澦 滪
澩 泶
+澫 𬇕
澬 𫞚
澮 浍
澱 淀
@@ -1331,19 +1220,21 @@
熅 煴
熉 𤈶
熌 𤇄
-熏 熏
熒 荧
熓 𤆡
熗 炝
熚 𤇹
熡 𤋏
+熰 𬉼
熱 热
熲 颎
熾 炽
+燀 𬊤
燁 烨
燈 灯
燉 炖
燒 烧
+燖 𬊈
燙 烫
燜 焖
營 营
@@ -1423,6 +1314,8 @@
瑽 𪻐
璉 琏
璊 𫞩
+璕 𬍤
+璗 𬍡
璝 𪻺
璡 琎
璣 玑
@@ -1435,14 +1328,15 @@
璼 𫞨
璽 玺
璾 𫞦
+璿 璇
瓄 𪻨
+瓅 𬍛
瓊 琼
瓏 珑
瓔 璎
瓕 𤦀
瓚 瓒
瓛 𤩽
-瓮 瓮
甌 瓯
甕 瓮
產 产
@@ -1458,7 +1352,6 @@
畼 𪽈
疇 畴
疊 叠
-症 症
痙 痉
痠 酸
痮 𪽪
@@ -1519,7 +1412,6 @@
睏 困
睜 睁
睞 睐
-睪 睾 睪
瞘 眍
瞜 䁖
瞞 瞒
@@ -1532,13 +1424,11 @@
矑 𪾦
矓 眬
矚 瞩
-矩 矩
矯 矫
硃 朱
硜 硁
硤 硖
硨 砗
-确 确
硯 砚
碕 埼
碙 𥐻
@@ -1559,6 +1449,7 @@
礄 硚
礆 硷
礎 础
+礐 𬒈
礒 𥐟
礙 碍
礦 矿
@@ -1569,7 +1460,6 @@
礱 砻
祇 祇 只
祕 秘
-祘 祘
祿 禄
禍 祸
禎 祯
@@ -1581,10 +1471,7 @@
禰 祢
禱 祷
禿 秃
-私 私
秈 籼
-秋 秋
-种 种
稅 税
稈 秆
稏 䅉
@@ -1597,7 +1484,6 @@
穌 稣
積 积
穎 颖
-穗 穗
穠 秾
穡 穑
穢 秽
@@ -1622,7 +1508,6 @@
競 竞
筆 笔
筍 笋
-筑 筑
筧 笕
筴 䇲
箇 个
@@ -1635,6 +1520,7 @@
篔 筼
篘 𥬠
篠 筿
+篢 𬕂
篤 笃
篩 筛
篳 筚
@@ -1678,10 +1564,10 @@
糶 粜
糹 纟
糺 𫄙
-系 系
糾 纠
紀 纪
紂 纣
+紃 𬘓
約 约
紅 红
紆 纡
@@ -1702,11 +1588,11 @@
紛 纷
紜 纭
紝 纴
+紞 𬘘
紟 𫄛
紡 纺
紬 䌷
紮 扎
-累 累
細 细
紱 绂
紲 绁
@@ -1737,6 +1623,7 @@
給 给
絧 𫄡
絨 绒
+絪 𬘡
絰 绖
統 统
絲 丝
@@ -1747,24 +1634,29 @@
綀 𦈌
綁 绑
綃 绡
+綄 𬘫
綆 绠
綇 𦈋
綈 绨
綉 绣
綋 𫟄
綌 绤
+綎 𬘩
綏 绥
綐 䌼
綑 捆
經 经
綖 𫄧
綜 综
+綝 𬘭
綞 缍
綟 𫄫
綠 绿
綡 𫟅
綢 绸
綣 绻
+綧 𬘯
+綪 𬘬
綫 线
綬 绶
維 维
@@ -1838,6 +1730,7 @@
縬 𦈚
縭 缡
縮 缩
+縯 𬙂
縰 𫄳
縱 纵
縲 缧
@@ -1857,7 +1750,7 @@
繆 缪
繈 𫄶
繏 𦈝
-繐 穗
+繐 𰬸
繒 缯
繓 𦈛
織 织
@@ -1887,6 +1780,7 @@
繾 缱
繿 䍀
纁 𫄸
+纆 𬙊
纇 颣
纈 缬
纊 纩
@@ -1895,6 +1789,7 @@
纏 缠
纓 缨
纔 才
+纕 𬙋
纖 纤
纗 𫄹
纘 缵
@@ -1919,6 +1814,7 @@
羵 𫅗
羶 膻
習 习
+翫 玩
翬 翚
翹 翘
翽 翙
@@ -1938,9 +1834,6 @@
聽 听
聾 聋
肅 肃
-肴 肴
-胜 胜
-胡 胡
脅 胁
脈 脉
脛 胫
@@ -1949,8 +1842,6 @@
脩 修
脫 脱
脹 胀
-腊 腊
-腌 腌
腎 肾
腖 胨
腡 脶
@@ -1981,13 +1872,11 @@
臢 臜
臥 卧
臨 临
-致 致
臺 台
與 与
興 兴
舉 举
舊 旧
-舍 舍
舘 馆
艙 舱
艣 𫇛
@@ -1998,16 +1887,13 @@
艷 艳
芻 刍
苧 苎
-苹 苹
-范 范
茲 兹
荊 荆
-荐 荐
莊 庄
莖 茎
莢 荚
莧 苋
-菕 芲
+菕 𰰨
華 华
菴 庵
菸 烟
@@ -2018,7 +1904,6 @@
萵 莴
葉 叶
葒 荭
-著 著
葝 𫈎
葤 荮
葦 苇
@@ -2029,7 +1914,6 @@
蒓 莼
蒔 莳
蒕 蒀
-蒙 蒙
蒞 莅
蒭 𫇴
蒼 苍
@@ -2041,7 +1925,7 @@
蓯 苁
蓴 莼
蓽 荜
-蔑 蔑
+蔄 𬜬
蔔 卜
蔘 参
蔞 蒌
@@ -2077,7 +1961,6 @@
薟 莶
薦 荐
薩 萨
-薰 薰 熏
薳 䓕
薴 苧
薵 䓓
@@ -2100,7 +1983,7 @@
蘆 芦
蘇 苏
蘊 蕴
-蘋 苹 蘋
+蘋 苹 𬞟
蘚 藓
蘞 蔹
蘟 𦻕
@@ -2109,17 +1992,17 @@
蘺 蓠
蘿 萝
虆 蔂
+虉 𬟁
處 处
虛 虚
虜 虏
號 号
虧 亏
-虫 虫
虯 虬
蛺 蛱
蛻 蜕
蜆 蚬
-蜡 蜡
+蝀 𬟽
蝕 蚀
蝟 猬
蝦 虾
@@ -2168,7 +2051,6 @@
衚 胡
衛 卫
衝 冲
-表 表
衹 衹 只
袞 衮
裊 袅
@@ -2185,7 +2067,6 @@
褸 褛
褻 亵
襀 𫌀
-襆 幞
襇 裥
襉 裥
襏 袯
@@ -2236,6 +2117,7 @@
訊 讯
訌 讧
討 讨
+訏 𬣙
訐 讦
訑 𫍙
訒 讱
@@ -2277,6 +2159,7 @@
詗 诇
詘 诎
詛 诅
+詝 𬣞
詞 词
詠 咏
詡 诩
@@ -2284,6 +2167,7 @@
詣 诣
試 试
詩 诗
+詪 𬣳
詫 诧
詬 诟
詭 诡
@@ -2340,12 +2224,14 @@
諏 诹
諑 诼
諒 谅
+諓 𬣡
論 论
諗 谂
諛 谀
諜 谍
諝 谞
諞 谝
+諟 𬤊
諡 谥
諢 诨
諣 𫍩
@@ -2359,6 +2245,7 @@
諯 𫍱
諰 𫍰
諱 讳
+諲 𬤇
諳 谙
諴 𫍯
諶 谌
@@ -2399,13 +2286,14 @@
謾 谩
譁 哗
譂 𫟠
-譅 䜧
+譅 𰶎
譆 𫍻
證 证
譊 𫍢
譎 谲
譏 讥
譑 𫍤
+譓 𬤝
譖 谮
識 识
譙 谯
@@ -2436,7 +2324,6 @@
讚 赞
讜 谠
讞 谳
-谷 谷
豈 岂
豎 竖
豐 丰
@@ -2535,7 +2422,6 @@
趨 趋
趲 趱
跡 迹
-踊 踊
踐 践
踰 逾
踴 踊
@@ -2543,6 +2429,7 @@
蹔 𫏐
蹕 跸
蹟 迹
+蹠 跖
蹣 蹒
蹤 踪
蹳 𫏆
@@ -2579,6 +2466,7 @@
軗 𨐅
軛 轭
軜 𫐇
+軝 𬨂
軟 软
軤 轷
軨 𫐉
@@ -2622,6 +2510,7 @@
輮 𫐓
輯 辑
輳 辏
+輶 𬨎
輷 𫐒
輸 输
輻 辐
@@ -2647,14 +2536,12 @@
轢 轹
轣 𫐆
轤 轳
-辟 辟
辦 办
辭 辞
辮 辫
辯 辩
農 农
迴 回
-适 适
逕 迳
這 这
連 连
@@ -2683,7 +2570,6 @@
邊 边
邏 逻
邐 逦
-郁 郁
郟 郏
郵 邮
鄆 郓
@@ -2693,6 +2579,7 @@
鄖 郧
鄟 𫑘
鄧 邓
+鄩 𬩽
鄭 郑
鄰 邻
鄲 郸
@@ -2702,7 +2589,6 @@
鄺 邝
酇 酂
酈 郦
-酸 酸
醃 腌
醖 酝
醜 丑
@@ -2712,14 +2598,13 @@
醫 医
醬 酱
醱 酦
+醲 𬪩
醶 𫑷
釀 酿
釁 衅
釃 酾
釅 酽
-采 采
釋 释
-里 里
釐 厘
釒 钅
釓 钆
@@ -2739,11 +2624,13 @@
釩 钒
釲 𫟳
釳 𨰿
+釴 𬬩
釵 钗
釷 钍
釹 钕
釺 钎
釾 䥺
+釿 𬬱
鈀 钯
鈁 钫
鈃 钘
@@ -2760,7 +2647,7 @@
鈑 钣
鈒 钑
鈔 钞
-鈕 钮 纽
+鈕 钮
鈖 𫟴
鈗 𫟵
鈛 𫓨
@@ -2790,6 +2677,7 @@
鉆 钻
鉈 铊
鉉 铉
+鉊 𬬿
鉋 铇
鉍 铋
鉑 铂
@@ -2803,9 +2691,12 @@
鉠 𫓭
鉢 钵
鉤 钩
+鉥 𬬸
鉦 钲
+鉧 𬭁
鉬 钼
鉭 钽
+鉮 𬬹
鉳 锫
鉶 铏
鉷 𫟹
@@ -2848,13 +2739,14 @@
銻 锑
銼 锉
鋁 铝
-鋂 镅
+鋂 𰾄
鋃 锒
鋅 锌
鋇 钡
鋉 𨱈
鋌 铤
鋏 铗
+鋐 𬭎
鋒 锋
鋗 𫓶
鋙 铻
@@ -2875,6 +2767,7 @@
鋱 铽
鋶 锍
鋸 锯
+鋹 𬬮
鋼 钢
錀 𬬭
錁 锞
@@ -2893,6 +2786,7 @@
錛 锛
錜 𫓻
錝 𫓽
+錞 𬭚
錟 锬
錠 锭
錡 锜
@@ -2933,6 +2827,7 @@
鍥 锲
鍩 锘
鍬 锹
+鍭 𬭤
鍮 𨱎
鍰 锾
鍵 键
@@ -2947,6 +2842,7 @@
鎊 镑
鎌 镰
鎍 𫔅
+鎓 𬭩
鎔 镕
鎖 锁
鎘 镉
@@ -2976,16 +2872,17 @@
鎿 镎
鏃 镞
鏆 𨱌
-鏇 镟
+鏇 旋 镟
鏈 链
鏉 𨱒
鏌 镆
鏍 镙
+鏏 𬭬
鏐 镠
鏑 镝
鏗 铿
鏘 锵
-鏚 戚
+鏚 𬭭
鏜 镗
鏝 镘
鏞 镛
@@ -3001,6 +2898,7 @@
鏷 镤
鏹 镪
鏺 䥽
+鏻 𬭸
鏽 锈
鏾 𫔌
鐃 铙
@@ -3015,7 +2913,6 @@
鐒 铹
鐓 镦
鐔 镡
-鐗 锏
鐘 钟
鐙 镫
鐝 镢
@@ -3024,6 +2921,7 @@
鐦 锎
鐧 锏
鐨 镄
+鐩 𬭼
鐪 𫓺
鐫 镌
鐮 镰
@@ -3037,7 +2935,7 @@
鐼 𫔁
鐽 𫟼
鐿 镱
-鑀 锿
+鑀 𰾭
鑄 铸
鑉 𫠁
鑊 镬
@@ -3064,7 +2962,6 @@
鑿 凿
钁 镢 䦆
钂 镋
-镟 旋
長 长
門 门
閂 闩
@@ -3109,6 +3006,7 @@
闆 板
闇 暗
闈 闱
+闉 𬮱
闊 阔
闋 阕
闌 阑
@@ -3139,18 +3037,19 @@
隉 陧
隊 队
階 阶
+隑 𬮿
隕 陨
際 际
+隤 𬯎
隨 随
險 险
+隮 𬯀
隯 陦
隱 隐
隴 陇
隸 隶
隻 只
-雇 雇
雋 隽
-雕 雕
雖 虽
雙 双
雛 雏
@@ -3160,6 +3059,7 @@
難 难
雲 云
電 电
+霑 沾
霢 霡
霣 𫕥
霧 雾
@@ -3173,11 +3073,9 @@
靚 靓
靜 静
靝 靔
-面 面
靦 腼 䩄
靧 𫖃
靨 靥
-鞀 鼗
鞏 巩
鞝 绱
鞦 秋
@@ -3216,9 +3114,11 @@
頑 顽
頒 颁
頓 顿
+頔 𬱖
頗 颇
領 领
頜 颌
+頠 𬱟
頡 颉
頤 颐
頦 颏
@@ -3303,6 +3203,7 @@
餃 饺
餄 饸
餅 饼
+餈 糍
餉 饷
養 养
餌 饵
@@ -3366,11 +3267,13 @@
馼 𫘜
駁 驳
駃 𫘝
+駉 𬳶
駊 𫘟
駎 𩧨
駐 驻
駑 驽
駒 驹
+駓 𬳵
駔 驵
駕 驾
駘 骀
@@ -3385,6 +3288,7 @@
駤 𫘠
駧 𩧲
駩 𩧴
+駪 𬳽
駫 𫘡
駭 骇
駰 骃
@@ -3392,6 +3296,7 @@
駶 𩧺
駸 骎
駻 𫘣
+駼 𬳿
駿 骏
騁 骋
騂 骍
@@ -3404,12 +3309,14 @@
騍 骒
騎 骑
騏 骐
+騑 𬴂
騔 𩨀
騖 骛
騙 骗
騚 𩨊
騜 𫘩
騝 𩨃
+騞 𬴃
騟 𩨈
騠 𫘨
騤 骙
@@ -3438,6 +3345,7 @@
驋 𩧯
驌 骕
驍 骁
+驎 𬴊
驏 骣
驓 𫘯
驕 骄
@@ -3488,11 +3396,13 @@
魷 鱿
魺 鲄
魽 𫠐
+鮀 𬶍
鮁 鲅
鮃 鲆
鮄 𫚒
鮅 𫚑
鮆 𫚖
+鮈 𬶋
鮊 鲌
鮋 鲉
鮍 鲏
@@ -3501,12 +3411,13 @@
鮑 鲍
鮒 鲋
鮓 鲊
-鮕 𩾀
鮚 鲒
鮜 鲘
鮝 鲞
鮞 鲕
鮟 𩽾
+鮠 𬶏
+鮡 𬶐
鮣 䲟
鮤 𫚓
鮦 鲖
@@ -3550,6 +3461,7 @@
鯴 鲺
鯶 𩽼
鯷 鳀
+鯻 𬶟
鯽 鲫
鯾 𫚣
鯿 鳊
@@ -3559,6 +3471,7 @@
鰆 䲠
鰈 鲽
鰉 鳇
+鰊 𬶠
鰋 𫚢
鰌 䲡
鰍 鳅
@@ -3586,6 +3499,7 @@
鰲 鳌
鰳 鳓
鰵 鳘
+鰶 𬶭
鰷 鲦
鰹 鲣
鰺 鲹
@@ -3593,6 +3507,7 @@
鰼 鳛
鰽 𫚧
鰾 鳔
+鱀 𬶨
鱂 鳉
鱄 𫚋
鱅 鳙
@@ -3606,6 +3521,7 @@
鱖 鳜
鱗 鳞
鱘 鲟
+鱚 𬶮
鱝 鲼
鱟 鲎
鱠 鲙
@@ -3667,6 +3583,7 @@
鵂 鸺
鵃 鸼
鵊 𫛥
+鵏 𬷕
鵐 鹀
鵑 鹃
鵒 鹆
@@ -3699,6 +3616,7 @@
鶗 𫛸
鶘 鹕
鶚 鹗
+鶠 𬸘
鶡 鹖
鶥 鹛
鶦 𫛷
@@ -3708,6 +3626,7 @@
鶭 𫛯
鶯 莺
鶰 𫛫
+鶱 𬸣
鶲 鹟
鶴 鹤
鶹 鹠
@@ -3720,7 +3639,6 @@
鷂 鹞
鷄 鸡
鷅 𫛽
-鷈 䴘
鷉 䴘
鷊 鹝
鷐 𫜀
@@ -3730,6 +3648,7 @@
鷗 鸥
鷙 鸷
鷚 鹨
+鷟 𬸦
鷣 𫜃
鷤 𫛴
鷥 鸶
@@ -3737,6 +3656,7 @@
鷨 𪉊
鷩 𫜁
鷫 鹔
+鷭 𬸪
鷯 鹩
鷲 鹫
鷳 鹇
@@ -3746,13 +3666,14 @@
鷹 鹰
鷺 鹭
鷽 鸴
-鷿 䴙
+鷿 𬸯
鸂 㶉
鸇 鹯
鸊 䴙
鸋 𫛢
鸌 鹱
鸏 鹲
+鸑 𬸚
鸕 鸬
鸗 𫛟
鸘 鹴
@@ -3794,7 +3715,6 @@
鼉 鼍
鼕 冬
鼴 鼹
-齇 齄
齊 齐
齋 斋
齎 赍
@@ -3803,6 +3723,7 @@
齔 龀
齕 龁
齗 龂
+齘 𬹼
齙 龅
齜 龇
齟 龃
@@ -3815,12 +3736,14 @@
齪 龊
齬 龉
齭 𫜭
+齮 𬺈
齯 𫠜
齰 𫜬
齲 龋
齴 𫜮
齶 腭
齷 龌
+齼 𬺓
齾 𫜰
龍 龙
龎 厐
@@ -3852,6 +3775,7 @@
𡄣 𠵸
𡅏 𠲥
𡅯 𪢖
+𡑍 𫭼
𡑭 𡋗
𡓁 𪤄
𡓾 𡋀
@@ -3859,7 +3783,6 @@
𡞵 㛟
𡟫 𫝪
𡠹 㛿
-𡡎 𡞱
𡢃 㛠
𡮉 𡭜
𡮣 𡭬
@@ -3881,13 +3804,12 @@
𢯷 𪭝
𢶒 𪭯
𢶫 𢫞
-𢷬 𢭏
𢷮 𢫊
𢹿 𢬦
𢺳 𪮳
𣈶 暅
𣋋 𣈣
-𣍐 𠊉
+𣍐 𫧃
𣙎 㭣
𣜬 𪳗
𣝕 𣘷
@@ -3908,6 +3830,7 @@
𤒎 𤊀
𤒻 𪹹
𤓌 𪹠
+𤓎 𤎺
𤓩 𤊰
𤘀 𪺣
𤛮 𤙯
@@ -3932,6 +3855,7 @@
𥖅 𥐯
𥖲 𪿞
𥗇 𪿵
+𥗽 𬒗
𥜐 𫀓
𥜰 𫀌
𥞵 𥞦
@@ -4173,9 +4097,9 @@
𪅂 𫜂
𪆷 𫛾
𪇳 𪉕
-𪈼 𪉓
+𪈼 𱊜
𪉸 𫜊
-𪋿 𪎍
+𪋿 𫧮
𪌭 𫜓
𪍠 𫜕
𪓰 𫜟
diff --git a/data/dictionary/TSPhrases.txt b/data/dictionary/TSPhrases.txt
index 03da3890f..792a1cad1 100644
--- a/data/dictionary/TSPhrases.txt
+++ b/data/dictionary/TSPhrases.txt
@@ -29,14 +29,15 @@
乾隆 乾隆
乾隆年間 乾隆年间
乾隆皇帝 乾隆皇帝
+二噁英 二𫫇英
以免藉口 以免借口
以功覆過 以功复过
侔德覆載 侔德复载
傢俱 家具
-傷亡枕藉 伤亡枕借
+傷亡枕藉 伤亡枕藉
八濛山 八濛山
凌藉 凌借
-出醜狼藉 出丑狼借
+出醜狼藉 出丑狼藉
函覆 函复
千鍾粟 千锺粟
反反覆覆 反反复复
@@ -51,6 +52,7 @@
大目乾連冥間救母變文 大目乾连冥间救母变文
宫商角徵羽 宫商角徵羽
射覆 射复
+尼乾子 尼乾子
尼乾陀 尼乾陀
幺麼 幺麽
幺麼小丑 幺麽小丑
@@ -61,6 +63,7 @@
彷徨 彷徨
徵弦 徵弦
徵絃 徵弦
+徵羽摩柯 徵羽摩柯
徵聲 徵声
徵調 徵调
徵音 徵音
@@ -92,6 +95,7 @@
於敖 於敖
於梨華 於梨华
於清言 於清言
+於潛 於潜
於琳 於琳
於穆 於穆
於竹屋 於竹屋
@@ -104,6 +108,7 @@
明瞭 明了
明覆 明复
書中自有千鍾粟 书中自有千锺粟
+有序 有序
朝乾夕惕 朝乾夕惕
木吒 木吒
李乾德 李乾德
@@ -119,6 +124,7 @@
流徵 流徵
浪蕩乾坤 浪荡乾坤
滑藉 滑借
+無序 无序
牴牾 抵牾
牴觸 抵触
狐藉虎威 狐借虎威
@@ -127,7 +133,6 @@
申覆 申复
畢昇 毕昇
發覆 发复
-盼既示覆 盼既示复
瞭如 了如
瞭如指掌 了如指掌
瞭望 瞭望
@@ -139,6 +144,7 @@
示覆 示复
神祇 神祇
稟覆 禀复
+竺乾 竺乾
答覆 答复
篤麼 笃麽
簡單明瞭 简单明了
@@ -178,7 +184,7 @@
藉端生事 借端生事
藉箸代籌 借箸代筹
藉草枕塊 借草枕块
-藉藉 借借
+藉藉 藉藉
藉藉无名 藉藉无名
藉詞 借词
藉讀 借读
@@ -235,7 +241,6 @@
重覆 重复
金吒 金吒
金鍊 金链
-鈕釦 纽扣
鈞覆 钧复
鉅子 钜子
鉅萬 钜万
diff --git a/data/dictionary/TWPhrasesIT.txt b/data/dictionary/TWPhrasesIT.txt
index 47225685f..8fd94f3ea 100644
--- a/data/dictionary/TWPhrasesIT.txt
+++ b/data/dictionary/TWPhrasesIT.txt
@@ -1,13 +1,14 @@
PN結 PN接面
SQL注入 SQL隱碼攻擊
SQL注入攻擊 SQL隱碼攻擊
+U盤 隨身碟
三極管 三極體
-下拉列表 下拉選單
+下拉列表 下拉式清單
並行計算 平行計算
中間件 中介軟體
-串口 串列埠
+串口 序列埠
串行 序列
-串行端口 串列埠
+串行端口 序列埠
主引導記錄 主開機記錄
主板 主機板
二極管 二極體
@@ -27,7 +28,7 @@ SQL注入攻擊 SQL隱碼攻擊
保存 儲存
信噪比 訊雜比
信息 資訊
-信息安全 資訊保安
+信息安全 資訊安全
信息技術 資訊科技
信息論 資訊理論
信號 訊號 信號
@@ -36,6 +37,7 @@ SQL注入攻擊 SQL隱碼攻擊
像素 畫素
僞代碼 虛擬碼
優先級 優先順序
+優化 最佳化
元數據 後設資料
元編程 超程式設計
光標 游標
@@ -72,15 +74,15 @@ SQL注入攻擊 SQL隱碼攻擊
句柄 控制代碼
可視化 視覺化
呼出 撥出
-呼叫轉移 來電轉駁
+呼叫轉移 來電轉接
命令式編程 指令式程式設計
命令行 命令列
-命名空間 名稱空間
+命名空間 名稱空間 名字空間
哈希 雜湊
單片機 微控制器
回調 回撥
固件 韌體
-圖像 影象
+圖像 影像
圖庫 相簿
圖標 圖示
在線 線上
@@ -91,7 +93,7 @@ SQL注入攻擊 SQL隱碼攻擊
場效應管 場效電晶體
壁紙 桌布 壁紙
外置 外接
-外鍵 外來鍵
+外鍵 外部索引鍵
多任務 多工
多態 多型
多線程 多執行緒
@@ -99,12 +101,12 @@ SQL注入攻擊 SQL隱碼攻擊
字段 欄位
字符 字元
字符串 字串
-字符集 字符集
+字符集 字元集
字節 位元組
字體 字型
存儲 儲存
存盤 存檔
-宏 巨集
+宏 宏 巨集
宏內核 單核心
寄存器 暫存器
密鑰 金鑰
@@ -137,7 +139,9 @@ SQL注入攻擊 SQL隱碼攻擊
打印 列印
打印機 印表機
打開 開啟 打開
+批量 批次
拋出 丟擲
+拷貝 複製
持久性 永續性
指針 指標
捲積 摺積
@@ -150,6 +154,7 @@ SQL注入攻擊 SQL隱碼攻擊
插件 外掛
搜索 搜尋
操作數 運算元
+操作符 運算子
操作系統 作業系統
擴展 擴充套件
擴展名 副檔名
@@ -210,8 +215,9 @@ SQL注入攻擊 SQL隱碼攻擊
源文件 原始檔
源碼 原始碼
溢出 溢位
+滾動條 捲軸
演示文稿 簡報
-激光 鐳射
+激光 雷射
激活 啟用
無損壓縮 無失真壓縮
物理內存 實體記憶體
@@ -224,9 +230,8 @@ SQL注入攻擊 SQL隱碼攻擊
登錄 登入
發佈 釋出
發送 傳送
-皮膚 面板
盤片 碟片
-盤符 碟符
+盤符 磁碟機代號
目標代碼 目的碼
相冊 相簿
矢量 向量
@@ -239,6 +244,7 @@ SQL注入攻擊 SQL隱碼攻擊
磁盤 磁碟
磁道 磁軌
社區 社羣 社區
+禁用 停用
移動硬盤 行動硬碟
移動網絡 行動網路
移動資料 行動資料
@@ -250,7 +256,7 @@ SQL注入攻擊 SQL隱碼攻擊
空分複用 空間多工
窗口 視窗
端口 埠
-筆記本電腦 膝上型電腦
+筆記本電腦 筆記型電腦
算子 運算元
算法 演算法
範式 正規化
@@ -281,17 +287,22 @@ SQL注入攻擊 SQL隱碼攻擊
臺式機 桌上型電腦
航天飛機 太空梭
芯片 晶片
+花屏 破圖
菜單 選單 菜單
萬維網 全球資訊網
-藍牙 藍芽
+藍屏 藍色畫面
+處理程序 處理程序
虛函數 虛擬函式
虛擬機 虛擬機器
+虛擬機器 虛擬機器
表達式 表示式 運算式
複印 影印
複選按鈕 覈取按鈕
複選框 覈取方塊
視圖 檢視
-視頻 視訊
+視頻 影片 視訊
+視頻會議 視訊會議
+視頻通話 視訊通話
解釋器 直譯器
觸摸 觸控
觸摸屏 觸控式螢幕
@@ -313,6 +324,7 @@ SQL注入攻擊 SQL隱碼攻擊
變量 變數
軟件 軟體
軟驅 軟碟機
+轉義字符 跳脫字元
通信 通訊
通訊卡 通話卡
通配符 萬用字元
@@ -366,9 +378,11 @@ SQL注入攻擊 SQL隱碼攻擊
首席技術官 技術長
首席運營官 營運長
高性能計算 高效能運算
+高清 高畫質
高端 高階 進階
高級 高階 進階 高級
高速緩存 快取記憶體
+黑客 駭客
默認 預設
默認值 預設值
點擊 點選
diff --git a/data/dictionary/TWPhrasesName.txt b/data/dictionary/TWPhrasesName.txt
index 6b0b3b6a0..6437a5531 100644
--- a/data/dictionary/TWPhrasesName.txt
+++ b/data/dictionary/TWPhrasesName.txt
@@ -17,6 +17,7 @@
吉布堤 吉布地
哈薩克斯坦 哈薩克
哥斯達黎加 哥斯大黎加
+喫茶小舖 喫茶小舖
圖瓦盧 吐瓦魯
土庫曼斯坦 土庫曼
圭亞那 蓋亞那
@@ -62,6 +63,7 @@
科摩羅 葛摩
科特迪瓦 象牙海岸
突尼斯 突尼西亞
+純喫茶 純喫茶
索馬里 索馬利亞
老撾 寮國
聖基茨和尼維斯 聖克里斯多福及尼維斯
diff --git a/data/dictionary/TWPhrasesOther.txt b/data/dictionary/TWPhrasesOther.txt
index 090a9a0bb..9285daeb9 100644
--- a/data/dictionary/TWPhrasesOther.txt
+++ b/data/dictionary/TWPhrasesOther.txt
@@ -1,16 +1,32 @@
+借記卡 簽帳金融卡
元音 母音
+冰棍 冰棒
出租車 計程車
咖喱 咖哩
+塑料 塑膠
奔馳 賓士
奶酪 乳酪
-方便麵 速食麵
+字節跳動 字節跳動
+幾率 機率
+摩爾線程 摩爾線程
+方便麪 泡麵 速食麵
+李彥宏 李彥宏
+概率 機率
+海內存知己 海內存知己
涼菜 冷盤
+的士 計程車
砹 砈
硅 矽
+程序不正義 程序不正義
+程序正義 程序正義
+空氣淨化器 空氣清淨機
納米 奈米
+自行車 腳踏車
詞組 片語
-蹦極 笨豬跳
+蹦極 高空彈跳
+軟體動物 軟體動物
輔音 子音
+通過 透過 通過
酰 醯
鈁 鍅
鈈 鈽
@@ -21,3 +37,4 @@
鎿 錼
鐦 鉲
鑥 鎦
+黃宏 黃宏
diff --git a/data/dictionary/TWVariants.txt b/data/dictionary/TWVariants.txt
index ce6ba24e2..023a0687b 100644
--- a/data/dictionary/TWVariants.txt
+++ b/data/dictionary/TWVariants.txt
@@ -1,36 +1,39 @@
僞 偽
-兇 凶
啓 啟
+喫 吃
嫺 嫻
嬀 媯
峯 峰
幺 么
擡 抬
-曬 晒
棱 稜
檐 簷
污 汙
泄 洩
-涌 湧
潙 溈
潨 潀
爲 為
牀 床
痹 痺
癡 痴
+皁 皂
着 著
睾 睪
+祕 秘
竈 灶
糉 粽
繮 韁
纔 才
羣 群
+脣 唇
+蔘 參
蔿 蒍
衆 眾
裏 裡
覈 核
踊 踴
鉢 缽
+鍼 針
鮎 鯰
麪 麵
齶 顎
diff --git a/data/dictionary/TWVariantsRevPhrases.txt b/data/dictionary/TWVariantsRevPhrases.txt
index 039fe9e14..ec94209de 100644
--- a/data/dictionary/TWVariantsRevPhrases.txt
+++ b/data/dictionary/TWVariantsRevPhrases.txt
@@ -1,3 +1,9 @@
+一口吃個 一口喫個
+一口吃成 一口喫成
+一家三口 一家三口
+一家五口 一家五口
+一家六口 一家六口
+一家四口 一家四口
凶事 凶事
凶信 凶信
凶兆 凶兆
@@ -25,14 +31,22 @@
凶身 凶身
凶逆 凶逆
凶門 凶門
+口吃 口吃
+吃口 喫口 吃口
+吃口令 吃口令
+吃口飯 喫口飯
+吃吃 喫喫 吃吃
+吃子 喫子 吃子
合著 合著
吉凶 吉凶
名著 名著
四凶 四凶
大凶 大凶
巨著 巨著
+張口 張口
昭著 昭著
歲凶 歲凶
+胃口 胃口
著作 著作
著名 著名
著式 著式
@@ -44,8 +58,11 @@
著者 著者
著述 著述
著錄 著錄
+蹇吃 蹇吃
逢凶 逢凶
避凶 避凶
+鄧艾吃 鄧艾吃
鉅著 鉅著
+開口 開口
閔凶 閔凶
顯著 顯著
diff --git a/data/icon/opencc.svg b/data/icon/opencc.svg
new file mode 100644
index 000000000..cff146d04
--- /dev/null
+++ b/data/icon/opencc.svg
@@ -0,0 +1,39 @@
+
+
+
+]>
+
+
+
+
+
+
+
diff --git a/data/scheme/st_multi.txt b/data/scheme/st_multi.txt
index 188f0ee05..d316bbacd 100644
--- a/data/scheme/st_multi.txt
+++ b/data/scheme/st_multi.txt
@@ -82,6 +82,7 @@
熏 熏 燻 「燻」特指一種烹飪方法,其餘用「熏」。 熏陶 利慾熏心 臭氣熏天 燻肉
赞 贊 讚 與「表揚」有關意義用「讚」,其餘用「贊」。 贊助 贊同 讚美
尝 嘗 嚐 與「喫」、「品嚐」有關意義用「嚐」,其餘用「嘗」。 嘗試 品嚐
+吃 喫 吃 解作「食」時用「喫」,解作「言蹇難也」時用「吃」。 喫飯 喫水 口吃
烟 煙 菸 「煙」用於一般煙霧,與「菸草」有關時用「菸」。 煙霧 菸草 香菸
周 周 週 賙 與「週期」有關用「週」,濟助他人用「賙」,其餘意義爲「周」。 周朝 眾所周知 週歲 週而復始 賙濟
柜 櫃 柜 表示收藏東西的傢具時作「櫃」,表示一種落葉喬木用「柜」。 書櫃 柜柳
@@ -167,6 +168,7 @@
背 背 揹 「揹」作動詞,表示「負荷」,讀陰平聲。 揹黑鍋 揹負
夫 夫 伕 「伕」指「出苦力的人」。 車伕 轎伕 腳伕
迹 蹟 跡 「蹟」特指「前人留下的事物」。 遺蹟 事蹟 奇蹟
+涌 湧 涌 「湧」本作「涌」,後分化。「湧」爲「水上溢」;「涌」爲「小河」,讀音chong1。 湧起 洶湧 浪湧 東涌
录 錄 彔 「彔」爲雕刻木材,見於古文。
极 極 极 「极」見於古文。
愿 願 愿 「愿」見於古文,意義爲「忠厚」﹑「謹慎」。
@@ -194,3 +196,12 @@
证 證 証 証諫、士尉以証君
佑 佑 祐 福祉用「祐」。嘉祐 僧祐
谥 諡 謚 「諡」用於「諡號」,「謚」見於古文。
+熏 熏 燻 「熏」可用於「煙燻」或「薰香」義。
+旋 旋 鏇 「旋」用於「旋轉」等。「鏇」用於「旋轉削切」等。
+沾 沾 霑 「雨水浸潤」、「受恩」等義用「霑」,「浸溼」等義通用,「接觸」「染上」「帶有」等義用「沾」。
+跖 跖 蹠 「腳掌」等以「蹠」為正字。「跖」可用於人名,如「盜跖」。
+玩 玩 翫 「鬆懈、輕忽」用「翫」,其餘「玩」「翫」通用。
+璇 璇 璿 星名用「璇」。「天文儀」、「美玉」義可互通。二字皆有用於人名。 天璇
+它 它 牠 對動物的第三人稱用「牠」。
+蝎 蠍 蝎 「蝎」另兼正字義為「木中蠹蟲」。
+唇 脣 唇 「嘴脣」以「脣」為正字。「唇」另義為「驚駭」,讀作zhēn。
diff --git a/data/scheme/ts_multi.txt b/data/scheme/ts_multi.txt
index 9ac401fdb..7ab04dfde 100644
--- a/data/scheme/ts_multi.txt
+++ b/data/scheme/ts_multi.txt
@@ -10,3 +10,5 @@
衹 衹 只
著 着 著
沈 沈 沉
+噁 恶 𫫇 「𫫇」爲化學名詞用字,如「二𫫇英」。 可恶 恶心 二𫫇英
+蘋 苹 𬞟 「𬞟」爲一種蕨類植物,生於淺水,四片小葉似「田」字,亦稱「田字草」,音pin2,粵音pan4。蘋果之「苹」音ping2,粵音ping4。
diff --git a/data/scripts/BUILD.bazel b/data/scripts/BUILD.bazel
new file mode 100644
index 000000000..d9f718d4e
--- /dev/null
+++ b/data/scripts/BUILD.bazel
@@ -0,0 +1,23 @@
+load("@rules_python//python:py_binary.bzl", "py_binary")
+load("@rules_python//python:py_library.bzl", "py_library")
+
+package(default_visibility = ["//visibility:public"])
+
+py_library(
+ name = "common",
+ srcs = ["common.py"],
+)
+
+py_binary(
+ name = "merge",
+ srcs = ["merge.py"],
+ imports = ["."],
+ deps = [":common"],
+)
+
+py_binary(
+ name = "reverse",
+ srcs = ["reverse.py"],
+ imports = ["."],
+ deps = [":common"],
+)
diff --git a/data/scripts/common.py b/data/scripts/common.py
index f94bca9d9..addd3c02b 100644
--- a/data/scripts/common.py
+++ b/data/scripts/common.py
@@ -1,72 +1,76 @@
-#coding: utf-8
+# -*- coding: utf-8 -*-
+
import codecs
import sys
+
def sort_items(input_filename, output_filename):
- input_file = codecs.open(input_filename, "r", encoding="utf-8")
- dic = {}
-
- for line in input_file:
- if len(line) == 0 or line == '\n':
- continue
- try:
- key, value = line.split("\t")
- except ValueError:
- print(line)
- while value[-1] == "\n" or value[-1] == "\r":
- value = value[:-1]
- dic[key] = value
-
- input_file.close()
-
- output_file = open(output_filename, "wb")
-
- for key in sorted(dic.keys()):
- line = key + "\t" + dic[key] + "\n"
- output_file.write(line.encode('utf-8'))
-
- output_file.close()
+ input_file = codecs.open(input_filename, "r", encoding="utf-8")
+ dic = {}
+
+ for line in input_file:
+ if len(line) == 0 or line == '\n':
+ continue
+ try:
+ key, value = line.split("\t")
+ except ValueError:
+ print(line)
+ while value[-1] == "\n" or value[-1] == "\r":
+ value = value[:-1]
+ dic[key] = value
+
+ input_file.close()
+
+ output_file = open(output_filename, "wb")
+
+ for key in sorted(dic.keys()):
+ line = key + "\t" + dic[key] + "\n"
+ output_file.write(line.encode('utf-8'))
+
+ output_file.close()
+
def reverse_items(input_filename, output_filename):
- input_file = codecs.open(input_filename, "r", encoding="utf-8")
- dic = {}
-
- for line in input_file:
- if len(line) == 0:
- continue
- key, value = line.split("\t")
- while value[-1] == "\n" or value[-1] == "\r":
- value = value[:-1]
-
- value_list = value.split(" ")
- for value in value_list:
- if value in dic:
- dic[value].append(key)
- else:
- dic[value] = [key]
-
- input_file.close()
-
- output_file = open(output_filename, "wb")
-
- for key in sorted(dic.keys()):
- line = key + "\t" + " ".join(dic[key]) + "\n"
- output_file.write(line.encode('utf-8'))
-
- output_file.close()
+ input_file = codecs.open(input_filename, "r", encoding="utf-8")
+ dic = {}
+
+ for line in input_file:
+ if len(line) == 0:
+ continue
+ key, value = line.split("\t")
+ while value[-1] == "\n" or value[-1] == "\r":
+ value = value[:-1]
+
+ value_list = value.split(" ")
+ for value in value_list:
+ if value in dic:
+ dic[value].append(key)
+ else:
+ dic[value] = [key]
+
+ input_file.close()
+
+ output_file = open(output_filename, "wb")
+
+ for key in sorted(dic.keys()):
+ line = key + "\t" + " ".join(dic[key]) + "\n"
+ output_file.write(line.encode('utf-8'))
+
+ output_file.close()
+
def find_target_items(input_filename, keyword):
- input_file = codecs.open(input_filename, "r", encoding="utf-8")
- for line in input_file:
- if len(line) == 0:
- continue
- key, value = line.split("\t")
- while value[-1] == "\n" or value[-1] == "\r":
- value = value[:-1]
-
- value_list = value.split(" ")
- for value in value_list:
- if keyword in value:
- sys.stdout.write(line)
-
- input_file.close()
+ input_file = codecs.open(input_filename, "r", encoding="utf-8")
+ for line in input_file:
+ if len(line) == 0:
+ continue
+ key, value = line.split("\t")
+ while value[-1] == "\n" or value[-1] == "\r":
+ value = value[:-1]
+
+ value_list = value.split(" ")
+ for value in value_list:
+ if keyword in value:
+ sys.stdout.write(line)
+
+ input_file.close()
diff --git a/data/scripts/find_target.py b/data/scripts/find_target.py
index 28ada2767..7b2b4771e 100755
--- a/data/scripts/find_target.py
+++ b/data/scripts/find_target.py
@@ -1,11 +1,12 @@
-#!/usr/bin/env python
-#coding: utf-8
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
import sys
from common import find_target_items
if len(sys.argv) != 3:
- print("Find the value keyword in all pairs")
- print(("Usage: ", sys.argv[0], "[input] [keyword]"))
- exit(1)
+ print("Find the value keyword in all pairs")
+ print(("Usage: ", sys.argv[0], "[input] [keyword]"))
+ exit(1)
find_target_items(sys.argv[1], sys.argv[2])
diff --git a/data/scripts/merge.py b/data/scripts/merge.py
index 170bf60c0..01fcf511e 100755
--- a/data/scripts/merge.py
+++ b/data/scripts/merge.py
@@ -1,26 +1,28 @@
-#!/usr/bin/env python
-#coding: utf-8
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
import codecs
import sys
+
from common import sort_items
if len(sys.argv) < 4:
- print("Merge and sort all text dictionaries")
- print(("Usage: ", sys.argv[0], "[input1] [input2] ... [inputN] [output]"))
- exit(1)
+ print("Merge and sort all text dictionaries")
+ print(("Usage: ", sys.argv[0], "[input1] [input2] ... [inputN] [output]"))
+ exit(1)
all_lines = []
for i in range(1, len(sys.argv) - 1):
- input_file = codecs.open(sys.argv[i], "r", encoding="utf-8")
- for line in input_file:
- all_lines += line
- input_file.close()
- all_lines += '\n'
+ input_file = codecs.open(sys.argv[i], "r", encoding="utf-8")
+ for line in input_file:
+ all_lines += line
+ input_file.close()
+ all_lines += '\n'
output_filename = sys.argv[-1]
output_file = open(output_filename, "wb")
for line in all_lines:
- output_file.write(line.encode('utf-8'))
+ output_file.write(line.encode('utf-8'))
output_file.close()
sort_items(output_filename, output_filename)
diff --git a/data/scripts/reverse.py b/data/scripts/reverse.py
index f70246058..a87ae4674 100755
--- a/data/scripts/reverse.py
+++ b/data/scripts/reverse.py
@@ -1,11 +1,13 @@
-#!/usr/bin/env python
-#coding: utf-8
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
import sys
+
from common import reverse_items
if len(sys.argv) != 3:
- print("Reverse key and value of all pairs")
- print(("Usage: ", sys.argv[0], "[input] [output]"))
- exit(1)
+ print("Reverse key and value of all pairs")
+ print(("Usage: ", sys.argv[0], "[input] [output]"))
+ exit(1)
reverse_items(sys.argv[1], sys.argv[2])
diff --git a/data/scripts/sort.py b/data/scripts/sort.py
index 8268bde81..6ad6e8cb9 100755
--- a/data/scripts/sort.py
+++ b/data/scripts/sort.py
@@ -1,18 +1,19 @@
-#!/usr/bin/env python
-#coding: utf-8
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
import sys
+
from common import sort_items
if len(sys.argv) < 2:
- print("Sort the dictionary")
- print(("Usage: ", sys.argv[0], "[input] ([output])"))
- exit(1)
+ print("Sort the dictionary")
+ print(("Usage: ", sys.argv[0], "[input] ([output])"))
+ exit(1)
input = sys.argv[1]
if len(sys.argv) < 3:
- output = input
+ output = input
else:
- output = sys.argv[2]
+ output = sys.argv[2]
sort_items(input, output)
diff --git a/data/scripts/sort_all.py b/data/scripts/sort_all.py
index 0cecdaa5b..c742413ed 100755
--- a/data/scripts/sort_all.py
+++ b/data/scripts/sort_all.py
@@ -1,16 +1,17 @@
-#!/usr/bin/env python
-#coding: utf-8
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
import glob
import sys
+
from common import sort_items
if len(sys.argv) < 2:
- print("Sort the dictionary")
- print(("Usage: ", sys.argv[0], "[directory]"))
- exit(1)
+ print("Sort the dictionary")
+ print(("Usage: ", sys.argv[0], "[directory]"))
+ exit(1)
-dirtectory = sys.argv[1]
-files = glob.glob(dirtectory + "/*")
+directory = sys.argv[1]
+files = glob.glob(directory + "/*.txt")
for filename in files:
- print(filename)
- sort_items(filename, filename)
+ print(filename)
+ sort_items(filename, filename)
diff --git a/deps/darts-clone/darts.h b/deps/darts-clone-0.32/darts.h
similarity index 100%
rename from deps/darts-clone/darts.h
rename to deps/darts-clone-0.32/darts.h
diff --git a/deps/google-benchmark/.clang-format b/deps/google-benchmark/.clang-format
new file mode 100644
index 000000000..e7d00feaa
--- /dev/null
+++ b/deps/google-benchmark/.clang-format
@@ -0,0 +1,5 @@
+---
+Language: Cpp
+BasedOnStyle: Google
+PointerAlignment: Left
+...
diff --git a/deps/google-benchmark/.clang-tidy b/deps/google-benchmark/.clang-tidy
new file mode 100644
index 000000000..56938a598
--- /dev/null
+++ b/deps/google-benchmark/.clang-tidy
@@ -0,0 +1,7 @@
+---
+Checks: 'clang-analyzer-*,readability-redundant-*,performance-*'
+WarningsAsErrors: 'clang-analyzer-*,readability-redundant-*,performance-*'
+HeaderFilterRegex: '.*'
+AnalyzeTemporaryDtors: false
+FormatStyle: none
+User: user
diff --git a/deps/google-benchmark/.github/.libcxx-setup.sh b/deps/google-benchmark/.github/.libcxx-setup.sh
new file mode 100755
index 000000000..c173111f6
--- /dev/null
+++ b/deps/google-benchmark/.github/.libcxx-setup.sh
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+
+# Checkout LLVM sources
+git clone --depth=1 https://github.com/llvm/llvm-project.git llvm-project
+
+# Setup libc++ options
+if [ -z "$BUILD_32_BITS" ]; then
+ export BUILD_32_BITS=OFF && echo disabling 32 bit build
+fi
+
+# Build and install libc++ (Use unstable ABI for better sanitizer coverage)
+cd ./llvm-project
+cmake -DCMAKE_C_COMPILER=${CC} \
+ -DCMAKE_CXX_COMPILER=${CXX} \
+ -DCMAKE_BUILD_TYPE=RelWithDebInfo \
+ -DCMAKE_INSTALL_PREFIX=/usr \
+ -DLIBCXX_ABI_UNSTABLE=OFF \
+ -DLLVM_USE_SANITIZER=${LIBCXX_SANITIZER} \
+ -DLLVM_BUILD_32_BITS=${BUILD_32_BITS} \
+ -DLLVM_ENABLE_RUNTIMES='libcxx;libcxxabi' \
+ -S llvm -B llvm-build -G "Unix Makefiles"
+make -C llvm-build -j3 cxx cxxabi
+sudo make -C llvm-build install-cxx install-cxxabi
+cd ..
diff --git a/deps/google-benchmark/.github/ISSUE_TEMPLATE/bug_report.md b/deps/google-benchmark/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 000000000..6c2ced9b2
--- /dev/null
+++ b/deps/google-benchmark/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,32 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: "[BUG]"
+labels: ''
+assignees: ''
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**System**
+Which OS, compiler, and compiler version are you using:
+ - OS:
+ - Compiler and version:
+
+**To reproduce**
+Steps to reproduce the behavior:
+1. sync to commit ...
+2. cmake/bazel...
+3. make ...
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Additional context**
+Add any other context about the problem here.
diff --git a/deps/google-benchmark/.github/ISSUE_TEMPLATE/feature_request.md b/deps/google-benchmark/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 000000000..9e8ab6a67
--- /dev/null
+++ b/deps/google-benchmark/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,20 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: "[FR]"
+labels: ''
+assignees: ''
+
+---
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
diff --git a/deps/google-benchmark/.github/install_bazel.sh b/deps/google-benchmark/.github/install_bazel.sh
new file mode 100644
index 000000000..afdd8db8a
--- /dev/null
+++ b/deps/google-benchmark/.github/install_bazel.sh
@@ -0,0 +1,13 @@
+if ! bazel version; then
+ arch=$(uname -m)
+ if [ "$arch" == "aarch64" ]; then
+ arch="arm64"
+ fi
+ echo "Installing wget and downloading $arch Bazel binary from GitHub releases."
+ yum install -y wget
+ wget "https://github.com/bazelbuild/bazel/releases/download/5.2.0/bazel-5.2.0-linux-$arch" -O /usr/local/bin/bazel
+ chmod +x /usr/local/bin/bazel
+else
+ # bazel is installed for the correct architecture
+ exit 0
+fi
diff --git a/deps/google-benchmark/.github/workflows/bazel.yml b/deps/google-benchmark/.github/workflows/bazel.yml
new file mode 100644
index 000000000..1d0864b94
--- /dev/null
+++ b/deps/google-benchmark/.github/workflows/bazel.yml
@@ -0,0 +1,35 @@
+name: bazel
+
+on:
+ push: {}
+ pull_request: {}
+
+jobs:
+ job:
+ name: bazel.${{ matrix.os }}
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ubuntu-latest, macos-latest, windows-2022]
+
+ steps:
+ - uses: actions/checkout@v1
+
+ - name: mount bazel cache
+ uses: actions/cache@v2.0.0
+ env:
+ cache-name: bazel-cache
+ with:
+ path: "~/.cache/bazel"
+ key: ${{ env.cache-name }}-${{ matrix.os }}-${{ github.ref }}
+ restore-keys: |
+ ${{ env.cache-name }}-${{ matrix.os }}-main
+
+ - name: build
+ run: |
+ bazel build //:benchmark //:benchmark_main //test/...
+
+ - name: test
+ run: |
+ bazel test --test_output=all //test/...
diff --git a/deps/google-benchmark/.github/workflows/build-and-test-perfcounters.yml b/deps/google-benchmark/.github/workflows/build-and-test-perfcounters.yml
new file mode 100644
index 000000000..e162edcbe
--- /dev/null
+++ b/deps/google-benchmark/.github/workflows/build-and-test-perfcounters.yml
@@ -0,0 +1,56 @@
+name: build-and-test-perfcounters
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+ branches: [ main ]
+
+jobs:
+ job:
+ # TODO(dominic): Extend this to include compiler and set through env: CC/CXX.
+ name: ${{ matrix.os }}.${{ matrix.build_type }}
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ # ubuntu-18.04 is deprecated but included for best-effort
+ os: [ubuntu-22.04, ubuntu-20.04, ubuntu-18.04]
+ build_type: ['Release', 'Debug']
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: install libpfm
+ run: sudo apt -y install libpfm4-dev
+
+ - name: setup cmake
+ if: matrix.os == 'ubuntu-18.04'
+ uses: jwlawson/actions-setup-cmake@v1.9
+ with:
+ cmake-version: '3.16.3'
+
+ - name: create build environment
+ run: cmake -E make_directory ${{ runner.workspace }}/_build
+
+ - name: configure cmake
+ shell: bash
+ working-directory: ${{ runner.workspace }}/_build
+ run: >
+ cmake $GITHUB_WORKSPACE
+ -DBENCHMARK_ENABLE_LIBPFM=1
+ -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON
+ -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
+
+ - name: build
+ shell: bash
+ working-directory: ${{ runner.workspace }}/_build
+ run: cmake --build . --config ${{ matrix.build_type }}
+
+ # Skip testing, for now. It seems perf_event_open does not succeed on the
+ # hosting machine, very likely a permissions issue.
+ # TODO(mtrofin): Enable test.
+ # - name: test
+ # shell: bash
+ # working-directory: ${{ runner.workspace }}/_build
+ # run: ctest -C ${{ matrix.build_type }} --rerun-failed --output-on-failure
+
diff --git a/deps/google-benchmark/.github/workflows/build-and-test.yml b/deps/google-benchmark/.github/workflows/build-and-test.yml
new file mode 100644
index 000000000..2441e26b6
--- /dev/null
+++ b/deps/google-benchmark/.github/workflows/build-and-test.yml
@@ -0,0 +1,116 @@
+name: build-and-test
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+ branches: [ main ]
+
+jobs:
+ # TODO: add 32-bit builds (g++ and clang++) for ubuntu
+ # (requires g++-multilib and libc6:i386)
+ # TODO: add coverage build (requires lcov)
+ # TODO: add clang + libc++ builds for ubuntu
+ job:
+ name: ${{ matrix.os }}.${{ matrix.build_type }}.${{ matrix.lib }}.${{ matrix.compiler }}
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ # ubuntu-18.04 is deprecated but included for best-effort support
+ os: [ubuntu-22.04, ubuntu-20.04, ubuntu-18.04, macos-latest]
+ build_type: ['Release', 'Debug']
+ compiler: [g++, clang++]
+ lib: ['shared', 'static']
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: setup cmake
+ if: matrix.os == 'ubuntu-18.04'
+ uses: jwlawson/actions-setup-cmake@v1.9
+ with:
+ cmake-version: '3.16.3'
+
+ - name: create build environment
+ run: cmake -E make_directory ${{ runner.workspace }}/_build
+
+ - name: setup cmake initial cache
+ run: touch compiler-cache.cmake
+
+ - name: configure cmake
+ env:
+ CXX: ${{ matrix.compiler }}
+ shell: bash
+ working-directory: ${{ runner.workspace }}/_build
+ run: >
+ cmake -C ${{ github.workspace }}/compiler-cache.cmake
+ $GITHUB_WORKSPACE
+ -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON
+ -DBUILD_SHARED_LIBS=${{ matrix.lib == 'shared' }}
+ -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
+ -DCMAKE_CXX_VISIBILITY_PRESET=hidden
+ -DCMAKE_VISIBILITY_INLINES_HIDDEN=ON
+
+ - name: build
+ shell: bash
+ working-directory: ${{ runner.workspace }}/_build
+ run: cmake --build . --config ${{ matrix.build_type }}
+
+ - name: test
+ shell: bash
+ working-directory: ${{ runner.workspace }}/_build
+ run: ctest -C ${{ matrix.build_type }} -VV
+
+ msvc:
+ name: ${{ matrix.os }}.${{ matrix.build_type }}.${{ matrix.lib }}.${{ matrix.msvc }}
+ runs-on: ${{ matrix.os }}
+ defaults:
+ run:
+ shell: powershell
+ strategy:
+ fail-fast: false
+ matrix:
+ msvc:
+ - VS-16-2019
+ - VS-17-2022
+ arch:
+ - x64
+ build_type:
+ - Debug
+ - Release
+ lib:
+ - shared
+ - static
+ include:
+ - msvc: VS-16-2019
+ os: windows-2019
+ generator: 'Visual Studio 16 2019'
+ - msvc: VS-17-2022
+ os: windows-2022
+ generator: 'Visual Studio 17 2022'
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: configure cmake
+ run: >
+ cmake -S . -B _build/
+ -A ${{ matrix.arch }}
+ -G "${{ matrix.generator }}"
+ -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON
+ -DBUILD_SHARED_LIBS=${{ matrix.lib == 'shared' }}
+
+ - name: build
+ run: cmake --build _build/ --config ${{ matrix.build_type }}
+
+ - name: setup test environment
+ # Make sure gmock and benchmark DLLs can be found
+ run: >
+ echo "$((Get-Item .).FullName)/_build/bin/${{ matrix.build_type }}" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append;
+ echo "$((Get-Item .).FullName)/_build/src/${{ matrix.build_type }}" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append;
+
+ - name: test
+ run: ctest --test-dir _build/ -C ${{ matrix.build_type }} -VV
+
+
diff --git a/deps/google-benchmark/.github/workflows/clang-format-lint.yml b/deps/google-benchmark/.github/workflows/clang-format-lint.yml
new file mode 100644
index 000000000..75775c7cf
--- /dev/null
+++ b/deps/google-benchmark/.github/workflows/clang-format-lint.yml
@@ -0,0 +1,17 @@
+name: clang-format-lint
+on:
+ push: {}
+ pull_request: {}
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - uses: DoozyX/clang-format-lint-action@v0.13
+ with:
+ source: './include/benchmark ./src ./test'
+ extensions: 'h,cc'
+ clangFormatVersion: 12
+ style: Google
diff --git a/deps/google-benchmark/.github/workflows/clang-tidy.yml b/deps/google-benchmark/.github/workflows/clang-tidy.yml
new file mode 100644
index 000000000..978171df0
--- /dev/null
+++ b/deps/google-benchmark/.github/workflows/clang-tidy.yml
@@ -0,0 +1,38 @@
+name: clang-tidy
+
+on:
+ push: {}
+ pull_request: {}
+
+jobs:
+ job:
+ name: run-clang-tidy
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: install clang-tidy
+ run: sudo apt update && sudo apt -y install clang-tidy
+
+ - name: create build environment
+ run: cmake -E make_directory ${{ runner.workspace }}/_build
+
+ - name: configure cmake
+ shell: bash
+ working-directory: ${{ runner.workspace }}/_build
+ run: >
+ cmake $GITHUB_WORKSPACE
+ -DBENCHMARK_ENABLE_ASSEMBLY_TESTS=OFF
+ -DBENCHMARK_ENABLE_LIBPFM=OFF
+ -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON
+ -DCMAKE_C_COMPILER=clang
+ -DCMAKE_CXX_COMPILER=clang++
+ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
+ -DGTEST_COMPILE_COMMANDS=OFF
+
+ - name: run
+ shell: bash
+ working-directory: ${{ runner.workspace }}/_build
+ run: run-clang-tidy
diff --git a/deps/google-benchmark/.github/workflows/doxygen.yml b/deps/google-benchmark/.github/workflows/doxygen.yml
new file mode 100644
index 000000000..e15e69e3c
--- /dev/null
+++ b/deps/google-benchmark/.github/workflows/doxygen.yml
@@ -0,0 +1,28 @@
+name: doxygen
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+ branches: [main]
+
+jobs:
+ build-and-deploy:
+ name: Build HTML documentation
+ runs-on: ubuntu-latest
+ steps:
+ - name: Fetching sources
+ uses: actions/checkout@v2
+
+ - name: Installing build dependencies
+ run: |
+ sudo apt update
+ sudo apt install doxygen gcc git
+
+ - name: Creating build directory
+ run: mkdir build
+
+ - name: Building HTML documentation with Doxygen
+ run: |
+ cmake -S . -B build -DBENCHMARK_ENABLE_TESTING:BOOL=OFF -DBENCHMARK_ENABLE_DOXYGEN:BOOL=ON -DBENCHMARK_INSTALL_DOCS:BOOL=ON
+ cmake --build build --target benchmark_doxygen
diff --git a/deps/google-benchmark/.github/workflows/pylint.yml b/deps/google-benchmark/.github/workflows/pylint.yml
new file mode 100644
index 000000000..f6d368b48
--- /dev/null
+++ b/deps/google-benchmark/.github/workflows/pylint.yml
@@ -0,0 +1,28 @@
+name: pylint
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+ branches: [ main ]
+
+jobs:
+ pylint:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up Python 3.8
+ uses: actions/setup-python@v1
+ with:
+ python-version: 3.8
+
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install pylint pylint-exit conan
+
+ - name: Run pylint
+ run: |
+ pylint `find . -name '*.py'|xargs` || pylint-exit $?
diff --git a/deps/google-benchmark/.github/workflows/sanitizer.yml b/deps/google-benchmark/.github/workflows/sanitizer.yml
new file mode 100644
index 000000000..7fff2cea9
--- /dev/null
+++ b/deps/google-benchmark/.github/workflows/sanitizer.yml
@@ -0,0 +1,100 @@
+name: sanitizer
+
+on:
+ push: {}
+ pull_request: {}
+
+env:
+ UBSAN_OPTIONS: "print_stacktrace=1"
+
+jobs:
+ job:
+ name: ${{ matrix.sanitizer }}.${{ matrix.build_type }}.${{ matrix.compiler }}
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ build_type: ['Debug', 'RelWithDebInfo']
+ sanitizer: ['asan', 'ubsan', 'tsan']
+ compiler: ['clang', 'gcc']
+ # TODO: add 'msan' above. currently failing and needs investigation.
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: configure msan env
+ if: matrix.sanitizer == 'msan'
+ run: |
+ echo "EXTRA_FLAGS=-g -O2 -fno-omit-frame-pointer -fsanitize=memory -fsanitize-memory-track-origins" >> $GITHUB_ENV
+ echo "LIBCXX_SANITIZER=MemoryWithOrigins" >> $GITHUB_ENV
+
+ - name: configure ubsan env
+ if: matrix.sanitizer == 'ubsan'
+ run: |
+ echo "EXTRA_FLAGS=-g -O2 -fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover=all" >> $GITHUB_ENV
+ echo "LIBCXX_SANITIZER=Undefined" >> $GITHUB_ENV
+
+ - name: configure asan env
+ if: matrix.sanitizer == 'asan'
+ run: |
+ echo "EXTRA_FLAGS=-g -O2 -fno-omit-frame-pointer -fsanitize=address -fno-sanitize-recover=all" >> $GITHUB_ENV
+ echo "LIBCXX_SANITIZER=Address" >> $GITHUB_ENV
+
+ - name: configure tsan env
+ if: matrix.sanitizer == 'tsan'
+ run: |
+ echo "EXTRA_FLAGS=-g -O2 -fno-omit-frame-pointer -fsanitize=thread -fno-sanitize-recover=all" >> $GITHUB_ENV
+ echo "LIBCXX_SANITIZER=Thread" >> $GITHUB_ENV
+
+ - name: setup clang
+ if: matrix.compiler == 'clang'
+ uses: egor-tensin/setup-clang@v1
+ with:
+ version: latest
+ platform: x64
+
+ - name: configure clang
+ if: matrix.compiler == 'clang'
+ run: |
+ echo "CC=cc" >> $GITHUB_ENV
+ echo "CXX=c++" >> $GITHUB_ENV
+
+ - name: configure gcc
+ if: matrix.compiler == 'gcc'
+ run: |
+ sudo apt update && sudo apt -y install gcc-10 g++-10
+ echo "CC=gcc-10" >> $GITHUB_ENV
+ echo "CXX=g++-10" >> $GITHUB_ENV
+
+ - name: install llvm stuff
+ if: matrix.compiler == 'clang'
+ run: |
+ "${GITHUB_WORKSPACE}/.github/.libcxx-setup.sh"
+ echo "EXTRA_CXX_FLAGS=\"-stdlib=libc++\"" >> $GITHUB_ENV
+
+ - name: create build environment
+ run: cmake -E make_directory ${{ runner.workspace }}/_build
+
+ - name: configure cmake
+ shell: bash
+ working-directory: ${{ runner.workspace }}/_build
+ run: >
+ VERBOSE=1
+ cmake $GITHUB_WORKSPACE
+ -DBENCHMARK_ENABLE_ASSEMBLY_TESTS=OFF
+ -DBENCHMARK_ENABLE_LIBPFM=OFF
+ -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON
+ -DCMAKE_C_COMPILER=${{ env.CC }}
+ -DCMAKE_CXX_COMPILER=${{ env.CXX }}
+ -DCMAKE_C_FLAGS="${{ env.EXTRA_FLAGS }}"
+ -DCMAKE_CXX_FLAGS="${{ env.EXTRA_FLAGS }} ${{ env.EXTRA_CXX_FLAGS }}"
+ -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
+
+ - name: build
+ shell: bash
+ working-directory: ${{ runner.workspace }}/_build
+ run: cmake --build . --config ${{ matrix.build_type }}
+
+ - name: test
+ shell: bash
+ working-directory: ${{ runner.workspace }}/_build
+ run: ctest -C ${{ matrix.build_type }} -VV
diff --git a/deps/google-benchmark/.github/workflows/test_bindings.yml b/deps/google-benchmark/.github/workflows/test_bindings.yml
new file mode 100644
index 000000000..4a580ebe0
--- /dev/null
+++ b/deps/google-benchmark/.github/workflows/test_bindings.yml
@@ -0,0 +1,24 @@
+name: test-bindings
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+ branches: [main]
+
+jobs:
+ python_bindings:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up Python
+ uses: actions/setup-python@v1
+ with:
+ python-version: 3.8
+ - name: Install benchmark
+ run:
+ python setup.py install
+ - name: Run example bindings
+ run:
+ python bindings/python/google_benchmark/example.py
diff --git a/deps/google-benchmark/.github/workflows/wheels.yml b/deps/google-benchmark/.github/workflows/wheels.yml
new file mode 100644
index 000000000..e8c807401
--- /dev/null
+++ b/deps/google-benchmark/.github/workflows/wheels.yml
@@ -0,0 +1,79 @@
+name: Build and upload Python wheels
+
+on:
+ workflow_dispatch:
+ release:
+ types:
+ - published
+
+jobs:
+ build_sdist:
+ name: Build source distribution
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check out repo
+ uses: actions/checkout@v3
+
+ - name: Install Python 3.9
+ uses: actions/setup-python@v3
+ with:
+ python-version: 3.9
+
+ - name: Build and check sdist
+ run: |
+ python setup.py sdist
+ - name: Upload sdist
+ uses: actions/upload-artifact@v3
+ with:
+ name: dist
+ path: dist/*.tar.gz
+
+ build_wheels:
+ name: Build Google Benchmark wheels on ${{ matrix.os }}
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [ubuntu-latest, macos-latest, windows-latest]
+
+ steps:
+ - name: Check out Google Benchmark
+ uses: actions/checkout@v3
+
+ - name: Set up QEMU
+ if: runner.os == 'Linux'
+ uses: docker/setup-qemu-action@v2
+ with:
+ platforms: all
+
+ - name: Build wheels on ${{ matrix.os }} using cibuildwheel
+ uses: pypa/cibuildwheel@v2.9.0
+ env:
+ CIBW_BUILD: 'cp37-* cp38-* cp39-* cp310-* cp311-*'
+ CIBW_SKIP: "cp37-*-arm64 *-musllinux_*"
+ # TODO: Build ppc64le using some other trick
+ CIBW_ARCHS_LINUX: x86_64 aarch64
+ CIBW_ARCHS_MACOS: x86_64 arm64
+ CIBW_ARCHS_WINDOWS: AMD64
+ CIBW_BEFORE_ALL_LINUX: bash .github/install_bazel.sh
+ CIBW_TEST_COMMAND: python {project}/bindings/python/google_benchmark/example.py
+
+ - name: Upload Google Benchmark ${{ matrix.os }} wheels
+ uses: actions/upload-artifact@v3
+ with:
+ name: dist
+ path: ./wheelhouse/*.whl
+
+ pypi_upload:
+ name: Publish google-benchmark wheels to PyPI
+ needs: [build_sdist, build_wheels]
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/download-artifact@v3
+ with:
+ name: dist
+ path: dist
+
+ - uses: pypa/gh-action-pypi-publish@v1.5.0
+ with:
+ user: __token__
+ password: ${{ secrets.PYPI_PASSWORD }}
diff --git a/deps/google-benchmark/.gitignore b/deps/google-benchmark/.gitignore
new file mode 100644
index 000000000..704f56c25
--- /dev/null
+++ b/deps/google-benchmark/.gitignore
@@ -0,0 +1,67 @@
+*.a
+*.so
+*.so.?*
+*.dll
+*.exe
+*.dylib
+*.cmake
+!/cmake/*.cmake
+!/test/AssemblyTests.cmake
+*~
+*.swp
+*.pyc
+__pycache__
+.DS_Store
+
+# lcov
+*.lcov
+/lcov
+
+# cmake files.
+/Testing
+CMakeCache.txt
+CMakeFiles/
+cmake_install.cmake
+
+# makefiles.
+Makefile
+
+# in-source build.
+bin/
+lib/
+/test/*_test
+
+# exuberant ctags.
+tags
+
+# YouCompleteMe configuration.
+.ycm_extra_conf.pyc
+
+# ninja generated files.
+.ninja_deps
+.ninja_log
+build.ninja
+install_manifest.txt
+rules.ninja
+
+# bazel output symlinks.
+bazel-*
+
+# out-of-source build top-level folders.
+build/
+_build/
+build*/
+
+# in-source dependencies
+/googletest/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+CMakeSettings.json
+
+# Visual Studio Code cache/options directory
+.vscode/
+
+# Python build stuff
+dist/
+*.egg-info*
diff --git a/deps/google-benchmark/.travis.yml b/deps/google-benchmark/.travis.yml
new file mode 100644
index 000000000..8cfed3d10
--- /dev/null
+++ b/deps/google-benchmark/.travis.yml
@@ -0,0 +1,208 @@
+sudo: required
+dist: trusty
+language: cpp
+
+matrix:
+ include:
+ - compiler: gcc
+ addons:
+ apt:
+ packages:
+ - lcov
+ env: COMPILER=g++ C_COMPILER=gcc BUILD_TYPE=Coverage
+ - compiler: gcc
+ addons:
+ apt:
+ packages:
+ - g++-multilib
+ - libc6:i386
+ env:
+ - COMPILER=g++
+ - C_COMPILER=gcc
+ - BUILD_TYPE=Debug
+ - BUILD_32_BITS=ON
+ - EXTRA_FLAGS="-m32"
+ - compiler: gcc
+ addons:
+ apt:
+ packages:
+ - g++-multilib
+ - libc6:i386
+ env:
+ - COMPILER=g++
+ - C_COMPILER=gcc
+ - BUILD_TYPE=Release
+ - BUILD_32_BITS=ON
+ - EXTRA_FLAGS="-m32"
+ - compiler: gcc
+ env:
+ - INSTALL_GCC6_FROM_PPA=1
+ - COMPILER=g++-6 C_COMPILER=gcc-6 BUILD_TYPE=Debug
+ - ENABLE_SANITIZER=1
+ - EXTRA_FLAGS="-fno-omit-frame-pointer -g -O2 -fsanitize=undefined,address -fuse-ld=gold"
+ # Clang w/ libc++
+ - compiler: clang
+ dist: xenial
+ addons:
+ apt:
+ packages:
+ clang-3.8
+ env:
+ - INSTALL_GCC6_FROM_PPA=1
+ - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=Debug
+ - LIBCXX_BUILD=1
+ - EXTRA_CXX_FLAGS="-stdlib=libc++"
+ - compiler: clang
+ dist: xenial
+ addons:
+ apt:
+ packages:
+ clang-3.8
+ env:
+ - INSTALL_GCC6_FROM_PPA=1
+ - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=Release
+ - LIBCXX_BUILD=1
+ - EXTRA_CXX_FLAGS="-stdlib=libc++"
+ # Clang w/ 32bit libc++
+ - compiler: clang
+ dist: xenial
+ addons:
+ apt:
+ packages:
+ - clang-3.8
+ - g++-multilib
+ - libc6:i386
+ env:
+ - INSTALL_GCC6_FROM_PPA=1
+ - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=Debug
+ - LIBCXX_BUILD=1
+ - BUILD_32_BITS=ON
+ - EXTRA_FLAGS="-m32"
+ - EXTRA_CXX_FLAGS="-stdlib=libc++"
+ # Clang w/ 32bit libc++
+ - compiler: clang
+ dist: xenial
+ addons:
+ apt:
+ packages:
+ - clang-3.8
+ - g++-multilib
+ - libc6:i386
+ env:
+ - INSTALL_GCC6_FROM_PPA=1
+ - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=Release
+ - LIBCXX_BUILD=1
+ - BUILD_32_BITS=ON
+ - EXTRA_FLAGS="-m32"
+ - EXTRA_CXX_FLAGS="-stdlib=libc++"
+ # Clang w/ libc++, ASAN, UBSAN
+ - compiler: clang
+ dist: xenial
+ addons:
+ apt:
+ packages:
+ clang-3.8
+ env:
+ - INSTALL_GCC6_FROM_PPA=1
+ - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=Debug
+ - LIBCXX_BUILD=1 LIBCXX_SANITIZER="Undefined;Address"
+ - ENABLE_SANITIZER=1
+ - EXTRA_FLAGS="-g -O2 -fno-omit-frame-pointer -fsanitize=undefined,address -fno-sanitize-recover=all"
+ - EXTRA_CXX_FLAGS="-stdlib=libc++"
+ - UBSAN_OPTIONS=print_stacktrace=1
+ # Clang w/ libc++ and MSAN
+ - compiler: clang
+ dist: xenial
+ addons:
+ apt:
+ packages:
+ clang-3.8
+ env:
+ - INSTALL_GCC6_FROM_PPA=1
+ - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=Debug
+ - LIBCXX_BUILD=1 LIBCXX_SANITIZER=MemoryWithOrigins
+ - ENABLE_SANITIZER=1
+ - EXTRA_FLAGS="-g -O2 -fno-omit-frame-pointer -fsanitize=memory -fsanitize-memory-track-origins"
+ - EXTRA_CXX_FLAGS="-stdlib=libc++"
+ # Clang w/ libc++ and MSAN
+ - compiler: clang
+ dist: xenial
+ addons:
+ apt:
+ packages:
+ clang-3.8
+ env:
+ - INSTALL_GCC6_FROM_PPA=1
+ - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=RelWithDebInfo
+ - LIBCXX_BUILD=1 LIBCXX_SANITIZER=Thread
+ - ENABLE_SANITIZER=1
+ - EXTRA_FLAGS="-g -O2 -fno-omit-frame-pointer -fsanitize=thread -fno-sanitize-recover=all"
+ - EXTRA_CXX_FLAGS="-stdlib=libc++"
+ - os: osx
+ osx_image: xcode8.3
+ compiler: clang
+ env:
+ - COMPILER=clang++
+ - BUILD_TYPE=Release
+ - BUILD_32_BITS=ON
+ - EXTRA_FLAGS="-m32"
+
+before_script:
+ - if [ -n "${LIBCXX_BUILD}" ]; then
+ source .libcxx-setup.sh;
+ fi
+ - if [ -n "${ENABLE_SANITIZER}" ]; then
+ export EXTRA_OPTIONS="-DBENCHMARK_ENABLE_ASSEMBLY_TESTS=OFF";
+ else
+ export EXTRA_OPTIONS="";
+ fi
+ - mkdir -p build && cd build
+
+before_install:
+ - if [ -z "$BUILD_32_BITS" ]; then
+ export BUILD_32_BITS=OFF && echo disabling 32 bit build;
+ fi
+ - if [ -n "${INSTALL_GCC6_FROM_PPA}" ]; then
+ sudo add-apt-repository -y "ppa:ubuntu-toolchain-r/test";
+ sudo apt-get update --option Acquire::Retries=100 --option Acquire::http::Timeout="60";
+ fi
+
+install:
+ - if [ -n "${INSTALL_GCC6_FROM_PPA}" ]; then
+ travis_wait sudo -E apt-get -yq --no-install-suggests --no-install-recommends install g++-6;
+ fi
+ - if [ "${TRAVIS_OS_NAME}" == "linux" -a "${BUILD_32_BITS}" == "OFF" ]; then
+ travis_wait sudo -E apt-get -y --no-install-suggests --no-install-recommends install llvm-3.9-tools;
+ sudo cp /usr/lib/llvm-3.9/bin/FileCheck /usr/local/bin/;
+ fi
+ - if [ "${BUILD_TYPE}" == "Coverage" -a "${TRAVIS_OS_NAME}" == "linux" ]; then
+ PATH=~/.local/bin:${PATH};
+ pip install --user --upgrade pip;
+ travis_wait pip install --user cpp-coveralls;
+ fi
+ - if [ "${C_COMPILER}" == "gcc-7" -a "${TRAVIS_OS_NAME}" == "osx" ]; then
+ rm -f /usr/local/include/c++;
+ brew update;
+ travis_wait brew install gcc@7;
+ fi
+ - if [ "${TRAVIS_OS_NAME}" == "linux" ]; then
+ sudo apt-get update -qq;
+ sudo apt-get install -qq unzip cmake3;
+ wget https://github.com/bazelbuild/bazel/releases/download/3.2.0/bazel-3.2.0-installer-linux-x86_64.sh --output-document bazel-installer.sh;
+ travis_wait sudo bash bazel-installer.sh;
+ fi
+ - if [ "${TRAVIS_OS_NAME}" == "osx" ]; then
+ curl -L -o bazel-installer.sh https://github.com/bazelbuild/bazel/releases/download/3.2.0/bazel-3.2.0-installer-darwin-x86_64.sh;
+ travis_wait sudo bash bazel-installer.sh;
+ fi
+
+script:
+ - cmake -DCMAKE_C_COMPILER=${C_COMPILER} -DCMAKE_CXX_COMPILER=${COMPILER} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DCMAKE_C_FLAGS="${EXTRA_FLAGS}" -DCMAKE_CXX_FLAGS="${EXTRA_FLAGS} ${EXTRA_CXX_FLAGS}" -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON -DBENCHMARK_BUILD_32_BITS=${BUILD_32_BITS} ${EXTRA_OPTIONS} ..
+ - make
+ - ctest -C ${BUILD_TYPE} --output-on-failure
+ - bazel test -c dbg --define google_benchmark.have_regex=posix --announce_rc --verbose_failures --test_output=errors --keep_going //test/...
+
+after_success:
+ - if [ "${BUILD_TYPE}" == "Coverage" -a "${TRAVIS_OS_NAME}" == "linux" ]; then
+ coveralls --include src --include include --gcov-options '\-lp' --root .. --build-root .;
+ fi
diff --git a/deps/google-benchmark/.ycm_extra_conf.py b/deps/google-benchmark/.ycm_extra_conf.py
new file mode 100644
index 000000000..5649ddcc7
--- /dev/null
+++ b/deps/google-benchmark/.ycm_extra_conf.py
@@ -0,0 +1,115 @@
+import os
+import ycm_core
+
+# These are the compilation flags that will be used in case there's no
+# compilation database set (by default, one is not set).
+# CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR.
+flags = [
+'-Wall',
+'-Werror',
+'-pedantic-errors',
+'-std=c++0x',
+'-fno-strict-aliasing',
+'-O3',
+'-DNDEBUG',
+# ...and the same thing goes for the magic -x option which specifies the
+# language that the files to be compiled are written in. This is mostly
+# relevant for c++ headers.
+# For a C project, you would set this to 'c' instead of 'c++'.
+'-x', 'c++',
+'-I', 'include',
+'-isystem', '/usr/include',
+'-isystem', '/usr/local/include',
+]
+
+
+# Set this to the absolute path to the folder (NOT the file!) containing the
+# compile_commands.json file to use that instead of 'flags'. See here for
+# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
+#
+# Most projects will NOT need to set this to anything; you can just change the
+# 'flags' list of compilation flags. Notice that YCM itself uses that approach.
+compilation_database_folder = ''
+
+if os.path.exists( compilation_database_folder ):
+ database = ycm_core.CompilationDatabase( compilation_database_folder )
+else:
+ database = None
+
+SOURCE_EXTENSIONS = [ '.cc' ]
+
+def DirectoryOfThisScript():
+ return os.path.dirname( os.path.abspath( __file__ ) )
+
+
+def MakeRelativePathsInFlagsAbsolute( flags, working_directory ):
+ if not working_directory:
+ return list( flags )
+ new_flags = []
+ make_next_absolute = False
+ path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ]
+ for flag in flags:
+ new_flag = flag
+
+ if make_next_absolute:
+ make_next_absolute = False
+ if not flag.startswith( '/' ):
+ new_flag = os.path.join( working_directory, flag )
+
+ for path_flag in path_flags:
+ if flag == path_flag:
+ make_next_absolute = True
+ break
+
+ if flag.startswith( path_flag ):
+ path = flag[ len( path_flag ): ]
+ new_flag = path_flag + os.path.join( working_directory, path )
+ break
+
+ if new_flag:
+ new_flags.append( new_flag )
+ return new_flags
+
+
+def IsHeaderFile( filename ):
+ extension = os.path.splitext( filename )[ 1 ]
+ return extension in [ '.h', '.hxx', '.hpp', '.hh' ]
+
+
+def GetCompilationInfoForFile( filename ):
+ # The compilation_commands.json file generated by CMake does not have entries
+ # for header files. So we do our best by asking the db for flags for a
+ # corresponding source file, if any. If one exists, the flags for that file
+ # should be good enough.
+ if IsHeaderFile( filename ):
+ basename = os.path.splitext( filename )[ 0 ]
+ for extension in SOURCE_EXTENSIONS:
+ replacement_file = basename + extension
+ if os.path.exists( replacement_file ):
+ compilation_info = database.GetCompilationInfoForFile(
+ replacement_file )
+ if compilation_info.compiler_flags_:
+ return compilation_info
+ return None
+ return database.GetCompilationInfoForFile( filename )
+
+
+def FlagsForFile( filename, **kwargs ):
+ if database:
+ # Bear in mind that compilation_info.compiler_flags_ does NOT return a
+ # python list, but a "list-like" StringVec object
+ compilation_info = GetCompilationInfoForFile( filename )
+ if not compilation_info:
+ return None
+
+ final_flags = MakeRelativePathsInFlagsAbsolute(
+ compilation_info.compiler_flags_,
+ compilation_info.compiler_working_dir_ )
+ else:
+ relative_to = DirectoryOfThisScript()
+ final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to )
+
+ return {
+ 'flags': final_flags,
+ 'do_cache': True
+ }
diff --git a/deps/google-benchmark/AUTHORS b/deps/google-benchmark/AUTHORS
new file mode 100644
index 000000000..98d2d98b0
--- /dev/null
+++ b/deps/google-benchmark/AUTHORS
@@ -0,0 +1,67 @@
+# This is the official list of benchmark authors for copyright purposes.
+# This file is distinct from the CONTRIBUTORS files.
+# See the latter for an explanation.
+#
+# Names should be added to this file as:
+# Name or Organization
+# The email address is not required for organizations.
+#
+# Please keep the list sorted.
+
+Albert Pretorius
+Alex Steele
+Andriy Berestovskyy
+Arne Beer
+Carto
+Cezary Skrzyński
+Christian Wassermann
+Christopher Seymour
+Colin Braley
+Daniel Harvey
+David Coeurjolly
+Deniz Evrenci
+Dirac Research
+Dominik Czarnota
+Dominik Korman
+Donald Aingworth
+Eric Backus
+Eric Fiselier
+Eugene Zhuk
+Evgeny Safronov
+Federico Ficarelli
+Felix Homann
+Gergő Szitár
+Google Inc.
+International Business Machines Corporation
+Ismael Jimenez Martinez
+Jern-Kuan Leong
+JianXiong Zhou
+Joao Paulo Magalhaes
+Jordan Williams
+Jussi Knuuttila
+Kaito Udagawa
+Kishan Kumar
+Lei Xu
+Matt Clarkson
+Maxim Vafin
+MongoDB Inc.
+Nick Hutchinson
+Norman Heino
+Oleksandr Sochka
+Ori Livneh
+Paul Redmond
+Raghu Raja
+Radoslav Yovchev
+Rainer Orth
+Roman Lebedev
+Sayan Bhattacharjee
+Shapr3D
+Shuo Chen
+Staffan Tjernstrom
+Steinar H. Gunderson
+Stripe, Inc.
+Tobias Schmidt
+Yixuan Qiu
+Yusuke Suzuki
+Zbigniew Skowron
+Min-Yih Hsu
diff --git a/deps/google-benchmark/BUILD.bazel b/deps/google-benchmark/BUILD.bazel
new file mode 100644
index 000000000..64f86eedc
--- /dev/null
+++ b/deps/google-benchmark/BUILD.bazel
@@ -0,0 +1,77 @@
+licenses(["notice"])
+
+config_setting(
+ name = "qnx",
+ constraint_values = ["@platforms//os:qnx"],
+ values = {
+ "cpu": "x64_qnx",
+ },
+ visibility = [":__subpackages__"],
+)
+
+config_setting(
+ name = "windows",
+ constraint_values = ["@platforms//os:windows"],
+ values = {
+ "cpu": "x64_windows",
+ },
+ visibility = [":__subpackages__"],
+)
+
+config_setting(
+ name = "perfcounters",
+ define_values = {
+ "pfm": "1",
+ },
+ visibility = [":__subpackages__"],
+)
+
+cc_library(
+ name = "benchmark",
+ srcs = glob(
+ [
+ "src/*.cc",
+ "src/*.h",
+ ],
+ exclude = ["src/benchmark_main.cc"],
+ ),
+ hdrs = [
+ "include/benchmark/benchmark.h",
+ "include/benchmark/export.h",
+ ],
+ linkopts = select({
+ ":windows": ["-DEFAULTLIB:shlwapi.lib"],
+ "//conditions:default": ["-pthread"],
+ }),
+ strip_include_prefix = "include",
+ visibility = ["//visibility:public"],
+ # Only static linking is allowed; no .so will be produced.
+ # Using `defines` (i.e. not `local_defines`) means that no
+ # dependent rules need to bother about defining the macro.
+ linkstatic = True,
+ defines = [
+ "BENCHMARK_STATIC_DEFINE",
+ ] + select({
+ ":perfcounters": ["HAVE_LIBPFM"],
+ "//conditions:default": [],
+ }),
+ deps = select({
+ ":perfcounters": ["@libpfm//:libpfm"],
+ "//conditions:default": [],
+ }),
+)
+
+cc_library(
+ name = "benchmark_main",
+ srcs = ["src/benchmark_main.cc"],
+ hdrs = ["include/benchmark/benchmark.h", "include/benchmark/export.h"],
+ strip_include_prefix = "include",
+ visibility = ["//visibility:public"],
+ deps = [":benchmark"],
+)
+
+cc_library(
+ name = "benchmark_internal_headers",
+ hdrs = glob(["src/*.h"]),
+ visibility = ["//test:__pkg__"],
+)
diff --git a/deps/google-benchmark/CMakeLists.txt b/deps/google-benchmark/CMakeLists.txt
new file mode 100644
index 000000000..9ab265ed8
--- /dev/null
+++ b/deps/google-benchmark/CMakeLists.txt
@@ -0,0 +1,350 @@
+cmake_minimum_required (VERSION 3.16.3)
+
+foreach(p
+ CMP0048 # OK to clear PROJECT_VERSION on project()
+ CMP0054 # CMake 3.1
+ CMP0056 # export EXE_LINKER_FLAGS to try_run
+ CMP0057 # Support no if() IN_LIST operator
+ CMP0063 # Honor visibility properties for all targets
+ CMP0067 # Honor language standard in try_compile() source file signature
+ CMP0077 # Allow option() overrides in importing projects
+ )
+ if(POLICY ${p})
+ cmake_policy(SET ${p} NEW)
+ endif()
+endforeach()
+
+project (benchmark VERSION 1.7.1 LANGUAGES CXX)
+
+option(BENCHMARK_ENABLE_TESTING "Enable testing of the benchmark library." ON)
+option(BENCHMARK_ENABLE_EXCEPTIONS "Enable the use of exceptions in the benchmark library." ON)
+option(BENCHMARK_ENABLE_LTO "Enable link time optimisation of the benchmark library." OFF)
+option(BENCHMARK_USE_LIBCXX "Build and test using libc++ as the standard library." OFF)
+option(BENCHMARK_ENABLE_WERROR "Build Release candidates with -Werror." ON)
+option(BENCHMARK_FORCE_WERROR "Build Release candidates with -Werror regardless of compiler issues." OFF)
+
+if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "PGI")
+ # PGC++ maybe reporting false positives.
+ set(BENCHMARK_ENABLE_WERROR OFF)
+endif()
+if(BENCHMARK_FORCE_WERROR)
+ set(BENCHMARK_ENABLE_WERROR ON)
+endif(BENCHMARK_FORCE_WERROR)
+
+if(NOT MSVC)
+ option(BENCHMARK_BUILD_32_BITS "Build a 32 bit version of the library." OFF)
+else()
+ set(BENCHMARK_BUILD_32_BITS OFF CACHE BOOL "Build a 32 bit version of the library - unsupported when using MSVC)" FORCE)
+endif()
+option(BENCHMARK_ENABLE_INSTALL "Enable installation of benchmark. (Projects embedding benchmark may want to turn this OFF.)" ON)
+option(BENCHMARK_ENABLE_DOXYGEN "Build documentation with Doxygen." OFF)
+option(BENCHMARK_INSTALL_DOCS "Enable installation of documentation." ON)
+
+# Allow unmet dependencies to be met using CMake's ExternalProject mechanics, which
+# may require downloading the source code.
+option(BENCHMARK_DOWNLOAD_DEPENDENCIES "Allow the downloading and in-tree building of unmet dependencies" OFF)
+
+# This option can be used to disable building and running unit tests which depend on gtest
+# in cases where it is not possible to build or find a valid version of gtest.
+option(BENCHMARK_ENABLE_GTEST_TESTS "Enable building the unit tests which depend on gtest" ON)
+option(BENCHMARK_USE_BUNDLED_GTEST "Use bundled GoogleTest. If disabled, the find_package(GTest) will be used." ON)
+
+option(BENCHMARK_ENABLE_LIBPFM "Enable performance counters provided by libpfm" OFF)
+
+# Export only public symbols
+set(CMAKE_CXX_VISIBILITY_PRESET hidden)
+set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
+
+if(MSVC)
+ # As of CMake 3.18, CMAKE_SYSTEM_PROCESSOR is not set properly for MSVC and
+ # cross-compilation (e.g. Host=x86_64, target=aarch64) requires using the
+ # undocumented, but working variable.
+ # See https://gitlab.kitware.com/cmake/cmake/-/issues/15170
+ set(CMAKE_SYSTEM_PROCESSOR ${MSVC_CXX_ARCHITECTURE_ID})
+ if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "ARM")
+ set(CMAKE_CROSSCOMPILING TRUE)
+ endif()
+endif()
+
+set(ENABLE_ASSEMBLY_TESTS_DEFAULT OFF)
+function(should_enable_assembly_tests)
+ if(CMAKE_BUILD_TYPE)
+ string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER)
+ if (${CMAKE_BUILD_TYPE_LOWER} MATCHES "coverage")
+ # FIXME: The --coverage flag needs to be removed when building assembly
+ # tests for this to work.
+ return()
+ endif()
+ endif()
+ if (MSVC)
+ return()
+ elseif(NOT CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ return()
+ elseif(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
+ # FIXME: Make these work on 32 bit builds
+ return()
+ elseif(BENCHMARK_BUILD_32_BITS)
+ # FIXME: Make these work on 32 bit builds
+ return()
+ endif()
+ find_program(LLVM_FILECHECK_EXE FileCheck)
+ if (LLVM_FILECHECK_EXE)
+ set(LLVM_FILECHECK_EXE "${LLVM_FILECHECK_EXE}" CACHE PATH "llvm filecheck" FORCE)
+ message(STATUS "LLVM FileCheck Found: ${LLVM_FILECHECK_EXE}")
+ else()
+ message(STATUS "Failed to find LLVM FileCheck")
+ return()
+ endif()
+ set(ENABLE_ASSEMBLY_TESTS_DEFAULT ON PARENT_SCOPE)
+endfunction()
+should_enable_assembly_tests()
+
+# This option disables the building and running of the assembly verification tests
+option(BENCHMARK_ENABLE_ASSEMBLY_TESTS "Enable building and running the assembly tests"
+ ${ENABLE_ASSEMBLY_TESTS_DEFAULT})
+
+# Make sure we can import out CMake functions
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
+
+
+# Read the git tags to determine the project version
+include(GetGitVersion)
+get_git_version(GIT_VERSION)
+
+# If no git version can be determined, use the version
+# from the project() command
+if ("${GIT_VERSION}" STREQUAL "0.0.0")
+ set(VERSION "${benchmark_VERSION}")
+else()
+ set(VERSION "${GIT_VERSION}")
+endif()
+# Tell the user what versions we are using
+message(STATUS "Version: ${VERSION}")
+
+# The version of the libraries
+set(GENERIC_LIB_VERSION ${VERSION})
+string(SUBSTRING ${VERSION} 0 1 GENERIC_LIB_SOVERSION)
+
+# Import our CMake modules
+include(AddCXXCompilerFlag)
+include(CheckCXXCompilerFlag)
+include(CheckLibraryExists)
+include(CXXFeatureCheck)
+
+check_library_exists(rt shm_open "" HAVE_LIB_RT)
+
+if (BENCHMARK_BUILD_32_BITS)
+ add_required_cxx_compiler_flag(-m32)
+endif()
+
+if (MSVC)
+ set(BENCHMARK_CXX_STANDARD 14)
+else()
+ set(BENCHMARK_CXX_STANDARD 11)
+endif()
+
+set(CMAKE_CXX_STANDARD ${BENCHMARK_CXX_STANDARD})
+set(CMAKE_CXX_STANDARD_REQUIRED YES)
+set(CMAKE_CXX_EXTENSIONS OFF)
+
+if (MSVC)
+ # Turn compiler warnings up to 11
+ string(REGEX REPLACE "[-/]W[1-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
+ add_definitions(-D_CRT_SECURE_NO_WARNINGS)
+
+ if (NOT BENCHMARK_ENABLE_EXCEPTIONS)
+ add_cxx_compiler_flag(-EHs-)
+ add_cxx_compiler_flag(-EHa-)
+ add_definitions(-D_HAS_EXCEPTIONS=0)
+ endif()
+ # Link time optimisation
+ if (BENCHMARK_ENABLE_LTO)
+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL")
+ set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} /LTCG")
+ set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG")
+ set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG")
+
+ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /GL")
+ string(REGEX REPLACE "[-/]INCREMENTAL" "/INCREMENTAL:NO" CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO}")
+ set(CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO} /LTCG")
+ string(REGEX REPLACE "[-/]INCREMENTAL" "/INCREMENTAL:NO" CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}")
+ set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} /LTCG")
+ string(REGEX REPLACE "[-/]INCREMENTAL" "/INCREMENTAL:NO" CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}")
+ set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /LTCG")
+
+ set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /GL")
+ set(CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL "${CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL} /LTCG")
+ set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "${CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL} /LTCG")
+ set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL} /LTCG")
+ endif()
+else()
+ # Turn compiler warnings up to 11
+ add_cxx_compiler_flag(-Wall)
+ add_cxx_compiler_flag(-Wextra)
+ add_cxx_compiler_flag(-Wshadow)
+ add_cxx_compiler_flag(-Wfloat-equal)
+ if(BENCHMARK_ENABLE_WERROR)
+ add_cxx_compiler_flag(-Werror RELEASE)
+ add_cxx_compiler_flag(-Werror RELWITHDEBINFO)
+ add_cxx_compiler_flag(-Werror MINSIZEREL)
+ endif()
+ if (NOT BENCHMARK_ENABLE_TESTING)
+ # Disable warning when compiling tests as gtest does not use 'override'.
+ add_cxx_compiler_flag(-Wsuggest-override)
+ endif()
+ add_cxx_compiler_flag(-pedantic)
+ add_cxx_compiler_flag(-pedantic-errors)
+ add_cxx_compiler_flag(-Wshorten-64-to-32)
+ add_cxx_compiler_flag(-fstrict-aliasing)
+ # Disable warnings regarding deprecated parts of the library while building
+ # and testing those parts of the library.
+ add_cxx_compiler_flag(-Wno-deprecated-declarations)
+ if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
+ # Intel silently ignores '-Wno-deprecated-declarations',
+ # warning no. 1786 must be explicitly disabled.
+ # See #631 for rationale.
+ add_cxx_compiler_flag(-wd1786)
+ endif()
+ # Disable deprecation warnings for release builds (when -Werror is enabled).
+ if(BENCHMARK_ENABLE_WERROR)
+ add_cxx_compiler_flag(-Wno-deprecated RELEASE)
+ add_cxx_compiler_flag(-Wno-deprecated RELWITHDEBINFO)
+ add_cxx_compiler_flag(-Wno-deprecated MINSIZEREL)
+ endif()
+ if (NOT BENCHMARK_ENABLE_EXCEPTIONS)
+ add_cxx_compiler_flag(-fno-exceptions)
+ endif()
+
+ if (HAVE_CXX_FLAG_FSTRICT_ALIASING)
+ if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "Intel") #ICC17u2: Many false positives for Wstrict-aliasing
+ add_cxx_compiler_flag(-Wstrict-aliasing)
+ endif()
+ endif()
+ # ICC17u2: overloaded virtual function "benchmark::Fixture::SetUp" is only partially overridden
+ # (because of deprecated overload)
+ add_cxx_compiler_flag(-wd654)
+ add_cxx_compiler_flag(-Wthread-safety)
+ if (HAVE_CXX_FLAG_WTHREAD_SAFETY)
+ cxx_feature_check(THREAD_SAFETY_ATTRIBUTES "-DINCLUDE_DIRECTORIES=${PROJECT_SOURCE_DIR}/include")
+ endif()
+
+ # On most UNIX like platforms g++ and clang++ define _GNU_SOURCE as a
+ # predefined macro, which turns on all of the wonderful libc extensions.
+ # However g++ doesn't do this in Cygwin so we have to define it ourselfs
+ # since we depend on GNU/POSIX/BSD extensions.
+ if (CYGWIN)
+ add_definitions(-D_GNU_SOURCE=1)
+ endif()
+
+ if (QNXNTO)
+ add_definitions(-D_QNX_SOURCE)
+ endif()
+
+ # Link time optimisation
+ if (BENCHMARK_ENABLE_LTO)
+ add_cxx_compiler_flag(-flto)
+ add_cxx_compiler_flag(-Wno-lto-type-mismatch)
+ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+ find_program(GCC_AR gcc-ar)
+ if (GCC_AR)
+ set(CMAKE_AR ${GCC_AR})
+ endif()
+ find_program(GCC_RANLIB gcc-ranlib)
+ if (GCC_RANLIB)
+ set(CMAKE_RANLIB ${GCC_RANLIB})
+ endif()
+ elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
+ include(llvm-toolchain)
+ endif()
+ endif()
+
+ # Coverage build type
+ set(BENCHMARK_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_DEBUG}"
+ CACHE STRING "Flags used by the C++ compiler during coverage builds."
+ FORCE)
+ set(BENCHMARK_EXE_LINKER_FLAGS_COVERAGE "${CMAKE_EXE_LINKER_FLAGS_DEBUG}"
+ CACHE STRING "Flags used for linking binaries during coverage builds."
+ FORCE)
+ set(BENCHMARK_SHARED_LINKER_FLAGS_COVERAGE "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}"
+ CACHE STRING "Flags used by the shared libraries linker during coverage builds."
+ FORCE)
+ mark_as_advanced(
+ BENCHMARK_CXX_FLAGS_COVERAGE
+ BENCHMARK_EXE_LINKER_FLAGS_COVERAGE
+ BENCHMARK_SHARED_LINKER_FLAGS_COVERAGE)
+ set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING
+ "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Coverage.")
+ add_cxx_compiler_flag(--coverage COVERAGE)
+endif()
+
+if (BENCHMARK_USE_LIBCXX)
+ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
+ add_cxx_compiler_flag(-stdlib=libc++)
+ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR
+ "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
+ add_cxx_compiler_flag(-nostdinc++)
+ message(WARNING "libc++ header path must be manually specified using CMAKE_CXX_FLAGS")
+ # Adding -nodefaultlibs directly to CMAKE__LINKER_FLAGS will break
+ # configuration checks such as 'find_package(Threads)'
+ list(APPEND BENCHMARK_CXX_LINKER_FLAGS -nodefaultlibs)
+ # -lc++ cannot be added directly to CMAKE__LINKER_FLAGS because
+ # linker flags appear before all linker inputs and -lc++ must appear after.
+ list(APPEND BENCHMARK_CXX_LIBRARIES c++)
+ else()
+ message(FATAL_ERROR "-DBENCHMARK_USE_LIBCXX:BOOL=ON is not supported for compiler")
+ endif()
+endif(BENCHMARK_USE_LIBCXX)
+
+set(EXTRA_CXX_FLAGS "")
+if (WIN32 AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
+ # Clang on Windows fails to compile the regex feature check under C++11
+ set(EXTRA_CXX_FLAGS "-DCMAKE_CXX_STANDARD=14")
+endif()
+
+# C++ feature checks
+# Determine the correct regular expression engine to use
+cxx_feature_check(STD_REGEX ${EXTRA_CXX_FLAGS})
+cxx_feature_check(GNU_POSIX_REGEX ${EXTRA_CXX_FLAGS})
+cxx_feature_check(POSIX_REGEX ${EXTRA_CXX_FLAGS})
+if(NOT HAVE_STD_REGEX AND NOT HAVE_GNU_POSIX_REGEX AND NOT HAVE_POSIX_REGEX)
+ message(FATAL_ERROR "Failed to determine the source files for the regular expression backend")
+endif()
+if (NOT BENCHMARK_ENABLE_EXCEPTIONS AND HAVE_STD_REGEX
+ AND NOT HAVE_GNU_POSIX_REGEX AND NOT HAVE_POSIX_REGEX)
+ message(WARNING "Using std::regex with exceptions disabled is not fully supported")
+endif()
+
+cxx_feature_check(STEADY_CLOCK)
+# Ensure we have pthreads
+set(THREADS_PREFER_PTHREAD_FLAG ON)
+find_package(Threads REQUIRED)
+
+if (BENCHMARK_ENABLE_LIBPFM)
+ find_package(PFM)
+endif()
+
+# Set up directories
+include_directories(${PROJECT_SOURCE_DIR}/include)
+
+# Build the targets
+add_subdirectory(src)
+
+if (BENCHMARK_ENABLE_TESTING)
+ enable_testing()
+ if (BENCHMARK_ENABLE_GTEST_TESTS AND
+ NOT (TARGET gtest AND TARGET gtest_main AND
+ TARGET gmock AND TARGET gmock_main))
+ if (BENCHMARK_USE_BUNDLED_GTEST)
+ include(GoogleTest)
+ else()
+ find_package(GTest CONFIG REQUIRED)
+ add_library(gtest ALIAS GTest::gtest)
+ add_library(gtest_main ALIAS GTest::gtest_main)
+ add_library(gmock ALIAS GTest::gmock)
+ add_library(gmock_main ALIAS GTest::gmock_main)
+ endif()
+ endif()
+ add_subdirectory(test)
+endif()
diff --git a/deps/google-benchmark/CONTRIBUTING.md b/deps/google-benchmark/CONTRIBUTING.md
new file mode 100644
index 000000000..43de4c9d4
--- /dev/null
+++ b/deps/google-benchmark/CONTRIBUTING.md
@@ -0,0 +1,58 @@
+# How to contribute #
+
+We'd love to accept your patches and contributions to this project. There are
+a just a few small guidelines you need to follow.
+
+
+## Contributor License Agreement ##
+
+Contributions to any Google project must be accompanied by a Contributor
+License Agreement. This is not a copyright **assignment**, it simply gives
+Google permission to use and redistribute your contributions as part of the
+project.
+
+ * If you are an individual writing original source code and you're sure you
+ own the intellectual property, then you'll need to sign an [individual
+ CLA][].
+
+ * If you work for a company that wants to allow you to contribute your work,
+ then you'll need to sign a [corporate CLA][].
+
+You generally only need to submit a CLA once, so if you've already submitted
+one (even if it was for a different project), you probably don't need to do it
+again.
+
+[individual CLA]: https://developers.google.com/open-source/cla/individual
+[corporate CLA]: https://developers.google.com/open-source/cla/corporate
+
+Once your CLA is submitted (or if you already submitted one for
+another Google project), make a commit adding yourself to the
+[AUTHORS][] and [CONTRIBUTORS][] files. This commit can be part
+of your first [pull request][].
+
+[AUTHORS]: AUTHORS
+[CONTRIBUTORS]: CONTRIBUTORS
+
+
+## Submitting a patch ##
+
+ 1. It's generally best to start by opening a new issue describing the bug or
+ feature you're intending to fix. Even if you think it's relatively minor,
+ it's helpful to know what people are working on. Mention in the initial
+ issue that you are planning to work on that bug or feature so that it can
+ be assigned to you.
+
+ 1. Follow the normal process of [forking][] the project, and setup a new
+ branch to work in. It's important that each group of changes be done in
+ separate branches in order to ensure that a pull request only includes the
+ commits related to that bug or feature.
+
+ 1. Do your best to have [well-formed commit messages][] for each change.
+ This provides consistency throughout the project, and ensures that commit
+ messages are able to be formatted properly by various git tools.
+
+ 1. Finally, push the commits to your fork and submit a [pull request][].
+
+[forking]: https://help.github.com/articles/fork-a-repo
+[well-formed commit messages]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
+[pull request]: https://help.github.com/articles/creating-a-pull-request
diff --git a/deps/google-benchmark/CONTRIBUTORS b/deps/google-benchmark/CONTRIBUTORS
new file mode 100644
index 000000000..32ab15bbe
--- /dev/null
+++ b/deps/google-benchmark/CONTRIBUTORS
@@ -0,0 +1,91 @@
+# People who have agreed to one of the CLAs and can contribute patches.
+# The AUTHORS file lists the copyright holders; this file
+# lists people. For example, Google employees are listed here
+# but not in AUTHORS, because Google holds the copyright.
+#
+# Names should be added to this file only after verifying that
+# the individual or the individual's organization has agreed to
+# the appropriate Contributor License Agreement, found here:
+#
+# https://developers.google.com/open-source/cla/individual
+# https://developers.google.com/open-source/cla/corporate
+#
+# The agreement for individuals can be filled out on the web.
+#
+# When adding J Random Contributor's name to this file,
+# either J's name or J's organization's name should be
+# added to the AUTHORS file, depending on whether the
+# individual or corporate CLA was used.
+#
+# Names should be added to this file as:
+# Name
+#
+# Please keep the list sorted.
+
+Abhina Sreeskantharajan
+Albert Pretorius
+Alex Steele
+Andriy Berestovskyy
+Arne Beer
+Bátor Tallér
+Billy Robert O'Neal III
+Cezary Skrzyński
+Chris Kennelly
+Christian Wassermann
+Christopher Seymour
+Colin Braley
+Cyrille Faucheux
+Daniel Harvey
+David Coeurjolly
+Deniz Evrenci
+Dominic Hamon
+Dominik Czarnota
+Dominik Korman
+Donald Aingworth
+Eric Backus
+Eric Fiselier
+Eugene Zhuk
+Evgeny Safronov
+Fanbo Meng
+Federico Ficarelli
+Felix Homann
+Geoffrey Martin-Noble
+Gergő Szitár
+Hannes Hauswedell
+Ismael Jimenez Martinez
+Jern-Kuan Leong
+JianXiong Zhou
+Joao Paulo Magalhaes
+John Millikin
+Jordan Williams
+Jussi Knuuttila
+Kai Wolf
+Kaito Udagawa
+Kishan Kumar
+Lei Xu
+Matt Clarkson
+Maxim Vafin
+Nick Hutchinson
+Norman Heino
+Oleksandr Sochka
+Ori Livneh
+Pascal Leroy
+Paul Redmond
+Pierre Phaneuf
+Radoslav Yovchev
+Rainer Orth
+Raghu Raja
+Raul Marin
+Ray Glover
+Robert Guo
+Roman Lebedev
+Sayan Bhattacharjee
+Shuo Chen
+Steven Wan
+Tobias Schmidt
+Tobias Ulvgård
+Tom Madams
+Yixuan Qiu
+Yusuke Suzuki
+Zbigniew Skowron
+Min-Yih Hsu
diff --git a/deps/google-benchmark/LICENSE b/deps/google-benchmark/LICENSE
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/deps/google-benchmark/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/deps/google-benchmark/README.md b/deps/google-benchmark/README.md
new file mode 100644
index 000000000..205fb008a
--- /dev/null
+++ b/deps/google-benchmark/README.md
@@ -0,0 +1,218 @@
+# Benchmark
+
+[](https://github.com/google/benchmark/actions?query=workflow%3Abuild-and-test)
+[](https://github.com/google/benchmark/actions/workflows/bazel.yml)
+[](https://github.com/google/benchmark/actions?query=workflow%3Apylint)
+[](https://github.com/google/benchmark/actions?query=workflow%3Atest-bindings)
+
+[](https://travis-ci.org/google/benchmark)
+[](https://coveralls.io/r/google/benchmark)
+
+
+A library to benchmark code snippets, similar to unit tests. Example:
+
+```c++
+#include
+
+static void BM_SomeFunction(benchmark::State& state) {
+ // Perform setup here
+ for (auto _ : state) {
+ // This code gets timed
+ SomeFunction();
+ }
+}
+// Register the function as a benchmark
+BENCHMARK(BM_SomeFunction);
+// Run the benchmark
+BENCHMARK_MAIN();
+```
+
+## Getting Started
+
+To get started, see [Requirements](#requirements) and
+[Installation](#installation). See [Usage](#usage) for a full example and the
+[User Guide](docs/user_guide.md) for a more comprehensive feature overview.
+
+It may also help to read the [Google Test documentation](https://github.com/google/googletest/blob/master/docs/primer.md)
+as some of the structural aspects of the APIs are similar.
+
+## Resources
+
+[Discussion group](https://groups.google.com/d/forum/benchmark-discuss)
+
+IRC channels:
+* [libera](https://libera.chat) #benchmark
+
+[Additional Tooling Documentation](docs/tools.md)
+
+[Assembly Testing Documentation](docs/AssemblyTests.md)
+
+[Building and installing Python bindings](docs/python_bindings.md)
+
+## Requirements
+
+The library can be used with C++03. However, it requires C++11 to build,
+including compiler and standard library support.
+
+The following minimum versions are required to build the library:
+
+* GCC 4.8
+* Clang 3.4
+* Visual Studio 14 2015
+* Intel 2015 Update 1
+
+See [Platform-Specific Build Instructions](docs/platform_specific_build_instructions.md).
+
+## Installation
+
+This describes the installation process using cmake. As pre-requisites, you'll
+need git and cmake installed.
+
+_See [dependencies.md](docs/dependencies.md) for more details regarding supported
+versions of build tools._
+
+```bash
+# Check out the library.
+$ git clone https://github.com/google/benchmark.git
+# Go to the library root directory
+$ cd benchmark
+# Make a build directory to place the build output.
+$ cmake -E make_directory "build"
+# Generate build system files with cmake, and download any dependencies.
+$ cmake -E chdir "build" cmake -DBENCHMARK_DOWNLOAD_DEPENDENCIES=on -DCMAKE_BUILD_TYPE=Release ../
+# or, starting with CMake 3.13, use a simpler form:
+# cmake -DCMAKE_BUILD_TYPE=Release -S . -B "build"
+# Build the library.
+$ cmake --build "build" --config Release
+```
+This builds the `benchmark` and `benchmark_main` libraries and tests.
+On a unix system, the build directory should now look something like this:
+
+```
+/benchmark
+ /build
+ /src
+ /libbenchmark.a
+ /libbenchmark_main.a
+ /test
+ ...
+```
+
+Next, you can run the tests to check the build.
+
+```bash
+$ cmake -E chdir "build" ctest --build-config Release
+```
+
+If you want to install the library globally, also run:
+
+```
+sudo cmake --build "build" --config Release --target install
+```
+
+Note that Google Benchmark requires Google Test to build and run the tests. This
+dependency can be provided two ways:
+
+* Checkout the Google Test sources into `benchmark/googletest`.
+* Otherwise, if `-DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON` is specified during
+ configuration as above, the library will automatically download and build
+ any required dependencies.
+
+If you do not wish to build and run the tests, add `-DBENCHMARK_ENABLE_GTEST_TESTS=OFF`
+to `CMAKE_ARGS`.
+
+### Debug vs Release
+
+By default, benchmark builds as a debug library. You will see a warning in the
+output when this is the case. To build it as a release library instead, add
+`-DCMAKE_BUILD_TYPE=Release` when generating the build system files, as shown
+above. The use of `--config Release` in build commands is needed to properly
+support multi-configuration tools (like Visual Studio for example) and can be
+skipped for other build systems (like Makefile).
+
+To enable link-time optimisation, also add `-DBENCHMARK_ENABLE_LTO=true` when
+generating the build system files.
+
+If you are using gcc, you might need to set `GCC_AR` and `GCC_RANLIB` cmake
+cache variables, if autodetection fails.
+
+If you are using clang, you may need to set `LLVMAR_EXECUTABLE`,
+`LLVMNM_EXECUTABLE` and `LLVMRANLIB_EXECUTABLE` cmake cache variables.
+
+### Stable and Experimental Library Versions
+
+The main branch contains the latest stable version of the benchmarking library;
+the API of which can be considered largely stable, with source breaking changes
+being made only upon the release of a new major version.
+
+Newer, experimental, features are implemented and tested on the
+[`v2` branch](https://github.com/google/benchmark/tree/v2). Users who wish
+to use, test, and provide feedback on the new features are encouraged to try
+this branch. However, this branch provides no stability guarantees and reserves
+the right to change and break the API at any time.
+
+## Usage
+
+### Basic usage
+
+Define a function that executes the code to measure, register it as a benchmark
+function using the `BENCHMARK` macro, and ensure an appropriate `main` function
+is available:
+
+```c++
+#include
+
+static void BM_StringCreation(benchmark::State& state) {
+ for (auto _ : state)
+ std::string empty_string;
+}
+// Register the function as a benchmark
+BENCHMARK(BM_StringCreation);
+
+// Define another benchmark
+static void BM_StringCopy(benchmark::State& state) {
+ std::string x = "hello";
+ for (auto _ : state)
+ std::string copy(x);
+}
+BENCHMARK(BM_StringCopy);
+
+BENCHMARK_MAIN();
+```
+
+To run the benchmark, compile and link against the `benchmark` library
+(libbenchmark.a/.so). If you followed the build steps above, this library will
+be under the build directory you created.
+
+```bash
+# Example on linux after running the build steps above. Assumes the
+# `benchmark` and `build` directories are under the current directory.
+$ g++ mybenchmark.cc -std=c++11 -isystem benchmark/include \
+ -Lbenchmark/build/src -lbenchmark -lpthread -o mybenchmark
+```
+
+Alternatively, link against the `benchmark_main` library and remove
+`BENCHMARK_MAIN();` above to get the same behavior.
+
+The compiled executable will run all benchmarks by default. Pass the `--help`
+flag for option information or see the [User Guide](docs/user_guide.md).
+
+### Usage with CMake
+
+If using CMake, it is recommended to link against the project-provided
+`benchmark::benchmark` and `benchmark::benchmark_main` targets using
+`target_link_libraries`.
+It is possible to use ```find_package``` to import an installed version of the
+library.
+```cmake
+find_package(benchmark REQUIRED)
+```
+Alternatively, ```add_subdirectory``` will incorporate the library directly in
+to one's CMake project.
+```cmake
+add_subdirectory(benchmark)
+```
+Either way, link to the library as follows.
+```cmake
+target_link_libraries(MyTarget benchmark::benchmark)
+```
diff --git a/deps/google-benchmark/WORKSPACE b/deps/google-benchmark/WORKSPACE
new file mode 100644
index 000000000..b468abafd
--- /dev/null
+++ b/deps/google-benchmark/WORKSPACE
@@ -0,0 +1,75 @@
+workspace(name = "com_github_google_benchmark")
+
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
+
+
+http_archive(
+ name = "bazel_skylib",
+ urls = [
+ "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.2.1/bazel-skylib-1.2.1.tar.gz",
+ "https://github.com/bazelbuild/bazel-skylib/releases/download/1.2.1/bazel-skylib-1.2.1.tar.gz",
+ ],
+ sha256 = "f7be3474d42aae265405a592bb7da8e171919d74c16f082a5457840f06054728",
+)
+
+# https://github.com/bazelbuild/rules_foreign_cc/
+http_archive(
+ name = "rules_foreign_cc",
+ sha256 = "bcd0c5f46a49b85b384906daae41d277b3dc0ff27c7c752cc51e43048a58ec83",
+ strip_prefix = "rules_foreign_cc-0.7.1",
+ url = "https://github.com/bazelbuild/rules_foreign_cc/archive/0.7.1.tar.gz",
+)
+
+load("@rules_foreign_cc//foreign_cc:repositories.bzl", "rules_foreign_cc_dependencies")
+rules_foreign_cc_dependencies()
+
+http_archive(
+ name = "com_google_absl",
+ sha256 = "f41868f7a938605c92936230081175d1eae87f6ea2c248f41077c8f88316f111",
+ strip_prefix = "abseil-cpp-20200225.2",
+ urls = ["https://github.com/abseil/abseil-cpp/archive/20200225.2.tar.gz"],
+)
+
+git_repository(
+ name = "com_google_googletest",
+ remote = "https://github.com/google/googletest.git",
+ tag = "release-1.11.0",
+)
+
+# Downloaded from v4.9.0 tag at https://sourceforge.net/p/perfmon2/libpfm4/ref/master/tags/
+http_archive(
+ name = "libpfm",
+ build_file = "//tools:libpfm.BUILD.bazel",
+ sha256 = "5da5f8872bde14b3634c9688d980f68bda28b510268723cc12973eedbab9fecc",
+ type = "tar.gz",
+ strip_prefix = "libpfm-4.11.0",
+ urls = ["https://sourceforge.net/projects/perfmon2/files/libpfm4/libpfm-4.11.0.tar.gz/download"],
+)
+
+http_archive(
+ name = "pybind11",
+ build_file = "@//bindings/python:pybind11.BUILD",
+ sha256 = "eacf582fa8f696227988d08cfc46121770823839fe9e301a20fbce67e7cd70ec",
+ strip_prefix = "pybind11-2.10.0",
+ urls = ["https://github.com/pybind/pybind11/archive/v2.10.0.tar.gz"],
+)
+
+new_local_repository(
+ name = "python_headers",
+ build_file = "@//bindings/python:python_headers.BUILD",
+ path = "/usr/include/python3.6", # May be overwritten by setup.py.
+)
+
+http_archive(
+ name = "rules_python",
+ url = "https://github.com/bazelbuild/rules_python/releases/download/0.1.0/rules_python-0.1.0.tar.gz",
+ sha256 = "b6d46438523a3ec0f3cead544190ee13223a52f6a6765a29eae7b7cc24cc83a0",
+)
+
+load("@rules_python//python:pip.bzl", pip3_install="pip_install")
+
+pip3_install(
+ name = "py_deps",
+ requirements = "//:requirements.txt",
+)
diff --git a/deps/google-benchmark/_config.yml b/deps/google-benchmark/_config.yml
new file mode 100644
index 000000000..1fa5ff852
--- /dev/null
+++ b/deps/google-benchmark/_config.yml
@@ -0,0 +1,2 @@
+theme: jekyll-theme-midnight
+markdown: GFM
diff --git a/deps/google-benchmark/appveyor.yml b/deps/google-benchmark/appveyor.yml
new file mode 100644
index 000000000..81da955f0
--- /dev/null
+++ b/deps/google-benchmark/appveyor.yml
@@ -0,0 +1,50 @@
+version: '{build}'
+
+image: Visual Studio 2017
+
+configuration:
+ - Debug
+ - Release
+
+environment:
+ matrix:
+ - compiler: msvc-15-seh
+ generator: "Visual Studio 15 2017"
+
+ - compiler: msvc-15-seh
+ generator: "Visual Studio 15 2017 Win64"
+
+ - compiler: msvc-14-seh
+ generator: "Visual Studio 14 2015"
+
+ - compiler: msvc-14-seh
+ generator: "Visual Studio 14 2015 Win64"
+
+ - compiler: gcc-5.3.0-posix
+ generator: "MinGW Makefiles"
+ cxx_path: 'C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin'
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+
+matrix:
+ fast_finish: true
+
+install:
+ # git bash conflicts with MinGW makefiles
+ - if "%generator%"=="MinGW Makefiles" (set "PATH=%PATH:C:\Program Files\Git\usr\bin;=%")
+ - if not "%cxx_path%"=="" (set "PATH=%PATH%;%cxx_path%")
+
+build_script:
+ - md _build -Force
+ - cd _build
+ - echo %configuration%
+ - cmake -G "%generator%" "-DCMAKE_BUILD_TYPE=%configuration%" -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON ..
+ - cmake --build . --config %configuration%
+
+test_script:
+ - ctest --build-config %configuration% --timeout 300 --output-on-failure
+
+artifacts:
+ - path: '_build/CMakeFiles/*.log'
+ name: logs
+ - path: '_build/Testing/**/*.xml'
+ name: test_results
diff --git a/deps/google-benchmark/bindings/python/BUILD b/deps/google-benchmark/bindings/python/BUILD
new file mode 100644
index 000000000..9559a76b3
--- /dev/null
+++ b/deps/google-benchmark/bindings/python/BUILD
@@ -0,0 +1,3 @@
+exports_files(glob(["*.BUILD"]))
+exports_files(["build_defs.bzl"])
+
diff --git a/deps/google-benchmark/bindings/python/build_defs.bzl b/deps/google-benchmark/bindings/python/build_defs.bzl
new file mode 100644
index 000000000..009820afd
--- /dev/null
+++ b/deps/google-benchmark/bindings/python/build_defs.bzl
@@ -0,0 +1,25 @@
+_SHARED_LIB_SUFFIX = {
+ "//conditions:default": ".so",
+ "//:windows": ".dll",
+}
+
+def py_extension(name, srcs, hdrs = [], copts = [], features = [], deps = []):
+ for shared_lib_suffix in _SHARED_LIB_SUFFIX.values():
+ shared_lib_name = name + shared_lib_suffix
+ native.cc_binary(
+ name = shared_lib_name,
+ linkshared = True,
+ linkstatic = True,
+ srcs = srcs + hdrs,
+ copts = copts,
+ features = features,
+ deps = deps,
+ )
+
+ return native.py_library(
+ name = name,
+ data = select({
+ platform: [name + shared_lib_suffix]
+ for platform, shared_lib_suffix in _SHARED_LIB_SUFFIX.items()
+ }),
+ )
diff --git a/deps/google-benchmark/bindings/python/google_benchmark/BUILD b/deps/google-benchmark/bindings/python/google_benchmark/BUILD
new file mode 100644
index 000000000..3c1561f48
--- /dev/null
+++ b/deps/google-benchmark/bindings/python/google_benchmark/BUILD
@@ -0,0 +1,38 @@
+load("//bindings/python:build_defs.bzl", "py_extension")
+
+py_library(
+ name = "google_benchmark",
+ srcs = ["__init__.py"],
+ visibility = ["//visibility:public"],
+ deps = [
+ ":_benchmark",
+ # pip; absl:app
+ ],
+)
+
+py_extension(
+ name = "_benchmark",
+ srcs = ["benchmark.cc"],
+ copts = [
+ "-fexceptions",
+ "-fno-strict-aliasing",
+ ],
+ features = ["-use_header_modules"],
+ deps = [
+ "//:benchmark",
+ "@pybind11",
+ "@python_headers",
+ ],
+)
+
+py_test(
+ name = "example",
+ srcs = ["example.py"],
+ python_version = "PY3",
+ srcs_version = "PY3",
+ visibility = ["//visibility:public"],
+ deps = [
+ ":google_benchmark",
+ ],
+)
+
diff --git a/deps/google-benchmark/bindings/python/google_benchmark/__init__.py b/deps/google-benchmark/bindings/python/google_benchmark/__init__.py
new file mode 100644
index 000000000..10f5d5dde
--- /dev/null
+++ b/deps/google-benchmark/bindings/python/google_benchmark/__init__.py
@@ -0,0 +1,162 @@
+# Copyright 2020 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Python benchmarking utilities.
+
+Example usage:
+ import google_benchmark as benchmark
+
+ @benchmark.register
+ def my_benchmark(state):
+ ... # Code executed outside `while` loop is not timed.
+
+ while state:
+ ... # Code executed within `while` loop is timed.
+
+ if __name__ == '__main__':
+ benchmark.main()
+"""
+import atexit
+
+from absl import app
+from google_benchmark import _benchmark
+from google_benchmark._benchmark import (
+ Counter,
+ kNanosecond,
+ kMicrosecond,
+ kMillisecond,
+ kSecond,
+ oNone,
+ o1,
+ oN,
+ oNSquared,
+ oNCubed,
+ oLogN,
+ oNLogN,
+ oAuto,
+ oLambda,
+ State,
+)
+
+
+__all__ = [
+ "register",
+ "main",
+ "Counter",
+ "kNanosecond",
+ "kMicrosecond",
+ "kMillisecond",
+ "kSecond",
+ "oNone",
+ "o1",
+ "oN",
+ "oNSquared",
+ "oNCubed",
+ "oLogN",
+ "oNLogN",
+ "oAuto",
+ "oLambda",
+ "State",
+]
+
+__version__ = "1.7.1"
+
+
+class __OptionMaker:
+ """A stateless class to collect benchmark options.
+
+ Collect all decorator calls like @option.range(start=0, limit=1<<5).
+ """
+
+ class Options:
+ """Pure data class to store options calls, along with the benchmarked function."""
+
+ def __init__(self, func):
+ self.func = func
+ self.builder_calls = []
+
+ @classmethod
+ def make(cls, func_or_options):
+ """Make Options from Options or the benchmarked function."""
+ if isinstance(func_or_options, cls.Options):
+ return func_or_options
+ return cls.Options(func_or_options)
+
+ def __getattr__(self, builder_name):
+ """Append option call in the Options."""
+
+ # The function that get returned on @option.range(start=0, limit=1<<5).
+ def __builder_method(*args, **kwargs):
+
+ # The decorator that get called, either with the benchmared function
+ # or the previous Options
+ def __decorator(func_or_options):
+ options = self.make(func_or_options)
+ options.builder_calls.append((builder_name, args, kwargs))
+ # The decorator returns Options so it is not technically a decorator
+ # and needs a final call to @regiser
+ return options
+
+ return __decorator
+
+ return __builder_method
+
+
+# Alias for nicer API.
+# We have to instantiate an object, even if stateless, to be able to use __getattr__
+# on option.range
+option = __OptionMaker()
+
+
+def register(undefined=None, *, name=None):
+ """Register function for benchmarking."""
+ if undefined is None:
+ # Decorator is called without parenthesis so we return a decorator
+ return lambda f: register(f, name=name)
+
+ # We have either the function to benchmark (simple case) or an instance of Options
+ # (@option._ case).
+ options = __OptionMaker.make(undefined)
+
+ if name is None:
+ name = options.func.__name__
+
+ # We register the benchmark and reproduce all the @option._ calls onto the
+ # benchmark builder pattern
+ benchmark = _benchmark.RegisterBenchmark(name, options.func)
+ for name, args, kwargs in options.builder_calls[::-1]:
+ getattr(benchmark, name)(*args, **kwargs)
+
+ # return the benchmarked function because the decorator does not modify it
+ return options.func
+
+
+def _flags_parser(argv):
+ argv = _benchmark.Initialize(argv)
+ return app.parse_flags_with_usage(argv)
+
+
+def _run_benchmarks(argv):
+ if len(argv) > 1:
+ raise app.UsageError("Too many command-line arguments.")
+ return _benchmark.RunSpecifiedBenchmarks()
+
+
+def main(argv=None):
+ return app.run(_run_benchmarks, argv=argv, flags_parser=_flags_parser)
+
+
+# Methods for use with custom main function.
+initialize = _benchmark.Initialize
+run_benchmarks = _benchmark.RunSpecifiedBenchmarks
+atexit.register(_benchmark.ClearRegisteredBenchmarks)
diff --git a/deps/google-benchmark/bindings/python/google_benchmark/benchmark.cc b/deps/google-benchmark/bindings/python/google_benchmark/benchmark.cc
new file mode 100644
index 000000000..5614b9281
--- /dev/null
+++ b/deps/google-benchmark/bindings/python/google_benchmark/benchmark.cc
@@ -0,0 +1,184 @@
+// Benchmark for Python.
+
+#include "benchmark/benchmark.h"
+
+#include
+#include
+#include
+
+#include "pybind11/operators.h"
+#include "pybind11/pybind11.h"
+#include "pybind11/stl.h"
+#include "pybind11/stl_bind.h"
+
+PYBIND11_MAKE_OPAQUE(benchmark::UserCounters);
+
+namespace {
+namespace py = ::pybind11;
+
+std::vector Initialize(const std::vector& argv) {
+ // The `argv` pointers here become invalid when this function returns, but
+ // benchmark holds the pointer to `argv[0]`. We create a static copy of it
+ // so it persists, and replace the pointer below.
+ static std::string executable_name(argv[0]);
+ std::vector ptrs;
+ ptrs.reserve(argv.size());
+ for (auto& arg : argv) {
+ ptrs.push_back(const_cast(arg.c_str()));
+ }
+ ptrs[0] = const_cast(executable_name.c_str());
+ int argc = static_cast(argv.size());
+ benchmark::Initialize(&argc, ptrs.data());
+ std::vector remaining_argv;
+ remaining_argv.reserve(argc);
+ for (int i = 0; i < argc; ++i) {
+ remaining_argv.emplace_back(ptrs[i]);
+ }
+ return remaining_argv;
+}
+
+benchmark::internal::Benchmark* RegisterBenchmark(const char* name,
+ py::function f) {
+ return benchmark::RegisterBenchmark(
+ name, [f](benchmark::State& state) { f(&state); });
+}
+
+PYBIND11_MODULE(_benchmark, m) {
+ using benchmark::TimeUnit;
+ py::enum_(m, "TimeUnit")
+ .value("kNanosecond", TimeUnit::kNanosecond)
+ .value("kMicrosecond", TimeUnit::kMicrosecond)
+ .value("kMillisecond", TimeUnit::kMillisecond)
+ .value("kSecond", TimeUnit::kSecond)
+ .export_values();
+
+ using benchmark::BigO;
+ py::enum_(m, "BigO")
+ .value("oNone", BigO::oNone)
+ .value("o1", BigO::o1)
+ .value("oN", BigO::oN)
+ .value("oNSquared", BigO::oNSquared)
+ .value("oNCubed", BigO::oNCubed)
+ .value("oLogN", BigO::oLogN)
+ .value("oNLogN", BigO::oLogN)
+ .value("oAuto", BigO::oAuto)
+ .value("oLambda", BigO::oLambda)
+ .export_values();
+
+ using benchmark::internal::Benchmark;
+ py::class_(m, "Benchmark")
+ // For methods returning a pointer tor the current object, reference
+ // return policy is used to ask pybind not to take ownership oof the
+ // returned object and avoid calling delete on it.
+ // https://pybind11.readthedocs.io/en/stable/advanced/functions.html#return-value-policies
+ //
+ // For methods taking a const std::vector<...>&, a copy is created
+ // because a it is bound to a Python list.
+ // https://pybind11.readthedocs.io/en/stable/advanced/cast/stl.html
+ .def("unit", &Benchmark::Unit, py::return_value_policy::reference)
+ .def("arg", &Benchmark::Arg, py::return_value_policy::reference)
+ .def("args", &Benchmark::Args, py::return_value_policy::reference)
+ .def("range", &Benchmark::Range, py::return_value_policy::reference,
+ py::arg("start"), py::arg("limit"))
+ .def("dense_range", &Benchmark::DenseRange,
+ py::return_value_policy::reference, py::arg("start"),
+ py::arg("limit"), py::arg("step") = 1)
+ .def("ranges", &Benchmark::Ranges, py::return_value_policy::reference)
+ .def("args_product", &Benchmark::ArgsProduct,
+ py::return_value_policy::reference)
+ .def("arg_name", &Benchmark::ArgName, py::return_value_policy::reference)
+ .def("arg_names", &Benchmark::ArgNames,
+ py::return_value_policy::reference)
+ .def("range_pair", &Benchmark::RangePair,
+ py::return_value_policy::reference, py::arg("lo1"), py::arg("hi1"),
+ py::arg("lo2"), py::arg("hi2"))
+ .def("range_multiplier", &Benchmark::RangeMultiplier,
+ py::return_value_policy::reference)
+ .def("min_time", &Benchmark::MinTime, py::return_value_policy::reference)
+ .def("min_warmup_time", &Benchmark::MinWarmUpTime,
+ py::return_value_policy::reference)
+ .def("iterations", &Benchmark::Iterations,
+ py::return_value_policy::reference)
+ .def("repetitions", &Benchmark::Repetitions,
+ py::return_value_policy::reference)
+ .def("report_aggregates_only", &Benchmark::ReportAggregatesOnly,
+ py::return_value_policy::reference, py::arg("value") = true)
+ .def("display_aggregates_only", &Benchmark::DisplayAggregatesOnly,
+ py::return_value_policy::reference, py::arg("value") = true)
+ .def("measure_process_cpu_time", &Benchmark::MeasureProcessCPUTime,
+ py::return_value_policy::reference)
+ .def("use_real_time", &Benchmark::UseRealTime,
+ py::return_value_policy::reference)
+ .def("use_manual_time", &Benchmark::UseManualTime,
+ py::return_value_policy::reference)
+ .def(
+ "complexity",
+ (Benchmark * (Benchmark::*)(benchmark::BigO)) & Benchmark::Complexity,
+ py::return_value_policy::reference,
+ py::arg("complexity") = benchmark::oAuto);
+
+ using benchmark::Counter;
+ py::class_ py_counter(m, "Counter");
+
+ py::enum_(py_counter, "Flags")
+ .value("kDefaults", Counter::Flags::kDefaults)
+ .value("kIsRate", Counter::Flags::kIsRate)
+ .value("kAvgThreads", Counter::Flags::kAvgThreads)
+ .value("kAvgThreadsRate", Counter::Flags::kAvgThreadsRate)
+ .value("kIsIterationInvariant", Counter::Flags::kIsIterationInvariant)
+ .value("kIsIterationInvariantRate",
+ Counter::Flags::kIsIterationInvariantRate)
+ .value("kAvgIterations", Counter::Flags::kAvgIterations)
+ .value("kAvgIterationsRate", Counter::Flags::kAvgIterationsRate)
+ .value("kInvert", Counter::Flags::kInvert)
+ .export_values()
+ .def(py::self | py::self);
+
+ py::enum_(py_counter, "OneK")
+ .value("kIs1000", Counter::OneK::kIs1000)
+ .value("kIs1024", Counter::OneK::kIs1024)
+ .export_values();
+
+ py_counter
+ .def(py::init(),
+ py::arg("value") = 0., py::arg("flags") = Counter::kDefaults,
+ py::arg("k") = Counter::kIs1000)
+ .def(py::init([](double value) { return Counter(value); }))
+ .def_readwrite("value", &Counter::value)
+ .def_readwrite("flags", &Counter::flags)
+ .def_readwrite("oneK", &Counter::oneK);
+ py::implicitly_convertible();
+ py::implicitly_convertible();
+
+ py::bind_map(m, "UserCounters");
+
+ using benchmark::State;
+ py::class_(m, "State")
+ .def("__bool__", &State::KeepRunning)
+ .def_property_readonly("keep_running", &State::KeepRunning)
+ .def("pause_timing", &State::PauseTiming)
+ .def("resume_timing", &State::ResumeTiming)
+ .def("skip_with_error", &State::SkipWithError)
+ .def_property_readonly("error_occurred", &State::error_occurred)
+ .def("set_iteration_time", &State::SetIterationTime)
+ .def_property("bytes_processed", &State::bytes_processed,
+ &State::SetBytesProcessed)
+ .def_property("complexity_n", &State::complexity_length_n,
+ &State::SetComplexityN)
+ .def_property("items_processed", &State::items_processed,
+ &State::SetItemsProcessed)
+ .def("set_label", (void (State::*)(const char*)) & State::SetLabel)
+ .def("range", &State::range, py::arg("pos") = 0)
+ .def_property_readonly("iterations", &State::iterations)
+ .def_readwrite("counters", &State::counters)
+ .def_property_readonly("thread_index", &State::thread_index)
+ .def_property_readonly("threads", &State::threads);
+
+ m.def("Initialize", Initialize);
+ m.def("RegisterBenchmark", RegisterBenchmark,
+ py::return_value_policy::reference);
+ m.def("RunSpecifiedBenchmarks",
+ []() { benchmark::RunSpecifiedBenchmarks(); });
+ m.def("ClearRegisteredBenchmarks", benchmark::ClearRegisteredBenchmarks);
+};
+} // namespace
diff --git a/deps/google-benchmark/bindings/python/google_benchmark/example.py b/deps/google-benchmark/bindings/python/google_benchmark/example.py
new file mode 100644
index 000000000..487acc9f1
--- /dev/null
+++ b/deps/google-benchmark/bindings/python/google_benchmark/example.py
@@ -0,0 +1,136 @@
+# Copyright 2020 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Example of Python using C++ benchmark framework.
+
+To run this example, you must first install the `google_benchmark` Python package.
+
+To install using `setup.py`, download and extract the `google_benchmark` source.
+In the extracted directory, execute:
+ python setup.py install
+"""
+
+import random
+import time
+
+import google_benchmark as benchmark
+from google_benchmark import Counter
+
+
+@benchmark.register
+def empty(state):
+ while state:
+ pass
+
+
+@benchmark.register
+def sum_million(state):
+ while state:
+ sum(range(1_000_000))
+
+@benchmark.register
+def pause_timing(state):
+ """Pause timing every iteration."""
+ while state:
+ # Construct a list of random ints every iteration without timing it
+ state.pause_timing()
+ random_list = [random.randint(0, 100) for _ in range(100)]
+ state.resume_timing()
+ # Time the in place sorting algorithm
+ random_list.sort()
+
+
+@benchmark.register
+def skipped(state):
+ if True: # Test some predicate here.
+ state.skip_with_error("some error")
+ return # NOTE: You must explicitly return, or benchmark will continue.
+
+ ... # Benchmark code would be here.
+
+
+@benchmark.register
+def manual_timing(state):
+ while state:
+ # Manually count Python CPU time
+ start = time.perf_counter() # perf_counter_ns() in Python 3.7+
+ # Something to benchmark
+ time.sleep(0.01)
+ end = time.perf_counter()
+ state.set_iteration_time(end - start)
+
+
+@benchmark.register
+def custom_counters(state):
+ """Collect cutom metric using benchmark.Counter."""
+ num_foo = 0.0
+ while state:
+ # Benchmark some code here
+ pass
+ # Collect some custom metric named foo
+ num_foo += 0.13
+
+ # Automatic Counter from numbers.
+ state.counters["foo"] = num_foo
+ # Set a counter as a rate.
+ state.counters["foo_rate"] = Counter(num_foo, Counter.kIsRate)
+ # Set a counter as an inverse of rate.
+ state.counters["foo_inv_rate"] = Counter(num_foo, Counter.kIsRate | Counter.kInvert)
+ # Set a counter as a thread-average quantity.
+ state.counters["foo_avg"] = Counter(num_foo, Counter.kAvgThreads)
+ # There's also a combined flag:
+ state.counters["foo_avg_rate"] = Counter(num_foo, Counter.kAvgThreadsRate)
+
+
+@benchmark.register
+@benchmark.option.measure_process_cpu_time()
+@benchmark.option.use_real_time()
+def with_options(state):
+ while state:
+ sum(range(1_000_000))
+
+
+@benchmark.register(name="sum_million_microseconds")
+@benchmark.option.unit(benchmark.kMicrosecond)
+def with_options2(state):
+ while state:
+ sum(range(1_000_000))
+
+
+@benchmark.register
+@benchmark.option.arg(100)
+@benchmark.option.arg(1000)
+def passing_argument(state):
+ while state:
+ sum(range(state.range(0)))
+
+
+@benchmark.register
+@benchmark.option.range(8, limit=8 << 10)
+def using_range(state):
+ while state:
+ sum(range(state.range(0)))
+
+
+@benchmark.register
+@benchmark.option.range_multiplier(2)
+@benchmark.option.range(1 << 10, 1 << 18)
+@benchmark.option.complexity(benchmark.oN)
+def computing_complexity(state):
+ while state:
+ sum(range(state.range(0)))
+ state.complexity_n = state.range(0)
+
+
+if __name__ == "__main__":
+ benchmark.main()
diff --git a/deps/google-benchmark/bindings/python/pybind11.BUILD b/deps/google-benchmark/bindings/python/pybind11.BUILD
new file mode 100644
index 000000000..bc8335003
--- /dev/null
+++ b/deps/google-benchmark/bindings/python/pybind11.BUILD
@@ -0,0 +1,20 @@
+cc_library(
+ name = "pybind11",
+ hdrs = glob(
+ include = [
+ "include/pybind11/*.h",
+ "include/pybind11/detail/*.h",
+ ],
+ exclude = [
+ "include/pybind11/common.h",
+ "include/pybind11/eigen.h",
+ ],
+ ),
+ copts = [
+ "-fexceptions",
+ "-Wno-undefined-inline",
+ "-Wno-pragma-once-outside-header",
+ ],
+ includes = ["include"],
+ visibility = ["//visibility:public"],
+)
diff --git a/deps/google-benchmark/bindings/python/python_headers.BUILD b/deps/google-benchmark/bindings/python/python_headers.BUILD
new file mode 100644
index 000000000..9c34cf6ca
--- /dev/null
+++ b/deps/google-benchmark/bindings/python/python_headers.BUILD
@@ -0,0 +1,6 @@
+cc_library(
+ name = "python_headers",
+ hdrs = glob(["**/*.h"]),
+ includes = ["."],
+ visibility = ["//visibility:public"],
+)
diff --git a/deps/google-benchmark/bindings/python/requirements.txt b/deps/google-benchmark/bindings/python/requirements.txt
new file mode 100644
index 000000000..f5bbe7eca
--- /dev/null
+++ b/deps/google-benchmark/bindings/python/requirements.txt
@@ -0,0 +1,2 @@
+absl-py>=0.7.1
+
diff --git a/deps/google-benchmark/cmake/AddCXXCompilerFlag.cmake b/deps/google-benchmark/cmake/AddCXXCompilerFlag.cmake
new file mode 100644
index 000000000..858589e97
--- /dev/null
+++ b/deps/google-benchmark/cmake/AddCXXCompilerFlag.cmake
@@ -0,0 +1,78 @@
+# - Adds a compiler flag if it is supported by the compiler
+#
+# This function checks that the supplied compiler flag is supported and then
+# adds it to the corresponding compiler flags
+#
+# add_cxx_compiler_flag( [])
+#
+# - Example
+#
+# include(AddCXXCompilerFlag)
+# add_cxx_compiler_flag(-Wall)
+# add_cxx_compiler_flag(-no-strict-aliasing RELEASE)
+# Requires CMake 2.6+
+
+if(__add_cxx_compiler_flag)
+ return()
+endif()
+set(__add_cxx_compiler_flag INCLUDED)
+
+include(CheckCXXCompilerFlag)
+
+function(mangle_compiler_flag FLAG OUTPUT)
+ string(TOUPPER "HAVE_CXX_FLAG_${FLAG}" SANITIZED_FLAG)
+ string(REPLACE "+" "X" SANITIZED_FLAG ${SANITIZED_FLAG})
+ string(REGEX REPLACE "[^A-Za-z_0-9]" "_" SANITIZED_FLAG ${SANITIZED_FLAG})
+ string(REGEX REPLACE "_+" "_" SANITIZED_FLAG ${SANITIZED_FLAG})
+ set(${OUTPUT} "${SANITIZED_FLAG}" PARENT_SCOPE)
+endfunction(mangle_compiler_flag)
+
+function(add_cxx_compiler_flag FLAG)
+ mangle_compiler_flag("${FLAG}" MANGLED_FLAG)
+ set(OLD_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
+ set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${FLAG}")
+ check_cxx_compiler_flag("${FLAG}" ${MANGLED_FLAG})
+ set(CMAKE_REQUIRED_FLAGS "${OLD_CMAKE_REQUIRED_FLAGS}")
+ if(${MANGLED_FLAG})
+ if(ARGC GREATER 1)
+ set(VARIANT ${ARGV1})
+ string(TOUPPER "_${VARIANT}" VARIANT)
+ else()
+ set(VARIANT "")
+ endif()
+ set(CMAKE_CXX_FLAGS${VARIANT} "${CMAKE_CXX_FLAGS${VARIANT}} ${BENCHMARK_CXX_FLAGS${VARIANT}} ${FLAG}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+function(add_required_cxx_compiler_flag FLAG)
+ mangle_compiler_flag("${FLAG}" MANGLED_FLAG)
+ set(OLD_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
+ set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${FLAG}")
+ check_cxx_compiler_flag("${FLAG}" ${MANGLED_FLAG})
+ set(CMAKE_REQUIRED_FLAGS "${OLD_CMAKE_REQUIRED_FLAGS}")
+ if(${MANGLED_FLAG})
+ if(ARGC GREATER 1)
+ set(VARIANT ${ARGV1})
+ string(TOUPPER "_${VARIANT}" VARIANT)
+ else()
+ set(VARIANT "")
+ endif()
+ set(CMAKE_CXX_FLAGS${VARIANT} "${CMAKE_CXX_FLAGS${VARIANT}} ${FLAG}" PARENT_SCOPE)
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAG}" PARENT_SCOPE)
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${FLAG}" PARENT_SCOPE)
+ set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${FLAG}" PARENT_SCOPE)
+ set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${FLAG}" PARENT_SCOPE)
+ else()
+ message(FATAL_ERROR "Required flag '${FLAG}' is not supported by the compiler")
+ endif()
+endfunction()
+
+function(check_cxx_warning_flag FLAG)
+ mangle_compiler_flag("${FLAG}" MANGLED_FLAG)
+ set(OLD_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
+ # Add -Werror to ensure the compiler generates an error if the warning flag
+ # doesn't exist.
+ set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror ${FLAG}")
+ check_cxx_compiler_flag("${FLAG}" ${MANGLED_FLAG})
+ set(CMAKE_REQUIRED_FLAGS "${OLD_CMAKE_REQUIRED_FLAGS}")
+endfunction()
diff --git a/deps/google-benchmark/cmake/CXXFeatureCheck.cmake b/deps/google-benchmark/cmake/CXXFeatureCheck.cmake
new file mode 100644
index 000000000..50e5f680b
--- /dev/null
+++ b/deps/google-benchmark/cmake/CXXFeatureCheck.cmake
@@ -0,0 +1,78 @@
+# - Compile and run code to check for C++ features
+#
+# This functions compiles a source file under the `cmake` folder
+# and adds the corresponding `HAVE_[FILENAME]` flag to the CMake
+# environment
+#
+# cxx_feature_check( [])
+#
+# - Example
+#
+# include(CXXFeatureCheck)
+# cxx_feature_check(STD_REGEX)
+# Requires CMake 2.8.12+
+
+if(__cxx_feature_check)
+ return()
+endif()
+set(__cxx_feature_check INCLUDED)
+
+option(CXXFEATURECHECK_DEBUG OFF)
+
+function(cxx_feature_check FILE)
+ string(TOLOWER ${FILE} FILE)
+ string(TOUPPER ${FILE} VAR)
+ string(TOUPPER "HAVE_${VAR}" FEATURE)
+ if (DEFINED HAVE_${VAR})
+ set(HAVE_${VAR} 1 PARENT_SCOPE)
+ add_definitions(-DHAVE_${VAR})
+ return()
+ endif()
+
+ set(FEATURE_CHECK_CMAKE_FLAGS ${BENCHMARK_CXX_LINKER_FLAGS})
+ if (ARGC GREATER 1)
+ message(STATUS "Enabling additional flags: ${ARGV1}")
+ list(APPEND FEATURE_CHECK_CMAKE_FLAGS ${ARGV1})
+ endif()
+
+ if (NOT DEFINED COMPILE_${FEATURE})
+ if(CMAKE_CROSSCOMPILING)
+ message(STATUS "Cross-compiling to test ${FEATURE}")
+ try_compile(COMPILE_${FEATURE}
+ ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp
+ CMAKE_FLAGS ${FEATURE_CHECK_CMAKE_FLAGS}
+ LINK_LIBRARIES ${BENCHMARK_CXX_LIBRARIES}
+ OUTPUT_VARIABLE COMPILE_OUTPUT_VAR)
+ if(COMPILE_${FEATURE})
+ message(WARNING
+ "If you see build failures due to cross compilation, try setting HAVE_${VAR} to 0")
+ set(RUN_${FEATURE} 0 CACHE INTERNAL "")
+ else()
+ set(RUN_${FEATURE} 1 CACHE INTERNAL "")
+ endif()
+ else()
+ message(STATUS "Compiling and running to test ${FEATURE}")
+ try_run(RUN_${FEATURE} COMPILE_${FEATURE}
+ ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp
+ CMAKE_FLAGS ${FEATURE_CHECK_CMAKE_FLAGS}
+ LINK_LIBRARIES ${BENCHMARK_CXX_LIBRARIES}
+ COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT_VAR)
+ endif()
+ endif()
+
+ if(RUN_${FEATURE} EQUAL 0)
+ message(STATUS "Performing Test ${FEATURE} -- success")
+ set(HAVE_${VAR} 1 PARENT_SCOPE)
+ add_definitions(-DHAVE_${VAR})
+ else()
+ if(NOT COMPILE_${FEATURE})
+ if(CXXFEATURECHECK_DEBUG)
+ message(STATUS "Performing Test ${FEATURE} -- failed to compile: ${COMPILE_OUTPUT_VAR}")
+ else()
+ message(STATUS "Performing Test ${FEATURE} -- failed to compile")
+ endif()
+ else()
+ message(STATUS "Performing Test ${FEATURE} -- compiled but failed to run")
+ endif()
+ endif()
+endfunction()
diff --git a/deps/google-benchmark/cmake/Config.cmake.in b/deps/google-benchmark/cmake/Config.cmake.in
new file mode 100644
index 000000000..2e15f0cf8
--- /dev/null
+++ b/deps/google-benchmark/cmake/Config.cmake.in
@@ -0,0 +1,7 @@
+@PACKAGE_INIT@
+
+include (CMakeFindDependencyMacro)
+
+find_dependency (Threads)
+
+include("${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake")
diff --git a/deps/google-benchmark/cmake/GetGitVersion.cmake b/deps/google-benchmark/cmake/GetGitVersion.cmake
new file mode 100644
index 000000000..04a1f9b70
--- /dev/null
+++ b/deps/google-benchmark/cmake/GetGitVersion.cmake
@@ -0,0 +1,58 @@
+# - Returns a version string from Git tags
+#
+# This function inspects the annotated git tags for the project and returns a string
+# into a CMake variable
+#
+# get_git_version()
+#
+# - Example
+#
+# include(GetGitVersion)
+# get_git_version(GIT_VERSION)
+#
+# Requires CMake 2.8.11+
+find_package(Git)
+
+if(__get_git_version)
+ return()
+endif()
+set(__get_git_version INCLUDED)
+
+function(get_git_version var)
+ if(GIT_EXECUTABLE)
+ execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --match "v[0-9]*.[0-9]*.[0-9]*" --abbrev=8
+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+ RESULT_VARIABLE status
+ OUTPUT_VARIABLE GIT_DESCRIBE_VERSION
+ ERROR_QUIET)
+ if(status)
+ set(GIT_DESCRIBE_VERSION "v0.0.0")
+ endif()
+
+ string(STRIP ${GIT_DESCRIBE_VERSION} GIT_DESCRIBE_VERSION)
+ if(GIT_DESCRIBE_VERSION MATCHES v[^-]*-)
+ string(REGEX REPLACE "v([^-]*)-([0-9]+)-.*" "\\1.\\2" GIT_VERSION ${GIT_DESCRIBE_VERSION})
+ else()
+ string(REGEX REPLACE "v(.*)" "\\1" GIT_VERSION ${GIT_DESCRIBE_VERSION})
+ endif()
+
+ # Work out if the repository is dirty
+ execute_process(COMMAND ${GIT_EXECUTABLE} update-index -q --refresh
+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+ OUTPUT_QUIET
+ ERROR_QUIET)
+ execute_process(COMMAND ${GIT_EXECUTABLE} diff-index --name-only HEAD --
+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+ OUTPUT_VARIABLE GIT_DIFF_INDEX
+ ERROR_QUIET)
+ string(COMPARE NOTEQUAL "${GIT_DIFF_INDEX}" "" GIT_DIRTY)
+ if (${GIT_DIRTY})
+ set(GIT_DESCRIBE_VERSION "${GIT_DESCRIBE_VERSION}-dirty")
+ endif()
+ message(STATUS "git version: ${GIT_DESCRIBE_VERSION} normalized to ${GIT_VERSION}")
+ else()
+ set(GIT_VERSION "0.0.0")
+ endif()
+
+ set(${var} ${GIT_VERSION} PARENT_SCOPE)
+endfunction()
diff --git a/deps/google-benchmark/cmake/GoogleTest.cmake b/deps/google-benchmark/cmake/GoogleTest.cmake
new file mode 100644
index 000000000..44adbfbe4
--- /dev/null
+++ b/deps/google-benchmark/cmake/GoogleTest.cmake
@@ -0,0 +1,52 @@
+# Download and unpack googletest at configure time
+set(GOOGLETEST_PREFIX "${benchmark_BINARY_DIR}/third_party/googletest")
+configure_file(${benchmark_SOURCE_DIR}/cmake/GoogleTest.cmake.in ${GOOGLETEST_PREFIX}/CMakeLists.txt @ONLY)
+
+set(GOOGLETEST_PATH "${CMAKE_CURRENT_SOURCE_DIR}/googletest" CACHE PATH "") # Mind the quotes
+execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}"
+ -DALLOW_DOWNLOADING_GOOGLETEST=${BENCHMARK_DOWNLOAD_DEPENDENCIES} -DGOOGLETEST_PATH:PATH=${GOOGLETEST_PATH} .
+ RESULT_VARIABLE result
+ WORKING_DIRECTORY ${GOOGLETEST_PREFIX}
+)
+
+if(result)
+ message(FATAL_ERROR "CMake step for googletest failed: ${result}")
+endif()
+
+execute_process(
+ COMMAND ${CMAKE_COMMAND} --build .
+ RESULT_VARIABLE result
+ WORKING_DIRECTORY ${GOOGLETEST_PREFIX}
+)
+
+if(result)
+ message(FATAL_ERROR "Build step for googletest failed: ${result}")
+endif()
+
+# Prevent overriding the parent project's compiler/linker
+# settings on Windows
+set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
+
+include(${GOOGLETEST_PREFIX}/googletest-paths.cmake)
+
+# googletest doesn't seem to want to stay build warning clean so let's not hurt ourselves.
+if (MSVC)
+ add_compile_options(/wd4244 /wd4722)
+else()
+ add_compile_options(-w)
+endif()
+
+# Add googletest directly to our build. This defines
+# the gtest and gtest_main targets.
+add_subdirectory(${GOOGLETEST_SOURCE_DIR}
+ ${GOOGLETEST_BINARY_DIR}
+ EXCLUDE_FROM_ALL)
+
+if(NOT DEFINED GTEST_COMPILE_COMMANDS)
+ set(GTEST_COMPILE_COMMANDS ON)
+endif()
+
+set_target_properties(gtest PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $ EXPORT_COMPILE_COMMANDS ${GTEST_COMPILE_COMMANDS})
+set_target_properties(gtest_main PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $ EXPORT_COMPILE_COMMANDS ${GTEST_COMPILE_COMMANDS})
+set_target_properties(gmock PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $ EXPORT_COMPILE_COMMANDS ${GTEST_COMPILE_COMMANDS})
+set_target_properties(gmock_main PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $ EXPORT_COMPILE_COMMANDS ${GTEST_COMPILE_COMMANDS})
diff --git a/deps/google-benchmark/cmake/GoogleTest.cmake.in b/deps/google-benchmark/cmake/GoogleTest.cmake.in
new file mode 100644
index 000000000..ce653ac37
--- /dev/null
+++ b/deps/google-benchmark/cmake/GoogleTest.cmake.in
@@ -0,0 +1,59 @@
+cmake_minimum_required(VERSION 2.8.12)
+
+project(googletest-download NONE)
+
+# Enable ExternalProject CMake module
+include(ExternalProject)
+
+option(ALLOW_DOWNLOADING_GOOGLETEST "If googletest src tree is not found in location specified by GOOGLETEST_PATH, do fetch the archive from internet" OFF)
+set(GOOGLETEST_PATH "/usr/src/googletest" CACHE PATH
+ "Path to the googletest root tree. Should contain googletest and googlemock subdirs. And CMakeLists.txt in root, and in both of these subdirs")
+
+# Download and install GoogleTest
+
+message(STATUS "Looking for Google Test sources")
+message(STATUS "Looking for Google Test sources in ${GOOGLETEST_PATH}")
+if(EXISTS "${GOOGLETEST_PATH}" AND IS_DIRECTORY "${GOOGLETEST_PATH}" AND EXISTS "${GOOGLETEST_PATH}/CMakeLists.txt" AND
+ EXISTS "${GOOGLETEST_PATH}/googletest" AND IS_DIRECTORY "${GOOGLETEST_PATH}/googletest" AND EXISTS "${GOOGLETEST_PATH}/googletest/CMakeLists.txt" AND
+ EXISTS "${GOOGLETEST_PATH}/googlemock" AND IS_DIRECTORY "${GOOGLETEST_PATH}/googlemock" AND EXISTS "${GOOGLETEST_PATH}/googlemock/CMakeLists.txt")
+ message(STATUS "Found Google Test in ${GOOGLETEST_PATH}")
+
+ ExternalProject_Add(
+ googletest
+ PREFIX "${CMAKE_BINARY_DIR}"
+ DOWNLOAD_DIR "${CMAKE_BINARY_DIR}/download"
+ SOURCE_DIR "${GOOGLETEST_PATH}" # use existing src dir.
+ BINARY_DIR "${CMAKE_BINARY_DIR}/build"
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ TEST_COMMAND ""
+ )
+else()
+ if(NOT ALLOW_DOWNLOADING_GOOGLETEST)
+ message(SEND_ERROR "Did not find Google Test sources! Either pass correct path in GOOGLETEST_PATH, or enable BENCHMARK_DOWNLOAD_DEPENDENCIES, or disable BENCHMARK_USE_BUNDLED_GTEST, or disable BENCHMARK_ENABLE_GTEST_TESTS / BENCHMARK_ENABLE_TESTING.")
+ return()
+ else()
+ message(WARNING "Did not find Google Test sources! Fetching from web...")
+ ExternalProject_Add(
+ googletest
+ GIT_REPOSITORY https://github.com/google/googletest.git
+ GIT_TAG "release-1.11.0"
+ PREFIX "${CMAKE_BINARY_DIR}"
+ STAMP_DIR "${CMAKE_BINARY_DIR}/stamp"
+ DOWNLOAD_DIR "${CMAKE_BINARY_DIR}/download"
+ SOURCE_DIR "${CMAKE_BINARY_DIR}/src"
+ BINARY_DIR "${CMAKE_BINARY_DIR}/build"
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ TEST_COMMAND ""
+ )
+ endif()
+endif()
+
+ExternalProject_Get_Property(googletest SOURCE_DIR BINARY_DIR)
+file(WRITE googletest-paths.cmake
+"set(GOOGLETEST_SOURCE_DIR \"${SOURCE_DIR}\")
+set(GOOGLETEST_BINARY_DIR \"${BINARY_DIR}\")
+")
diff --git a/deps/google-benchmark/cmake/benchmark.pc.in b/deps/google-benchmark/cmake/benchmark.pc.in
new file mode 100644
index 000000000..9dae881c7
--- /dev/null
+++ b/deps/google-benchmark/cmake/benchmark.pc.in
@@ -0,0 +1,12 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=${prefix}
+libdir=@CMAKE_INSTALL_FULL_LIBDIR@
+includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
+
+Name: @PROJECT_NAME@
+Description: Google microbenchmark framework
+Version: @VERSION@
+
+Libs: -L${libdir} -lbenchmark
+Libs.private: -lpthread
+Cflags: -I${includedir}
diff --git a/deps/google-benchmark/cmake/gnu_posix_regex.cpp b/deps/google-benchmark/cmake/gnu_posix_regex.cpp
new file mode 100644
index 000000000..b5b91cdab
--- /dev/null
+++ b/deps/google-benchmark/cmake/gnu_posix_regex.cpp
@@ -0,0 +1,12 @@
+#include
+#include
+int main() {
+ std::string str = "test0159";
+ regex_t re;
+ int ec = regcomp(&re, "^[a-z]+[0-9]+$", REG_EXTENDED | REG_NOSUB);
+ if (ec != 0) {
+ return ec;
+ }
+ return regexec(&re, str.c_str(), 0, nullptr, 0) ? -1 : 0;
+}
+
diff --git a/deps/google-benchmark/cmake/llvm-toolchain.cmake b/deps/google-benchmark/cmake/llvm-toolchain.cmake
new file mode 100644
index 000000000..fc119e52f
--- /dev/null
+++ b/deps/google-benchmark/cmake/llvm-toolchain.cmake
@@ -0,0 +1,8 @@
+find_package(LLVMAr REQUIRED)
+set(CMAKE_AR "${LLVMAR_EXECUTABLE}" CACHE FILEPATH "" FORCE)
+
+find_package(LLVMNm REQUIRED)
+set(CMAKE_NM "${LLVMNM_EXECUTABLE}" CACHE FILEPATH "" FORCE)
+
+find_package(LLVMRanLib REQUIRED)
+set(CMAKE_RANLIB "${LLVMRANLIB_EXECUTABLE}" CACHE FILEPATH "" FORCE)
diff --git a/deps/google-benchmark/cmake/posix_regex.cpp b/deps/google-benchmark/cmake/posix_regex.cpp
new file mode 100644
index 000000000..466dc6256
--- /dev/null
+++ b/deps/google-benchmark/cmake/posix_regex.cpp
@@ -0,0 +1,14 @@
+#include
+#include
+int main() {
+ std::string str = "test0159";
+ regex_t re;
+ int ec = regcomp(&re, "^[a-z]+[0-9]+$", REG_EXTENDED | REG_NOSUB);
+ if (ec != 0) {
+ return ec;
+ }
+ int ret = regexec(&re, str.c_str(), 0, nullptr, 0) ? -1 : 0;
+ regfree(&re);
+ return ret;
+}
+
diff --git a/deps/google-benchmark/cmake/split_list.cmake b/deps/google-benchmark/cmake/split_list.cmake
new file mode 100644
index 000000000..67aed3fdc
--- /dev/null
+++ b/deps/google-benchmark/cmake/split_list.cmake
@@ -0,0 +1,3 @@
+macro(split_list listname)
+ string(REPLACE ";" " " ${listname} "${${listname}}")
+endmacro()
diff --git a/deps/google-benchmark/cmake/std_regex.cpp b/deps/google-benchmark/cmake/std_regex.cpp
new file mode 100644
index 000000000..696f2a26b
--- /dev/null
+++ b/deps/google-benchmark/cmake/std_regex.cpp
@@ -0,0 +1,10 @@
+#include
+#include
+int main() {
+ const std::string str = "test0159";
+ std::regex re;
+ re = std::regex("^[a-z]+[0-9]+$",
+ std::regex_constants::extended | std::regex_constants::nosubs);
+ return std::regex_search(str, re) ? 0 : -1;
+}
+
diff --git a/deps/google-benchmark/cmake/steady_clock.cpp b/deps/google-benchmark/cmake/steady_clock.cpp
new file mode 100644
index 000000000..66d50d17e
--- /dev/null
+++ b/deps/google-benchmark/cmake/steady_clock.cpp
@@ -0,0 +1,7 @@
+#include
+
+int main() {
+ typedef std::chrono::steady_clock Clock;
+ Clock::time_point tp = Clock::now();
+ ((void)tp);
+}
diff --git a/deps/google-benchmark/cmake/thread_safety_attributes.cpp b/deps/google-benchmark/cmake/thread_safety_attributes.cpp
new file mode 100644
index 000000000..46161babd
--- /dev/null
+++ b/deps/google-benchmark/cmake/thread_safety_attributes.cpp
@@ -0,0 +1,4 @@
+#define HAVE_THREAD_SAFETY_ATTRIBUTES
+#include "../src/mutex.h"
+
+int main() {}
diff --git a/deps/google-benchmark/docs/AssemblyTests.md b/deps/google-benchmark/docs/AssemblyTests.md
new file mode 100644
index 000000000..1fbdc269b
--- /dev/null
+++ b/deps/google-benchmark/docs/AssemblyTests.md
@@ -0,0 +1,147 @@
+# Assembly Tests
+
+The Benchmark library provides a number of functions whose primary
+purpose in to affect assembly generation, including `DoNotOptimize`
+and `ClobberMemory`. In addition there are other functions,
+such as `KeepRunning`, for which generating good assembly is paramount.
+
+For these functions it's important to have tests that verify the
+correctness and quality of the implementation. This requires testing
+the code generated by the compiler.
+
+This document describes how the Benchmark library tests compiler output,
+as well as how to properly write new tests.
+
+
+## Anatomy of a Test
+
+Writing a test has two steps:
+
+* Write the code you want to generate assembly for.
+* Add `// CHECK` lines to match against the verified assembly.
+
+Example:
+```c++
+
+// CHECK-LABEL: test_add:
+extern "C" int test_add() {
+ extern int ExternInt;
+ return ExternInt + 1;
+
+ // CHECK: movl ExternInt(%rip), %eax
+ // CHECK: addl %eax
+ // CHECK: ret
+}
+
+```
+
+#### LLVM Filecheck
+
+[LLVM's Filecheck](https://llvm.org/docs/CommandGuide/FileCheck.html)
+is used to test the generated assembly against the `// CHECK` lines
+specified in the tests source file. Please see the documentation
+linked above for information on how to write `CHECK` directives.
+
+#### Tips and Tricks:
+
+* Tests should match the minimal amount of output required to establish
+correctness. `CHECK` directives don't have to match on the exact next line
+after the previous match, so tests should omit checks for unimportant
+bits of assembly. ([`CHECK-NEXT`](https://llvm.org/docs/CommandGuide/FileCheck.html#the-check-next-directive)
+can be used to ensure a match occurs exactly after the previous match).
+
+* The tests are compiled with `-O3 -g0`. So we're only testing the
+optimized output.
+
+* The assembly output is further cleaned up using `tools/strip_asm.py`.
+This removes comments, assembler directives, and unused labels before
+the test is run.
+
+* The generated and stripped assembly file for a test is output under
+`/test/.s`
+
+* Filecheck supports using [`CHECK` prefixes](https://llvm.org/docs/CommandGuide/FileCheck.html#cmdoption-check-prefixes)
+to specify lines that should only match in certain situations.
+The Benchmark tests use `CHECK-CLANG` and `CHECK-GNU` for lines that
+are only expected to match Clang or GCC's output respectively. Normal
+`CHECK` lines match against all compilers. (Note: `CHECK-NOT` and
+`CHECK-LABEL` are NOT prefixes. They are versions of non-prefixed
+`CHECK` lines)
+
+* Use `extern "C"` to disable name mangling for specific functions. This
+makes them easier to name in the `CHECK` lines.
+
+
+## Problems Writing Portable Tests
+
+Writing tests which check the code generated by a compiler are
+inherently non-portable. Different compilers and even different compiler
+versions may generate entirely different code. The Benchmark tests
+must tolerate this.
+
+LLVM Filecheck provides a number of mechanisms to help write
+"more portable" tests; including [matching using regular expressions](https://llvm.org/docs/CommandGuide/FileCheck.html#filecheck-pattern-matching-syntax),
+allowing the creation of [named variables](https://llvm.org/docs/CommandGuide/FileCheck.html#filecheck-variables)
+for later matching, and [checking non-sequential matches](https://llvm.org/docs/CommandGuide/FileCheck.html#the-check-dag-directive).
+
+#### Capturing Variables
+
+For example, say GCC stores a variable in a register but Clang stores
+it in memory. To write a test that tolerates both cases we "capture"
+the destination of the store, and then use the captured expression
+to write the remainder of the test.
+
+```c++
+// CHECK-LABEL: test_div_no_op_into_shr:
+extern "C" void test_div_no_op_into_shr(int value) {
+ int divisor = 2;
+ benchmark::DoNotOptimize(divisor); // hide the value from the optimizer
+ return value / divisor;
+
+ // CHECK: movl $2, [[DEST:.*]]
+ // CHECK: idivl [[DEST]]
+ // CHECK: ret
+}
+```
+
+#### Using Regular Expressions to Match Differing Output
+
+Often tests require testing assembly lines which may subtly differ
+between compilers or compiler versions. A common example of this
+is matching stack frame addresses. In this case regular expressions
+can be used to match the differing bits of output. For example:
+
+```c++
+int ExternInt;
+struct Point { int x, y, z; };
+
+// CHECK-LABEL: test_store_point:
+extern "C" void test_store_point() {
+ Point p{ExternInt, ExternInt, ExternInt};
+ benchmark::DoNotOptimize(p);
+
+ // CHECK: movl ExternInt(%rip), %eax
+ // CHECK: movl %eax, -{{[0-9]+}}(%rsp)
+ // CHECK: movl %eax, -{{[0-9]+}}(%rsp)
+ // CHECK: movl %eax, -{{[0-9]+}}(%rsp)
+ // CHECK: ret
+}
+```
+
+## Current Requirements and Limitations
+
+The tests require Filecheck to be installed along the `PATH` of the
+build machine. Otherwise the tests will be disabled.
+
+Additionally, as mentioned in the previous section, codegen tests are
+inherently non-portable. Currently the tests are limited to:
+
+* x86_64 targets.
+* Compiled with GCC or Clang
+
+Further work could be done, at least on a limited basis, to extend the
+tests to other architectures and compilers (using `CHECK` prefixes).
+
+Furthermore, the tests fail for builds which specify additional flags
+that modify code generation, including `--coverage` or `-fsanitize=`.
+
diff --git a/deps/google-benchmark/docs/_config.yml b/deps/google-benchmark/docs/_config.yml
new file mode 100644
index 000000000..2f7efbeab
--- /dev/null
+++ b/deps/google-benchmark/docs/_config.yml
@@ -0,0 +1 @@
+theme: jekyll-theme-minimal
\ No newline at end of file
diff --git a/deps/google-benchmark/docs/dependencies.md b/deps/google-benchmark/docs/dependencies.md
new file mode 100644
index 000000000..57003aa33
--- /dev/null
+++ b/deps/google-benchmark/docs/dependencies.md
@@ -0,0 +1,21 @@
+# Build tool dependency policy
+
+To ensure the broadest compatibility when building the benchmark library, but
+still allow forward progress, we require any build tooling to be available for:
+
+* Debian stable _and_
+* The last two Ubuntu LTS releases
+
+Currently, this means using build tool versions that are available for Ubuntu
+Ubuntu 20.04 (Focal Fossa), Ubuntu 22.04 (Jammy Jellyfish) and Debian 11.4 (bullseye).
+
+_Note, CI also runs ubuntu-18.04 to attempt best effort support for older versions._
+
+## cmake
+The current supported version is cmake 3.16.3 as of 2022-08-10.
+
+* _3.10.2 (ubuntu 18.04)_
+* 3.16.3 (ubuntu 20.04)
+* 3.18.4 (debian 11.4)
+* 3.22.1 (ubuntu 22.04)
+
diff --git a/deps/google-benchmark/docs/index.md b/deps/google-benchmark/docs/index.md
new file mode 100644
index 000000000..eb82eff9e
--- /dev/null
+++ b/deps/google-benchmark/docs/index.md
@@ -0,0 +1,10 @@
+# Benchmark
+
+* [Assembly Tests](AssemblyTests.md)
+* [Dependencies](dependencies.md)
+* [Perf Counters](perf_counters.md)
+* [Platform Specific Build Instructions](platform_specific_build_instructions.md)
+* [Random Interleaving](random_interleaving.md)
+* [Releasing](releasing.md)
+* [Tools](tools.md)
+* [User Guide](user_guide.md)
\ No newline at end of file
diff --git a/deps/google-benchmark/docs/perf_counters.md b/deps/google-benchmark/docs/perf_counters.md
new file mode 100644
index 000000000..db83145c9
--- /dev/null
+++ b/deps/google-benchmark/docs/perf_counters.md
@@ -0,0 +1,35 @@
+
+
+# User-Requested Performance Counters
+
+When running benchmarks, the user may choose to request collection of
+performance counters. This may be useful in investigation scenarios - narrowing
+down the cause of a regression; or verifying that the underlying cause of a
+performance improvement matches expectations.
+
+This feature is available if:
+
+* The benchmark is run on an architecture featuring a Performance Monitoring
+ Unit (PMU),
+* The benchmark is compiled with support for collecting counters. Currently,
+ this requires [libpfm](http://perfmon2.sourceforge.net/), which is built as a
+ dependency via Bazel.
+
+The feature does not require modifying benchmark code. Counter collection is
+handled at the boundaries where timer collection is also handled.
+
+To opt-in:
+* If using a Bazel build, add `--define pfm=1` to your buid flags
+* If using CMake:
+ * Install `libpfm4-dev`, e.g. `apt-get install libpfm4-dev`.
+ * Enable the CMake flag `BENCHMARK_ENABLE_LIBPFM` in `CMakeLists.txt`.
+
+To use, pass a comma-separated list of counter names through the
+`--benchmark_perf_counters` flag. The names are decoded through libpfm - meaning,
+they are platform specific, but some (e.g. `CYCLES` or `INSTRUCTIONS`) are
+mapped by libpfm to platform-specifics - see libpfm
+[documentation](http://perfmon2.sourceforge.net/docs.html) for more details.
+
+The counter values are reported back through the [User Counters](../README.md#custom-counters)
+mechanism, meaning, they are available in all the formats (e.g. JSON) supported
+by User Counters.
diff --git a/deps/google-benchmark/docs/platform_specific_build_instructions.md b/deps/google-benchmark/docs/platform_specific_build_instructions.md
new file mode 100644
index 000000000..2d5d6c47e
--- /dev/null
+++ b/deps/google-benchmark/docs/platform_specific_build_instructions.md
@@ -0,0 +1,48 @@
+# Platform Specific Build Instructions
+
+## Building with GCC
+
+When the library is built using GCC it is necessary to link with the pthread
+library due to how GCC implements `std::thread`. Failing to link to pthread will
+lead to runtime exceptions (unless you're using libc++), not linker errors. See
+[issue #67](https://github.com/google/benchmark/issues/67) for more details. You
+can link to pthread by adding `-pthread` to your linker command. Note, you can
+also use `-lpthread`, but there are potential issues with ordering of command
+line parameters if you use that.
+
+On QNX, the pthread library is part of libc and usually included automatically
+(see
+[`pthread_create()`](https://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.neutrino.lib_ref/topic/p/pthread_create.html)).
+There's no separate pthread library to link.
+
+## Building with Visual Studio 2015 or 2017
+
+The `shlwapi` library (`-lshlwapi`) is required to support a call to `CPUInfo` which reads the registry. Either add `shlwapi.lib` under `[ Configuration Properties > Linker > Input ]`, or use the following:
+
+```
+// Alternatively, can add libraries using linker options.
+#ifdef _WIN32
+#pragma comment ( lib, "Shlwapi.lib" )
+#ifdef _DEBUG
+#pragma comment ( lib, "benchmarkd.lib" )
+#else
+#pragma comment ( lib, "benchmark.lib" )
+#endif
+#endif
+```
+
+Can also use the graphical version of CMake:
+* Open `CMake GUI`.
+* Under `Where to build the binaries`, same path as source plus `build`.
+* Under `CMAKE_INSTALL_PREFIX`, same path as source plus `install`.
+* Click `Configure`, `Generate`, `Open Project`.
+* If build fails, try deleting entire directory and starting again, or unticking options to build less.
+
+## Building with Intel 2015 Update 1 or Intel System Studio Update 4
+
+See instructions for building with Visual Studio. Once built, right click on the solution and change the build to Intel.
+
+## Building on Solaris
+
+If you're running benchmarks on solaris, you'll want the kstat library linked in
+too (`-lkstat`).
\ No newline at end of file
diff --git a/deps/google-benchmark/docs/python_bindings.md b/deps/google-benchmark/docs/python_bindings.md
new file mode 100644
index 000000000..6a7aab0a2
--- /dev/null
+++ b/deps/google-benchmark/docs/python_bindings.md
@@ -0,0 +1,34 @@
+# Building and installing Python bindings
+
+Python bindings are available as wheels on [PyPI](https://pypi.org/project/google-benchmark/) for importing and
+using Google Benchmark directly in Python.
+Currently, pre-built wheels exist for macOS (both ARM64 and Intel x86), Linux x86-64 and 64-bit Windows.
+Supported Python versions are Python 3.7 - 3.10.
+
+To install Google Benchmark's Python bindings, run:
+
+```bash
+python -m pip install --upgrade pip # for manylinux2014 support
+python -m pip install google-benchmark
+```
+
+In order to keep your system Python interpreter clean, it is advisable to run these commands in a virtual
+environment. See the [official Python documentation](https://docs.python.org/3/library/venv.html)
+on how to create virtual environments.
+
+To build a wheel directly from source, you can follow these steps:
+```bash
+git clone https://github.com/google/benchmark.git
+cd benchmark
+# create a virtual environment and activate it
+python3 -m venv venv --system-site-packages
+source venv/bin/activate # .\venv\Scripts\Activate.ps1 on Windows
+
+# upgrade Python's system-wide packages
+python -m pip install --upgrade pip setuptools wheel
+# builds the wheel and stores it in the directory "wheelhouse".
+python -m pip wheel . -w wheelhouse
+```
+
+NB: Building wheels from source requires Bazel. For platform-specific instructions on how to install Bazel,
+refer to the [Bazel installation docs](https://bazel.build/install).
diff --git a/deps/google-benchmark/docs/random_interleaving.md b/deps/google-benchmark/docs/random_interleaving.md
new file mode 100644
index 000000000..c08303684
--- /dev/null
+++ b/deps/google-benchmark/docs/random_interleaving.md
@@ -0,0 +1,13 @@
+
+
+# Random Interleaving
+
+[Random Interleaving](https://github.com/google/benchmark/issues/1051) is a
+technique to lower run-to-run variance. It randomly interleaves repetitions of a
+microbenchmark with repetitions from other microbenchmarks in the same benchmark
+test. Data shows it is able to lower run-to-run variance by
+[40%](https://github.com/google/benchmark/issues/1051) on average.
+
+To use, you mainly need to set `--benchmark_enable_random_interleaving=true`,
+and optionally specify non-zero repetition count `--benchmark_repetitions=9`
+and optionally decrease the per-repetition time `--benchmark_min_time=0.1`.
diff --git a/deps/google-benchmark/docs/reducing_variance.md b/deps/google-benchmark/docs/reducing_variance.md
new file mode 100644
index 000000000..f8b757580
--- /dev/null
+++ b/deps/google-benchmark/docs/reducing_variance.md
@@ -0,0 +1,100 @@
+# Reducing Variance
+
+
+
+## Disabling CPU Frequency Scaling
+
+If you see this error:
+
+```
+***WARNING*** CPU scaling is enabled, the benchmark real time measurements may be noisy and will incur extra overhead.
+```
+
+you might want to disable the CPU frequency scaling while running the
+benchmark, as well as consider other ways to stabilize the performance of
+your system while benchmarking.
+
+See [Reducing Variance](reducing_variance.md) for more information.
+
+Exactly how to do this depends on the Linux distribution,
+desktop environment, and installed programs. Specific details are a moving
+target, so we will not attempt to exhaustively document them here.
+
+One simple option is to use the `cpupower` program to change the
+performance governor to "performance". This tool is maintained along with
+the Linux kernel and provided by your distribution.
+
+It must be run as root, like this:
+
+```bash
+sudo cpupower frequency-set --governor performance
+```
+
+After this you can verify that all CPUs are using the performance governor
+by running this command:
+
+```bash
+cpupower frequency-info -o proc
+```
+
+The benchmarks you subsequently run will have less variance.
+
+
+
+## Reducing Variance in Benchmarks
+
+The Linux CPU frequency governor [discussed
+above](user_guide#disabling-cpu-frequency-scaling) is not the only source
+of noise in benchmarks. Some, but not all, of the sources of variance
+include:
+
+1. On multi-core machines not all CPUs/CPU cores/CPU threads run the same
+ speed, so running a benchmark one time and then again may give a
+ different result depending on which CPU it ran on.
+2. CPU scaling features that run on the CPU, like Intel's Turbo Boost and
+ AMD Turbo Core and Precision Boost, can temporarily change the CPU
+ frequency even when the using the "performance" governor on Linux.
+3. Context switching between CPUs, or scheduling competition on the CPU the
+ benchmark is running on.
+4. Intel Hyperthreading or AMD SMT causing the same issue as above.
+5. Cache effects caused by code running on other CPUs.
+6. Non-uniform memory architectures (NUMA).
+
+These can cause variance in benchmarks results within a single run
+(`--benchmark_repetitions=N`) or across multiple runs of the benchmark
+program.
+
+Reducing sources of variance is OS and architecture dependent, which is one
+reason some companies maintain machines dedicated to performance testing.
+
+Some of the easier and and effective ways of reducing variance on a typical
+Linux workstation are:
+
+1. Use the performance governer as [discussed
+above](user_guide#disabling-cpu-frequency-scaling).
+1. Disable processor boosting by:
+ ```sh
+ echo 0 | sudo tee /sys/devices/system/cpu/cpufreq/boost
+ ```
+ See the Linux kernel's
+ [boost.txt](https://www.kernel.org/doc/Documentation/cpu-freq/boost.txt)
+ for more information.
+2. Set the benchmark program's task affinity to a fixed cpu. For example:
+ ```sh
+ taskset -c 0 ./mybenchmark
+ ```
+3. Disabling Hyperthreading/SMT. This can be done in the Bios or using the
+ `/sys` file system (see the LLVM project's [Benchmarking
+ tips](https://llvm.org/docs/Benchmarking.html)).
+4. Close other programs that do non-trivial things based on timers, such as
+ your web browser, desktop environment, etc.
+5. Reduce the working set of your benchmark to fit within the L1 cache, but
+ do be aware that this may lead you to optimize for an unrelistic
+ situation.
+
+Further resources on this topic:
+
+1. The LLVM project's [Benchmarking
+ tips](https://llvm.org/docs/Benchmarking.html).
+1. The Arch Wiki [Cpu frequency
+scaling](https://wiki.archlinux.org/title/CPU_frequency_scaling) page.
diff --git a/deps/google-benchmark/docs/releasing.md b/deps/google-benchmark/docs/releasing.md
new file mode 100644
index 000000000..6d3b6138c
--- /dev/null
+++ b/deps/google-benchmark/docs/releasing.md
@@ -0,0 +1,37 @@
+# How to release
+
+* Make sure you're on main and synced to HEAD
+* Ensure the project builds and tests run
+ * `parallel -j0 exec ::: test/*_test` can help ensure everything at least
+ passes
+* Prepare release notes
+ * `git log $(git describe --abbrev=0 --tags)..HEAD` gives you the list of
+ commits between the last annotated tag and HEAD
+ * Pick the most interesting.
+* Create one last commit that updates the version saved in `CMakeLists.txt` and the
+ `__version__` variable in `bindings/python/google_benchmark/__init__.py`to the release
+ version you're creating. (This version will be used if benchmark is installed from the
+ archive you'll be creating in the next step.)
+
+```
+project (benchmark VERSION 1.6.0 LANGUAGES CXX)
+```
+
+```python
+# bindings/python/google_benchmark/__init__.py
+
+# ...
+
+__version__ = "1.6.0" # <-- change this to the release version you are creating
+
+# ...
+```
+
+* Create a release through github's interface
+ * Note this will create a lightweight tag.
+ * Update this to an annotated tag:
+ * `git pull --tags`
+ * `git tag -a -f `
+ * `git push --force --tags origin`
+* Confirm that the "Build and upload Python wheels" action runs to completion
+ * run it manually if it hasn't run
diff --git a/deps/google-benchmark/docs/tools.md b/deps/google-benchmark/docs/tools.md
new file mode 100644
index 000000000..f2d0c497f
--- /dev/null
+++ b/deps/google-benchmark/docs/tools.md
@@ -0,0 +1,203 @@
+# Benchmark Tools
+
+## compare.py
+
+The `compare.py` can be used to compare the result of benchmarks.
+
+### Dependencies
+The utility relies on the [scipy](https://www.scipy.org) package which can be installed using pip:
+```bash
+pip3 install -r requirements.txt
+```
+
+### Displaying aggregates only
+
+The switch `-a` / `--display_aggregates_only` can be used to control the
+displayment of the normal iterations vs the aggregates. When passed, it will
+be passthrough to the benchmark binaries to be run, and will be accounted for
+in the tool itself; only the aggregates will be displayed, but not normal runs.
+It only affects the display, the separate runs will still be used to calculate
+the U test.
+
+### Modes of operation
+
+There are three modes of operation:
+
+1. Just compare two benchmarks
+The program is invoked like:
+
+``` bash
+$ compare.py benchmarks [benchmark options]...
+```
+Where `` and `` either specify a benchmark executable file, or a JSON output file. The type of the input file is automatically detected. If a benchmark executable is specified then the benchmark is run to obtain the results. Otherwise the results are simply loaded from the output file.
+
+`[benchmark options]` will be passed to the benchmarks invocations. They can be anything that binary accepts, be it either normal `--benchmark_*` parameters, or some custom parameters your binary takes.
+
+Example output:
+```
+$ ./compare.py benchmarks ./a.out ./a.out
+RUNNING: ./a.out --benchmark_out=/tmp/tmprBT5nW
+Run on (8 X 4000 MHz CPU s)
+2017-11-07 21:16:44
+------------------------------------------------------
+Benchmark Time CPU Iterations
+------------------------------------------------------
+BM_memcpy/8 36 ns 36 ns 19101577 211.669MB/s
+BM_memcpy/64 76 ns 76 ns 9412571 800.199MB/s
+BM_memcpy/512 84 ns 84 ns 8249070 5.64771GB/s
+BM_memcpy/1024 116 ns 116 ns 6181763 8.19505GB/s
+BM_memcpy/8192 643 ns 643 ns 1062855 11.8636GB/s
+BM_copy/8 222 ns 222 ns 3137987 34.3772MB/s
+BM_copy/64 1608 ns 1608 ns 432758 37.9501MB/s
+BM_copy/512 12589 ns 12589 ns 54806 38.7867MB/s
+BM_copy/1024 25169 ns 25169 ns 27713 38.8003MB/s
+BM_copy/8192 201165 ns 201112 ns 3486 38.8466MB/s
+RUNNING: ./a.out --benchmark_out=/tmp/tmpt1wwG_
+Run on (8 X 4000 MHz CPU s)
+2017-11-07 21:16:53
+------------------------------------------------------
+Benchmark Time CPU Iterations
+------------------------------------------------------
+BM_memcpy/8 36 ns 36 ns 19397903 211.255MB/s
+BM_memcpy/64 73 ns 73 ns 9691174 839.635MB/s
+BM_memcpy/512 85 ns 85 ns 8312329 5.60101GB/s
+BM_memcpy/1024 118 ns 118 ns 6438774 8.11608GB/s
+BM_memcpy/8192 656 ns 656 ns 1068644 11.6277GB/s
+BM_copy/8 223 ns 223 ns 3146977 34.2338MB/s
+BM_copy/64 1611 ns 1611 ns 435340 37.8751MB/s
+BM_copy/512 12622 ns 12622 ns 54818 38.6844MB/s
+BM_copy/1024 25257 ns 25239 ns 27779 38.6927MB/s
+BM_copy/8192 205013 ns 205010 ns 3479 38.108MB/s
+Comparing ./a.out to ./a.out
+Benchmark Time CPU Time Old Time New CPU Old CPU New
+------------------------------------------------------------------------------------------------------
+BM_memcpy/8 +0.0020 +0.0020 36 36 36 36
+BM_memcpy/64 -0.0468 -0.0470 76 73 76 73
+BM_memcpy/512 +0.0081 +0.0083 84 85 84 85
+BM_memcpy/1024 +0.0098 +0.0097 116 118 116 118
+BM_memcpy/8192 +0.0200 +0.0203 643 656 643 656
+BM_copy/8 +0.0046 +0.0042 222 223 222 223
+BM_copy/64 +0.0020 +0.0020 1608 1611 1608 1611
+BM_copy/512 +0.0027 +0.0026 12589 12622 12589 12622
+BM_copy/1024 +0.0035 +0.0028 25169 25257 25169 25239
+BM_copy/8192 +0.0191 +0.0194 201165 205013 201112 205010
+```
+
+What it does is for the every benchmark from the first run it looks for the benchmark with exactly the same name in the second run, and then compares the results. If the names differ, the benchmark is omitted from the diff.
+As you can note, the values in `Time` and `CPU` columns are calculated as `(new - old) / |old|`.
+
+2. Compare two different filters of one benchmark
+The program is invoked like:
+
+``` bash
+$ compare.py filters [benchmark options]...
+```
+Where `` either specify a benchmark executable file, or a JSON output file. The type of the input file is automatically detected. If a benchmark executable is specified then the benchmark is run to obtain the results. Otherwise the results are simply loaded from the output file.
+
+Where `` and `` are the same regex filters that you would pass to the `[--benchmark_filter=]` parameter of the benchmark binary.
+
+`[benchmark options]` will be passed to the benchmarks invocations. They can be anything that binary accepts, be it either normal `--benchmark_*` parameters, or some custom parameters your binary takes.
+
+Example output:
+```
+$ ./compare.py filters ./a.out BM_memcpy BM_copy
+RUNNING: ./a.out --benchmark_filter=BM_memcpy --benchmark_out=/tmp/tmpBWKk0k
+Run on (8 X 4000 MHz CPU s)
+2017-11-07 21:37:28
+------------------------------------------------------
+Benchmark Time CPU Iterations
+------------------------------------------------------
+BM_memcpy/8 36 ns 36 ns 17891491 211.215MB/s
+BM_memcpy/64 74 ns 74 ns 9400999 825.646MB/s
+BM_memcpy/512 87 ns 87 ns 8027453 5.46126GB/s
+BM_memcpy/1024 111 ns 111 ns 6116853 8.5648GB/s
+BM_memcpy/8192 657 ns 656 ns 1064679 11.6247GB/s
+RUNNING: ./a.out --benchmark_filter=BM_copy --benchmark_out=/tmp/tmpAvWcOM
+Run on (8 X 4000 MHz CPU s)
+2017-11-07 21:37:33
+----------------------------------------------------
+Benchmark Time CPU Iterations
+----------------------------------------------------
+BM_copy/8 227 ns 227 ns 3038700 33.6264MB/s
+BM_copy/64 1640 ns 1640 ns 426893 37.2154MB/s
+BM_copy/512 12804 ns 12801 ns 55417 38.1444MB/s
+BM_copy/1024 25409 ns 25407 ns 27516 38.4365MB/s
+BM_copy/8192 202986 ns 202990 ns 3454 38.4871MB/s
+Comparing BM_memcpy to BM_copy (from ./a.out)
+Benchmark Time CPU Time Old Time New CPU Old CPU New
+--------------------------------------------------------------------------------------------------------------------
+[BM_memcpy vs. BM_copy]/8 +5.2829 +5.2812 36 227 36 227
+[BM_memcpy vs. BM_copy]/64 +21.1719 +21.1856 74 1640 74 1640
+[BM_memcpy vs. BM_copy]/512 +145.6487 +145.6097 87 12804 87 12801
+[BM_memcpy vs. BM_copy]/1024 +227.1860 +227.1776 111 25409 111 25407
+[BM_memcpy vs. BM_copy]/8192 +308.1664 +308.2898 657 202986 656 202990
+```
+
+As you can see, it applies filter to the benchmarks, both when running the benchmark, and before doing the diff. And to make the diff work, the matches are replaced with some common string. Thus, you can compare two different benchmark families within one benchmark binary.
+As you can note, the values in `Time` and `CPU` columns are calculated as `(new - old) / |old|`.
+
+3. Compare filter one from benchmark one to filter two from benchmark two:
+The program is invoked like:
+
+``` bash
+$ compare.py filters [benchmark options]...
+```
+
+Where `` and `` either specify a benchmark executable file, or a JSON output file. The type of the input file is automatically detected. If a benchmark executable is specified then the benchmark is run to obtain the results. Otherwise the results are simply loaded from the output file.
+
+Where `` and `` are the same regex filters that you would pass to the `[--benchmark_filter=]` parameter of the benchmark binary.
+
+`[benchmark options]` will be passed to the benchmarks invocations. They can be anything that binary accepts, be it either normal `--benchmark_*` parameters, or some custom parameters your binary takes.
+
+Example output:
+```
+$ ./compare.py benchmarksfiltered ./a.out BM_memcpy ./a.out BM_copy
+RUNNING: ./a.out --benchmark_filter=BM_memcpy --benchmark_out=/tmp/tmp_FvbYg
+Run on (8 X 4000 MHz CPU s)
+2017-11-07 21:38:27
+------------------------------------------------------
+Benchmark Time CPU Iterations
+------------------------------------------------------
+BM_memcpy/8 37 ns 37 ns 18953482 204.118MB/s
+BM_memcpy/64 74 ns 74 ns 9206578 828.245MB/s
+BM_memcpy/512 91 ns 91 ns 8086195 5.25476GB/s
+BM_memcpy/1024 120 ns 120 ns 5804513 7.95662GB/s
+BM_memcpy/8192 664 ns 664 ns 1028363 11.4948GB/s
+RUNNING: ./a.out --benchmark_filter=BM_copy --benchmark_out=/tmp/tmpDfL5iE
+Run on (8 X 4000 MHz CPU s)
+2017-11-07 21:38:32
+----------------------------------------------------
+Benchmark Time CPU Iterations
+----------------------------------------------------
+BM_copy/8 230 ns 230 ns 2985909 33.1161MB/s
+BM_copy/64 1654 ns 1653 ns 419408 36.9137MB/s
+BM_copy/512 13122 ns 13120 ns 53403 37.2156MB/s
+BM_copy/1024 26679 ns 26666 ns 26575 36.6218MB/s
+BM_copy/8192 215068 ns 215053 ns 3221 36.3283MB/s
+Comparing BM_memcpy (from ./a.out) to BM_copy (from ./a.out)
+Benchmark Time CPU Time Old Time New CPU Old CPU New
+--------------------------------------------------------------------------------------------------------------------
+[BM_memcpy vs. BM_copy]/8 +5.1649 +5.1637 37 230 37 230
+[BM_memcpy vs. BM_copy]/64 +21.4352 +21.4374 74 1654 74 1653
+[BM_memcpy vs. BM_copy]/512 +143.6022 +143.5865 91 13122 91 13120
+[BM_memcpy vs. BM_copy]/1024 +221.5903 +221.4790 120 26679 120 26666
+[BM_memcpy vs. BM_copy]/8192 +322.9059 +323.0096 664 215068 664 215053
+```
+This is a mix of the previous two modes, two (potentially different) benchmark binaries are run, and a different filter is applied to each one.
+As you can note, the values in `Time` and `CPU` columns are calculated as `(new - old) / |old|`.
+
+### U test
+
+If there is a sufficient repetition count of the benchmarks, the tool can do
+a [U Test](https://en.wikipedia.org/wiki/Mann%E2%80%93Whitney_U_test), of the
+null hypothesis that it is equally likely that a randomly selected value from
+one sample will be less than or greater than a randomly selected value from a
+second sample.
+
+If the calculated p-value is below this value is lower than the significance
+level alpha, then the result is said to be statistically significant and the
+null hypothesis is rejected. Which in other words means that the two benchmarks
+aren't identical.
+
+**WARNING**: requires **LARGE** (no less than 9) number of repetitions to be
+meaningful!
diff --git a/deps/google-benchmark/docs/user_guide.md b/deps/google-benchmark/docs/user_guide.md
new file mode 100644
index 000000000..3c2e8f7ed
--- /dev/null
+++ b/deps/google-benchmark/docs/user_guide.md
@@ -0,0 +1,1252 @@
+# User Guide
+
+## Command Line
+
+[Output Formats](#output-formats)
+
+[Output Files](#output-files)
+
+[Running Benchmarks](#running-benchmarks)
+
+[Running a Subset of Benchmarks](#running-a-subset-of-benchmarks)
+
+[Result Comparison](#result-comparison)
+
+[Extra Context](#extra-context)
+
+## Library
+
+[Runtime and Reporting Considerations](#runtime-and-reporting-considerations)
+
+[Setup/Teardown](#setupteardown)
+
+[Passing Arguments](#passing-arguments)
+
+[Custom Benchmark Name](#custom-benchmark-name)
+
+[Calculating Asymptotic Complexity](#asymptotic-complexity)
+
+[Templated Benchmarks](#templated-benchmarks)
+
+[Fixtures](#fixtures)
+
+[Custom Counters](#custom-counters)
+
+[Multithreaded Benchmarks](#multithreaded-benchmarks)
+
+[CPU Timers](#cpu-timers)
+
+[Manual Timing](#manual-timing)
+
+[Setting the Time Unit](#setting-the-time-unit)
+
+[Random Interleaving](random_interleaving.md)
+
+[User-Requested Performance Counters](perf_counters.md)
+
+[Preventing Optimization](#preventing-optimization)
+
+[Reporting Statistics](#reporting-statistics)
+
+[Custom Statistics](#custom-statistics)
+
+[Memory Usage](#memory-usage)
+
+[Using RegisterBenchmark](#using-register-benchmark)
+
+[Exiting with an Error](#exiting-with-an-error)
+
+[A Faster KeepRunning Loop](#a-faster-keep-running-loop)
+
+## Benchmarking Tips
+
+[Disabling CPU Frequency Scaling](#disabling-cpu-frequency-scaling)
+
+[Reducing Variance in Benchmarks](reducing_variance.md)
+
+
+
+## Output Formats
+
+The library supports multiple output formats. Use the
+`--benchmark_format=` flag (or set the
+`BENCHMARK_FORMAT=` environment variable) to set
+the format type. `console` is the default format.
+
+The Console format is intended to be a human readable format. By default
+the format generates color output. Context is output on stderr and the
+tabular data on stdout. Example tabular output looks like:
+
+```
+Benchmark Time(ns) CPU(ns) Iterations
+----------------------------------------------------------------------
+BM_SetInsert/1024/1 28928 29349 23853 133.097kB/s 33.2742k items/s
+BM_SetInsert/1024/8 32065 32913 21375 949.487kB/s 237.372k items/s
+BM_SetInsert/1024/10 33157 33648 21431 1.13369MB/s 290.225k items/s
+```
+
+The JSON format outputs human readable json split into two top level attributes.
+The `context` attribute contains information about the run in general, including
+information about the CPU and the date.
+The `benchmarks` attribute contains a list of every benchmark run. Example json
+output looks like:
+
+```json
+{
+ "context": {
+ "date": "2015/03/17-18:40:25",
+ "num_cpus": 40,
+ "mhz_per_cpu": 2801,
+ "cpu_scaling_enabled": false,
+ "build_type": "debug"
+ },
+ "benchmarks": [
+ {
+ "name": "BM_SetInsert/1024/1",
+ "iterations": 94877,
+ "real_time": 29275,
+ "cpu_time": 29836,
+ "bytes_per_second": 134066,
+ "items_per_second": 33516
+ },
+ {
+ "name": "BM_SetInsert/1024/8",
+ "iterations": 21609,
+ "real_time": 32317,
+ "cpu_time": 32429,
+ "bytes_per_second": 986770,
+ "items_per_second": 246693
+ },
+ {
+ "name": "BM_SetInsert/1024/10",
+ "iterations": 21393,
+ "real_time": 32724,
+ "cpu_time": 33355,
+ "bytes_per_second": 1199226,
+ "items_per_second": 299807
+ }
+ ]
+}
+```
+
+The CSV format outputs comma-separated values. The `context` is output on stderr
+and the CSV itself on stdout. Example CSV output looks like:
+
+```
+name,iterations,real_time,cpu_time,bytes_per_second,items_per_second,label
+"BM_SetInsert/1024/1",65465,17890.7,8407.45,475768,118942,
+"BM_SetInsert/1024/8",116606,18810.1,9766.64,3.27646e+06,819115,
+"BM_SetInsert/1024/10",106365,17238.4,8421.53,4.74973e+06,1.18743e+06,
+```
+
+
+
+## Output Files
+
+Write benchmark results to a file with the `--benchmark_out=` option
+(or set `BENCHMARK_OUT`). Specify the output format with
+`--benchmark_out_format={json|console|csv}` (or set
+`BENCHMARK_OUT_FORMAT={json|console|csv}`). Note that the 'csv' reporter is
+deprecated and the saved `.csv` file
+[is not parsable](https://github.com/google/benchmark/issues/794) by csv
+parsers.
+
+Specifying `--benchmark_out` does not suppress the console output.
+
+
+
+## Running Benchmarks
+
+Benchmarks are executed by running the produced binaries. Benchmarks binaries,
+by default, accept options that may be specified either through their command
+line interface or by setting environment variables before execution. For every
+`--option_flag=` CLI switch, a corresponding environment variable
+`OPTION_FLAG=` exist and is used as default if set (CLI switches always
+ prevails). A complete list of CLI options is available running benchmarks
+ with the `--help` switch.
+
+
+
+## Running a Subset of Benchmarks
+
+The `--benchmark_filter=` option (or `BENCHMARK_FILTER=`
+environment variable) can be used to only run the benchmarks that match
+the specified ``. For example:
+
+```bash
+$ ./run_benchmarks.x --benchmark_filter=BM_memcpy/32
+Run on (1 X 2300 MHz CPU )
+2016-06-25 19:34:24
+Benchmark Time CPU Iterations
+----------------------------------------------------
+BM_memcpy/32 11 ns 11 ns 79545455
+BM_memcpy/32k 2181 ns 2185 ns 324074
+BM_memcpy/32 12 ns 12 ns 54687500
+BM_memcpy/32k 1834 ns 1837 ns 357143
+```
+
+## Disabling Benchmarks
+
+It is possible to temporarily disable benchmarks by renaming the benchmark
+function to have the prefix "DISABLED_". This will cause the benchmark to
+be skipped at runtime.
+
+
+
+## Result comparison
+
+It is possible to compare the benchmarking results.
+See [Additional Tooling Documentation](tools.md)
+
+
+
+## Extra Context
+
+Sometimes it's useful to add extra context to the content printed before the
+results. By default this section includes information about the CPU on which
+the benchmarks are running. If you do want to add more context, you can use
+the `benchmark_context` command line flag:
+
+```bash
+$ ./run_benchmarks --benchmark_context=pwd=`pwd`
+Run on (1 x 2300 MHz CPU)
+pwd: /home/user/benchmark/
+Benchmark Time CPU Iterations
+----------------------------------------------------
+BM_memcpy/32 11 ns 11 ns 79545455
+BM_memcpy/32k 2181 ns 2185 ns 324074
+```
+
+You can get the same effect with the API:
+
+```c++
+ benchmark::AddCustomContext("foo", "bar");
+```
+
+Note that attempts to add a second value with the same key will fail with an
+error message.
+
+
+
+## Runtime and Reporting Considerations
+
+When the benchmark binary is executed, each benchmark function is run serially.
+The number of iterations to run is determined dynamically by running the
+benchmark a few times and measuring the time taken and ensuring that the
+ultimate result will be statistically stable. As such, faster benchmark
+functions will be run for more iterations than slower benchmark functions, and
+the number of iterations is thus reported.
+
+In all cases, the number of iterations for which the benchmark is run is
+governed by the amount of time the benchmark takes. Concretely, the number of
+iterations is at least one, not more than 1e9, until CPU time is greater than
+the minimum time, or the wallclock time is 5x minimum time. The minimum time is
+set per benchmark by calling `MinTime` on the registered benchmark object.
+
+Furthermore warming up a benchmark might be necessary in order to get
+stable results because of e.g caching effects of the code under benchmark.
+Warming up means running the benchmark a given amount of time, before
+results are actually taken into account. The amount of time for which
+the warmup should be run can be set per benchmark by calling
+`MinWarmUpTime` on the registered benchmark object or for all benchmarks
+using the `--benchmark_min_warmup_time` command-line option. Note that
+`MinWarmUpTime` will overwrite the value of `--benchmark_min_warmup_time`
+for the single benchmark. How many iterations the warmup run of each
+benchmark takes is determined the same way as described in the paragraph
+above. Per default the warmup phase is set to 0 seconds and is therefore
+disabled.
+
+Average timings are then reported over the iterations run. If multiple
+repetitions are requested using the `--benchmark_repetitions` command-line
+option, or at registration time, the benchmark function will be run several
+times and statistical results across these repetitions will also be reported.
+
+As well as the per-benchmark entries, a preamble in the report will include
+information about the machine on which the benchmarks are run.
+
+
+
+## Setup/Teardown
+
+Global setup/teardown specific to each benchmark can be done by
+passing a callback to Setup/Teardown:
+
+The setup/teardown callbacks will be invoked once for each benchmark.
+If the benchmark is multi-threaded (will run in k threads), they will be invoked exactly once before
+each run with k threads.
+If the benchmark uses different size groups of threads, the above will be true for each size group.
+
+Eg.,
+
+```c++
+static void DoSetup(const benchmark::State& state) {
+}
+
+static void DoTeardown(const benchmark::State& state) {
+}
+
+static void BM_func(benchmark::State& state) {...}
+
+BENCHMARK(BM_func)->Arg(1)->Arg(3)->Threads(16)->Threads(32)->Setup(DoSetup)->Teardown(DoTeardown);
+
+```
+
+In this example, `DoSetup` and `DoTearDown` will be invoked 4 times each,
+specifically, once for each of this family:
+ - BM_func_Arg_1_Threads_16, BM_func_Arg_1_Threads_32
+ - BM_func_Arg_3_Threads_16, BM_func_Arg_3_Threads_32
+
+
+
+## Passing Arguments
+
+Sometimes a family of benchmarks can be implemented with just one routine that
+takes an extra argument to specify which one of the family of benchmarks to
+run. For example, the following code defines a family of benchmarks for
+measuring the speed of `memcpy()` calls of different lengths:
+
+```c++
+static void BM_memcpy(benchmark::State& state) {
+ char* src = new char[state.range(0)];
+ char* dst = new char[state.range(0)];
+ memset(src, 'x', state.range(0));
+ for (auto _ : state)
+ memcpy(dst, src, state.range(0));
+ state.SetBytesProcessed(int64_t(state.iterations()) *
+ int64_t(state.range(0)));
+ delete[] src;
+ delete[] dst;
+}
+BENCHMARK(BM_memcpy)->Arg(8)->Arg(64)->Arg(512)->Arg(4<<10)->Arg(8<<10);
+```
+
+The preceding code is quite repetitive, and can be replaced with the following
+short-hand. The following invocation will pick a few appropriate arguments in
+the specified range and will generate a benchmark for each such argument.
+
+```c++
+BENCHMARK(BM_memcpy)->Range(8, 8<<10);
+```
+
+By default the arguments in the range are generated in multiples of eight and
+the command above selects [ 8, 64, 512, 4k, 8k ]. In the following code the
+range multiplier is changed to multiples of two.
+
+```c++
+BENCHMARK(BM_memcpy)->RangeMultiplier(2)->Range(8, 8<<10);
+```
+
+Now arguments generated are [ 8, 16, 32, 64, 128, 256, 512, 1024, 2k, 4k, 8k ].
+
+The preceding code shows a method of defining a sparse range. The following
+example shows a method of defining a dense range. It is then used to benchmark
+the performance of `std::vector` initialization for uniformly increasing sizes.
+
+```c++
+static void BM_DenseRange(benchmark::State& state) {
+ for(auto _ : state) {
+ std::vector v(state.range(0), state.range(0));
+ benchmark::DoNotOptimize(v.data());
+ benchmark::ClobberMemory();
+ }
+}
+BENCHMARK(BM_DenseRange)->DenseRange(0, 1024, 128);
+```
+
+Now arguments generated are [ 0, 128, 256, 384, 512, 640, 768, 896, 1024 ].
+
+You might have a benchmark that depends on two or more inputs. For example, the
+following code defines a family of benchmarks for measuring the speed of set
+insertion.
+
+```c++
+static void BM_SetInsert(benchmark::State& state) {
+ std::set data;
+ for (auto _ : state) {
+ state.PauseTiming();
+ data = ConstructRandomSet(state.range(0));
+ state.ResumeTiming();
+ for (int j = 0; j < state.range(1); ++j)
+ data.insert(RandomNumber());
+ }
+}
+BENCHMARK(BM_SetInsert)
+ ->Args({1<<10, 128})
+ ->Args({2<<10, 128})
+ ->Args({4<<10, 128})
+ ->Args({8<<10, 128})
+ ->Args({1<<10, 512})
+ ->Args({2<<10, 512})
+ ->Args({4<<10, 512})
+ ->Args({8<<10, 512});
+```
+
+The preceding code is quite repetitive, and can be replaced with the following
+short-hand. The following macro will pick a few appropriate arguments in the
+product of the two specified ranges and will generate a benchmark for each such
+pair.
+
+```c++
+BENCHMARK(BM_SetInsert)->Ranges({{1<<10, 8<<10}, {128, 512}});
+```
+
+Some benchmarks may require specific argument values that cannot be expressed
+with `Ranges`. In this case, `ArgsProduct` offers the ability to generate a
+benchmark input for each combination in the product of the supplied vectors.
+
+```c++
+BENCHMARK(BM_SetInsert)
+ ->ArgsProduct({{1<<10, 3<<10, 8<<10}, {20, 40, 60, 80}})
+// would generate the same benchmark arguments as
+BENCHMARK(BM_SetInsert)
+ ->Args({1<<10, 20})
+ ->Args({3<<10, 20})
+ ->Args({8<<10, 20})
+ ->Args({3<<10, 40})
+ ->Args({8<<10, 40})
+ ->Args({1<<10, 40})
+ ->Args({1<<10, 60})
+ ->Args({3<<10, 60})
+ ->Args({8<<10, 60})
+ ->Args({1<<10, 80})
+ ->Args({3<<10, 80})
+ ->Args({8<<10, 80});
+```
+
+For the most common scenarios, helper methods for creating a list of
+integers for a given sparse or dense range are provided.
+
+```c++
+BENCHMARK(BM_SetInsert)
+ ->ArgsProduct({
+ benchmark::CreateRange(8, 128, /*multi=*/2),
+ benchmark::CreateDenseRange(1, 4, /*step=*/1)
+ })
+// would generate the same benchmark arguments as
+BENCHMARK(BM_SetInsert)
+ ->ArgsProduct({
+ {8, 16, 32, 64, 128},
+ {1, 2, 3, 4}
+ });
+```
+
+For more complex patterns of inputs, passing a custom function to `Apply` allows
+programmatic specification of an arbitrary set of arguments on which to run the
+benchmark. The following example enumerates a dense range on one parameter,
+and a sparse range on the second.
+
+```c++
+static void CustomArguments(benchmark::internal::Benchmark* b) {
+ for (int i = 0; i <= 10; ++i)
+ for (int j = 32; j <= 1024*1024; j *= 8)
+ b->Args({i, j});
+}
+BENCHMARK(BM_SetInsert)->Apply(CustomArguments);
+```
+
+### Passing Arbitrary Arguments to a Benchmark
+
+In C++11 it is possible to define a benchmark that takes an arbitrary number
+of extra arguments. The `BENCHMARK_CAPTURE(func, test_case_name, ...args)`
+macro creates a benchmark that invokes `func` with the `benchmark::State` as
+the first argument followed by the specified `args...`.
+The `test_case_name` is appended to the name of the benchmark and
+should describe the values passed.
+
+```c++
+template
+void BM_takes_args(benchmark::State& state, Args&&... args) {
+ auto args_tuple = std::make_tuple(std::move(args)...);
+ for (auto _ : state) {
+ std::cout << std::get<0>(args_tuple) << ": " << std::get<1>(args_tuple)
+ << '\n';
+ [...]
+ }
+}
+// Registers a benchmark named "BM_takes_args/int_string_test" that passes
+// the specified values to `args`.
+BENCHMARK_CAPTURE(BM_takes_args, int_string_test, 42, std::string("abc"));
+
+// Registers the same benchmark "BM_takes_args/int_test" that passes
+// the specified values to `args`.
+BENCHMARK_CAPTURE(BM_takes_args, int_test, 42, 43);
+```
+
+Note that elements of `...args` may refer to global variables. Users should
+avoid modifying global state inside of a benchmark.
+
+
+
+## Calculating Asymptotic Complexity (Big O)
+
+Asymptotic complexity might be calculated for a family of benchmarks. The
+following code will calculate the coefficient for the high-order term in the
+running time and the normalized root-mean square error of string comparison.
+
+```c++
+static void BM_StringCompare(benchmark::State& state) {
+ std::string s1(state.range(0), '-');
+ std::string s2(state.range(0), '-');
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(s1.compare(s2));
+ }
+ state.SetComplexityN(state.range(0));
+}
+BENCHMARK(BM_StringCompare)
+ ->RangeMultiplier(2)->Range(1<<10, 1<<18)->Complexity(benchmark::oN);
+```
+
+As shown in the following invocation, asymptotic complexity might also be
+calculated automatically.
+
+```c++
+BENCHMARK(BM_StringCompare)
+ ->RangeMultiplier(2)->Range(1<<10, 1<<18)->Complexity();
+```
+
+The following code will specify asymptotic complexity with a lambda function,
+that might be used to customize high-order term calculation.
+
+```c++
+BENCHMARK(BM_StringCompare)->RangeMultiplier(2)
+ ->Range(1<<10, 1<<18)->Complexity([](benchmark::IterationCount n)->double{return n; });
+```
+
+
+
+## Custom Benchmark Name
+
+You can change the benchmark's name as follows:
+
+```c++
+BENCHMARK(BM_memcpy)->Name("memcpy")->RangeMultiplier(2)->Range(8, 8<<10);
+```
+
+The invocation will execute the benchmark as before using `BM_memcpy` but changes
+the prefix in the report to `memcpy`.
+
+
+
+## Templated Benchmarks
+
+This example produces and consumes messages of size `sizeof(v)` `range_x`
+times. It also outputs throughput in the absence of multiprogramming.
+
+```c++
+template void BM_Sequential(benchmark::State& state) {
+ Q q;
+ typename Q::value_type v;
+ for (auto _ : state) {
+ for (int i = state.range(0); i--; )
+ q.push(v);
+ for (int e = state.range(0); e--; )
+ q.Wait(&v);
+ }
+ // actually messages, not bytes:
+ state.SetBytesProcessed(
+ static_cast(state.iterations())*state.range(0));
+}
+// C++03
+BENCHMARK_TEMPLATE(BM_Sequential, WaitQueue)->Range(1<<0, 1<<10);
+
+// C++11 or newer, you can use the BENCHMARK macro with template parameters:
+BENCHMARK(BM_Sequential>)->Range(1<<0, 1<<10);
+
+```
+
+Three macros are provided for adding benchmark templates.
+
+```c++
+#ifdef BENCHMARK_HAS_CXX11
+#define BENCHMARK(func<...>) // Takes any number of parameters.
+#else // C++ < C++11
+#define BENCHMARK_TEMPLATE(func, arg1)
+#endif
+#define BENCHMARK_TEMPLATE1(func, arg1)
+#define BENCHMARK_TEMPLATE2(func, arg1, arg2)
+```
+
+
+
+## Fixtures
+
+Fixture tests are created by first defining a type that derives from
+`::benchmark::Fixture` and then creating/registering the tests using the
+following macros:
+
+* `BENCHMARK_F(ClassName, Method)`
+* `BENCHMARK_DEFINE_F(ClassName, Method)`
+* `BENCHMARK_REGISTER_F(ClassName, Method)`
+
+For Example:
+
+```c++
+class MyFixture : public benchmark::Fixture {
+public:
+ void SetUp(const ::benchmark::State& state) {
+ }
+
+ void TearDown(const ::benchmark::State& state) {
+ }
+};
+
+BENCHMARK_F(MyFixture, FooTest)(benchmark::State& st) {
+ for (auto _ : st) {
+ ...
+ }
+}
+
+BENCHMARK_DEFINE_F(MyFixture, BarTest)(benchmark::State& st) {
+ for (auto _ : st) {
+ ...
+ }
+}
+/* BarTest is NOT registered */
+BENCHMARK_REGISTER_F(MyFixture, BarTest)->Threads(2);
+/* BarTest is now registered */
+```
+
+### Templated Fixtures
+
+Also you can create templated fixture by using the following macros:
+
+* `BENCHMARK_TEMPLATE_F(ClassName, Method, ...)`
+* `BENCHMARK_TEMPLATE_DEFINE_F(ClassName, Method, ...)`
+
+For example:
+
+```c++
+template
+class MyFixture : public benchmark::Fixture {};
+
+BENCHMARK_TEMPLATE_F(MyFixture, IntTest, int)(benchmark::State& st) {
+ for (auto _ : st) {
+ ...
+ }
+}
+
+BENCHMARK_TEMPLATE_DEFINE_F(MyFixture, DoubleTest, double)(benchmark::State& st) {
+ for (auto _ : st) {
+ ...
+ }
+}
+
+BENCHMARK_REGISTER_F(MyFixture, DoubleTest)->Threads(2);
+```
+
+
+
+## Custom Counters
+
+You can add your own counters with user-defined names. The example below
+will add columns "Foo", "Bar" and "Baz" in its output:
+
+```c++
+static void UserCountersExample1(benchmark::State& state) {
+ double numFoos = 0, numBars = 0, numBazs = 0;
+ for (auto _ : state) {
+ // ... count Foo,Bar,Baz events
+ }
+ state.counters["Foo"] = numFoos;
+ state.counters["Bar"] = numBars;
+ state.counters["Baz"] = numBazs;
+}
+```
+
+The `state.counters` object is a `std::map` with `std::string` keys
+and `Counter` values. The latter is a `double`-like class, via an implicit
+conversion to `double&`. Thus you can use all of the standard arithmetic
+assignment operators (`=,+=,-=,*=,/=`) to change the value of each counter.
+
+In multithreaded benchmarks, each counter is set on the calling thread only.
+When the benchmark finishes, the counters from each thread will be summed;
+the resulting sum is the value which will be shown for the benchmark.
+
+The `Counter` constructor accepts three parameters: the value as a `double`
+; a bit flag which allows you to show counters as rates, and/or as per-thread
+iteration, and/or as per-thread averages, and/or iteration invariants,
+and/or finally inverting the result; and a flag specifying the 'unit' - i.e.
+is 1k a 1000 (default, `benchmark::Counter::OneK::kIs1000`), or 1024
+(`benchmark::Counter::OneK::kIs1024`)?
+
+```c++
+ // sets a simple counter
+ state.counters["Foo"] = numFoos;
+
+ // Set the counter as a rate. It will be presented divided
+ // by the duration of the benchmark.
+ // Meaning: per one second, how many 'foo's are processed?
+ state.counters["FooRate"] = Counter(numFoos, benchmark::Counter::kIsRate);
+
+ // Set the counter as a rate. It will be presented divided
+ // by the duration of the benchmark, and the result inverted.
+ // Meaning: how many seconds it takes to process one 'foo'?
+ state.counters["FooInvRate"] = Counter(numFoos, benchmark::Counter::kIsRate | benchmark::Counter::kInvert);
+
+ // Set the counter as a thread-average quantity. It will
+ // be presented divided by the number of threads.
+ state.counters["FooAvg"] = Counter(numFoos, benchmark::Counter::kAvgThreads);
+
+ // There's also a combined flag:
+ state.counters["FooAvgRate"] = Counter(numFoos,benchmark::Counter::kAvgThreadsRate);
+
+ // This says that we process with the rate of state.range(0) bytes every iteration:
+ state.counters["BytesProcessed"] = Counter(state.range(0), benchmark::Counter::kIsIterationInvariantRate, benchmark::Counter::OneK::kIs1024);
+```
+
+When you're compiling in C++11 mode or later you can use `insert()` with
+`std::initializer_list`:
+
+```c++
+ // With C++11, this can be done:
+ state.counters.insert({{"Foo", numFoos}, {"Bar", numBars}, {"Baz", numBazs}});
+ // ... instead of:
+ state.counters["Foo"] = numFoos;
+ state.counters["Bar"] = numBars;
+ state.counters["Baz"] = numBazs;
+```
+
+### Counter Reporting
+
+When using the console reporter, by default, user counters are printed at
+the end after the table, the same way as ``bytes_processed`` and
+``items_processed``. This is best for cases in which there are few counters,
+or where there are only a couple of lines per benchmark. Here's an example of
+the default output:
+
+```
+------------------------------------------------------------------------------
+Benchmark Time CPU Iterations UserCounters...
+------------------------------------------------------------------------------
+BM_UserCounter/threads:8 2248 ns 10277 ns 68808 Bar=16 Bat=40 Baz=24 Foo=8
+BM_UserCounter/threads:1 9797 ns 9788 ns 71523 Bar=2 Bat=5 Baz=3 Foo=1024m
+BM_UserCounter/threads:2 4924 ns 9842 ns 71036 Bar=4 Bat=10 Baz=6 Foo=2
+BM_UserCounter/threads:4 2589 ns 10284 ns 68012 Bar=8 Bat=20 Baz=12 Foo=4
+BM_UserCounter/threads:8 2212 ns 10287 ns 68040 Bar=16 Bat=40 Baz=24 Foo=8
+BM_UserCounter/threads:16 1782 ns 10278 ns 68144 Bar=32 Bat=80 Baz=48 Foo=16
+BM_UserCounter/threads:32 1291 ns 10296 ns 68256 Bar=64 Bat=160 Baz=96 Foo=32
+BM_UserCounter/threads:4 2615 ns 10307 ns 68040 Bar=8 Bat=20 Baz=12 Foo=4
+BM_Factorial 26 ns 26 ns 26608979 40320
+BM_Factorial/real_time 26 ns 26 ns 26587936 40320
+BM_CalculatePiRange/1 16 ns 16 ns 45704255 0
+BM_CalculatePiRange/8 73 ns 73 ns 9520927 3.28374
+BM_CalculatePiRange/64 609 ns 609 ns 1140647 3.15746
+BM_CalculatePiRange/512 4900 ns 4901 ns 142696 3.14355
+```
+
+If this doesn't suit you, you can print each counter as a table column by
+passing the flag `--benchmark_counters_tabular=true` to the benchmark
+application. This is best for cases in which there are a lot of counters, or
+a lot of lines per individual benchmark. Note that this will trigger a
+reprinting of the table header any time the counter set changes between
+individual benchmarks. Here's an example of corresponding output when
+`--benchmark_counters_tabular=true` is passed:
+
+```
+---------------------------------------------------------------------------------------
+Benchmark Time CPU Iterations Bar Bat Baz Foo
+---------------------------------------------------------------------------------------
+BM_UserCounter/threads:8 2198 ns 9953 ns 70688 16 40 24 8
+BM_UserCounter/threads:1 9504 ns 9504 ns 73787 2 5 3 1
+BM_UserCounter/threads:2 4775 ns 9550 ns 72606 4 10 6 2
+BM_UserCounter/threads:4 2508 ns 9951 ns 70332 8 20 12 4
+BM_UserCounter/threads:8 2055 ns 9933 ns 70344 16 40 24 8
+BM_UserCounter/threads:16 1610 ns 9946 ns 70720 32 80 48 16
+BM_UserCounter/threads:32 1192 ns 9948 ns 70496 64 160 96 32
+BM_UserCounter/threads:4 2506 ns 9949 ns 70332 8 20 12 4
+--------------------------------------------------------------
+Benchmark Time CPU Iterations
+--------------------------------------------------------------
+BM_Factorial 26 ns 26 ns 26392245 40320
+BM_Factorial/real_time 26 ns 26 ns 26494107 40320
+BM_CalculatePiRange/1 15 ns 15 ns 45571597 0
+BM_CalculatePiRange/8 74 ns 74 ns 9450212 3.28374
+BM_CalculatePiRange/64 595 ns 595 ns 1173901 3.15746
+BM_CalculatePiRange/512 4752 ns 4752 ns 147380 3.14355
+BM_CalculatePiRange/4k 37970 ns 37972 ns 18453 3.14184
+BM_CalculatePiRange/32k 303733 ns 303744 ns 2305 3.14162
+BM_CalculatePiRange/256k 2434095 ns 2434186 ns 288 3.1416
+BM_CalculatePiRange/1024k 9721140 ns 9721413 ns 71 3.14159
+BM_CalculatePi/threads:8 2255 ns 9943 ns 70936
+```
+
+Note above the additional header printed when the benchmark changes from
+``BM_UserCounter`` to ``BM_Factorial``. This is because ``BM_Factorial`` does
+not have the same counter set as ``BM_UserCounter``.
+
+
+
+## Multithreaded Benchmarks
+
+In a multithreaded test (benchmark invoked by multiple threads simultaneously),
+it is guaranteed that none of the threads will start until all have reached
+the start of the benchmark loop, and all will have finished before any thread
+exits the benchmark loop. (This behavior is also provided by the `KeepRunning()`
+API) As such, any global setup or teardown can be wrapped in a check against the thread
+index:
+
+```c++
+static void BM_MultiThreaded(benchmark::State& state) {
+ if (state.thread_index() == 0) {
+ // Setup code here.
+ }
+ for (auto _ : state) {
+ // Run the test as normal.
+ }
+ if (state.thread_index() == 0) {
+ // Teardown code here.
+ }
+}
+BENCHMARK(BM_MultiThreaded)->Threads(2);
+```
+
+To run the benchmark across a range of thread counts, instead of `Threads`, use
+`ThreadRange`. This takes two parameters (`min_threads` and `max_threads`) and
+runs the benchmark once for values in the inclusive range. For example:
+
+```c++
+BENCHMARK(BM_MultiThreaded)->ThreadRange(1, 8);
+```
+
+will run `BM_MultiThreaded` with thread counts 1, 2, 4, and 8.
+
+If the benchmarked code itself uses threads and you want to compare it to
+single-threaded code, you may want to use real-time ("wallclock") measurements
+for latency comparisons:
+
+```c++
+BENCHMARK(BM_test)->Range(8, 8<<10)->UseRealTime();
+```
+
+Without `UseRealTime`, CPU time is used by default.
+
+
+
+## CPU Timers
+
+By default, the CPU timer only measures the time spent by the main thread.
+If the benchmark itself uses threads internally, this measurement may not
+be what you are looking for. Instead, there is a way to measure the total
+CPU usage of the process, by all the threads.
+
+```c++
+void callee(int i);
+
+static void MyMain(int size) {
+#pragma omp parallel for
+ for(int i = 0; i < size; i++)
+ callee(i);
+}
+
+static void BM_OpenMP(benchmark::State& state) {
+ for (auto _ : state)
+ MyMain(state.range(0));
+}
+
+// Measure the time spent by the main thread, use it to decide for how long to
+// run the benchmark loop. Depending on the internal implementation detail may
+// measure to anywhere from near-zero (the overhead spent before/after work
+// handoff to worker thread[s]) to the whole single-thread time.
+BENCHMARK(BM_OpenMP)->Range(8, 8<<10);
+
+// Measure the user-visible time, the wall clock (literally, the time that
+// has passed on the clock on the wall), use it to decide for how long to
+// run the benchmark loop. This will always be meaningful, an will match the
+// time spent by the main thread in single-threaded case, in general decreasing
+// with the number of internal threads doing the work.
+BENCHMARK(BM_OpenMP)->Range(8, 8<<10)->UseRealTime();
+
+// Measure the total CPU consumption, use it to decide for how long to
+// run the benchmark loop. This will always measure to no less than the
+// time spent by the main thread in single-threaded case.
+BENCHMARK(BM_OpenMP)->Range(8, 8<<10)->MeasureProcessCPUTime();
+
+// A mixture of the last two. Measure the total CPU consumption, but use the
+// wall clock to decide for how long to run the benchmark loop.
+BENCHMARK(BM_OpenMP)->Range(8, 8<<10)->MeasureProcessCPUTime()->UseRealTime();
+```
+
+### Controlling Timers
+
+Normally, the entire duration of the work loop (`for (auto _ : state) {}`)
+is measured. But sometimes, it is necessary to do some work inside of
+that loop, every iteration, but without counting that time to the benchmark time.
+That is possible, although it is not recommended, since it has high overhead.
+
+```c++
+static void BM_SetInsert_With_Timer_Control(benchmark::State& state) {
+ std::set data;
+ for (auto _ : state) {
+ state.PauseTiming(); // Stop timers. They will not count until they are resumed.
+ data = ConstructRandomSet(state.range(0)); // Do something that should not be measured
+ state.ResumeTiming(); // And resume timers. They are now counting again.
+ // The rest will be measured.
+ for (int j = 0; j < state.range(1); ++j)
+ data.insert(RandomNumber());
+ }
+}
+BENCHMARK(BM_SetInsert_With_Timer_Control)->Ranges({{1<<10, 8<<10}, {128, 512}});
+```
+
+
+
+## Manual Timing
+
+For benchmarking something for which neither CPU time nor real-time are
+correct or accurate enough, completely manual timing is supported using
+the `UseManualTime` function.
+
+When `UseManualTime` is used, the benchmarked code must call
+`SetIterationTime` once per iteration of the benchmark loop to
+report the manually measured time.
+
+An example use case for this is benchmarking GPU execution (e.g. OpenCL
+or CUDA kernels, OpenGL or Vulkan or Direct3D draw calls), which cannot
+be accurately measured using CPU time or real-time. Instead, they can be
+measured accurately using a dedicated API, and these measurement results
+can be reported back with `SetIterationTime`.
+
+```c++
+static void BM_ManualTiming(benchmark::State& state) {
+ int microseconds = state.range(0);
+ std::chrono::duration sleep_duration {
+ static_cast(microseconds)
+ };
+
+ for (auto _ : state) {
+ auto start = std::chrono::high_resolution_clock::now();
+ // Simulate some useful workload with a sleep
+ std::this_thread::sleep_for(sleep_duration);
+ auto end = std::chrono::high_resolution_clock::now();
+
+ auto elapsed_seconds =
+ std::chrono::duration_cast>(
+ end - start);
+
+ state.SetIterationTime(elapsed_seconds.count());
+ }
+}
+BENCHMARK(BM_ManualTiming)->Range(1, 1<<17)->UseManualTime();
+```
+
+
+
+## Setting the Time Unit
+
+If a benchmark runs a few milliseconds it may be hard to visually compare the
+measured times, since the output data is given in nanoseconds per default. In
+order to manually set the time unit, you can specify it manually:
+
+```c++
+BENCHMARK(BM_test)->Unit(benchmark::kMillisecond);
+```
+
+Additionally the default time unit can be set globally with the
+`--benchmark_time_unit={ns|us|ms|s}` command line argument. The argument only
+affects benchmarks where the time unit is not set explicitly.
+
+
+
+## Preventing Optimization
+
+To prevent a value or expression from being optimized away by the compiler
+the `benchmark::DoNotOptimize(...)` and `benchmark::ClobberMemory()`
+functions can be used.
+
+```c++
+static void BM_test(benchmark::State& state) {
+ for (auto _ : state) {
+ int x = 0;
+ for (int i=0; i < 64; ++i) {
+ benchmark::DoNotOptimize(x += i);
+ }
+ }
+}
+```
+
+`DoNotOptimize()` forces the *result* of `` to be stored in either
+memory or a register. For GNU based compilers it acts as read/write barrier
+for global memory. More specifically it forces the compiler to flush pending
+writes to memory and reload any other values as necessary.
+
+Note that `DoNotOptimize()` does not prevent optimizations on ``
+in any way. `` may even be removed entirely when the result is already
+known. For example:
+
+```c++
+ /* Example 1: `` is removed entirely. */
+ int foo(int x) { return x + 42; }
+ while (...) DoNotOptimize(foo(0)); // Optimized to DoNotOptimize(42);
+
+ /* Example 2: Result of '' is only reused */
+ int bar(int) __attribute__((const));
+ while (...) DoNotOptimize(bar(0)); // Optimized to:
+ // int __result__ = bar(0);
+ // while (...) DoNotOptimize(__result__);
+```
+
+The second tool for preventing optimizations is `ClobberMemory()`. In essence
+`ClobberMemory()` forces the compiler to perform all pending writes to global
+memory. Memory managed by block scope objects must be "escaped" using
+`DoNotOptimize(...)` before it can be clobbered. In the below example
+`ClobberMemory()` prevents the call to `v.push_back(42)` from being optimized
+away.
+
+```c++
+static void BM_vector_push_back(benchmark::State& state) {
+ for (auto _ : state) {
+ std::vector v;
+ v.reserve(1);
+ benchmark::DoNotOptimize(v.data()); // Allow v.data() to be clobbered.
+ v.push_back(42);
+ benchmark::ClobberMemory(); // Force 42 to be written to memory.
+ }
+}
+```
+
+Note that `ClobberMemory()` is only available for GNU or MSVC based compilers.
+
+
+
+## Statistics: Reporting the Mean, Median and Standard Deviation / Coefficient of variation of Repeated Benchmarks
+
+By default each benchmark is run once and that single result is reported.
+However benchmarks are often noisy and a single result may not be representative
+of the overall behavior. For this reason it's possible to repeatedly rerun the
+benchmark.
+
+The number of runs of each benchmark is specified globally by the
+`--benchmark_repetitions` flag or on a per benchmark basis by calling
+`Repetitions` on the registered benchmark object. When a benchmark is run more
+than once the mean, median, standard deviation and coefficient of variation
+of the runs will be reported.
+
+Additionally the `--benchmark_report_aggregates_only={true|false}`,
+`--benchmark_display_aggregates_only={true|false}` flags or
+`ReportAggregatesOnly(bool)`, `DisplayAggregatesOnly(bool)` functions can be
+used to change how repeated tests are reported. By default the result of each
+repeated run is reported. When `report aggregates only` option is `true`,
+only the aggregates (i.e. mean, median, standard deviation and coefficient
+of variation, maybe complexity measurements if they were requested) of the runs
+is reported, to both the reporters - standard output (console), and the file.
+However when only the `display aggregates only` option is `true`,
+only the aggregates are displayed in the standard output, while the file
+output still contains everything.
+Calling `ReportAggregatesOnly(bool)` / `DisplayAggregatesOnly(bool)` on a
+registered benchmark object overrides the value of the appropriate flag for that
+benchmark.
+
+
+
+## Custom Statistics
+
+While having these aggregates is nice, this may not be enough for everyone.
+For example you may want to know what the largest observation is, e.g. because
+you have some real-time constraints. This is easy. The following code will
+specify a custom statistic to be calculated, defined by a lambda function.
+
+```c++
+void BM_spin_empty(benchmark::State& state) {
+ for (auto _ : state) {
+ for (int x = 0; x < state.range(0); ++x) {
+ benchmark::DoNotOptimize(x);
+ }
+ }
+}
+
+BENCHMARK(BM_spin_empty)
+ ->ComputeStatistics("max", [](const std::vector& v) -> double {
+ return *(std::max_element(std::begin(v), std::end(v)));
+ })
+ ->Arg(512);
+```
+
+While usually the statistics produce values in time units,
+you can also produce percentages:
+
+```c++
+void BM_spin_empty(benchmark::State& state) {
+ for (auto _ : state) {
+ for (int x = 0; x < state.range(0); ++x) {
+ benchmark::DoNotOptimize(x);
+ }
+ }
+}
+
+BENCHMARK(BM_spin_empty)
+ ->ComputeStatistics("ratio", [](const std::vector& v) -> double {
+ return std::begin(v) / std::end(v);
+ }, benchmark::StatisticUnit::kPercentage)
+ ->Arg(512);
+```
+
+
+
+## Memory Usage
+
+It's often useful to also track memory usage for benchmarks, alongside CPU
+performance. For this reason, benchmark offers the `RegisterMemoryManager`
+method that allows a custom `MemoryManager` to be injected.
+
+If set, the `MemoryManager::Start` and `MemoryManager::Stop` methods will be
+called at the start and end of benchmark runs to allow user code to fill out
+a report on the number of allocations, bytes used, etc.
+
+This data will then be reported alongside other performance data, currently
+only when using JSON output.
+
+
+
+## Using RegisterBenchmark(name, fn, args...)
+
+The `RegisterBenchmark(name, func, args...)` function provides an alternative
+way to create and register benchmarks.
+`RegisterBenchmark(name, func, args...)` creates, registers, and returns a
+pointer to a new benchmark with the specified `name` that invokes
+`func(st, args...)` where `st` is a `benchmark::State` object.
+
+Unlike the `BENCHMARK` registration macros, which can only be used at the global
+scope, the `RegisterBenchmark` can be called anywhere. This allows for
+benchmark tests to be registered programmatically.
+
+Additionally `RegisterBenchmark` allows any callable object to be registered
+as a benchmark. Including capturing lambdas and function objects.
+
+For Example:
+```c++
+auto BM_test = [](benchmark::State& st, auto Inputs) { /* ... */ };
+
+int main(int argc, char** argv) {
+ for (auto& test_input : { /* ... */ })
+ benchmark::RegisterBenchmark(test_input.name(), BM_test, test_input);
+ benchmark::Initialize(&argc, argv);
+ benchmark::RunSpecifiedBenchmarks();
+ benchmark::Shutdown();
+}
+```
+
+
+
+## Exiting with an Error
+
+When errors caused by external influences, such as file I/O and network
+communication, occur within a benchmark the
+`State::SkipWithError(const char* msg)` function can be used to skip that run
+of benchmark and report the error. Note that only future iterations of the
+`KeepRunning()` are skipped. For the ranged-for version of the benchmark loop
+Users must explicitly exit the loop, otherwise all iterations will be performed.
+Users may explicitly return to exit the benchmark immediately.
+
+The `SkipWithError(...)` function may be used at any point within the benchmark,
+including before and after the benchmark loop. Moreover, if `SkipWithError(...)`
+has been used, it is not required to reach the benchmark loop and one may return
+from the benchmark function early.
+
+For example:
+
+```c++
+static void BM_test(benchmark::State& state) {
+ auto resource = GetResource();
+ if (!resource.good()) {
+ state.SkipWithError("Resource is not good!");
+ // KeepRunning() loop will not be entered.
+ }
+ while (state.KeepRunning()) {
+ auto data = resource.read_data();
+ if (!resource.good()) {
+ state.SkipWithError("Failed to read data!");
+ break; // Needed to skip the rest of the iteration.
+ }
+ do_stuff(data);
+ }
+}
+
+static void BM_test_ranged_fo(benchmark::State & state) {
+ auto resource = GetResource();
+ if (!resource.good()) {
+ state.SkipWithError("Resource is not good!");
+ return; // Early return is allowed when SkipWithError() has been used.
+ }
+ for (auto _ : state) {
+ auto data = resource.read_data();
+ if (!resource.good()) {
+ state.SkipWithError("Failed to read data!");
+ break; // REQUIRED to prevent all further iterations.
+ }
+ do_stuff(data);
+ }
+}
+```
+
+
+## A Faster KeepRunning Loop
+
+In C++11 mode, a ranged-based for loop should be used in preference to
+the `KeepRunning` loop for running the benchmarks. For example:
+
+```c++
+static void BM_Fast(benchmark::State &state) {
+ for (auto _ : state) {
+ FastOperation();
+ }
+}
+BENCHMARK(BM_Fast);
+```
+
+The reason the ranged-for loop is faster than using `KeepRunning`, is
+because `KeepRunning` requires a memory load and store of the iteration count
+ever iteration, whereas the ranged-for variant is able to keep the iteration count
+in a register.
+
+For example, an empty inner loop of using the ranged-based for method looks like:
+
+```asm
+# Loop Init
+ mov rbx, qword ptr [r14 + 104]
+ call benchmark::State::StartKeepRunning()
+ test rbx, rbx
+ je .LoopEnd
+.LoopHeader: # =>This Inner Loop Header: Depth=1
+ add rbx, -1
+ jne .LoopHeader
+.LoopEnd:
+```
+
+Compared to an empty `KeepRunning` loop, which looks like:
+
+```asm
+.LoopHeader: # in Loop: Header=BB0_3 Depth=1
+ cmp byte ptr [rbx], 1
+ jne .LoopInit
+.LoopBody: # =>This Inner Loop Header: Depth=1
+ mov rax, qword ptr [rbx + 8]
+ lea rcx, [rax + 1]
+ mov qword ptr [rbx + 8], rcx
+ cmp rax, qword ptr [rbx + 104]
+ jb .LoopHeader
+ jmp .LoopEnd
+.LoopInit:
+ mov rdi, rbx
+ call benchmark::State::StartKeepRunning()
+ jmp .LoopBody
+.LoopEnd:
+```
+
+Unless C++03 compatibility is required, the ranged-for variant of writing
+the benchmark loop should be preferred.
+
+
+
+## Disabling CPU Frequency Scaling
+
+If you see this error:
+
+```
+***WARNING*** CPU scaling is enabled, the benchmark real time measurements may be noisy and will incur extra overhead.
+```
+
+you might want to disable the CPU frequency scaling while running the
+benchmark, as well as consider other ways to stabilize the performance of
+your system while benchmarking.
+
+See [Reducing Variance](reducing_variance.md) for more information.
diff --git a/deps/google-benchmark/include/benchmark/benchmark.h b/deps/google-benchmark/include/benchmark/benchmark.h
new file mode 100644
index 000000000..54d4e3cf0
--- /dev/null
+++ b/deps/google-benchmark/include/benchmark/benchmark.h
@@ -0,0 +1,1868 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Support for registering benchmarks for functions.
+
+/* Example usage:
+// Define a function that executes the code to be measured a
+// specified number of times:
+static void BM_StringCreation(benchmark::State& state) {
+ for (auto _ : state)
+ std::string empty_string;
+}
+
+// Register the function as a benchmark
+BENCHMARK(BM_StringCreation);
+
+// Define another benchmark
+static void BM_StringCopy(benchmark::State& state) {
+ std::string x = "hello";
+ for (auto _ : state)
+ std::string copy(x);
+}
+BENCHMARK(BM_StringCopy);
+
+// Augment the main() program to invoke benchmarks if specified
+// via the --benchmark_filter command line flag. E.g.,
+// my_unittest --benchmark_filter=all
+// my_unittest --benchmark_filter=BM_StringCreation
+// my_unittest --benchmark_filter=String
+// my_unittest --benchmark_filter='Copy|Creation'
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ benchmark::RunSpecifiedBenchmarks();
+ benchmark::Shutdown();
+ return 0;
+}
+
+// Sometimes a family of microbenchmarks can be implemented with
+// just one routine that takes an extra argument to specify which
+// one of the family of benchmarks to run. For example, the following
+// code defines a family of microbenchmarks for measuring the speed
+// of memcpy() calls of different lengths:
+
+static void BM_memcpy(benchmark::State& state) {
+ char* src = new char[state.range(0)]; char* dst = new char[state.range(0)];
+ memset(src, 'x', state.range(0));
+ for (auto _ : state)
+ memcpy(dst, src, state.range(0));
+ state.SetBytesProcessed(state.iterations() * state.range(0));
+ delete[] src; delete[] dst;
+}
+BENCHMARK(BM_memcpy)->Arg(8)->Arg(64)->Arg(512)->Arg(1<<10)->Arg(8<<10);
+
+// The preceding code is quite repetitive, and can be replaced with the
+// following short-hand. The following invocation will pick a few
+// appropriate arguments in the specified range and will generate a
+// microbenchmark for each such argument.
+BENCHMARK(BM_memcpy)->Range(8, 8<<10);
+
+// You might have a microbenchmark that depends on two inputs. For
+// example, the following code defines a family of microbenchmarks for
+// measuring the speed of set insertion.
+static void BM_SetInsert(benchmark::State& state) {
+ set data;
+ for (auto _ : state) {
+ state.PauseTiming();
+ data = ConstructRandomSet(state.range(0));
+ state.ResumeTiming();
+ for (int j = 0; j < state.range(1); ++j)
+ data.insert(RandomNumber());
+ }
+}
+BENCHMARK(BM_SetInsert)
+ ->Args({1<<10, 128})
+ ->Args({2<<10, 128})
+ ->Args({4<<10, 128})
+ ->Args({8<<10, 128})
+ ->Args({1<<10, 512})
+ ->Args({2<<10, 512})
+ ->Args({4<<10, 512})
+ ->Args({8<<10, 512});
+
+// The preceding code is quite repetitive, and can be replaced with
+// the following short-hand. The following macro will pick a few
+// appropriate arguments in the product of the two specified ranges
+// and will generate a microbenchmark for each such pair.
+BENCHMARK(BM_SetInsert)->Ranges({{1<<10, 8<<10}, {128, 512}});
+
+// For more complex patterns of inputs, passing a custom function
+// to Apply allows programmatic specification of an
+// arbitrary set of arguments to run the microbenchmark on.
+// The following example enumerates a dense range on
+// one parameter, and a sparse range on the second.
+static void CustomArguments(benchmark::internal::Benchmark* b) {
+ for (int i = 0; i <= 10; ++i)
+ for (int j = 32; j <= 1024*1024; j *= 8)
+ b->Args({i, j});
+}
+BENCHMARK(BM_SetInsert)->Apply(CustomArguments);
+
+// Templated microbenchmarks work the same way:
+// Produce then consume 'size' messages 'iters' times
+// Measures throughput in the absence of multiprogramming.
+template int BM_Sequential(benchmark::State& state) {
+ Q q;
+ typename Q::value_type v;
+ for (auto _ : state) {
+ for (int i = state.range(0); i--; )
+ q.push(v);
+ for (int e = state.range(0); e--; )
+ q.Wait(&v);
+ }
+ // actually messages, not bytes:
+ state.SetBytesProcessed(state.iterations() * state.range(0));
+}
+BENCHMARK_TEMPLATE(BM_Sequential, WaitQueue)->Range(1<<0, 1<<10);
+
+Use `Benchmark::MinTime(double t)` to set the minimum time used to run the
+benchmark. This option overrides the `benchmark_min_time` flag.
+
+void BM_test(benchmark::State& state) {
+ ... body ...
+}
+BENCHMARK(BM_test)->MinTime(2.0); // Run for at least 2 seconds.
+
+In a multithreaded test, it is guaranteed that none of the threads will start
+until all have reached the loop start, and all will have finished before any
+thread exits the loop body. As such, any global setup or teardown you want to
+do can be wrapped in a check against the thread index:
+
+static void BM_MultiThreaded(benchmark::State& state) {
+ if (state.thread_index() == 0) {
+ // Setup code here.
+ }
+ for (auto _ : state) {
+ // Run the test as normal.
+ }
+ if (state.thread_index() == 0) {
+ // Teardown code here.
+ }
+}
+BENCHMARK(BM_MultiThreaded)->Threads(4);
+
+
+If a benchmark runs a few milliseconds it may be hard to visually compare the
+measured times, since the output data is given in nanoseconds per default. In
+order to manually set the time unit, you can specify it manually:
+
+BENCHMARK(BM_test)->Unit(benchmark::kMillisecond);
+*/
+
+#ifndef BENCHMARK_BENCHMARK_H_
+#define BENCHMARK_BENCHMARK_H_
+
+// The _MSVC_LANG check should detect Visual Studio 2015 Update 3 and newer.
+#if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)
+#define BENCHMARK_HAS_CXX11
+#endif
+
+// This _MSC_VER check should detect VS 2017 v15.3 and newer.
+#if __cplusplus >= 201703L || \
+ (defined(_MSC_VER) && _MSC_VER >= 1911 && _MSVC_LANG >= 201703L)
+#define BENCHMARK_HAS_CXX17
+#endif
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "benchmark/export.h"
+
+#if defined(BENCHMARK_HAS_CXX11)
+#include
+#include
+#include
+#include
+#endif
+
+#if defined(_MSC_VER)
+#include // for _ReadWriteBarrier
+#endif
+
+#ifndef BENCHMARK_HAS_CXX11
+#define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \
+ TypeName(const TypeName&); \
+ TypeName& operator=(const TypeName&)
+#else
+#define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \
+ TypeName(const TypeName&) = delete; \
+ TypeName& operator=(const TypeName&) = delete
+#endif
+
+#ifdef BENCHMARK_HAS_CXX17
+#define BENCHMARK_UNUSED [[maybe_unused]]
+#elif defined(__GNUC__) || defined(__clang__)
+#define BENCHMARK_UNUSED __attribute__((unused))
+#else
+#define BENCHMARK_UNUSED
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define BENCHMARK_ALWAYS_INLINE __attribute__((always_inline))
+#elif defined(_MSC_VER) && !defined(__clang__)
+#define BENCHMARK_ALWAYS_INLINE __forceinline
+#define __func__ __FUNCTION__
+#else
+#define BENCHMARK_ALWAYS_INLINE
+#endif
+
+#define BENCHMARK_INTERNAL_TOSTRING2(x) #x
+#define BENCHMARK_INTERNAL_TOSTRING(x) BENCHMARK_INTERNAL_TOSTRING2(x)
+
+// clang-format off
+#if defined(__GNUC__) && !defined(__NVCC__) || defined(__clang__)
+#define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y)
+#define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
+#define BENCHMARK_DISABLE_DEPRECATED_WARNING \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
+#define BENCHMARK_RESTORE_DEPRECATED_WARNING _Pragma("GCC diagnostic pop")
+#else
+#define BENCHMARK_BUILTIN_EXPECT(x, y) x
+#define BENCHMARK_DEPRECATED_MSG(msg)
+#define BENCHMARK_WARNING_MSG(msg) \
+ __pragma(message(__FILE__ "(" BENCHMARK_INTERNAL_TOSTRING( \
+ __LINE__) ") : warning note: " msg))
+#define BENCHMARK_DISABLE_DEPRECATED_WARNING
+#define BENCHMARK_RESTORE_DEPRECATED_WARNING
+#endif
+// clang-format on
+
+#if defined(__GNUC__) && !defined(__clang__)
+#define BENCHMARK_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
+#endif
+
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
+#if defined(__GNUC__) || __has_builtin(__builtin_unreachable)
+#define BENCHMARK_UNREACHABLE() __builtin_unreachable()
+#elif defined(_MSC_VER)
+#define BENCHMARK_UNREACHABLE() __assume(false)
+#else
+#define BENCHMARK_UNREACHABLE() ((void)0)
+#endif
+
+#ifdef BENCHMARK_HAS_CXX11
+#define BENCHMARK_OVERRIDE override
+#else
+#define BENCHMARK_OVERRIDE
+#endif
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+// C4251: needs to have dll-interface to be used by clients of class
+#pragma warning(disable : 4251)
+#endif
+
+namespace benchmark {
+class BenchmarkReporter;
+
+BENCHMARK_EXPORT void PrintDefaultHelp();
+
+BENCHMARK_EXPORT void Initialize(int* argc, char** argv,
+ void (*HelperPrinterf)() = PrintDefaultHelp);
+BENCHMARK_EXPORT void Shutdown();
+
+// Report to stdout all arguments in 'argv' as unrecognized except the first.
+// Returns true there is at least on unrecognized argument (i.e. 'argc' > 1).
+BENCHMARK_EXPORT bool ReportUnrecognizedArguments(int argc, char** argv);
+
+// Returns the current value of --benchmark_filter.
+BENCHMARK_EXPORT std::string GetBenchmarkFilter();
+
+// Sets a new value to --benchmark_filter. (This will override this flag's
+// current value).
+// Should be called after `benchmark::Initialize()`, as
+// `benchmark::Initialize()` will override the flag's value.
+BENCHMARK_EXPORT void SetBenchmarkFilter(std::string value);
+
+// Returns the current value of --v (command line value for verbosity).
+BENCHMARK_EXPORT int32_t GetBenchmarkVerbosity();
+
+// Creates a default display reporter. Used by the library when no display
+// reporter is provided, but also made available for external use in case a
+// custom reporter should respect the `--benchmark_format` flag as a fallback
+BENCHMARK_EXPORT BenchmarkReporter* CreateDefaultDisplayReporter();
+
+// Generate a list of benchmarks matching the specified --benchmark_filter flag
+// and if --benchmark_list_tests is specified return after printing the name
+// of each matching benchmark. Otherwise run each matching benchmark and
+// report the results.
+//
+// spec : Specify the benchmarks to run. If users do not specify this arg,
+// then the value of FLAGS_benchmark_filter
+// will be used.
+//
+// The second and third overload use the specified 'display_reporter' and
+// 'file_reporter' respectively. 'file_reporter' will write to the file
+// specified
+// by '--benchmark_output'. If '--benchmark_output' is not given the
+// 'file_reporter' is ignored.
+//
+// RETURNS: The number of matching benchmarks.
+BENCHMARK_EXPORT size_t RunSpecifiedBenchmarks();
+BENCHMARK_EXPORT size_t RunSpecifiedBenchmarks(std::string spec);
+
+BENCHMARK_EXPORT size_t
+RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter);
+BENCHMARK_EXPORT size_t
+RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter, std::string spec);
+
+BENCHMARK_EXPORT size_t RunSpecifiedBenchmarks(
+ BenchmarkReporter* display_reporter, BenchmarkReporter* file_reporter);
+BENCHMARK_EXPORT size_t
+RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,
+ BenchmarkReporter* file_reporter, std::string spec);
+
+// TimeUnit is passed to a benchmark in order to specify the order of magnitude
+// for the measured time.
+enum TimeUnit { kNanosecond, kMicrosecond, kMillisecond, kSecond };
+
+BENCHMARK_EXPORT TimeUnit GetDefaultTimeUnit();
+
+// Sets the default time unit the benchmarks use
+// Has to be called before the benchmark loop to take effect
+BENCHMARK_EXPORT void SetDefaultTimeUnit(TimeUnit unit);
+
+// If a MemoryManager is registered (via RegisterMemoryManager()),
+// it can be used to collect and report allocation metrics for a run of the
+// benchmark.
+class MemoryManager {
+ public:
+ static const int64_t TombstoneValue;
+
+ struct Result {
+ Result()
+ : num_allocs(0),
+ max_bytes_used(0),
+ total_allocated_bytes(TombstoneValue),
+ net_heap_growth(TombstoneValue) {}
+
+ // The number of allocations made in total between Start and Stop.
+ int64_t num_allocs;
+
+ // The peak memory use between Start and Stop.
+ int64_t max_bytes_used;
+
+ // The total memory allocated, in bytes, between Start and Stop.
+ // Init'ed to TombstoneValue if metric not available.
+ int64_t total_allocated_bytes;
+
+ // The net changes in memory, in bytes, between Start and Stop.
+ // ie., total_allocated_bytes - total_deallocated_bytes.
+ // Init'ed to TombstoneValue if metric not available.
+ int64_t net_heap_growth;
+ };
+
+ virtual ~MemoryManager() {}
+
+ // Implement this to start recording allocation information.
+ virtual void Start() = 0;
+
+ // Implement this to stop recording and fill out the given Result structure.
+ virtual void Stop(Result& result) = 0;
+};
+
+// Register a MemoryManager instance that will be used to collect and report
+// allocation measurements for benchmark runs.
+BENCHMARK_EXPORT
+void RegisterMemoryManager(MemoryManager* memory_manager);
+
+// Add a key-value pair to output as part of the context stanza in the report.
+BENCHMARK_EXPORT
+void AddCustomContext(const std::string& key, const std::string& value);
+
+namespace internal {
+class Benchmark;
+class BenchmarkImp;
+class BenchmarkFamilies;
+
+BENCHMARK_EXPORT std::map