CLI11
2.7.2
C++11 Command Line Interface Parser
Toggle main menu visibility
Loading...
Searching...
No Matches
TypeTools_inl.hpp
1
// Copyright (c) 2017-2026, University of Cincinnati, developed by Henry Schreiner
2
// under NSF AWARD 1414736 and by the respective contributors.
3
// All rights reserved.
4
//
5
// SPDX-License-Identifier: BSD-3-Clause
6
7
#pragma once
8
9
// IWYU pragma: private, include "CLI/CLI.hpp"
10
11
// This include is only needed for IDEs to discover symbols
12
#include "../TypeTools.hpp"
13
14
#include "../StringTools.hpp"
15
16
// [CLI11:public_includes:set]
17
#include <cerrno>
18
#include <cstdint>
19
#include <cstdlib>
20
#include <limits>
21
#include <sstream>
22
#include <string>
23
#include <utility>
24
#include <vector>
25
// [CLI11:public_includes:end]
26
27
namespace
CLI {
28
// [CLI11:type_tools_inl_hpp:verbatim]
29
30
namespace
detail {
31
32
CLI11_INLINE std::int64_t to_flag_value(std::string val)
noexcept
{
33
static
const
std::string trueString(
"true"
);
34
static
const
std::string falseString(
"false"
);
35
if
(val == trueString) {
36
return
1;
37
}
38
if
(val == falseString) {
39
return
-1;
40
}
41
val = detail::to_lower(std::move(val));
42
std::int64_t ret = 0;
43
if
(val.size() == 1) {
44
if
(val[0] >=
'1'
&& val[0] <=
'9'
) {
45
return
(
static_cast<
std::int64_t
>
(val[0]) -
'0'
);
46
}
47
switch
(val[0]) {
48
case
'0'
:
49
case
'f'
:
50
case
'n'
:
51
case
'-'
:
52
ret = -1;
53
break
;
54
case
't'
:
55
case
'y'
:
56
case
'+'
:
57
ret = 1;
58
break
;
59
default
:
60
errno = EINVAL;
61
return
-1;
62
}
63
return
ret;
64
}
65
if
(val == trueString || val ==
"on"
|| val ==
"yes"
|| val ==
"enable"
) {
66
ret = 1;
67
}
else
if
(val == falseString || val ==
"off"
|| val ==
"no"
|| val ==
"disable"
) {
68
ret = -1;
69
}
else
{
70
char
*loc_ptr{
nullptr
};
71
ret = std::strtoll(val.c_str(), &loc_ptr, 0);
72
if
(loc_ptr != (val.c_str() + val.size()) && errno == 0) {
73
errno = EINVAL;
74
}
75
}
76
return
ret;
77
}
78
79
CLI11_INLINE std::string sum_string_vector(
const
std::vector<std::string> &values) {
80
// First try a pure integer sum so that large integral totals (>= 1e16, or beyond the 2^53 mantissa of
81
// double) are preserved exactly and rendered as a plain integer rather than scientific notation
82
std::int64_t ival{0};
83
bool
int_sum{
true
};
84
for
(
const
auto
&arg : values) {
85
std::int64_t tv{0};
86
if
(!integral_conversion(arg, tv)) {
87
int_sum =
false
;
88
break
;
89
}
90
// detect signed overflow before performing the addition since signed overflow is undefined behavior
91
if
((tv > 0 && ival > (std::numeric_limits<std::int64_t>::max)() - tv) ||
92
(tv < 0 && ival < (std::numeric_limits<std::int64_t>::min)() - tv)) {
93
int_sum =
false
;
94
break
;
95
}
96
ival += tv;
97
}
98
if
(int_sum) {
99
return
std::to_string(ival);
100
}
101
102
double
val{0.0};
103
bool
fail{
false
};
104
std::string output;
105
for
(
const
auto
&arg : values) {
106
double
tv{0.0};
107
auto
comp = lexical_cast(arg, tv);
108
if
(!comp) {
109
errno = 0;
110
auto
fv = detail::to_flag_value(arg);
111
fail = (errno != 0);
112
if
(fail) {
113
break
;
114
}
115
tv =
static_cast<
double
>
(fv);
116
}
117
val += tv;
118
}
119
if
(fail) {
120
for
(
const
auto
&arg : values) {
121
output.append(arg);
122
}
123
}
else
{
124
std::ostringstream out;
125
out.precision(16);
126
out << val;
127
output = out.str();
128
}
129
return
output;
130
}
131
132
}
// namespace detail
133
// [CLI11:type_tools_inl_hpp:end]
134
}
// namespace CLI
include
CLI
impl
TypeTools_inl.hpp
Generated by
1.17.0