diff --git a/shim/sl/canonical/DriverOptions.cpp b/shim/sl/canonical/DriverOptions.cpp
index 5c73edf..b23dd06 100644
--- a/shim/sl/canonical/DriverOptions.cpp
+++ b/shim/sl/canonical/DriverOptions.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2022 Arm Ltd and Contributors. All rights reserved.
+// Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -106,7 +106,7 @@
     string optionsAsString(rawEnv);
     regex whiteSpaceRegex("\\s+");
     // Tokienize the string based on whitespace.
-    sregex_token_iterator iter(optionsAsString.begin(), optionsAsString.end(), whiteSpaceRegex, -1);  
+    sregex_token_iterator iter(optionsAsString.begin(), optionsAsString.end(), whiteSpaceRegex, -1);
     sregex_token_iterator end;
     vector<string> cliAsVector(iter, end);
     // As we're pretending to be a command line, argv[0] should be an executable name.
@@ -216,7 +216,7 @@
     {
         cxxopts::ParseResult result = optionsDesc.parse(argc, argv);
     }
-    catch (const cxxopts::OptionException& e)
+    catch (const cxxopts::exceptions::exception& e)
     {
         VLOG(DRIVER) << "An exception occurred attempting to parse program options: " << e.what();
         std::cout << optionsDesc.help() << std::endl
diff --git a/src/armnnConverter/ArmnnConverter.cpp b/src/armnnConverter/ArmnnConverter.cpp
index c1190d8..0129204 100644
--- a/src/armnnConverter/ArmnnConverter.cpp
+++ b/src/armnnConverter/ArmnnConverter.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017, 2023 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 #include <armnn/Logging.hpp>
@@ -151,7 +151,7 @@
             return EXIT_FAILURE;
         }
     }
-    catch (const cxxopts::OptionException& e)
+    catch (const cxxopts::exceptions::exception& e)
     {
         std::cerr << e.what() << std::endl << std::endl;
         return EXIT_FAILURE;
diff --git a/tests/ExecuteNetwork/ExecuteNetworkProgramOptions.cpp b/tests/ExecuteNetwork/ExecuteNetworkProgramOptions.cpp
index 007f818..3a54b1a 100644
--- a/tests/ExecuteNetwork/ExecuteNetworkProgramOptions.cpp
+++ b/tests/ExecuteNetwork/ExecuteNetworkProgramOptions.cpp
@@ -34,7 +34,7 @@
     // Check that the given options are valid.
     if (option == nullptr || required == nullptr)
     {
-        throw cxxopts::OptionParseException("Invalid option to check dependency for");
+        throw cxxopts::exceptions::exception("Invalid option to check dependency for");
     }
 
     // Check that if 'option' is provided, 'required' is also provided.
@@ -42,7 +42,7 @@
     {
         if (CheckOption(result, required) == 0 || result[required].has_default())
         {
-            throw cxxopts::OptionParseException(
+            throw cxxopts::exceptions::exception(
                     std::string("Option '") + option + "' requires option '" + required + "'.");
         }
     }
@@ -514,7 +514,7 @@
          m_ExNetParams.m_OutputDetailsOnlyToStdOut) &&
         !m_ExNetParams.m_EnableProfiling)
     {
-        throw cxxopts::OptionParseException("You must enable profiling if you would like to output layer details");
+        throw cxxopts::exceptions::exception("You must enable profiling if you would like to output layer details");
     }
 
     // Some options can't be assigned directly because they need some post-processing:
@@ -617,4 +617,3 @@
         m_ExNetParams.m_ComparisonComputeDevices = GetBackendIDs(comparisonComputDevices);
     }
 }
-
diff --git a/tests/ImageCSVFileGenerator/ImageCSVFileGenerator.cpp b/tests/ImageCSVFileGenerator/ImageCSVFileGenerator.cpp
index a949da3..46aad43 100644
--- a/tests/ImageCSVFileGenerator/ImageCSVFileGenerator.cpp
+++ b/tests/ImageCSVFileGenerator/ImageCSVFileGenerator.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017, 2023 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -167,7 +167,7 @@
                 return false;
             }
         }
-        catch (const cxxopts::OptionException& e)
+        catch (const cxxopts::exceptions::exception& e)
         {
             std::cerr << e.what() << std::endl << std::endl;
             return false;
@@ -249,4 +249,4 @@
     }
 
     return 0;
-}
\ No newline at end of file
+}
diff --git a/tests/ImageTensorGenerator/ImageTensorGenerator.cpp b/tests/ImageTensorGenerator/ImageTensorGenerator.cpp
index d4a2103..6e5b8ca 100644
--- a/tests/ImageTensorGenerator/ImageTensorGenerator.cpp
+++ b/tests/ImageTensorGenerator/ImageTensorGenerator.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017, 2023 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -205,7 +205,7 @@
                 return false;
             }
         }
-        catch (const cxxopts::OptionException& e)
+        catch (const cxxopts::exceptions::exception& e)
         {
             std::cerr << e.what() << std::endl << std::endl;
             return false;
diff --git a/tests/InferenceTest.cpp b/tests/InferenceTest.cpp
index 01b8983..9949e06 100644
--- a/tests/InferenceTest.cpp
+++ b/tests/InferenceTest.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017, 2023 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 #include "InferenceTest.hpp"
@@ -61,7 +61,7 @@
         CheckRequiredOptions(result, required);
 
     }
-    catch (const cxxopts::OptionException& e)
+    catch (const cxxopts::exceptions::exception& e)
     {
         std::cerr << e.what() << std::endl << options.help() << std::endl;
         return false;
diff --git a/tests/InferenceTest.hpp b/tests/InferenceTest.hpp
index fb9c048..f8a7d5e 100644
--- a/tests/InferenceTest.hpp
+++ b/tests/InferenceTest.hpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017, 2023 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 #pragma once
@@ -28,7 +28,7 @@
     if (compute == armnn::Compute::Undefined)
     {
         in.setstate(std::ios_base::failbit);
-        throw cxxopts::OptionException(fmt::format("Unrecognised compute device: {}", token));
+        throw cxxopts::exceptions::exception(fmt::format("Unrecognised compute device: {}", token));
     }
     return in;
 }
@@ -41,7 +41,7 @@
     if (compute == armnn::Compute::Undefined)
     {
         in.setstate(std::ios_base::failbit);
-        throw cxxopts::OptionException(fmt::format("Unrecognised compute device: {}", token));
+        throw cxxopts::exceptions::exception(fmt::format("Unrecognised compute device: {}", token));
     }
     backend = compute;
     return in;
diff --git a/tests/ModelAccuracyTool-Armnn/ModelAccuracyTool-Armnn.cpp b/tests/ModelAccuracyTool-Armnn/ModelAccuracyTool-Armnn.cpp
index 9e5507b..b2fd5cb 100644
--- a/tests/ModelAccuracyTool-Armnn/ModelAccuracyTool-Armnn.cpp
+++ b/tests/ModelAccuracyTool-Armnn/ModelAccuracyTool-Armnn.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017, 2023 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -131,7 +131,7 @@
                 }
             }
         }
-        catch (const cxxopts::OptionException& e)
+        catch (const cxxopts::exceptions::exception& e)
         {
             std::cerr << e.what() << std::endl << std::endl;
             return EXIT_FAILURE;
@@ -498,4 +498,4 @@
         modelOutputLabels.push_back(predictionCategoryNames);
     }
     return modelOutputLabels;
-}
\ No newline at end of file
+}
diff --git a/tests/MultipleNetworksCifar10/MultipleNetworksCifar10.cpp b/tests/MultipleNetworksCifar10/MultipleNetworksCifar10.cpp
index 133b8d8..823cbbc 100644
--- a/tests/MultipleNetworksCifar10/MultipleNetworksCifar10.cpp
+++ b/tests/MultipleNetworksCifar10/MultipleNetworksCifar10.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017, 2023 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -83,7 +83,7 @@
                 }
             }
         }
-        catch (const cxxopts::OptionException& e)
+        catch (const cxxopts::exceptions::exception& e)
         {
             std::cerr << e.what() << std::endl << in_options.help() << std::endl;
             return EXIT_FAILURE;
diff --git a/tests/TfLiteMobilenetQuantized-Armnn/TfLiteMobilenetQuantized-Armnn.cpp b/tests/TfLiteMobilenetQuantized-Armnn/TfLiteMobilenetQuantized-Armnn.cpp
index 56b145d..e554111 100644
--- a/tests/TfLiteMobilenetQuantized-Armnn/TfLiteMobilenetQuantized-Armnn.cpp
+++ b/tests/TfLiteMobilenetQuantized-Armnn/TfLiteMobilenetQuantized-Armnn.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017, 2023 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 #include "../InferenceTest.hpp"
@@ -76,7 +76,7 @@
 
         auto result = options.parse(argc, argv);
     }
-    catch (const cxxopts::OptionException& e)
+    catch (const cxxopts::exceptions::exception& e)
     {
         std::cerr << e.what() << std::endl;
         exit(EXIT_FAILURE);
diff --git a/tests/TfLiteYoloV3Big-Armnn/TfLiteYoloV3Big-Armnn.cpp b/tests/TfLiteYoloV3Big-Armnn/TfLiteYoloV3Big-Armnn.cpp
index 3ecd160..355fa25 100644
--- a/tests/TfLiteYoloV3Big-Armnn/TfLiteYoloV3Big-Armnn.cpp
+++ b/tests/TfLiteYoloV3Big-Armnn/TfLiteYoloV3Big-Armnn.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2020 Arm Ltd. All rights reserved.
+// Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -417,7 +417,7 @@
             {
                 std::stringstream ss;
                 ss << "Argument given to" << argName << "is not a valid file path";
-                throw cxxopts::option_syntax_exception(ss.str().c_str());
+                throw cxxopts::exceptions::invalid_option_syntax(ss.str().c_str());
             }
             return path;
         }
@@ -428,7 +428,7 @@
                 return "";
             }
 
-            throw cxxopts::missing_argument_exception(argName);
+            throw cxxopts::exceptions::missing_argument(argName);
         }
     }
 
@@ -440,7 +440,7 @@
             {
                 return std::vector<std::string>();
             }
-            throw cxxopts::option_syntax_exception("Comparison files requires 5 file paths.");
+            throw cxxopts::exceptions::invalid_option_syntax("Comparison files requires 5 file paths.");
         }
 
         std::vector<std::string> filePaths;
@@ -449,7 +449,8 @@
             filePaths.push_back(path);
             if (!ValidateFilePath(filePaths.back(), ExpectFile::True))
             {
-                throw cxxopts::option_syntax_exception("Argument given to Comparison Files is not a valid file path");
+                throw cxxopts::exceptions::invalid_option_syntax(
+                    "Argument given to Comparison Files is not a valid file path");
             }
         }
         return filePaths;
diff --git a/tests/profiling/gatordmock/CommandLineProcessor.cpp b/tests/profiling/gatordmock/CommandLineProcessor.cpp
index c1b6a6b..a532401 100644
--- a/tests/profiling/gatordmock/CommandLineProcessor.cpp
+++ b/tests/profiling/gatordmock/CommandLineProcessor.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
+// Copyright © 2019, 2023 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -63,7 +63,7 @@
             m_Echo = true;
         }
     }
-    catch (const cxxopts::OptionException& e)
+    catch (const cxxopts::exceptions::exception& e)
     {
         std::cerr << e.what() << std::endl;
         return false;
@@ -74,4 +74,4 @@
 
 } // namespace gatordmock
 
-} // namespace armnn
\ No newline at end of file
+} // namespace armnn
diff --git a/third-party/cxxopts/CHANGELOG.md b/third-party/cxxopts/CHANGELOG.md
index df0e110..782f4d0 100644
--- a/third-party/cxxopts/CHANGELOG.md
+++ b/third-party/cxxopts/CHANGELOG.md
@@ -3,6 +3,31 @@
 This is the changelog for `cxxopts`, a C++11 library for parsing command line
 options. The project adheres to semantic versioning.
 
+## 3.1.1
+
+### Bug Fixes
+
+* Fixed version number in header.
+* Fixed cast warning in Unicode function.
+
+## 3.1
+
+### Added
+
+* Support for multiple long names for the same option (= multiple long aliases)
+* Add a `program()` function to retrieve the program name.
+* Added a .clang-format file.
+* Added iterator and printing for a ParseResult.
+
+### Changed
+
+* Cleanup exception code, add cxxopts::exceptions namespace.
+* Renamed several exceptions to be more descriptive, and added to a nested namespace.
+
+### Bug Fixes
+
+* Fix `arguments()` having no key for options that only have a short name.
+
 ## 3.0
 
 ### Changed
@@ -15,10 +40,19 @@
 * Change argument type in `Options::parse` from `char**` to `const char**`.
 * Refactor parser to not change its arguments.
 * `ParseResult` doesn't depend on a reference to the parser.
+* Fixed several warnings and code quality issues.
+* Improved formatting for help descriptions.
+* Improve integer parsing.
 
 ### Added
 
 * A list of unmatched arguments is available in `ParseResult`.
+* Support single letter options with argument attached.
+* Use <optional> if it is present.
+
+### Bug Fixes
+
+* Fix missing option name in exception.
 
 ## 2.2
 
diff --git a/third-party/cxxopts/CHANGELOG.md.license b/third-party/cxxopts/CHANGELOG.md.license
index bf1b5b5..2a9007a 100644
--- a/third-party/cxxopts/CHANGELOG.md.license
+++ b/third-party/cxxopts/CHANGELOG.md.license
@@ -1,4 +1,4 @@
 #
-# Copyright (c) 2014 Jarryd Beck
+# Copyright (c) 2014-2022 Jarryd Beck
 # SPDX-License-Identifier: MIT
 #
diff --git a/third-party/cxxopts/LICENSE.spdx b/third-party/cxxopts/LICENSE.spdx
index e4139cb..079b1a7 100644
--- a/third-party/cxxopts/LICENSE.spdx
+++ b/third-party/cxxopts/LICENSE.spdx
@@ -4,4 +4,4 @@
 PackageLicenseConcluded: MIT
 PackageLicenseInfoFromFiles: MIT
 PackageLicenseDeclared: MIT
-PackageCopyrightText: <text>Copyright (c) 2014, 2015, 2016, 2017 Jarryd Beck</text>
+PackageCopyrightText: <text>Copyright (c) 2014-2022 Jarryd Beck</text>
diff --git a/third-party/cxxopts/README.md b/third-party/cxxopts/README.md
index 9517993..de69e5a 100644
--- a/third-party/cxxopts/README.md
+++ b/third-party/cxxopts/README.md
@@ -7,9 +7,9 @@
 
 ## Version 3 breaking changes
 
