diff options
author | evelkin <evelkin@yandex-team.com> | 2022-08-09 21:48:31 +0300 |
---|---|---|
committer | evelkin <evelkin@yandex-team.com> | 2022-08-09 21:48:31 +0300 |
commit | dd2db1bb6afc3705b308e83bef1a467ac38d4427 (patch) | |
tree | 08057116ec1ec06069c4ed0fdf0ffacfa76fe2e3 | |
parent | f07e857ae1593c68375cdea3a2a9bdbdd164ccc8 (diff) | |
download | ydb-dd2db1bb6afc3705b308e83bef1a467ac38d4427.tar.gz |
Introduce TryFromString returning TMaybe
Позволяем писать без неиницилизированных переменных по месту использования.
Вот такую красоту например:
```
if (auto a = TryFromString<T>(str)) {
что-то делаем с \*a
}
```
-rw-r--r-- | util/string/cast.h | 31 | ||||
-rw-r--r-- | util/string/cast_ut.cpp | 30 |
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); |