diff --git a/.github/config/codechecker.yml b/.github/config/codechecker.yml index dec75185..c18b08a7 100644 --- a/.github/config/codechecker.yml +++ b/.github/config/codechecker.yml @@ -7,6 +7,7 @@ analyze: - --enable=bugprone - --enable=clang-diagnostic-shadow - --disable=bugprone-easily-swappable-parameters + - --disable=cert-dcl58-cpp - --disable=clang-diagnostic-implicit-int-float-conversion - --disable=clang-diagnostic-float-conversion - --disable=clang-diagnostic-implicit-int-conversion diff --git a/doc/tutorial/parser/solution3.cpp b/doc/tutorial/parser/solution3.cpp index 094525af..8eefd34d 100644 --- a/doc/tutorial/parser/solution3.cpp +++ b/doc/tutorial/parser/solution3.cpp @@ -19,7 +19,7 @@ number_type to_number(range_type && range) return s; }(); number_type num; - auto res = std::from_chars(&str[0], &str[0] + str.size(), num); + auto res = std::from_chars(str.data(), str.data() + str.size(), num); if (res.ec != std::errc{}) { diff --git a/doc/tutorial/parser/solution4.cpp b/doc/tutorial/parser/solution4.cpp index 34fead81..142d987d 100644 --- a/doc/tutorial/parser/solution4.cpp +++ b/doc/tutorial/parser/solution4.cpp @@ -18,7 +18,7 @@ number_type to_number(range_type && range) return s; }(); number_type num; - auto res = std::from_chars(&str[0], &str[0] + str.size(), num); + auto res = std::from_chars(str.data(), str.data() + str.size(), num); if (res.ec != std::errc{}) { diff --git a/doc/tutorial/parser/solution5.cpp b/doc/tutorial/parser/solution5.cpp index 3a6f2130..6522ce8c 100644 --- a/doc/tutorial/parser/solution5.cpp +++ b/doc/tutorial/parser/solution5.cpp @@ -18,7 +18,7 @@ number_type to_number(range_type && range) return s; }(); number_type num; - auto res = std::from_chars(&str[0], &str[0] + str.size(), num); + auto res = std::from_chars(str.data(), str.data() + str.size(), num); if (res.ec != std::errc{}) { diff --git a/doc/tutorial/parser/solution6.cpp b/doc/tutorial/parser/solution6.cpp index 079d84b4..fc692c86 100644 --- a/doc/tutorial/parser/solution6.cpp +++ b/doc/tutorial/parser/solution6.cpp @@ -18,7 +18,7 @@ number_type to_number(range_type && range) return s; }(); number_type num; - auto res = std::from_chars(&str[0], &str[0] + str.size(), num); + auto res = std::from_chars(str.data(), str.data() + str.size(), num); if (res.ec != std::errc{}) { diff --git a/include/sharg/detail/format_base.hpp b/include/sharg/detail/format_base.hpp index 8689b44a..a8564281 100644 --- a/include/sharg/detail/format_base.hpp +++ b/include/sharg/detail/format_base.hpp @@ -373,7 +373,7 @@ class format_help_base : public format_base if (!meta.description.empty()) { derived_t().print_section("Description"); - for (auto desc : meta.description) + for (auto && desc : meta.description) print_line(desc); } @@ -397,14 +397,14 @@ class format_help_base : public format_base derived_t().print_section("Positional Arguments"); // each call will evaluate the function derived_t().print_list_item() - for (auto f : positional_option_calls) + for (auto && f : positional_option_calls) f(); // There are always options because of the common options derived_t().print_section("Options"); // each call will evaluate the function derived_t().print_list_item() - for (auto f : parser_set_up_calls) + for (auto && f : parser_set_up_calls) f(); // print Common options after developer options @@ -424,7 +424,7 @@ class format_help_base : public format_base if (!meta.examples.empty()) { derived_t().print_section("Examples"); - for (auto example : meta.examples) + for (auto && example : meta.examples) print_line(example); } diff --git a/include/sharg/detail/format_html.hpp b/include/sharg/detail/format_html.hpp index cfa93e48..c4b962d2 100644 --- a/include/sharg/detail/format_html.hpp +++ b/include/sharg/detail/format_html.hpp @@ -172,7 +172,8 @@ class format_html : public format_help_base */ std::string to_html(std::string const & input) { - std::string buffer = escape_special_xml_chars(input); + // Todo: Input is escaped, but then not used. Same in SeqAn2. Why? + // std::string buffer = escape_special_xml_chars(input); std::string result; std::vector open_tags; // acts as a stack of html tags diff --git a/include/sharg/detail/format_man.hpp b/include/sharg/detail/format_man.hpp index 96843c23..5ece60b7 100644 --- a/include/sharg/detail/format_man.hpp +++ b/include/sharg/detail/format_man.hpp @@ -79,7 +79,7 @@ class format_man : public format_help_base std::cout << " " << meta.version << "\" \"" << meta.man_page_title << "\"\n"; // Print NAME section. - std::cout << ".SH NAME\n" << meta.app_name << " \\- " << meta.short_description << std::endl; + std::cout << ".SH NAME\n" << meta.app_name << " \\- " << meta.short_description << '\n'; } /*!\brief Prints a section title in man page format to std::cout. diff --git a/include/sharg/detail/format_parse.hpp b/include/sharg/detail/format_parse.hpp index b2b0feb4..01a6b384 100644 --- a/include/sharg/detail/format_parse.hpp +++ b/include/sharg/detail/format_parse.hpp @@ -331,7 +331,7 @@ class format_parse : public format_base std::string result{'['}; for (auto const & [key, value] : key_value_pairs) - result += std::string{key.data()} + ", "; + result += std::string{key} + ", "; result.replace(result.size() - 2, 2, "]"); // replace last ", " by "]" return result; }(); @@ -402,11 +402,11 @@ class format_parse : public format_base requires std::is_arithmetic_v && istreamable option_parse_result parse_option_value(option_t & value, std::string const & in) { - auto res = std::from_chars(&in[0], &in[in.size()], value); + auto res = std::from_chars(in.data(), in.data() + in.size(), value); if (res.ec == std::errc::result_out_of_range) return option_parse_result::overflow_error; - else if (res.ec == std::errc::invalid_argument || res.ptr != &in[in.size()]) + else if (res.ec == std::errc::invalid_argument || res.ptr != in.data() + in.size()) return option_parse_result::error; return option_parse_result::success; @@ -424,14 +424,10 @@ class format_parse : public format_base */ option_parse_result parse_option_value(bool & value, std::string const & in) { - if (in == "0") + if (in == "0" || in == "false") value = false; - else if (in == "1") + else if (in == "1" || in == "true") value = true; - else if (in == "true") - value = true; - else if (in == "false") - value = false; else return option_parse_result::error; diff --git a/include/sharg/detail/format_tdl.hpp b/include/sharg/detail/format_tdl.hpp index 418ae3ac..66066437 100644 --- a/include/sharg/detail/format_tdl.hpp +++ b/include/sharg/detail/format_tdl.hpp @@ -79,7 +79,7 @@ auto to_tdl(std::integral auto v) //!\copydetails sharg::detail::to_tdl auto to_tdl(std::floating_point auto v) { - return tdl::DoubleValue(v); + return tdl::DoubleValue(static_cast(v)); } //!\copydetails sharg::detail::to_tdl @@ -339,7 +339,7 @@ class format_tdl : format_base .description = std::accumulate(begin(meta.description), end(meta.description), std::string{}, - [](auto a, auto v) + [](auto const & a, auto const & v) { return a + v + '\n'; }), diff --git a/include/sharg/parser.hpp b/include/sharg/parser.hpp index 7f996ae0..00937c50 100644 --- a/include/sharg/parser.hpp +++ b/include/sharg/parser.hpp @@ -185,7 +185,7 @@ class parser version_check_dev_decision{version_updates}, arguments{arguments} { - add_subcommands(subcommands); + add_subcommands(std::move(subcommands)); info.app_name = app_name; } diff --git a/include/sharg/std/charconv b/include/sharg/std/charconv index f8211d7c..671c47d3 100644 --- a/include/sharg/std/charconv +++ b/include/sharg/std/charconv @@ -87,7 +87,7 @@ inline from_chars_result from_chars_floating_point(char const * first, if (*first == '+') // + is permitted in function strto[d/f/ld] but not in from_chars return {last, std::errc::invalid_argument}; - float tmp{}; + value_type tmp{}; constexpr ptrdiff_t buffer_size = 100; char buffer[buffer_size]; diff --git a/include/sharg/validators.hpp b/include/sharg/validators.hpp index f448d51c..8a30dc74 100644 --- a/include/sharg/validators.hpp +++ b/include/sharg/validators.hpp @@ -387,7 +387,7 @@ class file_validator_base file_path.erase(0, 1); // Store a string_view containing all extensions for a better error message. - std::string const all_extensions{file_path.substr(file_path.find(".") + 1)}; + std::string const all_extensions{file_path.substr(file_path.find('.') + 1)}; // Compares the extensions in lower case. auto case_insensitive_ends_with = [&](std::string const & ext) @@ -601,7 +601,7 @@ class input_file_validator : public file_validator_base * \details * \experimentalapi{Experimental since version 1.0.} */ -enum class output_file_open_options +enum class output_file_open_options : uint8_t { //!\brief Allow to overwrite the output file open_or_create, @@ -660,7 +660,7 @@ class output_file_validator : public file_validator_base * \details * \experimentalapi{Experimental since version 1.0.} */ - explicit output_file_validator(output_file_open_options const mode, std::vector const & extensions) : + explicit output_file_validator(output_file_open_options const mode, std::vector extensions) : open_mode{mode} { file_validator_base::extensions_str = detail::to_string(extensions); diff --git a/test/unit/detail/safe_filesystem_entry_test.cpp b/test/unit/detail/safe_filesystem_entry_test.cpp index 72321866..08801d70 100644 --- a/test/unit/detail/safe_filesystem_entry_test.cpp +++ b/test/unit/detail/safe_filesystem_entry_test.cpp @@ -12,7 +12,7 @@ TEST(safe_filesystem_entry, file) { sharg::test::tmp_filename tmp_file{"dummy.txt"}; - std::filesystem::path my_file = tmp_file.get_path(); + std::filesystem::path const & my_file = tmp_file.get_path(); { std::ofstream file{my_file}; EXPECT_TRUE(std::filesystem::exists(my_file)); @@ -25,7 +25,7 @@ TEST(safe_filesystem_entry, file) TEST(safe_filesystem_entry, file_already_removed) { sharg::test::tmp_filename tmp_file{"dummy.txt"}; - std::filesystem::path my_file = tmp_file.get_path(); + std::filesystem::path const & my_file = tmp_file.get_path(); { EXPECT_FALSE(std::filesystem::exists(my_file)); sharg::detail::safe_filesystem_entry file_guard{my_file}; @@ -37,7 +37,7 @@ TEST(safe_filesystem_entry, file_already_removed) TEST(safe_filesystem_entry, directory) { sharg::test::tmp_filename tmp_file{"dummy.txt"}; - std::filesystem::path my_dir = tmp_file.get_path(); + std::filesystem::path const & my_dir = tmp_file.get_path(); { std::filesystem::create_directory(my_dir); EXPECT_TRUE(std::filesystem::exists(my_dir)); @@ -50,7 +50,7 @@ TEST(safe_filesystem_entry, directory) TEST(safe_filesystem_entry, directory_already_removed) { sharg::test::tmp_filename tmp_file{"dummy.txt"}; - std::filesystem::path my_dir = tmp_file.get_path(); + std::filesystem::path const & my_dir = tmp_file.get_path(); { EXPECT_FALSE(std::filesystem::exists(my_dir)); sharg::detail::safe_filesystem_entry dir_guard{my_dir}; @@ -62,7 +62,7 @@ TEST(safe_filesystem_entry, directory_already_removed) TEST(safe_filesystem_entry, remove) { sharg::test::tmp_filename tmp_file{"dummy.txt"}; - std::filesystem::path my_file = tmp_file.get_path(); + std::filesystem::path const & my_file = tmp_file.get_path(); { std::ofstream file{my_file}; EXPECT_TRUE(std::filesystem::exists(my_file)); @@ -76,7 +76,7 @@ TEST(safe_filesystem_entry, remove) TEST(safe_filesystem_entry, remove_all) { sharg::test::tmp_filename tmp_file{"dummy.txt"}; - std::filesystem::path my_dir = tmp_file.get_path(); + std::filesystem::path const & my_dir = tmp_file.get_path(); { std::filesystem::create_directory(my_dir); EXPECT_TRUE(std::filesystem::exists(my_dir)); diff --git a/test/unit/detail/version_check_test.hpp b/test/unit/detail/version_check_test.hpp index 651e057a..323913b6 100644 --- a/test/unit/detail/version_check_test.hpp +++ b/test/unit/detail/version_check_test.hpp @@ -28,7 +28,7 @@ class version_check_test : public sharg::test::test_fixture void randomise_home_folder() { - auto tmp_directory = tmp_file.get_path().parent_path(); + auto const tmp_directory = tmp_file.get_path().parent_path(); std::string const base_path = tmp_directory.string(); if (setenv(sharg::detail::version_checker::home_env_name, base_path.data(), 1)) diff --git a/test/unit/parser/format_parse_test.cpp b/test/unit/parser/format_parse_test.cpp index d21dc2ce..dd5e295c 100644 --- a/test/unit/parser/format_parse_test.cpp +++ b/test/unit/parser/format_parse_test.cpp @@ -846,9 +846,9 @@ TEST_F(format_parse_test, executable_name) bool flag{false}; auto parser = get_parser(); - auto check = [&](std::string_view expected) + auto check = [&](std::string expected) { - parser = sharg::parser{"test_parser", {expected.data(), "-t"}, sharg::update_notifications::off}; + parser = sharg::parser{"test_parser", {expected, std::string{"-t"}}, sharg::update_notifications::off}; parser.add_flag(flag, sharg::config{.short_id = 't'}); EXPECT_NO_THROW(parser.parse()); auto & executable_name = sharg::detail::test_accessor::executable_name(parser); diff --git a/test/unit/parser/format_parse_validators_test.cpp b/test/unit/parser/format_parse_validators_test.cpp index 66871904..b57fbfec 100644 --- a/test/unit/parser/format_parse_validators_test.cpp +++ b/test/unit/parser/format_parse_validators_test.cpp @@ -44,10 +44,10 @@ TEST_F(validator_test, input_file) sharg::test::tmp_filename const tmp_name_hidden{".testbox.fasta"}; sharg::test::tmp_filename const tmp_name_multiple{"testbox.fasta.txt"}; - std::filesystem::path const tmp_path{tmp_name.get_path()}; - std::filesystem::path const tmp_path_2{tmp_name_2.get_path()}; - std::filesystem::path const tmp_path_hidden{tmp_name_hidden.get_path()}; - std::filesystem::path const tmp_path_multiple{tmp_name_multiple.get_path()}; + std::filesystem::path const & tmp_path{tmp_name.get_path()}; + std::filesystem::path const & tmp_path_2{tmp_name_2.get_path()}; + std::filesystem::path const & tmp_path_hidden{tmp_name_hidden.get_path()}; + std::filesystem::path const & tmp_path_multiple{tmp_name_multiple.get_path()}; { // Open fstream to create files. std::ofstream tmp_file{tmp_path}; @@ -133,8 +133,8 @@ TEST_F(validator_test, output_file) sharg::test::tmp_filename const tmp_name_3{"testbox_3.fa"}; sharg::test::tmp_filename const hidden_name{".testbox.fasta"}; - std::filesystem::path const not_existing_path{tmp_name.get_path()}; - std::filesystem::path const existing_path{tmp_name_2.get_path()}; + std::filesystem::path const & not_existing_path{tmp_name.get_path()}; + std::filesystem::path const & existing_path{tmp_name_2.get_path()}; { // Open fstream to create files. std::ofstream tmp_file{existing_path}; @@ -279,7 +279,7 @@ TEST_F(validator_test, output_file) TEST_F(validator_test, input_directory) { sharg::test::tmp_filename const tmp_name{"testbox.fasta"}; - std::filesystem::path const tmp_path{tmp_name.get_path()}; + std::filesystem::path const & tmp_path{tmp_name.get_path()}; { // Open fstream to create files. std::ofstream tmp_file{tmp_path}; @@ -321,7 +321,7 @@ TEST_F(validator_test, input_directory) TEST_F(validator_test, output_directory) { sharg::test::tmp_filename const tmp_name{"testbox.fasta"}; - std::filesystem::path const tmp_path{tmp_name.get_path()}; + std::filesystem::path const & tmp_path{tmp_name.get_path()}; { // Open fstream to create files. std::ofstream tmp_file{tmp_path}; @@ -348,8 +348,8 @@ TEST_F(validator_test, output_directory) // Parent path exists and is writable. sharg::test::tmp_filename tmp_child_name{"dir/child_dir"}; - std::filesystem::path tmp_child_dir{tmp_child_name.get_path()}; - std::filesystem::path tmp_parent_path{tmp_child_dir.parent_path()}; + std::filesystem::path const & tmp_child_dir{tmp_child_name.get_path()}; + std::filesystem::path const tmp_parent_path{tmp_child_dir.parent_path()}; EXPECT_FALSE(std::filesystem::exists(tmp_parent_path)); EXPECT_THROW(my_validator(tmp_child_dir), sharg::validation_error); @@ -375,7 +375,7 @@ TEST_F(validator_test, output_directory) TEST_F(validator_test, inputfile_not_readable) { sharg::test::tmp_filename const tmp_name{"my_file.test"}; - std::filesystem::path const tmp_path{tmp_name.get_path()}; + std::filesystem::path const & tmp_path{tmp_name.get_path()}; { // Open fstream to create files. std::ofstream tmp_file{tmp_path}; @@ -413,7 +413,7 @@ TEST_F(validator_test, inputfile_not_regular) TEST_F(validator_test, inputdir_not_existing) { sharg::test::tmp_filename const tmp_name{"dir"}; - std::filesystem::path const not_existing_dir{tmp_name.get_path()}; + std::filesystem::path const & not_existing_dir{tmp_name.get_path()}; EXPECT_THROW(sharg::input_directory_validator{}(not_existing_dir), sharg::validation_error); } @@ -421,7 +421,7 @@ TEST_F(validator_test, inputdir_not_existing) TEST_F(validator_test, inputdir_not_readable) { sharg::test::tmp_filename const tmp_name{"dir"}; - std::filesystem::path const tmp_dir{tmp_name.get_path()}; + std::filesystem::path const & tmp_dir{tmp_name.get_path()}; std::filesystem::create_directory(tmp_dir); @@ -448,7 +448,7 @@ TEST_F(validator_test, inputdir_not_readable) TEST_F(validator_test, outputfile_not_writable) { sharg::test::tmp_filename const tmp_name{"my_file.test"}; - std::filesystem::path const tmp_file{tmp_name.get_path()}; + std::filesystem::path const & tmp_file{tmp_name.get_path()}; sharg::output_file_validator my_validator{sharg::output_file_open_options::create_new}; @@ -475,7 +475,7 @@ TEST_F(validator_test, outputfile_not_writable) TEST_F(validator_test, output_parent_dir_not_writable) { sharg::test::tmp_filename const tmp_name{"dir"}; - std::filesystem::path const tmp_dir{tmp_name.get_path()}; + std::filesystem::path const & tmp_dir{tmp_name.get_path()}; sharg::output_file_validator my_validator{}; @@ -517,7 +517,7 @@ TEST_F(validator_test, output_parent_dir_not_writable) TEST_F(validator_test, outputdir_not_writable) { sharg::test::tmp_filename const tmp_name{"dir"}; - std::filesystem::path const tmp_dir{tmp_name.get_path()}; + std::filesystem::path const & tmp_dir{tmp_name.get_path()}; std::filesystem::create_directory(tmp_dir); diff --git a/test/unit/std/charconv_float_test.cpp b/test/unit/std/charconv_float_test.cpp index 0a03a016..c72c6aec 100644 --- a/test/unit/std/charconv_float_test.cpp +++ b/test/unit/std/charconv_float_test.cpp @@ -28,142 +28,147 @@ TYPED_TEST_SUITE(from_char_real_test, real_types, ); TYPED_TEST(from_char_real_test, real_numbers) { - std::setlocale(LC_NUMERIC, "C"); + auto to_TypeParam = [](auto value) -> TypeParam + { + return static_cast(value); + }; + + (void)std::setlocale(LC_NUMERIC, "C"); { TypeParam val{}; std::string str = "1234"; - auto res = std::from_chars(&str[0], &str[0] + str.size(), val); - EXPECT_FLOAT_EQ(val, TypeParam{1234}); + auto res = std::from_chars(str.data(), str.data() + str.size(), val); + EXPECT_FLOAT_EQ(val, to_TypeParam(1234)); EXPECT_EQ(res.ec, std::errc{}); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); } { TypeParam val{}; std::string str = "1.2e3"; - auto res = std::from_chars(&str[0], &str[0] + str.size(), val); - EXPECT_FLOAT_EQ(val, TypeParam{1200}); + auto res = std::from_chars(str.data(), str.data() + str.size(), val); + EXPECT_FLOAT_EQ(val, to_TypeParam(1200)); EXPECT_EQ(res.ec, std::errc{}); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); } { TypeParam val{}; std::string str = "1.2e-3"; - auto res = std::from_chars(&str[0], &str[0] + str.size(), val); - EXPECT_FLOAT_EQ(val, TypeParam{0.0012}); + auto res = std::from_chars(str.data(), str.data() + str.size(), val); + EXPECT_FLOAT_EQ(val, to_TypeParam(0.0012)); EXPECT_EQ(res.ec, std::errc{}); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); } { TypeParam val{}; std::string str = "1.e2"; - auto res = std::from_chars(&str[0], &str[0] + str.size(), val); - EXPECT_FLOAT_EQ(val, TypeParam{100}); + auto res = std::from_chars(str.data(), str.data() + str.size(), val); + EXPECT_FLOAT_EQ(val, to_TypeParam(100)); EXPECT_EQ(res.ec, std::errc{}); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); } { TypeParam val{}; std::string str = "1."; - auto res = std::from_chars(&str[0], &str[0] + str.size(), val); - EXPECT_FLOAT_EQ(val, TypeParam{1}); + auto res = std::from_chars(str.data(), str.data() + str.size(), val); + EXPECT_FLOAT_EQ(val, to_TypeParam(1)); EXPECT_EQ(res.ec, std::errc{}); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); } { TypeParam val{}; std::string str = ".2e3"; - auto res = std::from_chars(&str[0], &str[0] + str.size(), val); - EXPECT_FLOAT_EQ(val, TypeParam{200}); + auto res = std::from_chars(str.data(), str.data() + str.size(), val); + EXPECT_FLOAT_EQ(val, to_TypeParam(200)); EXPECT_EQ(res.ec, std::errc{}); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); } { TypeParam val{}; std::string str = "2e3"; - auto res = std::from_chars(&str[0], &str[0] + str.size(), val); - EXPECT_FLOAT_EQ(val, TypeParam{2000}); + auto res = std::from_chars(str.data(), str.data() + str.size(), val); + EXPECT_FLOAT_EQ(val, to_TypeParam(2000)); EXPECT_EQ(res.ec, std::errc{}); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); } { TypeParam val{}; std::string str = "2"; - auto res = std::from_chars(&str[0], &str[0] + str.size(), val); - EXPECT_FLOAT_EQ(val, TypeParam{2}); + auto res = std::from_chars(str.data(), str.data() + str.size(), val); + EXPECT_FLOAT_EQ(val, to_TypeParam(2)); EXPECT_EQ(res.ec, std::errc{}); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); } { TypeParam val{}; std::string str = "4em"; - auto res = std::from_chars(&str[0], &str[0] + str.size(), val); - EXPECT_FLOAT_EQ(val, TypeParam{4}); + auto res = std::from_chars(str.data(), str.data() + str.size(), val); + EXPECT_FLOAT_EQ(val, to_TypeParam(4)); EXPECT_EQ(res.ec, std::errc{}); - EXPECT_EQ(res.ptr, &str[0] + 1); + EXPECT_EQ(res.ptr, str.data() + 1); } { TypeParam val{}; std::string str = "-1.2e3"; - auto res = std::from_chars(&str[0], &str[0] + str.size(), val); - EXPECT_FLOAT_EQ(val, TypeParam{-1200}); + auto res = std::from_chars(str.data(), str.data() + str.size(), val); + EXPECT_FLOAT_EQ(val, to_TypeParam(-1200)); EXPECT_EQ(res.ec, std::errc{}); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); } { TypeParam val{42}; std::string str = "-.3"; - auto res = std::from_chars(&str[0], &str[0] + str.size(), val); - EXPECT_FLOAT_EQ(val, TypeParam{-0.3}); + auto res = std::from_chars(str.data(), str.data() + str.size(), val); + EXPECT_FLOAT_EQ(val, to_TypeParam(-0.3)); EXPECT_EQ(res.ec, std::errc{}); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); } { TypeParam val{42}; std::string str = "1.2e"; - auto res = std::from_chars(&str[0], &str[0] + str.size(), val); - EXPECT_FLOAT_EQ(val, TypeParam{1.2}); + auto res = std::from_chars(str.data(), str.data() + str.size(), val); + EXPECT_FLOAT_EQ(val, to_TypeParam(1.2)); EXPECT_EQ(res.ec, std::errc{}); - EXPECT_EQ(res.ptr, &str[0] + 3); + EXPECT_EQ(res.ptr, str.data() + 3); } { TypeParam val{42}; std::string str = "0.0"; - auto res = std::from_chars(&str[0], &str[0] + str.size(), val); - EXPECT_FLOAT_EQ(val, TypeParam{0}); + auto res = std::from_chars(str.data(), str.data() + str.size(), val); + EXPECT_FLOAT_EQ(val, to_TypeParam(0)); EXPECT_EQ(res.ec, std::errc{}); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); } // Read only until a certain position { TypeParam val{42}; std::string str = "3.194357"; - auto res = std::from_chars(&str[0], &str[0] + 4, val); - EXPECT_FLOAT_EQ(val, TypeParam{3.19}); + auto res = std::from_chars(str.data(), str.data() + 4, val); + EXPECT_FLOAT_EQ(val, to_TypeParam(3.19)); EXPECT_EQ(res.ec, std::errc{}); - EXPECT_EQ(res.ptr, &str[0] + 4); + EXPECT_EQ(res.ptr, str.data() + 4); } // Partial Parsing { TypeParam val{42}; std::string str = "3.19abc"; - auto res = std::from_chars(&str[0], &str[0] + str.size(), val); - EXPECT_FLOAT_EQ(val, TypeParam{3.19}); + auto res = std::from_chars(str.data(), str.data() + str.size(), val); + EXPECT_FLOAT_EQ(val, to_TypeParam(3.19)); EXPECT_EQ(res.ec, std::errc{}); - EXPECT_EQ(res.ptr, &str[0] + 4); + EXPECT_EQ(res.ptr, str.data() + 4); } } @@ -172,37 +177,37 @@ TYPED_TEST(from_char_real_test, infinity_value) { TypeParam val{}; std::string str = "inf"; - auto res = std::from_chars(&str[0], &str[0] + str.size(), val); + auto res = std::from_chars(str.data(), str.data() + str.size(), val); EXPECT_EQ(val, std::numeric_limits::infinity()); EXPECT_EQ(res.ec, std::errc{}); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); } { TypeParam val{}; std::string str = "infinity"; - auto res = std::from_chars(&str[0], &str[0] + str.size(), val); + auto res = std::from_chars(str.data(), str.data() + str.size(), val); EXPECT_EQ(val, std::numeric_limits::infinity()); EXPECT_EQ(res.ec, std::errc{}); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); } { TypeParam val{}; std::string str = "INF"; - auto res = std::from_chars(&str[0], &str[0] + str.size(), val); + auto res = std::from_chars(str.data(), str.data() + str.size(), val); EXPECT_EQ(val, std::numeric_limits::infinity()); EXPECT_EQ(res.ec, std::errc{}); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); } { TypeParam val{}; std::string str = "INFINITY"; - auto res = std::from_chars(&str[0], &str[0] + str.size(), val); + auto res = std::from_chars(str.data(), str.data() + str.size(), val); EXPECT_EQ(val, std::numeric_limits::infinity()); EXPECT_EQ(res.ec, std::errc{}); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); } } @@ -215,37 +220,37 @@ TYPED_TEST(from_char_real_test, nan_value) { TypeParam val{}; std::string str = "nan"; - auto res = std::from_chars(&str[0], &str[0] + str.size(), val); + auto res = std::from_chars(str.data(), str.data() + str.size(), val); EXPECT_TRUE(std::isnan(val)); EXPECT_EQ(res.ec, std::errc{}); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); } { TypeParam val{}; std::string str = "NAN"; - auto res = std::from_chars(&str[0], &str[0] + str.size(), val); + auto res = std::from_chars(str.data(), str.data() + str.size(), val); EXPECT_TRUE(std::isnan(val)); EXPECT_EQ(res.ec, std::errc{}); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); } { TypeParam val{}; std::string str = "nan(abc)"; - auto res = std::from_chars(&str[0], &str[0] + str.size(), val); + auto res = std::from_chars(str.data(), str.data() + str.size(), val); EXPECT_TRUE(std::isnan(val)); EXPECT_EQ(res.ec, std::errc{}); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); } { TypeParam val{}; std::string str = "NAN(abc)"; - auto res = std::from_chars(&str[0], &str[0] + str.size(), val); + auto res = std::from_chars(str.data(), str.data() + str.size(), val); EXPECT_TRUE(std::isnan(val)); EXPECT_EQ(res.ec, std::errc{}); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); } } @@ -254,7 +259,7 @@ TYPED_TEST(from_char_real_test, non_valid_strings) { TypeParam val{42}; std::string str = "e3"; - auto res = std::from_chars(&str[0], &str[0] + str.size(), val); + auto res = std::from_chars(str.data(), str.data() + str.size(), val); EXPECT_FLOAT_EQ(val, TypeParam{42}); EXPECT_EQ(res.ec, std::errc::invalid_argument); } @@ -262,7 +267,7 @@ TYPED_TEST(from_char_real_test, non_valid_strings) { TypeParam val{42}; std::string str = "+1.2e3"; - auto res = std::from_chars(&str[0], &str[0] + str.size(), val); + auto res = std::from_chars(str.data(), str.data() + str.size(), val); EXPECT_FLOAT_EQ(val, TypeParam{42}); EXPECT_EQ(res.ec, std::errc::invalid_argument); } @@ -278,7 +283,7 @@ TYPED_TEST(from_char_real_test, to_chars) // different floating point types (e.g. `float`, `double`, `long double`). // Other values, lets say 120.3, could have different string representations like `120.3`, `120.30000...01`, or // `120.2999...9716` depending on the actual implementation. - TypeParam val{120.25}; + TypeParam val{static_cast(120.25)}; std::array buffer{}; auto res = std::to_chars(buffer.data(), buffer.data() + buffer.size(), val); diff --git a/test/unit/std/charconv_int_test.cpp b/test/unit/std/charconv_int_test.cpp index 0c3221d3..3caca42f 100644 --- a/test/unit/std/charconv_int_test.cpp +++ b/test/unit/std/charconv_int_test.cpp @@ -32,29 +32,29 @@ TYPED_TEST(integral_from_char_test, postive_number) { std::vector const str{'1', '2', '3'}; - auto res = std::from_chars(&str[0], &str[0] + str.size(), value); + auto res = std::from_chars(str.data(), str.data() + str.size(), value); EXPECT_EQ(value, TypeParam{123}); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); EXPECT_EQ(res.ec, std::errc{}); } { std::vector const str{'0', '2', '3'}; - auto res = std::from_chars(&str[0], &str[0] + str.size(), value); + auto res = std::from_chars(str.data(), str.data() + str.size(), value); EXPECT_EQ(value, TypeParam{23}); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); EXPECT_EQ(res.ec, std::errc{}); } // Read only up to a certain point { std::vector const str{'0', '2', '3', '4', '5', '6'}; - auto res = std::from_chars(&str[0], &str[0] + 3, value); + auto res = std::from_chars(str.data(), str.data() + 3, value); EXPECT_EQ(value, TypeParam{23}); - EXPECT_EQ(res.ptr, &str[0] + 3); + EXPECT_EQ(res.ptr, str.data() + 3); EXPECT_EQ(res.ec, std::errc{}); } } @@ -63,18 +63,18 @@ TYPED_TEST(integral_from_char_test, negative_number) { TypeParam value{42}; std::vector const str{'-', '1', '2', '3'}; - auto res = std::from_chars(&str[0], &str[0] + str.size(), value); + auto res = std::from_chars(str.data(), str.data() + str.size(), value); if constexpr (std::is_unsigned_v) { - EXPECT_EQ(res.ptr, &str[0]); + EXPECT_EQ(res.ptr, str.data()); EXPECT_EQ(res.ec, std::errc::invalid_argument); EXPECT_EQ(value, TypeParam{42}); } else { EXPECT_EQ(value, TypeParam{-123}); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); EXPECT_EQ(res.ec, std::errc{}); } } @@ -85,9 +85,9 @@ TYPED_TEST(integral_from_char_test, overflow_error) std::vector const str{'1', '2', '3', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'}; - auto res = std::from_chars(&str[0], &str[0] + str.size(), value); + auto res = std::from_chars(str.data(), str.data() + str.size(), value); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); EXPECT_EQ(res.ec, std::errc::result_out_of_range); EXPECT_EQ(value, TypeParam{42}); } @@ -99,7 +99,7 @@ TYPED_TEST(integral_from_char_test, partial_parsing) { // interleaved char std::vector const str{'1', 'a', '3'}; - auto res = std::from_chars(&str[0], &str[0] + str.size(), value); + auto res = std::from_chars(str.data(), str.data() + str.size(), value); EXPECT_EQ(res.ptr, &str[1]); EXPECT_EQ(res.ec, std::errc{}); @@ -110,7 +110,7 @@ TYPED_TEST(integral_from_char_test, partial_parsing) { // trailing char std::vector const str{'1', '2', 'a'}; - auto res = std::from_chars(&str[0], &str[0] + str.size(), value); + auto res = std::from_chars(str.data(), str.data() + str.size(), value); EXPECT_EQ(res.ptr, &str[2]); EXPECT_EQ(res.ec, std::errc{}); @@ -121,7 +121,7 @@ TYPED_TEST(integral_from_char_test, partial_parsing) { // float std::vector const str{'1', '.', '3'}; - auto res = std::from_chars(&str[0], &str[0] + str.size(), value); + auto res = std::from_chars(str.data(), str.data() + str.size(), value); EXPECT_EQ(res.ptr, &str[1]); EXPECT_EQ(res.ec, std::errc{}); @@ -131,7 +131,7 @@ TYPED_TEST(integral_from_char_test, partial_parsing) { // hexadecimal 0x prefix is not recognized std::vector const str{'0', 'x', '3', 'f'}; - auto res = std::from_chars(&str[0], &str[0] + str.size(), value, 16); + auto res = std::from_chars(str.data(), str.data() + str.size(), value, 16); EXPECT_EQ(res.ptr, &str[1]); EXPECT_EQ(res.ec, std::errc{}); @@ -141,7 +141,7 @@ TYPED_TEST(integral_from_char_test, partial_parsing) { // hexadecimal 0X prefix is not recognized std::vector const str{'0', 'X', '3', 'f'}; - auto res = std::from_chars(&str[0], &str[0] + str.size(), value, 16); + auto res = std::from_chars(str.data(), str.data() + str.size(), value, 16); EXPECT_EQ(res.ptr, &str[1]); EXPECT_EQ(res.ec, std::errc{}); @@ -156,9 +156,9 @@ TYPED_TEST(integral_from_char_test, invalid_argument_error) { // leading char std::vector const str{'a', '1', '3'}; - auto res = std::from_chars(&str[0], &str[0] + str.size(), value); + auto res = std::from_chars(str.data(), str.data() + str.size(), value); - EXPECT_EQ(res.ptr, &str[0]); + EXPECT_EQ(res.ptr, str.data()); EXPECT_EQ(res.ec, std::errc::invalid_argument); EXPECT_EQ(value, TypeParam{42}); } @@ -166,9 +166,9 @@ TYPED_TEST(integral_from_char_test, invalid_argument_error) { // leading + sign (or do we want this to succeed?) std::vector const str{'+', '1', '3'}; - auto res = std::from_chars(&str[0], &str[0] + str.size(), value); + auto res = std::from_chars(str.data(), str.data() + str.size(), value); - EXPECT_EQ(res.ptr, &str[0]); + EXPECT_EQ(res.ptr, str.data()); EXPECT_EQ(res.ec, std::errc::invalid_argument); EXPECT_EQ(value, TypeParam{42}); } @@ -176,9 +176,9 @@ TYPED_TEST(integral_from_char_test, invalid_argument_error) { // hexadecimal x prefix is not recognized std::vector const str{'x', '3', 'f'}; - auto res = std::from_chars(&str[0], &str[0] + str.size(), value, 16); + auto res = std::from_chars(str.data(), str.data() + str.size(), value, 16); - EXPECT_EQ(res.ptr, &str[0]); + EXPECT_EQ(res.ptr, str.data()); EXPECT_EQ(res.ec, std::errc::invalid_argument); EXPECT_EQ(value, TypeParam{42}); } @@ -189,9 +189,9 @@ TYPED_TEST(integral_from_char_test, binary_number) TypeParam value{42}; std::vector const str{'1', '1', '0', '1'}; - auto res = std::from_chars(&str[0], &str[0] + str.size(), value, 2); + auto res = std::from_chars(str.data(), str.data() + str.size(), value, 2); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); EXPECT_EQ(res.ec, std::errc{}); EXPECT_EQ(value, TypeParam{13}); } @@ -206,9 +206,9 @@ TYPED_TEST(integral_from_char_test, hexadicimal_number) // be updated when header is included into the stl. std::vector const str{'3', 'F'}; - auto res = std::from_chars(&str[0], &str[0] + str.size(), value, 16); + auto res = std::from_chars(str.data(), str.data() + str.size(), value, 16); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); EXPECT_EQ(res.ec, std::errc{}); EXPECT_EQ(value, TypeParam{63}); } @@ -217,9 +217,9 @@ TYPED_TEST(integral_from_char_test, hexadicimal_number) { std::vector const str{'3', 'f'}; - auto res = std::from_chars(&str[0], &str[0] + str.size(), value, 16); + auto res = std::from_chars(str.data(), str.data() + str.size(), value, 16); - EXPECT_EQ(res.ptr, &str[0] + str.size()); + EXPECT_EQ(res.ptr, str.data() + str.size()); EXPECT_EQ(res.ec, std::errc{}); EXPECT_EQ(value, TypeParam{63}); }