From 8b800df9a5d6730d42c3969b1c2494f28ac61cdf Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Tue, 10 Apr 2018 20:30:15 +0200
Subject: [PATCH] git subrepo pull packages/CLI11

subrepo:
  subdir:   "packages/CLI11"
  merged:   "df5b157d"
upstream:
  origin:   "git@github.com:CLIUtils/CLI11.git"
  branch:   "master"
  commit:   "df5b157d"
git-subrepo:
  version:  "0.3.1"
  origin:   "git@github.com:ingydotnet/git-subrepo.git"
  commit:   "a7ee886"
---
 packages/CLI11/.github/CONTRIBUTING.md        | 38 +++++++++++-
 packages/CLI11/.gitrepo                       |  4 +-
 packages/CLI11/.travis.yml                    |  5 +-
 packages/CLI11/CHANGELOG.md                   | 13 +++-
 packages/CLI11/CONTRIBUTING.md                | 20 -------
 packages/CLI11/README.md                      | 21 ++++---
 packages/CLI11/examples/CMakeLists.txt        | 60 +++++++++++++++++++
 .../CLI11/examples/inter_argument_order.cpp   | 10 ++--
 packages/CLI11/examples/modhelp.cpp           |  9 ++-
 packages/CLI11/examples/prefix_command.cpp    |  8 +--
 packages/CLI11/examples/simple.cpp            |  2 +-
 .../examples/subcom_in_files/CMakeLists.txt   |  2 +-
 .../{main.cpp => subcommand_main.cpp}         |  0
 packages/CLI11/examples/subcommands.cpp       |  9 ++-
 packages/CLI11/include/CLI/App.hpp            | 14 ++---
 packages/CLI11/include/CLI/Version.hpp        |  4 +-
 .../CLI11/scripts/clang-format-pre-commit     | 30 ++++++++++
 packages/CLI11/tests/AppTest.cpp              | 59 ++++++++++++++++++
 packages/CLI11/tests/HelpTest.cpp             | 16 +++++
 packages/CLI11/tests/SubcommandTest.cpp       | 27 +++++++++
 20 files changed, 286 insertions(+), 65 deletions(-)
 delete mode 100644 packages/CLI11/CONTRIBUTING.md
 rename packages/CLI11/examples/subcom_in_files/{main.cpp => subcommand_main.cpp} (100%)
 create mode 100755 packages/CLI11/scripts/clang-format-pre-commit

diff --git a/packages/CLI11/.github/CONTRIBUTING.md b/packages/CLI11/.github/CONTRIBUTING.md
index 8db2a87a2..c93c400b4 100644
--- a/packages/CLI11/.github/CONTRIBUTING.md
+++ b/packages/CLI11/.github/CONTRIBUTING.md
@@ -1,9 +1,41 @@
-# A few notes on contributions
+Thanks for considering to write a Pull Request (PR) for CLI11! Here are a few guidelines to get you started:
 
-If you want to add code, please make sure it passes the clang-format style (I am using LLVM 4.0):
+Make sure you are comfortable with the license; all contributions are licensed under the original license.
+
+## Adding functionality
+Make sure any new functions you add are are:
+
+* Documented by `///` documentation for Doxygen
+* Mentioned in the instructions in the README, though brief mentions are okay
+* Explained in your PR (or previously explained in an Issue mentioned in the PR)
+* Completely covered by tests
+
+In general, make sure the addition is well thought out and does not increase the complexity of CLI11 needlessly.
+
+## Things you should know:
+
+* Once you make the PR, tests will run to make sure your code works on all supported platforms
+* The test coverage is also measured, and that should remain 100%
+* Formatting should be done with clang-format, otherwise the format check will not pass. However, it is trivial to apply this to your PR, so don't worry about this check. If you do have clang-format, just run `scripts/check_style.sh`
+* Everything must pass clang-tidy as well, run with `-DCLANG_TIDY_FIX-ON` (make sure you use a single threaded build process!)
+
+Note that the style check is really just:
 
 ```bash
 git ls-files -- '.cpp' '.hpp' | xargs clang-format -i -style=file
 ```
 
-It is also a good idea to check this with `clang-tidy`; automatic fixes can be made using `-DCLANG_TIDY_FIX-ON` (resets to `OFF` when rerunning CMake).
+And, if you want to always use it, feel free to install the git hook provided in scripts.
+
+## For developers releasing to Conan.io
+
+The steps to make a Conan.io release are:
+
+```bash
+conan delete '*' # optional, I like to be clean
+
+conan create . cliutils/stable
+conan upload "*" -r cli11 --all
+```
+
+Here I've assumed that the remote is `cli11`.
diff --git a/packages/CLI11/.gitrepo b/packages/CLI11/.gitrepo
index 8e84b44c4..19886d90e 100644
--- a/packages/CLI11/.gitrepo
+++ b/packages/CLI11/.gitrepo
@@ -6,6 +6,6 @@
 [subrepo]
 	remote = git@github.com:CLIUtils/CLI11.git
 	branch = master
