aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorevelkin <evelkin@yandex-team.com>2022-08-09 21:48:31 +0300
committerevelkin <evelkin@yandex-team.com>2022-08-09 21:48:31 +0300
commitdd2db1bb6afc3705b308e83bef1a467ac38d4427 (patch)
tree08057116ec1ec06069c4ed0fdf0ffacfa76fe2e3
parentf07e857ae1593c68375cdea3a2a9bdbdd164ccc8 (diff)
downloadydb-dd2db1bb6afc3705b308e83bef1a467ac38d4427.tar.gz
Introduce TryFromString returning TMaybe
Позволяем писать без неиницилизированных переменных по месту использования. Вот такую красоту например: ``` if (auto a = TryFromString<T>(str)) { что-то делаем с \*a } ```
-rw-r--r--util/string/cast.h31
-rw-r--r--util/string/cast_ut.cpp30
2 files changed, 59 insertions, 2 deletions
diff --git a/util/string/cast.h b/util/string/cast.h
index 90e925c194..3d94ecb0de 100644
--- a/util/string/cast.h
+++ b/util/string/cast.h
@@ -2,6 +2,7 @@
#include <util/system/defaults.h>
#include <util/stream/str.h>
+#include <util/generic/maybe.h>
#include <util/generic/string.h>
#include <util/generic/strbuf.h>
#include <util/generic/typetraits.h>
@@ -270,6 +271,36 @@ inline bool TryFromString(const TUtf16String& s, T& result) {
return TryFromString<T>(s.data(), s.size(), result);
}
+template <class T, class TChar>
+inline TMaybe<T> TryFromString(TBasicStringBuf<TChar> s) {
+ TMaybe<T> result{NMaybe::TInPlace{}};
+ if (!TryFromString<T>(s, *result)) {
+ result.Clear();
+ }
+
+ return result;
+}
+
+template <class T, class TChar>
+inline TMaybe<T> TryFromString(const TChar* data) {
+ return TryFromString<T>(TBasicStringBuf<TChar>(data));
+}
+
+template <class T>
+inline TMaybe<T> TryFromString(const TString& s) {
+ return TryFromString<T>(TStringBuf(s));
+}
+
+template <class T>
+inline TMaybe<T> TryFromString(const std::string& s) {
+ return TryFromString<T>(TStringBuf(s));
+}
+
+template <class T>
+inline TMaybe<T> TryFromString(const TUtf16String& s) {
+ return TryFromString<T>(TWtringBuf(s));
+}
+
template <class T, class TStringType>
inline bool TryFromStringWithDefault(const TStringType& s, T& result, const T& def) {
return TryFromString<T>(s.data(), s.size(), result, def);
diff --git a/util/string/cast_ut.cpp b/util/string/cast_ut.cpp
index ca235c1436..8690fa78dc 100644
--- a/util/string/cast_ut.cpp
+++ b/util/string/cast_ut.cpp
@@ -300,8 +300,8 @@ Y_UNIT_TEST_SUITE(TCastTest) {
BadFloatTester<float>("a10E-5");
BadFloatTester<float>("10 ");
BadFloatTester<float>("10\t");
- //BadFloatTester<float>("10E");
- //BadFloatTester<float>("10.E");
+ // BadFloatTester<float>("10E");
+ // BadFloatTester<float>("10.E");
BadFloatTester<float>("..0");
BadFloatTester<float>(""); // IGNIETFERRO-300
BadFloatTester<double>("1.00.01");
@@ -437,6 +437,32 @@ Y_UNIT_TEST_SUITE(TCastTest) {
UNIT_ASSERT_VALUES_EQUAL(FromStringWithDefault<size_t>(s4), size_t());
}
+ Y_UNIT_TEST(TestMaybe) {
+ TMaybe<int> res;
+
+ TString s1("100500");
+ UNIT_CHECK_GENERATED_NO_EXCEPTION(res = TryFromString<int>(s1), yexception);
+ UNIT_ASSERT_VALUES_EQUAL(res, 100500);
+
+ UNIT_ASSERT_VALUES_EQUAL(TryFromString<int>("100500"), 100500);
+
+ TString s2("100q500");
+ UNIT_CHECK_GENERATED_NO_EXCEPTION(res = TryFromString<int>(s2), yexception);
+ UNIT_ASSERT(res.Empty());
+
+ TUtf16String s3 = u"-100500";
+ UNIT_CHECK_GENERATED_NO_EXCEPTION(res = TryFromString<size_t>(s3), yexception);
+ UNIT_ASSERT(res.Empty());
+
+ TUtf16String s4 = u"-f100500";
+ UNIT_CHECK_GENERATED_NO_EXCEPTION(res = TryFromString<int>(s4), yexception);
+ UNIT_ASSERT(res.Empty());
+
+ std::string s5 = "100500";
+ UNIT_CHECK_GENERATED_NO_EXCEPTION(res = TryFromString<int>(s5), yexception);
+ UNIT_ASSERT_VALUES_EQUAL(res, 100500);
+ }
+
Y_UNIT_TEST(TestBool) {
// True cases
UNIT_ASSERT_VALUES_EQUAL(FromString<bool>("yes"), true);