Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
cdo
Manage
Activity
Members
Labels
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Analyze
Contributor analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
mpim-sw
cdo
Compare revisions
8cbb799cf85cf889944fa95d229019085cd5cfd8 to c271fbd7746e0997488c1605d97aa916d8ab30a9
Compare revisions
Changes are shown as if the
source
revision was being merged into the
target
revision.
Learn more about comparing revisions.
Source
mpim-sw/cdo
Select target project
No results found
c271fbd7746e0997488c1605d97aa916d8ab30a9
Select Git revision
Swap
Target
mpim-sw/cdo
Select target project
mpim-sw/cdo
1 result
8cbb799cf85cf889944fa95d229019085cd5cfd8
Select Git revision
Show changes
Only incoming changes from source
Include changes to target since source was created
Compare
Commits on Source (3)
fixed str to integral number converision returning nonexistent NaN
· 9019945d
Oliver Heidmann
authored
2 months ago
9019945d
added tests for empty strings and other failure tests for number conversions
· e2541047
Oliver Heidmann
authored
2 months ago
e2541047
option missval now uses string_to_floating
· c271fbd7
Oliver Heidmann
authored
2 months ago
c271fbd7
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
src/cdo_def_options.cc
+1
-1
1 addition, 1 deletion
src/cdo_def_options.cc
src/util_string.h
+34
-3
34 additions, 3 deletions
src/util_string.h
test/bandit_tests/util_string.cc
+67
-11
67 additions, 11 deletions
test/bandit_tests/util_string.cc
with
102 additions
and
15 deletions
src/cdo_def_options.cc
View file @
c271fbd7
...
...
@@ -328,7 +328,7 @@ setup_options()
CLIOptions
::
option
(
"set_missval"
,
"m"
)
->
describe_argument
(
"missval"
)
->
add_effect
([
&
](
const
std
::
string
&
argument
)
{
auto
[
success
,
mv
]
=
string_to_
number
<
double
>
(
argument
);
auto
[
success
,
mv
]
=
string_to_
floating
<
double
>
(
argument
);
if
(
success
)
{
Debug
(
"set missval of cdi to: %f"
,
mv
);
...
...
This diff is collapsed.
Click to expand it.
src/util_string.h
View file @
c271fbd7
...
...
@@ -63,19 +63,50 @@ string_contains(const std::string &s, unsigned char ch)
}
template
<
typename
Precission
>
std
::
tuple
<
bool
,
Precission
>
Precission
string_to_number
(
const
std
::
string
&
str
)
{
static_assert
(
std
::
is_arithmetic
<
Precission
>::
value
,
"Only arithmetic types allowed"
);
std
::
stringstream
ss
(
str
);
if
(
str
.
empty
())
{
throw
std
::
invalid_argument
(
"Error, conversion of "
+
str
+
" not possible, string empty"
);
}
std
::
stringstream
ss
(
str
);
Precission
number
=
0.0
;
ss
>>
number
;
if
(
!
ss
.
eof
())
{
return
{
false
,
std
::
numeric_limits
<
Precission
>::
quiet_NaN
()
};
}
if
(
!
ss
.
eof
())
{
throw
std
::
invalid_argument
(
"Error, conversion of "
+
str
+
" not possible"
);
}
return
number
;
}
template
<
typename
Precission
>
std
::
tuple
<
bool
,
Precission
>
string_to_integral
(
const
std
::
string
&
str
)
{
static_assert
(
std
::
is_integral
<
Precission
>::
value
,
"Only integral number types allowed"
);
Precission
number
;
/* clang-format off */
try
{
number
=
string_to_number
<
Precission
>
(
str
);
}
catch
(
std
::
invalid_argument
&
e
)
{
return
{
false
,
std
::
numeric_limits
<
Precission
>::
max
()
};
}
/* clang-format on */
return
{
true
,
number
};
}
template
<
typename
Precission
>
std
::
tuple
<
bool
,
Precission
>
string_to_floating
(
const
std
::
string
&
str
)
{
static_assert
(
std
::
is_floating_point
<
Precission
>::
value
,
"Only floating point number types allowed"
);
Precission
number
;
/* clang-format off */
try
{
number
=
string_to_number
<
Precission
>
(
str
);
}
catch
(
std
::
invalid_argument
&
e
)
{
return
{
false
,
std
::
numeric_limits
<
Precission
>::
quiet_NaN
()
};
}
/* clang-format on */
return
{
true
,
number
};
}
namespace
Util
{
namespace
String
...
...
This diff is collapsed.
Click to expand it.
test/bandit_tests/util_string.cc
View file @
c271fbd7
...
...
@@ -36,7 +36,7 @@ test_string_to_number_unsigned()
bandit
::
it
(
msg
,
[
&
]()
{
bool
success
;
T
result
;
std
::
tie
(
success
,
result
)
=
string_to_
number
<
T
>
(
to_be_tested
[
i
]);
std
::
tie
(
success
,
result
)
=
string_to_
integral
<
T
>
(
to_be_tested
[
i
]);
AssertThat
(
success
,
Equals
(
true
));
AssertThat
(
result
,
Equals
(
expected
[
i
]));
});
...
...
@@ -58,7 +58,7 @@ test_string_to_number()
std
::
vector
<
std
::
string
>
to_be_tested
;
std
::
vector
<
T
>
expected
;
to_be_tested
=
{
"1"
,
"0"
,
str_num_max
.
str
(),
"-1"
,
str_num_min
.
str
()
};
to_be_tested
=
{
"1"
,
"0"
,
str_num_max
.
str
(),
"-1"
,
str_num_min
.
str
()
};
expected
=
{
1
,
0
,
std
::
numeric_limits
<
T
>::
max
(),
-
1
,
std
::
numeric_limits
<
T
>::
min
()
};
for
(
std
::
size_t
i
=
0
;
i
<
to_be_tested
.
size
();
i
++
)
...
...
@@ -67,7 +67,7 @@ test_string_to_number()
bandit
::
it
(
msg
,
[
&
]()
{
bool
success
;
T
result
;
std
::
tie
(
success
,
result
)
=
string_to_
number
<
T
>
(
to_be_tested
[
i
]);
std
::
tie
(
success
,
result
)
=
string_to_
integral
<
T
>
(
to_be_tested
[
i
]);
AssertThat
(
success
,
Equals
(
true
));
AssertThat
(
result
,
Equals
(
expected
[
i
]));
});
...
...
@@ -86,8 +86,7 @@ test_string_to_number_fl()
std
::
stringstream
str_num_min
;
str_num_min
<<
std
::
setprecision
(
std
::
numeric_limits
<
T
>::
max_digits10
)
<<
num_min
;
std
::
vector
<
std
::
string
>
to_be_tested
=
{
"0.0"
,
"0"
,
"0.0e1"
,
"2.e3"
,
"2.0e3"
,
"2.0625"
,
str_num_max
.
str
(),
str_num_min
.
str
()
};
std
::
vector
<
std
::
string
>
to_be_tested
=
{
"0.0"
,
"0"
,
"0.0e1"
,
"2.e3"
,
"2.0e3"
,
"2.0625"
,
str_num_max
.
str
(),
str_num_min
.
str
()
};
std
::
vector
<
T
>
expected
=
{
0
,
0
,
0
,
2000
,
2000
,
2.0625
,
num_max
,
num_min
};
for
(
std
::
size_t
i
=
0
;
i
<
to_be_tested
.
size
();
i
++
)
{
...
...
@@ -95,14 +94,14 @@ test_string_to_number_fl()
bandit
::
it
(
msg
,
[
&
]()
{
bool
success
;
T
result
;
std
::
tie
(
success
,
result
)
=
string_to_
number
<
T
>
(
to_be_tested
[
i
]);
std
::
tie
(
success
,
result
)
=
string_to_
floating
<
T
>
(
to_be_tested
[
i
]);
AssertThat
(
success
,
Equals
(
true
));
AssertThat
(
result
,
Equals
(
expected
[
i
]));
});
}
}
template
<
typename
T
>
template
<
auto
func
>
void
test_string_to_number_failures
()
{
...
...
@@ -111,13 +110,29 @@ test_string_to_number_failures()
{
auto
msg
=
"correctly throws error on "
+
to_be_tested
[
i
];
bandit
::
it
(
msg
,
[
&
]()
{
auto
[
success
,
result
]
=
string_to_number
<
T
>
(
to_be_tested
[
i
]);
auto
[
success
,
result
]
=
func
(
to_be_tested
[
i
]);
AssertThat
(
success
,
Equals
(
false
));
AssertThat
(
std
::
isnan
(
result
),
Equals
(
true
));
});
}
}
template
<
auto
func
>
void
test_string_to_integral_failures
()
{
std
::
vector
<
std
::
string
>
to_be_tested
=
{
"1.0"
,
"a2"
,
"2a"
,
"2e"
};
for
(
std
::
size_t
i
=
0
;
i
<
to_be_tested
.
size
();
i
++
)
{
auto
msg
=
"correctly throws error on "
+
to_be_tested
[
i
];
bandit
::
it
(
msg
,
[
&
]()
{
auto
[
success
,
result
]
=
func
(
to_be_tested
[
i
]);
AssertThat
(
success
,
Equals
(
false
));
AssertThat
(
std
::
numeric_limits
<
decltype
(
result
)
>::
max
(),
Equals
(
result
));
});
}
}
go_bandit
([]()
{
//==============================================================================
//
...
...
@@ -143,9 +158,50 @@ go_bandit([]() {
});
bandit
::
describe
(
"Testing string_to_number negatives"
,
[]()
{
bandit
::
describe
(
"Testing errors for float"
,
[]()
{
test_string_to_number_failures
<
float
>
();
});
bandit
::
describe
(
"Testing errors for double"
,
[]()
{
test_string_to_number_failures
<
double
>
();
});
bandit
::
describe
(
"Testing errors for long double"
,
[]()
{
test_string_to_number_failures
<
long
double
>
();
});
bandit
::
describe
(
"Testing errors for float"
,
[]()
{
test_string_to_number_failures
<
string_to_floating
<
float
>>
();
bandit
::
it
(
"correctly throws error on empty string with float"
,
[
&
]()
{
auto
[
success_f
,
result_f
]
=
string_to_floating
<
float
>
(
""
);
AssertThat
(
success_f
,
Equals
(
false
));
AssertThat
(
std
::
isnan
(
result_f
),
Equals
(
true
));
});
});
bandit
::
describe
(
"Testing errors for double"
,
[]()
{
test_string_to_number_failures
<
string_to_floating
<
double
>>
();
bandit
::
it
(
"correctly throws error on empty string with double"
,
[
&
]()
{
auto
[
success_d
,
result_d
]
=
string_to_floating
<
double
>
(
""
);
AssertThat
(
success_d
,
Equals
(
false
));
AssertThat
(
std
::
isnan
(
result_d
),
Equals
(
true
));
});
});
bandit
::
describe
(
"Testing errors for long double"
,
[]()
{
test_string_to_number_failures
<
string_to_floating
<
long
double
>>
();
bandit
::
it
(
"correctly throws error on empty string with long double"
,
[
&
]()
{
auto
[
success_d
,
result_d
]
=
string_to_floating
<
long
double
>
(
""
);
AssertThat
(
success_d
,
Equals
(
false
));
AssertThat
(
std
::
isnan
(
result_d
),
Equals
(
true
));
});
});
bandit
::
describe
(
"Testing errors for int"
,
[]()
{
test_string_to_integral_failures
<
string_to_integral
<
int
>>
();
bandit
::
it
(
"correctly throws error on empty string with int"
,
[
&
]()
{
auto
[
success_i
,
result_i
]
=
string_to_integral
<
int
>
(
""
);
AssertThat
(
success_i
,
Equals
(
false
));
AssertThat
(
std
::
numeric_limits
<
int
>::
max
(),
Equals
(
result_i
));
});
});
bandit
::
describe
(
"Testing errors for int"
,
[]()
{
test_string_to_integral_failures
<
string_to_integral
<
unsigned
int
>>
();
bandit
::
it
(
"correctly throws error on empty string with unsigned int"
,
[
&
]()
{
auto
[
success_ui
,
result_ui
]
=
string_to_integral
<
unsigned
int
>
(
""
);
AssertThat
(
success_ui
,
Equals
(
false
));
AssertThat
(
std
::
numeric_limits
<
unsigned
int
>::
max
(),
Equals
(
result_ui
));
});
});
});
});
...
...
This diff is collapsed.
Click to expand it.