-If you have used version 2, there are a couple of breaking changes in (the as
-yet unreleased, current master) version 3 that you should be aware of. If you are new to
-`cxxopts` you can skip this section.
+If you have used version 2, there are a couple of breaking changes in version 3
+that you should be aware of. If you are new to `cxxopts` you can skip this
+section.
 
 The parser no longer modifies its arguments, so you can pass a const `argc` and
 `argv` and expect them not to be changed.
@@ -109,9 +109,9 @@
 
 Exceptional situations throw C++ exceptions. There are two types of
 exceptions: errors defining the options, and errors when parsing a list of
-arguments. All exceptions derive from `cxxopts::OptionException`. Errors
-defining options derive from `cxxopts::OptionSpecException` and errors
-parsing arguments derive from `cxxopts::OptionParseException`.
+arguments. All exceptions derive from `cxxopts::exceptions::exception`. Errors
+defining options derive from `cxxopts::exceptions::specification` and errors
+parsing arguments derive from `cxxopts::exceptions::parsing`.
 
 All exceptions define a `what()` function to get a printable string
 explaining the error.
@@ -125,15 +125,37 @@
 
 ## Positional Arguments
 
-Positional arguments can be optionally parsed into one or more options.
-To set up positional arguments, call
+Positional arguments are those given without a preceding flag and can be used
+alongside non-positional arguments. There may be multiple positional arguments,
+and the final positional argument may be a container type to hold a list of all
+remaining positionals.
+
+To set up positional arguments, first declare the options, then configure a
+set of those arguments as positional like:
 
 ```cpp
-options.parse_positional({"first", "second", "last"})
+options.add_options()
+  ("script", "The script file to execute", cxxopts::value<std::string>())
+  ("server", "The server to execute on", cxxopts::value<std::string>())
+  ("filenames", "The filename(s) to process", cxxopts::value<std::vector<std::string>>());
+
+options.parse_positional({"script", "server", "filenames"});
+
+// Parse options the usual way
+options.parse(argc, argv);
 ```
 
-where "last" should be the name of an option with a container type, and the
-others should have a single value.
+For example, parsing the following arguments:
+~~~
+my_script.py my_server.com file1.txt file2.txt file3.txt
+~~~
+will result in parsed arguments like the following table:
+
+| Field         | Value                                     |
+| ------------- | ----------------------------------------- |
+| `"script"`    | `"my_script.py"`                          |
+| `"server"`    | `"my_server.com"`                         |
+| `"filenames"` | `{"file1.txt", "file2.txt", "file3.txt"}` |
 
 ## Default and implicit values
 
@@ -161,6 +183,8 @@
 regardless of the type that you want to store it in. It will be parsed as
 though it was given on the command line.
 
+Default values are not counted by `Options::count`.
+
 ## Boolean values
 
 Boolean options have a default implicit value of `"true"`, which can be
diff --git a/third-party/cxxopts/README.md.license b/third-party/cxxopts/README.md.license
index bf1b5b5..2a9007a 100644
--- a/third-party/cxxopts/README.md.license
+++ b/third-party/cxxopts/README.md.license
@@ -1,4 +1,4 @@
 #
-# Copyright (c) 2014 Jarryd Beck
+# Copyright (c) 2014-2022 Jarryd Beck
 # SPDX-License-Identifier: MIT
 #
diff --git a/third-party/cxxopts/cxxopts.hpp b/third-party/cxxopts/cxxopts.hpp
index 5cebc4b..8aa17bd 100644
--- a/third-party/cxxopts/cxxopts.hpp
+++ b/third-party/cxxopts/cxxopts.hpp
@@ -1,7 +1,6 @@
 /*
 
-Copyright (c) 2014, 2015, 2016, 2017 Jarryd Beck
-
+Copyright (c) 2014-2022 Jarryd Beck
 SPDX-License-Identifier: MIT
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -24,28 +23,55 @@
 
 */
 
+// vim: ts=2:sw=2:expandtab
+
 #ifndef CXXOPTS_HPP_INCLUDED
 #define CXXOPTS_HPP_INCLUDED
 
-#include <cctype>
 #include <cstring>
 #include <exception>
-#include <iostream>
 #include <limits>
-#include <list>
+#include <initializer_list>
 #include <map>
 #include <memory>
-#include <regex>
 #include <sstream>
 #include <string>
 #include <unordered_map>
 #include <unordered_set>
 #include <utility>
 #include <vector>
+#include <algorithm>
+#include <locale>
 
-#ifdef __cpp_lib_optional
-#include <optional>
-#define CXXOPTS_HAS_OPTIONAL
+#ifdef CXXOPTS_NO_EXCEPTIONS
+#include <iostream>
+#endif
+
+#if defined(__GNUC__) && !defined(__clang__)
+#  if (__GNUC__ * 10 + __GNUC_MINOR__) < 49
+#    define CXXOPTS_NO_REGEX true
+#  endif
+#endif
+#if defined(_MSC_VER) && !defined(__clang__)
+#define CXXOPTS_LINKONCE_CONST	__declspec(selectany) extern
+#define CXXOPTS_LINKONCE		__declspec(selectany) extern
+#else
+#define CXXOPTS_LINKONCE_CONST
+#define CXXOPTS_LINKONCE
+#endif
+
+#ifndef CXXOPTS_NO_REGEX
+#  include <regex>
+#endif  // CXXOPTS_NO_REGEX
+
+// Nonstandard before C++17, which is coincidentally what we also need for <optional>
+#ifdef __has_include
+#  if __has_include(<optional>)
+#    include <optional>
+#    ifdef __cpp_lib_optional
+#      define CXXOPTS_HAS_OPTIONAL
+#    endif
+#  endif
 #endif
 
 #if __cplusplus >= 201603L
@@ -59,18 +85,39 @@
 #endif
 
 #define CXXOPTS__VERSION_MAJOR 3
-#define CXXOPTS__VERSION_MINOR 0
-#define CXXOPTS__VERSION_PATCH 0
+#define CXXOPTS__VERSION_MINOR 1
+#define CXXOPTS__VERSION_PATCH 1
 
-namespace cxxopts
-{
-  static constexpr struct {
-    uint8_t major, minor, patch;
-  } version = {
-    CXXOPTS__VERSION_MAJOR,
-    CXXOPTS__VERSION_MINOR,
-    CXXOPTS__VERSION_PATCH
-  };
+#if (__GNUC__ < 10 || (__GNUC__ == 10 && __GNUC_MINOR__ < 1)) && __GNUC__ >= 6
+  #define CXXOPTS_NULL_DEREF_IGNORE
+#endif
+
+#if defined(__GNUC__)
+#define DO_PRAGMA(x) _Pragma(#x)
+#define CXXOPTS_DIAGNOSTIC_PUSH DO_PRAGMA(GCC diagnostic push)
+#define CXXOPTS_DIAGNOSTIC_POP DO_PRAGMA(GCC diagnostic pop)
+#define CXXOPTS_IGNORE_WARNING(x) DO_PRAGMA(GCC diagnostic ignored x)
+#else
+// define other compilers here if needed
+#define CXXOPTS_DIAGNOSTIC_PUSH
+#define CXXOPTS_DIAGNOSTIC_POP
+#define CXXOPTS_IGNORE_WARNING(x)
+#endif
+
+#ifdef CXXOPTS_NO_RTTI
+#define CXXOPTS_RTTI_CAST static_cast
+#else
+#define CXXOPTS_RTTI_CAST dynamic_cast
+#endif
+
+namespace cxxopts {
+static constexpr struct {
+  uint8_t major, minor, patch;
+} version = {
+  CXXOPTS__VERSION_MAJOR,
+  CXXOPTS__VERSION_MINOR,
+  CXXOPTS__VERSION_PATCH
+};
 } // namespace cxxopts
 
 //when we ask cxxopts to use Unicode, help strings are processed using ICU,
@@ -82,1602 +129,2064 @@
 #ifdef CXXOPTS_USE_UNICODE
 #include <unicode/unistr.h>
 
-namespace cxxopts
+namespace cxxopts {
+
+using String = icu::UnicodeString;
+
+inline
+String
+toLocalString(std::string s)
 {
-  typedef icu::UnicodeString String;
+  return icu::UnicodeString::fromUTF8(std::move(s));
+}
 
-  inline
-  String
-  toLocalString(std::string s)
+// GNU GCC with -Weffc++ will issue a warning regarding the upcoming class, we want to silence it:
+// warning: base class 'class std::enable_shared_from_this<cxxopts::Value>' has accessible non-virtual destructor
+CXXOPTS_DIAGNOSTIC_PUSH
+CXXOPTS_IGNORE_WARNING("-Wnon-virtual-dtor")
+// This will be ignored under other compilers like LLVM clang.
+class UnicodeStringIterator
+{
+  public:
+
+  using iterator_category = std::forward_iterator_tag;
+  using value_type = int32_t;
+  using difference_type = std::ptrdiff_t;
+  using pointer = value_type*;
+  using reference = value_type&;
+
+  UnicodeStringIterator(const icu::UnicodeString* string, int32_t pos)
+  : s(string)
+  , i(pos)
   {
-    return icu::UnicodeString::fromUTF8(std::move(s));
   }
 
-  class UnicodeStringIterator : public
-    std::iterator<std::forward_iterator_tag, int32_t>
+  value_type
+  operator*() const
   {
-    public:
-
-    UnicodeStringIterator(const icu::UnicodeString* string, int32_t pos)
-    : s(string)
-    , i(pos)
-    {
-    }
-
-    value_type
-    operator*() const
-    {
-      return s->char32At(i);
-    }
-
-    bool
-    operator==(const UnicodeStringIterator& rhs) const
-    {
-      return s == rhs.s && i == rhs.i;
-    }
-
-    bool
-    operator!=(const UnicodeStringIterator& rhs) const
-    {
-      return !(*this == rhs);
-    }
-
-    UnicodeStringIterator&
-    operator++()
-    {
-      ++i;
-      return *this;
-    }
-
-    UnicodeStringIterator
-    operator+(int32_t v)
-    {
-      return UnicodeStringIterator(s, i + v);
-    }
-
-    private:
-    const icu::UnicodeString* s;
-    int32_t i;
-  };
-
-  inline
-  String&
-  stringAppend(String&s, String a)
-  {
-    return s.append(std::move(a));
+    return s->char32At(i);
   }
 
-  inline
-  String&
-  stringAppend(String& s, size_t n, UChar32 c)
-  {
-    for (size_t i = 0; i != n; ++i)
-    {
-      s.append(c);
-    }
-
-    return s;
-  }
-
-  template <typename Iterator>
-  String&
-  stringAppend(String& s, Iterator begin, Iterator end)
-  {
-    while (begin != end)
-    {
-      s.append(*begin);
-      ++begin;
-    }
-
-    return s;
-  }
-
-  inline
-  size_t
-  stringLength(const String& s)
-  {
-    return s.length();
-  }
-
-  inline
-  std::string
-  toUTF8String(const String& s)
-  {
-    std::string result;
-    s.toUTF8String(result);
-
-    return result;
-  }
-
-  inline
   bool
-  empty(const String& s)
+  operator==(const UnicodeStringIterator& rhs) const
   {
-    return s.isEmpty();
+    return s == rhs.s && i == rhs.i;
   }
-}
 
-namespace std
+  bool
+  operator!=(const UnicodeStringIterator& rhs) const
+  {
+    return !(*this == rhs);
+  }
+
+  UnicodeStringIterator&
+  operator++()
+  {
+    ++i;
+    return *this;
+  }
+
+  UnicodeStringIterator
+  operator+(int32_t v)
+  {
+    return UnicodeStringIterator(s, i + v);
+  }
+
+  private:
+  const icu::UnicodeString* s;
+  int32_t i;
+};
+CXXOPTS_DIAGNOSTIC_POP
+
+inline
+String&
+stringAppend(String&s, String a)
 {
-  inline
-  cxxopts::UnicodeStringIterator
-  begin(const icu::UnicodeString& s)
+  return s.append(std::move(a));
+}
+
+inline
+String&
+stringAppend(String& s, std::size_t n, UChar32 c)
+{
+  for (std::size_t i = 0; i != n; ++i)
   {
-    return cxxopts::UnicodeStringIterator(&s, 0);
+    s.append(c);
   }
 
-  inline
-  cxxopts::UnicodeStringIterator
-  end(const icu::UnicodeString& s)
-  {
-    return cxxopts::UnicodeStringIterator(&s, s.length());
-  }
+  return s;
 }
 
+template <typename Iterator>
+String&
+stringAppend(String& s, Iterator begin, Iterator end)
+{
+  while (begin != end)
+  {
+    s.append(*begin);
+    ++begin;
+  }
+
+  return s;
+}
+
+inline
+size_t
+stringLength(const String& s)
+{
+  return static_cast<size_t>(s.length());
+}
+
+inline
+std::string
+toUTF8String(const String& s)
+{
+  std::string result;
+  s.toUTF8String(result);
+
+  return result;
+}
+
+inline
+bool
+empty(const String& s)
+{
+  return s.isEmpty();
+}
+
+} // namespace cxxopts
+
+namespace std {
+
+inline
+cxxopts::UnicodeStringIterator
+begin(const icu::UnicodeString& s)
+{
+  return cxxopts::UnicodeStringIterator(&s, 0);
+}
+
+inline
+cxxopts::UnicodeStringIterator
+end(const icu::UnicodeString& s)
+{
+  return cxxopts::UnicodeStringIterator(&s, s.length());
+}
+
+} // namespace std
+
 //ifdef CXXOPTS_USE_UNICODE
 #else
 
-namespace cxxopts
+namespace cxxopts {
+
+using String = std::string;
+
+template <typename T>
+T
+toLocalString(T&& t)
 {
-  typedef std::string String;
+  return std::forward<T>(t);
+}
 
-  template <typename T>
-  T
-  toLocalString(T&& t)
-  {
-    return std::forward<T>(t);
-  }
+inline
+std::size_t
+stringLength(const String& s)
+{
+  return s.length();
+}
 
-  inline
-  size_t
-  stringLength(const String& s)
-  {
-    return s.length();
-  }
+inline
+String&
+stringAppend(String&s, const String& a)
+{
+  return s.append(a);
+}
 
-  inline
-  String&
-  stringAppend(String&s, const String& a)
-  {
-    return s.append(a);
-  }
+inline
+String&
+stringAppend(String& s, std::size_t n, char c)
+{
+  return s.append(n, c);
+}
 
-  inline
-  String&
-  stringAppend(String& s, size_t n, char c)
-  {
-    return s.append(n, c);
-  }
+template <typename Iterator>
+String&
+stringAppend(String& s, Iterator begin, Iterator end)
+{
+  return s.append(begin, end);
+}
 
-  template <typename Iterator>
-  String&
-  stringAppend(String& s, Iterator begin, Iterator end)
-  {
-    return s.append(begin, end);
-  }
+template <typename T>
+std::string
+toUTF8String(T&& t)
+{
+  return std::forward<T>(t);
+}
 
-  template <typename T>
-  std::string
-  toUTF8String(T&& t)
-  {
-    return std::forward<T>(t);
-  }
+inline
+bool
+empty(const std::string& s)
+{
+  return s.empty();
+}
 
-  inline
-  bool
-  empty(const std::string& s)
-  {
-    return s.empty();
-  }
 } // namespace cxxopts
 
 //ifdef CXXOPTS_USE_UNICODE
 #endif
 
