.. Copyright (c) 2026 Tobias Erbsland - Erbsland DEV. https://erbsland.dev SPDX-License-Identifier: Apache-2.0 .. index:: single: Options; Option Values single: OptionValues single: OptionValue .. _options-option-values: ************* Option Values ************* :cpp:class:`OptionValues ` is the parsed result of a successful command-line parse. This page explains how values are assigned, how aliases work, and how application code should read flags, counts, lists, defaults, and selected module names. How the Parser Fills the Result =============================== After the parser has selected the active root and module sets, it assigns command-line arguments to the matching definitions. For each option, every accepted name and lookup alias maps to the same :cpp:class:`OptionValue ` instance. For a definition such as ``{"-v", "--verbose", "verbose"}``, all three names refer to the same parsed value. Application code normally reads the dashless alias, because it is stable even if the command-line spelling changes. Defaults from option definitions are inserted when the user omits a value. Those default values are present in :cpp:class:`OptionValues ` just like user-supplied values, except that they do not have a source argument index. .. erbsland-demo:: :source: option/OptionValues/main.cpp :exec: option/option_values :source-sha256: 744eccb15abaff817a33ab03770c152788dfe94467de5646614a5f66bb1a8590 .. code-block:: cpp /// `OptionValues` stores parsed values under every accepted name of an option. /// /// Command line spellings and dashless lookup aliases point to the same `OptionValue` instance. /// Typed getters return flags, flag counts, integers, text, and lists without forcing application code to inspect the /// underlying variant directly. auto optionValues() -> el::ExitCode { auto options = el::Options::create(); auto info = el::ApplicationInfo{}; info.setApplicationName("Laboratory Values"_el); info.setApplicationVersion(el::Version{0, 8, 0}); options->setApplicationInfo(info); options->addOption({"-v"_el, "--verbose"_el, "verbose"_el}).setHelpDescription("Increases the detail level."_el); options->addOption({"-p"_el, "--point"_el, "point"_el}) .setType(el::OptionType::Text) .setMaximum(el::ArgumentCount{4U}) .setHelpDescription("Measurement point. Can appear up to four times."_el); options->addOption({"--level"_el, "level"_el}) .setType(el::OptionType::Integer) .setDefaultValue(el::OptionInteger{2}) .setHelpDescription("Default observation level."_el); options->addOption("instrument"_el).setRequired().setHelpDescription("Primary instrument."_el); auto manager = el::OptionManager{options}; auto arguments = makeArgs({"valores"_el, "-vv"_el, "--point"_el, "entrada"_el, "-p"_el, "lente"_el, "microscopio"_el}); const auto values = manager.parseOrThrow(arguments); const auto verboseByLongName = values->value("--verbose"_el); const auto verboseByAlias = values->value("verbose"_el); const auto points = values->getTextList("point"_el); el::io::printLine("same object: "_el, el::BooleanFormat::yesNo(), verboseByLongName == verboseByAlias); el::io::printLine("verbose count: "_el, values->getFlagCount("verbose"_el)); el::io::printLine("instrument: "_el, values->getText("instrument"_el)); el::io::printLine("level: "_el, values->getInteger("level"_el)); auto pointList = el::StringList{}; for (const auto &point : points) { pointList.append(point.copy()); } el::io::printLine("points: "_el, pointList.join(", "_el)); el::io::printLine("first index: "_el, values->value("point"_el)->argumentIndex().toSizeT()); return el::ExitCode::success(); } .. erbsland-ansi:: :escape-char: ␛ same object: yes verbose count: 2 instrument: microscopio level: 2 points: entrada, lente first index: 3 .. erbsland-demo-end:: Use Typed Getters for Normal Code ================================= The typed getters are the easiest and safest way to read parsed values: * :cpp:func:`getFlag() ` tests for valueless flag storage. * :cpp:func:`getFlagCount() ` reads how often a flag appeared. * ``getBoolean()`` reads a Boolean value. * :cpp:func:`getInteger() ` reads an integer. * :cpp:func:`getText() ` reads text, choice, or marked sensitive text. * :cpp:func:`getIntegerList() ` reads repeated integers. * ``getBooleanList()`` reads repeated Boolean values. * :cpp:func:`getTextList() ` reads repeated text values. Each getter accepts a fallback value. Use static defaults in the option definition when the default is part of the command-line contract and should appear in help. Use getter defaults when the fallback is local to one code path or depends on runtime state. Flags, Lists, and Module Names ============================== Repeated flags are stored as a count. This makes ``-vv`` and ``-v -v`` useful for verbosity levels without creating extra options. Boolean values are separate typed scalars or ordered lists and never contribute to a flag count. For an option using ``AcceptAsFlag``, a bare occurrence returns true through ``getFlag()``, while a valued occurrence is available only through its declared typed getter. Repeated Boolean and integer values use standard-library vectors; repeated text values use :cpp:type:`StringList `. The parser preserves the order in which the values were assigned to that option. If modules are used, :cpp:func:`moduleName() ` returns the selected module name. Applications that do not use module main functions can dispatch manually with this value. .. erbsland-demo:: :source: option/OptionValueAccess/main.cpp :exec: option/option_value_access :source-sha256: 09e86783add390fdea58d16cdbfdb3282bdb5fb63239e77112c192a21db978c9 .. code-block:: cpp /// `OptionValues` is the parsed result map produced by `OptionManager`. /// /// Every command-line spelling and lookup alias for an option points to the same `OptionValue` object. /// Typed getters read flags, flag counts, integers, text, and repeated value lists. /// Defaults can come from the option definition or from the getter call, and module-aware tools can inspect /// `moduleName()` when dispatching manually. auto optionValueAccess() -> el::ExitCode { auto manager = el::OptionManager{createValueOptions()}; auto arguments = makeArgs( {"night-values"_el, "count"_el, "-vv"_el, "--route"_el, "forest-edge"_el, "-r"_el, "pond"_el, "dune"_el}); const auto values = manager.parseOrThrow(arguments); const auto routes = values->getTextList("route"_el); auto routeList = el::StringList{}; for (const auto &route : routes) { routeList.append(route.copy()); } el::io::printLine("module: "_el, values->moduleName()); el::io::printLine("area: "_el, values->getText("area"_el)); el::io::printLine("verbose count: "_el, values->getFlagCount("verbose"_el)); el::io::printLine("routes: "_el, routeList.join(", "_el)); el::io::printLine("level: "_el, values->getInteger("level"_el)); el::io::printLine("profile: "_el, values->getText("profile"_el, "night"_el)); el::io::printLine("route argument index: "_el, values->value("route"_el)->argumentIndex().toSizeT()); return el::ExitCode::success(); } .. erbsland-ansi:: :escape-char: ␛ module: count area: dune verbose count: 2 routes: forest-edge, pond level: 2 profile: night route argument index: 4 .. erbsland-demo-end:: Inspect Raw OptionValue Objects =============================== Use :cpp:func:`value() ` when application code needs details beyond the typed getter result. The returned :cpp:class:`OptionValue ` stores the source option, the concrete storage variant, and the argument indexes that produced the value. Raw values are useful for diagnostics, telemetry, or tooling that needs to explain where a setting came from. Most application logic should still prefer typed getters, because they express the expected value kind directly.