diff options
author | shakurov <shakurov@yandex-team.ru> | 2022-02-10 16:49:23 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:49:23 +0300 |
commit | 296627beeba9eb1fbc3cc1ff3dbae3ff192fb2a8 (patch) | |
tree | 5d5cb817648f650d76cf1076100726fd9b8448e8 /library/cpp | |
parent | 6750fac04a33847862ab7bfb19145f6f91207be6 (diff) | |
download | ydb-296627beeba9eb1fbc3cc1ff3dbae3ff192fb2a8.tar.gz |
Restoring authorship annotation for <shakurov@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'library/cpp')
-rw-r--r-- | library/cpp/binsaver/bin_saver.h | 74 | ||||
-rw-r--r-- | library/cpp/binsaver/blob_io.h | 4 | ||||
-rw-r--r-- | library/cpp/binsaver/buffered_io.cpp | 56 | ||||
-rw-r--r-- | library/cpp/binsaver/buffered_io.h | 46 | ||||
-rw-r--r-- | library/cpp/binsaver/mem_io.h | 6 | ||||
-rw-r--r-- | library/cpp/yt/memory/range.h | 24 | ||||
-rw-r--r-- | library/cpp/yt/memory/ref.h | 4 | ||||
-rw-r--r-- | library/cpp/yt/misc/cast-inl.h | 160 | ||||
-rw-r--r-- | library/cpp/yt/misc/cast.h | 48 | ||||
-rw-r--r-- | library/cpp/yt/misc/variant.h | 66 | ||||
-rw-r--r-- | library/cpp/yt/small_containers/compact_flat_map-inl.h | 242 | ||||
-rw-r--r-- | library/cpp/yt/small_containers/compact_flat_map.h | 184 | ||||
-rw-r--r-- | library/cpp/yt/small_containers/compact_set-inl.h | 604 | ||||
-rw-r--r-- | library/cpp/yt/small_containers/compact_set.h | 70 | ||||
-rw-r--r-- | library/cpp/yt/string/format-inl.h | 46 | ||||
-rw-r--r-- | library/cpp/yt/string/format.h | 26 | ||||
-rw-r--r-- | library/cpp/yt/yson_string/string.cpp | 2 |
17 files changed, 831 insertions, 831 deletions
diff --git a/library/cpp/binsaver/bin_saver.h b/library/cpp/binsaver/bin_saver.h index 6ba6364626..412424889f 100644 --- a/library/cpp/binsaver/bin_saver.h +++ b/library/cpp/binsaver/bin_saver.h @@ -46,7 +46,7 @@ namespace NBinSaverInternals { struct IBinSaver { public: typedef unsigned char chunk_id; - typedef ui32 TStoredSize; // changing this will break compatibility + typedef ui32 TStoredSize; // changing this will break compatibility private: // This overload is required to avoid infinite recursion when overriding serialization in derived classes: @@ -85,20 +85,20 @@ private: // vector template <class T, class TA> void DoVector(TVector<T, TA>& data) { - TStoredSize nSize; + TStoredSize nSize; if (IsReading()) { data.clear(); Add(2, &nSize); data.resize(nSize); } else { - nSize = data.size(); - CheckOverflow(nSize, data.size()); + nSize = data.size(); + CheckOverflow(nSize, data.size()); Add(2, &nSize); } - for (TStoredSize i = 0; i < nSize; i++) + for (TStoredSize i = 0; i < nSize; i++) Add(1, &data[i]); } - + template <class T, int N> void DoArray(T (&data)[N]) { for (size_t i = 0; i < N; i++) { @@ -108,16 +108,16 @@ private: template <typename TLarge> void CheckOverflow(TStoredSize nSize, TLarge origSize) { - if (nSize != origSize) { - fprintf(stderr, "IBinSaver: object size is too large to be serialized (%" PRIu32 " != %" PRIu64 ")\n", nSize, (ui64)origSize); - abort(); - } - } - + if (nSize != origSize) { + fprintf(stderr, "IBinSaver: object size is too large to be serialized (%" PRIu32 " != %" PRIu64 ")\n", nSize, (ui64)origSize); + abort(); + } + } + template <class T, class TA> void DoDataVector(TVector<T, TA>& data) { - TStoredSize nSize = data.size(); - CheckOverflow(nSize, data.size()); + TStoredSize nSize = data.size(); + CheckOverflow(nSize, data.size()); Add(1, &nSize); if (IsReading()) { data.clear(); @@ -131,22 +131,22 @@ private: void DoAnyMap(AM& data) { if (IsReading()) { data.clear(); - TStoredSize nSize; + TStoredSize nSize; Add(3, &nSize); TVector<typename AM::key_type, typename std::allocator_traits<typename AM::allocator_type>::template rebind_alloc<typename AM::key_type>> indices; indices.resize(nSize); - for (TStoredSize i = 0; i < nSize; ++i) + for (TStoredSize i = 0; i < nSize; ++i) Add(1, &indices[i]); - for (TStoredSize i = 0; i < nSize; ++i) + for (TStoredSize i = 0; i < nSize; ++i) Add(2, &data[indices[i]]); } else { - TStoredSize nSize = data.size(); - CheckOverflow(nSize, data.size()); + TStoredSize nSize = data.size(); + CheckOverflow(nSize, data.size()); Add(3, &nSize); TVector<typename AM::key_type, typename std::allocator_traits<typename AM::allocator_type>::template rebind_alloc<typename AM::key_type>> indices; indices.resize(nSize); - TStoredSize i = 1; + TStoredSize i = 1; for (auto pos = data.begin(); pos != data.end(); ++pos, ++i) indices[nSize - i] = pos->first; for (TStoredSize j = 0; j < nSize; ++j) @@ -161,21 +161,21 @@ private: void DoAnyMultiMap(AMM& data) { if (IsReading()) { data.clear(); - TStoredSize nSize; + TStoredSize nSize; Add(3, &nSize); TVector<typename AMM::key_type, typename std::allocator_traits<typename AMM::allocator_type>::template rebind_alloc<typename AMM::key_type>> indices; indices.resize(nSize); - for (TStoredSize i = 0; i < nSize; ++i) + for (TStoredSize i = 0; i < nSize; ++i) Add(1, &indices[i]); - for (TStoredSize i = 0; i < nSize; ++i) { + for (TStoredSize i = 0; i < nSize; ++i) { std::pair<typename AMM::key_type, typename AMM::mapped_type> valToInsert; valToInsert.first = indices[i]; Add(2, &valToInsert.second); data.insert(valToInsert); } } else { - TStoredSize nSize = data.size(); - CheckOverflow(nSize, data.size()); + TStoredSize nSize = data.size(); + CheckOverflow(nSize, data.size()); Add(3, &nSize); for (auto pos = data.begin(); pos != data.end(); ++pos) Add(1, (typename AMM::key_type*)(&pos->first)); @@ -188,16 +188,16 @@ private: void DoAnySet(T& data) { if (IsReading()) { data.clear(); - TStoredSize nSize; + TStoredSize nSize; Add(2, &nSize); - for (TStoredSize i = 0; i < nSize; ++i) { + for (TStoredSize i = 0; i < nSize; ++i) { typename T::value_type member; Add(1, &member); data.insert(member); } } else { - TStoredSize nSize = data.size(); - CheckOverflow(nSize, data.size()); + TStoredSize nSize = data.size(); + CheckOverflow(nSize, data.size()); Add(2, &nSize); for (const auto& elem : data) { auto member = elem; @@ -231,15 +231,15 @@ private: template <class TStringType> void DataChunkStr(TStringType& data, i64 elemSize) { if (bRead) { - TStoredSize nCount = 0; - File.Read(&nCount, sizeof(TStoredSize)); + TStoredSize nCount = 0; + File.Read(&nCount, sizeof(TStoredSize)); data.resize(nCount); if (nCount) File.Read(&*data.begin(), nCount * elemSize); } else { - TStoredSize nCount = data.size(); - CheckOverflow(nCount, data.size()); - File.Write(&nCount, sizeof(TStoredSize)); + TStoredSize nCount = data.size(); + CheckOverflow(nCount, data.size()); + File.Write(&nCount, sizeof(TStoredSize)); File.Write(data.c_str(), nCount * elemSize); } } @@ -254,10 +254,10 @@ private: } void DataChunk(void* pData, i64 nSize) { - i64 chunkSize = 1 << 30; - for (i64 offset = 0; offset < nSize; offset += chunkSize) { + i64 chunkSize = 1 << 30; + for (i64 offset = 0; offset < nSize; offset += chunkSize) { void* ptr = (char*)pData + offset; - i64 size = offset + chunkSize < nSize ? chunkSize : (nSize - offset); + i64 size = offset + chunkSize < nSize ? chunkSize : (nSize - offset); if (bRead) File.Read(ptr, size); else diff --git a/library/cpp/binsaver/blob_io.h b/library/cpp/binsaver/blob_io.h index e83e00bc4c..abe518ef30 100644 --- a/library/cpp/binsaver/blob_io.h +++ b/library/cpp/binsaver/blob_io.h @@ -7,7 +7,7 @@ class TYaBlobStream: public IBinaryStream { TBlob Blob; - i64 Pos; + i64 Pos; int WriteImpl(const void*, int) override { Y_ASSERT(0); @@ -16,7 +16,7 @@ class TYaBlobStream: public IBinaryStream { int ReadImpl(void* userBuffer, int size) override { if (size == 0) return 0; - i64 res = Min<i64>(Blob.Length() - Pos, size); + i64 res = Min<i64>(Blob.Length() - Pos, size); if (res) memcpy(userBuffer, ((const char*)Blob.Data()) + Pos, res); Pos += res; diff --git a/library/cpp/binsaver/buffered_io.cpp b/library/cpp/binsaver/buffered_io.cpp index da9cef5da4..dd88b04bc5 100644 --- a/library/cpp/binsaver/buffered_io.cpp +++ b/library/cpp/binsaver/buffered_io.cpp @@ -3,37 +3,37 @@ i64 IBinaryStream::LongWrite(const void* userBuffer, i64 size) { Y_VERIFY(size >= 0, "IBinaryStream::Write() called with a negative buffer size."); - i64 leftToWrite = size; - while (leftToWrite != 0) { - int writeSz = static_cast<int>(Min<i64>(leftToWrite, std::numeric_limits<int>::max())); - int written = WriteImpl(userBuffer, writeSz); + i64 leftToWrite = size; + while (leftToWrite != 0) { + int writeSz = static_cast<int>(Min<i64>(leftToWrite, std::numeric_limits<int>::max())); + int written = WriteImpl(userBuffer, writeSz); Y_ASSERT(written <= writeSz); - leftToWrite -= written; - // Assumption: if WriteImpl(buf, writeSz) returns < writeSz, the stream is - // full and there's no sense in continuing. - if (written < writeSz) - break; - } + leftToWrite -= written; + // Assumption: if WriteImpl(buf, writeSz) returns < writeSz, the stream is + // full and there's no sense in continuing. + if (written < writeSz) + break; + } Y_ASSERT(size >= leftToWrite); - return size - leftToWrite; -} - + return size - leftToWrite; +} + i64 IBinaryStream::LongRead(void* userBuffer, i64 size) { Y_VERIFY(size >= 0, "IBinaryStream::Read() called with a negative buffer size."); - - i64 leftToRead = size; - while (leftToRead != 0) { - int readSz = static_cast<int>(Min<i64>(leftToRead, std::numeric_limits<int>::max())); - int read = ReadImpl(userBuffer, readSz); + + i64 leftToRead = size; + while (leftToRead != 0) { + int readSz = static_cast<int>(Min<i64>(leftToRead, std::numeric_limits<int>::max())); + int read = ReadImpl(userBuffer, readSz); Y_ASSERT(read <= readSz); - leftToRead -= read; - // Assumption: if ReadImpl(buf, readSz) returns < readSz, the stream is - // full and there's no sense in continuing. - if (read < readSz) { - memset(static_cast<char*>(userBuffer) + (size - leftToRead), 0, leftToRead); - break; - } - } + leftToRead -= read; + // Assumption: if ReadImpl(buf, readSz) returns < readSz, the stream is + // full and there's no sense in continuing. + if (read < readSz) { + memset(static_cast<char*>(userBuffer) + (size - leftToRead), 0, leftToRead); + break; + } + } Y_ASSERT(size >= leftToRead); - return size - leftToRead; -} + return size - leftToRead; +} diff --git a/library/cpp/binsaver/buffered_io.h b/library/cpp/binsaver/buffered_io.h index 80ad1a0937..75465c9c5c 100644 --- a/library/cpp/binsaver/buffered_io.h +++ b/library/cpp/binsaver/buffered_io.h @@ -1,37 +1,37 @@ #pragma once #include <util/system/yassert.h> -#include <util/generic/utility.h> -#include <util/generic/ylimits.h> +#include <util/generic/utility.h> +#include <util/generic/ylimits.h> #include <string.h> struct IBinaryStream { virtual ~IBinaryStream() = default; ; - + inline i64 Write(const void* userBuffer, i64 size) { - if (size <= Max<int>()) { - return WriteImpl(userBuffer, static_cast<int>(size)); - } else { - return LongWrite(userBuffer, size); - } - } - + if (size <= Max<int>()) { + return WriteImpl(userBuffer, static_cast<int>(size)); + } else { + return LongWrite(userBuffer, size); + } + } + inline i64 Read(void* userBuffer, i64 size) { - if (size <= Max<int>()) { - return ReadImpl(userBuffer, static_cast<int>(size)); - } else { - return LongRead(userBuffer, size); - } - } - + if (size <= Max<int>()) { + return ReadImpl(userBuffer, static_cast<int>(size)); + } else { + return LongRead(userBuffer, size); + } + } + virtual bool IsValid() const = 0; virtual bool IsFailed() const = 0; - -private: + +private: virtual int WriteImpl(const void* userBuffer, int size) = 0; virtual int ReadImpl(void* userBuffer, int size) = 0; - + i64 LongRead(void* userBuffer, i64 size); i64 LongWrite(const void* userBuffer, i64 size); }; @@ -39,7 +39,7 @@ private: template <int N_SIZE = 16384> class TBufferedStream { char Buf[N_SIZE]; - i64 Pos, BufSize; + i64 Pos, BufSize; IBinaryStream& Stream; bool bIsReading, bIsEof, bFailed; @@ -49,13 +49,13 @@ class TBufferedStream { return; } char* dst = (char*)userBuffer; - i64 leftBytes = BufSize - Pos; + i64 leftBytes = BufSize - Pos; memcpy(dst, Buf + Pos, leftBytes); dst += leftBytes; size -= leftBytes; Pos = BufSize = 0; if (size > N_SIZE) { - i64 n = Stream.Read(dst, size); + i64 n = Stream.Read(dst, size); bFailed = Stream.IsFailed(); if (n != size) { bIsEof = true; diff --git a/library/cpp/binsaver/mem_io.h b/library/cpp/binsaver/mem_io.h index 5b8696cc76..2a9e36fe68 100644 --- a/library/cpp/binsaver/mem_io.h +++ b/library/cpp/binsaver/mem_io.h @@ -83,18 +83,18 @@ namespace NMemIoInternals { , ShrinkOnRead(shrinkOnRead) { Y_ASSERT(!data->empty()); - } + } ~THugeMemoryStream() override { } // keep gcc happy bool IsValid() const override { return true; - } + } bool IsFailed() const override { return false; } - + private: int WriteImpl(const void* userDataArg, int sizeArg) override { if (sizeArg == 0) diff --git a/library/cpp/yt/memory/range.h b/library/cpp/yt/memory/range.h index 079ce3e6ac..6c71aa9496 100644 --- a/library/cpp/yt/memory/range.h +++ b/library/cpp/yt/memory/range.h @@ -367,23 +367,23 @@ public: return const_cast<T*>(this->Data_); } - // STL interop, for gcc. - iterator begin() const - { - return Begin(); - } - + // STL interop, for gcc. + iterator begin() const + { + return Begin(); + } + iterator End() const { return this->Begin() + this->Size(); } - // STL interop, for gcc. - iterator end() const - { - return End(); - } - + // STL interop, for gcc. + iterator end() const + { + return End(); + } + T& operator[](size_t index) { YT_ASSERT(index <= this->Size()); diff --git a/library/cpp/yt/memory/ref.h b/library/cpp/yt/memory/ref.h index 94a215f6ac..73d19d9013 100644 --- a/library/cpp/yt/memory/ref.h +++ b/library/cpp/yt/memory/ref.h @@ -94,8 +94,8 @@ public: //! 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. + * Each newly allocated TSharedRef blob is associated with a tag type + * that appears in ref-counted statistics. */ struct TDefaultSharedBlobTag { }; diff --git a/library/cpp/yt/misc/cast-inl.h b/library/cpp/yt/misc/cast-inl.h index b87f77793c..1920b7c0b7 100644 --- a/library/cpp/yt/misc/cast-inl.h +++ b/library/cpp/yt/misc/cast-inl.h @@ -1,44 +1,44 @@ -#ifndef CAST_INL_H_ -#error "Direct inclusion of this file is not allowed, include cast.h" +#ifndef CAST_INL_H_ +#error "Direct inclusion of this file is not allowed, include cast.h" // For the sake of sane code completion. #include "cast.h" -#endif - +#endif + #include <util/string/cast.h> #include <util/string/printf.h> -#include <type_traits> - -namespace NYT { - -//////////////////////////////////////////////////////////////////////////////// - -namespace NDetail { - -template <class T, class S> -typename std::enable_if<std::is_signed<T>::value && std::is_signed<S>::value, bool>::type IsInIntegralRange(S value) -{ - return value >= std::numeric_limits<T>::min() && value <= std::numeric_limits<T>::max(); -} - -template <class T, class S> -static typename std::enable_if<std::is_signed<T>::value && std::is_unsigned<S>::value, bool>::type IsInIntegralRange(S value) -{ - return value <= static_cast<typename std::make_unsigned<T>::type>(std::numeric_limits<T>::max()); -} - -template <class T, class S> -static typename std::enable_if<std::is_unsigned<T>::value && std::is_signed<S>::value, bool>::type IsInIntegralRange(S value) -{ - return value >= 0 && static_cast<typename std::make_unsigned<S>::type>(value) <= std::numeric_limits<T>::max(); -} - -template <class T, class S> -typename std::enable_if<std::is_unsigned<T>::value && std::is_unsigned<S>::value, bool>::type IsInIntegralRange(S value) -{ - return value <= std::numeric_limits<T>::max(); -} - +#include <type_traits> + +namespace NYT { + +//////////////////////////////////////////////////////////////////////////////// + +namespace NDetail { + +template <class T, class S> +typename std::enable_if<std::is_signed<T>::value && std::is_signed<S>::value, bool>::type IsInIntegralRange(S value) +{ + return value >= std::numeric_limits<T>::min() && value <= std::numeric_limits<T>::max(); +} + +template <class T, class S> +static typename std::enable_if<std::is_signed<T>::value && std::is_unsigned<S>::value, bool>::type IsInIntegralRange(S value) +{ + return value <= static_cast<typename std::make_unsigned<T>::type>(std::numeric_limits<T>::max()); +} + +template <class T, class S> +static typename std::enable_if<std::is_unsigned<T>::value && std::is_signed<S>::value, bool>::type IsInIntegralRange(S value) +{ + return value >= 0 && static_cast<typename std::make_unsigned<S>::type>(value) <= std::numeric_limits<T>::max(); +} + +template <class T, class S> +typename std::enable_if<std::is_unsigned<T>::value && std::is_unsigned<S>::value, bool>::type IsInIntegralRange(S value) +{ + return value <= std::numeric_limits<T>::max(); +} + template <class T> TString FormatInvalidCastValue(T value) { @@ -62,52 +62,52 @@ inline TString FormatInvalidCastValue(char8_t value) } #endif -} // namespace NDetail - -template <class T, class S> -bool TryIntegralCast(S value, T* result) -{ - if (!NDetail::IsInIntegralRange<T>(value)) { - return false; - } - *result = static_cast<T>(value); - return true; -} - -template <class T, class S> -T CheckedIntegralCast(S value) -{ - T result; - if (!TryIntegralCast<T>(value, &result)) { +} // namespace NDetail + +template <class T, class S> +bool TryIntegralCast(S value, T* result) +{ + if (!NDetail::IsInIntegralRange<T>(value)) { + return false; + } + *result = static_cast<T>(value); + return true; +} + +template <class T, class S> +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())); - } - return result; -} - -template <class T, class S> -bool TryEnumCast(S value, T* result) -{ - auto candidate = static_cast<T>(value); - if (!TEnumTraits<T>::FindLiteralByValue(candidate)) { - return false; - } - *result = candidate; - return true; -} - -template <class T, class S> -T CheckedEnumCast(S value) -{ - T result; - if (!TryEnumCast<T>(value, &result)) { + } + return result; +} + +template <class T, class S> +bool TryEnumCast(S value, T* result) +{ + auto candidate = static_cast<T>(value); + if (!TEnumTraits<T>::FindLiteralByValue(candidate)) { + return false; + } + *result = candidate; + return true; +} + +template <class T, class S> +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())); - } - return result; -} - -//////////////////////////////////////////////////////////////////////////////// - -} // namespace NYT + } + return result; +} + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT diff --git a/library/cpp/yt/misc/cast.h b/library/cpp/yt/misc/cast.h index 1a043907b6..c7565c9e6d 100644 --- a/library/cpp/yt/misc/cast.h +++ b/library/cpp/yt/misc/cast.h @@ -1,29 +1,29 @@ -#pragma once - +#pragma once + #include <library/cpp/yt/exception/exception.h> -namespace NYT { - -//////////////////////////////////////////////////////////////////////////////// - -template <class T, class S> -bool TryIntegralCast(S value, T* result); - -template <class T, class S> -T CheckedIntegralCast(S value); - +namespace NYT { + +//////////////////////////////////////////////////////////////////////////////// + +template <class T, class S> +bool TryIntegralCast(S value, T* result); + +template <class T, class S> +T CheckedIntegralCast(S value); + //////////////////////////////////////////////////////////////////////////////// -template <class T, class S> +template <class T, class S> bool TryEnumCast(S value, T* result); - -template <class T, class S> -T CheckedEnumCast(S value); - -//////////////////////////////////////////////////////////////////////////////// - -} // namespace NYT - -#define CAST_INL_H_ -#include "cast-inl.h" -#undef CAST_INL_H_ + +template <class T, class S> +T CheckedEnumCast(S value); + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT + +#define CAST_INL_H_ +#include "cast-inl.h" +#undef CAST_INL_H_ diff --git a/library/cpp/yt/misc/variant.h b/library/cpp/yt/misc/variant.h index d5bacda74c..27c0a2bc08 100644 --- a/library/cpp/yt/misc/variant.h +++ b/library/cpp/yt/misc/variant.h @@ -36,39 +36,39 @@ 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: - * - * std::visit(TOverloaded{ - * [] (int i) { printf("The variant holds an int: %d!", i); }, - * [] (const std::string& s) { printf("The variant holds a string: '%s'!", s); } - * }, variantVariable); - */ -template<class... Ts> struct TOverloaded : Ts... { using Ts::operator()...; }; -template<class... Ts> TOverloaded(Ts...) -> TOverloaded<Ts...>; - -//////////////////////////////////////////////////////////////////////////////// - -//! An alternative to std::visit that takes its variant argument first. -/*! - * This deprives it of being able to visit a Cartesian product of variants but - * in exchange allows to receive multiple visitor functors. All of operator()s - * these functors have are used to visit the variant after a single unified - * overload resolution. For example: - * - * Visit(variantVariable, - * [] (int i) { printf("The variant holds an int: %d!", i); }, - * [] (const std::string& s) { printf("The variant holds a string: '%s'!", s); }); - */ -template <class T, class... U> -auto Visit(T&& variant, U&&... visitorOverloads) -{ - return std::visit(TOverloaded{std::forward<U>(visitorOverloads)...}, std::forward<T>(variant)); -} - -//////////////////////////////////////////////////////////////////////////////// - +//! A concise way of creating a functor with an overloaded operator(). +/*! + * Very useful for std::visit-ing variants. For example: + * + * std::visit(TOverloaded{ + * [] (int i) { printf("The variant holds an int: %d!", i); }, + * [] (const std::string& s) { printf("The variant holds a string: '%s'!", s); } + * }, variantVariable); + */ +template<class... Ts> struct TOverloaded : Ts... { using Ts::operator()...; }; +template<class... Ts> TOverloaded(Ts...) -> TOverloaded<Ts...>; + +//////////////////////////////////////////////////////////////////////////////// + +//! An alternative to std::visit that takes its variant argument first. +/*! + * This deprives it of being able to visit a Cartesian product of variants but + * in exchange allows to receive multiple visitor functors. All of operator()s + * these functors have are used to visit the variant after a single unified + * overload resolution. For example: + * + * Visit(variantVariable, + * [] (int i) { printf("The variant holds an int: %d!", i); }, + * [] (const std::string& s) { printf("The variant holds a string: '%s'!", s); }); + */ +template <class T, class... U> +auto Visit(T&& variant, U&&... visitorOverloads) +{ + return std::visit(TOverloaded{std::forward<U>(visitorOverloads)...}, std::forward<T>(variant)); +} + +//////////////////////////////////////////////////////////////////////////////// + } // namespace NYT #define VARIANT_INL_H_ diff --git a/library/cpp/yt/small_containers/compact_flat_map-inl.h b/library/cpp/yt/small_containers/compact_flat_map-inl.h index b3ddb14c59..45a4dd1de3 100644 --- a/library/cpp/yt/small_containers/compact_flat_map-inl.h +++ b/library/cpp/yt/small_containers/compact_flat_map-inl.h @@ -1,21 +1,21 @@ #ifndef COMPACT_FLAT_MAP_INL_H_ #error "Direct inclusion of this file is not allowed, include compact_flat_map.h" -// For the sake of sane code completion. +// For the sake of sane code completion. #include "compact_flat_map.h" -#endif - -namespace NYT { - -/////////////////////////////////////////////////////////////////////////////// - -template <class K, class V, unsigned N> -template <class TInputIterator> +#endif + +namespace NYT { + +/////////////////////////////////////////////////////////////////////////////// + +template <class K, class V, unsigned N> +template <class TInputIterator> TCompactFlatMap<K, V, N>::TCompactFlatMap(TInputIterator begin, TInputIterator end) -{ - insert(begin, end); -} - -template <class K, class V, unsigned N> +{ + insert(begin, end); +} + +template <class K, class V, unsigned N> bool TCompactFlatMap<K, V, N>::operator==(const TCompactFlatMap& rhs) const { return Storage_ == rhs.Storage_; @@ -29,73 +29,73 @@ bool TCompactFlatMap<K, V, N>::operator!=(const TCompactFlatMap& rhs) const template <class K, class V, unsigned N> typename TCompactFlatMap<K, V, N>::iterator TCompactFlatMap<K, V, N>::begin() -{ - return Storage_.begin(); -} - -template <class K, class V, unsigned N> +{ + return Storage_.begin(); +} + +template <class K, class V, unsigned N> typename TCompactFlatMap<K, V, N>::const_iterator TCompactFlatMap<K, V, N>::begin() const -{ - return Storage_.begin(); -} - -template <class K, class V, unsigned N> +{ + return Storage_.begin(); +} + +template <class K, class V, unsigned N> typename TCompactFlatMap<K, V, N>::iterator TCompactFlatMap<K, V, N>::end() -{ - return Storage_.end(); -} - -template <class K, class V, unsigned N> +{ + return Storage_.end(); +} + +template <class K, class V, unsigned N> typename TCompactFlatMap<K, V, N>::const_iterator TCompactFlatMap<K, V, N>::end() const -{ - return Storage_.end(); -} - -template <class K, class V, unsigned N> +{ + return Storage_.end(); +} + +template <class K, class V, unsigned N> void TCompactFlatMap<K, V, N>::reserve(size_type n) -{ - Storage_.reserve(n); -} - -template <class K, class V, unsigned N> +{ + Storage_.reserve(n); +} + +template <class K, class V, unsigned N> typename TCompactFlatMap<K, V, N>::size_type TCompactFlatMap<K, V, N>::size() const -{ - return Storage_.size(); -} - -template <class K, class V, unsigned N> +{ + return Storage_.size(); +} + +template <class K, class V, unsigned N> int TCompactFlatMap<K, V, N>::ssize() const -{ - return static_cast<int>(Storage_.size()); -} - -template <class K, class V, unsigned N> +{ + return static_cast<int>(Storage_.size()); +} + +template <class K, class V, unsigned N> bool TCompactFlatMap<K, V, N>::empty() const -{ - return Storage_.empty(); -} - -template <class K, class V, unsigned N> +{ + return Storage_.empty(); +} + +template <class K, class V, unsigned N> void TCompactFlatMap<K, V, N>::clear() -{ - Storage_.clear(); -} - -template <class K, class V, unsigned N> +{ + Storage_.clear(); +} + +template <class K, class V, unsigned N> typename TCompactFlatMap<K, V, N>::iterator TCompactFlatMap<K, V, N>::find(const K& k) -{ - auto [rangeBegin, rangeEnd] = EqualRange(k); - return rangeBegin == rangeEnd ? end() : rangeBegin; -} - -template <class K, class V, unsigned N> +{ + auto [rangeBegin, rangeEnd] = EqualRange(k); + return rangeBegin == rangeEnd ? end() : rangeBegin; +} + +template <class K, class V, unsigned N> typename TCompactFlatMap<K, V, N>::const_iterator TCompactFlatMap<K, V, N>::find(const K& k) const -{ - auto [rangeBegin, rangeEnd] = EqualRange(k); - return rangeBegin == rangeEnd ? end() : rangeBegin; -} - -template <class K, class V, unsigned N> +{ + auto [rangeBegin, rangeEnd] = EqualRange(k); + return rangeBegin == rangeEnd ? end() : rangeBegin; +} + +template <class K, class V, unsigned N> bool TCompactFlatMap<K, V, N>::contains(const K& k) const { return find(k) != end(); @@ -103,26 +103,26 @@ bool TCompactFlatMap<K, V, N>::contains(const K& k) const template <class K, class V, unsigned N> auto TCompactFlatMap<K, V, N>::insert(const value_type& value) -> std::pair<iterator, bool> -{ - auto [rangeBegin, rangeEnd] = EqualRange(value.first); - if (rangeBegin != rangeEnd) { - return {rangeBegin, false}; - } else { +{ + auto [rangeBegin, rangeEnd] = EqualRange(value.first); + if (rangeBegin != rangeEnd) { + return {rangeBegin, false}; + } else { auto it = Storage_.insert(rangeBegin, value); return {it, true}; - } -} - -template <class K, class V, unsigned N> -template <class TInputIterator> + } +} + +template <class K, class V, unsigned N> +template <class TInputIterator> void TCompactFlatMap<K, V, N>::insert(TInputIterator begin, TInputIterator end) -{ - for (auto it = begin; it != end; ++it) { - insert(*it); - } -} - -template <class K, class V, unsigned N> +{ + for (auto it = begin; it != end; ++it) { + insert(*it); + } +} + +template <class K, class V, unsigned N> template <class... TArgs> auto TCompactFlatMap<K, V, N>::emplace(TArgs&&... args) -> std::pair<iterator, bool> { @@ -131,19 +131,19 @@ auto TCompactFlatMap<K, V, N>::emplace(TArgs&&... args) -> std::pair<iterator, b template <class K, class V, unsigned N> V& TCompactFlatMap<K, V, N>::operator[](const K& k) -{ - auto [it, inserted] = insert({k, V()}); - return it->second; -} - -template <class K, class V, unsigned N> +{ + auto [it, inserted] = insert({k, V()}); + return it->second; +} + +template <class K, class V, unsigned N> void TCompactFlatMap<K, V, N>::erase(const K& k) -{ - auto [rangeBegin, rangeEnd] = EqualRange(k); - erase(rangeBegin, rangeEnd); -} - -template <class K, class V, unsigned N> +{ + auto [rangeBegin, rangeEnd] = EqualRange(k); + erase(rangeBegin, rangeEnd); +} + +template <class K, class V, unsigned N> void TCompactFlatMap<K, V, N>::erase(iterator pos) { Storage_.erase(pos); @@ -154,31 +154,31 @@ void TCompactFlatMap<K, V, N>::erase(iterator pos) template <class K, class V, unsigned N> void TCompactFlatMap<K, V, N>::erase(iterator b, iterator e) -{ - Storage_.erase(b, e); +{ + Storage_.erase(b, e); // Try to keep the storage inline. This is why erase doesn't return an iterator. Storage_.shrink_to_small(); -} - -template <class K, class V, unsigned N> +} + +template <class K, class V, unsigned N> std::pair<typename TCompactFlatMap<K, V, N>::iterator, typename TCompactFlatMap<K, V, N>::iterator> TCompactFlatMap<K, V, N>::EqualRange(const K& k) -{ - auto result = std::equal_range(Storage_.begin(), Storage_.end(), k, TKeyComparer()); - YT_ASSERT(std::distance(result.first, result.second) <= 1); - return result; -} - -template <class K, class V, unsigned N> +{ + auto result = std::equal_range(Storage_.begin(), Storage_.end(), k, TKeyComparer()); + YT_ASSERT(std::distance(result.first, result.second) <= 1); + return result; +} + +template <class K, class V, unsigned N> std::pair<typename TCompactFlatMap<K, V, N>::const_iterator, typename TCompactFlatMap<K, V, N>::const_iterator> TCompactFlatMap<K, V, N>::EqualRange(const K& k) const -{ - auto result = std::equal_range(Storage_.begin(), Storage_.end(), k, TKeyComparer()); - YT_ASSERT(std::distance(result.first, result.second) <= 1); - return result; -} - -//////////////////////////////////////////////////////////////////////////////// - -} // namespace NYT +{ + auto result = std::equal_range(Storage_.begin(), Storage_.end(), k, TKeyComparer()); + YT_ASSERT(std::distance(result.first, result.second) <= 1); + return result; +} + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT diff --git a/library/cpp/yt/small_containers/compact_flat_map.h b/library/cpp/yt/small_containers/compact_flat_map.h index 1cd1bfab63..13bdc0e9da 100644 --- a/library/cpp/yt/small_containers/compact_flat_map.h +++ b/library/cpp/yt/small_containers/compact_flat_map.h @@ -1,109 +1,109 @@ -#pragma once - +#pragma once + #include "compact_vector.h" - -namespace NYT { - -/////////////////////////////////////////////////////////////////////////////// - + +namespace NYT { + +/////////////////////////////////////////////////////////////////////////////// + //! A flat map implementation over TCompactVector that tries to keep data inline. -/*! - * Similarly to SmallSet, this is implemented via binary search over a sorted - * vector. Unlike SmallSet, however, this one never falls back to std::map (or - * set) for larger sizes. This means that the flat map is only useful - * - at small sizes, when there's absolutely no chance of it getting big, or - * - when it's filled once and is then only read from. - * - * In return, the flat map provides - * - a smaller size overhead and - * - a guarantee that if data fits into inline storage, it goes there. - * - * Because of the latter, one should be very careful with iterators: virtually - * any call to insert or erase may potentially invalidate all iterators. - */ -template <class K, class V, unsigned N> +/*! + * Similarly to SmallSet, this is implemented via binary search over a sorted + * vector. Unlike SmallSet, however, this one never falls back to std::map (or + * set) for larger sizes. This means that the flat map is only useful + * - at small sizes, when there's absolutely no chance of it getting big, or + * - when it's filled once and is then only read from. + * + * In return, the flat map provides + * - a smaller size overhead and + * - a guarantee that if data fits into inline storage, it goes there. + * + * Because of the latter, one should be very careful with iterators: virtually + * any call to insert or erase may potentially invalidate all iterators. + */ +template <class K, class V, unsigned N> class TCompactFlatMap -{ -public: +{ +public: // NB: can't make this pair<const K, V> as TCompactVector requires its type - // parameter to be copy-assignable. - using value_type = std::pair<K, V>; + // parameter to be copy-assignable. + using value_type = std::pair<K, V>; using key_type = K; using mapped_type = V; - -private: + +private: using TStorage = TCompactVector<value_type, N>; - - struct TKeyComparer - { - bool operator()(const K& lhs, const value_type& rhs) - { - return lhs < rhs.first; - } - - bool operator()(const value_type& lhs, const K& rhs) - { - return lhs.first < rhs; - } - }; - -public: - using iterator = typename TStorage::iterator; - using const_iterator = typename TStorage::const_iterator; - using size_type = size_t; - + + struct TKeyComparer + { + bool operator()(const K& lhs, const value_type& rhs) + { + return lhs < rhs.first; + } + + bool operator()(const value_type& lhs, const K& rhs) + { + return lhs.first < rhs; + } + }; + +public: + using iterator = typename TStorage::iterator; + using const_iterator = typename TStorage::const_iterator; + using size_type = size_t; + TCompactFlatMap() = default; - - template <class TInputIterator> + + template <class TInputIterator> TCompactFlatMap(TInputIterator begin, TInputIterator end); - + bool operator==(const TCompactFlatMap& rhs) const; bool operator!=(const TCompactFlatMap& rhs) const; - - iterator begin(); - const_iterator begin() const; - - iterator end(); - const_iterator end() const; - - void reserve(size_type n); - - size_type size() const; - int ssize() const; - - bool empty() const; - void clear(); - - iterator find(const K& k); - const_iterator find(const K& k) const; - - bool contains(const K& k) const; - - std::pair<iterator, bool> insert(const value_type& value); - - template <class TInputIterator> - void insert(TInputIterator begin, TInputIterator end); - + + iterator begin(); + const_iterator begin() const; + + iterator end(); + const_iterator end() const; + + void reserve(size_type n); + + size_type size() const; + int ssize() const; + + bool empty() const; + void clear(); + + iterator find(const K& k); + const_iterator find(const K& k) const; + + bool contains(const K& k) const; + + std::pair<iterator, bool> insert(const value_type& value); + + template <class TInputIterator> + void insert(TInputIterator begin, TInputIterator end); + template <class... TArgs> std::pair<iterator, bool> emplace(TArgs&&... args); - V& operator[](const K& k); - - void erase(const K& k); - void erase(iterator pos); - void erase(iterator b, iterator e); - -private: - std::pair<iterator, iterator> EqualRange(const K& k); - std::pair<const_iterator, const_iterator> EqualRange(const K& k) const; - - TStorage Storage_; -}; - -//////////////////////////////////////////////////////////////////////////////// - -} // namespace NYT - + V& operator[](const K& k); + + void erase(const K& k); + void erase(iterator pos); + void erase(iterator b, iterator e); + +private: + std::pair<iterator, iterator> EqualRange(const K& k); + std::pair<const_iterator, const_iterator> EqualRange(const K& k) const; + + TStorage Storage_; +}; + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT + #define COMPACT_FLAT_MAP_INL_H_ #include "compact_flat_map-inl.h" #undef COMPACT_FLAT_MAP_INL_H_ diff --git a/library/cpp/yt/small_containers/compact_set-inl.h b/library/cpp/yt/small_containers/compact_set-inl.h index 88180f606c..75b8600175 100644 --- a/library/cpp/yt/small_containers/compact_set-inl.h +++ b/library/cpp/yt/small_containers/compact_set-inl.h @@ -1,322 +1,322 @@ #ifndef COMPACT_SET_INL_H_ #error "Direct inclusion of this file is not allowed, include compact_set.h" -// For the sake of sane code completion. +// For the sake of sane code completion. #include "compact_set.h" -#endif - -namespace NYT { - -//////////////////////////////////////////////////////////////////////////////// - -template <typename T, unsigned N, typename C> +#endif + +namespace NYT { + +//////////////////////////////////////////////////////////////////////////////// + +template <typename T, unsigned N, typename C> class TCompactSet<T, N, C>::const_iterator -{ -private: +{ +private: friend class TCompactSet<T, N, C>; - - union - { - TVectorConstIterator VIter; - TSetConstIterator SIter; - }; - - bool Small; - - const_iterator(TVectorConstIterator it) - : VIter(it) - , Small(true) - { } - - const_iterator(TSetConstIterator it) - : SIter(it) - , Small(false) - { } - - template <class TOther> - void ConstructFrom(TOther&& rhs) - { + + union + { + TVectorConstIterator VIter; + TSetConstIterator SIter; + }; + + bool Small; + + const_iterator(TVectorConstIterator it) + : VIter(it) + , Small(true) + { } + + const_iterator(TSetConstIterator it) + : SIter(it) + , Small(false) + { } + + template <class TOther> + void ConstructFrom(TOther&& rhs) + { Y_VERIFY_DEBUG(Small == rhs.Small); - - if (Small) { - new (&VIter)TVectorConstIterator(std::forward<TOther>(rhs).VIter); - } else { - new (&SIter)TSetConstIterator(std::forward<TOther>(rhs).SIter); - } - } - - template <class TOther> - const_iterator& AssignFrom(TOther&& rhs) - { - if (this == &rhs) { - return *this; - } - - if (Small && rhs.Small) { - VIter = std::forward<TOther>(rhs).VIter; - } else if (!Small && !rhs.Small) { - SIter = std::forward<TOther>(rhs).SIter; - } else { - if (Small) { - VIter.~TVectorConstIterator(); - } else { - SIter.~TSetConstIterator(); - } - - if (rhs.Small) { - new (&VIter)TVectorConstIterator(std::forward<TOther>(rhs).VIter); - } else { - new (&SIter)TSetConstIterator(std::forward<TOther>(rhs).SIter); - } - } - - Small = rhs.Small; - - return *this; - } - -public: - static_assert(std::is_same_v< - typename std::iterator_traits<TVectorConstIterator>::difference_type, - typename std::iterator_traits<TSetConstIterator>::difference_type>); - static_assert(std::is_same_v< - typename std::iterator_traits<TVectorConstIterator>::value_type, - typename std::iterator_traits<TSetConstIterator>::value_type>); - static_assert(std::is_same_v< - typename std::iterator_traits<TVectorConstIterator>::pointer, - typename std::iterator_traits<TSetConstIterator>::pointer>); - static_assert(std::is_same_v< - typename std::iterator_traits<TVectorConstIterator>::reference, - typename std::iterator_traits<TSetConstIterator>::reference>); - - using difference_type = typename std::iterator_traits<TVectorConstIterator>::difference_type; - using value_type = typename std::iterator_traits<TVectorConstIterator>::value_type; - using pointer = typename std::iterator_traits<TVectorConstIterator>::pointer; - using reference = typename std::iterator_traits<TVectorConstIterator>::reference; - using iterator_category = std::bidirectional_iterator_tag; - - const_iterator(const const_iterator& rhs) - : Small(rhs.Small) - { - ConstructFrom(rhs); - } - - const_iterator(const_iterator&& rhs) - : Small(rhs.Small) - { - ConstructFrom(std::move(rhs)); - } - - ~const_iterator() - { - if (Small) { - VIter.~TVectorConstIterator(); - } else { - SIter.~TSetConstIterator(); - } - } - - const_iterator& operator=(const const_iterator& rhs) - { - return AssignFrom(rhs); - } - - const_iterator& operator=(const_iterator&& rhs) - { - return AssignFrom(std::move(rhs)); - } - - const_iterator& operator++() - { - if (Small) { - ++VIter; - } else { - ++SIter; - } - - return *this; - } - - const_iterator operator++(int) - { - auto result = *this; - - if (Small) { - ++VIter; - } else { - ++SIter; - } - - return result; - } - - const_iterator& operator--() - { - if (Small) { - --VIter; - } else { - --SIter; - } - - return *this; - } - - const_iterator operator--(int) - { - auto result = *this; - - if (Small) { - --VIter; - } else { - --SIter; - } - - return result; - } - - bool operator==(const const_iterator& rhs) const - { - if (Small != rhs.Small) { - return false; - } - - return Small ? (VIter == rhs.VIter) : (SIter == rhs.SIter); - } - - bool operator!=(const const_iterator& rhs) const - { - return !(*this == rhs); - } - - const T& operator*() const - { - return Small ? *VIter : *SIter; - } - - const T* operator->() const - { - return &operator*(); - } -}; - -//////////////////////////////////////////////////////////////////////////////// - -template <typename T, unsigned N, typename C> + + if (Small) { + new (&VIter)TVectorConstIterator(std::forward<TOther>(rhs).VIter); + } else { + new (&SIter)TSetConstIterator(std::forward<TOther>(rhs).SIter); + } + } + + template <class TOther> + const_iterator& AssignFrom(TOther&& rhs) + { + if (this == &rhs) { + return *this; + } + + if (Small && rhs.Small) { + VIter = std::forward<TOther>(rhs).VIter; + } else if (!Small && !rhs.Small) { + SIter = std::forward<TOther>(rhs).SIter; + } else { + if (Small) { + VIter.~TVectorConstIterator(); + } else { + SIter.~TSetConstIterator(); + } + + if (rhs.Small) { + new (&VIter)TVectorConstIterator(std::forward<TOther>(rhs).VIter); + } else { + new (&SIter)TSetConstIterator(std::forward<TOther>(rhs).SIter); + } + } + + Small = rhs.Small; + + return *this; + } + +public: + static_assert(std::is_same_v< + typename std::iterator_traits<TVectorConstIterator>::difference_type, + typename std::iterator_traits<TSetConstIterator>::difference_type>); + static_assert(std::is_same_v< + typename std::iterator_traits<TVectorConstIterator>::value_type, + typename std::iterator_traits<TSetConstIterator>::value_type>); + static_assert(std::is_same_v< + typename std::iterator_traits<TVectorConstIterator>::pointer, + typename std::iterator_traits<TSetConstIterator>::pointer>); + static_assert(std::is_same_v< + typename std::iterator_traits<TVectorConstIterator>::reference, + typename std::iterator_traits<TSetConstIterator>::reference>); + + using difference_type = typename std::iterator_traits<TVectorConstIterator>::difference_type; + using value_type = typename std::iterator_traits<TVectorConstIterator>::value_type; + using pointer = typename std::iterator_traits<TVectorConstIterator>::pointer; + using reference = typename std::iterator_traits<TVectorConstIterator>::reference; + using iterator_category = std::bidirectional_iterator_tag; + + const_iterator(const const_iterator& rhs) + : Small(rhs.Small) + { + ConstructFrom(rhs); + } + + const_iterator(const_iterator&& rhs) + : Small(rhs.Small) + { + ConstructFrom(std::move(rhs)); + } + + ~const_iterator() + { + if (Small) { + VIter.~TVectorConstIterator(); + } else { + SIter.~TSetConstIterator(); + } + } + + const_iterator& operator=(const const_iterator& rhs) + { + return AssignFrom(rhs); + } + + const_iterator& operator=(const_iterator&& rhs) + { + return AssignFrom(std::move(rhs)); + } + + const_iterator& operator++() + { + if (Small) { + ++VIter; + } else { + ++SIter; + } + + return *this; + } + + const_iterator operator++(int) + { + auto result = *this; + + if (Small) { + ++VIter; + } else { + ++SIter; + } + + return result; + } + + const_iterator& operator--() + { + if (Small) { + --VIter; + } else { + --SIter; + } + + return *this; + } + + const_iterator operator--(int) + { + auto result = *this; + + if (Small) { + --VIter; + } else { + --SIter; + } + + return result; + } + + bool operator==(const const_iterator& rhs) const + { + if (Small != rhs.Small) { + return false; + } + + return Small ? (VIter == rhs.VIter) : (SIter == rhs.SIter); + } + + bool operator!=(const const_iterator& rhs) const + { + return !(*this == rhs); + } + + const T& operator*() const + { + return Small ? *VIter : *SIter; + } + + const T* operator->() const + { + return &operator*(); + } +}; + +//////////////////////////////////////////////////////////////////////////////// + +template <typename T, unsigned N, typename C> bool TCompactSet<T, N, C>::empty() const -{ - return Vector.empty() && Set.empty(); -} - -template <typename T, unsigned N, typename C> +{ + return Vector.empty() && Set.empty(); +} + +template <typename T, unsigned N, typename C> typename TCompactSet<T, N, C>::size_type TCompactSet<T, N, C>::size() const -{ - return IsSmall() ? Vector.size() : Set.size(); -} - -template <typename T, unsigned N, typename C> +{ + return IsSmall() ? Vector.size() : Set.size(); +} + +template <typename T, unsigned N, typename C> const T& TCompactSet<T, N, C>::front() const -{ - return IsSmall() ? Vector.front() : *Set.begin(); -} - - -template <typename T, unsigned N, typename C> +{ + return IsSmall() ? Vector.front() : *Set.begin(); +} + + +template <typename T, unsigned N, typename C> typename TCompactSet<T, N, C>::size_type TCompactSet<T, N, C>::count(const T& v) const -{ - if (IsSmall()) { - return std::binary_search(Vector.begin(), Vector.end(), v, C()) ? 1 : 0; - } else { - return Set.count(v); - } -} - -template <typename T, unsigned N, typename C> +{ + if (IsSmall()) { + return std::binary_search(Vector.begin(), Vector.end(), v, C()) ? 1 : 0; + } else { + return Set.count(v); + } +} + +template <typename T, unsigned N, typename C> std::pair<typename TCompactSet<T, N, C>::const_iterator, bool> TCompactSet<T, N, C>::insert(const T& v) -{ - if (!IsSmall()) { - auto [it, inserted] = Set.insert(v); - return {const_iterator(std::move(it)), inserted}; - } - - auto it = std::lower_bound(Vector.begin(), Vector.end(), v, C()); - if (it != Vector.end() && !C()(v, *it)) { - return {const_iterator(std::move(it)), false}; // Don't reinsert if it already exists. - } - - if (Vector.size() < N) { - auto newIt = Vector.insert(it, v); - return {const_iterator(std::move(newIt)), true}; - } - - Set.insert(Vector.begin(), Vector.end()); - Vector.clear(); - - auto [newIt, inserted] = Set.insert(v); +{ + if (!IsSmall()) { + auto [it, inserted] = Set.insert(v); + return {const_iterator(std::move(it)), inserted}; + } + + auto it = std::lower_bound(Vector.begin(), Vector.end(), v, C()); + if (it != Vector.end() && !C()(v, *it)) { + return {const_iterator(std::move(it)), false}; // Don't reinsert if it already exists. + } + + if (Vector.size() < N) { + auto newIt = Vector.insert(it, v); + return {const_iterator(std::move(newIt)), true}; + } + + Set.insert(Vector.begin(), Vector.end()); + Vector.clear(); + + auto [newIt, inserted] = Set.insert(v); Y_VERIFY_DEBUG(inserted); - return {const_iterator(std::move(newIt)), true}; -} - -template <typename T, unsigned N, typename C> -template <typename TIter> + return {const_iterator(std::move(newIt)), true}; +} + +template <typename T, unsigned N, typename C> +template <typename TIter> void TCompactSet<T, N, C>::insert(TIter i, TIter e) -{ - for (; i != e; ++i) { - insert(*i); - } -} - -template <typename T, unsigned N, typename C> +{ + for (; i != e; ++i) { + insert(*i); + } +} + +template <typename T, unsigned N, typename C> bool TCompactSet<T, N, C>::erase(const T& v) -{ - if (!IsSmall()) { - return Set.erase(v); - } - - auto [rangeBegin, rangeEnd] = std::equal_range(Vector.begin(), Vector.end(), v, C()); - if (rangeBegin != rangeEnd) { - Vector.erase(rangeBegin, rangeEnd); - return true; - } else { - return false; - } -} - -template <typename T, unsigned N, typename C> +{ + if (!IsSmall()) { + return Set.erase(v); + } + + auto [rangeBegin, rangeEnd] = std::equal_range(Vector.begin(), Vector.end(), v, C()); + if (rangeBegin != rangeEnd) { + Vector.erase(rangeBegin, rangeEnd); + return true; + } else { + return false; + } +} + +template <typename T, unsigned N, typename C> void TCompactSet<T, N, C>::clear() -{ - Vector.clear(); - Set.clear(); -} - -template <typename T, unsigned N, typename C> +{ + Vector.clear(); + Set.clear(); +} + +template <typename T, unsigned N, typename C> typename TCompactSet<T, N, C>::const_iterator TCompactSet<T, N, C>::begin() const -{ - return IsSmall() ? const_iterator(Vector.begin()) : const_iterator(Set.begin()); -} - -template <typename T, unsigned N, typename C> +{ + return IsSmall() ? const_iterator(Vector.begin()) : const_iterator(Set.begin()); +} + +template <typename T, unsigned N, typename C> typename TCompactSet<T, N, C>::const_iterator TCompactSet<T, N, C>::cbegin() const -{ - return begin(); -} - -template <typename T, unsigned N, typename C> +{ + return begin(); +} + +template <typename T, unsigned N, typename C> typename TCompactSet<T, N, C>::const_iterator TCompactSet<T, N, C>::end() const -{ - return IsSmall() ? const_iterator(Vector.end()) : const_iterator(Set.end()); -} - -template <typename T, unsigned N, typename C> +{ + return IsSmall() ? const_iterator(Vector.end()) : const_iterator(Set.end()); +} + +template <typename T, unsigned N, typename C> typename TCompactSet<T, N, C>::const_iterator TCompactSet<T, N, C>::cend() const -{ - return end(); -} - -template <typename T, unsigned N, typename C> +{ + return end(); +} + +template <typename T, unsigned N, typename C> bool TCompactSet<T, N, C>::IsSmall() const -{ - return Set.empty(); -} - -//////////////////////////////////////////////////////////////////////////////// - -} // namespace NYT +{ + return Set.empty(); +} + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT diff --git a/library/cpp/yt/small_containers/compact_set.h b/library/cpp/yt/small_containers/compact_set.h index f937114cd5..2ca8713ea7 100644 --- a/library/cpp/yt/small_containers/compact_set.h +++ b/library/cpp/yt/small_containers/compact_set.h @@ -17,10 +17,10 @@ #include <util/system/yassert.h> -#include <cstddef> -#include <iterator> +#include <cstddef> +#include <iterator> #include <set> -#include <type_traits> +#include <type_traits> namespace NYT { @@ -29,58 +29,58 @@ namespace NYT { /// maintained with no mallocs. If the set gets large, we expand to using an /// std::set to maintain reasonable lookup times. /// -/// Note that any modification of the set may invalidate *all* iterators. -template <typename T, unsigned N, typename C = std::less<T>> +/// Note that any modification of the set may invalidate *all* iterators. +template <typename T, unsigned N, typename C = std::less<T>> class TCompactSet { -private: +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 - /// we will never use. + /// reach its 'large' stage) to avoid calling the default ctors of elements + /// we will never use. TCompactVector<T, N> Vector; - std::set<T, C> Set; - - using TSetConstIterator = typename std::set<T, C>::const_iterator; + std::set<T, C> Set; + + using TSetConstIterator = typename std::set<T, C>::const_iterator; using TVectorConstIterator = typename TCompactVector<T, N>::const_iterator; - + public: - class const_iterator; - using size_type = std::size_t; + class const_iterator; + using size_type = std::size_t; TCompactSet() {} - [[nodiscard]] bool empty() const; + [[nodiscard]] bool empty() const; + + size_type size() const; - size_type size() const; + const T& front() const; - const T& front() const; + /// count - Return true if the element is in the set. + size_type count(const T& v) const; - /// count - Return true if the element is in the set. - size_type count(const T& v) const; + /// insert - Insert an element into the set if it isn't already there. + std::pair<const_iterator, bool> insert(const T& v); - /// insert - Insert an element into the set if it isn't already there. - std::pair<const_iterator, bool> insert(const T& v); + template <typename TIter> + void insert(TIter i, TIter e); - template <typename TIter> - void insert(TIter i, TIter e); + bool erase(const T& v); - bool erase(const T& v); + void clear(); + + const_iterator begin() const; + const_iterator cbegin() const; + + const_iterator end() const; + const_iterator cend() const; - void clear(); - - const_iterator begin() const; - const_iterator cbegin() const; - - const_iterator end() const; - const_iterator cend() const; - private: - bool IsSmall() const; + bool IsSmall() const; }; } // namespace NYT - + #define COMPACT_SET_INL_H_ #include "compact_set-inl.h" #undef COMPACT_SET_INL_H_ - + diff --git a/library/cpp/yt/string/format-inl.h b/library/cpp/yt/string/format-inl.h index 87914932fb..5484d4a216 100644 --- a/library/cpp/yt/string/format-inl.h +++ b/library/cpp/yt/string/format-inl.h @@ -190,32 +190,32 @@ struct TValueFormatter<TEnum, typename std::enable_if<TEnumTraits<TEnum>::IsEnum }; template <class TRange, class TFormatter> -typename TFormattableView<TRange, TFormatter>::TBegin TFormattableView<TRange, TFormatter>::begin() const -{ - return RangeBegin; -} - -template <class TRange, class TFormatter> -typename TFormattableView<TRange, TFormatter>::TEnd TFormattableView<TRange, TFormatter>::end() const -{ - return RangeEnd; -} - -template <class TRange, class TFormatter> -TFormattableView<TRange, TFormatter> MakeFormattableView( +typename TFormattableView<TRange, TFormatter>::TBegin TFormattableView<TRange, TFormatter>::begin() const +{ + return RangeBegin; +} + +template <class TRange, class TFormatter> +typename TFormattableView<TRange, TFormatter>::TEnd TFormattableView<TRange, TFormatter>::end() const +{ + return RangeEnd; +} + +template <class TRange, class TFormatter> +TFormattableView<TRange, TFormatter> MakeFormattableView( const TRange& range, - TFormatter&& formatter) + TFormatter&& formatter) { - return TFormattableView<TRange, std::decay_t<TFormatter>>{range.begin(), range.end(), std::forward<TFormatter>(formatter)}; + return TFormattableView<TRange, std::decay_t<TFormatter>>{range.begin(), range.end(), std::forward<TFormatter>(formatter)}; } template <class TRange, class TFormatter> -TFormattableView<TRange, TFormatter> MakeShrunkFormattableView( +TFormattableView<TRange, TFormatter> MakeShrunkFormattableView( const TRange& range, - TFormatter&& formatter, + TFormatter&& formatter, size_t limit) { - return TFormattableView<TRange, std::decay_t<TFormatter>>{range.begin(), range.end(), std::forward<TFormatter>(formatter), limit}; + return TFormattableView<TRange, std::decay_t<TFormatter>>{range.begin(), range.end(), std::forward<TFormatter>(formatter), limit}; } template <class TRange, class TFormatter> @@ -258,13 +258,13 @@ void FormatKeyValueRange(TStringBuilderBase* builder, const TRange& range, const builder->AppendChar('}'); } -// TFormattableView +// TFormattableView template <class TRange, class TFormatter> -struct TValueFormatter<TFormattableView<TRange, TFormatter>> +struct TValueFormatter<TFormattableView<TRange, TFormatter>> { static void Do(TStringBuilderBase* builder, const TFormattableView<TRange, TFormatter>& range, TStringBuf /*format*/) { - FormatRange(builder, range, range.Formatter, range.Limit); + FormatRange(builder, range, range.Formatter, range.Limit); } }; @@ -337,9 +337,9 @@ struct TValueFormatter<std::multimap<K, V>> } }; -// THashSet +// THashSet template <class T> -struct TValueFormatter<THashSet<T>> +struct TValueFormatter<THashSet<T>> { static void Do(TStringBuilderBase* builder, const THashSet<T>& collection, TStringBuf /*format*/) { diff --git a/library/cpp/yt/string/format.h b/library/cpp/yt/string/format.h index 4f3f8a710a..9708fe5906 100644 --- a/library/cpp/yt/string/format.h +++ b/library/cpp/yt/string/format.h @@ -67,30 +67,30 @@ TString Format(TStringBuf format, TArgs&&... args); //////////////////////////////////////////////////////////////////////////////// template <class TRange, class TFormatter> -struct TFormattableView +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; + 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; size_t Limit = std::numeric_limits<size_t>::max(); - - TBegin begin() const; - TEnd end() const; + + TBegin begin() const; + TEnd end() const; }; //! Annotates a given #range with #formatter to be applied to each item. template <class TRange, class TFormatter> -TFormattableView<TRange, TFormatter> MakeFormattableView( +TFormattableView<TRange, TFormatter> MakeFormattableView( const TRange& range, - TFormatter&& formatter); + TFormatter&& formatter); template <class TRange, class TFormatter> -TFormattableView<TRange, TFormatter> MakeShrunkFormattableView( +TFormattableView<TRange, TFormatter> MakeShrunkFormattableView( const TRange& range, - TFormatter&& formatter, + TFormatter&& formatter, size_t limit); //////////////////////////////////////////////////////////////////////////////// diff --git a/library/cpp/yt/yson_string/string.cpp b/library/cpp/yt/yson_string/string.cpp index 749f3b7c5c..99d45e8616 100644 --- a/library/cpp/yt/yson_string/string.cpp +++ b/library/cpp/yt/yson_string/string.cpp @@ -88,7 +88,7 @@ TYsonString::TYsonString(const TYsonStringBuf& ysonStringBuf) Begin_ = payload->GetData(); Size_ = data.Size(); Type_ = ysonStringBuf.GetType(); - } else { + } else { Begin_ = nullptr; Size_ = 0; Type_ = EYsonType::Node; // fake |