-namespace cxxopts
+namespace cxxopts {
+
+namespace {
+CXXOPTS_LINKONCE_CONST std::string LQUOTE("\'");
+CXXOPTS_LINKONCE_CONST std::string RQUOTE("\'");
+} // namespace
+
+// GNU GCC with -Weffc++ will issue a warning regarding the upcoming class, we
+// want to silence it: warning: base class 'class
+// std::enable_shared_from_this<cxxopts::Value>' has accessible non-virtual
+// destructor This will be ignored under other compilers like LLVM clang.
+CXXOPTS_DIAGNOSTIC_PUSH
+CXXOPTS_IGNORE_WARNING("-Wnon-virtual-dtor")
+
+// some older versions of GCC warn under this warning
+CXXOPTS_IGNORE_WARNING("-Weffc++")
+class Value : public std::enable_shared_from_this<Value>
 {
-  namespace
+  public:
+
+  virtual ~Value() = default;
+
+  virtual
+  std::shared_ptr<Value>
+  clone() const = 0;
+
+  virtual void
+  parse(const std::string& text) const = 0;
+
+  virtual void
+  parse() const = 0;
+
+  virtual bool
+  has_default() const = 0;
+
+  virtual bool
+  is_container() const = 0;
+
+  virtual bool
+  has_implicit() const = 0;
+
+  virtual std::string
+  get_default_value() const = 0;
+
+  virtual std::string
+  get_implicit_value() const = 0;
+
+  virtual std::shared_ptr<Value>
+  default_value(const std::string& value) = 0;
+
+  virtual std::shared_ptr<Value>
+  implicit_value(const std::string& value) = 0;
+
+  virtual std::shared_ptr<Value>
+  no_implicit_value() = 0;
+
+  virtual bool
+  is_boolean() const = 0;
+};
+
+CXXOPTS_DIAGNOSTIC_POP
+
+namespace exceptions {
+
+class exception : public std::exception
+{
+  public:
+  explicit exception(std::string  message)
+  : m_message(std::move(message))
   {
-#ifdef _WIN32
-    const std::string LQUOTE("\'");
-    const std::string RQUOTE("\'");
-#else
-    const std::string LQUOTE("‘");
-    const std::string RQUOTE("’");
-#endif
-  } // namespace
+  }
 
-#if defined(__GNUC__)
-// GNU GCC with -Weffc++ will issue a warning regarding the upcoming class, we want to silence it:
-// warning: base class 'class std::enable_shared_from_this<cxxopts::Value>' has accessible non-virtual destructor
-#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
-#pragma GCC diagnostic push
-// This will be ignored under other compilers like LLVM clang.
-#endif
-  class Value : public std::enable_shared_from_this<Value>
+  CXXOPTS_NODISCARD
+  const char*
+  what() const noexcept override
   {
-    public:
+    return m_message.c_str();
+  }
 
-    virtual ~Value() = default;
+  private:
+  std::string m_message;
+};
 
-    virtual
-    std::shared_ptr<Value>
-    clone() const = 0;
+class specification : public exception
+{
+  public:
 
-    virtual void
-    parse(const std::string& text) const = 0;
-
-    virtual void
-    parse() const = 0;
-
-    virtual bool
-    has_default() const = 0;
-
-    virtual bool
-    is_container() const = 0;
-
-    virtual bool
-    has_implicit() const = 0;
-
-    virtual std::string
-    get_default_value() const = 0;
-
-    virtual std::string
-    get_implicit_value() const = 0;
-
-    virtual std::shared_ptr<Value>
-    default_value(const std::string& value) = 0;
-
-    virtual std::shared_ptr<Value>
-    implicit_value(const std::string& value) = 0;
-
-    virtual std::shared_ptr<Value>
-    no_implicit_value() = 0;
-
-    virtual bool
-    is_boolean() const = 0;
-  };
-#if defined(__GNUC__)
-#pragma GCC diagnostic pop
-#endif
-  class OptionException : public std::exception
+  explicit specification(const std::string& message)
+  : exception(message)
   {
-    public:
-    explicit OptionException(std::string  message)
-    : m_message(std::move(message))
-    {
-    }
+  }
+};
 
-    CXXOPTS_NODISCARD
-    const char*
-    what() const noexcept override
-    {
-      return m_message.c_str();
-    }
-
-    private:
-    std::string m_message;
-  };
-
-  class OptionSpecException : public OptionException
+class parsing : public exception
+{
+  public:
+  explicit parsing(const std::string& message)
+  : exception(message)
   {
-    public:
+  }
+};
 
-    explicit OptionSpecException(const std::string& message)
-    : OptionException(message)
-    {
-    }
-  };
-
-  class OptionParseException : public OptionException
+class option_already_exists : public specification
+{
+  public:
+  explicit option_already_exists(const std::string& option)
+  : specification("Option " + LQUOTE + option + RQUOTE + " already exists")
   {
-    public:
-    explicit OptionParseException(const std::string& message)
-    : OptionException(message)
-    {
-    }
-  };
+  }
+};
 
-  class option_exists_error : public OptionSpecException
+class invalid_option_format : public specification
+{
+  public:
+  explicit invalid_option_format(const std::string& format)
+  : specification("Invalid option format " + LQUOTE + format + RQUOTE)
   {
-    public:
-    explicit option_exists_error(const std::string& option)
-    : OptionSpecException("Option " + LQUOTE + option + RQUOTE + " already exists")
-    {
-    }
-  };
+  }
+};
 
-  class invalid_option_format_error : public OptionSpecException
+class invalid_option_syntax : public parsing {
+  public:
+  explicit invalid_option_syntax(const std::string& text)
+  : parsing("Argument " + LQUOTE + text + RQUOTE +
+            " starts with a - but has incorrect syntax")
   {
-    public:
-    explicit invalid_option_format_error(const std::string& format)
-    : OptionSpecException("Invalid option format " + LQUOTE + format + RQUOTE)
-    {
-    }
-  };
+  }
+};
 
-  class option_syntax_exception : public OptionParseException {
-    public:
-    explicit option_syntax_exception(const std::string& text)
-    : OptionParseException("Argument " + LQUOTE + text + RQUOTE +
-        " starts with a - but has incorrect syntax")
-    {
-    }
-  };
-
-  class option_not_exists_exception : public OptionParseException
+class no_such_option : public parsing
+{
+  public:
+  explicit no_such_option(const std::string& option)
+  : parsing("Option " + LQUOTE + option + RQUOTE + " does not exist")
   {
-    public:
-    explicit option_not_exists_exception(const std::string& option)
-    : OptionParseException("Option " + LQUOTE + option + RQUOTE + " does not exist")
-    {
-    }
-  };
+  }
+};
 
-  class missing_argument_exception : public OptionParseException
-  {
-    public:
-    explicit missing_argument_exception(const std::string& option)
-    : OptionParseException(
-        "Option " + LQUOTE + option + RQUOTE + " is missing an argument"
-      )
-    {
-    }
-  };
-
-  class option_requires_argument_exception : public OptionParseException
-  {
-    public:
-    explicit option_requires_argument_exception(const std::string& option)
-    : OptionParseException(
-        "Option " + LQUOTE + option + RQUOTE + " requires an argument"
-      )
-    {
-    }
-  };
-
-  class option_not_has_argument_exception : public OptionParseException
-  {
-    public:
-    option_not_has_argument_exception
-    (
-      const std::string& option,
-      const std::string& arg
+class missing_argument : public parsing
+{
+  public:
+  explicit missing_argument(const std::string& option)
+  : parsing(
+      "Option " + LQUOTE + option + RQUOTE + " is missing an argument"
     )
-    : OptionParseException(
-        "Option " + LQUOTE + option + RQUOTE +
-        " does not take an argument, but argument " +
-        LQUOTE + arg + RQUOTE + " given"
-      )
-    {
-    }
-  };
-
-  class option_not_present_exception : public OptionParseException
   {
-    public:
-    explicit option_not_present_exception(const std::string& option)
-    : OptionParseException("Option " + LQUOTE + option + RQUOTE + " not present")
-    {
-    }
-  };
+  }
+};
 
-  class option_has_no_value_exception : public OptionException
-  {
-    public:
-    explicit option_has_no_value_exception(const std::string& option)
-    : OptionException(
-        option.empty() ?
-        ("Option " + LQUOTE + option + RQUOTE + " has no value") :
-        "Option has no value")
-    {
-    }
-  };
-
-  class argument_incorrect_type : public OptionParseException
-  {
-    public:
-    explicit argument_incorrect_type
-    (
-      const std::string& arg
+class option_requires_argument : public parsing
+{
+  public:
+  explicit option_requires_argument(const std::string& option)
+  : parsing(
+      "Option " + LQUOTE + option + RQUOTE + " requires an argument"
     )
-    : OptionParseException(
-        "Argument " + LQUOTE + arg + RQUOTE + " failed to parse"
-      )
-    {
-    }
-  };
-
-  class option_required_exception : public OptionParseException
   {
-    public:
-    explicit option_required_exception(const std::string& option)
-    : OptionParseException(
-        "Option " + LQUOTE + option + RQUOTE + " is required but not present"
-      )
-    {
-    }
-  };
+  }
+};
 
