From 3bd400f6fe6c32b0425d77c271de9c7e87ea9fbf Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Tue, 25 Feb 2020 11:48:16 -0400 Subject: [PATCH] Fix string_view C++17 compatibility string_view was implicitly convertible to std::string, but std::string_view is only explicitly convertible. This makes the `operator std::string` explicit to be more compatible, and re-adds a bunch of explicit string casts to the code where needed. (This also fixes the build if changing the standard to c++17) --- llarp/config/config.cpp | 38 +++++++++++++-------------- llarp/config/ini.cpp | 2 +- llarp/handlers/tun.cpp | 2 +- llarp/util/string_view.hpp | 12 ++++++++- test/config/test_llarp_config_ini.cpp | 4 --- test/util/test_llarp_util_str.cpp | 4 +-- 6 files changed, 34 insertions(+), 28 deletions(-) diff --git a/llarp/config/config.cpp b/llarp/config/config.cpp index 46bfd4ca7..392b8b58d 100644 --- a/llarp/config/config.cpp +++ b/llarp/config/config.cpp @@ -106,14 +106,14 @@ namespace llarp } if(key == "default-protocol") { - m_DefaultLinkProto = val; + m_DefaultLinkProto = str(val); LogInfo("overriding default link protocol to '", val, "'"); } if(key == "netid") { if(val.size() <= NetID::size()) { - m_netId = val; + m_netId = str(val); LogInfo("setting netid to '", val, "'"); } else @@ -141,29 +141,29 @@ namespace llarp } if(key == "nickname") { - m_nickname = val; + m_nickname = str(val); // set logger name here LogContext::Instance().nodeName = nickname(); LogInfo("nickname set"); } if(key == "encryption-privkey") { - m_encryptionKeyfile = val; + m_encryptionKeyfile = str(val); LogDebug("encryption key set to ", m_encryptionKeyfile); } if(key == "contact-file") { - m_ourRcFile = val; + m_ourRcFile = str(val); LogDebug("rc file set to ", m_ourRcFile); } if(key == "transport-privkey") { - m_transportKeyfile = val; + m_transportKeyfile = str(val); LogDebug("transport key set to ", m_transportKeyfile); } if((key == "identity-privkey" || key == "ident-privkey")) { - m_identKeyfile = val; + m_identKeyfile = str(val); LogDebug("identity key set to ", m_identKeyfile); } if(key == "public-address" || key == "public-ip") @@ -229,12 +229,12 @@ namespace llarp } else if(key == "profiles") { - m_routerProfilesFile = val; + m_routerProfilesFile = str(val); llarp::LogInfo("setting profiles to ", routerProfilesFile()); } else if(key == "strict-connect") { - m_strictConnect = val; + m_strictConnect = str(val); } else { @@ -247,7 +247,7 @@ namespace llarp { if(key == "dir") { - m_nodedbDir = val; + m_nodedbDir = str(val); } } @@ -279,12 +279,12 @@ namespace llarp idx = val.find_first_of(delimiter); if(idx != string_view::npos) { - parsed_opts.insert(TrimWhitespace(val.substr(0, idx))); + parsed_opts.emplace(TrimWhitespace(val.substr(0, idx))); val.remove_prefix(idx + 1); } else { - parsed_opts.insert(TrimWhitespace(val)); + parsed_opts.emplace(TrimWhitespace(val)); } } while(idx != string_view::npos); std::unordered_set< std::string > opts; @@ -335,7 +335,7 @@ namespace llarp { if(key == "pidfile") { - pidfile = val; + pidfile = str(val); } } @@ -348,7 +348,7 @@ namespace llarp } if(key == "bind") { - m_rpcBindAddr = val; + m_rpcBindAddr = str(val); } if(key == "authkey") { @@ -370,15 +370,15 @@ namespace llarp } if(key == "jsonrpc" || key == "addr") { - lokidRPCAddr = val; + lokidRPCAddr = str(val); } if(key == "username") { - lokidRPCUser = val; + lokidRPCUser = str(val); } if(key == "password") { - lokidRPCPassword = val; + lokidRPCPassword = str(val); } } @@ -406,7 +406,7 @@ namespace llarp } if(key == "level") { - const auto maybe = LogLevelFromString(val); + const auto maybe = LogLevelFromString(str(val)); if(not maybe.has_value()) { LogError("bad log level: ", val); @@ -423,7 +423,7 @@ namespace llarp if(key == "file") { LogInfo("open log file: ", val); - std::string fname = val; + std::string fname{val}; FILE *const logfile = ::fopen(fname.c_str(), "a"); if(logfile) { diff --git a/llarp/config/ini.cpp b/llarp/config/ini.cpp index d30a81af0..8d68ac654 100644 --- a/llarp/config/ini.cpp +++ b/llarp/config/ini.cpp @@ -129,7 +129,7 @@ namespace llarp LogError(m_FileName, " invalid line (", lineno, "): '", line, "'"); return false; } - Section_t& sect = m_Config[sectName]; + Section_t& sect = m_Config[str(sectName)]; LogDebug(m_FileName, ": ", sectName, ".", k, "=", v); sect.emplace(k, v); } diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index d95aef442..fa39d404e 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -191,7 +191,7 @@ namespace llarp { routerStr = v; } - routerStr = TrimWhitespace(routerStr); + routerStr = str(TrimWhitespace(routerStr)); if(!(exitRouter.FromString(routerStr) || HexDecode(routerStr.c_str(), exitRouter.begin(), exitRouter.size()))) diff --git a/llarp/util/string_view.hpp b/llarp/util/string_view.hpp index 6fef3dec4..fd2266346 100644 --- a/llarp/util/string_view.hpp +++ b/llarp/util/string_view.hpp @@ -53,7 +53,7 @@ public: constexpr size_t length() const noexcept { return size_; } constexpr size_t max_size() const noexcept { return std::numeric_limits::max(); } constexpr bool empty() const noexcept { return size_ == 0; } - operator std::string() const { return {data_, size_}; } + explicit operator std::string() const { return {data_, size_}; } constexpr const char* begin() const noexcept { return data_; } constexpr const char* cbegin() const noexcept { return data_; } constexpr const char* end() const noexcept { return data_ + size_; } @@ -218,4 +218,14 @@ using string_view = simple_string_view; #endif +namespace llarp { + +// Shortcut for explicitly casting a string_view to a string. Saves 8 +// characters compared to `std::string(view)`. +inline std::string str(string_view s) { + return std::string{s}; +} + +} + #endif diff --git a/test/config/test_llarp_config_ini.cpp b/test/config/test_llarp_config_ini.cpp index 0e82aeb24..c78eee9fc 100644 --- a/test/config/test_llarp_config_ini.cpp +++ b/test/config/test_llarp_config_ini.cpp @@ -32,11 +32,7 @@ TEST_F(TestINIParser, TestParseOneSection) ASSERT_EQ(itr, sect.end()); itr = sect.find("key"); ASSERT_NE(itr, sect.end()); -#if __cplusplus >= 201703L - ASSERT_STREQ(llarp::string_view_string(itr->second).c_str(), "val"); -#else ASSERT_EQ(itr->second, "val"); -#endif } TEST_F(TestINIParser, TestParseSectionDuplicateKeys) diff --git a/test/util/test_llarp_util_str.cpp b/test/util/test_llarp_util_str.cpp index c621c6292..f4fc6ff9e 100644 --- a/test/util/test_llarp_util_str.cpp +++ b/test/util/test_llarp_util_str.cpp @@ -11,7 +11,7 @@ TEST_CASE("TrimWhitespace -- positive tests", "[str][trim]") auto fo = "\fthe "s; auto fum = " \t\r\n\v\f Beanstalk\n\n\n\t\r\f\v \n\n\r\f\f\f\f\v"s; for (auto* s: {&fee, &fi, &fo, &fum}) - *s = llarp::TrimWhitespace(*s); + *s = llarp::str(llarp::TrimWhitespace(*s)); REQUIRE( fee == "J a c k" ); REQUIRE( fi == "a\nd" ); @@ -24,7 +24,7 @@ TEST_CASE("TrimWhitespace -- negative tests", "[str][trim]") // Test that things that shouldn't be trimmed don't get trimmed auto c = GENERATE(range(std::numeric_limits::min(), std::numeric_limits::max())); std::string plant = c + "bean"s + c; - plant = llarp::TrimWhitespace(plant); + plant = llarp::str(llarp::TrimWhitespace(plant)); if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\f' || c == '\v') REQUIRE( plant == "bean" ); else