diff --git a/packages/PEGTL/.conan/build.py b/packages/PEGTL/.conan/build.py
index 838e7975543621810e255aa80c7d5a61331ea578..d558f1f9c7a76d4211499d1947b5bc6a8f5ec0d8 100644
--- a/packages/PEGTL/.conan/build.py
+++ b/packages/PEGTL/.conan/build.py
@@ -52,17 +52,17 @@ class BuilderSettings(object):
 
     @property
     def reference(self):
-        """ Read project version from CMake file to create Conan referece
+        """ Read project version from version.hpp file to create Conan referece
         """
-        pattern = re.compile(r"project\(pegtl VERSION (\d+\.\d+\.\d+) LANGUAGES CXX\)")
+        pattern = re.compile(r"#define TAO_PEGTL_VERSION \"(\d+\.\d+\.\d+)\"")
         version = None
-        with open('CMakeLists.txt') as file:
+        with open('include/tao/pegtl/version.hpp') as file:
             for line in file:
                 result = pattern.match(line)
                 if result:
                     version = result.group(1)
         if not version:
-            raise Exception("Could not find version in CMakeLists.txt")
+            raise Exception("Could not find version in version.hpp")
         return os.getenv("CONAN_REFERENCE", "pegtl/{}@taocpp/stable".format(version))
 
 if __name__ == "__main__":
diff --git a/packages/PEGTL/.gitignore b/packages/PEGTL/.gitignore
index 454bccb45403f97193099b1a478996608a632508..90173b58d947cdff1175a16b8c2a9e67ec4ca0bf 100644
--- a/packages/PEGTL/.gitignore
+++ b/packages/PEGTL/.gitignore
@@ -1,3 +1,4 @@
 *~
 build
 private
+/.vs
diff --git a/packages/PEGTL/.gitrepo b/packages/PEGTL/.gitrepo
index 943a8805864d887b81d04ed035cee2e1181d3661..b7e013522865c8d94d09390f5a9ef3f89c6e6563 100644
--- a/packages/PEGTL/.gitrepo
+++ b/packages/PEGTL/.gitrepo
@@ -6,7 +6,7 @@
 [subrepo]
 	remote = git@github.com:taocpp/PEGTL.git
 	branch = master
-	commit = 68790bd2c25fceff1049e9fc2fb9528ca4d93bbf
-	parent = 0fc26ddb5da553e9b9ddff3db48b3d6a1617eb96
+	commit = 293ef9f549bfde12f78c6117a6d13a1f5b9879d2
+	parent = 512de6bdac8531e32026970fcf476a1a1154ae62
 	cmdver = 0.4.0
 	method = merge
diff --git a/packages/PEGTL/.travis.yml b/packages/PEGTL/.travis.yml
index 32500f24224920c429068cea59853f9db37b5f0e..efdead2af923ebf7467ffcff7fd9f9584d6526c9 100644
--- a/packages/PEGTL/.travis.yml
+++ b/packages/PEGTL/.travis.yml
@@ -20,6 +20,14 @@ matrix:
       env:
         - CXX=g++-8
 
+    - compiler: gcc
+      addons:
+        apt:
+          sources: ['ubuntu-toolchain-r-test']
+          packages: ['g++-9']
+      env:
+        - CXX=g++-9
+
     - compiler: clang
       addons:
         apt:
@@ -77,9 +85,9 @@ matrix:
       addons:
         apt:
           sources: ['ubuntu-toolchain-r-test']
-          packages: ['g++-8']
+          packages: ['g++-9']
       env:
-        - CXX=g++-8
+        - CXX=g++-9
         - CPPFLAGS="-fsanitize=undefined -fuse-ld=gold"
 
     - compiler: gcc
@@ -87,9 +95,9 @@ matrix:
       addons:
         apt:
           sources: ['ubuntu-toolchain-r-test']
-          packages: ['g++-8']
+          packages: ['g++-9']
       env:
-        - CXX=g++-8
+        - CXX=g++-9
         - CPPFLAGS="-fsanitize=address -fuse-ld=gold"
 
     - compiler: clang
@@ -135,9 +143,9 @@ matrix:
       addons:
         apt:
           sources: ['ubuntu-toolchain-r-test']
-          packages: ['g++-8', 'valgrind']
+          packages: ['g++-9', 'valgrind']
       env:
-        - CXX=g++-8
+        - CXX=g++-9
         - SPECIAL=valgrind
       script:
         - make -kj3 valgrind
diff --git a/packages/PEGTL/CMakeLists.txt b/packages/PEGTL/CMakeLists.txt
index 410ec90d1380f6d0461ce48eecfedfd117b90412..0fe7e8e7a5d93ffa969b7129b84ee9b71de03270 100644
--- a/packages/PEGTL/CMakeLists.txt
+++ b/packages/PEGTL/CMakeLists.txt
@@ -1,6 +1,11 @@
 cmake_minimum_required(VERSION 3.8.0 FATAL_ERROR)
 
-project(pegtl VERSION 3.0.0 LANGUAGES CXX)
+# Read version from version.hpp
+file(READ "${CMAKE_CURRENT_LIST_DIR}/include/tao/pegtl/version.hpp" version_hpp_data)
+string(REGEX MATCH "#define TAO_PEGTL_VERSION \"([^\"]+)\"" _ ${version_hpp_data})
+set(PEGTL_VERSION "${CMAKE_MATCH_1}")
+
+project(pegtl VERSION ${PEGTL_VERSION} LANGUAGES CXX)
 
 if(${PROJECT_NAME}_FOUND)
   # Multiple versions of PEGTL can't co-exist
@@ -55,6 +60,13 @@ endif()
 # Make package findable
 configure_file(cmake/dummy-config.cmake.in pegtl-config.cmake @ONLY)
 
+# Ignore pointer width differences since this is a header-only library
+unset(CMAKE_SIZEOF_VOID_P)
+
+# Enable version checks in find_package
+include(CMakePackageConfigHelpers)
+write_basic_package_version_file(pegtl-config-version.cmake COMPATIBILITY SameMajorVersion)
+
 # install and export target
 install(TARGETS pegtl EXPORT pegtl-targets)
 
@@ -64,5 +76,6 @@ install(EXPORT pegtl-targets
   DESTINATION ${PEGTL_INSTALL_CMAKE_DIR}
 )
 
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pegtl-config-version.cmake DESTINATION ${PEGTL_INSTALL_CMAKE_DIR})
 install(DIRECTORY include/ DESTINATION ${PEGTL_INSTALL_INCLUDE_DIR})
 install(FILES LICENSE DESTINATION ${PEGTL_INSTALL_DOC_DIR})
diff --git a/packages/PEGTL/README.md b/packages/PEGTL/README.md
index d9798a2260477fd6edf914fae582485250fce3e3..08940817946007af1ccd41084d6ecbde7b31cf7b 100644
--- a/packages/PEGTL/README.md
+++ b/packages/PEGTL/README.md
@@ -69,7 +69,7 @@ Each commit is automatically tested with multiple architectures, operating syste
 
 * Ubuntu 16.04 LTS (using libstdc++)
 
-  * GCC 7.x, 8.x
+  * GCC 7.x, 8.x, 9.x
   * Clang 5.x, 6.x, 7.x, 8.x
 
 Additionally, each commit is checked with Clang's [Static Analyzer](https://clang-analyzer.llvm.org/), GCC's and Clang's [sanitizers](https://github.com/google/sanitizers), [`clang-tidy`](http://clang.llvm.org/extra/clang-tidy/), and [`valgrind`](http://valgrind.org/).
@@ -79,11 +79,48 @@ Code coverage is automatically measured and the unit tests cover 100% of the cor
 Incompatible API changes are *only* allowed to occur between major versions.
 For details see the [changelog](doc/Changelog.md).
 
-## Contact
+## Thank You
+
+In appreciation of all contributions here are the people that have [directly contributed](https://github.com/taocpp/PEGTL/graphs/contributors) to the PEGTL and/or its development.
+
+[<img alt="andoma" src="https://avatars2.githubusercontent.com/u/216384?v=4&s=117" width="117">](https://github.com/andoma)
+[<img alt="Bjoe" src="https://avatars3.githubusercontent.com/u/727911?v=4&s=117" width="117">](https://github.com/Bjoe)
+[<img alt="bwagner" src="https://avatars3.githubusercontent.com/u/447049?v=4&s=117" width="117">](https://github.com/bwagner)
+[<img alt="cdiggins" src="https://avatars2.githubusercontent.com/u/1759994?s=460&v=4?v=4&s=117" width="117">](https://github.com/cdiggins)
+[<img alt="delpinux" src="https://avatars0.githubusercontent.com/u/35096584?v=4&s=117" width="117">](https://github.com/delpinux)
+[<img alt="dkopecek" src="https://avatars2.githubusercontent.com/u/1353140?v=4&s=117" width="117">](https://github.com/dkopecek)
+[<img alt="irrequietus" src="https://avatars0.githubusercontent.com/u/231192?v=4&s=117" width="117">](https://github.com/irrequietus)
+[<img alt="jedelbo" src="https://avatars2.githubusercontent.com/u/572755?v=4&s=117" width="117">](https://github.com/jedelbo)
+[<img alt="joelfrederico" src="https://avatars0.githubusercontent.com/u/458871?v=4&s=117" width="117">](https://github.com/joelfrederico)
+[<img alt="jovermann" src="https://avatars3.githubusercontent.com/u/6087443?v=4&s=117" width="117">](https://github.com/jovermann)
+[<img alt="kneth" src="https://avatars0.githubusercontent.com/u/1225363?v=4&s=117" width="117">](https://github.com/kneth)
+[<img alt="kuzmas" src="https://avatars1.githubusercontent.com/u/1858553?v=4&s=117" width="117">](https://github.com/kuzmas)
+[<img alt="lambdafu" src="https://avatars1.githubusercontent.com/u/1138455?v=4&s=117" width="117">](https://github.com/lambdafu)
+[<img alt="lichray" src="https://avatars2.githubusercontent.com/u/433009?v=4&s=117" width="117">](https://github.com/lichray)
+[<img alt="michael-brade" src="https://avatars0.githubusercontent.com/u/8768950?v=4&s=117" width="117">](https://github.com/michael-brade)
+[<img alt="mkrupcale" src="https://avatars1.githubusercontent.com/u/13936020?v=4&s=117" width="117">](https://github.com/mkrupcale)
+[<img alt="NewProggie" src="https://avatars3.githubusercontent.com/u/162319?s=460&v=4?v=4&s=117" width="117">](https://github.com/NewProggie)
+[<img alt="pauloscustodio" src="https://avatars1.githubusercontent.com/u/70773?v=4&s=117" width="117">](https://github.com/pauloscustodio)
+[<img alt="pleroux0" src="https://avatars2.githubusercontent.com/u/39619854?v=4&s=117" width="117">](https://github.com/pleroux0)
+[<img alt="quadfault" src="https://avatars3.githubusercontent.com/u/30195320?v=4&s=117" width="117">](https://github.com/quadfault)
+[<img alt="samhocevar" src="https://avatars2.githubusercontent.com/u/245089?v=4&s=117" width="117">](https://github.com/samhocevar)
+[<img alt="sanssecours" src="https://avatars2.githubusercontent.com/u/691989?v=4&s=117" width="117">](https://github.com/sanssecours)
+[<img alt="sgbeal" src="https://avatars1.githubusercontent.com/u/235303?v=4&s=117" width="117">](https://github.com/sgbeal)
+[<img alt="studoot" src="https://avatars1.githubusercontent.com/u/799344?v=4&s=117" width="117">](https://github.com/studoot)
+[<img alt="SvenJo" src="https://avatars1.githubusercontent.com/u/1538181?s=460&v=4?v=4&s=117" width="117">](https://github.com/SvenJo)
+[<img alt="wickedmic" src="https://avatars1.githubusercontent.com/u/12001183?v=4&s=117" width="117">](https://github.com/wickedmic)
+[<img alt="wravery" src="https://avatars0.githubusercontent.com/u/6502881?v=4&s=117" width="117">](https://github.com/wravery)
+[<img alt="zhihaoy" src="https://avatars2.githubusercontent.com/u/43971430?v=4&s=117" width="117">](https://github.com/zhihaoy)
+
+## The Art of C++
 
 The PEGTL is part of [The Art of C++](https://taocpp.github.io/).
 
-We [are grateful](doc/Thank-You.md) for all support and contributions.
+[<img alt="ColinH" src="https://avatars0.githubusercontent.com/u/113184?v=4&s=117" width="117">](https://github.com/ColinH)
+[<img alt="d-frey" src="https://avatars2.githubusercontent.com/u/3956325?v=4&s=117" width="117">](https://github.com/d-frey)
+[<img alt="uilianries" src="https://avatars0.githubusercontent.com/u/4870173?v=4&s=117" width="117">](https://github.com/uilianries)
+
+## Contact
 
 For questions and suggestions regarding the PEGTL, success or failure stories, and any other kind of feedback, please feel free to open an issue or a PR on GitHub or contact the authors at `taocpp(at)icemx.net`.
 
diff --git a/packages/PEGTL/doc/Changelog.md b/packages/PEGTL/doc/Changelog.md
index 37b4184c7e05a19895e8aefb29f5023ed7ad4198..9fc17ba38b84307c1c64a9aed9a32c748b282549 100644
--- a/packages/PEGTL/doc/Changelog.md
+++ b/packages/PEGTL/doc/Changelog.md
@@ -10,6 +10,8 @@
 * The macro `TAO_PEGTL_NAMESPACE` now contains the fully qualified namespace, e.g. `tao::pegtl`.
 * Replaced `tao::pegtl::input_error` with `std::system_error`.
 * Changed message of `tao::pegtl::parse_error` to no longer contain the position redundantly.
+* Changed rules in `tao/pegtl/contrib/integer.hpp` to not accept redundant leading zeros.
+* Added rules to `tao/pegtl/contrib/integer.hpp` that test unsigned values against a maximum.
 * Removed option of [state](Rule-Reference.md#state-s-r-)'s `S::success()` to have an extended signature to get access to the current `apply_mode`, `rewind_mode`, *action*- and *control* class (template).
 * Added `[[nodiscard]]` to most non-void functions.
 * Removed compatibility macros starting with `TAOCPP_PEGTL_`.
@@ -17,6 +19,12 @@
 * Removed compatibility `peek_byte()` member functions.
 * Removed compatibility header `changes.hpp` from contrib.
 
+## 2.8.1
+
+**Not yet released**
+
+* Fixed missing `string_input<>` in amalgamated header.
+
 ## 2.8.0
 
 Released 2019-04-09
diff --git a/packages/PEGTL/doc/Contrib-and-Examples.md b/packages/PEGTL/doc/Contrib-and-Examples.md
index f83cc6cf1d4e78cb45f312e0ce7a909d23124878..7f844ad132bf01895d9f368581e44eb022ff5649 100644
--- a/packages/PEGTL/doc/Contrib-and-Examples.md
+++ b/packages/PEGTL/doc/Contrib-and-Examples.md
@@ -206,12 +206,12 @@ The example shows how to choose which rules will produce a parse tree node, whic
 The output is in [DOT](https://en.wikipedia.org/wiki/DOT_(graph_description_language)) format and can be converted into a graph.
 
 ```sh
-$ build/src/example/pegtl/parse_tree "(2*a + 3*b) / (4*n)" | dot -Tpng -o parse_tree.png
+$ build/src/example/pegtl/parse_tree "(2*a + 3*b) / (4*n)" | dot -Tsvg -o parse_tree.svg
 ```
 
-The above will generate a PNG with a graphical representation of the parse tree.
+The above will generate an SVG file with a graphical representation of the parse tree.
 
-![Parse Tree](Parse-Tree.png)
+![Parse Tree](Parse-Tree.svg)
 
 ###### `src/example/pegtl/proto3.cpp`
 
diff --git a/packages/PEGTL/doc/Installing-and-Using.md b/packages/PEGTL/doc/Installing-and-Using.md
index d0b78a470eb3f5a24de38f1804d14612d6e2f7c5..7b73f223674f261eb29b6add78522cf3c8062b61 100644
--- a/packages/PEGTL/doc/Installing-and-Using.md
+++ b/packages/PEGTL/doc/Installing-and-Using.md
@@ -36,6 +36,8 @@ on either
 It requires C++17, e.g. using the `--std=c++17` compiler switch.
 Using newer versions of the C++ standard is supported.
 
+Larger projects will frequently require the `/bigobj` option when compiling with Visual Studio on Windows.
+
 It should also work with other C++17 compilers on other Unix systems (or any sufficiently compatible platform).
 
 The PEGTL is written with an emphasis on clean code and is compatible with
diff --git a/packages/PEGTL/doc/Parse-Tree.png b/packages/PEGTL/doc/Parse-Tree.png
deleted file mode 100644
index fcacd0611dbb67c7516dbc0df9c54211d21d3ae9..0000000000000000000000000000000000000000
Binary files a/packages/PEGTL/doc/Parse-Tree.png and /dev/null differ
diff --git a/packages/PEGTL/doc/Parse-Tree.svg b/packages/PEGTL/doc/Parse-Tree.svg
new file mode 100644
index 0000000000000000000000000000000000000000..87792aff99e338eda8df9b54e79f814561a902e1
--- /dev/null
+++ b/packages/PEGTL/doc/Parse-Tree.svg
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by graphviz version 2.40.1 (0)
+ -->
+<!-- Title: parse_tree Pages: 1 -->
+<svg width="1063pt" height="367pt"
+ viewBox="0.00 0.00 1062.99 367.48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 363.4802)">
+<title>parse_tree</title>
+<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-363.4802 1058.9899,-363.4802 1058.9899,4 -4,4"/>
+<!-- x0x1604e70 -->
+<g id="node1" class="node">
+<title>x0x1604e70</title>
+<ellipse fill="none" stroke="#000000" cx="632.8736" cy="-341.4802" rx="39.7935" ry="18"/>
+<text text-anchor="middle" x="632.8736" y="-337.7802" font-family="Times,serif" font-size="14.00" fill="#000000">ROOT</text>
+</g>
+<!-- x0x1605200 -->
+<g id="node2" class="node">
+<title>x0x1605200</title>
+<ellipse fill="none" stroke="#000000" cx="632.8736" cy="-269.4802" rx="83.6854" ry="18"/>
+<text text-anchor="middle" x="632.8736" y="-265.7802" font-family="Times,serif" font-size="14.00" fill="#000000">example::divide</text>
+</g>
+<!-- x0x1604e70&#45;&gt;x0x1605200 -->
+<g id="edge1" class="edge">
+<title>x0x1604e70&#45;&gt;x0x1605200</title>
+<path fill="none" stroke="#000000" d="M632.8736,-323.3116C632.8736,-315.6112 632.8736,-306.4546 632.8736,-297.8969"/>
+<polygon fill="#000000" stroke="#000000" points="636.3737,-297.8935 632.8736,-287.8935 629.3737,-297.8935 636.3737,-297.8935"/>
+</g>
+<!-- x0x16053b0 -->
+<g id="node3" class="node">
+<title>x0x16053b0</title>
+<ellipse fill="none" stroke="#000000" cx="528.8736" cy="-197.4802" rx="75.2868" ry="18"/>
+<text text-anchor="middle" x="528.8736" y="-193.7802" font-family="Times,serif" font-size="14.00" fill="#000000">example::plus</text>
+</g>
+<!-- x0x1605200&#45;&gt;x0x16053b0 -->
+<g id="edge2" class="edge">
+<title>x0x1605200&#45;&gt;x0x16053b0</title>
+<path fill="none" stroke="#000000" d="M607.963,-252.2344C594.199,-242.7055 576.9218,-230.7443 562.0293,-220.4341"/>
+<polygon fill="#000000" stroke="#000000" points="563.7951,-217.3998 553.581,-214.5853 559.8106,-223.1551 563.7951,-217.3998"/>
+</g>
+<!-- x0x1605a60 -->
+<g id="node4" class="node">
+<title>x0x1605a60</title>
+<ellipse fill="none" stroke="#000000" cx="737.8736" cy="-197.4802" rx="94.4839" ry="18"/>
+<text text-anchor="middle" x="737.8736" y="-193.7802" font-family="Times,serif" font-size="14.00" fill="#000000">example::multiply</text>
+</g>
+<!-- x0x1605200&#45;&gt;x0x1605a60 -->
+<g id="edge3" class="edge">
+<title>x0x1605200&#45;&gt;x0x1605a60</title>
+<path fill="none" stroke="#000000" d="M658.0237,-252.2344C671.8187,-242.775 689.109,-230.9188 704.0695,-220.6602"/>
+<polygon fill="#000000" stroke="#000000" points="706.2969,-223.3767 712.5648,-214.8348 702.3381,-217.6036 706.2969,-223.3767"/>
+</g>
+<!-- x0x1605560 -->
+<g id="node5" class="node">
+<title>x0x1605560</title>
+<ellipse fill="none" stroke="#000000" cx="312.8736" cy="-116.6102" rx="94.4839" ry="18"/>
+<text text-anchor="middle" x="312.8736" y="-112.9102" font-family="Times,serif" font-size="14.00" fill="#000000">example::multiply</text>
+</g>
+<!-- x0x16053b0&#45;&gt;x0x1605560 -->
+<g id="edge4" class="edge">
+<title>x0x16053b0&#45;&gt;x0x1605560</title>
+<path fill="none" stroke="#000000" d="M488.2457,-182.2692C453.5814,-169.2909 403.4996,-150.5404 365.7225,-136.3967"/>
+<polygon fill="#000000" stroke="#000000" points="366.5019,-132.9513 355.9096,-132.7228 364.0475,-139.5069 366.5019,-132.9513"/>
+</g>
+<!-- x0x16057e0 -->
+<g id="node6" class="node">
+<title>x0x16057e0</title>
+<ellipse fill="none" stroke="#000000" cx="528.8736" cy="-116.6102" rx="94.4839" ry="18"/>
+<text text-anchor="middle" x="528.8736" y="-112.9102" font-family="Times,serif" font-size="14.00" fill="#000000">example::multiply</text>
+</g>
+<!-- x0x16053b0&#45;&gt;x0x16057e0 -->
+<g id="edge5" class="edge">
+<title>x0x16053b0&#45;&gt;x0x16057e0</title>
+<path fill="none" stroke="#000000" d="M528.8736,-179.1296C528.8736,-169.1 528.8736,-156.4555 528.8736,-145.1666"/>
+<polygon fill="#000000" stroke="#000000" points="532.3737,-144.8882 528.8736,-134.8882 525.3737,-144.8883 532.3737,-144.8882"/>
+</g>
+<!-- x0x16059d0 -->
+<g id="node11" class="node">
+<title>x0x16059d0</title>
+<ellipse fill="none" stroke="#000000" cx="737.8736" cy="-116.6102" rx="96.7474" ry="26.7407"/>
+<text text-anchor="middle" x="737.8736" y="-120.4102" font-family="Times,serif" font-size="14.00" fill="#000000">example::integer</text>
+<text text-anchor="middle" x="737.8736" y="-105.4102" font-family="Times,serif" font-size="14.00" fill="#000000">&quot;4&quot;</text>
+</g>
+<!-- x0x1605a60&#45;&gt;x0x16059d0 -->
+<g id="edge10" class="edge">
+<title>x0x1605a60&#45;&gt;x0x16059d0</title>
+<path fill="none" stroke="#000000" d="M737.8736,-179.1296C737.8736,-171.5597 737.8736,-162.5002 737.8736,-153.6583"/>
+<polygon fill="#000000" stroke="#000000" points="741.3737,-153.4808 737.8736,-143.4808 734.3737,-153.4808 741.3737,-153.4808"/>
+</g>
+<!-- x0x1605b10 -->
+<g id="node12" class="node">
+<title>x0x1605b10</title>
+<ellipse fill="none" stroke="#000000" cx="953.8736" cy="-116.6102" rx="101.2327" ry="26.7407"/>
+<text text-anchor="middle" x="953.8736" y="-120.4102" font-family="Times,serif" font-size="14.00" fill="#000000">example::variable</text>
+<text text-anchor="middle" x="953.8736" y="-105.4102" font-family="Times,serif" font-size="14.00" fill="#000000">&quot;n&quot;</text>
+</g>
+<!-- x0x1605a60&#45;&gt;x0x1605b10 -->
+<g id="edge11" class="edge">
+<title>x0x1605a60&#45;&gt;x0x1605b10</title>
+<path fill="none" stroke="#000000" d="M780.8065,-181.4062C810.7205,-170.2065 851.2523,-155.0314 885.5715,-142.1824"/>
+<polygon fill="#000000" stroke="#000000" points="886.9346,-145.4094 895.0725,-138.6252 884.4801,-138.8538 886.9346,-145.4094"/>
+</g>
+<!-- x0x16054d0 -->
+<g id="node7" class="node">
+<title>x0x16054d0</title>
+<ellipse fill="none" stroke="#000000" cx="96.8736" cy="-26.8701" rx="96.7474" ry="26.7407"/>
+<text text-anchor="middle" x="96.8736" y="-30.6701" font-family="Times,serif" font-size="14.00" fill="#000000">example::integer</text>
+<text text-anchor="middle" x="96.8736" y="-15.6701" font-family="Times,serif" font-size="14.00" fill="#000000">&quot;2&quot;</text>
+</g>
+<!-- x0x1605560&#45;&gt;x0x16054d0 -->
+<g id="edge6" class="edge">
+<title>x0x1605560&#45;&gt;x0x16054d0</title>
+<path fill="none" stroke="#000000" d="M273.2559,-100.1505C241.728,-87.0518 196.9923,-68.4657 160.464,-53.2895"/>
+<polygon fill="#000000" stroke="#000000" points="161.4608,-49.9137 150.8832,-49.3091 158.7751,-56.378 161.4608,-49.9137"/>
+</g>
+<!-- x0x1605610 -->
+<g id="node8" class="node">
+<title>x0x1605610</title>
+<ellipse fill="none" stroke="#000000" cx="312.8736" cy="-26.8701" rx="101.2327" ry="26.7407"/>
+<text text-anchor="middle" x="312.8736" y="-30.6701" font-family="Times,serif" font-size="14.00" fill="#000000">example::variable</text>
+<text text-anchor="middle" x="312.8736" y="-15.6701" font-family="Times,serif" font-size="14.00" fill="#000000">&quot;a&quot;</text>
+</g>
+<!-- x0x1605560&#45;&gt;x0x1605610 -->
+<g id="edge7" class="edge">
+<title>x0x1605560&#45;&gt;x0x1605610</title>
+<path fill="none" stroke="#000000" d="M312.8736,-98.4499C312.8736,-88.5469 312.8736,-75.9148 312.8736,-64.0273"/>
+<polygon fill="#000000" stroke="#000000" points="316.3737,-63.8597 312.8736,-53.8597 309.3737,-63.8597 316.3737,-63.8597"/>
+</g>
+<!-- x0x1605750 -->
+<g id="node9" class="node">
+<title>x0x1605750</title>
+<ellipse fill="none" stroke="#000000" cx="528.8736" cy="-26.8701" rx="96.7474" ry="26.7407"/>
+<text text-anchor="middle" x="528.8736" y="-30.6701" font-family="Times,serif" font-size="14.00" fill="#000000">example::integer</text>
+<text text-anchor="middle" x="528.8736" y="-15.6701" font-family="Times,serif" font-size="14.00" fill="#000000">&quot;3&quot;</text>
+</g>
+<!-- x0x16057e0&#45;&gt;x0x1605750 -->
+<g id="edge8" class="edge">
+<title>x0x16057e0&#45;&gt;x0x1605750</title>
+<path fill="none" stroke="#000000" d="M528.8736,-98.4499C528.8736,-88.5469 528.8736,-75.9148 528.8736,-64.0273"/>
+<polygon fill="#000000" stroke="#000000" points="532.3737,-63.8597 528.8736,-53.8597 525.3737,-63.8597 532.3737,-63.8597"/>
+</g>
+<!-- x0x1605890 -->
+<g id="node10" class="node">
+<title>x0x1605890</title>
+<ellipse fill="none" stroke="#000000" cx="744.8736" cy="-26.8701" rx="101.2327" ry="26.7407"/>
+<text text-anchor="middle" x="744.8736" y="-30.6701" font-family="Times,serif" font-size="14.00" fill="#000000">example::variable</text>
+<text text-anchor="middle" x="744.8736" y="-15.6701" font-family="Times,serif" font-size="14.00" fill="#000000">&quot;b&quot;</text>
+</g>
+<!-- x0x16057e0&#45;&gt;x0x1605890 -->
+<g id="edge9" class="edge">
+<title>x0x16057e0&#45;&gt;x0x1605890</title>
+<path fill="none" stroke="#000000" d="M568.4914,-100.1505C599.7956,-87.1447 644.1211,-68.7291 680.5048,-53.6129"/>
+<polygon fill="#000000" stroke="#000000" points="682.1617,-56.7147 690.0535,-49.6458 679.476,-50.2504 682.1617,-56.7147"/>
+</g>
+</g>
+</svg>
diff --git a/packages/PEGTL/doc/README.md b/packages/PEGTL/doc/README.md
index 4f98196acd8814c5b1b92a783a4eefdfeedd6e2f..7c9acc81db8ac8f92b8ee3cace061f568045de7b 100644
--- a/packages/PEGTL/doc/README.md
+++ b/packages/PEGTL/doc/README.md
@@ -104,7 +104,6 @@
   * [Custom Rules](Grammar-Analysis.md#custom-rules)
 * [Changelog](Changelog.md)
 * [Migration Guide](Migration-Guide.md)
-* [Thank You](Thank-You.md)
 
 # Rule Reference Index
 
diff --git a/packages/PEGTL/doc/Rule-Reference.md b/packages/PEGTL/doc/Rule-Reference.md
index 85040484d959eca8015d4f6625538bd4f1001bdc..160f743724414f650cd0ff51f711319aefecb590 100644
--- a/packages/PEGTL/doc/Rule-Reference.md
+++ b/packages/PEGTL/doc/Rule-Reference.md
@@ -103,7 +103,6 @@ These are the classical PEG combinator rules defined in namespace `tao::pegtl`.
 * Succeeds if and only if `seq< R... >` would succeed.
 * Consumes nothing, i.e. rewinds after matching.
 * Disables all actions.
-* Allows local failure of `R...` even within `must<>` etc.
 
 ###### `not_at< R... >`
 
@@ -111,14 +110,12 @@ These are the classical PEG combinator rules defined in namespace `tao::pegtl`.
 * Succeeds if and only if `seq< R... >` would **not** succeed.
 * Consumes nothing, i.e. rewinds after matching.
 * Disables all actions.
-* Allows local failure of `R...` even within `must<>` etc.
 
 ###### `opt< R... >`
 
 * PEG **optional** *e*?
 * Optional `seq< R... >`, i.e. attempt to match `seq< R... >` and signal success regardless of the result.
 * Equivalent to `sor< seq< R... >, success >`.
-* Allows local failure of `R...` even within `must<>` etc.
 
 ###### `plus< R... >`
 
@@ -143,14 +140,12 @@ These are the classical PEG combinator rules defined in namespace `tao::pegtl`.
 * Matches the given rules `R...` in the given order.
 * Succeeds and stops matching when one of the given rules succeeds.
 * Consumes whatever the first rule that succeeded consumed.
-* Allows local failure of `R...` even within `must<>` etc.
 * Fails if `R` is an empty rule pack.
 
 ###### `star< R... >`
 
 * PEG **zero-or-more** *e**
 * Matches `seq< R... >` as often as possible and always succeeds.
-* Allows local failure of `R...` even within `must<>` etc.
 * `R` must be a non-empty rule pack.
 
 ## Convenience
diff --git a/packages/PEGTL/doc/Thank-You.md b/packages/PEGTL/doc/Thank-You.md
deleted file mode 100644
index 63beb187c8e0e95720d965e3a6e7f14ff5ef04d8..0000000000000000000000000000000000000000
--- a/packages/PEGTL/doc/Thank-You.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# Thank You
-
-In appreciation of all contributions here are the people that have [directly contributed](https://github.com/taocpp/PEGTL/graphs/contributors) to the PEGTL and/or its development.
-
-[<img alt="andoma" src="https://avatars2.githubusercontent.com/u/216384?v=4&s=117" width="117">](https://github.com/andoma)
-[<img alt="Bjoe" src="https://avatars3.githubusercontent.com/u/727911?v=4&s=117" width="117">](https://github.com/Bjoe)
-[<img alt="bwagner" src="https://avatars3.githubusercontent.com/u/447049?v=4&s=117" width="117">](https://github.com/bwagner)
-[<img alt="cdiggins" src="https://avatars2.githubusercontent.com/u/1759994?s=460&v=4?v=4&s=117" width="117">](https://github.com/cdiggins)
-[<img alt="delpinux" src="https://avatars0.githubusercontent.com/u/35096584?v=4&s=117" width="117">](https://github.com/delpinux)
-[<img alt="dkopecek" src="https://avatars2.githubusercontent.com/u/1353140?v=4&s=117" width="117">](https://github.com/dkopecek)
-[<img alt="irrequietus" src="https://avatars0.githubusercontent.com/u/231192?v=4&s=117" width="117">](https://github.com/irrequietus)
-[<img alt="jedelbo" src="https://avatars2.githubusercontent.com/u/572755?v=4&s=117" width="117">](https://github.com/jedelbo)
-[<img alt="joelfrederico" src="https://avatars0.githubusercontent.com/u/458871?v=4&s=117" width="117">](https://github.com/joelfrederico)
-[<img alt="jovermann" src="https://avatars3.githubusercontent.com/u/6087443?v=4&s=117" width="117">](https://github.com/jovermann)
-[<img alt="kneth" src="https://avatars0.githubusercontent.com/u/1225363?v=4&s=117" width="117">](https://github.com/kneth)
-[<img alt="kuzmas" src="https://avatars1.githubusercontent.com/u/1858553?v=4&s=117" width="117">](https://github.com/kuzmas)
-[<img alt="lambdafu" src="https://avatars1.githubusercontent.com/u/1138455?v=4&s=117" width="117">](https://github.com/lambdafu)
-[<img alt="lichray" src="https://avatars2.githubusercontent.com/u/433009?v=4&s=117" width="117">](https://github.com/lichray)
-[<img alt="michael-brade" src="https://avatars0.githubusercontent.com/u/8768950?v=4&s=117" width="117">](https://github.com/michael-brade)
-[<img alt="mkrupcale" src="https://avatars1.githubusercontent.com/u/13936020?v=4&s=117" width="117">](https://github.com/mkrupcale)
-[<img alt="NewProggie" src="https://avatars3.githubusercontent.com/u/162319?s=460&v=4?v=4&s=117" width="117">](https://github.com/NewProggie)
-[<img alt="pauloscustodio" src="https://avatars1.githubusercontent.com/u/70773?v=4&s=117" width="117">](https://github.com/pauloscustodio)
-[<img alt="pleroux0" src="https://avatars2.githubusercontent.com/u/39619854?v=4&s=117" width="117">](https://github.com/pleroux0)
-[<img alt="quadfault" src="https://avatars3.githubusercontent.com/u/30195320?v=4&s=117" width="117">](https://github.com/quadfault)
-[<img alt="samhocevar" src="https://avatars2.githubusercontent.com/u/245089?v=4&s=117" width="117">](https://github.com/samhocevar)
-[<img alt="sanssecours" src="https://avatars2.githubusercontent.com/u/691989?v=4&s=117" width="117">](https://github.com/sanssecours)
-[<img alt="sgbeal" src="https://avatars1.githubusercontent.com/u/235303?v=4&s=117" width="117">](https://github.com/sgbeal)
-[<img alt="studoot" src="https://avatars1.githubusercontent.com/u/799344?v=4&s=117" width="117">](https://github.com/studoot)
-[<img alt="SvenJo" src="https://avatars1.githubusercontent.com/u/1538181?s=460&v=4?v=4&s=117" width="117">](https://github.com/SvenJo)
-[<img alt="wickedmic" src="https://avatars1.githubusercontent.com/u/12001183?v=4&s=117" width="117">](https://github.com/wickedmic)
-[<img alt="zhihaoy" src="https://avatars2.githubusercontent.com/u/43971430?v=4&s=117" width="117">](https://github.com/zhihaoy)
-
-## The Art of C++
-
-Members of the *Art of C++* project.
-
-[<img alt="ColinH" src="https://avatars0.githubusercontent.com/u/113184?v=4&s=117" width="117">](https://github.com/ColinH)
-[<img alt="d-frey" src="https://avatars2.githubusercontent.com/u/3956325?v=4&s=117" width="117">](https://github.com/d-frey)
-[<img alt="uilianries" src="https://avatars0.githubusercontent.com/u/4870173?v=4&s=117" width="117">](https://github.com/uilianries)
-
-Copyright (c) 2019 Dr. Colin Hirsch and Daniel Frey
diff --git a/packages/PEGTL/include/tao/pegtl.hpp b/packages/PEGTL/include/tao/pegtl.hpp
index 42141a9df128515b3638fca8b70baf585c876d62..832fc9eaefaee66124eadf9d040f6de1c90d7eea 100644
--- a/packages/PEGTL/include/tao/pegtl.hpp
+++ b/packages/PEGTL/include/tao/pegtl.hpp
@@ -22,12 +22,15 @@
 #include "pegtl/argv_input.hpp"
 #include "pegtl/buffer_input.hpp"
 #include "pegtl/cstream_input.hpp"
-#include "pegtl/file_input.hpp"
 #include "pegtl/istream_input.hpp"
 #include "pegtl/memory_input.hpp"
 #include "pegtl/read_input.hpp"
 #include "pegtl/string_input.hpp"
 
+// this has to be included *after* the above inputs,
+// otherwise the amalgamated header will not work!
+#include "pegtl/file_input.hpp"
+
 #include "pegtl/change_action.hpp"
 #include "pegtl/change_action_and_state.hpp"
 #include "pegtl/change_action_and_states.hpp"
diff --git a/packages/PEGTL/include/tao/pegtl/contrib/integer.hpp b/packages/PEGTL/include/tao/pegtl/contrib/integer.hpp
index 77d11421bb033414df96df4506356efeec04de5c..2e9c8edb19b32b33515aaa290c84b8479c2154ef 100644
--- a/packages/PEGTL/include/tao/pegtl/contrib/integer.hpp
+++ b/packages/PEGTL/include/tao/pegtl/contrib/integer.hpp
@@ -1,13 +1,16 @@
-// Copyright (c) 2018-2019 Dr. Colin Hirsch and Daniel Frey
+// Copyright (c) 2019 Dr. Colin Hirsch and Daniel Frey
 // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/
 
 #ifndef TAO_PEGTL_CONTRIB_INTEGER_HPP
 #define TAO_PEGTL_CONTRIB_INTEGER_HPP
 
-#include <limits>
+#include <cstdint>
+#include <cstdlib>
+
 #include <type_traits>
 
 #include "../ascii.hpp"
+#include "../parse.hpp"
 #include "../parse_error.hpp"
 #include "../rules.hpp"
 
@@ -15,63 +18,332 @@ namespace TAO_PEGTL_NAMESPACE::integer
 {
    namespace internal
    {
-      template< typename I, I Limit, typename Input >
-      [[nodiscard]] I actual_convert( const Input& in, std::size_t index )
+      struct unsigned_rule_old
+         : plus< digit >
+      {
+         // Pre-3.0 version of this rule.
+      };
+
+      struct unsigned_rule_new
+         : if_then_else< one< '0' >, not_at< digit >, plus< digit > >
+      {
+         // New version that does not allow leading zeros.
+      };
+
+      struct signed_rule_old
+         : seq< opt< one< '-', '+' > >, plus< digit > >
+      {
+         // Pre-3.0 version of this rule.
+      };
+
+      struct signed_rule_new
+         : seq< opt< one< '-', '+' > >, if_then_else< one< '0' >, not_at< digit >, plus< digit > > >
+      {
+         // New version that does not allow leading zeros.
+      };
+
+      struct signed_rule_bis
+         : seq< opt< one< '-' > >, if_then_else< one< '0' >, not_at< digit >, plus< digit > > >
       {
-         static constexpr I cutoff = Limit / 10;
-         static constexpr I cutlim = Limit % 10;
+      };
+
+      struct signed_rule_ter
+         : seq< one< '-', '+' >, if_then_else< one< '0' >, not_at< digit >, plus< digit > > >
+      {
+      };
+
+      [[nodiscard]] constexpr bool is_digit( const char c ) noexcept
+      {
+         // We don't use std::isdigit() because it might
+         // return true for other values on MS platforms.
+
+         return ( '0' <= c ) && ( c <= '9' );
+      }
+
+      template< typename Integer, Integer Maximum = ( std::numeric_limits< Integer >::max )() >
+      [[nodiscard]] constexpr bool accumulate_digit( Integer& result, const char digit ) noexcept
+      {
+         // Assumes that digit is a digit as per is_digit(); returns false on overflow.
+
+         static_assert( std::is_integral_v< Integer > );
 
-         I out = in.peek_char( index ) - '0';
-         while( ++index < in.size() ) {
-            const I c = in.peek_char( index ) - '0';
-            if( ( out > cutoff ) || ( ( out == cutoff ) && ( c > cutlim ) ) ) {
-               throw parse_error( "integer out of range", in );
+         constexpr Integer cutoff = Maximum / 10;
+         constexpr Integer cutlim = Maximum % 10;
+
+         const Integer c = digit - '0';
+
+         if( ( result > cutoff ) || ( ( result == cutoff ) && ( c > cutlim ) ) ) {
+            return false;
+         }
+         result *= 10;
+         result += c;
+         return true;
+      }
+
+      template< typename Integer, Integer Maximum = ( std::numeric_limits< Integer >::max )() >
+      [[nodiscard]] constexpr bool accumulate_digits( Integer& result, const std::string_view input ) noexcept
+      {
+         // Assumes input is a non-empty sequence of digits; returns false on overflow.
+
+         for( std::size_t i = 0; i < input.size(); ++i ) {
+            if( !accumulate_digit< Integer, Maximum >( result, input[ i ] ) ) {
+               return false;
             }
-            out *= 10;
-            out += c;
          }
-         return out;
+         return true;
       }
 
-      template< typename I, typename Input >
-      [[nodiscard]] I convert_positive( const Input& in, std::size_t index )
+      template< typename Integer, Integer Maximum = ( std::numeric_limits< Integer >::max )() >
+      [[nodiscard]] constexpr bool convert_positive( Integer& result, const std::string_view input ) noexcept
       {
-         static constexpr I limit = ( std::numeric_limits< I >::max )();
-         return actual_convert< I, limit >( in, index );
+         // Assumes result == 0 and that input is a non-empty sequence of digits; returns false on overflow.
+
+         static_assert( std::is_integral_v< Integer > );
+         return accumulate_digits< Integer, Maximum >( result, input );
       }
 
-      template< typename I, typename Input >
-      [[nodiscard]] I convert_negative( const Input& in, std::size_t index )
+      template< typename Signed >
+      [[nodiscard]] constexpr bool convert_negative( Signed& result, const std::string_view input ) noexcept
       {
-         using U = std::make_unsigned_t< I >;
-         static constexpr U limit = static_cast< U >( ( std::numeric_limits< I >::max )() ) + 1;
-         return static_cast< I >( ~actual_convert< U, limit >( in, index ) ) + 1;
+         // Assumes result == 0 and that input is a non-empty sequence of digits; returns false on overflow.
+
+         static_assert( std::is_signed_v< Signed > );
+         using Unsigned = std::make_unsigned_t< Signed >;
+         constexpr Unsigned maximum = static_cast< Unsigned >( ( std::numeric_limits< Signed >::max )() ) + 1;
+         Unsigned temporary = 0;
+         if( accumulate_digits< Unsigned, maximum >( temporary, input ) ) {
+            result = static_cast< Signed >( ~temporary ) + 1;
+            return true;
+         }
+         return false;
+      }
+
+      template< typename Unsigned, Unsigned Maximum = ( std::numeric_limits< Unsigned >::max )() >
+      [[nodiscard]] constexpr bool convert_unsigned( Unsigned& result, const std::string_view input ) noexcept
+      {
+         // Assumes result == 0 and that input is a non-empty sequence of digits; returns false on overflow.
+
+         static_assert( std::is_unsigned_v< Unsigned > );
+         return accumulate_digits< Unsigned, Maximum >( result, input );
+      }
+
+      template< typename Signed >
+      [[nodiscard]] constexpr bool convert_signed( Signed& result, const std::string_view input ) noexcept
+      {
+         // Assumes result == 0 and that input is an optional sign followed by a non-empty sequence of digits; returns false on overflow.
+
+         static_assert( std::is_signed_v< Signed > );
+         if( input[ 0 ] == '-' ) {
+            return convert_negative< Signed >( result, std::string_view( input.data() + 1, input.size() - 1 ) );
+         }
+         const auto offset = unsigned( input[ 0 ] == '+' );
+         return convert_positive< Signed >( result, std::string_view( input.data() + offset, input.size() - offset ) );
+      }
+
+      template< typename Input >
+      [[nodiscard]] bool match_unsigned( Input& in ) noexcept( noexcept( in.empty() ) )
+      {
+         if( !in.empty() ) {
+            const char c = in.peek_char();
+            if( is_digit( c ) ) {
+               in.bump_in_this_line();
+               if( c == '0' ) {
+                  return in.empty() || ( !is_digit( in.peek_char() ) );  // TODO: Throw exception on digit?
+               }
+               while( ( !in.empty() ) && is_digit( in.peek_char() ) ) {
+                  in.bump_in_this_line();
+               }
+               return true;
+            }
+         }
+         return false;
+      }
+
+      template< typename Input,
+                typename Unsigned,
+                Unsigned Maximum = ( std::numeric_limits< Unsigned >::max )() >
+      [[nodiscard]] bool match_and_convert_unsigned_with_maximum( Input& in, Unsigned& st )
+      {
+         // Assumes st == 0.
+
+         if( !in.empty() ) {
+            char c = in.peek_char();
+            if( is_digit( c ) ) {
+               if( c == '0' ) {
+                  in.bump_in_this_line();
+                  return in.empty() || ( !is_digit( in.peek_char() ) );  // TODO: Throw exception on digit?
+               }
+               do {
+                  if( !accumulate_digit< Unsigned, Maximum >( st, c ) ) {
+                     throw parse_error( "integer overflow", in );  // Consistent with "as if" an action was doing the conversion.
+                  }
+                  in.bump_in_this_line();
+               } while( ( !in.empty() ) && is_digit( c = in.peek_char() ) );
+               return true;
+            }
+         }
+         return false;
       }
 
    }  // namespace internal
 
+   struct unsigned_action
+   {
+      // Assumes that 'in' contains a non-empty sequence of ASCII digits.
+
+      template< typename Input, typename Unsigned >
+      static auto apply( const Input& in, Unsigned& st ) -> std::enable_if_t< std::is_unsigned_v< Unsigned >, void >
+      {
+         st = 0;  // This function "only" offers basic exception safety.
+         if( !internal::convert_unsigned( st, in.string_view() ) ) {
+            throw parse_error( "unsigned integer overflow", in );
+         }
+      }
+
+      template< typename Input, typename State >
+      static auto apply( const Input& in, State& st ) -> std::enable_if_t< std::is_class_v< State >, void >
+      {
+         apply( in, st.converted );  // Compatibility for pre-3.0 behaviour.
+      }
+
+      template< typename Input, typename Unsigned, typename... Ts >
+      static auto apply( const Input& in, std::vector< Unsigned, Ts... >& st ) -> std::enable_if_t< std::is_unsigned_v< Unsigned >, void >
+      {
+         Unsigned u = 0;
+         apply( in, u );
+         st.emplace_back( u );
+      }
+   };
+
    struct unsigned_rule
-      : plus< digit >
    {
+      using analyze_t = internal::unsigned_rule_new::analyze_t;
+
+      template< typename Input >
+      [[nodiscard]] static bool match( Input& in ) noexcept( noexcept( in.empty() ) )
+      {
+         return internal::match_unsigned( in );  // Does not check for any overflow.
+      }
    };
 
-   struct unsigned_action
+   struct unsigned_rule_with_action
+   {
+      using analyze_t = internal::unsigned_rule_new::analyze_t;
+
+      template< apply_mode A,
+                rewind_mode M,
+                template< typename... >
+                class Action,
+                template< typename... >
+                class Control,
+                typename Input,
+                typename... States >
+      [[nodiscard]] static auto match( Input& in, States&&... /*unused*/ ) noexcept( noexcept( in.empty() ) ) -> std::enable_if_t< A == apply_mode::nothing, bool >
+      {
+         return internal::match_unsigned( in );  // Does not check for any overflow.
+      }
+
+      template< apply_mode A,
+                rewind_mode M,
+                template< typename... >
+                class Action,
+                template< typename... >
+                class Control,
+                typename Input,
+                typename Unsigned >
+      [[nodiscard]] static auto match( Input& in, Unsigned& st ) -> std::enable_if_t< ( A == apply_mode::action ) && std::is_unsigned_v< Unsigned >, bool >
+      {
+         st = 0;  // This function "only" offers basic exception safety.
+         return internal::match_and_convert_unsigned_with_maximum( in, st );  // Throws on overflow.
+      }
+
+      // TODO: Overload for st.converted?
+      // TODO: Overload for std::vector< Unsigned >?
+   };
+
+   template< typename Unsigned, Unsigned Maximum >
+   struct maximum_action
    {
       // Assumes that 'in' contains a non-empty sequence of ASCII digits.
 
+      static_assert( std::is_unsigned_v< Unsigned > );
+
+      template< typename Input, typename Unsigned2 >
+      static auto apply( const Input& in, Unsigned2& st ) -> std::enable_if_t< std::is_same_v< Unsigned, Unsigned2 >, void >
+      {
+         st = 0;  // This function "only" offers basic exception safety.
+         if( !internal::convert_unsigned< Unsigned, Maximum >( st, in.string_view() ) ) {
+            throw parse_error( "unsigned integer overflow", in );
+         }
+      }
+
       template< typename Input, typename State >
-      static void apply( const Input& in, State& st )
+      static auto apply( const Input& in, State& st ) -> std::enable_if_t< std::is_class_v< State >, void >
+      {
+         apply( in, st.converted );  // Compatibility for pre-3.0 behaviour.
+      }
+
+      template< typename Input, typename Unsigned2, typename... Ts >
+      static auto apply( const Input& in, std::vector< Unsigned2, Ts... >& st ) -> std::enable_if_t< std::is_same_v< Unsigned, Unsigned2 >, void >
       {
-         using T = std::decay_t< decltype( st.converted ) >;
-         static_assert( std::is_integral_v< T > );
-         static_assert( std::is_unsigned_v< T > );
-         st.converted = internal::convert_positive< T >( in, 0 );
+         Unsigned u = 0;
+         apply( in, u );
+         st.emplace_back( u );
       }
    };
 
-   struct signed_rule
-      : seq< opt< one< '+', '-' > >, plus< digit > >
+   template< typename Unsigned, Unsigned Maximum = ( std::numeric_limits< Unsigned >::max )() >
+   struct maximum_rule
    {
+      static_assert( std::is_unsigned_v< Unsigned > );
+
+      using analyze_t = internal::unsigned_rule_new::analyze_t;
+
+      template< typename Input >
+      [[nodiscard]] static bool match( Input& in )
+      {
+         Unsigned st = 0;
+         return internal::match_and_convert_unsigned_with_maximum< Input, Unsigned, Maximum >( in, st );  // Throws on overflow.
+      }
+   };
+
+   template< typename Unsigned, Unsigned Maximum = ( std::numeric_limits< Unsigned >::max )() >
+   struct maximum_rule_with_action
+   {
+      static_assert( std::is_unsigned_v< Unsigned > );
+
+      using analyze_t = internal::unsigned_rule_new::analyze_t;
+
+      template< apply_mode A,
+                rewind_mode M,
+                template< typename... >
+                class Action,
+                template< typename... >
+                class Control,
+                typename Input,
+                typename... States >
+      [[nodiscard]] static auto match( Input& in, States&&... /*unused*/ ) -> std::enable_if_t< A == apply_mode::nothing, bool >
+      {
+         Unsigned st = 0;
+         return internal::match_and_convert_unsigned_with_maximum< Input, Unsigned, Maximum >( in, st );  // Throws on overflow.
+      }
+
+      template< apply_mode A,
+                rewind_mode M,
+                template< typename... >
+                class Action,
+                template< typename... >
+                class Control,
+                typename Input,
+                typename Unsigned2 >
+      [[nodiscard]] static auto match( Input& in, Unsigned2& st ) -> std::enable_if_t< ( A == apply_mode::action ) && std::is_same_v< Unsigned, Unsigned2 >, bool >
+      {
+         st = 0;  // This function "only" offers basic exception safety.
+         return internal::match_and_convert_unsigned_with_maximum< Input, Unsigned, Maximum >( in, st );  // Throws on overflow.
+      }
+
+      // TODO: Overload for st.converted?
+      // TODO: Overload for std::vector< Unsigned >?
    };
 
    struct signed_action
@@ -79,20 +351,96 @@ namespace TAO_PEGTL_NAMESPACE::integer
       // Assumes that 'in' contains a non-empty sequence of ASCII digits,
       // with optional leading sign; with sign, in.size() must be >= 2.
 
-      template< typename Input, typename State >
-      static void apply( const Input& in, State& st )
-      {
-         using T = std::decay_t< decltype( st.converted ) >;
-         static_assert( std::is_integral_v< T > );
-         static_assert( std::is_signed_v< T > );
-         const auto c = in.peek_char();
-         if( c == '-' ) {
-            st.converted = internal::convert_negative< T >( in, 1 );
-         }
-         else {
-            st.converted = internal::convert_positive< T >( in, std::size_t( c == '+' ) );
+      template< typename Input, typename Signed >
+      static auto apply( const Input& in, Signed& st ) -> std::enable_if_t< std::is_signed_v< Signed >, void >
+      {
+         st = 0;  // This function "only" offers basic exception safety.
+         if( !internal::convert_signed( st, in.string_view() ) ) {
+            throw parse_error( "signed integer overflow", in );
          }
       }
+
+      template< typename Input, typename State >
+      static auto apply( const Input& in, State& st ) -> std::enable_if_t< std::is_class_v< State >, void >
+      {
+         apply( in, st.converted );  // Compatibility for pre-3.0 behaviour.
+      }
+
+      template< typename Input, typename Signed, typename... Ts >
+      static auto apply( const Input& in, std::vector< Signed, Ts... >& st ) -> std::enable_if_t< std::is_signed_v< Signed >, void >
+      {
+         Signed s = 0;
+         apply( in, s );
+         st.emplace_back( s );
+      }
+   };
+
+   struct signed_rule
+   {
+      using analyze_t = internal::signed_rule_new::analyze_t;
+
+      template< apply_mode A,
+                rewind_mode M,
+                template< typename... >
+                class Action,
+                template< typename... >
+                class Control,
+                typename Input,
+                typename... States >
+      [[nodiscard]] static bool match( Input& in, States&&... /*unused*/ ) noexcept( noexcept( in.empty() ) )
+      {
+         return TAO_PEGTL_NAMESPACE::parse< internal::signed_rule_new >( in );  // Does not check for any overflow.
+      }
+   };
+
+   namespace internal
+   {
+      template< typename Rule >
+      struct signed_action_action
+         : nothing< Rule >
+      {
+      };
+
+      template<>
+      struct signed_action_action< signed_rule_new >
+         : signed_action
+      {
+      };
+
+   }  // namespace internal
+
+   struct signed_rule_with_action
+   {
+      using analyze_t = internal::signed_rule_new::analyze_t;
+
+      template< apply_mode A,
+                rewind_mode M,
+                template< typename... >
+                class Action,
+                template< typename... >
+                class Control,
+                typename Input,
+                typename... States >
+      [[nodiscard]] static auto match( Input& in, States&&... /*unused*/ ) noexcept( noexcept( in.empty() ) ) -> std::enable_if_t< A == apply_mode::nothing, bool >
+      {
+         return TAO_PEGTL_NAMESPACE::parse< internal::signed_rule_new >( in );  // Does not check for any overflow.
+      }
+
+      template< apply_mode A,
+                rewind_mode M,
+                template< typename... >
+                class Action,
+                template< typename... >
+                class Control,
+                typename Input,
+                typename Signed >
+      [[nodiscard]] static auto match( Input& in, Signed& st ) -> std::enable_if_t< ( A == apply_mode::action ) && std::is_signed_v< Signed >, bool >
+      {
+         return TAO_PEGTL_NAMESPACE::parse< internal::signed_rule_new, internal::signed_action_action >( in, st );  // Throws on overflow.
+      }
+
+      // TODO: Overload for st.converted?
+      // TODO: Overload for std::vector< Signed >?
    };
 
 }  // namespace TAO_PEGTL_NAMESPACE::integer
diff --git a/packages/PEGTL/include/tao/pegtl/contrib/json.hpp b/packages/PEGTL/include/tao/pegtl/contrib/json.hpp
index 76564b5ef991f9a8cc788784f58a1e05fec5918e..a105f0ef810ec60e2ae55f220553808e4fa78289 100644
--- a/packages/PEGTL/include/tao/pegtl/contrib/json.hpp
+++ b/packages/PEGTL/include/tao/pegtl/contrib/json.hpp
@@ -9,8 +9,6 @@
 #include "../rules.hpp"
 #include "../utf8.hpp"
 
-#include "abnf.hpp"
-
 namespace TAO_PEGTL_NAMESPACE::json
 {
    // JSON grammar according to RFC 8259
@@ -32,13 +30,13 @@ namespace TAO_PEGTL_NAMESPACE::json
    struct null : string< 'n', 'u', 'l', 'l' > {};
    struct true_ : string< 't', 'r', 'u', 'e' > {};
 
-   struct digits : plus< abnf::DIGIT > {};
+   struct digits : plus< digit > {};
    struct exp : seq< one< 'e', 'E' >, opt< one< '-', '+'> >, must< digits > > {};
    struct frac : if_must< one< '.' >, digits > {};
    struct int_ : sor< one< '0' >, digits > {};
    struct number : seq< opt< one< '-' > >, int_, opt< frac >, opt< exp > > {};
 
-   struct xdigit : abnf::HEXDIG {};
+   struct xdigit : pegtl::xdigit {};
    struct unicode : list< seq< one< 'u' >, rep< 4, must< xdigit > > >, one< '\\' > > {};
    struct escaped_char : one< '"', '\\', '/', 'b', 'f', 'n', 'r', 't' > {};
    struct escaped : sor< escaped_char, unicode > {};
diff --git a/packages/PEGTL/include/tao/pegtl/contrib/json_pointer.hpp b/packages/PEGTL/include/tao/pegtl/contrib/json_pointer.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d03c8364e7ef0bd7409844284441a2fbe8eaedb6
--- /dev/null
+++ b/packages/PEGTL/include/tao/pegtl/contrib/json_pointer.hpp
@@ -0,0 +1,33 @@
+// Copyright (c) 2019 Dr. Colin Hirsch and Daniel Frey
+// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/
+
+#ifndef TAO_PEGTL_CONTRIB_JSON_POINTER_HPP
+#define TAO_PEGTL_CONTRIB_JSON_POINTER_HPP
+
+#include "../ascii.hpp"
+#include "../config.hpp"
+#include "../rules.hpp"
+#include "../utf8.hpp"
+
+namespace TAO_PEGTL_NAMESPACE::json_pointer
+{
+   // JSON pointer grammar according to RFC 6901
+
+   // clang-format off
+   struct unescaped : utf8::ranges< 0x0, 0x2E, 0x30, 0x7D, 0x7F, 0x10FFFF > {};
+   struct escaped : seq< one< '~' >, one< '0', '1' > > {};
+
+   struct reference_token : star< sor< unescaped, escaped > > {};
+   struct json_pointer : star< one< '/' >, reference_token > {};
+   // clang-format on
+
+   // relative JSON pointer, see ...
+
+   // clang-format off
+   struct non_negative_integer : sor< one< '0' >, plus< digit > > {};
+   struct relative_json_pointer : seq< non_negative_integer, sor< one< '#' >, json_pointer > > {};
+   // clang-format on
+
+}  // namespace TAO_PEGTL_NAMESPACE::json_pointer
+
+#endif
diff --git a/packages/PEGTL/include/tao/pegtl/contrib/uri.hpp b/packages/PEGTL/include/tao/pegtl/contrib/uri.hpp
index 06f5e7cf86e1a36014de94a0549ea0cfa15e72cf..2a391bd6968189f6e3dab26d48ccc73d2271ae56 100644
--- a/packages/PEGTL/include/tao/pegtl/contrib/uri.hpp
+++ b/packages/PEGTL/include/tao/pegtl/contrib/uri.hpp
@@ -4,12 +4,15 @@
 #ifndef TAO_PEGTL_CONTRIB_URI_HPP
 #define TAO_PEGTL_CONTRIB_URI_HPP
 
+#include <cstdint>
+
 #include "../ascii.hpp"
 #include "../config.hpp"
 #include "../rules.hpp"
 #include "../utf8.hpp"
 
 #include "abnf.hpp"
+#include "integer.hpp"
 
 namespace TAO_PEGTL_NAMESPACE::uri
 {
@@ -25,11 +28,7 @@ namespace TAO_PEGTL_NAMESPACE::uri
    using colon = one< ':' >;
 
    // clang-format off
-   struct dec_octet : sor< one< '0' >,
-                           rep_min_max< 1, 2, abnf::DIGIT >,
-                           seq< one< '1' >, abnf::DIGIT, abnf::DIGIT >,
-                           seq< one< '2' >, range< '0', '4' >, abnf::DIGIT >,
-                           seq< string< '2', '5' >, range< '0', '5' > > > {};
+   struct dec_octet : integer::maximum_rule< std::uint8_t > {};
 
    struct IPv4address : seq< dec_octet, dot, dec_octet, dot, dec_octet, dot, dec_octet > {};
 
diff --git a/packages/PEGTL/src/test/pegtl/ascii_forty_two.cpp b/packages/PEGTL/src/test/pegtl/ascii_forty_two.cpp
index 4e79fdd9df37413eda5c18e0b3e004bb8dbb7341..e1224b2d6f7414e20d5f81bb9abe333926529514 100644
--- a/packages/PEGTL/src/test/pegtl/ascii_forty_two.cpp
+++ b/packages/PEGTL/src/test/pegtl/ascii_forty_two.cpp
@@ -16,19 +16,19 @@ namespace TAO_PEGTL_NAMESPACE
          verify_rule< forty_two< 'a' > >( __LINE__, __FILE__, std::string( i, 'a' ), result_type::local_failure );
       }
       for( std::size_t i = 42; i < 100; ++i ) {
-         verify_rule< forty_two< 'a' > >( __LINE__, __FILE__, std::string( i, 'a' ), result_type::success, i - 42 );
+         verify_rule< forty_two< 'a' > >( __LINE__, __FILE__, std::string( i, 'a' ), result_type::success, int( i - 42 ) );
       }
       for( std::size_t i = 0; i < 42; ++i ) {
          verify_rule< forty_two< 'a', 'z' > >( __LINE__, __FILE__, std::string( i, 'a' ), result_type::local_failure );
       }
       for( std::size_t i = 42; i < 100; ++i ) {
-         verify_rule< forty_two< 'a', 'z' > >( __LINE__, __FILE__, std::string( i, 'a' ), result_type::success, i - 42 );
+         verify_rule< forty_two< 'a', 'z' > >( __LINE__, __FILE__, std::string( i, 'a' ), result_type::success, int( i - 42 ) );
       }
       for( std::size_t i = 0; i < 42; ++i ) {
          verify_rule< forty_two< 'a', 'z' > >( __LINE__, __FILE__, std::string( i, 'z' ), result_type::local_failure );
       }
       for( std::size_t i = 42; i < 100; ++i ) {
-         verify_rule< forty_two< 'a', 'z' > >( __LINE__, __FILE__, std::string( i, 'z' ), result_type::success, i - 42 );
+         verify_rule< forty_two< 'a', 'z' > >( __LINE__, __FILE__, std::string( i, 'z' ), result_type::success, int( i - 42 ) );
       }
       verify_rule< forty_two< 'a', 'z' > >( __LINE__, __FILE__, "azzaazaazaaazzzaaaazzaaazzaazazzzaazzazaza", result_type::success );
    }
diff --git a/packages/PEGTL/src/test/pegtl/contrib_integer.cpp b/packages/PEGTL/src/test/pegtl/contrib_integer.cpp
index a6f3d9a52e698dc1a6002a5da1e02e000a48fc81..e819cdc6d27a6d52748bd9c50db963eb9a4878a8 100644
--- a/packages/PEGTL/src/test/pegtl/contrib_integer.cpp
+++ b/packages/PEGTL/src/test/pegtl/contrib_integer.cpp
@@ -6,6 +6,8 @@
 
 #include "test.hpp"
 
+#include "verify_rule.hpp"
+
 #include <tao/pegtl/contrib/integer.hpp>
 
 namespace TAO_PEGTL_NAMESPACE
@@ -18,6 +20,7 @@ namespace TAO_PEGTL_NAMESPACE
 
    template< typename Rule >
    struct int_action
+      : nothing< Rule >
    {};
 
    template<>
@@ -33,10 +36,24 @@ namespace TAO_PEGTL_NAMESPACE
    template< typename S >
    void test_signed( const std::string& i, const S s )
    {
-      int_state< S > st;
-      memory_input in( i, __FUNCTION__ );
-      parse< must< integer::signed_rule, eof >, int_action >( in, st );
-      TAO_PEGTL_TEST_ASSERT( st.converted == s );
+      {
+         S st = -123;
+         memory_input in( i, __FUNCTION__ );
+         parse< must< integer::signed_rule, eof >, int_action >( in, st );
+         TAO_PEGTL_TEST_ASSERT( st == s );
+      }
+      {
+         int_state< S > st;
+         memory_input in( i, __FUNCTION__ );
+         parse< must< integer::signed_rule, eof >, int_action >( in, st );
+         TAO_PEGTL_TEST_ASSERT( st.converted == s );
+      }
+      {
+         S st = -123;
+         memory_input in( i, __FUNCTION__ );
+         parse< must< integer::signed_rule_with_action, eof > >( in, st );
+         TAO_PEGTL_TEST_ASSERT( st == s );
+      }
    }
 
    template< typename S >
@@ -68,16 +85,30 @@ namespace TAO_PEGTL_NAMESPACE
    template< typename S >
    void test_unsigned( const std::string& i, const S s )
    {
-      int_state< S > st;
-      memory_input in( i, __FUNCTION__ );
-      parse< must< integer::unsigned_rule, eof >, int_action >( in, st );
-      TAO_PEGTL_TEST_ASSERT( st.converted == s );
+      {
+         S st = 123;
+         memory_input in( i, __FUNCTION__ );
+         parse< must< integer::unsigned_rule, eof >, int_action >( in, st );
+         TAO_PEGTL_TEST_ASSERT( st == s );
+      }
+      {
+         int_state< S > st;
+         memory_input in( i, __FUNCTION__ );
+         parse< must< integer::unsigned_rule, eof >, int_action >( in, st );
+         TAO_PEGTL_TEST_ASSERT( st.converted == s );
+      }
+      {
+         S st = 123;
+         memory_input in( i, __FUNCTION__ );
+         parse< must< integer::unsigned_rule_with_action, eof > >( in, st );
+         TAO_PEGTL_TEST_ASSERT( st == s );
+      }
    }
 
    template< typename S >
    void test_unsigned( const std::string& i )
    {
-      int_state< S > st;
+      S st = 123;
       memory_input in( i, __FUNCTION__ );
       TAO_PEGTL_TEST_THROWS( parse< must< integer::unsigned_rule, eof >, int_action >( in, st ) );
    }
@@ -85,15 +116,22 @@ namespace TAO_PEGTL_NAMESPACE
    template< typename S >
    void test_unsigned( const S s )
    {
-      int_state< S > st;
+      S st = 123;
       const auto i = lexical_cast( s );
       memory_input in( i, __FUNCTION__ );
       parse< must< integer::unsigned_rule, eof >, int_action >( in, st );
-      TAO_PEGTL_TEST_ASSERT( st.converted == s );
+      TAO_PEGTL_TEST_ASSERT( st == s );
    }
 
+   template< auto M > using max_seq_rule = seq< one< 'a' >, integer::maximum_rule< std::uint64_t, M >, one< 'b' >, eof >;
+
    void unit_test()
    {
+      test_signed< signed char >( "" );
+      test_signed< signed char >( "-" );
+      test_signed< signed char >( "+" );
+      test_signed< signed char >( "a" );
+
       test_signed< signed char >( "--0" );
       test_signed< signed char >( "++0" );
       test_signed< signed char >( "-+0" );
@@ -101,32 +139,44 @@ namespace TAO_PEGTL_NAMESPACE
       test_signed< signed char >( "0", 0 );
       test_signed< signed char >( "+0", 0 );
       test_signed< signed char >( "-0", 0 );
-      test_signed< signed char >( "000", 0 );
-      test_signed< signed char >( "+000", 0 );
-      test_signed< signed char >( "-000", 0 );
+      test_signed< signed char >( "000" );
+
+      test_signed< signed char >( "+000" );
+      test_signed< signed char >( "-000" );
 
       test_signed< signed char >( "127", 127 );
+      test_signed< signed char >( "0127" );
 
       test_signed< signed char >( "-1", -1 );
-      test_signed< signed char >( "-001", -1 );
+      test_signed< signed char >( "-01" );
+      test_signed< signed char >( "-001" );
 
       test_signed< signed char >( "-127", -127 );
       test_signed< signed char >( "-128", -128 );
 
       test_signed< signed char >( "128" );
       test_signed< signed char >( "-129" );
+      test_signed< signed char >( "0128" );
       test_signed< signed char >( "00128" );
+      test_signed< signed char >( "-0129" );
       test_signed< signed char >( "-00129" );
 
+      test_unsigned< unsigned char >( "" );
+      test_unsigned< unsigned char >( "-" );
+      test_unsigned< unsigned char >( "+" );
+      test_unsigned< unsigned char >( "a" );
+
       test_unsigned< unsigned char >( "-0" );
       test_unsigned< unsigned char >( "+1" );
 
       test_unsigned< unsigned char >( "0", 0 );
-      test_unsigned< unsigned char >( "000", 0 );
+      test_unsigned< unsigned char >( "000" );
       test_unsigned< unsigned char >( "0", 0 );
       test_unsigned< unsigned char >( "255", 255 );
-      test_unsigned< unsigned char >( "000255", 255 );
+      test_unsigned< unsigned char >( "0255" );
+      test_unsigned< unsigned char >( "000255" );
       test_unsigned< unsigned char >( "256" );
+      test_unsigned< unsigned char >( "0256" );
       test_unsigned< unsigned char >( "000256" );
 
       test_signed< signed long long >( "0", 0 );
@@ -135,6 +185,76 @@ namespace TAO_PEGTL_NAMESPACE
 
       test_unsigned< unsigned long long >( "0", 0 );
       test_unsigned< unsigned long long >( ( std::numeric_limits< unsigned long long >::max )() );
+
+      verify_rule< max_seq_rule< 0 > >( __LINE__, __FILE__, "a0b", result_type::success );
+      verify_rule< max_seq_rule< 0 > >( __LINE__, __FILE__, "ab", result_type::local_failure );
+      verify_rule< max_seq_rule< 0 > >( __LINE__, __FILE__, "a1b", result_type::global_failure );
+      verify_rule< max_seq_rule< 0 > >( __LINE__, __FILE__, "a9b", result_type::global_failure );
+      verify_rule< max_seq_rule< 0 > >( __LINE__, __FILE__, "a11b", result_type::global_failure );
+
+      verify_rule< max_seq_rule< 1 > >( __LINE__, __FILE__, "a0b", result_type::success );
+      verify_rule< max_seq_rule< 1 > >( __LINE__, __FILE__, "a1b", result_type::success );
+      verify_rule< max_seq_rule< 1 > >( __LINE__, __FILE__, "ab", result_type::local_failure );
+      verify_rule< max_seq_rule< 1 > >( __LINE__, __FILE__, "a2b", result_type::global_failure );
+      verify_rule< max_seq_rule< 1 > >( __LINE__, __FILE__, "a9b", result_type::global_failure );
+      verify_rule< max_seq_rule< 1 > >( __LINE__, __FILE__, "a11b", result_type::global_failure );
+
+      verify_rule< max_seq_rule< 2 > >( __LINE__, __FILE__, "a0b", result_type::success );
+      verify_rule< max_seq_rule< 2 > >( __LINE__, __FILE__, "a1b", result_type::success );
+      verify_rule< max_seq_rule< 2 > >( __LINE__, __FILE__, "a2b", result_type::success );
+      verify_rule< max_seq_rule< 2 > >( __LINE__, __FILE__, "ab", result_type::local_failure );
+      verify_rule< max_seq_rule< 2 > >( __LINE__, __FILE__, "a3b", result_type::global_failure );
+      verify_rule< max_seq_rule< 2 > >( __LINE__, __FILE__, "a9b", result_type::global_failure );
+      verify_rule< max_seq_rule< 2 > >( __LINE__, __FILE__, "a11b", result_type::global_failure );
+
+      verify_rule< max_seq_rule< 3 > >( __LINE__, __FILE__, "a0b", result_type::success );
+      verify_rule< max_seq_rule< 3 > >( __LINE__, __FILE__, "a3b", result_type::success );
+      verify_rule< max_seq_rule< 3 > >( __LINE__, __FILE__, "ab", result_type::local_failure );
+      verify_rule< max_seq_rule< 3 > >( __LINE__, __FILE__, "a4b", result_type::global_failure );
+      verify_rule< max_seq_rule< 3 > >( __LINE__, __FILE__, "a11b", result_type::global_failure );
+
+      verify_rule< max_seq_rule< 4 > >( __LINE__, __FILE__, "a5b", result_type::global_failure );
+      verify_rule< max_seq_rule< 4 > >( __LINE__, __FILE__, "a11b", result_type::global_failure );
+
+      verify_rule< max_seq_rule< 9 > >( __LINE__, __FILE__, "a0b", result_type::success );
+      verify_rule< max_seq_rule< 9 > >( __LINE__, __FILE__, "a9b", result_type::success );
+      verify_rule< max_seq_rule< 9 > >( __LINE__, __FILE__, "ab", result_type::local_failure );
+      verify_rule< max_seq_rule< 9 > >( __LINE__, __FILE__, "a10b", result_type::global_failure );
+      verify_rule< max_seq_rule< 9 > >( __LINE__, __FILE__, "a11b", result_type::global_failure );
+
+      verify_rule< max_seq_rule< 10 > >( __LINE__, __FILE__, "a0b", result_type::success );
+      verify_rule< max_seq_rule< 10 > >( __LINE__, __FILE__, "a9b", result_type::success );
+      verify_rule< max_seq_rule< 10 > >( __LINE__, __FILE__, "a10b", result_type::success );
+      verify_rule< max_seq_rule< 10 > >( __LINE__, __FILE__, "ab", result_type::local_failure );
+      verify_rule< max_seq_rule< 10 > >( __LINE__, __FILE__, "a11b", result_type::global_failure );
+      verify_rule< max_seq_rule< 10 > >( __LINE__, __FILE__, "a19b", result_type::global_failure );
+
+      verify_rule< max_seq_rule< 11 > >( __LINE__, __FILE__, "a0b", result_type::success );
+      verify_rule< max_seq_rule< 11 > >( __LINE__, __FILE__, "a9b", result_type::success );
+      verify_rule< max_seq_rule< 11 > >( __LINE__, __FILE__, "a10b", result_type::success );
+      verify_rule< max_seq_rule< 11 > >( __LINE__, __FILE__, "a11b", result_type::success );
+      verify_rule< max_seq_rule< 11 > >( __LINE__, __FILE__, "ab", result_type::local_failure );
+      verify_rule< max_seq_rule< 11 > >( __LINE__, __FILE__, "a12b", result_type::global_failure );
+      verify_rule< max_seq_rule< 11 > >( __LINE__, __FILE__, "a13b", result_type::global_failure );
+      verify_rule< max_seq_rule< 11 > >( __LINE__, __FILE__, "a111b", result_type::global_failure );
+
+      verify_rule< max_seq_rule< 12 > >( __LINE__, __FILE__, "a0b", result_type::success );
+      verify_rule< max_seq_rule< 12 > >( __LINE__, __FILE__, "a1b", result_type::success );
+      verify_rule< max_seq_rule< 12 > >( __LINE__, __FILE__, "a9b", result_type::success );
+      verify_rule< max_seq_rule< 12 > >( __LINE__, __FILE__, "a10b", result_type::success );
+      verify_rule< max_seq_rule< 12 > >( __LINE__, __FILE__, "a11b", result_type::success );
+      verify_rule< max_seq_rule< 12 > >( __LINE__, __FILE__, "a12b", result_type::success );
+      verify_rule< max_seq_rule< 12 > >( __LINE__, __FILE__, "ab", result_type::local_failure );
+      verify_rule< max_seq_rule< 12 > >( __LINE__, __FILE__, "a13b", result_type::global_failure );
+      verify_rule< max_seq_rule< 12 > >( __LINE__, __FILE__, "a19b", result_type::global_failure );
+      verify_rule< max_seq_rule< 12 > >( __LINE__, __FILE__, "a111b", result_type::global_failure );
+
+      verify_rule< max_seq_rule< 18446744073709551614ULL > >( __LINE__, __FILE__, "a18446744073709551614b", result_type::success );
+      verify_rule< max_seq_rule< 18446744073709551614ULL > >( __LINE__, __FILE__, "a18446744073709551615b", result_type::global_failure );
+
+      verify_rule< max_seq_rule< 18446744073709551615ULL > >( __LINE__, __FILE__, "a18446744073709551615b", result_type::success );
+      verify_rule< max_seq_rule< 18446744073709551615ULL > >( __LINE__, __FILE__, "a18446744073709551616b", result_type::global_failure );
+      verify_rule< max_seq_rule< 18446744073709551615ULL > >( __LINE__, __FILE__, "a98446744073709551614b", result_type::global_failure );
    }
 
 }  // namespace TAO_PEGTL_NAMESPACE
diff --git a/packages/PEGTL/src/test/pegtl/rule_rematch.cpp b/packages/PEGTL/src/test/pegtl/rule_rematch.cpp
index d6d384469a350c37ca0f1b3998dfb8529438581f..0cc22500f9cf815a2724b8a251f774a660cb5b4d 100644
--- a/packages/PEGTL/src/test/pegtl/rule_rematch.cpp
+++ b/packages/PEGTL/src/test/pegtl/rule_rematch.cpp
@@ -9,11 +9,11 @@ namespace TAO_PEGTL_NAMESPACE
 {
    void unit_test()
    {
-      verify_rule< rematch< one< 'c' > > >( __LINE__, __FILE__, "c", result_type::success, 0 );
-      verify_rule< rematch< one< 'c' > > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 );
-      verify_rule< rematch< one< 'c' > > >( __LINE__, __FILE__, "b", result_type::local_failure, 1 );
+      verify_rule< rematch< one< 'c' > > >( __LINE__, __FILE__, "c", result_type::success );
+      verify_rule< rematch< one< 'c' > > >( __LINE__, __FILE__, "a", result_type::local_failure );
+      verify_rule< rematch< one< 'c' > > >( __LINE__, __FILE__, "b", result_type::local_failure );
       verify_rule< rematch< one< 'c' > > >( __LINE__, __FILE__, "cc", result_type::success, 1 );
-      verify_rule< rematch< one< 'c' > > >( __LINE__, __FILE__, "bc", result_type::local_failure, 2 );
+      verify_rule< rematch< one< 'c' > > >( __LINE__, __FILE__, "bc", result_type::local_failure );
 
       verify_analyze< rematch< alpha, digit > >( __LINE__, __FILE__, true, false );
       verify_analyze< rematch< opt< alpha >, digit > >( __LINE__, __FILE__, false, false );
@@ -45,12 +45,12 @@ namespace TAO_PEGTL_NAMESPACE
       verify_rule< rematch< alnum, success, digit > >( __LINE__, __FILE__, "12", result_type::success, 1 );
       verify_rule< rematch< alnum, success, digit > >( __LINE__, __FILE__, "1c", result_type::success, 1 );
 
-      verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "", result_type::local_failure, 0 );
-      verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "1", result_type::success, 0 );
-      verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 );
-      verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "%", result_type::local_failure, 1 );
+      verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "", result_type::local_failure );
+      verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "1", result_type::success );
+      verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "a", result_type::local_failure );
+      verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "%", result_type::local_failure );
       verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "1%", result_type::success, 1 );
-      verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "a%", result_type::local_failure, 1 );
+      verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "a%", result_type::local_failure );
       verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "12", result_type::success, 0 );
       verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "1c", result_type::success, 0 );
       verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "aa", result_type::local_failure, 2 );
@@ -62,7 +62,7 @@ namespace TAO_PEGTL_NAMESPACE
       verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 );
       verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "%", result_type::local_failure, 1 );
       verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "1%", result_type::success, 1 );
-      verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "a%", result_type::local_failure, 1 );
+      verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "a%", result_type::local_failure );
       verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "12", result_type::success, 0 );
       verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "1c", result_type::success, 0 );
       verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "aa", result_type::local_failure, 2 );
diff --git a/packages/PEGTL/src/test/pegtl/utf16_general.cpp b/packages/PEGTL/src/test/pegtl/utf16_general.cpp
index 1a9521612ede6d3230f1bc5bae4fd17f2d66fbbb..fd84074943d037acb10e80132963e9e6cda23cf7 100644
--- a/packages/PEGTL/src/test/pegtl/utf16_general.cpp
+++ b/packages/PEGTL/src/test/pegtl/utf16_general.cpp
@@ -29,114 +29,114 @@ namespace TAO_PEGTL_NAMESPACE
 
    void test_utf16()
    {
-      verify_rule< utf16::any >( __LINE__, __FILE__, "", result_type::local_failure, 0 );
-      verify_rule< utf16::any >( __LINE__, __FILE__, "\x01", result_type::local_failure, 1 );
-      verify_rule< utf16::any >( __LINE__, __FILE__, "\xff", result_type::local_failure, 1 );
-
-      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0 ), result_type::success, 0 );
-      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 1 ), result_type::success, 0 );
-      verify_rule< utf16::any >( __LINE__, __FILE__, "  ", result_type::success, 0 );
-      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0x00ff ), result_type::success, 0 );
-      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0x0100 ), result_type::success, 0 );
-      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0x0fff ), result_type::success, 0 );
-      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0x1000 ), result_type::success, 0 );
-      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd800 ), result_type::local_failure, 0 );
-      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd900 ), result_type::local_failure, 0 );
-      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xde00 ), result_type::local_failure, 0 );
+      verify_rule< utf16::any >( __LINE__, __FILE__, "", result_type::local_failure );
+      verify_rule< utf16::any >( __LINE__, __FILE__, "\x01", result_type::local_failure );
+      verify_rule< utf16::any >( __LINE__, __FILE__, "\xff", result_type::local_failure );
+
+      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0 ), result_type::success );
+      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 1 ), result_type::success );
+      verify_rule< utf16::any >( __LINE__, __FILE__, "  ", result_type::success );
+      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0x00ff ), result_type::success );
+      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0x0100 ), result_type::success );
+      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0x0fff ), result_type::success );
+      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0x1000 ), result_type::success );
+      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd800 ), result_type::local_failure );
+      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd900 ), result_type::local_failure );
+      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xde00 ), result_type::local_failure );
       verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xfffe ) + " ", result_type::success, 1 );
       verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xffff ) + "  ", result_type::success, 2 );
 
       verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd7ff ) + u16s( 0xdfff ), result_type::success, 2 );
-      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xdc00 ) + u16s( 0xdfff ), result_type::local_failure, 4 );
-      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd800 ) + u16s( 0x0020 ), result_type::local_failure, 4 );
-      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd800 ) + u16s( 0xff20 ), result_type::local_failure, 4 );
-      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd800 ) + u16s( 0xdf00 ), result_type::success, 0 );
-      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd800 ) + u16s( 0xdfff ), result_type::success, 0 );
-      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xdbff ) + u16s( 0xdc00 ), result_type::success, 0 );
-      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xdbff ) + u16s( 0xdfff ), result_type::success, 0 );
+      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xdc00 ) + u16s( 0xdfff ), result_type::local_failure );
+      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd800 ) + u16s( 0x0020 ), result_type::local_failure );
+      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd800 ) + u16s( 0xff20 ), result_type::local_failure );
+      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd800 ) + u16s( 0xdf00 ), result_type::success );
+      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd800 ) + u16s( 0xdfff ), result_type::success );
+      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xdbff ) + u16s( 0xdc00 ), result_type::success );
+      verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xdbff ) + u16s( 0xdfff ), result_type::success );
 
-      verify_rule< utf16::one< 0x20 > >( __LINE__, __FILE__, u16s( 0x20 ), result_type::success, 0 );
-      verify_rule< utf16::one< 0x20ac > >( __LINE__, __FILE__, u16s( 0x20ac ), result_type::success, 0 );
-      verify_rule< utf16::one< 0x10437 > >( __LINE__, __FILE__, u16s( 0xd801 ) + u16s( 0xdc37 ), result_type::success, 0 );
+      verify_rule< utf16::one< 0x20 > >( __LINE__, __FILE__, u16s( 0x20 ), result_type::success );
+      verify_rule< utf16::one< 0x20ac > >( __LINE__, __FILE__, u16s( 0x20ac ), result_type::success );
+      verify_rule< utf16::one< 0x10437 > >( __LINE__, __FILE__, u16s( 0xd801 ) + u16s( 0xdc37 ), result_type::success );
 
-      verify_rule< utf16::bom >( __LINE__, __FILE__, u16s( 0xfeff ), result_type::success, 0 );
-      verify_rule< utf16::bom >( __LINE__, __FILE__, u16s( 0xfffe ), result_type::local_failure, 2 );
+      verify_rule< utf16::bom >( __LINE__, __FILE__, u16s( 0xfeff ), result_type::success );
+      verify_rule< utf16::bom >( __LINE__, __FILE__, u16s( 0xfffe ), result_type::local_failure );
 
       verify_rule< utf16::string< 0x20, 0x20ac, 0x10437 > >( __LINE__, __FILE__, u16s( 0x20 ) + u16s( 0x20ac ) + u16s( 0xd801 ) + u16s( 0xdc37 ) + u16s( 0x20 ), result_type::success, 2 );
    }
 
    void test_utf16_be()
    {
-      verify_rule< utf16_be::any >( __LINE__, __FILE__, "", result_type::local_failure, 0 );
-      verify_rule< utf16_be::any >( __LINE__, __FILE__, "\x01", result_type::local_failure, 1 );
-      verify_rule< utf16_be::any >( __LINE__, __FILE__, "\xff", result_type::local_failure, 1 );
-
-      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0 ), result_type::success, 0 );
-      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 1 ), result_type::success, 0 );
-      verify_rule< utf16_be::any >( __LINE__, __FILE__, "  ", result_type::success, 0 );
-      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0x00ff ), result_type::success, 0 );
-      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0x0100 ), result_type::success, 0 );
-      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0x0fff ), result_type::success, 0 );
-      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0x1000 ), result_type::success, 0 );
-      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd800 ), result_type::local_failure, 0 );
-      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd900 ), result_type::local_failure, 0 );
-      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xde00 ), result_type::local_failure, 0 );
+      verify_rule< utf16_be::any >( __LINE__, __FILE__, "", result_type::local_failure );
+      verify_rule< utf16_be::any >( __LINE__, __FILE__, "\x01", result_type::local_failure );
+      verify_rule< utf16_be::any >( __LINE__, __FILE__, "\xff", result_type::local_failure );
+
+      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0 ), result_type::success );
+      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 1 ), result_type::success );
+      verify_rule< utf16_be::any >( __LINE__, __FILE__, "  ", result_type::success );
+      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0x00ff ), result_type::success );
+      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0x0100 ), result_type::success );
+      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0x0fff ), result_type::success );
+      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0x1000 ), result_type::success );
+      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd800 ), result_type::local_failure );
+      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd900 ), result_type::local_failure );
+      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xde00 ), result_type::local_failure );
       verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xfffe ) + " ", result_type::success, 1 );
       verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xffff ) + "  ", result_type::success, 2 );
 
       verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd7ff ) + u16s_be( 0xdfff ), result_type::success, 2 );
-      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xdc00 ) + u16s_be( 0xdfff ), result_type::local_failure, 0 );
-      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd800 ) + u16s_be( 0x0020 ), result_type::local_failure, 0 );
-      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd800 ) + u16s_be( 0xff20 ), result_type::local_failure, 0 );
-      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd800 ) + u16s_be( 0xdf00 ), result_type::success, 0 );
-      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd800 ) + u16s_be( 0xdfff ), result_type::success, 0 );
-      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xdbff ) + u16s_be( 0xdc00 ), result_type::success, 0 );
-      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xdbff ) + u16s_be( 0xdfff ), result_type::success, 0 );
+      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xdc00 ) + u16s_be( 0xdfff ), result_type::local_failure );
+      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd800 ) + u16s_be( 0x0020 ), result_type::local_failure );
+      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd800 ) + u16s_be( 0xff20 ), result_type::local_failure );
+      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd800 ) + u16s_be( 0xdf00 ), result_type::success );
+      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd800 ) + u16s_be( 0xdfff ), result_type::success );
+      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xdbff ) + u16s_be( 0xdc00 ), result_type::success );
+      verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xdbff ) + u16s_be( 0xdfff ), result_type::success );
 
-      verify_rule< utf16_be::one< 0x20 > >( __LINE__, __FILE__, u16s_be( 0x20 ), result_type::success, 0 );
-      verify_rule< utf16_be::one< 0x20ac > >( __LINE__, __FILE__, u16s_be( 0x20ac ), result_type::success, 0 );
-      verify_rule< utf16_be::one< 0x10437 > >( __LINE__, __FILE__, u16s_be( 0xd801 ) + u16s_be( 0xdc37 ), result_type::success, 0 );
+      verify_rule< utf16_be::one< 0x20 > >( __LINE__, __FILE__, u16s_be( 0x20 ), result_type::success );
+      verify_rule< utf16_be::one< 0x20ac > >( __LINE__, __FILE__, u16s_be( 0x20ac ), result_type::success );
+      verify_rule< utf16_be::one< 0x10437 > >( __LINE__, __FILE__, u16s_be( 0xd801 ) + u16s_be( 0xdc37 ), result_type::success );
 
-      verify_rule< utf16_be::bom >( __LINE__, __FILE__, u16s_be( 0xfeff ), result_type::success, 0 );
-      verify_rule< utf16_be::bom >( __LINE__, __FILE__, u16s_be( 0xfffe ), result_type::local_failure, 2 );
+      verify_rule< utf16_be::bom >( __LINE__, __FILE__, u16s_be( 0xfeff ), result_type::success );
+      verify_rule< utf16_be::bom >( __LINE__, __FILE__, u16s_be( 0xfffe ), result_type::local_failure );
 
       verify_rule< utf16_be::string< 0x20, 0x20ac, 0x10437 > >( __LINE__, __FILE__, u16s_be( 0x20 ) + u16s_be( 0x20ac ) + u16s_be( 0xd801 ) + u16s_be( 0xdc37 ) + u16s_be( 0x20 ), result_type::success, 2 );
    }
 
    void test_utf16_le()
    {
-      verify_rule< utf16_le::any >( __LINE__, __FILE__, "", result_type::local_failure, 0 );
-      verify_rule< utf16_le::any >( __LINE__, __FILE__, "\x01", result_type::local_failure, 1 );
-      verify_rule< utf16_le::any >( __LINE__, __FILE__, "\xff", result_type::local_failure, 1 );
-
-      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0 ), result_type::success, 0 );
-      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 1 ), result_type::success, 0 );
-      verify_rule< utf16_le::any >( __LINE__, __FILE__, "  ", result_type::success, 0 );
-      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0x00ff ), result_type::success, 0 );
-      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0x0100 ), result_type::success, 0 );
-      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0x0fff ), result_type::success, 0 );
-      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0x1000 ), result_type::success, 0 );
-      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd800 ), result_type::local_failure, 0 );
-      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd900 ), result_type::local_failure, 0 );
-      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xde00 ), result_type::local_failure, 0 );
+      verify_rule< utf16_le::any >( __LINE__, __FILE__, "", result_type::local_failure );
+      verify_rule< utf16_le::any >( __LINE__, __FILE__, "\x01", result_type::local_failure );
+      verify_rule< utf16_le::any >( __LINE__, __FILE__, "\xff", result_type::local_failure );
+
+      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0 ), result_type::success );
+      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 1 ), result_type::success );
+      verify_rule< utf16_le::any >( __LINE__, __FILE__, "  ", result_type::success );
+      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0x00ff ), result_type::success );
+      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0x0100 ), result_type::success );
+      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0x0fff ), result_type::success );
+      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0x1000 ), result_type::success );
+      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd800 ), result_type::local_failure );
+      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd900 ), result_type::local_failure );
+      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xde00 ), result_type::local_failure );
       verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xfffe ) + " ", result_type::success, 1 );
       verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xffff ) + "  ", result_type::success, 2 );
 
       verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd7ff ) + u16s_le( 0xdfff ), result_type::success, 2 );
-      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xdc00 ) + u16s_le( 0xdfff ), result_type::local_failure, 0 );
-      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd800 ) + u16s_le( 0x0020 ), result_type::local_failure, 0 );
-      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd800 ) + u16s_le( 0xff20 ), result_type::local_failure, 0 );
-      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd800 ) + u16s_le( 0xdf00 ), result_type::success, 0 );
-      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd800 ) + u16s_le( 0xdfff ), result_type::success, 0 );
-      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xdbff ) + u16s_le( 0xdc00 ), result_type::success, 0 );
-      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xdbff ) + u16s_le( 0xdfff ), result_type::success, 0 );
-
-      verify_rule< utf16_le::one< 0x20 > >( __LINE__, __FILE__, u16s_le( 0x20 ), result_type::success, 0 );
-      verify_rule< utf16_le::one< 0x20ac > >( __LINE__, __FILE__, u16s_le( 0x20ac ), result_type::success, 0 );
-      verify_rule< utf16_le::one< 0x10437 > >( __LINE__, __FILE__, u16s_le( 0xd801 ) + u16s_le( 0xdc37 ), result_type::success, 0 );
-
-      verify_rule< utf16_le::bom >( __LINE__, __FILE__, u16s_le( 0xfeff ), result_type::success, 0 );
-      verify_rule< utf16_le::bom >( __LINE__, __FILE__, u16s_le( 0xfffe ), result_type::local_failure, 2 );
+      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xdc00 ) + u16s_le( 0xdfff ), result_type::local_failure );
+      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd800 ) + u16s_le( 0x0020 ), result_type::local_failure );
+      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd800 ) + u16s_le( 0xff20 ), result_type::local_failure );
+      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd800 ) + u16s_le( 0xdf00 ), result_type::success );
+      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd800 ) + u16s_le( 0xdfff ), result_type::success );
+      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xdbff ) + u16s_le( 0xdc00 ), result_type::success );
+      verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xdbff ) + u16s_le( 0xdfff ), result_type::success );
+
+      verify_rule< utf16_le::one< 0x20 > >( __LINE__, __FILE__, u16s_le( 0x20 ), result_type::success );
+      verify_rule< utf16_le::one< 0x20ac > >( __LINE__, __FILE__, u16s_le( 0x20ac ), result_type::success );
+      verify_rule< utf16_le::one< 0x10437 > >( __LINE__, __FILE__, u16s_le( 0xd801 ) + u16s_le( 0xdc37 ), result_type::success );
+
+      verify_rule< utf16_le::bom >( __LINE__, __FILE__, u16s_le( 0xfeff ), result_type::success );
+      verify_rule< utf16_le::bom >( __LINE__, __FILE__, u16s_le( 0xfffe ), result_type::local_failure );
 
       verify_rule< utf16_le::string< 0x20, 0x20ac, 0x10437 > >( __LINE__, __FILE__, u16s_le( 0x20 ) + u16s_le( 0x20ac ) + u16s_le( 0xd801 ) + u16s_le( 0xdc37 ) + u16s_le( 0x20 ), result_type::success, 2 );
    }
diff --git a/packages/PEGTL/src/test/pegtl/verify_rule.hpp b/packages/PEGTL/src/test/pegtl/verify_rule.hpp
index a6a8ef4a8ccc0981739278154d24cb757752746d..e8c516f6c90feeefb859f0d125ba4a99eaa98083 100644
--- a/packages/PEGTL/src/test/pegtl/verify_rule.hpp
+++ b/packages/PEGTL/src/test/pegtl/verify_rule.hpp
@@ -35,9 +35,11 @@ namespace TAO_PEGTL_NAMESPACE
    };
 
    template< typename Rule, typename Eol = eol::lf_crlf >
-   void verify_rule( const std::size_t line, const char* file, const std::string& data, const result_type expected, std::size_t remain = 0 )
+   void verify_rule( const std::size_t line, const char* file, const std::string& data, const result_type expected, int remain = -1 )
    {
-      remain = ( expected == result_type::success ) ? remain : data.size();
+      if( remain < 0 ) {
+         remain = ( expected == result_type::success ) ? 0 : int( data.size() );
+      }
       {
          memory_input< tracking_mode::eager, Eol > in( data.data(), data.data() + data.size(), file, 0, line, 0 );
          verify_impl_one< Rule, nothing >( line, file, data, in, expected, remain );