-  template <typename T>
-  void throw_or_mimic(const std::string& text)
+class gratuitous_argument_for_option : public parsing
+{
+  public:
+  gratuitous_argument_for_option
+  (
+    const std::string& option,
+    const std::string& arg
+  )
+  : parsing(
+      "Option " + LQUOTE + option + RQUOTE +
+      " does not take an argument, but argument " +
+      LQUOTE + arg + RQUOTE + " given"
+    )
   {
-    static_assert(std::is_base_of<std::exception, T>::value,
-                  "throw_or_mimic only works on std::exception and "
-                  "deriving classes");
+  }
+};
+
+class requested_option_not_present : public parsing
+{
+  public:
+  explicit requested_option_not_present(const std::string& option)
+  : parsing("Option " + LQUOTE + option + RQUOTE + " not present")
+  {
+  }
+};
+
+class option_has_no_value : public exception
+{
+  public:
+  explicit option_has_no_value(const std::string& option)
+  : exception(
+      !option.empty() ?
+      ("Option " + LQUOTE + option + RQUOTE + " has no value") :
+      "Option has no value")
+  {
+  }
+};
+
+class incorrect_argument_type : public parsing
+{
+  public:
+  explicit incorrect_argument_type
+  (
+    const std::string& arg
+  )
+  : parsing(
+      "Argument " + LQUOTE + arg + RQUOTE + " failed to parse"
+    )
+  {
+  }
+};
+
+} // namespace exceptions
+
+
+template <typename T>
+void throw_or_mimic(const std::string& text)
+{
+  static_assert(std::is_base_of<std::exception, T>::value,
+                "throw_or_mimic only works on std::exception and "
+                "deriving classes");
 
 #ifndef CXXOPTS_NO_EXCEPTIONS
-    // If CXXOPTS_NO_EXCEPTIONS is not defined, just throw
-    throw T{text};
+  // If CXXOPTS_NO_EXCEPTIONS is not defined, just throw
+  throw T{text};
 #else
-    // Otherwise manually instantiate the exception, print what() to stderr,
-    // and exit
-    T exception{text};
-    std::cerr << exception.what() << std::endl;
-    std::exit(EXIT_FAILURE);
+  // Otherwise manually instantiate the exception, print what() to stderr,
+  // and exit
+  T exception{text};
+  std::cerr << exception.what() << std::endl;
+  std::exit(EXIT_FAILURE);
 #endif
+}
+
+using OptionNames = std::vector<std::string>;
+
+namespace values {
+
+namespace parser_tool {
+
+struct IntegerDesc
+{
+  std::string negative = "";
+  std::string base     = "";
+  std::string value    = "";
+};
+struct ArguDesc {
+  std::string arg_name  = "";
+  bool        grouping  = false;
+  bool        set_value = false;
+  std::string value     = "";
+};
+
+#ifdef CXXOPTS_NO_REGEX
+inline IntegerDesc SplitInteger(const std::string &text)
+{
+  if (text.empty())
+  {
+    throw_or_mimic<exceptions::incorrect_argument_type>(text);
+  }
+  IntegerDesc desc;
+  const char *pdata = text.c_str();
+  if (*pdata == '-')
+  {
+    pdata += 1;
+    desc.negative = "-";
+  }
+  if (strncmp(pdata, "0x", 2) == 0)
+  {
+    pdata += 2;
+    desc.base = "0x";
+  }
+  if (*pdata != '\0')
+  {
+    desc.value = std::string(pdata);
+  }
+  else
+  {
+    throw_or_mimic<exceptions::incorrect_argument_type>(text);
+  }
+  return desc;
+}
+
+inline bool IsTrueText(const std::string &text)
+{
+  const char *pdata = text.c_str();
+  if (*pdata == 't' || *pdata == 'T')
+  {
+    pdata += 1;
+    if (strncmp(pdata, "rue\0", 4) == 0)
+    {
+      return true;
+    }
+  }
+  else if (strncmp(pdata, "1\0", 2) == 0)
+  {
+    return true;
+  }
+  return false;
+}
+
+inline bool IsFalseText(const std::string &text)
+{
+  const char *pdata = text.c_str();
+  if (*pdata == 'f' || *pdata == 'F')
+  {
+    pdata += 1;
+    if (strncmp(pdata, "alse\0", 5) == 0)
+    {
+      return true;
+    }
+  }
+  else if (strncmp(pdata, "0\0", 2) == 0)
+  {
+    return true;
+  }
+  return false;
+}
+
+inline OptionNames split_option_names(const std::string &text)
+{
+  OptionNames split_names;
+
+  std::string::size_type token_start_pos = 0;
+  auto length = text.length();
+
+  if (length == 0)
+  {
+    throw_or_mimic<exceptions::invalid_option_format>(text);
   }
 
-  namespace values
+  while (token_start_pos < length) {
+    const auto &npos = std::string::npos;
+    auto next_non_space_pos = text.find_first_not_of(' ', token_start_pos);
+    if (next_non_space_pos == npos) {
+      throw_or_mimic<exceptions::invalid_option_format>(text);
+    }
+    token_start_pos = next_non_space_pos;
+    auto next_delimiter_pos = text.find(',', token_start_pos);
+    if (next_delimiter_pos == token_start_pos) {
+      throw_or_mimic<exceptions::invalid_option_format>(text);
+    }
+    if (next_delimiter_pos == npos) {
+      next_delimiter_pos = length;
+    }
+    auto token_length = next_delimiter_pos - token_start_pos;
+    // validate the token itself matches the regex /([:alnum:][-_[:alnum:]]*/
+    {
+      const char* option_name_valid_chars =
+        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+        "abcdefghijklmnopqrstuvwxyz"
+        "0123456789"
+        "_-.?";
+
+      if (!std::isalnum(text[token_start_pos], std::locale::classic()) ||
+          text.find_first_not_of(option_name_valid_chars, token_start_pos) < next_delimiter_pos) {
+        throw_or_mimic<exceptions::invalid_option_format>(text);
+      }
+    }
+    split_names.emplace_back(text.substr(token_start_pos, token_length));
+    token_start_pos = next_delimiter_pos + 1;
+  }
+  return split_names;
+}
+
+inline ArguDesc ParseArgument(const char *arg, bool &matched)
+{
+  ArguDesc argu_desc;
+  const char *pdata = arg;
+  matched = false;
+  if (strncmp(pdata, "--", 2) == 0)
   {
-    namespace
+    pdata += 2;
+    if (isalnum(*pdata, std::locale::classic()))
     {
-      std::basic_regex<char> integer_pattern
-        ("(-)?(0x)?([0-9a-zA-Z]+)|((0x)?0)");
-      std::basic_regex<char> truthy_pattern
-        ("(t|T)(rue)?|1");
-      std::basic_regex<char> falsy_pattern
-        ("(f|F)(alse)?|0");
-    } // namespace
-
-    namespace detail
-    {
-      template <typename T, bool B>
-      struct SignedCheck;
-
-      template <typename T>
-      struct SignedCheck<T, true>
+      argu_desc.arg_name.push_back(*pdata);
+      pdata += 1;
+      while (isalnum(*pdata, std::locale::classic()) || *pdata == '-' || *pdata == '_')
       {
-        template <typename U>
-        void
-        operator()(bool negative, U u, const std::string& text)
+        argu_desc.arg_name.push_back(*pdata);
+        pdata += 1;
+      }
+      if (argu_desc.arg_name.length() > 1)
+      {
+        if (*pdata == '=')
         {
-          if (negative)
+          argu_desc.set_value = true;
+          pdata += 1;
+          if (*pdata != '\0')
           {
-            if (u > static_cast<U>((std::numeric_limits<T>::min)()))
-            {
-              throw_or_mimic<argument_incorrect_type>(text);
-            }
+            argu_desc.value = std::string(pdata);
           }
-          else
-          {
-            if (u > static_cast<U>((std::numeric_limits<T>::max)()))
-            {
-              throw_or_mimic<argument_incorrect_type>(text);
-            }
-          }
+          matched = true;
         }
-      };
-
-      template <typename T>
-      struct SignedCheck<T, false>
-      {
-        template <typename U>
-        void
-        operator()(bool, U, const std::string&) {}
-      };
-
-      template <typename T, typename U>
-      void
-      check_signed_range(bool negative, U value, const std::string& text)
-      {
-        SignedCheck<T, std::numeric_limits<T>::is_signed>()(negative, value, text);
-      }
-    } // namespace detail
-
-    template <typename R, typename T>
-    void
-    checked_negate(R& r, T&& t, const std::string&, std::true_type)
-    {
-      // if we got to here, then `t` is a positive number that fits into
-      // `R`. So to avoid MSVC C4146, we first cast it to `R`.
-      // See https://github.com/jarro2783/cxxopts/issues/62 for more details.
-      r = static_cast<R>(-static_cast<R>(t-1)-1);
-    }
-
-    template <typename R, typename T>
-    void
-    checked_negate(R&, T&&, const std::string& text, std::false_type)
-    {
-      throw_or_mimic<argument_incorrect_type>(text);
-    }
-
-    template <typename T>
-    void
-    integer_parser(const std::string& text, T& value)
-    {
-      std::smatch match;
-      std::regex_match(text, match, integer_pattern);
-
-      if (match.length() == 0)
-      {
-        throw_or_mimic<argument_incorrect_type>(text);
-      }
-
-      if (match.length(4) > 0)
-      {
-        value = 0;
-        return;
-      }
-
-      using US = typename std::make_unsigned<T>::type;
-
-      constexpr bool is_signed = std::numeric_limits<T>::is_signed;
-      const bool negative = match.length(1) > 0;
-      const uint8_t base = match.length(2) > 0 ? 16 : 10;
-
-      auto value_match = match[3];
-
-      US result = 0;
-
-      for (auto iter = value_match.first; iter != value_match.second; ++iter)
-      {
-        US digit = 0;
-
-        if (*iter >= '0' && *iter <= '9')
+        else if (*pdata == '\0')
         {
-          digit = static_cast<US>(*iter - '0');
+          matched = true;
         }
-        else if (base == 16 && *iter >= 'a' && *iter <= 'f')
-        {
-          digit = static_cast<US>(*iter - 'a' + 10);
-        }
-        else if (base == 16 && *iter >= 'A' && *iter <= 'F')
-        {
-          digit = static_cast<US>(*iter - 'A' + 10);
-        }
-        else
-        {
-          throw_or_mimic<argument_incorrect_type>(text);
-        }
-
-        const US next = static_cast<US>(result * base + digit);
-        if (result > next)
-        {
-          throw_or_mimic<argument_incorrect_type>(text);
-        }
-
-        result = next;
       }
+    }
+  }
+  else if (strncmp(pdata, "-", 1) == 0)
+  {
+    pdata += 1;
+    argu_desc.grouping = true;
+    while (isalnum(*pdata, std::locale::classic()))
+    {
+      argu_desc.arg_name.push_back(*pdata);
+      pdata += 1;
+    }
+    matched = !argu_desc.arg_name.empty() && *pdata == '\0';
+  }
+  return argu_desc;
+}
 
-      detail::check_signed_range<T>(negative, result, text);
+#else  // CXXOPTS_NO_REGEX
 
-      if (negative)
+namespace {
+CXXOPTS_LINKONCE
+std::basic_regex<char> integer_pattern
+  ("(-)?(0x)?([0-9a-zA-Z]+)|((0x)?0)");
+CXXOPTS_LINKONCE
+std::basic_regex<char> truthy_pattern
+  ("(t|T)(rue)?|1");
+CXXOPTS_LINKONCE
+std::basic_regex<char> falsy_pattern
+  ("(f|F)(alse)?|0");
+CXXOPTS_LINKONCE
+std::basic_regex<char> option_matcher
+  ("--([[:alnum:]][-_[:alnum:]\\.]+)(=(.*))?|-([[:alnum:]].*)");
+CXXOPTS_LINKONCE
+std::basic_regex<char> option_specifier
+  ("([[:alnum:]][-_[:alnum:]\\.]*)(,[ ]*[[:alnum:]][-_[:alnum:]]*)*");
+CXXOPTS_LINKONCE
+std::basic_regex<char> option_specifier_separator(", *");
+
+} // namespace
+
+inline IntegerDesc SplitInteger(const std::string &text)
+{
+  std::smatch match;
+  std::regex_match(text, match, integer_pattern);
+
+  if (match.length() == 0)
+  {
+    throw_or_mimic<exceptions::incorrect_argument_type>(text);
+  }
+
+  IntegerDesc desc;
+  desc.negative = match[1];
+  desc.base = match[2];
+  desc.value = match[3];
+
+  if (match.length(4) > 0)
+  {
+    desc.base = match[5];
+    desc.value = "0";
+    return desc;
+  }
+
+  return desc;
+}
+
+inline bool IsTrueText(const std::string &text)
+{
+  std::smatch result;
+  std::regex_match(text, result, truthy_pattern);
+  return !result.empty();
+}
+
+inline bool IsFalseText(const std::string &text)
+{
+  std::smatch result;
+  std::regex_match(text, result, falsy_pattern);
+  return !result.empty();
+}
+
+// Gets the option names specified via a single, comma-separated string,
+// and returns the separate, space-discarded, non-empty names
+// (without considering which or how many are single-character)
+inline OptionNames split_option_names(const std::string &text)
+{
+  if (!std::regex_match(text.c_str(), option_specifier))
+  {
+    throw_or_mimic<exceptions::invalid_option_format>(text);
+  }
+
+  OptionNames split_names;
+
+  constexpr int use_non_matches { -1 };
+  auto token_iterator = std::sregex_token_iterator(
+    text.begin(), text.end(), option_specifier_separator, use_non_matches);
+  std::copy(token_iterator, std::sregex_token_iterator(), std::back_inserter(split_names));
+  return split_names;
+}
+
+inline ArguDesc ParseArgument(const char *arg, bool &matched)
+{
+  std::match_results<const char*> result;
+  std::regex_match(arg, result, option_matcher);
+  matched = !result.empty();
+
+  ArguDesc argu_desc;
+  if (matched) {
+    argu_desc.arg_name = result[1].str();
+    argu_desc.set_value = result[2].length() > 0;
+    argu_desc.value = result[3].str();
+    if (result[4].length() > 0)
+    {
+      argu_desc.grouping = true;
+      argu_desc.arg_name = result[4].str();
+    }
+  }
+
+  return argu_desc;
+}
+
+#endif  // CXXOPTS_NO_REGEX
+#undef CXXOPTS_NO_REGEX
+} // namespace parser_tool
+
+namespace detail {
+
+template <typename T, bool B>
+struct SignedCheck;
+
+template <typename T>
+struct SignedCheck<T, true>
+{
+  template <typename U>
+  void
+  operator()(bool negative, U u, const std::string& text)
+  {
+    if (negative)
+    {
+      if (u > static_cast<U>((std::numeric_limits<T>::min)()))
       {
-        checked_negate<T>(value, result, text, std::integral_constant<bool, is_signed>());
+        throw_or_mimic<exceptions::incorrect_argument_type>(text);
       }
-      else
+    }
+    else
+    {
+      if (u > static_cast<U>((std::numeric_limits<T>::max)()))
       {
-        value = static_cast<T>(result);
+        throw_or_mimic<exceptions::incorrect_argument_type>(text);
       }
     }
+  }
+};
 
-    template <typename T>
-    void stringstream_parser(const std::string& text, T& value)
+template <typename T>
+struct SignedCheck<T, false>
+{
+  template <typename U>
+  void
+  operator()(bool, U, const std::string&) const {}
+};
+
+template <typename T, typename U>
+void
+check_signed_range(bool negative, U value, const std::string& text)
+{
+  SignedCheck<T, std::numeric_limits<T>::is_signed>()(negative, value, text);
+}
+
+} // namespace detail
+
+template <typename R, typename T>
+void
+checked_negate(R& r, T&& t, const std::string&, std::true_type)
+{
+  // if we got to here, then `t` is a positive number that fits into
+  // `R`. So to avoid MSVC C4146, we first cast it to `R`.
+  // See https://github.com/jarro2783/cxxopts/issues/62 for more details.
+  r = static_cast<R>(-static_cast<R>(t-1)-1);
+}
+
+template <typename R, typename T>
+void
+checked_negate(R&, T&&, const std::string& text, std::false_type)
+{
+  throw_or_mimic<exceptions::incorrect_argument_type>(text);
+}
+
+template <typename T>
+void
+integer_parser(const std::string& text, T& value)
+{
+  parser_tool::IntegerDesc int_desc = parser_tool::SplitInteger(text);
+
+  using US = typename std::make_unsigned<T>::type;
+  constexpr bool is_signed = std::numeric_limits<T>::is_signed;
+
+  const bool          negative    = int_desc.negative.length() > 0;
+  const uint8_t       base        = int_desc.base.length() > 0 ? 16 : 10;
+  const std::string & value_match = int_desc.value;
+
+  US result = 0;
+
+  for (char ch : value_match)
+  {
+    US digit = 0;
+
+    if (ch >= '0' && ch <= '9')
     {
-      std::stringstream in(text);
-      in >> value;
-      if (!in) {
-        throw_or_mimic<argument_incorrect_type>(text);
-      }
+      digit = static_cast<US>(ch - '0');
     }
-
-    inline
-    void
-    parse_value(const std::string& text, uint8_t& value)
+    else if (base == 16 && ch >= 'a' && ch <= 'f')
     {
-      integer_parser(text, value);
+      digit = static_cast<US>(ch - 'a' + 10);
     }
-
-    inline
-    void
-    parse_value(const std::string& text, int8_t& value)
+    else if (base == 16 && ch >= 'A' && ch <= 'F')
     {
-      integer_parser(text, value);
+      digit = static_cast<US>(ch - 'A' + 10);
     }
-
-    inline
-    void
-    parse_value(const std::string& text, uint16_t& value)
+    else
     {
-      integer_parser(text, value);
+      throw_or_mimic<exceptions::incorrect_argument_type>(text);
     }
 
-    inline
-    void
-    parse_value(const std::string& text, int16_t& value)
+    const US next = static_cast<US>(result * base + digit);
+    if (result > next)
     {
-      integer_parser(text, value);
+      throw_or_mimic<exceptions::incorrect_argument_type>(text);
     }
 
-    inline
-    void
-    parse_value(const std::string& text, uint32_t& value)
-    {
-      integer_parser(text, value);
-    }
+    result = next;
+  }
 
-    inline
-    void
-    parse_value(const std::string& text, int32_t& value)
-    {
-      integer_parser(text, value);
-    }
+  detail::check_signed_range<T>(negative, result, text);
 
-    inline
-    void
-    parse_value(const std::string& text, uint64_t& value)
-    {
-      integer_parser(text, value);
-    }
+  if (negative)
+  {
+    checked_negate<T>(value, result, text, std::integral_constant<bool, is_signed>());
+  }
+  else
+  {
+    value = static_cast<T>(result);
+  }
+}
 
-    inline
-    void
-    parse_value(const std::string& text, int64_t& value)
-    {
-      integer_parser(text, value);
-    }
+template <typename T>
+void stringstream_parser(const std::string& text, T& value)
+{
+  std::stringstream in(text);
+  in >> value;
+  if (!in) {
+    throw_or_mimic<exceptions::incorrect_argument_type>(text);
+  }
+}
 
-    inline
-    void
-    parse_value(const std::string& text, bool& value)
-    {
-      std::smatch result;
-      std::regex_match(text, result, truthy_pattern);
+template <typename T,
+         typename std::enable_if<std::is_integral<T>::value>::type* = nullptr
+         >
+void parse_value(const std::string& text, T& value)
+{
+    integer_parser(text, value);
+}
 
-      if (!result.empty())
-      {
-        value = true;
-        return;
-      }
+inline
+void
+parse_value(const std::string& text, bool& value)
+{
+  if (parser_tool::IsTrueText(text))
+  {
+    value = true;
+    return;
+  }
 
-      std::regex_match(text, result, falsy_pattern);
-      if (!result.empty())
-      {
-        value = false;
-        return;
-      }
+  if (parser_tool::IsFalseText(text))
+  {
+    value = false;
+    return;
+  }
 
-      throw_or_mimic<argument_incorrect_type>(text);
-    }
+  throw_or_mimic<exceptions::incorrect_argument_type>(text);
+}
 
-    inline
-    void
-    parse_value(const std::string& text, std::string& value)
-    {
-      value = text;
-    }
+inline
+void
+parse_value(const std::string& text, std::string& value)
+{
+  value = text;
+}
 
-    // The fallback parser. It uses the stringstream parser to parse all types
-    // that have not been overloaded explicitly.  It has to be placed in the
-    // source code before all other more specialized templates.
-    template <typename T>
-    void
-    parse_value(const std::string& text, T& value) {
-      stringstream_parser(text, value);
-    }
+// The fallback parser. It uses the stringstream parser to parse all types
+// that have not been overloaded explicitly.  It has to be placed in the
+// source code before all other more specialized templates.
+template <typename T,
+         typename std::enable_if<!std::is_integral<T>::value>::type* = nullptr
+         >
+void
+parse_value(const std::string& text, T& value) {
+  stringstream_parser(text, value);
+}
 
-    template <typename T>
-    void
-    parse_value(const std::string& text, std::vector<T>& value)
-    {
-      std::stringstream in(text);
-      std::string token;
-      while(!in.eof() && std::getline(in, token, CXXOPTS_VECTOR_DELIMITER)) {
-        T v;
-        parse_value(token, v);
-        value.emplace_back(std::move(v));
-      }
-    }
+template <typename T>
+void
+parse_value(const std::string& text, std::vector<T>& value)
+{
+  if (text.empty()) {
+    T v;
+    parse_value(text, v);
+    value.emplace_back(std::move(v));
+    return;
+  }
+  std::stringstream in(text);
+  std::string token;
+  while(!in.eof() && std::getline(in, token, CXXOPTS_VECTOR_DELIMITER)) {
+    T v;
+    parse_value(token, v);
+    value.emplace_back(std::move(v));
+  }
+}
 
 #ifdef CXXOPTS_HAS_OPTIONAL
-    template <typename T>
-    void
-    parse_value(const std::string& text, std::optional<T>& value)
-    {
-      T result;
-      parse_value(text, result);
-      value = std::move(result);
-    }
+template <typename T>
+void
+parse_value(const std::string& text, std::optional<T>& value)
+{
+  T result;
+  parse_value(text, result);
+  value = std::move(result);
+}
 #endif
 
-    inline
-    void parse_value(const std::string& text, char& c)
-    {
-      if (text.length() != 1)
-      {
-        throw_or_mimic<argument_incorrect_type>(text);
-      }
+inline
+void parse_value(const std::string& text, char& c)
+{
+  if (text.length() != 1)
+  {
+    throw_or_mimic<exceptions::incorrect_argument_type>(text);
+  }
 
-      c = text[0];
+  c = text[0];
+}
+
+template <typename T>
+struct type_is_container
+{
+  static constexpr bool value = false;
+};
+
+template <typename T>
+struct type_is_container<std::vector<T>>
+{
+  static constexpr bool value = true;
+};
+
+template <typename T>
+class abstract_value : public Value
+{
+  using Self = abstract_value<T>;
+
+  public:
+  abstract_value()
+  : m_result(std::make_shared<T>())
+  , m_store(m_result.get())
+  {
+  }
+
+  explicit abstract_value(T* t)
+  : m_store(t)
+  {
+  }
+
+  ~abstract_value() override = default;
+
+  abstract_value& operator=(const abstract_value&) = default;
+
+  abstract_value(const abstract_value& rhs)
+  {
+    if (rhs.m_result)
+    {
+      m_result = std::make_shared<T>();
+      m_store = m_result.get();
+    }
+    else
+    {
+      m_store = rhs.m_store;
     }
 
-    template <typename T>
-    struct type_is_container
-    {
-      static constexpr bool value = false;
-    };
+    m_default = rhs.m_default;
+    m_implicit = rhs.m_implicit;
+    m_default_value = rhs.m_default_value;
+    m_implicit_value = rhs.m_implicit_value;
+  }
 
-    template <typename T>
-    struct type_is_container<std::vector<T>>
-    {
-      static constexpr bool value = true;
-    };
-
-    template <typename T>
-    class abstract_value : public Value
-    {
-      using Self = abstract_value<T>;
-
-      public:
-      abstract_value()
-      : m_result(std::make_shared<T>())
-      , m_store(m_result.get())
-      {
-      }
-
-      explicit abstract_value(T* t)
-      : m_store(t)
-      {
-      }
-
-      ~abstract_value() override = default;
-
-      abstract_value& operator=(const abstract_value&) = default;
-
-      abstract_value(const abstract_value& rhs)
-      {
-        if (rhs.m_result)
-        {
-          m_result = std::make_shared<T>();
-          m_store = m_result.get();
-        }
-        else
-        {
-          m_store = rhs.m_store;
-        }
-
-        m_default = rhs.m_default;
-        m_implicit = rhs.m_implicit;
-        m_default_value = rhs.m_default_value;
-        m_implicit_value = rhs.m_implicit_value;
-      }
-
-      void
-      parse(const std::string& text) const override
-      {
-        parse_value(text, *m_store);
-      }
-
-      bool
-      is_container() const override
-      {
-        return type_is_container<T>::value;
-      }
-
-      void
-      parse() const override
-      {
-        parse_value(m_default_value, *m_store);
-      }
-
-      bool
-      has_default() const override
-      {
-        return m_default;
-      }
-
-      bool
-      has_implicit() const override
-      {
-        return m_implicit;
-      }
-
-      std::shared_ptr<Value>
-      default_value(const std::string& value) override
-      {
-        m_default = true;
-        m_default_value = value;
-        return shared_from_this();
-      }
-
-      std::shared_ptr<Value>
-      implicit_value(const std::string& value) override
-      {
-        m_implicit = true;
-        m_implicit_value = value;
-        return shared_from_this();
-      }
-
-      std::shared_ptr<Value>
-      no_implicit_value() override
-      {
-        m_implicit = false;
-        return shared_from_this();
-      }
-
-      std::string
-      get_default_value() const override
-      {
-        return m_default_value;
-      }
-
-      std::string
-      get_implicit_value() const override
-      {
-        return m_implicit_value;
-      }
-
-      bool
-      is_boolean() const override
-      {
-        return std::is_same<T, bool>::value;
-      }
-
-      const T&
-      get() const
-      {
-        if (m_store == nullptr)
-        {
-          return *m_result;
-        }
-        return *m_store;
-      }
-
-      protected:
-      std::shared_ptr<T> m_result{};
-      T* m_store{};
-
-      bool m_default = false;
-      bool m_implicit = false;
-
-      std::string m_default_value{};
-      std::string m_implicit_value{};
-    };
-
-    template <typename T>
-    class standard_value : public abstract_value<T>
-    {
-      public:
-      using abstract_value<T>::abstract_value;
-
-      CXXOPTS_NODISCARD
-      std::shared_ptr<Value>
-      clone() const
-      {
-        return std::make_shared<standard_value<T>>(*this);
-      }
-    };
-
-    template <>
-    class standard_value<bool> : public abstract_value<bool>
-    {
-      public:
-      ~standard_value() override = default;
-
-      standard_value()
-      {
-        set_default_and_implicit();
-      }
-
-      explicit standard_value(bool* b)
-      : abstract_value(b)
-      {
-        set_default_and_implicit();
-      }
-
-      std::shared_ptr<Value>
-      clone() const override
-      {
-        return std::make_shared<standard_value<bool>>(*this);
-      }
-
-      private:
-
-      void
-      set_default_and_implicit()
-      {
-        m_default = true;
-        m_default_value = "false";
-        m_implicit = true;
-        m_implicit_value = "true";
-      }
-    };
-  } // namespace values
-
-  template <typename T>
-  std::shared_ptr<Value>
-  value()
+  void
+  parse(const std::string& text) const override
   {
-    return std::make_shared<values::standard_value<T>>();
+    parse_value(text, *m_store);
+  }
+
+  bool
+  is_container() const override
+  {
+    return type_is_container<T>::value;
+  }
+
+  void
+  parse() const override
+  {
+    parse_value(m_default_value, *m_store);
+  }
+
+  bool
+  has_default() const override
+  {
+    return m_default;
+  }
+
+  bool
+  has_implicit() const override
+  {
+    return m_implicit;
+  }
+
+  std::shared_ptr<Value>
+  default_value(const std::string& value) override
+  {
+    m_default = true;
+    m_default_value = value;
+    return shared_from_this();
+  }
+
+  std::shared_ptr<Value>
+  implicit_value(const std::string& value) override
+  {
+    m_implicit = true;
+    m_implicit_value = value;
+    return shared_from_this();
+  }
+
+  std::shared_ptr<Value>
+  no_implicit_value() override
+  {
+    m_implicit = false;
+    return shared_from_this();
+  }
+
+  std::string
+  get_default_value() const override
+  {
+    return m_default_value;
+  }
+
+  std::string
+  get_implicit_value() const override
+  {
+    return m_implicit_value;
+  }
+
+  bool
+  is_boolean() const override
+  {
+    return std::is_same<T, bool>::value;
+  }
+
+  const T&
+  get() const
+  {
+    if (m_store == nullptr)
+    {
+      return *m_result;
+    }
+    return *m_store;
+  }
+
+  protected:
+  std::shared_ptr<T> m_result{};
+  T* m_store{};
+
+  bool m_default = false;
+  bool m_implicit = false;
+
+  std::string m_default_value{};
+  std::string m_implicit_value{};
+};
+
+template <typename T>
+class standard_value : public abstract_value<T>
+{
+  public:
+  using abstract_value<T>::abstract_value;
+
+  CXXOPTS_NODISCARD
+  std::shared_ptr<Value>
+  clone() const override
+  {
+    return std::make_shared<standard_value<T>>(*this);
+  }
+};
+
+template <>
+class standard_value<bool> : public abstract_value<bool>
+{
+  public:
+  ~standard_value() override = default;
+
+  standard_value()
+  {
+    set_default_and_implicit();
+  }
+
+  explicit standard_value(bool* b)
+  : abstract_value(b)
+  {
+    m_implicit = true;
+    m_implicit_value = "true";
+  }
+
+  std::shared_ptr<Value>
+  clone() const override
+  {
+    return std::make_shared<standard_value<bool>>(*this);
+  }
+
+  private:
+
+  void
+  set_default_and_implicit()
+  {
+    m_default = true;
+    m_default_value = "false";
+    m_implicit = true;
+    m_implicit_value = "true";
+  }
+};
+
+} // namespace values
+
+template <typename T>
+std::shared_ptr<Value>
+value()
+{
+  return std::make_shared<values::standard_value<T>>();
+}
+
+template <typename T>
+std::shared_ptr<Value>
+value(T& t)
+{
+  return std::make_shared<values::standard_value<T>>(&t);
+}
+
+class OptionAdder;
+
+CXXOPTS_NODISCARD
+inline
+const std::string&
+first_or_empty(const OptionNames& long_names)
+{
+  static const std::string empty{""};
+  return long_names.empty() ? empty : long_names.front();
+}
+
+class OptionDetails
+{
+  public:
+  OptionDetails
+  (
+    std::string short_,
+    OptionNames long_,
+    String desc,
+    std::shared_ptr<const Value> val
+  )
+  : m_short(std::move(short_))
+  , m_long(std::move(long_))
+  , m_desc(std::move(desc))
+  , m_value(std::move(val))
+  , m_count(0)
+  {
+    m_hash = std::hash<std::string>{}(first_long_name() + m_short);
+  }
+
+  OptionDetails(const OptionDetails& rhs)
+  : m_desc(rhs.m_desc)
+  , m_value(rhs.m_value->clone())
+  , m_count(rhs.m_count)
+  {
+  }
+
+  OptionDetails(OptionDetails&& rhs) = default;
+
+  CXXOPTS_NODISCARD
+  const String&
+  description() const
+  {
+    return m_desc;
+  }
+
+  CXXOPTS_NODISCARD
+  const Value&
+  value() const {
+      return *m_value;
+  }
+
+  CXXOPTS_NODISCARD
+  std::shared_ptr<Value>
+  make_storage() const
+  {
+    return m_value->clone();
+  }
+
+  CXXOPTS_NODISCARD
+  const std::string&
+  short_name() const
+  {
+    return m_short;
+  }
+
+  CXXOPTS_NODISCARD
+  const std::string&
+  first_long_name() const
+  {
+    return first_or_empty(m_long);
+  }
+
+  CXXOPTS_NODISCARD
+  const std::string&
+  essential_name() const
+  {
+    return m_long.empty() ? m_short : m_long.front();
+  }
+
+  CXXOPTS_NODISCARD
+  const OptionNames &
+  long_names() const
+  {
+    return m_long;
+  }
+
+  std::size_t
+  hash() const
+  {
+    return m_hash;
+  }
+
+  private:
+  std::string m_short{};
+  OptionNames m_long{};
+  String m_desc{};
+  std::shared_ptr<const Value> m_value{};
+  int m_count;
+
+  std::size_t m_hash{};
+};
+
+struct HelpOptionDetails
+{
+  std::string s;
+  OptionNames l;
+  String desc;
+  bool has_default;
+  std::string default_value;
+  bool has_implicit;
+  std::string implicit_value;
+  std::string arg_help;
+  bool is_container;
+  bool is_boolean;
+};
+
+struct HelpGroupDetails
+{
+  std::string name{};
+  std::string description{};
+  std::vector<HelpOptionDetails> options{};
+};
+
+class OptionValue
+{
+  public:
+  void
+  parse
+  (
+    const std::shared_ptr<const OptionDetails>& details,
+    const std::string& text
+  )
+  {
+    ensure_value(details);
+    ++m_count;
+    m_value->parse(text);
+    m_long_names = &details->long_names();
+  }
+
+  void
+  parse_default(const std::shared_ptr<const OptionDetails>& details)
+  {
+    ensure_value(details);
+    m_default = true;
+    m_long_names = &details->long_names();
+    m_value->parse();
+  }
+
+  void
+  parse_no_value(const std::shared_ptr<const OptionDetails>& details)
+  {
+    m_long_names = &details->long_names();
+  }
+
+#if defined(CXXOPTS_NULL_DEREF_IGNORE)
+CXXOPTS_DIAGNOSTIC_PUSH
+CXXOPTS_IGNORE_WARNING("-Wnull-dereference")
+#endif
+
+  CXXOPTS_NODISCARD
+  std::size_t
+  count() const noexcept
+  {
+    return m_count;
+  }
+
+#if defined(CXXOPTS_NULL_DEREF_IGNORE)
+CXXOPTS_DIAGNOSTIC_POP
+#endif
+
+  // TODO: maybe default options should count towards the number of arguments
+  CXXOPTS_NODISCARD
+  bool
+  has_default() const noexcept
+  {
+    return m_default;
   }
 
   template <typename T>
-  std::shared_ptr<Value>
-  value(T& t)
+  const T&
+  as() const
   {
-    return std::make_shared<values::standard_value<T>>(&t);
+    if (m_value == nullptr) {
+        throw_or_mimic<exceptions::option_has_no_value>(
+            m_long_names == nullptr ? "" : first_or_empty(*m_long_names));
+    }
+
+    return CXXOPTS_RTTI_CAST<const values::standard_value<T>&>(*m_value).get();
   }
 
-  class OptionAdder;
+  private:
+  void
+  ensure_value(const std::shared_ptr<const OptionDetails>& details)
+  {
+    if (m_value == nullptr)
+    {
+      m_value = details->make_storage();
+    }
+  }
 
-  class OptionDetails
+
+  const OptionNames * m_long_names = nullptr;
+  // Holding this pointer is safe, since OptionValue's only exist in key-value pairs,
+  // where the key has the string we point to.
+  std::shared_ptr<Value> m_value{};
+  std::size_t m_count = 0;
+  bool m_default = false;
+};
+
+class KeyValue
+{
+  public:
+  KeyValue(std::string key_, std::string value_) noexcept
+  : m_key(std::move(key_))
+  , m_value(std::move(value_))
+  {
+  }
+
+  CXXOPTS_NODISCARD
+  const std::string&
+  key() const
+  {
+    return m_key;
+  }
+
+  CXXOPTS_NODISCARD
+  const std::string&
+  value() const
+  {
+    return m_value;
+  }
+
+  template <typename T>
+  T
+  as() const
+  {
+    T result;
+    values::parse_value(m_value, result);
+    return result;
+  }
+
+  private:
+  std::string m_key;
+  std::string m_value;
+};
+
+using ParsedHashMap = std::unordered_map<std::size_t, OptionValue>;
+using NameHashMap = std::unordered_map<std::string, std::size_t>;
+
+class ParseResult
+{
+  public:
+  class Iterator
   {
     public:
-    OptionDetails
-    (
-      std::string short_,
-      std::string long_,
-      String desc,
-      std::shared_ptr<const Value> val
-    )
-    : m_short(std::move(short_))
-    , m_long(std::move(long_))
-    , m_desc(std::move(desc))
-    , m_value(std::move(val))
-    , m_count(0)
+    using iterator_category = std::forward_iterator_tag;
+    using value_type = KeyValue;
+    using difference_type = void;
+    using pointer = const KeyValue*;
+    using reference = const KeyValue&;
+
+    Iterator() = default;
+    Iterator(const Iterator&) = default;
+
+// GCC complains about m_iter not being initialised in the member
+// initializer list
+CXXOPTS_DIAGNOSTIC_PUSH
+CXXOPTS_IGNORE_WARNING("-Weffc++")
+    Iterator(const ParseResult *pr, bool end=false)
+    : m_pr(pr)
     {
-      m_hash = std::hash<std::string>{}(m_long + m_short);
-    }
-
-    OptionDetails(const OptionDetails& rhs)
-    : m_desc(rhs.m_desc)
-    , m_count(rhs.m_count)
-    {
-      m_value = rhs.m_value->clone();
-    }
-
-    OptionDetails(OptionDetails&& rhs) = default;
-
-    CXXOPTS_NODISCARD
-    const String&
-    description() const
-    {
-      return m_desc;
-    }
-
-    CXXOPTS_NODISCARD
-    const Value&
-    value() const {
-        return *m_value;
-    }
-
-    CXXOPTS_NODISCARD
-    std::shared_ptr<Value>
-    make_storage() const
-    {
-      return m_value->clone();
-    }
-
-    CXXOPTS_NODISCARD
-    const std::string&
-    short_name() const
-    {
-      return m_short;
-    }
-
-    CXXOPTS_NODISCARD
-    const std::string&
-    long_name() const
-    {
-      return m_long;
-    }
-
-    size_t
-    hash() const
-    {
-      return m_hash;
-    }
-
-    private:
-    std::string m_short{};
-    std::string m_long{};
-    String m_desc{};
-    std::shared_ptr<const Value> m_value{};
-    int m_count;
-
-    size_t m_hash{};
-  };
-
-  struct HelpOptionDetails
-  {
-    std::string s;
-    std::string l;
-    String desc;
-    bool has_default;
-    std::string default_value;
-    bool has_implicit;
-    std::string implicit_value;
-    std::string arg_help;
-    bool is_container;
-    bool is_boolean;
-  };
-
-  struct HelpGroupDetails
-  {
-    std::string name{};
-    std::string description{};
-    std::vector<HelpOptionDetails> options{};
-  };
-
-  class OptionValue
-  {
-    public:
-    void
-    parse
-    (
-      const std::shared_ptr<const OptionDetails>& details,
-      const std::string& text
-    )
-    {
-      ensure_value(details);
-      ++m_count;
-      m_value->parse(text);
-      m_long_name = &details->long_name();
-    }
-
-    void
-    parse_default(const std::shared_ptr<const OptionDetails>& details)
-    {
-      ensure_value(details);
-      m_default = true;
-      m_long_name = &details->long_name();
-      m_value->parse();
-    }
-
-    CXXOPTS_NODISCARD
-    size_t
-    count() const noexcept
-    {
-      return m_count;
-    }
-
-    // TODO: maybe default options should count towards the number of arguments
-    CXXOPTS_NODISCARD
-    bool
-    has_default() const noexcept
-    {
-      return m_default;
-    }
-
-    template <typename T>
-    const T&
-    as() const
-    {
-      if (m_value == nullptr) {
-          throw_or_mimic<option_has_no_value_exception>(
-              m_long_name == nullptr ? "" : *m_long_name);
-      }
-
-#ifdef CXXOPTS_NO_RTTI
-      return static_cast<const values::standard_value<T>&>(*m_value).get();
-#else
-      return dynamic_cast<const values::standard_value<T>&>(*m_value).get();
-#endif
-    }
-
-    private:
-    void
-    ensure_value(const std::shared_ptr<const OptionDetails>& details)
-    {
-      if (m_value == nullptr)
+      if (end)
       {
-        m_value = details->make_storage();
-      }
-    }
-
-
-    const std::string* m_long_name = nullptr;
-    // Holding this pointer is safe, since OptionValue's only exist in key-value pairs,
-    // where the key has the string we point to.
-    std::shared_ptr<Value> m_value{};
-    size_t m_count = 0;
-    bool m_default = false;
-  };
-
-  class KeyValue
-  {
-    public:
-    KeyValue(std::string key_, std::string value_)
-    : m_key(std::move(key_))
-    , m_value(std::move(value_))
-    {
-    }
-
-    CXXOPTS_NODISCARD
-    const std::string&
-    key() const
-    {
-      return m_key;
-    }
-
-    CXXOPTS_NODISCARD
-    const std::string&
-    value() const
-    {
-      return m_value;
-    }
-
-    template <typename T>
-    T
-    as() const
-    {
-      T result;
-      values::parse_value(m_value, result);
-      return result;
-    }
-
-    private:
-    std::string m_key;
-    std::string m_value;
-  };
-
-  using ParsedHashMap = std::unordered_map<size_t, OptionValue>;
-  using NameHashMap = std::unordered_map<std::string, size_t>;
-
-  class ParseResult
-  {
-    public:
-
-    ParseResult() {}
-
-    ParseResult(const ParseResult&) = default;
-
-    ParseResult(NameHashMap&& keys, ParsedHashMap&& values, std::vector<KeyValue> sequential, std::vector<std::string>&& unmatched_args)
-    : m_keys(std::move(keys))
-    , m_values(std::move(values))
-    , m_sequential(std::move(sequential))
-    , m_unmatched(std::move(unmatched_args))
-    {
-    }
-
-    ParseResult& operator=(ParseResult&&) = default;
-    ParseResult& operator=(const ParseResult&) = default;
-
-    size_t
-    count(const std::string& o) const
-    {
-      auto iter = m_keys.find(o);
-      if (iter == m_keys.end())
-      {
-        return 0;
-      }
-
-      auto viter = m_values.find(iter->second);
-
-      if (viter == m_values.end())
-      {
-        return 0;
-      }
-
-      return viter->second.count();
-    }
-
-    const OptionValue&
-    operator[](const std::string& option) const
-    {
-      auto iter = m_keys.find(option);
-
-      if (iter == m_keys.end())
-      {
-        throw_or_mimic<option_not_present_exception>(option);
-      }
-
-      auto viter = m_values.find(iter->second);
-
-      if (viter == m_values.end())
-      {
-        throw_or_mimic<option_not_present_exception>(option);
-      }
-
-      return viter->second;
-    }
-
-    const std::vector<KeyValue>&
-    arguments() const
-    {
-      return m_sequential;
-    }
-
-    const std::vector<std::string>&
-    unmatched() const
-    {
-      return m_unmatched;
-    }
-
-    private:
-    NameHashMap m_keys{};
-    ParsedHashMap m_values{};
-    std::vector<KeyValue> m_sequential{};
-    std::vector<std::string> m_unmatched{};
-  };
-
-  struct Option
-  {
-    Option
-    (
-      std::string opts,
-      std::string desc,
-      std::shared_ptr<const Value>  value = ::cxxopts::value<bool>(),
-      std::string arg_help = ""
-    )
-    : opts_(std::move(opts))
-    , desc_(std::move(desc))
-    , value_(std::move(value))
-    , arg_help_(std::move(arg_help))
-    {
-    }
-
-    std::string opts_;
-    std::string desc_;
-    std::shared_ptr<const Value> value_;
-    std::string arg_help_;
-  };
-
-  using OptionMap = std::unordered_map<std::string, std::shared_ptr<OptionDetails>>;
-  using PositionalList = std::vector<std::string>;
-  using PositionalListIterator = PositionalList::const_iterator;
-
-  class OptionParser
-  {
-    public:
-    OptionParser(const OptionMap& options, const PositionalList& positional, bool allow_unrecognised)
-    : m_options(options)
-    , m_positional(positional)
-    , m_allow_unrecognised(allow_unrecognised)
-    {
-    }
-
-    ParseResult
-    parse(int argc, const char* const* argv);
-
-    bool
-    consume_positional(const std::string& a, PositionalListIterator& next);
-
-    void
-    checked_parse_arg
-    (
-      int argc,
-      const char* const* argv,
-      int& current,
-      const std::shared_ptr<OptionDetails>& value,
-      const std::string& name
-    );
-
-    void
-    add_to_option(OptionMap::const_iterator iter, const std::string& option, const std::string& arg);
-
-    void
-    parse_option
-    (
-      const std::shared_ptr<OptionDetails>& value,
-      const std::string& name,
-      const std::string& arg = ""
-    );
-
-    void
-    parse_default(const std::shared_ptr<OptionDetails>& details);
-
-    private:
-
-    void finalise_aliases();
-
-    const OptionMap& m_options;
-    const PositionalList& m_positional;
-
-    std::vector<KeyValue> m_sequential{};
-    bool m_allow_unrecognised;
-
-    ParsedHashMap m_parsed{};
-    NameHashMap m_keys{};
-  };
-
-  class Options
-  {
-    public:
-
-    explicit Options(std::string program, std::string help_string = "")
-    : m_program(std::move(program))
-    , m_help_string(toLocalString(std::move(help_string)))
-    , m_custom_help("[OPTION...]")
-    , m_positional_help("positional parameters")
-    , m_show_positional(false)
-    , m_allow_unrecognised(false)
-    , m_options(std::make_shared<OptionMap>())
-    {
-    }
-
-    Options&
-    positional_help(std::string help_text)
-    {
-      m_positional_help = std::move(help_text);
-      return *this;
-    }
-
-    Options&
-    custom_help(std::string help_text)
-    {
-      m_custom_help = std::move(help_text);
-      return *this;
-    }
-
-    Options&
-    show_positional_help()
-    {
-      m_show_positional = true;
-      return *this;
-    }
-
-    Options&
-    allow_unrecognised_options()
-    {
-      m_allow_unrecognised = true;
-      return *this;
-    }
-
-    ParseResult
-    parse(int argc, const char* const* argv);
-
-    OptionAdder
-    add_options(std::string group = "");
-
-    void
-    add_options
-    (
-      const std::string& group,
-      std::initializer_list<Option> options
-    );
-
-    void
-    add_option
-    (
-      const std::string& group,
-      const Option& option
-    );
-
-    void
-    add_option
-    (
-      const std::string& group,
-      const std::string& s,
-      const std::string& l,
-      std::string desc,
-      const std::shared_ptr<const Value>& value,
-      std::string arg_help
-    );
-
-    //parse positional arguments into the given option
-    void
-    parse_positional(std::string option);
-
-    void
-    parse_positional(std::vector<std::string> options);
-
-    void
-    parse_positional(std::initializer_list<std::string> options);
-
-    template <typename Iterator>
-    void
-    parse_positional(Iterator begin, Iterator end) {
-      parse_positional(std::vector<std::string>{begin, end});
-    }
-
-    std::string
-    help(const std::vector<std::string>& groups = {}) const;
-
-    std::vector<std::string>
-    groups() const;
-
-    const HelpGroupDetails&
-    group_help(const std::string& group) const;
-
-    private:
-
-    void
-    add_one_option
-    (
-      const std::string& option,
-      const std::shared_ptr<OptionDetails>& details
-    );
-
-    String
-    help_one_group(const std::string& group) const;
-
-    void
-    generate_group_help
-    (
-      String& result,
-      const std::vector<std::string>& groups
-    ) const;
-
-    void
-    generate_all_groups_help(String& result) const;
-
-    std::string m_program{};
-    String m_help_string{};
-    std::string m_custom_help{};
-    std::string m_positional_help{};
-    bool m_show_positional;
-    bool m_allow_unrecognised;
-
-    std::shared_ptr<OptionMap> m_options;
-    std::vector<std::string> m_positional{};
-    std::unordered_set<std::string> m_positional_set{};
-
-    //mapping from groups to help options
-    std::map<std::string, HelpGroupDetails> m_help{};
-
-    std::list<OptionDetails> m_option_list{};
-    std::unordered_map<std::string, decltype(m_option_list)::iterator> m_option_map{};
-  };
-
-  class OptionAdder
-  {
-    public:
-
-    OptionAdder(Options& options, std::string group)
-    : m_options(options), m_group(std::move(group))
-    {
-    }
-
-    OptionAdder&
-    operator()
-    (
-      const std::string& opts,
-      const std::string& desc,
-      const std::shared_ptr<const Value>& value
-        = ::cxxopts::value<bool>(),
-      std::string arg_help = ""
-    );
-
-    private:
-    Options& m_options;
-    std::string m_group;
-  };
-
-  namespace
-  {
-    constexpr int OPTION_LONGEST = 30;
-    constexpr int OPTION_DESC_GAP = 2;
-
-    std::basic_regex<char> option_matcher
-      ("--([[:alnum:]][-_[:alnum:]]+)(=(.*))?|-([[:alnum:]]+)");
-
-    std::basic_regex<char> option_specifier
-      ("(([[:alnum:]]),)?[ ]*([[:alnum:]][-_[:alnum:]]*)?");
-
-    String
-    format_option
-    (
-      const HelpOptionDetails& o
-    )
-    {
-      const auto& s = o.s;
-      const auto& l = o.l;
-
-      String result = "  ";
-
-      if (!s.empty())
-      {
-        result += "-" + toLocalString(s);
-        if (!l.empty())
-        {
-          result += ",";
-        }
+        m_sequential = false;
+        m_iter = m_pr->m_defaults.end();
       }
       else
       {
-        result += "   ";
-      }
+        m_sequential = true;
+        m_iter = m_pr->m_sequential.begin();
 
-      if (!l.empty())
-      {
-        result += " --" + toLocalString(l);
-      }
-
-      auto arg = !o.arg_help.empty() ? toLocalString(o.arg_help) : "arg";
-
-      if (!o.is_boolean)
-      {
-        if (o.has_implicit)
+        if (m_iter == m_pr->m_sequential.end())
         {
-          result += " [=" + arg + "(=" + toLocalString(o.implicit_value) + ")]";
-        }
-        else
-        {
-          result += " " + arg;
+          m_sequential = false;
+          m_iter = m_pr->m_defaults.begin();
         }
       }
-
-      return result;
     }
+CXXOPTS_DIAGNOSTIC_POP
 
-    String
-    format_description
-    (
-      const HelpOptionDetails& o,
-      size_t start,
-      size_t width
-    )
+    Iterator& operator++()
     {
-      auto desc = o.desc;
-
-      if (o.has_default && (!o.is_boolean || o.default_value != "false"))
+      ++m_iter;
+      if(m_sequential && m_iter == m_pr->m_sequential.end())
       {
-        if(!o.default_value.empty())
-        {
-          desc += toLocalString(" (default: " + o.default_value + ")");
-        }
-        else
-        {
-          desc += toLocalString(" (default: \"\")");
-        }
+        m_sequential = false;
+        m_iter = m_pr->m_defaults.begin();
+        return *this;
       }
-
-      String result;
-
-      auto current = std::begin(desc);
-      auto startLine = current;
-      auto lastSpace = current;
-
-      auto size = size_t{};
-
-      while (current != std::end(desc))
-      {
-        if (*current == ' ')
-        {
-          lastSpace = current;
-        }
-
-        if (*current == '\n')
-        {
-          startLine = current + 1;
-          lastSpace = startLine;
-        }
-        else if (size > width)
-        {
-          if (lastSpace == startLine)
-          {
-            stringAppend(result, startLine, current + 1);
-            stringAppend(result, "\n");
-            stringAppend(result, start, ' ');
-            startLine = current + 1;
-            lastSpace = startLine;
-          }
-          else
-          {
-            stringAppend(result, startLine, lastSpace);
-            stringAppend(result, "\n");
-            stringAppend(result, start, ' ');
-            startLine = lastSpace + 1;
-            lastSpace = startLine;
-          }
-          size = 0;
-        }
-        else
-        {
-          ++size;
-        }
-
-        ++current;
-      }
-
-      //append whatever is left
-      stringAppend(result, startLine, current);
-
-      return result;
+      return *this;
     }
-  } // namespace
+
+    Iterator operator++(int)
+    {
+      Iterator retval = *this;
+      ++(*this);
+      return retval;
+    }
+
+    bool operator==(const Iterator& other) const
+    {
+      return (m_sequential == other.m_sequential) && (m_iter == other.m_iter);
+    }
+
+    bool operator!=(const Iterator& other) const
+    {
+      return !(*this == other);
+    }
+
+    const KeyValue& operator*()
+    {
+      return *m_iter;
+    }
+
+    const KeyValue* operator->()
+    {
+      return m_iter.operator->();
+    }
+
+    private:
+    const ParseResult* m_pr;
+    std::vector<KeyValue>::const_iterator m_iter;
+    bool m_sequential = true;
+  };
+
+  ParseResult() = default;
+  ParseResult(const ParseResult&) = default;
+
+  ParseResult(NameHashMap&& keys, ParsedHashMap&& values, std::vector<KeyValue> sequential,
+          std::vector<KeyValue> default_opts, std::vector<std::string>&& unmatched_args)
+  : m_keys(std::move(keys))
+  , m_values(std::move(values))
+  , m_sequential(std::move(sequential))
+  , m_defaults(std::move(default_opts))
+  , m_unmatched(std::move(unmatched_args))
+  {
+  }
+
+  ParseResult& operator=(ParseResult&&) = default;
+  ParseResult& operator=(const ParseResult&) = default;
+
+  Iterator
+  begin() const
+  {
+    return Iterator(this);
+  }
+
+  Iterator
+  end() const
+  {
+    return Iterator(this, true);
+  }
+
+  std::size_t
+  count(const std::string& o) const
+  {
+    auto iter = m_keys.find(o);
+    if (iter == m_keys.end())
+    {
+      return 0;
+    }
+
+    auto viter = m_values.find(iter->second);
+
+    if (viter == m_values.end())
+    {
+      return 0;
+    }
+
+    return viter->second.count();
+  }
+
+  const OptionValue&
+  operator[](const std::string& option) const
+  {
+    auto iter = m_keys.find(option);
+
+    if (iter == m_keys.end())
+    {
+      throw_or_mimic<exceptions::requested_option_not_present>(option);
+    }
+
+    auto viter = m_values.find(iter->second);
+
+    if (viter == m_values.end())
+    {
+      throw_or_mimic<exceptions::requested_option_not_present>(option);
+    }
+
+    return viter->second;
+  }
+
+  const std::vector<KeyValue>&
+  arguments() const
+  {
+    return m_sequential;
+  }
+
+  const std::vector<std::string>&
+  unmatched() const
+  {
+    return m_unmatched;
+  }
+
+  const std::vector<KeyValue>&
+  defaults() const
+  {
+    return m_defaults;
+  }
+
+  const std::string
+  arguments_string() const
+  {
+    std::string result;
+    for(const auto& kv: m_sequential)
+    {
+      result += kv.key() + " = " + kv.value() + "\n";
+    }
+    for(const auto& kv: m_defaults)
+    {
+      result += kv.key() + " = " + kv.value() + " " + "(default)" + "\n";
+    }
+    return result;
+  }
+
+  private:
+  NameHashMap m_keys{};
+  ParsedHashMap m_values{};
+  std::vector<KeyValue> m_sequential{};
+  std::vector<KeyValue> m_defaults{};
+  std::vector<std::string> m_unmatched{};
+};
+
+struct Option
+{
+  Option
+  (
+    std::string opts,
+    std::string desc,
+    std::shared_ptr<const Value>  value = ::cxxopts::value<bool>(),
+    std::string arg_help = ""
+  )
+  : opts_(std::move(opts))
+  , desc_(std::move(desc))
+  , value_(std::move(value))
+  , arg_help_(std::move(arg_help))
+  {
+  }
+
+  std::string opts_;
+  std::string desc_;
+  std::shared_ptr<const Value> value_;
+  std::string arg_help_;
+};
+
+using OptionMap = std::unordered_map<std::string, std::shared_ptr<OptionDetails>>;
+using PositionalList = std::vector<std::string>;
+using PositionalListIterator = PositionalList::const_iterator;
+
+class OptionParser
+{
+  public:
+  OptionParser(const OptionMap& options, const PositionalList& positional, bool allow_unrecognised)
+  : m_options(options)
+  , m_positional(positional)
+  , m_allow_unrecognised(allow_unrecognised)
+  {
+  }
+
+  ParseResult
+  parse(int argc, const char* const* argv);
+
+  bool
+  consume_positional(const std::string& a, PositionalListIterator& next);
+
+  void
+  checked_parse_arg
+  (
+    int argc,
+    const char* const* argv,
+    int& current,
+    const std::shared_ptr<OptionDetails>& value,
+    const std::string& name
+  );
+
+  void
+  add_to_option(OptionMap::const_iterator iter, const std::string& option, const std::string& arg);
+
+  void
+  parse_option
+  (
+    const std::shared_ptr<OptionDetails>& value,
+    const std::string& name,
+    const std::string& arg = ""
+  );
+
+  void
+  parse_default(const std::shared_ptr<OptionDetails>& details);
+
+  void
+  parse_no_value(const std::shared_ptr<OptionDetails>& details);
+
+  private:
+
+  void finalise_aliases();
+
+  const OptionMap& m_options;
+  const PositionalList& m_positional;
+
+  std::vector<KeyValue> m_sequential{};
+  std::vector<KeyValue> m_defaults{};
+  bool m_allow_unrecognised;
+
+  ParsedHashMap m_parsed{};
+  NameHashMap m_keys{};
+};
+
+class Options
+{
+  public:
+
+  explicit Options(std::string program_name, std::string help_string = "")
+  : m_program(std::move(program_name))
+  , m_help_string(toLocalString(std::move(help_string)))
+  , m_custom_help("[OPTION...]")
+  , m_positional_help("positional parameters")
+  , m_show_positional(false)
+  , m_allow_unrecognised(false)
+  , m_width(76)
+  , m_tab_expansion(false)
+  , m_options(std::make_shared<OptionMap>())
+  {
+  }
+
+  Options&
+  positional_help(std::string help_text)
+  {
+    m_positional_help = std::move(help_text);
+    return *this;
+  }
+
+  Options&
+  custom_help(std::string help_text)
+  {
+    m_custom_help = std::move(help_text);
+    return *this;
+  }
+
+  Options&
+  show_positional_help()
+  {
+    m_show_positional = true;
+    return *this;
+  }
+
+  Options&
+  allow_unrecognised_options()
+  {
+    m_allow_unrecognised = true;
+    return *this;
+  }
+
+  Options&
+  set_width(std::size_t width)
+  {
+    m_width = width;
+    return *this;
+  }
+
+  Options&
+  set_tab_expansion(bool expansion=true)
+  {
+    m_tab_expansion = expansion;
+    return *this;
+  }
+
+  ParseResult
+  parse(int argc, const char* const* argv);
+
+  OptionAdder
+  add_options(std::string group = "");
+
+  void
+  add_options
+  (
+    const std::string& group,
+    std::initializer_list<Option> options
+  );
+
+  void
+  add_option
+  (
+    const std::string& group,
+    const Option& option
+  );
+
+  void
+  add_option
+  (
+    const std::string& group,
+    const std::string& s,
+    const OptionNames& l,
+    std::string desc,
+    const std::shared_ptr<const Value>& value,
+    std::string arg_help
+  );
+
+  void
+  add_option
+  (
+    const std::string& group,
+    const std::string& short_name,
+    const std::string& single_long_name,
+    std::string desc,
+    const std::shared_ptr<const Value>& value,
+    std::string arg_help
+  )
+  {
+    OptionNames long_names;
+    long_names.emplace_back(single_long_name);
+    add_option(group, short_name, long_names, desc, value, arg_help);
+  }
+
+  //parse positional arguments into the given option
+  void
+  parse_positional(std::string option);
+
+  void
+  parse_positional(std::vector<std::string> options);
+
+  void
+  parse_positional(std::initializer_list<std::string> options);
+
+  template <typename Iterator>
+  void
+  parse_positional(Iterator begin, Iterator end) {
+    parse_positional(std::vector<std::string>{begin, end});
+  }
+
+  std::string
+  help(const std::vector<std::string>& groups = {}, bool print_usage=true) const;
+
+  std::vector<std::string>
+  groups() const;
+
+  const HelpGroupDetails&
+  group_help(const std::string& group) const;
+
+  const std::string& program() const
+  {
+    return m_program;
+  }
+
+  private:
+
+  void
+  add_one_option
+  (
+    const std::string& option,
+    const std::shared_ptr<OptionDetails>& details
+  );
+
+  String
+  help_one_group(const std::string& group) const;
+
+  void
+  generate_group_help
+  (
+    String& result,
+    const std::vector<std::string>& groups
+  ) const;
+
+  void
+  generate_all_groups_help(String& result) const;
+
+  std::string m_program{};
+  String m_help_string{};
+  std::string m_custom_help{};
+  std::string m_positional_help{};
+  bool m_show_positional;
+  bool m_allow_unrecognised;
+  std::size_t m_width;
+  bool m_tab_expansion;
+
+  std::shared_ptr<OptionMap> m_options;
+  std::vector<std::string> m_positional{};
+  std::unordered_set<std::string> m_positional_set{};
+
+  //mapping from groups to help options
+  std::map<std::string, HelpGroupDetails> m_help{};
+};
+
+class OptionAdder
+{
+  public:
+
+  OptionAdder(Options& options, std::string group)
+  : m_options(options), m_group(std::move(group))
+  {
+  }
+
+  OptionAdder&
+  operator()
+  (
+    const std::string& opts,
+    const std::string& desc,
+    const std::shared_ptr<const Value>& value
+      = ::cxxopts::value<bool>(),
+    std::string arg_help = ""
+  );
+
+  private:
+  Options& m_options;
+  std::string m_group;
+};
+
+namespace {
+constexpr std::size_t OPTION_LONGEST = 30;
+constexpr std::size_t OPTION_DESC_GAP = 2;
+
+String
+format_option
+(
+  const HelpOptionDetails& o
+)
+{
+  const auto& s = o.s;
+  const auto& l = first_or_empty(o.l);
+
+  String result = "  ";
+
+  if (!s.empty())
+  {
+    result += "-" + toLocalString(s);
+    if (!l.empty())
+    {
+      result += ",";
+    }
+  }
+  else
+  {
+    result += "   ";
+  }
+
+  if (!l.empty())
+  {
+    result += " --" + toLocalString(l);
+  }
+
+  auto arg = !o.arg_help.empty() ? toLocalString(o.arg_help) : "arg";
+
+  if (!o.is_boolean)
+  {
+    if (o.has_implicit)
+    {
+      result += " [=" + arg + "(=" + toLocalString(o.implicit_value) + ")]";
+    }
+    else
+    {
+      result += " " + arg;
+    }
+  }
+
+  return result;
+}
+
+String
+format_description
+(
+  const HelpOptionDetails& o,
+  std::size_t start,
+  std::size_t allowed,
+  bool tab_expansion
+)
+{
+  auto desc = o.desc;
+
+  if (o.has_default && (!o.is_boolean || o.default_value != "false"))
+  {
+    if(!o.default_value.empty())
+    {
+      desc += toLocalString(" (default: " + o.default_value + ")");
+    }
+    else
+    {
+      desc += toLocalString(" (default: \"\")");
+    }
+  }
+
+  String result;
+
+  if (tab_expansion)
+  {
+    String desc2;
+    auto size = std::size_t{ 0 };
+    for (auto c = std::begin(desc); c != std::end(desc); ++c)
+    {
+      if (*c == '\n')
+      {
+        desc2 += *c;
+        size = 0;
+      }
+      else if (*c == '\t')
+      {
+        auto skip = 8 - size % 8;
+        stringAppend(desc2, skip, ' ');
+        size += skip;
+      }
+      else
+      {
+        desc2 += *c;
+        ++size;
+      }
+    }
+    desc = desc2;
+  }
+
+  desc += " ";
+
+  auto current = std::begin(desc);
+  auto previous = current;
+  auto startLine = current;
+  auto lastSpace = current;
+
+  auto size = std::size_t{};
+
+  bool appendNewLine;
+  bool onlyWhiteSpace = true;
+
+  while (current != std::end(desc))
+  {
+    appendNewLine = false;
+    if (*previous == ' ' || *previous == '\t')
+    {
+      lastSpace = current;
+    }
+    if (*current != ' ' && *current != '\t')
+    {
+      onlyWhiteSpace = false;
+    }
+
+    while (*current == '\n')
+    {
+      previous = current;
+      ++current;
+      appendNewLine = true;
+    }
+
+    if (!appendNewLine && size >= allowed)
+    {
+      if (lastSpace != startLine)
+      {
+        current = lastSpace;
+        previous = current;
+      }
+      appendNewLine = true;
+    }
+
+    if (appendNewLine)
+    {
+      stringAppend(result, startLine, current);
+      startLine = current;
+      lastSpace = current;
+
+      if (*previous != '\n')
+      {
+        stringAppend(result, "\n");
+      }
+
+      stringAppend(result, start, ' ');
+
+      if (*previous != '\n')
+      {
+        stringAppend(result, lastSpace, current);
+      }
+
+      onlyWhiteSpace = true;
+      size = 0;
+    }
+
+    previous = current;
+    ++current;
+    ++size;
+  }
+
+  //append whatever is left but ignore whitespace
+  if (!onlyWhiteSpace)
+  {
+    stringAppend(result, startLine, previous);
+  }
+
+  return result;
+}
+
+} // namespace
 
 inline
 void