-	commit = 4f6bbba3170dc9b1f0c671298e12d8b49c160ce0
-	parent = 4326875f2ca41888cc0384b68d2a90324b7580cc
+	commit = df5b157d97530ed605532e7ed0799fdf6659bbc3
+	parent = 3c3894389721d339e70c9996ab528e8795d3f723
 	cmdver = 0.3.1
diff --git a/packages/CLI11/.travis.yml b/packages/CLI11/.travis.yml
index 872aa39f9..ac8ba7619 100644
--- a/packages/CLI11/.travis.yml
+++ b/packages/CLI11/.travis.yml
@@ -4,9 +4,11 @@ dist: trusty
 
 # Exclude ghpages,
 # but even better, don't build branch and PR, just PR
+# Include tags starting with v and a digit
 branches:
   only:
   - master
+  - /^v\d/
 
 cache:
   ccache: true
@@ -35,7 +37,7 @@ matrix:
     # Docs and clang 3.5
   - compiler: clang
     env:
-    - DEPLOYMAT=yes
+    - DEPLOY_MAT=yes
     addons:
       apt:
         packages:
@@ -145,3 +147,4 @@ env:
   global:
   - secure: cY0OI609iTAxLRYuYQnNMi+H6n0dBwioTAoFXGGRTnngw2V9om3UmY5eUu4HQEQsQZovHdYpNhlSgRmdwQ4UqSp3FGyrwobf0kzacV4bVnMDeXDmHt8RzE5wP/LwDd8elNF6RRYjElY99f0k0FyXVd0fIvuVkGKQECNLOtEk0jQo+4YTh7dhuCxRhBYgTbNiRL6UJynfrcK0YN+DQ+8CJNupu2VxgaEpCSngTfvDHLcddcrXwpvn3MPc3FsDUbtN389ZCIe41qqIL0ATv46DQaTw4FOevyVfRyrBOznONoGCVeAYKL6VBdrk01Fh6aytF5zgI3hKaKobgEn+QFfzR6l68c6APvqA0Qv39iLjuh6KbdIV2YsqXfyt6FBgqP2xZuNEZW1jZ8LxUOLl2I40UEh87nFutvnSbfIzN+FcLrajm2H2jV2kZGNKAMx+4qxkZuXSre4JPkENfJm2WNFAKlqPt4ZSEQarkDYzZPcEr2I9fbGjQYVJICoN4LikCv9K5z7ujpTxCTNbVpQWZcEOT6QQBc6Vml/N/NKAIl9o2OeTLiXCmT31+KQMeO492KYNQ6VmkeqrVhGExOUcJdNyDJV9C+3mSekb3Sq78SneYRKDechkWbMl0ol07wGTdBwQQwgaorjRyn07x1rDxpPr3z19/+eubnpPUW4UQ5MYsjs=
   - secure: G6H5HA9pPUgsd96A+uvTxbLjR1rcT9NtxsknIkFDfzGDpffn6wVX+kCIQLf9zFDnQnsfYA/4piiuoBN5U5C7HQrh9UCvBVptXjWviea0Y7CRbMJZpw2rPvXWQtrFNzYkaV7kdJ5B0Mmvh6rcH/I8gKFrkdjF7i7sfzWdFWRU5QXfxXOk2n+xCXX6uFemxHH9850XEjVtnU7YYUebQFaoTYLLy05nlt9JaEF84wfJljY/SJX7I9gpNLtizE9MpJylnrwUeL66OqFievmjL3/bWpPUBjUF0WdtXYlVDja7O582FQDs94ofgqeGieGIMQ0VuovpbQOJSdjs5XHZwu2ce6HZxtOhJJqw6xEwbq43ZdofAlJ5GUEOgrr+j25zIDkdzOhliDKJtw5ysmmTUKEcZ36iWbCE0YP/IC42yOV9oOP6UkgbuwpVDdxAFRgLZLahW9Ok+c1PlzIauPxv+jIEI4rSEEJRKZG2JK3TXUdhd58mHBfQMNjKQMF+Y2wCCGjfMO0q4SgvBhYyb4oBTxEqnc2Pzh2DJdNzRFsV7ktsQSRglHGVI+1XTmQ+2kbBzNOQBLjOuRvDZENUhyxPKGZDHyAOMlVvYm8vvWebM1/F3YgDb/tPh33+EGSvpKkCZ5nUxB5e605H6gdYlNKNhuWKlEKTo2/kF0D39gAUCIcGbzw=
+  - CCACHE_CPP2: yes
diff --git a/packages/CLI11/CHANGELOG.md b/packages/CLI11/CHANGELOG.md
index f1f52fe82..0262b0e0c 100644
--- a/packages/CLI11/CHANGELOG.md
+++ b/packages/CLI11/CHANGELOG.md
@@ -1,6 +1,13 @@
 ## In progress
 
