aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/yt
diff options
context:
space:
mode:
authorbabenko <babenko@yandex-team.ru>2022-02-10 16:49:19 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:49:19 +0300
commitf31097c96270919a1f49360bdaaa69ea4f3fefab (patch)
tree5d5cb817648f650d76cf1076100726fd9b8448e8 /library/cpp/yt
parentcec37806d8847aa3db53bafc9e251d4aaf325c12 (diff)
downloadydb-f31097c96270919a1f49360bdaaa69ea4f3fefab.tar.gz
Restoring authorship annotation for <babenko@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'library/cpp/yt')
-rw-r--r--library/cpp/yt/assert/assert.cpp58
-rw-r--r--library/cpp/yt/assert/assert.h152
-rw-r--r--library/cpp/yt/assert/ya.make18
-rw-r--r--library/cpp/yt/coding/unittests/varint_ut.cpp268
-rw-r--r--library/cpp/yt/coding/unittests/ya.make30
-rw-r--r--library/cpp/yt/coding/unittests/zig_zag_ut.cpp114
-rw-r--r--library/cpp/yt/coding/varint-inl.h322
-rw-r--r--library/cpp/yt/coding/varint.h26
-rw-r--r--library/cpp/yt/coding/ya.make24
-rw-r--r--library/cpp/yt/coding/zig_zag-inl.h80
-rw-r--r--library/cpp/yt/coding/zig_zag.h22
-rw-r--r--library/cpp/yt/exception/exception.cpp96
-rw-r--r--library/cpp/yt/exception/exception.h90
-rw-r--r--library/cpp/yt/exception/ya.make14
-rw-r--r--library/cpp/yt/malloc/malloc.cpp38
-rw-r--r--library/cpp/yt/malloc/malloc.h16
-rw-r--r--library/cpp/yt/malloc/ya.make14
-rw-r--r--library/cpp/yt/memory/blob.cpp140
-rw-r--r--library/cpp/yt/memory/blob.h138
-rw-r--r--library/cpp/yt/memory/intrusive_ptr.h176
-rw-r--r--library/cpp/yt/memory/leaky_ref_counted_singleton-inl.h86
-rw-r--r--library/cpp/yt/memory/leaky_ref_counted_singleton.h36
-rw-r--r--library/cpp/yt/memory/leaky_singleton-inl.h68
-rw-r--r--library/cpp/yt/memory/leaky_singleton.h46
-rw-r--r--library/cpp/yt/memory/new-inl.h2
-rw-r--r--library/cpp/yt/memory/new.h150
-rw-r--r--library/cpp/yt/memory/range.h462
-rw-r--r--library/cpp/yt/memory/ref-inl.h1020
-rw-r--r--library/cpp/yt/memory/ref.cpp474
-rw-r--r--library/cpp/yt/memory/ref.h470
-rw-r--r--library/cpp/yt/memory/ref_counted-inl.h4
-rw-r--r--library/cpp/yt/memory/ref_counted.h54
-rw-r--r--library/cpp/yt/memory/ref_tracked.h20
-rw-r--r--library/cpp/yt/memory/shared_range.h500
-rw-r--r--library/cpp/yt/memory/unittests/intrusive_ptr_ut.cpp964
-rw-r--r--library/cpp/yt/memory/unittests/weak_ptr_ut.cpp800
-rw-r--r--library/cpp/yt/memory/unittests/ya.make2
-rw-r--r--library/cpp/yt/memory/weak_ptr.h80
-rw-r--r--library/cpp/yt/memory/ya.make12
-rw-r--r--library/cpp/yt/misc/cast-inl.h62
-rw-r--r--library/cpp/yt/misc/cast.h8
-rw-r--r--library/cpp/yt/misc/enum-inl.h618
-rw-r--r--library/cpp/yt/misc/enum.h392
-rw-r--r--library/cpp/yt/misc/guid-inl.h132
-rw-r--r--library/cpp/yt/misc/guid.cpp76
-rw-r--r--library/cpp/yt/misc/guid.h128
-rw-r--r--library/cpp/yt/misc/hash-inl.h90
-rw-r--r--library/cpp/yt/misc/hash.h50
-rw-r--r--library/cpp/yt/misc/port.h114
-rw-r--r--library/cpp/yt/misc/preprocessor-gen.h1298
-rw-r--r--library/cpp/yt/misc/preprocessor-gen.h.pump138
-rw-r--r--library/cpp/yt/misc/preprocessor.h248
-rw-r--r--library/cpp/yt/misc/property.h202
-rw-r--r--library/cpp/yt/misc/source_location.cpp106
-rw-r--r--library/cpp/yt/misc/source_location.h76
-rw-r--r--library/cpp/yt/misc/unittests/enum_ut.cpp496
-rw-r--r--library/cpp/yt/misc/unittests/guid_ut.cpp36
-rw-r--r--library/cpp/yt/misc/unittests/preprocessor_ut.cpp204
-rw-r--r--library/cpp/yt/misc/unittests/ya.make26
-rw-r--r--library/cpp/yt/misc/variant-inl.h136
-rw-r--r--library/cpp/yt/misc/variant.h82
-rw-r--r--library/cpp/yt/misc/ya.make10
-rw-r--r--library/cpp/yt/small_containers/compact_set.h4
-rw-r--r--library/cpp/yt/small_containers/compact_vector-inl.h1968
-rw-r--r--library/cpp/yt/small_containers/compact_vector.h424
-rw-r--r--library/cpp/yt/small_containers/unittests/compact_flat_map_ut.cpp336
-rw-r--r--library/cpp/yt/small_containers/unittests/compact_set_ut.cpp362
-rw-r--r--library/cpp/yt/small_containers/unittests/compact_vector_ut.cpp2090
-rw-r--r--library/cpp/yt/small_containers/unittests/ya.make6
-rw-r--r--library/cpp/yt/small_containers/ya.make4
-rw-r--r--library/cpp/yt/string/enum-inl.h236
-rw-r--r--library/cpp/yt/string/enum.cpp58
-rw-r--r--library/cpp/yt/string/enum.h34
-rw-r--r--library/cpp/yt/string/format-inl.h918
-rw-r--r--library/cpp/yt/string/format.h160
-rw-r--r--library/cpp/yt/string/guid.cpp2
-rw-r--r--library/cpp/yt/string/string.cpp200
-rw-r--r--library/cpp/yt/string/string.h346
-rw-r--r--library/cpp/yt/string/string_builder-inl.h244
-rw-r--r--library/cpp/yt/string/string_builder.h214
-rw-r--r--library/cpp/yt/string/unittests/enum_ut.cpp114
-rw-r--r--library/cpp/yt/string/unittests/format_ut.cpp278
-rw-r--r--library/cpp/yt/string/unittests/guid_ut.cpp80
-rw-r--r--library/cpp/yt/string/unittests/string_ut.cpp102
-rw-r--r--library/cpp/yt/string/unittests/ya.make2
-rw-r--r--library/cpp/yt/string/ya.make8
-rw-r--r--library/cpp/yt/ya.make30
-rw-r--r--library/cpp/yt/yson/consumer.cpp4
-rw-r--r--library/cpp/yt/yson/consumer.h10
-rw-r--r--library/cpp/yt/yson_string/convert.cpp762
-rw-r--r--library/cpp/yt/yson_string/convert.h228
-rw-r--r--library/cpp/yt/yson_string/format.h88
-rw-r--r--library/cpp/yt/yson_string/public.h78
-rw-r--r--library/cpp/yt/yson_string/string-inl.h186
-rw-r--r--library/cpp/yt/yson_string/string.cpp288
-rw-r--r--library/cpp/yt/yson_string/string.h210
-rw-r--r--library/cpp/yt/yson_string/unittests/convert_ut.cpp158
-rw-r--r--library/cpp/yt/yson_string/unittests/ya.make30
-rw-r--r--library/cpp/yt/yson_string/ya.make42
99 files changed, 11059 insertions, 11059 deletions
diff --git a/library/cpp/yt/assert/assert.cpp b/library/cpp/yt/assert/assert.cpp
index 0c393c2511..095357cdfa 100644
--- a/library/cpp/yt/assert/assert.cpp
+++ b/library/cpp/yt/assert/assert.cpp
@@ -1,29 +1,29 @@
-#include "assert.h"
-
-#include <util/system/yassert.h>
-#include <util/system/compiler.h>
-
-namespace NYT::NDetail {
-
-////////////////////////////////////////////////////////////////////////////////
-
-Y_WEAK void AssertTrapImpl(
- TStringBuf trapType,
- TStringBuf expr,
- TStringBuf file,
- int line,
- TStringBuf function)
-{
- // Map to Arcadia assert, poorly...
- ::NPrivate::Panic(
- ::NPrivate::TStaticBuf(file.data(), file.length()),
- line,
- function.data(),
- expr.data(),
- "%s",
- trapType.data());
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT::NDetail
+#include "assert.h"
+
+#include <util/system/yassert.h>
+#include <util/system/compiler.h>
+
+namespace NYT::NDetail {
+
+////////////////////////////////////////////////////////////////////////////////
+
+Y_WEAK void AssertTrapImpl(
+ TStringBuf trapType,
+ TStringBuf expr,
+ TStringBuf file,
+ int line,
+ TStringBuf function)
+{
+ // Map to Arcadia assert, poorly...
+ ::NPrivate::Panic(
+ ::NPrivate::TStaticBuf(file.data(), file.length()),
+ line,
+ function.data(),
+ expr.data(),
+ "%s",
+ trapType.data());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT::NDetail
diff --git a/library/cpp/yt/assert/assert.h b/library/cpp/yt/assert/assert.h
index 40f1d5d829..7a9e761a3a 100644
--- a/library/cpp/yt/assert/assert.h
+++ b/library/cpp/yt/assert/assert.h
@@ -1,76 +1,76 @@
-#pragma once
-
-#include <util/system/compiler.h>
-#include <util/system/src_root.h>
-
-#include <util/generic/strbuf.h>
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-namespace NDetail {
-
-[[noreturn]]
-void AssertTrapImpl(
- TStringBuf trapType,
- TStringBuf expr,
- TStringBuf file,
- int line,
- TStringBuf function);
-
-} // namespace NDetail
-
-#ifdef __GNUC__
- #define YT_BUILTIN_TRAP() __builtin_trap()
-#else
- #define YT_BUILTIN_TRAP() std::terminate()
-#endif
-
-#define YT_ASSERT_TRAP(trapType, expr) \
- ::NYT::NDetail::AssertTrapImpl(TStringBuf(trapType), TStringBuf(expr), __SOURCE_FILE_IMPL__.As<TStringBuf>(), __LINE__, TStringBuf(__FUNCTION__)); \
- Y_UNREACHABLE() \
-
-#ifdef NDEBUG
- #define YT_ASSERT(expr) \
- do { \
- if (false) { \
- (void) (expr); \
- } \
- } while (false)
-#else
- #define YT_ASSERT(expr) \
- do { \
- if (Y_UNLIKELY(!(expr))) { \
- YT_ASSERT_TRAP("YT_ASSERT", #expr); \
- } \
- } while (false)
-#endif
-
-//! Same as |YT_ASSERT| but evaluates and checks the expression in both release and debug mode.
-#define YT_VERIFY(expr) \
- do { \
- if (Y_UNLIKELY(!(expr))) { \
- YT_ASSERT_TRAP("YT_VERIFY", #expr); \
- } \
- } while (false)
-
-//! Fatal error code marker. Abnormally terminates the current process.
-#ifdef YT_COMPILING_UDF
- #define YT_ABORT() __YT_BUILTIN_ABORT()
-#else
- #define YT_ABORT() \
- do { \
- YT_ASSERT_TRAP("YT_ABORT", ""); \
- } while (false)
-#endif
-
-//! Unimplemented code marker. Abnormally terminates the current process.
-#define YT_UNIMPLEMENTED() \
- do { \
- YT_ASSERT_TRAP("YT_UNIMPLEMENTED", ""); \
- } while (false)
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
+#pragma once
+
+#include <util/system/compiler.h>
+#include <util/system/src_root.h>
+
+#include <util/generic/strbuf.h>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+namespace NDetail {
+
+[[noreturn]]
+void AssertTrapImpl(
+ TStringBuf trapType,
+ TStringBuf expr,
+ TStringBuf file,
+ int line,
+ TStringBuf function);
+
+} // namespace NDetail
+
+#ifdef __GNUC__
+ #define YT_BUILTIN_TRAP() __builtin_trap()
+#else
+ #define YT_BUILTIN_TRAP() std::terminate()
+#endif
+
+#define YT_ASSERT_TRAP(trapType, expr) \
+ ::NYT::NDetail::AssertTrapImpl(TStringBuf(trapType), TStringBuf(expr), __SOURCE_FILE_IMPL__.As<TStringBuf>(), __LINE__, TStringBuf(__FUNCTION__)); \
+ Y_UNREACHABLE() \
+
+#ifdef NDEBUG
+ #define YT_ASSERT(expr) \
+ do { \
+ if (false) { \
+ (void) (expr); \
+ } \
+ } while (false)
+#else
+ #define YT_ASSERT(expr) \
+ do { \
+ if (Y_UNLIKELY(!(expr))) { \
+ YT_ASSERT_TRAP("YT_ASSERT", #expr); \
+ } \
+ } while (false)
+#endif
+
+//! Same as |YT_ASSERT| but evaluates and checks the expression in both release and debug mode.
+#define YT_VERIFY(expr) \
+ do { \
+ if (Y_UNLIKELY(!(expr))) { \
+ YT_ASSERT_TRAP("YT_VERIFY", #expr); \
+ } \
+ } while (false)
+
+//! Fatal error code marker. Abnormally terminates the current process.
+#ifdef YT_COMPILING_UDF
+ #define YT_ABORT() __YT_BUILTIN_ABORT()
+#else
+ #define YT_ABORT() \
+ do { \
+ YT_ASSERT_TRAP("YT_ABORT", ""); \
+ } while (false)
+#endif
+
+//! Unimplemented code marker. Abnormally terminates the current process.
+#define YT_UNIMPLEMENTED() \
+ do { \
+ YT_ASSERT_TRAP("YT_UNIMPLEMENTED", ""); \
+ } while (false)
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/assert/ya.make b/library/cpp/yt/assert/ya.make
index 19358ca018..df74a4f1fa 100644
--- a/library/cpp/yt/assert/ya.make
+++ b/library/cpp/yt/assert/ya.make
@@ -1,9 +1,9 @@
-LIBRARY()
-
-OWNER(g:yt)
-
-SRCS(
- assert.cpp
-)
-
-END()
+LIBRARY()
+
+OWNER(g:yt)
+
+SRCS(
+ assert.cpp
+)
+
+END()
diff --git a/library/cpp/yt/coding/unittests/varint_ut.cpp b/library/cpp/yt/coding/unittests/varint_ut.cpp
index 8ebfdfbed8..ed83ab5c92 100644
--- a/library/cpp/yt/coding/unittests/varint_ut.cpp
+++ b/library/cpp/yt/coding/unittests/varint_ut.cpp
@@ -1,134 +1,134 @@
-#include <library/cpp/testing/gtest/gtest.h>
-
-#include <library/cpp/yt/coding/varint.h>
-
-#include <util/random/random.h>
-
-#include <util/string/escape.h>
-
-#include <tuple>
-
-namespace NYT {
-namespace {
-
-using ::testing::Values;
-
-////////////////////////////////////////////////////////////////////////////////
-
-class TWriteVarIntTest: public ::testing::TestWithParam<std::tuple<ui64, TString> >
-{ };
-
-TEST_P(TWriteVarIntTest, Serialization)
-{
- ui64 value = std::get<0>(GetParam());
- TString rightAnswer = std::get<1>(GetParam());
-
- TStringStream outputStream;
- WriteVarUint64(&outputStream, value);
- EXPECT_EQ(rightAnswer, outputStream.Str());
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-class TReadVarIntTest: public ::testing::TestWithParam<std::tuple<ui64, TString> >
-{ };
-
-TEST_P(TReadVarIntTest, Serialization)
-{
- ui64 rightAnswer = std::get<0>(GetParam());
- TString input = std::get<1>(GetParam());
-
- TStringInput inputStream(input);
- ui64 value;
- ReadVarUint64(&inputStream, &value);
- EXPECT_EQ(rightAnswer, value);
-}
-
-TEST(TReadVarIntTest, Overflow)
-{
- TString input("\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x01", 11);
- TStringInput inputStream(input);
- ui64 value;
- EXPECT_ANY_THROW(ReadVarUint64(&inputStream, &value));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-auto ValuesForVarIntTests = Values(
- // Simple cases.
- std::make_tuple(0x0ull, TString("\x00", 1)),
- std::make_tuple(0x1ull, TString("\x01", 1)),
- std::make_tuple(0x2ull, TString("\x02", 1)),
- std::make_tuple(0x3ull, TString("\x03", 1)),
- std::make_tuple(0x4ull, TString("\x04", 1)),
-
- // The following "magic numbers" are critical points for varint encoding.
- std::make_tuple((1ull << 7) - 1, TString("\x7f", 1)),
- std::make_tuple((1ull << 7), TString("\x80\x01", 2)),
- std::make_tuple((1ull << 14) - 1, TString("\xff\x7f", 2)),
- std::make_tuple((1ull << 14), TString("\x80\x80\x01", 3)),
- std::make_tuple((1ull << 21) - 1, TString("\xff\xff\x7f", 3)),
- std::make_tuple((1ull << 21), TString("\x80\x80\x80\x01", 4)),
- std::make_tuple((1ull << 28) - 1, TString("\xff\xff\xff\x7f", 4)),
- std::make_tuple((1ull << 28), TString("\x80\x80\x80\x80\x01", 5)),
- std::make_tuple((1ull << 35) - 1, TString("\xff\xff\xff\xff\x7f", 5)),
- std::make_tuple((1ull << 35), TString("\x80\x80\x80\x80\x80\x01", 6)),
- std::make_tuple((1ull << 42) - 1, TString("\xff\xff\xff\xff\xff\x7f", 6)),
- std::make_tuple((1ull << 42), TString("\x80\x80\x80\x80\x80\x80\x01", 7)),
- std::make_tuple((1ull << 49) - 1, TString("\xff\xff\xff\xff\xff\xff\x7f", 7)),
- std::make_tuple((1ull << 49), TString("\x80\x80\x80\x80\x80\x80\x80\x01", 8)),
- std::make_tuple((1ull << 56) - 1, TString("\xff\xff\xff\xff\xff\xff\xff\x7f", 8)),
- std::make_tuple((1ull << 56), TString("\x80\x80\x80\x80\x80\x80\x80\x80\x01", 9)),
- std::make_tuple((1ull << 63) - 1, TString("\xff\xff\xff\xff\xff\xff\xff\xff\x7f", 9)),
- std::make_tuple((1ull << 63), TString("\x80\x80\x80\x80\x80\x80\x80\x80\x80\x01", 10)),
-
- // Boundary case.
- std::make_tuple(static_cast<ui64>(-1), TString("\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01", 10))
-);
-
-INSTANTIATE_TEST_SUITE_P(ValueParametrized, TWriteVarIntTest,
- ValuesForVarIntTests);
-
-INSTANTIATE_TEST_SUITE_P(ValueParametrized, TReadVarIntTest,
- ValuesForVarIntTests);
-
-////////////////////////////////////////////////////////////////////////////////
-
-TEST(TVarInt32Test, RandomValues)
-{
- srand(100500); // Set seed
- const int numberOfValues = 10000;
-
- TStringStream stream;
- for (int i = 0; i < numberOfValues; ++i) {
- i32 expected = static_cast<i32>(RandomNumber<ui32>());
- WriteVarInt32(&stream, expected);
- i32 actual;
- ReadVarInt32(&stream, &actual);
- EXPECT_EQ(expected, actual)
- << "Encoded Variant: " << EscapeC(stream.Str());
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-TEST(TVarInt64Test, RandomValues)
-{
- srand(100500); // Set seed
- const int numberOfValues = 10000;
-
- TStringStream stream;
- for (int i = 0; i < numberOfValues; ++i) {
- i64 expected = static_cast<i64>(RandomNumber<ui64>());
- WriteVarInt64(&stream, expected);
- i64 actual;
- ReadVarInt64(&stream, &actual);
- EXPECT_EQ(expected, actual)
- << "Encoded Variant: " << EscapeC(stream.Str());
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace
-} // namespace NYT
+#include <library/cpp/testing/gtest/gtest.h>
+
+#include <library/cpp/yt/coding/varint.h>
+
+#include <util/random/random.h>
+
+#include <util/string/escape.h>
+
+#include <tuple>
+
+namespace NYT {
+namespace {
+
+using ::testing::Values;
+
+////////////////////////////////////////////////////////////////////////////////
+
+class TWriteVarIntTest: public ::testing::TestWithParam<std::tuple<ui64, TString> >
+{ };
+
+TEST_P(TWriteVarIntTest, Serialization)
+{
+ ui64 value = std::get<0>(GetParam());
+ TString rightAnswer = std::get<1>(GetParam());
+
+ TStringStream outputStream;
+ WriteVarUint64(&outputStream, value);
+ EXPECT_EQ(rightAnswer, outputStream.Str());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+class TReadVarIntTest: public ::testing::TestWithParam<std::tuple<ui64, TString> >
+{ };
+
+TEST_P(TReadVarIntTest, Serialization)
+{
+ ui64 rightAnswer = std::get<0>(GetParam());
+ TString input = std::get<1>(GetParam());
+
+ TStringInput inputStream(input);
+ ui64 value;
+ ReadVarUint64(&inputStream, &value);
+ EXPECT_EQ(rightAnswer, value);
+}
+
+TEST(TReadVarIntTest, Overflow)
+{
+ TString input("\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x01", 11);
+ TStringInput inputStream(input);
+ ui64 value;
+ EXPECT_ANY_THROW(ReadVarUint64(&inputStream, &value));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+auto ValuesForVarIntTests = Values(
+ // Simple cases.
+ std::make_tuple(0x0ull, TString("\x00", 1)),
+ std::make_tuple(0x1ull, TString("\x01", 1)),
+ std::make_tuple(0x2ull, TString("\x02", 1)),
+ std::make_tuple(0x3ull, TString("\x03", 1)),
+ std::make_tuple(0x4ull, TString("\x04", 1)),
+
+ // The following "magic numbers" are critical points for varint encoding.
+ std::make_tuple((1ull << 7) - 1, TString("\x7f", 1)),
+ std::make_tuple((1ull << 7), TString("\x80\x01", 2)),
+ std::make_tuple((1ull << 14) - 1, TString("\xff\x7f", 2)),
+ std::make_tuple((1ull << 14), TString("\x80\x80\x01", 3)),
+ std::make_tuple((1ull << 21) - 1, TString("\xff\xff\x7f", 3)),
+ std::make_tuple((1ull << 21), TString("\x80\x80\x80\x01", 4)),
+ std::make_tuple((1ull << 28) - 1, TString("\xff\xff\xff\x7f", 4)),
+ std::make_tuple((1ull << 28), TString("\x80\x80\x80\x80\x01", 5)),
+ std::make_tuple((1ull << 35) - 1, TString("\xff\xff\xff\xff\x7f", 5)),
+ std::make_tuple((1ull << 35), TString("\x80\x80\x80\x80\x80\x01", 6)),
+ std::make_tuple((1ull << 42) - 1, TString("\xff\xff\xff\xff\xff\x7f", 6)),
+ std::make_tuple((1ull << 42), TString("\x80\x80\x80\x80\x80\x80\x01", 7)),
+ std::make_tuple((1ull << 49) - 1, TString("\xff\xff\xff\xff\xff\xff\x7f", 7)),
+ std::make_tuple((1ull << 49), TString("\x80\x80\x80\x80\x80\x80\x80\x01", 8)),
+ std::make_tuple((1ull << 56) - 1, TString("\xff\xff\xff\xff\xff\xff\xff\x7f", 8)),
+ std::make_tuple((1ull << 56), TString("\x80\x80\x80\x80\x80\x80\x80\x80\x01", 9)),
+ std::make_tuple((1ull << 63) - 1, TString("\xff\xff\xff\xff\xff\xff\xff\xff\x7f", 9)),
+ std::make_tuple((1ull << 63), TString("\x80\x80\x80\x80\x80\x80\x80\x80\x80\x01", 10)),
+
+ // Boundary case.
+ std::make_tuple(static_cast<ui64>(-1), TString("\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01", 10))
+);
+
+INSTANTIATE_TEST_SUITE_P(ValueParametrized, TWriteVarIntTest,
+ ValuesForVarIntTests);
+
+INSTANTIATE_TEST_SUITE_P(ValueParametrized, TReadVarIntTest,
+ ValuesForVarIntTests);
+
+////////////////////////////////////////////////////////////////////////////////
+
+TEST(TVarInt32Test, RandomValues)
+{
+ srand(100500); // Set seed
+ const int numberOfValues = 10000;
+
+ TStringStream stream;
+ for (int i = 0; i < numberOfValues; ++i) {
+ i32 expected = static_cast<i32>(RandomNumber<ui32>());
+ WriteVarInt32(&stream, expected);
+ i32 actual;
+ ReadVarInt32(&stream, &actual);
+ EXPECT_EQ(expected, actual)
+ << "Encoded Variant: " << EscapeC(stream.Str());
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+TEST(TVarInt64Test, RandomValues)
+{
+ srand(100500); // Set seed
+ const int numberOfValues = 10000;
+
+ TStringStream stream;
+ for (int i = 0; i < numberOfValues; ++i) {
+ i64 expected = static_cast<i64>(RandomNumber<ui64>());
+ WriteVarInt64(&stream, expected);
+ i64 actual;
+ ReadVarInt64(&stream, &actual);
+ EXPECT_EQ(expected, actual)
+ << "Encoded Variant: " << EscapeC(stream.Str());
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace
+} // namespace NYT
diff --git a/library/cpp/yt/coding/unittests/ya.make b/library/cpp/yt/coding/unittests/ya.make
index 23e4387fb2..e0622db22d 100644
--- a/library/cpp/yt/coding/unittests/ya.make
+++ b/library/cpp/yt/coding/unittests/ya.make
@@ -1,15 +1,15 @@
-GTEST()
-
-OWNER(g:yt)
-
-SRCS(
- zig_zag_ut.cpp
- varint_ut.cpp
-)
-
-PEERDIR(
- library/cpp/yt/coding
- library/cpp/testing/gtest
-)
-
-END()
+GTEST()
+
+OWNER(g:yt)
+
+SRCS(
+ zig_zag_ut.cpp
+ varint_ut.cpp
+)
+
+PEERDIR(
+ library/cpp/yt/coding
+ library/cpp/testing/gtest
+)
+
+END()
diff --git a/library/cpp/yt/coding/unittests/zig_zag_ut.cpp b/library/cpp/yt/coding/unittests/zig_zag_ut.cpp
index ba092df287..fae4e63064 100644
--- a/library/cpp/yt/coding/unittests/zig_zag_ut.cpp
+++ b/library/cpp/yt/coding/unittests/zig_zag_ut.cpp
@@ -1,57 +1,57 @@
-#include <library/cpp/testing/gtest/gtest.h>
-
-#include <library/cpp/yt/coding/zig_zag.h>
-
-namespace NYT {
-namespace {
-
-////////////////////////////////////////////////////////////////////////////////
-
-TEST(TZigZagTest, Encode32)
-{
- EXPECT_EQ(0u, ZigZagEncode32( 0));
- EXPECT_EQ(1u, ZigZagEncode32(-1));
- EXPECT_EQ(2u, ZigZagEncode32( 1));
- EXPECT_EQ(3u, ZigZagEncode32(-2));
- // ...
- EXPECT_EQ(std::numeric_limits<ui32>::max() - 1, ZigZagEncode32(std::numeric_limits<i32>::max()));
- EXPECT_EQ(std::numeric_limits<ui32>::max(), ZigZagEncode32(std::numeric_limits<i32>::min()));
-}
-
-TEST(TZigZagTest, Decode32)
-{
- EXPECT_EQ( 0, ZigZagDecode32(0));
- EXPECT_EQ(-1, ZigZagDecode32(1));
- EXPECT_EQ( 1, ZigZagDecode32(2));
- EXPECT_EQ(-2, ZigZagDecode32(3));
- // ...
- EXPECT_EQ(std::numeric_limits<i32>::max(), ZigZagDecode32(std::numeric_limits<ui32>::max() - 1));
- EXPECT_EQ(std::numeric_limits<i32>::min(), ZigZagDecode32(std::numeric_limits<ui32>::max()));
-}
-
-TEST(TZigZagTest, Encode64)
-{
- EXPECT_EQ(0ull, ZigZagEncode64( 0));
- EXPECT_EQ(1ull, ZigZagEncode64(-1));
- EXPECT_EQ(2ull, ZigZagEncode64( 1));
- EXPECT_EQ(3ull, ZigZagEncode64(-2));
- // ...
- EXPECT_EQ(std::numeric_limits<ui64>::max() - 1, ZigZagEncode64(std::numeric_limits<i64>::max()));
- EXPECT_EQ(std::numeric_limits<ui64>::max(), ZigZagEncode64(std::numeric_limits<i64>::min()));
-}
-
-TEST(TZigZagTest, Decode64)
-{
- EXPECT_EQ(ZigZagDecode64(0), 0ll);
- EXPECT_EQ(ZigZagDecode64(1), -1ll);
- EXPECT_EQ(ZigZagDecode64(2), 1ll);
- EXPECT_EQ(ZigZagDecode64(3), -2ll);
- // ...
- EXPECT_EQ(std::numeric_limits<i64>::max(), ZigZagDecode64(std::numeric_limits<ui64>::max() - 1));
- EXPECT_EQ(std::numeric_limits<i64>::min(), ZigZagDecode64(std::numeric_limits<ui64>::max()));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace
-} // namespace NYT
+#include <library/cpp/testing/gtest/gtest.h>
+
+#include <library/cpp/yt/coding/zig_zag.h>
+
+namespace NYT {
+namespace {
+
+////////////////////////////////////////////////////////////////////////////////
+
+TEST(TZigZagTest, Encode32)
+{
+ EXPECT_EQ(0u, ZigZagEncode32( 0));
+ EXPECT_EQ(1u, ZigZagEncode32(-1));
+ EXPECT_EQ(2u, ZigZagEncode32( 1));
+ EXPECT_EQ(3u, ZigZagEncode32(-2));
+ // ...
+ EXPECT_EQ(std::numeric_limits<ui32>::max() - 1, ZigZagEncode32(std::numeric_limits<i32>::max()));
+ EXPECT_EQ(std::numeric_limits<ui32>::max(), ZigZagEncode32(std::numeric_limits<i32>::min()));
+}
+
+TEST(TZigZagTest, Decode32)
+{
+ EXPECT_EQ( 0, ZigZagDecode32(0));
+ EXPECT_EQ(-1, ZigZagDecode32(1));
+ EXPECT_EQ( 1, ZigZagDecode32(2));
+ EXPECT_EQ(-2, ZigZagDecode32(3));
+ // ...
+ EXPECT_EQ(std::numeric_limits<i32>::max(), ZigZagDecode32(std::numeric_limits<ui32>::max() - 1));
+ EXPECT_EQ(std::numeric_limits<i32>::min(), ZigZagDecode32(std::numeric_limits<ui32>::max()));
+}
+
+TEST(TZigZagTest, Encode64)
+{
+ EXPECT_EQ(0ull, ZigZagEncode64( 0));
+ EXPECT_EQ(1ull, ZigZagEncode64(-1));
+ EXPECT_EQ(2ull, ZigZagEncode64( 1));
+ EXPECT_EQ(3ull, ZigZagEncode64(-2));
+ // ...
+ EXPECT_EQ(std::numeric_limits<ui64>::max() - 1, ZigZagEncode64(std::numeric_limits<i64>::max()));
+ EXPECT_EQ(std::numeric_limits<ui64>::max(), ZigZagEncode64(std::numeric_limits<i64>::min()));
+}
+
+TEST(TZigZagTest, Decode64)
+{
+ EXPECT_EQ(ZigZagDecode64(0), 0ll);
+ EXPECT_EQ(ZigZagDecode64(1), -1ll);
+ EXPECT_EQ(ZigZagDecode64(2), 1ll);
+ EXPECT_EQ(ZigZagDecode64(3), -2ll);
+ // ...
+ EXPECT_EQ(std::numeric_limits<i64>::max(), ZigZagDecode64(std::numeric_limits<ui64>::max() - 1));
+ EXPECT_EQ(std::numeric_limits<i64>::min(), ZigZagDecode64(std::numeric_limits<ui64>::max()));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace
+} // namespace NYT
diff --git a/library/cpp/yt/coding/varint-inl.h b/library/cpp/yt/coding/varint-inl.h
index c70b737af3..f0a09e9d30 100644
--- a/library/cpp/yt/coding/varint-inl.h
+++ b/library/cpp/yt/coding/varint-inl.h
@@ -4,146 +4,146 @@
#include "varint.h"
#endif
-#include "zig_zag.h"
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class TWriteCallback>
+#include "zig_zag.h"
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class TWriteCallback>
Y_FORCE_INLINE int WriteVarUint64Impl(TWriteCallback doWrite, ui64 value)
-{
- bool stop = false;
- int bytesWritten = 0;
- while (!stop) {
- ++bytesWritten;
+{
+ bool stop = false;
+ int bytesWritten = 0;
+ while (!stop) {
+ ++bytesWritten;
ui8 byte = static_cast<ui8>(value | 0x80);
- value >>= 7;
- if (value == 0) {
- stop = true;
- byte &= 0x7F;
- }
- doWrite(byte);
- }
- return bytesWritten;
-}
-
-// These are optimized versions of these Read/Write functions in protobuf/io/coded_stream.cc.
+ value >>= 7;
+ if (value == 0) {
+ stop = true;
+ byte &= 0x7F;
+ }
+ doWrite(byte);
+ }
+ return bytesWritten;
+}
+
+// These are optimized versions of these Read/Write functions in protobuf/io/coded_stream.cc.
Y_FORCE_INLINE int WriteVarUint64(IOutputStream* output, ui64 value)
-{
+{
return WriteVarUint64Impl([&] (ui8 byte) {
- output->Write(byte);
- }, value);
-}
-
+ output->Write(byte);
+ }, value);
+}
+
Y_FORCE_INLINE int WriteVarUint64(char* output, ui64 value)
-{
+{
return WriteVarUint64Impl([&] (ui8 byte) {
*output++ = byte;
- }, value);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class TOutput>
+ }, value);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class TOutput>
Y_FORCE_INLINE int WriteVarUint32Impl(TOutput output, ui32 value)
-{
+{
return WriteVarUint64(output, static_cast<ui64>(value));
-}
-
+}
+
Y_FORCE_INLINE int WriteVarUint32(IOutputStream* output, ui32 value)
-{
+{
return WriteVarUint32Impl(output, value);
-}
-
+}
+
Y_FORCE_INLINE int WriteVarUint32(char* output, ui32 value)
-{
+{
return WriteVarUint32Impl(output, value);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class TOutput>
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class TOutput>
Y_FORCE_INLINE int WriteVarInt32Impl(TOutput output, i32 value)
-{
+{
return WriteVarUint64(output, static_cast<ui64>(ZigZagEncode32(value)));
-}
-
+}
+
Y_FORCE_INLINE int WriteVarInt32(IOutputStream* output, i32 value)
-{
- return WriteVarInt32Impl(output, value);
-}
-
+{
+ return WriteVarInt32Impl(output, value);
+}
+
Y_FORCE_INLINE int WriteVarInt32(char* output, i32 value)
-{
- return WriteVarInt32Impl(output, value);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class TOutput>
+{
+ return WriteVarInt32Impl(output, value);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class TOutput>
Y_FORCE_INLINE int WriteVarInt64Impl(TOutput output, i64 value)
-{
+{
return WriteVarUint64(output, static_cast<ui64>(ZigZagEncode64(value)));
-}
-
+}
+
Y_FORCE_INLINE int WriteVarInt64(IOutputStream* output, i64 value)
-{
- return WriteVarInt64Impl(output, value);
-}
-
+{
+ return WriteVarInt64Impl(output, value);
+}
+
Y_FORCE_INLINE int WriteVarInt64(char* output, i64 value)
-{
- return WriteVarInt64Impl(output, value);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class TReadCallback>
+{
+ return WriteVarInt64Impl(output, value);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class TReadCallback>
Y_FORCE_INLINE int ReadVarUint64Impl(TReadCallback doRead, ui64* value)
-{
- size_t count = 0;
- ui64 result = 0;
-
- ui8 byte;
- do {
- if (7 * count > 8 * sizeof(ui64) ) {
- throw TSimpleException("Value is too big for varuint64");
- }
- byte = doRead();
- result |= (static_cast<ui64> (byte & 0x7F)) << (7 * count);
- ++count;
- } while (byte & 0x80);
-
- *value = result;
- return count;
-}
-
+{
+ size_t count = 0;
+ ui64 result = 0;
+
+ ui8 byte;
+ do {
+ if (7 * count > 8 * sizeof(ui64) ) {
+ throw TSimpleException("Value is too big for varuint64");
+ }
+ byte = doRead();
+ result |= (static_cast<ui64> (byte & 0x7F)) << (7 * count);
+ ++count;
+ } while (byte & 0x80);
+
+ *value = result;
+ return count;
+}
+
Y_FORCE_INLINE int ReadVarUint64(IInputStream* input, ui64* value)
-{
+{
return ReadVarUint64Impl([&] () {
- char byte;
- if (input->Read(&byte, 1) != 1) {
- throw TSimpleException("Premature end of stream while reading varuint64");
- }
- return byte;
- }, value);
-}
-
+ char byte;
+ if (input->Read(&byte, 1) != 1) {
+ throw TSimpleException("Premature end of stream while reading varuint64");
+ }
+ return byte;
+ }, value);
+}
+
Y_FORCE_INLINE int ReadVarUint64(const char* input, ui64* value)
-{
+{
return ReadVarUint64Impl([&] () {
- char byte = *input;
- ++input;
- return byte;
- }, value);
-}
-
+ char byte = *input;
+ ++input;
+ return byte;
+ }, value);
+}
+
Y_FORCE_INLINE int ReadVarUint64(const char* input, const char* end, ui64* value)
{
return ReadVarUint64Impl([&] () {
if (input == end) {
- throw TSimpleException("Premature end of data while reading varuint64");
+ throw TSimpleException("Premature end of data while reading varuint64");
}
char byte = *input;
++input;
@@ -151,90 +151,90 @@ Y_FORCE_INLINE int ReadVarUint64(const char* input, const char* end, ui64* value
}, value);
}
-////////////////////////////////////////////////////////////////////////////////
-
+////////////////////////////////////////////////////////////////////////////////
+
template <class... Args>
Y_FORCE_INLINE int ReadVarUint32Impl(ui32* value, Args... args)
-{
- ui64 varInt;
+{
+ ui64 varInt;
int bytesRead = ReadVarUint64(args..., &varInt);
- if (varInt > std::numeric_limits<ui32>::max()) {
- throw TSimpleException("Value is too big for varuint32");
- }
- *value = static_cast<ui32>(varInt);
- return bytesRead;
-}
-
+ if (varInt > std::numeric_limits<ui32>::max()) {
+ throw TSimpleException("Value is too big for varuint32");
+ }
+ *value = static_cast<ui32>(varInt);
+ return bytesRead;
+}
+
Y_FORCE_INLINE int ReadVarUint32(IInputStream* input, ui32* value)
-{
+{
return ReadVarUint32Impl(value, input);
-}
-
+}
+
Y_FORCE_INLINE int ReadVarUint32(const char* input, ui32* value)
-{
+{
return ReadVarUint32Impl(value, input);
-}
-
+}
+
Y_FORCE_INLINE int ReadVarUint32(const char* input, const char* end, ui32* value)
{
return ReadVarUint32Impl(value, input, end);
}
-////////////////////////////////////////////////////////////////////////////////
-
+////////////////////////////////////////////////////////////////////////////////
+
template <class... Args>
Y_FORCE_INLINE int ReadVarInt32Impl(i32* value, Args... args)
-{
- ui64 varInt;
+{
+ ui64 varInt;
int bytesRead = ReadVarUint64(args..., &varInt);
- if (varInt > std::numeric_limits<ui32>::max()) {
- throw TSimpleException("Value is too big for varint32");
- }
- *value = ZigZagDecode32(static_cast<ui32>(varInt));
- return bytesRead;
-}
-
+ if (varInt > std::numeric_limits<ui32>::max()) {
+ throw TSimpleException("Value is too big for varint32");
+ }
+ *value = ZigZagDecode32(static_cast<ui32>(varInt));
+ return bytesRead;
+}
+
Y_FORCE_INLINE int ReadVarInt32(IInputStream* input, i32* value)
-{
+{
return ReadVarInt32Impl(value, input);
-}
-
+}
+
Y_FORCE_INLINE int ReadVarInt32(const char* input, i32* value)
-{
+{
return ReadVarInt32Impl(value, input);
-}
-
+}
+
Y_FORCE_INLINE int ReadVarInt32(const char* input, const char* end, i32* value)
{
return ReadVarInt32Impl(value, input, end);
}
-////////////////////////////////////////////////////////////////////////////////
-
+////////////////////////////////////////////////////////////////////////////////
+
template <class... Args>
Y_FORCE_INLINE int ReadVarInt64Impl(i64* value, Args... args)
-{
- ui64 varInt;
+{
+ ui64 varInt;
int bytesRead = ReadVarUint64(args..., &varInt);
- *value = ZigZagDecode64(varInt);
- return bytesRead;
-}
-
+ *value = ZigZagDecode64(varInt);
+ return bytesRead;
+}
+
Y_FORCE_INLINE int ReadVarInt64(IInputStream* input, i64* value)
-{
+{
return ReadVarInt64Impl(value, input);
-}
-
+}
+
Y_FORCE_INLINE int ReadVarInt64(const char* input, i64* value)
-{
+{
return ReadVarInt64Impl(value, input);
-}
-
+}
+
Y_FORCE_INLINE int ReadVarInt64(const char* input, const char* end, i64* value)
{
return ReadVarInt64Impl(value, input, end);
}
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/coding/varint.h b/library/cpp/yt/coding/varint.h
index 78e7e5990c..c5399f8b06 100644
--- a/library/cpp/yt/coding/varint.h
+++ b/library/cpp/yt/coding/varint.h
@@ -1,23 +1,23 @@
#pragma once
-#include <library/cpp/yt/exception/exception.h>
-
+#include <library/cpp/yt/exception/exception.h>
+
#include <util/system/defaults.h>
-#include <util/stream/input.h>
-#include <util/stream/output.h>
+#include <util/stream/input.h>
+#include <util/stream/output.h>
namespace NYT {
////////////////////////////////////////////////////////////////////////////////
-constexpr size_t MaxVarInt64Size = (8 * sizeof(ui64) - 1) / 7 + 1;
-constexpr size_t MaxVarUint64Size = (8 * sizeof(ui64) - 1) / 7 + 1;
+constexpr size_t MaxVarInt64Size = (8 * sizeof(ui64) - 1) / 7 + 1;
+constexpr size_t MaxVarUint64Size = (8 * sizeof(ui64) - 1) / 7 + 1;
-constexpr size_t MaxVarInt32Size = (8 * sizeof(ui32) - 1) / 7 + 1;
-constexpr size_t MaxVarUint32Size = (8 * sizeof(ui32) - 1) / 7 + 1;
+constexpr size_t MaxVarInt32Size = (8 * sizeof(ui32) - 1) / 7 + 1;
+constexpr size_t MaxVarUint32Size = (8 * sizeof(ui32) - 1) / 7 + 1;
-// Various functions to read/write varints.
+// Various functions to read/write varints.
// Returns the number of bytes written.
int WriteVarUint64(IOutputStream* output, ui64 value);
@@ -27,8 +27,8 @@ int WriteVarInt64(IOutputStream* output, i64 value);
int WriteVarUint64(char* output, ui64 value);
int WriteVarUint32(char* output, ui32 value);
-int WriteVarInt32(char* output, i32 value);
-int WriteVarInt64(char* output, i64 value);
+int WriteVarInt32(char* output, i32 value);
+int WriteVarInt64(char* output, i64 value);
// Returns the number of bytes read.
int ReadVarUint64(IInputStream* input, ui64* value);
@@ -38,8 +38,8 @@ int ReadVarInt64(IInputStream* input, i64* value);
int ReadVarUint64(const char* input, ui64* value);
int ReadVarUint32(const char* input, ui32* value);
-int ReadVarInt32(const char* input, i32* value);
-int ReadVarInt64(const char* input, i64* value);
+int ReadVarInt32(const char* input, i32* value);
+int ReadVarInt64(const char* input, i64* value);
// Throws exception if integer is not complete when `end' is reached.
int ReadVarUint64(const char* input, const char* end, ui64* value);
diff --git a/library/cpp/yt/coding/ya.make b/library/cpp/yt/coding/ya.make
index ca7b97fbfb..3dae919e57 100644
--- a/library/cpp/yt/coding/ya.make
+++ b/library/cpp/yt/coding/ya.make
@@ -1,12 +1,12 @@
-LIBRARY()
-
-SRCS(
-)
-
-PEERDIR(
- library/cpp/yt/exception
-)
-
-END()
-
-RECURSE_FOR_TESTS(unittests)
+LIBRARY()
+
+SRCS(
+)
+
+PEERDIR(
+ library/cpp/yt/exception
+)
+
+END()
+
+RECURSE_FOR_TESTS(unittests)
diff --git a/library/cpp/yt/coding/zig_zag-inl.h b/library/cpp/yt/coding/zig_zag-inl.h
index 67ad1f98b0..c611f7e1d4 100644
--- a/library/cpp/yt/coding/zig_zag-inl.h
+++ b/library/cpp/yt/coding/zig_zag-inl.h
@@ -1,40 +1,40 @@
-#ifndef ZIG_ZAG_INL_H_
-#error "Direct inclusion of this file is not allowed, include zig_zag.h"
-// For the sake of sane code completion.
-#include "zig_zag.h"
-#endif
-#undef ZIG_ZAG_INL_H_
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-inline ui32 ZigZagEncode32(i32 n)
-{
- // Note: the right-shift must be arithmetic.
- // Note: left shift must be unsigned because of overflow.
- return (static_cast<ui32>(n) << 1) ^ static_cast<ui32>(n >> 31);
-}
-
-inline i32 ZigZagDecode32(ui32 n)
-{
- // Note: using unsigned types prevent undefined behavior.
- return static_cast<i32>((n >> 1) ^ (~(n & 1) + 1));
-}
-
-inline ui64 ZigZagEncode64(i64 n)
-{
- // Note: the right-shift must be arithmetic.
- // Note: left shift must be unsigned because of overflow.
- return (static_cast<ui64>(n) << 1) ^ static_cast<ui64>(n >> 63);
-}
-
-inline i64 ZigZagDecode64(ui64 n)
-{
- // Note: using unsigned types prevent undefined behavior.
- return static_cast<i64>((n >> 1) ^ (~(n & 1) + 1));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
+#ifndef ZIG_ZAG_INL_H_
+#error "Direct inclusion of this file is not allowed, include zig_zag.h"
+// For the sake of sane code completion.
+#include "zig_zag.h"
+#endif
+#undef ZIG_ZAG_INL_H_
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+inline ui32 ZigZagEncode32(i32 n)
+{
+ // Note: the right-shift must be arithmetic.
+ // Note: left shift must be unsigned because of overflow.
+ return (static_cast<ui32>(n) << 1) ^ static_cast<ui32>(n >> 31);
+}
+
+inline i32 ZigZagDecode32(ui32 n)
+{
+ // Note: using unsigned types prevent undefined behavior.
+ return static_cast<i32>((n >> 1) ^ (~(n & 1) + 1));
+}
+
+inline ui64 ZigZagEncode64(i64 n)
+{
+ // Note: the right-shift must be arithmetic.
+ // Note: left shift must be unsigned because of overflow.
+ return (static_cast<ui64>(n) << 1) ^ static_cast<ui64>(n >> 63);
+}
+
+inline i64 ZigZagDecode64(ui64 n)
+{
+ // Note: using unsigned types prevent undefined behavior.
+ return static_cast<i64>((n >> 1) ^ (~(n & 1) + 1));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/coding/zig_zag.h b/library/cpp/yt/coding/zig_zag.h
index 19782704e7..aa6d425a1c 100644
--- a/library/cpp/yt/coding/zig_zag.h
+++ b/library/cpp/yt/coding/zig_zag.h
@@ -1,24 +1,24 @@
#pragma once
-#include <util/system/types.h>
+#include <util/system/types.h>
namespace NYT {
////////////////////////////////////////////////////////////////////////////////
-// These Functions provide coding of integers with property: 0 <= f(x) <= 2 * |x|
-// Actually taken 'as is' from protobuf/wire_format_lite.h
+// These Functions provide coding of integers with property: 0 <= f(x) <= 2 * |x|
+// Actually taken 'as is' from protobuf/wire_format_lite.h
-ui32 ZigZagEncode32(i32 n);
-i32 ZigZagDecode32(ui32 n);
+ui32 ZigZagEncode32(i32 n);
+i32 ZigZagDecode32(ui32 n);
-ui64 ZigZagEncode64(i64 n);
-i64 ZigZagDecode64(ui64 n);
+ui64 ZigZagEncode64(i64 n);
+i64 ZigZagDecode64(ui64 n);
////////////////////////////////////////////////////////////////////////////////
} // namespace NYT
-
-#define ZIG_ZAG_INL_H_
-#include "zig_zag-inl.h"
-#undef ZIG_ZAG_INL_H_
+
+#define ZIG_ZAG_INL_H_
+#include "zig_zag-inl.h"
+#undef ZIG_ZAG_INL_H_
diff --git a/library/cpp/yt/exception/exception.cpp b/library/cpp/yt/exception/exception.cpp
index fee90ec2dd..1059d497e8 100644
--- a/library/cpp/yt/exception/exception.cpp
+++ b/library/cpp/yt/exception/exception.cpp
@@ -1,48 +1,48 @@
-#include "exception.h"
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-TSimpleException::TSimpleException(TString message)
- : Message_(std::move(message))
-{ }
-
-const TString& TSimpleException::GetMesage() const
-{
- return Message_;
-}
-
-const char* TSimpleException::what() const noexcept
-{
- return Message_.c_str();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-TCompositeException::TCompositeException(TString message)
- : TSimpleException(std::move(message))
- , What_(Message_)
-{ }
-
-TCompositeException::TCompositeException(
- const std::exception& exception,
- TString message)
- : TSimpleException(message)
- , InnerException_(std::current_exception())
- , What_(message + "\n" + exception.what())
-{ }
-
-const std::exception_ptr& TCompositeException::GetInnerException() const
-{
- return InnerException_;
-}
-
-const char* TCompositeException::what() const noexcept
-{
- return What_.c_str();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
+#include "exception.h"
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+TSimpleException::TSimpleException(TString message)
+ : Message_(std::move(message))
+{ }
+
+const TString& TSimpleException::GetMesage() const
+{
+ return Message_;
+}
+
+const char* TSimpleException::what() const noexcept
+{
+ return Message_.c_str();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+TCompositeException::TCompositeException(TString message)
+ : TSimpleException(std::move(message))
+ , What_(Message_)
+{ }
+
+TCompositeException::TCompositeException(
+ const std::exception& exception,
+ TString message)
+ : TSimpleException(message)
+ , InnerException_(std::current_exception())
+ , What_(message + "\n" + exception.what())
+{ }
+
+const std::exception_ptr& TCompositeException::GetInnerException() const
+{
+ return InnerException_;
+}
+
+const char* TCompositeException::what() const noexcept
+{
+ return What_.c_str();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/exception/exception.h b/library/cpp/yt/exception/exception.h
index 9697c1d51f..7d35637d60 100644
--- a/library/cpp/yt/exception/exception.h
+++ b/library/cpp/yt/exception/exception.h
@@ -1,45 +1,45 @@
-#pragma once
-
-#include <util/generic/string.h>
-
-#include <exception>
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-// These are poor man's versions of NYT::TErrorException to be used in
-// a limited subset of core libraries that are needed to implement NYT::TError.
-
-class TSimpleException
- : public std::exception
-{
-public:
- explicit TSimpleException(TString message);
-
- const TString& GetMesage() const;
- const char* what() const noexcept override;
-
-protected:
- const TString Message_;
-};
-
-class TCompositeException
- : public TSimpleException
-{
-public:
- explicit TCompositeException(TString message);
- TCompositeException(
- const std::exception& exception,
- TString message);
-
- const std::exception_ptr& GetInnerException() const;
- const char* what() const noexcept override;
-
-private:
- const std::exception_ptr InnerException_;
- const TString What_;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
+#pragma once
+
+#include <util/generic/string.h>
+
+#include <exception>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+// These are poor man's versions of NYT::TErrorException to be used in
+// a limited subset of core libraries that are needed to implement NYT::TError.
+
+class TSimpleException
+ : public std::exception
+{
+public:
+ explicit TSimpleException(TString message);
+
+ const TString& GetMesage() const;
+ const char* what() const noexcept override;
+
+protected:
+ const TString Message_;
+};
+
+class TCompositeException
+ : public TSimpleException
+{
+public:
+ explicit TCompositeException(TString message);
+ TCompositeException(
+ const std::exception& exception,
+ TString message);
+
+ const std::exception_ptr& GetInnerException() const;
+ const char* what() const noexcept override;
+
+private:
+ const std::exception_ptr InnerException_;
+ const TString What_;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/exception/ya.make b/library/cpp/yt/exception/ya.make
index a93b31edd9..0c89c31dc3 100644
--- a/library/cpp/yt/exception/ya.make
+++ b/library/cpp/yt/exception/ya.make
@@ -1,7 +1,7 @@
-LIBRARY()
-
-SRCS(
- exception.cpp
-)
-
-END()
+LIBRARY()
+
+SRCS(
+ exception.cpp
+)
+
+END()
diff --git a/library/cpp/yt/malloc/malloc.cpp b/library/cpp/yt/malloc/malloc.cpp
index e43a96f2ac..808afacdfb 100644
--- a/library/cpp/yt/malloc/malloc.cpp
+++ b/library/cpp/yt/malloc/malloc.cpp
@@ -1,19 +1,19 @@
-#include "malloc.h"
-
-#include <util/system/compiler.h>
-
-////////////////////////////////////////////////////////////////////////////////
-
-Y_WEAK extern "C" size_t nallocx(size_t size, int /* flags */) noexcept
-{
- return size;
-}
-
-#ifndef _win_
-Y_WEAK extern "C" size_t malloc_usable_size(void* /* ptr */) noexcept
-{
- return 0;
-}
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
+#include "malloc.h"
+
+#include <util/system/compiler.h>
+
+////////////////////////////////////////////////////////////////////////////////
+
+Y_WEAK extern "C" size_t nallocx(size_t size, int /* flags */) noexcept
+{
+ return size;
+}
+
+#ifndef _win_
+Y_WEAK extern "C" size_t malloc_usable_size(void* /* ptr */) noexcept
+{
+ return 0;
+}
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
diff --git a/library/cpp/yt/malloc/malloc.h b/library/cpp/yt/malloc/malloc.h
index 592d4dbe29..b3c16d7849 100644
--- a/library/cpp/yt/malloc/malloc.h
+++ b/library/cpp/yt/malloc/malloc.h
@@ -1,8 +1,8 @@
-#include <cstddef>
-
-////////////////////////////////////////////////////////////////////////////////
-
-extern "C" size_t malloc_usable_size(void* ptr) noexcept;
-extern "C" size_t nallocx(size_t size, int flags) noexcept;
-
-////////////////////////////////////////////////////////////////////////////////
+#include <cstddef>
+
+////////////////////////////////////////////////////////////////////////////////
+
+extern "C" size_t malloc_usable_size(void* ptr) noexcept;
+extern "C" size_t nallocx(size_t size, int flags) noexcept;
+
+////////////////////////////////////////////////////////////////////////////////
diff --git a/library/cpp/yt/malloc/ya.make b/library/cpp/yt/malloc/ya.make
index 8e36a95292..0a07d93b36 100644
--- a/library/cpp/yt/malloc/ya.make
+++ b/library/cpp/yt/malloc/ya.make
@@ -1,7 +1,7 @@
-LIBRARY()
-
-SRCS(
- malloc.cpp
-)
-
-END()
+LIBRARY()
+
+SRCS(
+ malloc.cpp
+)
+
+END()
diff --git a/library/cpp/yt/memory/blob.cpp b/library/cpp/yt/memory/blob.cpp
index cfc2cf6dba..86000b033b 100644
--- a/library/cpp/yt/memory/blob.cpp
+++ b/library/cpp/yt/memory/blob.cpp
@@ -1,65 +1,65 @@
#include "blob.h"
#include "ref.h"
-#include <library/cpp/ytalloc/api/ytalloc.h>
-
+#include <library/cpp/ytalloc/api/ytalloc.h>
+
namespace NYT {
////////////////////////////////////////////////////////////////////////////////
-static constexpr size_t InitialBlobCapacity = 16;
-static constexpr double BlobCapacityMultiplier = 1.5;
+static constexpr size_t InitialBlobCapacity = 16;
+static constexpr double BlobCapacityMultiplier = 1.5;
TBlob::TBlob(
TRefCountedTypeCookie tagCookie,
size_t size,
bool initiailizeStorage,
- bool pageAligned)
- : PageAligned_(pageAligned)
+ bool pageAligned)
+ : PageAligned_(pageAligned)
{
- SetTagCookie(tagCookie);
+ SetTagCookie(tagCookie);
if (size == 0) {
Reset();
} else {
Allocate(std::max(size, InitialBlobCapacity));
- Size_ = size;
+ Size_ = size;
if (initiailizeStorage) {
- ::memset(Begin_, 0, Size_);
+ ::memset(Begin_, 0, Size_);
}
}
}
TBlob::TBlob(
TRefCountedTypeCookie tagCookie,
- TRef data,
- bool pageAligned)
- : PageAligned_(pageAligned)
+ TRef data,
+ bool pageAligned)
+ : PageAligned_(pageAligned)
{
- SetTagCookie(tagCookie);
+ SetTagCookie(tagCookie);
Reset();
- Append(data);
+ Append(data);
}
TBlob::TBlob(const TBlob& other)
- : PageAligned_(other.PageAligned_)
+ : PageAligned_(other.PageAligned_)
{
- SetTagCookie(other);
+ SetTagCookie(other);
if (other.Size_ == 0) {
Reset();
} else {
Allocate(std::max(InitialBlobCapacity, other.Size_));
- ::memcpy(Begin_, other.Begin_, other.Size_);
- Size_ = other.Size_;
+ ::memcpy(Begin_, other.Begin_, other.Size_);
+ Size_ = other.Size_;
}
}
TBlob::TBlob(TBlob&& other) noexcept
- : Begin_(other.Begin_)
+ : Begin_(other.Begin_)
, Size_(other.Size_)
, Capacity_(other.Capacity_)
- , PageAligned_(other.PageAligned_)
+ , PageAligned_(other.PageAligned_)
{
- SetTagCookie(other);
+ SetTagCookie(other);
other.Reset();
}
@@ -88,7 +88,7 @@ void TBlob::Resize(size_t newSize, bool initializeStorage /*= true*/)
Reallocate(newCapacity);
}
if (initializeStorage) {
- ::memset(Begin_ + Size_, 0, newSize - Size_);
+ ::memset(Begin_ + Size_, 0, newSize - Size_);
}
}
Size_ = newSize;
@@ -114,66 +114,66 @@ TBlob& TBlob::operator = (TBlob&& rhs) noexcept
void TBlob::Append(const void* data, size_t size)
{
- if (Size_ + size > Capacity_) {
- Resize(Size_ + size, false);
- ::memcpy(Begin_ + Size_ - size, data, size);
- } else {
- ::memcpy(Begin_ + Size_, data, size);
- Size_ += size;
- }
+ if (Size_ + size > Capacity_) {
+ Resize(Size_ + size, false);
+ ::memcpy(Begin_ + Size_ - size, data, size);
+ } else {
+ ::memcpy(Begin_ + Size_, data, size);
+ Size_ += size;
+ }
}
-void TBlob::Append(TRef ref)
+void TBlob::Append(TRef ref)
{
Append(ref.Begin(), ref.Size());
}
-void TBlob::Append(char ch)
-{
- if (Size_ + 1 > Capacity_) {
- Resize(Size_ + 1, false);
- Begin_[Size_ - 1] = ch;
- } else {
- Begin_[Size_++] = ch;
- }
-}
-
+void TBlob::Append(char ch)
+{
+ if (Size_ + 1 > Capacity_) {
+ Resize(Size_ + 1, false);
+ Begin_[Size_ - 1] = ch;
+ } else {
+ Begin_[Size_++] = ch;
+ }
+}
+
void TBlob::Reset()
{
- Begin_ = nullptr;
+ Begin_ = nullptr;
Size_ = Capacity_ = 0;
}
-char* TBlob::DoAllocate(size_t size)
-{
- return static_cast<char*>(PageAligned_
- ? NYTAlloc::AllocatePageAligned(size)
- : NYTAlloc::Allocate(size));
-}
-
+char* TBlob::DoAllocate(size_t size)
+{
+ return static_cast<char*>(PageAligned_
+ ? NYTAlloc::AllocatePageAligned(size)
+ : NYTAlloc::Allocate(size));
+}
+
void TBlob::Allocate(size_t newCapacity)
{
- YT_VERIFY(!Begin_);
- Begin_ = DoAllocate(newCapacity);
+ YT_VERIFY(!Begin_);
+ Begin_ = DoAllocate(newCapacity);
Capacity_ = newCapacity;
#ifdef YT_ENABLE_REF_COUNTED_TRACKING
- TRefCountedTrackerFacade::AllocateTagInstance(TagCookie_);
- TRefCountedTrackerFacade::AllocateSpace(TagCookie_, newCapacity);
+ TRefCountedTrackerFacade::AllocateTagInstance(TagCookie_);
+ TRefCountedTrackerFacade::AllocateSpace(TagCookie_, newCapacity);
#endif
}
void TBlob::Reallocate(size_t newCapacity)
{
- if (!Begin_) {
+ if (!Begin_) {
Allocate(newCapacity);
return;
}
- char* newBegin = DoAllocate(newCapacity);
- ::memcpy(newBegin, Begin_, Size_);
- NYTAlloc::FreeNonNull(Begin_);
+ char* newBegin = DoAllocate(newCapacity);
+ ::memcpy(newBegin, Begin_, Size_);
+ NYTAlloc::FreeNonNull(Begin_);
#ifdef YT_ENABLE_REF_COUNTED_TRACKING
- TRefCountedTrackerFacade::AllocateSpace(TagCookie_, newCapacity);
- TRefCountedTrackerFacade::FreeSpace(TagCookie_, Capacity_);
+ TRefCountedTrackerFacade::AllocateSpace(TagCookie_, newCapacity);
+ TRefCountedTrackerFacade::FreeSpace(TagCookie_, Capacity_);
#endif
Begin_ = newBegin;
Capacity_ = newCapacity;
@@ -181,28 +181,28 @@ void TBlob::Reallocate(size_t newCapacity)
void TBlob::Free()
{
- if (!Begin_) {
+ if (!Begin_) {
return;
}
- NYTAlloc::FreeNonNull(Begin_);
+ NYTAlloc::FreeNonNull(Begin_);
#ifdef YT_ENABLE_REF_COUNTED_TRACKING
- TRefCountedTrackerFacade::FreeTagInstance(TagCookie_);
- TRefCountedTrackerFacade::FreeSpace(TagCookie_, Capacity_);
+ TRefCountedTrackerFacade::FreeTagInstance(TagCookie_);
+ TRefCountedTrackerFacade::FreeSpace(TagCookie_, Capacity_);
#endif
- Reset();
+ Reset();
}
-void TBlob::SetTagCookie(TRefCountedTypeCookie tagCookie)
+void TBlob::SetTagCookie(TRefCountedTypeCookie tagCookie)
{
#ifdef YT_ENABLE_REF_COUNTED_TRACKING
- TagCookie_ = tagCookie;
+ TagCookie_ = tagCookie;
#endif
}
-
-void TBlob::SetTagCookie(const TBlob& other)
+
+void TBlob::SetTagCookie(const TBlob& other)
{
#ifdef YT_ENABLE_REF_COUNTED_TRACKING
- TagCookie_ = other.TagCookie_;
+ TagCookie_ = other.TagCookie_;
#endif
}
@@ -212,9 +212,9 @@ void swap(TBlob& left, TBlob& right)
std::swap(left.Begin_, right.Begin_);
std::swap(left.Size_, right.Size_);
std::swap(left.Capacity_, right.Capacity_);
- std::swap(left.PageAligned_, right.PageAligned_);
+ std::swap(left.PageAligned_, right.PageAligned_);
#ifdef YT_ENABLE_REF_COUNTED_TRACKING
- std::swap(left.TagCookie_, right.TagCookie_);
+ std::swap(left.TagCookie_, right.TagCookie_);
#endif
}
}
diff --git a/library/cpp/yt/memory/blob.h b/library/cpp/yt/memory/blob.h
index 3490071848..99441fb8c9 100644
--- a/library/cpp/yt/memory/blob.h
+++ b/library/cpp/yt/memory/blob.h
@@ -1,6 +1,6 @@
#pragma once
-#include "ref.h"
+#include "ref.h"
#include "ref_counted.h"
namespace NYT {
@@ -8,8 +8,8 @@ namespace NYT {
////////////////////////////////////////////////////////////////////////////////
//! Default memory tag for TBlob.
-struct TDefaultBlobTag
-{ };
+struct TDefaultBlobTag
+{ };
//! A home-grown optimized replacement for |std::vector<char>| suitable for carrying
//! large chunks of data.
@@ -21,48 +21,48 @@ class TBlob
{
public:
//! Constructs a blob with a given size.
- TBlob(
- TRefCountedTypeCookie tagCookie,
- size_t size,
- bool initiailizeStorage = true,
- bool pageAligned = false);
+ TBlob(
+ TRefCountedTypeCookie tagCookie,
+ size_t size,
+ bool initiailizeStorage = true,
+ bool pageAligned = false);
//! Copies a chunk of memory into a new instance.
- TBlob(
- TRefCountedTypeCookie tagCookie,
- TRef data,
- bool pageAligned = false);
+ TBlob(
+ TRefCountedTypeCookie tagCookie,
+ TRef data,
+ bool pageAligned = false);
//! Constructs an empty blob.
template <class TTag = TDefaultBlobTag>
- explicit TBlob(TTag tag = {})
- : TBlob(tag, 0, true, false)
+ explicit TBlob(TTag tag = {})
+ : TBlob(tag, 0, true, false)
{ }
//! Constructs a blob with a given size.
template <class TTag>
- explicit TBlob(
- TTag,
- size_t size,
- bool initiailizeStorage = true,
- bool pageAligned = false)
- : TBlob(
- GetRefCountedTypeCookie<TTag>(),
- size,
- initiailizeStorage,
- pageAligned)
+ explicit TBlob(
+ TTag,
+ size_t size,
+ bool initiailizeStorage = true,
+ bool pageAligned = false)
+ : TBlob(
+ GetRefCountedTypeCookie<TTag>(),
+ size,
+ initiailizeStorage,
+ pageAligned)
{ }
//! Copies a chunk of memory into a new instance.
template <class TTag>
- TBlob(
- TTag,
- TRef data,
- bool pageAligned = false)
- : TBlob(
- GetRefCountedTypeCookie<TTag>(),
- data,
- pageAligned)
+ TBlob(
+ TTag,
+ TRef data,
+ bool pageAligned = false)
+ : TBlob(
+ GetRefCountedTypeCookie<TTag>(),
+ data,
+ pageAligned)
{ }
//! Remind user about the tag argument.
@@ -70,8 +70,8 @@ public:
TBlob(i64 size, bool initiailizeStorage = true) = delete;
TBlob(ui32 size, bool initiailizeStorage = true) = delete;
TBlob(ui64 size, bool initiailizeStorage = true) = delete;
- template <typename T, typename U>
- TBlob(const T*, U) = delete;
+ template <typename T, typename U>
+ TBlob(const T*, U) = delete;
//! Copies the data.
TBlob(const TBlob& other);
@@ -95,25 +95,25 @@ public:
void Resize(size_t newSize, bool initializeStorage = true);
//! Returns the start pointer.
- Y_FORCE_INLINE const char* Begin() const
+ Y_FORCE_INLINE const char* Begin() const
{
return Begin_;
}
//! Returns the start pointer.
- Y_FORCE_INLINE char* Begin()
+ Y_FORCE_INLINE char* Begin()
{
return Begin_;
}
//! Returns the end pointer.
- Y_FORCE_INLINE const char* End() const
+ Y_FORCE_INLINE const char* End() const
{
return Begin_ + Size_;
}
//! Returns the end pointer.
- Y_FORCE_INLINE char* End()
+ Y_FORCE_INLINE char* End()
{
return Begin_ + Size_;
}
@@ -125,49 +125,49 @@ public:
}
//! Returns the size.
- Y_FORCE_INLINE size_t Size() const
+ Y_FORCE_INLINE size_t Size() const
{
return Size_;
}
//! Returns the capacity.
- Y_FORCE_INLINE size_t Capacity() const
+ Y_FORCE_INLINE size_t Capacity() const
{
return Capacity_;
}
- //! Returns the TStringBuf instance for the occupied part of the blob.
- Y_FORCE_INLINE TStringBuf ToStringBuf() const
- {
- return TStringBuf(Begin_, Size_);
- }
-
- //! Returns the TRef instance for the occupied part of the blob.
- Y_FORCE_INLINE TRef ToRef() const
- {
- return TRef(Begin_, Size_);
- }
-
+ //! Returns the TStringBuf instance for the occupied part of the blob.
+ Y_FORCE_INLINE TStringBuf ToStringBuf() const
+ {
+ return TStringBuf(Begin_, Size_);
+ }
+
+ //! Returns the TRef instance for the occupied part of the blob.
+ Y_FORCE_INLINE TRef ToRef() const
+ {
+ return TRef(Begin_, Size_);
+ }
+
//! Provides by-value access to the underlying storage.
- Y_FORCE_INLINE char operator [] (size_t index) const
+ Y_FORCE_INLINE char operator [] (size_t index) const
{
return Begin_[index];
}
//! Provides by-ref access to the underlying storage.
- Y_FORCE_INLINE char& operator [] (size_t index)
+ Y_FORCE_INLINE char& operator [] (size_t index)
{
return Begin_[index];
}
//! Clears the instance but does not reclaim the memory.
- Y_FORCE_INLINE void Clear()
+ Y_FORCE_INLINE void Clear()
{
Size_ = 0;
}
//! Returns |true| if size is zero.
- Y_FORCE_INLINE bool IsEmpty() const
+ Y_FORCE_INLINE bool IsEmpty() const
{
return Size_ == 0;
}
@@ -182,35 +182,35 @@ public:
void Append(const void* data, size_t size);
//! Appends a chunk of memory to the end.
- void Append(TRef ref);
+ void Append(TRef ref);
+
+ //! Appends a single char to the end.
+ void Append(char ch);
- //! Appends a single char to the end.
- void Append(char ch);
-
//! Swaps the current and other instances
void Swap(TBlob& other);
-
+
friend void swap(TBlob& left, TBlob& right);
private:
- char* Begin_ = nullptr;
- size_t Size_ = 0;
- size_t Capacity_ = 0;
- bool PageAligned_ = false;
+ char* Begin_ = nullptr;
+ size_t Size_ = 0;
+ size_t Capacity_ = 0;
+ bool PageAligned_ = false;
#ifdef YT_ENABLE_REF_COUNTED_TRACKING
- TRefCountedTypeCookie TagCookie_ = NullRefCountedTypeCookie;
+ TRefCountedTypeCookie TagCookie_ = NullRefCountedTypeCookie;
#endif
- char* DoAllocate(size_t newCapacity);
+ char* DoAllocate(size_t newCapacity);
void Allocate(size_t newCapacity);
void Reallocate(size_t newCapacity);
void Free();
void Reset();
- void SetTagCookie(TRefCountedTypeCookie tagCookie);
- void SetTagCookie(const TBlob& other);
+ void SetTagCookie(TRefCountedTypeCookie tagCookie);
+ void SetTagCookie(const TBlob& other);
};
void swap(TBlob& left, TBlob& right);
diff --git a/library/cpp/yt/memory/intrusive_ptr.h b/library/cpp/yt/memory/intrusive_ptr.h
index d40a71766f..3dead7db1d 100644
--- a/library/cpp/yt/memory/intrusive_ptr.h
+++ b/library/cpp/yt/memory/intrusive_ptr.h
@@ -1,29 +1,29 @@
-#pragma once
-
+#pragma once
+
#include "ref_counted.h"
-
-#include <util/generic/hash.h>
+
+#include <util/generic/hash.h>
#include <util/generic/utility.h>
#include <utility>
#include <type_traits>
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
template <class T>
class TIntrusivePtr
{
public:
- typedef T TUnderlying;
-
+ typedef T TUnderlying;
+
constexpr TIntrusivePtr() noexcept
- { }
-
+ { }
+
constexpr TIntrusivePtr(std::nullptr_t) noexcept
- { }
-
+ { }
+
//! Constructor from an unqualified reference.
/*!
* Note that this constructor could be racy due to unsynchronized operations
@@ -33,22 +33,22 @@ public:
* given the current amount of code written.
*/
TIntrusivePtr(T* obj, bool addReference = true) noexcept
- : T_(obj)
+ : T_(obj)
{
if (T_ && addReference) {
- Ref(T_);
- }
- }
-
+ Ref(T_);
+ }
+ }
+
//! Copy constructor.
TIntrusivePtr(const TIntrusivePtr& other) noexcept
: T_(other.Get())
{
- if (T_) {
- Ref(T_);
+ if (T_) {
+ Ref(T_);
}
}
-
+
//! Copy constructor with an upcast.
template <class U, class = typename std::enable_if_t<std::is_convertible_v<U*, T*>>>
TIntrusivePtr(const TIntrusivePtr<U>& other) noexcept
@@ -57,16 +57,16 @@ public:
static_assert(
std::is_base_of_v<TRefCountedBase, T>,
"Cast allowed only for types derived from TRefCountedBase");
- if (T_) {
- Ref(T_);
- }
+ if (T_) {
+ Ref(T_);
+ }
}
-
+
//! Move constructor.
TIntrusivePtr(TIntrusivePtr&& other) noexcept
: T_(other.Get())
{
- other.T_ = nullptr;
+ other.T_ = nullptr;
}
//! Move constructor with an upcast.
@@ -77,19 +77,19 @@ public:
static_assert(
std::is_base_of_v<TRefCountedBase, T>,
"Cast allowed only for types derived from TRefCountedBase");
- other.T_ = nullptr;
+ other.T_ = nullptr;
}
//! Destructor.
~TIntrusivePtr()
{
- if (T_) {
- Unref(T_);
- }
+ if (T_) {
+ Unref(T_);
+ }
}
-
+
//! Copy assignment operator.
- TIntrusivePtr& operator=(const TIntrusivePtr& other) noexcept
+ TIntrusivePtr& operator=(const TIntrusivePtr& other) noexcept
{
TIntrusivePtr(other).Swap(*this);
return *this;
@@ -97,7 +97,7 @@ public:
//! Copy assignment operator with an upcast.
template <class U>
- TIntrusivePtr& operator=(const TIntrusivePtr<U>& other) noexcept
+ TIntrusivePtr& operator=(const TIntrusivePtr<U>& other) noexcept
{
static_assert(
std::is_convertible_v<U*, T*>,
@@ -118,7 +118,7 @@ public:
//! Move assignment operator with an upcast.
template <class U>
- TIntrusivePtr& operator=(TIntrusivePtr<U>&& other) noexcept
+ TIntrusivePtr& operator=(TIntrusivePtr<U>&& other) noexcept
{
static_assert(
std::is_convertible_v<U*, T*>,
@@ -130,21 +130,21 @@ public:
return *this;
}
- //! Drop the pointer.
+ //! Drop the pointer.
void Reset() // noexcept
{
TIntrusivePtr().Swap(*this);
}
- //! Replace the pointer with a specified one.
+ //! Replace the pointer with a specified one.
void Reset(T* p) // noexcept
{
TIntrusivePtr(p).Swap(*this);
}
- //! Returns the pointer.
- T* Get() const noexcept
- {
+ //! Returns the pointer.
+ T* Get() const noexcept
+ {
return T_;
}
@@ -156,46 +156,46 @@ public:
return p;
}
- T& operator*() const noexcept
+ T& operator*() const noexcept
{
- YT_ASSERT(T_);
+ YT_ASSERT(T_);
return *T_;
}
- T* operator->() const noexcept
+ T* operator->() const noexcept
{
- YT_ASSERT(T_);
+ YT_ASSERT(T_);
return T_;
}
- explicit operator bool() const noexcept
- {
+ explicit operator bool() const noexcept
+ {
return T_ != nullptr;
- }
-
+ }
+
//! Swap the pointer with the other one.
- void Swap(TIntrusivePtr& r) noexcept
- {
+ void Swap(TIntrusivePtr& r) noexcept
+ {
DoSwap(T_, r.T_);
}
private:
template <class U>
friend class TIntrusivePtr;
-
- T* T_ = nullptr;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-//! Creates a strong pointer wrapper for a given raw pointer.
-//! Compared to |TIntrusivePtr<T>::ctor|, type inference enables omitting |T|.
+
+ T* T_ = nullptr;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+//! Creates a strong pointer wrapper for a given raw pointer.
+//! Compared to |TIntrusivePtr<T>::ctor|, type inference enables omitting |T|.
template <class T>
-TIntrusivePtr<T> MakeStrong(T* p)
-{
- return TIntrusivePtr<T>(p);
-}
-
+TIntrusivePtr<T> MakeStrong(T* p)
+{
+ return TIntrusivePtr<T>(p);
+}
+
//! Tries to obtain an intrusive pointer for an object that may had
//! already lost all of its references and, thus, is about to be deleted.
/*!
@@ -221,8 +221,8 @@ Y_FORCE_INLINE TIntrusivePtr<T> DangerousGetPtr(T* object)
: TIntrusivePtr<T>();
}
-////////////////////////////////////////////////////////////////////////////////
-
+////////////////////////////////////////////////////////////////////////////////
+
template <class T, class U>
TIntrusivePtr<T> StaticPointerCast(const TIntrusivePtr<U>& ptr)
{
@@ -255,18 +255,18 @@ TIntrusivePtr<T> DynamicPointerCast(const TIntrusivePtr<U>& ptr)
////////////////////////////////////////////////////////////////////////////////
-template <class T>
-bool operator<(const TIntrusivePtr<T>& lhs, const TIntrusivePtr<T>& rhs)
-{
- return lhs.Get() < rhs.Get();
-}
-
template <class T>
-bool operator>(const TIntrusivePtr<T>& lhs, const TIntrusivePtr<T>& rhs)
-{
- return lhs.Get() > rhs.Get();
-}
-
+bool operator<(const TIntrusivePtr<T>& lhs, const TIntrusivePtr<T>& rhs)
+{
+ return lhs.Get() < rhs.Get();
+}
+
+template <class T>
+bool operator>(const TIntrusivePtr<T>& lhs, const TIntrusivePtr<T>& rhs)
+{
+ return lhs.Get() > rhs.Get();
+}
+
template <class T, class U>
bool operator==(const TIntrusivePtr<T>& lhs, const TIntrusivePtr<U>& rhs)
{
@@ -345,16 +345,16 @@ bool operator!=(const TIntrusivePtr<T>& lhs, std::nullptr_t)
return nullptr != lhs.Get();
}
-////////////////////////////////////////////////////////////////////////////////
-
-} //namespace NYT
-
-//! A hasher for TIntrusivePtr.
-template <class T>
+////////////////////////////////////////////////////////////////////////////////
+
+} //namespace NYT
+
+//! A hasher for TIntrusivePtr.
+template <class T>
struct THash<NYT::TIntrusivePtr<T>>
-{
- Y_FORCE_INLINE size_t operator () (const NYT::TIntrusivePtr<T>& ptr) const
- {
- return THash<T*>()(ptr.Get());
- }
-};
+{
+ Y_FORCE_INLINE size_t operator () (const NYT::TIntrusivePtr<T>& ptr) const
+ {
+ return THash<T*>()(ptr.Get());
+ }
+};
diff --git a/library/cpp/yt/memory/leaky_ref_counted_singleton-inl.h b/library/cpp/yt/memory/leaky_ref_counted_singleton-inl.h
index b6f261543b..a68ec5ed6a 100644
--- a/library/cpp/yt/memory/leaky_ref_counted_singleton-inl.h
+++ b/library/cpp/yt/memory/leaky_ref_counted_singleton-inl.h
@@ -1,43 +1,43 @@
-#ifndef LEAKY_REF_COUNTED_SINGLETON_INL_H_
-#error "Direct inclusion of this file is not allowed, include leaky_ref_counted_singleton.h"
-// For the sake of sane code completion.
-#include "leaky_ref_counted_singleton.h"
-#endif
-
-#include "new.h"
-
-#include <atomic>
-#include <mutex>
-
-#include <util/system/compiler.h>
-#include <util/system/sanitizers.h>
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class T>
-TIntrusivePtr<T> LeakyRefCountedSingleton()
-{
- static std::atomic<T*> Ptr;
- auto* ptr = Ptr.load(std::memory_order_acquire);
- if (Y_LIKELY(ptr)) {
- return ptr;
- }
-
- static std::once_flag Initialized;
- std::call_once(Initialized, [] {
- auto ptr = New<T>();
- Ref(ptr.Get());
- Ptr.store(ptr.Get());
-#if defined(_asan_enabled_)
- NSan::MarkAsIntentionallyLeaked(ptr.Get());
-#endif
- });
-
- return Ptr.load();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
+#ifndef LEAKY_REF_COUNTED_SINGLETON_INL_H_
+#error "Direct inclusion of this file is not allowed, include leaky_ref_counted_singleton.h"
+// For the sake of sane code completion.
+#include "leaky_ref_counted_singleton.h"
+#endif
+
+#include "new.h"
+
+#include <atomic>
+#include <mutex>
+
+#include <util/system/compiler.h>
+#include <util/system/sanitizers.h>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T>
+TIntrusivePtr<T> LeakyRefCountedSingleton()
+{
+ static std::atomic<T*> Ptr;
+ auto* ptr = Ptr.load(std::memory_order_acquire);
+ if (Y_LIKELY(ptr)) {
+ return ptr;
+ }
+
+ static std::once_flag Initialized;
+ std::call_once(Initialized, [] {
+ auto ptr = New<T>();
+ Ref(ptr.Get());
+ Ptr.store(ptr.Get());
+#if defined(_asan_enabled_)
+ NSan::MarkAsIntentionallyLeaked(ptr.Get());
+#endif
+ });
+
+ return Ptr.load();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/memory/leaky_ref_counted_singleton.h b/library/cpp/yt/memory/leaky_ref_counted_singleton.h
index 93dbe7488a..1d5761bd9d 100644
--- a/library/cpp/yt/memory/leaky_ref_counted_singleton.h
+++ b/library/cpp/yt/memory/leaky_ref_counted_singleton.h
@@ -1,18 +1,18 @@
-#pragma once
-
-#include "intrusive_ptr.h"
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class T>
-TIntrusivePtr<T> LeakyRefCountedSingleton();
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
-
-#define LEAKY_REF_COUNTED_SINGLETON_INL_H_
-#include "leaky_ref_counted_singleton-inl.h"
-#undef LEAKY_REF_COUNTED_SINGLETON_INL_H_
+#pragma once
+
+#include "intrusive_ptr.h"
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T>
+TIntrusivePtr<T> LeakyRefCountedSingleton();
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
+
+#define LEAKY_REF_COUNTED_SINGLETON_INL_H_
+#include "leaky_ref_counted_singleton-inl.h"
+#undef LEAKY_REF_COUNTED_SINGLETON_INL_H_
diff --git a/library/cpp/yt/memory/leaky_singleton-inl.h b/library/cpp/yt/memory/leaky_singleton-inl.h
index 4c7212e1be..932747c921 100644
--- a/library/cpp/yt/memory/leaky_singleton-inl.h
+++ b/library/cpp/yt/memory/leaky_singleton-inl.h
@@ -1,34 +1,34 @@
-#ifndef LEAKY_SINGLETON_INL_H_
-#error "Direct inclusion of this file is not allowed, include leaky_singleton.h"
-// For the sake of sane code completion.
-#include "leaky_singleton.h"
-#endif
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class T>
-TLeakyStorage<T>::TLeakyStorage()
-{
- new (Get()) T();
-}
-
-template <class T>
-T* TLeakyStorage<T>::Get()
-{
- return reinterpret_cast<T*>(Buffer_);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class T>
-T* LeakySingleton()
-{
- static TLeakyStorage<T> Storage;
- return Storage.Get();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
+#ifndef LEAKY_SINGLETON_INL_H_
+#error "Direct inclusion of this file is not allowed, include leaky_singleton.h"
+// For the sake of sane code completion.
+#include "leaky_singleton.h"
+#endif
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T>
+TLeakyStorage<T>::TLeakyStorage()
+{
+ new (Get()) T();
+}
+
+template <class T>
+T* TLeakyStorage<T>::Get()
+{
+ return reinterpret_cast<T*>(Buffer_);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T>
+T* LeakySingleton()
+{
+ static TLeakyStorage<T> Storage;
+ return Storage.Get();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/memory/leaky_singleton.h b/library/cpp/yt/memory/leaky_singleton.h
index df157f5574..03b5e51d78 100644
--- a/library/cpp/yt/memory/leaky_singleton.h
+++ b/library/cpp/yt/memory/leaky_singleton.h
@@ -4,31 +4,31 @@ namespace NYT {
////////////////////////////////////////////////////////////////////////////////
-template <class T>
-class TLeakyStorage
-{
-public:
- TLeakyStorage();
-
- T* Get();
-
-private:
- alignas(T) char Buffer_[sizeof(T)];
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-#define DECLARE_LEAKY_SINGLETON_FRIEND() \
- template <class T> \
- friend class ::NYT::TLeakyStorage;
-
template <class T>
-T* LeakySingleton();
+class TLeakyStorage
+{
+public:
+ TLeakyStorage();
+
+ T* Get();
+
+private:
+ alignas(T) char Buffer_[sizeof(T)];
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+#define DECLARE_LEAKY_SINGLETON_FRIEND() \
+ template <class T> \
+ friend class ::NYT::TLeakyStorage;
+
+template <class T>
+T* LeakySingleton();
////////////////////////////////////////////////////////////////////////////////
} // namespace NYT
-
-#define LEAKY_SINGLETON_INL_H_
-#include "leaky_singleton-inl.h"
-#undef LEAKY_SINGLETON_INL_H_
+
+#define LEAKY_SINGLETON_INL_H_
+#include "leaky_singleton-inl.h"
+#undef LEAKY_SINGLETON_INL_H_
diff --git a/library/cpp/yt/memory/new-inl.h b/library/cpp/yt/memory/new-inl.h
index 8458a0c367..0a84818516 100644
--- a/library/cpp/yt/memory/new-inl.h
+++ b/library/cpp/yt/memory/new-inl.h
@@ -4,7 +4,7 @@
#include "new.h"
#endif
-#include <library/cpp/ytalloc/api/ytalloc.h>
+#include <library/cpp/ytalloc/api/ytalloc.h>
namespace NYT {
diff --git a/library/cpp/yt/memory/new.h b/library/cpp/yt/memory/new.h
index d8a1db0df4..2db45e0465 100644
--- a/library/cpp/yt/memory/new.h
+++ b/library/cpp/yt/memory/new.h
@@ -1,70 +1,70 @@
-#pragma once
-
+#pragma once
+
#include "intrusive_ptr.h"
#include "ref_tracked.h"
-
-#include <library/cpp/yt/misc/source_location.h>
-
-#include <util/system/defaults.h>
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-/*!
- * \defgroup yt_new New<T> safe smart pointer constructors
- * \ingroup yt_new
- *
- * This is collection of safe smart pointer constructors.
- *
- * \page yt_new_rationale Rationale
- * New<T> function family was designed to prevent the following problem.
- * Consider the following piece of code.
- *
- * \code
- * class TFoo
- * : public virtual TRefCounted
- * {
- * public:
- * TFoo();
- * };
- *
- * typedef TIntrusivePtr<TFoo> TFooPtr;
- *
- * void RegisterObject(TFooPtr foo)
- * {
- * ...
- * }
- *
- * TFoo::TFoo()
- * {
- * // ... do something before
- * RegisterObject(this);
- * // ... do something after
- * }
- * \endcode
- *
- * What will happen on <tt>new TFoo()</tt> construction? After memory allocation
- * the reference counter for newly created instance would be initialized to zero.
- * Afterwards, the control goes to TFoo constructor. To invoke
- * <tt>RegisterObject</tt> a new temporary smart pointer to the current instance
- * have to be created effectively incrementing the reference counter (now one).
- * After <tt>RegisterObject</tt> returns the control to the constructor
- * the temporary pointer is destroyed effectively decrementing the reference
- * counter to zero hence triggering object destruction during its initialization.
- *
- * To avoid this undefined behavior <tt>New<T></tt> was introduced.
- * <tt>New<T></tt> holds a fake
- * reference to the object during its construction effectively preventing
- * premature destruction.
- *
- * \note An initialization like <tt>TIntrusivePtr&lt;T&gt; p = new T()</tt>
- * would result in a dangling reference due to internals of #New<T> and
- * #TRefCountedBase.
- */
-
-////////////////////////////////////////////////////////////////////////////////
-
+
+#include <library/cpp/yt/misc/source_location.h>
+
+#include <util/system/defaults.h>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+/*!
+ * \defgroup yt_new New<T> safe smart pointer constructors
+ * \ingroup yt_new
+ *
+ * This is collection of safe smart pointer constructors.
+ *
+ * \page yt_new_rationale Rationale
+ * New<T> function family was designed to prevent the following problem.
+ * Consider the following piece of code.
+ *
+ * \code
+ * class TFoo
+ * : public virtual TRefCounted
+ * {
+ * public:
+ * TFoo();
+ * };
+ *
+ * typedef TIntrusivePtr<TFoo> TFooPtr;
+ *
+ * void RegisterObject(TFooPtr foo)
+ * {
+ * ...
+ * }
+ *
+ * TFoo::TFoo()
+ * {
+ * // ... do something before
+ * RegisterObject(this);
+ * // ... do something after
+ * }
+ * \endcode
+ *
+ * What will happen on <tt>new TFoo()</tt> construction? After memory allocation
+ * the reference counter for newly created instance would be initialized to zero.
+ * Afterwards, the control goes to TFoo constructor. To invoke
+ * <tt>RegisterObject</tt> a new temporary smart pointer to the current instance
+ * have to be created effectively incrementing the reference counter (now one).
+ * After <tt>RegisterObject</tt> returns the control to the constructor
+ * the temporary pointer is destroyed effectively decrementing the reference
+ * counter to zero hence triggering object destruction during its initialization.
+ *
+ * To avoid this undefined behavior <tt>New<T></tt> was introduced.
+ * <tt>New<T></tt> holds a fake
+ * reference to the object during its construction effectively preventing
+ * premature destruction.
+ *
+ * \note An initialization like <tt>TIntrusivePtr&lt;T&gt; p = new T()</tt>
+ * would result in a dangling reference due to internals of #New<T> and
+ * #TRefCountedBase.
+ */
+
+////////////////////////////////////////////////////////////////////////////////
+
template <class T, class = void>
struct THasAllocator
{
@@ -72,7 +72,7 @@ struct THasAllocator
};
template <class T>
-struct THasAllocator<T, std::void_t<typename T::TAllocator>>
+struct THasAllocator<T, std::void_t<typename T::TAllocator>>
{
using TTrue = void;
};
@@ -82,7 +82,7 @@ struct THasAllocator<T, std::void_t<typename T::TAllocator>>
//! Allocates a new instance of |T|.
template <class T, class... As, class = typename THasAllocator<T>::TFalse>
TIntrusivePtr<T> New(As&&... args);
-
+
template <class T, class... As, class = typename THasAllocator<T>::TTrue>
TIntrusivePtr<T> New(typename T::TAllocator* allocator, As&&... args);
@@ -101,26 +101,26 @@ TIntrusivePtr<T> NewWithDelete(const TDeleter& deleter, As&&... args);
//! The allocation is additionally marked with #location.
template <class T, class TTag, int Counter, class... As>
TIntrusivePtr<T> NewWithLocation(const TSourceLocation& location, As&&... args);
-
+
//! Enables calling #New and co for types with private ctors.
#define DECLARE_NEW_FRIEND() \
template <class DECLARE_NEW_FRIEND_T> \
friend struct NYT::TRefCountedWrapper;
-
+
////////////////////////////////////////////////////////////////////////////////
-
+
//! CRTP mixin enabling access to instance's extra space.
template <class T>
class TWithExtraSpace
-{
+{
protected:
const void* GetExtraSpacePtr() const;
void* GetExtraSpacePtr();
};
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
#define NEW_INL_H_
#include "new-inl.h"
diff --git a/library/cpp/yt/memory/range.h b/library/cpp/yt/memory/range.h
index 0c893c72ce..6c71aa9496 100644
--- a/library/cpp/yt/memory/range.h
+++ b/library/cpp/yt/memory/range.h
@@ -1,42 +1,42 @@
#pragma once
-#include <library/cpp/yt/assert/assert.h>
-
-#include <library/cpp/yt/misc/hash.h>
-
+#include <library/cpp/yt/assert/assert.h>
+
+#include <library/cpp/yt/misc/hash.h>
+
#include <vector>
-#include <array>
-#include <optional>
-#include <initializer_list>
-
-// For size_t.
-#include <stddef.h>
-
-namespace google::protobuf {
-
-////////////////////////////////////////////////////////////////////////////////
-// Forward declarations
-
-template <class T>
-class RepeatedField;
-
-template <class T>
-class RepeatedPtrField;
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace google::protobuf
-
+#include <array>
+#include <optional>
+#include <initializer_list>
+
+// For size_t.
+#include <stddef.h>
+
+namespace google::protobuf {
+
+////////////////////////////////////////////////////////////////////////////////
+// Forward declarations
+
+template <class T>
+class RepeatedField;
+
+template <class T>
+class RepeatedPtrField;
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace google::protobuf
+
namespace NYT {
////////////////////////////////////////////////////////////////////////////////
-// Forward declarations
+// Forward declarations
+
+template <class T, size_t N>
+class TCompactVector;
+
+////////////////////////////////////////////////////////////////////////////////
-template <class T, size_t N>
-class TCompactVector;
-
-////////////////////////////////////////////////////////////////////////////////
-
//! TRange (inspired by TArrayRef from LLVM)
/*!
* Represents a constant reference to an array (zero or more elements
@@ -93,28 +93,28 @@ public:
//! Constructs a TRange from a C array.
template <size_t N>
- TRange(const T (&elements)[N])
- : Data_(elements)
+ TRange(const T (&elements)[N])
+ : Data_(elements)
+ , Length_(N)
+ { }
+
+ //! Constructs a TRange from std::initializer_list.
+ TRange(std::initializer_list<T> elements)
+ : Data_(elements.begin())
+ , Length_(elements.size())
+ { }
+
+ //! Constructs a TRange from std::array.
+ template <size_t N>
+ TRange(const std::array<T, N>& elements)
+ : Data_(elements.data())
, Length_(N)
{ }
- //! Constructs a TRange from std::initializer_list.
- TRange(std::initializer_list<T> elements)
- : Data_(elements.begin())
- , Length_(elements.size())
- { }
-
- //! Constructs a TRange from std::array.
- template <size_t N>
- TRange(const std::array<T, N>& elements)
- : Data_(elements.data())
- , Length_(N)
- { }
-
- //! Constructs a TRange from std::optional.
+ //! Constructs a TRange from std::optional.
//! Range will contain 0-1 elements.
- explicit TRange(const std::optional<T>& element)
- : Data_(element ? &*element : nullptr)
+ explicit TRange(const std::optional<T>& element)
+ : Data_(element ? &*element : nullptr)
, Length_(element ? 1 : 0)
{ }
@@ -123,33 +123,33 @@ public:
return Data_;
}
- // STL interop, for gcc.
- const_iterator begin() const
- {
- return Begin();
- }
-
+ // STL interop, for gcc.
+ const_iterator begin() const
+ {
+ return Begin();
+ }
+
const_iterator End() const
{
return Data_ + Length_;
}
- // STL interop, for gcc.
- const_iterator end() const
- {
- return End();
- }
-
+ // STL interop, for gcc.
+ const_iterator end() const
+ {
+ return End();
+ }
+
bool Empty() const
{
return Length_ == 0;
}
- bool empty() const
- {
- return Empty();
- }
-
+ bool empty() const
+ {
+ return Empty();
+ }
+
explicit operator bool() const
{
return Data_ != nullptr;
@@ -167,24 +167,24 @@ public:
const T& operator[](size_t index) const
{
- YT_ASSERT(index < Size());
+ YT_ASSERT(index < Size());
return Data_[index];
}
- const T& Front() const
- {
- YT_ASSERT(Length_ > 0);
- return Data_[0];
- }
-
- const T& Back() const
- {
- YT_ASSERT(Length_ > 0);
- return Data_[Length_ - 1];
- }
-
-
+ const T& Front() const
+ {
+ YT_ASSERT(Length_ > 0);
+ return Data_[0];
+ }
+
+ const T& Back() const
+ {
+ YT_ASSERT(Length_ > 0);
+ return Data_[Length_ - 1];
+ }
+
+
TRange<T> Slice(size_t startOffset, size_t endOffset) const
{
YT_ASSERT(startOffset <= endOffset && endOffset <= Size());
@@ -207,13 +207,13 @@ protected:
// STL interop.
template <class T>
-typename TRange<T>::const_iterator begin(TRange<T> ref)
+typename TRange<T>::const_iterator begin(TRange<T> ref)
{
return ref.Begin();
}
template <class T>
-typename TRange<T>::const_iterator end(TRange<T> ref)
+typename TRange<T>::const_iterator end(TRange<T> ref)
{
return ref.End();
}
@@ -241,13 +241,13 @@ TRange<T> MakeRange(const TCompactVector<T, N>& elements)
return elements;
}
-//! "Copy-constructor".
-template <class T>
-TRange<T> MakeRange(TRange<T> range)
-{
- return range;
-}
-
+//! "Copy-constructor".
+template <class T>
+TRange<T> MakeRange(TRange<T> range)
+{
+ return range;
+}
+
//! Constructs a TRange from an std::vector.
template <class T>
TRange<T> MakeRange(const std::vector<T>& elements)
@@ -255,13 +255,13 @@ TRange<T> MakeRange(const std::vector<T>& elements)
return elements;
}
-//! Constructs a TRange from an std::array.
-template <class T, size_t N>
-TRange<T> MakeRange(const std::array<T, N>& elements)
-{
- return elements;
-}
-
+//! Constructs a TRange from an std::array.
+template <class T, size_t N>
+TRange<T> MakeRange(const std::array<T, N>& elements)
+{
+ return elements;
+}
+
//! Constructs a TRange from a C array.
template <class T, size_t N>
TRange<T> MakeRange(const T (& elements)[N])
@@ -269,27 +269,27 @@ TRange<T> MakeRange(const T (& elements)[N])
return TRange<T>(elements);
}
-//! Constructs a TRange from RepeatedField.
-template <class T>
-TRange<T> MakeRange(const google::protobuf::RepeatedField<T>& elements)
-{
- return TRange<T>(elements.data(), elements.size());
-}
-
-//! Constructs a TRange from RepeatedPtrField.
-template <class T>
-TRange<const T*> MakeRange(const google::protobuf::RepeatedPtrField<T>& elements)
-{
- return TRange<const T*>(elements.data(), elements.size());
-}
-
-template <class U, class T>
-TRange<U> ReinterpretCastRange(TRange<T> range)
-{
- static_assert(sizeof(T) == sizeof(U), "T and U must have equal sizes.");
- return TRange<U>(reinterpret_cast<const U*>(range.Begin()), range.Size());
-};
-
+//! Constructs a TRange from RepeatedField.
+template <class T>
+TRange<T> MakeRange(const google::protobuf::RepeatedField<T>& elements)
+{
+ return TRange<T>(elements.data(), elements.size());
+}
+
+//! Constructs a TRange from RepeatedPtrField.
+template <class T>
+TRange<const T*> MakeRange(const google::protobuf::RepeatedPtrField<T>& elements)
+{
+ return TRange<const T*>(elements.data(), elements.size());
+}
+
+template <class U, class T>
+TRange<U> ReinterpretCastRange(TRange<T> range)
+{
+ static_assert(sizeof(T) == sizeof(U), "T and U must have equal sizes.");
+ return TRange<U>(reinterpret_cast<const U*>(range.Begin()), range.Size());
+};
+
////////////////////////////////////////////////////////////////////////////////
// TMutableRange (inspired by TMutableArrayRef from LLVM)
@@ -338,16 +338,16 @@ public:
: TRange<T>(elements)
{ }
- //! Constructs a TMutableRange from std::array.
- template <size_t N>
- TMutableRange(std::array<T, N>& elements)
- : TRange<T>(elements.data(), N)
- { }
-
- //! Construct a TMutableRange from an std::optional
+ //! Constructs a TMutableRange from std::array.
+ template <size_t N>
+ TMutableRange(std::array<T, N>& elements)
+ : TRange<T>(elements.data(), N)
+ { }
+
+ //! Construct a TMutableRange from an std::optional
//! Range will contain 0-1 elements.
- explicit TMutableRange(std::optional<T>& optional)
- : TRange<T>(optional)
+ explicit TMutableRange(std::optional<T>& optional)
+ : TRange<T>(optional)
{ }
//! Constructs a TMutableRange from a C array.
@@ -356,11 +356,11 @@ public:
: TRange<T>(elements)
{ }
- using TRange<T>::Begin;
- using TRange<T>::End;
- using TRange<T>::Front;
- using TRange<T>::Back;
- using TRange<T>::operator[];
+ using TRange<T>::Begin;
+ using TRange<T>::End;
+ using TRange<T>::Front;
+ using TRange<T>::Back;
+ using TRange<T>::operator[];
iterator Begin() const
{
@@ -384,24 +384,24 @@ public:
return End();
}
- T& operator[](size_t index)
+ T& operator[](size_t index)
+ {
+ YT_ASSERT(index <= this->Size());
+ return Begin()[index];
+ }
+
+ T& Front()
+ {
+ YT_ASSERT(this->Length_ > 0);
+ return Begin()[0];
+ }
+
+ T& Back()
{
- YT_ASSERT(index <= this->Size());
- return Begin()[index];
+ YT_ASSERT(this->Length_ > 0);
+ return Begin()[this->Length_ - 1];
}
- T& Front()
- {
- YT_ASSERT(this->Length_ > 0);
- return Begin()[0];
- }
-
- T& Back()
- {
- YT_ASSERT(this->Length_ > 0);
- return Begin()[this->Length_ - 1];
- }
-
TMutableRange<T> Slice(size_t startOffset, size_t endOffset) const
{
YT_ASSERT(startOffset <= endOffset && endOffset <= this->Size());
@@ -410,41 +410,41 @@ public:
TMutableRange<T> Slice(T* begin, T* end) const
{
- YT_ASSERT(begin >= Begin());
- YT_ASSERT(end <= End());
+ YT_ASSERT(begin >= Begin());
+ YT_ASSERT(end <= End());
return TMutableRange<T>(begin, end);
}
};
// STL interop.
template <class T>
-typename TMutableRange<T>::iterator begin(TMutableRange<T> ref)
+typename TMutableRange<T>::iterator begin(TMutableRange<T> ref)
{
return ref.Begin();
}
template <class T>
-typename TMutableRange<T>::iterator end(TMutableRange<T> ref)
+typename TMutableRange<T>::iterator end(TMutableRange<T> ref)
{
return ref.End();
}
////////////////////////////////////////////////////////////////////////////////
-//! Constructs a TMutableRange from a pointer and length.
-template <class T>
-TMutableRange<T> MakeMutableRange(T* data, size_t length)
-{
- return TMutableRange<T>(data, length);
-}
-
-//! Constructs a TMutableRange from a native range.
-template <class T>
-TMutableRange<T> MakeMutableRange(T* begin, T* end)
-{
- return TMutableRange<T>(begin, end);
-}
-
+//! Constructs a TMutableRange from a pointer and length.
+template <class T>
+TMutableRange<T> MakeMutableRange(T* data, size_t length)
+{
+ return TMutableRange<T>(data, length);
+}
+
+//! Constructs a TMutableRange from a native range.
+template <class T>
+TMutableRange<T> MakeMutableRange(T* begin, T* end)
+{
+ return TMutableRange<T>(begin, end);
+}
+
//! Constructs a TMutableRange from a TCompactVector.
template <class T, size_t N>
TMutableRange<T> MakeMutableRange(TCompactVector<T, N>& elements)
@@ -452,58 +452,58 @@ TMutableRange<T> MakeMutableRange(TCompactVector<T, N>& elements)
return elements;
}
-//! "Copy-constructor".
-template <class T>
-TMutableRange<T> MakeMutableRange(TMutableRange<T> range)
-{
- return range;
-}
-
-//! Constructs a TMutableRange from an std::vector.
-template <class T>
-TMutableRange<T> MakeMutableRange(std::vector<T>& elements)
-{
- return elements;
-}
-
-//! Constructs a TMutableRange from an std::array.
-template <class T, size_t N>
-TMutableRange<T> MakeMutableRange(std::array<T, N>& elements)
-{
- return elements;
-}
-
-//! Constructs a TMutableRange from a C array.
-template <class T, size_t N>
-TMutableRange<T> MakeMutableRange(T (& elements)[N])
-{
- return TMutableRange<T>(elements);
-}
-
-//! Constructs a TMutableRange from RepeatedField.
-template <class T>
-TMutableRange<T> MakeMutableRange(google::protobuf::RepeatedField<T>& elements)
-{
- return TMutableRange<T>(elements.data(), elements.size());
-}
-
-//! Constructs a TMutableRange from RepeatedPtrField.
-template <class T>
-TMutableRange<T*> MakeMutableRange(google::protobuf::RepeatedPtrField<T>& elements)
-{
- return TMutableRange<const T*>(elements.data(), elements.size());
-}
-
-template <class U, class T>
-TMutableRange<U> ReinterpretCastMutableRange(TMutableRange<T> range)
-{
- static_assert(sizeof(T) == sizeof(U), "T and U must have equal sizes.");
- return TMutableRange<U>(reinterpret_cast<U*>(range.Begin()), range.Size());
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-// Mark TMutableRange and TMutableRange as PODs.
+//! "Copy-constructor".
+template <class T>
+TMutableRange<T> MakeMutableRange(TMutableRange<T> range)
+{
+ return range;
+}
+
+//! Constructs a TMutableRange from an std::vector.
+template <class T>
+TMutableRange<T> MakeMutableRange(std::vector<T>& elements)
+{
+ return elements;
+}
+
+//! Constructs a TMutableRange from an std::array.
+template <class T, size_t N>
+TMutableRange<T> MakeMutableRange(std::array<T, N>& elements)
+{
+ return elements;
+}
+
+//! Constructs a TMutableRange from a C array.
+template <class T, size_t N>
+TMutableRange<T> MakeMutableRange(T (& elements)[N])
+{
+ return TMutableRange<T>(elements);
+}
+
+//! Constructs a TMutableRange from RepeatedField.
+template <class T>
+TMutableRange<T> MakeMutableRange(google::protobuf::RepeatedField<T>& elements)
+{
+ return TMutableRange<T>(elements.data(), elements.size());
+}
+
+//! Constructs a TMutableRange from RepeatedPtrField.
+template <class T>
+TMutableRange<T*> MakeMutableRange(google::protobuf::RepeatedPtrField<T>& elements)
+{
+ return TMutableRange<const T*>(elements.data(), elements.size());
+}
+
+template <class U, class T>
+TMutableRange<U> ReinterpretCastMutableRange(TMutableRange<T> range)
+{
+ static_assert(sizeof(T) == sizeof(U), "T and U must have equal sizes.");
+ return TMutableRange<U>(reinterpret_cast<U*>(range.Begin()), range.Size());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Mark TMutableRange and TMutableRange as PODs.
namespace NMpl {
template <class T>
@@ -540,17 +540,17 @@ struct hash<NYT::TRange<T>>
}
};
-template <class T>
-struct hash<NYT::TMutableRange<T>>
-{
- size_t operator()(const NYT::TMutableRange<T>& range) const
- {
- size_t result = 0;
- for (const auto& element : range) {
- NYT::HashCombine(result, element);
- }
- return result;
- }
-};
-
-
+template <class T>
+struct hash<NYT::TMutableRange<T>>
+{
+ size_t operator()(const NYT::TMutableRange<T>& range) const
+ {
+ size_t result = 0;
+ for (const auto& element : range) {
+ NYT::HashCombine(result, element);
+ }
+ return result;
+ }
+};
+
+
diff --git a/library/cpp/yt/memory/ref-inl.h b/library/cpp/yt/memory/ref-inl.h
index 6d11347527..79be8356c5 100644
--- a/library/cpp/yt/memory/ref-inl.h
+++ b/library/cpp/yt/memory/ref-inl.h
@@ -1,517 +1,517 @@
-#ifndef REF_INL_H_
-#error "Direct inclusion of this file is not allowed, include ref.h"
-// For the sake of sane code completion.
-#include "ref.h"
-#endif
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-namespace NDetail {
-
+#ifndef REF_INL_H_
+#error "Direct inclusion of this file is not allowed, include ref.h"
+// For the sake of sane code completion.
+#include "ref.h"
+#endif
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+namespace NDetail {
+
extern const char EmptyRefData[];
extern char MutableEmptyRefData[];
-
-} // namespace NDetail
-
-////////////////////////////////////////////////////////////////////////////////
-
-Y_FORCE_INLINE TRef::TRef(const void* data, size_t size)
- : TRange<char>(static_cast<const char*>(data), size)
-{ }
-
-Y_FORCE_INLINE TRef::TRef(const void* begin, const void* end)
- : TRange<char>(static_cast<const char*>(begin), static_cast<const char*>(end))
-{ }
-
-Y_FORCE_INLINE TRef TRef::MakeEmpty()
-{
- return TRef(NDetail::EmptyRefData, NDetail::EmptyRefData);
-}
-
-Y_FORCE_INLINE TRef TRef::FromString(const TString& str)
-{
- return FromStringBuf(str);
-}
-
-Y_FORCE_INLINE TRef TRef::FromStringBuf(TStringBuf strBuf)
-{
- return TRef(strBuf.data(), strBuf.length());
-}
-
-template <class T>
-Y_FORCE_INLINE TRef TRef::FromPod(const T& data)
-{
- static_assert(TTypeTraits<T>::IsPod || std::is_pod<T>::value, "T must be a pod-type.");
- return TRef(&data, sizeof (data));
-}
-
-Y_FORCE_INLINE TRef TRef::Slice(size_t startOffset, size_t endOffset) const
-{
- YT_ASSERT(endOffset >= startOffset && endOffset <= Size());
- return TRef(Begin() + startOffset, endOffset - startOffset);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-Y_FORCE_INLINE TMutableRef::TMutableRef(void* data, size_t size)
- : TMutableRange<char>(static_cast<char*>(data), size)
-{ }
-
-Y_FORCE_INLINE TMutableRef::TMutableRef(void* begin, void* end)
- : TMutableRange<char>(static_cast<char*>(begin), static_cast<char*>(end))
-{ }
-
-Y_FORCE_INLINE TMutableRef TMutableRef::MakeEmpty()
-{
- return TMutableRef(NDetail::MutableEmptyRefData, NDetail::MutableEmptyRefData);
-}
-
-Y_FORCE_INLINE TMutableRef::operator TRef() const
-{
- return TRef(Begin(), Size());
-}
-
-template <class T>
-Y_FORCE_INLINE TMutableRef TMutableRef::FromPod(T& data)
-{
- static_assert(TTypeTraits<T>::IsPod || std::is_pod<T>::value, "T must be a pod-type.");
- return TMutableRef(&data, sizeof (data));
-}
-
-Y_FORCE_INLINE TMutableRef TMutableRef::FromString(TString& str)
-{
- // NB: begin() invokes CloneIfShared().
- return TMutableRef(str.begin(), str.length());
-}
-
-Y_FORCE_INLINE TMutableRef TMutableRef::Slice(size_t startOffset, size_t endOffset) const
-{
- YT_ASSERT(endOffset >= startOffset && endOffset <= Size());
- return TMutableRef(Begin() + startOffset, endOffset - startOffset);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-Y_FORCE_INLINE TSharedRef::TSharedRef(TRef ref, TSharedRange<char>::THolderPtr holder)
- : TSharedRange<char>(ref, std::move(holder))
-{ }
-
-Y_FORCE_INLINE TSharedRef::TSharedRef(const void* data, size_t length, TSharedRange<char>::THolderPtr holder)
- : TSharedRange<char>(static_cast<const char*>(data), length, std::move(holder))
-{ }
-
-Y_FORCE_INLINE TSharedRef::TSharedRef(const void* begin, const void* end, TSharedRange<char>::THolderPtr holder)
- : TSharedRange<char>(static_cast<const char*>(begin), static_cast<const char*>(end), std::move(holder))
-{ }
-
-Y_FORCE_INLINE TSharedRef TSharedRef::MakeEmpty()
-{
- return TSharedRef(TRef::MakeEmpty(), nullptr);
-}
-
-Y_FORCE_INLINE TSharedRef::operator TRef() const
-{
- return TRef(Begin(), Size());
-}
-
-template <class TTag>
-Y_FORCE_INLINE TSharedRef TSharedRef::FromString(TString str)
-{
- return FromString(std::move(str), GetRefCountedTypeCookie<TTag>());
-}
-
-Y_FORCE_INLINE TSharedRef TSharedRef::FromString(TString str)
-{
- return FromString<TDefaultSharedBlobTag>(std::move(str));
-}
-
-template <class TTag>
-Y_FORCE_INLINE TSharedRef TSharedRef::MakeCopy(TRef ref)
-{
- return MakeCopy(ref, GetRefCountedTypeCookie<TTag>());
-}
-
-Y_FORCE_INLINE TSharedRef TSharedRef::Slice(size_t startOffset, size_t endOffset) const
-{
- YT_ASSERT(endOffset >= startOffset && endOffset <= Size());
- return TSharedRef(Begin() + startOffset, endOffset - startOffset, Holder_);
-}
-
-Y_FORCE_INLINE TSharedRef TSharedRef::Slice(const void* begin, const void* end) const
-{
- YT_ASSERT(begin >= Begin());
- YT_ASSERT(end <= End());
- return TSharedRef(begin, end, Holder_);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-Y_FORCE_INLINE TSharedMutableRef::TSharedMutableRef(const TMutableRef& ref, TSharedMutableRange<char>::THolderPtr holder)
- : TSharedMutableRange<char>(ref, std::move(holder))
-{ }
-
-Y_FORCE_INLINE TSharedMutableRef::TSharedMutableRef(void* data, size_t length, TSharedMutableRange<char>::THolderPtr holder)
- : TSharedMutableRange<char>(static_cast<char*>(data), length, std::move(holder))
-{ }
-
-Y_FORCE_INLINE TSharedMutableRef::TSharedMutableRef(void* begin, void* end, TSharedMutableRange<char>::THolderPtr holder)
- : TSharedMutableRange<char>(static_cast<char*>(begin), static_cast<char*>(end), std::move(holder))
-{ }
-
-Y_FORCE_INLINE TSharedMutableRef TSharedMutableRef::MakeEmpty()
-{
- return TSharedMutableRef(TMutableRef::MakeEmpty(), nullptr);
-}
-
-Y_FORCE_INLINE TSharedMutableRef::operator TMutableRef() const
-{
- return TMutableRef(Begin(), Size());
-}
-
-Y_FORCE_INLINE TSharedMutableRef::operator TSharedRef() const
-{
- return TSharedRef(Begin(), Size(), Holder_);
-}
-
-Y_FORCE_INLINE TSharedMutableRef::operator TRef() const
-{
- return TRef(Begin(), Size());
-}
-
-Y_FORCE_INLINE TSharedMutableRef TSharedMutableRef::Allocate(size_t size, bool initializeStorage)
-{
- return Allocate<TDefaultSharedBlobTag>(size, initializeStorage);
-}
-
-Y_FORCE_INLINE TSharedMutableRef TSharedMutableRef::AllocatePageAligned(size_t size, bool initializeStorage)
-{
- return AllocatePageAligned<TDefaultSharedBlobTag>(size, initializeStorage);
-}
-
-template <class TTag>
-Y_FORCE_INLINE TSharedMutableRef TSharedMutableRef::MakeCopy(TRef ref)
-{
- return MakeCopy(ref, GetRefCountedTypeCookie<TTag>());
-}
-
-Y_FORCE_INLINE TSharedMutableRef TSharedMutableRef::Slice(size_t startOffset, size_t endOffset) const
-{
- YT_ASSERT(endOffset >= startOffset && endOffset <= Size());
- return TSharedMutableRef(Begin() + startOffset, endOffset - startOffset, Holder_);
-}
-
-Y_FORCE_INLINE TSharedMutableRef TSharedMutableRef::Slice(void* begin, void* end) const
-{
- YT_ASSERT(begin >= Begin());
- YT_ASSERT(end <= End());
- return TSharedMutableRef(begin, end, Holder_);
-}
-
-template <class TTag>
-Y_FORCE_INLINE TSharedMutableRef TSharedMutableRef::Allocate(size_t size, bool initializeStorage)
-{
- return Allocate(size, initializeStorage, GetRefCountedTypeCookie<TTag>());
-}
-
-template <class TTag>
-Y_FORCE_INLINE TSharedMutableRef TSharedMutableRef::AllocatePageAligned(size_t size, bool initializeStorage)
-{
- return AllocatePageAligned(size, initializeStorage, GetRefCountedTypeCookie<TTag>());
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-Y_FORCE_INLINE size_t GetByteSize(TRef ref)
-{
- return ref ? ref.Size() : 0;
-}
-
-template <class T>
-size_t GetByteSize(TRange<T> parts)
-{
- size_t size = 0;
- for (const auto& part : parts) {
- size += part.Size();
- }
- return size;
-}
-
-template <class T>
-size_t GetByteSize(const std::vector<T>& parts)
-{
- return GetByteSize(MakeRange(parts));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-class TSharedRefArrayImpl
- : public TRefCounted
- , public TWithExtraSpace<TSharedRefArrayImpl>
-{
-public:
- TSharedRefArrayImpl(
- size_t extraSpaceSize,
- TRefCountedTypeCookie tagCookie,
- size_t size)
- : Size_(size)
- , ExtraSpaceSize_(extraSpaceSize)
- , TagCookie_(tagCookie)
- {
- for (size_t index = 0; index < Size_; ++index) {
- new (MutableBegin() + index) TSharedRef();
- }
- RegisterWithRefCountedTracker();
- }
-
- TSharedRefArrayImpl(
- size_t extraSpaceSize,
- TRefCountedTypeCookie tagCookie,
- const TSharedRef& part)
- : Size_(1)
- , ExtraSpaceSize_(extraSpaceSize)
- , TagCookie_(tagCookie)
- {
- new (MutableBegin()) TSharedRef(part);
- RegisterWithRefCountedTracker();
- }
-
- TSharedRefArrayImpl(
- size_t extraSpaceSize,
- TRefCountedTypeCookie tagCookie,
- TSharedRef&& part)
- : Size_(1)
- , ExtraSpaceSize_(extraSpaceSize)
- , TagCookie_(tagCookie)
- {
- new (MutableBegin()) TSharedRef(std::move(part));
- RegisterWithRefCountedTracker();
- }
-
- template <class TParts>
- TSharedRefArrayImpl(
- size_t extraSpaceSize,
- TRefCountedTypeCookie tagCookie,
- const TParts& parts,
- TSharedRefArray::TCopyParts)
- : Size_(parts.size())
- , ExtraSpaceSize_(extraSpaceSize)
- , TagCookie_(tagCookie)
- {
- for (size_t index = 0; index < Size_; ++index) {
- new (MutableBegin() + index) TSharedRef(parts[index]);
- }
- RegisterWithRefCountedTracker();
- }
-
- template <class TParts>
- TSharedRefArrayImpl(
- size_t extraSpaceSize,
- TRefCountedTypeCookie tagCookie,
- TParts&& parts,
- TSharedRefArray::TMoveParts)
- : Size_(parts.size())
- , ExtraSpaceSize_(extraSpaceSize)
- , TagCookie_(tagCookie)
- {
- for (size_t index = 0; index < Size_; ++index) {
- new (MutableBegin() + index) TSharedRef(std::move(parts[index]));
- }
- RegisterWithRefCountedTracker();
- }
-
- ~TSharedRefArrayImpl()
- {
- for (size_t index = 0; index < Size_; ++index) {
- auto& part = MutableBegin()[index];
- if (part.GetHolder() == this) {
- part.Holder_.Release();
- }
- part.TSharedRef::~TSharedRef();
- }
- UnregisterFromRefCountedTracker();
- }
-
-
- size_t Size() const
- {
- return Size_;
- }
-
- bool Empty() const
- {
- return Size_ == 0;
- }
-
- const TSharedRef& operator [] (size_t index) const
- {
- YT_ASSERT(index < Size());
- return Begin()[index];
- }
-
-
- const TSharedRef* Begin() const
- {
- return static_cast<const TSharedRef*>(GetExtraSpacePtr());
- }
-
- const TSharedRef* End() const
- {
- return Begin() + Size_;
- }
-
-private:
- friend class TSharedRefArrayBuilder;
-
- const size_t Size_;
- const size_t ExtraSpaceSize_;
- const TRefCountedTypeCookie TagCookie_;
-
-
- void RegisterWithRefCountedTracker()
- {
- TRefCountedTrackerFacade::AllocateTagInstance(TagCookie_);
- TRefCountedTrackerFacade::AllocateSpace(TagCookie_, ExtraSpaceSize_);
- }
-
- void UnregisterFromRefCountedTracker()
- {
- TRefCountedTrackerFacade::FreeTagInstance(TagCookie_);
- TRefCountedTrackerFacade::FreeSpace(TagCookie_, ExtraSpaceSize_);
- }
-
-
- TSharedRef* MutableBegin()
- {
- return static_cast<TSharedRef*>(GetExtraSpacePtr());
- }
-
- TSharedRef* MutableEnd()
- {
- return MutableBegin() + Size_;
- }
-
- char* GetBeginAllocationPtr()
- {
- return static_cast<char*>(static_cast<void*>(MutableEnd()));
- }
-};
-
-DEFINE_REFCOUNTED_TYPE(TSharedRefArrayImpl)
-
-////////////////////////////////////////////////////////////////////////////////
-
-struct TSharedRefArrayTag { };
-
-Y_FORCE_INLINE TSharedRefArray::TSharedRefArray(TIntrusivePtr<TSharedRefArrayImpl> impl)
- : Impl_(std::move(impl))
-{ }
-
-Y_FORCE_INLINE TSharedRefArray::TSharedRefArray(const TSharedRefArray& other)
- : Impl_(other.Impl_)
-{ }
-
-Y_FORCE_INLINE TSharedRefArray::TSharedRefArray(TSharedRefArray&& other) noexcept
- : Impl_(std::move(other.Impl_))
-{ }
-
-Y_FORCE_INLINE TSharedRefArray::TSharedRefArray(const TSharedRef& part)
- : Impl_(NewImpl(1, 0, GetRefCountedTypeCookie<TSharedRefArrayTag>(), part))
-{ }
-
-Y_FORCE_INLINE TSharedRefArray::TSharedRefArray(TSharedRef&& part)
- : Impl_(NewImpl(1, 0, GetRefCountedTypeCookie<TSharedRefArrayTag>(), std::move(part)))
-{ }
-
-template <class TParts>
-Y_FORCE_INLINE TSharedRefArray::TSharedRefArray(const TParts& parts, TSharedRefArray::TCopyParts)
- : Impl_(NewImpl(parts.size(), 0, GetRefCountedTypeCookie<TSharedRefArrayTag>(), parts, TSharedRefArray::TCopyParts{}))
-{ }
-
-template <class TParts>
-Y_FORCE_INLINE TSharedRefArray::TSharedRefArray(TParts&& parts, TSharedRefArray::TMoveParts)
- : Impl_(NewImpl(parts.size(), 0, GetRefCountedTypeCookie<TSharedRefArrayTag>(), std::move(parts), TSharedRefArray::TMoveParts{}))
-{ }
-
-Y_FORCE_INLINE TSharedRefArray& TSharedRefArray::operator=(const TSharedRefArray& other)
-{
- Impl_ = other.Impl_;
- return *this;
-}
-
-Y_FORCE_INLINE TSharedRefArray& TSharedRefArray::operator=(TSharedRefArray&& other)
-{
- Impl_ = std::move(other.Impl_);
- return *this;
-}
-
-Y_FORCE_INLINE void TSharedRefArray::Reset()
-{
- Impl_.Reset();
-}
-
-Y_FORCE_INLINE TSharedRefArray::operator bool() const
-{
- return Impl_.operator bool();
-}
-
-Y_FORCE_INLINE size_t TSharedRefArray::Size() const
-{
- return Impl_ ? Impl_->Size() : 0;
-}
-
+
+} // namespace NDetail
+
+////////////////////////////////////////////////////////////////////////////////
+
+Y_FORCE_INLINE TRef::TRef(const void* data, size_t size)
+ : TRange<char>(static_cast<const char*>(data), size)
+{ }
+
+Y_FORCE_INLINE TRef::TRef(const void* begin, const void* end)
+ : TRange<char>(static_cast<const char*>(begin), static_cast<const char*>(end))
+{ }
+
+Y_FORCE_INLINE TRef TRef::MakeEmpty()
+{
+ return TRef(NDetail::EmptyRefData, NDetail::EmptyRefData);
+}
+
+Y_FORCE_INLINE TRef TRef::FromString(const TString& str)
+{
+ return FromStringBuf(str);
+}
+
+Y_FORCE_INLINE TRef TRef::FromStringBuf(TStringBuf strBuf)
+{
+ return TRef(strBuf.data(), strBuf.length());
+}
+
+template <class T>
+Y_FORCE_INLINE TRef TRef::FromPod(const T& data)
+{
+ static_assert(TTypeTraits<T>::IsPod || std::is_pod<T>::value, "T must be a pod-type.");
+ return TRef(&data, sizeof (data));
+}
+
+Y_FORCE_INLINE TRef TRef::Slice(size_t startOffset, size_t endOffset) const
+{
+ YT_ASSERT(endOffset >= startOffset && endOffset <= Size());
+ return TRef(Begin() + startOffset, endOffset - startOffset);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+Y_FORCE_INLINE TMutableRef::TMutableRef(void* data, size_t size)
+ : TMutableRange<char>(static_cast<char*>(data), size)
+{ }
+
+Y_FORCE_INLINE TMutableRef::TMutableRef(void* begin, void* end)
+ : TMutableRange<char>(static_cast<char*>(begin), static_cast<char*>(end))
+{ }
+
+Y_FORCE_INLINE TMutableRef TMutableRef::MakeEmpty()
+{
+ return TMutableRef(NDetail::MutableEmptyRefData, NDetail::MutableEmptyRefData);
+}
+
+Y_FORCE_INLINE TMutableRef::operator TRef() const
+{
+ return TRef(Begin(), Size());
+}
+
+template <class T>
+Y_FORCE_INLINE TMutableRef TMutableRef::FromPod(T& data)
+{
+ static_assert(TTypeTraits<T>::IsPod || std::is_pod<T>::value, "T must be a pod-type.");
+ return TMutableRef(&data, sizeof (data));
+}
+
+Y_FORCE_INLINE TMutableRef TMutableRef::FromString(TString& str)
+{
+ // NB: begin() invokes CloneIfShared().
+ return TMutableRef(str.begin(), str.length());
+}
+
+Y_FORCE_INLINE TMutableRef TMutableRef::Slice(size_t startOffset, size_t endOffset) const
+{
+ YT_ASSERT(endOffset >= startOffset && endOffset <= Size());
+ return TMutableRef(Begin() + startOffset, endOffset - startOffset);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+Y_FORCE_INLINE TSharedRef::TSharedRef(TRef ref, TSharedRange<char>::THolderPtr holder)
+ : TSharedRange<char>(ref, std::move(holder))
+{ }
+
+Y_FORCE_INLINE TSharedRef::TSharedRef(const void* data, size_t length, TSharedRange<char>::THolderPtr holder)
+ : TSharedRange<char>(static_cast<const char*>(data), length, std::move(holder))
+{ }
+
+Y_FORCE_INLINE TSharedRef::TSharedRef(const void* begin, const void* end, TSharedRange<char>::THolderPtr holder)
+ : TSharedRange<char>(static_cast<const char*>(begin), static_cast<const char*>(end), std::move(holder))
+{ }
+
+Y_FORCE_INLINE TSharedRef TSharedRef::MakeEmpty()
+{
+ return TSharedRef(TRef::MakeEmpty(), nullptr);
+}
+
+Y_FORCE_INLINE TSharedRef::operator TRef() const
+{
+ return TRef(Begin(), Size());
+}
+
+template <class TTag>
+Y_FORCE_INLINE TSharedRef TSharedRef::FromString(TString str)
+{
+ return FromString(std::move(str), GetRefCountedTypeCookie<TTag>());
+}
+
+Y_FORCE_INLINE TSharedRef TSharedRef::FromString(TString str)
+{
+ return FromString<TDefaultSharedBlobTag>(std::move(str));
+}
+
+template <class TTag>
+Y_FORCE_INLINE TSharedRef TSharedRef::MakeCopy(TRef ref)
+{
+ return MakeCopy(ref, GetRefCountedTypeCookie<TTag>());
+}
+
+Y_FORCE_INLINE TSharedRef TSharedRef::Slice(size_t startOffset, size_t endOffset) const
+{
+ YT_ASSERT(endOffset >= startOffset && endOffset <= Size());
+ return TSharedRef(Begin() + startOffset, endOffset - startOffset, Holder_);
+}
+
+Y_FORCE_INLINE TSharedRef TSharedRef::Slice(const void* begin, const void* end) const
+{
+ YT_ASSERT(begin >= Begin());
+ YT_ASSERT(end <= End());
+ return TSharedRef(begin, end, Holder_);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+Y_FORCE_INLINE TSharedMutableRef::TSharedMutableRef(const TMutableRef& ref, TSharedMutableRange<char>::THolderPtr holder)
+ : TSharedMutableRange<char>(ref, std::move(holder))
+{ }
+
+Y_FORCE_INLINE TSharedMutableRef::TSharedMutableRef(void* data, size_t length, TSharedMutableRange<char>::THolderPtr holder)
+ : TSharedMutableRange<char>(static_cast<char*>(data), length, std::move(holder))
+{ }
+
+Y_FORCE_INLINE TSharedMutableRef::TSharedMutableRef(void* begin, void* end, TSharedMutableRange<char>::THolderPtr holder)
+ : TSharedMutableRange<char>(static_cast<char*>(begin), static_cast<char*>(end), std::move(holder))
+{ }
+
+Y_FORCE_INLINE TSharedMutableRef TSharedMutableRef::MakeEmpty()
+{
+ return TSharedMutableRef(TMutableRef::MakeEmpty(), nullptr);
+}
+
+Y_FORCE_INLINE TSharedMutableRef::operator TMutableRef() const
+{
+ return TMutableRef(Begin(), Size());
+}
+
+Y_FORCE_INLINE TSharedMutableRef::operator TSharedRef() const
+{
+ return TSharedRef(Begin(), Size(), Holder_);
+}
+
+Y_FORCE_INLINE TSharedMutableRef::operator TRef() const
+{
+ return TRef(Begin(), Size());
+}
+
+Y_FORCE_INLINE TSharedMutableRef TSharedMutableRef::Allocate(size_t size, bool initializeStorage)
+{
+ return Allocate<TDefaultSharedBlobTag>(size, initializeStorage);
+}
+
+Y_FORCE_INLINE TSharedMutableRef TSharedMutableRef::AllocatePageAligned(size_t size, bool initializeStorage)
+{
+ return AllocatePageAligned<TDefaultSharedBlobTag>(size, initializeStorage);
+}
+
+template <class TTag>
+Y_FORCE_INLINE TSharedMutableRef TSharedMutableRef::MakeCopy(TRef ref)
+{
+ return MakeCopy(ref, GetRefCountedTypeCookie<TTag>());
+}
+
+Y_FORCE_INLINE TSharedMutableRef TSharedMutableRef::Slice(size_t startOffset, size_t endOffset) const
+{
+ YT_ASSERT(endOffset >= startOffset && endOffset <= Size());
+ return TSharedMutableRef(Begin() + startOffset, endOffset - startOffset, Holder_);
+}
+
+Y_FORCE_INLINE TSharedMutableRef TSharedMutableRef::Slice(void* begin, void* end) const
+{
+ YT_ASSERT(begin >= Begin());
+ YT_ASSERT(end <= End());
+ return TSharedMutableRef(begin, end, Holder_);
+}
+
+template <class TTag>
+Y_FORCE_INLINE TSharedMutableRef TSharedMutableRef::Allocate(size_t size, bool initializeStorage)
+{
+ return Allocate(size, initializeStorage, GetRefCountedTypeCookie<TTag>());
+}
+
+template <class TTag>
+Y_FORCE_INLINE TSharedMutableRef TSharedMutableRef::AllocatePageAligned(size_t size, bool initializeStorage)
+{
+ return AllocatePageAligned(size, initializeStorage, GetRefCountedTypeCookie<TTag>());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+Y_FORCE_INLINE size_t GetByteSize(TRef ref)
+{
+ return ref ? ref.Size() : 0;
+}
+
+template <class T>
+size_t GetByteSize(TRange<T> parts)
+{
+ size_t size = 0;
+ for (const auto& part : parts) {
+ size += part.Size();
+ }
+ return size;
+}
+
+template <class T>
+size_t GetByteSize(const std::vector<T>& parts)
+{
+ return GetByteSize(MakeRange(parts));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+class TSharedRefArrayImpl
+ : public TRefCounted
+ , public TWithExtraSpace<TSharedRefArrayImpl>
+{
+public:
+ TSharedRefArrayImpl(
+ size_t extraSpaceSize,
+ TRefCountedTypeCookie tagCookie,
+ size_t size)
+ : Size_(size)
+ , ExtraSpaceSize_(extraSpaceSize)
+ , TagCookie_(tagCookie)
+ {
+ for (size_t index = 0; index < Size_; ++index) {
+ new (MutableBegin() + index) TSharedRef();
+ }
+ RegisterWithRefCountedTracker();
+ }
+
+ TSharedRefArrayImpl(
+ size_t extraSpaceSize,
+ TRefCountedTypeCookie tagCookie,
+ const TSharedRef& part)
+ : Size_(1)
+ , ExtraSpaceSize_(extraSpaceSize)
+ , TagCookie_(tagCookie)
+ {
+ new (MutableBegin()) TSharedRef(part);
+ RegisterWithRefCountedTracker();
+ }
+
+ TSharedRefArrayImpl(
+ size_t extraSpaceSize,
+ TRefCountedTypeCookie tagCookie,
+ TSharedRef&& part)
+ : Size_(1)
+ , ExtraSpaceSize_(extraSpaceSize)
+ , TagCookie_(tagCookie)
+ {
+ new (MutableBegin()) TSharedRef(std::move(part));
+ RegisterWithRefCountedTracker();
+ }
+
+ template <class TParts>
+ TSharedRefArrayImpl(
+ size_t extraSpaceSize,
+ TRefCountedTypeCookie tagCookie,
+ const TParts& parts,
+ TSharedRefArray::TCopyParts)
+ : Size_(parts.size())
+ , ExtraSpaceSize_(extraSpaceSize)
+ , TagCookie_(tagCookie)
+ {
+ for (size_t index = 0; index < Size_; ++index) {
+ new (MutableBegin() + index) TSharedRef(parts[index]);
+ }
+ RegisterWithRefCountedTracker();
+ }
+
+ template <class TParts>
+ TSharedRefArrayImpl(
+ size_t extraSpaceSize,
+ TRefCountedTypeCookie tagCookie,
+ TParts&& parts,
+ TSharedRefArray::TMoveParts)
+ : Size_(parts.size())
+ , ExtraSpaceSize_(extraSpaceSize)
+ , TagCookie_(tagCookie)
+ {
+ for (size_t index = 0; index < Size_; ++index) {
+ new (MutableBegin() + index) TSharedRef(std::move(parts[index]));
+ }
+ RegisterWithRefCountedTracker();
+ }
+
+ ~TSharedRefArrayImpl()
+ {
+ for (size_t index = 0; index < Size_; ++index) {
+ auto& part = MutableBegin()[index];
+ if (part.GetHolder() == this) {
+ part.Holder_.Release();
+ }
+ part.TSharedRef::~TSharedRef();
+ }
+ UnregisterFromRefCountedTracker();
+ }
+
+
+ size_t Size() const
+ {
+ return Size_;
+ }
+
+ bool Empty() const
+ {
+ return Size_ == 0;
+ }
+
+ const TSharedRef& operator [] (size_t index) const
+ {
+ YT_ASSERT(index < Size());
+ return Begin()[index];
+ }
+
+
+ const TSharedRef* Begin() const
+ {
+ return static_cast<const TSharedRef*>(GetExtraSpacePtr());
+ }
+
+ const TSharedRef* End() const
+ {
+ return Begin() + Size_;
+ }
+
+private:
+ friend class TSharedRefArrayBuilder;
+
+ const size_t Size_;
+ const size_t ExtraSpaceSize_;
+ const TRefCountedTypeCookie TagCookie_;
+
+
+ void RegisterWithRefCountedTracker()
+ {
+ TRefCountedTrackerFacade::AllocateTagInstance(TagCookie_);
+ TRefCountedTrackerFacade::AllocateSpace(TagCookie_, ExtraSpaceSize_);
+ }
+
+ void UnregisterFromRefCountedTracker()
+ {
+ TRefCountedTrackerFacade::FreeTagInstance(TagCookie_);
+ TRefCountedTrackerFacade::FreeSpace(TagCookie_, ExtraSpaceSize_);
+ }
+
+
+ TSharedRef* MutableBegin()
+ {
+ return static_cast<TSharedRef*>(GetExtraSpacePtr());
+ }
+
+ TSharedRef* MutableEnd()
+ {
+ return MutableBegin() + Size_;
+ }
+
+ char* GetBeginAllocationPtr()
+ {
+ return static_cast<char*>(static_cast<void*>(MutableEnd()));
+ }
+};
+
+DEFINE_REFCOUNTED_TYPE(TSharedRefArrayImpl)
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct TSharedRefArrayTag { };
+
+Y_FORCE_INLINE TSharedRefArray::TSharedRefArray(TIntrusivePtr<TSharedRefArrayImpl> impl)
+ : Impl_(std::move(impl))
+{ }
+
+Y_FORCE_INLINE TSharedRefArray::TSharedRefArray(const TSharedRefArray& other)
+ : Impl_(other.Impl_)
+{ }
+
+Y_FORCE_INLINE TSharedRefArray::TSharedRefArray(TSharedRefArray&& other) noexcept
+ : Impl_(std::move(other.Impl_))
+{ }
+
+Y_FORCE_INLINE TSharedRefArray::TSharedRefArray(const TSharedRef& part)
+ : Impl_(NewImpl(1, 0, GetRefCountedTypeCookie<TSharedRefArrayTag>(), part))
+{ }
+
+Y_FORCE_INLINE TSharedRefArray::TSharedRefArray(TSharedRef&& part)
+ : Impl_(NewImpl(1, 0, GetRefCountedTypeCookie<TSharedRefArrayTag>(), std::move(part)))
+{ }
+
+template <class TParts>
+Y_FORCE_INLINE TSharedRefArray::TSharedRefArray(const TParts& parts, TSharedRefArray::TCopyParts)
+ : Impl_(NewImpl(parts.size(), 0, GetRefCountedTypeCookie<TSharedRefArrayTag>(), parts, TSharedRefArray::TCopyParts{}))
+{ }
+
+template <class TParts>
+Y_FORCE_INLINE TSharedRefArray::TSharedRefArray(TParts&& parts, TSharedRefArray::TMoveParts)
+ : Impl_(NewImpl(parts.size(), 0, GetRefCountedTypeCookie<TSharedRefArrayTag>(), std::move(parts), TSharedRefArray::TMoveParts{}))
+{ }
+
+Y_FORCE_INLINE TSharedRefArray& TSharedRefArray::operator=(const TSharedRefArray& other)
+{
+ Impl_ = other.Impl_;
+ return *this;
+}
+
+Y_FORCE_INLINE TSharedRefArray& TSharedRefArray::operator=(TSharedRefArray&& other)
+{
+ Impl_ = std::move(other.Impl_);
+ return *this;
+}
+
+Y_FORCE_INLINE void TSharedRefArray::Reset()
+{
+ Impl_.Reset();
+}
+
+Y_FORCE_INLINE TSharedRefArray::operator bool() const
+{
+ return Impl_.operator bool();
+}
+
+Y_FORCE_INLINE size_t TSharedRefArray::Size() const
+{
+ return Impl_ ? Impl_->Size() : 0;
+}
+
Y_FORCE_INLINE size_t TSharedRefArray::size() const
{
return Impl_ ? Impl_->Size() : 0;
}
-Y_FORCE_INLINE bool TSharedRefArray::Empty() const
-{
- return Impl_ ? Impl_->Empty() : true;
-}
-
-Y_FORCE_INLINE const TSharedRef& TSharedRefArray::operator[](size_t index) const
-{
- YT_ASSERT(Impl_);
- return (*Impl_)[index];
-}
-
-Y_FORCE_INLINE const TSharedRef* TSharedRefArray::Begin() const
-{
- return Impl_ ? Impl_->Begin() : nullptr;
-}
-
-Y_FORCE_INLINE const TSharedRef* TSharedRefArray::End() const
-{
- return Impl_ ? Impl_->End() : nullptr;
-}
-
-template <class... As>
-TSharedRefArrayImplPtr TSharedRefArray::NewImpl(
- size_t size,
- size_t poolCapacity,
- TRefCountedTypeCookie tagCookie,
- As&&... args)
-{
- auto extraSpaceSize = sizeof (TSharedRef) * size + poolCapacity;
- return NewWithExtraSpace<TSharedRefArrayImpl>(
- extraSpaceSize,
- extraSpaceSize,
- tagCookie,
- std::forward<As>(args)...);
-}
-
-Y_FORCE_INLINE const TSharedRef* begin(const TSharedRefArray& array)
-{
- return array.Begin();
-}
-
-Y_FORCE_INLINE const TSharedRef* end(const TSharedRefArray& array)
-{
- return array.End();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
+Y_FORCE_INLINE bool TSharedRefArray::Empty() const
+{
+ return Impl_ ? Impl_->Empty() : true;
+}
+
+Y_FORCE_INLINE const TSharedRef& TSharedRefArray::operator[](size_t index) const
+{
+ YT_ASSERT(Impl_);
+ return (*Impl_)[index];
+}
+
+Y_FORCE_INLINE const TSharedRef* TSharedRefArray::Begin() const
+{
+ return Impl_ ? Impl_->Begin() : nullptr;
+}
+
+Y_FORCE_INLINE const TSharedRef* TSharedRefArray::End() const
+{
+ return Impl_ ? Impl_->End() : nullptr;
+}
+
+template <class... As>
+TSharedRefArrayImplPtr TSharedRefArray::NewImpl(
+ size_t size,
+ size_t poolCapacity,
+ TRefCountedTypeCookie tagCookie,
+ As&&... args)
+{
+ auto extraSpaceSize = sizeof (TSharedRef) * size + poolCapacity;
+ return NewWithExtraSpace<TSharedRefArrayImpl>(
+ extraSpaceSize,
+ extraSpaceSize,
+ tagCookie,
+ std::forward<As>(args)...);
+}
+
+Y_FORCE_INLINE const TSharedRef* begin(const TSharedRefArray& array)
+{
+ return array.Begin();
+}
+
+Y_FORCE_INLINE const TSharedRef* end(const TSharedRefArray& array)
+{
+ return array.End();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/memory/ref.cpp b/library/cpp/yt/memory/ref.cpp
index 18113e8570..e8ff42e976 100644
--- a/library/cpp/yt/memory/ref.cpp
+++ b/library/cpp/yt/memory/ref.cpp
@@ -1,25 +1,25 @@
#include "ref.h"
-#include "blob.h"
+#include "blob.h"
+
+#include <library/cpp/ytalloc/api/ytalloc.h>
+
+#include <util/system/info.h>
-#include <library/cpp/ytalloc/api/ytalloc.h>
-
-#include <util/system/info.h>
-
namespace NYT {
////////////////////////////////////////////////////////////////////////////////
-namespace NDetail {
-
+namespace NDetail {
+
// N.B. We would prefer these arrays to be zero sized
// but zero sized arrays are not supported in MSVC.
const char EmptyRefData[1] = {0};
char MutableEmptyRefData[1] = {0};
-
-} // namespace NDetail
-
-////////////////////////////////////////////////////////////////////////////////
-
+
+} // namespace NDetail
+
+////////////////////////////////////////////////////////////////////////////////
+
class TBlobHolder
: public TRefCounted
{
@@ -71,19 +71,19 @@ private:
////////////////////////////////////////////////////////////////////////////////
-template <class TDerived>
-class TAllocationHolderBase
+template <class TDerived>
+class TAllocationHolderBase
: public TRefCounted
{
public:
- TAllocationHolderBase(size_t size, TRefCountedTypeCookie cookie)
+ TAllocationHolderBase(size_t size, TRefCountedTypeCookie cookie)
: Size_(size)
#ifdef YT_ENABLE_REF_COUNTED_TRACKING
, Cookie_(cookie)
#endif
- { }
-
- ~TAllocationHolderBase()
+ { }
+
+ ~TAllocationHolderBase()
{
#ifdef YT_ENABLE_REF_COUNTED_TRACKING
TRefCountedTrackerFacade::FreeTagInstance(Cookie_);
@@ -93,25 +93,25 @@ public:
TMutableRef GetRef()
{
- return TMutableRef(static_cast<TDerived*>(this)->GetBegin(), Size_);
+ return TMutableRef(static_cast<TDerived*>(this)->GetBegin(), Size_);
}
-protected:
+protected:
const size_t Size_;
#ifdef YT_ENABLE_REF_COUNTED_TRACKING
const TRefCountedTypeCookie Cookie_;
#endif
-
- void Initialize(bool initializeStorage)
- {
- if (initializeStorage) {
- ::memset(static_cast<TDerived*>(this)->GetBegin(), 0, Size_);
- }
-#ifdef YT_ENABLE_REF_COUNTED_TRACKING
- TRefCountedTrackerFacade::AllocateTagInstance(Cookie_);
- TRefCountedTrackerFacade::AllocateSpace(Cookie_, Size_);
-#endif
- }
+
+ void Initialize(bool initializeStorage)
+ {
+ if (initializeStorage) {
+ ::memset(static_cast<TDerived*>(this)->GetBegin(), 0, Size_);
+ }
+#ifdef YT_ENABLE_REF_COUNTED_TRACKING
+ TRefCountedTrackerFacade::AllocateTagInstance(Cookie_);
+ TRefCountedTrackerFacade::AllocateSpace(Cookie_, Size_);
+#endif
+ }
};
////////////////////////////////////////////////////////////////////////////////
@@ -119,171 +119,171 @@ protected:
class TDefaultAllocationHolder
: public TAllocationHolderBase<TDefaultAllocationHolder>
, public TWithExtraSpace<TDefaultAllocationHolder>
-{
-public:
+{
+public:
TDefaultAllocationHolder(size_t size, bool initializeStorage, TRefCountedTypeCookie cookie)
- : TAllocationHolderBase(size, cookie)
- {
- Initialize(initializeStorage);
- }
-
- char* GetBegin()
- {
- return static_cast<char*>(GetExtraSpacePtr());
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-class TPageAlignedAllocationHolder
- : public TAllocationHolderBase<TPageAlignedAllocationHolder>
-{
-public:
- TPageAlignedAllocationHolder(size_t size, bool initializeStorage, TRefCountedTypeCookie cookie)
- : TAllocationHolderBase(size, cookie)
- , Begin_(static_cast<char*>(NYTAlloc::AllocatePageAligned(size)))
- {
- Initialize(initializeStorage);
- }
-
- ~TPageAlignedAllocationHolder()
- {
- NYTAlloc::Free(Begin_);
- }
-
- char* GetBegin()
- {
- return Begin_;
- }
-
-private:
- char* const Begin_;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-TRef TRef::FromBlob(const TBlob& blob)
-{
- return TRef(blob.Begin(), blob.Size());
-}
-
-bool TRef::AreBitwiseEqual(TRef lhs, TRef rhs)
-{
- if (lhs.Size() != rhs.Size()) {
- return false;
- }
- if (lhs.Size() == 0) {
- return true;
- }
- return ::memcmp(lhs.Begin(), rhs.Begin(), lhs.Size()) == 0;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-TMutableRef TMutableRef::FromBlob(TBlob& blob)
-{
- return TMutableRef(blob.Begin(), blob.Size());
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-TSharedRef TSharedRef::FromString(TString str, TRefCountedTypeCookie tagCookie)
-{
- auto holder = New<TStringHolder>(std::move(str), tagCookie);
+ : TAllocationHolderBase(size, cookie)
+ {
+ Initialize(initializeStorage);
+ }
+
+ char* GetBegin()
+ {
+ return static_cast<char*>(GetExtraSpacePtr());
+ }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class TPageAlignedAllocationHolder
+ : public TAllocationHolderBase<TPageAlignedAllocationHolder>
+{
+public:
+ TPageAlignedAllocationHolder(size_t size, bool initializeStorage, TRefCountedTypeCookie cookie)
+ : TAllocationHolderBase(size, cookie)
+ , Begin_(static_cast<char*>(NYTAlloc::AllocatePageAligned(size)))
+ {
+ Initialize(initializeStorage);
+ }
+
+ ~TPageAlignedAllocationHolder()
+ {
+ NYTAlloc::Free(Begin_);
+ }
+
+ char* GetBegin()
+ {
+ return Begin_;
+ }
+
+private:
+ char* const Begin_;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+TRef TRef::FromBlob(const TBlob& blob)
+{
+ return TRef(blob.Begin(), blob.Size());
+}
+
+bool TRef::AreBitwiseEqual(TRef lhs, TRef rhs)
+{
+ if (lhs.Size() != rhs.Size()) {
+ return false;
+ }
+ if (lhs.Size() == 0) {
+ return true;
+ }
+ return ::memcmp(lhs.Begin(), rhs.Begin(), lhs.Size()) == 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+TMutableRef TMutableRef::FromBlob(TBlob& blob)
+{
+ return TMutableRef(blob.Begin(), blob.Size());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+TSharedRef TSharedRef::FromString(TString str, TRefCountedTypeCookie tagCookie)
+{
+ auto holder = New<TStringHolder>(std::move(str), tagCookie);
auto ref = TRef::FromString(holder->String());
- return TSharedRef(ref, std::move(holder));
-}
-
-TSharedRef TSharedRef::FromBlob(TBlob&& blob)
-{
- auto ref = TRef::FromBlob(blob);
- auto holder = New<TBlobHolder>(std::move(blob));
- return TSharedRef(ref, std::move(holder));
-}
-
-TSharedRef TSharedRef::MakeCopy(TRef ref, TRefCountedTypeCookie tagCookie)
-{
- if (!ref) {
- return {};
- }
+ return TSharedRef(ref, std::move(holder));
+}
+
+TSharedRef TSharedRef::FromBlob(TBlob&& blob)
+{
+ auto ref = TRef::FromBlob(blob);
+ auto holder = New<TBlobHolder>(std::move(blob));
+ return TSharedRef(ref, std::move(holder));
+}
+
+TSharedRef TSharedRef::MakeCopy(TRef ref, TRefCountedTypeCookie tagCookie)
+{
+ if (!ref) {
+ return {};
+ }
if (ref.Empty()) {
- return TSharedRef::MakeEmpty();
+ return TSharedRef::MakeEmpty();
}
auto result = TSharedMutableRef::Allocate(ref.Size(), false, tagCookie);
::memcpy(result.Begin(), ref.Begin(), ref.Size());
return result;
-}
-
-std::vector<TSharedRef> TSharedRef::Split(size_t partSize) const
-{
- YT_VERIFY(partSize > 0);
- std::vector<TSharedRef> result;
- result.reserve(Size() / partSize + 1);
- auto sliceBegin = Begin();
- while (sliceBegin < End()) {
- auto sliceEnd = sliceBegin + partSize;
- if (sliceEnd < sliceBegin || sliceEnd > End()) {
- sliceEnd = End();
- }
- result.push_back(Slice(sliceBegin, sliceEnd));
- sliceBegin = sliceEnd;
- }
- return result;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-TSharedMutableRef TSharedMutableRef::Allocate(size_t size, bool initializeStorage, TRefCountedTypeCookie tagCookie)
-{
+}
+
+std::vector<TSharedRef> TSharedRef::Split(size_t partSize) const
+{
+ YT_VERIFY(partSize > 0);
+ std::vector<TSharedRef> result;
+ result.reserve(Size() / partSize + 1);
+ auto sliceBegin = Begin();
+ while (sliceBegin < End()) {
+ auto sliceEnd = sliceBegin + partSize;
+ if (sliceEnd < sliceBegin || sliceEnd > End()) {
+ sliceEnd = End();
+ }
+ result.push_back(Slice(sliceBegin, sliceEnd));
+ sliceBegin = sliceEnd;
+ }
+ return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+TSharedMutableRef TSharedMutableRef::Allocate(size_t size, bool initializeStorage, TRefCountedTypeCookie tagCookie)
+{
auto holder = NewWithExtraSpace<TDefaultAllocationHolder>(size, size, initializeStorage, tagCookie);
- auto ref = holder->GetRef();
- return TSharedMutableRef(ref, std::move(holder));
-}
-
-TSharedMutableRef TSharedMutableRef::AllocatePageAligned(size_t size, bool initializeStorage, TRefCountedTypeCookie tagCookie)
-{
- auto holder = New<TPageAlignedAllocationHolder>(size, initializeStorage, tagCookie);
- auto ref = holder->GetRef();
- return TSharedMutableRef(ref, std::move(holder));
-}
-
-TSharedMutableRef TSharedMutableRef::FromBlob(TBlob&& blob)
-{
- auto ref = TMutableRef::FromBlob(blob);
- auto holder = New<TBlobHolder>(std::move(blob));
- return TSharedMutableRef(ref, std::move(holder));
-}
-
-TSharedMutableRef TSharedMutableRef::MakeCopy(TRef ref, TRefCountedTypeCookie tagCookie)
-{
- if (!ref) {
- return {};
- }
+ auto ref = holder->GetRef();
+ return TSharedMutableRef(ref, std::move(holder));
+}
+
+TSharedMutableRef TSharedMutableRef::AllocatePageAligned(size_t size, bool initializeStorage, TRefCountedTypeCookie tagCookie)
+{
+ auto holder = New<TPageAlignedAllocationHolder>(size, initializeStorage, tagCookie);
+ auto ref = holder->GetRef();
+ return TSharedMutableRef(ref, std::move(holder));
+}
+
+TSharedMutableRef TSharedMutableRef::FromBlob(TBlob&& blob)
+{
+ auto ref = TMutableRef::FromBlob(blob);
+ auto holder = New<TBlobHolder>(std::move(blob));
+ return TSharedMutableRef(ref, std::move(holder));
+}
+
+TSharedMutableRef TSharedMutableRef::MakeCopy(TRef ref, TRefCountedTypeCookie tagCookie)
+{
+ if (!ref) {
+ return {};
+ }
if (ref.Empty()) {
- return TSharedMutableRef::MakeEmpty();
+ return TSharedMutableRef::MakeEmpty();
}
auto result = Allocate(ref.Size(), false, tagCookie);
::memcpy(result.Begin(), ref.Begin(), ref.Size());
return result;
-}
-
+}
+
////////////////////////////////////////////////////////////////////////////////
-TString ToString(TRef ref)
-{
+TString ToString(TRef ref)
+{
return TString(ref.Begin(), ref.End());
-}
-
+}
+
TString ToString(const TMutableRef& ref)
{
return ToString(TRef(ref));
}
-TString ToString(const TSharedRef& ref)
-{
- return ToString(TRef(ref));
-}
-
+TString ToString(const TSharedRef& ref)
+{
+ return ToString(TRef(ref));
+}
+
TString ToString(const TSharedMutableRef& ref)
{
return ToString(TRef(ref));
@@ -298,23 +298,23 @@ size_t GetPageSize()
size_t RoundUpToPage(size_t bytes)
{
static const size_t PageSize = NSystemInfo::GetPageSize();
- YT_ASSERT((PageSize & (PageSize - 1)) == 0);
+ YT_ASSERT((PageSize & (PageSize - 1)) == 0);
return (bytes + PageSize - 1) & (~(PageSize - 1));
}
-size_t GetByteSize(const TSharedRefArray& array)
-{
- size_t size = 0;
- if (array) {
- for (const auto& part : array) {
- size += part.Size();
- }
- }
- return size;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
+size_t GetByteSize(const TSharedRefArray& array)
+{
+ size_t size = 0;
+ if (array) {
+ for (const auto& part : array) {
+ size += part.Size();
+ }
+ }
+ return size;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
i64 TSharedRefArray::ByteSize() const
{
i64 result = 0;
@@ -326,53 +326,53 @@ i64 TSharedRefArray::ByteSize() const
return result;
}
-std::vector<TSharedRef> TSharedRefArray::ToVector() const
-{
- if (!Impl_) {
- return {};
- }
-
- return std::vector<TSharedRef>(Begin(), End());
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-TSharedRefArrayBuilder::TSharedRefArrayBuilder(
- size_t size,
- size_t poolCapacity,
- TRefCountedTypeCookie tagCookie)
- : AllocationCapacity_(poolCapacity)
- , Impl_(TSharedRefArray::NewImpl(
- size,
- poolCapacity,
- tagCookie,
- size))
- , CurrentAllocationPtr_(Impl_->GetBeginAllocationPtr())
-{ }
-
-void TSharedRefArrayBuilder::Add(TSharedRef part)
-{
- YT_ASSERT(CurrentPartIndex_ < Impl_->Size());
- Impl_->MutableBegin()[CurrentPartIndex_++] = std::move(part);
-}
-
-TMutableRef TSharedRefArrayBuilder::AllocateAndAdd(size_t size)
-{
- YT_ASSERT(CurrentPartIndex_ < Impl_->Size());
- YT_ASSERT(CurrentAllocationPtr_ + size <= Impl_->GetBeginAllocationPtr() + AllocationCapacity_);
- TMutableRef ref(CurrentAllocationPtr_, size);
- CurrentAllocationPtr_ += size;
+std::vector<TSharedRef> TSharedRefArray::ToVector() const
+{
+ if (!Impl_) {
+ return {};
+ }
+
+ return std::vector<TSharedRef>(Begin(), End());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+TSharedRefArrayBuilder::TSharedRefArrayBuilder(
+ size_t size,
+ size_t poolCapacity,
+ TRefCountedTypeCookie tagCookie)
+ : AllocationCapacity_(poolCapacity)
+ , Impl_(TSharedRefArray::NewImpl(
+ size,
+ poolCapacity,
+ tagCookie,
+ size))
+ , CurrentAllocationPtr_(Impl_->GetBeginAllocationPtr())
+{ }
+
+void TSharedRefArrayBuilder::Add(TSharedRef part)
+{
+ YT_ASSERT(CurrentPartIndex_ < Impl_->Size());
+ Impl_->MutableBegin()[CurrentPartIndex_++] = std::move(part);
+}
+
+TMutableRef TSharedRefArrayBuilder::AllocateAndAdd(size_t size)
+{
+ YT_ASSERT(CurrentPartIndex_ < Impl_->Size());
+ YT_ASSERT(CurrentAllocationPtr_ + size <= Impl_->GetBeginAllocationPtr() + AllocationCapacity_);
+ TMutableRef ref(CurrentAllocationPtr_, size);
+ CurrentAllocationPtr_ += size;
TRefCountedPtr holder(Impl_.Get(), false);
- TSharedRef sharedRef(ref, std::move(holder));
- Add(std::move(sharedRef));
- return ref;
-}
-
-TSharedRefArray TSharedRefArrayBuilder::Finish()
-{
- return TSharedRefArray(std::move(Impl_));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
+ TSharedRef sharedRef(ref, std::move(holder));
+ Add(std::move(sharedRef));
+ return ref;
+}
+
+TSharedRefArray TSharedRefArrayBuilder::Finish()
+{
+ return TSharedRefArray(std::move(Impl_));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
} // namespace NYT
diff --git a/library/cpp/yt/memory/ref.h b/library/cpp/yt/memory/ref.h
index 9ad82a8258..73d19d9013 100644
--- a/library/cpp/yt/memory/ref.h
+++ b/library/cpp/yt/memory/ref.h
@@ -1,53 +1,53 @@
#pragma once
-#include "new.h"
+#include "new.h"
#include "range.h"
-#include "shared_range.h"
+#include "shared_range.h"
+
+#include <type_traits>
-#include <type_traits>
-
namespace NYT {
////////////////////////////////////////////////////////////////////////////////
-// Forward declaration.
-class TBlob;
-
+// Forward declaration.
+class TBlob;
+
//! A non-owning reference to a range of memory.
class TRef
: public TRange<char>
{
public:
//! Creates a null TRef.
- TRef() = default;
+ TRef() = default;
//! Creates a TRef for a given block of memory.
- TRef(const void* data, size_t size);
+ TRef(const void* data, size_t size);
//! Creates a TRef for a given range of memory.
- TRef(const void* begin, const void* end);
-
- //! Creates an empty TRef.
- static TRef MakeEmpty();
+ TRef(const void* begin, const void* end);
+
+ //! Creates an empty TRef.
+ static TRef MakeEmpty();
//! Creates a non-owning TRef for a given blob.
- static TRef FromBlob(const TBlob& blob);
+ static TRef FromBlob(const TBlob& blob);
//! Creates a non-owning TRef for a given string.
- static TRef FromString(const TString& str);
-
- //! Creates a non-owning TRef for a given stringbuf.
- static TRef FromStringBuf(TStringBuf strBuf);
-
+ static TRef FromString(const TString& str);
+
+ //! Creates a non-owning TRef for a given stringbuf.
+ static TRef FromStringBuf(TStringBuf strBuf);
+
//! Creates a non-owning TRef for a given pod structure.
- template <class T>
- static TRef FromPod(const T& data);
+ template <class T>
+ static TRef FromPod(const T& data);
//! Creates a TRef for a part of existing range.
- TRef Slice(size_t startOffset, size_t endOffset) const;
+ TRef Slice(size_t startOffset, size_t endOffset) const;
//! Compares the content for bitwise equality.
- static bool AreBitwiseEqual(TRef lhs, TRef rhs);
+ static bool AreBitwiseEqual(TRef lhs, TRef rhs);
};
////////////////////////////////////////////////////////////////////////////////
@@ -61,107 +61,107 @@ public:
//! Creates a null TMutableRef.
//! Note empty TMutableRef is not the same as null TMutableRef.
//! `operator bool` can be used to check if ref is nonnull.
- TMutableRef() = default;
+ TMutableRef() = default;
//! Creates a TMutableRef for a given block of memory.
- TMutableRef(void* data, size_t size);
+ TMutableRef(void* data, size_t size);
//! Creates a TMutableRef for a given range of memory.
- TMutableRef(void* begin, void* end);
+ TMutableRef(void* begin, void* end);
+
+ //! Creates an empty TMutableRef.
+ static TMutableRef MakeEmpty();
- //! Creates an empty TMutableRef.
- static TMutableRef MakeEmpty();
-
//! Converts a TMutableRef to TRef.
- operator TRef() const;
-
+ operator TRef() const;
+
//! Creates a non-owning TMutableRef for a given blob.
- static TMutableRef FromBlob(TBlob& blob);
+ static TMutableRef FromBlob(TBlob& blob);
//! Creates a non-owning TMutableRef for a given pod structure.
template <class T>
- static TMutableRef FromPod(T& data);
-
+ static TMutableRef FromPod(T& data);
+
//! Creates a non-owning TMutableRef for a given string.
//! Ensures that the string is not shared.
- static TMutableRef FromString(TString& str);
-
+ static TMutableRef FromString(TString& str);
+
//! Creates a TMutableRef for a part of existing range.
- TMutableRef Slice(size_t startOffset, size_t endOffset) const;
+ TMutableRef Slice(size_t startOffset, size_t endOffset) const;
};
////////////////////////////////////////////////////////////////////////////////
-//! Default tag type for memory blocks allocated via TSharedRef.
-/*!
+//! Default tag type for memory blocks allocated via TSharedRef.
+/*!
* Each newly allocated TSharedRef blob is associated with a tag type
* that appears in ref-counted statistics.
- */
-struct TDefaultSharedBlobTag { };
-
-//! A reference to a range of memory with shared ownership.
+ */
+struct TDefaultSharedBlobTag { };
+
+//! A reference to a range of memory with shared ownership.
class TSharedRef
: public TSharedRange<char>
{
public:
//! Creates a null TSharedRef.
- TSharedRef() = default;
-
+ TSharedRef() = default;
+
//! Creates a TSharedRef with a given holder.
- TSharedRef(TRef ref, THolderPtr holder);
-
+ TSharedRef(TRef ref, THolderPtr holder);
+
//! Creates a TSharedRef from a pointer and length.
- TSharedRef(const void* data, size_t length, THolderPtr holder);
-
- //! Creates a TSharedRef from a range.
- TSharedRef(const void* begin, const void* end, THolderPtr holder);
-
- //! Creates an empty TSharedRef.
- static TSharedRef MakeEmpty();
-
+ TSharedRef(const void* data, size_t length, THolderPtr holder);
+
+ //! Creates a TSharedRef from a range.
+ TSharedRef(const void* begin, const void* end, THolderPtr holder);
+
+ //! Creates an empty TSharedRef.
+ static TSharedRef MakeEmpty();
+
//! Converts a TSharedRef to TRef.
- operator TRef() const;
-
-
+ operator TRef() const;
+
+
//! Creates a TSharedRef from a string.
- //! Since strings are ref-counted, no data is copied.
- //! The memory is marked with a given tag.
- template <class TTag>
- static TSharedRef FromString(TString str);
-
+ //! Since strings are ref-counted, no data is copied.
+ //! The memory is marked with a given tag.
+ template <class TTag>
+ static TSharedRef FromString(TString str);
+
//! Creates a TSharedRef from a string.
- //! Since strings are ref-counted, no data is copied.
- //! The memory is marked with TDefaultSharedBlobTag.
- static TSharedRef FromString(TString str);
-
+ //! Since strings are ref-counted, no data is copied.
+ //! The memory is marked with TDefaultSharedBlobTag.
+ static TSharedRef FromString(TString str);
+
//! Creates a TSharedRef reference from a string.
- //! Since strings are ref-counted, no data is copied.
- //! The memory is marked with a given tag.
- static TSharedRef FromString(TString str, TRefCountedTypeCookie tagCookie);
-
+ //! Since strings are ref-counted, no data is copied.
+ //! The memory is marked with a given tag.
+ static TSharedRef FromString(TString str, TRefCountedTypeCookie tagCookie);
+
//! Creates a TSharedRef for a given blob taking ownership of its content.
- static TSharedRef FromBlob(TBlob&& blob);
+ static TSharedRef FromBlob(TBlob&& blob);
//! Creates a copy of a given TRef.
//! The memory is marked with a given tag.
- static TSharedRef MakeCopy(TRef ref, TRefCountedTypeCookie tagCookie);
+ static TSharedRef MakeCopy(TRef ref, TRefCountedTypeCookie tagCookie);
//! Creates a copy of a given TRef.
//! The memory is marked with a given tag.
template <class TTag>
- static TSharedRef MakeCopy(TRef ref);
+ static TSharedRef MakeCopy(TRef ref);
//! Creates a TSharedRef for a part of existing range.
- TSharedRef Slice(size_t startOffset, size_t endOffset) const;
+ TSharedRef Slice(size_t startOffset, size_t endOffset) const;
//! Creates a TSharedRef for a part of existing range.
- TSharedRef Slice(const void* begin, const void* end) const;
+ TSharedRef Slice(const void* begin, const void* end) const;
//! Creates a vector of slices with specified size.
- std::vector<TSharedRef> Split(size_t partSize) const;
+ std::vector<TSharedRef> Split(size_t partSize) const;
private:
- friend class TSharedRefArrayImpl;
+ friend class TSharedRefArrayImpl;
};
////////////////////////////////////////////////////////////////////////////////
@@ -173,194 +173,194 @@ class TSharedMutableRef
{
public:
//! Creates a null TSharedMutableRef.
- TSharedMutableRef() = default;
+ TSharedMutableRef() = default;
//! Creates a TSharedMutableRef with a given holder.
- TSharedMutableRef(const TMutableRef& ref, THolderPtr holder);
+ TSharedMutableRef(const TMutableRef& ref, THolderPtr holder);
//! Creates a TSharedMutableRef from a pointer and length.
- TSharedMutableRef(void* data, size_t length, THolderPtr holder);
+ TSharedMutableRef(void* data, size_t length, THolderPtr holder);
- //! Creates a TSharedMutableRef from a range.
- TSharedMutableRef(void* begin, void* end, THolderPtr holder);
+ //! Creates a TSharedMutableRef from a range.
+ TSharedMutableRef(void* begin, void* end, THolderPtr holder);
+
+ //! Creates an empty TSharedMutableRef.
+ static TSharedMutableRef MakeEmpty();
- //! Creates an empty TSharedMutableRef.
- static TSharedMutableRef MakeEmpty();
-
//! Converts a TSharedMutableRef to TMutableRef.
- operator TMutableRef() const;
+ operator TMutableRef() const;
//! Converts a TSharedMutableRef to TSharedRef.
- operator TSharedRef() const;
+ operator TSharedRef() const;
//! Converts a TSharedMutableRef to TRef.
- operator TRef() const;
+ operator TRef() const;
//! Allocates a new shared block of memory.
//! The memory is marked with a given tag.
template <class TTag>
- static TSharedMutableRef Allocate(size_t size, bool initializeStorage = true);
-
+ static TSharedMutableRef Allocate(size_t size, bool initializeStorage = true);
+
//! Allocates a new shared block of memory.
//! The memory is marked with TDefaultSharedBlobTag.
- static TSharedMutableRef Allocate(size_t size, bool initializeStorage = true);
-
+ static TSharedMutableRef Allocate(size_t size, bool initializeStorage = true);
+
//! Allocates a new shared block of memory.
//! The memory is marked with a given tag.
- static TSharedMutableRef Allocate(size_t size, bool initializeStorage, TRefCountedTypeCookie tagCookie);
-
- //! Allocates a new page aligned shared block of memory.
- //! #size must be divisible by page size.
- //! The memory is marked with a given tag.
- template <class TTag>
- static TSharedMutableRef AllocatePageAligned(size_t size, bool initializeStorage = true);
-
- //! Allocates a new page aligned shared block of memory.
- //! #size must be divisible by page size.
- //! The memory is marked with TDefaultSharedBlobTag.
- static TSharedMutableRef AllocatePageAligned(size_t size, bool initializeStorage = true);
-
- //! Allocates a new page aligned shared block of memory.
- //! #size must be divisible by page size.
- //! The memory is marked with a given tag.
- static TSharedMutableRef AllocatePageAligned(size_t size, bool initializeStorage, TRefCountedTypeCookie tagCookie);
-
+ static TSharedMutableRef Allocate(size_t size, bool initializeStorage, TRefCountedTypeCookie tagCookie);
+
+ //! Allocates a new page aligned shared block of memory.
+ //! #size must be divisible by page size.
+ //! The memory is marked with a given tag.
+ template <class TTag>
+ static TSharedMutableRef AllocatePageAligned(size_t size, bool initializeStorage = true);
+
+ //! Allocates a new page aligned shared block of memory.
+ //! #size must be divisible by page size.
+ //! The memory is marked with TDefaultSharedBlobTag.
+ static TSharedMutableRef AllocatePageAligned(size_t size, bool initializeStorage = true);
+
+ //! Allocates a new page aligned shared block of memory.
+ //! #size must be divisible by page size.
+ //! The memory is marked with a given tag.
+ static TSharedMutableRef AllocatePageAligned(size_t size, bool initializeStorage, TRefCountedTypeCookie tagCookie);
+
//! Creates a TSharedMutableRef for the whole blob taking ownership of its content.
- static TSharedMutableRef FromBlob(TBlob&& blob);
-
+ static TSharedMutableRef FromBlob(TBlob&& blob);
+
//! Creates a copy of a given TRef.
//! The memory is marked with a given tag.
- static TSharedMutableRef MakeCopy(TRef ref, TRefCountedTypeCookie tagCookie);
-
+ static TSharedMutableRef MakeCopy(TRef ref, TRefCountedTypeCookie tagCookie);
+
//! Creates a copy of a given TRef.
//! The memory is marked with a given tag.
template <class TTag>
- static TSharedMutableRef MakeCopy(TRef ref);
-
+ static TSharedMutableRef MakeCopy(TRef ref);
+
//! Creates a reference for a part of existing range.
- TSharedMutableRef Slice(size_t startOffset, size_t endOffset) const;
-
+ TSharedMutableRef Slice(size_t startOffset, size_t endOffset) const;
+
//! Creates a reference for a part of existing range.
- TSharedMutableRef Slice(void* begin, void* end) const;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-DECLARE_REFCOUNTED_CLASS(TSharedRefArrayImpl)
-
-//! A smart-pointer to a ref-counted immutable sequence of TSharedRef-s.
-class TSharedRefArray
-{
-public:
- TSharedRefArray() = default;
- TSharedRefArray(const TSharedRefArray& other);
- TSharedRefArray(TSharedRefArray&& other) noexcept;
-
- explicit TSharedRefArray(const TSharedRef& part);
- explicit TSharedRefArray(TSharedRef&& part);
-
- struct TCopyParts
- { };
- struct TMoveParts
- { };
-
- template <class TParts>
- TSharedRefArray(const TParts& parts, TCopyParts);
- template <class TParts>
- TSharedRefArray(TParts&& parts, TMoveParts);
-
+ TSharedMutableRef Slice(void* begin, void* end) const;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+DECLARE_REFCOUNTED_CLASS(TSharedRefArrayImpl)
+
+//! A smart-pointer to a ref-counted immutable sequence of TSharedRef-s.
+class TSharedRefArray
+{
+public:
+ TSharedRefArray() = default;
+ TSharedRefArray(const TSharedRefArray& other);
+ TSharedRefArray(TSharedRefArray&& other) noexcept;
+
+ explicit TSharedRefArray(const TSharedRef& part);
+ explicit TSharedRefArray(TSharedRef&& part);
+
+ struct TCopyParts
+ { };
+ struct TMoveParts
+ { };
+
+ template <class TParts>
+ TSharedRefArray(const TParts& parts, TCopyParts);
+ template <class TParts>
+ TSharedRefArray(TParts&& parts, TMoveParts);
+
TSharedRefArray& operator = (const TSharedRefArray& other);
TSharedRefArray& operator = (TSharedRefArray&& other);
-
- explicit operator bool() const;
-
+
+ explicit operator bool() const;
+
void Reset();
- size_t Size() const;
+ size_t Size() const;
size_t size() const;
i64 ByteSize() const;
- bool Empty() const;
- const TSharedRef& operator [] (size_t index) const;
-
- const TSharedRef* Begin() const;
- const TSharedRef* End() const;
-
- std::vector<TSharedRef> ToVector() const;
-
-private:
- friend class TSharedRefArrayBuilder;
-
- TSharedRefArrayImplPtr Impl_;
-
- explicit TSharedRefArray(TSharedRefArrayImplPtr impl);
-
- template <class... As>
- static TSharedRefArrayImplPtr NewImpl(
- size_t size,
- size_t poolCapacity,
- TRefCountedTypeCookie cookie,
- As&&... args);
+ bool Empty() const;
+ const TSharedRef& operator [] (size_t index) const;
+
+ const TSharedRef* Begin() const;
+ const TSharedRef* End() const;
+
+ std::vector<TSharedRef> ToVector() const;
+
+private:
+ friend class TSharedRefArrayBuilder;
+
+ TSharedRefArrayImplPtr Impl_;
+
+ explicit TSharedRefArray(TSharedRefArrayImplPtr impl);
+
+ template <class... As>
+ static TSharedRefArrayImplPtr NewImpl(
+ size_t size,
+ size_t poolCapacity,
+ TRefCountedTypeCookie cookie,
+ As&&... args);
};
// STL interop.
-const TSharedRef* begin(const TSharedRefArray& array);
-const TSharedRef* end(const TSharedRefArray& array);
-
+const TSharedRef* begin(const TSharedRefArray& array);
+const TSharedRef* end(const TSharedRefArray& array);
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct TDefaultSharedRefArrayBuilderTag { };
+
+//! A helper for creating TSharedRefArray.
+class TSharedRefArrayBuilder
+{
+public:
+ //! Creates a builder instance.
+ /*
+ * The user must provide the total (resulting) part count in #size.
+ *
+ * Additionally, the user may request a certain memory pool of size #poolCapacity
+ * to be created. Parts occupiying space in the above pool are created with #AllocateAndAdd
+ * calls.
+ *
+ * The pool (if any) and the array are created within a single memory allocation tagged with
+ * #tagCookie.
+ *
+ * If less than #size parts are added, the trailing ones are null.
+ */
+ explicit TSharedRefArrayBuilder(
+ size_t size,
+ size_t poolCapacity = 0,
+ TRefCountedTypeCookie tagCookie = GetRefCountedTypeCookie<TDefaultSharedRefArrayBuilderTag>());
+
+ //! Adds an existing TSharedRef part to the constructed array.
+ void Add(TSharedRef part);
+
+ //! Allocates #size memory from the pool and adds a part to the constuctured array.
+ /*!
+ * The resulting TMutableRef enables the user to fill the just-created part appropriately.
+ * The total sum of #size during all #AllocateAndAll calls must now exceed #allocationCapacity
+ * passed to the ctor.
+ *
+ * The memory is being claimed from the pool contiguously; the user must
+ * take care of the alignment issues on its own.
+ */
+ TMutableRef AllocateAndAdd(size_t size);
+
+ //! Finalizes the construction; returns the constructed TSharedRefArray.
+ TSharedRefArray Finish();
+
+private:
+ const size_t AllocationCapacity_;
+ TSharedRefArrayImplPtr Impl_;
+ char* CurrentAllocationPtr_;
+ size_t CurrentPartIndex_ = 0;
+};
+
+
////////////////////////////////////////////////////////////////////////////////
-struct TDefaultSharedRefArrayBuilderTag { };
-
-//! A helper for creating TSharedRefArray.
-class TSharedRefArrayBuilder
-{
-public:
- //! Creates a builder instance.
- /*
- * The user must provide the total (resulting) part count in #size.
- *
- * Additionally, the user may request a certain memory pool of size #poolCapacity
- * to be created. Parts occupiying space in the above pool are created with #AllocateAndAdd
- * calls.
- *
- * The pool (if any) and the array are created within a single memory allocation tagged with
- * #tagCookie.
- *
- * If less than #size parts are added, the trailing ones are null.
- */
- explicit TSharedRefArrayBuilder(
- size_t size,
- size_t poolCapacity = 0,
- TRefCountedTypeCookie tagCookie = GetRefCountedTypeCookie<TDefaultSharedRefArrayBuilderTag>());
-
- //! Adds an existing TSharedRef part to the constructed array.
- void Add(TSharedRef part);
-
- //! Allocates #size memory from the pool and adds a part to the constuctured array.
- /*!
- * The resulting TMutableRef enables the user to fill the just-created part appropriately.
- * The total sum of #size during all #AllocateAndAll calls must now exceed #allocationCapacity
- * passed to the ctor.
- *
- * The memory is being claimed from the pool contiguously; the user must
- * take care of the alignment issues on its own.
- */
- TMutableRef AllocateAndAdd(size_t size);
-
- //! Finalizes the construction; returns the constructed TSharedRefArray.
- TSharedRefArray Finish();
-
-private:
- const size_t AllocationCapacity_;
- TSharedRefArrayImplPtr Impl_;
- char* CurrentAllocationPtr_;
- size_t CurrentPartIndex_ = 0;
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-
-TString ToString(TRef ref);
+TString ToString(TRef ref);
TString ToString(const TMutableRef& ref);
TString ToString(const TSharedRef& ref);
TString ToString(const TSharedMutableRef& ref);
@@ -368,17 +368,17 @@ TString ToString(const TSharedMutableRef& ref);
size_t GetPageSize();
size_t RoundUpToPage(size_t bytes);
-size_t GetByteSize(TRef ref);
-size_t GetByteSize(const TSharedRefArray& array);
+size_t GetByteSize(TRef ref);
+size_t GetByteSize(const TSharedRefArray& array);
+template <class T>
+size_t GetByteSize(TRange<T> parts);
template <class T>
-size_t GetByteSize(TRange<T> parts);
-template <class T>
-size_t GetByteSize(const std::vector<T>& parts);
+size_t GetByteSize(const std::vector<T>& parts);
////////////////////////////////////////////////////////////////////////////////
} // namespace NYT
-#define REF_INL_H_
-#include "ref-inl.h"
-#undef REF_INL_H_
+#define REF_INL_H_
+#include "ref-inl.h"
+#undef REF_INL_H_
diff --git a/library/cpp/yt/memory/ref_counted-inl.h b/library/cpp/yt/memory/ref_counted-inl.h
index 1e5eb937b5..e6d64fec18 100644
--- a/library/cpp/yt/memory/ref_counted-inl.h
+++ b/library/cpp/yt/memory/ref_counted-inl.h
@@ -47,7 +47,7 @@ using TDeleter = void (*)(void*);
void ScheduleObjectDeletion(void* ptr, TDeleter deleter);
template <class T>
-struct TMemoryReleaser<T, std::enable_if_t<T::EnableHazard>>
+struct TMemoryReleaser<T, std::enable_if_t<T::EnableHazard>>
{
static void Do(void* ptr, uint16_t offset)
{
@@ -94,7 +94,7 @@ Y_FORCE_INLINE bool TRefCounter::Unref() const
// See http://www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html#boost_atomic.usage_examples.example_reference_counters
//
auto oldStrongCount = StrongCount_.fetch_sub(1, std::memory_order_release);
- YT_ASSERT(oldStrongCount > 0);
+ YT_ASSERT(oldStrongCount > 0);
if (oldStrongCount == 1) {
StrongCount_.load(std::memory_order_acquire);
return true;
diff --git a/library/cpp/yt/memory/ref_counted.h b/library/cpp/yt/memory/ref_counted.h
index fd5d69439d..b683615b83 100644
--- a/library/cpp/yt/memory/ref_counted.h
+++ b/library/cpp/yt/memory/ref_counted.h
@@ -1,17 +1,17 @@
-#pragma once
-
-#include <library/cpp/yt/misc/port.h>
+#pragma once
-#include <library/cpp/yt/assert/assert.h>
-
-#include <library/cpp/ytalloc/api/ytalloc.h>
+#include <library/cpp/yt/misc/port.h>
+
+#include <library/cpp/yt/assert/assert.h>
+
+#include <library/cpp/ytalloc/api/ytalloc.h>
#include <atomic>
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
//! A technical base class for ref-counted objects and promise states.
class TRefCountedBase
{
@@ -20,30 +20,30 @@ public:
// Make destructor protected
virtual ~TRefCountedBase() noexcept = default;
-
+
virtual void DestroyRefCounted() = 0;
-
+
private:
- TRefCountedBase(const TRefCountedBase&) = delete;
- TRefCountedBase(TRefCountedBase&&) = delete;
-
+ TRefCountedBase(const TRefCountedBase&) = delete;
+ TRefCountedBase(TRefCountedBase&&) = delete;
+
TRefCountedBase& operator=(const TRefCountedBase&) = delete;
TRefCountedBase& operator=(TRefCountedBase&&) = delete;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
template <class T, class = void>
struct TFreeMemory
-{
+{
static void Do(void* ptr)
{
NYTAlloc::FreeNonNull(ptr);
}
};
-
+
template <class T>
-struct TFreeMemory<T, std::void_t<typename T::TAllocator>>
+struct TFreeMemory<T, std::void_t<typename T::TAllocator>>
{
static void Do(void* ptr)
{
@@ -51,17 +51,17 @@ struct TFreeMemory<T, std::void_t<typename T::TAllocator>>
TAllocator::Free(ptr);
}
};
-
+
////////////////////////////////////////////////////////////////////////////////
-class TRefCounter
+class TRefCounter
{
-public:
+public:
//! Returns current number of strong references to the object.
- /*!
+ /*!
* Note that you should never ever use this method in production code.
* This method is mainly for debugging purposes.
- */
+ */
int GetRefCount() const noexcept;
//! Increments the strong reference counter.
diff --git a/library/cpp/yt/memory/ref_tracked.h b/library/cpp/yt/memory/ref_tracked.h
index 554f433f2f..75c1eb5985 100644
--- a/library/cpp/yt/memory/ref_tracked.h
+++ b/library/cpp/yt/memory/ref_tracked.h
@@ -1,7 +1,7 @@
#pragma once
-#include <library/cpp/yt/misc/port.h>
-#include <library/cpp/yt/misc/source_location.h>
+#include <library/cpp/yt/misc/port.h>
+#include <library/cpp/yt/misc/source_location.h>
#include <util/system/defaults.h>
@@ -78,26 +78,26 @@ public:
#ifdef YT_ENABLE_REF_COUNTED_TRACKING
TRefTracked()
{
- auto cookie = GetRefCountedTypeCookie<T>();
- TRefCountedTrackerFacade::AllocateInstance(cookie);
+ auto cookie = GetRefCountedTypeCookie<T>();
+ TRefCountedTrackerFacade::AllocateInstance(cookie);
}
- TRefTracked(const TRefTracked&)
+ TRefTracked(const TRefTracked&)
{
auto cookie = GetRefCountedTypeCookie<T>();
- TRefCountedTrackerFacade::AllocateInstance(cookie);
+ TRefCountedTrackerFacade::AllocateInstance(cookie);
}
- TRefTracked(TRefTracked&&)
+ TRefTracked(TRefTracked&&)
{
auto cookie = GetRefCountedTypeCookie<T>();
- TRefCountedTrackerFacade::AllocateInstance(cookie);
+ TRefCountedTrackerFacade::AllocateInstance(cookie);
}
~TRefTracked()
{
- auto cookie = GetRefCountedTypeCookie<T>();
- TRefCountedTrackerFacade::FreeInstance(cookie);
+ auto cookie = GetRefCountedTypeCookie<T>();
+ TRefCountedTrackerFacade::FreeInstance(cookie);
}
#endif
};
diff --git a/library/cpp/yt/memory/shared_range.h b/library/cpp/yt/memory/shared_range.h
index 81a1266ff1..9841d7a0df 100644
--- a/library/cpp/yt/memory/shared_range.h
+++ b/library/cpp/yt/memory/shared_range.h
@@ -1,48 +1,48 @@
-#pragma once
-
-#include "intrusive_ptr.h"
+#pragma once
+
+#include "intrusive_ptr.h"
#include "range.h"
#include "ref_counted.h"
-
-#include <library/cpp/yt/assert/assert.h>
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
+
+#include <library/cpp/yt/assert/assert.h>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
template <class T, size_t N>
class TCompactVector;
-//! TRange with ownership semantics.
-template <class T>
-class TSharedRange
- : public TRange<T>
-{
-public:
+//! TRange with ownership semantics.
+template <class T>
+class TSharedRange
+ : public TRange<T>
+{
+public:
using THolderPtr = TRefCountedPtr;
-
+
//! Constructs a null TSharedRange.
- TSharedRange()
- { }
-
- //! Constructs a TSharedRange from TRange.
- TSharedRange(TRange<T> range, THolderPtr holder)
- : TRange<T>(range)
- , Holder_(std::move(holder))
- { }
-
- //! Constructs a TSharedRange from a pointer and length.
- TSharedRange(const T* data, size_t length, THolderPtr holder)
- : TRange<T>(data, length)
- , Holder_(std::move(holder))
- { }
-
- //! Constructs a TSharedRange from a range.
- TSharedRange(const T* begin, const T* end, THolderPtr holder)
- : TRange<T>(begin, end)
- , Holder_(std::move(holder))
- { }
-
+ TSharedRange()
+ { }
+
+ //! Constructs a TSharedRange from TRange.
+ TSharedRange(TRange<T> range, THolderPtr holder)
+ : TRange<T>(range)
+ , Holder_(std::move(holder))
+ { }
+
+ //! Constructs a TSharedRange from a pointer and length.
+ TSharedRange(const T* data, size_t length, THolderPtr holder)
+ : TRange<T>(data, length)
+ , Holder_(std::move(holder))
+ { }
+
+ //! Constructs a TSharedRange from a range.
+ TSharedRange(const T* begin, const T* end, THolderPtr holder)
+ : TRange<T>(begin, end)
+ , Holder_(std::move(holder))
+ { }
+
//! Constructs a TSharedRange from a TCompactVector.
template <size_t N>
TSharedRange(const TCompactVector<T, N>& elements, THolderPtr holder)
@@ -50,99 +50,99 @@ public:
, Holder_(std::move(holder))
{ }
- //! Constructs a TSharedRange from an std::vector.
- TSharedRange(const std::vector<T>& elements, THolderPtr holder)
- : TRange<T>(elements)
- , Holder_(std::move(holder))
- { }
-
- //! Constructs a TSharedRange from a C array.
- template <size_t N>
- TSharedRange(const T (& elements)[N], THolderPtr holder)
- : TRange<T>(elements)
- , Holder_(std::move(holder))
- { }
-
-
- void Reset()
- {
- TRange<T>::Data_ = nullptr;
- TRange<T>::Length_ = 0;
- Holder_.Reset();
- }
-
- TSharedRange<T> Slice(size_t startOffset, size_t endOffset) const
- {
- YT_ASSERT(startOffset <= this->Size());
- YT_ASSERT(endOffset >= startOffset && endOffset <= this->Size());
- return TSharedRange<T>(this->Begin() + startOffset, endOffset - startOffset, Holder_);
- }
-
- TSharedRange<T> Slice(const T* begin, const T* end) const
- {
- YT_ASSERT(begin >= this->Begin());
- YT_ASSERT(end <= this->End());
- return TSharedRange<T>(begin, end, Holder_);
- }
-
- const THolderPtr& GetHolder() const
- {
- return Holder_;
- }
-
+ //! Constructs a TSharedRange from an std::vector.
+ TSharedRange(const std::vector<T>& elements, THolderPtr holder)
+ : TRange<T>(elements)
+ , Holder_(std::move(holder))
+ { }
+
+ //! Constructs a TSharedRange from a C array.
+ template <size_t N>
+ TSharedRange(const T (& elements)[N], THolderPtr holder)
+ : TRange<T>(elements)
+ , Holder_(std::move(holder))
+ { }
+
+
+ void Reset()
+ {
+ TRange<T>::Data_ = nullptr;
+ TRange<T>::Length_ = 0;
+ Holder_.Reset();
+ }
+
+ TSharedRange<T> Slice(size_t startOffset, size_t endOffset) const
+ {
+ YT_ASSERT(startOffset <= this->Size());
+ YT_ASSERT(endOffset >= startOffset && endOffset <= this->Size());
+ return TSharedRange<T>(this->Begin() + startOffset, endOffset - startOffset, Holder_);
+ }
+
+ TSharedRange<T> Slice(const T* begin, const T* end) const
+ {
+ YT_ASSERT(begin >= this->Begin());
+ YT_ASSERT(end <= this->End());
+ return TSharedRange<T>(begin, end, Holder_);
+ }
+
+ const THolderPtr& GetHolder() const
+ {
+ return Holder_;
+ }
+
THolderPtr&& ReleaseHolder()
{
return std::move(Holder_);
}
-protected:
- THolderPtr Holder_;
-
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-//! Constructs a combined holder instance by taking ownership of a given list of holders.
-template <class... THolders>
+protected:
+ THolderPtr Holder_;
+
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+//! Constructs a combined holder instance by taking ownership of a given list of holders.
+template <class... THolders>
TRefCountedPtr MakeCompositeHolder(THolders&&... holders)
-{
- struct THolder
- : public TRefCounted
- {
- std::tuple<typename std::decay<THolders>::type...> Holders;
- };
-
- auto holder = New<THolder>();
- holder->Holders = std::tuple<THolders...>(std::forward<THolders>(holders)...);
- return holder;
-}
-
-template <class T, class TContainer, class... THolders>
-TSharedRange<T> DoMakeSharedRange(TContainer&& elements, THolders&&... holders)
-{
- struct THolder
- : public TRefCounted
- {
- typename std::decay<TContainer>::type Elements;
- std::tuple<typename std::decay<THolders>::type...> Holders;
- };
-
- auto holder = New<THolder>();
- holder->Holders = std::tuple<THolders...>(std::forward<THolders>(holders)...);
- holder->Elements = std::forward<TContainer>(elements);
-
- auto range = MakeRange<T>(holder->Elements);
-
+{
+ struct THolder
+ : public TRefCounted
+ {
+ std::tuple<typename std::decay<THolders>::type...> Holders;
+ };
+
+ auto holder = New<THolder>();
+ holder->Holders = std::tuple<THolders...>(std::forward<THolders>(holders)...);
+ return holder;
+}
+
+template <class T, class TContainer, class... THolders>
+TSharedRange<T> DoMakeSharedRange(TContainer&& elements, THolders&&... holders)
+{
+ struct THolder
+ : public TRefCounted
+ {
+ typename std::decay<TContainer>::type Elements;
+ std::tuple<typename std::decay<THolders>::type...> Holders;
+ };
+
+ auto holder = New<THolder>();
+ holder->Holders = std::tuple<THolders...>(std::forward<THolders>(holders)...);
+ holder->Elements = std::forward<TContainer>(elements);
+
+ auto range = MakeRange<T>(holder->Elements);
+
return TSharedRange<T>(range, std::move(holder));
-}
-
-//! Constructs a TSharedRange by taking ownership of an std::vector.
-template <class T, class... THolders>
-TSharedRange<T> MakeSharedRange(std::vector<T>&& elements, THolders&&... holders)
-{
- return DoMakeSharedRange<T>(std::move(elements), std::forward<THolders>(holders)...);
-}
-
+}
+
+//! Constructs a TSharedRange by taking ownership of an std::vector.
+template <class T, class... THolders>
+TSharedRange<T> MakeSharedRange(std::vector<T>&& elements, THolders&&... holders)
+{
+ return DoMakeSharedRange<T>(std::move(elements), std::forward<THolders>(holders)...);
+}
+
//! Constructs a TSharedRange by taking ownership of an TCompactVector.
template <class T, size_t N, class... THolders>
TSharedRange<T> MakeSharedRange(TCompactVector<T, N>&& elements, THolders&&... holders)
@@ -150,65 +150,65 @@ TSharedRange<T> MakeSharedRange(TCompactVector<T, N>&& elements, THolders&&... h
return DoMakeSharedRange<T>(std::move(elements), std::forward<THolders>(holders)...);
}
-//! Constructs a TSharedRange by copying an std::vector.
-template <class T, class... THolders>
-TSharedRange<T> MakeSharedRange(const std::vector<T>& elements, THolders&&... holders)
-{
- return DoMakeSharedRange<T>(elements, std::forward<THolders>(holders)...);
-}
-
-template <class T, class... THolders>
-TSharedRange<T> MakeSharedRange(TRange<T> range, THolders&&... holders)
-{
- return TSharedRange<T>(range, MakeCompositeHolder(std::forward<THolders>(holders)...));
-}
-
+//! Constructs a TSharedRange by copying an std::vector.
+template <class T, class... THolders>
+TSharedRange<T> MakeSharedRange(const std::vector<T>& elements, THolders&&... holders)
+{
+ return DoMakeSharedRange<T>(elements, std::forward<THolders>(holders)...);
+}
+
+template <class T, class... THolders>
+TSharedRange<T> MakeSharedRange(TRange<T> range, THolders&&... holders)
+{
+ return TSharedRange<T>(range, MakeCompositeHolder(std::forward<THolders>(holders)...));
+}
+
template <class T, class THolder>
TSharedRange<T> MakeSharedRange(TRange<T> range, TIntrusivePtr<THolder> holder)
{
return TSharedRange<T>(range, std::move(holder));
}
-template <class U, class T>
-TSharedRange<U> ReinterpretCastRange(const TSharedRange<T>& range)
-{
- static_assert(sizeof(T) == sizeof(U), "T and U must have equal sizes.");
- return TSharedRange<U>(reinterpret_cast<const U*>(range.Begin()), range.Size(), range.GetHolder());
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-//! TMutableRange with ownership semantics.
-//! Use with caution :)
-template <class T>
-class TSharedMutableRange
- : public TMutableRange<T>
-{
-public:
+template <class U, class T>
+TSharedRange<U> ReinterpretCastRange(const TSharedRange<T>& range)
+{
+ static_assert(sizeof(T) == sizeof(U), "T and U must have equal sizes.");
+ return TSharedRange<U>(reinterpret_cast<const U*>(range.Begin()), range.Size(), range.GetHolder());
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+//! TMutableRange with ownership semantics.
+//! Use with caution :)
+template <class T>
+class TSharedMutableRange
+ : public TMutableRange<T>
+{
+public:
using THolderPtr = TRefCountedPtr;
-
- //! Constructs a null TSharedMutableRange.
- TSharedMutableRange()
- { }
-
- //! Constructs a TSharedMutableRange from TMutableRange.
- TSharedMutableRange(TMutableRange<T> range, THolderPtr holder)
- : TMutableRange<T>(range)
- , Holder_(std::move(holder))
- { }
-
- //! Constructs a TSharedMutableRange from a pointer and length.
- TSharedMutableRange(T* data, size_t length, THolderPtr holder)
- : TMutableRange<T>(data, length)
- , Holder_(std::move(holder))
- { }
-
- //! Constructs a TSharedMutableRange from a range.
- TSharedMutableRange(T* begin, T* end, THolderPtr holder)
- : TMutableRange<T>(begin, end)
- , Holder_(std::move(holder))
- { }
-
+
+ //! Constructs a null TSharedMutableRange.
+ TSharedMutableRange()
+ { }
+
+ //! Constructs a TSharedMutableRange from TMutableRange.
+ TSharedMutableRange(TMutableRange<T> range, THolderPtr holder)
+ : TMutableRange<T>(range)
+ , Holder_(std::move(holder))
+ { }
+
+ //! Constructs a TSharedMutableRange from a pointer and length.
+ TSharedMutableRange(T* data, size_t length, THolderPtr holder)
+ : TMutableRange<T>(data, length)
+ , Holder_(std::move(holder))
+ { }
+
+ //! Constructs a TSharedMutableRange from a range.
+ TSharedMutableRange(T* begin, T* end, THolderPtr holder)
+ : TMutableRange<T>(begin, end)
+ , Holder_(std::move(holder))
+ { }
+
//! Constructs a TSharedMutableRange from a TCompactVector.
template <size_t N>
TSharedMutableRange(TCompactVector<T, N>& elements, THolderPtr holder)
@@ -216,82 +216,82 @@ public:
, Holder_(std::move(holder))
{ }
- //! Constructs a TSharedMutableRange from an std::vector.
- TSharedMutableRange(std::vector<T>& elements, THolderPtr holder)
- : TMutableRange<T>(elements)
- , Holder_(std::move(holder))
- { }
-
- //! Constructs a TSharedMutableRange from a C array.
- template <size_t N>
- TSharedMutableRange(T (& elements)[N], THolderPtr holder)
- : TMutableRange<T>(elements)
- , Holder_(std::move(holder))
- { }
-
-
- void Reset()
- {
- TRange<T>::Data_ = nullptr;
- TRange<T>::Length_ = 0;
- Holder_.Reset();
- }
-
- TSharedMutableRange<T> Slice(size_t startOffset, size_t endOffset) const
- {
- YT_ASSERT(startOffset <= this->Size());
- YT_ASSERT(endOffset >= startOffset && endOffset <= this->Size());
- return TSharedMutableRange<T>(this->Begin() + startOffset, endOffset - startOffset, Holder_);
- }
-
- TSharedMutableRange<T> Slice(T* begin, T* end) const
- {
- YT_ASSERT(begin >= this->Begin());
- YT_ASSERT(end <= this->End());
- return TSharedMutableRange<T>(begin, end, Holder_);
- }
-
- THolderPtr GetHolder() const
- {
- return Holder_;
- }
-
+ //! Constructs a TSharedMutableRange from an std::vector.
+ TSharedMutableRange(std::vector<T>& elements, THolderPtr holder)
+ : TMutableRange<T>(elements)
+ , Holder_(std::move(holder))
+ { }
+
+ //! Constructs a TSharedMutableRange from a C array.
+ template <size_t N>
+ TSharedMutableRange(T (& elements)[N], THolderPtr holder)
+ : TMutableRange<T>(elements)
+ , Holder_(std::move(holder))
+ { }
+
+
+ void Reset()
+ {
+ TRange<T>::Data_ = nullptr;
+ TRange<T>::Length_ = 0;
+ Holder_.Reset();
+ }
+
+ TSharedMutableRange<T> Slice(size_t startOffset, size_t endOffset) const
+ {
+ YT_ASSERT(startOffset <= this->Size());
+ YT_ASSERT(endOffset >= startOffset && endOffset <= this->Size());
+ return TSharedMutableRange<T>(this->Begin() + startOffset, endOffset - startOffset, Holder_);
+ }
+
+ TSharedMutableRange<T> Slice(T* begin, T* end) const
+ {
+ YT_ASSERT(begin >= this->Begin());
+ YT_ASSERT(end <= this->End());
+ return TSharedMutableRange<T>(begin, end, Holder_);
+ }
+
+ THolderPtr GetHolder() const
+ {
+ return Holder_;
+ }
+
THolderPtr&& ReleaseHolder()
{
return std::move(Holder_);
}
-protected:
- THolderPtr Holder_;
-
-};
-
-template <class T, class TContainer, class... THolders>
-TSharedMutableRange<T> DoMakeSharedMutableRange(TContainer&& elements, THolders&&... holders)
-{
- struct THolder
- : public TRefCounted
- {
- typename std::decay<TContainer>::type Elements;
- std::tuple<typename std::decay<THolders>::type...> Holders;
- };
-
- auto holder = New<THolder>();
- holder->Holders = std::tuple<THolders...>(std::forward<THolders>(holders)...);
- holder->Elements = std::forward<TContainer>(elements);
-
- auto range = TMutableRange<T>(holder->Elements);
-
- return TSharedMutableRange<T>(range, holder);
-}
-
-//! Constructs a TSharedMutableRange by taking ownership of an std::vector.
-template <class T, class... THolders>
-TSharedMutableRange<T> MakeSharedMutableRange(std::vector<T>&& elements, THolders&&... holders)
-{
- return DoMakeSharedMutableRange<T>(std::move(elements), std::forward<THolders>(holders)...);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
+protected:
+ THolderPtr Holder_;
+
+};
+
+template <class T, class TContainer, class... THolders>
+TSharedMutableRange<T> DoMakeSharedMutableRange(TContainer&& elements, THolders&&... holders)
+{
+ struct THolder
+ : public TRefCounted
+ {
+ typename std::decay<TContainer>::type Elements;
+ std::tuple<typename std::decay<THolders>::type...> Holders;
+ };
+
+ auto holder = New<THolder>();
+ holder->Holders = std::tuple<THolders...>(std::forward<THolders>(holders)...);
+ holder->Elements = std::forward<TContainer>(elements);
+
+ auto range = TMutableRange<T>(holder->Elements);
+
+ return TSharedMutableRange<T>(range, holder);
+}
+
+//! Constructs a TSharedMutableRange by taking ownership of an std::vector.
+template <class T, class... THolders>
+TSharedMutableRange<T> MakeSharedMutableRange(std::vector<T>&& elements, THolders&&... holders)
+{
+ return DoMakeSharedMutableRange<T>(std::move(elements), std::forward<THolders>(holders)...);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/memory/unittests/intrusive_ptr_ut.cpp b/library/cpp/yt/memory/unittests/intrusive_ptr_ut.cpp
index abd55e7661..622bed0eb0 100644
--- a/library/cpp/yt/memory/unittests/intrusive_ptr_ut.cpp
+++ b/library/cpp/yt/memory/unittests/intrusive_ptr_ut.cpp
@@ -1,485 +1,485 @@
#include <library/cpp/testing/gtest/gtest.h>
-
-#include <library/cpp/yt/memory/new.h>
-#include <library/cpp/yt/memory/ref_counted.h>
-
-namespace NYT {
-namespace {
-
-////////////////////////////////////////////////////////////////////////////////
-
-using ::testing::IsNull;
-using ::testing::NotNull;
-using ::testing::InSequence;
-using ::testing::MockFunction;
-using ::testing::StrictMock;
-
-////////////////////////////////////////////////////////////////////////////////
-// Auxiliary types and functions.
-////////////////////////////////////////////////////////////////////////////////
-
-// This object tracks number of increments and decrements
-// to the reference counter (see traits specialization below).
-struct TIntricateObject
- : private TNonCopyable
-{
- int Increments = 0;
- int Decrements = 0;
- int Zeros = 0;
-
- void Ref()
- {
- ++Increments;
- }
-
- void Unref()
- {
- ++Decrements;
- if (Increments == Decrements) {
- ++Zeros;
- }
- }
-};
-
-typedef TIntrusivePtr<TIntricateObject> TIntricateObjectPtr;
-
-void Ref(TIntricateObject* obj)
-{
- obj->Ref();
-}
-
-void Unref(TIntricateObject* obj)
-{
- obj->Unref();
-}
-
-MATCHER_P3(HasRefCounts, increments, decrements, zeros,
- "Reference counter " \
- "was incremented " + ::testing::PrintToString(increments) + " times, " +
- "was decremented " + ::testing::PrintToString(decrements) + " times, " +
- "vanished to zero " + ::testing::PrintToString(zeros) + " times")
-{
- Y_UNUSED(result_listener);
- return
- arg.Increments == increments &&
- arg.Decrements == decrements &&
- arg.Zeros == zeros;
-}
-
-void PrintTo(const TIntricateObject& arg, ::std::ostream* os)
-{
+
+#include <library/cpp/yt/memory/new.h>
+#include <library/cpp/yt/memory/ref_counted.h>
+
+namespace NYT {
+namespace {
+
+////////////////////////////////////////////////////////////////////////////////
+
+using ::testing::IsNull;
+using ::testing::NotNull;
+using ::testing::InSequence;
+using ::testing::MockFunction;
+using ::testing::StrictMock;
+
+////////////////////////////////////////////////////////////////////////////////
+// Auxiliary types and functions.
+////////////////////////////////////////////////////////////////////////////////
+
+// This object tracks number of increments and decrements
+// to the reference counter (see traits specialization below).
+struct TIntricateObject
+ : private TNonCopyable
+{
+ int Increments = 0;
+ int Decrements = 0;
+ int Zeros = 0;
+
+ void Ref()
+ {
+ ++Increments;
+ }
+
+ void Unref()
+ {
+ ++Decrements;
+ if (Increments == Decrements) {
+ ++Zeros;
+ }
+ }
+};
+
+typedef TIntrusivePtr<TIntricateObject> TIntricateObjectPtr;
+
+void Ref(TIntricateObject* obj)
+{
+ obj->Ref();
+}
+
+void Unref(TIntricateObject* obj)
+{
+ obj->Unref();
+}
+
+MATCHER_P3(HasRefCounts, increments, decrements, zeros,
+ "Reference counter " \
+ "was incremented " + ::testing::PrintToString(increments) + " times, " +
+ "was decremented " + ::testing::PrintToString(decrements) + " times, " +
+ "vanished to zero " + ::testing::PrintToString(zeros) + " times")
+{
+ Y_UNUSED(result_listener);
+ return
+ arg.Increments == increments &&
+ arg.Decrements == decrements &&
+ arg.Zeros == zeros;
+}
+
+void PrintTo(const TIntricateObject& arg, ::std::ostream* os)
+{
*os << arg.Increments << " increments, "
<< arg.Decrements << " decrements and "
<< arg.Zeros << " times vanished";
-}
-
-// This is an object which creates intrusive pointers to the self
-// during its construction.
-class TObjectWithSelfPointers
- : public TRefCounted
-{
-public:
- explicit TObjectWithSelfPointers(IOutputStream* output)
- : Output_(output)
- {
- *Output_ << "Cb";
-
- for (int i = 0; i < 3; ++i) {
- *Output_ << '!';
- TIntrusivePtr<TObjectWithSelfPointers> ptr(this);
- }
-
- *Output_ << "Ca";
- }
-
- virtual ~TObjectWithSelfPointers()
- {
- *Output_ << 'D';
- }
-
-private:
- IOutputStream* const Output_;
-
-};
-
-// This is a simple object with simple reference counting.
-class TObjectWithSimpleRC
- : public TRefCounted
-{
-public:
- explicit TObjectWithSimpleRC(IOutputStream* output)
- : Output_(output)
- {
- *Output_ << 'C';
- }
-
- virtual ~TObjectWithSimpleRC()
- {
- *Output_ << 'D';
- }
-
- void DoSomething()
- {
- *Output_ << '!';
- }
-
-private:
- IOutputStream* const Output_;
-
-};
-
-// This is a simple object with full-fledged reference counting.
-class TObjectWithFullRC
- : public TRefCounted
-{
-public:
- explicit TObjectWithFullRC(IOutputStream* output)
- : Output_(output)
- {
- *Output_ << 'C';
- }
-
- virtual ~TObjectWithFullRC()
- {
- *Output_ << 'D';
- }
-
- void DoSomething()
- {
- *Output_ << '!';
- }
-
-private:
- IOutputStream* const Output_;
-
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-TEST(TIntrusivePtrTest, Empty)
-{
- TIntricateObjectPtr emptyPointer;
- EXPECT_EQ(nullptr, emptyPointer.Get());
-}
-
-TEST(TIntrusivePtrTest, Basic)
-{
- TIntricateObject object;
-
- EXPECT_THAT(object, HasRefCounts(0, 0, 0));
-
- {
- TIntricateObjectPtr owningPointer(&object);
- EXPECT_THAT(object, HasRefCounts(1, 0, 0));
- EXPECT_EQ(&object, owningPointer.Get());
- }
-
- EXPECT_THAT(object, HasRefCounts(1, 1, 1));
-
- {
- TIntricateObjectPtr nonOwningPointer(&object, false);
- EXPECT_THAT(object, HasRefCounts(1, 1, 1));
- EXPECT_EQ(&object, nonOwningPointer.Get());
- }
-
- EXPECT_THAT(object, HasRefCounts(1, 2, 1));
-}
-
-TEST(TIntrusivePtrTest, ResetToNull)
-{
- TIntricateObject object;
- TIntricateObjectPtr ptr(&object);
-
- EXPECT_THAT(object, HasRefCounts(1, 0, 0));
- EXPECT_EQ(&object, ptr.Get());
-
- ptr.Reset();
-
- EXPECT_THAT(object, HasRefCounts(1, 1, 1));
- EXPECT_EQ(nullptr, ptr.Get());
-}
-
-TEST(TIntrusivePtrTest, ResetToOtherObject)
-{
- TIntricateObject firstObject;
- TIntricateObject secondObject;
-
- TIntricateObjectPtr ptr(&firstObject);
-
- EXPECT_THAT(firstObject, HasRefCounts(1, 0, 0));
- EXPECT_THAT(secondObject, HasRefCounts(0, 0, 0));
- EXPECT_EQ(&firstObject, ptr.Get());
-
- ptr.Reset(&secondObject);
-
- EXPECT_THAT(firstObject, HasRefCounts(1, 1, 1));
- EXPECT_THAT(secondObject, HasRefCounts(1, 0, 0));
- EXPECT_EQ(&secondObject, ptr.Get());
-}
-
-TEST(TIntrusivePtrTest, CopySemantics)
-{
- TIntricateObject object;
-
- TIntricateObjectPtr foo(&object);
- EXPECT_THAT(object, HasRefCounts(1, 0, 0));
-
- {
- TIntricateObjectPtr bar(foo);
- EXPECT_THAT(object, HasRefCounts(2, 0, 0));
- EXPECT_EQ(&object, foo.Get());
- EXPECT_EQ(&object, bar.Get());
- }
-
- EXPECT_THAT(object, HasRefCounts(2, 1, 0));
-
- {
- TIntricateObjectPtr bar;
- bar = foo;
-
- EXPECT_THAT(object, HasRefCounts(3, 1, 0));
- EXPECT_EQ(&object, foo.Get());
- EXPECT_EQ(&object, bar.Get());
- }
-
- EXPECT_THAT(object, HasRefCounts(3, 2, 0));
-}
-
-TEST(TIntrusivePtrTest, MoveSemantics)
-{
- TIntricateObject object;
-
- TIntricateObjectPtr foo(&object);
- EXPECT_THAT(object, HasRefCounts(1, 0, 0));
-
- {
- TIntricateObjectPtr bar(std::move(foo));
- EXPECT_THAT(object, HasRefCounts(1, 0, 0));
- EXPECT_THAT(foo.Get(), IsNull());
- EXPECT_EQ(&object, bar.Get());
- }
-
- EXPECT_THAT(object, HasRefCounts(1, 1, 1));
- foo.Reset(&object);
- EXPECT_THAT(object, HasRefCounts(2, 1, 1));
-
- {
- TIntricateObjectPtr bar;
- bar = std::move(foo);
- EXPECT_THAT(object, HasRefCounts(2, 1, 1));
- EXPECT_THAT(foo.Get(), IsNull());
- EXPECT_EQ(&object, bar.Get());
- }
-}
-
-TEST(TIntrusivePtrTest, Swap)
-{
- TIntricateObject object;
-
- TIntricateObjectPtr foo(&object);
- TIntricateObjectPtr bar;
-
- EXPECT_THAT(object, HasRefCounts(1, 0, 0));
- EXPECT_THAT(foo.Get(), NotNull());
- EXPECT_THAT(bar.Get(), IsNull());
-
- foo.Swap(bar);
-
- EXPECT_THAT(object, HasRefCounts(1, 0, 0));
- EXPECT_THAT(foo.Get(), IsNull());
- EXPECT_THAT(bar.Get(), NotNull());
-
- foo.Swap(bar);
-
- EXPECT_THAT(object, HasRefCounts(1, 0, 0));
- EXPECT_THAT(foo.Get(), NotNull());
- EXPECT_THAT(bar.Get(), IsNull());
-}
-
-TEST(TIntrusivePtrTest, UpCast)
-{
- //! This is a simple typical reference-counted object.
- class TSimpleObject
- : public TRefCounted
- { };
-
- //! This is a simple inherited reference-counted object.
- class TAnotherObject
- : public TSimpleObject
- { };
-
- auto foo = New<TSimpleObject>();
- auto bar = New<TAnotherObject>();
- auto baz = New<TAnotherObject>();
-
- foo = baz;
-
- EXPECT_TRUE(foo == baz);
-}
-
-TEST(TIntrusivePtrTest, DownCast)
-{
- class TBaseObject
- : public TRefCounted
- { };
-
- class TDerivedObject
- : public TBaseObject
- { };
-
- //! This is a simple inherited reference-counted object.
- class TAnotherObject
- : public TBaseObject
- { };
-
- TIntrusivePtr<TBaseObject> foo = New<TDerivedObject>();
- TIntrusivePtr<TBaseObject> bar = New<TAnotherObject>();
- {
- auto baz = StaticPointerCast<TDerivedObject>(foo);
- EXPECT_TRUE(foo == baz);
- }
- {
- auto baz = StaticPointerCast<TDerivedObject>(TIntrusivePtr<TBaseObject>{foo});
- EXPECT_TRUE(foo == baz);
- }
- {
- auto baz = DynamicPointerCast<TDerivedObject>(foo);
- EXPECT_TRUE(foo == baz);
- }
- {
- auto baz = DynamicPointerCast<TDerivedObject>(bar);
- EXPECT_TRUE(nullptr == baz);
- }
- {
- auto baz = ConstPointerCast<const TBaseObject>(foo);
- EXPECT_TRUE(foo.Get() == baz.Get());
- }
- {
- auto baz = ConstPointerCast<const TBaseObject>(TIntrusivePtr<TBaseObject>{foo});
- EXPECT_TRUE(foo.Get() == baz.Get());
- }
-}
-
-TEST(TIntrusivePtrTest, UnspecifiedBoolType)
-{
- TIntricateObject object;
-
- TIntricateObjectPtr foo;
- TIntricateObjectPtr bar(&object);
-
- EXPECT_FALSE(foo);
- EXPECT_TRUE(bar);
-}
-
-TEST(TIntrusivePtrTest, ObjectIsNotDestroyedPrematurely)
-{
- TStringStream output;
- New<TObjectWithSelfPointers>(&output);
-
- // TObject... appends symbols to the output; see definitions.
- EXPECT_STREQ("Cb!!!CaD", output.Str().c_str());
-}
-
-TEST(TIntrusivePtrTest, EqualityOperator)
-{
- TIntricateObject object, anotherObject;
-
- TIntricateObjectPtr emptyPointer;
- TIntricateObjectPtr somePointer(&object);
- TIntricateObjectPtr samePointer(&object);
- TIntricateObjectPtr anotherPointer(&anotherObject);
-
- EXPECT_FALSE(somePointer == emptyPointer);
- EXPECT_FALSE(samePointer == emptyPointer);
-
- EXPECT_TRUE(somePointer != emptyPointer);
- EXPECT_TRUE(samePointer != emptyPointer);
-
- EXPECT_TRUE(somePointer == samePointer);
-
- EXPECT_TRUE(&object == somePointer);
- EXPECT_TRUE(&object == samePointer);
-
- EXPECT_FALSE(somePointer == anotherPointer);
- EXPECT_TRUE(somePointer != anotherPointer);
-
- EXPECT_TRUE(&anotherObject == anotherPointer);
-}
-
-TEST(TIntrusivePtrTest, Reset)
-{
- TIntricateObject object;
- TIntricateObjectPtr pointer(&object);
- EXPECT_THAT(object, HasRefCounts(1, 0, 0));
- EXPECT_EQ(&object, pointer.Release());
- EXPECT_THAT(object, HasRefCounts(1, 0, 0));
-}
-
-TEST(TIntrusivePtrTest, CompareWithNullptr)
-{
- TIntricateObjectPtr pointer1;
- EXPECT_TRUE(nullptr == pointer1);
- EXPECT_FALSE(nullptr != pointer1);
- TIntricateObject object;
- TIntricateObjectPtr pointer2(&object);
- EXPECT_TRUE(pointer2 != nullptr);
- EXPECT_FALSE(pointer2 == nullptr);
-}
-
-
-template <class T>
-void TestIntrusivePtrBehavior()
-{
- typedef TIntrusivePtr<T> TMyPtr;
-
- TStringStream output;
- {
- TMyPtr ptr(New<T>(&output));
- {
- TMyPtr anotherPtr(ptr);
- anotherPtr->DoSomething();
- }
- {
- TMyPtr anotherPtr(ptr);
- anotherPtr->DoSomething();
- }
- ptr->DoSomething();
- }
-
- // TObject... appends symbols to the output; see definitions.
- EXPECT_STREQ("C!!!D", output.Str().c_str());
-}
-
-TEST(TIntrusivePtrTest, SimpleRCBehaviour)
-{
- TestIntrusivePtrBehavior<TObjectWithSimpleRC>();
-}
-
-TEST(TIntrusivePtrTest, FullRCBehaviour)
-{
- TestIntrusivePtrBehavior<TObjectWithFullRC>();
-}
-
-TEST(TIntrusivePtrTest, ObjectAlignment)
-{
- struct TObject
- : public TRefCounted
- {
- alignas(64) ui64 Data;
- };
-
- struct TPODObject final
- {
- alignas(64) ui64 Data;
- };
-
- auto foo = New<TObject>();
- auto bar = New<TPODObject>();
-
- EXPECT_TRUE(reinterpret_cast<uintptr_t>(foo.Get()) % 64 == 0);
- EXPECT_TRUE(reinterpret_cast<uintptr_t>(bar.Get()) % 64 == 0);
-}
-
+}
+
+// This is an object which creates intrusive pointers to the self
+// during its construction.
+class TObjectWithSelfPointers
+ : public TRefCounted
+{
+public:
+ explicit TObjectWithSelfPointers(IOutputStream* output)
+ : Output_(output)
+ {
+ *Output_ << "Cb";
+
+ for (int i = 0; i < 3; ++i) {
+ *Output_ << '!';
+ TIntrusivePtr<TObjectWithSelfPointers> ptr(this);
+ }
+
+ *Output_ << "Ca";
+ }
+
+ virtual ~TObjectWithSelfPointers()
+ {
+ *Output_ << 'D';
+ }
+
+private:
+ IOutputStream* const Output_;
+
+};
+
+// This is a simple object with simple reference counting.
+class TObjectWithSimpleRC
+ : public TRefCounted
+{
+public:
+ explicit TObjectWithSimpleRC(IOutputStream* output)
+ : Output_(output)
+ {
+ *Output_ << 'C';
+ }
+
+ virtual ~TObjectWithSimpleRC()
+ {
+ *Output_ << 'D';
+ }
+
+ void DoSomething()
+ {
+ *Output_ << '!';
+ }
+
+private:
+ IOutputStream* const Output_;
+
+};
+
+// This is a simple object with full-fledged reference counting.
+class TObjectWithFullRC
+ : public TRefCounted
+{
+public:
+ explicit TObjectWithFullRC(IOutputStream* output)
+ : Output_(output)
+ {
+ *Output_ << 'C';
+ }
+
+ virtual ~TObjectWithFullRC()
+ {
+ *Output_ << 'D';
+ }
+
+ void DoSomething()
+ {
+ *Output_ << '!';
+ }
+
+private:
+ IOutputStream* const Output_;
+
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+TEST(TIntrusivePtrTest, Empty)
+{
+ TIntricateObjectPtr emptyPointer;
+ EXPECT_EQ(nullptr, emptyPointer.Get());
+}
+
+TEST(TIntrusivePtrTest, Basic)
+{
+ TIntricateObject object;
+
+ EXPECT_THAT(object, HasRefCounts(0, 0, 0));
+
+ {
+ TIntricateObjectPtr owningPointer(&object);
+ EXPECT_THAT(object, HasRefCounts(1, 0, 0));
+ EXPECT_EQ(&object, owningPointer.Get());
+ }
+
+ EXPECT_THAT(object, HasRefCounts(1, 1, 1));
+
+ {
+ TIntricateObjectPtr nonOwningPointer(&object, false);
+ EXPECT_THAT(object, HasRefCounts(1, 1, 1));
+ EXPECT_EQ(&object, nonOwningPointer.Get());
+ }
+
+ EXPECT_THAT(object, HasRefCounts(1, 2, 1));
+}
+
+TEST(TIntrusivePtrTest, ResetToNull)
+{
+ TIntricateObject object;
+ TIntricateObjectPtr ptr(&object);
+
+ EXPECT_THAT(object, HasRefCounts(1, 0, 0));
+ EXPECT_EQ(&object, ptr.Get());
+
+ ptr.Reset();
+
+ EXPECT_THAT(object, HasRefCounts(1, 1, 1));
+ EXPECT_EQ(nullptr, ptr.Get());
+}
+
+TEST(TIntrusivePtrTest, ResetToOtherObject)
+{
+ TIntricateObject firstObject;
+ TIntricateObject secondObject;
+
+ TIntricateObjectPtr ptr(&firstObject);
+
+ EXPECT_THAT(firstObject, HasRefCounts(1, 0, 0));
+ EXPECT_THAT(secondObject, HasRefCounts(0, 0, 0));
+ EXPECT_EQ(&firstObject, ptr.Get());
+
+ ptr.Reset(&secondObject);
+
+ EXPECT_THAT(firstObject, HasRefCounts(1, 1, 1));
+ EXPECT_THAT(secondObject, HasRefCounts(1, 0, 0));
+ EXPECT_EQ(&secondObject, ptr.Get());
+}
+
+TEST(TIntrusivePtrTest, CopySemantics)
+{
+ TIntricateObject object;
+
+ TIntricateObjectPtr foo(&object);
+ EXPECT_THAT(object, HasRefCounts(1, 0, 0));
+
+ {
+ TIntricateObjectPtr bar(foo);
+ EXPECT_THAT(object, HasRefCounts(2, 0, 0));
+ EXPECT_EQ(&object, foo.Get());
+ EXPECT_EQ(&object, bar.Get());
+ }
+
+ EXPECT_THAT(object, HasRefCounts(2, 1, 0));
+
+ {
+ TIntricateObjectPtr bar;
+ bar = foo;
+
+ EXPECT_THAT(object, HasRefCounts(3, 1, 0));
+ EXPECT_EQ(&object, foo.Get());
+ EXPECT_EQ(&object, bar.Get());
+ }
+
+ EXPECT_THAT(object, HasRefCounts(3, 2, 0));
+}
+
+TEST(TIntrusivePtrTest, MoveSemantics)
+{
+ TIntricateObject object;
+
+ TIntricateObjectPtr foo(&object);
+ EXPECT_THAT(object, HasRefCounts(1, 0, 0));
+
+ {
+ TIntricateObjectPtr bar(std::move(foo));
+ EXPECT_THAT(object, HasRefCounts(1, 0, 0));
+ EXPECT_THAT(foo.Get(), IsNull());
+ EXPECT_EQ(&object, bar.Get());
+ }
+
+ EXPECT_THAT(object, HasRefCounts(1, 1, 1));
+ foo.Reset(&object);
+ EXPECT_THAT(object, HasRefCounts(2, 1, 1));
+
+ {
+ TIntricateObjectPtr bar;
+ bar = std::move(foo);
+ EXPECT_THAT(object, HasRefCounts(2, 1, 1));
+ EXPECT_THAT(foo.Get(), IsNull());
+ EXPECT_EQ(&object, bar.Get());
+ }
+}
+
+TEST(TIntrusivePtrTest, Swap)
+{
+ TIntricateObject object;
+
+ TIntricateObjectPtr foo(&object);
+ TIntricateObjectPtr bar;
+
+ EXPECT_THAT(object, HasRefCounts(1, 0, 0));
+ EXPECT_THAT(foo.Get(), NotNull());
+ EXPECT_THAT(bar.Get(), IsNull());
+
+ foo.Swap(bar);
+
+ EXPECT_THAT(object, HasRefCounts(1, 0, 0));
+ EXPECT_THAT(foo.Get(), IsNull());
+ EXPECT_THAT(bar.Get(), NotNull());
+
+ foo.Swap(bar);
+
+ EXPECT_THAT(object, HasRefCounts(1, 0, 0));
+ EXPECT_THAT(foo.Get(), NotNull());
+ EXPECT_THAT(bar.Get(), IsNull());
+}
+
+TEST(TIntrusivePtrTest, UpCast)
+{
+ //! This is a simple typical reference-counted object.
+ class TSimpleObject
+ : public TRefCounted
+ { };
+
+ //! This is a simple inherited reference-counted object.
+ class TAnotherObject
+ : public TSimpleObject
+ { };
+
+ auto foo = New<TSimpleObject>();
+ auto bar = New<TAnotherObject>();
+ auto baz = New<TAnotherObject>();
+
+ foo = baz;
+
+ EXPECT_TRUE(foo == baz);
+}
+
+TEST(TIntrusivePtrTest, DownCast)
+{
+ class TBaseObject
+ : public TRefCounted
+ { };
+
+ class TDerivedObject
+ : public TBaseObject
+ { };
+
+ //! This is a simple inherited reference-counted object.
+ class TAnotherObject
+ : public TBaseObject
+ { };
+
+ TIntrusivePtr<TBaseObject> foo = New<TDerivedObject>();
+ TIntrusivePtr<TBaseObject> bar = New<TAnotherObject>();
+ {
+ auto baz = StaticPointerCast<TDerivedObject>(foo);
+ EXPECT_TRUE(foo == baz);
+ }
+ {
+ auto baz = StaticPointerCast<TDerivedObject>(TIntrusivePtr<TBaseObject>{foo});
+ EXPECT_TRUE(foo == baz);
+ }
+ {
+ auto baz = DynamicPointerCast<TDerivedObject>(foo);
+ EXPECT_TRUE(foo == baz);
+ }
+ {
+ auto baz = DynamicPointerCast<TDerivedObject>(bar);
+ EXPECT_TRUE(nullptr == baz);
+ }
+ {
+ auto baz = ConstPointerCast<const TBaseObject>(foo);
+ EXPECT_TRUE(foo.Get() == baz.Get());
+ }
+ {
+ auto baz = ConstPointerCast<const TBaseObject>(TIntrusivePtr<TBaseObject>{foo});
+ EXPECT_TRUE(foo.Get() == baz.Get());
+ }
+}
+
+TEST(TIntrusivePtrTest, UnspecifiedBoolType)
+{
+ TIntricateObject object;
+
+ TIntricateObjectPtr foo;
+ TIntricateObjectPtr bar(&object);
+
+ EXPECT_FALSE(foo);
+ EXPECT_TRUE(bar);
+}
+
+TEST(TIntrusivePtrTest, ObjectIsNotDestroyedPrematurely)
+{
+ TStringStream output;
+ New<TObjectWithSelfPointers>(&output);
+
+ // TObject... appends symbols to the output; see definitions.
+ EXPECT_STREQ("Cb!!!CaD", output.Str().c_str());
+}
+
+TEST(TIntrusivePtrTest, EqualityOperator)
+{
+ TIntricateObject object, anotherObject;
+
+ TIntricateObjectPtr emptyPointer;
+ TIntricateObjectPtr somePointer(&object);
+ TIntricateObjectPtr samePointer(&object);
+ TIntricateObjectPtr anotherPointer(&anotherObject);
+
+ EXPECT_FALSE(somePointer == emptyPointer);
+ EXPECT_FALSE(samePointer == emptyPointer);
+
+ EXPECT_TRUE(somePointer != emptyPointer);
+ EXPECT_TRUE(samePointer != emptyPointer);
+
+ EXPECT_TRUE(somePointer == samePointer);
+
+ EXPECT_TRUE(&object == somePointer);
+ EXPECT_TRUE(&object == samePointer);
+
+ EXPECT_FALSE(somePointer == anotherPointer);
+ EXPECT_TRUE(somePointer != anotherPointer);
+
+ EXPECT_TRUE(&anotherObject == anotherPointer);
+}
+
+TEST(TIntrusivePtrTest, Reset)
+{
+ TIntricateObject object;
+ TIntricateObjectPtr pointer(&object);
+ EXPECT_THAT(object, HasRefCounts(1, 0, 0));
+ EXPECT_EQ(&object, pointer.Release());
+ EXPECT_THAT(object, HasRefCounts(1, 0, 0));
+}
+
+TEST(TIntrusivePtrTest, CompareWithNullptr)
+{
+ TIntricateObjectPtr pointer1;
+ EXPECT_TRUE(nullptr == pointer1);
+ EXPECT_FALSE(nullptr != pointer1);
+ TIntricateObject object;
+ TIntricateObjectPtr pointer2(&object);
+ EXPECT_TRUE(pointer2 != nullptr);
+ EXPECT_FALSE(pointer2 == nullptr);
+}
+
+
+template <class T>
+void TestIntrusivePtrBehavior()
+{
+ typedef TIntrusivePtr<T> TMyPtr;
+
+ TStringStream output;
+ {
+ TMyPtr ptr(New<T>(&output));
+ {
+ TMyPtr anotherPtr(ptr);
+ anotherPtr->DoSomething();
+ }
+ {
+ TMyPtr anotherPtr(ptr);
+ anotherPtr->DoSomething();
+ }
+ ptr->DoSomething();
+ }
+
+ // TObject... appends symbols to the output; see definitions.
+ EXPECT_STREQ("C!!!D", output.Str().c_str());
+}
+
+TEST(TIntrusivePtrTest, SimpleRCBehaviour)
+{
+ TestIntrusivePtrBehavior<TObjectWithSimpleRC>();
+}
+
+TEST(TIntrusivePtrTest, FullRCBehaviour)
+{
+ TestIntrusivePtrBehavior<TObjectWithFullRC>();
+}
+
+TEST(TIntrusivePtrTest, ObjectAlignment)
+{
+ struct TObject
+ : public TRefCounted
+ {
+ alignas(64) ui64 Data;
+ };
+
+ struct TPODObject final
+ {
+ alignas(64) ui64 Data;
+ };
+
+ auto foo = New<TObject>();
+ auto bar = New<TPODObject>();
+
+ EXPECT_TRUE(reinterpret_cast<uintptr_t>(foo.Get()) % 64 == 0);
+ EXPECT_TRUE(reinterpret_cast<uintptr_t>(bar.Get()) % 64 == 0);
+}
+
TEST(TIntrusivePtrTest, InitStruct)
{
struct TObj1 final
@@ -556,7 +556,7 @@ TEST(TIntrusivePtrTest, InitStruct)
New<TObj6>(1, 2);
}
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace
-} // namespace NYT
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace
+} // namespace NYT
diff --git a/library/cpp/yt/memory/unittests/weak_ptr_ut.cpp b/library/cpp/yt/memory/unittests/weak_ptr_ut.cpp
index 2a420e8315..180c16b5ca 100644
--- a/library/cpp/yt/memory/unittests/weak_ptr_ut.cpp
+++ b/library/cpp/yt/memory/unittests/weak_ptr_ut.cpp
@@ -1,358 +1,358 @@
#include <library/cpp/testing/gtest/gtest.h>
-
-#include <library/cpp/yt/memory/new.h>
-#include <library/cpp/yt/memory/weak_ptr.h>
-
+
+#include <library/cpp/yt/memory/new.h>
+#include <library/cpp/yt/memory/weak_ptr.h>
+
#include <array>
-
-namespace NYT {
-namespace {
-
-using ::testing::IsNull;
-using ::testing::NotNull;
-using ::testing::InSequence;
-using ::testing::MockFunction;
-using ::testing::StrictMock;
-
-////////////////////////////////////////////////////////////////////////////////
-// Auxiliary types and functions.
-////////////////////////////////////////////////////////////////////////////////
-
-static int ConstructorShadowState = 0;
-static int DestructorShadowState = 0;
-
-void ResetShadowState()
-{
- ConstructorShadowState = 0;
- DestructorShadowState = 0;
-}
-
-class TIntricateObject
- : public TRefCounted
-{
-public:
- TIntricateObject()
- {
- ++ConstructorShadowState;
- }
-
- virtual ~TIntricateObject()
- {
- ++DestructorShadowState;
- }
-
- // Prevent the counter from destruction by holding an additional
- // reference to the counter.
- void LockCounter()
- {
- WeakRef();
- }
-
- // Release an additional reference to the reference counter acquired by
- // #LockCounter().
- void UnlockCounter()
- {
- WeakUnref();
- }
-
-private:
- // Explicitly non-copyable.
- TIntricateObject(const TIntricateObject&);
- TIntricateObject(TIntricateObject&&);
- TIntricateObject& operator=(const TIntricateObject&);
- TIntricateObject& operator=(TIntricateObject&&);
-};
-
-typedef TIntrusivePtr<TIntricateObject> TIntricateObjectPtr;
-typedef TWeakPtr<TIntricateObject> TIntricateObjectWkPtr;
-
-class TDerivedIntricateObject
- : public TIntricateObject
-{
-private:
- // Payload.
+
+namespace NYT {
+namespace {
+
+using ::testing::IsNull;
+using ::testing::NotNull;
+using ::testing::InSequence;
+using ::testing::MockFunction;
+using ::testing::StrictMock;
+
+////////////////////////////////////////////////////////////////////////////////
+// Auxiliary types and functions.
+////////////////////////////////////////////////////////////////////////////////
+
+static int ConstructorShadowState = 0;
+static int DestructorShadowState = 0;
+
+void ResetShadowState()
+{
+ ConstructorShadowState = 0;
+ DestructorShadowState = 0;
+}
+
+class TIntricateObject
+ : public TRefCounted
+{
+public:
+ TIntricateObject()
+ {
+ ++ConstructorShadowState;
+ }
+
+ virtual ~TIntricateObject()
+ {
+ ++DestructorShadowState;
+ }
+
+ // Prevent the counter from destruction by holding an additional
+ // reference to the counter.
+ void LockCounter()
+ {
+ WeakRef();
+ }
+
+ // Release an additional reference to the reference counter acquired by
+ // #LockCounter().
+ void UnlockCounter()
+ {
+ WeakUnref();
+ }
+
+private:
+ // Explicitly non-copyable.
+ TIntricateObject(const TIntricateObject&);
+ TIntricateObject(TIntricateObject&&);
+ TIntricateObject& operator=(const TIntricateObject&);
+ TIntricateObject& operator=(TIntricateObject&&);
+};
+
+typedef TIntrusivePtr<TIntricateObject> TIntricateObjectPtr;
+typedef TWeakPtr<TIntricateObject> TIntricateObjectWkPtr;
+
+class TDerivedIntricateObject
+ : public TIntricateObject
+{
+private:
+ // Payload.
[[maybe_unused]] std::array<char, 32> Payload;
-};
-
-typedef TIntrusivePtr<TDerivedIntricateObject> TDerivedIntricateObjectPtr;
-typedef TWeakPtr<TDerivedIntricateObject> TDerivedIntricateObjectWkPtr;
-
-MATCHER_P2(HasRefCounts, strongRefs, weakRefs,
- "The object has "
- + ::testing::PrintToString(strongRefs) + " strong and "
- + ::testing::PrintToString(weakRefs) + " weak references")
-{
- Y_UNUSED(result_listener);
- return
- arg.GetRefCount() == strongRefs &&
- arg.GetWeakRefCount() == weakRefs;
-}
-
-template <class T>
-void PrintExtrinsicRefCounted(const T& arg, ::std::ostream* os)
-{
+};
+
+typedef TIntrusivePtr<TDerivedIntricateObject> TDerivedIntricateObjectPtr;
+typedef TWeakPtr<TDerivedIntricateObject> TDerivedIntricateObjectWkPtr;
+
+MATCHER_P2(HasRefCounts, strongRefs, weakRefs,
+ "The object has "
+ + ::testing::PrintToString(strongRefs) + " strong and "
+ + ::testing::PrintToString(weakRefs) + " weak references")
+{
+ Y_UNUSED(result_listener);
+ return
+ arg.GetRefCount() == strongRefs &&
+ arg.GetWeakRefCount() == weakRefs;
+}
+
+template <class T>
+void PrintExtrinsicRefCounted(const T& arg, ::std::ostream* os)
+{
*os << arg.GetRefCount() << " strong and "
<< arg.GetWeakRefCount() << " weak references";
-}
-
-void PrintTo(const TIntricateObject& arg, ::std::ostream* os)
-{
- PrintExtrinsicRefCounted(arg, os);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-class TWeakPtrTest
- : public ::testing::Test
-{
-public:
- virtual void SetUp()
- {
- ResetShadowState();
- }
-};
-
-TEST_F(TWeakPtrTest, Empty)
-{
- TIntricateObjectWkPtr emptyPointer;
- EXPECT_EQ(TIntricateObjectPtr(), emptyPointer.Lock());
-}
-
-TEST_F(TWeakPtrTest, Basic)
-{
- TIntricateObjectPtr object = New<TIntricateObject>();
- TIntricateObject* objectPtr = object.Get();
-
- EXPECT_THAT(*object, HasRefCounts(1, 1));
-
- {
- TIntricateObjectWkPtr ptr(objectPtr);
- EXPECT_THAT(*object, HasRefCounts(1, 2));
- EXPECT_EQ(object, ptr.Lock());
- }
-
- EXPECT_THAT(*object, HasRefCounts(1, 1));
-
- {
- TIntricateObjectWkPtr ptr(object);
- EXPECT_THAT(*object, HasRefCounts(1, 2));
- EXPECT_EQ(object, ptr.Lock());
- }
-
- EXPECT_THAT(*object, HasRefCounts(1, 1));
-
- object.Reset();
-
- EXPECT_EQ(1, ConstructorShadowState);
- EXPECT_EQ(1, DestructorShadowState);
-}
-
-TEST_F(TWeakPtrTest, ResetToNull)
-{
- TIntricateObjectPtr object = New<TIntricateObject>();
- TIntricateObjectWkPtr ptr(object);
-
- EXPECT_THAT(*object, HasRefCounts(1, 2));
- EXPECT_EQ(object, ptr.Lock());
-
- ptr.Reset();
-
- EXPECT_THAT(*object, HasRefCounts(1, 1));
- EXPECT_EQ(TIntricateObjectPtr(), ptr.Lock());
-}
-
-TEST_F(TWeakPtrTest, ResetToOtherObject)
-{
- TIntricateObjectPtr firstObject = New<TIntricateObject>();
- TIntricateObjectPtr secondObject = New<TIntricateObject>();
-
- {
- TIntricateObjectWkPtr ptr(firstObject);
-
- EXPECT_THAT(*firstObject, HasRefCounts(1, 2));
- EXPECT_THAT(*secondObject, HasRefCounts(1, 1));
- EXPECT_EQ(firstObject, ptr.Lock());
-
- ptr.Reset(secondObject);
-
- EXPECT_THAT(*firstObject, HasRefCounts(1, 1));
- EXPECT_THAT(*secondObject, HasRefCounts(1, 2));
- EXPECT_EQ(secondObject, ptr.Lock());
- }
-
- TIntricateObject* firstObjectPtr = firstObject.Get();
- TIntricateObject* secondObjectPtr = secondObject.Get();
-
- {
- TIntricateObjectWkPtr ptr(firstObjectPtr);
-
- EXPECT_THAT(*firstObject, HasRefCounts(1, 2));
- EXPECT_THAT(*secondObject, HasRefCounts(1, 1));
- EXPECT_EQ(firstObject, ptr.Lock());
-
- ptr.Reset(secondObjectPtr);
-
- EXPECT_THAT(*firstObject, HasRefCounts(1, 1));
- EXPECT_THAT(*secondObject, HasRefCounts(1, 2));
- EXPECT_EQ(secondObject, ptr.Lock());
- }
-}
-
-TEST_F(TWeakPtrTest, CopySemantics)
-{
- TIntricateObjectPtr object = New<TIntricateObject>();
- TIntricateObjectWkPtr foo(object);
-
- {
- EXPECT_THAT(*object, HasRefCounts(1, 2));
- TIntricateObjectWkPtr bar(foo);
- EXPECT_THAT(*object, HasRefCounts(1, 3));
-
- EXPECT_EQ(object, foo.Lock());
- EXPECT_EQ(object, bar.Lock());
- }
-
- {
- EXPECT_THAT(*object, HasRefCounts(1, 2));
- TIntricateObjectWkPtr bar;
- bar = foo;
- EXPECT_THAT(*object, HasRefCounts(1, 3));
-
- EXPECT_EQ(object, foo.Lock());
- EXPECT_EQ(object, bar.Lock());
- }
-}
-
-TEST_F(TWeakPtrTest, MoveSemantics)
-{
- TIntricateObjectPtr object = New<TIntricateObject>();
- TIntricateObjectWkPtr foo(object);
-
- {
- EXPECT_THAT(*object, HasRefCounts(1, 2));
- TIntricateObjectWkPtr bar(std::move(foo));
- EXPECT_THAT(*object, HasRefCounts(1, 2));
-
- EXPECT_EQ(TIntricateObjectPtr(), foo.Lock());
- EXPECT_EQ(object, bar.Lock());
- }
-
- foo.Reset(object);
-
- {
- EXPECT_THAT(*object, HasRefCounts(1, 2));
- TIntricateObjectWkPtr bar;
- bar = std::move(foo);
- EXPECT_THAT(*object, HasRefCounts(1, 2));
-
- EXPECT_EQ(TIntricateObjectPtr(), foo.Lock());
- EXPECT_EQ(object, bar.Lock());
- }
-}
-
-TEST_F(TWeakPtrTest, OutOfScope)
-{
- TIntricateObjectWkPtr ptr;
-
- EXPECT_EQ(TIntricateObjectPtr(), ptr.Lock());
- {
- TIntricateObjectPtr object = New<TIntricateObject>();
- ptr = object;
- EXPECT_EQ(object, ptr.Lock());
- }
- EXPECT_EQ(TIntricateObjectPtr(), ptr.Lock());
-}
-
-TEST_F(TWeakPtrTest, OutOfNestedScope)
-{
- TIntricateObjectWkPtr foo;
-
- EXPECT_EQ(TIntricateObjectPtr(), foo.Lock());
- {
- TIntricateObjectPtr object = New<TIntricateObject>();
- foo = object;
-
- EXPECT_EQ(object, foo.Lock());
- {
- TIntricateObjectWkPtr bar;
- bar = object;
-
- EXPECT_EQ(object, bar.Lock());
- }
- EXPECT_EQ(object, foo.Lock());
- }
- EXPECT_EQ(TIntricateObjectPtr(), foo.Lock());
-
- EXPECT_EQ(1, ConstructorShadowState);
- EXPECT_EQ(1, DestructorShadowState);
-}
-
-TEST_F(TWeakPtrTest, IsExpired)
-{
- TIntricateObjectWkPtr ptr;
-
- EXPECT_TRUE(ptr.IsExpired());
- {
- TIntricateObjectPtr object = New<TIntricateObject>();
- ptr = object;
- EXPECT_FALSE(ptr.IsExpired());
- }
- EXPECT_TRUE(ptr.IsExpired());
-}
-
-TEST_F(TWeakPtrTest, UpCast)
-{
- TDerivedIntricateObjectPtr object = New<TDerivedIntricateObject>();
- TIntricateObjectWkPtr ptr = object;
-
- EXPECT_EQ(object.Get(), ptr.Lock().Get());
-}
-
-class TIntricateObjectVirtual
- : public virtual TRefCounted
-{
-public:
- TIntricateObjectVirtual()
- {
- ++ConstructorShadowState;
- }
-
- virtual ~TIntricateObjectVirtual()
- {
- ++DestructorShadowState;
- }
-
- // Prevent the counter from destruction by holding an additional
- // reference to the counter.
- void LockCounter()
- {
- WeakRef();
- }
-
- // Release an additional reference to the reference counter acquired by
- // #LockCounter().
- void UnlockCounter()
- {
- WeakUnref();
- }
-
-private:
- // Explicitly non-copyable.
- TIntricateObjectVirtual(const TIntricateObjectVirtual&);
- TIntricateObjectVirtual(TIntricateObjectVirtual&&);
- TIntricateObjectVirtual& operator=(const TIntricateObjectVirtual&);
- TIntricateObjectVirtual& operator=(TIntricateObjectVirtual&&);
-};
-
-TEST_F(TWeakPtrTest, VirtualBase)
-{
- auto object = New<TIntricateObjectVirtual>();
- TWeakPtr<TIntricateObjectVirtual> ptr = object;
-
- object.Reset();
- ptr.Reset();
-}
-
+}
+
+void PrintTo(const TIntricateObject& arg, ::std::ostream* os)
+{
+ PrintExtrinsicRefCounted(arg, os);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+class TWeakPtrTest
+ : public ::testing::Test
+{
+public:
+ virtual void SetUp()
+ {
+ ResetShadowState();
+ }
+};
+
+TEST_F(TWeakPtrTest, Empty)
+{
+ TIntricateObjectWkPtr emptyPointer;
+ EXPECT_EQ(TIntricateObjectPtr(), emptyPointer.Lock());
+}
+
+TEST_F(TWeakPtrTest, Basic)
+{
+ TIntricateObjectPtr object = New<TIntricateObject>();
+ TIntricateObject* objectPtr = object.Get();
+
+ EXPECT_THAT(*object, HasRefCounts(1, 1));
+
+ {
+ TIntricateObjectWkPtr ptr(objectPtr);
+ EXPECT_THAT(*object, HasRefCounts(1, 2));
+ EXPECT_EQ(object, ptr.Lock());
+ }
+
+ EXPECT_THAT(*object, HasRefCounts(1, 1));
+
+ {
+ TIntricateObjectWkPtr ptr(object);
+ EXPECT_THAT(*object, HasRefCounts(1, 2));
+ EXPECT_EQ(object, ptr.Lock());
+ }
+
+ EXPECT_THAT(*object, HasRefCounts(1, 1));
+
+ object.Reset();
+
+ EXPECT_EQ(1, ConstructorShadowState);
+ EXPECT_EQ(1, DestructorShadowState);
+}
+
+TEST_F(TWeakPtrTest, ResetToNull)
+{
+ TIntricateObjectPtr object = New<TIntricateObject>();
+ TIntricateObjectWkPtr ptr(object);
+
+ EXPECT_THAT(*object, HasRefCounts(1, 2));
+ EXPECT_EQ(object, ptr.Lock());
+
+ ptr.Reset();
+
+ EXPECT_THAT(*object, HasRefCounts(1, 1));
+ EXPECT_EQ(TIntricateObjectPtr(), ptr.Lock());
+}
+
+TEST_F(TWeakPtrTest, ResetToOtherObject)
+{
+ TIntricateObjectPtr firstObject = New<TIntricateObject>();
+ TIntricateObjectPtr secondObject = New<TIntricateObject>();
+
+ {
+ TIntricateObjectWkPtr ptr(firstObject);
+
+ EXPECT_THAT(*firstObject, HasRefCounts(1, 2));
+ EXPECT_THAT(*secondObject, HasRefCounts(1, 1));
+ EXPECT_EQ(firstObject, ptr.Lock());
+
+ ptr.Reset(secondObject);
+
+ EXPECT_THAT(*firstObject, HasRefCounts(1, 1));
+ EXPECT_THAT(*secondObject, HasRefCounts(1, 2));
+ EXPECT_EQ(secondObject, ptr.Lock());
+ }
+
+ TIntricateObject* firstObjectPtr = firstObject.Get();
+ TIntricateObject* secondObjectPtr = secondObject.Get();
+
+ {
+ TIntricateObjectWkPtr ptr(firstObjectPtr);
+
+ EXPECT_THAT(*firstObject, HasRefCounts(1, 2));
+ EXPECT_THAT(*secondObject, HasRefCounts(1, 1));
+ EXPECT_EQ(firstObject, ptr.Lock());
+
+ ptr.Reset(secondObjectPtr);
+
+ EXPECT_THAT(*firstObject, HasRefCounts(1, 1));
+ EXPECT_THAT(*secondObject, HasRefCounts(1, 2));
+ EXPECT_EQ(secondObject, ptr.Lock());
+ }
+}
+
+TEST_F(TWeakPtrTest, CopySemantics)
+{
+ TIntricateObjectPtr object = New<TIntricateObject>();
+ TIntricateObjectWkPtr foo(object);
+
+ {
+ EXPECT_THAT(*object, HasRefCounts(1, 2));
+ TIntricateObjectWkPtr bar(foo);
+ EXPECT_THAT(*object, HasRefCounts(1, 3));
+
+ EXPECT_EQ(object, foo.Lock());
+ EXPECT_EQ(object, bar.Lock());
+ }
+
+ {
+ EXPECT_THAT(*object, HasRefCounts(1, 2));
+ TIntricateObjectWkPtr bar;
+ bar = foo;
+ EXPECT_THAT(*object, HasRefCounts(1, 3));
+
+ EXPECT_EQ(object, foo.Lock());
+ EXPECT_EQ(object, bar.Lock());
+ }
+}
+
+TEST_F(TWeakPtrTest, MoveSemantics)
+{
+ TIntricateObjectPtr object = New<TIntricateObject>();
+ TIntricateObjectWkPtr foo(object);
+
+ {
+ EXPECT_THAT(*object, HasRefCounts(1, 2));
+ TIntricateObjectWkPtr bar(std::move(foo));
+ EXPECT_THAT(*object, HasRefCounts(1, 2));
+
+ EXPECT_EQ(TIntricateObjectPtr(), foo.Lock());
+ EXPECT_EQ(object, bar.Lock());
+ }
+
+ foo.Reset(object);
+
+ {
+ EXPECT_THAT(*object, HasRefCounts(1, 2));
+ TIntricateObjectWkPtr bar;
+ bar = std::move(foo);
+ EXPECT_THAT(*object, HasRefCounts(1, 2));
+
+ EXPECT_EQ(TIntricateObjectPtr(), foo.Lock());
+ EXPECT_EQ(object, bar.Lock());
+ }
+}
+
+TEST_F(TWeakPtrTest, OutOfScope)
+{
+ TIntricateObjectWkPtr ptr;
+
+ EXPECT_EQ(TIntricateObjectPtr(), ptr.Lock());
+ {
+ TIntricateObjectPtr object = New<TIntricateObject>();
+ ptr = object;
+ EXPECT_EQ(object, ptr.Lock());
+ }
+ EXPECT_EQ(TIntricateObjectPtr(), ptr.Lock());
+}
+
+TEST_F(TWeakPtrTest, OutOfNestedScope)
+{
+ TIntricateObjectWkPtr foo;
+
+ EXPECT_EQ(TIntricateObjectPtr(), foo.Lock());
+ {
+ TIntricateObjectPtr object = New<TIntricateObject>();
+ foo = object;
+
+ EXPECT_EQ(object, foo.Lock());
+ {
+ TIntricateObjectWkPtr bar;
+ bar = object;
+
+ EXPECT_EQ(object, bar.Lock());
+ }
+ EXPECT_EQ(object, foo.Lock());
+ }
+ EXPECT_EQ(TIntricateObjectPtr(), foo.Lock());
+
+ EXPECT_EQ(1, ConstructorShadowState);
+ EXPECT_EQ(1, DestructorShadowState);
+}
+
+TEST_F(TWeakPtrTest, IsExpired)
+{
+ TIntricateObjectWkPtr ptr;
+
+ EXPECT_TRUE(ptr.IsExpired());
+ {
+ TIntricateObjectPtr object = New<TIntricateObject>();
+ ptr = object;
+ EXPECT_FALSE(ptr.IsExpired());
+ }
+ EXPECT_TRUE(ptr.IsExpired());
+}
+
+TEST_F(TWeakPtrTest, UpCast)
+{
+ TDerivedIntricateObjectPtr object = New<TDerivedIntricateObject>();
+ TIntricateObjectWkPtr ptr = object;
+
+ EXPECT_EQ(object.Get(), ptr.Lock().Get());
+}
+
+class TIntricateObjectVirtual
+ : public virtual TRefCounted
+{
+public:
+ TIntricateObjectVirtual()
+ {
+ ++ConstructorShadowState;
+ }
+
+ virtual ~TIntricateObjectVirtual()
+ {
+ ++DestructorShadowState;
+ }
+
+ // Prevent the counter from destruction by holding an additional
+ // reference to the counter.
+ void LockCounter()
+ {
+ WeakRef();
+ }
+
+ // Release an additional reference to the reference counter acquired by
+ // #LockCounter().
+ void UnlockCounter()
+ {
+ WeakUnref();
+ }
+
+private:
+ // Explicitly non-copyable.
+ TIntricateObjectVirtual(const TIntricateObjectVirtual&);
+ TIntricateObjectVirtual(TIntricateObjectVirtual&&);
+ TIntricateObjectVirtual& operator=(const TIntricateObjectVirtual&);
+ TIntricateObjectVirtual& operator=(TIntricateObjectVirtual&&);
+};
+
+TEST_F(TWeakPtrTest, VirtualBase)
+{
+ auto object = New<TIntricateObjectVirtual>();
+ TWeakPtr<TIntricateObjectVirtual> ptr = object;
+
+ object.Reset();
+ ptr.Reset();
+}
+
#if 0
class TSlowlyDyingObject
: public TRefCounted
@@ -379,55 +379,55 @@ void PrintTo(const TSlowlyDyingObject& arg, ::std::ostream* os)
typedef TIntrusivePtr<TSlowlyDyingObject> TSlowlyDyingObjectPtr;
typedef TWeakPtr<TSlowlyDyingObject> TSlowlyDyingObjectWkPtr;
-static void* AsynchronousDeleter(void* param)
-{
- TSlowlyDyingObjectPtr* indirectObject =
- reinterpret_cast<TSlowlyDyingObjectPtr*>(param);
- indirectObject->Reset();
- return nullptr;
-}
-
-std::unique_ptr<NThreading::TEvent> DeathEvent;
-
-TEST_F(TWeakPtrTest, DISABLED_AcquisionOfSlowlyDyingObject)
-{
- DeathEvent.reset(new NThreading::TEvent());
-
- TSlowlyDyingObjectPtr object = New<TSlowlyDyingObject>();
- TSlowlyDyingObjectWkPtr ptr(object);
-
- TSlowlyDyingObject* objectPtr = object.Get();
-
- EXPECT_EQ(object, ptr.Lock());
- EXPECT_THAT(*objectPtr, HasRefCounts(1, 2));
-
- ASSERT_EQ(1, ConstructorShadowState);
- ASSERT_EQ(0, DestructorShadowState);
-
- // Kick off object deletion in the background.
- TThread thread(&AsynchronousDeleter, &object);
- thread.Start();
- Sleep(TDuration::Seconds(0.100));
-
- ASSERT_EQ(1, ConstructorShadowState);
- ASSERT_EQ(1, DestructorShadowState);
-
- EXPECT_EQ(TSlowlyDyingObjectPtr(), ptr.Lock());
- EXPECT_THAT(*objectPtr, HasRefCounts(0, 2));
-
- // Finalize object destruction.
- DeathEvent->NotifyAll();
- thread.Join();
-
- ASSERT_EQ(1, ConstructorShadowState);
- ASSERT_EQ(2, DestructorShadowState);
-
- EXPECT_EQ(TSlowlyDyingObjectPtr(), ptr.Lock());
-}
-
+static void* AsynchronousDeleter(void* param)
+{
+ TSlowlyDyingObjectPtr* indirectObject =
+ reinterpret_cast<TSlowlyDyingObjectPtr*>(param);
+ indirectObject->Reset();
+ return nullptr;
+}
+
+std::unique_ptr<NThreading::TEvent> DeathEvent;
+
+TEST_F(TWeakPtrTest, DISABLED_AcquisionOfSlowlyDyingObject)
+{
+ DeathEvent.reset(new NThreading::TEvent());
+
+ TSlowlyDyingObjectPtr object = New<TSlowlyDyingObject>();
+ TSlowlyDyingObjectWkPtr ptr(object);
+
+ TSlowlyDyingObject* objectPtr = object.Get();
+
+ EXPECT_EQ(object, ptr.Lock());
+ EXPECT_THAT(*objectPtr, HasRefCounts(1, 2));
+
+ ASSERT_EQ(1, ConstructorShadowState);
+ ASSERT_EQ(0, DestructorShadowState);
+
+ // Kick off object deletion in the background.
+ TThread thread(&AsynchronousDeleter, &object);
+ thread.Start();
+ Sleep(TDuration::Seconds(0.100));
+
+ ASSERT_EQ(1, ConstructorShadowState);
+ ASSERT_EQ(1, DestructorShadowState);
+
+ EXPECT_EQ(TSlowlyDyingObjectPtr(), ptr.Lock());
+ EXPECT_THAT(*objectPtr, HasRefCounts(0, 2));
+
+ // Finalize object destruction.
+ DeathEvent->NotifyAll();
+ thread.Join();
+
+ ASSERT_EQ(1, ConstructorShadowState);
+ ASSERT_EQ(2, DestructorShadowState);
+
+ EXPECT_EQ(TSlowlyDyingObjectPtr(), ptr.Lock());
+}
+
#endif
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace
-} // namespace NYT
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace
+} // namespace NYT
diff --git a/library/cpp/yt/memory/unittests/ya.make b/library/cpp/yt/memory/unittests/ya.make
index da95290172..f09ad7d0c9 100644
--- a/library/cpp/yt/memory/unittests/ya.make
+++ b/library/cpp/yt/memory/unittests/ya.make
@@ -13,7 +13,7 @@ SRCS(
PEERDIR(
library/cpp/testing/gtest
- library/cpp/yt/memory
+ library/cpp/yt/memory
)
END()
diff --git a/library/cpp/yt/memory/weak_ptr.h b/library/cpp/yt/memory/weak_ptr.h
index b8b7152933..25a242bb8a 100644
--- a/library/cpp/yt/memory/weak_ptr.h
+++ b/library/cpp/yt/memory/weak_ptr.h
@@ -2,8 +2,8 @@
#include "ref_counted.h"
-#include <util/generic/hash.h>
-
+#include <util/generic/hash.h>
+
namespace NYT {
////////////////////////////////////////////////////////////////////////////////
@@ -12,12 +12,12 @@ template <class T>
class TWeakPtr
{
public:
- typedef T TUnderlying;
+ typedef T TUnderlying;
//! Empty constructor.
- TWeakPtr() = default;
-
- TWeakPtr(std::nullptr_t)
+ TWeakPtr() = default;
+
+ TWeakPtr(std::nullptr_t)
{ }
//! Constructor from an unqualified reference.
@@ -25,7 +25,7 @@ public:
* Note that this constructor could be racy due to unsynchronized operations
* on the object and on the counter.
*/
- explicit TWeakPtr(T* p) noexcept
+ explicit TWeakPtr(T* p) noexcept
: T_(p)
{
@@ -110,7 +110,7 @@ public:
}
//! Copy assignment operator.
- TWeakPtr& operator=(const TWeakPtr& other) noexcept
+ TWeakPtr& operator=(const TWeakPtr& other) noexcept
{
TWeakPtr(other).Swap(*this);
return *this;
@@ -118,7 +118,7 @@ public:
//! Copy assignment operator with an upcast.
template <class U>
- TWeakPtr& operator=(const TWeakPtr<U>& other) noexcept
+ TWeakPtr& operator=(const TWeakPtr<U>& other) noexcept
{
static_assert(
std::is_convertible_v<U*, T*>,
@@ -136,7 +136,7 @@ public:
//! Move assignment operator with an upcast.
template <class U>
- TWeakPtr& operator=(TWeakPtr<U>&& other) noexcept
+ TWeakPtr& operator=(TWeakPtr<U>&& other) noexcept
{
static_assert(
std::is_convertible_v<U*, T*>,
@@ -177,7 +177,7 @@ public:
}
//! Acquire a strong reference to the pointee and return a strong pointer.
- TIntrusivePtr<T> Lock() const noexcept
+ TIntrusivePtr<T> Lock() const noexcept
{
return T_ && RefCounter()->TryRef()
? TIntrusivePtr<T>(T_, false)
@@ -209,10 +209,10 @@ private:
template <class U>
friend class TWeakPtr;
- template <class U>
+ template <class U>
friend struct ::THash;
- T* T_ = nullptr;
+ T* T_ = nullptr;
#if defined(_tsan_enabled_)
const TRefCounter* RefCounter_ = nullptr;
@@ -230,22 +230,22 @@ private:
////////////////////////////////////////////////////////////////////////////////
-//! Creates a weak pointer wrapper for a given raw pointer.
-//! Compared to |TWeakPtr<T>::ctor|, type inference enables omitting |T|.
+//! Creates a weak pointer wrapper for a given raw pointer.
+//! Compared to |TWeakPtr<T>::ctor|, type inference enables omitting |T|.
+template <class T>
+TWeakPtr<T> MakeWeak(T* p)
+{
+ return TWeakPtr<T>(p);
+}
+
+//! Creates a weak pointer wrapper for a given intrusive pointer.
+//! Compared to |TWeakPtr<T>::ctor|, type inference enables omitting |T|.
template <class T>
-TWeakPtr<T> MakeWeak(T* p)
-{
- return TWeakPtr<T>(p);
-}
-
-//! Creates a weak pointer wrapper for a given intrusive pointer.
-//! Compared to |TWeakPtr<T>::ctor|, type inference enables omitting |T|.
-template <class T>
-TWeakPtr<T> MakeWeak(const TIntrusivePtr<T>& p)
-{
- return TWeakPtr<T>(p);
-}
-
+TWeakPtr<T> MakeWeak(const TIntrusivePtr<T>& p)
+{
+ return TWeakPtr<T>(p);
+}
+
//! A helper for acquiring weak pointer for pointee, resetting intrusive pointer and then
//! returning the pointee reference count using the acquired weak pointer.
//! This helper is designed for best effort in checking that the object is not leaked after
@@ -265,10 +265,10 @@ int ResetAndGetResidualRefCount(TIntrusivePtr<T>& pointer)
}
}
-////////////////////////////////////////////////////////////////////////////////
-
+////////////////////////////////////////////////////////////////////////////////
+
// TODO(sandello): Kill comparsions.
-template <class T>
+template <class T>
bool operator<(const TWeakPtr<T>& lhs, const TWeakPtr<T>& rhs)
{
return lhs.Lock().Get() < rhs.Lock().Get();
@@ -301,14 +301,14 @@ bool operator!=(const TWeakPtr<T>& lhs, const TWeakPtr<U>& rhs)
////////////////////////////////////////////////////////////////////////////////
} // namespace NYT
-
-
-//! A hasher for TWeakPtr.
-template <class T>
+
+
+//! A hasher for TWeakPtr.
+template <class T>
struct THash<NYT::TWeakPtr<T>>
-{
- size_t operator () (const NYT::TWeakPtr<T>& ptr) const
- {
+{
+ size_t operator () (const NYT::TWeakPtr<T>& ptr) const
+ {
return THash<const NYT::TRefCountedBase*>()(ptr.T_);
- }
-};
+ }
+};
diff --git a/library/cpp/yt/memory/ya.make b/library/cpp/yt/memory/ya.make
index 07a2501fa1..a925c714ee 100644
--- a/library/cpp/yt/memory/ya.make
+++ b/library/cpp/yt/memory/ya.make
@@ -3,14 +3,14 @@ LIBRARY()
OWNER(g:yt)
SRCS(
- blob.cpp
- ref.cpp
+ blob.cpp
+ ref.cpp
ref_tracked.cpp
)
PEERDIR(
- library/cpp/yt/assert
- library/cpp/yt/misc
+ library/cpp/yt/assert
+ library/cpp/yt/misc
library/cpp/ytalloc/api
)
@@ -20,8 +20,8 @@ CHECK_DEPENDENT_DIRS(
contrib
library
util
- library/cpp/yt/assert
- library/cpp/yt/misc
+ library/cpp/yt/assert
+ library/cpp/yt/misc
)
END()
diff --git a/library/cpp/yt/misc/cast-inl.h b/library/cpp/yt/misc/cast-inl.h
index 78884df637..1920b7c0b7 100644
--- a/library/cpp/yt/misc/cast-inl.h
+++ b/library/cpp/yt/misc/cast-inl.h
@@ -4,9 +4,9 @@
#include "cast.h"
#endif
-#include <util/string/cast.h>
-#include <util/string/printf.h>
-
+#include <util/string/cast.h>
+#include <util/string/printf.h>
+
#include <type_traits>
namespace NYT {
@@ -39,29 +39,29 @@ typename std::enable_if<std::is_unsigned<T>::value && std::is_unsigned<S>::value
return value <= std::numeric_limits<T>::max();
}
-template <class T>
-TString FormatInvalidCastValue(T value)
-{
- return ::ToString(value);
-}
-
-inline TString FormatInvalidCastValue(signed char value)
-{
- return TString("'") + value + TString("'");
-}
-
-inline TString FormatInvalidCastValue(unsigned char value)
-{
- return TString("'") + value + TString("'");
-}
-
-#ifdef __cpp_char8_t
-inline TString FormatInvalidCastValue(char8_t value)
-{
- return FormatInvalidCastValue(static_cast<unsigned char>(value));
-}
-#endif
-
+template <class T>
+TString FormatInvalidCastValue(T value)
+{
+ return ::ToString(value);
+}
+
+inline TString FormatInvalidCastValue(signed char value)
+{
+ return TString("'") + value + TString("'");
+}
+
+inline TString FormatInvalidCastValue(unsigned char value)
+{
+ return TString("'") + value + TString("'");
+}
+
+#ifdef __cpp_char8_t
+inline TString FormatInvalidCastValue(char8_t value)
+{
+ return FormatInvalidCastValue(static_cast<unsigned char>(value));
+}
+#endif
+
} // namespace NDetail
template <class T, class S>
@@ -79,8 +79,8 @@ T CheckedIntegralCast(S value)
{
T result;
if (!TryIntegralCast<T>(value, &result)) {
- throw TSimpleException(Sprintf("Argument value %s is out of expected range",
- NDetail::FormatInvalidCastValue(value).c_str()));
+ throw TSimpleException(Sprintf("Argument value %s is out of expected range",
+ NDetail::FormatInvalidCastValue(value).c_str()));
}
return result;
}
@@ -101,9 +101,9 @@ T CheckedEnumCast(S value)
{
T result;
if (!TryEnumCast<T>(value, &result)) {
- throw TSimpleException(Sprintf("Invalid value %d of enum type %s",
- static_cast<int>(value),
- TEnumTraits<T>::GetTypeName().data()));
+ throw TSimpleException(Sprintf("Invalid value %d of enum type %s",
+ static_cast<int>(value),
+ TEnumTraits<T>::GetTypeName().data()));
}
return result;
}
diff --git a/library/cpp/yt/misc/cast.h b/library/cpp/yt/misc/cast.h
index 5adb3553e9..c7565c9e6d 100644
--- a/library/cpp/yt/misc/cast.h
+++ b/library/cpp/yt/misc/cast.h
@@ -1,7 +1,7 @@
#pragma once
-#include <library/cpp/yt/exception/exception.h>
-
+#include <library/cpp/yt/exception/exception.h>
+
namespace NYT {
////////////////////////////////////////////////////////////////////////////////
@@ -12,8 +12,8 @@ bool TryIntegralCast(S value, T* result);
template <class T, class S>
T CheckedIntegralCast(S value);
-////////////////////////////////////////////////////////////////////////////////
-
+////////////////////////////////////////////////////////////////////////////////
+
template <class T, class S>
bool TryEnumCast(S value, T* result);
diff --git a/library/cpp/yt/misc/enum-inl.h b/library/cpp/yt/misc/enum-inl.h
index 7666181aa2..59ef704775 100644
--- a/library/cpp/yt/misc/enum-inl.h
+++ b/library/cpp/yt/misc/enum-inl.h
@@ -1,41 +1,41 @@
-#pragma once
-#ifndef ENUM_INL_H_
-#error "Direct inclusion of this file is not allowed, include enum.h"
-// For the sake of sane code completion.
-#include "enum.h"
-#endif
-
-#include <util/string/printf.h>
-#include <util/string/cast.h>
-
+#pragma once
+#ifndef ENUM_INL_H_
+#error "Direct inclusion of this file is not allowed, include enum.h"
+// For the sake of sane code completion.
+#include "enum.h"
+#endif
+
+#include <util/string/printf.h>
+#include <util/string/cast.h>
+
#include <algorithm>
-#include <stdexcept>
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-#define ENUM__CLASS(name, underlyingType, seq) \
- enum class name : underlyingType \
- { \
- PP_FOR_EACH(ENUM__DOMAIN_ITEM, seq) \
- };
-
-#define ENUM__DOMAIN_ITEM(item) \
- PP_IF( \
- PP_IS_SEQUENCE(item), \
- ENUM__DOMAIN_ITEM_SEQ, \
- ENUM__DOMAIN_ITEM_ATOMIC \
- )(item)()
-
-#define ENUM__DOMAIN_ITEM_ATOMIC(item) \
- item PP_COMMA
-
-#define ENUM__DOMAIN_ITEM_SEQ(seq) \
- PP_ELEMENT(seq, 0) = PP_ELEMENT(seq, 1) PP_COMMA
-
-////////////////////////////////////////////////////////////////////////////////
-
+#include <stdexcept>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+#define ENUM__CLASS(name, underlyingType, seq) \
+ enum class name : underlyingType \
+ { \
+ PP_FOR_EACH(ENUM__DOMAIN_ITEM, seq) \
+ };
+
+#define ENUM__DOMAIN_ITEM(item) \
+ PP_IF( \
+ PP_IS_SEQUENCE(item), \
+ ENUM__DOMAIN_ITEM_SEQ, \
+ ENUM__DOMAIN_ITEM_ATOMIC \
+ )(item)()
+
+#define ENUM__DOMAIN_ITEM_ATOMIC(item) \
+ item PP_COMMA
+
+#define ENUM__DOMAIN_ITEM_SEQ(seq) \
+ PP_ELEMENT(seq, 0) = PP_ELEMENT(seq, 1) PP_COMMA
+
+////////////////////////////////////////////////////////////////////////////////
+
namespace NDetail {
template <typename TValues>
@@ -55,15 +55,15 @@ static constexpr bool AreValuesDistinct(const TValues& values)
////////////////////////////////////////////////////////////////////////////////
-#define ENUM__BEGIN_TRAITS(name, underlyingType, isBit, isStringSerializable, seq) \
- struct TEnumTraitsImpl_##name \
- { \
- using TType = name; \
- using TUnderlying = underlyingType; \
- [[maybe_unused]] static constexpr bool IsBitEnum = isBit; \
- [[maybe_unused]] static constexpr bool IsStringSerializableEnum = isStringSerializable; \
- [[maybe_unused]] static constexpr int DomainSize = PP_COUNT(seq); \
- \
+#define ENUM__BEGIN_TRAITS(name, underlyingType, isBit, isStringSerializable, seq) \
+ struct TEnumTraitsImpl_##name \
+ { \
+ using TType = name; \
+ using TUnderlying = underlyingType; \
+ [[maybe_unused]] static constexpr bool IsBitEnum = isBit; \
+ [[maybe_unused]] static constexpr bool IsStringSerializableEnum = isStringSerializable; \
+ [[maybe_unused]] static constexpr int DomainSize = PP_COUNT(seq); \
+ \
static constexpr std::array<TStringBuf, DomainSize> Names{{ \
PP_FOR_EACH(ENUM__GET_DOMAIN_NAMES_ITEM, seq) \
}}; \
@@ -71,95 +71,95 @@ static constexpr bool AreValuesDistinct(const TValues& values)
PP_FOR_EACH(ENUM__GET_DOMAIN_VALUES_ITEM, seq) \
}}; \
\
- static TStringBuf GetTypeName() \
- { \
+ static TStringBuf GetTypeName() \
+ { \
static constexpr TStringBuf typeName = PP_STRINGIZE(name); \
- return typeName; \
- } \
- \
- static const TStringBuf* FindLiteralByValue(TType value) \
- { \
+ return typeName; \
+ } \
+ \
+ static const TStringBuf* FindLiteralByValue(TType value) \
+ { \
for (int i = 0; i < DomainSize; ++i) { \
if (Values[i] == value) { \
return &Names[i]; \
} \
} \
- return nullptr; \
- } \
- \
- static bool FindValueByLiteral(TStringBuf literal, TType* result) \
- { \
+ return nullptr; \
+ } \
+ \
+ static bool FindValueByLiteral(TStringBuf literal, TType* result) \
+ { \
for (int i = 0; i < DomainSize; ++i) { \
if (Names[i] == literal) { \
*result = Values[i]; \
return true; \
} \
} \
- return false; \
- } \
- \
- static const std::array<TStringBuf, DomainSize>& GetDomainNames() \
- { \
+ return false; \
+ } \
+ \
+ static const std::array<TStringBuf, DomainSize>& GetDomainNames() \
+ { \
return Names; \
- } \
- \
- static const std::array<TType, DomainSize>& GetDomainValues() \
- { \
+ } \
+ \
+ static const std::array<TType, DomainSize>& GetDomainValues() \
+ { \
return Values; \
- } \
- \
- static TType FromString(TStringBuf str) \
- { \
- TType value; \
- if (!FindValueByLiteral(str, &value)) { \
- throw ::NYT::TSimpleException(Sprintf("Error parsing %s value %s", \
- PP_STRINGIZE(name), \
- TString(str).Quote().c_str()).c_str()); \
- } \
- return value; \
- }
-
-#define ENUM__GET_DOMAIN_VALUES_ITEM(item) \
- PP_IF( \
- PP_IS_SEQUENCE(item), \
- ENUM__GET_DOMAIN_VALUES_ITEM_SEQ, \
- ENUM__GET_DOMAIN_VALUES_ITEM_ATOMIC \
- )(item)
-
-#define ENUM__GET_DOMAIN_VALUES_ITEM_SEQ(seq) \
- ENUM__GET_DOMAIN_VALUES_ITEM_ATOMIC(PP_ELEMENT(seq, 0))
-
-#define ENUM__GET_DOMAIN_VALUES_ITEM_ATOMIC(item) \
- TType::item,
-
-#define ENUM__GET_DOMAIN_NAMES_ITEM(item) \
- PP_IF( \
- PP_IS_SEQUENCE(item), \
- ENUM__GET_DOMAIN_NAMES_ITEM_SEQ, \
- ENUM__GET_DOMAIN_NAMES_ITEM_ATOMIC \
- )(item)
-
-#define ENUM__GET_DOMAIN_NAMES_ITEM_SEQ(seq) \
- ENUM__GET_DOMAIN_NAMES_ITEM_ATOMIC(PP_ELEMENT(seq, 0))
-
-#define ENUM__GET_DOMAIN_NAMES_ITEM_ATOMIC(item) \
+ } \
+ \
+ static TType FromString(TStringBuf str) \
+ { \
+ TType value; \
+ if (!FindValueByLiteral(str, &value)) { \
+ throw ::NYT::TSimpleException(Sprintf("Error parsing %s value %s", \
+ PP_STRINGIZE(name), \
+ TString(str).Quote().c_str()).c_str()); \
+ } \
+ return value; \
+ }
+
+#define ENUM__GET_DOMAIN_VALUES_ITEM(item) \
+ PP_IF( \
+ PP_IS_SEQUENCE(item), \
+ ENUM__GET_DOMAIN_VALUES_ITEM_SEQ, \
+ ENUM__GET_DOMAIN_VALUES_ITEM_ATOMIC \
+ )(item)
+
+#define ENUM__GET_DOMAIN_VALUES_ITEM_SEQ(seq) \
+ ENUM__GET_DOMAIN_VALUES_ITEM_ATOMIC(PP_ELEMENT(seq, 0))
+
+#define ENUM__GET_DOMAIN_VALUES_ITEM_ATOMIC(item) \
+ TType::item,
+
+#define ENUM__GET_DOMAIN_NAMES_ITEM(item) \
+ PP_IF( \
+ PP_IS_SEQUENCE(item), \
+ ENUM__GET_DOMAIN_NAMES_ITEM_SEQ, \
+ ENUM__GET_DOMAIN_NAMES_ITEM_ATOMIC \
+ )(item)
+
+#define ENUM__GET_DOMAIN_NAMES_ITEM_SEQ(seq) \
+ ENUM__GET_DOMAIN_NAMES_ITEM_ATOMIC(PP_ELEMENT(seq, 0))
+
+#define ENUM__GET_DOMAIN_NAMES_ITEM_ATOMIC(item) \
TStringBuf(PP_STRINGIZE(item)),
-
+
#define ENUM__DECOMPOSE \
- static std::vector<TType> Decompose(TType value) \
- { \
- std::vector<TType> result; \
+ static std::vector<TType> Decompose(TType value) \
+ { \
+ std::vector<TType> result; \
for (int i = 0; i < DomainSize; ++i) { \
if (static_cast<TUnderlying>(value) & static_cast<TUnderlying>(Values[i])) { \
result.push_back(Values[i]); \
} \
} \
- return result; \
- }
-
+ return result; \
+ }
+
#define ENUM__MINMAX \
static constexpr TType GetMinValue() \
- { \
+ { \
static_assert(!Values.empty()); \
return *std::min_element(std::begin(Values), std::end(Values)); \
} \
@@ -174,212 +174,212 @@ static constexpr bool AreValuesDistinct(const TValues& values)
static_assert(::NYT::NDetail::AreValuesDistinct(Values), \
"Enumeration " #name " contains duplicate values");
-#define ENUM__END_TRAITS(name) \
- }; \
- \
+#define ENUM__END_TRAITS(name) \
+ }; \
+ \
[[maybe_unused]] inline TEnumTraitsImpl_##name GetEnumTraitsImpl(name) \
- { \
- return TEnumTraitsImpl_##name(); \
- } \
+ { \
+ return TEnumTraitsImpl_##name(); \
+ } \
\
- using ::ToString; \
+ using ::ToString; \
[[maybe_unused]] inline TString ToString(name value) \
- { \
- return ::NYT::TEnumTraits<name>::ToString(value); \
- }
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class T>
-std::vector<T> TEnumTraits<T, true>::Decompose(T value)
-{
- return TImpl::Decompose(value);
-}
-
-template <class T>
-T TEnumTraits<T, true>::FromString(TStringBuf str)
-{
- return TImpl::FromString(str);
-}
-
-template <class T>
-TString TEnumTraits<T, true>::ToString(TType value)
-{
- TString result;
- const auto* literal = FindLiteralByValue(value);
- if (literal) {
- result = *literal;
- } else {
- result = GetTypeName();
- result += "(";
- result += ::ToString(static_cast<TUnderlying>(value));
- result += ")";
- }
- return result;
-}
-
-template <class T>
-auto TEnumTraits<T, true>::GetDomainValues() -> const std::array<T, DomainSize>&
-{
- return TImpl::GetDomainValues();
-}
-
-template <class T>
-auto TEnumTraits<T, true>::GetDomainNames() -> const std::array<TStringBuf, DomainSize>&
-{
- return TImpl::GetDomainNames();
-}
-
-template <class T>
-constexpr T TEnumTraits<T, true>::GetMaxValue()
-{
- return TImpl::GetMaxValue();
-}
-
-template <class T>
-constexpr T TEnumTraits<T, true>::GetMinValue()
-{
- return TImpl::GetMinValue();
-}
-
-template <class T>
-bool TEnumTraits<T, true>::FindValueByLiteral(TStringBuf literal, TType* result)
-{
- return TImpl::FindValueByLiteral(literal, result);
-}
-
-template <class T>
-const TStringBuf* TEnumTraits<T, true>::FindLiteralByValue(TType value)
-{
- return TImpl::FindLiteralByValue(value);
-}
-
-template <class T>
-TStringBuf TEnumTraits<T, true>::GetTypeName()
-{
- return TImpl::GetTypeName();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class E, class T, E Min, E Max>
-TEnumIndexedVector<E, T, Min, Max>::TEnumIndexedVector()
- : Items_{}
-{ }
-
-template <class E, class T, E Min, E Max>
-TEnumIndexedVector<E, T, Min, Max>::TEnumIndexedVector(std::initializer_list<T> elements)
- : Items_{}
-{
- Y_ASSERT(std::distance(elements.begin(), elements.end()) <= N);
- size_t index = 0;
- for (const auto& element : elements) {
- Items_[index++] = element;
- }
-}
-
-template <class E, class T, E Min, E Max>
-T& TEnumIndexedVector<E, T, Min, Max>::operator[] (E index)
-{
- Y_ASSERT(index >= Min && index <= Max);
- return Items_[static_cast<TUnderlying>(index) - static_cast<TUnderlying>(Min)];
-}
-
-template <class E, class T, E Min, E Max>
-const T& TEnumIndexedVector<E, T, Min, Max>::operator[] (E index) const
-{
- return const_cast<TEnumIndexedVector&>(*this)[index];
-}
-
-template <class E, class T, E Min, E Max>
-T* TEnumIndexedVector<E, T, Min, Max>::begin()
-{
- return Items_.data();
-}
-
-template <class E, class T, E Min, E Max>
-const T* TEnumIndexedVector<E, T, Min, Max>::begin() const
-{
- return Items_.data();
-}
-
-template <class E, class T, E Min, E Max>
-T* TEnumIndexedVector<E, T, Min, Max>::end()
-{
- return begin() + N;
-}
-
-template <class E, class T, E Min, E Max>
-const T* TEnumIndexedVector<E, T, Min, Max>::end() const
-{
- return begin() + N;
-}
-
-template <class E, class T, E Min, E Max>
-bool TEnumIndexedVector<E, T, Min, Max>::IsDomainValue(E value)
-{
- return value >= Min && value <= Max;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-#define ENUM__BINARY_BITWISE_OPERATOR(T, assignOp, op) \
+ { \
+ return ::NYT::TEnumTraits<name>::ToString(value); \
+ }
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T>
+std::vector<T> TEnumTraits<T, true>::Decompose(T value)
+{
+ return TImpl::Decompose(value);
+}
+
+template <class T>
+T TEnumTraits<T, true>::FromString(TStringBuf str)
+{
+ return TImpl::FromString(str);
+}
+
+template <class T>
+TString TEnumTraits<T, true>::ToString(TType value)
+{
+ TString result;
+ const auto* literal = FindLiteralByValue(value);
+ if (literal) {
+ result = *literal;
+ } else {
+ result = GetTypeName();
+ result += "(";
+ result += ::ToString(static_cast<TUnderlying>(value));
+ result += ")";
+ }
+ return result;
+}
+
+template <class T>
+auto TEnumTraits<T, true>::GetDomainValues() -> const std::array<T, DomainSize>&
+{
+ return TImpl::GetDomainValues();
+}
+
+template <class T>
+auto TEnumTraits<T, true>::GetDomainNames() -> const std::array<TStringBuf, DomainSize>&
+{
+ return TImpl::GetDomainNames();
+}
+
+template <class T>
+constexpr T TEnumTraits<T, true>::GetMaxValue()
+{
+ return TImpl::GetMaxValue();
+}
+
+template <class T>
+constexpr T TEnumTraits<T, true>::GetMinValue()
+{
+ return TImpl::GetMinValue();
+}
+
+template <class T>
+bool TEnumTraits<T, true>::FindValueByLiteral(TStringBuf literal, TType* result)
+{
+ return TImpl::FindValueByLiteral(literal, result);
+}
+
+template <class T>
+const TStringBuf* TEnumTraits<T, true>::FindLiteralByValue(TType value)
+{
+ return TImpl::FindLiteralByValue(value);
+}
+
+template <class T>
+TStringBuf TEnumTraits<T, true>::GetTypeName()
+{
+ return TImpl::GetTypeName();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class E, class T, E Min, E Max>
+TEnumIndexedVector<E, T, Min, Max>::TEnumIndexedVector()
+ : Items_{}
+{ }
+
+template <class E, class T, E Min, E Max>
+TEnumIndexedVector<E, T, Min, Max>::TEnumIndexedVector(std::initializer_list<T> elements)
+ : Items_{}
+{
+ Y_ASSERT(std::distance(elements.begin(), elements.end()) <= N);
+ size_t index = 0;
+ for (const auto& element : elements) {
+ Items_[index++] = element;
+ }
+}
+
+template <class E, class T, E Min, E Max>
+T& TEnumIndexedVector<E, T, Min, Max>::operator[] (E index)
+{
+ Y_ASSERT(index >= Min && index <= Max);
+ return Items_[static_cast<TUnderlying>(index) - static_cast<TUnderlying>(Min)];
+}
+
+template <class E, class T, E Min, E Max>
+const T& TEnumIndexedVector<E, T, Min, Max>::operator[] (E index) const
+{
+ return const_cast<TEnumIndexedVector&>(*this)[index];
+}
+
+template <class E, class T, E Min, E Max>
+T* TEnumIndexedVector<E, T, Min, Max>::begin()
+{
+ return Items_.data();
+}
+
+template <class E, class T, E Min, E Max>
+const T* TEnumIndexedVector<E, T, Min, Max>::begin() const
+{
+ return Items_.data();
+}
+
+template <class E, class T, E Min, E Max>
+T* TEnumIndexedVector<E, T, Min, Max>::end()
+{
+ return begin() + N;
+}
+
+template <class E, class T, E Min, E Max>
+const T* TEnumIndexedVector<E, T, Min, Max>::end() const
+{
+ return begin() + N;
+}
+
+template <class E, class T, E Min, E Max>
+bool TEnumIndexedVector<E, T, Min, Max>::IsDomainValue(E value)
+{
+ return value >= Min && value <= Max;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#define ENUM__BINARY_BITWISE_OPERATOR(T, assignOp, op) \
[[maybe_unused]] inline constexpr T operator op (T lhs, T rhs) \
- { \
- using TUnderlying = typename TEnumTraits<T>::TUnderlying; \
- return T(static_cast<TUnderlying>(lhs) op static_cast<TUnderlying>(rhs)); \
- } \
- \
+ { \
+ using TUnderlying = typename TEnumTraits<T>::TUnderlying; \
+ return T(static_cast<TUnderlying>(lhs) op static_cast<TUnderlying>(rhs)); \
+ } \
+ \
[[maybe_unused]] inline T& operator assignOp (T& lhs, T rhs) \
- { \
- using TUnderlying = typename TEnumTraits<T>::TUnderlying; \
- lhs = T(static_cast<TUnderlying>(lhs) op static_cast<TUnderlying>(rhs)); \
- return lhs; \
- }
-
-#define ENUM__UNARY_BITWISE_OPERATOR(T, op) \
+ { \
+ using TUnderlying = typename TEnumTraits<T>::TUnderlying; \
+ lhs = T(static_cast<TUnderlying>(lhs) op static_cast<TUnderlying>(rhs)); \
+ return lhs; \
+ }
+
+#define ENUM__UNARY_BITWISE_OPERATOR(T, op) \
[[maybe_unused]] inline constexpr T operator op (T value) \
- { \
- using TUnderlying = typename TEnumTraits<T>::TUnderlying; \
- return T(op static_cast<TUnderlying>(value)); \
- }
-
-#define ENUM__BIT_SHIFT_OPERATOR(T, assignOp, op) \
+ { \
+ using TUnderlying = typename TEnumTraits<T>::TUnderlying; \
+ return T(op static_cast<TUnderlying>(value)); \
+ }
+
+#define ENUM__BIT_SHIFT_OPERATOR(T, assignOp, op) \
[[maybe_unused]] inline constexpr T operator op (T lhs, size_t rhs) \
- { \
- using TUnderlying = typename TEnumTraits<T>::TUnderlying; \
- return T(static_cast<TUnderlying>(lhs) op rhs); \
- } \
- \
+ { \
+ using TUnderlying = typename TEnumTraits<T>::TUnderlying; \
+ return T(static_cast<TUnderlying>(lhs) op rhs); \
+ } \
+ \
[[maybe_unused]] inline T& operator assignOp (T& lhs, size_t rhs) \
- { \
- using TUnderlying = typename TEnumTraits<T>::TUnderlying; \
- lhs = T(static_cast<TUnderlying>(lhs) op rhs); \
- return lhs; \
- }
-
-#define ENUM__BITWISE_OPS(name) \
- ENUM__BINARY_BITWISE_OPERATOR(name, &=, &) \
- ENUM__BINARY_BITWISE_OPERATOR(name, |=, | ) \
- ENUM__BINARY_BITWISE_OPERATOR(name, ^=, ^) \
- ENUM__UNARY_BITWISE_OPERATOR(name, ~) \
- ENUM__BIT_SHIFT_OPERATOR(name, <<=, << ) \
- ENUM__BIT_SHIFT_OPERATOR(name, >>=, >> )
-
-////////////////////////////////////////////////////////////////////////////////
-
+ { \
+ using TUnderlying = typename TEnumTraits<T>::TUnderlying; \
+ lhs = T(static_cast<TUnderlying>(lhs) op rhs); \
+ return lhs; \
+ }
+
+#define ENUM__BITWISE_OPS(name) \
+ ENUM__BINARY_BITWISE_OPERATOR(name, &=, &) \
+ ENUM__BINARY_BITWISE_OPERATOR(name, |=, | ) \
+ ENUM__BINARY_BITWISE_OPERATOR(name, ^=, ^) \
+ ENUM__UNARY_BITWISE_OPERATOR(name, ~) \
+ ENUM__BIT_SHIFT_OPERATOR(name, <<=, << ) \
+ ENUM__BIT_SHIFT_OPERATOR(name, >>=, >> )
+
+////////////////////////////////////////////////////////////////////////////////
+
template <typename E, typename>
bool Any(E value)
-{
- return static_cast<typename TEnumTraits<E>::TUnderlying>(value) != 0;
-}
-
+{
+ return static_cast<typename TEnumTraits<E>::TUnderlying>(value) != 0;
+}
+
template <class E, typename>
bool None(E value)
-{
- return static_cast<typename TEnumTraits<E>::TUnderlying>(value) == 0;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
+{
+ return static_cast<typename TEnumTraits<E>::TUnderlying>(value) == 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/misc/enum.h b/library/cpp/yt/misc/enum.h
index b30d20dbe0..894364aa43 100644
--- a/library/cpp/yt/misc/enum.h
+++ b/library/cpp/yt/misc/enum.h
@@ -1,113 +1,113 @@
-#pragma once
-
-#include "preprocessor.h"
-
-#include <util/generic/strbuf.h>
-
-#include <stdexcept>
-#include <type_traits>
-#include <array>
-#include <vector>
-
-#include <library/cpp/yt/exception/exception.h>
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-/*
- * Smart enumerations augment C++ enum classes with a bunch of reflection
- * capabilities accessible via TEnumTraits class specialization.
- *
- * Please refer to the unit test for an actual example of usage
- * (unittests/enum_ut.cpp).
- */
-
+#pragma once
+
+#include "preprocessor.h"
+
+#include <util/generic/strbuf.h>
+
+#include <stdexcept>
+#include <type_traits>
+#include <array>
+#include <vector>
+
+#include <library/cpp/yt/exception/exception.h>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+/*
+ * Smart enumerations augment C++ enum classes with a bunch of reflection
+ * capabilities accessible via TEnumTraits class specialization.
+ *
+ * Please refer to the unit test for an actual example of usage
+ * (unittests/enum_ut.cpp).
+ */
+
// Actual overload must be provided with defines DEFINE_ENUM_XXX (see below).
template <class T>
void GetEnumTraitsImpl(T);
-template <
- class T,
+template <
+ class T,
bool = std::is_enum<T>::value &&
!std::is_convertible<T, int>::value &&
!std::is_same<void, decltype(GetEnumTraitsImpl(T()))>::value
->
-struct TEnumTraits
-{
- static constexpr bool IsEnum = false;
- static constexpr bool IsBitEnum = false;
- static constexpr bool IsStringSerializableEnum = false;
-};
-
-template <class T>
-struct TEnumTraits<T, true>
-{
- using TImpl = decltype(GetEnumTraitsImpl(T()));
- using TType = T;
- using TUnderlying = typename TImpl::TUnderlying;
-
- static constexpr bool IsEnum = true;
- static constexpr bool IsBitEnum = TImpl::IsBitEnum;
- static constexpr bool IsStringSerializableEnum = TImpl::IsStringSerializableEnum;
-
- static constexpr int DomainSize = TImpl::DomainSize;
-
- static TStringBuf GetTypeName();
-
- static const TStringBuf* FindLiteralByValue(TType value);
- static bool FindValueByLiteral(TStringBuf literal, TType* result);
-
- static const std::array<TStringBuf, DomainSize>& GetDomainNames();
- static const std::array<TType, DomainSize>& GetDomainValues();
-
- static TType FromString(TStringBuf str);
- static TString ToString(TType value);
-
- // For non-bit enums only.
- static constexpr TType GetMinValue();
- static constexpr TType GetMaxValue();
-
- // For bit enums only.
- static std::vector<TType> Decompose(TType value);
-
- // LLVM SmallDenseMap interop.
- // This should only be used for enums whose underlying type has big enough range
- // (see getEmptyKey and getTombstoneKey functions).
- struct TDenseMapInfo
- {
- static inline TType getEmptyKey()
- {
- return static_cast<TType>(-1);
- }
-
- static inline TType getTombstoneKey()
- {
- return static_cast<TType>(-2);
- }
-
- static unsigned getHashValue(const TType& key)
- {
- return static_cast<unsigned>(key) * 37U;
- }
-
- static bool isEqual(const TType& lhs, const TType& rhs)
- {
- return lhs == rhs;
- }
- };
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-//! Defines a smart enumeration with a specific underlying type.
-/*!
- * \param name Enumeration name.
- * \param seq Enumeration domain encoded as a <em>sequence</em>.
- * \param underlyingType Underlying type.
- */
-#define DEFINE_ENUM_WITH_UNDERLYING_TYPE(name, underlyingType, seq) \
- ENUM__CLASS(name, underlyingType, seq) \
- ENUM__BEGIN_TRAITS(name, underlyingType, false, false, seq) \
+>
+struct TEnumTraits
+{
+ static constexpr bool IsEnum = false;
+ static constexpr bool IsBitEnum = false;
+ static constexpr bool IsStringSerializableEnum = false;
+};
+
+template <class T>
+struct TEnumTraits<T, true>
+{
+ using TImpl = decltype(GetEnumTraitsImpl(T()));
+ using TType = T;
+ using TUnderlying = typename TImpl::TUnderlying;
+
+ static constexpr bool IsEnum = true;
+ static constexpr bool IsBitEnum = TImpl::IsBitEnum;
+ static constexpr bool IsStringSerializableEnum = TImpl::IsStringSerializableEnum;
+
+ static constexpr int DomainSize = TImpl::DomainSize;
+
+ static TStringBuf GetTypeName();
+
+ static const TStringBuf* FindLiteralByValue(TType value);
+ static bool FindValueByLiteral(TStringBuf literal, TType* result);
+
+ static const std::array<TStringBuf, DomainSize>& GetDomainNames();
+ static const std::array<TType, DomainSize>& GetDomainValues();
+
+ static TType FromString(TStringBuf str);
+ static TString ToString(TType value);
+
+ // For non-bit enums only.
+ static constexpr TType GetMinValue();
+ static constexpr TType GetMaxValue();
+
+ // For bit enums only.
+ static std::vector<TType> Decompose(TType value);
+
+ // LLVM SmallDenseMap interop.
+ // This should only be used for enums whose underlying type has big enough range
+ // (see getEmptyKey and getTombstoneKey functions).
+ struct TDenseMapInfo
+ {
+ static inline TType getEmptyKey()
+ {
+ return static_cast<TType>(-1);
+ }
+
+ static inline TType getTombstoneKey()
+ {
+ return static_cast<TType>(-2);
+ }
+
+ static unsigned getHashValue(const TType& key)
+ {
+ return static_cast<unsigned>(key) * 37U;
+ }
+
+ static bool isEqual(const TType& lhs, const TType& rhs)
+ {
+ return lhs == rhs;
+ }
+ };
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+//! Defines a smart enumeration with a specific underlying type.
+/*!
+ * \param name Enumeration name.
+ * \param seq Enumeration domain encoded as a <em>sequence</em>.
+ * \param underlyingType Underlying type.
+ */
+#define DEFINE_ENUM_WITH_UNDERLYING_TYPE(name, underlyingType, seq) \
+ ENUM__CLASS(name, underlyingType, seq) \
+ ENUM__BEGIN_TRAITS(name, underlyingType, false, false, seq) \
ENUM__MINMAX \
ENUM__VALIDATE_UNIQUE(name) \
ENUM__END_TRAITS(name)
@@ -118,26 +118,26 @@ struct TEnumTraits<T, true>
ENUM__CLASS(name, underlyingType, seq) \
ENUM__BEGIN_TRAITS(name, underlyingType, false, false, seq) \
ENUM__MINMAX \
- ENUM__END_TRAITS(name)
-
-//! Defines a smart enumeration with the default |int| underlying type.
-#define DEFINE_ENUM(name, seq) \
- DEFINE_ENUM_WITH_UNDERLYING_TYPE(name, int, seq)
-
-//! Defines a smart enumeration with a specific underlying type.
-/*!
- * \param name Enumeration name.
- * \param seq Enumeration domain encoded as a <em>sequence</em>.
- * \param underlyingType Underlying type.
- */
-#define DEFINE_BIT_ENUM_WITH_UNDERLYING_TYPE(name, underlyingType, seq) \
- ENUM__CLASS(name, underlyingType, seq) \
- ENUM__BEGIN_TRAITS(name, underlyingType, true, false, seq) \
+ ENUM__END_TRAITS(name)
+
+//! Defines a smart enumeration with the default |int| underlying type.
+#define DEFINE_ENUM(name, seq) \
+ DEFINE_ENUM_WITH_UNDERLYING_TYPE(name, int, seq)
+
+//! Defines a smart enumeration with a specific underlying type.
+/*!
+ * \param name Enumeration name.
+ * \param seq Enumeration domain encoded as a <em>sequence</em>.
+ * \param underlyingType Underlying type.
+ */
+#define DEFINE_BIT_ENUM_WITH_UNDERLYING_TYPE(name, underlyingType, seq) \
+ ENUM__CLASS(name, underlyingType, seq) \
+ ENUM__BEGIN_TRAITS(name, underlyingType, true, false, seq) \
ENUM__DECOMPOSE \
ENUM__VALIDATE_UNIQUE(name) \
- ENUM__END_TRAITS(name) \
- ENUM__BITWISE_OPS(name)
-
+ ENUM__END_TRAITS(name) \
+ ENUM__BITWISE_OPS(name)
+
//! Defines a smart enumeration with a specific underlying type.
//! Duplicate enumeration values are allowed.
/*!
@@ -152,23 +152,23 @@ struct TEnumTraits<T, true>
ENUM__END_TRAITS(name) \
ENUM__BITWISE_OPS(name)
-//! Defines a smart enumeration with the default |unsigned| underlying type.
-/*!
- * \param name Enumeration name.
- * \param seq Enumeration domain encoded as a <em>sequence</em>.
- */
-#define DEFINE_BIT_ENUM(name, seq) \
- DEFINE_BIT_ENUM_WITH_UNDERLYING_TYPE(name, unsigned, seq)
-
-//! Defines a smart enumeration with a specific underlying type and IsStringSerializable attribute.
-/*!
- * \param name Enumeration name.
- * \param seq Enumeration domain encoded as a <em>sequence</em>.
- * \param underlyingType Underlying type.
- */
-#define DEFINE_STRING_SERIALIZABLE_ENUM_WITH_UNDERLYING_TYPE(name, underlyingType, seq) \
- ENUM__CLASS(name, underlyingType, seq) \
- ENUM__BEGIN_TRAITS(name, underlyingType, false, true, seq) \
+//! Defines a smart enumeration with the default |unsigned| underlying type.
+/*!
+ * \param name Enumeration name.
+ * \param seq Enumeration domain encoded as a <em>sequence</em>.
+ */
+#define DEFINE_BIT_ENUM(name, seq) \
+ DEFINE_BIT_ENUM_WITH_UNDERLYING_TYPE(name, unsigned, seq)
+
+//! Defines a smart enumeration with a specific underlying type and IsStringSerializable attribute.
+/*!
+ * \param name Enumeration name.
+ * \param seq Enumeration domain encoded as a <em>sequence</em>.
+ * \param underlyingType Underlying type.
+ */
+#define DEFINE_STRING_SERIALIZABLE_ENUM_WITH_UNDERLYING_TYPE(name, underlyingType, seq) \
+ ENUM__CLASS(name, underlyingType, seq) \
+ ENUM__BEGIN_TRAITS(name, underlyingType, false, true, seq) \
ENUM__MINMAX \
ENUM__VALIDATE_UNIQUE(name) \
ENUM__END_TRAITS(name) \
@@ -179,65 +179,65 @@ struct TEnumTraits<T, true>
ENUM__CLASS(name, underlyingType, seq) \
ENUM__BEGIN_TRAITS(name, underlyingType, false, true, seq) \
ENUM__MINMAX \
- ENUM__END_TRAITS(name)
-
-//! Defines a smart enumeration with the default |int| underlying type and IsStringSerializable attribute.
-#define DEFINE_STRING_SERIALIZABLE_ENUM(name, seq) \
- DEFINE_STRING_SERIALIZABLE_ENUM_WITH_UNDERLYING_TYPE(name, int, seq)
-
-////////////////////////////////////////////////////////////////////////////////
-
-//! A statically sized vector with elements of type |T| indexed by
-//! the items of enumeration type |E|.
-/*!
- * Items are value-initialized on construction.
- */
-template <
- class E,
- class T,
- E Min = TEnumTraits<E>::GetMinValue(),
- E Max = TEnumTraits<E>::GetMaxValue()
->
-class TEnumIndexedVector
-{
-public:
- using TIndex = E;
- using TValue = T;
-
- TEnumIndexedVector();
- TEnumIndexedVector(std::initializer_list<T> elements);
-
- T& operator[] (E index);
- const T& operator[] (E index) const;
-
- // STL interop.
- T* begin();
- const T* begin() const;
- T* end();
- const T* end() const;
-
- static bool IsDomainValue(E value);
-
-private:
- using TUnderlying = typename TEnumTraits<E>::TUnderlying;
- static constexpr int N = static_cast<TUnderlying>(Max) - static_cast<TUnderlying>(Min) + 1;
- std::array<T, N> Items_;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-//! Returns |true| iff the enumeration value is not bitwise zero.
+ ENUM__END_TRAITS(name)
+
+//! Defines a smart enumeration with the default |int| underlying type and IsStringSerializable attribute.
+#define DEFINE_STRING_SERIALIZABLE_ENUM(name, seq) \
+ DEFINE_STRING_SERIALIZABLE_ENUM_WITH_UNDERLYING_TYPE(name, int, seq)
+
+////////////////////////////////////////////////////////////////////////////////
+
+//! A statically sized vector with elements of type |T| indexed by
+//! the items of enumeration type |E|.
+/*!
+ * Items are value-initialized on construction.
+ */
+template <
+ class E,
+ class T,
+ E Min = TEnumTraits<E>::GetMinValue(),
+ E Max = TEnumTraits<E>::GetMaxValue()
+>
+class TEnumIndexedVector
+{
+public:
+ using TIndex = E;
+ using TValue = T;
+
+ TEnumIndexedVector();
+ TEnumIndexedVector(std::initializer_list<T> elements);
+
+ T& operator[] (E index);
+ const T& operator[] (E index) const;
+
+ // STL interop.
+ T* begin();
+ const T* begin() const;
+ T* end();
+ const T* end() const;
+
+ static bool IsDomainValue(E value);
+
+private:
+ using TUnderlying = typename TEnumTraits<E>::TUnderlying;
+ static constexpr int N = static_cast<TUnderlying>(Max) - static_cast<TUnderlying>(Min) + 1;
+ std::array<T, N> Items_;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+//! Returns |true| iff the enumeration value is not bitwise zero.
template <typename E, typename = std::enable_if_t<NYT::TEnumTraits<E>::IsBitEnum, E>>
bool Any(E value);
-
-//! Returns |true| iff the enumeration value is bitwise zero.
+
+//! Returns |true| iff the enumeration value is bitwise zero.
template <typename E, typename = std::enable_if_t<NYT::TEnumTraits<E>::IsBitEnum, E>>
bool None(E value);
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
-
-#define ENUM_INL_H_
-#include "enum-inl.h"
-#undef ENUM_INL_H_
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
+
+#define ENUM_INL_H_
+#include "enum-inl.h"
+#undef ENUM_INL_H_
diff --git a/library/cpp/yt/misc/guid-inl.h b/library/cpp/yt/misc/guid-inl.h
index 3f0768cca2..2d94b5701b 100644
--- a/library/cpp/yt/misc/guid-inl.h
+++ b/library/cpp/yt/misc/guid-inl.h
@@ -1,76 +1,76 @@
-#ifndef GUID_INL_H_
-#error "Direct inclusion of this file is not allowed, include guid.h"
+#ifndef GUID_INL_H_
+#error "Direct inclusion of this file is not allowed, include guid.h"
// For the sake of sane code completion.
#include "guid.h"
-#endif
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-Y_FORCE_INLINE constexpr TGuid::TGuid()
- : Parts32{}
-{ }
-
-Y_FORCE_INLINE constexpr TGuid::TGuid(ui32 part0, ui32 part1, ui32 part2, ui32 part3)
- : Parts32{part0, part1, part2, part3}
-{ }
-
-Y_FORCE_INLINE constexpr TGuid::TGuid(ui64 part0, ui64 part1)
- : Parts64{part0, part1}
-{ }
-
-Y_FORCE_INLINE bool TGuid::IsEmpty() const
-{
- return Parts64[0] == 0 && Parts64[1] == 0;
-}
-
-Y_FORCE_INLINE TGuid::operator bool() const
+#endif
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+Y_FORCE_INLINE constexpr TGuid::TGuid()
+ : Parts32{}
+{ }
+
+Y_FORCE_INLINE constexpr TGuid::TGuid(ui32 part0, ui32 part1, ui32 part2, ui32 part3)
+ : Parts32{part0, part1, part2, part3}
+{ }
+
+Y_FORCE_INLINE constexpr TGuid::TGuid(ui64 part0, ui64 part1)
+ : Parts64{part0, part1}
+{ }
+
+Y_FORCE_INLINE bool TGuid::IsEmpty() const
+{
+ return Parts64[0] == 0 && Parts64[1] == 0;
+}
+
+Y_FORCE_INLINE TGuid::operator bool() const
{
return !IsEmpty();
}
-////////////////////////////////////////////////////////////////////////////////
-
+////////////////////////////////////////////////////////////////////////////////
+
Y_FORCE_INLINE bool operator == (TGuid lhs, TGuid rhs)
-{
- return lhs.Parts64[0] == rhs.Parts64[0] &&
- lhs.Parts64[1] == rhs.Parts64[1];
-}
-
+{
+ return lhs.Parts64[0] == rhs.Parts64[0] &&
+ lhs.Parts64[1] == rhs.Parts64[1];
+}
+
Y_FORCE_INLINE bool operator != (TGuid lhs, TGuid rhs)
-{
- return !(lhs == rhs);
-}
-
+{
+ return !(lhs == rhs);
+}
+
Y_FORCE_INLINE bool operator < (TGuid lhs, TGuid rhs)
-{
-#ifdef __GNUC__
- ui64 lhs0 = __builtin_bswap64(lhs.Parts64[0]);
- ui64 rhs0 = __builtin_bswap64(rhs.Parts64[0]);
- if (lhs0 < rhs0) {
- return true;
- }
- if (lhs0 > rhs0) {
- return false;
- }
- ui64 lhs1 = __builtin_bswap64(lhs.Parts64[1]);
- ui64 rhs1 = __builtin_bswap64(rhs.Parts64[1]);
- return lhs1 < rhs1;
-#else
- return memcmp(&lhs, &rhs, sizeof(TGuid)) < 0;
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
-
+{
+#ifdef __GNUC__
+ ui64 lhs0 = __builtin_bswap64(lhs.Parts64[0]);
+ ui64 rhs0 = __builtin_bswap64(rhs.Parts64[0]);
+ if (lhs0 < rhs0) {
+ return true;
+ }
+ if (lhs0 > rhs0) {
+ return false;
+ }
+ ui64 lhs1 = __builtin_bswap64(lhs.Parts64[1]);
+ ui64 rhs1 = __builtin_bswap64(rhs.Parts64[1]);
+ return lhs1 < rhs1;
+#else
+ return memcmp(&lhs, &rhs, sizeof(TGuid)) < 0;
+#endif
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
+
Y_FORCE_INLINE size_t THash<NYT::TGuid>::operator()(const NYT::TGuid& guid) const
-{
- const size_t p = 1000000009; // prime number
- return guid.Parts32[0] +
- guid.Parts32[1] * p +
- guid.Parts32[2] * p * p +
- guid.Parts32[3] * p * p * p;
-}
+{
+ const size_t p = 1000000009; // prime number
+ return guid.Parts32[0] +
+ guid.Parts32[1] * p +
+ guid.Parts32[2] * p * p +
+ guid.Parts32[3] * p * p * p;
+}
diff --git a/library/cpp/yt/misc/guid.cpp b/library/cpp/yt/misc/guid.cpp
index f08ca7c99f..882787d7a2 100644
--- a/library/cpp/yt/misc/guid.cpp
+++ b/library/cpp/yt/misc/guid.cpp
@@ -1,13 +1,13 @@
-#include "guid.h"
-
-#include <util/random/random.h>
-
-#include <util/string/printf.h>
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
+#include "guid.h"
+
+#include <util/random/random.h>
+
+#include <util/string/printf.h>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
namespace {
const ui8 HexDigits1[16] = {
@@ -37,23 +37,23 @@ const ui16 HexDigits2[256] = {
////////////////////////////////////////////////////////////////////////////////
-TGuid TGuid::Create()
-{
- return TGuid(RandomNumber<ui64>(), RandomNumber<ui64>());
-}
-
-TGuid TGuid::FromString(TStringBuf str)
-{
- TGuid guid;
- if (!FromString(str, &guid)) {
- throw TSimpleException(Sprintf("Error parsing GUID \"%s\"",
- TString(str).c_str()));
- }
- return guid;
-}
-
-bool TGuid::FromString(TStringBuf str, TGuid* result)
-{
+TGuid TGuid::Create()
+{
+ return TGuid(RandomNumber<ui64>(), RandomNumber<ui64>());
+}
+
+TGuid TGuid::FromString(TStringBuf str)
+{
+ TGuid guid;
+ if (!FromString(str, &guid)) {
+ throw TSimpleException(Sprintf("Error parsing GUID \"%s\"",
+ TString(str).c_str()));
+ }
+ return guid;
+}
+
+bool TGuid::FromString(TStringBuf str, TGuid* result)
+{
size_t partId = 3;
ui64 partValue = 0;
bool isEmptyPart = true;
@@ -93,18 +93,18 @@ bool TGuid::FromString(TStringBuf str, TGuid* result)
}
if (partId != 0 || isEmptyPart) { // x-y or x-y-z-
- return false;
- }
+ return false;
+ }
result->Parts32[partId] = static_cast<ui32>(partValue);
- return true;
-}
-
+ return true;
+}
+
TGuid TGuid::FromStringHex32(TStringBuf str)
{
TGuid guid;
if (!FromStringHex32(str, &guid)) {
- throw TSimpleException(Sprintf("Error parsing Hex32 GUID \"%s\"",
- TString(str).c_str()));
+ throw TSimpleException(Sprintf("Error parsing Hex32 GUID \"%s\"",
+ TString(str).c_str()));
}
return guid;
}
@@ -131,7 +131,7 @@ bool TGuid::FromStringHex32(TStringBuf str, TGuid* result)
}
return digit;
};
-
+
for (size_t j = 0; j < 16; ++j) {
result->ReversedParts8[15 - j] = parseChar() * 16 + parseChar();
}
@@ -198,6 +198,6 @@ char* WriteGuidToBuffer(char* ptr, TGuid value)
return ptr;
}
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/misc/guid.h b/library/cpp/yt/misc/guid.h
index 1517c006ed..ec4ba3526a 100644
--- a/library/cpp/yt/misc/guid.h
+++ b/library/cpp/yt/misc/guid.h
@@ -1,14 +1,14 @@
-#pragma once
-
+#pragma once
+
#include <util/generic/string.h>
-#include <util/generic/typetraits.h>
-
-#include <library/cpp/yt/exception/exception.h>
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
+#include <util/generic/typetraits.h>
+
+#include <library/cpp/yt/exception/exception.h>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
//! TGuid is 16-byte value that might be interpreted as four little-endian 32-bit integers or two 64-bit little-endian integers.
/*!
* *-------------------------*-------------------------*
@@ -35,75 +35,75 @@ namespace NYT {
* 34 is byte [9]
* ff is byte [15]
*/
-struct TGuid
-{
- union
- {
- ui32 Parts32[4];
- ui64 Parts64[2];
+struct TGuid
+{
+ union
+ {
+ ui32 Parts32[4];
+ ui64 Parts64[2];
ui8 ReversedParts8[16];
- };
-
- //! Constructs a null (zero) guid.
- constexpr TGuid();
-
- //! Constructs guid from parts.
- constexpr TGuid(ui32 part0, ui32 part1, ui32 part2, ui32 part3);
-
- //! Constructs guid from parts.
- constexpr TGuid(ui64 part0, ui64 part1);
-
- //! Copies an existing guid.
- TGuid(const TGuid& other) = default;
-
- //! Checks if TGuid is zero.
- bool IsEmpty() const;
-
+ };
+
+ //! Constructs a null (zero) guid.
+ constexpr TGuid();
+
+ //! Constructs guid from parts.
+ constexpr TGuid(ui32 part0, ui32 part1, ui32 part2, ui32 part3);
+
+ //! Constructs guid from parts.
+ constexpr TGuid(ui64 part0, ui64 part1);
+
+ //! Copies an existing guid.
+ TGuid(const TGuid& other) = default;
+
+ //! Checks if TGuid is zero.
+ bool IsEmpty() const;
+
//! Converts TGuid to bool, returns |false| iff TGuid is zero.
explicit operator bool() const;
- //! Creates a new instance.
- static TGuid Create();
-
- //! Parses guid from TStringBuf, throws an exception if something went wrong.
- static TGuid FromString(TStringBuf str);
-
- //! Parses guid from TStringBuf, returns |true| if everything was ok.
- static bool FromString(TStringBuf str, TGuid* guid);
+ //! Creates a new instance.
+ static TGuid Create();
+
+ //! Parses guid from TStringBuf, throws an exception if something went wrong.
+ static TGuid FromString(TStringBuf str);
+
+ //! Parses guid from TStringBuf, returns |true| if everything was ok.
+ static bool FromString(TStringBuf str, TGuid* guid);
//! Same as FromString, but expects exactly 32 hex digits without dashes.
static TGuid FromStringHex32(TStringBuf str);
//! Same as TryFromString, but expects exactly 32 hex digits without dashes.
static bool FromStringHex32(TStringBuf str, TGuid* guid);
-};
-
+};
+
bool operator == (TGuid lhs, TGuid rhs);
bool operator != (TGuid lhs, TGuid rhs);
bool operator < (TGuid lhs, TGuid rhs);
-
-////////////////////////////////////////////////////////////////////////////////
-
-constexpr int MaxGuidStringSize = 4 * 8 + 3;
+
+////////////////////////////////////////////////////////////////////////////////
+
+constexpr int MaxGuidStringSize = 4 * 8 + 3;
char* WriteGuidToBuffer(char* ptr, TGuid value);
////////////////////////////////////////////////////////////////////////////////
-} // namespace NYT
-
-////////////////////////////////////////////////////////////////////////////////
-
-Y_DECLARE_PODTYPE(NYT::TGuid);
-
-//! A hasher for TGuid.
-template <>
+} // namespace NYT
+
+////////////////////////////////////////////////////////////////////////////////
+
+Y_DECLARE_PODTYPE(NYT::TGuid);
+
+//! A hasher for TGuid.
+template <>
struct THash<NYT::TGuid>
-{
- size_t operator()(const NYT::TGuid& guid) const;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-#define GUID_INL_H_
-#include "guid-inl.h"
-#undef GUID_INL_H_
+{
+ size_t operator()(const NYT::TGuid& guid) const;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+#define GUID_INL_H_
+#include "guid-inl.h"
+#undef GUID_INL_H_
diff --git a/library/cpp/yt/misc/hash-inl.h b/library/cpp/yt/misc/hash-inl.h
index 0b8873c2d3..46eeefe620 100644
--- a/library/cpp/yt/misc/hash-inl.h
+++ b/library/cpp/yt/misc/hash-inl.h
@@ -1,47 +1,47 @@
-#ifndef HASH_INL_H_
-#error "Direct inclusion of this file is not allowed, include hash.h"
+#ifndef HASH_INL_H_
+#error "Direct inclusion of this file is not allowed, include hash.h"
// For the sake of sane code completion.
#include "hash.h"
-#endif
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-inline void HashCombine(size_t& h, size_t k)
-{
- static_assert(sizeof(size_t) == 8, "size_t must be 64 bit.");
-
- const size_t m = 0xc6a4a7935bd1e995ULL;
- const int r = 47;
-
- k *= m;
- k ^= k >> r;
- k *= m;
-
- h ^= k;
- h *= m;
-}
-
-template <class T>
-void HashCombine(size_t& h, const T& k)
-{
- HashCombine(h, THash<T>()(k));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class TElement, class TUnderlying>
-TRandomizedHash<TElement, TUnderlying>::TRandomizedHash()
- : Seed_(RandomNumber<size_t>())
-{ }
-
-template <class TElement, class TUnderlying>
-size_t TRandomizedHash<TElement, TUnderlying>::operator ()(const TElement& element) const
-{
- return Underlying_(element) + Seed_;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
+#endif
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+inline void HashCombine(size_t& h, size_t k)
+{
+ static_assert(sizeof(size_t) == 8, "size_t must be 64 bit.");
+
+ const size_t m = 0xc6a4a7935bd1e995ULL;
+ const int r = 47;
+
+ k *= m;
+ k ^= k >> r;
+ k *= m;
+
+ h ^= k;
+ h *= m;
+}
+
+template <class T>
+void HashCombine(size_t& h, const T& k)
+{
+ HashCombine(h, THash<T>()(k));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class TElement, class TUnderlying>
+TRandomizedHash<TElement, TUnderlying>::TRandomizedHash()
+ : Seed_(RandomNumber<size_t>())
+{ }
+
+template <class TElement, class TUnderlying>
+size_t TRandomizedHash<TElement, TUnderlying>::operator ()(const TElement& element) const
+{
+ return Underlying_(element) + Seed_;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/misc/hash.h b/library/cpp/yt/misc/hash.h
index ec03732999..2fecf89506 100644
--- a/library/cpp/yt/misc/hash.h
+++ b/library/cpp/yt/misc/hash.h
@@ -1,31 +1,31 @@
-#pragma once
-
-#include <util/generic/hash.h>
-
+#pragma once
+
+#include <util/generic/hash.h>
+
#include <util/random/random.h>
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-//! Updates #h with #k.
-//! Cf. |boost::hash_combine|.
-void HashCombine(size_t& h, size_t k);
-
-//! Updates #h with the hash of #k.
-//! Cf. |boost::hash_combine|.
-template <class T>
-void HashCombine(size_t& h, const T& k);
-
-////////////////////////////////////////////////////////////////////////////////
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+//! Updates #h with #k.
+//! Cf. |boost::hash_combine|.
+void HashCombine(size_t& h, size_t k);
+
+//! Updates #h with the hash of #k.
+//! Cf. |boost::hash_combine|.
+template <class T>
+void HashCombine(size_t& h, const T& k);
+
+////////////////////////////////////////////////////////////////////////////////
//! Provides a hasher that randomizes the results of another one.
template <class TElement, class TUnderlying = ::THash<TElement>>
class TRandomizedHash
{
public:
- TRandomizedHash();
- size_t operator () (const TElement& element) const;
+ TRandomizedHash();
+ size_t operator () (const TElement& element) const;
private:
size_t Seed_;
@@ -33,10 +33,10 @@ private:
};
-////////////////////////////////////////////////////////////////////////////////
-
+////////////////////////////////////////////////////////////////////////////////
+
} // namespace NYT
-#define HASH_INL_H_
-#include "hash-inl.h"
-#undef HASH_INL_H_
+#define HASH_INL_H_
+#include "hash-inl.h"
+#undef HASH_INL_H_
diff --git a/library/cpp/yt/misc/port.h b/library/cpp/yt/misc/port.h
index 894a485b5a..b24ac50995 100644
--- a/library/cpp/yt/misc/port.h
+++ b/library/cpp/yt/misc/port.h
@@ -2,69 +2,69 @@
#include <util/system/platform.h>
-// Check platform bitness.
+// Check platform bitness.
#if !defined(_64_)
- #error YT requires 64-bit platform
-#endif
-
-// This define enables tracking of reference-counted objects to provide
-// various insightful information on memory usage and object creation patterns.
-#define YT_ENABLE_REF_COUNTED_TRACKING
-
+ #error YT requires 64-bit platform
+#endif
+
+// This define enables tracking of reference-counted objects to provide
+// various insightful information on memory usage and object creation patterns.
+#define YT_ENABLE_REF_COUNTED_TRACKING
+
// This define enables logging with TRACE level. You can still disable trace logging
// for particular TU by discarding this macro identifier.
#define YT_ENABLE_TRACE_LOGGING
-#ifndef NDEBUG
- // This define enables thread affinity check -- a user-defined verification ensuring
- // that some functions are called from particular threads.
- #define YT_ENABLE_THREAD_AFFINITY_CHECK
-
- // This define enables tracking of BIND callbacks location.
- #define YT_ENABLE_BIND_LOCATION_TRACKING
-
- // This define enables checking that all required protobuf fields are present
- // during serialization.
- #define YT_VALIDATE_REQUIRED_PROTO_FIELDS
-
- // Detects deadlocks caused by recursive acquisitions of (non-recursive) spin locks.
- #define YT_ENABLE_SPIN_LOCK_OWNERSHIP_TRACKING
-#endif
-
-// Configure SSE usage.
+#ifndef NDEBUG
+ // This define enables thread affinity check -- a user-defined verification ensuring
+ // that some functions are called from particular threads.
+ #define YT_ENABLE_THREAD_AFFINITY_CHECK
+
+ // This define enables tracking of BIND callbacks location.
+ #define YT_ENABLE_BIND_LOCATION_TRACKING
+
+ // This define enables checking that all required protobuf fields are present
+ // during serialization.
+ #define YT_VALIDATE_REQUIRED_PROTO_FIELDS
+
+ // Detects deadlocks caused by recursive acquisitions of (non-recursive) spin locks.
+ #define YT_ENABLE_SPIN_LOCK_OWNERSHIP_TRACKING
+#endif
+
+// Configure SSE usage.
#ifdef SSE42_ENABLED
- #define YT_USE_SSE42
-#endif
-
-#ifdef _win_
- // Someone above has defined this by including one of Windows headers.
- #undef GetMessage
- #undef Yield
-
- // For protobuf-generated files:
- // C4125: decimal digit terminates octal escape sequence
- #pragma warning (disable: 4125)
- // C4505: unreferenced local function has been removed
- #pragma warning (disable : 4505)
- // C4121: alignment of a member was sensitive to packing
- #pragma warning (disable: 4121)
- // C4503: decorated name length exceeded, name was truncated
- #pragma warning (disable : 4503)
- // C4714: function marked as __forceinline not inlined
- #pragma warning (disable: 4714)
- // C4250: inherits via dominance
- #pragma warning (disable: 4250)
-#endif
-
-#if defined(__GNUC__) || defined(__clang__)
- #define PER_THREAD __thread
- #define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
+ #define YT_USE_SSE42
+#endif
+
+#ifdef _win_
+ // Someone above has defined this by including one of Windows headers.
+ #undef GetMessage
+ #undef Yield
+
+ // For protobuf-generated files:
+ // C4125: decimal digit terminates octal escape sequence
+ #pragma warning (disable: 4125)
+ // C4505: unreferenced local function has been removed
+ #pragma warning (disable : 4505)
+ // C4121: alignment of a member was sensitive to packing
+ #pragma warning (disable: 4121)
+ // C4503: decorated name length exceeded, name was truncated
+ #pragma warning (disable : 4503)
+ // C4714: function marked as __forceinline not inlined
+ #pragma warning (disable: 4714)
+ // C4250: inherits via dominance
+ #pragma warning (disable: 4250)
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+ #define PER_THREAD __thread
+ #define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
// Prevent GCC from throwing out functions in release builds.
#define ATTRIBUTE_USED __attribute__((used))
-#elif defined(_MSC_VER)
- #define PER_THREAD __declspec(thread)
- #define ATTRIBUTE_NO_SANITIZE_ADDRESS
+#elif defined(_MSC_VER)
+ #define PER_THREAD __declspec(thread)
+ #define ATTRIBUTE_NO_SANITIZE_ADDRESS
#define ATTRIBUTE_USED
-#else
- #error Unsupported compiler
-#endif
+#else
+ #error Unsupported compiler
+#endif
diff --git a/library/cpp/yt/misc/preprocessor-gen.h b/library/cpp/yt/misc/preprocessor-gen.h
index 912216330a..b809941bcd 100644
--- a/library/cpp/yt/misc/preprocessor-gen.h
+++ b/library/cpp/yt/misc/preprocessor-gen.h
@@ -1,125 +1,125 @@
-#pragma once
-
-// WARNING: This file was auto-generated.
-// Please, consider incorporating any changes into the generator.
-
-// Generated on Wed Dec 9 14:20:20 2015.
-
-
-/*!
- \internal
-*/
-
-#ifndef PREPROCESSOR_GEN_H_
-#error "Direct inclusion of this file is not allowed, include preprocessor.h"
-// For the sake of sane code completion.
-#include "preprocessor.h"
-#endif
-#undef PREPROCESSOR_GEN_H_
-
-////////////////////////////////////////////////////////////////////////////////
-#define PP_COUNT_IMPL(...) PP_CONCAT(PP_COUNT_CONST_, \
- PP_COUNT_IMPL_0 __VA_ARGS__)
-#define PP_COUNT_CONST_PP_COUNT_IMPL_0 0
-#define PP_COUNT_CONST_PP_COUNT_IMPL_1 1
-#define PP_COUNT_CONST_PP_COUNT_IMPL_2 2
-#define PP_COUNT_CONST_PP_COUNT_IMPL_3 3
-#define PP_COUNT_CONST_PP_COUNT_IMPL_4 4
-#define PP_COUNT_CONST_PP_COUNT_IMPL_5 5
-#define PP_COUNT_CONST_PP_COUNT_IMPL_6 6
-#define PP_COUNT_CONST_PP_COUNT_IMPL_7 7
-#define PP_COUNT_CONST_PP_COUNT_IMPL_8 8
-#define PP_COUNT_CONST_PP_COUNT_IMPL_9 9
-#define PP_COUNT_CONST_PP_COUNT_IMPL_10 10
-#define PP_COUNT_CONST_PP_COUNT_IMPL_11 11
-#define PP_COUNT_CONST_PP_COUNT_IMPL_12 12
-#define PP_COUNT_CONST_PP_COUNT_IMPL_13 13
-#define PP_COUNT_CONST_PP_COUNT_IMPL_14 14
-#define PP_COUNT_CONST_PP_COUNT_IMPL_15 15
-#define PP_COUNT_CONST_PP_COUNT_IMPL_16 16
-#define PP_COUNT_CONST_PP_COUNT_IMPL_17 17
-#define PP_COUNT_CONST_PP_COUNT_IMPL_18 18
-#define PP_COUNT_CONST_PP_COUNT_IMPL_19 19
-#define PP_COUNT_CONST_PP_COUNT_IMPL_20 20
-#define PP_COUNT_CONST_PP_COUNT_IMPL_21 21
-#define PP_COUNT_CONST_PP_COUNT_IMPL_22 22
-#define PP_COUNT_CONST_PP_COUNT_IMPL_23 23
-#define PP_COUNT_CONST_PP_COUNT_IMPL_24 24
-#define PP_COUNT_CONST_PP_COUNT_IMPL_25 25
-#define PP_COUNT_CONST_PP_COUNT_IMPL_26 26
-#define PP_COUNT_CONST_PP_COUNT_IMPL_27 27
-#define PP_COUNT_CONST_PP_COUNT_IMPL_28 28
-#define PP_COUNT_CONST_PP_COUNT_IMPL_29 29
-#define PP_COUNT_CONST_PP_COUNT_IMPL_30 30
-#define PP_COUNT_CONST_PP_COUNT_IMPL_31 31
-#define PP_COUNT_CONST_PP_COUNT_IMPL_32 32
-#define PP_COUNT_CONST_PP_COUNT_IMPL_33 33
-#define PP_COUNT_CONST_PP_COUNT_IMPL_34 34
-#define PP_COUNT_CONST_PP_COUNT_IMPL_35 35
-#define PP_COUNT_CONST_PP_COUNT_IMPL_36 36
-#define PP_COUNT_CONST_PP_COUNT_IMPL_37 37
-#define PP_COUNT_CONST_PP_COUNT_IMPL_38 38
-#define PP_COUNT_CONST_PP_COUNT_IMPL_39 39
-#define PP_COUNT_CONST_PP_COUNT_IMPL_40 40
-#define PP_COUNT_CONST_PP_COUNT_IMPL_41 41
-#define PP_COUNT_CONST_PP_COUNT_IMPL_42 42
-#define PP_COUNT_CONST_PP_COUNT_IMPL_43 43
-#define PP_COUNT_CONST_PP_COUNT_IMPL_44 44
-#define PP_COUNT_CONST_PP_COUNT_IMPL_45 45
-#define PP_COUNT_CONST_PP_COUNT_IMPL_46 46
-#define PP_COUNT_CONST_PP_COUNT_IMPL_47 47
-#define PP_COUNT_CONST_PP_COUNT_IMPL_48 48
-#define PP_COUNT_CONST_PP_COUNT_IMPL_49 49
-#define PP_COUNT_CONST_PP_COUNT_IMPL_50 50
-#define PP_COUNT_CONST_PP_COUNT_IMPL_51 51
-#define PP_COUNT_CONST_PP_COUNT_IMPL_52 52
-#define PP_COUNT_CONST_PP_COUNT_IMPL_53 53
-#define PP_COUNT_CONST_PP_COUNT_IMPL_54 54
-#define PP_COUNT_CONST_PP_COUNT_IMPL_55 55
-#define PP_COUNT_CONST_PP_COUNT_IMPL_56 56
-#define PP_COUNT_CONST_PP_COUNT_IMPL_57 57
-#define PP_COUNT_CONST_PP_COUNT_IMPL_58 58
-#define PP_COUNT_CONST_PP_COUNT_IMPL_59 59
-#define PP_COUNT_CONST_PP_COUNT_IMPL_60 60
-#define PP_COUNT_CONST_PP_COUNT_IMPL_61 61
-#define PP_COUNT_CONST_PP_COUNT_IMPL_62 62
-#define PP_COUNT_CONST_PP_COUNT_IMPL_63 63
-#define PP_COUNT_CONST_PP_COUNT_IMPL_64 64
-#define PP_COUNT_CONST_PP_COUNT_IMPL_65 65
-#define PP_COUNT_CONST_PP_COUNT_IMPL_66 66
-#define PP_COUNT_CONST_PP_COUNT_IMPL_67 67
-#define PP_COUNT_CONST_PP_COUNT_IMPL_68 68
-#define PP_COUNT_CONST_PP_COUNT_IMPL_69 69
-#define PP_COUNT_CONST_PP_COUNT_IMPL_70 70
-#define PP_COUNT_CONST_PP_COUNT_IMPL_71 71
-#define PP_COUNT_CONST_PP_COUNT_IMPL_72 72
-#define PP_COUNT_CONST_PP_COUNT_IMPL_73 73
-#define PP_COUNT_CONST_PP_COUNT_IMPL_74 74
-#define PP_COUNT_CONST_PP_COUNT_IMPL_75 75
-#define PP_COUNT_CONST_PP_COUNT_IMPL_76 76
-#define PP_COUNT_CONST_PP_COUNT_IMPL_77 77
-#define PP_COUNT_CONST_PP_COUNT_IMPL_78 78
-#define PP_COUNT_CONST_PP_COUNT_IMPL_79 79
-#define PP_COUNT_CONST_PP_COUNT_IMPL_80 80
-#define PP_COUNT_CONST_PP_COUNT_IMPL_81 81
-#define PP_COUNT_CONST_PP_COUNT_IMPL_82 82
-#define PP_COUNT_CONST_PP_COUNT_IMPL_83 83
-#define PP_COUNT_CONST_PP_COUNT_IMPL_84 84
-#define PP_COUNT_CONST_PP_COUNT_IMPL_85 85
-#define PP_COUNT_CONST_PP_COUNT_IMPL_86 86
-#define PP_COUNT_CONST_PP_COUNT_IMPL_87 87
-#define PP_COUNT_CONST_PP_COUNT_IMPL_88 88
-#define PP_COUNT_CONST_PP_COUNT_IMPL_89 89
-#define PP_COUNT_CONST_PP_COUNT_IMPL_90 90
-#define PP_COUNT_CONST_PP_COUNT_IMPL_91 91
-#define PP_COUNT_CONST_PP_COUNT_IMPL_92 92
-#define PP_COUNT_CONST_PP_COUNT_IMPL_93 93
-#define PP_COUNT_CONST_PP_COUNT_IMPL_94 94
-#define PP_COUNT_CONST_PP_COUNT_IMPL_95 95
-#define PP_COUNT_CONST_PP_COUNT_IMPL_96 96
-#define PP_COUNT_CONST_PP_COUNT_IMPL_97 97
-#define PP_COUNT_CONST_PP_COUNT_IMPL_98 98
-#define PP_COUNT_CONST_PP_COUNT_IMPL_99 99
+#pragma once
+
+// WARNING: This file was auto-generated.
+// Please, consider incorporating any changes into the generator.
+
+// Generated on Wed Dec 9 14:20:20 2015.
+
+
+/*!
+ \internal
+*/
+
+#ifndef PREPROCESSOR_GEN_H_
+#error "Direct inclusion of this file is not allowed, include preprocessor.h"
+// For the sake of sane code completion.
+#include "preprocessor.h"
+#endif
+#undef PREPROCESSOR_GEN_H_
+
+////////////////////////////////////////////////////////////////////////////////
+#define PP_COUNT_IMPL(...) PP_CONCAT(PP_COUNT_CONST_, \
+ PP_COUNT_IMPL_0 __VA_ARGS__)
+#define PP_COUNT_CONST_PP_COUNT_IMPL_0 0
+#define PP_COUNT_CONST_PP_COUNT_IMPL_1 1
+#define PP_COUNT_CONST_PP_COUNT_IMPL_2 2
+#define PP_COUNT_CONST_PP_COUNT_IMPL_3 3
+#define PP_COUNT_CONST_PP_COUNT_IMPL_4 4
+#define PP_COUNT_CONST_PP_COUNT_IMPL_5 5
+#define PP_COUNT_CONST_PP_COUNT_IMPL_6 6
+#define PP_COUNT_CONST_PP_COUNT_IMPL_7 7
+#define PP_COUNT_CONST_PP_COUNT_IMPL_8 8
+#define PP_COUNT_CONST_PP_COUNT_IMPL_9 9
+#define PP_COUNT_CONST_PP_COUNT_IMPL_10 10
+#define PP_COUNT_CONST_PP_COUNT_IMPL_11 11
+#define PP_COUNT_CONST_PP_COUNT_IMPL_12 12
+#define PP_COUNT_CONST_PP_COUNT_IMPL_13 13
+#define PP_COUNT_CONST_PP_COUNT_IMPL_14 14
+#define PP_COUNT_CONST_PP_COUNT_IMPL_15 15
+#define PP_COUNT_CONST_PP_COUNT_IMPL_16 16
+#define PP_COUNT_CONST_PP_COUNT_IMPL_17 17
+#define PP_COUNT_CONST_PP_COUNT_IMPL_18 18
+#define PP_COUNT_CONST_PP_COUNT_IMPL_19 19
+#define PP_COUNT_CONST_PP_COUNT_IMPL_20 20
+#define PP_COUNT_CONST_PP_COUNT_IMPL_21 21
+#define PP_COUNT_CONST_PP_COUNT_IMPL_22 22
+#define PP_COUNT_CONST_PP_COUNT_IMPL_23 23
+#define PP_COUNT_CONST_PP_COUNT_IMPL_24 24
+#define PP_COUNT_CONST_PP_COUNT_IMPL_25 25
+#define PP_COUNT_CONST_PP_COUNT_IMPL_26 26
+#define PP_COUNT_CONST_PP_COUNT_IMPL_27 27
+#define PP_COUNT_CONST_PP_COUNT_IMPL_28 28
+#define PP_COUNT_CONST_PP_COUNT_IMPL_29 29
+#define PP_COUNT_CONST_PP_COUNT_IMPL_30 30
+#define PP_COUNT_CONST_PP_COUNT_IMPL_31 31
+#define PP_COUNT_CONST_PP_COUNT_IMPL_32 32
+#define PP_COUNT_CONST_PP_COUNT_IMPL_33 33
+#define PP_COUNT_CONST_PP_COUNT_IMPL_34 34
+#define PP_COUNT_CONST_PP_COUNT_IMPL_35 35
+#define PP_COUNT_CONST_PP_COUNT_IMPL_36 36
+#define PP_COUNT_CONST_PP_COUNT_IMPL_37 37
+#define PP_COUNT_CONST_PP_COUNT_IMPL_38 38
+#define PP_COUNT_CONST_PP_COUNT_IMPL_39 39
+#define PP_COUNT_CONST_PP_COUNT_IMPL_40 40
+#define PP_COUNT_CONST_PP_COUNT_IMPL_41 41
+#define PP_COUNT_CONST_PP_COUNT_IMPL_42 42
+#define PP_COUNT_CONST_PP_COUNT_IMPL_43 43
+#define PP_COUNT_CONST_PP_COUNT_IMPL_44 44
+#define PP_COUNT_CONST_PP_COUNT_IMPL_45 45
+#define PP_COUNT_CONST_PP_COUNT_IMPL_46 46
+#define PP_COUNT_CONST_PP_COUNT_IMPL_47 47
+#define PP_COUNT_CONST_PP_COUNT_IMPL_48 48
+#define PP_COUNT_CONST_PP_COUNT_IMPL_49 49
+#define PP_COUNT_CONST_PP_COUNT_IMPL_50 50
+#define PP_COUNT_CONST_PP_COUNT_IMPL_51 51
+#define PP_COUNT_CONST_PP_COUNT_IMPL_52 52
+#define PP_COUNT_CONST_PP_COUNT_IMPL_53 53
+#define PP_COUNT_CONST_PP_COUNT_IMPL_54 54
+#define PP_COUNT_CONST_PP_COUNT_IMPL_55 55
+#define PP_COUNT_CONST_PP_COUNT_IMPL_56 56
+#define PP_COUNT_CONST_PP_COUNT_IMPL_57 57
+#define PP_COUNT_CONST_PP_COUNT_IMPL_58 58
+#define PP_COUNT_CONST_PP_COUNT_IMPL_59 59
+#define PP_COUNT_CONST_PP_COUNT_IMPL_60 60
+#define PP_COUNT_CONST_PP_COUNT_IMPL_61 61
+#define PP_COUNT_CONST_PP_COUNT_IMPL_62 62
+#define PP_COUNT_CONST_PP_COUNT_IMPL_63 63
+#define PP_COUNT_CONST_PP_COUNT_IMPL_64 64
+#define PP_COUNT_CONST_PP_COUNT_IMPL_65 65
+#define PP_COUNT_CONST_PP_COUNT_IMPL_66 66
+#define PP_COUNT_CONST_PP_COUNT_IMPL_67 67
+#define PP_COUNT_CONST_PP_COUNT_IMPL_68 68
+#define PP_COUNT_CONST_PP_COUNT_IMPL_69 69
+#define PP_COUNT_CONST_PP_COUNT_IMPL_70 70
+#define PP_COUNT_CONST_PP_COUNT_IMPL_71 71
+#define PP_COUNT_CONST_PP_COUNT_IMPL_72 72
+#define PP_COUNT_CONST_PP_COUNT_IMPL_73 73
+#define PP_COUNT_CONST_PP_COUNT_IMPL_74 74
+#define PP_COUNT_CONST_PP_COUNT_IMPL_75 75
+#define PP_COUNT_CONST_PP_COUNT_IMPL_76 76
+#define PP_COUNT_CONST_PP_COUNT_IMPL_77 77
+#define PP_COUNT_CONST_PP_COUNT_IMPL_78 78
+#define PP_COUNT_CONST_PP_COUNT_IMPL_79 79
+#define PP_COUNT_CONST_PP_COUNT_IMPL_80 80
+#define PP_COUNT_CONST_PP_COUNT_IMPL_81 81
+#define PP_COUNT_CONST_PP_COUNT_IMPL_82 82
+#define PP_COUNT_CONST_PP_COUNT_IMPL_83 83
+#define PP_COUNT_CONST_PP_COUNT_IMPL_84 84
+#define PP_COUNT_CONST_PP_COUNT_IMPL_85 85
+#define PP_COUNT_CONST_PP_COUNT_IMPL_86 86
+#define PP_COUNT_CONST_PP_COUNT_IMPL_87 87
+#define PP_COUNT_CONST_PP_COUNT_IMPL_88 88
+#define PP_COUNT_CONST_PP_COUNT_IMPL_89 89
+#define PP_COUNT_CONST_PP_COUNT_IMPL_90 90
+#define PP_COUNT_CONST_PP_COUNT_IMPL_91 91
+#define PP_COUNT_CONST_PP_COUNT_IMPL_92 92
+#define PP_COUNT_CONST_PP_COUNT_IMPL_93 93
+#define PP_COUNT_CONST_PP_COUNT_IMPL_94 94
+#define PP_COUNT_CONST_PP_COUNT_IMPL_95 95
+#define PP_COUNT_CONST_PP_COUNT_IMPL_96 96
+#define PP_COUNT_CONST_PP_COUNT_IMPL_97 97
+#define PP_COUNT_CONST_PP_COUNT_IMPL_98 98
+#define PP_COUNT_CONST_PP_COUNT_IMPL_99 99
#define PP_COUNT_CONST_PP_COUNT_IMPL_100 100
#define PP_COUNT_CONST_PP_COUNT_IMPL_101 101
#define PP_COUNT_CONST_PP_COUNT_IMPL_102 102
@@ -220,106 +220,106 @@
#define PP_COUNT_CONST_PP_COUNT_IMPL_197 197
#define PP_COUNT_CONST_PP_COUNT_IMPL_198 198
#define PP_COUNT_CONST_PP_COUNT_IMPL_199 199
-#define PP_COUNT_IMPL_0(_) PP_COUNT_IMPL_1
-#define PP_COUNT_IMPL_1(_) PP_COUNT_IMPL_2
-#define PP_COUNT_IMPL_2(_) PP_COUNT_IMPL_3
-#define PP_COUNT_IMPL_3(_) PP_COUNT_IMPL_4
-#define PP_COUNT_IMPL_4(_) PP_COUNT_IMPL_5
-#define PP_COUNT_IMPL_5(_) PP_COUNT_IMPL_6
-#define PP_COUNT_IMPL_6(_) PP_COUNT_IMPL_7
-#define PP_COUNT_IMPL_7(_) PP_COUNT_IMPL_8
-#define PP_COUNT_IMPL_8(_) PP_COUNT_IMPL_9
-#define PP_COUNT_IMPL_9(_) PP_COUNT_IMPL_10
-#define PP_COUNT_IMPL_10(_) PP_COUNT_IMPL_11
-#define PP_COUNT_IMPL_11(_) PP_COUNT_IMPL_12
-#define PP_COUNT_IMPL_12(_) PP_COUNT_IMPL_13
-#define PP_COUNT_IMPL_13(_) PP_COUNT_IMPL_14
-#define PP_COUNT_IMPL_14(_) PP_COUNT_IMPL_15
-#define PP_COUNT_IMPL_15(_) PP_COUNT_IMPL_16
-#define PP_COUNT_IMPL_16(_) PP_COUNT_IMPL_17
-#define PP_COUNT_IMPL_17(_) PP_COUNT_IMPL_18
-#define PP_COUNT_IMPL_18(_) PP_COUNT_IMPL_19
-#define PP_COUNT_IMPL_19(_) PP_COUNT_IMPL_20
-#define PP_COUNT_IMPL_20(_) PP_COUNT_IMPL_21
-#define PP_COUNT_IMPL_21(_) PP_COUNT_IMPL_22
-#define PP_COUNT_IMPL_22(_) PP_COUNT_IMPL_23
-#define PP_COUNT_IMPL_23(_) PP_COUNT_IMPL_24
-#define PP_COUNT_IMPL_24(_) PP_COUNT_IMPL_25
-#define PP_COUNT_IMPL_25(_) PP_COUNT_IMPL_26
-#define PP_COUNT_IMPL_26(_) PP_COUNT_IMPL_27
-#define PP_COUNT_IMPL_27(_) PP_COUNT_IMPL_28
-#define PP_COUNT_IMPL_28(_) PP_COUNT_IMPL_29
-#define PP_COUNT_IMPL_29(_) PP_COUNT_IMPL_30
-#define PP_COUNT_IMPL_30(_) PP_COUNT_IMPL_31
-#define PP_COUNT_IMPL_31(_) PP_COUNT_IMPL_32
-#define PP_COUNT_IMPL_32(_) PP_COUNT_IMPL_33
-#define PP_COUNT_IMPL_33(_) PP_COUNT_IMPL_34
-#define PP_COUNT_IMPL_34(_) PP_COUNT_IMPL_35
-#define PP_COUNT_IMPL_35(_) PP_COUNT_IMPL_36
-#define PP_COUNT_IMPL_36(_) PP_COUNT_IMPL_37
-#define PP_COUNT_IMPL_37(_) PP_COUNT_IMPL_38
-#define PP_COUNT_IMPL_38(_) PP_COUNT_IMPL_39
-#define PP_COUNT_IMPL_39(_) PP_COUNT_IMPL_40
-#define PP_COUNT_IMPL_40(_) PP_COUNT_IMPL_41
-#define PP_COUNT_IMPL_41(_) PP_COUNT_IMPL_42
-#define PP_COUNT_IMPL_42(_) PP_COUNT_IMPL_43
-#define PP_COUNT_IMPL_43(_) PP_COUNT_IMPL_44
-#define PP_COUNT_IMPL_44(_) PP_COUNT_IMPL_45
-#define PP_COUNT_IMPL_45(_) PP_COUNT_IMPL_46
-#define PP_COUNT_IMPL_46(_) PP_COUNT_IMPL_47
-#define PP_COUNT_IMPL_47(_) PP_COUNT_IMPL_48
-#define PP_COUNT_IMPL_48(_) PP_COUNT_IMPL_49
-#define PP_COUNT_IMPL_49(_) PP_COUNT_IMPL_50
-#define PP_COUNT_IMPL_50(_) PP_COUNT_IMPL_51
-#define PP_COUNT_IMPL_51(_) PP_COUNT_IMPL_52
-#define PP_COUNT_IMPL_52(_) PP_COUNT_IMPL_53
-#define PP_COUNT_IMPL_53(_) PP_COUNT_IMPL_54
-#define PP_COUNT_IMPL_54(_) PP_COUNT_IMPL_55
-#define PP_COUNT_IMPL_55(_) PP_COUNT_IMPL_56
-#define PP_COUNT_IMPL_56(_) PP_COUNT_IMPL_57
-#define PP_COUNT_IMPL_57(_) PP_COUNT_IMPL_58
-#define PP_COUNT_IMPL_58(_) PP_COUNT_IMPL_59
-#define PP_COUNT_IMPL_59(_) PP_COUNT_IMPL_60
-#define PP_COUNT_IMPL_60(_) PP_COUNT_IMPL_61
-#define PP_COUNT_IMPL_61(_) PP_COUNT_IMPL_62
-#define PP_COUNT_IMPL_62(_) PP_COUNT_IMPL_63
-#define PP_COUNT_IMPL_63(_) PP_COUNT_IMPL_64
-#define PP_COUNT_IMPL_64(_) PP_COUNT_IMPL_65
-#define PP_COUNT_IMPL_65(_) PP_COUNT_IMPL_66
-#define PP_COUNT_IMPL_66(_) PP_COUNT_IMPL_67
-#define PP_COUNT_IMPL_67(_) PP_COUNT_IMPL_68
-#define PP_COUNT_IMPL_68(_) PP_COUNT_IMPL_69
-#define PP_COUNT_IMPL_69(_) PP_COUNT_IMPL_70
-#define PP_COUNT_IMPL_70(_) PP_COUNT_IMPL_71
-#define PP_COUNT_IMPL_71(_) PP_COUNT_IMPL_72
-#define PP_COUNT_IMPL_72(_) PP_COUNT_IMPL_73
-#define PP_COUNT_IMPL_73(_) PP_COUNT_IMPL_74
-#define PP_COUNT_IMPL_74(_) PP_COUNT_IMPL_75
-#define PP_COUNT_IMPL_75(_) PP_COUNT_IMPL_76
-#define PP_COUNT_IMPL_76(_) PP_COUNT_IMPL_77
-#define PP_COUNT_IMPL_77(_) PP_COUNT_IMPL_78
-#define PP_COUNT_IMPL_78(_) PP_COUNT_IMPL_79
-#define PP_COUNT_IMPL_79(_) PP_COUNT_IMPL_80
-#define PP_COUNT_IMPL_80(_) PP_COUNT_IMPL_81
-#define PP_COUNT_IMPL_81(_) PP_COUNT_IMPL_82
-#define PP_COUNT_IMPL_82(_) PP_COUNT_IMPL_83
-#define PP_COUNT_IMPL_83(_) PP_COUNT_IMPL_84
-#define PP_COUNT_IMPL_84(_) PP_COUNT_IMPL_85
-#define PP_COUNT_IMPL_85(_) PP_COUNT_IMPL_86
-#define PP_COUNT_IMPL_86(_) PP_COUNT_IMPL_87
-#define PP_COUNT_IMPL_87(_) PP_COUNT_IMPL_88
-#define PP_COUNT_IMPL_88(_) PP_COUNT_IMPL_89
-#define PP_COUNT_IMPL_89(_) PP_COUNT_IMPL_90
-#define PP_COUNT_IMPL_90(_) PP_COUNT_IMPL_91
-#define PP_COUNT_IMPL_91(_) PP_COUNT_IMPL_92
-#define PP_COUNT_IMPL_92(_) PP_COUNT_IMPL_93
-#define PP_COUNT_IMPL_93(_) PP_COUNT_IMPL_94
-#define PP_COUNT_IMPL_94(_) PP_COUNT_IMPL_95
-#define PP_COUNT_IMPL_95(_) PP_COUNT_IMPL_96
-#define PP_COUNT_IMPL_96(_) PP_COUNT_IMPL_97
-#define PP_COUNT_IMPL_97(_) PP_COUNT_IMPL_98
-#define PP_COUNT_IMPL_98(_) PP_COUNT_IMPL_99
-#define PP_COUNT_IMPL_99(_) PP_COUNT_IMPL_100
+#define PP_COUNT_IMPL_0(_) PP_COUNT_IMPL_1
+#define PP_COUNT_IMPL_1(_) PP_COUNT_IMPL_2
+#define PP_COUNT_IMPL_2(_) PP_COUNT_IMPL_3
+#define PP_COUNT_IMPL_3(_) PP_COUNT_IMPL_4
+#define PP_COUNT_IMPL_4(_) PP_COUNT_IMPL_5
+#define PP_COUNT_IMPL_5(_) PP_COUNT_IMPL_6
+#define PP_COUNT_IMPL_6(_) PP_COUNT_IMPL_7
+#define PP_COUNT_IMPL_7(_) PP_COUNT_IMPL_8
+#define PP_COUNT_IMPL_8(_) PP_COUNT_IMPL_9
+#define PP_COUNT_IMPL_9(_) PP_COUNT_IMPL_10
+#define PP_COUNT_IMPL_10(_) PP_COUNT_IMPL_11
+#define PP_COUNT_IMPL_11(_) PP_COUNT_IMPL_12
+#define PP_COUNT_IMPL_12(_) PP_COUNT_IMPL_13
+#define PP_COUNT_IMPL_13(_) PP_COUNT_IMPL_14
+#define PP_COUNT_IMPL_14(_) PP_COUNT_IMPL_15
+#define PP_COUNT_IMPL_15(_) PP_COUNT_IMPL_16
+#define PP_COUNT_IMPL_16(_) PP_COUNT_IMPL_17
+#define PP_COUNT_IMPL_17(_) PP_COUNT_IMPL_18
+#define PP_COUNT_IMPL_18(_) PP_COUNT_IMPL_19
+#define PP_COUNT_IMPL_19(_) PP_COUNT_IMPL_20
+#define PP_COUNT_IMPL_20(_) PP_COUNT_IMPL_21
+#define PP_COUNT_IMPL_21(_) PP_COUNT_IMPL_22
+#define PP_COUNT_IMPL_22(_) PP_COUNT_IMPL_23
+#define PP_COUNT_IMPL_23(_) PP_COUNT_IMPL_24
+#define PP_COUNT_IMPL_24(_) PP_COUNT_IMPL_25
+#define PP_COUNT_IMPL_25(_) PP_COUNT_IMPL_26
+#define PP_COUNT_IMPL_26(_) PP_COUNT_IMPL_27
+#define PP_COUNT_IMPL_27(_) PP_COUNT_IMPL_28
+#define PP_COUNT_IMPL_28(_) PP_COUNT_IMPL_29
+#define PP_COUNT_IMPL_29(_) PP_COUNT_IMPL_30
+#define PP_COUNT_IMPL_30(_) PP_COUNT_IMPL_31
+#define PP_COUNT_IMPL_31(_) PP_COUNT_IMPL_32
+#define PP_COUNT_IMPL_32(_) PP_COUNT_IMPL_33
+#define PP_COUNT_IMPL_33(_) PP_COUNT_IMPL_34
+#define PP_COUNT_IMPL_34(_) PP_COUNT_IMPL_35
+#define PP_COUNT_IMPL_35(_) PP_COUNT_IMPL_36
+#define PP_COUNT_IMPL_36(_) PP_COUNT_IMPL_37
+#define PP_COUNT_IMPL_37(_) PP_COUNT_IMPL_38
+#define PP_COUNT_IMPL_38(_) PP_COUNT_IMPL_39
+#define PP_COUNT_IMPL_39(_) PP_COUNT_IMPL_40
+#define PP_COUNT_IMPL_40(_) PP_COUNT_IMPL_41
+#define PP_COUNT_IMPL_41(_) PP_COUNT_IMPL_42
+#define PP_COUNT_IMPL_42(_) PP_COUNT_IMPL_43
+#define PP_COUNT_IMPL_43(_) PP_COUNT_IMPL_44
+#define PP_COUNT_IMPL_44(_) PP_COUNT_IMPL_45
+#define PP_COUNT_IMPL_45(_) PP_COUNT_IMPL_46
+#define PP_COUNT_IMPL_46(_) PP_COUNT_IMPL_47
+#define PP_COUNT_IMPL_47(_) PP_COUNT_IMPL_48
+#define PP_COUNT_IMPL_48(_) PP_COUNT_IMPL_49
+#define PP_COUNT_IMPL_49(_) PP_COUNT_IMPL_50
+#define PP_COUNT_IMPL_50(_) PP_COUNT_IMPL_51
+#define PP_COUNT_IMPL_51(_) PP_COUNT_IMPL_52
+#define PP_COUNT_IMPL_52(_) PP_COUNT_IMPL_53
+#define PP_COUNT_IMPL_53(_) PP_COUNT_IMPL_54
+#define PP_COUNT_IMPL_54(_) PP_COUNT_IMPL_55
+#define PP_COUNT_IMPL_55(_) PP_COUNT_IMPL_56
+#define PP_COUNT_IMPL_56(_) PP_COUNT_IMPL_57
+#define PP_COUNT_IMPL_57(_) PP_COUNT_IMPL_58
+#define PP_COUNT_IMPL_58(_) PP_COUNT_IMPL_59
+#define PP_COUNT_IMPL_59(_) PP_COUNT_IMPL_60
+#define PP_COUNT_IMPL_60(_) PP_COUNT_IMPL_61
+#define PP_COUNT_IMPL_61(_) PP_COUNT_IMPL_62
+#define PP_COUNT_IMPL_62(_) PP_COUNT_IMPL_63
+#define PP_COUNT_IMPL_63(_) PP_COUNT_IMPL_64
+#define PP_COUNT_IMPL_64(_) PP_COUNT_IMPL_65
+#define PP_COUNT_IMPL_65(_) PP_COUNT_IMPL_66
+#define PP_COUNT_IMPL_66(_) PP_COUNT_IMPL_67
+#define PP_COUNT_IMPL_67(_) PP_COUNT_IMPL_68
+#define PP_COUNT_IMPL_68(_) PP_COUNT_IMPL_69
+#define PP_COUNT_IMPL_69(_) PP_COUNT_IMPL_70
+#define PP_COUNT_IMPL_70(_) PP_COUNT_IMPL_71
+#define PP_COUNT_IMPL_71(_) PP_COUNT_IMPL_72
+#define PP_COUNT_IMPL_72(_) PP_COUNT_IMPL_73
+#define PP_COUNT_IMPL_73(_) PP_COUNT_IMPL_74
+#define PP_COUNT_IMPL_74(_) PP_COUNT_IMPL_75
+#define PP_COUNT_IMPL_75(_) PP_COUNT_IMPL_76
+#define PP_COUNT_IMPL_76(_) PP_COUNT_IMPL_77
+#define PP_COUNT_IMPL_77(_) PP_COUNT_IMPL_78
+#define PP_COUNT_IMPL_78(_) PP_COUNT_IMPL_79
+#define PP_COUNT_IMPL_79(_) PP_COUNT_IMPL_80
+#define PP_COUNT_IMPL_80(_) PP_COUNT_IMPL_81
+#define PP_COUNT_IMPL_81(_) PP_COUNT_IMPL_82
+#define PP_COUNT_IMPL_82(_) PP_COUNT_IMPL_83
+#define PP_COUNT_IMPL_83(_) PP_COUNT_IMPL_84
+#define PP_COUNT_IMPL_84(_) PP_COUNT_IMPL_85
+#define PP_COUNT_IMPL_85(_) PP_COUNT_IMPL_86
+#define PP_COUNT_IMPL_86(_) PP_COUNT_IMPL_87
+#define PP_COUNT_IMPL_87(_) PP_COUNT_IMPL_88
+#define PP_COUNT_IMPL_88(_) PP_COUNT_IMPL_89
+#define PP_COUNT_IMPL_89(_) PP_COUNT_IMPL_90
+#define PP_COUNT_IMPL_90(_) PP_COUNT_IMPL_91
+#define PP_COUNT_IMPL_91(_) PP_COUNT_IMPL_92
+#define PP_COUNT_IMPL_92(_) PP_COUNT_IMPL_93
+#define PP_COUNT_IMPL_93(_) PP_COUNT_IMPL_94
+#define PP_COUNT_IMPL_94(_) PP_COUNT_IMPL_95
+#define PP_COUNT_IMPL_95(_) PP_COUNT_IMPL_96
+#define PP_COUNT_IMPL_96(_) PP_COUNT_IMPL_97
+#define PP_COUNT_IMPL_97(_) PP_COUNT_IMPL_98
+#define PP_COUNT_IMPL_98(_) PP_COUNT_IMPL_99
+#define PP_COUNT_IMPL_99(_) PP_COUNT_IMPL_100
#define PP_COUNT_IMPL_100(_) PP_COUNT_IMPL_101
#define PP_COUNT_IMPL_101(_) PP_COUNT_IMPL_102
#define PP_COUNT_IMPL_102(_) PP_COUNT_IMPL_103
@@ -420,110 +420,110 @@
#define PP_COUNT_IMPL_197(_) PP_COUNT_IMPL_198
#define PP_COUNT_IMPL_198(_) PP_COUNT_IMPL_199
#define PP_COUNT_IMPL_199(_) PP_COUNT_IMPL_200
-
-////////////////////////////////////////////////////////////////////////////////
-#define PP_KILL_IMPL(seq, index) PP_CONCAT(PP_KILL_IMPL_, index) seq
-#define PP_KILL_IMPL_0
-#define PP_KILL_IMPL_1(_) PP_KILL_IMPL_0
-#define PP_KILL_IMPL_2(_) PP_KILL_IMPL_1
-#define PP_KILL_IMPL_3(_) PP_KILL_IMPL_2
-#define PP_KILL_IMPL_4(_) PP_KILL_IMPL_3
-#define PP_KILL_IMPL_5(_) PP_KILL_IMPL_4
-#define PP_KILL_IMPL_6(_) PP_KILL_IMPL_5
-#define PP_KILL_IMPL_7(_) PP_KILL_IMPL_6
-#define PP_KILL_IMPL_8(_) PP_KILL_IMPL_7
-#define PP_KILL_IMPL_9(_) PP_KILL_IMPL_8
-#define PP_KILL_IMPL_10(_) PP_KILL_IMPL_9
-#define PP_KILL_IMPL_11(_) PP_KILL_IMPL_10
-#define PP_KILL_IMPL_12(_) PP_KILL_IMPL_11
-#define PP_KILL_IMPL_13(_) PP_KILL_IMPL_12
-#define PP_KILL_IMPL_14(_) PP_KILL_IMPL_13
-#define PP_KILL_IMPL_15(_) PP_KILL_IMPL_14
-#define PP_KILL_IMPL_16(_) PP_KILL_IMPL_15
-#define PP_KILL_IMPL_17(_) PP_KILL_IMPL_16
-#define PP_KILL_IMPL_18(_) PP_KILL_IMPL_17
-#define PP_KILL_IMPL_19(_) PP_KILL_IMPL_18
-#define PP_KILL_IMPL_20(_) PP_KILL_IMPL_19
-#define PP_KILL_IMPL_21(_) PP_KILL_IMPL_20
-#define PP_KILL_IMPL_22(_) PP_KILL_IMPL_21
-#define PP_KILL_IMPL_23(_) PP_KILL_IMPL_22
-#define PP_KILL_IMPL_24(_) PP_KILL_IMPL_23
-#define PP_KILL_IMPL_25(_) PP_KILL_IMPL_24
-#define PP_KILL_IMPL_26(_) PP_KILL_IMPL_25
-#define PP_KILL_IMPL_27(_) PP_KILL_IMPL_26
-#define PP_KILL_IMPL_28(_) PP_KILL_IMPL_27
-#define PP_KILL_IMPL_29(_) PP_KILL_IMPL_28
-#define PP_KILL_IMPL_30(_) PP_KILL_IMPL_29
-#define PP_KILL_IMPL_31(_) PP_KILL_IMPL_30
-#define PP_KILL_IMPL_32(_) PP_KILL_IMPL_31
-#define PP_KILL_IMPL_33(_) PP_KILL_IMPL_32
-#define PP_KILL_IMPL_34(_) PP_KILL_IMPL_33
-#define PP_KILL_IMPL_35(_) PP_KILL_IMPL_34
-#define PP_KILL_IMPL_36(_) PP_KILL_IMPL_35
-#define PP_KILL_IMPL_37(_) PP_KILL_IMPL_36
-#define PP_KILL_IMPL_38(_) PP_KILL_IMPL_37
-#define PP_KILL_IMPL_39(_) PP_KILL_IMPL_38
-#define PP_KILL_IMPL_40(_) PP_KILL_IMPL_39
-#define PP_KILL_IMPL_41(_) PP_KILL_IMPL_40
-#define PP_KILL_IMPL_42(_) PP_KILL_IMPL_41
-#define PP_KILL_IMPL_43(_) PP_KILL_IMPL_42
-#define PP_KILL_IMPL_44(_) PP_KILL_IMPL_43
-#define PP_KILL_IMPL_45(_) PP_KILL_IMPL_44
-#define PP_KILL_IMPL_46(_) PP_KILL_IMPL_45
-#define PP_KILL_IMPL_47(_) PP_KILL_IMPL_46
-#define PP_KILL_IMPL_48(_) PP_KILL_IMPL_47
-#define PP_KILL_IMPL_49(_) PP_KILL_IMPL_48
-#define PP_KILL_IMPL_50(_) PP_KILL_IMPL_49
-#define PP_KILL_IMPL_51(_) PP_KILL_IMPL_50
-#define PP_KILL_IMPL_52(_) PP_KILL_IMPL_51
-#define PP_KILL_IMPL_53(_) PP_KILL_IMPL_52
-#define PP_KILL_IMPL_54(_) PP_KILL_IMPL_53
-#define PP_KILL_IMPL_55(_) PP_KILL_IMPL_54
-#define PP_KILL_IMPL_56(_) PP_KILL_IMPL_55
-#define PP_KILL_IMPL_57(_) PP_KILL_IMPL_56
-#define PP_KILL_IMPL_58(_) PP_KILL_IMPL_57
-#define PP_KILL_IMPL_59(_) PP_KILL_IMPL_58
-#define PP_KILL_IMPL_60(_) PP_KILL_IMPL_59
-#define PP_KILL_IMPL_61(_) PP_KILL_IMPL_60
-#define PP_KILL_IMPL_62(_) PP_KILL_IMPL_61
-#define PP_KILL_IMPL_63(_) PP_KILL_IMPL_62
-#define PP_KILL_IMPL_64(_) PP_KILL_IMPL_63
-#define PP_KILL_IMPL_65(_) PP_KILL_IMPL_64
-#define PP_KILL_IMPL_66(_) PP_KILL_IMPL_65
-#define PP_KILL_IMPL_67(_) PP_KILL_IMPL_66
-#define PP_KILL_IMPL_68(_) PP_KILL_IMPL_67
-#define PP_KILL_IMPL_69(_) PP_KILL_IMPL_68
-#define PP_KILL_IMPL_70(_) PP_KILL_IMPL_69
-#define PP_KILL_IMPL_71(_) PP_KILL_IMPL_70
-#define PP_KILL_IMPL_72(_) PP_KILL_IMPL_71
-#define PP_KILL_IMPL_73(_) PP_KILL_IMPL_72
-#define PP_KILL_IMPL_74(_) PP_KILL_IMPL_73
-#define PP_KILL_IMPL_75(_) PP_KILL_IMPL_74
-#define PP_KILL_IMPL_76(_) PP_KILL_IMPL_75
-#define PP_KILL_IMPL_77(_) PP_KILL_IMPL_76
-#define PP_KILL_IMPL_78(_) PP_KILL_IMPL_77
-#define PP_KILL_IMPL_79(_) PP_KILL_IMPL_78
-#define PP_KILL_IMPL_80(_) PP_KILL_IMPL_79
-#define PP_KILL_IMPL_81(_) PP_KILL_IMPL_80
-#define PP_KILL_IMPL_82(_) PP_KILL_IMPL_81
-#define PP_KILL_IMPL_83(_) PP_KILL_IMPL_82
-#define PP_KILL_IMPL_84(_) PP_KILL_IMPL_83
-#define PP_KILL_IMPL_85(_) PP_KILL_IMPL_84
-#define PP_KILL_IMPL_86(_) PP_KILL_IMPL_85
-#define PP_KILL_IMPL_87(_) PP_KILL_IMPL_86
-#define PP_KILL_IMPL_88(_) PP_KILL_IMPL_87
-#define PP_KILL_IMPL_89(_) PP_KILL_IMPL_88
-#define PP_KILL_IMPL_90(_) PP_KILL_IMPL_89
-#define PP_KILL_IMPL_91(_) PP_KILL_IMPL_90
-#define PP_KILL_IMPL_92(_) PP_KILL_IMPL_91
-#define PP_KILL_IMPL_93(_) PP_KILL_IMPL_92
-#define PP_KILL_IMPL_94(_) PP_KILL_IMPL_93
-#define PP_KILL_IMPL_95(_) PP_KILL_IMPL_94
-#define PP_KILL_IMPL_96(_) PP_KILL_IMPL_95
-#define PP_KILL_IMPL_97(_) PP_KILL_IMPL_96
-#define PP_KILL_IMPL_98(_) PP_KILL_IMPL_97
-#define PP_KILL_IMPL_99(_) PP_KILL_IMPL_98
-#define PP_KILL_IMPL_100(_) PP_KILL_IMPL_99
+
+////////////////////////////////////////////////////////////////////////////////
+#define PP_KILL_IMPL(seq, index) PP_CONCAT(PP_KILL_IMPL_, index) seq
+#define PP_KILL_IMPL_0
+#define PP_KILL_IMPL_1(_) PP_KILL_IMPL_0
+#define PP_KILL_IMPL_2(_) PP_KILL_IMPL_1
+#define PP_KILL_IMPL_3(_) PP_KILL_IMPL_2
+#define PP_KILL_IMPL_4(_) PP_KILL_IMPL_3
+#define PP_KILL_IMPL_5(_) PP_KILL_IMPL_4
+#define PP_KILL_IMPL_6(_) PP_KILL_IMPL_5
+#define PP_KILL_IMPL_7(_) PP_KILL_IMPL_6
+#define PP_KILL_IMPL_8(_) PP_KILL_IMPL_7
+#define PP_KILL_IMPL_9(_) PP_KILL_IMPL_8
+#define PP_KILL_IMPL_10(_) PP_KILL_IMPL_9
+#define PP_KILL_IMPL_11(_) PP_KILL_IMPL_10
+#define PP_KILL_IMPL_12(_) PP_KILL_IMPL_11
+#define PP_KILL_IMPL_13(_) PP_KILL_IMPL_12
+#define PP_KILL_IMPL_14(_) PP_KILL_IMPL_13
+#define PP_KILL_IMPL_15(_) PP_KILL_IMPL_14
+#define PP_KILL_IMPL_16(_) PP_KILL_IMPL_15
+#define PP_KILL_IMPL_17(_) PP_KILL_IMPL_16
+#define PP_KILL_IMPL_18(_) PP_KILL_IMPL_17
+#define PP_KILL_IMPL_19(_) PP_KILL_IMPL_18
+#define PP_KILL_IMPL_20(_) PP_KILL_IMPL_19
+#define PP_KILL_IMPL_21(_) PP_KILL_IMPL_20
+#define PP_KILL_IMPL_22(_) PP_KILL_IMPL_21
+#define PP_KILL_IMPL_23(_) PP_KILL_IMPL_22
+#define PP_KILL_IMPL_24(_) PP_KILL_IMPL_23
+#define PP_KILL_IMPL_25(_) PP_KILL_IMPL_24
+#define PP_KILL_IMPL_26(_) PP_KILL_IMPL_25
+#define PP_KILL_IMPL_27(_) PP_KILL_IMPL_26
+#define PP_KILL_IMPL_28(_) PP_KILL_IMPL_27
+#define PP_KILL_IMPL_29(_) PP_KILL_IMPL_28
+#define PP_KILL_IMPL_30(_) PP_KILL_IMPL_29
+#define PP_KILL_IMPL_31(_) PP_KILL_IMPL_30
+#define PP_KILL_IMPL_32(_) PP_KILL_IMPL_31
+#define PP_KILL_IMPL_33(_) PP_KILL_IMPL_32
+#define PP_KILL_IMPL_34(_) PP_KILL_IMPL_33
+#define PP_KILL_IMPL_35(_) PP_KILL_IMPL_34
+#define PP_KILL_IMPL_36(_) PP_KILL_IMPL_35
+#define PP_KILL_IMPL_37(_) PP_KILL_IMPL_36
+#define PP_KILL_IMPL_38(_) PP_KILL_IMPL_37
+#define PP_KILL_IMPL_39(_) PP_KILL_IMPL_38
+#define PP_KILL_IMPL_40(_) PP_KILL_IMPL_39
+#define PP_KILL_IMPL_41(_) PP_KILL_IMPL_40
+#define PP_KILL_IMPL_42(_) PP_KILL_IMPL_41
+#define PP_KILL_IMPL_43(_) PP_KILL_IMPL_42
+#define PP_KILL_IMPL_44(_) PP_KILL_IMPL_43
+#define PP_KILL_IMPL_45(_) PP_KILL_IMPL_44
+#define PP_KILL_IMPL_46(_) PP_KILL_IMPL_45
+#define PP_KILL_IMPL_47(_) PP_KILL_IMPL_46
+#define PP_KILL_IMPL_48(_) PP_KILL_IMPL_47
+#define PP_KILL_IMPL_49(_) PP_KILL_IMPL_48
+#define PP_KILL_IMPL_50(_) PP_KILL_IMPL_49
+#define PP_KILL_IMPL_51(_) PP_KILL_IMPL_50
+#define PP_KILL_IMPL_52(_) PP_KILL_IMPL_51
+#define PP_KILL_IMPL_53(_) PP_KILL_IMPL_52
+#define PP_KILL_IMPL_54(_) PP_KILL_IMPL_53
+#define PP_KILL_IMPL_55(_) PP_KILL_IMPL_54
+#define PP_KILL_IMPL_56(_) PP_KILL_IMPL_55
+#define PP_KILL_IMPL_57(_) PP_KILL_IMPL_56
+#define PP_KILL_IMPL_58(_) PP_KILL_IMPL_57
+#define PP_KILL_IMPL_59(_) PP_KILL_IMPL_58
+#define PP_KILL_IMPL_60(_) PP_KILL_IMPL_59
+#define PP_KILL_IMPL_61(_) PP_KILL_IMPL_60
+#define PP_KILL_IMPL_62(_) PP_KILL_IMPL_61
+#define PP_KILL_IMPL_63(_) PP_KILL_IMPL_62
+#define PP_KILL_IMPL_64(_) PP_KILL_IMPL_63
+#define PP_KILL_IMPL_65(_) PP_KILL_IMPL_64
+#define PP_KILL_IMPL_66(_) PP_KILL_IMPL_65
+#define PP_KILL_IMPL_67(_) PP_KILL_IMPL_66
+#define PP_KILL_IMPL_68(_) PP_KILL_IMPL_67
+#define PP_KILL_IMPL_69(_) PP_KILL_IMPL_68
+#define PP_KILL_IMPL_70(_) PP_KILL_IMPL_69
+#define PP_KILL_IMPL_71(_) PP_KILL_IMPL_70
+#define PP_KILL_IMPL_72(_) PP_KILL_IMPL_71
+#define PP_KILL_IMPL_73(_) PP_KILL_IMPL_72
+#define PP_KILL_IMPL_74(_) PP_KILL_IMPL_73
+#define PP_KILL_IMPL_75(_) PP_KILL_IMPL_74
+#define PP_KILL_IMPL_76(_) PP_KILL_IMPL_75
+#define PP_KILL_IMPL_77(_) PP_KILL_IMPL_76
+#define PP_KILL_IMPL_78(_) PP_KILL_IMPL_77
+#define PP_KILL_IMPL_79(_) PP_KILL_IMPL_78
+#define PP_KILL_IMPL_80(_) PP_KILL_IMPL_79
+#define PP_KILL_IMPL_81(_) PP_KILL_IMPL_80
+#define PP_KILL_IMPL_82(_) PP_KILL_IMPL_81
+#define PP_KILL_IMPL_83(_) PP_KILL_IMPL_82
+#define PP_KILL_IMPL_84(_) PP_KILL_IMPL_83
+#define PP_KILL_IMPL_85(_) PP_KILL_IMPL_84
+#define PP_KILL_IMPL_86(_) PP_KILL_IMPL_85
+#define PP_KILL_IMPL_87(_) PP_KILL_IMPL_86
+#define PP_KILL_IMPL_88(_) PP_KILL_IMPL_87
+#define PP_KILL_IMPL_89(_) PP_KILL_IMPL_88
+#define PP_KILL_IMPL_90(_) PP_KILL_IMPL_89
+#define PP_KILL_IMPL_91(_) PP_KILL_IMPL_90
+#define PP_KILL_IMPL_92(_) PP_KILL_IMPL_91
+#define PP_KILL_IMPL_93(_) PP_KILL_IMPL_92
+#define PP_KILL_IMPL_94(_) PP_KILL_IMPL_93
+#define PP_KILL_IMPL_95(_) PP_KILL_IMPL_94
+#define PP_KILL_IMPL_96(_) PP_KILL_IMPL_95
+#define PP_KILL_IMPL_97(_) PP_KILL_IMPL_96
+#define PP_KILL_IMPL_98(_) PP_KILL_IMPL_97
+#define PP_KILL_IMPL_99(_) PP_KILL_IMPL_98
+#define PP_KILL_IMPL_100(_) PP_KILL_IMPL_99
#define PP_KILL_IMPL_101(_) PP_KILL_IMPL_100
#define PP_KILL_IMPL_102(_) PP_KILL_IMPL_101
#define PP_KILL_IMPL_103(_) PP_KILL_IMPL_102
@@ -624,114 +624,114 @@
#define PP_KILL_IMPL_198(_) PP_KILL_IMPL_197
#define PP_KILL_IMPL_199(_) PP_KILL_IMPL_198
#define PP_KILL_IMPL_200(_) PP_KILL_IMPL_199
-
-////////////////////////////////////////////////////////////////////////////////
-#define PP_ELEMENT_IMPL(seq, \
- index) PP_ELEMENT_IMPL_A((PP_CONCAT(PP_ELEMENT_IMPL_, index) seq))
-#define PP_ELEMENT_IMPL_A(x) PP_ELEMENT_IMPL_C(PP_ELEMENT_IMPL_B x)
-#define PP_ELEMENT_IMPL_B(x, _) x
-#define PP_ELEMENT_IMPL_C(x) x
-#define PP_ELEMENT_IMPL_0(x) x, PP_NIL
-#define PP_ELEMENT_IMPL_1(_) PP_ELEMENT_IMPL_0
-#define PP_ELEMENT_IMPL_2(_) PP_ELEMENT_IMPL_1
-#define PP_ELEMENT_IMPL_3(_) PP_ELEMENT_IMPL_2
-#define PP_ELEMENT_IMPL_4(_) PP_ELEMENT_IMPL_3
-#define PP_ELEMENT_IMPL_5(_) PP_ELEMENT_IMPL_4
-#define PP_ELEMENT_IMPL_6(_) PP_ELEMENT_IMPL_5
-#define PP_ELEMENT_IMPL_7(_) PP_ELEMENT_IMPL_6
-#define PP_ELEMENT_IMPL_8(_) PP_ELEMENT_IMPL_7
-#define PP_ELEMENT_IMPL_9(_) PP_ELEMENT_IMPL_8
-#define PP_ELEMENT_IMPL_10(_) PP_ELEMENT_IMPL_9
-#define PP_ELEMENT_IMPL_11(_) PP_ELEMENT_IMPL_10
-#define PP_ELEMENT_IMPL_12(_) PP_ELEMENT_IMPL_11
-#define PP_ELEMENT_IMPL_13(_) PP_ELEMENT_IMPL_12
-#define PP_ELEMENT_IMPL_14(_) PP_ELEMENT_IMPL_13
-#define PP_ELEMENT_IMPL_15(_) PP_ELEMENT_IMPL_14
-#define PP_ELEMENT_IMPL_16(_) PP_ELEMENT_IMPL_15
-#define PP_ELEMENT_IMPL_17(_) PP_ELEMENT_IMPL_16
-#define PP_ELEMENT_IMPL_18(_) PP_ELEMENT_IMPL_17
-#define PP_ELEMENT_IMPL_19(_) PP_ELEMENT_IMPL_18
-#define PP_ELEMENT_IMPL_20(_) PP_ELEMENT_IMPL_19
-#define PP_ELEMENT_IMPL_21(_) PP_ELEMENT_IMPL_20
-#define PP_ELEMENT_IMPL_22(_) PP_ELEMENT_IMPL_21
-#define PP_ELEMENT_IMPL_23(_) PP_ELEMENT_IMPL_22
-#define PP_ELEMENT_IMPL_24(_) PP_ELEMENT_IMPL_23
-#define PP_ELEMENT_IMPL_25(_) PP_ELEMENT_IMPL_24
-#define PP_ELEMENT_IMPL_26(_) PP_ELEMENT_IMPL_25
-#define PP_ELEMENT_IMPL_27(_) PP_ELEMENT_IMPL_26
-#define PP_ELEMENT_IMPL_28(_) PP_ELEMENT_IMPL_27
-#define PP_ELEMENT_IMPL_29(_) PP_ELEMENT_IMPL_28
-#define PP_ELEMENT_IMPL_30(_) PP_ELEMENT_IMPL_29
-#define PP_ELEMENT_IMPL_31(_) PP_ELEMENT_IMPL_30
-#define PP_ELEMENT_IMPL_32(_) PP_ELEMENT_IMPL_31
-#define PP_ELEMENT_IMPL_33(_) PP_ELEMENT_IMPL_32
-#define PP_ELEMENT_IMPL_34(_) PP_ELEMENT_IMPL_33
-#define PP_ELEMENT_IMPL_35(_) PP_ELEMENT_IMPL_34
-#define PP_ELEMENT_IMPL_36(_) PP_ELEMENT_IMPL_35
-#define PP_ELEMENT_IMPL_37(_) PP_ELEMENT_IMPL_36
-#define PP_ELEMENT_IMPL_38(_) PP_ELEMENT_IMPL_37
-#define PP_ELEMENT_IMPL_39(_) PP_ELEMENT_IMPL_38
-#define PP_ELEMENT_IMPL_40(_) PP_ELEMENT_IMPL_39
-#define PP_ELEMENT_IMPL_41(_) PP_ELEMENT_IMPL_40
-#define PP_ELEMENT_IMPL_42(_) PP_ELEMENT_IMPL_41
-#define PP_ELEMENT_IMPL_43(_) PP_ELEMENT_IMPL_42
-#define PP_ELEMENT_IMPL_44(_) PP_ELEMENT_IMPL_43
-#define PP_ELEMENT_IMPL_45(_) PP_ELEMENT_IMPL_44
-#define PP_ELEMENT_IMPL_46(_) PP_ELEMENT_IMPL_45
-#define PP_ELEMENT_IMPL_47(_) PP_ELEMENT_IMPL_46
-#define PP_ELEMENT_IMPL_48(_) PP_ELEMENT_IMPL_47
-#define PP_ELEMENT_IMPL_49(_) PP_ELEMENT_IMPL_48
-#define PP_ELEMENT_IMPL_50(_) PP_ELEMENT_IMPL_49
-#define PP_ELEMENT_IMPL_51(_) PP_ELEMENT_IMPL_50
-#define PP_ELEMENT_IMPL_52(_) PP_ELEMENT_IMPL_51
-#define PP_ELEMENT_IMPL_53(_) PP_ELEMENT_IMPL_52
-#define PP_ELEMENT_IMPL_54(_) PP_ELEMENT_IMPL_53
-#define PP_ELEMENT_IMPL_55(_) PP_ELEMENT_IMPL_54
-#define PP_ELEMENT_IMPL_56(_) PP_ELEMENT_IMPL_55
-#define PP_ELEMENT_IMPL_57(_) PP_ELEMENT_IMPL_56
-#define PP_ELEMENT_IMPL_58(_) PP_ELEMENT_IMPL_57
-#define PP_ELEMENT_IMPL_59(_) PP_ELEMENT_IMPL_58
-#define PP_ELEMENT_IMPL_60(_) PP_ELEMENT_IMPL_59
-#define PP_ELEMENT_IMPL_61(_) PP_ELEMENT_IMPL_60
-#define PP_ELEMENT_IMPL_62(_) PP_ELEMENT_IMPL_61
-#define PP_ELEMENT_IMPL_63(_) PP_ELEMENT_IMPL_62
-#define PP_ELEMENT_IMPL_64(_) PP_ELEMENT_IMPL_63
-#define PP_ELEMENT_IMPL_65(_) PP_ELEMENT_IMPL_64
-#define PP_ELEMENT_IMPL_66(_) PP_ELEMENT_IMPL_65
-#define PP_ELEMENT_IMPL_67(_) PP_ELEMENT_IMPL_66
-#define PP_ELEMENT_IMPL_68(_) PP_ELEMENT_IMPL_67
-#define PP_ELEMENT_IMPL_69(_) PP_ELEMENT_IMPL_68
-#define PP_ELEMENT_IMPL_70(_) PP_ELEMENT_IMPL_69
-#define PP_ELEMENT_IMPL_71(_) PP_ELEMENT_IMPL_70
-#define PP_ELEMENT_IMPL_72(_) PP_ELEMENT_IMPL_71
-#define PP_ELEMENT_IMPL_73(_) PP_ELEMENT_IMPL_72
-#define PP_ELEMENT_IMPL_74(_) PP_ELEMENT_IMPL_73
-#define PP_ELEMENT_IMPL_75(_) PP_ELEMENT_IMPL_74
-#define PP_ELEMENT_IMPL_76(_) PP_ELEMENT_IMPL_75
-#define PP_ELEMENT_IMPL_77(_) PP_ELEMENT_IMPL_76
-#define PP_ELEMENT_IMPL_78(_) PP_ELEMENT_IMPL_77
-#define PP_ELEMENT_IMPL_79(_) PP_ELEMENT_IMPL_78
-#define PP_ELEMENT_IMPL_80(_) PP_ELEMENT_IMPL_79
-#define PP_ELEMENT_IMPL_81(_) PP_ELEMENT_IMPL_80
-#define PP_ELEMENT_IMPL_82(_) PP_ELEMENT_IMPL_81
-#define PP_ELEMENT_IMPL_83(_) PP_ELEMENT_IMPL_82
-#define PP_ELEMENT_IMPL_84(_) PP_ELEMENT_IMPL_83
-#define PP_ELEMENT_IMPL_85(_) PP_ELEMENT_IMPL_84
-#define PP_ELEMENT_IMPL_86(_) PP_ELEMENT_IMPL_85
-#define PP_ELEMENT_IMPL_87(_) PP_ELEMENT_IMPL_86
-#define PP_ELEMENT_IMPL_88(_) PP_ELEMENT_IMPL_87
-#define PP_ELEMENT_IMPL_89(_) PP_ELEMENT_IMPL_88
-#define PP_ELEMENT_IMPL_90(_) PP_ELEMENT_IMPL_89
-#define PP_ELEMENT_IMPL_91(_) PP_ELEMENT_IMPL_90
-#define PP_ELEMENT_IMPL_92(_) PP_ELEMENT_IMPL_91
-#define PP_ELEMENT_IMPL_93(_) PP_ELEMENT_IMPL_92
-#define PP_ELEMENT_IMPL_94(_) PP_ELEMENT_IMPL_93
-#define PP_ELEMENT_IMPL_95(_) PP_ELEMENT_IMPL_94
-#define PP_ELEMENT_IMPL_96(_) PP_ELEMENT_IMPL_95
-#define PP_ELEMENT_IMPL_97(_) PP_ELEMENT_IMPL_96
-#define PP_ELEMENT_IMPL_98(_) PP_ELEMENT_IMPL_97
-#define PP_ELEMENT_IMPL_99(_) PP_ELEMENT_IMPL_98
-#define PP_ELEMENT_IMPL_100(_) PP_ELEMENT_IMPL_99
+
+////////////////////////////////////////////////////////////////////////////////
+#define PP_ELEMENT_IMPL(seq, \
+ index) PP_ELEMENT_IMPL_A((PP_CONCAT(PP_ELEMENT_IMPL_, index) seq))
+#define PP_ELEMENT_IMPL_A(x) PP_ELEMENT_IMPL_C(PP_ELEMENT_IMPL_B x)
+#define PP_ELEMENT_IMPL_B(x, _) x
+#define PP_ELEMENT_IMPL_C(x) x
+#define PP_ELEMENT_IMPL_0(x) x, PP_NIL
+#define PP_ELEMENT_IMPL_1(_) PP_ELEMENT_IMPL_0
+#define PP_ELEMENT_IMPL_2(_) PP_ELEMENT_IMPL_1
+#define PP_ELEMENT_IMPL_3(_) PP_ELEMENT_IMPL_2
+#define PP_ELEMENT_IMPL_4(_) PP_ELEMENT_IMPL_3
+#define PP_ELEMENT_IMPL_5(_) PP_ELEMENT_IMPL_4
+#define PP_ELEMENT_IMPL_6(_) PP_ELEMENT_IMPL_5
+#define PP_ELEMENT_IMPL_7(_) PP_ELEMENT_IMPL_6
+#define PP_ELEMENT_IMPL_8(_) PP_ELEMENT_IMPL_7
+#define PP_ELEMENT_IMPL_9(_) PP_ELEMENT_IMPL_8
+#define PP_ELEMENT_IMPL_10(_) PP_ELEMENT_IMPL_9
+#define PP_ELEMENT_IMPL_11(_) PP_ELEMENT_IMPL_10
+#define PP_ELEMENT_IMPL_12(_) PP_ELEMENT_IMPL_11
+#define PP_ELEMENT_IMPL_13(_) PP_ELEMENT_IMPL_12
+#define PP_ELEMENT_IMPL_14(_) PP_ELEMENT_IMPL_13
+#define PP_ELEMENT_IMPL_15(_) PP_ELEMENT_IMPL_14
+#define PP_ELEMENT_IMPL_16(_) PP_ELEMENT_IMPL_15
+#define PP_ELEMENT_IMPL_17(_) PP_ELEMENT_IMPL_16
+#define PP_ELEMENT_IMPL_18(_) PP_ELEMENT_IMPL_17
+#define PP_ELEMENT_IMPL_19(_) PP_ELEMENT_IMPL_18
+#define PP_ELEMENT_IMPL_20(_) PP_ELEMENT_IMPL_19
+#define PP_ELEMENT_IMPL_21(_) PP_ELEMENT_IMPL_20
+#define PP_ELEMENT_IMPL_22(_) PP_ELEMENT_IMPL_21
+#define PP_ELEMENT_IMPL_23(_) PP_ELEMENT_IMPL_22
+#define PP_ELEMENT_IMPL_24(_) PP_ELEMENT_IMPL_23
+#define PP_ELEMENT_IMPL_25(_) PP_ELEMENT_IMPL_24
+#define PP_ELEMENT_IMPL_26(_) PP_ELEMENT_IMPL_25
+#define PP_ELEMENT_IMPL_27(_) PP_ELEMENT_IMPL_26
+#define PP_ELEMENT_IMPL_28(_) PP_ELEMENT_IMPL_27
+#define PP_ELEMENT_IMPL_29(_) PP_ELEMENT_IMPL_28
+#define PP_ELEMENT_IMPL_30(_) PP_ELEMENT_IMPL_29
+#define PP_ELEMENT_IMPL_31(_) PP_ELEMENT_IMPL_30
+#define PP_ELEMENT_IMPL_32(_) PP_ELEMENT_IMPL_31
+#define PP_ELEMENT_IMPL_33(_) PP_ELEMENT_IMPL_32
+#define PP_ELEMENT_IMPL_34(_) PP_ELEMENT_IMPL_33
+#define PP_ELEMENT_IMPL_35(_) PP_ELEMENT_IMPL_34
+#define PP_ELEMENT_IMPL_36(_) PP_ELEMENT_IMPL_35
+#define PP_ELEMENT_IMPL_37(_) PP_ELEMENT_IMPL_36
+#define PP_ELEMENT_IMPL_38(_) PP_ELEMENT_IMPL_37
+#define PP_ELEMENT_IMPL_39(_) PP_ELEMENT_IMPL_38
+#define PP_ELEMENT_IMPL_40(_) PP_ELEMENT_IMPL_39
+#define PP_ELEMENT_IMPL_41(_) PP_ELEMENT_IMPL_40
+#define PP_ELEMENT_IMPL_42(_) PP_ELEMENT_IMPL_41
+#define PP_ELEMENT_IMPL_43(_) PP_ELEMENT_IMPL_42
+#define PP_ELEMENT_IMPL_44(_) PP_ELEMENT_IMPL_43
+#define PP_ELEMENT_IMPL_45(_) PP_ELEMENT_IMPL_44
+#define PP_ELEMENT_IMPL_46(_) PP_ELEMENT_IMPL_45
+#define PP_ELEMENT_IMPL_47(_) PP_ELEMENT_IMPL_46
+#define PP_ELEMENT_IMPL_48(_) PP_ELEMENT_IMPL_47
+#define PP_ELEMENT_IMPL_49(_) PP_ELEMENT_IMPL_48
+#define PP_ELEMENT_IMPL_50(_) PP_ELEMENT_IMPL_49
+#define PP_ELEMENT_IMPL_51(_) PP_ELEMENT_IMPL_50
+#define PP_ELEMENT_IMPL_52(_) PP_ELEMENT_IMPL_51
+#define PP_ELEMENT_IMPL_53(_) PP_ELEMENT_IMPL_52
+#define PP_ELEMENT_IMPL_54(_) PP_ELEMENT_IMPL_53
+#define PP_ELEMENT_IMPL_55(_) PP_ELEMENT_IMPL_54
+#define PP_ELEMENT_IMPL_56(_) PP_ELEMENT_IMPL_55
+#define PP_ELEMENT_IMPL_57(_) PP_ELEMENT_IMPL_56
+#define PP_ELEMENT_IMPL_58(_) PP_ELEMENT_IMPL_57
+#define PP_ELEMENT_IMPL_59(_) PP_ELEMENT_IMPL_58
+#define PP_ELEMENT_IMPL_60(_) PP_ELEMENT_IMPL_59
+#define PP_ELEMENT_IMPL_61(_) PP_ELEMENT_IMPL_60
+#define PP_ELEMENT_IMPL_62(_) PP_ELEMENT_IMPL_61
+#define PP_ELEMENT_IMPL_63(_) PP_ELEMENT_IMPL_62
+#define PP_ELEMENT_IMPL_64(_) PP_ELEMENT_IMPL_63
+#define PP_ELEMENT_IMPL_65(_) PP_ELEMENT_IMPL_64
+#define PP_ELEMENT_IMPL_66(_) PP_ELEMENT_IMPL_65
+#define PP_ELEMENT_IMPL_67(_) PP_ELEMENT_IMPL_66
+#define PP_ELEMENT_IMPL_68(_) PP_ELEMENT_IMPL_67
+#define PP_ELEMENT_IMPL_69(_) PP_ELEMENT_IMPL_68
+#define PP_ELEMENT_IMPL_70(_) PP_ELEMENT_IMPL_69
+#define PP_ELEMENT_IMPL_71(_) PP_ELEMENT_IMPL_70
+#define PP_ELEMENT_IMPL_72(_) PP_ELEMENT_IMPL_71
+#define PP_ELEMENT_IMPL_73(_) PP_ELEMENT_IMPL_72
+#define PP_ELEMENT_IMPL_74(_) PP_ELEMENT_IMPL_73
+#define PP_ELEMENT_IMPL_75(_) PP_ELEMENT_IMPL_74
+#define PP_ELEMENT_IMPL_76(_) PP_ELEMENT_IMPL_75
+#define PP_ELEMENT_IMPL_77(_) PP_ELEMENT_IMPL_76
+#define PP_ELEMENT_IMPL_78(_) PP_ELEMENT_IMPL_77
+#define PP_ELEMENT_IMPL_79(_) PP_ELEMENT_IMPL_78
+#define PP_ELEMENT_IMPL_80(_) PP_ELEMENT_IMPL_79
+#define PP_ELEMENT_IMPL_81(_) PP_ELEMENT_IMPL_80
+#define PP_ELEMENT_IMPL_82(_) PP_ELEMENT_IMPL_81
+#define PP_ELEMENT_IMPL_83(_) PP_ELEMENT_IMPL_82
+#define PP_ELEMENT_IMPL_84(_) PP_ELEMENT_IMPL_83
+#define PP_ELEMENT_IMPL_85(_) PP_ELEMENT_IMPL_84
+#define PP_ELEMENT_IMPL_86(_) PP_ELEMENT_IMPL_85
+#define PP_ELEMENT_IMPL_87(_) PP_ELEMENT_IMPL_86
+#define PP_ELEMENT_IMPL_88(_) PP_ELEMENT_IMPL_87
+#define PP_ELEMENT_IMPL_89(_) PP_ELEMENT_IMPL_88
+#define PP_ELEMENT_IMPL_90(_) PP_ELEMENT_IMPL_89
+#define PP_ELEMENT_IMPL_91(_) PP_ELEMENT_IMPL_90
+#define PP_ELEMENT_IMPL_92(_) PP_ELEMENT_IMPL_91
+#define PP_ELEMENT_IMPL_93(_) PP_ELEMENT_IMPL_92
+#define PP_ELEMENT_IMPL_94(_) PP_ELEMENT_IMPL_93
+#define PP_ELEMENT_IMPL_95(_) PP_ELEMENT_IMPL_94
+#define PP_ELEMENT_IMPL_96(_) PP_ELEMENT_IMPL_95
+#define PP_ELEMENT_IMPL_97(_) PP_ELEMENT_IMPL_96
+#define PP_ELEMENT_IMPL_98(_) PP_ELEMENT_IMPL_97
+#define PP_ELEMENT_IMPL_99(_) PP_ELEMENT_IMPL_98
+#define PP_ELEMENT_IMPL_100(_) PP_ELEMENT_IMPL_99
#define PP_ELEMENT_IMPL_101(_) PP_ELEMENT_IMPL_100
#define PP_ELEMENT_IMPL_102(_) PP_ELEMENT_IMPL_101
#define PP_ELEMENT_IMPL_103(_) PP_ELEMENT_IMPL_102
@@ -832,217 +832,217 @@
#define PP_ELEMENT_IMPL_198(_) PP_ELEMENT_IMPL_197
#define PP_ELEMENT_IMPL_199(_) PP_ELEMENT_IMPL_198
#define PP_ELEMENT_IMPL_200(_) PP_ELEMENT_IMPL_199
-
-////////////////////////////////////////////////////////////////////////////////
-#define PP_HEAD_IMPL(seq) PP_ELEMENT_IMPL(seq, 0)
-
-////////////////////////////////////////////////////////////////////////////////
-#define PP_TAIL_IMPL(seq) PP_KILL_IMPL(seq, 1)
-
-////////////////////////////////////////////////////////////////////////////////
-#define PP_FOR_EACH_IMPL(what, seq) PP_CONCAT(PP_FOR_EACH_IMPL_, \
- PP_COUNT(seq))(what, seq)
-#define PP_FOR_EACH_IMPL_0(what, seq)
-#define PP_FOR_EACH_IMPL_1(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_0(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_2(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_1(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_3(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_2(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_4(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_3(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_5(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_4(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_6(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_5(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_7(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_6(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_8(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_7(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_9(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_8(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_10(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_9(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_11(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_10(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_12(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_11(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_13(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_12(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_14(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_13(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_15(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_14(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_16(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_15(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_17(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_16(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_18(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_17(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_19(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_18(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_20(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_19(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_21(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_20(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_22(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_21(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_23(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_22(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_24(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_23(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_25(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_24(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_26(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_25(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_27(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_26(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_28(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_27(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_29(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_28(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_30(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_29(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_31(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_30(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_32(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_31(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_33(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_32(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_34(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_33(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_35(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_34(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_36(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_35(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_37(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_36(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_38(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_37(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_39(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_38(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_40(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_39(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_41(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_40(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_42(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_41(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_43(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_42(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_44(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_43(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_45(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_44(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_46(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_45(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_47(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_46(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_48(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_47(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_49(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_48(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_50(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_49(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_51(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_50(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_52(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_51(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_53(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_52(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_54(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_53(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_55(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_54(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_56(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_55(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_57(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_56(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_58(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_57(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_59(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_58(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_60(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_59(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_61(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_60(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_62(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_61(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_63(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_62(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_64(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_63(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_65(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_64(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_66(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_65(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_67(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_66(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_68(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_67(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_69(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_68(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_70(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_69(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_71(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_70(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_72(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_71(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_73(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_72(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_74(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_73(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_75(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_74(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_76(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_75(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_77(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_76(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_78(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_77(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_79(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_78(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_80(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_79(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_81(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_80(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_82(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_81(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_83(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_82(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_84(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_83(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_85(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_84(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_86(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_85(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_87(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_86(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_88(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_87(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_89(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_88(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_90(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_89(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_91(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_90(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_92(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_91(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_93(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_92(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_94(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_93(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_95(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_94(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_96(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_95(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_97(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_96(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_98(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_97(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_99(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_98(what, PP_TAIL(seq))
-#define PP_FOR_EACH_IMPL_100(what, \
- seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_99(what, PP_TAIL(seq))
+
+////////////////////////////////////////////////////////////////////////////////
+#define PP_HEAD_IMPL(seq) PP_ELEMENT_IMPL(seq, 0)
+
+////////////////////////////////////////////////////////////////////////////////
+#define PP_TAIL_IMPL(seq) PP_KILL_IMPL(seq, 1)
+
+////////////////////////////////////////////////////////////////////////////////
+#define PP_FOR_EACH_IMPL(what, seq) PP_CONCAT(PP_FOR_EACH_IMPL_, \
+ PP_COUNT(seq))(what, seq)
+#define PP_FOR_EACH_IMPL_0(what, seq)
+#define PP_FOR_EACH_IMPL_1(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_0(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_2(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_1(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_3(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_2(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_4(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_3(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_5(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_4(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_6(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_5(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_7(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_6(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_8(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_7(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_9(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_8(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_10(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_9(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_11(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_10(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_12(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_11(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_13(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_12(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_14(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_13(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_15(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_14(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_16(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_15(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_17(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_16(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_18(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_17(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_19(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_18(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_20(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_19(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_21(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_20(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_22(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_21(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_23(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_22(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_24(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_23(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_25(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_24(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_26(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_25(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_27(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_26(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_28(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_27(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_29(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_28(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_30(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_29(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_31(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_30(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_32(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_31(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_33(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_32(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_34(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_33(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_35(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_34(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_36(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_35(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_37(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_36(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_38(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_37(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_39(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_38(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_40(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_39(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_41(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_40(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_42(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_41(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_43(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_42(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_44(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_43(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_45(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_44(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_46(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_45(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_47(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_46(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_48(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_47(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_49(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_48(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_50(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_49(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_51(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_50(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_52(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_51(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_53(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_52(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_54(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_53(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_55(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_54(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_56(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_55(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_57(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_56(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_58(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_57(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_59(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_58(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_60(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_59(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_61(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_60(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_62(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_61(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_63(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_62(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_64(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_63(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_65(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_64(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_66(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_65(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_67(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_66(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_68(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_67(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_69(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_68(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_70(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_69(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_71(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_70(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_72(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_71(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_73(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_72(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_74(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_73(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_75(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_74(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_76(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_75(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_77(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_76(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_78(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_77(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_79(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_78(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_80(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_79(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_81(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_80(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_82(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_81(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_83(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_82(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_84(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_83(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_85(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_84(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_86(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_85(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_87(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_86(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_88(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_87(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_89(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_88(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_90(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_89(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_91(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_90(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_92(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_91(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_93(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_92(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_94(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_93(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_95(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_94(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_96(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_95(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_97(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_96(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_98(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_97(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_99(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_98(what, PP_TAIL(seq))
+#define PP_FOR_EACH_IMPL_100(what, \
+ seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_99(what, PP_TAIL(seq))
#define PP_FOR_EACH_IMPL_101(what, \
seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_100(what, PP_TAIL(seq))
#define PP_FOR_EACH_IMPL_102(what, \
@@ -1243,7 +1243,7 @@
seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_198(what, PP_TAIL(seq))
#define PP_FOR_EACH_IMPL_200(what, \
seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_199(what, PP_TAIL(seq))
-////////////////////////////////////////////////////////////////////////////////
-/*!
- \endinternal
-*/
+////////////////////////////////////////////////////////////////////////////////
+/*!
+ \endinternal
+*/
diff --git a/library/cpp/yt/misc/preprocessor-gen.h.pump b/library/cpp/yt/misc/preprocessor-gen.h.pump
index 7e3517fdd1..0f178ae37e 100644
--- a/library/cpp/yt/misc/preprocessor-gen.h.pump
+++ b/library/cpp/yt/misc/preprocessor-gen.h.pump
@@ -1,70 +1,70 @@
-#pragma once
-
-$$ Please, use Pump to convert this source file to valid C++ header.
-$$ Note that lines in this file could be longer than 80 symbols.
+#pragma once
+
+$$ Please, use Pump to convert this source file to valid C++ header.
+$$ Note that lines in this file could be longer than 80 symbols.
$var n = 199
-$range i 0..n
-
-/*!
- \internal
-*/
-
-#ifndef PREPROCESSOR_GEN_H_
-#error "Direct inclusion of this file is not allowed, include preprocessor.h"
-// For the sake of sane code completion.
-#include "preprocessor.h"
-#endif
-#undef PREPROCESSOR_GEN_H_
-
-////////////////////////////////////////////////////////////////////////////////
-#define PP_COUNT_IMPL(...) PP_CONCAT(PP_COUNT_CONST_, PP_COUNT_IMPL_0 __VA_ARGS__)
-
-$for i [[
-#define PP_COUNT_CONST_PP_COUNT_IMPL_$i $i
-
-]]
-
-$for i [[
-#define PP_COUNT_IMPL_$i(_) PP_COUNT_IMPL_$(i+1)
-
-]]
-
-////////////////////////////////////////////////////////////////////////////////
-#define PP_KILL_IMPL(seq, index) PP_CONCAT(PP_KILL_IMPL_, index) seq
-#define PP_KILL_IMPL_0
-
-$for i [[
-#define PP_KILL_IMPL_$(i+1)(_) PP_KILL_IMPL_$i
-
-]]
-
-////////////////////////////////////////////////////////////////////////////////
-#define PP_ELEMENT_IMPL(seq, index) PP_ELEMENT_IMPL_A((PP_CONCAT(PP_ELEMENT_IMPL_, index) seq))
-#define PP_ELEMENT_IMPL_A(x) PP_ELEMENT_IMPL_C(PP_ELEMENT_IMPL_B x)
-#define PP_ELEMENT_IMPL_B(x, _) x
-#define PP_ELEMENT_IMPL_C(x) x
-#define PP_ELEMENT_IMPL_0(x) x, PP_NIL
-
-$for i [[
-#define PP_ELEMENT_IMPL_$(i+1)(_) PP_ELEMENT_IMPL_$i
-
-]]
-
-////////////////////////////////////////////////////////////////////////////////
-#define PP_HEAD_IMPL(seq) PP_ELEMENT_IMPL(seq, 0)
-
-////////////////////////////////////////////////////////////////////////////////
-#define PP_TAIL_IMPL(seq) PP_KILL_IMPL(seq, 1)
-
-////////////////////////////////////////////////////////////////////////////////
-#define PP_FOR_EACH_IMPL(what, seq) PP_CONCAT(PP_FOR_EACH_IMPL_, PP_COUNT(seq))(what, seq)
-#define PP_FOR_EACH_IMPL_0(what, seq)
-
-$for i [[
-#define PP_FOR_EACH_IMPL_$(i+1)(what, seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_$i(what, PP_TAIL(seq))
-
-]]
-////////////////////////////////////////////////////////////////////////////////
-/*!
- \endinternal
-*/
+$range i 0..n
+
+/*!
+ \internal
+*/
+
+#ifndef PREPROCESSOR_GEN_H_
+#error "Direct inclusion of this file is not allowed, include preprocessor.h"
+// For the sake of sane code completion.
+#include "preprocessor.h"
+#endif
+#undef PREPROCESSOR_GEN_H_
+
+////////////////////////////////////////////////////////////////////////////////
+#define PP_COUNT_IMPL(...) PP_CONCAT(PP_COUNT_CONST_, PP_COUNT_IMPL_0 __VA_ARGS__)
+
+$for i [[
+#define PP_COUNT_CONST_PP_COUNT_IMPL_$i $i
+
+]]
+
+$for i [[
+#define PP_COUNT_IMPL_$i(_) PP_COUNT_IMPL_$(i+1)
+
+]]
+
+////////////////////////////////////////////////////////////////////////////////
+#define PP_KILL_IMPL(seq, index) PP_CONCAT(PP_KILL_IMPL_, index) seq
+#define PP_KILL_IMPL_0
+
+$for i [[
+#define PP_KILL_IMPL_$(i+1)(_) PP_KILL_IMPL_$i
+
+]]
+
+////////////////////////////////////////////////////////////////////////////////
+#define PP_ELEMENT_IMPL(seq, index) PP_ELEMENT_IMPL_A((PP_CONCAT(PP_ELEMENT_IMPL_, index) seq))
+#define PP_ELEMENT_IMPL_A(x) PP_ELEMENT_IMPL_C(PP_ELEMENT_IMPL_B x)
+#define PP_ELEMENT_IMPL_B(x, _) x
+#define PP_ELEMENT_IMPL_C(x) x
+#define PP_ELEMENT_IMPL_0(x) x, PP_NIL
+
+$for i [[
+#define PP_ELEMENT_IMPL_$(i+1)(_) PP_ELEMENT_IMPL_$i
+
+]]
+
+////////////////////////////////////////////////////////////////////////////////
+#define PP_HEAD_IMPL(seq) PP_ELEMENT_IMPL(seq, 0)
+
+////////////////////////////////////////////////////////////////////////////////
+#define PP_TAIL_IMPL(seq) PP_KILL_IMPL(seq, 1)
+
+////////////////////////////////////////////////////////////////////////////////
+#define PP_FOR_EACH_IMPL(what, seq) PP_CONCAT(PP_FOR_EACH_IMPL_, PP_COUNT(seq))(what, seq)
+#define PP_FOR_EACH_IMPL_0(what, seq)
+
+$for i [[
+#define PP_FOR_EACH_IMPL_$(i+1)(what, seq) what(PP_HEAD(seq)) PP_FOR_EACH_IMPL_$i(what, PP_TAIL(seq))
+
+]]
+////////////////////////////////////////////////////////////////////////////////
+/*!
+ \endinternal
+*/
diff --git a/library/cpp/yt/misc/preprocessor.h b/library/cpp/yt/misc/preprocessor.h
index 1372d6534f..9afd3ae902 100644
--- a/library/cpp/yt/misc/preprocessor.h
+++ b/library/cpp/yt/misc/preprocessor.h
@@ -1,124 +1,124 @@
-#pragma once
-
-/*!
- * \file preprocesor.h
- * \brief Preprocessor metaprogramming macroses
- */
-
-#if !defined(_MSC_VER) && !defined(__GNUC__)
-# error Your compiler is not currently supported.
-#endif
-
-/*!
- * \defgroup yt_pp Preprocessor metaprogramming macroses
- * \ingroup yt_commons
- *
- * This is collection of macro definitions for various metaprogramming tasks
- * with the preprocessor.
- *
- * \{
- *
- * \page yt_pp_sequences Sequences
- * Everything revolves around the concept of a \em sequence. A typical
- * sequence is encoded like <tt>(1)(2)(3)...</tt>. Internally this allows
- * to apply some macro to the every element in the sequence (see #PP_FOR_EACH).
- *
- * Note that sequences can be nested, i. e. <tt>((1)(2)(3))(a)(b)(c)</tt>
- *
- * \page yt_pp_examples Examples
- * Please refer to the unit test for an actual example of usage
- * (unittests/preprocessor_ut.cpp).
- *
- */
-
-//! Concatenates two tokens.
-#define PP_CONCAT(x, y) PP_CONCAT_A(x, y)
-//! \cond Implementation
-#define PP_CONCAT_A(x, y) PP_CONCAT_B(x, y)
-#define PP_CONCAT_B(x, y) x ## y
-//! \endcond
-
-//! Transforms token into the string forcing argument expansion.
-#define PP_STRINGIZE(x) PP_STRINGIZE_A(x)
-//! \cond Implementation
-#define PP_STRINGIZE_A(x) PP_STRINGIZE_B(x)
-#define PP_STRINGIZE_B(x) #x
-//! \endcond
-
-//! \cond Implementation
-#define PP_LEFT_PARENTHESIS (
-#define PP_RIGHT_PARENTHESIS )
-#define PP_COMMA() ,
-#define PP_EMPTY()
-//! \endcond
-
-//! Performs (non-lazy) conditional expansion.
-/*!
- * \param cond Condition; should expands to either \c PP_TRUE or \c PP_FALSE.
- * \param _then Expansion result in case when \c cond holds.
- * \param _else Expansion result in case when \c cond does not hold.
- */
-#define PP_IF(cond, _then, _else) PP_CONCAT(PP_IF_, cond)(_then, _else)
-//! \cond Implementation
-#define PP_IF_PP_TRUE(x, y) x
-#define PP_IF_PP_FALSE(x, y) y
-//! \endcond
-
-//! Tests whether supplied argument can be treated as a sequence
-//! (i. e. <tt>()()()...</tt>)
-#define PP_IS_SEQUENCE(arg) PP_CONCAT(PP_IS_SEQUENCE_B_, PP_COUNT((PP_NIL PP_IS_SEQUENCE_A arg PP_NIL)))
-//! \cond Implementation
-#define PP_IS_SEQUENCE_A(_) PP_RIGHT_PARENTHESIS PP_LEFT_PARENTHESIS
-#define PP_IS_SEQUENCE_B_1 PP_FALSE
-#define PP_IS_SEQUENCE_B_2 PP_TRUE
-//! \endcond
-
-//! Computes the number of elements in the sequence.
-#define PP_COUNT(...) PP_COUNT_IMPL(__VA_ARGS__)
-
-//! Removes first \c n elements from the sequence.
-#define PP_KILL(seq, n) PP_KILL_IMPL(seq, n)
-
-//! Extracts the head of the sequence.
-/*! For example, \code PP_HEAD((0)(1)(2)(3)) == 0 \endcode
- */
-#define PP_HEAD(...) PP_HEAD_IMPL(__VA_ARGS__)
-
-//! Extracts the tail of the sequence.
-/*! For example, \code PP_TAIL((0)(1)(2)(3)) == (1)(2)(3) \endcode
- */
-#define PP_TAIL(...) PP_TAIL_IMPL(__VA_ARGS__)
-
-//! Extracts the element with the specified index from the sequence.
-/*! For example, \code PP_ELEMENT((0)(1)(2)(3), 1) == 1 \endcode
- */
-#define PP_ELEMENT(seq, index) PP_ELEMENT_IMPL(seq, index)
-
-//! Applies the macro to every member of the sequence.
-/*! For example,
- * \code
- * #define MyFunctor(x) +x+
- * PP_FOR_EACH(MyFunctor, (0)(1)(2)(3)) == +0+ +1+ +2+ +3+
- * \encode
- */
-#define PP_FOR_EACH(what, seq) PP_FOR_EACH_IMPL(what, seq)
-
-//! Declares an anonymous variable.
-#ifdef __COUNTER__
-#define PP_ANONYMOUS_VARIABLE(str) PP_CONCAT(str, __COUNTER__)
-#else
-#define PP_ANONYMOUS_VARIABLE(str) PP_CONCAT(str, __LINE__)
-#endif
-
-//! Insert prefix based on presence of additional arguments.
-#define PP_ONE_OR_NONE(a, ...) PP_THIRD(a, ## __VA_ARGS__, a)
-#define PP_THIRD(a, b, ...) __VA_ARGS__
-
-//! \cond Implementation
-#define PREPROCESSOR_GEN_H_
-#include "preprocessor-gen.h"
-#undef PREPROCESSOR_GEN_H_
-//! \endcond
-
-/*! \} */
-
+#pragma once
+
+/*!
+ * \file preprocesor.h
+ * \brief Preprocessor metaprogramming macroses
+ */
+
+#if !defined(_MSC_VER) && !defined(__GNUC__)
+# error Your compiler is not currently supported.
+#endif
+
+/*!
+ * \defgroup yt_pp Preprocessor metaprogramming macroses
+ * \ingroup yt_commons
+ *
+ * This is collection of macro definitions for various metaprogramming tasks
+ * with the preprocessor.
+ *
+ * \{
+ *
+ * \page yt_pp_sequences Sequences
+ * Everything revolves around the concept of a \em sequence. A typical
+ * sequence is encoded like <tt>(1)(2)(3)...</tt>. Internally this allows
+ * to apply some macro to the every element in the sequence (see #PP_FOR_EACH).
+ *
+ * Note that sequences can be nested, i. e. <tt>((1)(2)(3))(a)(b)(c)</tt>
+ *
+ * \page yt_pp_examples Examples
+ * Please refer to the unit test for an actual example of usage
+ * (unittests/preprocessor_ut.cpp).
+ *
+ */
+
+//! Concatenates two tokens.
+#define PP_CONCAT(x, y) PP_CONCAT_A(x, y)
+//! \cond Implementation
+#define PP_CONCAT_A(x, y) PP_CONCAT_B(x, y)
+#define PP_CONCAT_B(x, y) x ## y
+//! \endcond
+
+//! Transforms token into the string forcing argument expansion.
+#define PP_STRINGIZE(x) PP_STRINGIZE_A(x)
+//! \cond Implementation
+#define PP_STRINGIZE_A(x) PP_STRINGIZE_B(x)
+#define PP_STRINGIZE_B(x) #x
+//! \endcond
+
+//! \cond Implementation
+#define PP_LEFT_PARENTHESIS (
+#define PP_RIGHT_PARENTHESIS )
+#define PP_COMMA() ,
+#define PP_EMPTY()
+//! \endcond
+
+//! Performs (non-lazy) conditional expansion.
+/*!
+ * \param cond Condition; should expands to either \c PP_TRUE or \c PP_FALSE.
+ * \param _then Expansion result in case when \c cond holds.
+ * \param _else Expansion result in case when \c cond does not hold.
+ */
+#define PP_IF(cond, _then, _else) PP_CONCAT(PP_IF_, cond)(_then, _else)
+//! \cond Implementation
+#define PP_IF_PP_TRUE(x, y) x
+#define PP_IF_PP_FALSE(x, y) y
+//! \endcond
+
+//! Tests whether supplied argument can be treated as a sequence
+//! (i. e. <tt>()()()...</tt>)
+#define PP_IS_SEQUENCE(arg) PP_CONCAT(PP_IS_SEQUENCE_B_, PP_COUNT((PP_NIL PP_IS_SEQUENCE_A arg PP_NIL)))
+//! \cond Implementation
+#define PP_IS_SEQUENCE_A(_) PP_RIGHT_PARENTHESIS PP_LEFT_PARENTHESIS
+#define PP_IS_SEQUENCE_B_1 PP_FALSE
+#define PP_IS_SEQUENCE_B_2 PP_TRUE
+//! \endcond
+
+//! Computes the number of elements in the sequence.
+#define PP_COUNT(...) PP_COUNT_IMPL(__VA_ARGS__)
+
+//! Removes first \c n elements from the sequence.
+#define PP_KILL(seq, n) PP_KILL_IMPL(seq, n)
+
+//! Extracts the head of the sequence.
+/*! For example, \code PP_HEAD((0)(1)(2)(3)) == 0 \endcode
+ */
+#define PP_HEAD(...) PP_HEAD_IMPL(__VA_ARGS__)
+
+//! Extracts the tail of the sequence.
+/*! For example, \code PP_TAIL((0)(1)(2)(3)) == (1)(2)(3) \endcode
+ */
+#define PP_TAIL(...) PP_TAIL_IMPL(__VA_ARGS__)
+
+//! Extracts the element with the specified index from the sequence.
+/*! For example, \code PP_ELEMENT((0)(1)(2)(3), 1) == 1 \endcode
+ */
+#define PP_ELEMENT(seq, index) PP_ELEMENT_IMPL(seq, index)
+
+//! Applies the macro to every member of the sequence.
+/*! For example,
+ * \code
+ * #define MyFunctor(x) +x+
+ * PP_FOR_EACH(MyFunctor, (0)(1)(2)(3)) == +0+ +1+ +2+ +3+
+ * \encode
+ */
+#define PP_FOR_EACH(what, seq) PP_FOR_EACH_IMPL(what, seq)
+
+//! Declares an anonymous variable.
+#ifdef __COUNTER__
+#define PP_ANONYMOUS_VARIABLE(str) PP_CONCAT(str, __COUNTER__)
+#else
+#define PP_ANONYMOUS_VARIABLE(str) PP_CONCAT(str, __LINE__)
+#endif
+
+//! Insert prefix based on presence of additional arguments.
+#define PP_ONE_OR_NONE(a, ...) PP_THIRD(a, ## __VA_ARGS__, a)
+#define PP_THIRD(a, b, ...) __VA_ARGS__
+
+//! \cond Implementation
+#define PREPROCESSOR_GEN_H_
+#include "preprocessor-gen.h"
+#undef PREPROCESSOR_GEN_H_
+//! \endcond
+
+/*! \} */
+
diff --git a/library/cpp/yt/misc/property.h b/library/cpp/yt/misc/property.h
index 1bf1f1dfb6..bef8024ae1 100644
--- a/library/cpp/yt/misc/property.h
+++ b/library/cpp/yt/misc/property.h
@@ -8,40 +8,40 @@ public: \
type& name(); \
const type& name() const;
-//! Defines a trivial public read-write property that is passed by reference.
-//! All arguments after name are used as default value (via braced-init-list).
-#define DEFINE_BYREF_RW_PROPERTY(type, name, ...) \
-protected: \
- type name##_ { __VA_ARGS__ }; \
+//! Defines a trivial public read-write property that is passed by reference.
+//! All arguments after name are used as default value (via braced-init-list).
+#define DEFINE_BYREF_RW_PROPERTY(type, name, ...) \
+protected: \
+ type name##_ { __VA_ARGS__ }; \
\
public: \
- Y_FORCE_INLINE type& name() \
+ Y_FORCE_INLINE type& name() \
{ \
return name##_; \
} \
\
- Y_FORCE_INLINE const type& name() const \
+ Y_FORCE_INLINE const type& name() const \
+ { \
+ return name##_; \
+ }
+
+//! Defines a trivial public read-write property that is passed by reference
+//! and is not inline-initialized.
+#define DEFINE_BYREF_RW_PROPERTY_NO_INIT(type, name) \
+protected: \
+ type name##_; \
+ \
+public: \
+ Y_FORCE_INLINE type& name() \
+ { \
+ return name##_; \
+ } \
+ \
+ Y_FORCE_INLINE const type& name() const \
{ \
return name##_; \
}
-//! Defines a trivial public read-write property that is passed by reference
-//! and is not inline-initialized.
-#define DEFINE_BYREF_RW_PROPERTY_NO_INIT(type, name) \
-protected: \
- type name##_; \
- \
-public: \
- Y_FORCE_INLINE type& name() \
- { \
- return name##_; \
- } \
- \
- Y_FORCE_INLINE const type& name() const \
- { \
- return name##_; \
- }
-
//! Forwards a trivial public read-write property that is passed by reference.
#define DELEGATE_BYREF_RW_PROPERTY(declaringType, type, name, delegateTo) \
type& declaringType::name() \
@@ -59,32 +59,32 @@ public: \
//! Declares a trivial public read-only property that is passed by reference.
#define DECLARE_BYREF_RO_PROPERTY(type, name) \
public: \
- const type& name() const;
+ const type& name() const;
+
+//! Defines a trivial public read-only property that is passed by reference.
+//! All arguments after name are used as default value (via braced-init-list).
+#define DEFINE_BYREF_RO_PROPERTY(type, name, ...) \
+protected: \
+ type name##_ { __VA_ARGS__ }; \
+ \
+public: \
+ Y_FORCE_INLINE const type& name() const \
+ { \
+ return name##_; \
+ }
+
+//! Defines a trivial public read-only property that is passed by reference
+//! and is not inline-initialized.
+#define DEFINE_BYREF_RO_PROPERTY_NO_INIT(type, name) \
+protected: \
+ type name##_; \
+ \
+public: \
+ Y_FORCE_INLINE const type& name() const \
+ { \
+ return name##_; \
+ }
-//! Defines a trivial public read-only property that is passed by reference.
-//! All arguments after name are used as default value (via braced-init-list).
-#define DEFINE_BYREF_RO_PROPERTY(type, name, ...) \
-protected: \
- type name##_ { __VA_ARGS__ }; \
- \
-public: \
- Y_FORCE_INLINE const type& name() const \
- { \
- return name##_; \
- }
-
-//! Defines a trivial public read-only property that is passed by reference
-//! and is not inline-initialized.
-#define DEFINE_BYREF_RO_PROPERTY_NO_INIT(type, name) \
-protected: \
- type name##_; \
- \
-public: \
- Y_FORCE_INLINE const type& name() const \
- { \
- return name##_; \
- }
-
//! Forwards a trivial public read-only property that is passed by reference.
#define DELEGATE_BYREF_RO_PROPERTY(declaringType, type, name, delegateTo) \
const type& declaringType::name() const \
@@ -98,21 +98,21 @@ public: \
#define DECLARE_BYVAL_RW_PROPERTY(type, name) \
public: \
type Get##name() const; \
- void Set##name(type value);
+ void Set##name(type value);
-//! Defines a trivial public read-write property that is passed by value.
-//! All arguments after name are used as default value (via braced-init-list).
-#define DEFINE_BYVAL_RW_PROPERTY(type, name, ...) \
-protected: \
- type name##_ { __VA_ARGS__ }; \
+//! Defines a trivial public read-write property that is passed by value.
+//! All arguments after name are used as default value (via braced-init-list).
+#define DEFINE_BYVAL_RW_PROPERTY(type, name, ...) \
+protected: \
+ type name##_ { __VA_ARGS__ }; \
\
public: \
- Y_FORCE_INLINE type Get##name() const \
+ Y_FORCE_INLINE type Get##name() const \
{ \
return name##_; \
} \
\
- Y_FORCE_INLINE void Set##name(type value) \
+ Y_FORCE_INLINE void Set##name(type value) \
{ \
name##_ = value; \
} \
@@ -139,24 +139,24 @@ public: \
name##_ = value; \
return std::move(*this); \
} \
-
-//! Defines a trivial public read-write property that is passed by value
-//! and is not inline-initialized.
-#define DEFINE_BYVAL_RW_PROPERTY_NO_INIT(type, name, ...) \
-protected: \
- type name##_; \
- \
-public: \
- Y_FORCE_INLINE type Get##name() const \
- { \
- return name##_; \
- } \
- \
- Y_FORCE_INLINE void Set##name(type value) \
- { \
- name##_ = value; \
- } \
-
+
+//! Defines a trivial public read-write property that is passed by value
+//! and is not inline-initialized.
+#define DEFINE_BYVAL_RW_PROPERTY_NO_INIT(type, name, ...) \
+protected: \
+ type name##_; \
+ \
+public: \
+ Y_FORCE_INLINE type Get##name() const \
+ { \
+ return name##_; \
+ } \
+ \
+ Y_FORCE_INLINE void Set##name(type value) \
+ { \
+ name##_ = value; \
+ } \
+
//! Forwards a trivial public read-write property that is passed by value.
#define DELEGATE_BYVAL_RW_PROPERTY(declaringType, type, name, delegateTo) \
type declaringType::Get##name() const \
@@ -164,7 +164,7 @@ public: \
return (delegateTo).Get##name(); \
} \
\
- void declaringType::Set##name(type value) \
+ void declaringType::Set##name(type value) \
{ \
(delegateTo).Set##name(value); \
}
@@ -176,31 +176,31 @@ public: \
public: \
type Get##name() const;
-//! Defines a trivial public read-only property that is passed by value.
-//! All arguments after name are used as default value (via braced-init-list).
-#define DEFINE_BYVAL_RO_PROPERTY(type, name, ...) \
-protected: \
- type name##_ { __VA_ARGS__ }; \
- \
-public: \
- Y_FORCE_INLINE type Get##name() const \
- { \
- return name##_; \
- }
-
-
-//! Defines a trivial public read-only property that is passed by value
-//! and is not inline-initialized.
-#define DEFINE_BYVAL_RO_PROPERTY_NO_INIT(type, name) \
-protected: \
- type name##_; \
- \
-public: \
- Y_FORCE_INLINE type Get##name() const \
- { \
- return name##_; \
- }
-
+//! Defines a trivial public read-only property that is passed by value.
+//! All arguments after name are used as default value (via braced-init-list).
+#define DEFINE_BYVAL_RO_PROPERTY(type, name, ...) \
+protected: \
+ type name##_ { __VA_ARGS__ }; \
+ \
+public: \
+ Y_FORCE_INLINE type Get##name() const \
+ { \
+ return name##_; \
+ }
+
+
+//! Defines a trivial public read-only property that is passed by value
+//! and is not inline-initialized.
+#define DEFINE_BYVAL_RO_PROPERTY_NO_INIT(type, name) \
+protected: \
+ type name##_; \
+ \
+public: \
+ Y_FORCE_INLINE type Get##name() const \
+ { \
+ return name##_; \
+ }
+
//! Forwards a trivial public read-only property that is passed by value.
#define DELEGATE_BYVAL_RO_PROPERTY(declaringType, type, name, delegateTo) \
type declaringType::Get##name() \
diff --git a/library/cpp/yt/misc/source_location.cpp b/library/cpp/yt/misc/source_location.cpp
index c632378050..8d22d43636 100644
--- a/library/cpp/yt/misc/source_location.cpp
+++ b/library/cpp/yt/misc/source_location.cpp
@@ -1,54 +1,54 @@
-#include "source_location.h"
-
-#include <string.h>
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-const char* TSourceLocation::GetFileName() const
-{
- return FileName_;
-}
-
-int TSourceLocation::GetLine() const
-{
- return Line_;
-}
-
-bool TSourceLocation::IsValid() const
-{
- return FileName_ != nullptr;
-}
-
-bool TSourceLocation::operator<(const TSourceLocation& other) const
-{
- const char* fileName = FileName_ ? FileName_ : "";
- const char* otherFileName = other.FileName_ ? other.FileName_ : "";
- int fileNameResult = strcmp(fileName, otherFileName);
- if (fileNameResult != 0) {
+#include "source_location.h"
+
+#include <string.h>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+const char* TSourceLocation::GetFileName() const
+{
+ return FileName_;
+}
+
+int TSourceLocation::GetLine() const
+{
+ return Line_;
+}
+
+bool TSourceLocation::IsValid() const
+{
+ return FileName_ != nullptr;
+}
+
+bool TSourceLocation::operator<(const TSourceLocation& other) const
+{
+ const char* fileName = FileName_ ? FileName_ : "";
+ const char* otherFileName = other.FileName_ ? other.FileName_ : "";
+ int fileNameResult = strcmp(fileName, otherFileName);
+ if (fileNameResult != 0) {
return fileNameResult < 0;
- }
-
- if (Line_ < other.Line_) {
- return true;
- }
- if (Line_ > other.Line_) {
- return false;
- }
-
- return false;
-}
-
-bool TSourceLocation::operator==(const TSourceLocation& other) const
-{
- const char* fileName = FileName_ ? FileName_ : "";
- const char* otherFileName = other.FileName_ ? other.FileName_ : "";
- return
- strcmp(fileName, otherFileName) == 0 &&
- Line_ == other.Line_;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
+ }
+
+ if (Line_ < other.Line_) {
+ return true;
+ }
+ if (Line_ > other.Line_) {
+ return false;
+ }
+
+ return false;
+}
+
+bool TSourceLocation::operator==(const TSourceLocation& other) const
+{
+ const char* fileName = FileName_ ? FileName_ : "";
+ const char* otherFileName = other.FileName_ ? other.FileName_ : "";
+ return
+ strcmp(fileName, otherFileName) == 0 &&
+ Line_ == other.Line_;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/misc/source_location.h b/library/cpp/yt/misc/source_location.h
index b59896fcdd..84213eea70 100644
--- a/library/cpp/yt/misc/source_location.h
+++ b/library/cpp/yt/misc/source_location.h
@@ -1,38 +1,38 @@
-#pragma once
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-class TSourceLocation
-{
-public:
- TSourceLocation()
- : FileName_(nullptr)
- , Line_(-1)
- { }
-
- TSourceLocation(const char* fileName, int line)
- : FileName_(fileName)
- , Line_(line)
- { }
-
- const char* GetFileName() const;
- int GetLine() const;
- bool IsValid() const;
-
- bool operator<(const TSourceLocation& other) const;
- bool operator==(const TSourceLocation& other) const;
-
-private:
- const char* FileName_;
- int Line_;
-
-};
-
-//! Defines a macro to record the current source location.
-#define FROM_HERE ::NYT::TSourceLocation(__FILE__, __LINE__)
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
+#pragma once
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+class TSourceLocation
+{
+public:
+ TSourceLocation()
+ : FileName_(nullptr)
+ , Line_(-1)
+ { }
+
+ TSourceLocation(const char* fileName, int line)
+ : FileName_(fileName)
+ , Line_(line)
+ { }
+
+ const char* GetFileName() const;
+ int GetLine() const;
+ bool IsValid() const;
+
+ bool operator<(const TSourceLocation& other) const;
+ bool operator==(const TSourceLocation& other) const;
+
+private:
+ const char* FileName_;
+ int Line_;
+
+};
+
+//! Defines a macro to record the current source location.
+#define FROM_HERE ::NYT::TSourceLocation(__FILE__, __LINE__)
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/misc/unittests/enum_ut.cpp b/library/cpp/yt/misc/unittests/enum_ut.cpp
index 0ee906d2ae..6af11b04dc 100644
--- a/library/cpp/yt/misc/unittests/enum_ut.cpp
+++ b/library/cpp/yt/misc/unittests/enum_ut.cpp
@@ -1,250 +1,250 @@
#include <library/cpp/testing/gtest/gtest.h>
-
+
#include <library/cpp/yt/misc/enum.h>
-
-namespace NYT {
-namespace {
-
-////////////////////////////////////////////////////////////////////////////////
-
-DEFINE_ENUM(ESimple,
- (X)
- (Y)
- (Z)
-);
-
-DEFINE_ENUM(EColor,
- ((Red) (10))
- ((Green)(20))
- ((Blue) (30))
- (Black)
- (White)
-);
-
-DEFINE_BIT_ENUM(EFlag,
- ((_1)(0x0001))
- ((_2)(0x0002))
- ((_3)(0x0004))
- ((_4)(0x0008))
-);
-
-DEFINE_AMBIGUOUS_ENUM_WITH_UNDERLYING_TYPE(EMultipleNames, int,
- (A1)
- ((A2)(0))
- (B)
- (C)
- ((D1)(100))
- ((D2)(100))
-);
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class T, size_t N>
-std::vector<T> ToVector(std::array<T, N> array)
-{
- return std::vector<T>(array.begin(), array.end());
-}
-
-TEST(TEnumTest, Domain)
-{
- EXPECT_EQ(3, TEnumTraits<ESimple>::DomainSize);
- std::vector<ESimple> v {
- ESimple::X,
- ESimple::Y,
- ESimple::Z
- };
- EXPECT_EQ(v, ToVector(TEnumTraits<ESimple>::GetDomainValues()));
- EXPECT_EQ(ESimple::X, TEnumTraits<ESimple>::GetMinValue());
- EXPECT_EQ(ESimple::Z, TEnumTraits<ESimple>::GetMaxValue());
-}
-
-TEST(TEnumTest, Basic)
-{
- EXPECT_EQ(0, static_cast<int>(ESimple::X));
- EXPECT_EQ(1, static_cast<int>(ESimple::Y));
- EXPECT_EQ(2, static_cast<int>(ESimple::Z));
-
- EXPECT_EQ(0, static_cast<int>(EColor( )));
- EXPECT_EQ(5, static_cast<int>(EColor(5)));
-
- EXPECT_EQ(10, static_cast<int>(EColor::Red ));
- EXPECT_EQ(20, static_cast<int>(EColor::Green));
- EXPECT_EQ(30, static_cast<int>(EColor::Blue ));
- EXPECT_EQ(31, static_cast<int>(EColor::Black));
- EXPECT_EQ(32, static_cast<int>(EColor::White));
-}
-
-TEST(TEnumTest, ToString)
-{
- EXPECT_EQ("EColor(0)", ToString(EColor( )));
- EXPECT_EQ("EColor(5)", ToString(EColor(5)));
-
- EXPECT_EQ("Red", ToString(EColor(EColor::Red )));
- EXPECT_EQ("Green", ToString(EColor::Green));
- EXPECT_EQ("Blue", ToString(EColor(EColor::Blue )));
- EXPECT_EQ("Black", ToString(EColor::Black));
- EXPECT_EQ("White", ToString(EColor::White));
-}
-
-TEST(TEnumTest, FromString)
-{
- EXPECT_EQ(EColor::Red , TEnumTraits<EColor>::FromString("Red" ));
- EXPECT_EQ(EColor::Green, TEnumTraits<EColor>::FromString("Green"));
- EXPECT_EQ(EColor::Blue , TEnumTraits<EColor>::FromString("Blue" ));
- EXPECT_EQ(EColor::Black, TEnumTraits<EColor>::FromString("Black"));
- EXPECT_EQ(EColor::White, TEnumTraits<EColor>::FromString("White"));
-
- EXPECT_THROW(TEnumTraits<EColor>::FromString("Pink"), std::exception);
-
- EColor color;
- bool returnValue;
-
- returnValue = TEnumTraits<EColor>::FindValueByLiteral("Red", &color);
- EXPECT_EQ(EColor::Red, color);
- EXPECT_TRUE(returnValue);
-
- returnValue = TEnumTraits<EColor>::FindValueByLiteral("Pink", &color);
- EXPECT_EQ(EColor::Red, color);
- EXPECT_FALSE(returnValue);
-}
-
-TEST(TEnumTest, Ordering)
-{
- ESimple a(ESimple::X);
- ESimple b(ESimple::Y);
- ESimple c(ESimple::Y);
- ESimple d(ESimple::Z);
-
- EXPECT_FALSE(a < a); EXPECT_FALSE(a > a);
- EXPECT_TRUE (a < b); EXPECT_TRUE (b > a);
- EXPECT_TRUE (a < c); EXPECT_TRUE (c > a);
- EXPECT_TRUE (a < d); EXPECT_TRUE (d > a);
-
- EXPECT_FALSE(b < a); EXPECT_FALSE(a > b);
- EXPECT_FALSE(b < b); EXPECT_FALSE(b > b);
- EXPECT_FALSE(b < c); EXPECT_FALSE(c > b);
- EXPECT_TRUE (b < d); EXPECT_TRUE (d > b);
-
- EXPECT_FALSE(c < a); EXPECT_FALSE(a > c);
- EXPECT_FALSE(c < b); EXPECT_FALSE(b > c);
- EXPECT_FALSE(c < c); EXPECT_FALSE(c > c);
- EXPECT_TRUE (c < d); EXPECT_TRUE (d > c);
-
- EXPECT_FALSE(d < a); EXPECT_FALSE(a > d);
- EXPECT_FALSE(d < b); EXPECT_FALSE(b > d);
- EXPECT_FALSE(d < c); EXPECT_FALSE(c > d);
- EXPECT_FALSE(d < d); EXPECT_FALSE(d > d);
-
- EXPECT_TRUE (a <= b);
- EXPECT_TRUE (b <= c);
- EXPECT_TRUE (c <= d);
-
- EXPECT_TRUE (a == a);
- EXPECT_FALSE(a == b);
- EXPECT_TRUE (b == c);
- EXPECT_FALSE(c == d);
- EXPECT_FALSE(d == a);
-
- EXPECT_FALSE(a != a);
- EXPECT_TRUE (a != b);
- EXPECT_FALSE(b != c);
- EXPECT_TRUE (c != d);
- EXPECT_TRUE (d != a);
-}
-
-TEST(TEnumTest, OrderingWithDomainValues)
-{
- EColor color(EColor::Black);
-
- EXPECT_LT(EColor::Red, color);
- EXPECT_LT(color, EColor::White);
-
- EXPECT_GT(color, EColor::Red);
- EXPECT_GT(EColor::White, color);
-
- EXPECT_LE(EColor::Red, color);
- EXPECT_LE(color, EColor::White);
-
- EXPECT_GE(EColor::White, color);
- EXPECT_GE(color, EColor::Red);
-
- EXPECT_EQ(color, EColor::Black);
- EXPECT_EQ(EColor::Black, color);
-
- EXPECT_NE(color, EColor::Blue);
- EXPECT_NE(EColor::Blue, color);
-}
-
-TEST(TEnumTest, DomainSize)
-{
- EXPECT_EQ(3, TEnumTraits<ESimple>::DomainSize);
- EXPECT_EQ(5, TEnumTraits<EColor>::DomainSize);
-}
-
-TEST(TEnumTest, DomainValues)
-{
- std::vector<ESimple> simpleValues;
- simpleValues.push_back(ESimple::X);
- simpleValues.push_back(ESimple::Y);
- simpleValues.push_back(ESimple::Z);
- EXPECT_EQ(simpleValues, ToVector(TEnumTraits<ESimple>::GetDomainValues()));
-
- std::vector<EColor> colorValues;
- colorValues.push_back(EColor::Red);
- colorValues.push_back(EColor::Green);
- colorValues.push_back(EColor::Blue);
- colorValues.push_back(EColor::Black);
- colorValues.push_back(EColor::White);
- EXPECT_EQ(colorValues, ToVector(TEnumTraits<EColor>::GetDomainValues()));
-}
-
-TEST(TEnumTest, Decompose1)
-{
- auto f = EFlag(0);
- std::vector<EFlag> ff { };
- EXPECT_EQ(TEnumTraits<EFlag>::Decompose(f), ff);
-}
-
-TEST(TEnumTest, Decompose2)
-{
- auto f = EFlag::_1;
- std::vector<EFlag> ff {EFlag::_1};
- EXPECT_EQ(TEnumTraits<EFlag>::Decompose(f), ff);
-}
-
-TEST(TEnumTest, Decompose3)
-{
- auto f = EFlag(EFlag::_1|EFlag::_2);
- std::vector<EFlag> ff{EFlag::_1, EFlag::_2};
- EXPECT_EQ(TEnumTraits<EFlag>::Decompose(f), ff);
-}
-
-TEST(TEnumTest, Decompose4)
-{
- auto f = EFlag(EFlag::_2|EFlag::_4);
- std::vector<EFlag> ff{EFlag::_2, EFlag::_4};
- EXPECT_EQ(TEnumTraits<EFlag>::Decompose(f), ff);
-}
-
-TEST(TEnumTest, MultipleNames)
-{
- EXPECT_EQ(EMultipleNames::A1, TEnumTraits<EMultipleNames>::FromString("A1"));
- EXPECT_EQ(EMultipleNames::A1, TEnumTraits<EMultipleNames>::FromString("A2"));
- EXPECT_EQ(EMultipleNames::B, TEnumTraits<EMultipleNames>::FromString("B"));
- EXPECT_EQ(EMultipleNames::C, TEnumTraits<EMultipleNames>::FromString("C"));
- EXPECT_EQ(EMultipleNames::D1, TEnumTraits<EMultipleNames>::FromString("D1"));
- EXPECT_EQ(EMultipleNames::D1, TEnumTraits<EMultipleNames>::FromString("D2"));
-
- EXPECT_EQ("A1", ToString(EMultipleNames::A1));
- EXPECT_EQ("A1", ToString(EMultipleNames::A2));
- EXPECT_EQ("B", ToString(EMultipleNames::B));
- EXPECT_EQ("C", ToString(EMultipleNames::C));
- EXPECT_EQ("D1", ToString(EMultipleNames::D1));
- EXPECT_EQ("D1", ToString(EMultipleNames::D2));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace
-} // namespace NYT
-
+
+namespace NYT {
+namespace {
+
+////////////////////////////////////////////////////////////////////////////////
+
+DEFINE_ENUM(ESimple,
+ (X)
+ (Y)
+ (Z)
+);
+
+DEFINE_ENUM(EColor,
+ ((Red) (10))
+ ((Green)(20))
+ ((Blue) (30))
+ (Black)
+ (White)
+);
+
+DEFINE_BIT_ENUM(EFlag,
+ ((_1)(0x0001))
+ ((_2)(0x0002))
+ ((_3)(0x0004))
+ ((_4)(0x0008))
+);
+
+DEFINE_AMBIGUOUS_ENUM_WITH_UNDERLYING_TYPE(EMultipleNames, int,
+ (A1)
+ ((A2)(0))
+ (B)
+ (C)
+ ((D1)(100))
+ ((D2)(100))
+);
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T, size_t N>
+std::vector<T> ToVector(std::array<T, N> array)
+{
+ return std::vector<T>(array.begin(), array.end());
+}
+
+TEST(TEnumTest, Domain)
+{
+ EXPECT_EQ(3, TEnumTraits<ESimple>::DomainSize);
+ std::vector<ESimple> v {
+ ESimple::X,
+ ESimple::Y,
+ ESimple::Z
+ };
+ EXPECT_EQ(v, ToVector(TEnumTraits<ESimple>::GetDomainValues()));
+ EXPECT_EQ(ESimple::X, TEnumTraits<ESimple>::GetMinValue());
+ EXPECT_EQ(ESimple::Z, TEnumTraits<ESimple>::GetMaxValue());
+}
+
+TEST(TEnumTest, Basic)
+{
+ EXPECT_EQ(0, static_cast<int>(ESimple::X));
+ EXPECT_EQ(1, static_cast<int>(ESimple::Y));
+ EXPECT_EQ(2, static_cast<int>(ESimple::Z));
+
+ EXPECT_EQ(0, static_cast<int>(EColor( )));
+ EXPECT_EQ(5, static_cast<int>(EColor(5)));
+
+ EXPECT_EQ(10, static_cast<int>(EColor::Red ));
+ EXPECT_EQ(20, static_cast<int>(EColor::Green));
+ EXPECT_EQ(30, static_cast<int>(EColor::Blue ));
+ EXPECT_EQ(31, static_cast<int>(EColor::Black));
+ EXPECT_EQ(32, static_cast<int>(EColor::White));
+}
+
+TEST(TEnumTest, ToString)
+{
+ EXPECT_EQ("EColor(0)", ToString(EColor( )));
+ EXPECT_EQ("EColor(5)", ToString(EColor(5)));
+
+ EXPECT_EQ("Red", ToString(EColor(EColor::Red )));
+ EXPECT_EQ("Green", ToString(EColor::Green));
+ EXPECT_EQ("Blue", ToString(EColor(EColor::Blue )));
+ EXPECT_EQ("Black", ToString(EColor::Black));
+ EXPECT_EQ("White", ToString(EColor::White));
+}
+
+TEST(TEnumTest, FromString)
+{
+ EXPECT_EQ(EColor::Red , TEnumTraits<EColor>::FromString("Red" ));
+ EXPECT_EQ(EColor::Green, TEnumTraits<EColor>::FromString("Green"));
+ EXPECT_EQ(EColor::Blue , TEnumTraits<EColor>::FromString("Blue" ));
+ EXPECT_EQ(EColor::Black, TEnumTraits<EColor>::FromString("Black"));
+ EXPECT_EQ(EColor::White, TEnumTraits<EColor>::FromString("White"));
+
+ EXPECT_THROW(TEnumTraits<EColor>::FromString("Pink"), std::exception);
+
+ EColor color;
+ bool returnValue;
+
+ returnValue = TEnumTraits<EColor>::FindValueByLiteral("Red", &color);
+ EXPECT_EQ(EColor::Red, color);
+ EXPECT_TRUE(returnValue);
+
+ returnValue = TEnumTraits<EColor>::FindValueByLiteral("Pink", &color);
+ EXPECT_EQ(EColor::Red, color);
+ EXPECT_FALSE(returnValue);
+}
+
+TEST(TEnumTest, Ordering)
+{
+ ESimple a(ESimple::X);
+ ESimple b(ESimple::Y);
+ ESimple c(ESimple::Y);
+ ESimple d(ESimple::Z);
+
+ EXPECT_FALSE(a < a); EXPECT_FALSE(a > a);
+ EXPECT_TRUE (a < b); EXPECT_TRUE (b > a);
+ EXPECT_TRUE (a < c); EXPECT_TRUE (c > a);
+ EXPECT_TRUE (a < d); EXPECT_TRUE (d > a);
+
+ EXPECT_FALSE(b < a); EXPECT_FALSE(a > b);
+ EXPECT_FALSE(b < b); EXPECT_FALSE(b > b);
+ EXPECT_FALSE(b < c); EXPECT_FALSE(c > b);
+ EXPECT_TRUE (b < d); EXPECT_TRUE (d > b);
+
+ EXPECT_FALSE(c < a); EXPECT_FALSE(a > c);
+ EXPECT_FALSE(c < b); EXPECT_FALSE(b > c);
+ EXPECT_FALSE(c < c); EXPECT_FALSE(c > c);
+ EXPECT_TRUE (c < d); EXPECT_TRUE (d > c);
+
+ EXPECT_FALSE(d < a); EXPECT_FALSE(a > d);
+ EXPECT_FALSE(d < b); EXPECT_FALSE(b > d);
+ EXPECT_FALSE(d < c); EXPECT_FALSE(c > d);
+ EXPECT_FALSE(d < d); EXPECT_FALSE(d > d);
+
+ EXPECT_TRUE (a <= b);
+ EXPECT_TRUE (b <= c);
+ EXPECT_TRUE (c <= d);
+
+ EXPECT_TRUE (a == a);
+ EXPECT_FALSE(a == b);
+ EXPECT_TRUE (b == c);
+ EXPECT_FALSE(c == d);
+ EXPECT_FALSE(d == a);
+
+ EXPECT_FALSE(a != a);
+ EXPECT_TRUE (a != b);
+ EXPECT_FALSE(b != c);
+ EXPECT_TRUE (c != d);
+ EXPECT_TRUE (d != a);
+}
+
+TEST(TEnumTest, OrderingWithDomainValues)
+{
+ EColor color(EColor::Black);
+
+ EXPECT_LT(EColor::Red, color);
+ EXPECT_LT(color, EColor::White);
+
+ EXPECT_GT(color, EColor::Red);
+ EXPECT_GT(EColor::White, color);
+
+ EXPECT_LE(EColor::Red, color);
+ EXPECT_LE(color, EColor::White);
+
+ EXPECT_GE(EColor::White, color);
+ EXPECT_GE(color, EColor::Red);
+
+ EXPECT_EQ(color, EColor::Black);
+ EXPECT_EQ(EColor::Black, color);
+
+ EXPECT_NE(color, EColor::Blue);
+ EXPECT_NE(EColor::Blue, color);
+}
+
+TEST(TEnumTest, DomainSize)
+{
+ EXPECT_EQ(3, TEnumTraits<ESimple>::DomainSize);
+ EXPECT_EQ(5, TEnumTraits<EColor>::DomainSize);
+}
+
+TEST(TEnumTest, DomainValues)
+{
+ std::vector<ESimple> simpleValues;
+ simpleValues.push_back(ESimple::X);
+ simpleValues.push_back(ESimple::Y);
+ simpleValues.push_back(ESimple::Z);
+ EXPECT_EQ(simpleValues, ToVector(TEnumTraits<ESimple>::GetDomainValues()));
+
+ std::vector<EColor> colorValues;
+ colorValues.push_back(EColor::Red);
+ colorValues.push_back(EColor::Green);
+ colorValues.push_back(EColor::Blue);
+ colorValues.push_back(EColor::Black);
+ colorValues.push_back(EColor::White);
+ EXPECT_EQ(colorValues, ToVector(TEnumTraits<EColor>::GetDomainValues()));
+}
+
+TEST(TEnumTest, Decompose1)
+{
+ auto f = EFlag(0);
+ std::vector<EFlag> ff { };
+ EXPECT_EQ(TEnumTraits<EFlag>::Decompose(f), ff);
+}
+
+TEST(TEnumTest, Decompose2)
+{
+ auto f = EFlag::_1;
+ std::vector<EFlag> ff {EFlag::_1};
+ EXPECT_EQ(TEnumTraits<EFlag>::Decompose(f), ff);
+}
+
+TEST(TEnumTest, Decompose3)
+{
+ auto f = EFlag(EFlag::_1|EFlag::_2);
+ std::vector<EFlag> ff{EFlag::_1, EFlag::_2};
+ EXPECT_EQ(TEnumTraits<EFlag>::Decompose(f), ff);
+}
+
+TEST(TEnumTest, Decompose4)
+{
+ auto f = EFlag(EFlag::_2|EFlag::_4);
+ std::vector<EFlag> ff{EFlag::_2, EFlag::_4};
+ EXPECT_EQ(TEnumTraits<EFlag>::Decompose(f), ff);
+}
+
+TEST(TEnumTest, MultipleNames)
+{
+ EXPECT_EQ(EMultipleNames::A1, TEnumTraits<EMultipleNames>::FromString("A1"));
+ EXPECT_EQ(EMultipleNames::A1, TEnumTraits<EMultipleNames>::FromString("A2"));
+ EXPECT_EQ(EMultipleNames::B, TEnumTraits<EMultipleNames>::FromString("B"));
+ EXPECT_EQ(EMultipleNames::C, TEnumTraits<EMultipleNames>::FromString("C"));
+ EXPECT_EQ(EMultipleNames::D1, TEnumTraits<EMultipleNames>::FromString("D1"));
+ EXPECT_EQ(EMultipleNames::D1, TEnumTraits<EMultipleNames>::FromString("D2"));
+
+ EXPECT_EQ("A1", ToString(EMultipleNames::A1));
+ EXPECT_EQ("A1", ToString(EMultipleNames::A2));
+ EXPECT_EQ("B", ToString(EMultipleNames::B));
+ EXPECT_EQ("C", ToString(EMultipleNames::C));
+ EXPECT_EQ("D1", ToString(EMultipleNames::D1));
+ EXPECT_EQ("D1", ToString(EMultipleNames::D2));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace
+} // namespace NYT
+
diff --git a/library/cpp/yt/misc/unittests/guid_ut.cpp b/library/cpp/yt/misc/unittests/guid_ut.cpp
index bbbd6037aa..ce9ee52109 100644
--- a/library/cpp/yt/misc/unittests/guid_ut.cpp
+++ b/library/cpp/yt/misc/unittests/guid_ut.cpp
@@ -1,20 +1,20 @@
#include <library/cpp/testing/gtest/gtest.h>
-
+
#include <library/cpp/yt/misc/guid.h>
-
-namespace NYT {
-namespace {
-
-////////////////////////////////////////////////////////////////////////////////
-
-TEST(TGuidTest, RandomGuids)
-{
- auto guid = TGuid::Create();
- auto otherGuid = TGuid::Create();
- EXPECT_FALSE(guid == otherGuid);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace
-} // namespace NYT
+
+namespace NYT {
+namespace {
+
+////////////////////////////////////////////////////////////////////////////////
+
+TEST(TGuidTest, RandomGuids)
+{
+ auto guid = TGuid::Create();
+ auto otherGuid = TGuid::Create();
+ EXPECT_FALSE(guid == otherGuid);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace
+} // namespace NYT
diff --git a/library/cpp/yt/misc/unittests/preprocessor_ut.cpp b/library/cpp/yt/misc/unittests/preprocessor_ut.cpp
index b8ec44c00b..397e2a6a61 100644
--- a/library/cpp/yt/misc/unittests/preprocessor_ut.cpp
+++ b/library/cpp/yt/misc/unittests/preprocessor_ut.cpp
@@ -1,102 +1,102 @@
-#include <library/cpp/testing/gtest/gtest.h>
-
-#include <library/cpp/yt/misc/preprocessor.h>
-
-namespace NYT {
-namespace {
-
-////////////////////////////////////////////////////////////////////////////////
-
-TEST(TPreprocessorTest, Concatenation)
-{
- EXPECT_EQ(12, PP_CONCAT(1, 2));
- EXPECT_STREQ("FooBar", PP_STRINGIZE(PP_CONCAT(Foo, Bar)));
-}
-
-TEST(TPreprocessorTest, Stringize)
-{
- EXPECT_STREQ(PP_STRINGIZE(123456), "123456");
- EXPECT_STREQ(PP_STRINGIZE(FooBar), "FooBar");
- EXPECT_STREQ(PP_STRINGIZE(T::XYZ), "T::XYZ");
-}
-
-TEST(TPreprocessorTest, Count)
-{
- EXPECT_EQ(0, PP_COUNT());
- EXPECT_EQ(1, PP_COUNT((0)));
- EXPECT_EQ(2, PP_COUNT((0)(0)));
- EXPECT_EQ(3, PP_COUNT((0)(0)(0)));
- EXPECT_EQ(4, PP_COUNT((0)(0)(0)(0)));
- EXPECT_EQ(5, PP_COUNT((0)(0)(0)(0)(0)));
-}
-
-TEST(TPreprocessorTest, Kill)
-{
- EXPECT_STREQ("PP_NIL (0)", PP_STRINGIZE(PP_NIL PP_KILL((0), 0)));
- EXPECT_STREQ("PP_NIL", PP_STRINGIZE(PP_NIL PP_KILL((0), 1)));
- EXPECT_STREQ("PP_NIL (0)(1)(2)", PP_STRINGIZE(PP_NIL PP_KILL((0)(1)(2), 0)));
- EXPECT_STREQ("PP_NIL (1)(2)", PP_STRINGIZE(PP_NIL PP_KILL((0)(1)(2), 1)));
- EXPECT_STREQ("PP_NIL (2)", PP_STRINGIZE(PP_NIL PP_KILL((0)(1)(2), 2)));
- EXPECT_STREQ("PP_NIL", PP_STRINGIZE(PP_NIL PP_KILL((0)(1)(2), 3)));
-}
-
-TEST(TPreprocessorTest, Head)
-{
- EXPECT_STREQ("0", PP_STRINGIZE(PP_HEAD((0))));
- EXPECT_STREQ("0", PP_STRINGIZE(PP_HEAD((0)(1))));
- EXPECT_STREQ("0", PP_STRINGIZE(PP_HEAD((0)(1)(2))));
-}
-
-TEST(TPreprocessorTest, Tail)
-{
- EXPECT_STREQ("PP_NIL", PP_STRINGIZE(PP_NIL PP_TAIL((0))));
- EXPECT_STREQ("PP_NIL (1)", PP_STRINGIZE(PP_NIL PP_TAIL((0)(1))));
- EXPECT_STREQ("PP_NIL (1)(2)", PP_STRINGIZE(PP_NIL PP_TAIL((0)(1)(2))));
-}
-
-TEST(TPreprocessorTest, ForEach)
-{
- EXPECT_STREQ(
- "\"Foo\" \"Bar\" \"Spam\" \"Ham\"",
- PP_STRINGIZE(PP_FOR_EACH(PP_STRINGIZE, (Foo)(Bar)(Spam)(Ham)))
- );
-#define my_functor(x) +x+
- EXPECT_STREQ(
- "+1+ +2+ +3+",
- PP_STRINGIZE(PP_FOR_EACH(my_functor, (1)(2)(3)))
- );
-#undef my_functor
-}
-
-TEST(TPreprocessorTest, MakeSingleton)
-{
- EXPECT_EQ(1, PP_ELEMENT((1), 0));
- EXPECT_EQ(1, PP_ELEMENT((1)(2), 0));
- EXPECT_EQ(2, PP_ELEMENT((1)(2), 1));
- EXPECT_EQ(1, PP_ELEMENT((1)(2)(3), 0));
- EXPECT_EQ(2, PP_ELEMENT((1)(2)(3), 1));
- EXPECT_EQ(3, PP_ELEMENT((1)(2)(3), 2));
- EXPECT_EQ(1, PP_ELEMENT((1)(2)(3)(4), 0));
- EXPECT_EQ(2, PP_ELEMENT((1)(2)(3)(4), 1));
- EXPECT_EQ(3, PP_ELEMENT((1)(2)(3)(4), 2));
- EXPECT_EQ(4, PP_ELEMENT((1)(2)(3)(4), 3));
-}
-
-TEST(TPreprocessorTest, Conditional)
-{
- EXPECT_EQ(1, PP_IF(PP_TRUE, 1, 2));
- EXPECT_EQ(2, PP_IF(PP_FALSE, 1, 2));
-}
-
-TEST(TPreprocessorTest, IsSequence)
-{
- EXPECT_STREQ("PP_FALSE", PP_STRINGIZE(PP_IS_SEQUENCE( 0 )));
- EXPECT_STREQ("PP_TRUE", PP_STRINGIZE(PP_IS_SEQUENCE((0) )));
- EXPECT_STREQ("PP_TRUE", PP_STRINGIZE(PP_IS_SEQUENCE((0)(0))));
- EXPECT_STREQ("PP_FALSE", PP_STRINGIZE(PP_IS_SEQUENCE(PP_NIL)));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace
-} // namespace NYT
+#include <library/cpp/testing/gtest/gtest.h>
+
+#include <library/cpp/yt/misc/preprocessor.h>
+
+namespace NYT {
+namespace {
+
+////////////////////////////////////////////////////////////////////////////////
+
+TEST(TPreprocessorTest, Concatenation)
+{
+ EXPECT_EQ(12, PP_CONCAT(1, 2));
+ EXPECT_STREQ("FooBar", PP_STRINGIZE(PP_CONCAT(Foo, Bar)));
+}
+
+TEST(TPreprocessorTest, Stringize)
+{
+ EXPECT_STREQ(PP_STRINGIZE(123456), "123456");
+ EXPECT_STREQ(PP_STRINGIZE(FooBar), "FooBar");
+ EXPECT_STREQ(PP_STRINGIZE(T::XYZ), "T::XYZ");
+}
+
+TEST(TPreprocessorTest, Count)
+{
+ EXPECT_EQ(0, PP_COUNT());
+ EXPECT_EQ(1, PP_COUNT((0)));
+ EXPECT_EQ(2, PP_COUNT((0)(0)));
+ EXPECT_EQ(3, PP_COUNT((0)(0)(0)));
+ EXPECT_EQ(4, PP_COUNT((0)(0)(0)(0)));
+ EXPECT_EQ(5, PP_COUNT((0)(0)(0)(0)(0)));
+}
+
+TEST(TPreprocessorTest, Kill)
+{
+ EXPECT_STREQ("PP_NIL (0)", PP_STRINGIZE(PP_NIL PP_KILL((0), 0)));
+ EXPECT_STREQ("PP_NIL", PP_STRINGIZE(PP_NIL PP_KILL((0), 1)));
+ EXPECT_STREQ("PP_NIL (0)(1)(2)", PP_STRINGIZE(PP_NIL PP_KILL((0)(1)(2), 0)));
+ EXPECT_STREQ("PP_NIL (1)(2)", PP_STRINGIZE(PP_NIL PP_KILL((0)(1)(2), 1)));
+ EXPECT_STREQ("PP_NIL (2)", PP_STRINGIZE(PP_NIL PP_KILL((0)(1)(2), 2)));
+ EXPECT_STREQ("PP_NIL", PP_STRINGIZE(PP_NIL PP_KILL((0)(1)(2), 3)));
+}
+
+TEST(TPreprocessorTest, Head)
+{
+ EXPECT_STREQ("0", PP_STRINGIZE(PP_HEAD((0))));
+ EXPECT_STREQ("0", PP_STRINGIZE(PP_HEAD((0)(1))));
+ EXPECT_STREQ("0", PP_STRINGIZE(PP_HEAD((0)(1)(2))));
+}
+
+TEST(TPreprocessorTest, Tail)
+{
+ EXPECT_STREQ("PP_NIL", PP_STRINGIZE(PP_NIL PP_TAIL((0))));
+ EXPECT_STREQ("PP_NIL (1)", PP_STRINGIZE(PP_NIL PP_TAIL((0)(1))));
+ EXPECT_STREQ("PP_NIL (1)(2)", PP_STRINGIZE(PP_NIL PP_TAIL((0)(1)(2))));
+}
+
+TEST(TPreprocessorTest, ForEach)
+{
+ EXPECT_STREQ(
+ "\"Foo\" \"Bar\" \"Spam\" \"Ham\"",
+ PP_STRINGIZE(PP_FOR_EACH(PP_STRINGIZE, (Foo)(Bar)(Spam)(Ham)))
+ );
+#define my_functor(x) +x+
+ EXPECT_STREQ(
+ "+1+ +2+ +3+",
+ PP_STRINGIZE(PP_FOR_EACH(my_functor, (1)(2)(3)))
+ );
+#undef my_functor
+}
+
+TEST(TPreprocessorTest, MakeSingleton)
+{
+ EXPECT_EQ(1, PP_ELEMENT((1), 0));
+ EXPECT_EQ(1, PP_ELEMENT((1)(2), 0));
+ EXPECT_EQ(2, PP_ELEMENT((1)(2), 1));
+ EXPECT_EQ(1, PP_ELEMENT((1)(2)(3), 0));
+ EXPECT_EQ(2, PP_ELEMENT((1)(2)(3), 1));
+ EXPECT_EQ(3, PP_ELEMENT((1)(2)(3), 2));
+ EXPECT_EQ(1, PP_ELEMENT((1)(2)(3)(4), 0));
+ EXPECT_EQ(2, PP_ELEMENT((1)(2)(3)(4), 1));
+ EXPECT_EQ(3, PP_ELEMENT((1)(2)(3)(4), 2));
+ EXPECT_EQ(4, PP_ELEMENT((1)(2)(3)(4), 3));
+}
+
+TEST(TPreprocessorTest, Conditional)
+{
+ EXPECT_EQ(1, PP_IF(PP_TRUE, 1, 2));
+ EXPECT_EQ(2, PP_IF(PP_FALSE, 1, 2));
+}
+
+TEST(TPreprocessorTest, IsSequence)
+{
+ EXPECT_STREQ("PP_FALSE", PP_STRINGIZE(PP_IS_SEQUENCE( 0 )));
+ EXPECT_STREQ("PP_TRUE", PP_STRINGIZE(PP_IS_SEQUENCE((0) )));
+ EXPECT_STREQ("PP_TRUE", PP_STRINGIZE(PP_IS_SEQUENCE((0)(0))));
+ EXPECT_STREQ("PP_FALSE", PP_STRINGIZE(PP_IS_SEQUENCE(PP_NIL)));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace
+} // namespace NYT
diff --git a/library/cpp/yt/misc/unittests/ya.make b/library/cpp/yt/misc/unittests/ya.make
index 539c7c1a4e..690082ca59 100644
--- a/library/cpp/yt/misc/unittests/ya.make
+++ b/library/cpp/yt/misc/unittests/ya.make
@@ -1,15 +1,15 @@
-GTEST(unittester-library-misc)
-
-OWNER(g:yt)
-
-SRCS(
+GTEST(unittester-library-misc)
+
+OWNER(g:yt)
+
+SRCS(
enum_ut.cpp
guid_ut.cpp
- preprocessor_ut.cpp
-)
-
-PEERDIR(
- library/cpp/yt/misc
-)
-
-END()
+ preprocessor_ut.cpp
+)
+
+PEERDIR(
+ library/cpp/yt/misc
+)
+
+END()
diff --git a/library/cpp/yt/misc/variant-inl.h b/library/cpp/yt/misc/variant-inl.h
index 73d302eece..fb7d98d4be 100644
--- a/library/cpp/yt/misc/variant-inl.h
+++ b/library/cpp/yt/misc/variant-inl.h
@@ -1,70 +1,70 @@
-#ifndef VARIANT_INL_H_
-#error "Direct inclusion of this file is not allowed, include variant.h"
+#ifndef VARIANT_INL_H_
+#error "Direct inclusion of this file is not allowed, include variant.h"
// For the sake of sane code completion.
#include "variant.h"
-#endif
-
-#include <type_traits>
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-namespace NDetail {
-
-template <class T>
-struct TIndexOf<T>
-{
- static constexpr size_t Value = std::numeric_limits<size_t>::max();
-};
-
-template <class T, class T0, class... Ts>
-struct TIndexOf<T, T0, Ts...>
-{
- static constexpr size_t Value = std::is_same_v<T, T0>
- ? 0
- : 1 + TIndexOf<T, Ts...>::Value;
-};
-
-template <size_t Index, class... Ts>
-struct TVariantFormatter;
-
-template <size_t Index>
-struct TVariantFormatter<Index>
-{
- template <class TVariant>
- static void Do(TStringBuilderBase* /*builder*/, const TVariant& /*variant*/, TStringBuf /*spec*/)
- { }
-};
-
-template <size_t Index, class T, class... Ts>
-struct TVariantFormatter<Index, T, Ts...>
-{
- template <class TVariant>
- static void Do(TStringBuilderBase* builder, const TVariant& variant, TStringBuf spec)
- {
- if (variant.index() == Index) {
- FormatValue(builder, std::get<Index>(variant), spec);
- } else {
- TVariantFormatter<Index + 1, Ts...>::Do(builder, variant, spec);
- }
- }
-};
-
-} // namespace NDetail
-
-template <class... Ts>
-void FormatValue(TStringBuilderBase* builder, const std::variant<Ts...>& variant, TStringBuf spec)
-{
- NDetail::TVariantFormatter<0, Ts...>::Do(builder, variant, spec);
-}
-
-template <class... Ts>
-TString ToString(const std::variant<Ts...>& variant)
-{
- return ToStringViaBuilder(variant);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
+#endif
+
+#include <type_traits>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+namespace NDetail {
+
+template <class T>
+struct TIndexOf<T>
+{
+ static constexpr size_t Value = std::numeric_limits<size_t>::max();
+};
+
+template <class T, class T0, class... Ts>
+struct TIndexOf<T, T0, Ts...>
+{
+ static constexpr size_t Value = std::is_same_v<T, T0>
+ ? 0
+ : 1 + TIndexOf<T, Ts...>::Value;
+};
+
+template <size_t Index, class... Ts>
+struct TVariantFormatter;
+
+template <size_t Index>
+struct TVariantFormatter<Index>
+{
+ template <class TVariant>
+ static void Do(TStringBuilderBase* /*builder*/, const TVariant& /*variant*/, TStringBuf /*spec*/)
+ { }
+};
+
+template <size_t Index, class T, class... Ts>
+struct TVariantFormatter<Index, T, Ts...>
+{
+ template <class TVariant>
+ static void Do(TStringBuilderBase* builder, const TVariant& variant, TStringBuf spec)
+ {
+ if (variant.index() == Index) {
+ FormatValue(builder, std::get<Index>(variant), spec);
+ } else {
+ TVariantFormatter<Index + 1, Ts...>::Do(builder, variant, spec);
+ }
+ }
+};
+
+} // namespace NDetail
+
+template <class... Ts>
+void FormatValue(TStringBuilderBase* builder, const std::variant<Ts...>& variant, TStringBuf spec)
+{
+ NDetail::TVariantFormatter<0, Ts...>::Do(builder, variant, spec);
+}
+
+template <class... Ts>
+TString ToString(const std::variant<Ts...>& variant)
+{
+ return ToStringViaBuilder(variant);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/misc/variant.h b/library/cpp/yt/misc/variant.h
index a6b6821e1e..27c0a2bc08 100644
--- a/library/cpp/yt/misc/variant.h
+++ b/library/cpp/yt/misc/variant.h
@@ -1,41 +1,41 @@
-#pragma once
-
-#include <variant>
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-namespace NDetail {
-
-template <class T, class... Ts>
-struct TIndexOf;
-
-} // namespace NDetail
-
-template <class T, class V>
-struct TVariantIndex;
-
-template <class T, class... Ts>
-struct TVariantIndex<T, std::variant<Ts...>>
- : std::integral_constant<size_t, NDetail::TIndexOf<T, Ts...>::Value>
-{ };
-
-template <class T, class V>
-constexpr size_t VariantIndexV = TVariantIndex<T, V>::value;
-
-////////////////////////////////////////////////////////////////////////////////
-
-class TStringBuilderBase;
-
-template <class... Ts>
-void FormatValue(TStringBuilderBase* builder, const std::variant<Ts...>& variant, TStringBuf spec);
-
+#pragma once
+
+#include <variant>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+namespace NDetail {
+
+template <class T, class... Ts>
+struct TIndexOf;
+
+} // namespace NDetail
+
+template <class T, class V>
+struct TVariantIndex;
+
+template <class T, class... Ts>
+struct TVariantIndex<T, std::variant<Ts...>>
+ : std::integral_constant<size_t, NDetail::TIndexOf<T, Ts...>::Value>
+{ };
+
+template <class T, class V>
+constexpr size_t VariantIndexV = TVariantIndex<T, V>::value;
+
+////////////////////////////////////////////////////////////////////////////////
+
+class TStringBuilderBase;
+
template <class... Ts>
-TString ToString(const std::variant<Ts...>& variant);
+void FormatValue(TStringBuilderBase* builder, const std::variant<Ts...>& variant, TStringBuf spec);
+
+template <class... Ts>
+TString ToString(const std::variant<Ts...>& variant);
+
+////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-
//! A concise way of creating a functor with an overloaded operator().
/*!
* Very useful for std::visit-ing variants. For example:
@@ -69,8 +69,8 @@ auto Visit(T&& variant, U&&... visitorOverloads)
////////////////////////////////////////////////////////////////////////////////
-} // namespace NYT
-
-#define VARIANT_INL_H_
-#include "variant-inl.h"
-#undef VARIANT_INL_H_
+} // namespace NYT
+
+#define VARIANT_INL_H_
+#include "variant-inl.h"
+#undef VARIANT_INL_H_
diff --git a/library/cpp/yt/misc/ya.make b/library/cpp/yt/misc/ya.make
index 76323eb06a..bb76711ddd 100644
--- a/library/cpp/yt/misc/ya.make
+++ b/library/cpp/yt/misc/ya.make
@@ -8,7 +8,7 @@ SRCS(
)
PEERDIR(
- library/cpp/yt/exception
+ library/cpp/yt/exception
)
CHECK_DEPENDENT_DIRS(
@@ -21,7 +21,7 @@ CHECK_DEPENDENT_DIRS(
)
END()
-
-RECURSE_FOR_TESTS(
- unittests
-)
+
+RECURSE_FOR_TESTS(
+ unittests
+)
diff --git a/library/cpp/yt/small_containers/compact_set.h b/library/cpp/yt/small_containers/compact_set.h
index a02afa833b..2ca8713ea7 100644
--- a/library/cpp/yt/small_containers/compact_set.h
+++ b/library/cpp/yt/small_containers/compact_set.h
@@ -1,4 +1,4 @@
-//===- llvm/ADT/SmallSet.h - 'Normally small' sets --------------*- C++ -*-===//
+//===- llvm/ADT/SmallSet.h - 'Normally small' sets --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -32,7 +32,7 @@ namespace NYT {
/// Note that any modification of the set may invalidate *all* iterators.
template <typename T, unsigned N, typename C = std::less<T>>
class TCompactSet
-{
+{
private:
/// Use a CompactVector to hold the elements here (even though it will never
/// reach its 'large' stage) to avoid calling the default ctors of elements
diff --git a/library/cpp/yt/small_containers/compact_vector-inl.h b/library/cpp/yt/small_containers/compact_vector-inl.h
index 32a59bec50..52507e4768 100644
--- a/library/cpp/yt/small_containers/compact_vector-inl.h
+++ b/library/cpp/yt/small_containers/compact_vector-inl.h
@@ -1,694 +1,694 @@
-#ifndef COMPACT_VECTOR_INL_H_
-#error "Direct inclusion of this file is not allowed, include compact_vector.h"
-// For the sake of sane code completion.
-#include "compact_vector.h"
-#endif
-#undef COMPACT_VECTOR_INL_H_
-
-#include <library/cpp/yt/assert/assert.h>
-
-#include <library/cpp/yt/malloc/malloc.h>
-
-#include <util/system/compiler.h>
-
-#include <algorithm>
-#include <bit>
-
-#include <string.h>
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-static_assert(sizeof(uintptr_t) == 8);
-
+#ifndef COMPACT_VECTOR_INL_H_
+#error "Direct inclusion of this file is not allowed, include compact_vector.h"
+// For the sake of sane code completion.
+#include "compact_vector.h"
+#endif
+#undef COMPACT_VECTOR_INL_H_
+
+#include <library/cpp/yt/assert/assert.h>
+
+#include <library/cpp/yt/malloc/malloc.h>
+
+#include <util/system/compiler.h>
+
+#include <algorithm>
+#include <bit>
+
+#include <string.h>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+static_assert(sizeof(uintptr_t) == 8);
+
// TODO(gritukan, babenko): Uncomment check below after DEVTOOLS-7870.
// static_assert(std::endian::native == std::endian::little);
-////////////////////////////////////////////////////////////////////////////////
-
-template <class T>
-struct TCompactVectorOnHeapStorage
-{
- T* End;
- T* Capacity;
- T Elements[0];
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class TVector, class TPtr>
-class TCompactVectorReallocationPtrAdjuster
-{
-public:
- TCompactVectorReallocationPtrAdjuster(TVector* vector, TPtr& ptr)
- : Vector_(vector)
- , Ptr_(ptr)
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T>
+struct TCompactVectorOnHeapStorage
+{
+ T* End;
+ T* Capacity;
+ T Elements[0];
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class TVector, class TPtr>
+class TCompactVectorReallocationPtrAdjuster
+{
+public:
+ TCompactVectorReallocationPtrAdjuster(TVector* vector, TPtr& ptr)
+ : Vector_(vector)
+ , Ptr_(ptr)
, Index_(ptr >= Vector_->begin() && ptr <= Vector_->end()
- ? std::distance(Vector_->begin(), const_cast<typename TVector::iterator>(ptr))
- : -1)
- { }
-
- ~TCompactVectorReallocationPtrAdjuster()
- {
- if (Index_ >= 0) {
- Ptr_ = Vector_->begin() + Index_;
- }
- }
-
-private:
- TVector* const Vector_;
- TPtr& Ptr_;
- const ptrdiff_t Index_;
-};
-
-template <class TVector>
-class TCompactVectorReallocationPtrAdjuster<TVector, std::nullptr_t>
-{
-public:
- TCompactVectorReallocationPtrAdjuster(TVector* /*vector*/, std::nullptr_t /*ptr*/)
- { }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class T, size_t N>
-TCompactVector<T, N>::TCompactVector() noexcept
-{
- InlineMeta_.SizePlusOne = 1;
-}
-
-template <class T, size_t N>
-TCompactVector<T, N>::TCompactVector(const TCompactVector& other)
- : TCompactVector()
-{
- assign(other.begin(), other.end());
-}
-
-template <class T, size_t N>
-template <size_t OtherN>
-TCompactVector<T, N>::TCompactVector(const TCompactVector<T, OtherN>& other)
- : TCompactVector()
-{
- assign(other.begin(), other.end());
-}
-
-template <class T, size_t N>
+ ? std::distance(Vector_->begin(), const_cast<typename TVector::iterator>(ptr))
+ : -1)
+ { }
+
+ ~TCompactVectorReallocationPtrAdjuster()
+ {
+ if (Index_ >= 0) {
+ Ptr_ = Vector_->begin() + Index_;
+ }
+ }
+
+private:
+ TVector* const Vector_;
+ TPtr& Ptr_;
+ const ptrdiff_t Index_;
+};
+
+template <class TVector>
+class TCompactVectorReallocationPtrAdjuster<TVector, std::nullptr_t>
+{
+public:
+ TCompactVectorReallocationPtrAdjuster(TVector* /*vector*/, std::nullptr_t /*ptr*/)
+ { }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T, size_t N>
+TCompactVector<T, N>::TCompactVector() noexcept
+{
+ InlineMeta_.SizePlusOne = 1;
+}
+
+template <class T, size_t N>
+TCompactVector<T, N>::TCompactVector(const TCompactVector& other)
+ : TCompactVector()
+{
+ assign(other.begin(), other.end());
+}
+
+template <class T, size_t N>
+template <size_t OtherN>
+TCompactVector<T, N>::TCompactVector(const TCompactVector<T, OtherN>& other)
+ : TCompactVector()
+{
+ assign(other.begin(), other.end());
+}
+
+template <class T, size_t N>
TCompactVector<T, N>::TCompactVector(TCompactVector&& other) noexcept(std::is_nothrow_move_constructible_v<T>)
- : TCompactVector()
-{
- swap(other);
-}
-
-template <class T, size_t N>
-template <size_t OtherN>
-TCompactVector<T, N>::TCompactVector(TCompactVector<T, OtherN>&& other)
- : TCompactVector()
-{
- swap(other);
-}
-
-template <class T, size_t N>
-TCompactVector<T, N>::TCompactVector(size_type count)
- : TCompactVector()
-{
- assign(count, T());
-}
-
-template <class T, size_t N>
-TCompactVector<T, N>::TCompactVector(size_type count, const T& value)
- : TCompactVector()
-{
- assign(count, value);
-}
-
-template <class T, size_t N>
-template <class TIterator>
-TCompactVector<T, N>::TCompactVector(TIterator first, TIterator last)
- : TCompactVector()
-{
- assign(first, last);
-}
-
-template <class T, size_t N>
-TCompactVector<T, N>::TCompactVector(std::initializer_list<T> list)
- : TCompactVector()
-{
- assign(list.begin(), list.end());
-}
-
-template <class T, size_t N>
-TCompactVector<T, N>::~TCompactVector()
-{
- if (Y_LIKELY(IsInline())) {
- Destroy(&InlineElements_[0], &InlineElements_[InlineMeta_.SizePlusOne - 1]);
- } else {
- auto* storage = OnHeapMeta_.Storage;
- Destroy(storage->Elements, storage->End);
- ::free(storage);
- }
-}
-
-template <class T, size_t N>
-bool TCompactVector<T, N>::empty() const
-{
- if (Y_LIKELY(IsInline())) {
- return InlineMeta_.SizePlusOne == 1;
- } else {
- const auto* storage = OnHeapMeta_.Storage;
- return storage->Elements == storage->End;
- }
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::begin() -> iterator
-{
- return Y_LIKELY(IsInline()) ? &InlineElements_[0] : OnHeapMeta_.Storage->Elements;
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::begin() const -> const_iterator
-{
- return const_cast<TCompactVector*>(this)->begin();
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::end() -> iterator
-{
- return Y_LIKELY(IsInline()) ? &InlineElements_[InlineMeta_.SizePlusOne - 1] : OnHeapMeta_.Storage->End;
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::end() const -> const_iterator
-{
- return const_cast<TCompactVector*>(this)->end();
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::rbegin() -> reverse_iterator
-{
- return static_cast<reverse_iterator>(end());
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::rbegin() const -> const_reverse_iterator
-{
- return static_cast<const_reverse_iterator>(end());
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::rend() -> reverse_iterator
-{
- return static_cast<reverse_iterator>(begin());
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::rend() const -> const_reverse_iterator
-{
- return static_cast<const_reverse_iterator>(begin());
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::size() const -> size_type
-{
- if (Y_LIKELY(IsInline())) {
- return InlineMeta_.SizePlusOne - 1;
- } else {
- const auto* storage = OnHeapMeta_.Storage;
- return storage->End - storage->Elements;
- }
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::capacity() const -> size_type
-{
- if (Y_LIKELY(IsInline())) {
- return N;
- } else {
- const auto* storage = OnHeapMeta_.Storage;
- return storage->Capacity - storage->Elements;
- }
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::max_size() const -> size_type
-{
- return static_cast<size_type>(-1) / sizeof(T);
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::data() -> pointer
-{
- return static_cast<pointer>(begin());
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::data() const -> const_pointer
-{
- return static_cast<const_pointer>(begin());
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::operator[](size_type index) -> reference
-{
- YT_ASSERT(index < size());
- return begin()[index];
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::operator[](size_type index) const -> const_reference
-{
- return const_cast<TCompactVector*>(this)->operator[](index);
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::front() -> reference
-{
- YT_ASSERT(!empty());
- return begin()[0];
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::front() const -> const_reference
-{
- return const_cast<TCompactVector*>(this)->front();
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::back() -> reference
-{
- YT_ASSERT(!empty());
- return end()[-1];
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::back() const -> const_reference
-{
- return const_cast<TCompactVector*>(this)->back();
-}
-
-template <class T, size_t N>
-void TCompactVector<T, N>::push_back(const T& value)
-{
- PushBackImpl(
- &value,
- [&] (T* dst, const T* value) {
- ::new(dst) T(*value);
- });
-}
-
-template <class T, size_t N>
-void TCompactVector<T, N>::push_back(T&& value)
-{
- PushBackImpl(
- &value,
- [&] (T* dst, T* value) {
- ::new(dst) T(std::move(*value));
- });
-}
-
-template <class T, size_t N>
-template <class... TArgs>
-auto TCompactVector<T, N>::emplace(const_iterator pos, TArgs&&... args) -> iterator
-{
- return InsertOneImpl(
- pos,
- nullptr,
- [&] (auto* dst, std::nullptr_t) {
- ::new(dst) T(std::forward<TArgs>(args)...);
- },
- [&] (auto* dst, std::nullptr_t) {
- *dst = T(std::forward<TArgs>(args)...);
- });
-}
-
-template <class T, size_t N>
-template <class... TArgs>
-auto TCompactVector<T, N>::emplace_back(TArgs&&... args) -> reference
-{
- return PushBackImpl(
- nullptr,
- [&] (T* dst, std::nullptr_t) {
- ::new(dst) T(std::forward<TArgs>(args)...);
- });
-}
-
-template <class T, size_t N>
-void TCompactVector<T, N>::pop_back()
-{
- YT_ASSERT(!empty());
-
- if (Y_LIKELY(IsInline())) {
- InlineElements_[InlineMeta_.SizePlusOne - 2].T::~T();
- --InlineMeta_.SizePlusOne;
- } else {
- auto* storage = OnHeapMeta_.Storage;
- storage->End[-1].T::~T();
- --storage->End;
- }
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::erase(const_iterator pos) -> iterator
-{
- YT_ASSERT(pos >= begin());
- YT_ASSERT(pos < end());
-
- auto* mutablePos = const_cast<iterator>(pos);
- Move(mutablePos + 1, end(), mutablePos);
- pop_back();
-
- return mutablePos;
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::erase(const_iterator first, const_iterator last) -> iterator
-{
- YT_ASSERT(first >= begin());
- YT_ASSERT(last <= end());
-
- auto* mutableFirst = const_cast<iterator>(first);
- auto* mutableLast = const_cast<iterator>(last);
- auto count = std::distance(mutableFirst, mutableLast);
-
- if (Y_LIKELY(IsInline())) {
- auto* end = &InlineElements_[0] + InlineMeta_.SizePlusOne - 1;
- Move(mutableLast, end, mutableFirst);
- Destroy(end - count, end);
- InlineMeta_.SizePlusOne -= count;
- } else {
- auto* storage = OnHeapMeta_.Storage;
- auto* end = storage->End;
- Move(mutableLast, storage->End, mutableFirst);
- Destroy(end - count, end);
- storage->End -= count;
- }
-
- return mutableFirst;
-}
-
-template <class T, size_t N>
-void TCompactVector<T, N>::clear()
-{
- if (Y_LIKELY(IsInline())) {
- Destroy(&InlineElements_[0], &InlineElements_[InlineMeta_.SizePlusOne - 1]);
- InlineMeta_.SizePlusOne = 1;
- } else {
- auto* storage = OnHeapMeta_.Storage;
- Destroy(storage->Elements, storage->End);
- storage->End = storage->Elements;
- }
-}
-
-template <class T, size_t N>
-void TCompactVector<T, N>::resize(size_type newSize)
-{
- ResizeImpl(
- newSize,
- [] (auto* dst) {
- ::new(dst) T();
- });
-}
-
-template <class T, size_t N>
-void TCompactVector<T, N>::resize(size_type newSize, const T& value)
-{
- ResizeImpl(
- newSize,
- [&] (auto* dst) {
- ::new(dst) T(value);
- });
-}
-
-template <class T, size_t N>
-void TCompactVector<T, N>::reserve(size_t newCapacity)
-{
- if (Y_UNLIKELY(newCapacity > N)) {
- EnsureOnHeapCapacity(newCapacity, /*incremental*/ false);
- }
-}
-
-template <class T, size_t N>
-void TCompactVector<T, N>::swap(TCompactVector& other)
-{
- if (this == &other) {
- return;
- }
-
- if (!IsInline() && !other.IsInline()) {
- std::swap(OnHeapMeta_.Storage, other.OnHeapMeta_.Storage);
- return;
- }
-
- auto* lhs = this;
- auto* rhs = &other;
- if (lhs->size() < rhs->size()) {
- std::swap(lhs, rhs);
- }
-
- size_t rhsSize = rhs->size();
- size_t lhsSize = lhs->size();
- if (lhsSize > rhs->capacity()) {
- rhs->EnsureOnHeapCapacity(lhs->size(), /*incremental*/ false);
- }
-
- for (size_t index = 0; index < rhsSize; ++index) {
- std::swap((*lhs)[index], (*rhs)[index]);
- }
-
- UninitializedMove(lhs->begin() + rhsSize, lhs->end(), rhs->end());
- Destroy(lhs->begin() + rhsSize, lhs->end());
-
- rhs->SetSize(lhsSize);
- lhs->SetSize(rhsSize);
-}
-
-template <class T, size_t N>
-void TCompactVector<T, N>::assign(size_type count, const T& value)
-{
- clear();
-
- if (Y_UNLIKELY(count > capacity())) {
- EnsureOnHeapCapacity(count, /*incremental*/ false);
- }
-
- auto* dst = begin();
- std::uninitialized_fill(dst, dst + count, value);
-
- SetSize(count);
-}
-
-template <class T, size_t N>
-template <class TIterator>
-void TCompactVector<T, N>::assign(TIterator first, TIterator last)
-{
- clear();
-
- auto count = std::distance(first, last);
- if (Y_UNLIKELY(count > static_cast<ptrdiff_t>(capacity()))) {
- EnsureOnHeapCapacity(count, /*incremental*/ false);
- }
-
- std::uninitialized_copy(first, last, begin());
-
- SetSize(count);
-}
-
-template <class T, size_t N>
-void TCompactVector<T, N>::assign(std::initializer_list<T> list)
-{
- assign(list.begin(), list.end());
-}
-
-template <class T, size_t N>
-template <size_t OtherN>
-void TCompactVector<T, N>::assign(const TCompactVector<T, OtherN>& other)
-{
- if constexpr(N == OtherN) {
- if (this == &other) {
- return;
- }
- }
-
- auto otherSize = other.size();
- auto otherBegin = other.begin();
-
- if (capacity() >= otherSize) {
- const auto* src = other.begin();
- auto* dst = begin();
-
- auto thisSize = size();
- auto copySize = std::min(thisSize, otherSize);
- Copy(src, src + copySize, dst);
- src += copySize;
- dst += copySize;
-
- auto uninitializedCopySize = otherSize - copySize;
- UninitializedCopy(src, src + uninitializedCopySize, dst);
- // NB: src += uninitializedCopySize is not needed.
- dst += uninitializedCopySize;
-
- if (thisSize > otherSize) {
- Destroy(dst, end());
- }
-
- SetSize(otherSize);
- return;
- }
-
- clear();
-
- EnsureOnHeapCapacity(otherSize, /*incremental*/ false);
-
- YT_ASSERT(!IsInline());
- auto* storage = OnHeapMeta_.Storage;
- UninitializedCopy(otherBegin, otherBegin + otherSize, storage->Elements);
- storage->End = storage->Elements + otherSize;
-}
-
-template <class T, size_t N>
-template <size_t OtherN>
-void TCompactVector<T, N>::assign(TCompactVector<T, OtherN>&& other)
-{
- if constexpr(N == OtherN) {
- if (this == &other) {
- return;
- }
- }
-
- clear();
-
- if (!other.IsInline()) {
- if (Y_UNLIKELY(!IsInline())) {
- ::free(OnHeapMeta_.Storage);
- }
- OnHeapMeta_.Storage = other.OnHeapMeta_.Storage;
- other.InlineMeta_.SizePlusOne = 1;
- return;
- }
-
- auto otherSize = other.size();
- if (Y_UNLIKELY(otherSize > capacity())) {
- EnsureOnHeapCapacity(otherSize, /*incremental*/ false);
- }
-
- auto* otherBegin = other.begin();
- UninitializedMove(otherBegin, otherBegin + otherSize, begin());
- SetSize(otherSize);
-
- other.clear();
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::operator=(const TCompactVector& other) -> TCompactVector&
-{
- assign(other);
- return *this;
-}
-
-template <class T, size_t N>
-template <size_t OtherN>
-auto TCompactVector<T, N>::operator=(const TCompactVector<T, OtherN>& other) -> TCompactVector&
-{
- assign(other);
- return *this;
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::operator=(TCompactVector&& other) -> TCompactVector&
-{
- assign(std::move(other));
- return *this;
-}
-
-template <class T, size_t N>
-template <size_t OtherN>
-auto TCompactVector<T, N>::operator=(TCompactVector<T, OtherN>&& other) -> TCompactVector&
-{
- assign(std::move(other));
- return *this;
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::operator=(std::initializer_list<T> list) -> TCompactVector&
-{
- assign(list);
- return *this;
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::insert(const_iterator pos, const T& value) -> iterator
-{
- return InsertOneImpl(
- pos,
- &value,
- [&] (auto* dst, const auto* value) {
- ::new(dst) T(*value);
- },
- [&] (auto* dst, const auto* value) {
- *dst = *value;
- });
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::insert(const_iterator pos, T&& value) -> iterator
-{
- return InsertOneImpl(
- pos,
- &value,
- [&] (auto* dst, auto* value) {
- ::new(dst) T(std::move(*value));
- },
- [&] (auto* dst, auto* value) {
- *dst = std::move(*value);
- });
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::insert(const_iterator pos, size_type count, const T& value) -> iterator
-{
- return InsertManyImpl(
- pos,
- count,
- [&] (auto* dstFirst, auto* dstLast) {
- for (auto* dst = dstFirst; dst != dstLast; ++dst) {
- ::new(dst) T(value);
- }
- },
- [&] (auto* dstFirst, auto* dstLast) {
- for (auto* dst = dstFirst; dst != dstLast; ++dst) {
- *dst = value;
- }
- });
-}
-
-template <class T, size_t N>
-template <class TIterator>
-auto TCompactVector<T, N>::insert(const_iterator pos, TIterator first, TIterator last) -> iterator
-{
- auto current = first;
- return InsertManyImpl(
- pos,
- std::distance(first, last),
- [&] (auto* dstFirst, auto* dstLast) {
- for (auto* dst = dstFirst; dst != dstLast; ++dst) {
- ::new(dst) T(*current++);
- }
- },
- [&] (auto* dstFirst, auto* dstLast) {
- for (auto* dst = dstFirst; dst != dstLast; ++dst) {
- *dst = *current++;
- }
- });
-}
-
-template <class T, size_t N>
-auto TCompactVector<T, N>::insert(const_iterator pos, std::initializer_list<T> list) -> iterator
-{
- return insert(pos, list.begin(), list.end());
-}
-
-template <class T, size_t N>
+ : TCompactVector()
+{
+ swap(other);
+}
+
+template <class T, size_t N>
+template <size_t OtherN>
+TCompactVector<T, N>::TCompactVector(TCompactVector<T, OtherN>&& other)
+ : TCompactVector()
+{
+ swap(other);
+}
+
+template <class T, size_t N>
+TCompactVector<T, N>::TCompactVector(size_type count)
+ : TCompactVector()
+{
+ assign(count, T());
+}
+
+template <class T, size_t N>
+TCompactVector<T, N>::TCompactVector(size_type count, const T& value)
+ : TCompactVector()
+{
+ assign(count, value);
+}
+
+template <class T, size_t N>
+template <class TIterator>
+TCompactVector<T, N>::TCompactVector(TIterator first, TIterator last)
+ : TCompactVector()
+{
+ assign(first, last);
+}
+
+template <class T, size_t N>
+TCompactVector<T, N>::TCompactVector(std::initializer_list<T> list)
+ : TCompactVector()
+{
+ assign(list.begin(), list.end());
+}
+
+template <class T, size_t N>
+TCompactVector<T, N>::~TCompactVector()
+{
+ if (Y_LIKELY(IsInline())) {
+ Destroy(&InlineElements_[0], &InlineElements_[InlineMeta_.SizePlusOne - 1]);
+ } else {
+ auto* storage = OnHeapMeta_.Storage;
+ Destroy(storage->Elements, storage->End);
+ ::free(storage);
+ }
+}
+
+template <class T, size_t N>
+bool TCompactVector<T, N>::empty() const
+{
+ if (Y_LIKELY(IsInline())) {
+ return InlineMeta_.SizePlusOne == 1;
+ } else {
+ const auto* storage = OnHeapMeta_.Storage;
+ return storage->Elements == storage->End;
+ }
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::begin() -> iterator
+{
+ return Y_LIKELY(IsInline()) ? &InlineElements_[0] : OnHeapMeta_.Storage->Elements;
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::begin() const -> const_iterator
+{
+ return const_cast<TCompactVector*>(this)->begin();
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::end() -> iterator
+{
+ return Y_LIKELY(IsInline()) ? &InlineElements_[InlineMeta_.SizePlusOne - 1] : OnHeapMeta_.Storage->End;
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::end() const -> const_iterator
+{
+ return const_cast<TCompactVector*>(this)->end();
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::rbegin() -> reverse_iterator
+{
+ return static_cast<reverse_iterator>(end());
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::rbegin() const -> const_reverse_iterator
+{
+ return static_cast<const_reverse_iterator>(end());
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::rend() -> reverse_iterator
+{
+ return static_cast<reverse_iterator>(begin());
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::rend() const -> const_reverse_iterator
+{
+ return static_cast<const_reverse_iterator>(begin());
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::size() const -> size_type
+{
+ if (Y_LIKELY(IsInline())) {
+ return InlineMeta_.SizePlusOne - 1;
+ } else {
+ const auto* storage = OnHeapMeta_.Storage;
+ return storage->End - storage->Elements;
+ }
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::capacity() const -> size_type
+{
+ if (Y_LIKELY(IsInline())) {
+ return N;
+ } else {
+ const auto* storage = OnHeapMeta_.Storage;
+ return storage->Capacity - storage->Elements;
+ }
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::max_size() const -> size_type
+{
+ return static_cast<size_type>(-1) / sizeof(T);
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::data() -> pointer
+{
+ return static_cast<pointer>(begin());
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::data() const -> const_pointer
+{
+ return static_cast<const_pointer>(begin());
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::operator[](size_type index) -> reference
+{
+ YT_ASSERT(index < size());
+ return begin()[index];
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::operator[](size_type index) const -> const_reference
+{
+ return const_cast<TCompactVector*>(this)->operator[](index);
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::front() -> reference
+{
+ YT_ASSERT(!empty());
+ return begin()[0];
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::front() const -> const_reference
+{
+ return const_cast<TCompactVector*>(this)->front();
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::back() -> reference
+{
+ YT_ASSERT(!empty());
+ return end()[-1];
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::back() const -> const_reference
+{
+ return const_cast<TCompactVector*>(this)->back();
+}
+
+template <class T, size_t N>
+void TCompactVector<T, N>::push_back(const T& value)
+{
+ PushBackImpl(
+ &value,
+ [&] (T* dst, const T* value) {
+ ::new(dst) T(*value);
+ });
+}
+
+template <class T, size_t N>
+void TCompactVector<T, N>::push_back(T&& value)
+{
+ PushBackImpl(
+ &value,
+ [&] (T* dst, T* value) {
+ ::new(dst) T(std::move(*value));
+ });
+}
+
+template <class T, size_t N>
+template <class... TArgs>
+auto TCompactVector<T, N>::emplace(const_iterator pos, TArgs&&... args) -> iterator
+{
+ return InsertOneImpl(
+ pos,
+ nullptr,
+ [&] (auto* dst, std::nullptr_t) {
+ ::new(dst) T(std::forward<TArgs>(args)...);
+ },
+ [&] (auto* dst, std::nullptr_t) {
+ *dst = T(std::forward<TArgs>(args)...);
+ });
+}
+
+template <class T, size_t N>
+template <class... TArgs>
+auto TCompactVector<T, N>::emplace_back(TArgs&&... args) -> reference
+{
+ return PushBackImpl(
+ nullptr,
+ [&] (T* dst, std::nullptr_t) {
+ ::new(dst) T(std::forward<TArgs>(args)...);
+ });
+}
+
+template <class T, size_t N>
+void TCompactVector<T, N>::pop_back()
+{
+ YT_ASSERT(!empty());
+
+ if (Y_LIKELY(IsInline())) {
+ InlineElements_[InlineMeta_.SizePlusOne - 2].T::~T();
+ --InlineMeta_.SizePlusOne;
+ } else {
+ auto* storage = OnHeapMeta_.Storage;
+ storage->End[-1].T::~T();
+ --storage->End;
+ }
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::erase(const_iterator pos) -> iterator
+{
+ YT_ASSERT(pos >= begin());
+ YT_ASSERT(pos < end());
+
+ auto* mutablePos = const_cast<iterator>(pos);
+ Move(mutablePos + 1, end(), mutablePos);
+ pop_back();
+
+ return mutablePos;
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::erase(const_iterator first, const_iterator last) -> iterator
+{
+ YT_ASSERT(first >= begin());
+ YT_ASSERT(last <= end());
+
+ auto* mutableFirst = const_cast<iterator>(first);
+ auto* mutableLast = const_cast<iterator>(last);
+ auto count = std::distance(mutableFirst, mutableLast);
+
+ if (Y_LIKELY(IsInline())) {
+ auto* end = &InlineElements_[0] + InlineMeta_.SizePlusOne - 1;
+ Move(mutableLast, end, mutableFirst);
+ Destroy(end - count, end);
+ InlineMeta_.SizePlusOne -= count;
+ } else {
+ auto* storage = OnHeapMeta_.Storage;
+ auto* end = storage->End;
+ Move(mutableLast, storage->End, mutableFirst);
+ Destroy(end - count, end);
+ storage->End -= count;
+ }
+
+ return mutableFirst;
+}
+
+template <class T, size_t N>
+void TCompactVector<T, N>::clear()
+{
+ if (Y_LIKELY(IsInline())) {
+ Destroy(&InlineElements_[0], &InlineElements_[InlineMeta_.SizePlusOne - 1]);
+ InlineMeta_.SizePlusOne = 1;
+ } else {
+ auto* storage = OnHeapMeta_.Storage;
+ Destroy(storage->Elements, storage->End);
+ storage->End = storage->Elements;
+ }
+}
+
+template <class T, size_t N>
+void TCompactVector<T, N>::resize(size_type newSize)
+{
+ ResizeImpl(
+ newSize,
+ [] (auto* dst) {
+ ::new(dst) T();
+ });
+}
+
+template <class T, size_t N>
+void TCompactVector<T, N>::resize(size_type newSize, const T& value)
+{
+ ResizeImpl(
+ newSize,
+ [&] (auto* dst) {
+ ::new(dst) T(value);
+ });
+}
+
+template <class T, size_t N>
+void TCompactVector<T, N>::reserve(size_t newCapacity)
+{
+ if (Y_UNLIKELY(newCapacity > N)) {
+ EnsureOnHeapCapacity(newCapacity, /*incremental*/ false);
+ }
+}
+
+template <class T, size_t N>
+void TCompactVector<T, N>::swap(TCompactVector& other)
+{
+ if (this == &other) {
+ return;
+ }
+
+ if (!IsInline() && !other.IsInline()) {
+ std::swap(OnHeapMeta_.Storage, other.OnHeapMeta_.Storage);
+ return;
+ }
+
+ auto* lhs = this;
+ auto* rhs = &other;
+ if (lhs->size() < rhs->size()) {
+ std::swap(lhs, rhs);
+ }
+
+ size_t rhsSize = rhs->size();
+ size_t lhsSize = lhs->size();
+ if (lhsSize > rhs->capacity()) {
+ rhs->EnsureOnHeapCapacity(lhs->size(), /*incremental*/ false);
+ }
+
+ for (size_t index = 0; index < rhsSize; ++index) {
+ std::swap((*lhs)[index], (*rhs)[index]);
+ }
+
+ UninitializedMove(lhs->begin() + rhsSize, lhs->end(), rhs->end());
+ Destroy(lhs->begin() + rhsSize, lhs->end());
+
+ rhs->SetSize(lhsSize);
+ lhs->SetSize(rhsSize);
+}
+
+template <class T, size_t N>
+void TCompactVector<T, N>::assign(size_type count, const T& value)
+{
+ clear();
+
+ if (Y_UNLIKELY(count > capacity())) {
+ EnsureOnHeapCapacity(count, /*incremental*/ false);
+ }
+
+ auto* dst = begin();
+ std::uninitialized_fill(dst, dst + count, value);
+
+ SetSize(count);
+}
+
+template <class T, size_t N>
+template <class TIterator>
+void TCompactVector<T, N>::assign(TIterator first, TIterator last)
+{
+ clear();
+
+ auto count = std::distance(first, last);
+ if (Y_UNLIKELY(count > static_cast<ptrdiff_t>(capacity()))) {
+ EnsureOnHeapCapacity(count, /*incremental*/ false);
+ }
+
+ std::uninitialized_copy(first, last, begin());
+
+ SetSize(count);
+}
+
+template <class T, size_t N>
+void TCompactVector<T, N>::assign(std::initializer_list<T> list)
+{
+ assign(list.begin(), list.end());
+}
+
+template <class T, size_t N>
+template <size_t OtherN>
+void TCompactVector<T, N>::assign(const TCompactVector<T, OtherN>& other)
+{
+ if constexpr(N == OtherN) {
+ if (this == &other) {
+ return;
+ }
+ }
+
+ auto otherSize = other.size();
+ auto otherBegin = other.begin();
+
+ if (capacity() >= otherSize) {
+ const auto* src = other.begin();
+ auto* dst = begin();
+
+ auto thisSize = size();
+ auto copySize = std::min(thisSize, otherSize);
+ Copy(src, src + copySize, dst);
+ src += copySize;
+ dst += copySize;
+
+ auto uninitializedCopySize = otherSize - copySize;
+ UninitializedCopy(src, src + uninitializedCopySize, dst);
+ // NB: src += uninitializedCopySize is not needed.
+ dst += uninitializedCopySize;
+
+ if (thisSize > otherSize) {
+ Destroy(dst, end());
+ }
+
+ SetSize(otherSize);
+ return;
+ }
+
+ clear();
+
+ EnsureOnHeapCapacity(otherSize, /*incremental*/ false);
+
+ YT_ASSERT(!IsInline());
+ auto* storage = OnHeapMeta_.Storage;
+ UninitializedCopy(otherBegin, otherBegin + otherSize, storage->Elements);
+ storage->End = storage->Elements + otherSize;
+}
+
+template <class T, size_t N>
+template <size_t OtherN>
+void TCompactVector<T, N>::assign(TCompactVector<T, OtherN>&& other)
+{
+ if constexpr(N == OtherN) {
+ if (this == &other) {
+ return;
+ }
+ }
+
+ clear();
+
+ if (!other.IsInline()) {
+ if (Y_UNLIKELY(!IsInline())) {
+ ::free(OnHeapMeta_.Storage);
+ }
+ OnHeapMeta_.Storage = other.OnHeapMeta_.Storage;
+ other.InlineMeta_.SizePlusOne = 1;
+ return;
+ }
+
+ auto otherSize = other.size();
+ if (Y_UNLIKELY(otherSize > capacity())) {
+ EnsureOnHeapCapacity(otherSize, /*incremental*/ false);
+ }
+
+ auto* otherBegin = other.begin();
+ UninitializedMove(otherBegin, otherBegin + otherSize, begin());
+ SetSize(otherSize);
+
+ other.clear();
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::operator=(const TCompactVector& other) -> TCompactVector&
+{
+ assign(other);
+ return *this;
+}
+
+template <class T, size_t N>
+template <size_t OtherN>
+auto TCompactVector<T, N>::operator=(const TCompactVector<T, OtherN>& other) -> TCompactVector&
+{
+ assign(other);
+ return *this;
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::operator=(TCompactVector&& other) -> TCompactVector&
+{
+ assign(std::move(other));
+ return *this;
+}
+
+template <class T, size_t N>
+template <size_t OtherN>
+auto TCompactVector<T, N>::operator=(TCompactVector<T, OtherN>&& other) -> TCompactVector&
+{
+ assign(std::move(other));
+ return *this;
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::operator=(std::initializer_list<T> list) -> TCompactVector&
+{
+ assign(list);
+ return *this;
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::insert(const_iterator pos, const T& value) -> iterator
+{
+ return InsertOneImpl(
+ pos,
+ &value,
+ [&] (auto* dst, const auto* value) {
+ ::new(dst) T(*value);
+ },
+ [&] (auto* dst, const auto* value) {
+ *dst = *value;
+ });
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::insert(const_iterator pos, T&& value) -> iterator
+{
+ return InsertOneImpl(
+ pos,
+ &value,
+ [&] (auto* dst, auto* value) {
+ ::new(dst) T(std::move(*value));
+ },
+ [&] (auto* dst, auto* value) {
+ *dst = std::move(*value);
+ });
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::insert(const_iterator pos, size_type count, const T& value) -> iterator
+{
+ return InsertManyImpl(
+ pos,
+ count,
+ [&] (auto* dstFirst, auto* dstLast) {
+ for (auto* dst = dstFirst; dst != dstLast; ++dst) {
+ ::new(dst) T(value);
+ }
+ },
+ [&] (auto* dstFirst, auto* dstLast) {
+ for (auto* dst = dstFirst; dst != dstLast; ++dst) {
+ *dst = value;
+ }
+ });
+}
+
+template <class T, size_t N>
+template <class TIterator>
+auto TCompactVector<T, N>::insert(const_iterator pos, TIterator first, TIterator last) -> iterator
+{
+ auto current = first;
+ return InsertManyImpl(
+ pos,
+ std::distance(first, last),
+ [&] (auto* dstFirst, auto* dstLast) {
+ for (auto* dst = dstFirst; dst != dstLast; ++dst) {
+ ::new(dst) T(*current++);
+ }
+ },
+ [&] (auto* dstFirst, auto* dstLast) {
+ for (auto* dst = dstFirst; dst != dstLast; ++dst) {
+ *dst = *current++;
+ }
+ });
+}
+
+template <class T, size_t N>
+auto TCompactVector<T, N>::insert(const_iterator pos, std::initializer_list<T> list) -> iterator
+{
+ return insert(pos, list.begin(), list.end());
+}
+
+template <class T, size_t N>
void TCompactVector<T, N>::shrink_to_small()
{
if (Y_LIKELY(IsInline())) {
@@ -709,303 +709,303 @@ void TCompactVector<T, N>::shrink_to_small()
}
template <class T, size_t N>
-bool TCompactVector<T, N>::IsInline() const
-{
- return InlineMeta_.SizePlusOne != 0;
-}
-
-template <class T, size_t N>
-void TCompactVector<T, N>::SetSize(size_t newSize)
-{
- if (Y_LIKELY(IsInline())) {
- InlineMeta_.SizePlusOne = newSize + 1;
- } else {
- auto* storage = OnHeapMeta_.Storage;
- storage->End = storage->Elements + newSize;
- }
-}
-
-template <class T, size_t N>
-void TCompactVector<T, N>::EnsureOnHeapCapacity(size_t newCapacity, bool incremental)
-{
- newCapacity = std::max(newCapacity, N + 1);
- if (incremental) {
- newCapacity = std::max(newCapacity, capacity() * 2);
- }
-
- auto byteSize = sizeof(TOnHeapStorage) + newCapacity * sizeof(T);
+bool TCompactVector<T, N>::IsInline() const
+{
+ return InlineMeta_.SizePlusOne != 0;
+}
+
+template <class T, size_t N>
+void TCompactVector<T, N>::SetSize(size_t newSize)
+{
+ if (Y_LIKELY(IsInline())) {
+ InlineMeta_.SizePlusOne = newSize + 1;
+ } else {
+ auto* storage = OnHeapMeta_.Storage;
+ storage->End = storage->Elements + newSize;
+ }
+}
+
+template <class T, size_t N>
+void TCompactVector<T, N>::EnsureOnHeapCapacity(size_t newCapacity, bool incremental)
+{
+ newCapacity = std::max(newCapacity, N + 1);
+ if (incremental) {
+ newCapacity = std::max(newCapacity, capacity() * 2);
+ }
+
+ auto byteSize = sizeof(TOnHeapStorage) + newCapacity * sizeof(T);
byteSize = nallocx(byteSize, 0);
-
- newCapacity = (byteSize - sizeof(TOnHeapStorage)) / sizeof(T);
-
- auto* newStorage = static_cast<TOnHeapStorage*>(::malloc(byteSize));
- YT_VERIFY((reinterpret_cast<uintptr_t>(newStorage) >> 56) == 0);
-
- newStorage->Capacity = newStorage->Elements + newCapacity;
-
- size_t size;
- if (IsInline()) {
- size = InlineMeta_.SizePlusOne - 1;
- UninitializedMove(&InlineElements_[0], &InlineElements_[0] + size, newStorage->Elements);
- Destroy(&InlineElements_[0], &InlineElements_[0] + size);
- } else {
- auto* storage = OnHeapMeta_.Storage;
- size = storage->End - storage->Elements;
- UninitializedMove(storage->Elements, storage->End, newStorage->Elements);
- Destroy(storage->Elements, storage->End);
- ::free(storage);
- }
-
- newStorage->End = newStorage->Elements + size;
- OnHeapMeta_.Storage = newStorage;
-}
-
-template <class T, size_t N>
-template <class TPtr, class F>
-auto TCompactVector<T, N>::PushBackImpl(TPtr valuePtr, F&& func) -> reference
-{
- auto sizePlusOne = InlineMeta_.SizePlusOne;
- if (Y_LIKELY(sizePlusOne != 0 && sizePlusOne != N + 1)) {
- auto* dst = &InlineElements_[sizePlusOne - 1];
- func(dst, valuePtr);
- ++InlineMeta_.SizePlusOne;
- return *dst;
- }
-
- auto hasSpareOnHeapCapacity = [&] {
- if (sizePlusOne != 0) {
- return false;
- }
- auto* storage = OnHeapMeta_.Storage;
- return storage->End < storage->Capacity;
- };
-
- if (Y_UNLIKELY(!hasSpareOnHeapCapacity())) {
- TCompactVectorReallocationPtrAdjuster<TCompactVector, TPtr> valuePtrAdjuster(this, valuePtr);
- EnsureOnHeapCapacity(0, /*incremental*/ true);
- }
-
- YT_ASSERT(!IsInline());
- auto* storage = OnHeapMeta_.Storage;
- auto* dst = storage->End++;
- func(dst, valuePtr);
-
- return *dst;
-}
-
-template <class T, size_t N>
-template <class F>
-void TCompactVector<T, N>::ResizeImpl(size_type newSize, F&& func)
-{
- auto size = this->size();
- if (newSize > size) {
- if (Y_UNLIKELY(newSize > capacity())) {
- EnsureOnHeapCapacity(newSize, /*incremental*/ false);
- }
-
- auto* first = end();
- auto* last = first + newSize - size;
- for (auto* current = first; current != last; ++current) {
- func(current);
- }
- } else if (newSize < size) {
- Destroy(begin() + newSize, end());
- }
-
- SetSize(newSize);
-}
-
-template <class T, size_t N>
-template <class TPtr, class UninitializedF, class InitializedF>
-auto TCompactVector<T, N>::InsertOneImpl(const_iterator pos, TPtr valuePtr, UninitializedF&& uninitializedFunc, InitializedF&& initializedFunc) -> iterator
-{
- YT_ASSERT(pos >= begin());
- YT_ASSERT(pos <= end());
-
- auto* mutablePos = const_cast<iterator>(pos);
-
- auto newSize = size() + 1;
- if (Y_UNLIKELY(newSize > capacity())) {
- TCompactVectorReallocationPtrAdjuster<TCompactVector, iterator> mutablePosAdjuster(this, mutablePos);
- TCompactVectorReallocationPtrAdjuster<TCompactVector, TPtr> valuePtrAdjuster(this, valuePtr);
- EnsureOnHeapCapacity(newSize, /*incremental*/ true);
- }
-
- auto* end = this->end();
-
- if constexpr(!std::is_same_v<TPtr, std::nullptr_t>) {
- if (valuePtr >= mutablePos && valuePtr < end) {
- ++valuePtr;
- }
- }
-
- auto moveCount = std::distance(mutablePos, end);
- if (moveCount == 0) {
- uninitializedFunc(end, valuePtr);
- } else {
- if constexpr(std::is_trivially_copyable_v<T>) {
- ::memmove(mutablePos + 1, mutablePos, moveCount * sizeof(T));
- } else {
- ::new(end) T(std::move(end[-1]));
- MoveBackward(mutablePos, end - 1, mutablePos + 1);
- }
- initializedFunc(mutablePos, valuePtr);
- }
-
- SetSize(newSize);
-
- return mutablePos;
-}
-
-template <class T, size_t N>
-template <class UninitializedF, class InitializedF>
-auto TCompactVector<T, N>::InsertManyImpl(const_iterator pos, size_t insertCount, UninitializedF&& uninitializedFunc, InitializedF&& initializedFunc) -> iterator
-{
- YT_ASSERT(pos >= begin());
- YT_ASSERT(pos <= end());
-
- auto* mutablePos = const_cast<iterator>(pos);
- if (insertCount == 0) {
- return mutablePos;
- }
-
- auto size = this->size();
- auto newSize = size + insertCount;
- if (Y_UNLIKELY(newSize > capacity())) {
- auto index = std::distance(begin(), mutablePos);
- EnsureOnHeapCapacity(newSize, /*incremental*/ true);
- mutablePos = begin() + index;
- }
-
- auto* end = this->end();
- auto moveCount = std::distance(mutablePos, end);
- if constexpr(std::is_trivially_copyable_v<T>) {
- ::memmove(mutablePos + insertCount, mutablePos, moveCount * sizeof(T));
- initializedFunc(mutablePos, mutablePos + insertCount);
- } else {
- if (static_cast<ptrdiff_t>(insertCount) >= moveCount) {
- UninitializedMove(mutablePos, end, mutablePos + insertCount);
- initializedFunc(mutablePos, end);
- uninitializedFunc(end, end + insertCount - moveCount);
- } else {
- auto overlapCount = moveCount - insertCount;
- UninitializedMove(mutablePos + overlapCount, end, mutablePos + overlapCount + insertCount);
- MoveBackward(mutablePos, mutablePos + overlapCount, mutablePos + insertCount);
- initializedFunc(mutablePos, mutablePos + insertCount);
- }
- }
-
- SetSize(newSize);
-
- return mutablePos;
-}
-
-template <class T, size_t N>
-void TCompactVector<T, N>::Destroy(T* first, T* last)
-{
- if constexpr(!std::is_trivially_destructible_v<T>) {
- for (auto* current = first; current != last; ++current) {
- current->T::~T();
- }
- }
-}
-
-template <class T, size_t N>
-template <class T1, class T2>
-void TCompactVector<T, N>::Copy(const T1* srcFirst, const T1* srcLast, T2* dst)
-{
- if constexpr(std::is_trivially_copyable_v<T1> && std::is_same_v<T1, T2>) {
- ::memcpy(dst, srcFirst, (srcLast - srcFirst) * sizeof(T));
- } else {
- std::copy(srcFirst, srcLast, dst);
- }
-}
-
-template <class T, size_t N>
-template <class T1, class T2>
-void TCompactVector<T, N>::UninitializedCopy(const T1* srcFirst, const T1* srcLast, T2* dst)
-{
- if constexpr(std::is_trivially_copyable_v<T1> && std::is_same_v<T1, T2>) {
- ::memcpy(dst, srcFirst, (srcLast - srcFirst) * sizeof(T));
- } else {
- std::uninitialized_copy(srcFirst, srcLast, dst);
- }
-}
-
-template <class T, size_t N>
-void TCompactVector<T, N>::Move(T* srcFirst, T* srcLast, T* dst)
-{
- if constexpr(std::is_trivially_copyable_v<T>) {
+
+ newCapacity = (byteSize - sizeof(TOnHeapStorage)) / sizeof(T);
+
+ auto* newStorage = static_cast<TOnHeapStorage*>(::malloc(byteSize));
+ YT_VERIFY((reinterpret_cast<uintptr_t>(newStorage) >> 56) == 0);
+
+ newStorage->Capacity = newStorage->Elements + newCapacity;
+
+ size_t size;
+ if (IsInline()) {
+ size = InlineMeta_.SizePlusOne - 1;
+ UninitializedMove(&InlineElements_[0], &InlineElements_[0] + size, newStorage->Elements);
+ Destroy(&InlineElements_[0], &InlineElements_[0] + size);
+ } else {
+ auto* storage = OnHeapMeta_.Storage;
+ size = storage->End - storage->Elements;
+ UninitializedMove(storage->Elements, storage->End, newStorage->Elements);
+ Destroy(storage->Elements, storage->End);
+ ::free(storage);
+ }
+
+ newStorage->End = newStorage->Elements + size;
+ OnHeapMeta_.Storage = newStorage;
+}
+
+template <class T, size_t N>
+template <class TPtr, class F>
+auto TCompactVector<T, N>::PushBackImpl(TPtr valuePtr, F&& func) -> reference
+{
+ auto sizePlusOne = InlineMeta_.SizePlusOne;
+ if (Y_LIKELY(sizePlusOne != 0 && sizePlusOne != N + 1)) {
+ auto* dst = &InlineElements_[sizePlusOne - 1];
+ func(dst, valuePtr);
+ ++InlineMeta_.SizePlusOne;
+ return *dst;
+ }
+
+ auto hasSpareOnHeapCapacity = [&] {
+ if (sizePlusOne != 0) {
+ return false;
+ }
+ auto* storage = OnHeapMeta_.Storage;
+ return storage->End < storage->Capacity;
+ };
+
+ if (Y_UNLIKELY(!hasSpareOnHeapCapacity())) {
+ TCompactVectorReallocationPtrAdjuster<TCompactVector, TPtr> valuePtrAdjuster(this, valuePtr);
+ EnsureOnHeapCapacity(0, /*incremental*/ true);
+ }
+
+ YT_ASSERT(!IsInline());
+ auto* storage = OnHeapMeta_.Storage;
+ auto* dst = storage->End++;
+ func(dst, valuePtr);
+
+ return *dst;
+}
+
+template <class T, size_t N>
+template <class F>
+void TCompactVector<T, N>::ResizeImpl(size_type newSize, F&& func)
+{
+ auto size = this->size();
+ if (newSize > size) {
+ if (Y_UNLIKELY(newSize > capacity())) {
+ EnsureOnHeapCapacity(newSize, /*incremental*/ false);
+ }
+
+ auto* first = end();
+ auto* last = first + newSize - size;
+ for (auto* current = first; current != last; ++current) {
+ func(current);
+ }
+ } else if (newSize < size) {
+ Destroy(begin() + newSize, end());
+ }
+
+ SetSize(newSize);
+}
+
+template <class T, size_t N>
+template <class TPtr, class UninitializedF, class InitializedF>
+auto TCompactVector<T, N>::InsertOneImpl(const_iterator pos, TPtr valuePtr, UninitializedF&& uninitializedFunc, InitializedF&& initializedFunc) -> iterator
+{
+ YT_ASSERT(pos >= begin());
+ YT_ASSERT(pos <= end());
+
+ auto* mutablePos = const_cast<iterator>(pos);
+
+ auto newSize = size() + 1;
+ if (Y_UNLIKELY(newSize > capacity())) {
+ TCompactVectorReallocationPtrAdjuster<TCompactVector, iterator> mutablePosAdjuster(this, mutablePos);
+ TCompactVectorReallocationPtrAdjuster<TCompactVector, TPtr> valuePtrAdjuster(this, valuePtr);
+ EnsureOnHeapCapacity(newSize, /*incremental*/ true);
+ }
+
+ auto* end = this->end();
+
+ if constexpr(!std::is_same_v<TPtr, std::nullptr_t>) {
+ if (valuePtr >= mutablePos && valuePtr < end) {
+ ++valuePtr;
+ }
+ }
+
+ auto moveCount = std::distance(mutablePos, end);
+ if (moveCount == 0) {
+ uninitializedFunc(end, valuePtr);
+ } else {
+ if constexpr(std::is_trivially_copyable_v<T>) {
+ ::memmove(mutablePos + 1, mutablePos, moveCount * sizeof(T));
+ } else {
+ ::new(end) T(std::move(end[-1]));
+ MoveBackward(mutablePos, end - 1, mutablePos + 1);
+ }
+ initializedFunc(mutablePos, valuePtr);
+ }
+
+ SetSize(newSize);
+
+ return mutablePos;
+}
+
+template <class T, size_t N>
+template <class UninitializedF, class InitializedF>
+auto TCompactVector<T, N>::InsertManyImpl(const_iterator pos, size_t insertCount, UninitializedF&& uninitializedFunc, InitializedF&& initializedFunc) -> iterator
+{
+ YT_ASSERT(pos >= begin());
+ YT_ASSERT(pos <= end());
+
+ auto* mutablePos = const_cast<iterator>(pos);
+ if (insertCount == 0) {
+ return mutablePos;
+ }
+
+ auto size = this->size();
+ auto newSize = size + insertCount;
+ if (Y_UNLIKELY(newSize > capacity())) {
+ auto index = std::distance(begin(), mutablePos);
+ EnsureOnHeapCapacity(newSize, /*incremental*/ true);
+ mutablePos = begin() + index;
+ }
+
+ auto* end = this->end();
+ auto moveCount = std::distance(mutablePos, end);
+ if constexpr(std::is_trivially_copyable_v<T>) {
+ ::memmove(mutablePos + insertCount, mutablePos, moveCount * sizeof(T));
+ initializedFunc(mutablePos, mutablePos + insertCount);
+ } else {
+ if (static_cast<ptrdiff_t>(insertCount) >= moveCount) {
+ UninitializedMove(mutablePos, end, mutablePos + insertCount);
+ initializedFunc(mutablePos, end);
+ uninitializedFunc(end, end + insertCount - moveCount);
+ } else {
+ auto overlapCount = moveCount - insertCount;
+ UninitializedMove(mutablePos + overlapCount, end, mutablePos + overlapCount + insertCount);
+ MoveBackward(mutablePos, mutablePos + overlapCount, mutablePos + insertCount);
+ initializedFunc(mutablePos, mutablePos + insertCount);
+ }
+ }
+
+ SetSize(newSize);
+
+ return mutablePos;
+}
+
+template <class T, size_t N>
+void TCompactVector<T, N>::Destroy(T* first, T* last)
+{
+ if constexpr(!std::is_trivially_destructible_v<T>) {
+ for (auto* current = first; current != last; ++current) {
+ current->T::~T();
+ }
+ }
+}
+
+template <class T, size_t N>
+template <class T1, class T2>
+void TCompactVector<T, N>::Copy(const T1* srcFirst, const T1* srcLast, T2* dst)
+{
+ if constexpr(std::is_trivially_copyable_v<T1> && std::is_same_v<T1, T2>) {
+ ::memcpy(dst, srcFirst, (srcLast - srcFirst) * sizeof(T));
+ } else {
+ std::copy(srcFirst, srcLast, dst);
+ }
+}
+
+template <class T, size_t N>
+template <class T1, class T2>
+void TCompactVector<T, N>::UninitializedCopy(const T1* srcFirst, const T1* srcLast, T2* dst)
+{
+ if constexpr(std::is_trivially_copyable_v<T1> && std::is_same_v<T1, T2>) {
+ ::memcpy(dst, srcFirst, (srcLast - srcFirst) * sizeof(T));
+ } else {
+ std::uninitialized_copy(srcFirst, srcLast, dst);
+ }
+}
+
+template <class T, size_t N>
+void TCompactVector<T, N>::Move(T* srcFirst, T* srcLast, T* dst)
+{
+ if constexpr(std::is_trivially_copyable_v<T>) {
::memmove(dst, srcFirst, (srcLast - srcFirst) * sizeof(T));
- } else {
- std::move(srcFirst, srcLast, dst);
- }
-}
-
-template <class T, size_t N>
-void TCompactVector<T, N>::UninitializedMove(T* srcFirst, T* srcLast, T* dst)
-{
- if constexpr(std::is_trivially_copyable_v<T>) {
- ::memcpy(dst, srcFirst, (srcLast - srcFirst) * sizeof(T));
- } else {
- std::uninitialized_move(srcFirst, srcLast, dst);
- }
-}
-
-template <class T, size_t N>
-void TCompactVector<T, N>::MoveBackward(T* srcFirst, T* srcLast, T* dst)
-{
- auto* src = srcLast;
- dst += std::distance(srcFirst, srcLast);
- while (src > srcFirst) {
- *--dst = std::move(*--src);
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////
-
-template <class T, size_t LhsN, size_t RhsN>
-bool operator==(const TCompactVector<T, LhsN>& lhs, const TCompactVector<T, RhsN>& rhs)
-{
- if constexpr(LhsN == RhsN) {
- if (&lhs == &rhs) {
- return true;
- }
- }
-
- if (lhs.size() != rhs.size()) {
- return false;
- }
-
- return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
-}
-
-template <class T, size_t LhsN, size_t RhsN>
-bool operator!=(const TCompactVector<T, LhsN>& lhs, const TCompactVector<T, RhsN>& rhs)
-{
- return !(lhs == rhs);
-}
-
-template <class T, size_t LhsN, size_t RhsN>
-bool operator<(const TCompactVector<T, LhsN>& lhs, const TCompactVector<T, RhsN>& rhs)
-{
- return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
-}
-
-/////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
-
-namespace std {
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class T, size_t N>
-void swap(NYT::TCompactVector<T, N>& lhs, NYT::TCompactVector<T, N>& rhs)
-{
- lhs.swap(rhs);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace std
+ } else {
+ std::move(srcFirst, srcLast, dst);
+ }
+}
+
+template <class T, size_t N>
+void TCompactVector<T, N>::UninitializedMove(T* srcFirst, T* srcLast, T* dst)
+{
+ if constexpr(std::is_trivially_copyable_v<T>) {
+ ::memcpy(dst, srcFirst, (srcLast - srcFirst) * sizeof(T));
+ } else {
+ std::uninitialized_move(srcFirst, srcLast, dst);
+ }
+}
+
+template <class T, size_t N>
+void TCompactVector<T, N>::MoveBackward(T* srcFirst, T* srcLast, T* dst)
+{
+ auto* src = srcLast;
+ dst += std::distance(srcFirst, srcLast);
+ while (src > srcFirst) {
+ *--dst = std::move(*--src);
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+template <class T, size_t LhsN, size_t RhsN>
+bool operator==(const TCompactVector<T, LhsN>& lhs, const TCompactVector<T, RhsN>& rhs)
+{
+ if constexpr(LhsN == RhsN) {
+ if (&lhs == &rhs) {
+ return true;
+ }
+ }
+
+ if (lhs.size() != rhs.size()) {
+ return false;
+ }
+
+ return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
+}
+
+template <class T, size_t LhsN, size_t RhsN>
+bool operator!=(const TCompactVector<T, LhsN>& lhs, const TCompactVector<T, RhsN>& rhs)
+{
+ return !(lhs == rhs);
+}
+
+template <class T, size_t LhsN, size_t RhsN>
+bool operator<(const TCompactVector<T, LhsN>& lhs, const TCompactVector<T, RhsN>& rhs)
+{
+ return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
+
+namespace std {
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T, size_t N>
+void swap(NYT::TCompactVector<T, N>& lhs, NYT::TCompactVector<T, N>& rhs)
+{
+ lhs.swap(rhs);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace std
diff --git a/library/cpp/yt/small_containers/compact_vector.h b/library/cpp/yt/small_containers/compact_vector.h
index a2054ef9e7..6c4a0b0e39 100644
--- a/library/cpp/yt/small_containers/compact_vector.h
+++ b/library/cpp/yt/small_containers/compact_vector.h
@@ -1,219 +1,219 @@
-#pragma once
-
+#pragma once
+
#include <util/system/defaults.h>
-#include <cstdint>
-#include <iterator>
-#include <limits>
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class T>
-struct TCompactVectorOnHeapStorage;
-
-//! A vector-like structure optimized for storing elements inline
-//! and with little memory overhead.
-/*!
- * Stores up to #N (<= 254) elements inline.
- *
- * When capacity starts exceeding #N, moves all elements to heap;
- * \see #TCompactVectorOnHeapStorage.
- *
- * When linked with YTAlloc, employs its API to adjust the on-heap capacity in accordance
- * to the actual size of the allocated region.
- *
- * Assuming the entropy and the alignment constraints, yields a seemingly optimal memory overhead.
- * E.g. TCompactVector<uint8_t, 7> takes 8 bytes and TCompactVector<uint32_t, 3> takes 16 bytes.
- * \see #ByteSize.
- *
- * Assumes (and asserts) the following:
- * 1) the platform is 64 bit;
- * 2) the highest 8 bits of pointers returned by |malloc| are zeroes;
- * 3) the platform is little-endian.
- */
-template <class T, size_t N>
-class TCompactVector
-{
-public:
- static_assert(N < std::numeric_limits<uint8_t>::max());
-
- using size_type = size_t;
- using difference_type = ptrdiff_t;
-
- using value_type = T;
-
- using iterator = T*;
- using const_iterator = const T*;
-
- using const_reverse_iterator = std::reverse_iterator<const_iterator>;
- using reverse_iterator = std::reverse_iterator<iterator>;
-
- using reference = T&;
- using const_reference = const T&;
-
- using pointer = T*;
- using const_pointer = const T*;
-
- TCompactVector() noexcept;
- TCompactVector(const TCompactVector& other);
- template <size_t OtherN>
- TCompactVector(const TCompactVector<T, OtherN>& other);
+#include <cstdint>
+#include <iterator>
+#include <limits>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T>
+struct TCompactVectorOnHeapStorage;
+
+//! A vector-like structure optimized for storing elements inline
+//! and with little memory overhead.
+/*!
+ * Stores up to #N (<= 254) elements inline.
+ *
+ * When capacity starts exceeding #N, moves all elements to heap;
+ * \see #TCompactVectorOnHeapStorage.
+ *
+ * When linked with YTAlloc, employs its API to adjust the on-heap capacity in accordance
+ * to the actual size of the allocated region.
+ *
+ * Assuming the entropy and the alignment constraints, yields a seemingly optimal memory overhead.
+ * E.g. TCompactVector<uint8_t, 7> takes 8 bytes and TCompactVector<uint32_t, 3> takes 16 bytes.
+ * \see #ByteSize.
+ *
+ * Assumes (and asserts) the following:
+ * 1) the platform is 64 bit;
+ * 2) the highest 8 bits of pointers returned by |malloc| are zeroes;
+ * 3) the platform is little-endian.
+ */
+template <class T, size_t N>
+class TCompactVector
+{
+public:
+ static_assert(N < std::numeric_limits<uint8_t>::max());
+
+ using size_type = size_t;
+ using difference_type = ptrdiff_t;
+
+ using value_type = T;
+
+ using iterator = T*;
+ using const_iterator = const T*;
+
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+ using reverse_iterator = std::reverse_iterator<iterator>;
+
+ using reference = T&;
+ using const_reference = const T&;
+
+ using pointer = T*;
+ using const_pointer = const T*;
+
+ TCompactVector() noexcept;
+ TCompactVector(const TCompactVector& other);
+ template <size_t OtherN>
+ TCompactVector(const TCompactVector<T, OtherN>& other);
TCompactVector(TCompactVector&& other) noexcept(std::is_nothrow_move_constructible_v<T>);
- template <size_t OtherN>
- TCompactVector(TCompactVector<T, OtherN>&& other);
- explicit TCompactVector(size_type count);
- TCompactVector(size_type count, const T& value);
- template <class TIterator>
- TCompactVector(TIterator first, TIterator last);
- TCompactVector(std::initializer_list<T> list);
-
- ~TCompactVector();
-
- [[nodiscard]] bool empty() const;
-
- iterator begin();
- const_iterator begin() const;
- iterator end();
- const_iterator end() const;
-
- reverse_iterator rbegin();
- const_reverse_iterator rbegin() const;
- reverse_iterator rend();
- const_reverse_iterator rend() const;
-
- size_type size() const;
- size_type capacity() const;
- size_type max_size() const;
-
- pointer data();
- const_pointer data() const;
-
- reference operator[](size_type index);
- const_reference operator[](size_type index) const;
-
- reference front();
- const_reference front() const;
- reference back();
- const_reference back() const;
-
- void push_back(const T& value);
- void push_back(T&& value);
-
- template <class... TArgs>
- iterator emplace(const_iterator pos, TArgs&&... args);
- template <class... TArgs>
- reference emplace_back(TArgs&&... args);
-
- void pop_back();
-
- iterator erase(const_iterator pos);
- iterator erase(const_iterator first, const_iterator last);
-
- void clear();
-
- void resize(size_type newSize);
- void resize(size_type newSize, const T& value);
-
- void reserve(size_type newCapacity);
-
- void swap(TCompactVector& other);
-
- void assign(size_type count, const T& value);
- template <class TIterator>
- void assign(TIterator first, TIterator last);
- void assign(std::initializer_list<T> list);
- template <size_t OtherN>
- void assign(const TCompactVector<T, OtherN>& other);
- template <size_t OtherN>
- void assign(TCompactVector<T, OtherN>&& other);
-
- TCompactVector& operator=(const TCompactVector& other);
- template <size_t OtherN>
- TCompactVector& operator=(const TCompactVector<T, OtherN>& other);
- TCompactVector& operator=(TCompactVector&& other);
- template <size_t OtherN>
- TCompactVector& operator=(TCompactVector<T, OtherN>&& other);
- TCompactVector& operator=(std::initializer_list<T> list);
-
- iterator insert(const_iterator pos, const T& value);
- iterator insert(const_iterator pos, T&& value);
- iterator insert(const_iterator pos, size_type count, const T& value);
- template <class TIterator>
- iterator insert(const_iterator pos, TIterator first, TIterator last);
- iterator insert(const_iterator pos, std::initializer_list<T> list);
-
+ template <size_t OtherN>
+ TCompactVector(TCompactVector<T, OtherN>&& other);
+ explicit TCompactVector(size_type count);
+ TCompactVector(size_type count, const T& value);
+ template <class TIterator>
+ TCompactVector(TIterator first, TIterator last);
+ TCompactVector(std::initializer_list<T> list);
+
+ ~TCompactVector();
+
+ [[nodiscard]] bool empty() const;
+
+ iterator begin();
+ const_iterator begin() const;
+ iterator end();
+ const_iterator end() const;
+
+ reverse_iterator rbegin();
+ const_reverse_iterator rbegin() const;
+ reverse_iterator rend();
+ const_reverse_iterator rend() const;
+
+ size_type size() const;
+ size_type capacity() const;
+ size_type max_size() const;
+
+ pointer data();
+ const_pointer data() const;
+
+ reference operator[](size_type index);
+ const_reference operator[](size_type index) const;
+
+ reference front();
+ const_reference front() const;
+ reference back();
+ const_reference back() const;
+
+ void push_back(const T& value);
+ void push_back(T&& value);
+
+ template <class... TArgs>
+ iterator emplace(const_iterator pos, TArgs&&... args);
+ template <class... TArgs>
+ reference emplace_back(TArgs&&... args);
+
+ void pop_back();
+
+ iterator erase(const_iterator pos);
+ iterator erase(const_iterator first, const_iterator last);
+
+ void clear();
+
+ void resize(size_type newSize);
+ void resize(size_type newSize, const T& value);
+
+ void reserve(size_type newCapacity);
+
+ void swap(TCompactVector& other);
+
+ void assign(size_type count, const T& value);
+ template <class TIterator>
+ void assign(TIterator first, TIterator last);
+ void assign(std::initializer_list<T> list);
+ template <size_t OtherN>
+ void assign(const TCompactVector<T, OtherN>& other);
+ template <size_t OtherN>
+ void assign(TCompactVector<T, OtherN>&& other);
+
+ TCompactVector& operator=(const TCompactVector& other);
+ template <size_t OtherN>
+ TCompactVector& operator=(const TCompactVector<T, OtherN>& other);
+ TCompactVector& operator=(TCompactVector&& other);
+ template <size_t OtherN>
+ TCompactVector& operator=(TCompactVector<T, OtherN>&& other);
+ TCompactVector& operator=(std::initializer_list<T> list);
+
+ iterator insert(const_iterator pos, const T& value);
+ iterator insert(const_iterator pos, T&& value);
+ iterator insert(const_iterator pos, size_type count, const T& value);
+ template <class TIterator>
+ iterator insert(const_iterator pos, TIterator first, TIterator last);
+ iterator insert(const_iterator pos, std::initializer_list<T> list);
+
void shrink_to_small();
-private:
- template <class OtherT, size_t OtherN>
- friend class TCompactVector;
-
- using TOnHeapStorage = TCompactVectorOnHeapStorage<T>;
-
- static constexpr size_t ByteSize =
- (sizeof(T) * N + alignof(T) + sizeof(uintptr_t) - 1) &
- ~(sizeof(uintptr_t) - 1);
-
- struct TInlineMeta
- {
- char Padding[ByteSize - sizeof(uint8_t)];
- // > 0 indicates inline storage
- // == 0 indicates on-heap storage
- uint8_t SizePlusOne;
+private:
+ template <class OtherT, size_t OtherN>
+ friend class TCompactVector;
+
+ using TOnHeapStorage = TCompactVectorOnHeapStorage<T>;
+
+ static constexpr size_t ByteSize =
+ (sizeof(T) * N + alignof(T) + sizeof(uintptr_t) - 1) &
+ ~(sizeof(uintptr_t) - 1);
+
+ struct TInlineMeta
+ {
+ char Padding[ByteSize - sizeof(uint8_t)];
+ // > 0 indicates inline storage
+ // == 0 indicates on-heap storage
+ uint8_t SizePlusOne;
} alias_hack;
-
- struct TOnHeapMeta
- {
- char Padding[ByteSize - sizeof(uintptr_t)];
- TOnHeapStorage* Storage;
+
+ struct TOnHeapMeta
+ {
+ char Padding[ByteSize - sizeof(uintptr_t)];
+ TOnHeapStorage* Storage;
} alias_hack;
-
- union
- {
- T InlineElements_[N];
- TInlineMeta InlineMeta_;
- TOnHeapMeta OnHeapMeta_;
- };
-
- bool IsInline() const;
- void SetSize(size_t newSize);
- void EnsureOnHeapCapacity(size_t newCapacity, bool incremental);
- template <class TPtr, class F>
- reference PushBackImpl(TPtr valuePtr, F&& func);
- template <class F>
- void ResizeImpl(size_t newSize, F&& func);
- template <class TPtr, class UninitializedF, class InitializedF>
- iterator InsertOneImpl(const_iterator pos, TPtr valuePtr, UninitializedF&& uninitializedFunc, InitializedF&& initializedFunc);
- template <class UninitializedF, class InitializedF>
- iterator InsertManyImpl(const_iterator pos, size_t insertCount, UninitializedF&& uninitializedFunc, InitializedF&& initializedFunc);
-
- static void Destroy(T* first, T* last);
- template <class T1, class T2>
- static void Copy(const T1* srcFirst, const T1* srcLast, T2* dst);
- template <class T1, class T2>
- static void UninitializedCopy(const T1* srcFirst, const T1* srcLast, T2* dst);
- static void Move(T* srcFirst, T* srcLast, T* dst);
- static void MoveBackward(T* srcFirst, T* srcLast, T* dst);
- static void UninitializedMove(T* srcFirst, T* srcLast, T* dst);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class T, size_t LhsN, size_t RhsN>
-bool operator==(const TCompactVector<T, LhsN>& lhs, const TCompactVector<T, RhsN>& rhs);
-
-template <class T, size_t LhsN, size_t RhsN>
-bool operator!=(const TCompactVector<T, LhsN>& lhs, const TCompactVector<T, RhsN>& rhs);
-
-template <class T, size_t LhsN, size_t RhsN>
-bool operator<(const TCompactVector<T, LhsN>& lhs, const TCompactVector<T, RhsN>& rhs);
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
-
-#define COMPACT_VECTOR_INL_H_
-#include "compact_vector-inl.h"
-#undef COMPACT_VECTOR_INL_H_
+
+ union
+ {
+ T InlineElements_[N];
+ TInlineMeta InlineMeta_;
+ TOnHeapMeta OnHeapMeta_;
+ };
+
+ bool IsInline() const;
+ void SetSize(size_t newSize);
+ void EnsureOnHeapCapacity(size_t newCapacity, bool incremental);
+ template <class TPtr, class F>
+ reference PushBackImpl(TPtr valuePtr, F&& func);
+ template <class F>
+ void ResizeImpl(size_t newSize, F&& func);
+ template <class TPtr, class UninitializedF, class InitializedF>
+ iterator InsertOneImpl(const_iterator pos, TPtr valuePtr, UninitializedF&& uninitializedFunc, InitializedF&& initializedFunc);
+ template <class UninitializedF, class InitializedF>
+ iterator InsertManyImpl(const_iterator pos, size_t insertCount, UninitializedF&& uninitializedFunc, InitializedF&& initializedFunc);
+
+ static void Destroy(T* first, T* last);
+ template <class T1, class T2>
+ static void Copy(const T1* srcFirst, const T1* srcLast, T2* dst);
+ template <class T1, class T2>
+ static void UninitializedCopy(const T1* srcFirst, const T1* srcLast, T2* dst);
+ static void Move(T* srcFirst, T* srcLast, T* dst);
+ static void MoveBackward(T* srcFirst, T* srcLast, T* dst);
+ static void UninitializedMove(T* srcFirst, T* srcLast, T* dst);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T, size_t LhsN, size_t RhsN>
+bool operator==(const TCompactVector<T, LhsN>& lhs, const TCompactVector<T, RhsN>& rhs);
+
+template <class T, size_t LhsN, size_t RhsN>
+bool operator!=(const TCompactVector<T, LhsN>& lhs, const TCompactVector<T, RhsN>& rhs);
+
+template <class T, size_t LhsN, size_t RhsN>
+bool operator<(const TCompactVector<T, LhsN>& lhs, const TCompactVector<T, RhsN>& rhs);
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
+
+#define COMPACT_VECTOR_INL_H_
+#include "compact_vector-inl.h"
+#undef COMPACT_VECTOR_INL_H_
diff --git a/library/cpp/yt/small_containers/unittests/compact_flat_map_ut.cpp b/library/cpp/yt/small_containers/unittests/compact_flat_map_ut.cpp
index 5fed31d6c1..0b2f290692 100644
--- a/library/cpp/yt/small_containers/unittests/compact_flat_map_ut.cpp
+++ b/library/cpp/yt/small_containers/unittests/compact_flat_map_ut.cpp
@@ -1,134 +1,134 @@
#include <yt/yt/core/test_framework/framework.h>
-
+
#include <yt/yt/core/misc/compact_flat_map.h>
-#include <string>
-#include <vector>
-
-namespace NYT {
-namespace {
-
-////////////////////////////////////////////////////////////////////////////////
-
+#include <string>
+#include <vector>
+
+namespace NYT {
+namespace {
+
+////////////////////////////////////////////////////////////////////////////////
+
using TMap = TCompactFlatMap<std::string, std::string, 2>;
-
-TMap CreateMap()
-{
- std::vector<std::pair<std::string, std::string>> data = {{"I", "met"}, {"a", "traveller"}, {"from", "an"}, {"antique", "land"}};
- return {data.begin(), data.end()};
-}
-
+
+TMap CreateMap()
+{
+ std::vector<std::pair<std::string, std::string>> data = {{"I", "met"}, {"a", "traveller"}, {"from", "an"}, {"antique", "land"}};
+ return {data.begin(), data.end()};
+}
+
TEST(CompactFlatMapTest, DefaultEmpty)
{
- TMap m;
- EXPECT_TRUE(m.empty());
- EXPECT_EQ(m.begin(), m.end());
-}
-
+ TMap m;
+ EXPECT_TRUE(m.empty());
+ EXPECT_EQ(m.begin(), m.end());
+}
+
TEST(CompactFlatMapTest, Reserve)
{
- // No real way to test reserve - just use it and wiggle about.
- auto m1 = CreateMap();
- TMap m2;
- m2.reserve(m1.size());
- m2.insert(m1.begin(), m1.end());
- EXPECT_EQ(m1.size(), m2.size());
-}
-
+ // No real way to test reserve - just use it and wiggle about.
+ auto m1 = CreateMap();
+ TMap m2;
+ m2.reserve(m1.size());
+ m2.insert(m1.begin(), m1.end());
+ EXPECT_EQ(m1.size(), m2.size());
+}
+
TEST(CompactFlatMapTest, Size)
{
- auto m = CreateMap();
-
+ auto m = CreateMap();
+
EXPECT_EQ(m.size(), 4u);
- EXPECT_EQ(m.ssize(), 4);
-
- m.insert({"Who", "said"});
-
+ EXPECT_EQ(m.ssize(), 4);
+
+ m.insert({"Who", "said"});
+
EXPECT_EQ(m.size(), 5u);
- EXPECT_EQ(m.ssize(), 5);
-
- m.erase("antique");
-
+ EXPECT_EQ(m.ssize(), 5);
+
+ m.erase("antique");
+
EXPECT_EQ(m.size(), 4u);
- EXPECT_EQ(m.ssize(), 4);
-}
-
+ EXPECT_EQ(m.ssize(), 4);
+}
+
TEST(CompactFlatMapTest, ClearAndEmpty)
{
- auto m = CreateMap();
-
- EXPECT_FALSE(m.empty());
- EXPECT_NE(m.begin(), m.end());
-
- m.clear();
-
- EXPECT_TRUE(m.empty());
- EXPECT_EQ(m.begin(), m.end());
-
- m.insert({"Who", "said"});
-
- EXPECT_FALSE(m.empty());
- EXPECT_NE(m.begin(), m.end());
-}
-
+ auto m = CreateMap();
+
+ EXPECT_FALSE(m.empty());
+ EXPECT_NE(m.begin(), m.end());
+
+ m.clear();
+
+ EXPECT_TRUE(m.empty());
+ EXPECT_EQ(m.begin(), m.end());
+
+ m.insert({"Who", "said"});
+
+ EXPECT_FALSE(m.empty());
+ EXPECT_NE(m.begin(), m.end());
+}
+
TEST(CompactFlatMapTest, FindMutable)
{
- auto m = CreateMap();
- {
- auto it = m.find("from");
- EXPECT_NE(it, m.end());
- EXPECT_EQ(it->second, "an");
- it->second = "the";
- }
- {
- auto it = m.find("from");
- EXPECT_NE(it, m.end());
- EXPECT_EQ(it->second, "the");
- }
- {
- auto it = m.find("Who");
- EXPECT_EQ(it, m.end());
- }
-}
-
+ auto m = CreateMap();
+ {
+ auto it = m.find("from");
+ EXPECT_NE(it, m.end());
+ EXPECT_EQ(it->second, "an");
+ it->second = "the";
+ }
+ {
+ auto it = m.find("from");
+ EXPECT_NE(it, m.end());
+ EXPECT_EQ(it->second, "the");
+ }
+ {
+ auto it = m.find("Who");
+ EXPECT_EQ(it, m.end());
+ }
+}
+
TEST(CompactFlatMapTest, FindConst)
{
- const auto& m = CreateMap();
- {
- auto it = m.find("from");
- EXPECT_NE(it, m.end());
- EXPECT_EQ(it->second, "an");
- }
- {
- auto it = m.find("Who");
- EXPECT_EQ(it, m.end());
- }
-}
-
+ const auto& m = CreateMap();
+ {
+ auto it = m.find("from");
+ EXPECT_NE(it, m.end());
+ EXPECT_EQ(it->second, "an");
+ }
+ {
+ auto it = m.find("Who");
+ EXPECT_EQ(it, m.end());
+ }
+}
+
TEST(CompactFlatMapTest, Insert)
{
- auto m = CreateMap();
-
- auto [it, inserted] = m.insert({"Who", "said"});
- EXPECT_TRUE(inserted);
+ auto m = CreateMap();
+
+ auto [it, inserted] = m.insert({"Who", "said"});
+ EXPECT_TRUE(inserted);
EXPECT_EQ(m.ssize(), 5);
- EXPECT_NE(it, m.end());
- EXPECT_EQ(it, m.find("Who"));
- EXPECT_EQ(it->second, "said");
-
- auto [it2, inserted2] = m.insert({"Who", "told"});
- EXPECT_FALSE(inserted2);
+ EXPECT_NE(it, m.end());
+ EXPECT_EQ(it, m.find("Who"));
+ EXPECT_EQ(it->second, "said");
+
+ auto [it2, inserted2] = m.insert({"Who", "told"});
+ EXPECT_FALSE(inserted2);
EXPECT_EQ(m.ssize(), 5);
- EXPECT_EQ(it2, it);
- EXPECT_EQ(it->second, "said");
-
- std::vector<std::pair<std::string, std::string>> data = {{"Two", "vast"}, {"and", "trunkless"}, {"legs", "of"}, {"stone", "Stand"}, {"in", "the"}, {"desert", "..."}};
- m.insert(data.begin(), data.end());
+ EXPECT_EQ(it2, it);
+ EXPECT_EQ(it->second, "said");
+
+ std::vector<std::pair<std::string, std::string>> data = {{"Two", "vast"}, {"and", "trunkless"}, {"legs", "of"}, {"stone", "Stand"}, {"in", "the"}, {"desert", "..."}};
+ m.insert(data.begin(), data.end());
EXPECT_EQ(m.ssize(), 11);
- EXPECT_NE(m.find("and"), m.end());
- EXPECT_EQ(m.find("and")->second, "trunkless");
-}
-
+ EXPECT_NE(m.find("and"), m.end());
+ EXPECT_EQ(m.find("and")->second, "trunkless");
+}
+
TEST(CompactFlatMapTest, Emplace)
{
auto m = CreateMap();
@@ -149,77 +149,77 @@ TEST(CompactFlatMapTest, Emplace)
TEST(CompactFlatMapTest, Subscript)
{
- auto m = CreateMap();
-
- EXPECT_EQ(m["antique"], "land");
+ auto m = CreateMap();
+
+ EXPECT_EQ(m["antique"], "land");
EXPECT_EQ(m.ssize(), 4);
-
- EXPECT_EQ(m["Who"], "");
+
+ EXPECT_EQ(m["Who"], "");
EXPECT_EQ(m.ssize(), 5);
-}
-
+}
+
TEST(CompactFlatMapTest, Erase)
{
- auto m = CreateMap();
-
- m.erase("antique");
+ auto m = CreateMap();
+
+ m.erase("antique");
EXPECT_EQ(m.ssize(), 3);
-
- m.erase("Who");
+
+ m.erase("Who");
EXPECT_EQ(m.ssize(), 3);
-
- m.erase(m.begin(), m.end());
- EXPECT_TRUE(m.empty());
-}
-
+
+ m.erase(m.begin(), m.end());
+ EXPECT_TRUE(m.empty());
+}
+
TEST(CompactFlatMapTest, GrowShrink)
{
- TMap m;
- m.insert({"Two", "vast"});
- m.insert({"and", "trunkless"});
- m.insert({"legs", "of"});
- m.insert({"stone", "Stand"});
- m.insert({"in", "the"});
- m.insert({"desert", "..."});
-
- m.erase("legs");
- m.erase("stone");
- m.erase("in");
- m.erase("desert");
-
+ TMap m;
+ m.insert({"Two", "vast"});
+ m.insert({"and", "trunkless"});
+ m.insert({"legs", "of"});
+ m.insert({"stone", "Stand"});
+ m.insert({"in", "the"});
+ m.insert({"desert", "..."});
+
+ m.erase("legs");
+ m.erase("stone");
+ m.erase("in");
+ m.erase("desert");
+
EXPECT_EQ(m.ssize(), 2);
-
- // Must not crash or trigger asan.
-}
-
+
+ // Must not crash or trigger asan.
+}
+
TEST(CompactFlatMapTest, GrowShrinkGrow)
{
- TMap m;
- m.insert({"Two", "vast"});
- m.insert({"and", "trunkless"});
- m.insert({"legs", "of"});
- m.insert({"stone", "Stand"});
- m.insert({"in", "the"});
- m.insert({"desert", "..."});
-
- m.erase("legs");
- m.erase("stone");
- m.erase("in");
- m.erase("desert");
-
+ TMap m;
+ m.insert({"Two", "vast"});
+ m.insert({"and", "trunkless"});
+ m.insert({"legs", "of"});
+ m.insert({"stone", "Stand"});
+ m.insert({"in", "the"});
+ m.insert({"desert", "..."});
+
+ m.erase("legs");
+ m.erase("stone");
+ m.erase("in");
+ m.erase("desert");
+
EXPECT_EQ(m.ssize(), 2);
-
- m.insert({"I", "met"});
- m.insert({"a", "traveller"});
- m.insert({"from", "an"});
- m.insert({"antique", "land"});
-
+
+ m.insert({"I", "met"});
+ m.insert({"a", "traveller"});
+ m.insert({"from", "an"});
+ m.insert({"antique", "land"});
+
EXPECT_EQ(m.ssize(), 6);
-
- // Must not crash or trigger asan.
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace
-} // namespace NYT
+
+ // Must not crash or trigger asan.
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace
+} // namespace NYT
diff --git a/library/cpp/yt/small_containers/unittests/compact_set_ut.cpp b/library/cpp/yt/small_containers/unittests/compact_set_ut.cpp
index bbb2f5927b..ebab5846e1 100644
--- a/library/cpp/yt/small_containers/unittests/compact_set_ut.cpp
+++ b/library/cpp/yt/small_containers/unittests/compact_set_ut.cpp
@@ -1,204 +1,204 @@
//===- llvm/unittest/ADT/SmallSetTest.cpp ---------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
// CompactSet unit tests.
-//
-//===----------------------------------------------------------------------===//
-
+//
+//===----------------------------------------------------------------------===//
+
#include <library/cpp/yt/small_containers/compact_set.h>
-
+
#include <library/cpp/testing/gtest/gtest.h>
-#include <string>
-
-namespace NYT {
-namespace {
-
-////////////////////////////////////////////////////////////////////////////////
-
+#include <string>
+
+namespace NYT {
+namespace {
+
+////////////////////////////////////////////////////////////////////////////////
+
TEST(CompactSetTest, Insert) {
-
+
TCompactSet<int, 4> s1;
-
- for (int i = 0; i < 4; i++)
- s1.insert(i);
-
- for (int i = 0; i < 4; i++)
- s1.insert(i);
-
- EXPECT_EQ(4u, s1.size());
-
- for (int i = 0; i < 4; i++)
- EXPECT_EQ(1u, s1.count(i));
-
- EXPECT_EQ(0u, s1.count(4));
-}
-
+
+ for (int i = 0; i < 4; i++)
+ s1.insert(i);
+
+ for (int i = 0; i < 4; i++)
+ s1.insert(i);
+
+ EXPECT_EQ(4u, s1.size());
+
+ for (int i = 0; i < 4; i++)
+ EXPECT_EQ(1u, s1.count(i));
+
+ EXPECT_EQ(0u, s1.count(4));
+}
+
TEST(CompactSetTest, Grow) {
TCompactSet<int, 4> s1;
-
- for (int i = 0; i < 8; i++)
- s1.insert(i);
-
- EXPECT_EQ(8u, s1.size());
-
- for (int i = 0; i < 8; i++)
- EXPECT_EQ(1u, s1.count(i));
-
- EXPECT_EQ(0u, s1.count(8));
-}
-
+
+ for (int i = 0; i < 8; i++)
+ s1.insert(i);
+
+ EXPECT_EQ(8u, s1.size());
+
+ for (int i = 0; i < 8; i++)
+ EXPECT_EQ(1u, s1.count(i));
+
+ EXPECT_EQ(0u, s1.count(8));
+}
+
TEST(CompactSetTest, Erase) {
TCompactSet<int, 4> s1;
-
- for (int i = 0; i < 8; i++)
- s1.insert(i);
-
- EXPECT_EQ(8u, s1.size());
-
- // Remove elements one by one and check if all other elements are still there.
- for (int i = 0; i < 8; i++) {
- EXPECT_EQ(1u, s1.count(i));
- EXPECT_TRUE(s1.erase(i));
- EXPECT_EQ(0u, s1.count(i));
- EXPECT_EQ(8u - i - 1, s1.size());
- for (int j = i + 1; j < 8; j++)
- EXPECT_EQ(1u, s1.count(j));
- }
-
- EXPECT_EQ(0u, s1.count(8));
-}
-
+
+ for (int i = 0; i < 8; i++)
+ s1.insert(i);
+
+ EXPECT_EQ(8u, s1.size());
+
+ // Remove elements one by one and check if all other elements are still there.
+ for (int i = 0; i < 8; i++) {
+ EXPECT_EQ(1u, s1.count(i));
+ EXPECT_TRUE(s1.erase(i));
+ EXPECT_EQ(0u, s1.count(i));
+ EXPECT_EQ(8u - i - 1, s1.size());
+ for (int j = i + 1; j < 8; j++)
+ EXPECT_EQ(1u, s1.count(j));
+ }
+
+ EXPECT_EQ(0u, s1.count(8));
+}
+
TEST(CompactSetTest, IteratorInt) {
TCompactSet<int, 4> s1;
-
- // Test the 'small' case.
- for (int i = 0; i < 3; i++)
- s1.insert(i);
-
- std::vector<int> V(s1.begin(), s1.end());
- // Make sure the elements are in the expected order.
- std::sort(V.begin(), V.end());
- for (int i = 0; i < 3; i++)
- EXPECT_EQ(i, V[i]);
-
- // Test the 'big' case by adding a few more elements to switch to std::set
- // internally.
- for (int i = 3; i < 6; i++)
- s1.insert(i);
-
- V.assign(s1.begin(), s1.end());
- // Make sure the elements are in the expected order.
- std::sort(V.begin(), V.end());
- for (int i = 0; i < 6; i++)
- EXPECT_EQ(i, V[i]);
-}
-
+
+ // Test the 'small' case.
+ for (int i = 0; i < 3; i++)
+ s1.insert(i);
+
+ std::vector<int> V(s1.begin(), s1.end());
+ // Make sure the elements are in the expected order.
+ std::sort(V.begin(), V.end());
+ for (int i = 0; i < 3; i++)
+ EXPECT_EQ(i, V[i]);
+
+ // Test the 'big' case by adding a few more elements to switch to std::set
+ // internally.
+ for (int i = 3; i < 6; i++)
+ s1.insert(i);
+
+ V.assign(s1.begin(), s1.end());
+ // Make sure the elements are in the expected order.
+ std::sort(V.begin(), V.end());
+ for (int i = 0; i < 6; i++)
+ EXPECT_EQ(i, V[i]);
+}
+
TEST(CompactSetTest, IteratorString) {
// Test CompactSetIterator for TCompactSet with a type with non-trivial
- // ctors/dtors.
+ // ctors/dtors.
TCompactSet<std::string, 2> s1;
-
- s1.insert("str 1");
- s1.insert("str 2");
- s1.insert("str 1");
-
- std::vector<std::string> V(s1.begin(), s1.end());
- std::sort(V.begin(), V.end());
- EXPECT_EQ(2u, s1.size());
- EXPECT_EQ("str 1", V[0]);
- EXPECT_EQ("str 2", V[1]);
-
- s1.insert("str 4");
- s1.insert("str 0");
- s1.insert("str 4");
-
- V.assign(s1.begin(), s1.end());
- // Make sure the elements are in the expected order.
- std::sort(V.begin(), V.end());
- EXPECT_EQ(4u, s1.size());
- EXPECT_EQ("str 0", V[0]);
- EXPECT_EQ("str 1", V[1]);
- EXPECT_EQ("str 2", V[2]);
- EXPECT_EQ("str 4", V[3]);
-}
-
+
+ s1.insert("str 1");
+ s1.insert("str 2");
+ s1.insert("str 1");
+
+ std::vector<std::string> V(s1.begin(), s1.end());
+ std::sort(V.begin(), V.end());
+ EXPECT_EQ(2u, s1.size());
+ EXPECT_EQ("str 1", V[0]);
+ EXPECT_EQ("str 2", V[1]);
+
+ s1.insert("str 4");
+ s1.insert("str 0");
+ s1.insert("str 4");
+
+ V.assign(s1.begin(), s1.end());
+ // Make sure the elements are in the expected order.
+ std::sort(V.begin(), V.end());
+ EXPECT_EQ(4u, s1.size());
+ EXPECT_EQ("str 0", V[0]);
+ EXPECT_EQ("str 1", V[1]);
+ EXPECT_EQ("str 2", V[2]);
+ EXPECT_EQ("str 4", V[3]);
+}
+
TEST(CompactSetTest, IteratorIncMoveCopy) {
// Test CompactSetIterator for TCompactSet with a type with non-trivial
- // ctors/dtors.
+ // ctors/dtors.
TCompactSet<std::string, 2> s1;
-
- s1.insert("str 1");
- s1.insert("str 2");
-
- auto Iter = s1.begin();
- EXPECT_EQ("str 1", *Iter);
- ++Iter;
- EXPECT_EQ("str 2", *Iter);
-
- s1.insert("str 4");
- s1.insert("str 0");
- auto Iter2 = s1.begin();
- Iter = std::move(Iter2);
- EXPECT_EQ("str 0", *Iter);
-}
-
-// These test weren't taken from llvm.
-
+
+ s1.insert("str 1");
+ s1.insert("str 2");
+
+ auto Iter = s1.begin();
+ EXPECT_EQ("str 1", *Iter);
+ ++Iter;
+ EXPECT_EQ("str 2", *Iter);
+
+ s1.insert("str 4");
+ s1.insert("str 0");
+ auto Iter2 = s1.begin();
+ Iter = std::move(Iter2);
+ EXPECT_EQ("str 0", *Iter);
+}
+
+// These test weren't taken from llvm.
+
TEST(CompactSetTest, Empty) {
TCompactSet<int, 10> v;
- EXPECT_TRUE(v.empty());
-
- auto data = {1, 2, 3, 4, 5};
-
- v.insert(data.begin(), data.end()); // not crossing size threshold
- v.erase(4);
- v.erase(2);
- v.erase(3);
- v.erase(5);
- v.erase(1);
- EXPECT_TRUE(v.empty());
-
- auto data2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
- v.insert(data2.begin(), data2.end()); // crossing size threshold
- v.erase(7);
- v.erase(3);
- v.erase(1);
- v.erase(10);
- v.erase(9);
- v.erase(0);
- v.erase(2);
- v.erase(6);
- v.erase(4);
- v.erase(5);
- v.erase(8);
- EXPECT_TRUE(v.empty());
-}
-
+ EXPECT_TRUE(v.empty());
+
+ auto data = {1, 2, 3, 4, 5};
+
+ v.insert(data.begin(), data.end()); // not crossing size threshold
+ v.erase(4);
+ v.erase(2);
+ v.erase(3);
+ v.erase(5);
+ v.erase(1);
+ EXPECT_TRUE(v.empty());
+
+ auto data2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+ v.insert(data2.begin(), data2.end()); // crossing size threshold
+ v.erase(7);
+ v.erase(3);
+ v.erase(1);
+ v.erase(10);
+ v.erase(9);
+ v.erase(0);
+ v.erase(2);
+ v.erase(6);
+ v.erase(4);
+ v.erase(5);
+ v.erase(8);
+ EXPECT_TRUE(v.empty());
+}
+
TEST(CompactSetTest, ForEach) {
TCompactSet<int, 10> v;
-
- auto data = {10, 9, 3, 4, 1, 5, 6, 8};
-
- v.insert(data.begin(), data.end());
-
- std::vector<int> buf(v.begin(), v.end());
- std::vector<int> expected{1, 3, 4, 5, 6, 8, 9, 10};
- EXPECT_EQ(expected, buf);
-
- auto data2 = {7, 1, 2, 0};
- v.insert(data2.begin(), data2.end());
- buf.assign(v.begin(), v.end());
- expected = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
- EXPECT_EQ(expected, buf);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace
-} // namespace NYT
+
+ auto data = {10, 9, 3, 4, 1, 5, 6, 8};
+
+ v.insert(data.begin(), data.end());
+
+ std::vector<int> buf(v.begin(), v.end());
+ std::vector<int> expected{1, 3, 4, 5, 6, 8, 9, 10};
+ EXPECT_EQ(expected, buf);
+
+ auto data2 = {7, 1, 2, 0};
+ v.insert(data2.begin(), data2.end());
+ buf.assign(v.begin(), v.end());
+ expected = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+ EXPECT_EQ(expected, buf);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace
+} // namespace NYT
diff --git a/library/cpp/yt/small_containers/unittests/compact_vector_ut.cpp b/library/cpp/yt/small_containers/unittests/compact_vector_ut.cpp
index 508a29d103..770d62b9fd 100644
--- a/library/cpp/yt/small_containers/unittests/compact_vector_ut.cpp
+++ b/library/cpp/yt/small_containers/unittests/compact_vector_ut.cpp
@@ -1,272 +1,272 @@
-// Adapted from the following:
-//===- llvm/unittest/ADT/CompactVectorTest.cpp ------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
+// Adapted from the following:
+//===- llvm/unittest/ADT/CompactVectorTest.cpp ------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
// TCompactVector unit tests.
-//
-//===----------------------------------------------------------------------===//
-
-#include <yt/yt/core/test_framework/framework.h>
-
-#include <yt/yt/core/misc/compact_vector.h>
-
-#include <algorithm>
-#include <list>
-
-#include <stdarg.h>
-
-namespace NYT {
-namespace {
-
-////////////////////////////////////////////////////////////////////////////////
-
-/// A helper class that counts the total number of constructor and
-/// destructor calls.
-class Constructable {
-private:
- static int numConstructorCalls;
- static int numMoveConstructorCalls;
- static int numCopyConstructorCalls;
- static int numDestructorCalls;
- static int numAssignmentCalls;
- static int numMoveAssignmentCalls;
- static int numCopyAssignmentCalls;
-
- bool constructed;
- int value;
-
-public:
- Constructable() : constructed(true), value(0) {
- ++numConstructorCalls;
- }
-
- Constructable(int val) : constructed(true), value(val) {
- ++numConstructorCalls;
- }
-
- Constructable(const Constructable & src) : constructed(true) {
- value = src.value;
- ++numConstructorCalls;
- ++numCopyConstructorCalls;
- }
-
- Constructable(Constructable && src) : constructed(true) {
- value = src.value;
- ++numConstructorCalls;
- ++numMoveConstructorCalls;
- }
-
- ~Constructable() {
- EXPECT_TRUE(constructed);
- ++numDestructorCalls;
- constructed = false;
- }
-
- Constructable & operator=(const Constructable & src) {
- EXPECT_TRUE(constructed);
- value = src.value;
- ++numAssignmentCalls;
- ++numCopyAssignmentCalls;
- return *this;
- }
-
- Constructable & operator=(Constructable && src) {
- EXPECT_TRUE(constructed);
- value = src.value;
- ++numAssignmentCalls;
- ++numMoveAssignmentCalls;
- return *this;
- }
-
- int getValue() const {
- return abs(value);
- }
-
- static void reset() {
- numConstructorCalls = 0;
- numMoveConstructorCalls = 0;
- numCopyConstructorCalls = 0;
- numDestructorCalls = 0;
- numAssignmentCalls = 0;
- numMoveAssignmentCalls = 0;
- numCopyAssignmentCalls = 0;
- }
-
- static int getNumConstructorCalls() {
- return numConstructorCalls;
- }
-
- static int getNumMoveConstructorCalls() {
- return numMoveConstructorCalls;
- }
-
- static int getNumCopyConstructorCalls() {
- return numCopyConstructorCalls;
- }
-
- static int getNumDestructorCalls() {
- return numDestructorCalls;
- }
-
- static int getNumAssignmentCalls() {
- return numAssignmentCalls;
- }
-
- static int getNumMoveAssignmentCalls() {
- return numMoveAssignmentCalls;
- }
-
- static int getNumCopyAssignmentCalls() {
- return numCopyAssignmentCalls;
- }
-
- friend bool operator==(const Constructable & c0, const Constructable & c1) {
- return c0.getValue() == c1.getValue();
- }
-};
-
-int Constructable::numConstructorCalls;
-int Constructable::numCopyConstructorCalls;
-int Constructable::numMoveConstructorCalls;
-int Constructable::numDestructorCalls;
-int Constructable::numAssignmentCalls;
-int Constructable::numCopyAssignmentCalls;
-int Constructable::numMoveAssignmentCalls;
-
-struct NonCopyable {
- NonCopyable() {}
- NonCopyable(NonCopyable &&) {}
- NonCopyable &operator=(NonCopyable &&) { return *this; }
-private:
- NonCopyable(const NonCopyable &) = delete;
- NonCopyable &operator=(const NonCopyable &) = delete;
-};
-
-[[maybe_unused]] void CompileTest() {
- TCompactVector<NonCopyable, 0> V;
- V.resize(42);
-}
-
-class CompactVectorTestBase : public testing::Test {
-protected:
-
+//
+//===----------------------------------------------------------------------===//
+
+#include <yt/yt/core/test_framework/framework.h>
+
+#include <yt/yt/core/misc/compact_vector.h>
+
+#include <algorithm>
+#include <list>
+
+#include <stdarg.h>
+
+namespace NYT {
+namespace {
+
+////////////////////////////////////////////////////////////////////////////////
+
+/// A helper class that counts the total number of constructor and
+/// destructor calls.
+class Constructable {
+private:
+ static int numConstructorCalls;
+ static int numMoveConstructorCalls;
+ static int numCopyConstructorCalls;
+ static int numDestructorCalls;
+ static int numAssignmentCalls;
+ static int numMoveAssignmentCalls;
+ static int numCopyAssignmentCalls;
+
+ bool constructed;
+ int value;
+
+public:
+ Constructable() : constructed(true), value(0) {
+ ++numConstructorCalls;
+ }
+
+ Constructable(int val) : constructed(true), value(val) {
+ ++numConstructorCalls;
+ }
+
+ Constructable(const Constructable & src) : constructed(true) {
+ value = src.value;
+ ++numConstructorCalls;
+ ++numCopyConstructorCalls;
+ }
+
+ Constructable(Constructable && src) : constructed(true) {
+ value = src.value;
+ ++numConstructorCalls;
+ ++numMoveConstructorCalls;
+ }
+
+ ~Constructable() {
+ EXPECT_TRUE(constructed);
+ ++numDestructorCalls;
+ constructed = false;
+ }
+
+ Constructable & operator=(const Constructable & src) {
+ EXPECT_TRUE(constructed);
+ value = src.value;
+ ++numAssignmentCalls;
+ ++numCopyAssignmentCalls;
+ return *this;
+ }
+
+ Constructable & operator=(Constructable && src) {
+ EXPECT_TRUE(constructed);
+ value = src.value;
+ ++numAssignmentCalls;
+ ++numMoveAssignmentCalls;
+ return *this;
+ }
+
+ int getValue() const {
+ return abs(value);
+ }
+
+ static void reset() {
+ numConstructorCalls = 0;
+ numMoveConstructorCalls = 0;
+ numCopyConstructorCalls = 0;
+ numDestructorCalls = 0;
+ numAssignmentCalls = 0;
+ numMoveAssignmentCalls = 0;
+ numCopyAssignmentCalls = 0;
+ }
+
+ static int getNumConstructorCalls() {
+ return numConstructorCalls;
+ }
+
+ static int getNumMoveConstructorCalls() {
+ return numMoveConstructorCalls;
+ }
+
+ static int getNumCopyConstructorCalls() {
+ return numCopyConstructorCalls;
+ }
+
+ static int getNumDestructorCalls() {
+ return numDestructorCalls;
+ }
+
+ static int getNumAssignmentCalls() {
+ return numAssignmentCalls;
+ }
+
+ static int getNumMoveAssignmentCalls() {
+ return numMoveAssignmentCalls;
+ }
+
+ static int getNumCopyAssignmentCalls() {
+ return numCopyAssignmentCalls;
+ }
+
+ friend bool operator==(const Constructable & c0, const Constructable & c1) {
+ return c0.getValue() == c1.getValue();
+ }
+};
+
+int Constructable::numConstructorCalls;
+int Constructable::numCopyConstructorCalls;
+int Constructable::numMoveConstructorCalls;
+int Constructable::numDestructorCalls;
+int Constructable::numAssignmentCalls;
+int Constructable::numCopyAssignmentCalls;
+int Constructable::numMoveAssignmentCalls;
+
+struct NonCopyable {
+ NonCopyable() {}
+ NonCopyable(NonCopyable &&) {}
+ NonCopyable &operator=(NonCopyable &&) { return *this; }
+private:
+ NonCopyable(const NonCopyable &) = delete;
+ NonCopyable &operator=(const NonCopyable &) = delete;
+};
+
+[[maybe_unused]] void CompileTest() {
+ TCompactVector<NonCopyable, 0> V;
+ V.resize(42);
+}
+
+class CompactVectorTestBase : public testing::Test {
+protected:
+
void SetUp() override {
- Constructable::reset();
- }
-
- template <typename VectorT>
- void assertEmpty(VectorT & v) {
- // Size tests
- EXPECT_EQ(0u, v.size());
- EXPECT_TRUE(v.empty());
-
- // Iterator tests
- EXPECT_TRUE(v.begin() == v.end());
- }
-
- // Assert that v contains the specified values, in order.
- template <typename VectorT>
- void assertValuesInOrder(VectorT & v, size_t size, ...) {
- EXPECT_EQ(size, v.size());
-
- va_list ap;
- va_start(ap, size);
- for (size_t i = 0; i < size; ++i) {
- int value = va_arg(ap, int);
- EXPECT_EQ(value, v[i].getValue());
- }
-
- va_end(ap);
- }
-
- // Generate a sequence of values to initialize the vector.
- template <typename VectorT>
- void makeSequence(VectorT & v, int start, int end) {
- for (int i = start; i <= end; ++i) {
- v.push_back(Constructable(i));
- }
- }
-};
-
-// Test fixture class
-template <typename VectorT>
-class CompactVectorTest : public CompactVectorTestBase {
-protected:
- VectorT theVector;
- VectorT otherVector;
-};
-
-
-typedef ::testing::Types<TCompactVector<Constructable, 0>,
- TCompactVector<Constructable, 1>,
- TCompactVector<Constructable, 2>,
- TCompactVector<Constructable, 4>,
- TCompactVector<Constructable, 5>
- > CompactVectorTestTypes;
-TYPED_TEST_SUITE(CompactVectorTest, CompactVectorTestTypes);
-
-// New vector test.
-TYPED_TEST(CompactVectorTest, EmptyVectorTest) {
- SCOPED_TRACE("EmptyVectorTest");
- this->assertEmpty(this->theVector);
- EXPECT_TRUE(this->theVector.rbegin() == this->theVector.rend());
- EXPECT_EQ(0, Constructable::getNumConstructorCalls());
- EXPECT_EQ(0, Constructable::getNumDestructorCalls());
-}
-
-// Simple insertions and deletions.
-TYPED_TEST(CompactVectorTest, PushPopTest) {
- SCOPED_TRACE("PushPopTest");
-
- // Track whether the vector will potentially have to grow.
- bool RequiresGrowth = this->theVector.capacity() < 3;
-
- // Push an element
- this->theVector.push_back(Constructable(1));
-
- // Size tests
- this->assertValuesInOrder(this->theVector, 1u, 1);
- EXPECT_FALSE(this->theVector.begin() == this->theVector.end());
- EXPECT_FALSE(this->theVector.empty());
-
- // Push another element
- this->theVector.push_back(Constructable(2));
- this->assertValuesInOrder(this->theVector, 2u, 1, 2);
-
- // Insert at beginning
- this->theVector.insert(this->theVector.begin(), this->theVector[1]);
- this->assertValuesInOrder(this->theVector, 3u, 2, 1, 2);
-
- // Pop one element
- this->theVector.pop_back();
- this->assertValuesInOrder(this->theVector, 2u, 2, 1);
-
- // Pop remaining elements
- this->theVector.pop_back();
- this->theVector.pop_back();
- this->assertEmpty(this->theVector);
-
- // Check number of constructor calls. Should be 2 for each list element,
- // one for the argument to push_back, one for the argument to insert,
- // and one for the list element itself.
- if (!RequiresGrowth) {
- EXPECT_EQ(5, Constructable::getNumConstructorCalls());
- EXPECT_EQ(5, Constructable::getNumDestructorCalls());
- } else {
- // If we had to grow the vector, these only have a lower bound, but should
- // always be equal.
- EXPECT_LE(5, Constructable::getNumConstructorCalls());
- EXPECT_EQ(Constructable::getNumConstructorCalls(),
- Constructable::getNumDestructorCalls());
- }
-}
-
+ Constructable::reset();
+ }
+
+ template <typename VectorT>
+ void assertEmpty(VectorT & v) {
+ // Size tests
+ EXPECT_EQ(0u, v.size());
+ EXPECT_TRUE(v.empty());
+
+ // Iterator tests
+ EXPECT_TRUE(v.begin() == v.end());
+ }
+
+ // Assert that v contains the specified values, in order.
+ template <typename VectorT>
+ void assertValuesInOrder(VectorT & v, size_t size, ...) {
+ EXPECT_EQ(size, v.size());
+
+ va_list ap;
+ va_start(ap, size);
+ for (size_t i = 0; i < size; ++i) {
+ int value = va_arg(ap, int);
+ EXPECT_EQ(value, v[i].getValue());
+ }
+
+ va_end(ap);
+ }
+
+ // Generate a sequence of values to initialize the vector.
+ template <typename VectorT>
+ void makeSequence(VectorT & v, int start, int end) {
+ for (int i = start; i <= end; ++i) {
+ v.push_back(Constructable(i));
+ }
+ }
+};
+
+// Test fixture class
+template <typename VectorT>
+class CompactVectorTest : public CompactVectorTestBase {
+protected:
+ VectorT theVector;
+ VectorT otherVector;
+};
+
+
+typedef ::testing::Types<TCompactVector<Constructable, 0>,
+ TCompactVector<Constructable, 1>,
+ TCompactVector<Constructable, 2>,
+ TCompactVector<Constructable, 4>,
+ TCompactVector<Constructable, 5>
+ > CompactVectorTestTypes;
+TYPED_TEST_SUITE(CompactVectorTest, CompactVectorTestTypes);
+
+// New vector test.
+TYPED_TEST(CompactVectorTest, EmptyVectorTest) {
+ SCOPED_TRACE("EmptyVectorTest");
+ this->assertEmpty(this->theVector);
+ EXPECT_TRUE(this->theVector.rbegin() == this->theVector.rend());
+ EXPECT_EQ(0, Constructable::getNumConstructorCalls());
+ EXPECT_EQ(0, Constructable::getNumDestructorCalls());
+}
+
+// Simple insertions and deletions.
+TYPED_TEST(CompactVectorTest, PushPopTest) {
+ SCOPED_TRACE("PushPopTest");
+
+ // Track whether the vector will potentially have to grow.
+ bool RequiresGrowth = this->theVector.capacity() < 3;
+
+ // Push an element
+ this->theVector.push_back(Constructable(1));
+
+ // Size tests
+ this->assertValuesInOrder(this->theVector, 1u, 1);
+ EXPECT_FALSE(this->theVector.begin() == this->theVector.end());
+ EXPECT_FALSE(this->theVector.empty());
+
+ // Push another element
+ this->theVector.push_back(Constructable(2));
+ this->assertValuesInOrder(this->theVector, 2u, 1, 2);
+
+ // Insert at beginning
+ this->theVector.insert(this->theVector.begin(), this->theVector[1]);
+ this->assertValuesInOrder(this->theVector, 3u, 2, 1, 2);
+
+ // Pop one element
+ this->theVector.pop_back();
+ this->assertValuesInOrder(this->theVector, 2u, 2, 1);
+
+ // Pop remaining elements
+ this->theVector.pop_back();
+ this->theVector.pop_back();
+ this->assertEmpty(this->theVector);
+
+ // Check number of constructor calls. Should be 2 for each list element,
+ // one for the argument to push_back, one for the argument to insert,
+ // and one for the list element itself.
+ if (!RequiresGrowth) {
+ EXPECT_EQ(5, Constructable::getNumConstructorCalls());
+ EXPECT_EQ(5, Constructable::getNumDestructorCalls());
+ } else {
+ // If we had to grow the vector, these only have a lower bound, but should
+ // always be equal.
+ EXPECT_LE(5, Constructable::getNumConstructorCalls());
+ EXPECT_EQ(Constructable::getNumConstructorCalls(),
+ Constructable::getNumDestructorCalls());
+ }
+}
+
TYPED_TEST(CompactVectorTest, InsertEnd)
{
SCOPED_TRACE("InsertEnd");
@@ -304,781 +304,781 @@ TYPED_TEST(CompactVectorTest, ShrinkToSmall)
}
}
-// Clear test.
-TYPED_TEST(CompactVectorTest, ClearTest) {
- SCOPED_TRACE("ClearTest");
-
- this->theVector.reserve(2);
- this->makeSequence(this->theVector, 1, 2);
- this->theVector.clear();
-
- this->assertEmpty(this->theVector);
- EXPECT_EQ(4, Constructable::getNumConstructorCalls());
- EXPECT_EQ(4, Constructable::getNumDestructorCalls());
-}
-
-// Resize smaller test.
-TYPED_TEST(CompactVectorTest, ResizeShrinkTest) {
- SCOPED_TRACE("ResizeShrinkTest");
-
- this->theVector.reserve(3);
- this->makeSequence(this->theVector, 1, 3);
- this->theVector.resize(1);
-
- this->assertValuesInOrder(this->theVector, 1u, 1);
- EXPECT_EQ(6, Constructable::getNumConstructorCalls());
- EXPECT_EQ(5, Constructable::getNumDestructorCalls());
-}
-
-// Resize bigger test.
-TYPED_TEST(CompactVectorTest, ResizeGrowTest) {
- SCOPED_TRACE("ResizeGrowTest");
-
- this->theVector.resize(2);
-
- EXPECT_EQ(2, Constructable::getNumConstructorCalls());
- EXPECT_EQ(0, Constructable::getNumDestructorCalls());
- EXPECT_EQ(2u, this->theVector.size());
-}
-
-TYPED_TEST(CompactVectorTest, ResizeWithElementsTest) {
- this->theVector.resize(2);
-
- Constructable::reset();
-
- this->theVector.resize(4);
-
- size_t Ctors = Constructable::getNumConstructorCalls();
- EXPECT_TRUE(Ctors == 2 || Ctors == 4);
- size_t MoveCtors = Constructable::getNumMoveConstructorCalls();
- EXPECT_TRUE(MoveCtors == 0 || MoveCtors == 2);
- size_t Dtors = Constructable::getNumDestructorCalls();
- EXPECT_TRUE(Dtors == 0 || Dtors == 2);
-}
-
-// Resize with fill value.
-TYPED_TEST(CompactVectorTest, ResizeFillTest) {
- SCOPED_TRACE("ResizeFillTest");
-
- this->theVector.resize(3, Constructable(77));
- this->assertValuesInOrder(this->theVector, 3u, 77, 77, 77);
-}
-
-// Overflow past fixed size.
-TYPED_TEST(CompactVectorTest, OverflowTest) {
- SCOPED_TRACE("OverflowTest");
-
- // Push more elements than the fixed size.
- this->makeSequence(this->theVector, 1, 10);
-
- // Test size and values.
- EXPECT_EQ(10u, this->theVector.size());
- for (int i = 0; i < 10; ++i) {
- EXPECT_EQ(i+1, this->theVector[i].getValue());
- }
-
- // Now resize back to fixed size.
- this->theVector.resize(1);
-
- this->assertValuesInOrder(this->theVector, 1u, 1);
-}
-
-// Iteration tests.
-TYPED_TEST(CompactVectorTest, IterationTest) {
- this->makeSequence(this->theVector, 1, 2);
-
- // Forward Iteration
- typename TypeParam::iterator it = this->theVector.begin();
- EXPECT_TRUE(*it == this->theVector.front());
- EXPECT_TRUE(*it == this->theVector[0]);
- EXPECT_EQ(1, it->getValue());
- ++it;
- EXPECT_TRUE(*it == this->theVector[1]);
- EXPECT_TRUE(*it == this->theVector.back());
- EXPECT_EQ(2, it->getValue());
- ++it;
- EXPECT_TRUE(it == this->theVector.end());
- --it;
- EXPECT_TRUE(*it == this->theVector[1]);
- EXPECT_EQ(2, it->getValue());
- --it;
- EXPECT_TRUE(*it == this->theVector[0]);
- EXPECT_EQ(1, it->getValue());
-
- // Reverse Iteration
- typename TypeParam::reverse_iterator rit = this->theVector.rbegin();
- EXPECT_TRUE(*rit == this->theVector[1]);
- EXPECT_EQ(2, rit->getValue());
- ++rit;
- EXPECT_TRUE(*rit == this->theVector[0]);
- EXPECT_EQ(1, rit->getValue());
- ++rit;
- EXPECT_TRUE(rit == this->theVector.rend());
- --rit;
- EXPECT_TRUE(*rit == this->theVector[0]);
- EXPECT_EQ(1, rit->getValue());
- --rit;
- EXPECT_TRUE(*rit == this->theVector[1]);
- EXPECT_EQ(2, rit->getValue());
-}
-
-// Swap test.
-TYPED_TEST(CompactVectorTest, SwapTest) {
- SCOPED_TRACE("SwapTest");
-
- this->makeSequence(this->theVector, 1, 2);
- std::swap(this->theVector, this->otherVector);
-
- this->assertEmpty(this->theVector);
- this->assertValuesInOrder(this->otherVector, 2u, 1, 2);
-}
-
-// Append test
-TYPED_TEST(CompactVectorTest, AppendTest) {
- SCOPED_TRACE("AppendTest");
-
- this->makeSequence(this->otherVector, 2, 3);
-
- this->theVector.push_back(Constructable(1));
- this->theVector.insert(this->theVector.end(), this->otherVector.begin(), this->otherVector.end());
-
- this->assertValuesInOrder(this->theVector, 3u, 1, 2, 3);
-}
-
-// Append repeated test
-TYPED_TEST(CompactVectorTest, AppendRepeatedTest) {
- SCOPED_TRACE("AppendRepeatedTest");
-
- this->theVector.push_back(Constructable(1));
- this->theVector.insert(this->theVector.end(), 2, Constructable(77));
- this->assertValuesInOrder(this->theVector, 3u, 1, 77, 77);
-}
-
-// Assign test
-TYPED_TEST(CompactVectorTest, AssignTest) {
- SCOPED_TRACE("AssignTest");
-
- this->theVector.push_back(Constructable(1));
- this->theVector.assign(2, Constructable(77));
- this->assertValuesInOrder(this->theVector, 2u, 77, 77);
-}
-
-// Move-assign test
-TYPED_TEST(CompactVectorTest, MoveAssignTest) {
- SCOPED_TRACE("MoveAssignTest");
-
- // Set up our vector with a single element, but enough capacity for 4.
- this->theVector.reserve(4);
- this->theVector.push_back(Constructable(1));
-
- // Set up the other vector with 2 elements.
- this->otherVector.push_back(Constructable(2));
- this->otherVector.push_back(Constructable(3));
-
- // Move-assign from the other vector.
- this->theVector = std::move(this->otherVector);
-
- // Make sure we have the right result.
- this->assertValuesInOrder(this->theVector, 2u, 2, 3);
-
- // Make sure the # of constructor/destructor calls line up. There
- // are two live objects after clearing the other vector.
- this->otherVector.clear();
- EXPECT_EQ(Constructable::getNumConstructorCalls()-2,
- Constructable::getNumDestructorCalls());
-
- // There shouldn't be any live objects any more.
- this->theVector.clear();
- EXPECT_EQ(Constructable::getNumConstructorCalls(),
- Constructable::getNumDestructorCalls());
-}
-
-// Erase a single element
-TYPED_TEST(CompactVectorTest, EraseTest) {
- SCOPED_TRACE("EraseTest");
-
- this->makeSequence(this->theVector, 1, 3);
- this->theVector.erase(this->theVector.begin());
- this->assertValuesInOrder(this->theVector, 2u, 2, 3);
-}
-
-// Erase a range of elements
-TYPED_TEST(CompactVectorTest, EraseRangeTest) {
- SCOPED_TRACE("EraseRangeTest");
-
- this->makeSequence(this->theVector, 1, 3);
- this->theVector.erase(this->theVector.begin(), this->theVector.begin() + 2);
- this->assertValuesInOrder(this->theVector, 1u, 3);
-}
-
-// Insert a single element.
-TYPED_TEST(CompactVectorTest, InsertTest) {
- SCOPED_TRACE("InsertTest");
-
- this->makeSequence(this->theVector, 1, 3);
- typename TypeParam::iterator I =
- this->theVector.insert(this->theVector.begin() + 1, Constructable(77));
- EXPECT_EQ(this->theVector.begin() + 1, I);
- this->assertValuesInOrder(this->theVector, 4u, 1, 77, 2, 3);
-}
-
-// Insert a copy of a single element.
-TYPED_TEST(CompactVectorTest, InsertCopy) {
- SCOPED_TRACE("InsertTest");
-
- this->makeSequence(this->theVector, 1, 3);
- Constructable C(77);
- typename TypeParam::iterator I =
- this->theVector.insert(this->theVector.begin() + 1, C);
- EXPECT_EQ(this->theVector.begin() + 1, I);
- this->assertValuesInOrder(this->theVector, 4u, 1, 77, 2, 3);
-}
-
-// Insert repeated elements.
-TYPED_TEST(CompactVectorTest, InsertRepeatedTest) {
- SCOPED_TRACE("InsertRepeatedTest");
-
- this->makeSequence(this->theVector, 1, 4);
- Constructable::reset();
- auto I =
- this->theVector.insert(this->theVector.begin() + 1, 2, Constructable(16));
- // Move construct the top element into newly allocated space, and optionally
- // reallocate the whole buffer, move constructing into it.
- // FIXME: This is inefficient, we shouldn't move things into newly allocated
- // space, then move them up/around, there should only be 2 or 4 move
- // constructions here.
- EXPECT_TRUE(Constructable::getNumMoveConstructorCalls() == 2 ||
- Constructable::getNumMoveConstructorCalls() == 6);
- // Move assign the next two to shift them up and make a gap.
- EXPECT_EQ(1, Constructable::getNumMoveAssignmentCalls());
- // Copy construct the two new elements from the parameter.
- EXPECT_EQ(2, Constructable::getNumCopyAssignmentCalls());
- // All without any copy construction.
- EXPECT_EQ(0, Constructable::getNumCopyConstructorCalls());
- EXPECT_EQ(this->theVector.begin() + 1, I);
- this->assertValuesInOrder(this->theVector, 6u, 1, 16, 16, 2, 3, 4);
-}
-
-
-TYPED_TEST(CompactVectorTest, InsertRepeatedAtEndTest) {
- SCOPED_TRACE("InsertRepeatedTest");
-
- this->makeSequence(this->theVector, 1, 4);
- Constructable::reset();
- auto I = this->theVector.insert(this->theVector.end(), 2, Constructable(16));
- // Just copy construct them into newly allocated space
- EXPECT_EQ(2, Constructable::getNumCopyConstructorCalls());
- // Move everything across if reallocation is needed.
- EXPECT_TRUE(Constructable::getNumMoveConstructorCalls() == 0 ||
- Constructable::getNumMoveConstructorCalls() == 4);
- // Without ever moving or copying anything else.
- EXPECT_EQ(0, Constructable::getNumCopyAssignmentCalls());
- EXPECT_EQ(0, Constructable::getNumMoveAssignmentCalls());
-
- EXPECT_EQ(this->theVector.begin() + 4, I);
- this->assertValuesInOrder(this->theVector, 6u, 1, 2, 3, 4, 16, 16);
-}
-
-TYPED_TEST(CompactVectorTest, InsertRepeatedEmptyTest) {
- SCOPED_TRACE("InsertRepeatedTest");
-
- this->makeSequence(this->theVector, 10, 15);
-
- // Empty insert.
- EXPECT_EQ(this->theVector.end(),
- this->theVector.insert(this->theVector.end(),
- 0, Constructable(42)));
- EXPECT_EQ(this->theVector.begin() + 1,
- this->theVector.insert(this->theVector.begin() + 1,
- 0, Constructable(42)));
-}
-
-// Insert range.
-TYPED_TEST(CompactVectorTest, InsertRangeTest) {
- SCOPED_TRACE("InsertRangeTest");
-
- Constructable Arr[3] =
- { Constructable(77), Constructable(77), Constructable(77) };
-
- this->makeSequence(this->theVector, 1, 3);
- Constructable::reset();
- auto I = this->theVector.insert(this->theVector.begin() + 1, Arr, Arr + 3);
- // Move construct the top 3 elements into newly allocated space.
- // Possibly move the whole sequence into new space first.
- // FIXME: This is inefficient, we shouldn't move things into newly allocated
- // space, then move them up/around, there should only be 2 or 3 move
- // constructions here.
- EXPECT_TRUE(Constructable::getNumMoveConstructorCalls() == 2 ||
- Constructable::getNumMoveConstructorCalls() == 5);
- // Copy assign the lower 2 new elements into existing space.
- EXPECT_EQ(2, Constructable::getNumCopyAssignmentCalls());
- // Copy construct the third element into newly allocated space.
- EXPECT_EQ(1, Constructable::getNumCopyConstructorCalls());
- EXPECT_EQ(this->theVector.begin() + 1, I);
- this->assertValuesInOrder(this->theVector, 6u, 1, 77, 77, 77, 2, 3);
-}
-
-
-TYPED_TEST(CompactVectorTest, InsertRangeAtEndTest) {
- SCOPED_TRACE("InsertRangeTest");
-
- Constructable Arr[3] =
- { Constructable(77), Constructable(77), Constructable(77) };
-
- this->makeSequence(this->theVector, 1, 3);
-
- // Insert at end.
- Constructable::reset();
- auto I = this->theVector.insert(this->theVector.end(), Arr, Arr+3);
- // Copy construct the 3 elements into new space at the top.
- EXPECT_EQ(3, Constructable::getNumCopyConstructorCalls());
- // Don't copy/move anything else.
- EXPECT_EQ(0, Constructable::getNumCopyAssignmentCalls());
- // Reallocation might occur, causing all elements to be moved into the new
- // buffer.
- EXPECT_TRUE(Constructable::getNumMoveConstructorCalls() == 0 ||
- Constructable::getNumMoveConstructorCalls() == 3);
- EXPECT_EQ(0, Constructable::getNumMoveAssignmentCalls());
- EXPECT_EQ(this->theVector.begin() + 3, I);
- this->assertValuesInOrder(this->theVector, 6u,
- 1, 2, 3, 77, 77, 77);
-}
-
-TYPED_TEST(CompactVectorTest, InsertEmptyRangeTest) {
- SCOPED_TRACE("InsertRangeTest");
-
- this->makeSequence(this->theVector, 1, 3);
-
- // Empty insert.
- EXPECT_EQ(this->theVector.end(),
- this->theVector.insert(this->theVector.end(),
- this->theVector.begin(),
- this->theVector.begin()));
- EXPECT_EQ(this->theVector.begin() + 1,
- this->theVector.insert(this->theVector.begin() + 1,
- this->theVector.begin(),
- this->theVector.begin()));
-}
-
-// Comparison tests.
-TYPED_TEST(CompactVectorTest, ComparisonTest) {
- SCOPED_TRACE("ComparisonTest");
-
- this->makeSequence(this->theVector, 1, 3);
- this->makeSequence(this->otherVector, 1, 3);
-
- EXPECT_TRUE(this->theVector == this->otherVector);
- EXPECT_FALSE(this->theVector != this->otherVector);
-
- this->otherVector.clear();
- this->makeSequence(this->otherVector, 2, 4);
-
- EXPECT_FALSE(this->theVector == this->otherVector);
- EXPECT_TRUE(this->theVector != this->otherVector);
-}
-
-// Constant vector tests.
-TYPED_TEST(CompactVectorTest, ConstVectorTest) {
- const TypeParam constVector;
-
- EXPECT_EQ(0u, constVector.size());
- EXPECT_TRUE(constVector.empty());
- EXPECT_TRUE(constVector.begin() == constVector.end());
-}
-
-// Direct array access.
-TYPED_TEST(CompactVectorTest, DirectVectorTest) {
- EXPECT_EQ(0u, this->theVector.size());
- this->theVector.reserve(4);
- EXPECT_LE(4u, this->theVector.capacity());
- EXPECT_EQ(0, Constructable::getNumConstructorCalls());
- this->theVector.push_back(1);
- this->theVector.push_back(2);
- this->theVector.push_back(3);
- this->theVector.push_back(4);
- EXPECT_EQ(4u, this->theVector.size());
- EXPECT_EQ(8, Constructable::getNumConstructorCalls());
- EXPECT_EQ(1, this->theVector[0].getValue());
- EXPECT_EQ(2, this->theVector[1].getValue());
- EXPECT_EQ(3, this->theVector[2].getValue());
- EXPECT_EQ(4, this->theVector[3].getValue());
-}
-
-TYPED_TEST(CompactVectorTest, IteratorTest) {
- std::list<int> L;
- this->theVector.insert(this->theVector.end(), L.begin(), L.end());
-}
-
-template <typename InvalidType> class DualCompactVectorsTest;
-
-template <typename VectorT1, typename VectorT2>
-class DualCompactVectorsTest<std::pair<VectorT1, VectorT2>> : public CompactVectorTestBase {
-protected:
- VectorT1 theVector;
- VectorT2 otherVector;
-
- template <typename T, size_t N>
- static size_t NumBuiltinElts(const TCompactVector<T, N>&) { return N; }
-};
-
-typedef ::testing::Types<
- // Small mode -> Small mode.
- std::pair<TCompactVector<Constructable, 4>, TCompactVector<Constructable, 4>>,
- // Small mode -> Big mode.
- std::pair<TCompactVector<Constructable, 4>, TCompactVector<Constructable, 2>>,
- // Big mode -> Small mode.
- std::pair<TCompactVector<Constructable, 2>, TCompactVector<Constructable, 4>>,
- // Big mode -> Big mode.
- std::pair<TCompactVector<Constructable, 2>, TCompactVector<Constructable, 2>>
- > DualCompactVectorTestTypes;
-
-TYPED_TEST_SUITE(DualCompactVectorsTest, DualCompactVectorTestTypes);
-
-TYPED_TEST(DualCompactVectorsTest, MoveAssignment) {
- SCOPED_TRACE("MoveAssignTest-DualVectorTypes");
-
- // Set up our vector with four elements.
- for (unsigned I = 0; I < 4; ++I)
- this->otherVector.push_back(Constructable(I));
-
- const Constructable *OrigDataPtr = this->otherVector.data();
-
- // Move-assign from the other vector.
- this->theVector =
- std::move(this->otherVector);
-
- // Make sure we have the right result.
- this->assertValuesInOrder(this->theVector, 4u, 0, 1, 2, 3);
-
- // Make sure the # of constructor/destructor calls line up. There
- // are two live objects after clearing the other vector.
- this->otherVector.clear();
- EXPECT_EQ(Constructable::getNumConstructorCalls()-4,
- Constructable::getNumDestructorCalls());
-
- // If the source vector (otherVector) was in small-mode, assert that we just
- // moved the data pointer over.
- EXPECT_TRUE(this->NumBuiltinElts(this->otherVector) == 4 ||
- this->theVector.data() == OrigDataPtr);
-
- // There shouldn't be any live objects any more.
- this->theVector.clear();
- EXPECT_EQ(Constructable::getNumConstructorCalls(),
- Constructable::getNumDestructorCalls());
-
- // We shouldn't have copied anything in this whole process.
- EXPECT_EQ(Constructable::getNumCopyConstructorCalls(), 0);
-}
-
-struct notassignable {
- int &x;
- notassignable(int &x) : x(x) {}
-};
-
-TEST(CompactVectorCustomTest, NoAssignTest) {
- int x = 0;
- TCompactVector<notassignable, 2> vec;
- vec.push_back(notassignable(x));
- x = 42;
- EXPECT_EQ(42, vec.back().x);
-}
-
-struct MovedFrom {
- bool hasValue;
- MovedFrom() : hasValue(true) {
- }
- MovedFrom(MovedFrom&& m) : hasValue(m.hasValue) {
- m.hasValue = false;
- }
- MovedFrom &operator=(MovedFrom&& m) {
- hasValue = m.hasValue;
- m.hasValue = false;
- return *this;
- }
-};
-
-TEST(CompactVectorTest, MidInsert) {
- TCompactVector<MovedFrom, 3> v;
- v.push_back(MovedFrom());
- v.insert(v.begin(), MovedFrom());
- for (MovedFrom &m : v)
- EXPECT_TRUE(m.hasValue);
-}
-
-enum EmplaceableArgState {
- EAS_Defaulted,
- EAS_Arg,
- EAS_LValue,
- EAS_RValue,
- EAS_Failure
-};
-template <int I> struct EmplaceableArg {
- EmplaceableArgState State;
- EmplaceableArg() : State(EAS_Defaulted) {}
- EmplaceableArg(EmplaceableArg &&X)
- : State(X.State == EAS_Arg ? EAS_RValue : EAS_Failure) {}
- EmplaceableArg(EmplaceableArg &X)
- : State(X.State == EAS_Arg ? EAS_LValue : EAS_Failure) {}
-
- explicit EmplaceableArg(bool) : State(EAS_Arg) {}
-
-private:
- EmplaceableArg &operator=(EmplaceableArg &&) = delete;
- EmplaceableArg &operator=(const EmplaceableArg &) = delete;
-};
-
-enum EmplaceableState { ES_Emplaced, ES_Moved };
-struct Emplaceable {
- EmplaceableArg<0> A0;
- EmplaceableArg<1> A1;
- EmplaceableArg<2> A2;
- EmplaceableArg<3> A3;
- EmplaceableState State;
-
- Emplaceable() : State(ES_Emplaced) {}
-
- template <class A0Ty>
- explicit Emplaceable(A0Ty &&A0)
- : A0(std::forward<A0Ty>(A0)), State(ES_Emplaced) {}
-
- template <class A0Ty, class A1Ty>
- Emplaceable(A0Ty &&A0, A1Ty &&A1)
- : A0(std::forward<A0Ty>(A0)), A1(std::forward<A1Ty>(A1)),
- State(ES_Emplaced) {}
-
- template <class A0Ty, class A1Ty, class A2Ty>
- Emplaceable(A0Ty &&A0, A1Ty &&A1, A2Ty &&A2)
- : A0(std::forward<A0Ty>(A0)), A1(std::forward<A1Ty>(A1)),
- A2(std::forward<A2Ty>(A2)), State(ES_Emplaced) {}
-
- template <class A0Ty, class A1Ty, class A2Ty, class A3Ty>
- Emplaceable(A0Ty &&A0, A1Ty &&A1, A2Ty &&A2, A3Ty &&A3)
- : A0(std::forward<A0Ty>(A0)), A1(std::forward<A1Ty>(A1)),
- A2(std::forward<A2Ty>(A2)), A3(std::forward<A3Ty>(A3)),
- State(ES_Emplaced) {}
-
- Emplaceable(Emplaceable &&) : State(ES_Moved) {}
- Emplaceable &operator=(Emplaceable &&) {
- State = ES_Moved;
- return *this;
- }
-
-private:
- Emplaceable(const Emplaceable &) = delete;
- Emplaceable &operator=(const Emplaceable &) = delete;
-};
-
-TEST(CompactVectorTest, EmplaceBack) {
- EmplaceableArg<0> A0(true);
- EmplaceableArg<1> A1(true);
- EmplaceableArg<2> A2(true);
- EmplaceableArg<3> A3(true);
- {
- TCompactVector<Emplaceable, 3> V;
- V.emplace_back();
- EXPECT_TRUE(V.size() == 1);
- EXPECT_TRUE(V.back().State == ES_Emplaced);
- EXPECT_TRUE(V.back().A0.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A1.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
- }
- {
- TCompactVector<Emplaceable, 3> V;
- V.emplace_back(std::move(A0));
- EXPECT_TRUE(V.size() == 1);
- EXPECT_TRUE(V.back().State == ES_Emplaced);
- EXPECT_TRUE(V.back().A0.State == EAS_RValue);
- EXPECT_TRUE(V.back().A1.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
- }
- {
- TCompactVector<Emplaceable, 3> V;
- V.emplace_back(A0);
- EXPECT_TRUE(V.size() == 1);
- EXPECT_TRUE(V.back().State == ES_Emplaced);
- EXPECT_TRUE(V.back().A0.State == EAS_LValue);
- EXPECT_TRUE(V.back().A1.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
- }
- {
- TCompactVector<Emplaceable, 3> V;
- V.emplace_back(A0, A1);
- EXPECT_TRUE(V.size() == 1);
- EXPECT_TRUE(V.back().State == ES_Emplaced);
- EXPECT_TRUE(V.back().A0.State == EAS_LValue);
- EXPECT_TRUE(V.back().A1.State == EAS_LValue);
- EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
- }
- {
- TCompactVector<Emplaceable, 3> V;
- V.emplace_back(std::move(A0), std::move(A1));
- EXPECT_TRUE(V.size() == 1);
- EXPECT_TRUE(V.back().State == ES_Emplaced);
- EXPECT_TRUE(V.back().A0.State == EAS_RValue);
- EXPECT_TRUE(V.back().A1.State == EAS_RValue);
- EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
- }
- {
- TCompactVector<Emplaceable, 3> V;
- V.emplace_back(std::move(A0), A1, std::move(A2), A3);
- EXPECT_TRUE(V.size() == 1);
- EXPECT_TRUE(V.back().State == ES_Emplaced);
- EXPECT_TRUE(V.back().A0.State == EAS_RValue);
- EXPECT_TRUE(V.back().A1.State == EAS_LValue);
- EXPECT_TRUE(V.back().A2.State == EAS_RValue);
- EXPECT_TRUE(V.back().A3.State == EAS_LValue);
- }
- {
- TCompactVector<int, 1> V;
- V.emplace_back();
- V.emplace_back(42);
- EXPECT_EQ(2U, V.size());
- EXPECT_EQ(0, V[0]);
- EXPECT_EQ(42, V[1]);
- }
-}
-
-TEST(CompactVectorTest, Emplace) {
- EmplaceableArg<0> A0(true);
- EmplaceableArg<1> A1(true);
- EmplaceableArg<2> A2(true);
- EmplaceableArg<3> A3(true);
- {
- TCompactVector<Emplaceable, 3> V;
- V.emplace(V.end());
- EXPECT_TRUE(V.size() == 1);
- EXPECT_TRUE(V.back().State == ES_Emplaced);
- EXPECT_TRUE(V.back().A0.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A1.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
- }
- {
- TCompactVector<Emplaceable, 3> V;
- V.emplace(V.end(), std::move(A0));
- EXPECT_TRUE(V.size() == 1);
- EXPECT_TRUE(V.back().State == ES_Emplaced);
- EXPECT_TRUE(V.back().A0.State == EAS_RValue);
- EXPECT_TRUE(V.back().A1.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
- }
- {
- TCompactVector<Emplaceable, 3> V;
- V.emplace(V.end(), A0);
- EXPECT_TRUE(V.size() == 1);
- EXPECT_TRUE(V.back().State == ES_Emplaced);
- EXPECT_TRUE(V.back().A0.State == EAS_LValue);
- EXPECT_TRUE(V.back().A1.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
- }
- {
- TCompactVector<Emplaceable, 3> V;
- V.emplace(V.end(), A0, A1);
- EXPECT_TRUE(V.size() == 1);
- EXPECT_TRUE(V.back().State == ES_Emplaced);
- EXPECT_TRUE(V.back().A0.State == EAS_LValue);
- EXPECT_TRUE(V.back().A1.State == EAS_LValue);
- EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
- }
- {
- TCompactVector<Emplaceable, 3> V;
- V.emplace(V.end(), std::move(A0), std::move(A1));
- EXPECT_TRUE(V.size() == 1);
- EXPECT_TRUE(V.back().State == ES_Emplaced);
- EXPECT_TRUE(V.back().A0.State == EAS_RValue);
- EXPECT_TRUE(V.back().A1.State == EAS_RValue);
- EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
- }
- {
- TCompactVector<Emplaceable, 3> V;
- V.emplace(V.end(), std::move(A0), A1, std::move(A2), A3);
- EXPECT_TRUE(V.size() == 1);
- EXPECT_TRUE(V.back().State == ES_Emplaced);
- EXPECT_TRUE(V.back().A0.State == EAS_RValue);
- EXPECT_TRUE(V.back().A1.State == EAS_LValue);
- EXPECT_TRUE(V.back().A2.State == EAS_RValue);
- EXPECT_TRUE(V.back().A3.State == EAS_LValue);
- }
- {
- TCompactVector<int, 1> V;
- V.emplace_back(42);
- V.emplace(V.begin(), 0);
- EXPECT_EQ(2U, V.size());
- EXPECT_EQ(0, V[0]);
- EXPECT_EQ(42, V[1]);
- }
-}
-
-template <class T, size_t N>
-class TStubArray
-{
-public:
- TStubArray(const TCompactVector<T, N>& vector)
- : Vector_(vector)
- { }
-
- bool equals(std::initializer_list<T> list)
- {
- return std::equal(Vector_.begin(), Vector_.end(), list.begin());
- }
-
- TCompactVector<T, N> Vector_;
-};
-
-template <typename T, size_t N>
-TStubArray<T, N> makeArrayRef(const TCompactVector<T, N>& vector)
-{
- return TStubArray<T, N>(vector);
-}
-
-TEST(CompactVectorTest, InitializerList) {
- TCompactVector<int, 2> V1 = {};
- EXPECT_TRUE(V1.empty());
- V1 = {0, 0};
- EXPECT_TRUE(makeArrayRef(V1).equals({0, 0}));
- V1 = {-1, -1};
- EXPECT_TRUE(makeArrayRef(V1).equals({-1, -1}));
-
- TCompactVector<int, 2> V2 = {1, 2, 3, 4};
- EXPECT_TRUE(makeArrayRef(V2).equals({1, 2, 3, 4}));
- V2.assign({4});
- EXPECT_TRUE(makeArrayRef(V2).equals({4}));
- V2.insert(V2.end(), {3, 2});
- EXPECT_TRUE(makeArrayRef(V2).equals({4, 3, 2}));
- V2.insert(V2.begin() + 1, 5);
- EXPECT_TRUE(makeArrayRef(V2).equals({4, 5, 3, 2}));
-}
-
-TEST(CompactVectorTest, AssignToShorter) {
- TCompactVector<TString, 4> lhs;
- TCompactVector<TString, 4> rhs;
- rhs.emplace_back("foo");
- lhs = rhs;
- EXPECT_EQ(1U, lhs.size());
- EXPECT_EQ("foo", lhs[0]);
-}
-
-TEST(CompactVectorTest, AssignToLonger) {
- TCompactVector<TString, 4> lhs;
- lhs.emplace_back("bar");
- lhs.emplace_back("baz");
- TCompactVector<TString, 4> rhs;
- rhs.emplace_back("foo");
- lhs = rhs;
- EXPECT_EQ(1U, lhs.size());
- EXPECT_EQ("foo", lhs[0]);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace
-} // namespace NYT
+// Clear test.
+TYPED_TEST(CompactVectorTest, ClearTest) {
+ SCOPED_TRACE("ClearTest");
+
+ this->theVector.reserve(2);
+ this->makeSequence(this->theVector, 1, 2);
+ this->theVector.clear();
+
+ this->assertEmpty(this->theVector);
+ EXPECT_EQ(4, Constructable::getNumConstructorCalls());
+ EXPECT_EQ(4, Constructable::getNumDestructorCalls());
+}
+
+// Resize smaller test.
+TYPED_TEST(CompactVectorTest, ResizeShrinkTest) {
+ SCOPED_TRACE("ResizeShrinkTest");
+
+ this->theVector.reserve(3);
+ this->makeSequence(this->theVector, 1, 3);
+ this->theVector.resize(1);
+
+ this->assertValuesInOrder(this->theVector, 1u, 1);
+ EXPECT_EQ(6, Constructable::getNumConstructorCalls());
+ EXPECT_EQ(5, Constructable::getNumDestructorCalls());
+}
+
+// Resize bigger test.
+TYPED_TEST(CompactVectorTest, ResizeGrowTest) {
+ SCOPED_TRACE("ResizeGrowTest");
+
+ this->theVector.resize(2);
+
+ EXPECT_EQ(2, Constructable::getNumConstructorCalls());
+ EXPECT_EQ(0, Constructable::getNumDestructorCalls());
+ EXPECT_EQ(2u, this->theVector.size());
+}
+
+TYPED_TEST(CompactVectorTest, ResizeWithElementsTest) {
+ this->theVector.resize(2);
+
+ Constructable::reset();
+
+ this->theVector.resize(4);
+
+ size_t Ctors = Constructable::getNumConstructorCalls();
+ EXPECT_TRUE(Ctors == 2 || Ctors == 4);
+ size_t MoveCtors = Constructable::getNumMoveConstructorCalls();
+ EXPECT_TRUE(MoveCtors == 0 || MoveCtors == 2);
+ size_t Dtors = Constructable::getNumDestructorCalls();
+ EXPECT_TRUE(Dtors == 0 || Dtors == 2);
+}
+
+// Resize with fill value.
+TYPED_TEST(CompactVectorTest, ResizeFillTest) {
+ SCOPED_TRACE("ResizeFillTest");
+
+ this->theVector.resize(3, Constructable(77));
+ this->assertValuesInOrder(this->theVector, 3u, 77, 77, 77);
+}
+
+// Overflow past fixed size.
+TYPED_TEST(CompactVectorTest, OverflowTest) {
+ SCOPED_TRACE("OverflowTest");
+
+ // Push more elements than the fixed size.
+ this->makeSequence(this->theVector, 1, 10);
+
+ // Test size and values.
+ EXPECT_EQ(10u, this->theVector.size());
+ for (int i = 0; i < 10; ++i) {
+ EXPECT_EQ(i+1, this->theVector[i].getValue());
+ }
+
+ // Now resize back to fixed size.
+ this->theVector.resize(1);
+
+ this->assertValuesInOrder(this->theVector, 1u, 1);
+}
+
+// Iteration tests.
+TYPED_TEST(CompactVectorTest, IterationTest) {
+ this->makeSequence(this->theVector, 1, 2);
+
+ // Forward Iteration
+ typename TypeParam::iterator it = this->theVector.begin();
+ EXPECT_TRUE(*it == this->theVector.front());
+ EXPECT_TRUE(*it == this->theVector[0]);
+ EXPECT_EQ(1, it->getValue());
+ ++it;
+ EXPECT_TRUE(*it == this->theVector[1]);
+ EXPECT_TRUE(*it == this->theVector.back());
+ EXPECT_EQ(2, it->getValue());
+ ++it;
+ EXPECT_TRUE(it == this->theVector.end());
+ --it;
+ EXPECT_TRUE(*it == this->theVector[1]);
+ EXPECT_EQ(2, it->getValue());
+ --it;
+ EXPECT_TRUE(*it == this->theVector[0]);
+ EXPECT_EQ(1, it->getValue());
+
+ // Reverse Iteration
+ typename TypeParam::reverse_iterator rit = this->theVector.rbegin();
+ EXPECT_TRUE(*rit == this->theVector[1]);
+ EXPECT_EQ(2, rit->getValue());
+ ++rit;
+ EXPECT_TRUE(*rit == this->theVector[0]);
+ EXPECT_EQ(1, rit->getValue());
+ ++rit;
+ EXPECT_TRUE(rit == this->theVector.rend());
+ --rit;
+ EXPECT_TRUE(*rit == this->theVector[0]);
+ EXPECT_EQ(1, rit->getValue());
+ --rit;
+ EXPECT_TRUE(*rit == this->theVector[1]);
+ EXPECT_EQ(2, rit->getValue());
+}
+
+// Swap test.
+TYPED_TEST(CompactVectorTest, SwapTest) {
+ SCOPED_TRACE("SwapTest");
+
+ this->makeSequence(this->theVector, 1, 2);
+ std::swap(this->theVector, this->otherVector);
+
+ this->assertEmpty(this->theVector);
+ this->assertValuesInOrder(this->otherVector, 2u, 1, 2);
+}
+
+// Append test
+TYPED_TEST(CompactVectorTest, AppendTest) {
+ SCOPED_TRACE("AppendTest");
+
+ this->makeSequence(this->otherVector, 2, 3);
+
+ this->theVector.push_back(Constructable(1));
+ this->theVector.insert(this->theVector.end(), this->otherVector.begin(), this->otherVector.end());
+
+ this->assertValuesInOrder(this->theVector, 3u, 1, 2, 3);
+}
+
+// Append repeated test
+TYPED_TEST(CompactVectorTest, AppendRepeatedTest) {
+ SCOPED_TRACE("AppendRepeatedTest");
+
+ this->theVector.push_back(Constructable(1));
+ this->theVector.insert(this->theVector.end(), 2, Constructable(77));
+ this->assertValuesInOrder(this->theVector, 3u, 1, 77, 77);
+}
+
+// Assign test
+TYPED_TEST(CompactVectorTest, AssignTest) {
+ SCOPED_TRACE("AssignTest");
+
+ this->theVector.push_back(Constructable(1));
+ this->theVector.assign(2, Constructable(77));
+ this->assertValuesInOrder(this->theVector, 2u, 77, 77);
+}
+
+// Move-assign test
+TYPED_TEST(CompactVectorTest, MoveAssignTest) {
+ SCOPED_TRACE("MoveAssignTest");
+
+ // Set up our vector with a single element, but enough capacity for 4.
+ this->theVector.reserve(4);
+ this->theVector.push_back(Constructable(1));
+
+ // Set up the other vector with 2 elements.
+ this->otherVector.push_back(Constructable(2));
+ this->otherVector.push_back(Constructable(3));
+
+ // Move-assign from the other vector.
+ this->theVector = std::move(this->otherVector);
+
+ // Make sure we have the right result.
+ this->assertValuesInOrder(this->theVector, 2u, 2, 3);
+
+ // Make sure the # of constructor/destructor calls line up. There
+ // are two live objects after clearing the other vector.
+ this->otherVector.clear();
+ EXPECT_EQ(Constructable::getNumConstructorCalls()-2,
+ Constructable::getNumDestructorCalls());
+
+ // There shouldn't be any live objects any more.
+ this->theVector.clear();
+ EXPECT_EQ(Constructable::getNumConstructorCalls(),
+ Constructable::getNumDestructorCalls());
+}
+
+// Erase a single element
+TYPED_TEST(CompactVectorTest, EraseTest) {
+ SCOPED_TRACE("EraseTest");
+
+ this->makeSequence(this->theVector, 1, 3);
+ this->theVector.erase(this->theVector.begin());
+ this->assertValuesInOrder(this->theVector, 2u, 2, 3);
+}
+
+// Erase a range of elements
+TYPED_TEST(CompactVectorTest, EraseRangeTest) {
+ SCOPED_TRACE("EraseRangeTest");
+
+ this->makeSequence(this->theVector, 1, 3);
+ this->theVector.erase(this->theVector.begin(), this->theVector.begin() + 2);
+ this->assertValuesInOrder(this->theVector, 1u, 3);
+}
+
+// Insert a single element.
+TYPED_TEST(CompactVectorTest, InsertTest) {
+ SCOPED_TRACE("InsertTest");
+
+ this->makeSequence(this->theVector, 1, 3);
+ typename TypeParam::iterator I =
+ this->theVector.insert(this->theVector.begin() + 1, Constructable(77));
+ EXPECT_EQ(this->theVector.begin() + 1, I);
+ this->assertValuesInOrder(this->theVector, 4u, 1, 77, 2, 3);
+}
+
+// Insert a copy of a single element.
+TYPED_TEST(CompactVectorTest, InsertCopy) {
+ SCOPED_TRACE("InsertTest");
+
+ this->makeSequence(this->theVector, 1, 3);
+ Constructable C(77);
+ typename TypeParam::iterator I =
+ this->theVector.insert(this->theVector.begin() + 1, C);
+ EXPECT_EQ(this->theVector.begin() + 1, I);
+ this->assertValuesInOrder(this->theVector, 4u, 1, 77, 2, 3);
+}
+
+// Insert repeated elements.
+TYPED_TEST(CompactVectorTest, InsertRepeatedTest) {
+ SCOPED_TRACE("InsertRepeatedTest");
+
+ this->makeSequence(this->theVector, 1, 4);
+ Constructable::reset();
+ auto I =
+ this->theVector.insert(this->theVector.begin() + 1, 2, Constructable(16));
+ // Move construct the top element into newly allocated space, and optionally
+ // reallocate the whole buffer, move constructing into it.
+ // FIXME: This is inefficient, we shouldn't move things into newly allocated
+ // space, then move them up/around, there should only be 2 or 4 move
+ // constructions here.
+ EXPECT_TRUE(Constructable::getNumMoveConstructorCalls() == 2 ||
+ Constructable::getNumMoveConstructorCalls() == 6);
+ // Move assign the next two to shift them up and make a gap.
+ EXPECT_EQ(1, Constructable::getNumMoveAssignmentCalls());
+ // Copy construct the two new elements from the parameter.
+ EXPECT_EQ(2, Constructable::getNumCopyAssignmentCalls());
+ // All without any copy construction.
+ EXPECT_EQ(0, Constructable::getNumCopyConstructorCalls());
+ EXPECT_EQ(this->theVector.begin() + 1, I);
+ this->assertValuesInOrder(this->theVector, 6u, 1, 16, 16, 2, 3, 4);
+}
+
+
+TYPED_TEST(CompactVectorTest, InsertRepeatedAtEndTest) {
+ SCOPED_TRACE("InsertRepeatedTest");
+
+ this->makeSequence(this->theVector, 1, 4);
+ Constructable::reset();
+ auto I = this->theVector.insert(this->theVector.end(), 2, Constructable(16));
+ // Just copy construct them into newly allocated space
+ EXPECT_EQ(2, Constructable::getNumCopyConstructorCalls());
+ // Move everything across if reallocation is needed.
+ EXPECT_TRUE(Constructable::getNumMoveConstructorCalls() == 0 ||
+ Constructable::getNumMoveConstructorCalls() == 4);
+ // Without ever moving or copying anything else.
+ EXPECT_EQ(0, Constructable::getNumCopyAssignmentCalls());
+ EXPECT_EQ(0, Constructable::getNumMoveAssignmentCalls());
+
+ EXPECT_EQ(this->theVector.begin() + 4, I);
+ this->assertValuesInOrder(this->theVector, 6u, 1, 2, 3, 4, 16, 16);
+}
+
+TYPED_TEST(CompactVectorTest, InsertRepeatedEmptyTest) {
+ SCOPED_TRACE("InsertRepeatedTest");
+
+ this->makeSequence(this->theVector, 10, 15);
+
+ // Empty insert.
+ EXPECT_EQ(this->theVector.end(),
+ this->theVector.insert(this->theVector.end(),
+ 0, Constructable(42)));
+ EXPECT_EQ(this->theVector.begin() + 1,
+ this->theVector.insert(this->theVector.begin() + 1,
+ 0, Constructable(42)));
+}
+
+// Insert range.
+TYPED_TEST(CompactVectorTest, InsertRangeTest) {
+ SCOPED_TRACE("InsertRangeTest");
+
+ Constructable Arr[3] =
+ { Constructable(77), Constructable(77), Constructable(77) };
+
+ this->makeSequence(this->theVector, 1, 3);
+ Constructable::reset();
+ auto I = this->theVector.insert(this->theVector.begin() + 1, Arr, Arr + 3);
+ // Move construct the top 3 elements into newly allocated space.
+ // Possibly move the whole sequence into new space first.
+ // FIXME: This is inefficient, we shouldn't move things into newly allocated
+ // space, then move them up/around, there should only be 2 or 3 move
+ // constructions here.
+ EXPECT_TRUE(Constructable::getNumMoveConstructorCalls() == 2 ||
+ Constructable::getNumMoveConstructorCalls() == 5);
+ // Copy assign the lower 2 new elements into existing space.
+ EXPECT_EQ(2, Constructable::getNumCopyAssignmentCalls());
+ // Copy construct the third element into newly allocated space.
+ EXPECT_EQ(1, Constructable::getNumCopyConstructorCalls());
+ EXPECT_EQ(this->theVector.begin() + 1, I);
+ this->assertValuesInOrder(this->theVector, 6u, 1, 77, 77, 77, 2, 3);
+}
+
+
+TYPED_TEST(CompactVectorTest, InsertRangeAtEndTest) {
+ SCOPED_TRACE("InsertRangeTest");
+
+ Constructable Arr[3] =
+ { Constructable(77), Constructable(77), Constructable(77) };
+
+ this->makeSequence(this->theVector, 1, 3);
+
+ // Insert at end.
+ Constructable::reset();
+ auto I = this->theVector.insert(this->theVector.end(), Arr, Arr+3);
+ // Copy construct the 3 elements into new space at the top.
+ EXPECT_EQ(3, Constructable::getNumCopyConstructorCalls());
+ // Don't copy/move anything else.
+ EXPECT_EQ(0, Constructable::getNumCopyAssignmentCalls());
+ // Reallocation might occur, causing all elements to be moved into the new
+ // buffer.
+ EXPECT_TRUE(Constructable::getNumMoveConstructorCalls() == 0 ||
+ Constructable::getNumMoveConstructorCalls() == 3);
+ EXPECT_EQ(0, Constructable::getNumMoveAssignmentCalls());
+ EXPECT_EQ(this->theVector.begin() + 3, I);
+ this->assertValuesInOrder(this->theVector, 6u,
+ 1, 2, 3, 77, 77, 77);
+}
+
+TYPED_TEST(CompactVectorTest, InsertEmptyRangeTest) {
+ SCOPED_TRACE("InsertRangeTest");
+
+ this->makeSequence(this->theVector, 1, 3);
+
+ // Empty insert.
+ EXPECT_EQ(this->theVector.end(),
+ this->theVector.insert(this->theVector.end(),
+ this->theVector.begin(),
+ this->theVector.begin()));
+ EXPECT_EQ(this->theVector.begin() + 1,
+ this->theVector.insert(this->theVector.begin() + 1,
+ this->theVector.begin(),
+ this->theVector.begin()));
+}
+
+// Comparison tests.
+TYPED_TEST(CompactVectorTest, ComparisonTest) {
+ SCOPED_TRACE("ComparisonTest");
+
+ this->makeSequence(this->theVector, 1, 3);
+ this->makeSequence(this->otherVector, 1, 3);
+
+ EXPECT_TRUE(this->theVector == this->otherVector);
+ EXPECT_FALSE(this->theVector != this->otherVector);
+
+ this->otherVector.clear();
+ this->makeSequence(this->otherVector, 2, 4);
+
+ EXPECT_FALSE(this->theVector == this->otherVector);
+ EXPECT_TRUE(this->theVector != this->otherVector);
+}
+
+// Constant vector tests.
+TYPED_TEST(CompactVectorTest, ConstVectorTest) {
+ const TypeParam constVector;
+
+ EXPECT_EQ(0u, constVector.size());
+ EXPECT_TRUE(constVector.empty());
+ EXPECT_TRUE(constVector.begin() == constVector.end());
+}
+
+// Direct array access.
+TYPED_TEST(CompactVectorTest, DirectVectorTest) {
+ EXPECT_EQ(0u, this->theVector.size());
+ this->theVector.reserve(4);
+ EXPECT_LE(4u, this->theVector.capacity());
+ EXPECT_EQ(0, Constructable::getNumConstructorCalls());
+ this->theVector.push_back(1);
+ this->theVector.push_back(2);
+ this->theVector.push_back(3);
+ this->theVector.push_back(4);
+ EXPECT_EQ(4u, this->theVector.size());
+ EXPECT_EQ(8, Constructable::getNumConstructorCalls());
+ EXPECT_EQ(1, this->theVector[0].getValue());
+ EXPECT_EQ(2, this->theVector[1].getValue());
+ EXPECT_EQ(3, this->theVector[2].getValue());
+ EXPECT_EQ(4, this->theVector[3].getValue());
+}
+
+TYPED_TEST(CompactVectorTest, IteratorTest) {
+ std::list<int> L;
+ this->theVector.insert(this->theVector.end(), L.begin(), L.end());
+}
+
+template <typename InvalidType> class DualCompactVectorsTest;
+
+template <typename VectorT1, typename VectorT2>
+class DualCompactVectorsTest<std::pair<VectorT1, VectorT2>> : public CompactVectorTestBase {
+protected:
+ VectorT1 theVector;
+ VectorT2 otherVector;
+
+ template <typename T, size_t N>
+ static size_t NumBuiltinElts(const TCompactVector<T, N>&) { return N; }
+};
+
+typedef ::testing::Types<
+ // Small mode -> Small mode.
+ std::pair<TCompactVector<Constructable, 4>, TCompactVector<Constructable, 4>>,
+ // Small mode -> Big mode.
+ std::pair<TCompactVector<Constructable, 4>, TCompactVector<Constructable, 2>>,
+ // Big mode -> Small mode.
+ std::pair<TCompactVector<Constructable, 2>, TCompactVector<Constructable, 4>>,
+ // Big mode -> Big mode.
+ std::pair<TCompactVector<Constructable, 2>, TCompactVector<Constructable, 2>>
+ > DualCompactVectorTestTypes;
+
+TYPED_TEST_SUITE(DualCompactVectorsTest, DualCompactVectorTestTypes);
+
+TYPED_TEST(DualCompactVectorsTest, MoveAssignment) {
+ SCOPED_TRACE("MoveAssignTest-DualVectorTypes");
+
+ // Set up our vector with four elements.
+ for (unsigned I = 0; I < 4; ++I)
+ this->otherVector.push_back(Constructable(I));
+
+ const Constructable *OrigDataPtr = this->otherVector.data();
+
+ // Move-assign from the other vector.
+ this->theVector =
+ std::move(this->otherVector);
+
+ // Make sure we have the right result.
+ this->assertValuesInOrder(this->theVector, 4u, 0, 1, 2, 3);
+
+ // Make sure the # of constructor/destructor calls line up. There
+ // are two live objects after clearing the other vector.
+ this->otherVector.clear();
+ EXPECT_EQ(Constructable::getNumConstructorCalls()-4,
+ Constructable::getNumDestructorCalls());
+
+ // If the source vector (otherVector) was in small-mode, assert that we just
+ // moved the data pointer over.
+ EXPECT_TRUE(this->NumBuiltinElts(this->otherVector) == 4 ||
+ this->theVector.data() == OrigDataPtr);
+
+ // There shouldn't be any live objects any more.
+ this->theVector.clear();
+ EXPECT_EQ(Constructable::getNumConstructorCalls(),
+ Constructable::getNumDestructorCalls());
+
+ // We shouldn't have copied anything in this whole process.
+ EXPECT_EQ(Constructable::getNumCopyConstructorCalls(), 0);
+}
+
+struct notassignable {
+ int &x;
+ notassignable(int &x) : x(x) {}
+};
+
+TEST(CompactVectorCustomTest, NoAssignTest) {
+ int x = 0;
+ TCompactVector<notassignable, 2> vec;
+ vec.push_back(notassignable(x));
+ x = 42;
+ EXPECT_EQ(42, vec.back().x);
+}
+
+struct MovedFrom {
+ bool hasValue;
+ MovedFrom() : hasValue(true) {
+ }
+ MovedFrom(MovedFrom&& m) : hasValue(m.hasValue) {
+ m.hasValue = false;
+ }
+ MovedFrom &operator=(MovedFrom&& m) {
+ hasValue = m.hasValue;
+ m.hasValue = false;
+ return *this;
+ }
+};
+
+TEST(CompactVectorTest, MidInsert) {
+ TCompactVector<MovedFrom, 3> v;
+ v.push_back(MovedFrom());
+ v.insert(v.begin(), MovedFrom());
+ for (MovedFrom &m : v)
+ EXPECT_TRUE(m.hasValue);
+}
+
+enum EmplaceableArgState {
+ EAS_Defaulted,
+ EAS_Arg,
+ EAS_LValue,
+ EAS_RValue,
+ EAS_Failure
+};
+template <int I> struct EmplaceableArg {
+ EmplaceableArgState State;
+ EmplaceableArg() : State(EAS_Defaulted) {}
+ EmplaceableArg(EmplaceableArg &&X)
+ : State(X.State == EAS_Arg ? EAS_RValue : EAS_Failure) {}
+ EmplaceableArg(EmplaceableArg &X)
+ : State(X.State == EAS_Arg ? EAS_LValue : EAS_Failure) {}
+
+ explicit EmplaceableArg(bool) : State(EAS_Arg) {}
+
+private:
+ EmplaceableArg &operator=(EmplaceableArg &&) = delete;
+ EmplaceableArg &operator=(const EmplaceableArg &) = delete;
+};
+
+enum EmplaceableState { ES_Emplaced, ES_Moved };
+struct Emplaceable {
+ EmplaceableArg<0> A0;
+ EmplaceableArg<1> A1;
+ EmplaceableArg<2> A2;
+ EmplaceableArg<3> A3;
+ EmplaceableState State;
+
+ Emplaceable() : State(ES_Emplaced) {}
+
+ template <class A0Ty>
+ explicit Emplaceable(A0Ty &&A0)
+ : A0(std::forward<A0Ty>(A0)), State(ES_Emplaced) {}
+
+ template <class A0Ty, class A1Ty>
+ Emplaceable(A0Ty &&A0, A1Ty &&A1)
+ : A0(std::forward<A0Ty>(A0)), A1(std::forward<A1Ty>(A1)),
+ State(ES_Emplaced) {}
+
+ template <class A0Ty, class A1Ty, class A2Ty>
+ Emplaceable(A0Ty &&A0, A1Ty &&A1, A2Ty &&A2)
+ : A0(std::forward<A0Ty>(A0)), A1(std::forward<A1Ty>(A1)),
+ A2(std::forward<A2Ty>(A2)), State(ES_Emplaced) {}
+
+ template <class A0Ty, class A1Ty, class A2Ty, class A3Ty>
+ Emplaceable(A0Ty &&A0, A1Ty &&A1, A2Ty &&A2, A3Ty &&A3)
+ : A0(std::forward<A0Ty>(A0)), A1(std::forward<A1Ty>(A1)),
+ A2(std::forward<A2Ty>(A2)), A3(std::forward<A3Ty>(A3)),
+ State(ES_Emplaced) {}
+
+ Emplaceable(Emplaceable &&) : State(ES_Moved) {}
+ Emplaceable &operator=(Emplaceable &&) {
+ State = ES_Moved;
+ return *this;
+ }
+
+private:
+ Emplaceable(const Emplaceable &) = delete;
+ Emplaceable &operator=(const Emplaceable &) = delete;
+};
+
+TEST(CompactVectorTest, EmplaceBack) {
+ EmplaceableArg<0> A0(true);
+ EmplaceableArg<1> A1(true);
+ EmplaceableArg<2> A2(true);
+ EmplaceableArg<3> A3(true);
+ {
+ TCompactVector<Emplaceable, 3> V;
+ V.emplace_back();
+ EXPECT_TRUE(V.size() == 1);
+ EXPECT_TRUE(V.back().State == ES_Emplaced);
+ EXPECT_TRUE(V.back().A0.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A1.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+ }
+ {
+ TCompactVector<Emplaceable, 3> V;
+ V.emplace_back(std::move(A0));
+ EXPECT_TRUE(V.size() == 1);
+ EXPECT_TRUE(V.back().State == ES_Emplaced);
+ EXPECT_TRUE(V.back().A0.State == EAS_RValue);
+ EXPECT_TRUE(V.back().A1.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+ }
+ {
+ TCompactVector<Emplaceable, 3> V;
+ V.emplace_back(A0);
+ EXPECT_TRUE(V.size() == 1);
+ EXPECT_TRUE(V.back().State == ES_Emplaced);
+ EXPECT_TRUE(V.back().A0.State == EAS_LValue);
+ EXPECT_TRUE(V.back().A1.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+ }
+ {
+ TCompactVector<Emplaceable, 3> V;
+ V.emplace_back(A0, A1);
+ EXPECT_TRUE(V.size() == 1);
+ EXPECT_TRUE(V.back().State == ES_Emplaced);
+ EXPECT_TRUE(V.back().A0.State == EAS_LValue);
+ EXPECT_TRUE(V.back().A1.State == EAS_LValue);
+ EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+ }
+ {
+ TCompactVector<Emplaceable, 3> V;
+ V.emplace_back(std::move(A0), std::move(A1));
+ EXPECT_TRUE(V.size() == 1);
+ EXPECT_TRUE(V.back().State == ES_Emplaced);
+ EXPECT_TRUE(V.back().A0.State == EAS_RValue);
+ EXPECT_TRUE(V.back().A1.State == EAS_RValue);
+ EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+ }
+ {
+ TCompactVector<Emplaceable, 3> V;
+ V.emplace_back(std::move(A0), A1, std::move(A2), A3);
+ EXPECT_TRUE(V.size() == 1);
+ EXPECT_TRUE(V.back().State == ES_Emplaced);
+ EXPECT_TRUE(V.back().A0.State == EAS_RValue);
+ EXPECT_TRUE(V.back().A1.State == EAS_LValue);
+ EXPECT_TRUE(V.back().A2.State == EAS_RValue);
+ EXPECT_TRUE(V.back().A3.State == EAS_LValue);
+ }
+ {
+ TCompactVector<int, 1> V;
+ V.emplace_back();
+ V.emplace_back(42);
+ EXPECT_EQ(2U, V.size());
+ EXPECT_EQ(0, V[0]);
+ EXPECT_EQ(42, V[1]);
+ }
+}
+
+TEST(CompactVectorTest, Emplace) {
+ EmplaceableArg<0> A0(true);
+ EmplaceableArg<1> A1(true);
+ EmplaceableArg<2> A2(true);
+ EmplaceableArg<3> A3(true);
+ {
+ TCompactVector<Emplaceable, 3> V;
+ V.emplace(V.end());
+ EXPECT_TRUE(V.size() == 1);
+ EXPECT_TRUE(V.back().State == ES_Emplaced);
+ EXPECT_TRUE(V.back().A0.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A1.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+ }
+ {
+ TCompactVector<Emplaceable, 3> V;
+ V.emplace(V.end(), std::move(A0));
+ EXPECT_TRUE(V.size() == 1);
+ EXPECT_TRUE(V.back().State == ES_Emplaced);
+ EXPECT_TRUE(V.back().A0.State == EAS_RValue);
+ EXPECT_TRUE(V.back().A1.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+ }
+ {
+ TCompactVector<Emplaceable, 3> V;
+ V.emplace(V.end(), A0);
+ EXPECT_TRUE(V.size() == 1);
+ EXPECT_TRUE(V.back().State == ES_Emplaced);
+ EXPECT_TRUE(V.back().A0.State == EAS_LValue);
+ EXPECT_TRUE(V.back().A1.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+ }
+ {
+ TCompactVector<Emplaceable, 3> V;
+ V.emplace(V.end(), A0, A1);
+ EXPECT_TRUE(V.size() == 1);
+ EXPECT_TRUE(V.back().State == ES_Emplaced);
+ EXPECT_TRUE(V.back().A0.State == EAS_LValue);
+ EXPECT_TRUE(V.back().A1.State == EAS_LValue);
+ EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+ }
+ {
+ TCompactVector<Emplaceable, 3> V;
+ V.emplace(V.end(), std::move(A0), std::move(A1));
+ EXPECT_TRUE(V.size() == 1);
+ EXPECT_TRUE(V.back().State == ES_Emplaced);
+ EXPECT_TRUE(V.back().A0.State == EAS_RValue);
+ EXPECT_TRUE(V.back().A1.State == EAS_RValue);
+ EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+ }
+ {
+ TCompactVector<Emplaceable, 3> V;
+ V.emplace(V.end(), std::move(A0), A1, std::move(A2), A3);
+ EXPECT_TRUE(V.size() == 1);
+ EXPECT_TRUE(V.back().State == ES_Emplaced);
+ EXPECT_TRUE(V.back().A0.State == EAS_RValue);
+ EXPECT_TRUE(V.back().A1.State == EAS_LValue);
+ EXPECT_TRUE(V.back().A2.State == EAS_RValue);
+ EXPECT_TRUE(V.back().A3.State == EAS_LValue);
+ }
+ {
+ TCompactVector<int, 1> V;
+ V.emplace_back(42);
+ V.emplace(V.begin(), 0);
+ EXPECT_EQ(2U, V.size());
+ EXPECT_EQ(0, V[0]);
+ EXPECT_EQ(42, V[1]);
+ }
+}
+
+template <class T, size_t N>
+class TStubArray
+{
+public:
+ TStubArray(const TCompactVector<T, N>& vector)
+ : Vector_(vector)
+ { }
+
+ bool equals(std::initializer_list<T> list)
+ {
+ return std::equal(Vector_.begin(), Vector_.end(), list.begin());
+ }
+
+ TCompactVector<T, N> Vector_;
+};
+
+template <typename T, size_t N>
+TStubArray<T, N> makeArrayRef(const TCompactVector<T, N>& vector)
+{
+ return TStubArray<T, N>(vector);
+}
+
+TEST(CompactVectorTest, InitializerList) {
+ TCompactVector<int, 2> V1 = {};
+ EXPECT_TRUE(V1.empty());
+ V1 = {0, 0};
+ EXPECT_TRUE(makeArrayRef(V1).equals({0, 0}));
+ V1 = {-1, -1};
+ EXPECT_TRUE(makeArrayRef(V1).equals({-1, -1}));
+
+ TCompactVector<int, 2> V2 = {1, 2, 3, 4};
+ EXPECT_TRUE(makeArrayRef(V2).equals({1, 2, 3, 4}));
+ V2.assign({4});
+ EXPECT_TRUE(makeArrayRef(V2).equals({4}));
+ V2.insert(V2.end(), {3, 2});
+ EXPECT_TRUE(makeArrayRef(V2).equals({4, 3, 2}));
+ V2.insert(V2.begin() + 1, 5);
+ EXPECT_TRUE(makeArrayRef(V2).equals({4, 5, 3, 2}));
+}
+
+TEST(CompactVectorTest, AssignToShorter) {
+ TCompactVector<TString, 4> lhs;
+ TCompactVector<TString, 4> rhs;
+ rhs.emplace_back("foo");
+ lhs = rhs;
+ EXPECT_EQ(1U, lhs.size());
+ EXPECT_EQ("foo", lhs[0]);
+}
+
+TEST(CompactVectorTest, AssignToLonger) {
+ TCompactVector<TString, 4> lhs;
+ lhs.emplace_back("bar");
+ lhs.emplace_back("baz");
+ TCompactVector<TString, 4> rhs;
+ rhs.emplace_back("foo");
+ lhs = rhs;
+ EXPECT_EQ(1U, lhs.size());
+ EXPECT_EQ("foo", lhs[0]);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace
+} // namespace NYT
diff --git a/library/cpp/yt/small_containers/unittests/ya.make b/library/cpp/yt/small_containers/unittests/ya.make
index d4cb7b71e2..6bd8e1d0ec 100644
--- a/library/cpp/yt/small_containers/unittests/ya.make
+++ b/library/cpp/yt/small_containers/unittests/ya.make
@@ -3,14 +3,14 @@ GTEST(unittester-small-containers)
OWNER(g:yt)
SRCS(
- compact_flat_map_ut.cpp
+ compact_flat_map_ut.cpp
compact_heap_ut.cpp
compact_set_ut.cpp
- compact_vector_ut.cpp
+ compact_vector_ut.cpp
)
PEERDIR(
- library/cpp/yt/small_containers
+ library/cpp/yt/small_containers
library/cpp/testing/gtest
)
diff --git a/library/cpp/yt/small_containers/ya.make b/library/cpp/yt/small_containers/ya.make
index b73e27ba90..d886b2ddac 100644
--- a/library/cpp/yt/small_containers/ya.make
+++ b/library/cpp/yt/small_containers/ya.make
@@ -1,8 +1,8 @@
LIBRARY()
PEERDIR(
- library/cpp/yt/assert
- library/cpp/yt/malloc
+ library/cpp/yt/assert
+ library/cpp/yt/malloc
)
CHECK_DEPENDENT_DIRS(
diff --git a/library/cpp/yt/string/enum-inl.h b/library/cpp/yt/string/enum-inl.h
index 0095979824..ab8acff71b 100644
--- a/library/cpp/yt/string/enum-inl.h
+++ b/library/cpp/yt/string/enum-inl.h
@@ -1,118 +1,118 @@
-#ifndef ENUM_INL_H_
-#error "Direct inclusion of this file is not allowed, include enum.h"
-// For the sake of sane code completion.
-#include "enum.h"
-#endif
-
-#include <util/string/printf.h>
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-namespace NDetail {
-
-[[noreturn]]
-void ThrowMalformedEnumValueException(
- TStringBuf typeName,
- TStringBuf value);
-
-void FormatUnknownEnumValue(
- TStringBuilderBase* builder,
- TStringBuf name,
- i64 value);
-
-} // namespace NDetail
-
-template <class T>
-std::optional<T> TryParseEnum(TStringBuf value)
-{
- static_assert(TEnumTraits<T>::IsEnum);
-
- auto tryFromString = [] (TStringBuf value) -> std::optional<T> {
- T result;
- if (auto ok = TEnumTraits<T>::FindValueByLiteral(DecodeEnumValue(value), &result)) {
- return result;
- }
- return {};
- };
-
- if constexpr (TEnumTraits<T>::IsBitEnum) {
- T result{};
- TStringBuf token;
- while (value.NextTok('|', token)) {
- if (auto scalar = tryFromString(StripString(token))) {
- result |= *scalar;
- } else {
- return {};
- }
- }
- return result;
- } else {
- return tryFromString(value);
- }
-}
-
-template <class T>
-T ParseEnum(TStringBuf value)
-{
- if (auto optionalResult = TryParseEnum<T>(value)) {
- return *optionalResult;
- }
- NDetail::ThrowMalformedEnumValueException(TEnumTraits<T>::GetTypeName(), value);
-}
-
-template <class T>
-void FormatEnum(TStringBuilderBase* builder, T value, bool lowerCase)
-{
- static_assert(TEnumTraits<T>::IsEnum);
-
- auto formatScalarValue = [builder, lowerCase] (T value) {
- auto* literal = TEnumTraits<T>::FindLiteralByValue(value);
- if (!literal) {
- YT_VERIFY(!TEnumTraits<T>::IsBitEnum);
- NDetail::FormatUnknownEnumValue(
- builder,
- TEnumTraits<T>::GetTypeName(),
- static_cast<typename TEnumTraits<T>::TUnderlying>(value));
- return;
- }
-
- if (lowerCase) {
- CamelCaseToUnderscoreCase(builder, *literal);
- } else {
- builder->AppendString(*literal);
- }
- };
-
- if constexpr (TEnumTraits<T>::IsBitEnum) {
- if (auto* literal = TEnumTraits<T>::FindLiteralByValue(value)) {
- formatScalarValue(value);
- return;
- }
- auto first = true;
- for (auto scalarValue : TEnumTraits<T>::GetDomainValues()) {
- if (Any(value & scalarValue)) {
- if (!first) {
- builder->AppendString(TStringBuf(" | "));
- }
- first = false;
- formatScalarValue(scalarValue);
- }
- }
- } else {
- formatScalarValue(value);
- }
-}
-
-template <class T>
-TString FormatEnum(T value, typename TEnumTraits<T>::TType*)
-{
- TStringBuilder builder;
- FormatEnum(&builder, value, /*lowerCase*/ true);
- return builder.Flush();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
+#ifndef ENUM_INL_H_
+#error "Direct inclusion of this file is not allowed, include enum.h"
+// For the sake of sane code completion.
+#include "enum.h"
+#endif
+
+#include <util/string/printf.h>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+namespace NDetail {
+
+[[noreturn]]
+void ThrowMalformedEnumValueException(
+ TStringBuf typeName,
+ TStringBuf value);
+
+void FormatUnknownEnumValue(
+ TStringBuilderBase* builder,
+ TStringBuf name,
+ i64 value);
+
+} // namespace NDetail
+
+template <class T>
+std::optional<T> TryParseEnum(TStringBuf value)
+{
+ static_assert(TEnumTraits<T>::IsEnum);
+
+ auto tryFromString = [] (TStringBuf value) -> std::optional<T> {
+ T result;
+ if (auto ok = TEnumTraits<T>::FindValueByLiteral(DecodeEnumValue(value), &result)) {
+ return result;
+ }
+ return {};
+ };
+
+ if constexpr (TEnumTraits<T>::IsBitEnum) {
+ T result{};
+ TStringBuf token;
+ while (value.NextTok('|', token)) {
+ if (auto scalar = tryFromString(StripString(token))) {
+ result |= *scalar;
+ } else {
+ return {};
+ }
+ }
+ return result;
+ } else {
+ return tryFromString(value);
+ }
+}
+
+template <class T>
+T ParseEnum(TStringBuf value)
+{
+ if (auto optionalResult = TryParseEnum<T>(value)) {
+ return *optionalResult;
+ }
+ NDetail::ThrowMalformedEnumValueException(TEnumTraits<T>::GetTypeName(), value);
+}
+
+template <class T>
+void FormatEnum(TStringBuilderBase* builder, T value, bool lowerCase)
+{
+ static_assert(TEnumTraits<T>::IsEnum);
+
+ auto formatScalarValue = [builder, lowerCase] (T value) {
+ auto* literal = TEnumTraits<T>::FindLiteralByValue(value);
+ if (!literal) {
+ YT_VERIFY(!TEnumTraits<T>::IsBitEnum);
+ NDetail::FormatUnknownEnumValue(
+ builder,
+ TEnumTraits<T>::GetTypeName(),
+ static_cast<typename TEnumTraits<T>::TUnderlying>(value));
+ return;
+ }
+
+ if (lowerCase) {
+ CamelCaseToUnderscoreCase(builder, *literal);
+ } else {
+ builder->AppendString(*literal);
+ }
+ };
+
+ if constexpr (TEnumTraits<T>::IsBitEnum) {
+ if (auto* literal = TEnumTraits<T>::FindLiteralByValue(value)) {
+ formatScalarValue(value);
+ return;
+ }
+ auto first = true;
+ for (auto scalarValue : TEnumTraits<T>::GetDomainValues()) {
+ if (Any(value & scalarValue)) {
+ if (!first) {
+ builder->AppendString(TStringBuf(" | "));
+ }
+ first = false;
+ formatScalarValue(scalarValue);
+ }
+ }
+ } else {
+ formatScalarValue(value);
+ }
+}
+
+template <class T>
+TString FormatEnum(T value, typename TEnumTraits<T>::TType*)
+{
+ TStringBuilder builder;
+ FormatEnum(&builder, value, /*lowerCase*/ true);
+ return builder.Flush();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/string/enum.cpp b/library/cpp/yt/string/enum.cpp
index 5f8c032edf..7cb8e5c6b6 100644
--- a/library/cpp/yt/string/enum.cpp
+++ b/library/cpp/yt/string/enum.cpp
@@ -1,44 +1,44 @@
#include "enum.h"
-
+
#include "format.h"
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
TString DecodeEnumValue(TStringBuf value)
-{
- auto camelValue = UnderscoreCaseToCamelCase(value);
+{
+ auto camelValue = UnderscoreCaseToCamelCase(value);
auto underscoreValue = CamelCaseToUnderscoreCase(camelValue);
if (value != underscoreValue) {
- throw TSimpleException(Format("Enum value %Qv is not in a proper underscore case; did you mean %Qv?",
+ throw TSimpleException(Format("Enum value %Qv is not in a proper underscore case; did you mean %Qv?",
value,
- underscoreValue));
+ underscoreValue));
}
- return camelValue;
-}
-
+ return camelValue;
+}
+
TString EncodeEnumValue(TStringBuf value)
-{
- return CamelCaseToUnderscoreCase(value);
-}
-
-namespace NDetail {
-
-void ThrowMalformedEnumValueException(TStringBuf typeName, TStringBuf value)
{
- throw TSimpleException(Format("Error parsing %v value %Qv",
- typeName,
- value));
+ return CamelCaseToUnderscoreCase(value);
}
-void FormatUnknownEnumValue(TStringBuilderBase* builder, TStringBuf name, i64 value)
+namespace NDetail {
+
+void ThrowMalformedEnumValueException(TStringBuf typeName, TStringBuf value)
+{
+ throw TSimpleException(Format("Error parsing %v value %Qv",
+ typeName,
+ value));
+}
+
+void FormatUnknownEnumValue(TStringBuilderBase* builder, TStringBuf name, i64 value)
{
builder->AppendFormat("%v(%v)", name, value);
}
-} // namespace NDetail
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
+} // namespace NDetail
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/string/enum.h b/library/cpp/yt/string/enum.h
index 774ad5eb02..10dc02610f 100644
--- a/library/cpp/yt/string/enum.h
+++ b/library/cpp/yt/string/enum.h
@@ -1,31 +1,31 @@
-#pragma once
-
+#pragma once
+
#include "string.h"
-
+
#include <library/cpp/yt/misc/enum.h>
-
+
#include <optional>
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
TString DecodeEnumValue(TStringBuf value);
TString EncodeEnumValue(TStringBuf value);
-
+
template <class T>
-T ParseEnum(TStringBuf value);
+T ParseEnum(TStringBuf value);
template <class T>
-void FormatEnum(TStringBuilderBase* builder, T value, bool lowerCase);
+void FormatEnum(TStringBuilderBase* builder, T value, bool lowerCase);
template <class T>
-TString FormatEnum(T value, typename TEnumTraits<T>::TType* = nullptr);
+TString FormatEnum(T value, typename TEnumTraits<T>::TType* = nullptr);
////////////////////////////////////////////////////////////////////////////////
-} // namespace NYT
-
-#define ENUM_INL_H_
-#include "enum-inl.h"
-#undef ENUM_INL_H_
+} // namespace NYT
+
+#define ENUM_INL_H_
+#include "enum-inl.h"
+#undef ENUM_INL_H_
diff --git a/library/cpp/yt/string/format-inl.h b/library/cpp/yt/string/format-inl.h
index 550869846e..5484d4a216 100644
--- a/library/cpp/yt/string/format-inl.h
+++ b/library/cpp/yt/string/format-inl.h
@@ -1,72 +1,72 @@
-#ifndef FORMAT_INL_H_
-#error "Direct inclusion of this file is not allowed, include format.h"
+#ifndef FORMAT_INL_H_
+#error "Direct inclusion of this file is not allowed, include format.h"
// For the sake of sane code completion.
#include "format.h"
-#endif
-
+#endif
+
#include "enum.h"
-#include "string.h"
-
-#include <library/cpp/yt/assert/assert.h>
+#include "string.h"
+
+#include <library/cpp/yt/assert/assert.h>
#include <library/cpp/yt/small_containers/compact_vector.h>
-#include <library/cpp/yt/misc/enum.h>
+#include <library/cpp/yt/misc/enum.h>
#include <cctype>
#include <optional>
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
static const char GenericSpecSymbol = 'v';
-
+
inline bool IsQuotationSpecSymbol(char symbol)
{
return symbol == 'Q' || symbol == 'q';
}
-// TStringBuf
-inline void FormatValue(TStringBuilderBase* builder, TStringBuf value, TStringBuf format)
-{
- if (!format) {
- builder->AppendString(value);
- return;
- }
-
- // Parse alignment.
- bool alignLeft = false;
- const char* current = format.begin();
- if (*current == '-') {
- alignLeft = true;
- ++current;
- }
-
- bool hasAlign = false;
- int alignSize = 0;
- while (*current >= '0' && *current <= '9') {
- hasAlign = true;
- alignSize = 10 * alignSize + (*current - '0');
- if (alignSize > 1000000) {
+// TStringBuf
+inline void FormatValue(TStringBuilderBase* builder, TStringBuf value, TStringBuf format)
+{
+ if (!format) {
+ builder->AppendString(value);
+ return;
+ }
+
+ // Parse alignment.
+ bool alignLeft = false;
+ const char* current = format.begin();
+ if (*current == '-') {
+ alignLeft = true;
+ ++current;
+ }
+
+ bool hasAlign = false;
+ int alignSize = 0;
+ while (*current >= '0' && *current <= '9') {
+ hasAlign = true;
+ alignSize = 10 * alignSize + (*current - '0');
+ if (alignSize > 1000000) {
builder->AppendString(TStringBuf("<alignment overflow>"));
- return;
- }
- ++current;
- }
-
- int padding = 0;
- bool padLeft = false;
- bool padRight = false;
- if (hasAlign) {
- padding = alignSize - value.size();
- if (padding < 0) {
- padding = 0;
- }
- padLeft = !alignLeft;
- padRight = alignLeft;
- }
-
+ return;
+ }
+ ++current;
+ }
+
+ int padding = 0;
+ bool padLeft = false;
+ bool padRight = false;
+ if (hasAlign) {
+ padding = alignSize - value.size();
+ if (padding < 0) {
+ padding = 0;
+ }
+ padLeft = !alignLeft;
+ padRight = alignLeft;
+ }
+
bool singleQuotes = false;
bool doubleQuotes = false;
while (current < format.end()) {
@@ -78,9 +78,9 @@ inline void FormatValue(TStringBuilderBase* builder, TStringBuf value, TStringBu
++current;
}
- if (padLeft) {
- builder->AppendChar(' ', padding);
- }
+ if (padLeft) {
+ builder->AppendChar(' ', padding);
+ }
if (singleQuotes || doubleQuotes) {
for (const char* valueCurrent = value.begin(); valueCurrent < value.end(); ++valueCurrent) {
@@ -104,92 +104,92 @@ inline void FormatValue(TStringBuilderBase* builder, TStringBuf value, TStringBu
builder->AppendString(value);
}
- if (padRight) {
- builder->AppendChar(' ', padding);
- }
-}
-
+ if (padRight) {
+ builder->AppendChar(' ', padding);
+ }
+}
+
// TString
-inline void FormatValue(TStringBuilderBase* builder, const TString& value, TStringBuf format)
-{
- FormatValue(builder, TStringBuf(value), format);
-}
-
-// const char*
-inline void FormatValue(TStringBuilderBase* builder, const char* value, TStringBuf format)
-{
- FormatValue(builder, TStringBuf(value), format);
-}
-
+inline void FormatValue(TStringBuilderBase* builder, const TString& value, TStringBuf format)
+{
+ FormatValue(builder, TStringBuf(value), format);
+}
+
+// const char*
+inline void FormatValue(TStringBuilderBase* builder, const char* value, TStringBuf format)
+{
+ FormatValue(builder, TStringBuf(value), format);
+}
+
// char
-inline void FormatValue(TStringBuilderBase* builder, char value, TStringBuf format)
+inline void FormatValue(TStringBuilderBase* builder, char value, TStringBuf format)
{
FormatValue(builder, TStringBuf(&value, 1), format);
}
-// bool
-inline void FormatValue(TStringBuilderBase* builder, bool value, TStringBuf format)
-{
- // Parse custom flags.
- bool lowercase = false;
- const char* current = format.begin();
- while (current != format.end()) {
- if (*current == 'l') {
- ++current;
- lowercase = true;
+// bool
+inline void FormatValue(TStringBuilderBase* builder, bool value, TStringBuf format)
+{
+ // Parse custom flags.
+ bool lowercase = false;
+ const char* current = format.begin();
+ while (current != format.end()) {
+ if (*current == 'l') {
+ ++current;
+ lowercase = true;
} else if (IsQuotationSpecSymbol(*current)) {
++current;
- } else
- break;
- }
-
- auto str = lowercase
+ } else
+ break;
+ }
+
+ auto str = lowercase
? (value ? TStringBuf("true") : TStringBuf("false"))
: (value ? TStringBuf("True") : TStringBuf("False"));
-
- builder->AppendString(str);
-}
-
-// Fallback to ToString
-struct TToStringFallbackValueFormatterTag
-{ };
-
-template <class TValue, class = void>
-struct TValueFormatter
-{
- static TToStringFallbackValueFormatterTag Do(TStringBuilderBase* builder, const TValue& value, TStringBuf format)
- {
- using ::ToString;
- FormatValue(builder, ToString(value), format);
- return {};
- }
-};
-
-// Enum
-template <class TEnum>
-struct TValueFormatter<TEnum, typename std::enable_if<TEnumTraits<TEnum>::IsEnum>::type>
-{
- static void Do(TStringBuilderBase* builder, TEnum value, TStringBuf format)
- {
- // Parse custom flags.
- bool lowercase = false;
- const char* current = format.begin();
- while (current != format.end()) {
- if (*current == 'l') {
- ++current;
- lowercase = true;
+
+ builder->AppendString(str);
+}
+
+// Fallback to ToString
+struct TToStringFallbackValueFormatterTag
+{ };
+
+template <class TValue, class = void>
+struct TValueFormatter
+{
+ static TToStringFallbackValueFormatterTag Do(TStringBuilderBase* builder, const TValue& value, TStringBuf format)
+ {
+ using ::ToString;
+ FormatValue(builder, ToString(value), format);
+ return {};
+ }
+};
+
+// Enum
+template <class TEnum>
+struct TValueFormatter<TEnum, typename std::enable_if<TEnumTraits<TEnum>::IsEnum>::type>
+{
+ static void Do(TStringBuilderBase* builder, TEnum value, TStringBuf format)
+ {
+ // Parse custom flags.
+ bool lowercase = false;
+ const char* current = format.begin();
+ while (current != format.end()) {
+ if (*current == 'l') {
+ ++current;
+ lowercase = true;
} else if (IsQuotationSpecSymbol(*current)) {
++current;
} else {
- break;
+ break;
}
- }
-
+ }
+
FormatEnum(builder, value, lowercase);
- }
-};
-
-template <class TRange, class TFormatter>
+ }
+};
+
+template <class TRange, class TFormatter>
typename TFormattableView<TRange, TFormatter>::TBegin TFormattableView<TRange, TFormatter>::begin() const
{
return RangeBegin;
@@ -203,42 +203,42 @@ typename TFormattableView<TRange, TFormatter>::TEnd TFormattableView<TRange, TFo
template <class TRange, class TFormatter>
TFormattableView<TRange, TFormatter> MakeFormattableView(
- const TRange& range,
+ const TRange& range,
TFormatter&& formatter)
-{
+{
return TFormattableView<TRange, std::decay_t<TFormatter>>{range.begin(), range.end(), std::forward<TFormatter>(formatter)};
-}
-
-template <class TRange, class TFormatter>
+}
+
+template <class TRange, class TFormatter>
TFormattableView<TRange, TFormatter> MakeShrunkFormattableView(
const TRange& range,
TFormatter&& formatter,
size_t limit)
-{
+{
return TFormattableView<TRange, std::decay_t<TFormatter>>{range.begin(), range.end(), std::forward<TFormatter>(formatter), limit};
}
template <class TRange, class TFormatter>
-void FormatRange(TStringBuilderBase* builder, const TRange& range, const TFormatter& formatter, size_t limit = std::numeric_limits<size_t>::max())
+void FormatRange(TStringBuilderBase* builder, const TRange& range, const TFormatter& formatter, size_t limit = std::numeric_limits<size_t>::max())
{
- builder->AppendChar('[');
+ builder->AppendChar('[');
size_t index = 0;
- for (const auto& item : range) {
+ for (const auto& item : range) {
if (index > 0) {
- builder->AppendString(DefaultJoinToStringDelimiter);
- }
+ builder->AppendString(DefaultJoinToStringDelimiter);
+ }
if (index == limit) {
builder->AppendString(DefaultRangeEllipsisFormat);
break;
}
- formatter(builder, item);
+ formatter(builder, item);
++index;
- }
- builder->AppendChar(']');
-}
-
+ }
+ builder->AppendChar(']');
+}
+
template <class TRange, class TFormatter>
-void FormatKeyValueRange(TStringBuilderBase* builder, const TRange& range, const TFormatter& formatter, size_t limit = std::numeric_limits<size_t>::max())
+void FormatKeyValueRange(TStringBuilderBase* builder, const TRange& range, const TFormatter& formatter, size_t limit = std::numeric_limits<size_t>::max())
{
builder->AppendChar('{');
size_t index = 0;
@@ -259,44 +259,44 @@ void FormatKeyValueRange(TStringBuilderBase* builder, const TRange& range, const
}
// TFormattableView
-template <class TRange, class TFormatter>
+template <class TRange, class TFormatter>
struct TValueFormatter<TFormattableView<TRange, TFormatter>>
-{
- static void Do(TStringBuilderBase* builder, const TFormattableView<TRange, TFormatter>& range, TStringBuf /*format*/)
- {
+{
+ static void Do(TStringBuilderBase* builder, const TFormattableView<TRange, TFormatter>& range, TStringBuf /*format*/)
+ {
FormatRange(builder, range, range.Formatter, range.Limit);
- }
-};
-
-template <class TFormatter>
-TFormatterWrapper<TFormatter> MakeFormatterWrapper(
- TFormatter&& formatter)
-{
- return TFormatterWrapper<TFormatter>{
- .Formatter = std::move(formatter)
- };
-}
-
-// TFormatterWrapper
-template <class TFormatter>
-struct TValueFormatter<TFormatterWrapper<TFormatter>>
-{
- static void Do(TStringBuilderBase* builder, const TFormatterWrapper<TFormatter>& wrapper, TStringBuf /*format*/)
- {
- wrapper.Formatter(builder);
- }
-};
-
-// std::vector
+ }
+};
+
+template <class TFormatter>
+TFormatterWrapper<TFormatter> MakeFormatterWrapper(
+ TFormatter&& formatter)
+{
+ return TFormatterWrapper<TFormatter>{
+ .Formatter = std::move(formatter)
+ };
+}
+
+// TFormatterWrapper
+template <class TFormatter>
+struct TValueFormatter<TFormatterWrapper<TFormatter>>
+{
+ static void Do(TStringBuilderBase* builder, const TFormatterWrapper<TFormatter>& wrapper, TStringBuf /*format*/)
+ {
+ wrapper.Formatter(builder);
+ }
+};
+
+// std::vector
template <class T, class TAllocator>
struct TValueFormatter<std::vector<T, TAllocator>>
-{
+{
static void Do(TStringBuilderBase* builder, const std::vector<T, TAllocator>& collection, TStringBuf /*format*/)
- {
- FormatRange(builder, collection, TDefaultFormatter());
- }
-};
-
+ {
+ FormatRange(builder, collection, TDefaultFormatter());
+ }
+};
+
// TCompactVector
template <class T, unsigned N>
struct TValueFormatter<TCompactVector<T, N>>
@@ -307,21 +307,21 @@ struct TValueFormatter<TCompactVector<T, N>>
}
};
-// std::set
-template <class T>
-struct TValueFormatter<std::set<T>>
-{
- static void Do(TStringBuilderBase* builder, const std::set<T>& collection, TStringBuf /*format*/)
- {
- FormatRange(builder, collection, TDefaultFormatter());
- }
-};
-
+// std::set
+template <class T>
+struct TValueFormatter<std::set<T>>
+{
+ static void Do(TStringBuilderBase* builder, const std::set<T>& collection, TStringBuf /*format*/)
+ {
+ FormatRange(builder, collection, TDefaultFormatter());
+ }
+};
+
// std::map
template <class K, class V>
struct TValueFormatter<std::map<K, V>>
{
- static void Do(TStringBuilderBase* builder, const std::map<K, V>& collection, TStringBuf /*format*/)
+ static void Do(TStringBuilderBase* builder, const std::map<K, V>& collection, TStringBuf /*format*/)
{
FormatKeyValueRange(builder, collection, TDefaultFormatter());
}
@@ -331,37 +331,37 @@ struct TValueFormatter<std::map<K, V>>
template <class K, class V>
struct TValueFormatter<std::multimap<K, V>>
{
- static void Do(TStringBuilderBase* builder, const std::multimap<K, V>& collection, TStringBuf /*format*/)
+ static void Do(TStringBuilderBase* builder, const std::multimap<K, V>& collection, TStringBuf /*format*/)
{
FormatKeyValueRange(builder, collection, TDefaultFormatter());
}
};
// THashSet
-template <class T>
+template <class T>
struct TValueFormatter<THashSet<T>>
-{
- static void Do(TStringBuilderBase* builder, const THashSet<T>& collection, TStringBuf /*format*/)
- {
- FormatRange(builder, collection, TDefaultFormatter());
- }
-};
-
-// THashMultiSet
-template <class T>
-struct TValueFormatter<THashMultiSet<T>>
-{
- static void Do(TStringBuilderBase* builder, const THashMultiSet<T>& collection, TStringBuf /*format*/)
- {
- FormatRange(builder, collection, TDefaultFormatter());
- }
-};
-
+{
+ static void Do(TStringBuilderBase* builder, const THashSet<T>& collection, TStringBuf /*format*/)
+ {
+ FormatRange(builder, collection, TDefaultFormatter());
+ }
+};
+
+// THashMultiSet
+template <class T>
+struct TValueFormatter<THashMultiSet<T>>
+{
+ static void Do(TStringBuilderBase* builder, const THashMultiSet<T>& collection, TStringBuf /*format*/)
+ {
+ FormatRange(builder, collection, TDefaultFormatter());
+ }
+};
+
// THashMap
template <class K, class V>
struct TValueFormatter<THashMap<K, V>>
{
- static void Do(TStringBuilderBase* builder, const THashMap<K, V>& collection, TStringBuf /*format*/)
+ static void Do(TStringBuilderBase* builder, const THashMap<K, V>& collection, TStringBuf /*format*/)
{
FormatKeyValueRange(builder, collection, TDefaultFormatter());
}
@@ -371,7 +371,7 @@ struct TValueFormatter<THashMap<K, V>>
template <class K, class V>
struct TValueFormatter<THashMultiMap<K, V>>
{
- static void Do(TStringBuilderBase* builder, const THashMultiMap<K, V>& collection, TStringBuf /*format*/)
+ static void Do(TStringBuilderBase* builder, const THashMultiMap<K, V>& collection, TStringBuf /*format*/)
{
FormatKeyValueRange(builder, collection, TDefaultFormatter());
}
@@ -412,42 +412,42 @@ struct TValueFormatter<std::pair<T1, T2>>
}
};
-// std::optional
-inline void FormatValue(TStringBuilderBase* builder, std::nullopt_t, TStringBuf /*format*/)
-{
+// std::optional
+inline void FormatValue(TStringBuilderBase* builder, std::nullopt_t, TStringBuf /*format*/)
+{
builder->AppendString(TStringBuf("<null>"));
-}
-
-template <class T>
-struct TValueFormatter<std::optional<T>>
-{
- static void Do(TStringBuilderBase* builder, const std::optional<T>& value, TStringBuf format)
- {
- if (value) {
- FormatValue(builder, *value, format);
- } else {
- FormatValue(builder, std::nullopt, format);
- }
- }
-};
-
-template <class TValue>
-auto FormatValue(TStringBuilderBase* builder, const TValue& value, TStringBuf format) ->
- decltype(TValueFormatter<TValue>::Do(builder, value, format))
-{
- return TValueFormatter<TValue>::Do(builder, value, format);
-}
-
-template <class TValue>
+}
+
+template <class T>
+struct TValueFormatter<std::optional<T>>
+{
+ static void Do(TStringBuilderBase* builder, const std::optional<T>& value, TStringBuf format)
+ {
+ if (value) {
+ FormatValue(builder, *value, format);
+ } else {
+ FormatValue(builder, std::nullopt, format);
+ }
+ }
+};
+
+template <class TValue>
+auto FormatValue(TStringBuilderBase* builder, const TValue& value, TStringBuf format) ->
+ decltype(TValueFormatter<TValue>::Do(builder, value, format))
+{
+ return TValueFormatter<TValue>::Do(builder, value, format);
+}
+
+template <class TValue>
void FormatValueViaSprintf(
- TStringBuilderBase* builder,
+ TStringBuilderBase* builder,
TValue value,
- TStringBuf format,
- TStringBuf genericSpec)
-{
- constexpr int MaxFormatSize = 64;
- constexpr int SmallResultSize = 64;
-
+ TStringBuf format,
+ TStringBuf genericSpec)
+{
+ constexpr int MaxFormatSize = 64;
+ constexpr int SmallResultSize = 64;
+
auto copyFormat = [] (char* destination, const char* source, int length) {
int position = 0;
for (int index = 0; index < length; ++index) {
@@ -460,32 +460,32 @@ void FormatValueViaSprintf(
return destination + position;
};
- char formatBuf[MaxFormatSize];
- YT_VERIFY(format.length() >= 1 && format.length() <= MaxFormatSize - 2); // one for %, one for \0
- formatBuf[0] = '%';
- if (format[format.length() - 1] == GenericSpecSymbol) {
+ char formatBuf[MaxFormatSize];
+ YT_VERIFY(format.length() >= 1 && format.length() <= MaxFormatSize - 2); // one for %, one for \0
+ formatBuf[0] = '%';
+ if (format[format.length() - 1] == GenericSpecSymbol) {
char* formatEnd = copyFormat(formatBuf + 1, format.begin(), format.length() - 1);
- ::memcpy(formatEnd, genericSpec.begin(), genericSpec.length());
+ ::memcpy(formatEnd, genericSpec.begin(), genericSpec.length());
formatEnd[genericSpec.length()] = '\0';
- } else {
+ } else {
char* formatEnd = copyFormat(formatBuf + 1, format.begin(), format.length());
*formatEnd = '\0';
- }
-
+ }
+
char* result = builder->Preallocate(SmallResultSize);
- size_t resultSize = ::snprintf(result, SmallResultSize, formatBuf, value);
+ size_t resultSize = ::snprintf(result, SmallResultSize, formatBuf, value);
if (resultSize >= SmallResultSize) {
result = builder->Preallocate(resultSize + 1);
- YT_VERIFY(::snprintf(result, resultSize + 1, formatBuf, value) == static_cast<int>(resultSize));
+ YT_VERIFY(::snprintf(result, resultSize + 1, formatBuf, value) == static_cast<int>(resultSize));
}
- builder->Advance(resultSize);
-}
-
+ builder->Advance(resultSize);
+}
+
template <class TValue>
char* WriteIntToBufferBackwards(char* buffer, TValue value);
template <class TValue>
-void FormatValueViaHelper(TStringBuilderBase* builder, TValue value, TStringBuf format, TStringBuf genericSpec)
+void FormatValueViaHelper(TStringBuilderBase* builder, TValue value, TStringBuf format, TStringBuf genericSpec)
{
if (format == TStringBuf("v")) {
const int MaxResultSize = 64;
@@ -499,11 +499,11 @@ void FormatValueViaHelper(TStringBuilderBase* builder, TValue value, TStringBuf
}
#define XX(valueType, castType, genericSpec) \
- inline void FormatValue(TStringBuilderBase* builder, valueType value, TStringBuf format) \
- { \
+ inline void FormatValue(TStringBuilderBase* builder, valueType value, TStringBuf format) \
+ { \
FormatValueViaHelper(builder, static_cast<castType>(value), format, genericSpec); \
- }
-
+ }
+
XX(i8, int, TStringBuf("d"))
XX(ui8, unsigned int, TStringBuf("u"))
XX(i16, int, TStringBuf("d"))
@@ -512,11 +512,11 @@ XX(i32, int, TStringBuf("d"))
XX(ui32, unsigned int, TStringBuf("u"))
XX(long, long, TStringBuf("ld"))
XX(unsigned long, unsigned long, TStringBuf("lu"))
-
+
#undef XX
-
+
#define XX(valueType, castType, genericSpec) \
- inline void FormatValue(TStringBuilderBase* builder, valueType value, TStringBuf format) \
+ inline void FormatValue(TStringBuilderBase* builder, valueType value, TStringBuf format) \
{ \
FormatValueViaSprintf(builder, static_cast<castType>(value), format, genericSpec); \
}
@@ -526,219 +526,219 @@ XX(float, float, TStringBuf("f"))
#undef XX
-// Pointer
+// Pointer
template <class T>
-void FormatValue(TStringBuilderBase* builder, T* value, TStringBuf format)
+void FormatValue(TStringBuilderBase* builder, T* value, TStringBuf format)
{
FormatValueViaSprintf(builder, value, format, TStringBuf("p"));
}
// TDuration (specialize for performance reasons)
-inline void FormatValue(TStringBuilderBase* builder, TDuration value, TStringBuf /*format*/)
+inline void FormatValue(TStringBuilderBase* builder, TDuration value, TStringBuf /*format*/)
+{
+ builder->AppendFormat("%vus", value.MicroSeconds());
+}
+
+// TInstant (specialize for TFormatTraits)
+inline void FormatValue(TStringBuilderBase* builder, TInstant value, TStringBuf format)
{
- builder->AppendFormat("%vus", value.MicroSeconds());
+ // TODO(babenko): optimize
+ builder->AppendFormat("%v", ToString(value), format);
}
-// TInstant (specialize for TFormatTraits)
-inline void FormatValue(TStringBuilderBase* builder, TInstant value, TStringBuf format)
-{
- // TODO(babenko): optimize
- builder->AppendFormat("%v", ToString(value), format);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class TArgFormatter>
-void FormatImpl(
- TStringBuilderBase* builder,
- TStringBuf format,
- const TArgFormatter& argFormatter)
-{
- size_t argIndex = 0;
- auto current = format.begin();
- while (true) {
- // Scan verbatim part until stop symbol.
- auto verbatimBegin = current;
- auto verbatimEnd = verbatimBegin;
- while (verbatimEnd != format.end() && *verbatimEnd != '%') {
- ++verbatimEnd;
- }
-
- // Copy verbatim part, if any.
- size_t verbatimSize = verbatimEnd - verbatimBegin;
- if (verbatimSize > 0) {
- builder->AppendString(TStringBuf(verbatimBegin, verbatimSize));
- }
-
- // Handle stop symbol.
- current = verbatimEnd;
- if (current == format.end()) {
- break;
- }
-
- YT_ASSERT(*current == '%');
- ++current;
-
- if (*current == '%') {
- // Verbatim %.
- builder->AppendChar('%');
- ++current;
- } else {
- // Scan format part until stop symbol.
- auto argFormatBegin = current;
- auto argFormatEnd = argFormatBegin;
+////////////////////////////////////////////////////////////////////////////////
+
+template <class TArgFormatter>
+void FormatImpl(
+ TStringBuilderBase* builder,
+ TStringBuf format,
+ const TArgFormatter& argFormatter)
+{
+ size_t argIndex = 0;
+ auto current = format.begin();
+ while (true) {
+ // Scan verbatim part until stop symbol.
+ auto verbatimBegin = current;
+ auto verbatimEnd = verbatimBegin;
+ while (verbatimEnd != format.end() && *verbatimEnd != '%') {
+ ++verbatimEnd;
+ }
+
+ // Copy verbatim part, if any.
+ size_t verbatimSize = verbatimEnd - verbatimBegin;
+ if (verbatimSize > 0) {
+ builder->AppendString(TStringBuf(verbatimBegin, verbatimSize));
+ }
+
+ // Handle stop symbol.
+ current = verbatimEnd;
+ if (current == format.end()) {
+ break;
+ }
+
+ YT_ASSERT(*current == '%');
+ ++current;
+
+ if (*current == '%') {
+ // Verbatim %.
+ builder->AppendChar('%');
+ ++current;
+ } else {
+ // Scan format part until stop symbol.
+ auto argFormatBegin = current;
+ auto argFormatEnd = argFormatBegin;
bool singleQuotes = false;
bool doubleQuotes = false;
- while (
- argFormatEnd != format.end() &&
- *argFormatEnd != GenericSpecSymbol && // value in generic format
- *argFormatEnd != 'd' && // others are standard specifiers supported by printf
- *argFormatEnd != 'i' &&
- *argFormatEnd != 'u' &&
- *argFormatEnd != 'o' &&
- *argFormatEnd != 'x' &&
- *argFormatEnd != 'X' &&
- *argFormatEnd != 'f' &&
- *argFormatEnd != 'F' &&
- *argFormatEnd != 'e' &&
- *argFormatEnd != 'E' &&
- *argFormatEnd != 'g' &&
- *argFormatEnd != 'G' &&
- *argFormatEnd != 'a' &&
- *argFormatEnd != 'A' &&
- *argFormatEnd != 'c' &&
- *argFormatEnd != 's' &&
- *argFormatEnd != 'p' &&
- *argFormatEnd != 'n')
- {
+ while (
+ argFormatEnd != format.end() &&
+ *argFormatEnd != GenericSpecSymbol && // value in generic format
+ *argFormatEnd != 'd' && // others are standard specifiers supported by printf
+ *argFormatEnd != 'i' &&
+ *argFormatEnd != 'u' &&
+ *argFormatEnd != 'o' &&
+ *argFormatEnd != 'x' &&
+ *argFormatEnd != 'X' &&
+ *argFormatEnd != 'f' &&
+ *argFormatEnd != 'F' &&
+ *argFormatEnd != 'e' &&
+ *argFormatEnd != 'E' &&
+ *argFormatEnd != 'g' &&
+ *argFormatEnd != 'G' &&
+ *argFormatEnd != 'a' &&
+ *argFormatEnd != 'A' &&
+ *argFormatEnd != 'c' &&
+ *argFormatEnd != 's' &&
+ *argFormatEnd != 'p' &&
+ *argFormatEnd != 'n')
+ {
if (*argFormatEnd == 'q') {
singleQuotes = true;
} else if (*argFormatEnd == 'Q') {
doubleQuotes = true;
}
- ++argFormatEnd;
- }
-
- // Handle end of format string.
- if (argFormatEnd != format.end()) {
- ++argFormatEnd;
- }
-
- // 'n' means 'nothing'; skip the argument.
- if (*argFormatBegin != 'n') {
- // Format argument.
- TStringBuf argFormat(argFormatBegin, argFormatEnd);
- if (singleQuotes) {
- builder->AppendChar('\'');
- }
- if (doubleQuotes) {
- builder->AppendChar('"');
- }
- argFormatter(argIndex++, builder, argFormat);
- if (singleQuotes) {
- builder->AppendChar('\'');
- }
- if (doubleQuotes) {
- builder->AppendChar('"');
- }
- }
-
- current = argFormatEnd;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class T>
-struct TFormatTraits
-{
- static constexpr bool HasCustomFormatValue = !std::is_same_v<
- decltype(FormatValue(
- static_cast<TStringBuilderBase*>(nullptr),
- *static_cast<const T*>(nullptr),
- TStringBuf())),
- TToStringFallbackValueFormatterTag>;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <size_t IndexBase, class... TArgs>
-struct TArgFormatterImpl;
-
-template <size_t IndexBase>
-struct TArgFormatterImpl<IndexBase>
-{
- void operator() (size_t /*index*/, TStringBuilderBase* builder, TStringBuf /*format*/) const
- {
+ ++argFormatEnd;
+ }
+
+ // Handle end of format string.
+ if (argFormatEnd != format.end()) {
+ ++argFormatEnd;
+ }
+
+ // 'n' means 'nothing'; skip the argument.
+ if (*argFormatBegin != 'n') {
+ // Format argument.
+ TStringBuf argFormat(argFormatBegin, argFormatEnd);
+ if (singleQuotes) {
+ builder->AppendChar('\'');
+ }
+ if (doubleQuotes) {
+ builder->AppendChar('"');
+ }
+ argFormatter(argIndex++, builder, argFormat);
+ if (singleQuotes) {
+ builder->AppendChar('\'');
+ }
+ if (doubleQuotes) {
+ builder->AppendChar('"');
+ }
+ }
+
+ current = argFormatEnd;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T>
+struct TFormatTraits
+{
+ static constexpr bool HasCustomFormatValue = !std::is_same_v<
+ decltype(FormatValue(
+ static_cast<TStringBuilderBase*>(nullptr),
+ *static_cast<const T*>(nullptr),
+ TStringBuf())),
+ TToStringFallbackValueFormatterTag>;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <size_t IndexBase, class... TArgs>
+struct TArgFormatterImpl;
+
+template <size_t IndexBase>
+struct TArgFormatterImpl<IndexBase>
+{
+ void operator() (size_t /*index*/, TStringBuilderBase* builder, TStringBuf /*format*/) const
+ {
builder->AppendString(TStringBuf("<missing argument>"));
- }
-};
-
-template <size_t IndexBase, class THeadArg, class... TTailArgs>
-struct TArgFormatterImpl<IndexBase, THeadArg, TTailArgs...>
-{
- explicit TArgFormatterImpl(const THeadArg& headArg, const TTailArgs&... tailArgs)
- : HeadArg(headArg)
- , TailFormatter(tailArgs...)
- { }
-
- const THeadArg& HeadArg;
- TArgFormatterImpl<IndexBase + 1, TTailArgs...> TailFormatter;
-
- void operator() (size_t index, TStringBuilderBase* builder, TStringBuf format) const
- {
- YT_ASSERT(index >= IndexBase);
- if (index == IndexBase) {
- FormatValue(builder, HeadArg, format);
- } else {
- TailFormatter(index, builder, format);
- }
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <size_t Length, class... TArgs>
-void Format(
- TStringBuilderBase* builder,
- const char (&format)[Length],
- TArgs&&... args)
-{
- Format(builder, TStringBuf(format, Length - 1), std::forward<TArgs>(args)...);
-}
-
-template <class... TArgs>
-void Format(
- TStringBuilderBase* builder,
- TStringBuf format,
- TArgs&&... args)
-{
- TArgFormatterImpl<0, TArgs...> argFormatter(args...);
- FormatImpl(builder, format, argFormatter);
-}
-
-template <size_t Length, class... TArgs>
-TString Format(
- const char (&format)[Length],
- TArgs&&... args)
-{
- TStringBuilder builder;
- Format(&builder, format, std::forward<TArgs>(args)...);
- return builder.Flush();
-}
-
-template <class... TArgs>
+ }
+};
+
+template <size_t IndexBase, class THeadArg, class... TTailArgs>
+struct TArgFormatterImpl<IndexBase, THeadArg, TTailArgs...>
+{
+ explicit TArgFormatterImpl(const THeadArg& headArg, const TTailArgs&... tailArgs)
+ : HeadArg(headArg)
+ , TailFormatter(tailArgs...)
+ { }
+
+ const THeadArg& HeadArg;
+ TArgFormatterImpl<IndexBase + 1, TTailArgs...> TailFormatter;
+
+ void operator() (size_t index, TStringBuilderBase* builder, TStringBuf format) const
+ {
+ YT_ASSERT(index >= IndexBase);
+ if (index == IndexBase) {
+ FormatValue(builder, HeadArg, format);
+ } else {
+ TailFormatter(index, builder, format);
+ }
+ }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <size_t Length, class... TArgs>
+void Format(
+ TStringBuilderBase* builder,
+ const char (&format)[Length],
+ TArgs&&... args)
+{
+ Format(builder, TStringBuf(format, Length - 1), std::forward<TArgs>(args)...);
+}
+
+template <class... TArgs>
+void Format(
+ TStringBuilderBase* builder,
+ TStringBuf format,
+ TArgs&&... args)
+{
+ TArgFormatterImpl<0, TArgs...> argFormatter(args...);
+ FormatImpl(builder, format, argFormatter);
+}
+
+template <size_t Length, class... TArgs>
+TString Format(
+ const char (&format)[Length],
+ TArgs&&... args)
+{
+ TStringBuilder builder;
+ Format(&builder, format, std::forward<TArgs>(args)...);
+ return builder.Flush();
+}
+
+template <class... TArgs>
TString Format(
- TStringBuf format,
- TArgs&&... args)
-{
- TStringBuilder builder;
- Format(&builder, format, std::forward<TArgs>(args)...);
- return builder.Flush();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
+ TStringBuf format,
+ TArgs&&... args)
+{
+ TStringBuilder builder;
+ Format(&builder, format, std::forward<TArgs>(args)...);
+ return builder.Flush();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/string/format.h b/library/cpp/yt/string/format.h
index 956682b3d7..9708fe5906 100644
--- a/library/cpp/yt/string/format.h
+++ b/library/cpp/yt/string/format.h
@@ -1,92 +1,92 @@
-#pragma once
-
-#include "string_builder.h"
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-/*
- * Format: a type-safe and fast formatting utility.
- *
- * Basically works as a type-safe analogue of |sprintf| and is expected to
- * be backwards-compatible with the latter.
+#pragma once
+
+#include "string_builder.h"
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+/*
+ * Format: a type-safe and fast formatting utility.
+ *
+ * Basically works as a type-safe analogue of |sprintf| and is expected to
+ * be backwards-compatible with the latter.
*
- * Like Go's |Sprintf|, supports the ultimate format specifier |v|
- * causing arguments to be emitted in default format.
- * This is the default and preferred way of formatting things,
- * which should be used in newer code.
+ * Like Go's |Sprintf|, supports the ultimate format specifier |v|
+ * causing arguments to be emitted in default format.
+ * This is the default and preferred way of formatting things,
+ * which should be used in newer code.
*
- * |Format| may currently invoke |sprintf| internally for emitting numeric and some other
- * types. You can always write your own optimized implementation, if you wish :)
+ * |Format| may currently invoke |sprintf| internally for emitting numeric and some other
+ * types. You can always write your own optimized implementation, if you wish :)
*
- * In additional to the usual |sprintf|, supports a number of non-standard flags:
+ * In additional to the usual |sprintf|, supports a number of non-standard flags:
*
- * |q| Causes the argument to be surrounded with single quotes (|'|).
- * Applies to all types.
+ * |q| Causes the argument to be surrounded with single quotes (|'|).
+ * Applies to all types.
*
- * |Q| Causes the argument to be surrounded with double quotes (|"|).
- * Applies to all types.
+ * |Q| Causes the argument to be surrounded with double quotes (|"|).
+ * Applies to all types.
*
- * |l| The argument is emitted in "lowercase" style.
- * Only applies to enums and bools.
+ * |l| The argument is emitted in "lowercase" style.
+ * Only applies to enums and bools.
*
- * The following argument types are supported:
+ * The following argument types are supported:
*
* Strings (including |const char*|, |TStringBuf|, and |TString|) and chars:
- * Emitted as is. Fast.
+ * Emitted as is. Fast.
*
- * Numerics and pointers:
- * Emitted using |sprintf|. Maybe not that fast.
+ * Numerics and pointers:
+ * Emitted using |sprintf|. Maybe not that fast.
*
- * |bool|:
- * Emitted either as |True| and |False| or |true| and |false| (if lowercase mode is ON).
+ * |bool|:
+ * Emitted either as |True| and |False| or |true| and |false| (if lowercase mode is ON).
*
- * Enums:
- * Emitted in either camel (|SomeName|) or in lowercase-with-underscores style
- * (|some_name|, if lowercase mode is ON).
+ * Enums:
+ * Emitted in either camel (|SomeName|) or in lowercase-with-underscores style
+ * (|some_name|, if lowercase mode is ON).
*
- * Nullables:
- * |std::nullopt| is emitted as |<null>|.
+ * Nullables:
+ * |std::nullopt| is emitted as |<null>|.
*
- * All others:
- * Emitted as strings by calling |ToString|.
- *
- */
-
-template <size_t Length, class... TArgs>
-void Format(TStringBuilderBase* builder, const char (&format)[Length], TArgs&&... args);
-template <class... TArgs>
-void Format(TStringBuilderBase* builder, TStringBuf format, TArgs&&... args);
-
-template <size_t Length, class... TArgs>
-TString Format(const char (&format)[Length], TArgs&&... args);
-template <class... TArgs>
-TString Format(TStringBuf format, TArgs&&... args);
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class TRange, class TFormatter>
+ * All others:
+ * Emitted as strings by calling |ToString|.
+ *
+ */
+
+template <size_t Length, class... TArgs>
+void Format(TStringBuilderBase* builder, const char (&format)[Length], TArgs&&... args);
+template <class... TArgs>
+void Format(TStringBuilderBase* builder, TStringBuf format, TArgs&&... args);
+
+template <size_t Length, class... TArgs>
+TString Format(const char (&format)[Length], TArgs&&... args);
+template <class... TArgs>
+TString Format(TStringBuf format, TArgs&&... args);
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class TRange, class TFormatter>
struct TFormattableView
-{
+{
using TBegin = std::decay_t<decltype(std::declval<const TRange>().begin())>;
using TEnd = std::decay_t<decltype(std::declval<const TRange>().end())>;
TBegin RangeBegin;
TEnd RangeEnd;
- TFormatter Formatter;
+ TFormatter Formatter;
size_t Limit = std::numeric_limits<size_t>::max();
TBegin begin() const;
TEnd end() const;
-};
-
-//! Annotates a given #range with #formatter to be applied to each item.
-template <class TRange, class TFormatter>
+};
+
+//! Annotates a given #range with #formatter to be applied to each item.
+template <class TRange, class TFormatter>
TFormattableView<TRange, TFormatter> MakeFormattableView(
- const TRange& range,
+ const TRange& range,
TFormatter&& formatter);
-
+
template <class TRange, class TFormatter>
TFormattableView<TRange, TFormatter> MakeShrunkFormattableView(
const TRange& range,
@@ -95,20 +95,20 @@ TFormattableView<TRange, TFormatter> MakeShrunkFormattableView(
////////////////////////////////////////////////////////////////////////////////
-template <class TFormatter>
-struct TFormatterWrapper
-{
- TFormatter Formatter;
-};
-
-template <class TFormatter>
-TFormatterWrapper<TFormatter> MakeFormatterWrapper(
- TFormatter&& formatter);
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
-
-#define FORMAT_INL_H_
-#include "format-inl.h"
-#undef FORMAT_INL_H_
+template <class TFormatter>
+struct TFormatterWrapper
+{
+ TFormatter Formatter;
+};
+
+template <class TFormatter>
+TFormatterWrapper<TFormatter> MakeFormatterWrapper(
+ TFormatter&& formatter);
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
+
+#define FORMAT_INL_H_
+#include "format-inl.h"
+#undef FORMAT_INL_H_
diff --git a/library/cpp/yt/string/guid.cpp b/library/cpp/yt/string/guid.cpp
index 1d87478c7b..6c133a9778 100644
--- a/library/cpp/yt/string/guid.cpp
+++ b/library/cpp/yt/string/guid.cpp
@@ -6,7 +6,7 @@ namespace NYT {
void FormatValue(TStringBuilderBase* builder, TGuid value, TStringBuf /*format*/)
{
- char* begin = builder->Preallocate(MaxGuidStringSize);
+ char* begin = builder->Preallocate(MaxGuidStringSize);
char* end = WriteGuidToBuffer(begin, value);
builder->Advance(end - begin);
}
diff --git a/library/cpp/yt/string/string.cpp b/library/cpp/yt/string/string.cpp
index 683c46ab2f..7440ac3fdd 100644
--- a/library/cpp/yt/string/string.cpp
+++ b/library/cpp/yt/string/string.cpp
@@ -1,78 +1,78 @@
-#include "string.h"
+#include "string.h"
#include "format.h"
-
-#include <library/cpp/yt/assert/assert.h>
+
+#include <library/cpp/yt/assert/assert.h>
#include <util/generic/hash.h>
-#include <util/string/ascii.h>
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-void UnderscoreCaseToCamelCase(TStringBuilderBase* builder, TStringBuf str)
-{
+#include <util/string/ascii.h>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+void UnderscoreCaseToCamelCase(TStringBuilderBase* builder, TStringBuf str)
+{
bool first = true;
- bool upper = true;
- for (char c : str) {
- if (c == '_') {
- upper = true;
- } else {
- if (upper) {
+ bool upper = true;
+ for (char c : str) {
+ if (c == '_') {
+ upper = true;
+ } else {
+ if (upper) {
if (!std::isalpha(c) && !first) {
- builder->AppendChar('_');
+ builder->AppendChar('_');
}
- c = std::toupper(c);
- }
- builder->AppendChar(c);
- upper = false;
- }
+ c = std::toupper(c);
+ }
+ builder->AppendChar(c);
+ upper = false;
+ }
first = false;
- }
-}
-
-TString UnderscoreCaseToCamelCase(TStringBuf str)
-{
- TStringBuilder builder;
- UnderscoreCaseToCamelCase(&builder, str);
- return builder.Flush();
-}
-
-void CamelCaseToUnderscoreCase(TStringBuilderBase* builder, TStringBuf str)
-{
- bool first = true;
- for (char c : str) {
+ }
+}
+
+TString UnderscoreCaseToCamelCase(TStringBuf str)
+{
+ TStringBuilder builder;
+ UnderscoreCaseToCamelCase(&builder, str);
+ return builder.Flush();
+}
+
+void CamelCaseToUnderscoreCase(TStringBuilderBase* builder, TStringBuf str)
+{
+ bool first = true;
+ for (char c : str) {
if (std::isupper(c) && std::isalpha(c)) {
- if (!first) {
- builder->AppendChar('_');
- }
+ if (!first) {
+ builder->AppendChar('_');
+ }
c = std::tolower(c);
- }
- builder->AppendChar(c);
- first = false;
- }
-}
-
-TString CamelCaseToUnderscoreCase(TStringBuf str)
-{
- TStringBuilder builder;
- CamelCaseToUnderscoreCase(&builder, str);
- return builder.Flush();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
+ }
+ builder->AppendChar(c);
+ first = false;
+ }
+}
+
+TString CamelCaseToUnderscoreCase(TStringBuf str)
+{
+ TStringBuilder builder;
+ CamelCaseToUnderscoreCase(&builder, str);
+ return builder.Flush();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
TString TrimLeadingWhitespaces(const TString& str)
-{
+{
for (int i = 0; i < static_cast<int>(str.size()); ++i) {
- if (str[i] != ' ') {
- return str.substr(i);
- }
- }
- return "";
-}
-
+ if (str[i] != ' ') {
+ return str.substr(i);
+ }
+ }
+ return "";
+}
+
TString Trim(const TString& str, const TString& whitespaces)
{
size_t end = str.size();
@@ -96,13 +96,13 @@ TString Trim(const TString& str, const TString& whitespaces)
}
size_t begin = str.find_first_not_of(whitespaces);
- YT_VERIFY(begin != TString::npos);
- YT_VERIFY(begin < end);
+ YT_VERIFY(begin != TString::npos);
+ YT_VERIFY(begin < end);
return str.substr(begin, end - begin);
}
-////////////////////////////////////////////////////////////////////////////////
-
+////////////////////////////////////////////////////////////////////////////////
+
namespace {
ui16 DecimalDigits2[100] = {
@@ -119,7 +119,7 @@ ui16 DecimalDigits2[100] = {
};
template <class T>
-char* WriteSignedIntToBufferBackwardsImpl(char* ptr, T value, TStringBuf min)
+char* WriteSignedIntToBufferBackwardsImpl(char* ptr, T value, TStringBuf min)
{
if (value == 0) {
--ptr;
@@ -214,50 +214,50 @@ char* WriteIntToBufferBackwards(char* ptr, ui64 value)
////////////////////////////////////////////////////////////////////////////////
-size_t TCaseInsensitiveStringHasher::operator()(TStringBuf arg) const
-{
- auto compute = [&] (char* buffer) {
- for (size_t index = 0; index < arg.length(); ++index) {
- buffer[index] = AsciiToLower(arg[index]);
- }
+size_t TCaseInsensitiveStringHasher::operator()(TStringBuf arg) const
+{
+ auto compute = [&] (char* buffer) {
+ for (size_t index = 0; index < arg.length(); ++index) {
+ buffer[index] = AsciiToLower(arg[index]);
+ }
return ComputeHash(TStringBuf(buffer, arg.length()));
- };
- const size_t SmallSize = 256;
- if (arg.length() <= SmallSize) {
- std::array<char, SmallSize> stackBuffer;
- return compute(stackBuffer.data());
- } else {
- std::unique_ptr<char[]> heapBuffer(new char[arg.length()]);
- return compute(heapBuffer.get());
- }
-}
-
-bool TCaseInsensitiveStringEqualityComparer::operator()(TStringBuf lhs, TStringBuf rhs) const
-{
- return AsciiEqualsIgnoreCase(lhs, rhs);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-bool TryParseBool(TStringBuf value, bool* result)
+ };
+ const size_t SmallSize = 256;
+ if (arg.length() <= SmallSize) {
+ std::array<char, SmallSize> stackBuffer;
+ return compute(stackBuffer.data());
+ } else {
+ std::unique_ptr<char[]> heapBuffer(new char[arg.length()]);
+ return compute(heapBuffer.get());
+ }
+}
+
+bool TCaseInsensitiveStringEqualityComparer::operator()(TStringBuf lhs, TStringBuf rhs) const
+{
+ return AsciiEqualsIgnoreCase(lhs, rhs);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+bool TryParseBool(TStringBuf value, bool* result)
{
if (value == "true" || value == "1") {
- *result = true;
+ *result = true;
return true;
} else if (value == "false" || value == "0") {
- *result = false;
+ *result = false;
return true;
} else {
return false;
}
}
-bool ParseBool(TStringBuf value)
+bool ParseBool(TStringBuf value)
{
bool result;
- if (!TryParseBool(value, &result)) {
- throw TSimpleException(Format("Error parsing boolean value %Qv",
- value));
+ if (!TryParseBool(value, &result)) {
+ throw TSimpleException(Format("Error parsing boolean value %Qv",
+ value));
}
return result;
}
@@ -269,4 +269,4 @@ TStringBuf FormatBool(bool value)
////////////////////////////////////////////////////////////////////////////////
-} // namespace NYT
+} // namespace NYT
diff --git a/library/cpp/yt/string/string.h b/library/cpp/yt/string/string.h
index 92c7a2f472..ae6c99caab 100644
--- a/library/cpp/yt/string/string.h
+++ b/library/cpp/yt/string/string.h
@@ -1,9 +1,9 @@
-#pragma once
-
-#include "string_builder.h"
-
-#include <library/cpp/yt/exception/exception.h>
-
+#pragma once
+
+#include "string_builder.h"
+
+#include <library/cpp/yt/exception/exception.h>
+
#include <util/datetime/base.h>
#include <util/generic/string.h>
@@ -14,184 +14,184 @@
#include <set>
#include <map>
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-//! Formatters enable customizable way to turn an object into a string.
-//! This default implementation uses |FormatValue|.
-struct TDefaultFormatter
-{
- template <class T>
- void operator()(TStringBuilderBase* builder, const T& obj) const
- {
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+//! Formatters enable customizable way to turn an object into a string.
+//! This default implementation uses |FormatValue|.
+struct TDefaultFormatter
+{
+ template <class T>
+ void operator()(TStringBuilderBase* builder, const T& obj) const
+ {
FormatValue(builder, obj, TStringBuf("v"));
- }
-};
-
+ }
+};
+
static constexpr TStringBuf DefaultJoinToStringDelimiter = ", ";
static constexpr TStringBuf DefaultKeyValueDelimiter = ": ";
static constexpr TStringBuf DefaultRangeEllipsisFormat = "...";
-
+
// ASCII characters from 0x20 = ' ' to 0x7e = '~' are printable.
static constexpr char PrintableASCIILow = 0x20;
static constexpr char PrintableASCIIHigh = 0x7e;
static constexpr TStringBuf Int2Hex = "0123456789abcdef";
-//! Joins a range of items into a string intermixing them with the delimiter.
-/*!
- * \param builder String builder where the output goes.
- * \param begin Iterator pointing to the first item (inclusive).
- * \param end Iterator pointing to the last item (not inclusive).
- * \param formatter Formatter to apply to the items.
- * \param delimiter A delimiter to be inserted between items: ", " by default.
- * \return The resulting combined string.
- */
-template <class TIterator, class TFormatter>
-void JoinToString(
- TStringBuilderBase* builder,
- const TIterator& begin,
- const TIterator& end,
- const TFormatter& formatter,
- TStringBuf delimiter = DefaultJoinToStringDelimiter)
-{
- for (auto current = begin; current != end; ++current) {
- if (current != begin) {
- builder->AppendString(delimiter);
- }
- formatter(builder, *current);
- }
-}
-
-template <class TIterator, class TFormatter>
+//! Joins a range of items into a string intermixing them with the delimiter.
+/*!
+ * \param builder String builder where the output goes.
+ * \param begin Iterator pointing to the first item (inclusive).
+ * \param end Iterator pointing to the last item (not inclusive).
+ * \param formatter Formatter to apply to the items.
+ * \param delimiter A delimiter to be inserted between items: ", " by default.
+ * \return The resulting combined string.
+ */
+template <class TIterator, class TFormatter>
+void JoinToString(
+ TStringBuilderBase* builder,
+ const TIterator& begin,
+ const TIterator& end,
+ const TFormatter& formatter,
+ TStringBuf delimiter = DefaultJoinToStringDelimiter)
+{
+ for (auto current = begin; current != end; ++current) {
+ if (current != begin) {
+ builder->AppendString(delimiter);
+ }
+ formatter(builder, *current);
+ }
+}
+
+template <class TIterator, class TFormatter>
TString JoinToString(
- const TIterator& begin,
- const TIterator& end,
- const TFormatter& formatter,
- TStringBuf delimiter = DefaultJoinToStringDelimiter)
-{
- TStringBuilder builder;
- JoinToString(&builder, begin, end, formatter, delimiter);
- return builder.Flush();
-}
-
-//! A handy shortcut with default formatter.
-template <class TIterator>
+ const TIterator& begin,
+ const TIterator& end,
+ const TFormatter& formatter,
+ TStringBuf delimiter = DefaultJoinToStringDelimiter)
+{
+ TStringBuilder builder;
+ JoinToString(&builder, begin, end, formatter, delimiter);
+ return builder.Flush();
+}
+
+//! A handy shortcut with default formatter.
+template <class TIterator>
TString JoinToString(
- const TIterator& begin,
- const TIterator& end,
- TStringBuf delimiter = DefaultJoinToStringDelimiter)
-{
- return JoinToString(begin, end, TDefaultFormatter(), delimiter);
-}
-
-//! Joins a collection of given items into a string intermixing them with the delimiter.
-/*!
- * \param collection A collection containing the items to be joined.
- * \param formatter Formatter to apply to the items.
- * \param delimiter A delimiter to be inserted between items; ", " by default.
- */
-template <class TCollection, class TFormatter>
+ const TIterator& begin,
+ const TIterator& end,
+ TStringBuf delimiter = DefaultJoinToStringDelimiter)
+{
+ return JoinToString(begin, end, TDefaultFormatter(), delimiter);
+}
+
+//! Joins a collection of given items into a string intermixing them with the delimiter.
+/*!
+ * \param collection A collection containing the items to be joined.
+ * \param formatter Formatter to apply to the items.
+ * \param delimiter A delimiter to be inserted between items; ", " by default.
+ */
+template <class TCollection, class TFormatter>
TString JoinToString(
- const TCollection& collection,
- const TFormatter& formatter,
- TStringBuf delimiter = DefaultJoinToStringDelimiter)
-{
+ const TCollection& collection,
+ const TFormatter& formatter,
+ TStringBuf delimiter = DefaultJoinToStringDelimiter)
+{
using std::begin;
using std::end;
- return JoinToString(begin(collection), end(collection), formatter, delimiter);
-}
-
-//! A handy shortcut with the default formatter.
-template <class TCollection>
+ return JoinToString(begin(collection), end(collection), formatter, delimiter);
+}
+
+//! A handy shortcut with the default formatter.
+template <class TCollection>
TString JoinToString(
- const TCollection& collection,
- TStringBuf delimiter = DefaultJoinToStringDelimiter)
-{
- return JoinToString(collection, TDefaultFormatter(), delimiter);
-}
-
-//! Concatenates a bunch of TStringBuf-like instances into TString.
-template <class... Ts>
-TString ConcatToString(Ts... args)
-{
- size_t length = 0;
- ((length += args.length()), ...);
-
- TString result;
- result.reserve(length);
- (result.append(args), ...);
-
- return result;
-}
-
-//! Converts a range of items into strings.
-template <class TIter, class TFormatter>
+ const TCollection& collection,
+ TStringBuf delimiter = DefaultJoinToStringDelimiter)
+{
+ return JoinToString(collection, TDefaultFormatter(), delimiter);
+}
+
+//! Concatenates a bunch of TStringBuf-like instances into TString.
+template <class... Ts>
+TString ConcatToString(Ts... args)
+{
+ size_t length = 0;
+ ((length += args.length()), ...);
+
+ TString result;
+ result.reserve(length);
+ (result.append(args), ...);
+
+ return result;
+}
+
+//! Converts a range of items into strings.
+template <class TIter, class TFormatter>
std::vector<TString> ConvertToStrings(
- const TIter& begin,
- const TIter& end,
- const TFormatter& formatter,
- size_t maxSize = std::numeric_limits<size_t>::max())
-{
+ const TIter& begin,
+ const TIter& end,
+ const TFormatter& formatter,
+ size_t maxSize = std::numeric_limits<size_t>::max())
+{
std::vector<TString> result;
- for (auto it = begin; it != end; ++it) {
- TStringBuilder builder;
- formatter(&builder, *it);
- result.push_back(builder.Flush());
- if (result.size() == maxSize) {
- break;
- }
- }
- return result;
-}
-
-//! A handy shortcut with the default formatter.
-template <class TIter>
+ for (auto it = begin; it != end; ++it) {
+ TStringBuilder builder;
+ formatter(&builder, *it);
+ result.push_back(builder.Flush());
+ if (result.size() == maxSize) {
+ break;
+ }
+ }
+ return result;
+}
+
+//! A handy shortcut with the default formatter.
+template <class TIter>
std::vector<TString> ConvertToStrings(
- const TIter& begin,
- const TIter& end,
- size_t maxSize = std::numeric_limits<size_t>::max())
-{
- return ConvertToStrings(begin, end, TDefaultFormatter(), maxSize);
-}
-
-//! Converts a given collection of items into strings.
-/*!
- * \param collection A collection containing the items to be converted.
- * \param formatter Formatter to apply to the items.
- * \param maxSize Size limit for the resulting vector.
- */
-template <class TCollection, class TFormatter>
+ const TIter& begin,
+ const TIter& end,
+ size_t maxSize = std::numeric_limits<size_t>::max())
+{
+ return ConvertToStrings(begin, end, TDefaultFormatter(), maxSize);
+}
+
+//! Converts a given collection of items into strings.
+/*!
+ * \param collection A collection containing the items to be converted.
+ * \param formatter Formatter to apply to the items.
+ * \param maxSize Size limit for the resulting vector.
+ */
+template <class TCollection, class TFormatter>
std::vector<TString> ConvertToStrings(
- const TCollection& collection,
- const TFormatter& formatter,
- size_t maxSize = std::numeric_limits<size_t>::max())
-{
+ const TCollection& collection,
+ const TFormatter& formatter,
+ size_t maxSize = std::numeric_limits<size_t>::max())
+{
using std::begin;
using std::end;
return ConvertToStrings(begin(collection), end(collection), formatter, maxSize);
-}
-
-//! A handy shortcut with default formatter.
-template <class TCollection>
+}
+
+//! A handy shortcut with default formatter.
+template <class TCollection>
std::vector<TString> ConvertToStrings(
- const TCollection& collection,
- size_t maxSize = std::numeric_limits<size_t>::max())
-{
- return ConvertToStrings(collection, TDefaultFormatter(), maxSize);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-void UnderscoreCaseToCamelCase(TStringBuilderBase* builder, TStringBuf str);
-TString UnderscoreCaseToCamelCase(TStringBuf str);
-
-void CamelCaseToUnderscoreCase(TStringBuilderBase* builder, TStringBuf str);
-TString CamelCaseToUnderscoreCase(TStringBuf str);
+ const TCollection& collection,
+ size_t maxSize = std::numeric_limits<size_t>::max())
+{
+ return ConvertToStrings(collection, TDefaultFormatter(), maxSize);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void UnderscoreCaseToCamelCase(TStringBuilderBase* builder, TStringBuf str);
+TString UnderscoreCaseToCamelCase(TStringBuf str);
+
+void CamelCaseToUnderscoreCase(TStringBuilderBase* builder, TStringBuf str);
+TString CamelCaseToUnderscoreCase(TStringBuf str);
TString TrimLeadingWhitespaces(const TString& str);
TString Trim(const TString& str, const TString& whitespaces);
-
+
////////////////////////////////////////////////////////////////////////////////
//! Implemented for |[u]i(32|64)|.
@@ -200,22 +200,22 @@ char* WriteIntToBufferBackwards(char* ptr, T value);
////////////////////////////////////////////////////////////////////////////////
-struct TCaseInsensitiveStringHasher
-{
- size_t operator()(TStringBuf arg) const;
-};
-
-struct TCaseInsensitiveStringEqualityComparer
-{
- bool operator()(TStringBuf lhs, TStringBuf rhs) const;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-bool TryParseBool(TStringBuf value, bool* result);
-bool ParseBool(TStringBuf value);
+struct TCaseInsensitiveStringHasher
+{
+ size_t operator()(TStringBuf arg) const;
+};
+
+struct TCaseInsensitiveStringEqualityComparer
+{
+ bool operator()(TStringBuf lhs, TStringBuf rhs) const;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+bool TryParseBool(TStringBuf value, bool* result);
+bool ParseBool(TStringBuf value);
TStringBuf FormatBool(bool value);
////////////////////////////////////////////////////////////////////////////////
-} // namespace NYT
+} // namespace NYT
diff --git a/library/cpp/yt/string/string_builder-inl.h b/library/cpp/yt/string/string_builder-inl.h
index b207452568..151fcabf7f 100644
--- a/library/cpp/yt/string/string_builder-inl.h
+++ b/library/cpp/yt/string/string_builder-inl.h
@@ -1,129 +1,129 @@
-#ifndef STRING_BUILDER_INL_H_
-#error "Direct inclusion of this file is not allowed, include string.h"
-// For the sake of sane code completion.
-#include "string_builder.h"
-#endif
-
-#include <library/cpp/yt/assert/assert.h>
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-inline char* TStringBuilderBase::Preallocate(size_t size)
-{
+#ifndef STRING_BUILDER_INL_H_
+#error "Direct inclusion of this file is not allowed, include string.h"
+// For the sake of sane code completion.
+#include "string_builder.h"
+#endif
+
+#include <library/cpp/yt/assert/assert.h>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+inline char* TStringBuilderBase::Preallocate(size_t size)
+{
if (Y_UNLIKELY(End_ - Current_ < static_cast<ssize_t>(size))) {
- size_t length = GetLength();
- auto newLength = std::max(length + size, MinBufferLength);
- DoPreallocate(newLength);
- Current_ = Begin_ + length;
- }
- return Current_;
-}
-
-inline size_t TStringBuilderBase::GetLength() const
-{
- return Current_ ? Current_ - Begin_ : 0;
-}
-
-inline TStringBuf TStringBuilderBase::GetBuffer() const
-{
- return TStringBuf(Begin_, Current_);
-}
-
-inline void TStringBuilderBase::Advance(size_t size)
-{
- Current_ += size;
- YT_ASSERT(Current_ <= End_);
-}
-
-inline void TStringBuilderBase::AppendChar(char ch)
-{
- *Preallocate(1) = ch;
- Advance(1);
-}
-
-inline void TStringBuilderBase::AppendChar(char ch, int n)
-{
- YT_ASSERT(n >= 0);
+ size_t length = GetLength();
+ auto newLength = std::max(length + size, MinBufferLength);
+ DoPreallocate(newLength);
+ Current_ = Begin_ + length;
+ }
+ return Current_;
+}
+
+inline size_t TStringBuilderBase::GetLength() const
+{
+ return Current_ ? Current_ - Begin_ : 0;
+}
+
+inline TStringBuf TStringBuilderBase::GetBuffer() const
+{
+ return TStringBuf(Begin_, Current_);
+}
+
+inline void TStringBuilderBase::Advance(size_t size)
+{
+ Current_ += size;
+ YT_ASSERT(Current_ <= End_);
+}
+
+inline void TStringBuilderBase::AppendChar(char ch)
+{
+ *Preallocate(1) = ch;
+ Advance(1);
+}
+
+inline void TStringBuilderBase::AppendChar(char ch, int n)
+{
+ YT_ASSERT(n >= 0);
if (Y_LIKELY(0 != n)) {
char* dst = Preallocate(n);
::memset(dst, ch, n);
Advance(n);
}
-}
-
-inline void TStringBuilderBase::AppendString(TStringBuf str)
-{
- if (Y_LIKELY(str)) {
- char* dst = Preallocate(str.length());
- ::memcpy(dst, str.begin(), str.length());
- Advance(str.length());
- }
-}
-
-inline void TStringBuilderBase::AppendString(const char* str)
-{
- AppendString(TStringBuf(str));
-}
-
-inline void TStringBuilderBase::Reset()
-{
+}
+
+inline void TStringBuilderBase::AppendString(TStringBuf str)
+{
+ if (Y_LIKELY(str)) {
+ char* dst = Preallocate(str.length());
+ ::memcpy(dst, str.begin(), str.length());
+ Advance(str.length());
+ }
+}
+
+inline void TStringBuilderBase::AppendString(const char* str)
+{
+ AppendString(TStringBuf(str));
+}
+
+inline void TStringBuilderBase::Reset()
+{
Begin_ = Current_ = End_ = nullptr;
- DoReset();
-}
-
-template <class... TArgs>
-void TStringBuilderBase::AppendFormat(TStringBuf format, TArgs&& ... args)
-{
- Format(this, format, std::forward<TArgs>(args)...);
-}
-
-template <size_t Length, class... TArgs>
-void TStringBuilderBase::AppendFormat(const char (&format)[Length], TArgs&& ... args)
-{
- Format(this, format, std::forward<TArgs>(args)...);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-inline TString TStringBuilder::Flush()
-{
- Buffer_.resize(GetLength());
- auto result = std::move(Buffer_);
- Reset();
- return result;
-}
-
-inline void TStringBuilder::DoReset()
-{
- Buffer_ = {};
-}
-
-inline void TStringBuilder::DoPreallocate(size_t newLength)
-{
- Buffer_.ReserveAndResize(newLength);
- auto capacity = Buffer_.capacity();
- Buffer_.ReserveAndResize(capacity);
- Begin_ = &*Buffer_.begin();
- End_ = Begin_ + capacity;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-inline void FormatValue(TStringBuilderBase* builder, const TStringBuilder& value, TStringBuf /*format*/)
-{
- builder->AppendString(value.GetBuffer());
-}
-
-template <class T>
-TString ToStringViaBuilder(const T& value, TStringBuf spec)
-{
- TStringBuilder builder;
- FormatValue(&builder, value, spec);
- return builder.Flush();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
+ DoReset();
+}
+
+template <class... TArgs>
+void TStringBuilderBase::AppendFormat(TStringBuf format, TArgs&& ... args)
+{
+ Format(this, format, std::forward<TArgs>(args)...);
+}
+
+template <size_t Length, class... TArgs>
+void TStringBuilderBase::AppendFormat(const char (&format)[Length], TArgs&& ... args)
+{
+ Format(this, format, std::forward<TArgs>(args)...);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+inline TString TStringBuilder::Flush()
+{
+ Buffer_.resize(GetLength());
+ auto result = std::move(Buffer_);
+ Reset();
+ return result;
+}
+
+inline void TStringBuilder::DoReset()
+{
+ Buffer_ = {};
+}
+
+inline void TStringBuilder::DoPreallocate(size_t newLength)
+{
+ Buffer_.ReserveAndResize(newLength);
+ auto capacity = Buffer_.capacity();
+ Buffer_.ReserveAndResize(capacity);
+ Begin_ = &*Buffer_.begin();
+ End_ = Begin_ + capacity;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+inline void FormatValue(TStringBuilderBase* builder, const TStringBuilder& value, TStringBuf /*format*/)
+{
+ builder->AppendString(value.GetBuffer());
+}
+
+template <class T>
+TString ToStringViaBuilder(const T& value, TStringBuf spec)
+{
+ TStringBuilder builder;
+ FormatValue(&builder, value, spec);
+ return builder.Flush();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/string/string_builder.h b/library/cpp/yt/string/string_builder.h
index 6dac4a3eea..0e13e70904 100644
--- a/library/cpp/yt/string/string_builder.h
+++ b/library/cpp/yt/string/string_builder.h
@@ -1,116 +1,116 @@
-#pragma once
-
-#include <util/generic/string.h>
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-// Forward declarations.
-class TStringBuilderBase;
-class TStringBuilder;
-class TDelimitedStringBuilderWrapper;
-
-template <size_t Length, class... TArgs>
-void Format(TStringBuilderBase* builder, const char (&format)[Length], TArgs&&... args);
-template <class... TArgs>
-void Format(TStringBuilderBase* builder, TStringBuf format, TArgs&&... args);
-
-////////////////////////////////////////////////////////////////////////////////
-
-//! A simple helper for constructing strings by a sequence of appends.
-class TStringBuilderBase
-{
-public:
+#pragma once
+
+#include <util/generic/string.h>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Forward declarations.
+class TStringBuilderBase;
+class TStringBuilder;
+class TDelimitedStringBuilderWrapper;
+
+template <size_t Length, class... TArgs>
+void Format(TStringBuilderBase* builder, const char (&format)[Length], TArgs&&... args);
+template <class... TArgs>
+void Format(TStringBuilderBase* builder, TStringBuf format, TArgs&&... args);
+
+////////////////////////////////////////////////////////////////////////////////
+
+//! A simple helper for constructing strings by a sequence of appends.
+class TStringBuilderBase
+{
+public:
virtual ~TStringBuilderBase() = default;
- char* Preallocate(size_t size);
-
- size_t GetLength() const;
-
- TStringBuf GetBuffer() const;
-
- void Advance(size_t size);
-
- void AppendChar(char ch);
- void AppendChar(char ch, int n);
-
- void AppendString(TStringBuf str);
- void AppendString(const char* str);
-
- template <size_t Length, class... TArgs>
- void AppendFormat(const char (&format)[Length], TArgs&&... args);
- template <class... TArgs>
- void AppendFormat(TStringBuf format, TArgs&&... args);
-
- void Reset();
-
-protected:
+ char* Preallocate(size_t size);
+
+ size_t GetLength() const;
+
+ TStringBuf GetBuffer() const;
+
+ void Advance(size_t size);
+
+ void AppendChar(char ch);
+ void AppendChar(char ch, int n);
+
+ void AppendString(TStringBuf str);
+ void AppendString(const char* str);
+
+ template <size_t Length, class... TArgs>
+ void AppendFormat(const char (&format)[Length], TArgs&&... args);
+ template <class... TArgs>
+ void AppendFormat(TStringBuf format, TArgs&&... args);
+
+ void Reset();
+
+protected:
char* Begin_ = nullptr;
char* Current_ = nullptr;
char* End_ = nullptr;
-
- virtual void DoReset() = 0;
- virtual void DoPreallocate(size_t newLength) = 0;
-
- // -64 must account for any reasonable overhead in dynamic string allocation.
- static constexpr size_t MinBufferLength = 1024 - 64;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-class TStringBuilder
- : public TStringBuilderBase
-{
-public:
- TString Flush();
-
-protected:
- TString Buffer_;
-
+
+ virtual void DoReset() = 0;
+ virtual void DoPreallocate(size_t newLength) = 0;
+
+ // -64 must account for any reasonable overhead in dynamic string allocation.
+ static constexpr size_t MinBufferLength = 1024 - 64;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class TStringBuilder
+ : public TStringBuilderBase
+{
+public:
+ TString Flush();
+
+protected:
+ TString Buffer_;
+
void DoReset() override;
void DoPreallocate(size_t size) override;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class T>
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T>
TString ToStringViaBuilder(const T& value, TStringBuf spec = TStringBuf("v"));
-
-////////////////////////////////////////////////////////////////////////////////
-
-//! Appends a certain delimiter starting from the second call.
-class TDelimitedStringBuilderWrapper
- : private TNonCopyable
-{
-public:
- TDelimitedStringBuilderWrapper(
- TStringBuilderBase* builder,
+
+////////////////////////////////////////////////////////////////////////////////
+
+//! Appends a certain delimiter starting from the second call.
+class TDelimitedStringBuilderWrapper
+ : private TNonCopyable
+{
+public:
+ TDelimitedStringBuilderWrapper(
+ TStringBuilderBase* builder,
TStringBuf delimiter = TStringBuf(", "))
- : Builder_(builder)
- , Delimiter_(delimiter)
- { }
-
- TStringBuilderBase* operator->()
- {
- if (!FirstCall_) {
- Builder_->AppendString(Delimiter_);
- }
- FirstCall_ = false;
- return Builder_;
- }
-
-private:
- TStringBuilderBase* const Builder_;
- const TStringBuf Delimiter_;
-
- bool FirstCall_ = true;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
-
-#define STRING_BUILDER_INL_H_
-#include "string_builder-inl.h"
-#undef STRING_BUILDER_INL_H_
+ : Builder_(builder)
+ , Delimiter_(delimiter)
+ { }
+
+ TStringBuilderBase* operator->()
+ {
+ if (!FirstCall_) {
+ Builder_->AppendString(Delimiter_);
+ }
+ FirstCall_ = false;
+ return Builder_;
+ }
+
+private:
+ TStringBuilderBase* const Builder_;
+ const TStringBuf Delimiter_;
+
+ bool FirstCall_ = true;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
+
+#define STRING_BUILDER_INL_H_
+#include "string_builder-inl.h"
+#undef STRING_BUILDER_INL_H_
diff --git a/library/cpp/yt/string/unittests/enum_ut.cpp b/library/cpp/yt/string/unittests/enum_ut.cpp
index 948a0dd000..b8076fd8ee 100644
--- a/library/cpp/yt/string/unittests/enum_ut.cpp
+++ b/library/cpp/yt/string/unittests/enum_ut.cpp
@@ -1,61 +1,61 @@
#include <library/cpp/testing/gtest/gtest.h>
-
+
#include <library/cpp/yt/string/enum.h>
#include <library/cpp/yt/string/format.h>
-
-#include <limits>
-
-namespace NYT {
-namespace {
-
-////////////////////////////////////////////////////////////////////////////////
-
-// Some compile-time sanity checks.
-DEFINE_ENUM(ESample, (One)(Two));
-static_assert(TFormatTraits<ESample>::HasCustomFormatValue);
-static_assert(TFormatTraits<TEnumIndexedVector<ESample, int>>::HasCustomFormatValue);
-
-DEFINE_ENUM(EColor,
- (Red)
- (BlackAndWhite)
-);
-
-DEFINE_BIT_ENUM(ELangs,
- ((None) (0x00))
- ((Cpp) (0x01))
- ((Go) (0x02))
- ((Rust) (0x04))
- ((Python) (0x08))
- ((JavaScript) (0x10))
-)
-
-TEST(TFormatTest, Enum)
-{
- EXPECT_EQ("Red", Format("%v", EColor::Red));
- EXPECT_EQ("red", Format("%lv", EColor::Red));
-
- EXPECT_EQ("BlackAndWhite", Format("%v", EColor::BlackAndWhite));
- EXPECT_EQ("black_and_white", Format("%lv", EColor::BlackAndWhite));
-
- EXPECT_EQ("EColor(100)", Format("%v", EColor(100)));
-
- EXPECT_EQ("JavaScript", Format("%v", ELangs::JavaScript));
- EXPECT_EQ("java_script", Format("%lv", ELangs::JavaScript));
-
- EXPECT_EQ("None", Format("%v", ELangs::None));
- EXPECT_EQ("none", Format("%lv", ELangs::None));
-
- EXPECT_EQ("Cpp | Go", Format("%v", ELangs::Cpp | ELangs::Go));
- EXPECT_EQ("cpp | go", Format("%lv", ELangs::Cpp | ELangs::Go));
-
- auto four = ELangs::Cpp | ELangs::Go | ELangs::Python | ELangs::JavaScript;
- EXPECT_EQ("Cpp | Go | Python | JavaScript", Format("%v", four));
- EXPECT_EQ("cpp | go | python | java_script", Format("%lv", four));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace
-} // namespace NYT
-
+
+#include <limits>
+
+namespace NYT {
+namespace {
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Some compile-time sanity checks.
+DEFINE_ENUM(ESample, (One)(Two));
+static_assert(TFormatTraits<ESample>::HasCustomFormatValue);
+static_assert(TFormatTraits<TEnumIndexedVector<ESample, int>>::HasCustomFormatValue);
+
+DEFINE_ENUM(EColor,
+ (Red)
+ (BlackAndWhite)
+);
+
+DEFINE_BIT_ENUM(ELangs,
+ ((None) (0x00))
+ ((Cpp) (0x01))
+ ((Go) (0x02))
+ ((Rust) (0x04))
+ ((Python) (0x08))
+ ((JavaScript) (0x10))
+)
+
+TEST(TFormatTest, Enum)
+{
+ EXPECT_EQ("Red", Format("%v", EColor::Red));
+ EXPECT_EQ("red", Format("%lv", EColor::Red));
+
+ EXPECT_EQ("BlackAndWhite", Format("%v", EColor::BlackAndWhite));
+ EXPECT_EQ("black_and_white", Format("%lv", EColor::BlackAndWhite));
+
+ EXPECT_EQ("EColor(100)", Format("%v", EColor(100)));
+
+ EXPECT_EQ("JavaScript", Format("%v", ELangs::JavaScript));
+ EXPECT_EQ("java_script", Format("%lv", ELangs::JavaScript));
+
+ EXPECT_EQ("None", Format("%v", ELangs::None));
+ EXPECT_EQ("none", Format("%lv", ELangs::None));
+
+ EXPECT_EQ("Cpp | Go", Format("%v", ELangs::Cpp | ELangs::Go));
+ EXPECT_EQ("cpp | go", Format("%lv", ELangs::Cpp | ELangs::Go));
+
+ auto four = ELangs::Cpp | ELangs::Go | ELangs::Python | ELangs::JavaScript;
+ EXPECT_EQ("Cpp | Go | Python | JavaScript", Format("%v", four));
+ EXPECT_EQ("cpp | go | python | java_script", Format("%lv", four));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace
+} // namespace NYT
+
diff --git a/library/cpp/yt/string/unittests/format_ut.cpp b/library/cpp/yt/string/unittests/format_ut.cpp
index 58c757be0d..ee069bb2c0 100644
--- a/library/cpp/yt/string/unittests/format_ut.cpp
+++ b/library/cpp/yt/string/unittests/format_ut.cpp
@@ -1,149 +1,149 @@
#include <library/cpp/testing/gtest/gtest.h>
-
-#include <library/cpp/yt/string/format.h>
-
+
+#include <library/cpp/yt/string/format.h>
+
#include <library/cpp/yt/small_containers/compact_vector.h>
-#include <limits>
-
-namespace NYT {
-namespace {
-
-////////////////////////////////////////////////////////////////////////////////
-
-// Some compile-time sanity checks.
-static_assert(TFormatTraits<int>::HasCustomFormatValue);
-static_assert(TFormatTraits<double>::HasCustomFormatValue);
-static_assert(TFormatTraits<void*>::HasCustomFormatValue);
-static_assert(TFormatTraits<const char*>::HasCustomFormatValue);
-static_assert(TFormatTraits<TStringBuf>::HasCustomFormatValue);
-static_assert(TFormatTraits<TString>::HasCustomFormatValue);
-static_assert(TFormatTraits<std::vector<int>>::HasCustomFormatValue);
+#include <limits>
+
+namespace NYT {
+namespace {
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Some compile-time sanity checks.
+static_assert(TFormatTraits<int>::HasCustomFormatValue);
+static_assert(TFormatTraits<double>::HasCustomFormatValue);
+static_assert(TFormatTraits<void*>::HasCustomFormatValue);
+static_assert(TFormatTraits<const char*>::HasCustomFormatValue);
+static_assert(TFormatTraits<TStringBuf>::HasCustomFormatValue);
+static_assert(TFormatTraits<TString>::HasCustomFormatValue);
+static_assert(TFormatTraits<std::vector<int>>::HasCustomFormatValue);
// N.B. TCompactVector<int, 1> is not buildable on Windows
static_assert(TFormatTraits<TCompactVector<int, 2>>::HasCustomFormatValue);
-static_assert(TFormatTraits<std::set<int>>::HasCustomFormatValue);
-static_assert(TFormatTraits<std::map<int, int>>::HasCustomFormatValue);
-static_assert(TFormatTraits<std::multimap<int, int>>::HasCustomFormatValue);
-static_assert(TFormatTraits<THashSet<int>>::HasCustomFormatValue);
-static_assert(TFormatTraits<THashMap<int, int>>::HasCustomFormatValue);
-static_assert(TFormatTraits<THashMultiSet<int>>::HasCustomFormatValue);
-static_assert(TFormatTraits<std::pair<int, int>>::HasCustomFormatValue);
-static_assert(TFormatTraits<std::optional<int>>::HasCustomFormatValue);
-static_assert(TFormatTraits<TDuration>::HasCustomFormatValue);
-static_assert(TFormatTraits<TInstant>::HasCustomFormatValue);
-
-struct TUnformattable
-{ };
-static_assert(!TFormatTraits<TUnformattable>::HasCustomFormatValue);
-
-////////////////////////////////////////////////////////////////////////////////
-
-TEST(TFormatTest, Nothing)
-{
- EXPECT_EQ("abc", Format("a%nb%nc", 1, 2));
-}
-
-TEST(TFormatTest, Verbatim)
-{
- EXPECT_EQ("", Format(""));
- EXPECT_EQ("test", Format("test"));
- EXPECT_EQ("%", Format("%%"));
- EXPECT_EQ("%hello%world%", Format("%%hello%%world%%"));
-}
-
-TEST(TFormatTest, MultipleArgs)
-{
- EXPECT_EQ("2+2=4", Format("%v+%v=%v", 2, 2, 4));
-}
-
-TEST(TFormatTest, Strings)
-{
- EXPECT_EQ("test", Format("%s", "test"));
- EXPECT_EQ("test", Format("%s", TStringBuf("test")));
- EXPECT_EQ("test", Format("%s", TString("test")));
-
- EXPECT_EQ(" abc", Format("%6s", TString("abc")));
- EXPECT_EQ("abc ", Format("%-6s", TString("abc")));
- EXPECT_EQ(" abc", Format("%10v", TString("abc")));
- EXPECT_EQ("abc ", Format("%-10v", TString("abc")));
- EXPECT_EQ("abc", Format("%2s", TString("abc")));
- EXPECT_EQ("abc", Format("%-2s", TString("abc")));
- EXPECT_EQ("abc", Format("%0s", TString("abc")));
- EXPECT_EQ("abc", Format("%-0s", TString("abc")));
+static_assert(TFormatTraits<std::set<int>>::HasCustomFormatValue);
+static_assert(TFormatTraits<std::map<int, int>>::HasCustomFormatValue);
+static_assert(TFormatTraits<std::multimap<int, int>>::HasCustomFormatValue);
+static_assert(TFormatTraits<THashSet<int>>::HasCustomFormatValue);
+static_assert(TFormatTraits<THashMap<int, int>>::HasCustomFormatValue);
+static_assert(TFormatTraits<THashMultiSet<int>>::HasCustomFormatValue);
+static_assert(TFormatTraits<std::pair<int, int>>::HasCustomFormatValue);
+static_assert(TFormatTraits<std::optional<int>>::HasCustomFormatValue);
+static_assert(TFormatTraits<TDuration>::HasCustomFormatValue);
+static_assert(TFormatTraits<TInstant>::HasCustomFormatValue);
+
+struct TUnformattable
+{ };
+static_assert(!TFormatTraits<TUnformattable>::HasCustomFormatValue);
+
+////////////////////////////////////////////////////////////////////////////////
+
+TEST(TFormatTest, Nothing)
+{
+ EXPECT_EQ("abc", Format("a%nb%nc", 1, 2));
+}
+
+TEST(TFormatTest, Verbatim)
+{
+ EXPECT_EQ("", Format(""));
+ EXPECT_EQ("test", Format("test"));
+ EXPECT_EQ("%", Format("%%"));
+ EXPECT_EQ("%hello%world%", Format("%%hello%%world%%"));
+}
+
+TEST(TFormatTest, MultipleArgs)
+{
+ EXPECT_EQ("2+2=4", Format("%v+%v=%v", 2, 2, 4));
+}
+
+TEST(TFormatTest, Strings)
+{
+ EXPECT_EQ("test", Format("%s", "test"));
+ EXPECT_EQ("test", Format("%s", TStringBuf("test")));
+ EXPECT_EQ("test", Format("%s", TString("test")));
+
+ EXPECT_EQ(" abc", Format("%6s", TString("abc")));
+ EXPECT_EQ("abc ", Format("%-6s", TString("abc")));
+ EXPECT_EQ(" abc", Format("%10v", TString("abc")));
+ EXPECT_EQ("abc ", Format("%-10v", TString("abc")));
+ EXPECT_EQ("abc", Format("%2s", TString("abc")));
+ EXPECT_EQ("abc", Format("%-2s", TString("abc")));
+ EXPECT_EQ("abc", Format("%0s", TString("abc")));
+ EXPECT_EQ("abc", Format("%-0s", TString("abc")));
EXPECT_EQ(100, std::ssize(Format("%100v", "abc")));
-}
-
-TEST(TFormatTest, Integers)
-{
- EXPECT_EQ("123", Format("%d", 123));
- EXPECT_EQ("123", Format("%v", 123));
-
+}
+
+TEST(TFormatTest, Integers)
+{
+ EXPECT_EQ("123", Format("%d", 123));
+ EXPECT_EQ("123", Format("%v", 123));
+
EXPECT_EQ("042", Format("%03d", 42));
EXPECT_EQ("42", Format("%01d", 42));
- EXPECT_EQ("2147483647", Format("%d", std::numeric_limits<i32>::max()));
- EXPECT_EQ("-2147483648", Format("%d", std::numeric_limits<i32>::min()));
-
- EXPECT_EQ("0", Format("%u", 0U));
- EXPECT_EQ("0", Format("%v", 0U));
- EXPECT_EQ("4294967295", Format("%u", std::numeric_limits<ui32>::max()));
- EXPECT_EQ("4294967295", Format("%v", std::numeric_limits<ui32>::max()));
-
- EXPECT_EQ("9223372036854775807", Format("%" PRId64, std::numeric_limits<i64>::max()));
- EXPECT_EQ("9223372036854775807", Format("%v", std::numeric_limits<i64>::max()));
- EXPECT_EQ("-9223372036854775808", Format("%" PRId64, std::numeric_limits<i64>::min()));
- EXPECT_EQ("-9223372036854775808", Format("%v", std::numeric_limits<i64>::min()));
-
- EXPECT_EQ("0", Format("%" PRIu64, 0ULL));
- EXPECT_EQ("0", Format("%v", 0ULL));
- EXPECT_EQ("18446744073709551615", Format("%" PRIu64, std::numeric_limits<ui64>::max()));
- EXPECT_EQ("18446744073709551615", Format("%v", std::numeric_limits<ui64>::max()));
-}
-
-TEST(TFormatTest, Floats)
-{
- EXPECT_EQ("3.14", Format("%.2f", 3.1415F));
- EXPECT_EQ("3.14", Format("%.2v", 3.1415F));
- EXPECT_EQ("3.14", Format("%.2lf", 3.1415));
- EXPECT_EQ("3.14", Format("%.2v", 3.1415));
- EXPECT_EQ(TString(std::to_string(std::numeric_limits<double>::max())),
- Format("%lF", std::numeric_limits<double>::max()));
-}
-
-TEST(TFormatTest, Bool)
-{
- EXPECT_EQ("True", Format("%v", true));
- EXPECT_EQ("False", Format("%v", false));
- EXPECT_EQ("true", Format("%lv", true));
- EXPECT_EQ("false", Format("%lv", false));
-}
-
-TEST(TFormatTest, Quotes)
-{
- EXPECT_EQ("\"True\"", Format("%Qv", true));
- EXPECT_EQ("'False'", Format("%qv", false));
- EXPECT_EQ("'\\\'\"'", Format("%qv", "\'\""));
- EXPECT_EQ("\"\\x01\"", Format("%Qv", "\x1"));
- EXPECT_EQ("'\\x1b'", Format("%qv", '\x1b'));
-}
-
-TEST(TFormatTest, Nullable)
-{
- EXPECT_EQ("1", Format("%v", std::make_optional<int>(1)));
- EXPECT_EQ("<null>", Format("%v", std::nullopt));
- EXPECT_EQ("<null>", Format("%v", std::optional<int>()));
- EXPECT_EQ("3.14", Format("%.2f", std::optional<double>(3.1415)));
-}
-
-TEST(TFormatTest, Pointers)
-{
- // No idea if pointer format is standardized, check against Sprintf.
- auto p = reinterpret_cast<void*>(123);
- EXPECT_EQ(Sprintf("%p", reinterpret_cast<void*>(123)), Format("%p", p));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace
-} // namespace NYT
+ EXPECT_EQ("2147483647", Format("%d", std::numeric_limits<i32>::max()));
+ EXPECT_EQ("-2147483648", Format("%d", std::numeric_limits<i32>::min()));
+
+ EXPECT_EQ("0", Format("%u", 0U));
+ EXPECT_EQ("0", Format("%v", 0U));
+ EXPECT_EQ("4294967295", Format("%u", std::numeric_limits<ui32>::max()));
+ EXPECT_EQ("4294967295", Format("%v", std::numeric_limits<ui32>::max()));
+
+ EXPECT_EQ("9223372036854775807", Format("%" PRId64, std::numeric_limits<i64>::max()));
+ EXPECT_EQ("9223372036854775807", Format("%v", std::numeric_limits<i64>::max()));
+ EXPECT_EQ("-9223372036854775808", Format("%" PRId64, std::numeric_limits<i64>::min()));
+ EXPECT_EQ("-9223372036854775808", Format("%v", std::numeric_limits<i64>::min()));
+
+ EXPECT_EQ("0", Format("%" PRIu64, 0ULL));
+ EXPECT_EQ("0", Format("%v", 0ULL));
+ EXPECT_EQ("18446744073709551615", Format("%" PRIu64, std::numeric_limits<ui64>::max()));
+ EXPECT_EQ("18446744073709551615", Format("%v", std::numeric_limits<ui64>::max()));
+}
+
+TEST(TFormatTest, Floats)
+{
+ EXPECT_EQ("3.14", Format("%.2f", 3.1415F));
+ EXPECT_EQ("3.14", Format("%.2v", 3.1415F));
+ EXPECT_EQ("3.14", Format("%.2lf", 3.1415));
+ EXPECT_EQ("3.14", Format("%.2v", 3.1415));
+ EXPECT_EQ(TString(std::to_string(std::numeric_limits<double>::max())),
+ Format("%lF", std::numeric_limits<double>::max()));
+}
+
+TEST(TFormatTest, Bool)
+{
+ EXPECT_EQ("True", Format("%v", true));
+ EXPECT_EQ("False", Format("%v", false));
+ EXPECT_EQ("true", Format("%lv", true));
+ EXPECT_EQ("false", Format("%lv", false));
+}
+
+TEST(TFormatTest, Quotes)
+{
+ EXPECT_EQ("\"True\"", Format("%Qv", true));
+ EXPECT_EQ("'False'", Format("%qv", false));
+ EXPECT_EQ("'\\\'\"'", Format("%qv", "\'\""));
+ EXPECT_EQ("\"\\x01\"", Format("%Qv", "\x1"));
+ EXPECT_EQ("'\\x1b'", Format("%qv", '\x1b'));
+}
+
+TEST(TFormatTest, Nullable)
+{
+ EXPECT_EQ("1", Format("%v", std::make_optional<int>(1)));
+ EXPECT_EQ("<null>", Format("%v", std::nullopt));
+ EXPECT_EQ("<null>", Format("%v", std::optional<int>()));
+ EXPECT_EQ("3.14", Format("%.2f", std::optional<double>(3.1415)));
+}
+
+TEST(TFormatTest, Pointers)
+{
+ // No idea if pointer format is standardized, check against Sprintf.
+ auto p = reinterpret_cast<void*>(123);
+ EXPECT_EQ(Sprintf("%p", reinterpret_cast<void*>(123)), Format("%p", p));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace
+} // namespace NYT
diff --git a/library/cpp/yt/string/unittests/guid_ut.cpp b/library/cpp/yt/string/unittests/guid_ut.cpp
index b63c45d322..4b5eebea16 100644
--- a/library/cpp/yt/string/unittests/guid_ut.cpp
+++ b/library/cpp/yt/string/unittests/guid_ut.cpp
@@ -1,49 +1,49 @@
#include <library/cpp/testing/gtest/gtest.h>
-
+
#include <library/cpp/yt/string/guid.h>
#include <library/cpp/yt/string/format.h>
-
+
#include <util/string/hex.h>
-namespace NYT {
-namespace {
-
-////////////////////////////////////////////////////////////////////////////////
-
+namespace NYT {
+namespace {
+
+////////////////////////////////////////////////////////////////////////////////
+
static_assert(TFormatTraits<TGuid>::HasCustomFormatValue);
-
-TString CanonicalToString(TGuid value)
-{
- return Sprintf("%x-%x-%x-%x",
- value.Parts32[3],
- value.Parts32[2],
- value.Parts32[1],
- value.Parts32[0]);
-}
-
+
+TString CanonicalToString(TGuid value)
+{
+ return Sprintf("%x-%x-%x-%x",
+ value.Parts32[3],
+ value.Parts32[2],
+ value.Parts32[1],
+ value.Parts32[0]);
+}
+
const ui32 TrickyValues[] = {
0, 0x1, 0x12, 0x123, 0x1234, 0x12345, 0x123456, 0x1234567, 0x12345678
};
-TEST(TGuidTest, FormatAllTricky)
-{
- for (ui32 a : TrickyValues) {
- for (ui32 b : TrickyValues) {
- for (ui32 c : TrickyValues) {
- for (ui32 d : TrickyValues) {
- auto value = TGuid(a, b, c, d);
- EXPECT_EQ(CanonicalToString(value), ToString(value));
- }
- }
- }
- }
-}
-
-TEST(TGuidTest, FormatAllSymbols)
-{
- const auto Value = TGuid::FromString("12345678-abcdef01-12345678-abcdef01");
- EXPECT_EQ(CanonicalToString(Value), ToString(Value));
-}
+TEST(TGuidTest, FormatAllTricky)
+{
+ for (ui32 a : TrickyValues) {
+ for (ui32 b : TrickyValues) {
+ for (ui32 c : TrickyValues) {
+ for (ui32 d : TrickyValues) {
+ auto value = TGuid(a, b, c, d);
+ EXPECT_EQ(CanonicalToString(value), ToString(value));
+ }
+ }
+ }
+ }
+}
+
+TEST(TGuidTest, FormatAllSymbols)
+{
+ const auto Value = TGuid::FromString("12345678-abcdef01-12345678-abcdef01");
+ EXPECT_EQ(CanonicalToString(Value), ToString(Value));
+}
TEST(TGuidTest, ByteOrder)
{
@@ -52,7 +52,7 @@ TEST(TGuidTest, ByteOrder)
EXPECT_EQ(HexEncode(bytes), "01EFCDAB7856341201EFCDAB78563412");
}
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace
-} // namespace NYT
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace
+} // namespace NYT
diff --git a/library/cpp/yt/string/unittests/string_ut.cpp b/library/cpp/yt/string/unittests/string_ut.cpp
index 758c804b8a..3e12312af0 100644
--- a/library/cpp/yt/string/unittests/string_ut.cpp
+++ b/library/cpp/yt/string/unittests/string_ut.cpp
@@ -1,52 +1,52 @@
#include <library/cpp/testing/gtest/gtest.h>
-
-#include <library/cpp/yt/string/string.h>
-
-namespace NYT {
-namespace {
-
-////////////////////////////////////////////////////////////////////////////////
-
-struct TTestCase
-{
- const char* UnderCase;
- const char* CamelCase;
-};
-
-static std::vector<TTestCase> TestCases {
- { "kenny", "Kenny" },
- { "south_park", "SouthPark" },
- { "a", "A" },
- { "a_b_c", "ABC" },
- { "reed_solomon_6_3", "ReedSolomon_6_3" },
- { "lrc_12_2_2", "Lrc_12_2_2" },
- { "0", "0" },
- { "0_1_2", "0_1_2" },
- { "int64", "Int64" }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-TEST(TStringTest, UnderscoreCaseToCamelCase)
-{
- for (const auto& testCase : TestCases) {
- auto result = UnderscoreCaseToCamelCase(testCase.UnderCase);
- EXPECT_STREQ(testCase.CamelCase, result.c_str())
- << "Original: \"" << testCase.UnderCase << '"';
- }
-}
-
-TEST(TStringTest, CamelCaseToUnderscoreCase)
-{
- for (const auto& testCase : TestCases) {
- auto result = CamelCaseToUnderscoreCase(testCase.CamelCase);
- EXPECT_STREQ(testCase.UnderCase, result.c_str())
- << "Original: \"" << testCase.CamelCase << '"';
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace
-} // namespace NYT
-
+
+#include <library/cpp/yt/string/string.h>
+
+namespace NYT {
+namespace {
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct TTestCase
+{
+ const char* UnderCase;
+ const char* CamelCase;
+};
+
+static std::vector<TTestCase> TestCases {
+ { "kenny", "Kenny" },
+ { "south_park", "SouthPark" },
+ { "a", "A" },
+ { "a_b_c", "ABC" },
+ { "reed_solomon_6_3", "ReedSolomon_6_3" },
+ { "lrc_12_2_2", "Lrc_12_2_2" },
+ { "0", "0" },
+ { "0_1_2", "0_1_2" },
+ { "int64", "Int64" }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+TEST(TStringTest, UnderscoreCaseToCamelCase)
+{
+ for (const auto& testCase : TestCases) {
+ auto result = UnderscoreCaseToCamelCase(testCase.UnderCase);
+ EXPECT_STREQ(testCase.CamelCase, result.c_str())
+ << "Original: \"" << testCase.UnderCase << '"';
+ }
+}
+
+TEST(TStringTest, CamelCaseToUnderscoreCase)
+{
+ for (const auto& testCase : TestCases) {
+ auto result = CamelCaseToUnderscoreCase(testCase.CamelCase);
+ EXPECT_STREQ(testCase.UnderCase, result.c_str())
+ << "Original: \"" << testCase.CamelCase << '"';
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace
+} // namespace NYT
+
diff --git a/library/cpp/yt/string/unittests/ya.make b/library/cpp/yt/string/unittests/ya.make
index 51c85eea4c..9d539758d1 100644
--- a/library/cpp/yt/string/unittests/ya.make
+++ b/library/cpp/yt/string/unittests/ya.make
@@ -10,7 +10,7 @@ SRCS(
)
PEERDIR(
- library/cpp/yt/string
+ library/cpp/yt/string
library/cpp/testing/gtest
)
diff --git a/library/cpp/yt/string/ya.make b/library/cpp/yt/string/ya.make
index b1fc93929e..83efd5eb2f 100644
--- a/library/cpp/yt/string/ya.make
+++ b/library/cpp/yt/string/ya.make
@@ -7,8 +7,8 @@ SRCS(
)
PEERDIR(
- library/cpp/yt/assert
- library/cpp/yt/exception
+ library/cpp/yt/assert
+ library/cpp/yt/exception
library/cpp/yt/misc
)
@@ -18,9 +18,9 @@ CHECK_DEPENDENT_DIRS(
contrib
library
util
- library/cpp/yt/assert
+ library/cpp/yt/assert
library/cpp/yt/misc
- library/cpp/yt/small_containers
+ library/cpp/yt/small_containers
)
END()
diff --git a/library/cpp/yt/ya.make b/library/cpp/yt/ya.make
index 64083ccd17..f4d43806f4 100644
--- a/library/cpp/yt/ya.make
+++ b/library/cpp/yt/ya.make
@@ -1,24 +1,24 @@
RECURSE(
assert
- coding
- exception
+ coding
+ exception
misc
string
- system
+ system
yson
yson_string
)
-IF (NOT OS_WINDOWS)
- RECURSE(
- containers
- cpu_clock
- logging
- malloc
- memory
- mlock
- phdr_cache
- small_containers
- threading
- )
+IF (NOT OS_WINDOWS)
+ RECURSE(
+ containers
+ cpu_clock
+ logging
+ malloc
+ memory
+ mlock
+ phdr_cache
+ small_containers
+ threading
+ )
ENDIF()
diff --git a/library/cpp/yt/yson/consumer.cpp b/library/cpp/yt/yson/consumer.cpp
index 90438e541e..9b68ee8a22 100644
--- a/library/cpp/yt/yson/consumer.cpp
+++ b/library/cpp/yt/yson/consumer.cpp
@@ -6,8 +6,8 @@ namespace NYT::NYson {
////////////////////////////////////////////////////////////////////////////////
-void IYsonConsumer::OnRaw(const TYsonStringBuf& yson)
-{
+void IYsonConsumer::OnRaw(const TYsonStringBuf& yson)
+{
OnRaw(yson.AsStringBuf(), yson.GetType());
}
diff --git a/library/cpp/yt/yson/consumer.h b/library/cpp/yt/yson/consumer.h
index 7c3b7b0663..ea5f586b91 100644
--- a/library/cpp/yt/yson/consumer.h
+++ b/library/cpp/yt/yson/consumer.h
@@ -1,19 +1,19 @@
#pragma once
#include <util/generic/strbuf.h>
-
+
#include <util/system/defaults.h>
#include <library/cpp/yt/yson_string/public.h>
namespace NYT::NYson {
-
+
////////////////////////////////////////////////////////////////////////////////
//! A SAX-like interface for parsing a YSON stream.
-struct IYsonConsumer
-{
- virtual ~IYsonConsumer() = default;
+struct IYsonConsumer
+{
+ virtual ~IYsonConsumer() = default;
//! The current item is a string scalar (IStringNode).
/*!
diff --git a/library/cpp/yt/yson_string/convert.cpp b/library/cpp/yt/yson_string/convert.cpp
index d49d5d07bc..27f5c30d01 100644
--- a/library/cpp/yt/yson_string/convert.cpp
+++ b/library/cpp/yt/yson_string/convert.cpp
@@ -1,381 +1,381 @@
-#include "convert.h"
-#include "format.h"
-
-#include <library/cpp/yt/assert/assert.h>
-
-#include <library/cpp/yt/string/format.h>
-
-#include <library/cpp/yt/coding/varint.h>
-
-#include <library/cpp/yt/misc/cast.h>
-
-#include <array>
-
-#include <util/stream/mem.h>
-
-namespace NYT::NYson {
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <>
-TYsonString ConvertToYsonString<i8>(const i8& value)
-{
- return ConvertToYsonString(static_cast<i64>(value));
-}
-
-template <>
-TYsonString ConvertToYsonString<i32>(const i32& value)
-{
- return ConvertToYsonString(static_cast<i64>(value));
-}
-
-template <>
-TYsonString ConvertToYsonString<i64>(const i64& value)
-{
- std::array<char, 1 + MaxVarInt64Size> buffer;
- auto* ptr = buffer.data();
- *ptr++ = NDetail::Int64Marker;
- ptr += WriteVarInt64(ptr, value);
- return TYsonString(TStringBuf(buffer.data(), ptr - buffer.data()));
-}
-
-template <>
-TYsonString ConvertToYsonString<ui8>(const ui8& value)
-{
- return ConvertToYsonString(static_cast<ui64>(value));
-}
-
-template <>
-TYsonString ConvertToYsonString<ui32>(const ui32& value)
-{
- return ConvertToYsonString(static_cast<ui64>(value));
-}
-
-template <>
-TYsonString ConvertToYsonString<ui64>(const ui64& value)
-{
- std::array<char, 1 + MaxVarInt64Size> buffer;
- auto* ptr = buffer.data();
- *ptr++ = NDetail::Uint64Marker;
- ptr += WriteVarUint64(ptr, value);
- return TYsonString(TStringBuf(buffer.data(), ptr - buffer.data()));
-}
-
-template <>
-TYsonString ConvertToYsonString<TString>(const TString& value)
-{
- return ConvertToYsonString(static_cast<TStringBuf>(value));
-}
-
-struct TConvertStringToYsonStringTag
-{ };
-
-template <>
-TYsonString ConvertToYsonString<TStringBuf>(const TStringBuf& value)
-{
- auto buffer = TSharedMutableRef::Allocate<TConvertStringToYsonStringTag>(
- 1 + MaxVarInt64Size + value.length(),
- /*initializeStorage*/ false);
- auto* ptr = buffer.Begin();
- *ptr++ = NDetail::StringMarker;
- ptr += WriteVarInt64(ptr, static_cast<i64>(value.length()));
- ::memcpy(ptr, value.data(), value.length());
- ptr += value.length();
- return TYsonString(buffer.Slice(buffer.Begin(), ptr));
-}
-
-TYsonString ConvertToYsonString(const char* value)
-{
- return ConvertToYsonString(TStringBuf(value));
-}
-
-template <>
-TYsonString ConvertToYsonString<float>(const float& value)
-{
- return ConvertToYsonString(static_cast<double>(value));
-}
-
-template <>
-TYsonString ConvertToYsonString<double>(const double& value)
-{
- std::array<char, 1 + sizeof(double)> buffer;
- auto* ptr = buffer.data();
- *ptr++ = NDetail::DoubleMarker;
- ::memcpy(ptr, &value, sizeof(value));
- ptr += sizeof(value);
- return TYsonString(TStringBuf(buffer.data(), ptr - buffer.data()));
-}
-
-template <>
-TYsonString ConvertToYsonString<bool>(const bool& value)
-{
- char ch = value ? NDetail::TrueMarker : NDetail::FalseMarker;
- return TYsonString(TStringBuf(&ch, 1));
-}
-
-template <>
-TYsonString ConvertToYsonString<TInstant>(const TInstant& value)
-{
- return ConvertToYsonString(value.ToString());
-}
-
-template <>
-TYsonString ConvertToYsonString<TDuration>(const TDuration& value)
-{
- return ConvertToYsonString(value.MilliSeconds());
-}
-
-template <>
-TYsonString ConvertToYsonString<TGuid>(const TGuid& value)
-{
- std::array<char, MaxGuidStringSize> guidBuffer;
- auto guidLength = WriteGuidToBuffer(guidBuffer.data(), value) - guidBuffer.data();
- std::array<char, 1 + MaxVarInt64Size + MaxGuidStringSize> ysonBuffer;
- auto* ptr = ysonBuffer.data();
- *ptr++ = NDetail::StringMarker;
- ptr += WriteVarInt64(ptr, static_cast<i64>(guidLength));
- ::memcpy(ptr, guidBuffer.data(), guidLength);
- ptr += guidLength;
- return TYsonString(TStringBuf(ysonBuffer.data(), ptr - ysonBuffer.data()));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-namespace {
-
-TString FormatUnexpectedMarker(char ch)
-{
- switch (ch) {
- case NDetail::BeginListSymbol:
- return "list";
- case NDetail::BeginMapSymbol:
- return "map";
- case NDetail::BeginAttributesSymbol:
- return "attributes";
- case NDetail::EntitySymbol:
- return "\"entity\" literal";
- case NDetail::StringMarker:
- return "\"string\" literal";
- case NDetail::Int64Marker:
- return "\"int64\" literal";
- case NDetail::DoubleMarker:
- return "\"double\" literal";
- case NDetail::FalseMarker:
- case NDetail::TrueMarker:
- return "\"boolean\" literal";
- case NDetail::Uint64Marker:
- return "\"uint64\" literal";
- default:
- return Format("unexpected symbol %qv", ch);
- }
-}
-
-i64 ParseInt64FromYsonString(const TYsonStringBuf& str)
-{
- YT_ASSERT(str.GetType() == EYsonType::Node);
- auto strBuf = str.AsStringBuf();
- TMemoryInput input(strBuf.data(), strBuf.length());
- char ch;
- if (!input.ReadChar(ch)) {
- throw TYsonLiteralParseException("Missing type marker");
- }
- if (ch != NDetail::Int64Marker) {
- throw TYsonLiteralParseException(Format("Unexpected %v",
- FormatUnexpectedMarker(ch)));
- }
- i64 result;
- try {
- ReadVarInt64(&input, &result);
- } catch (const std::exception& ex) {
- throw TYsonLiteralParseException(ex, "Failed to decode \"int64\" value");
- }
- return result;
-}
-
-ui64 ParseUint64FromYsonString(const TYsonStringBuf& str)
-{
- YT_ASSERT(str.GetType() == EYsonType::Node);
- auto strBuf = str.AsStringBuf();
- TMemoryInput input(strBuf.data(), strBuf.length());
- char ch;
- if (!input.ReadChar(ch)) {
- throw TYsonLiteralParseException("Missing type marker");
- }
- if (ch != NDetail::Uint64Marker) {
- throw TYsonLiteralParseException(Format("Unexpected %v",
- FormatUnexpectedMarker(ch)));
- }
- ui64 result;
- try {
- ReadVarUint64(&input, &result);
- } catch (const std::exception& ex) {
- throw TYsonLiteralParseException(ex, "Failed to decode \"uint64\" value");
- }
- return result;
-}
-
-TString ParseStringFromYsonString(const TYsonStringBuf& str)
-{
- YT_ASSERT(str.GetType() == EYsonType::Node);
- auto strBuf = str.AsStringBuf();
- TMemoryInput input(strBuf.data(), strBuf.length());
- char ch;
- if (!input.ReadChar(ch)) {
- throw TYsonLiteralParseException("Missing type marker");
- }
- if (ch != NDetail::StringMarker) {
- throw TYsonLiteralParseException(Format("Unexpected %v",
- FormatUnexpectedMarker(ch)));
- }
- i64 length;
- try {
- ReadVarInt64(&input, &length);
- } catch (const std::exception& ex) {
- throw TYsonLiteralParseException(ex, "Failed to decode string length");
- }
- if (length < 0) {
- throw TYsonLiteralParseException(Format("Negative string length ",
- length));
- }
- if (static_cast<i64>(input.Avail()) != length) {
- throw TYsonLiteralParseException(Format("Incorrect remaining string length: expected %v, got %v",
- length,
- input.Avail()));
- }
- TString result;
- result.ReserveAndResize(length);
- YT_VERIFY(static_cast<i64>(input.Read(result.Detach(), length)) == length);
- return result;
-}
-
-double ParseDoubleFromYsonString(const TYsonStringBuf& str)
-{
- YT_ASSERT(str.GetType() == EYsonType::Node);
- auto strBuf = str.AsStringBuf();
- TMemoryInput input(strBuf.data(), strBuf.length());
- char ch;
- if (!input.ReadChar(ch)) {
- throw TYsonLiteralParseException("Missing type marker");
- }
- if (ch != NDetail::DoubleMarker) {
- throw TYsonLiteralParseException(Format("Unexpected %v",
- FormatUnexpectedMarker(ch)));
- }
- if (input.Avail() != sizeof(double)) {
- throw TYsonLiteralParseException(Format("Incorrect remaining string length: expected %v, got %v",
- sizeof(double),
- input.Avail()));
- }
- double result;
- YT_VERIFY(input.Read(&result, sizeof(result)));
- return result;
-}
-
-} // namespace
-
-#define PARSE(type, underlyingType) \
- template <> \
- type ConvertFromYsonString<type>(const TYsonStringBuf& str) \
- { \
- try { \
- return CheckedIntegralCast<type>(Parse ## underlyingType ## FromYsonString(str)); \
- } catch (const std::exception& ex) { \
- throw TYsonLiteralParseException(ex, "Error parsing \"" #type "\" value from YSON"); \
- } \
- }
-
-PARSE(i8, Int64 )
-PARSE(i16, Int64 )
-PARSE(i32, Int64 )
-PARSE(i64, Int64 )
-PARSE(ui8, Uint64)
-PARSE(ui16, Uint64)
-PARSE(ui32, Uint64)
-PARSE(ui64, Uint64)
-
-#undef PARSE
-
-template <>
-TString ConvertFromYsonString<TString>(const TYsonStringBuf& str)
-{
- try {
- return ParseStringFromYsonString(str);
- } catch (const std::exception& ex) {
- throw TYsonLiteralParseException(ex, "Error parsing \"string\" value from YSON");
- }
-}
-
-template <>
-float ConvertFromYsonString<float>(const TYsonStringBuf& str)
-{
- try {
- return static_cast<float>(ParseDoubleFromYsonString(str));
- } catch (const std::exception& ex) {
- throw TYsonLiteralParseException(ex, "Error parsing \"float\" value from YSON");
- }
-}
-
-template <>
-double ConvertFromYsonString<double>(const TYsonStringBuf& str)
-{
- try {
- return ParseDoubleFromYsonString(str);
- } catch (const std::exception& ex) {
- throw TYsonLiteralParseException(ex, "Error parsing \"double\" value from YSON");
- }
-}
-
-template <>
-bool ConvertFromYsonString<bool>(const TYsonStringBuf& str)
-{
- try {
- YT_ASSERT(str.GetType() == EYsonType::Node);
- auto strBuf = str.AsStringBuf();
- TMemoryInput input(strBuf.data(), strBuf.length());
- char ch;
- if (!input.ReadChar(ch)) {
- throw TYsonLiteralParseException("Missing type marker");
- }
- if (ch != NDetail::TrueMarker && ch != NDetail::FalseMarker) {
- throw TYsonLiteralParseException(Format("Unexpected %v",
- FormatUnexpectedMarker(ch)));
- }
- return ch == NDetail::TrueMarker;
- } catch (const std::exception& ex) {
- throw TYsonLiteralParseException(ex, "Error parsing \"boolean\" value from YSON");
- }
-}
-
-template <>
-TInstant ConvertFromYsonString<TInstant>(const TYsonStringBuf& str)
-{
- try {
- return TInstant::ParseIso8601(ParseStringFromYsonString(str));
- } catch (const std::exception& ex) {
- throw TYsonLiteralParseException(ex, "Error parsing \"instant\" value from YSON");
- }
-}
-
-template <>
-TDuration ConvertFromYsonString<TDuration>(const TYsonStringBuf& str)
-{
- try {
- return TDuration::MilliSeconds(ParseUint64FromYsonString(str));
- } catch (const std::exception& ex) {
- throw TYsonLiteralParseException(ex, "Error parsing \"duration\" value from YSON");
- }
-}
-
-template <>
-TGuid ConvertFromYsonString<TGuid>(const TYsonStringBuf& str)
-{
- try {
- return TGuid::FromString(ParseStringFromYsonString(str));
- } catch (const std::exception& ex) {
- throw TYsonLiteralParseException(ex, "Error parsing \"guid\" value from YSON");
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT::NYson
+#include "convert.h"
+#include "format.h"
+
+#include <library/cpp/yt/assert/assert.h>
+
+#include <library/cpp/yt/string/format.h>
+
+#include <library/cpp/yt/coding/varint.h>
+
+#include <library/cpp/yt/misc/cast.h>
+
+#include <array>
+
+#include <util/stream/mem.h>
+
+namespace NYT::NYson {
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <>
+TYsonString ConvertToYsonString<i8>(const i8& value)
+{
+ return ConvertToYsonString(static_cast<i64>(value));
+}
+
+template <>
+TYsonString ConvertToYsonString<i32>(const i32& value)
+{
+ return ConvertToYsonString(static_cast<i64>(value));
+}
+
+template <>
+TYsonString ConvertToYsonString<i64>(const i64& value)
+{
+ std::array<char, 1 + MaxVarInt64Size> buffer;
+ auto* ptr = buffer.data();
+ *ptr++ = NDetail::Int64Marker;
+ ptr += WriteVarInt64(ptr, value);
+ return TYsonString(TStringBuf(buffer.data(), ptr - buffer.data()));
+}
+
+template <>
+TYsonString ConvertToYsonString<ui8>(const ui8& value)
+{
+ return ConvertToYsonString(static_cast<ui64>(value));
+}
+
+template <>
+TYsonString ConvertToYsonString<ui32>(const ui32& value)
+{
+ return ConvertToYsonString(static_cast<ui64>(value));
+}
+
+template <>
+TYsonString ConvertToYsonString<ui64>(const ui64& value)
+{
+ std::array<char, 1 + MaxVarInt64Size> buffer;
+ auto* ptr = buffer.data();
+ *ptr++ = NDetail::Uint64Marker;
+ ptr += WriteVarUint64(ptr, value);
+ return TYsonString(TStringBuf(buffer.data(), ptr - buffer.data()));
+}
+
+template <>
+TYsonString ConvertToYsonString<TString>(const TString& value)
+{
+ return ConvertToYsonString(static_cast<TStringBuf>(value));
+}
+
+struct TConvertStringToYsonStringTag
+{ };
+
+template <>
+TYsonString ConvertToYsonString<TStringBuf>(const TStringBuf& value)
+{
+ auto buffer = TSharedMutableRef::Allocate<TConvertStringToYsonStringTag>(
+ 1 + MaxVarInt64Size + value.length(),
+ /*initializeStorage*/ false);
+ auto* ptr = buffer.Begin();
+ *ptr++ = NDetail::StringMarker;
+ ptr += WriteVarInt64(ptr, static_cast<i64>(value.length()));
+ ::memcpy(ptr, value.data(), value.length());
+ ptr += value.length();
+ return TYsonString(buffer.Slice(buffer.Begin(), ptr));
+}
+
+TYsonString ConvertToYsonString(const char* value)
+{
+ return ConvertToYsonString(TStringBuf(value));
+}
+
+template <>
+TYsonString ConvertToYsonString<float>(const float& value)
+{
+ return ConvertToYsonString(static_cast<double>(value));
+}
+
+template <>
+TYsonString ConvertToYsonString<double>(const double& value)
+{
+ std::array<char, 1 + sizeof(double)> buffer;
+ auto* ptr = buffer.data();
+ *ptr++ = NDetail::DoubleMarker;
+ ::memcpy(ptr, &value, sizeof(value));
+ ptr += sizeof(value);
+ return TYsonString(TStringBuf(buffer.data(), ptr - buffer.data()));
+}
+
+template <>
+TYsonString ConvertToYsonString<bool>(const bool& value)
+{
+ char ch = value ? NDetail::TrueMarker : NDetail::FalseMarker;
+ return TYsonString(TStringBuf(&ch, 1));
+}
+
+template <>
+TYsonString ConvertToYsonString<TInstant>(const TInstant& value)
+{
+ return ConvertToYsonString(value.ToString());
+}
+
+template <>
+TYsonString ConvertToYsonString<TDuration>(const TDuration& value)
+{
+ return ConvertToYsonString(value.MilliSeconds());
+}
+
+template <>
+TYsonString ConvertToYsonString<TGuid>(const TGuid& value)
+{
+ std::array<char, MaxGuidStringSize> guidBuffer;
+ auto guidLength = WriteGuidToBuffer(guidBuffer.data(), value) - guidBuffer.data();
+ std::array<char, 1 + MaxVarInt64Size + MaxGuidStringSize> ysonBuffer;
+ auto* ptr = ysonBuffer.data();
+ *ptr++ = NDetail::StringMarker;
+ ptr += WriteVarInt64(ptr, static_cast<i64>(guidLength));
+ ::memcpy(ptr, guidBuffer.data(), guidLength);
+ ptr += guidLength;
+ return TYsonString(TStringBuf(ysonBuffer.data(), ptr - ysonBuffer.data()));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+namespace {
+
+TString FormatUnexpectedMarker(char ch)
+{
+ switch (ch) {
+ case NDetail::BeginListSymbol:
+ return "list";
+ case NDetail::BeginMapSymbol:
+ return "map";
+ case NDetail::BeginAttributesSymbol:
+ return "attributes";
+ case NDetail::EntitySymbol:
+ return "\"entity\" literal";
+ case NDetail::StringMarker:
+ return "\"string\" literal";
+ case NDetail::Int64Marker:
+ return "\"int64\" literal";
+ case NDetail::DoubleMarker:
+ return "\"double\" literal";
+ case NDetail::FalseMarker:
+ case NDetail::TrueMarker:
+ return "\"boolean\" literal";
+ case NDetail::Uint64Marker:
+ return "\"uint64\" literal";
+ default:
+ return Format("unexpected symbol %qv", ch);
+ }
+}
+
+i64 ParseInt64FromYsonString(const TYsonStringBuf& str)
+{
+ YT_ASSERT(str.GetType() == EYsonType::Node);
+ auto strBuf = str.AsStringBuf();
+ TMemoryInput input(strBuf.data(), strBuf.length());
+ char ch;
+ if (!input.ReadChar(ch)) {
+ throw TYsonLiteralParseException("Missing type marker");
+ }
+ if (ch != NDetail::Int64Marker) {
+ throw TYsonLiteralParseException(Format("Unexpected %v",
+ FormatUnexpectedMarker(ch)));
+ }
+ i64 result;
+ try {
+ ReadVarInt64(&input, &result);
+ } catch (const std::exception& ex) {
+ throw TYsonLiteralParseException(ex, "Failed to decode \"int64\" value");
+ }
+ return result;
+}
+
+ui64 ParseUint64FromYsonString(const TYsonStringBuf& str)
+{
+ YT_ASSERT(str.GetType() == EYsonType::Node);
+ auto strBuf = str.AsStringBuf();
+ TMemoryInput input(strBuf.data(), strBuf.length());
+ char ch;
+ if (!input.ReadChar(ch)) {
+ throw TYsonLiteralParseException("Missing type marker");
+ }
+ if (ch != NDetail::Uint64Marker) {
+ throw TYsonLiteralParseException(Format("Unexpected %v",
+ FormatUnexpectedMarker(ch)));
+ }
+ ui64 result;
+ try {
+ ReadVarUint64(&input, &result);
+ } catch (const std::exception& ex) {
+ throw TYsonLiteralParseException(ex, "Failed to decode \"uint64\" value");
+ }
+ return result;
+}
+
+TString ParseStringFromYsonString(const TYsonStringBuf& str)
+{
+ YT_ASSERT(str.GetType() == EYsonType::Node);
+ auto strBuf = str.AsStringBuf();
+ TMemoryInput input(strBuf.data(), strBuf.length());
+ char ch;
+ if (!input.ReadChar(ch)) {
+ throw TYsonLiteralParseException("Missing type marker");
+ }
+ if (ch != NDetail::StringMarker) {
+ throw TYsonLiteralParseException(Format("Unexpected %v",
+ FormatUnexpectedMarker(ch)));
+ }
+ i64 length;
+ try {
+ ReadVarInt64(&input, &length);
+ } catch (const std::exception& ex) {
+ throw TYsonLiteralParseException(ex, "Failed to decode string length");
+ }
+ if (length < 0) {
+ throw TYsonLiteralParseException(Format("Negative string length ",
+ length));
+ }
+ if (static_cast<i64>(input.Avail()) != length) {
+ throw TYsonLiteralParseException(Format("Incorrect remaining string length: expected %v, got %v",
+ length,
+ input.Avail()));
+ }
+ TString result;
+ result.ReserveAndResize(length);
+ YT_VERIFY(static_cast<i64>(input.Read(result.Detach(), length)) == length);
+ return result;
+}
+
+double ParseDoubleFromYsonString(const TYsonStringBuf& str)
+{
+ YT_ASSERT(str.GetType() == EYsonType::Node);
+ auto strBuf = str.AsStringBuf();
+ TMemoryInput input(strBuf.data(), strBuf.length());
+ char ch;
+ if (!input.ReadChar(ch)) {
+ throw TYsonLiteralParseException("Missing type marker");
+ }
+ if (ch != NDetail::DoubleMarker) {
+ throw TYsonLiteralParseException(Format("Unexpected %v",
+ FormatUnexpectedMarker(ch)));
+ }
+ if (input.Avail() != sizeof(double)) {
+ throw TYsonLiteralParseException(Format("Incorrect remaining string length: expected %v, got %v",
+ sizeof(double),
+ input.Avail()));
+ }
+ double result;
+ YT_VERIFY(input.Read(&result, sizeof(result)));
+ return result;
+}
+
+} // namespace
+
+#define PARSE(type, underlyingType) \
+ template <> \
+ type ConvertFromYsonString<type>(const TYsonStringBuf& str) \
+ { \
+ try { \
+ return CheckedIntegralCast<type>(Parse ## underlyingType ## FromYsonString(str)); \
+ } catch (const std::exception& ex) { \
+ throw TYsonLiteralParseException(ex, "Error parsing \"" #type "\" value from YSON"); \
+ } \
+ }
+
+PARSE(i8, Int64 )
+PARSE(i16, Int64 )
+PARSE(i32, Int64 )
+PARSE(i64, Int64 )
+PARSE(ui8, Uint64)
+PARSE(ui16, Uint64)
+PARSE(ui32, Uint64)
+PARSE(ui64, Uint64)
+
+#undef PARSE
+
+template <>
+TString ConvertFromYsonString<TString>(const TYsonStringBuf& str)
+{
+ try {
+ return ParseStringFromYsonString(str);
+ } catch (const std::exception& ex) {
+ throw TYsonLiteralParseException(ex, "Error parsing \"string\" value from YSON");
+ }
+}
+
+template <>
+float ConvertFromYsonString<float>(const TYsonStringBuf& str)
+{
+ try {
+ return static_cast<float>(ParseDoubleFromYsonString(str));
+ } catch (const std::exception& ex) {
+ throw TYsonLiteralParseException(ex, "Error parsing \"float\" value from YSON");
+ }
+}
+
+template <>
+double ConvertFromYsonString<double>(const TYsonStringBuf& str)
+{
+ try {
+ return ParseDoubleFromYsonString(str);
+ } catch (const std::exception& ex) {
+ throw TYsonLiteralParseException(ex, "Error parsing \"double\" value from YSON");
+ }
+}
+
+template <>
+bool ConvertFromYsonString<bool>(const TYsonStringBuf& str)
+{
+ try {
+ YT_ASSERT(str.GetType() == EYsonType::Node);
+ auto strBuf = str.AsStringBuf();
+ TMemoryInput input(strBuf.data(), strBuf.length());
+ char ch;
+ if (!input.ReadChar(ch)) {
+ throw TYsonLiteralParseException("Missing type marker");
+ }
+ if (ch != NDetail::TrueMarker && ch != NDetail::FalseMarker) {
+ throw TYsonLiteralParseException(Format("Unexpected %v",
+ FormatUnexpectedMarker(ch)));
+ }
+ return ch == NDetail::TrueMarker;
+ } catch (const std::exception& ex) {
+ throw TYsonLiteralParseException(ex, "Error parsing \"boolean\" value from YSON");
+ }
+}
+
+template <>
+TInstant ConvertFromYsonString<TInstant>(const TYsonStringBuf& str)
+{
+ try {
+ return TInstant::ParseIso8601(ParseStringFromYsonString(str));
+ } catch (const std::exception& ex) {
+ throw TYsonLiteralParseException(ex, "Error parsing \"instant\" value from YSON");
+ }
+}
+
+template <>
+TDuration ConvertFromYsonString<TDuration>(const TYsonStringBuf& str)
+{
+ try {
+ return TDuration::MilliSeconds(ParseUint64FromYsonString(str));
+ } catch (const std::exception& ex) {
+ throw TYsonLiteralParseException(ex, "Error parsing \"duration\" value from YSON");
+ }
+}
+
+template <>
+TGuid ConvertFromYsonString<TGuid>(const TYsonStringBuf& str)
+{
+ try {
+ return TGuid::FromString(ParseStringFromYsonString(str));
+ } catch (const std::exception& ex) {
+ throw TYsonLiteralParseException(ex, "Error parsing \"guid\" value from YSON");
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT::NYson
diff --git a/library/cpp/yt/yson_string/convert.h b/library/cpp/yt/yson_string/convert.h
index 4bd636b2c6..3c2cc7d284 100644
--- a/library/cpp/yt/yson_string/convert.h
+++ b/library/cpp/yt/yson_string/convert.h
@@ -1,114 +1,114 @@
-#pragma once
-
-#include "string.h"
-
-#include <library/cpp/yt/misc/guid.h>
-
-#include <library/cpp/yt/exception/exception.h>
-
-#include <util/generic/string.h>
-
-#include <util/datetime/base.h>
-
-namespace NYT::NYson {
-
-////////////////////////////////////////////////////////////////////////////////
-// Generic forward declarations.
-
-template <class T>
-TYsonString ConvertToYsonString(const T& value);
-
-template <class T>
-TYsonString ConvertToYsonString(const T& value, EYsonFormat format);
-
-template <class T>
-T ConvertFromYsonString(const TYsonStringBuf& str);
-
-////////////////////////////////////////////////////////////////////////////////
-// Basic specializations for ConvertToYsonString.
-
-template <>
-TYsonString ConvertToYsonString<i8>(const i8& value);
-template <>
-TYsonString ConvertToYsonString<i32>(const i32& value);
-template <>
-TYsonString ConvertToYsonString<i64>(const i64& value);
-
-template <>
-TYsonString ConvertToYsonString<ui8>(const ui8& value);
-template <>
-TYsonString ConvertToYsonString<ui32>(const ui32& value);
-template <>
-TYsonString ConvertToYsonString<ui64>(const ui64& value);
-
-template <>
-TYsonString ConvertToYsonString<TString>(const TString& value);
-template <>
-TYsonString ConvertToYsonString<TStringBuf>(const TStringBuf& value);
-TYsonString ConvertToYsonString(const char* value);
-
-template <>
-TYsonString ConvertToYsonString<float>(const float& value);
-template <>
-TYsonString ConvertToYsonString<double>(const double& value);
-
-template <>
-TYsonString ConvertToYsonString<bool>(const bool& value);
-
-template <>
-TYsonString ConvertToYsonString<TInstant>(const TInstant& value);
-
-template <>
-TYsonString ConvertToYsonString<TDuration>(const TDuration& value);
-
-template <>
-TYsonString ConvertToYsonString<TGuid>(const TGuid& value);
-
-////////////////////////////////////////////////////////////////////////////////
-// Basic specializations for ConvertFromYsonString.
-// Note: these currently support a subset of NYT::NYTree::Convert features.
-
-class TYsonLiteralParseException
- : public TCompositeException
-{
-public:
- using TCompositeException::TCompositeException;
-};
-
-template <>
-i8 ConvertFromYsonString<i8>(const TYsonStringBuf& str);
-template <>
-i32 ConvertFromYsonString<i32>(const TYsonStringBuf& str);
-template <>
-i64 ConvertFromYsonString<i64>(const TYsonStringBuf& str);
-
-template <>
-ui8 ConvertFromYsonString<ui8>(const TYsonStringBuf& str);
-template <>
-ui32 ConvertFromYsonString<ui32>(const TYsonStringBuf& str);
-template <>
-ui64 ConvertFromYsonString<ui64>(const TYsonStringBuf& str);
-
-template <>
-TString ConvertFromYsonString<TString>(const TYsonStringBuf& str);
-
-template <>
-float ConvertFromYsonString<float>(const TYsonStringBuf& str);
-template <>
-double ConvertFromYsonString<double>(const TYsonStringBuf& str);
-
-template <>
-bool ConvertFromYsonString<bool>(const TYsonStringBuf& str);
-
-template <>
-TInstant ConvertFromYsonString<TInstant>(const TYsonStringBuf& str);
-
-template <>
-TDuration ConvertFromYsonString<TDuration>(const TYsonStringBuf& str);
-
-template <>
-TGuid ConvertFromYsonString<TGuid>(const TYsonStringBuf& str);
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT::NYson
+#pragma once
+
+#include "string.h"
+
+#include <library/cpp/yt/misc/guid.h>
+
+#include <library/cpp/yt/exception/exception.h>
+
+#include <util/generic/string.h>
+
+#include <util/datetime/base.h>
+
+namespace NYT::NYson {
+
+////////////////////////////////////////////////////////////////////////////////
+// Generic forward declarations.
+
+template <class T>
+TYsonString ConvertToYsonString(const T& value);
+
+template <class T>
+TYsonString ConvertToYsonString(const T& value, EYsonFormat format);
+
+template <class T>
+T ConvertFromYsonString(const TYsonStringBuf& str);
+
+////////////////////////////////////////////////////////////////////////////////
+// Basic specializations for ConvertToYsonString.
+
+template <>
+TYsonString ConvertToYsonString<i8>(const i8& value);
+template <>
+TYsonString ConvertToYsonString<i32>(const i32& value);
+template <>
+TYsonString ConvertToYsonString<i64>(const i64& value);
+
+template <>
+TYsonString ConvertToYsonString<ui8>(const ui8& value);
+template <>
+TYsonString ConvertToYsonString<ui32>(const ui32& value);
+template <>
+TYsonString ConvertToYsonString<ui64>(const ui64& value);
+
+template <>
+TYsonString ConvertToYsonString<TString>(const TString& value);
+template <>
+TYsonString ConvertToYsonString<TStringBuf>(const TStringBuf& value);
+TYsonString ConvertToYsonString(const char* value);
+
+template <>
+TYsonString ConvertToYsonString<float>(const float& value);
+template <>
+TYsonString ConvertToYsonString<double>(const double& value);
+
+template <>
+TYsonString ConvertToYsonString<bool>(const bool& value);
+
+template <>
+TYsonString ConvertToYsonString<TInstant>(const TInstant& value);
+
+template <>
+TYsonString ConvertToYsonString<TDuration>(const TDuration& value);
+
+template <>
+TYsonString ConvertToYsonString<TGuid>(const TGuid& value);
+
+////////////////////////////////////////////////////////////////////////////////
+// Basic specializations for ConvertFromYsonString.
+// Note: these currently support a subset of NYT::NYTree::Convert features.
+
+class TYsonLiteralParseException
+ : public TCompositeException
+{
+public:
+ using TCompositeException::TCompositeException;
+};
+
+template <>
+i8 ConvertFromYsonString<i8>(const TYsonStringBuf& str);
+template <>
+i32 ConvertFromYsonString<i32>(const TYsonStringBuf& str);
+template <>
+i64 ConvertFromYsonString<i64>(const TYsonStringBuf& str);
+
+template <>
+ui8 ConvertFromYsonString<ui8>(const TYsonStringBuf& str);
+template <>
+ui32 ConvertFromYsonString<ui32>(const TYsonStringBuf& str);
+template <>
+ui64 ConvertFromYsonString<ui64>(const TYsonStringBuf& str);
+
+template <>
+TString ConvertFromYsonString<TString>(const TYsonStringBuf& str);
+
+template <>
+float ConvertFromYsonString<float>(const TYsonStringBuf& str);
+template <>
+double ConvertFromYsonString<double>(const TYsonStringBuf& str);
+
+template <>
+bool ConvertFromYsonString<bool>(const TYsonStringBuf& str);
+
+template <>
+TInstant ConvertFromYsonString<TInstant>(const TYsonStringBuf& str);
+
+template <>
+TDuration ConvertFromYsonString<TDuration>(const TYsonStringBuf& str);
+
+template <>
+TGuid ConvertFromYsonString<TGuid>(const TYsonStringBuf& str);
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT::NYson
diff --git a/library/cpp/yt/yson_string/format.h b/library/cpp/yt/yson_string/format.h
index 23f14213d5..2efd4fa39a 100644
--- a/library/cpp/yt/yson_string/format.h
+++ b/library/cpp/yt/yson_string/format.h
@@ -1,44 +1,44 @@
-#pragma once
-
-namespace NYT::NYson::NDetail {
-
-////////////////////////////////////////////////////////////////////////////////
-
-//! Indicates the beginning of a list.
-constexpr char BeginListSymbol = '[';
-//! Indicates the end of a list.
-constexpr char EndListSymbol = ']';
-
-//! Indicates the beginning of a map.
-constexpr char BeginMapSymbol = '{';
-//! Indicates the end of a map.
-constexpr char EndMapSymbol = '}';
-
-//! Indicates the beginning of an attribute map.
-constexpr char BeginAttributesSymbol = '<';
-//! Indicates the end of an attribute map.
-constexpr char EndAttributesSymbol = '>';
-
-//! Separates items in lists, maps, attributes.
-constexpr char ItemSeparatorSymbol = ';';
-//! Separates keys from values in maps.
-constexpr char KeyValueSeparatorSymbol = '=';
-
-//! Indicates an entity.
-constexpr char EntitySymbol = '#';
-//! Marks the beginning of a binary string literal.
-constexpr char StringMarker = '\x01';
-//! Marks the beginning of a binary i64 literal.
-constexpr char Int64Marker = '\x02';
-//! Marks the beginning of a binary double literal.
-constexpr char DoubleMarker = '\x03';
-//! Marks |false| boolean value.
-constexpr char FalseMarker = '\x04';
-//! Marks |true| boolean value.
-constexpr char TrueMarker = '\x05';
-//! Marks the beginning of a binary ui64 literal.
-constexpr char Uint64Marker = '\x06';
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT::NYson::NDetail
+#pragma once
+
+namespace NYT::NYson::NDetail {
+
+////////////////////////////////////////////////////////////////////////////////
+
+//! Indicates the beginning of a list.
+constexpr char BeginListSymbol = '[';
+//! Indicates the end of a list.
+constexpr char EndListSymbol = ']';
+
+//! Indicates the beginning of a map.
+constexpr char BeginMapSymbol = '{';
+//! Indicates the end of a map.
+constexpr char EndMapSymbol = '}';
+
+//! Indicates the beginning of an attribute map.
+constexpr char BeginAttributesSymbol = '<';
+//! Indicates the end of an attribute map.
+constexpr char EndAttributesSymbol = '>';
+
+//! Separates items in lists, maps, attributes.
+constexpr char ItemSeparatorSymbol = ';';
+//! Separates keys from values in maps.
+constexpr char KeyValueSeparatorSymbol = '=';
+
+//! Indicates an entity.
+constexpr char EntitySymbol = '#';
+//! Marks the beginning of a binary string literal.
+constexpr char StringMarker = '\x01';
+//! Marks the beginning of a binary i64 literal.
+constexpr char Int64Marker = '\x02';
+//! Marks the beginning of a binary double literal.
+constexpr char DoubleMarker = '\x03';
+//! Marks |false| boolean value.
+constexpr char FalseMarker = '\x04';
+//! Marks |true| boolean value.
+constexpr char TrueMarker = '\x05';
+//! Marks the beginning of a binary ui64 literal.
+constexpr char Uint64Marker = '\x06';
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT::NYson::NDetail
diff --git a/library/cpp/yt/yson_string/public.h b/library/cpp/yt/yson_string/public.h
index 6e89f54ab2..42c1ce80bb 100644
--- a/library/cpp/yt/yson_string/public.h
+++ b/library/cpp/yt/yson_string/public.h
@@ -1,39 +1,39 @@
-#pragma once
-
-#include <library/cpp/yt/misc/enum.h>
-
-namespace NYT::NYson {
-
-////////////////////////////////////////////////////////////////////////////////
-
-//! The data format.
-DEFINE_ENUM(EYsonFormat,
- // Binary.
- // Most compact but not human-readable.
- (Binary)
-
- // Text.
- // Not so compact but human-readable.
- // Does not use indentation.
- // Uses escaping for non-text characters.
- (Text)
-
- // Text with indentation.
- // Extremely verbose but human-readable.
- // Uses escaping for non-text characters.
- (Pretty)
-);
-
-// NB: -1 is used for serializing null TYsonString.
-DEFINE_ENUM_WITH_UNDERLYING_TYPE(EYsonType, i8,
- ((Node) (0))
- ((ListFragment) (1))
- ((MapFragment) (2))
-);
-
-class TYsonString;
-class TYsonStringBuf;
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT::NYson
+#pragma once
+
+#include <library/cpp/yt/misc/enum.h>
+
+namespace NYT::NYson {
+
+////////////////////////////////////////////////////////////////////////////////
+
+//! The data format.
+DEFINE_ENUM(EYsonFormat,
+ // Binary.
+ // Most compact but not human-readable.
+ (Binary)
+
+ // Text.
+ // Not so compact but human-readable.
+ // Does not use indentation.
+ // Uses escaping for non-text characters.
+ (Text)
+
+ // Text with indentation.
+ // Extremely verbose but human-readable.
+ // Uses escaping for non-text characters.
+ (Pretty)
+);
+
+// NB: -1 is used for serializing null TYsonString.
+DEFINE_ENUM_WITH_UNDERLYING_TYPE(EYsonType, i8,
+ ((Node) (0))
+ ((ListFragment) (1))
+ ((MapFragment) (2))
+);
+
+class TYsonString;
+class TYsonStringBuf;
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT::NYson
diff --git a/library/cpp/yt/yson_string/string-inl.h b/library/cpp/yt/yson_string/string-inl.h
index 11e8af65a2..5c41629cc0 100644
--- a/library/cpp/yt/yson_string/string-inl.h
+++ b/library/cpp/yt/yson_string/string-inl.h
@@ -1,93 +1,93 @@
-#ifndef STRING_INL_H_
-#error "Direct inclusion of this file is not allowed, include string.h"
-// For the sake of sane code completion.
-#include "string.h"
-#endif
-
-namespace NYT::NYson {
-
-////////////////////////////////////////////////////////////////////////////////
-
-namespace NDetail {
-
-template <typename TLeft, typename TRight>
-bool Equals(const TLeft& lhs, const TRight& rhs)
-{
- auto lhsNull = !lhs.operator bool();
- auto rhsNull = !rhs.operator bool();
- if (lhsNull != rhsNull) {
- return false;
- }
- if (lhsNull && rhsNull) {
- return true;
- }
- return
- lhs.AsStringBuf() == rhs.AsStringBuf() &&
- lhs.GetType() == rhs.GetType();
-}
-
-} // namespace NDetail
-
-inline bool operator == (const TYsonString& lhs, const TYsonString& rhs)
-{
- return NDetail::Equals(lhs, rhs);
-}
-
-inline bool operator == (const TYsonString& lhs, const TYsonStringBuf& rhs)
-{
- return NDetail::Equals(lhs, rhs);
-}
-
-inline bool operator == (const TYsonStringBuf& lhs, const TYsonString& rhs)
-{
- return NDetail::Equals(lhs, rhs);
-}
-
-inline bool operator == (const TYsonStringBuf& lhs, const TYsonStringBuf& rhs)
-{
- return NDetail::Equals(lhs, rhs);
-}
-
-inline bool operator != (const TYsonString& lhs, const TYsonString& rhs)
-{
- return !(lhs == rhs);
-}
-
-inline bool operator != (const TYsonString& lhs, const TYsonStringBuf& rhs)
-{
- return !(lhs == rhs);
-}
-
-inline bool operator != (const TYsonStringBuf& lhs, const TYsonString& rhs)
-{
- return !(lhs == rhs);
-}
-
-inline bool operator != (const TYsonStringBuf& lhs, const TYsonStringBuf& rhs)
-{
- return !(lhs == rhs);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT::NYson
-
-//! A hasher for TYsonString
-template <>
-struct THash<NYT::NYson::TYsonString>
-{
- size_t operator () (const NYT::NYson::TYsonString& str) const
- {
- return str.ComputeHash();
- }
-};
-
-//! A hasher for TYsonStringBuf
-template <>
-struct THash<NYT::NYson::TYsonStringBuf>
-{
- size_t operator () (const NYT::NYson::TYsonStringBuf& str) const
- {
- return THash<TStringBuf>()(str.AsStringBuf());
- }
-};
+#ifndef STRING_INL_H_
+#error "Direct inclusion of this file is not allowed, include string.h"
+// For the sake of sane code completion.
+#include "string.h"
+#endif
+
+namespace NYT::NYson {
+
+////////////////////////////////////////////////////////////////////////////////
+
+namespace NDetail {
+
+template <typename TLeft, typename TRight>
+bool Equals(const TLeft& lhs, const TRight& rhs)
+{
+ auto lhsNull = !lhs.operator bool();
+ auto rhsNull = !rhs.operator bool();
+ if (lhsNull != rhsNull) {
+ return false;
+ }
+ if (lhsNull && rhsNull) {
+ return true;
+ }
+ return
+ lhs.AsStringBuf() == rhs.AsStringBuf() &&
+ lhs.GetType() == rhs.GetType();
+}
+
+} // namespace NDetail
+
+inline bool operator == (const TYsonString& lhs, const TYsonString& rhs)
+{
+ return NDetail::Equals(lhs, rhs);
+}
+
+inline bool operator == (const TYsonString& lhs, const TYsonStringBuf& rhs)
+{
+ return NDetail::Equals(lhs, rhs);
+}
+
+inline bool operator == (const TYsonStringBuf& lhs, const TYsonString& rhs)
+{
+ return NDetail::Equals(lhs, rhs);
+}
+
+inline bool operator == (const TYsonStringBuf& lhs, const TYsonStringBuf& rhs)
+{
+ return NDetail::Equals(lhs, rhs);
+}
+
+inline bool operator != (const TYsonString& lhs, const TYsonString& rhs)
+{
+ return !(lhs == rhs);
+}
+
+inline bool operator != (const TYsonString& lhs, const TYsonStringBuf& rhs)
+{
+ return !(lhs == rhs);
+}
+
+inline bool operator != (const TYsonStringBuf& lhs, const TYsonString& rhs)
+{
+ return !(lhs == rhs);
+}
+
+inline bool operator != (const TYsonStringBuf& lhs, const TYsonStringBuf& rhs)
+{
+ return !(lhs == rhs);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT::NYson
+
+//! A hasher for TYsonString
+template <>
+struct THash<NYT::NYson::TYsonString>
+{
+ size_t operator () (const NYT::NYson::TYsonString& str) const
+ {
+ return str.ComputeHash();
+ }
+};
+
+//! A hasher for TYsonStringBuf
+template <>
+struct THash<NYT::NYson::TYsonStringBuf>
+{
+ size_t operator () (const NYT::NYson::TYsonStringBuf& str) const
+ {
+ return THash<TStringBuf>()(str.AsStringBuf());
+ }
+};
diff --git a/library/cpp/yt/yson_string/string.cpp b/library/cpp/yt/yson_string/string.cpp
index 3643a7107d..99d45e8616 100644
--- a/library/cpp/yt/yson_string/string.cpp
+++ b/library/cpp/yt/yson_string/string.cpp
@@ -1,185 +1,185 @@
#include "string.h"
-
-#include <library/cpp/yt/assert/assert.h>
-
-#include <library/cpp/yt/misc/variant.h>
-
-#include <library/cpp/yt/memory/new.h>
-
-namespace NYT::NYson {
-
-////////////////////////////////////////////////////////////////////////////////
-
-TYsonStringBuf::TYsonStringBuf()
-{
- Type_ = EYsonType::Node; // fake
- Null_ = true;
-}
-
-TYsonStringBuf::TYsonStringBuf(const TYsonString& ysonString)
-{
- if (ysonString) {
- Data_ = ysonString.AsStringBuf();
- Type_ = ysonString.GetType();
- Null_ = false;
- } else {
- Type_ = EYsonType::Node; // fake
- Null_ = true;
- }
-}
-
-TYsonStringBuf::TYsonStringBuf(const TString& data, EYsonType type)
- : TYsonStringBuf(TStringBuf(data), type)
-{ }
-
-TYsonStringBuf::TYsonStringBuf(TStringBuf data, EYsonType type)
- : Data_(data)
+
+#include <library/cpp/yt/assert/assert.h>
+
+#include <library/cpp/yt/misc/variant.h>
+
+#include <library/cpp/yt/memory/new.h>
+
+namespace NYT::NYson {
+
+////////////////////////////////////////////////////////////////////////////////
+
+TYsonStringBuf::TYsonStringBuf()
+{
+ Type_ = EYsonType::Node; // fake
+ Null_ = true;
+}
+
+TYsonStringBuf::TYsonStringBuf(const TYsonString& ysonString)
+{
+ if (ysonString) {
+ Data_ = ysonString.AsStringBuf();
+ Type_ = ysonString.GetType();
+ Null_ = false;
+ } else {
+ Type_ = EYsonType::Node; // fake
+ Null_ = true;
+ }
+}
+
+TYsonStringBuf::TYsonStringBuf(const TString& data, EYsonType type)
+ : TYsonStringBuf(TStringBuf(data), type)
+{ }
+
+TYsonStringBuf::TYsonStringBuf(TStringBuf data, EYsonType type)
+ : Data_(data)
, Type_(type)
- , Null_(false)
+ , Null_(false)
{ }
TYsonStringBuf::TYsonStringBuf(const char* data, EYsonType type)
: TYsonStringBuf(TStringBuf(data), type)
{ }
-TYsonStringBuf::operator bool() const
-{
- return !Null_;
-}
-
-TStringBuf TYsonStringBuf::AsStringBuf() const
-{
- YT_VERIFY(*this);
- return Data_;
-}
-
-EYsonType TYsonStringBuf::GetType() const
-{
- YT_VERIFY(*this);
- return Type_;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-TYsonString::TYsonString()
-{
- Begin_ = nullptr;
- Size_ = 0;
- Type_ = EYsonType::Node; // fake
-}
-
-TYsonString::TYsonString(const TYsonStringBuf& ysonStringBuf)
-{
- if (ysonStringBuf) {
- struct TCapturedYsonStringPayload
- : public TRefCounted
- , public TWithExtraSpace<TCapturedYsonStringPayload>
- {
- char* GetData()
- {
- return static_cast<char*>(GetExtraSpacePtr());
- }
- };
-
- auto data = ysonStringBuf.AsStringBuf();
- auto payload = NewWithExtraSpace<TCapturedYsonStringPayload>(data.length());
- ::memcpy(payload->GetData(), data.data(), data.length());
- Payload_ = payload;
- Begin_ = payload->GetData();
- Size_ = data.Size();
- Type_ = ysonStringBuf.GetType();
+TYsonStringBuf::operator bool() const
+{
+ return !Null_;
+}
+
+TStringBuf TYsonStringBuf::AsStringBuf() const
+{
+ YT_VERIFY(*this);
+ return Data_;
+}
+
+EYsonType TYsonStringBuf::GetType() const
+{
+ YT_VERIFY(*this);
+ return Type_;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+TYsonString::TYsonString()
+{
+ Begin_ = nullptr;
+ Size_ = 0;
+ Type_ = EYsonType::Node; // fake
+}
+
+TYsonString::TYsonString(const TYsonStringBuf& ysonStringBuf)
+{
+ if (ysonStringBuf) {
+ struct TCapturedYsonStringPayload
+ : public TRefCounted
+ , public TWithExtraSpace<TCapturedYsonStringPayload>
+ {
+ char* GetData()
+ {
+ return static_cast<char*>(GetExtraSpacePtr());
+ }
+ };
+
+ auto data = ysonStringBuf.AsStringBuf();
+ auto payload = NewWithExtraSpace<TCapturedYsonStringPayload>(data.length());
+ ::memcpy(payload->GetData(), data.data(), data.length());
+ Payload_ = payload;
+ Begin_ = payload->GetData();
+ Size_ = data.Size();
+ Type_ = ysonStringBuf.GetType();
} else {
- Begin_ = nullptr;
- Size_ = 0;
- Type_ = EYsonType::Node; // fake
- }
-}
-
-TYsonString::TYsonString(
- TStringBuf data,
- EYsonType type)
- : TYsonString(TYsonStringBuf(data, type))
+ Begin_ = nullptr;
+ Size_ = 0;
+ Type_ = EYsonType::Node; // fake
+ }
+}
+
+TYsonString::TYsonString(
+ TStringBuf data,
+ EYsonType type)
+ : TYsonString(TYsonStringBuf(data, type))
{ }
#ifdef TSTRING_IS_STD_STRING
-TYsonString::TYsonString(
+TYsonString::TYsonString(
const TString& data,
- EYsonType type)
+ EYsonType type)
: TYsonString(TYsonStringBuf(data, type))
{ }
#else
TYsonString::TYsonString(
const TString& data,
EYsonType type)
-{
+{
// NOTE: CoW TString implementation is assumed
// Moving the payload MUST NOT invalidate its internal pointers
- Payload_ = data;
- Begin_ = data.data();
- Size_ = data.length();
- Type_ = type;
-}
+ Payload_ = data;
+ Begin_ = data.data();
+ Size_ = data.length();
+ Type_ = type;
+}
#endif
-TYsonString::TYsonString(
- const TSharedRef& data,
- EYsonType type)
-{
- Payload_ = data.GetHolder();
- Begin_ = data.Begin();
- Size_ = data.Size();
- Type_ = type;
-}
-
-TYsonString::operator bool() const
-{
- return !std::holds_alternative<TNullPayload>(Payload_);
+TYsonString::TYsonString(
+ const TSharedRef& data,
+ EYsonType type)
+{
+ Payload_ = data.GetHolder();
+ Begin_ = data.Begin();
+ Size_ = data.Size();
+ Type_ = type;
}
-EYsonType TYsonString::GetType() const
+TYsonString::operator bool() const
{
- YT_VERIFY(*this);
- return Type_;
-}
-
-TStringBuf TYsonString::AsStringBuf() const
+ return !std::holds_alternative<TNullPayload>(Payload_);
+}
+
+EYsonType TYsonString::GetType() const
{
- YT_VERIFY(*this);
- return TStringBuf(Begin_, Begin_ + Size_);
+ YT_VERIFY(*this);
+ return Type_;
}
-TString TYsonString::ToString() const
+TStringBuf TYsonString::AsStringBuf() const
{
- return Visit(
- Payload_,
- [] (const TNullPayload&) -> TString {
- YT_ABORT();
- },
+ YT_VERIFY(*this);
+ return TStringBuf(Begin_, Begin_ + Size_);
+}
+
+TString TYsonString::ToString() const
+{
+ return Visit(
+ Payload_,
+ [] (const TNullPayload&) -> TString {
+ YT_ABORT();
+ },
[&] (const TRefCountedPtr&) {
- return TString(AsStringBuf());
- },
- [] (const TString& payload) {
- return payload;
- });
+ return TString(AsStringBuf());
+ },
+ [] (const TString& payload) {
+ return payload;
+ });
}
-size_t TYsonString::ComputeHash() const
+size_t TYsonString::ComputeHash() const
{
- return THash<TStringBuf>()(TStringBuf(Begin_, Begin_ + Size_));
+ return THash<TStringBuf>()(TStringBuf(Begin_, Begin_ + Size_));
}
-////////////////////////////////////////////////////////////////////////////////
-
+////////////////////////////////////////////////////////////////////////////////
+
TString ToString(const TYsonString& yson)
-{
- return yson.ToString();
-}
-
+{
+ return yson.ToString();
+}
+
TString ToString(const TYsonStringBuf& yson)
{
- return TString(yson.AsStringBuf());
+ return TString(yson.AsStringBuf());
}
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT::NYson
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT::NYson
diff --git a/library/cpp/yt/yson_string/string.h b/library/cpp/yt/yson_string/string.h
index cbe6810252..e13af37a6d 100644
--- a/library/cpp/yt/yson_string/string.h
+++ b/library/cpp/yt/yson_string/string.h
@@ -1,34 +1,34 @@
-#pragma once
-
-#include "public.h"
-
-#include <library/cpp/yt/memory/ref.h>
-
-#include <variant>
-
-namespace NYT::NYson {
-
-////////////////////////////////////////////////////////////////////////////////
-
-//! Contains a sequence of bytes in YSON encoding annotated with EYsonType describing
-//! the content. Could be null. Non-owning.
-class TYsonStringBuf
-{
-public:
- //! Constructs a null instance.
- TYsonStringBuf();
-
- //! Constructs an instance from TYsonString.
- TYsonStringBuf(const TYsonString& ysonString);
-
+#pragma once
+
+#include "public.h"
+
+#include <library/cpp/yt/memory/ref.h>
+
+#include <variant>
+
+namespace NYT::NYson {
+
+////////////////////////////////////////////////////////////////////////////////
+
+//! Contains a sequence of bytes in YSON encoding annotated with EYsonType describing
+//! the content. Could be null. Non-owning.
+class TYsonStringBuf
+{
+public:
+ //! Constructs a null instance.
+ TYsonStringBuf();
+
+ //! Constructs an instance from TYsonString.
+ TYsonStringBuf(const TYsonString& ysonString);
+
//! Constructs a non-null instance with given type and content.
- explicit TYsonStringBuf(
- const TString& data,
+ explicit TYsonStringBuf(
+ const TString& data,
EYsonType type = EYsonType::Node);
-
+
//! Constructs a non-null instance with given type and content.
- explicit TYsonStringBuf(
- TStringBuf data,
+ explicit TYsonStringBuf(
+ TStringBuf data,
EYsonType type = EYsonType::Node);
//! Constructs a non-null instance with given type and content
@@ -38,103 +38,103 @@ public:
const char* data,
EYsonType type = EYsonType::Node);
- //! Returns |true| if the instance is not null.
- explicit operator bool() const;
-
- //! Returns the underlying YSON bytes. The instance must be non-null.
- TStringBuf AsStringBuf() const;
-
- //! Returns type of YSON contained here. The instance must be non-null.
- EYsonType GetType() const;
-
+ //! Returns |true| if the instance is not null.
+ explicit operator bool() const;
+
+ //! Returns the underlying YSON bytes. The instance must be non-null.
+ TStringBuf AsStringBuf() const;
+
+ //! Returns type of YSON contained here. The instance must be non-null.
+ EYsonType GetType() const;
+
protected:
- TStringBuf Data_;
- EYsonType Type_;
+ TStringBuf Data_;
+ EYsonType Type_;
bool Null_;
};
-////////////////////////////////////////////////////////////////////////////////
-
-//! An owning version of TYsonStringBuf.
-/*!
- * Internally captures the data either via TString or a polymorphic ref-counted holder.
- */
+////////////////////////////////////////////////////////////////////////////////
+
+//! An owning version of TYsonStringBuf.
+/*!
+ * Internally captures the data either via TString or a polymorphic ref-counted holder.
+ */
class TYsonString
{
public:
- //! Constructs a null instance.
- TYsonString();
+ //! Constructs a null instance.
+ TYsonString();
- //! Constructs an instance from TYsonStringBuf.
- //! Copies the data into a ref-counted payload.
+ //! Constructs an instance from TYsonStringBuf.
+ //! Copies the data into a ref-counted payload.
explicit TYsonString(const TYsonStringBuf& ysonStringBuf);
- //! Constructs an instance from TStringBuf.
- //! Copies the data into a ref-counted payload.
- explicit TYsonString(
- TStringBuf data,
- EYsonType type = EYsonType::Node);
-
- //! Constructs an instance from TString.
+ //! Constructs an instance from TStringBuf.
+ //! Copies the data into a ref-counted payload.
+ explicit TYsonString(
+ TStringBuf data,
+ EYsonType type = EYsonType::Node);
+
+ //! Constructs an instance from TString.
//! Zero-copy for CoW TString: retains the reference to TString in payload.
- explicit TYsonString(
+ explicit TYsonString(
const TString& data,
- EYsonType type = EYsonType::Node);
-
- //! Constructs an instance from TSharedRef.
- //! Zero-copy; retains the reference to TSharedRef holder in payload.
- explicit TYsonString(
- const TSharedRef& ref,
- EYsonType type = EYsonType::Node);
-
- //! Returns |true| if the instance is not null.
- explicit operator bool() const;
-
- //! Returns type of YSON contained here. The instance must be non-null.
- EYsonType GetType() const;
-
- //! Returns the non-owning data. The instance must be non-null.
- TStringBuf AsStringBuf() const;
-
- //! Returns the data represented by TString. The instance must be non-null.
- //! Copies the data in case the payload is not TString.
- TString ToString() const;
-
- //! Computes the hash code.
- size_t ComputeHash() const;
-
-private:
- struct TNullPayload
- { };
-
+ EYsonType type = EYsonType::Node);
+
+ //! Constructs an instance from TSharedRef.
+ //! Zero-copy; retains the reference to TSharedRef holder in payload.
+ explicit TYsonString(
+ const TSharedRef& ref,
+ EYsonType type = EYsonType::Node);
+
+ //! Returns |true| if the instance is not null.
+ explicit operator bool() const;
+
+ //! Returns type of YSON contained here. The instance must be non-null.
+ EYsonType GetType() const;
+
+ //! Returns the non-owning data. The instance must be non-null.
+ TStringBuf AsStringBuf() const;
+
+ //! Returns the data represented by TString. The instance must be non-null.
+ //! Copies the data in case the payload is not TString.
+ TString ToString() const;
+
+ //! Computes the hash code.
+ size_t ComputeHash() const;
+
+private:
+ struct TNullPayload
+ { };
+
using THolder = TRefCountedPtr;
- std::variant<TNullPayload, THolder, TString> Payload_;
-
- const char* Begin_;
- ui64 Size_ : 56;
- EYsonType Type_ : 8;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-bool operator == (const TYsonString& lhs, const TYsonString& rhs);
+ std::variant<TNullPayload, THolder, TString> Payload_;
+
+ const char* Begin_;
+ ui64 Size_ : 56;
+ EYsonType Type_ : 8;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+bool operator == (const TYsonString& lhs, const TYsonString& rhs);
bool operator == (const TYsonString& lhs, const TYsonStringBuf& rhs);
bool operator == (const TYsonStringBuf& lhs, const TYsonString& rhs);
bool operator == (const TYsonStringBuf& lhs, const TYsonStringBuf& rhs);
-bool operator != (const TYsonString& lhs, const TYsonString& rhs);
+bool operator != (const TYsonString& lhs, const TYsonString& rhs);
bool operator != (const TYsonString& lhs, const TYsonStringBuf& rhs);
bool operator != (const TYsonStringBuf& lhs, const TYsonString& rhs);
bool operator != (const TYsonStringBuf& lhs, const TYsonStringBuf& rhs);
-
+
TString ToString(const TYsonString& yson);
TString ToString(const TYsonStringBuf& yson);
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT::NYson
-
-#define STRING_INL_H_
-#include "string-inl.h"
-#undef STRING_INL_H_
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT::NYson
+
+#define STRING_INL_H_
+#include "string-inl.h"
+#undef STRING_INL_H_
diff --git a/library/cpp/yt/yson_string/unittests/convert_ut.cpp b/library/cpp/yt/yson_string/unittests/convert_ut.cpp
index 4050eb5889..3a64f63896 100644
--- a/library/cpp/yt/yson_string/unittests/convert_ut.cpp
+++ b/library/cpp/yt/yson_string/unittests/convert_ut.cpp
@@ -1,79 +1,79 @@
-#include <library/cpp/testing/gtest/gtest.h>
-
-#include <library/cpp/testing/gtest_extensions/assertions.h>
-
-#include <library/cpp/yt/yson_string/convert.h>
-
-#include <thread>
-
-namespace NYT::NYson {
-namespace {
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class T, class R = T, class U>
-void Check(const U& value)
-{
- auto str = ConvertToYsonString(static_cast<T>(value));
- auto anotherValue = ConvertFromYsonString<R>(str);
- EXPECT_EQ(static_cast<T>(value), anotherValue);
-}
-
-TEST(TConvertTest, Basic)
-{
- Check<i8>(13);
- Check<i32>(13);
- Check<i64>(13);
- Check<i8>(-13);
- Check<i32>(-13);
- Check<i64>(-13);
- Check<ui8>(13);
- Check<ui32>(13);
- Check<ui64>(13);
- Check<TString>("");
- Check<TString>("hello");
- Check<TStringBuf, TString>("hello");
- Check<const char*, TString>("hello");
- Check<float>(3.14);
- Check<double>(3.14);
- Check<bool>(true);
- Check<bool>(false);
- Check<TInstant>(TInstant::Now());
- Check<TDuration>(TDuration::Seconds(123));
- Check<TGuid>(TGuid::FromString("12345678-12345678-abcdabcd-fefefefe"));
-}
-
-TEST(TConvertTest, InRange)
-{
- EXPECT_EQ(ConvertFromYsonString<i16>(ConvertToYsonString(static_cast<i64>(-123))), -123);
- EXPECT_EQ(ConvertFromYsonString<ui16>(ConvertToYsonString(static_cast<ui64>(123))), 123U);
-}
-
-TEST(TConvertTest, OutOfRange)
-{
- EXPECT_THROW_MESSAGE_HAS_SUBSTR(
- ConvertFromYsonString<i8>(ConvertToYsonString(static_cast<i64>(128))),
- TYsonLiteralParseException,
- "is out of expected range");
- EXPECT_THROW_MESSAGE_HAS_SUBSTR(
- ConvertFromYsonString<ui8>(ConvertToYsonString(static_cast<ui64>(256))),
- TYsonLiteralParseException,
- "is out of expected range");
-}
-
-TEST(TConvertTest, MalformedValues)
-{
- EXPECT_THROW_MESSAGE_HAS_SUBSTR(
- ConvertFromYsonString<TInstant>(ConvertToYsonString(TStringBuf("sometime"))),
- TYsonLiteralParseException,
- "Error parsing \"instant\" value");
- EXPECT_THROW_MESSAGE_HAS_SUBSTR(
- ConvertFromYsonString<TGuid>(ConvertToYsonString(TStringBuf("1-2-3-g"))),
- TYsonLiteralParseException,
- "Error parsing \"guid\" value");
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace
-} // namespace NYT::NYson
+#include <library/cpp/testing/gtest/gtest.h>
+
+#include <library/cpp/testing/gtest_extensions/assertions.h>
+
+#include <library/cpp/yt/yson_string/convert.h>
+
+#include <thread>
+
+namespace NYT::NYson {
+namespace {
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T, class R = T, class U>
+void Check(const U& value)
+{
+ auto str = ConvertToYsonString(static_cast<T>(value));
+ auto anotherValue = ConvertFromYsonString<R>(str);
+ EXPECT_EQ(static_cast<T>(value), anotherValue);
+}
+
+TEST(TConvertTest, Basic)
+{
+ Check<i8>(13);
+ Check<i32>(13);
+ Check<i64>(13);
+ Check<i8>(-13);
+ Check<i32>(-13);
+ Check<i64>(-13);
+ Check<ui8>(13);
+ Check<ui32>(13);
+ Check<ui64>(13);
+ Check<TString>("");
+ Check<TString>("hello");
+ Check<TStringBuf, TString>("hello");
+ Check<const char*, TString>("hello");
+ Check<float>(3.14);
+ Check<double>(3.14);
+ Check<bool>(true);
+ Check<bool>(false);
+ Check<TInstant>(TInstant::Now());
+ Check<TDuration>(TDuration::Seconds(123));
+ Check<TGuid>(TGuid::FromString("12345678-12345678-abcdabcd-fefefefe"));
+}
+
+TEST(TConvertTest, InRange)
+{
+ EXPECT_EQ(ConvertFromYsonString<i16>(ConvertToYsonString(static_cast<i64>(-123))), -123);
+ EXPECT_EQ(ConvertFromYsonString<ui16>(ConvertToYsonString(static_cast<ui64>(123))), 123U);
+}
+
+TEST(TConvertTest, OutOfRange)
+{
+ EXPECT_THROW_MESSAGE_HAS_SUBSTR(
+ ConvertFromYsonString<i8>(ConvertToYsonString(static_cast<i64>(128))),
+ TYsonLiteralParseException,
+ "is out of expected range");
+ EXPECT_THROW_MESSAGE_HAS_SUBSTR(
+ ConvertFromYsonString<ui8>(ConvertToYsonString(static_cast<ui64>(256))),
+ TYsonLiteralParseException,
+ "is out of expected range");
+}
+
+TEST(TConvertTest, MalformedValues)
+{
+ EXPECT_THROW_MESSAGE_HAS_SUBSTR(
+ ConvertFromYsonString<TInstant>(ConvertToYsonString(TStringBuf("sometime"))),
+ TYsonLiteralParseException,
+ "Error parsing \"instant\" value");
+ EXPECT_THROW_MESSAGE_HAS_SUBSTR(
+ ConvertFromYsonString<TGuid>(ConvertToYsonString(TStringBuf("1-2-3-g"))),
+ TYsonLiteralParseException,
+ "Error parsing \"guid\" value");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace
+} // namespace NYT::NYson
diff --git a/library/cpp/yt/yson_string/unittests/ya.make b/library/cpp/yt/yson_string/unittests/ya.make
index aee36844f2..f327d298f1 100644
--- a/library/cpp/yt/yson_string/unittests/ya.make
+++ b/library/cpp/yt/yson_string/unittests/ya.make
@@ -1,15 +1,15 @@
-GTEST()
-
-OWNER(g:yt)
-
-SRCS(
- convert_ut.cpp
-)
-
-PEERDIR(
- library/cpp/yt/yson_string
- library/cpp/testing/gtest
- library/cpp/testing/gtest_extensions
-)
-
-END()
+GTEST()
+
+OWNER(g:yt)
+
+SRCS(
+ convert_ut.cpp
+)
+
+PEERDIR(
+ library/cpp/yt/yson_string
+ library/cpp/testing/gtest
+ library/cpp/testing/gtest_extensions
+)
+
+END()
diff --git a/library/cpp/yt/yson_string/ya.make b/library/cpp/yt/yson_string/ya.make
index ea57bc458d..b7447d89ff 100644
--- a/library/cpp/yt/yson_string/ya.make
+++ b/library/cpp/yt/yson_string/ya.make
@@ -1,21 +1,21 @@
-LIBRARY()
-
-SRCS(
- convert.cpp
- string.cpp
-)
-
-PEERDIR(
- library/cpp/yt/assert
- library/cpp/yt/coding
- library/cpp/yt/exception
- library/cpp/yt/string
- library/cpp/yt/memory
- library/cpp/yt/misc
-)
-
-END()
-
-RECURSE_FOR_TESTS(
- unittests
-)
+LIBRARY()
+
+SRCS(
+ convert.cpp
+ string.cpp
+)
+
+PEERDIR(
+ library/cpp/yt/assert
+ library/cpp/yt/coding
+ library/cpp/yt/exception
+ library/cpp/yt/string
+ library/cpp/yt/memory
+ library/cpp/yt/misc
+)
+
+END()
+
+RECURSE_FOR_TESTS(
+ unittests
+)