@@ -1711,43 +2220,31 @@
   std::string arg_help
 )
 {
-  std::match_results<const char*> result;
-  std::regex_match(opts.c_str(), result, option_specifier);
-
-  if (result.empty())
-  {
-    throw_or_mimic<invalid_option_format_error>(opts);
-  }
-
-  const auto& short_match = result[2];
-  const auto& long_match = result[3];
-
-  if (!short_match.length() && !long_match.length())
-  {
-    throw_or_mimic<invalid_option_format_error>(opts);
-  } else if (long_match.length() == 1 && short_match.length())
-  {
-    throw_or_mimic<invalid_option_format_error>(opts);
-  }
-
-  auto option_names = []
-  (
-    const std::sub_match<const char*>& short_,
-    const std::sub_match<const char*>& long_
-  )
-  {
-    if (long_.length() == 1)
-    {
-      return std::make_tuple(long_.str(), short_.str());
-    }
-    return std::make_tuple(short_.str(), long_.str());
-  }(short_match, long_match);
+  OptionNames option_names = values::parser_tool::split_option_names(opts);
+    // Note: All names will be non-empty; but we must separate the short
+    // (length-1) and longer names
+  std::string short_name {""};
+  auto first_short_name_iter =
+    std::partition(option_names.begin(), option_names.end(),
+      [&](const std::string& name) { return name.length() > 1; }
+    );
+  auto num_length_1_names = (option_names.end() - first_short_name_iter);
+  switch(num_length_1_names) {
+  case 1:
+    short_name = *first_short_name_iter;
+    option_names.erase(first_short_name_iter);
+    break;
+  case 0:
+    break;
+  default:
+    throw_or_mimic<exceptions::invalid_option_format>(opts);
+  };
 
   m_options.add_option
   (
     m_group,
-    std::get<0>(option_names),
-    std::get<1>(option_names),
+    short_name,
+    option_names,
     desc,
     value,
     std::move(arg_help)
@@ -1763,6 +2260,15 @@
   // TODO: remove the duplicate code here
   auto& store = m_parsed[details->hash()];
   store.parse_default(details);
+  m_defaults.emplace_back(details->essential_name(), details->value().get_default_value());
+}
+
+inline
+void
+OptionParser::parse_no_value(const std::shared_ptr<OptionDetails>& details)
+{
+  auto& store = m_parsed[details->hash()];
+  store.parse_no_value(details);
 }
 
 inline
@@ -1778,7 +2284,7 @@
   auto& result = m_parsed[hash];
   result.parse(value, arg);
 
-  m_sequential.emplace_back(value->long_name(), arg);
+  m_sequential.emplace_back(value->essential_name(), arg);
 }
 
 inline