-This version has some internal cleanup and improved support for the newest compilers.
+* Make unlimited positionals vs. unlimited options more intuitive [#102]
+
+[#102]: https://github.com/CLIUtils/CLI11/issues/102
+
+
+## Version 1.5: Optionals
+
+This version introduced support for optionals, along with clarification and examples of custom conversion overloads. Enums now have been dropped from the automatic conversion system, allowing explicit protection for out-of-range ints (or a completely custom conversion). This version has some internal cleanup and improved support for the newest compilers. Several bugs were fixed, as well.
 
 Note: This is the final release with `requires`, please switch to `needs`.
 
@@ -10,6 +17,7 @@ Note: This is the final release with `requires`, please switch to `needs`.
 * All macros/CMake variables now start with `CLI11_` instead of just `CLI_` [#95]
 * The internal stream was not being cleared before use in some cases. Fixed. [#95]
 * Using an emum now requires explicit conversion overload [#97]
+* The separator `--` now is removed when it ends unlimited arguments [#100]
 
 Other, non-user facing changes:
 
@@ -20,12 +28,15 @@ Other, non-user facing changes:
 * Better single file generation [#95]
 * Added support for GTest on MSVC 2017 (but not in C++17 mode, will need next version of GTest)
 * Types now have a specific size, separate from the expected number - cleaner and more powerful internally [#92]
+* Examples now run as part of testing [#99]
 
 [#64]: https://github.com/CLIUtils/CLI11/issues/64
 [#90]: https://github.com/CLIUtils/CLI11/issues/90
 [#92]: https://github.com/CLIUtils/CLI11/issues/92
 [#95]: https://github.com/CLIUtils/CLI11/pull/95
 [#97]: https://github.com/CLIUtils/CLI11/pull/97
+[#99]: https://github.com/CLIUtils/CLI11/pull/99
+[#100]: https://github.com/CLIUtils/CLI11/pull/100
 
 
 ## Version 1.4: More feedback
diff --git a/packages/CLI11/CONTRIBUTING.md b/packages/CLI11/CONTRIBUTING.md
deleted file mode 100644
index f4a67842a..000000000
--- a/packages/CLI11/CONTRIBUTING.md
+++ /dev/null
@@ -1,20 +0,0 @@
-
-Thanks for considering to write a Pull Request (PR) for CLI11! Here are a few guidelines to get you started:
-
-Make sure you are comfortable with the license; all contributions are licensed under the original license.
-
-## Adding functionality
-Make sure any new functions you add are are:
-
-* Documented by `///` documentation for Doxygen
-* Mentioned in the instructions in the README, though brief mentions are okay
-* Explained in your PR (or previously explained in an Issue mentioned in the PR)
-* Completely covered by tests
-
-In general, make sure the addition is well thought out and does not increase the complexity of CLI11 if possible.
-
-## Things you should know:
-
-* Once you make the PR, tests will run to make sure your code works on all supported platforms
-* The test coverage is also measured, and that should remain 100%
-* Formatting should be done with clang-format, otherwise the format check will not pass. However, it is trivial to apply this to your PR, so don't worry about this check. If you do have clang-format, just run `scripts/check_style.sh`
diff --git a/packages/CLI11/README.md b/packages/CLI11/README.md
index 437208ae9..4fd12b517 100644
--- a/packages/CLI11/README.md
+++ b/packages/CLI11/README.md
@@ -10,7 +10,7 @@
 [Documentation][GitBook] •
 [API Reference][api-docs] •
 [What's new](./CHANGELOG.md) •
-[Try CLI11 1.4 online][wandbox-link]
+[Try CLI11 1.5 online][wandbox-link]
 
 # CLI11: Command line parser for C++11
 
@@ -87,7 +87,9 @@ There are some other possible "features" that are intentionally not supported by
 To use, there are two methods:
 
 1. Copy `CLI11.hpp` from the [most recent release][Github Releases] into your include directory, and you are set. This is combined from the source files  for every release. This includes the entire command parser library, but does not include separate utilities (like `Timer`, `AutoTimer`). The utilities are completely self contained and can be copied separately.
-2. Use `CLI/*.hpp` files. You could check out the repository as a submodule, for example. You can use the `CLI11::CLI11` interface target when linking from `add_subdirectory`. You can also configure and optionally install the project, and then use `find_package(CLI11 CONFIG)` to get the `CLI11::CLI11` target. You can also use [Conan.io][conan-link]. (These are just conveniences to allow you to use your favorite method of managing packages; it's just header only so including the correct path and
+2. Use `CLI/*.hpp` files. You could check out the repository as a submodule, for example. You can use the `CLI11::CLI11` interface target when linking from `add_subdirectory`.
+   You can also configure and optionally install the project, and then use `find_package(CLI11 CONFIG)` to get the `CLI11::CLI11` target. You can also use [Conan.io][conan-link].
+   (These are just conveniences to allow you to use your favorite method of managing packages; it's just header only so including the correct path and
    using C++11 is all you really need.)
 
 To build the tests, checkout the repository and use CMake:
@@ -176,7 +178,7 @@ On a compiler that supports C++17's `__has_include`, you can also use `std::opti
 The add commands return a pointer to an internally stored `Option`. If you set the final argument to true, the default value is captured and printed on the command line with the help flag. This option can be used directly to check for the count (`->count()`) after parsing to avoid a string based lookup. Before parsing, you can set the following options:
 
 * `->required()`: The program will quit if this option is not present. This is `mandatory` in Plumbum, but required options seems to be a more standard term. For compatibility, `->mandatory()` also works.
-* `->expected(N)`: Take `N` values instead of as many as possible, only for vector args. If negative, require at least `-N`.
+* `->expected(N)`: Take `N` values instead of as many as possible, only for vector args. If negative, require at least `-N`; end with `--` or another recognized option.
 * `->needs(opt)`: This option requires another option to also be present, opt is an `Option` pointer.
 * `->excludes(opt)`: This option cannot be given with `opt` present, opt is an `Option` pointer.
 * `->envname(name)`: Gets the value from the environment if present and not passed on the command line.
@@ -209,7 +211,7 @@ Extra positional arguments will cause the program to exit, so at least one posit
 If you set `.allow_extras()` on the main `App`, you will not get an error. You can access the missing options using `remaining` (if you have subcommands, `app.remaining(true)` will get all remaining options, subcommands included).
 
 You can access a vector of pointers to the parsed options in the original order using `parse_order()`.
-If `--` is present in the command line,
+If `--` is present in the command line that does not end an unlimited option, then
 everything after that is positional only.
 
 
@@ -241,7 +243,7 @@ There are several options that are supported on the main app and subcommands. Th
 * `.add_subcommand(name, description="")` Add a subcommand, returns a pointer to the internally stored subcommand.
 * `.got_subcommand(App_or_name)`: Check to see if a subcommand was received on the command line
 * `.get_subcommands()`: The list of subcommands given on the command line
-* `.get_parent()`: Get the parent App or nullptr if called on master App **Coming in version 1.4**
+* `.get_parent()`: Get the parent App or nullptr if called on master App
 * `.parsed()`: True if this subcommand was given on the command line
 * `.set_callback(void() function)`: Set the callback that runs at the end of parsing. The options have already run at this point.
 * `.allow_extras()`: Do not throw an error if extra arguments are left over
@@ -388,7 +390,8 @@ Significant features and/or improvements to the code were contributed by:
 * [Lucas Czech](https://github.com/lczech)
 * [Mathias Soeken](https://github.com/msoeken)
 * [Nathan Hourt](https://github.com/nathanhourt)
-
+* [Stéphane Del Pino](https://github.com/delpinux)
+* [Anton](https://github.com/SX91)
 
 CLI11 was developed at the [University of Cincinnati] to support of the [GooFit] library under [NSF Award 1414736]. Version 0.9 was featured in a [DIANA/HEP] meeting at CERN ([see the slides][DIANA slides]). Please give it a try! Feedback is always welcome.
 
@@ -404,8 +407,8 @@ CLI11 was developed at the [University of Cincinnati] to support of the [GooFit]
 [gitter-badge]:          https://badges.gitter.im/CLI11gitter/Lobby.svg
 [gitter]:                https://gitter.im/CLI11gitter/Lobby
 [license-badge]:         https://img.shields.io/badge/License-BSD-blue.svg
-[conan-badge]:           https://api.bintray.com/packages/cliutils/CLI11/CLI11/images/download.svg
-[conan-link]:            https://bintray.com/cliutils/CLI11/CLI11/_latestVersion
+[conan-badge]:           https://api.bintray.com/packages/cliutils/CLI11/CLI11%3Acliutils/images/download.svg
+[conan-link]:            https://bintray.com/cliutils/CLI11/CLI11%3Acliutils/_latestVersion
 [Github Releases]:       https://github.com/CLIUtils/CLI11/releases
 [Github Issues]:         https://github.com/CLIUtils/CLI11/issues
 [Github Pull Requests]:  https://github.com/CLIUtils/CLI11/pulls
@@ -438,7 +441,7 @@ CLI11 was developed at the [University of Cincinnati] to support of the [GooFit]
 [Version 1.0 post]:      https://iscinumpy.gitlab.io/post/announcing-cli11-10/
 [Version 1.3 post]:      https://iscinumpy.gitlab.io/post/announcing-cli11-13/
 [wandbox-online]:        https://img.shields.io/badge/try%20it-online-orange.svg
-[wandbox-link]:          https://wandbox.org/permlink/g7tRkuU8xY3aTIVP
+[wandbox-link]:          https://wandbox.org/permlink/3a2C5qg6vUjSSpr7
 [releases-badge]:        https://img.shields.io/github/release/CLIUtils/CLI11.svg
 [cli11-po-compare]:      https://iscinumpy.gitlab.io/post/comparing-cli11-and-boostpo/
 [DIANA slides]:          https://indico.cern.ch/event/619465/contributions/2507949/attachments/1448567/2232649/20170424-diana-2.pdf
diff --git a/packages/CLI11/examples/CMakeLists.txt b/packages/CLI11/examples/CMakeLists.txt
index 8c2f13b3c..c6851229d 100644
--- a/packages/CLI11/examples/CMakeLists.txt
+++ b/packages/CLI11/examples/CMakeLists.txt
@@ -15,11 +15,71 @@ function(add_cli_exe T)
 endfunction()
 
 add_cli_exe(simple simple.cpp)
+add_test(NAME simple_basic COMMAND simple)
+add_test(NAME simple_all COMMAND simple -f filename.txt -c 12 --flag --flag -d 1.2)
+set_property(TEST simple_all PROPERTY PASS_REGULAR_EXPRESSION
+    "Working on file: filename.txt, direct count: 1, opt count: 1"
+    "Working on count: 12, direct count: 1, opt count: 1"
+    "Received flag: 2 (2) times"
+    "Some value: 1.2")
+
+
 add_cli_exe(subcommands subcommands.cpp)
+add_test(NAME subcommands_none COMMAND subcommands)
+set_property(TEST subcommands_none PROPERTY
+    PASS_REGULAR_EXPRESSION "A subcommand is required")
+add_test(NAME subcommands_all COMMAND subcommands --random start --file name stop --count)
+set_property(TEST subcommands_all PROPERTY PASS_REGULAR_EXPRESSION
+    "Working on --file from start: name"
+    "Working on --count from stop: 1, direct count: 1"
+    "Count of --random flag: 1"
+    "Subcommand: start"
+    "Subcommand: stop")
+
 add_cli_exe(groups groups.cpp)
+add_test(NAME groups_none COMMAND groups)
+set_property(TEST groups_none PROPERTY PASS_REGULAR_EXPRESSION
+    "This is a timer:"
+    "--file is required"
+    "Run with --help for more information.")
+add_test(NAME groups_all COMMAND groups --file this --count --count -d 1.2)
+set_property(TEST groups_all PROPERTY PASS_REGULAR_EXPRESSION
+    "This is a timer:"
+    "Working on file: this, direct count: 1, opt count: 1"
+    "Working on count: 2, direct count: 2, opt count: 2"
+    "Some value: 1.2")
+
 add_cli_exe(inter_argument_order inter_argument_order.cpp)
+add_test(NAME inter_argument_order COMMAND inter_argument_order --foo 1 2 3 --x --bar 4 5 6 --z --foo 7 8)
+set_property(TEST inter_argument_order PROPERTY PASS_REGULAR_EXPRESSION
+    [=[foo : 1
+foo : 2
+foo : 3
+bar : 4
+bar : 5
+bar : 6
+foo : 7
+foo : 8]=])
+
 add_cli_exe(prefix_command prefix_command.cpp)
+add_test(NAME prefix_command COMMAND prefix_command -v 3 2 1 -- other one two 3)
+set_property(TEST prefix_command PROPERTY PASS_REGULAR_EXPRESSION
+    "Prefix: 3 : 2 : 1"
+    "Remaining commands: other one two 3")
+
 add_cli_exe(enum enum.cpp)
+add_test(NAME enum_pass COMMAND enum -l 1)
+add_test(NAME enum_fail COMMAND enum -l 4)
+set_property(TEST enum_fail PROPERTY PASS_REGULAR_EXPRESSION
+    "Could not convert: -l,--level = 4")
+
 add_cli_exe(modhelp modhelp.cpp)
+add_test(NAME modhelp COMMAND modhelp -a test -h)
+set_property(TEST modhelp PROPERTY PASS_REGULAR_EXPRESSION
+    "Option -a string in help: test")
 
 add_subdirectory(subcom_in_files)
+add_test(NAME subcom_in_files COMMAND subcommand_main subcommand_a -f this.txt --with-foo)
+set_property(TEST subcom_in_files PROPERTY PASS_REGULAR_EXPRESSION
+    "Working on file: this\.txt"
+    "Using foo!")
diff --git a/packages/CLI11/examples/inter_argument_order.cpp b/packages/CLI11/examples/inter_argument_order.cpp
index 6609fd8be..9e3c246b9 100644
--- a/packages/CLI11/examples/inter_argument_order.cpp
+++ b/packages/CLI11/examples/inter_argument_order.cpp
@@ -5,15 +5,15 @@
 #include <algorithm>
 
 int main(int argc, char **argv) {
-    CLI::App app;
+    CLI::App app{"An app to practice mixing unlimited arguments, but still recover the original order."};
 
     std::vector<int> foos;
-    auto foo = app.add_option("--foo,-f", foos);
+    auto foo = app.add_option("--foo,-f", foos, "Some unlimited argument");
 
     std::vector<int> bars;
-    auto bar = app.add_option("--bar", bars);
+    auto bar = app.add_option("--bar", bars, "Some unlimited arggument");
 
-    app.add_flag("--z,--x"); // Random other flags
+    app.add_flag("--z,--x", "Random other flags");
 
     // Standard parsing lines (copy and paste in, or use CLI11_PARSE)
     try {
@@ -22,7 +22,7 @@ int main(int argc, char **argv) {
         return app.exit(e);
     }
 
-    // I perfer using the back and popping
+    // I prefer using the back and popping
     std::reverse(std::begin(foos), std::end(foos));
     std::reverse(std::begin(bars), std::end(bars));
 
diff --git a/packages/CLI11/examples/modhelp.cpp b/packages/CLI11/examples/modhelp.cpp
index 7533bf69c..a2568322a 100644
--- a/packages/CLI11/examples/modhelp.cpp
+++ b/packages/CLI11/examples/modhelp.cpp
@@ -1,12 +1,11 @@
-// Modify the help print so that argument values are accessible
-// Note that this will not shortcut `->required` and other similar options
 
 #include "CLI/CLI.hpp"
 
 #include <iostream>
 
 int main(int argc, char **argv) {
-    CLI::App test;
+    CLI::App test{R"raw(Modify the help print so that argument values are accessible.
+Note that this will not shortcut `->required` and other similar options.)raw"};
 
     // Remove help flag because it shortcuts all processing
     test.set_help_flag();
@@ -22,10 +21,10 @@ int main(int argc, char **argv) {
         if(*help)
             throw CLI::CallForHelp();
     } catch(const CLI::Error &e) {
-        std::cout << "Option string:" << some_option << std::endl;
+        std::cout << "Option -a string in help: " << some_option << std::endl;
         return test.exit(e);
     }
 
-    std::cout << "Option string:" << some_option << std::endl;
+    std::cout << "Option -a string: " << some_option << std::endl;
     return 0;
 }
diff --git a/packages/CLI11/examples/prefix_command.cpp b/packages/CLI11/examples/prefix_command.cpp
index 3a3a6f092..edd7a0d68 100644
--- a/packages/CLI11/examples/prefix_command.cpp
+++ b/packages/CLI11/examples/prefix_command.cpp
@@ -6,20 +6,18 @@ int main(int argc, char **argv) {
     app.prefix_command();
 
     std::vector<int> vals;
-    app.add_option("--vals,-v", vals)->expected(1);
+    app.add_option("--vals,-v", vals)->expected(-1);
 
     CLI11_PARSE(app, argc, argv);
 
     std::vector<std::string> more_comms = app.remaining();
 
-    std::cout << "Prefix:";
+    std::cout << "Prefix";
     for(int v : vals)
-        std::cout << v << ":";
+        std::cout << ": " << v << " ";
 
     std::cout << std::endl << "Remaining commands: ";
 
-    // Perfer to loop over from beginning, not "pop" order
-    std::reverse(std::begin(more_comms), std::end(more_comms));
     for(auto com : more_comms)
         std::cout << com << " ";
     std::cout << std::endl;
diff --git a/packages/CLI11/examples/simple.cpp b/packages/CLI11/examples/simple.cpp
index 612fd9e02..d1ae4716b 100644
--- a/packages/CLI11/examples/simple.cpp
+++ b/packages/CLI11/examples/simple.cpp
@@ -22,7 +22,7 @@ int main(int argc, char **argv) {
               << ", opt count: " << opt->count() << std::endl;
     std::cout << "Working on count: " << count << ", direct count: " << app.count("--count")
               << ", opt count: " << copt->count() << std::endl;
-    std::cout << "Recieved flag: " << v << " (" << flag->count() << ") times\n";
+    std::cout << "Received flag: " << v << " (" << flag->count() << ") times\n";
     std::cout << "Some value: " << value << std::endl;
 
     return 0;
diff --git a/packages/CLI11/examples/subcom_in_files/CMakeLists.txt b/packages/CLI11/examples/subcom_in_files/CMakeLists.txt
index be283a6bd..74ba5dd32 100644
--- a/packages/CLI11/examples/subcom_in_files/CMakeLists.txt
+++ b/packages/CLI11/examples/subcom_in_files/CMakeLists.txt
@@ -1 +1 @@
-add_cli_exe(main main.cpp subcommand_a.cpp subcommand_a.hpp)
+add_cli_exe(subcommand_main subcommand_main.cpp subcommand_a.cpp subcommand_a.hpp)
diff --git a/packages/CLI11/examples/subcom_in_files/main.cpp b/packages/CLI11/examples/subcom_in_files/subcommand_main.cpp
similarity index 100%
rename from packages/CLI11/examples/subcom_in_files/main.cpp
rename to packages/CLI11/examples/subcom_in_files/subcommand_main.cpp
diff --git a/packages/CLI11/examples/subcommands.cpp b/packages/CLI11/examples/subcommands.cpp
index a28b2aac2..8872d3fcd 100644
--- a/packages/CLI11/examples/subcommands.cpp
+++ b/packages/CLI11/examples/subcommands.cpp
@@ -6,6 +6,7 @@ int main(int argc, char **argv) {
     app.add_flag("--random", "Some random flag");
     CLI::App *start = app.add_subcommand("start", "A great subcommand");
     CLI::App *stop = app.add_subcommand("stop", "Do you really want to stop?");
+    app.require_subcommand(); // 1 or more
 
     std::string file;
     start->add_option("-f,--file", file, "File name");
@@ -14,10 +15,12 @@ int main(int argc, char **argv) {
 
     CLI11_PARSE(app, argc, argv);
 
-    std::cout << "Working on file: " << file << ", direct count: " << start->count("--file") << std::endl;
-    std::cout << "Working on count: " << s->count() << ", direct count: " << stop->count("--count") << std::endl;
+    std::cout << "Working on --file from start: " << file << std::endl;
+    std::cout << "Working on --count from stop: " << s->count() << ", direct count: " << stop->count("--count")
+              << std::endl;
+    std::cout << "Count of --random flag: " << app.count("--random") << std::endl;
     for(auto subcom : app.get_subcommands())
-        std::cout << "Subcommand:" << subcom->get_name() << std::endl;
+        std::cout << "Subcommand: " << subcom->get_name() << std::endl;
 
     return 0;
 }
diff --git a/packages/CLI11/include/CLI/App.hpp b/packages/CLI11/include/CLI/App.hpp
index 543b85a19..e2c239194 100644
--- a/packages/CLI11/include/CLI/App.hpp
+++ b/packages/CLI11/include/CLI/App.hpp
@@ -1035,12 +1035,14 @@ class App {
     /// This gets a vector of pointers with the original parse order
     const std::vector<Option *> &parse_order() const { return parse_order_; }
 
-    /// This retuns the missing options from the current subcommand
+    /// This returns the missing options from the current subcommand
     std::vector<std::string> remaining(bool recurse = false) const {
         std::vector<std::string> miss_list;
         for(const std::pair<detail::Classifer, std::string> &miss : missing_) {
             miss_list.push_back(std::get<1>(miss));
         }
+
+        // Recurse into subcommands
         if(recurse) {
             for(const App *sub : parsed_subcommands_) {
                 std::vector<std::string> output = sub->remaining(recurse);
@@ -1459,12 +1461,6 @@ class App {
                     // If any positionals remain, don't keep eating
                     if(_count_remaining_positionals() > 0)
                         break;
-
-                    // If there are any unlimited positionals, those also take priority
-                    if(std::any_of(std::begin(options_), std::end(options_), [](const Option_p &opt) {
-                           return opt->get_positional() && opt->get_items_expected() < 0;
-                       }))
-                        break;
                 }
                 op->add_result(args.back());
                 parse_order_.push_back(op.get());
@@ -1472,6 +1468,10 @@ class App {
                 collected++;
             }
 
+            // Allow -- to end an unlimited list and "eat" it
+            if(!args.empty() && _recognize(args.back()) == detail::Classifer::POSITIONAL_MARK)
+                args.pop_back();
+
         } else {
             while(num > 0 && !args.empty()) {
                 num--;
diff --git a/packages/CLI11/include/CLI/Version.hpp b/packages/CLI11/include/CLI/Version.hpp
index 40abb162f..009b3f875 100644
--- a/packages/CLI11/include/CLI/Version.hpp
+++ b/packages/CLI11/include/CLI/Version.hpp
@@ -8,8 +8,8 @@ namespace CLI {
 // Note that all code in CLI11 must be in a namespace, even if it just a define.
 
 #define CLI11_VERSION_MAJOR 1
-#define CLI11_VERSION_MINOR 4
+#define CLI11_VERSION_MINOR 5
 #define CLI11_VERSION_PATCH 0
-#define CLI11_VERSION "1.4.0"
+#define CLI11_VERSION "1.5.0"
 
 } // namespace CLI
diff --git a/packages/CLI11/scripts/clang-format-pre-commit b/packages/CLI11/scripts/clang-format-pre-commit
new file mode 100755
index 000000000..822becb06
--- /dev/null
+++ b/packages/CLI11/scripts/clang-format-pre-commit
@@ -0,0 +1,30 @@
+#!/usr/bin/env bash
+
+# To use:
+# ln -s scripts/clang-format.hook .git/hooks/pre-commit
+
+# Based loosely on https://github.com/andrewseidl/githook-clang-format
+
+format_file() {
+    file="${1}"
+    case "$file" in
+    *.hpp | *.cpp | .c | *.cc | *.cu | *.h )
+        echo "Fixing: $file"
+        clang-format -i -style=file "${1}"
+        git add "${1}"
+        ;;
+    *)
+        ;;
+    esac
+}
+
+case "${1}" in
+  --about )
+    echo "Runs clang-format on source files"
+    ;;
+  * )
+    for file in `git diff-index --cached --name-only HEAD` ; do
+      format_file "${file}"
+    done
+    ;;
+esac
diff --git a/packages/CLI11/tests/AppTest.cpp b/packages/CLI11/tests/AppTest.cpp
index 0b1c24164..5b1e0d925 100644
--- a/packages/CLI11/tests/AppTest.cpp
+++ b/packages/CLI11/tests/AppTest.cpp
@@ -542,9 +542,23 @@ TEST_F(TApp, RequiredOptsUnlimited) {
     app.allow_extras(false);
     std::vector<std::string> remain;
     app.add_option("positional", remain);
+    run();
+    EXPECT_EQ(strs, std::vector<std::string>({"one", "two"}));
+    EXPECT_EQ(remain, std::vector<std::string>());
+
+    app.reset();
+    args = {"--str", "one", "--", "two"};
+
     run();
     EXPECT_EQ(strs, std::vector<std::string>({"one"}));
     EXPECT_EQ(remain, std::vector<std::string>({"two"}));
+
+    app.reset();
+    args = {"one", "--str", "two"};
+
+    run();
+    EXPECT_EQ(strs, std::vector<std::string>({"two"}));
+    EXPECT_EQ(remain, std::vector<std::string>({"one"}));
 }
 
 TEST_F(TApp, RequiredOptsUnlimitedShort) {
@@ -576,9 +590,36 @@ TEST_F(TApp, RequiredOptsUnlimitedShort) {
     app.allow_extras(false);
     std::vector<std::string> remain;
     app.add_option("positional", remain);
+    run();
+    EXPECT_EQ(strs, std::vector<std::string>({"one", "two"}));
+    EXPECT_EQ(remain, std::vector<std::string>());
+
+    app.reset();
+    args = {"-s", "one", "--", "two"};
+
     run();
     EXPECT_EQ(strs, std::vector<std::string>({"one"}));
     EXPECT_EQ(remain, std::vector<std::string>({"two"}));
+
+    app.reset();
+    args = {"one", "-s", "two"};
+
+    run();
+    EXPECT_EQ(strs, std::vector<std::string>({"two"}));
+    EXPECT_EQ(remain, std::vector<std::string>({"one"}));
+}
+
+TEST_F(TApp, OptsUnlimitedEnd) {
+    std::vector<std::string> strs;
+    app.add_option("-s,--str", strs);
+    app.allow_extras();
+
+    args = {"one", "-s", "two", "three", "--", "four"};
+
+    run();
+
+    EXPECT_EQ(strs, std::vector<std::string>({"two", "three"}));
+    EXPECT_EQ(app.remaining(), std::vector<std::string>({"one", "four"}));
 }
 
 TEST_F(TApp, RequireOptPriority) {
@@ -1458,3 +1499,21 @@ TEST_F(TApp, ThrowingTransform) {
         EXPECT_EQ(e.what(), std::string("--mess: My Message"));
     }
 }
+
+// #87
+TEST_F(TApp, CustomDoubleOption) {
+
+    std::pair<int, double> custom_opt;
+
+    auto opt = app.add_option("posit", [&custom_opt](CLI::results_t vals) {
+        custom_opt = {stol(vals.at(0)), stod(vals.at(1))};
+        return true;
+    });
+    opt->set_custom_option("INT FLOAT", 2);
+
+    args = {"12", "1.5"};
+
+    run();
+    EXPECT_EQ(custom_opt.first, 12);
+    EXPECT_DOUBLE_EQ(custom_opt.second, 1.5);
+}
diff --git a/packages/CLI11/tests/HelpTest.cpp b/packages/CLI11/tests/HelpTest.cpp
index 52b566afb..8ac69a832 100644
--- a/packages/CLI11/tests/HelpTest.cpp
+++ b/packages/CLI11/tests/HelpTest.cpp
@@ -461,3 +461,19 @@ TEST_F(CapturedHelp, RepacedError) {
     EXPECT_THAT(err.str(), HasSubstr("Thing"));
     EXPECT_THAT(err.str(), HasSubstr("Usage"));
 }
+
+// #87
+TEST(THelp, CustomDoubleOption) {
+
+    std::pair<int, double> custom_opt;
+
+    CLI::App app;
+
+    auto opt = app.add_option("posit", [&custom_opt](CLI::results_t vals) {
+        custom_opt = {stol(vals.at(0)), stod(vals.at(1))};
+        return true;
+    });
+    opt->set_custom_option("INT FLOAT", 2);
+
+    EXPECT_THAT(app.help(), Not(HasSubstr("x 2")));
+}
diff --git a/packages/CLI11/tests/SubcommandTest.cpp b/packages/CLI11/tests/SubcommandTest.cpp
index 5f163f23d..84fa0ad2d 100644
--- a/packages/CLI11/tests/SubcommandTest.cpp
+++ b/packages/CLI11/tests/SubcommandTest.cpp
@@ -407,6 +407,33 @@ TEST_F(TApp, PrefixProgram) {
     EXPECT_EQ(app.remaining(), std::vector<std::string>({"other", "--simple", "--mine"}));
 }
 
+TEST_F(TApp, PrefixNoSeparation) {
+
+    app.prefix_command();
+
+    std::vector<int> vals;
+    app.add_option("--vals", vals);
+
+    args = {"--vals", "1", "2", "3", "other"};
+
+    EXPECT_THROW(run(), CLI::ConversionError);
+}
+
+TEST_F(TApp, PrefixSeparation) {
+
+    app.prefix_command();
+
+    std::vector<int> vals;
+    app.add_option("--vals", vals);
+
+    args = {"--vals", "1", "2", "3", "--", "other"};
+
+    run();
+
+    EXPECT_EQ(app.remaining(), std::vector<std::string>({"other"}));
+    EXPECT_EQ(vals, std::vector<int>({1, 2, 3}));
+}
+
 TEST_F(TApp, PrefixSubcom) {
     auto subc = app.add_subcommand("subc");
     subc->prefix_command();
-- 
GitLab