Skip to content

Commit 3ee5e03

Browse files
committed
Use [[unlikely]] for throw
1 parent b8a5ca8 commit 3ee5e03

6 files changed

+78
-60
lines changed

Argo/ArgoMetaAssigner.cc

+24-20
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ ARGO_ALWAYS_INLINE constexpr auto ValiadicArgAssign(
8282
template <class Arg>
8383
ARGO_ALWAYS_INLINE constexpr auto NLengthArgAssign(span<string_view>& values)
8484
-> void {
85-
if (Arg::nargs.nargs > values.size()) {
85+
if (Arg::nargs.nargs > values.size()) [[unlikely]] {
8686
throw Argo::InvalidArgument(
8787
format("Argument {}: invalid argument {}", Arg::name.getKey(), values));
8888
}
@@ -130,7 +130,7 @@ ARGO_ALWAYS_INLINE constexpr auto PArgAssigner(span<string_view> values)
130130
return true;
131131
}
132132
if constexpr (Arg::nargs.nargs == 1) {
133-
if (values.empty()) {
133+
if (values.empty()) [[unlikely]] {
134134
throw Argo::InvalidArgument(
135135
format("Argument {} should take exactly one value but zero",
136136
Arg::name.getKey()));
@@ -160,10 +160,12 @@ ARGO_ALWAYS_INLINE constexpr auto AssignOneArg(const string_view& key,
160160
throw Argo::InvalidArgument(format("Duplicated argument {}", key));
161161
}
162162
if constexpr (derived_from<Head, FlagArgTag>) {
163-
if (!values.empty()) {
164-
if constexpr (is_same_v<PArgs, tuple<>>) {
163+
if constexpr (is_same_v<PArgs, tuple<>>) {
164+
if (!values.empty()) [[unlikely]] {
165165
throw Argo::InvalidArgument(format("Flag {} can not take value", key));
166-
} else {
166+
}
167+
} else {
168+
if (!values.empty()) {
167169
PArgAssigner<PArgs>(values);
168170
}
169171
}
@@ -189,14 +191,14 @@ ARGO_ALWAYS_INLINE constexpr auto AssignOneArg(const string_view& key,
189191
ValiadicArgAssign<Head>(values);
190192
return true;
191193
} else if constexpr (Head::nargs.nargs_char == '+') {
192-
if (values.empty()) {
194+
if (values.empty()) [[unlikely]] {
193195
throw Argo::InvalidArgument(
194196
format("Argument {} should take more than one value", key));
195197
}
196198
ValiadicArgAssign<Head>(values);
197199
return true;
198200
} else if constexpr (Head::nargs.nargs == 1) {
199-
if (values.empty()) {
201+
if (values.empty()) [[unlikely]] {
200202
throw Argo::InvalidArgument(
201203
format("Argument {} should take exactly one value but zero", key));
202204
}
@@ -219,27 +221,29 @@ ARGO_ALWAYS_INLINE constexpr auto AssignOneArg(const string_view& key,
219221
template <class Args, class PArgs>
220222
ARGO_ALWAYS_INLINE constexpr auto assignArg(const string_view& key,
221223
const span<string_view>& values) {
222-
[&key, &values]<size_t... Is>(index_sequence<Is...>)
223-
ARGO_ALWAYS_INLINE -> void {
224-
if (!(... ||
225-
(tuple_element_t<Is, Args>::name.getKey() == key and
226-
AssignOneArg<tuple_element_t<Is, Args>, PArgs>(key, values)))) {
227-
throw Argo::InvalidArgument(format("Invalid argument {}", key));
228-
}
229-
}(make_index_sequence<tuple_size_v<Args>>());
224+
[&key,
225+
&values]<size_t... Is>(index_sequence<Is...>) ARGO_ALWAYS_INLINE -> void {
226+
if (!(... || (tuple_element_t<Is, Args>::name.getKey() == key and
227+
AssignOneArg<tuple_element_t<Is, Args>, PArgs>(key, values))))
228+
[[unlikely]] {
229+
throw Argo::InvalidArgument(format("Invalid argument {}", key));
230+
}
231+
}(make_index_sequence<tuple_size_v<Args>>());
230232
}
231233

232234
template <class Arguments, class PArgs>
233235
ARGO_ALWAYS_INLINE constexpr auto Assigner(string_view key,
234236
const span<string_view>& values)
235237
-> void {
236-
if (key.empty()) {
237-
if constexpr (!is_same_v<PArgs, tuple<>>) {
238-
if (!PArgAssigner<PArgs>(values)) {
238+
if constexpr (!is_same_v<PArgs, tuple<>>) {
239+
if (key.empty()) {
240+
if (!PArgAssigner<PArgs>(values)) [[unlikely]] {
239241
throw InvalidArgument("Duplicated positional argument");
240242
}
241243
return;
242-
} else {
244+
}
245+
} else {
246+
if (key.empty()) [[unlikely]] {
243247
throw Argo::InvalidArgument(format("Invalid argument {}", key));
244248
}
245249
}
@@ -261,7 +265,7 @@ ARGO_ALWAYS_INLINE constexpr auto ShortArgAssigner(
261265
auto value = vector<string_view>{key.substr(i + 1)};
262266
assignArg<Arguments, PArgs>(found_key, value);
263267
return has_help;
264-
} else {
268+
} else [[unlikely]] {
265269
throw Argo::InvalidArgument(
266270
format("Invalid Flag argument {} {}", key[i], key.substr(i + 1)));
267271
}

Argo/ArgoMetaLookup.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ ARGO_ALWAYS_INLINE constexpr auto GetkeyFromShortKey(char key) {
3131
}
3232
return false;
3333
}() || ...);
34-
}(make_type_sequence_t<Arguments>())) {
34+
}(make_type_sequence_t<Arguments>())) [[likely]] {
3535
return make_tuple(name, is_flag);
3636
}
3737
throw ParserInternalError("Fail to lookup");

Argo/ArgoParser.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ class Parser {
251251

252252
template <ArgName Name>
253253
constexpr auto getArg() {
254-
if (!this->parsed_) {
254+
if (!this->parsed_) [[unlikely]] {
255255
throw ParseError("Parser did not parse argument, call parse first");
256256
}
257257
if constexpr (!is_same_v<PArgs, tuple<>>) {
@@ -282,7 +282,7 @@ class Parser {
282282

283283
template <ArgName Name>
284284
constexpr auto isAssigned() {
285-
if (!this->parsed_) {
285+
if (!this->parsed_) [[unlikely]] {
286286
throw ParseError("Parser did not parse argument, call parse first");
287287
}
288288
if constexpr (!is_same_v<PArgs, tuple<>>) {

Argo/ArgoParserImpl.cc

+10-5
Original file line numberDiff line numberDiff line change
@@ -119,17 +119,20 @@ constexpr auto Parser<ID, Args, PArgs, HArg, SubParsers>::parse(int argc,
119119
} else {
120120
is_flag = true;
121121
}
122+
122123
if (i != 1 and is_flag) {
123124
if (!key.empty()) {
124125
goto SetArgSection;
125126
}
126127
if (!short_keys.empty()) {
127128
goto SetShortArgSection;
128129
}
129-
if (!values.empty()) {
130-
if constexpr (!is_same_v<PArgs, tuple<>>) {
130+
if constexpr (!is_same_v<PArgs, tuple<>>) {
131+
if (!values.empty()) {
131132
goto SetArgSection;
132-
} else {
133+
}
134+
} else {
135+
if (!values.empty()) [[unlikely]] {
133136
throw InvalidArgument(
134137
format("Invalid positional argument: {}", values));
135138
}
@@ -145,9 +148,11 @@ constexpr auto Parser<ID, Args, PArgs, HArg, SubParsers>::parse(int argc,
145148
values.clear();
146149
End:
147150
}
148-
if (i == cmd_end_pos) [[unlikely]] {
151+
152+
if (i == cmd_end_pos) {
149153
break;
150154
}
155+
151156
if (is_flag) {
152157
if (arg.size() > 1 and arg.at(1) == '-') {
153158
if (arg.contains('=')) [[unlikely]] {
@@ -176,7 +181,7 @@ constexpr auto Parser<ID, Args, PArgs, HArg, SubParsers>::parse(int argc,
176181
}
177182
});
178183

179-
if (!required_keys.empty()) {
184+
if (!required_keys.empty()) [[unlikely]] {
180185
throw InvalidArgument(format("Requried {}", required_keys));
181186
}
182187
if (subcmd_found_idx != -1) {

Argo/ArgoValidation.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export struct ValidationBase {
1616
template <class T>
1717
auto operator()(const T& value, span<string_view> values,
1818
string_view option_name) -> void {
19-
if (!this->isValid(value, values)) {
19+
if (!this->isValid(value, values)) [[unlikely]] {
2020
throw ValidationError(
2121
format("Option {} has invalid value {}", option_name, value));
2222
}
@@ -101,7 +101,7 @@ struct Range final : public ValidationBase {
101101
template <class U>
102102
auto operator()(const U& value, span<string_view> values,
103103
string_view option_name) -> void {
104-
if (!this->isValid(value, values)) {
104+
if (!this->isValid(value, values)) [[unlikely]] {
105105
throw ValidationError(
106106
format("Option {} has invalid value {}", option_name, value));
107107
}

include/Argo/Argo.hh

+39-30
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ struct ValidationBase {
199199
template <class T>
200200
auto operator()(const T& value, span<string_view> values,
201201
string_view option_name) -> void {
202-
if (!this->isValid(value, values)) {
202+
if (!this->isValid(value, values)) [[unlikely]] {
203203
throw ValidationError(
204204
format("Option {} has invalid value {}", option_name, value));
205205
}
@@ -284,7 +284,7 @@ struct Range final : public ValidationBase {
284284
template <class U>
285285
auto operator()(const U& value, span<string_view> values,
286286
string_view option_name) -> void {
287-
if (!this->isValid(value, values)) {
287+
if (!this->isValid(value, values)) [[unlikely]] {
288288
throw ValidationError(
289289
format("Option {} has invalid value {}", option_name, value));
290290
}
@@ -833,7 +833,7 @@ ARGO_ALWAYS_INLINE constexpr auto GetkeyFromShortKey(char key) {
833833
}
834834
return false;
835835
}() || ...);
836-
}(make_type_sequence_t<Arguments>())) {
836+
}(make_type_sequence_t<Arguments>())) [[likely]] {
837837
return make_tuple(name, is_flag);
838838
}
839839
throw ParserInternalError("Fail to lookup");
@@ -956,7 +956,7 @@ ARGO_ALWAYS_INLINE constexpr auto ValiadicArgAssign(
956956
template <class Arg>
957957
ARGO_ALWAYS_INLINE constexpr auto NLengthArgAssign(span<string_view>& values)
958958
-> void {
959-
if (Arg::nargs.nargs > values.size()) {
959+
if (Arg::nargs.nargs > values.size()) [[unlikely]] {
960960
throw Argo::InvalidArgument(
961961
format("Argument {}: invalid argument {}", Arg::name.getKey(), values));
962962
}
@@ -1004,7 +1004,7 @@ ARGO_ALWAYS_INLINE constexpr auto PArgAssigner(span<string_view> values)
10041004
return true;
10051005
}
10061006
if constexpr (Arg::nargs.nargs == 1) {
1007-
if (values.empty()) {
1007+
if (values.empty()) [[unlikely]] {
10081008
throw Argo::InvalidArgument(
10091009
format("Argument {} should take exactly one value but zero",
10101010
Arg::name.getKey()));
@@ -1034,10 +1034,12 @@ ARGO_ALWAYS_INLINE constexpr auto AssignOneArg(const string_view& key,
10341034
throw Argo::InvalidArgument(format("Duplicated argument {}", key));
10351035
}
10361036
if constexpr (derived_from<Head, FlagArgTag>) {
1037-
if (!values.empty()) {
1038-
if constexpr (is_same_v<PArgs, tuple<>>) {
1037+
if constexpr (is_same_v<PArgs, tuple<>>) {
1038+
if (!values.empty()) [[unlikely]] {
10391039
throw Argo::InvalidArgument(format("Flag {} can not take value", key));
1040-
} else {
1040+
}
1041+
} else {
1042+
if (!values.empty()) {
10411043
PArgAssigner<PArgs>(values);
10421044
}
10431045
}
@@ -1063,14 +1065,14 @@ ARGO_ALWAYS_INLINE constexpr auto AssignOneArg(const string_view& key,
10631065
ValiadicArgAssign<Head>(values);
10641066
return true;
10651067
} else if constexpr (Head::nargs.nargs_char == '+') {
1066-
if (values.empty()) {
1068+
if (values.empty()) [[unlikely]] {
10671069
throw Argo::InvalidArgument(
10681070
format("Argument {} should take more than one value", key));
10691071
}
10701072
ValiadicArgAssign<Head>(values);
10711073
return true;
10721074
} else if constexpr (Head::nargs.nargs == 1) {
1073-
if (values.empty()) {
1075+
if (values.empty()) [[unlikely]] {
10741076
throw Argo::InvalidArgument(
10751077
format("Argument {} should take exactly one value but zero", key));
10761078
}
@@ -1093,27 +1095,29 @@ ARGO_ALWAYS_INLINE constexpr auto AssignOneArg(const string_view& key,
10931095
template <class Args, class PArgs>
10941096
ARGO_ALWAYS_INLINE constexpr auto assignArg(const string_view& key,
10951097
const span<string_view>& values) {
1096-
[&key, &values]<size_t... Is>(index_sequence<Is...>)
1097-
ARGO_ALWAYS_INLINE -> void {
1098-
if (!(... ||
1099-
(tuple_element_t<Is, Args>::name.getKey() == key and
1100-
AssignOneArg<tuple_element_t<Is, Args>, PArgs>(key, values)))) {
1101-
throw Argo::InvalidArgument(format("Invalid argument {}", key));
1102-
}
1103-
}(make_index_sequence<tuple_size_v<Args>>());
1098+
[&key,
1099+
&values]<size_t... Is>(index_sequence<Is...>) ARGO_ALWAYS_INLINE -> void {
1100+
if (!(... || (tuple_element_t<Is, Args>::name.getKey() == key and
1101+
AssignOneArg<tuple_element_t<Is, Args>, PArgs>(key, values))))
1102+
[[unlikely]] {
1103+
throw Argo::InvalidArgument(format("Invalid argument {}", key));
1104+
}
1105+
}(make_index_sequence<tuple_size_v<Args>>());
11041106
}
11051107

11061108
template <class Arguments, class PArgs>
11071109
ARGO_ALWAYS_INLINE constexpr auto Assigner(string_view key,
11081110
const span<string_view>& values)
11091111
-> void {
1110-
if (key.empty()) {
1111-
if constexpr (!is_same_v<PArgs, tuple<>>) {
1112-
if (!PArgAssigner<PArgs>(values)) {
1112+
if constexpr (!is_same_v<PArgs, tuple<>>) {
1113+
if (key.empty()) {
1114+
if (!PArgAssigner<PArgs>(values)) [[unlikely]] {
11131115
throw InvalidArgument("Duplicated positional argument");
11141116
}
11151117
return;
1116-
} else {
1118+
}
1119+
} else {
1120+
if (key.empty()) [[unlikely]] {
11171121
throw Argo::InvalidArgument(format("Invalid argument {}", key));
11181122
}
11191123
}
@@ -1135,7 +1139,7 @@ ARGO_ALWAYS_INLINE constexpr auto ShortArgAssigner(
11351139
auto value = vector<string_view>{key.substr(i + 1)};
11361140
assignArg<Arguments, PArgs>(found_key, value);
11371141
return has_help;
1138-
} else {
1142+
} else [[unlikely]] {
11391143
throw Argo::InvalidArgument(
11401144
format("Invalid Flag argument {} {}", key[i], key.substr(i + 1)));
11411145
}
@@ -1439,7 +1443,7 @@ class Parser {
14391443

14401444
template <ArgName Name>
14411445
constexpr auto getArg() {
1442-
if (!this->parsed_) {
1446+
if (!this->parsed_) [[unlikely]] {
14431447
throw ParseError("Parser did not parse argument, call parse first");
14441448
}
14451449
if constexpr (!is_same_v<PArgs, tuple<>>) {
@@ -1470,7 +1474,7 @@ class Parser {
14701474

14711475
template <ArgName Name>
14721476
constexpr auto isAssigned() {
1473-
if (!this->parsed_) {
1477+
if (!this->parsed_) [[unlikely]] {
14741478
throw ParseError("Parser did not parse argument, call parse first");
14751479
}
14761480
if constexpr (!is_same_v<PArgs, tuple<>>) {
@@ -1638,17 +1642,20 @@ constexpr auto Parser<ID, Args, PArgs, HArg, SubParsers>::parse(int argc,
16381642
} else {
16391643
is_flag = true;
16401644
}
1645+
16411646
if (i != 1 and is_flag) {
16421647
if (!key.empty()) {
16431648
goto SetArgSection;
16441649
}
16451650
if (!short_keys.empty()) {
16461651
goto SetShortArgSection;
16471652
}
1648-
if (!values.empty()) {
1649-
if constexpr (!is_same_v<PArgs, tuple<>>) {
1653+
if constexpr (!is_same_v<PArgs, tuple<>>) {
1654+
if (!values.empty()) {
16501655
goto SetArgSection;
1651-
} else {
1656+
}
1657+
} else {
1658+
if (!values.empty()) [[unlikely]] {
16521659
throw InvalidArgument(
16531660
format("Invalid positional argument: {}", values));
16541661
}
@@ -1664,9 +1671,11 @@ constexpr auto Parser<ID, Args, PArgs, HArg, SubParsers>::parse(int argc,
16641671
values.clear();
16651672
End:
16661673
}
1667-
if (i == cmd_end_pos) [[unlikely]] {
1674+
1675+
if (i == cmd_end_pos) {
16681676
break;
16691677
}
1678+
16701679
if (is_flag) {
16711680
if (arg.size() > 1 and arg.at(1) == '-') {
16721681
if (arg.contains('=')) [[unlikely]] {
@@ -1695,7 +1704,7 @@ constexpr auto Parser<ID, Args, PArgs, HArg, SubParsers>::parse(int argc,
16951704
}
16961705
});
16971706

1698-
if (!required_keys.empty()) {
1707+
if (!required_keys.empty()) [[unlikely]] {
16991708
throw InvalidArgument(format("Requried {}", required_keys));
17001709
}
17011710
if (subcmd_found_idx != -1) {

0 commit comments

Comments
 (0)