@@ -1800,7 +2306,7 @@
     }
     else
     {
-      throw_or_mimic<missing_argument_exception>(name);
+      throw_or_mimic<exceptions::missing_argument>(name);
     }
   }
   else
@@ -1833,9 +2339,9 @@
     auto iter = m_options.find(*next);
     if (iter != m_options.end())
     {
-      auto& result = m_parsed[iter->second->hash()];
       if (!iter->second->value().is_container())
       {
+        auto& result = m_parsed[iter->second->hash()];
         if (result.count() == 0)
         {
           add_to_option(iter, *next, a);
@@ -1848,7 +2354,7 @@
       add_to_option(iter, *next, a);
       return true;
     }
-    throw_or_mimic<option_not_exists_exception>(*next);
+    throw_or_mimic<exceptions::no_such_option>(*next);
   }
 
   return false;
@@ -1891,7 +2397,7 @@
 {
   int current = 1;
   bool consume_remaining = false;
-  PositionalListIterator next_positional = m_positional.begin();
+  auto next_positional = m_positional.begin();
 
   std::vector<std::string> unmatched;
 
@@ -1903,18 +2409,18 @@
       ++current;
       break;
     }
+    bool matched = false;
+    values::parser_tool::ArguDesc argu_desc =
+        values::parser_tool::ParseArgument(argv[current], matched);
 
-    std::match_results<const char*> result;
-    std::regex_match(argv[current], result, option_matcher);
-
-    if (result.empty())
+    if (!matched)
     {
       //not a flag
 
       // but if it starts with a `-`, then it's an error
       if (argv[current][0] == '-' && argv[current][1] != '\0') {
         if (!m_allow_unrecognised) {
-          throw_or_mimic<option_syntax_exception>(argv[current]);
+          throw_or_mimic<exceptions::invalid_option_syntax>(argv[current]);
         }
       }
 
@@ -1925,16 +2431,16 @@
       }
       else
       {
-        unmatched.push_back(argv[current]);
+        unmatched.emplace_back(argv[current]);
       }
       //if we return from here then it was parsed successfully, so continue
     }
     else
     {
       //short or long option?
-      if (result[4].length() != 0)
+      if (argu_desc.grouping)
       {
-        const std::string& s = result[4];
+        const std::string& s = argu_desc.arg_name;
 
         for (std::size_t i = 0; i != s.size(); ++i)
         {
@@ -1945,10 +2451,11 @@
           {
             if (m_allow_unrecognised)
             {
+              unmatched.push_back(std::string("-") + s[i]);
               continue;
             }
             //error
-            throw_or_mimic<option_not_exists_exception>(name);
+            throw_or_mimic<exceptions::no_such_option>(name);
           }
 
           auto value = iter->second;
@@ -1962,16 +2469,22 @@
           {
             parse_option(value, name, value->value().get_implicit_value());
           }
+          else if (i + 1 < s.size())
+          {
+            std::string arg_value = s.substr(i + 1);
+            parse_option(value, name, arg_value);
+            break;
+          }
           else
           {
             //error
-            throw_or_mimic<option_requires_argument_exception>(name);
+            throw_or_mimic<exceptions::option_requires_argument>(name);
           }
         }
       }
-      else if (result[1].length() != 0)
+      else if (argu_desc.arg_name.length() != 0)
       {
-        const std::string& name = result[1];
+        const std::string& name = argu_desc.arg_name;
 
         auto iter = m_options.find(name);
 
@@ -1980,22 +2493,22 @@
           if (m_allow_unrecognised)
           {
             // keep unrecognised options in argument list, skip to next argument
-            unmatched.push_back(argv[current]);
+            unmatched.emplace_back(argv[current]);
             ++current;
             continue;
           }
           //error
-          throw_or_mimic<option_not_exists_exception>(name);
+          throw_or_mimic<exceptions::no_such_option>(name);
         }
 
         auto opt = iter->second;
 
         //equals provided for long option?
-        if (result[2].length() != 0)
+        if (argu_desc.set_value)
         {
           //parse the option given
 
-          parse_option(opt, name, result[3]);
+          parse_option(opt, name, argu_desc.value);
         }
         else
         {
@@ -2016,8 +2529,13 @@
 
     auto& store = m_parsed[detail->hash()];
 
-    if(value.has_default() && !store.count() && !store.has_default()){
-      parse_default(detail);
+    if (value.has_default()) {
+      if (!store.count() && !store.has_default()) {
+        parse_default(detail);
+      }
+    }
+    else {
+      parse_no_value(detail);
     }
   }
 
@@ -2033,14 +2551,14 @@
 
     //adjust argv for any that couldn't be swallowed
     while (current != argc) {
-      unmatched.push_back(argv[current]);
+      unmatched.emplace_back(argv[current]);
       ++current;
     }
   }
 
   finalise_aliases();
 
-  ParseResult parsed(std::move(m_keys), std::move(m_parsed), std::move(m_sequential), std::move(unmatched));
+  ParseResult parsed(std::move(m_keys), std::move(m_parsed), std::move(m_sequential), std::move(m_defaults), std::move(unmatched));
   return parsed;
 }
 
@@ -2053,7 +2571,9 @@
     auto& detail = *option.second;
     auto hash = detail.hash();
     m_keys[detail.short_name()] = hash;
-    m_keys[detail.long_name()] = hash;
+    for(const auto& long_name : detail.long_names()) {
+      m_keys[long_name] = hash;
+    }
 
     m_parsed.emplace(hash, OptionValue());
   }
@@ -2076,7 +2596,7 @@
 (
   const std::string& group,
   const std::string& s,
-  const std::string& l,
+  const OptionNames& l,
   std::string desc,
   const std::shared_ptr<const Value>& value,
   std::string arg_help
@@ -2090,16 +2610,10 @@
     add_one_option(s, option);
   }
 
-  if (!l.empty())
-  {
-    add_one_option(l, option);
+  for(const auto& long_name : l) {
+    add_one_option(long_name, option);
   }
 
-  m_option_list.push_front(*option.get());
-  auto iter = m_option_list.begin();
-  m_option_map[s] = iter;
-  m_option_map[l] = iter;
-
   //add the help details
   auto& options = m_help[group];
 
@@ -2123,7 +2637,7 @@
 
   if (!in.second)
   {
-    throw_or_mimic<option_exists_error>(option);
+    throw_or_mimic<exceptions::option_already_exists>(option);
   }
 }
 
@@ -2141,7 +2655,7 @@
 
   OptionHelp format;
 
-  size_t longest = 0;
+  std::size_t longest = 0;
 
   String result;
 
@@ -2152,7 +2666,8 @@
 
   for (const auto& o : group->second.options)
   {
-    if (m_positional_set.find(o.l) != m_positional_set.end() &&
+    if (o.l.size() &&
+        m_positional_set.find(o.l.front()) != m_positional_set.end() &&
         !m_show_positional)
     {
       continue;
@@ -2162,22 +2677,26 @@
     longest = (std::max)(longest, stringLength(s));
     format.push_back(std::make_pair(s, String()));
   }
+  longest = (std::min)(longest, OPTION_LONGEST);
 
-  longest = (std::min)(longest, static_cast<size_t>(OPTION_LONGEST));
-
-  //widest allowed description
-  auto allowed = size_t{76} - longest - OPTION_DESC_GAP;
+  //widest allowed description -- min 10 chars for helptext/line
+  std::size_t allowed = 10;
+  if (m_width > allowed + longest + OPTION_DESC_GAP)
+  {
+    allowed = m_width - longest - OPTION_DESC_GAP;
+  }
 
   auto fiter = format.begin();
   for (const auto& o : group->second.options)
   {
-    if (m_positional_set.find(o.l) != m_positional_set.end() &&
+    if (o.l.size() &&
+        m_positional_set.find(o.l.front()) != m_positional_set.end() &&
         !m_show_positional)
     {
       continue;
     }
 
-    auto d = format_description(o, longest + OPTION_DESC_GAP, allowed);
+    auto d = format_description(o, longest + OPTION_DESC_GAP, allowed, m_tab_expansion);
 
     result += fiter->first;
     if (stringLength(fiter->first) > longest)
@@ -2208,7 +2727,7 @@
   const std::vector<std::string>& print_groups
 ) const
 {
-  for (size_t i = 0; i != print_groups.size(); ++i)
+  for (std::size_t i = 0; i != print_groups.size(); ++i)
   {
     const String& group_help_text = help_one_group(print_groups[i]);
     if (empty(group_help_text))
@@ -2228,22 +2747,34 @@
 Options::generate_all_groups_help(String& result) const
 {
   std::vector<std::string> all_groups;
-  all_groups.reserve(m_help.size());
 
-  for (const auto& group : m_help)
-  {
-    all_groups.push_back(group.first);
-  }
+  std::transform(
+    m_help.begin(),
+    m_help.end(),
+    std::back_inserter(all_groups),
+    [] (const std::map<std::string, HelpGroupDetails>::value_type& group)
+    {
+      return group.first;
+    }
+  );
 
   generate_group_help(result, all_groups);
 }
 
 inline
 std::string
-Options::help(const std::vector<std::string>& help_groups) const
+Options::help(const std::vector<std::string>& help_groups, bool print_usage) const
 {
-  String result = m_help_string + "\nUsage:\n  " +
-    toLocalString(m_program) + " " + toLocalString(m_custom_help);
+  String result = m_help_string;
+  if(print_usage)
+  {
+    result+= "\nUsage:\n  " + toLocalString(m_program);
+  }
+
+  if (!m_custom_help.empty())
+  {
+    result += " " + toLocalString(m_custom_help);
+  }
 
   if (!m_positional.empty() && !m_positional_help.empty()) {
     result += " " + toLocalString(m_positional_help);
