diff options
author | tender-bum <tender-bum@yandex-team.ru> | 2022-02-10 16:50:01 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:50:01 +0300 |
commit | 4aef354b224559d2b031487a10d4f5cc6e82e95a (patch) | |
tree | 5d5cb817648f650d76cf1076100726fd9b8448e8 | |
parent | c78b06a63de7beec995c1007bc5332bdf3d75b69 (diff) | |
download | ydb-4aef354b224559d2b031487a10d4f5cc6e82e95a.tar.gz |
Restoring authorship annotation for <tender-bum@yandex-team.ru>. Commit 2 of 2.
107 files changed, 4060 insertions, 4060 deletions
diff --git a/library/cpp/actors/interconnect/interconnect_handshake.cpp b/library/cpp/actors/interconnect/interconnect_handshake.cpp index e23d3879a4..9ede998d8e 100644 --- a/library/cpp/actors/interconnect/interconnect_handshake.cpp +++ b/library/cpp/actors/interconnect/interconnect_handshake.cpp @@ -8,8 +8,8 @@ #include <google/protobuf/text_format.h> -#include <variant> - +#include <variant> + namespace NActors { static constexpr size_t StackSize = 64 * 1024; // 64k should be enough diff --git a/library/cpp/containers/flat_hash/benchmark/flat_hash_benchmark.cpp b/library/cpp/containers/flat_hash/benchmark/flat_hash_benchmark.cpp index db49c43357..040cff3fff 100644 --- a/library/cpp/containers/flat_hash/benchmark/flat_hash_benchmark.cpp +++ b/library/cpp/containers/flat_hash/benchmark/flat_hash_benchmark.cpp @@ -1,180 +1,180 @@ #include <library/cpp/containers/flat_hash/flat_hash.h> - + #include <library/cpp/containers/dense_hash/dense_hash.h> #include <library/cpp/testing/benchmark/bench.h> - -#include <util/random/random.h> -#include <util/generic/xrange.h> -#include <util/generic/hash.h> - -namespace { - -template <class Map, size_t elemCount, class... Args> -void RunLookupPositiveScalarKeysBench(::NBench::NCpu::TParams& iface, Args&&... args) { - using key_type = i32; - static_assert(std::is_same_v<typename Map::key_type, key_type>); - Map hm(std::forward<Args>(args)...); - - TVector<i32> keys(elemCount); - for (auto& k : keys) { - k = RandomNumber<ui32>(std::numeric_limits<i32>::max()); - hm.emplace(k, 0); - } - - for (const auto i : xrange(iface.Iterations())) { - Y_UNUSED(i); - for (const auto& k : keys) { - Y_DO_NOT_OPTIMIZE_AWAY(hm[k]); - } - } -} - -constexpr size_t TEST1_ELEM_COUNT = 10; -constexpr size_t TEST2_ELEM_COUNT = 1000; -constexpr size_t TEST3_ELEM_COUNT = 1000000; - -} - -/* *********************************** TEST1 *********************************** - * Insert TEST1_ELEM_COUNT positive integers and than make lookup. - * No init size provided for tables. - * key_type - i32 - */ - -Y_CPU_BENCHMARK(Test1_fh_TFlatHashMap_LinearProbing, iface) { - RunLookupPositiveScalarKeysBench<NFH::TFlatHashMap<i32, int>, TEST1_ELEM_COUNT>(iface); -} - -/* -Y_CPU_BENCHMARK(Test1_fh_TFlatHashMap_QuadraticProbing, iface) { - RunLookupPositiveScalarKeysBench<NFH::TFlatHashMap<i32, int, THash<i32>, - std::equal_to<i32>, NFlatHash::TQuadraticProbing>, TEST1_ELEM_COUNT>(iface); -} -*/ - -Y_CPU_BENCHMARK(Test1_fh_TFlatHashMap_DenseProbing, iface) { - RunLookupPositiveScalarKeysBench<NFH::TFlatHashMap<i32, int, THash<i32>, - std::equal_to<i32>, NFlatHash::TDenseProbing>, TEST1_ELEM_COUNT>(iface); -} - - -Y_CPU_BENCHMARK(Test1_fh_TDenseHashMapStaticMarker_LinearProbing, iface) { - RunLookupPositiveScalarKeysBench<NFH::TDenseHashMapStaticMarker<i32, int, -1, THash<i32>, - std::equal_to<i32>, NFlatHash::TLinearProbing>, TEST1_ELEM_COUNT>(iface); -} - -/* -Y_CPU_BENCHMARK(Test1_fh_TDenseHashMapStaticMarker_QuadraticProbing, iface) { - RunLookupPositiveScalarKeysBench<NFH::TDenseHashMapStaticMarker<i32, int, -1, THash<i32>, - std::equal_to<i32>, NFlatHash::TQuadraticProbing>, TEST1_ELEM_COUNT>(iface); -} -*/ - -Y_CPU_BENCHMARK(Test1_fh_TDenseHashMapStaticMarker_DenseProbing, iface) { - RunLookupPositiveScalarKeysBench<NFH::TDenseHashMapStaticMarker<i32, int, -1>, TEST1_ELEM_COUNT>(iface); -} - - -Y_CPU_BENCHMARK(Test1_foreign_TDenseHash, iface) { - RunLookupPositiveScalarKeysBench<TDenseHash<i32, int>, TEST1_ELEM_COUNT>(iface, (i32)-1); -} - -Y_CPU_BENCHMARK(Test1_foreign_THashMap, iface) { - RunLookupPositiveScalarKeysBench<THashMap<i32, int>, TEST1_ELEM_COUNT>(iface); -} - -/* *********************************** TEST2 *********************************** - * Insert TEST2_ELEM_COUNT positive integers and than make lookup. - * No init size provided for tables. - * key_type - i32 - */ - -Y_CPU_BENCHMARK(Test2_fh_TFlatHashMap_LinearProbing, iface) { - RunLookupPositiveScalarKeysBench<NFH::TFlatHashMap<i32, int>, TEST2_ELEM_COUNT>(iface); -} - -/* -Y_CPU_BENCHMARK(Test2_fh_TFlatHashMap_QuadraticProbing, iface) { - RunLookupPositiveScalarKeysBench<NFH::TFlatHashMap<i32, int, THash<i32>, - std::equal_to<i32>, NFlatHash::TQuadraticProbing>, TEST2_ELEM_COUNT>(iface); -} -*/ - -Y_CPU_BENCHMARK(Test2_fh_TFlatHashMap_DenseProbing, iface) { - RunLookupPositiveScalarKeysBench<NFH::TFlatHashMap<i32, int, THash<i32>, - std::equal_to<i32>, NFlatHash::TDenseProbing>, TEST2_ELEM_COUNT>(iface); -} - - -Y_CPU_BENCHMARK(Test2_fh_TDenseHashMapStaticMarker_LinearProbing, iface) { - RunLookupPositiveScalarKeysBench<NFH::TDenseHashMapStaticMarker<i32, int, -1, THash<i32>, - std::equal_to<i32>, NFlatHash::TLinearProbing>, TEST2_ELEM_COUNT>(iface); -} - -/* -Y_CPU_BENCHMARK(Test2_fh_TDenseHashMapStaticMarker_QuadraticProbing, iface) { - RunLookupPositiveScalarKeysBench<NFH::TDenseHashMapStaticMarker<i32, int, -1, THash<i32>, - std::equal_to<i32>, NFlatHash::TQuadraticProbing>, TEST2_ELEM_COUNT>(iface); -} -*/ - -Y_CPU_BENCHMARK(Test2_fh_TDenseHashMapStaticMarker_DenseProbing, iface) { - RunLookupPositiveScalarKeysBench<NFH::TDenseHashMapStaticMarker<i32, int, -1>, TEST2_ELEM_COUNT>(iface); -} - - -Y_CPU_BENCHMARK(Test2_foreign_TDenseHash, iface) { - RunLookupPositiveScalarKeysBench<TDenseHash<i32, int>, TEST2_ELEM_COUNT>(iface, (i32)-1); -} - -Y_CPU_BENCHMARK(Test2_foreign_THashMap, iface) { - RunLookupPositiveScalarKeysBench<THashMap<i32, int>, TEST2_ELEM_COUNT>(iface); -} - -/* *********************************** TEST3 *********************************** - * Insert TEST2_ELEM_COUNT positive integers and than make lookup. - * No init size provided for tables. - * key_type - i32 - */ - -Y_CPU_BENCHMARK(Test3_fh_TFlatHashMap_LinearProbing, iface) { - RunLookupPositiveScalarKeysBench<NFH::TFlatHashMap<i32, int>, TEST3_ELEM_COUNT>(iface); -} - -/* -Y_CPU_BENCHMARK(Test3_fh_TFlatHashMap_QuadraticProbing, iface) { - RunLookupPositiveScalarKeysBench<NFH::TFlatHashMap<i32, int, THash<i32>, - std::equal_to<i32>, NFlatHash::TQuadraticProbing>, TEST3_ELEM_COUNT>(iface); -} -*/ - -Y_CPU_BENCHMARK(Test3_fh_TFlatHashMap_DenseProbing, iface) { - RunLookupPositiveScalarKeysBench<NFH::TFlatHashMap<i32, int, THash<i32>, - std::equal_to<i32>, NFlatHash::TDenseProbing>, TEST3_ELEM_COUNT>(iface); -} - - -Y_CPU_BENCHMARK(Test3_fh_TDenseHashMapStaticMarker_LinearProbing, iface) { - RunLookupPositiveScalarKeysBench<NFH::TDenseHashMapStaticMarker<i32, int, -1, THash<i32>, - std::equal_to<i32>, NFlatHash::TLinearProbing>, TEST3_ELEM_COUNT>(iface); -} - -/* -Y_CPU_BENCHMARK(Test3_fh_TDenseHashMapStaticMarker_QuadraticProbing, iface) { - RunLookupPositiveScalarKeysBench<NFH::TDenseHashMapStaticMarker<i32, int, -1, THash<i32>, - std::equal_to<i32>, NFlatHash::TQuadraticProbing>, TEST3_ELEM_COUNT>(iface); -} -*/ - -Y_CPU_BENCHMARK(Test3_fh_TDenseHashMapStaticMarker_DenseProbing, iface) { - RunLookupPositiveScalarKeysBench<NFH::TDenseHashMapStaticMarker<i32, int, -1>, TEST3_ELEM_COUNT>(iface); -} - - -Y_CPU_BENCHMARK(Test3_foreign_TDenseHash, iface) { - RunLookupPositiveScalarKeysBench<TDenseHash<i32, int>, TEST3_ELEM_COUNT>(iface, (i32)-1); -} - -Y_CPU_BENCHMARK(Test3_foreign_THashMap, iface) { - RunLookupPositiveScalarKeysBench<THashMap<i32, int>, TEST3_ELEM_COUNT>(iface); -} + +#include <util/random/random.h> +#include <util/generic/xrange.h> +#include <util/generic/hash.h> + +namespace { + +template <class Map, size_t elemCount, class... Args> +void RunLookupPositiveScalarKeysBench(::NBench::NCpu::TParams& iface, Args&&... args) { + using key_type = i32; + static_assert(std::is_same_v<typename Map::key_type, key_type>); + Map hm(std::forward<Args>(args)...); + + TVector<i32> keys(elemCount); + for (auto& k : keys) { + k = RandomNumber<ui32>(std::numeric_limits<i32>::max()); + hm.emplace(k, 0); + } + + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + for (const auto& k : keys) { + Y_DO_NOT_OPTIMIZE_AWAY(hm[k]); + } + } +} + +constexpr size_t TEST1_ELEM_COUNT = 10; +constexpr size_t TEST2_ELEM_COUNT = 1000; +constexpr size_t TEST3_ELEM_COUNT = 1000000; + +} + +/* *********************************** TEST1 *********************************** + * Insert TEST1_ELEM_COUNT positive integers and than make lookup. + * No init size provided for tables. + * key_type - i32 + */ + +Y_CPU_BENCHMARK(Test1_fh_TFlatHashMap_LinearProbing, iface) { + RunLookupPositiveScalarKeysBench<NFH::TFlatHashMap<i32, int>, TEST1_ELEM_COUNT>(iface); +} + +/* +Y_CPU_BENCHMARK(Test1_fh_TFlatHashMap_QuadraticProbing, iface) { + RunLookupPositiveScalarKeysBench<NFH::TFlatHashMap<i32, int, THash<i32>, + std::equal_to<i32>, NFlatHash::TQuadraticProbing>, TEST1_ELEM_COUNT>(iface); +} +*/ + +Y_CPU_BENCHMARK(Test1_fh_TFlatHashMap_DenseProbing, iface) { + RunLookupPositiveScalarKeysBench<NFH::TFlatHashMap<i32, int, THash<i32>, + std::equal_to<i32>, NFlatHash::TDenseProbing>, TEST1_ELEM_COUNT>(iface); +} + + +Y_CPU_BENCHMARK(Test1_fh_TDenseHashMapStaticMarker_LinearProbing, iface) { + RunLookupPositiveScalarKeysBench<NFH::TDenseHashMapStaticMarker<i32, int, -1, THash<i32>, + std::equal_to<i32>, NFlatHash::TLinearProbing>, TEST1_ELEM_COUNT>(iface); +} + +/* +Y_CPU_BENCHMARK(Test1_fh_TDenseHashMapStaticMarker_QuadraticProbing, iface) { + RunLookupPositiveScalarKeysBench<NFH::TDenseHashMapStaticMarker<i32, int, -1, THash<i32>, + std::equal_to<i32>, NFlatHash::TQuadraticProbing>, TEST1_ELEM_COUNT>(iface); +} +*/ + +Y_CPU_BENCHMARK(Test1_fh_TDenseHashMapStaticMarker_DenseProbing, iface) { + RunLookupPositiveScalarKeysBench<NFH::TDenseHashMapStaticMarker<i32, int, -1>, TEST1_ELEM_COUNT>(iface); +} + + +Y_CPU_BENCHMARK(Test1_foreign_TDenseHash, iface) { + RunLookupPositiveScalarKeysBench<TDenseHash<i32, int>, TEST1_ELEM_COUNT>(iface, (i32)-1); +} + +Y_CPU_BENCHMARK(Test1_foreign_THashMap, iface) { + RunLookupPositiveScalarKeysBench<THashMap<i32, int>, TEST1_ELEM_COUNT>(iface); +} + +/* *********************************** TEST2 *********************************** + * Insert TEST2_ELEM_COUNT positive integers and than make lookup. + * No init size provided for tables. + * key_type - i32 + */ + +Y_CPU_BENCHMARK(Test2_fh_TFlatHashMap_LinearProbing, iface) { + RunLookupPositiveScalarKeysBench<NFH::TFlatHashMap<i32, int>, TEST2_ELEM_COUNT>(iface); +} + +/* +Y_CPU_BENCHMARK(Test2_fh_TFlatHashMap_QuadraticProbing, iface) { + RunLookupPositiveScalarKeysBench<NFH::TFlatHashMap<i32, int, THash<i32>, + std::equal_to<i32>, NFlatHash::TQuadraticProbing>, TEST2_ELEM_COUNT>(iface); +} +*/ + +Y_CPU_BENCHMARK(Test2_fh_TFlatHashMap_DenseProbing, iface) { + RunLookupPositiveScalarKeysBench<NFH::TFlatHashMap<i32, int, THash<i32>, + std::equal_to<i32>, NFlatHash::TDenseProbing>, TEST2_ELEM_COUNT>(iface); +} + + +Y_CPU_BENCHMARK(Test2_fh_TDenseHashMapStaticMarker_LinearProbing, iface) { + RunLookupPositiveScalarKeysBench<NFH::TDenseHashMapStaticMarker<i32, int, -1, THash<i32>, + std::equal_to<i32>, NFlatHash::TLinearProbing>, TEST2_ELEM_COUNT>(iface); +} + +/* +Y_CPU_BENCHMARK(Test2_fh_TDenseHashMapStaticMarker_QuadraticProbing, iface) { + RunLookupPositiveScalarKeysBench<NFH::TDenseHashMapStaticMarker<i32, int, -1, THash<i32>, + std::equal_to<i32>, NFlatHash::TQuadraticProbing>, TEST2_ELEM_COUNT>(iface); +} +*/ + +Y_CPU_BENCHMARK(Test2_fh_TDenseHashMapStaticMarker_DenseProbing, iface) { + RunLookupPositiveScalarKeysBench<NFH::TDenseHashMapStaticMarker<i32, int, -1>, TEST2_ELEM_COUNT>(iface); +} + + +Y_CPU_BENCHMARK(Test2_foreign_TDenseHash, iface) { + RunLookupPositiveScalarKeysBench<TDenseHash<i32, int>, TEST2_ELEM_COUNT>(iface, (i32)-1); +} + +Y_CPU_BENCHMARK(Test2_foreign_THashMap, iface) { + RunLookupPositiveScalarKeysBench<THashMap<i32, int>, TEST2_ELEM_COUNT>(iface); +} + +/* *********************************** TEST3 *********************************** + * Insert TEST2_ELEM_COUNT positive integers and than make lookup. + * No init size provided for tables. + * key_type - i32 + */ + +Y_CPU_BENCHMARK(Test3_fh_TFlatHashMap_LinearProbing, iface) { + RunLookupPositiveScalarKeysBench<NFH::TFlatHashMap<i32, int>, TEST3_ELEM_COUNT>(iface); +} + +/* +Y_CPU_BENCHMARK(Test3_fh_TFlatHashMap_QuadraticProbing, iface) { + RunLookupPositiveScalarKeysBench<NFH::TFlatHashMap<i32, int, THash<i32>, + std::equal_to<i32>, NFlatHash::TQuadraticProbing>, TEST3_ELEM_COUNT>(iface); +} +*/ + +Y_CPU_BENCHMARK(Test3_fh_TFlatHashMap_DenseProbing, iface) { + RunLookupPositiveScalarKeysBench<NFH::TFlatHashMap<i32, int, THash<i32>, + std::equal_to<i32>, NFlatHash::TDenseProbing>, TEST3_ELEM_COUNT>(iface); +} + + +Y_CPU_BENCHMARK(Test3_fh_TDenseHashMapStaticMarker_LinearProbing, iface) { + RunLookupPositiveScalarKeysBench<NFH::TDenseHashMapStaticMarker<i32, int, -1, THash<i32>, + std::equal_to<i32>, NFlatHash::TLinearProbing>, TEST3_ELEM_COUNT>(iface); +} + +/* +Y_CPU_BENCHMARK(Test3_fh_TDenseHashMapStaticMarker_QuadraticProbing, iface) { + RunLookupPositiveScalarKeysBench<NFH::TDenseHashMapStaticMarker<i32, int, -1, THash<i32>, + std::equal_to<i32>, NFlatHash::TQuadraticProbing>, TEST3_ELEM_COUNT>(iface); +} +*/ + +Y_CPU_BENCHMARK(Test3_fh_TDenseHashMapStaticMarker_DenseProbing, iface) { + RunLookupPositiveScalarKeysBench<NFH::TDenseHashMapStaticMarker<i32, int, -1>, TEST3_ELEM_COUNT>(iface); +} + + +Y_CPU_BENCHMARK(Test3_foreign_TDenseHash, iface) { + RunLookupPositiveScalarKeysBench<TDenseHash<i32, int>, TEST3_ELEM_COUNT>(iface, (i32)-1); +} + +Y_CPU_BENCHMARK(Test3_foreign_THashMap, iface) { + RunLookupPositiveScalarKeysBench<THashMap<i32, int>, TEST3_ELEM_COUNT>(iface); +} diff --git a/library/cpp/containers/flat_hash/benchmark/ya.make b/library/cpp/containers/flat_hash/benchmark/ya.make index beb4ca4b47..6f9aedf50d 100644 --- a/library/cpp/containers/flat_hash/benchmark/ya.make +++ b/library/cpp/containers/flat_hash/benchmark/ya.make @@ -1,13 +1,13 @@ Y_BENCHMARK() - -OWNER(tender-bum) - -SRCS( - flat_hash_benchmark.cpp -) - -PEERDIR( + +OWNER(tender-bum) + +SRCS( + flat_hash_benchmark.cpp +) + +PEERDIR( library/cpp/containers/flat_hash -) - -END() +) + +END() diff --git a/library/cpp/containers/flat_hash/flat_hash.cpp b/library/cpp/containers/flat_hash/flat_hash.cpp index e695283e0b..2a16398bd4 100644 --- a/library/cpp/containers/flat_hash/flat_hash.cpp +++ b/library/cpp/containers/flat_hash/flat_hash.cpp @@ -1 +1 @@ -#include "flat_hash.h" +#include "flat_hash.h" diff --git a/library/cpp/containers/flat_hash/flat_hash.h b/library/cpp/containers/flat_hash/flat_hash.h index 5e3d8922f9..582b8ae8f5 100644 --- a/library/cpp/containers/flat_hash/flat_hash.h +++ b/library/cpp/containers/flat_hash/flat_hash.h @@ -1,120 +1,120 @@ -#pragma once - +#pragma once + #include <library/cpp/containers/flat_hash/lib/map.h> #include <library/cpp/containers/flat_hash/lib/containers.h> #include <library/cpp/containers/flat_hash/lib/probings.h> #include <library/cpp/containers/flat_hash/lib/set.h> #include <library/cpp/containers/flat_hash/lib/size_fitters.h> #include <library/cpp/containers/flat_hash/lib/expanders.h> - -#include <util/str_stl.h> - -namespace NPrivate { - + +#include <util/str_stl.h> + +namespace NPrivate { + template <class Key, class T, class Hash, class KeyEqual, class Probing, class Alloc> -using TFlatHashMapImpl = NFlatHash::TMap<Key, T, Hash, KeyEqual, +using TFlatHashMapImpl = NFlatHash::TMap<Key, T, Hash, KeyEqual, NFlatHash::TFlatContainer<std::pair<const Key, T>, Alloc>, - Probing, NFlatHash::TAndSizeFitter, - NFlatHash::TSimpleExpander>; - + Probing, NFlatHash::TAndSizeFitter, + NFlatHash::TSimpleExpander>; + template <class Key, class T, auto emptyMarker, class Hash, class KeyEqual, class Probing, class Alloc> -using TDenseHashMapImpl = - NFlatHash::TMap<Key, T, Hash, KeyEqual, - NFlatHash::TDenseContainer<std::pair<const Key, T>, +using TDenseHashMapImpl = + NFlatHash::TMap<Key, T, Hash, KeyEqual, + NFlatHash::TDenseContainer<std::pair<const Key, T>, NFlatHash::NMap::TStaticValueMarker<emptyMarker, T>, Alloc>, - Probing, NFlatHash::TAndSizeFitter, NFlatHash::TSimpleExpander>; - - + Probing, NFlatHash::TAndSizeFitter, NFlatHash::TSimpleExpander>; + + template <class T, class Hash, class KeyEqual, class Probing, class Alloc> -using TFlatHashSetImpl = NFlatHash::TSet<T, Hash, KeyEqual, +using TFlatHashSetImpl = NFlatHash::TSet<T, Hash, KeyEqual, NFlatHash::TFlatContainer<T, Alloc>, - Probing, NFlatHash::TAndSizeFitter, - NFlatHash::TSimpleExpander>; - + Probing, NFlatHash::TAndSizeFitter, + NFlatHash::TSimpleExpander>; + template <class T, auto emptyMarker, class Hash, class KeyEqual, class Probing, class Alloc> -using TDenseHashSetImpl = - NFlatHash::TSet<T, Hash, KeyEqual, +using TDenseHashSetImpl = + NFlatHash::TSet<T, Hash, KeyEqual, NFlatHash::TDenseContainer<T, NFlatHash::NSet::TStaticValueMarker<emptyMarker>, Alloc>, - Probing, NFlatHash::TAndSizeFitter, NFlatHash::TSimpleExpander>; - -} // namespace NPrivate - -namespace NFH { - + Probing, NFlatHash::TAndSizeFitter, NFlatHash::TSimpleExpander>; + +} // namespace NPrivate + +namespace NFH { + /* flat_map: Fast and highly customizable hash map. - * - * Most features would be available soon. - * Until that time we strongly insist on using only class aliases listed below. - */ - -/* Simpliest open addressing hash map. - * Uses additional array to denote status of every bucket. - * Default probing is linear. - * Currently available probings: - * * TLinearProbing - * * TQuadraticProbing - * * TDenseProbing - */ -template <class Key, - class T, - class Hash = THash<Key>, - class KeyEqual = std::equal_to<>, + * + * Most features would be available soon. + * Until that time we strongly insist on using only class aliases listed below. + */ + +/* Simpliest open addressing hash map. + * Uses additional array to denote status of every bucket. + * Default probing is linear. + * Currently available probings: + * * TLinearProbing + * * TQuadraticProbing + * * TDenseProbing + */ +template <class Key, + class T, + class Hash = THash<Key>, + class KeyEqual = std::equal_to<>, class Probing = NFlatHash::TLinearProbing, class Alloc = std::allocator<std::pair<const Key, T>>> using TFlatHashMap = NPrivate::TFlatHashMapImpl<Key, T, Hash, KeyEqual, Probing, Alloc>; - -/* Open addressing table with user specified marker for empty buckets. - * Currently available probings: - * * TLinearProbing - * * TQuadraticProbing - * * TDenseProbing - */ -template <class Key, - class T, - auto emptyMarker, - class Hash = THash<Key>, - class KeyEqual = std::equal_to<>, + +/* Open addressing table with user specified marker for empty buckets. + * Currently available probings: + * * TLinearProbing + * * TQuadraticProbing + * * TDenseProbing + */ +template <class Key, + class T, + auto emptyMarker, + class Hash = THash<Key>, + class KeyEqual = std::equal_to<>, class Probing = NFlatHash::TDenseProbing, class Alloc = std::allocator<std::pair<const Key, T>>> -using TDenseHashMapStaticMarker = NPrivate::TDenseHashMapImpl<Key, T, emptyMarker, +using TDenseHashMapStaticMarker = NPrivate::TDenseHashMapImpl<Key, T, emptyMarker, Hash, KeyEqual, Probing, Alloc>; - - -/* flat_set: Fast and highly customizable hash set. - * - * Most features would be available soon. - * Until that time we strongly insist on using only class aliases listed below. - */ - -/* Simpliest open addressing hash map. - * Uses additional array to denote status of every bucket. - * Default probing is linear. - * Currently available probings: - * * TLinearProbing - * * TQuadraticProbing - * * TDenseProbing - */ -template <class T, - class Hash = THash<T>, - class KeyEqual = std::equal_to<>, + + +/* flat_set: Fast and highly customizable hash set. + * + * Most features would be available soon. + * Until that time we strongly insist on using only class aliases listed below. + */ + +/* Simpliest open addressing hash map. + * Uses additional array to denote status of every bucket. + * Default probing is linear. + * Currently available probings: + * * TLinearProbing + * * TQuadraticProbing + * * TDenseProbing + */ +template <class T, + class Hash = THash<T>, + class KeyEqual = std::equal_to<>, class Probing = NFlatHash::TLinearProbing, class Alloc = std::allocator<T>> using TFlatHashSet = NPrivate::TFlatHashSetImpl<T, Hash, KeyEqual, Probing, Alloc>; - -/* Open addressing table with user specified marker for empty buckets. - * Currently available probings: - * * TLinearProbing - * * TQuadraticProbing - * * TDenseProbing - */ -template <class T, - auto emptyMarker, - class Hash = THash<T>, - class KeyEqual = std::equal_to<>, + +/* Open addressing table with user specified marker for empty buckets. + * Currently available probings: + * * TLinearProbing + * * TQuadraticProbing + * * TDenseProbing + */ +template <class T, + auto emptyMarker, + class Hash = THash<T>, + class KeyEqual = std::equal_to<>, class Probing = NFlatHash::TDenseProbing, class Alloc = std::allocator<T>> -using TDenseHashSetStaticMarker = NPrivate::TDenseHashSetImpl<T, emptyMarker, +using TDenseHashSetStaticMarker = NPrivate::TDenseHashSetImpl<T, emptyMarker, Hash, KeyEqual, Probing, Alloc>; - -} // namespace NFH + +} // namespace NFH diff --git a/library/cpp/containers/flat_hash/lib/concepts/concepts.cpp b/library/cpp/containers/flat_hash/lib/concepts/concepts.cpp index 8e538fbd3d..63eed9acdd 100644 --- a/library/cpp/containers/flat_hash/lib/concepts/concepts.cpp +++ b/library/cpp/containers/flat_hash/lib/concepts/concepts.cpp @@ -1,4 +1,4 @@ -#include "container.h" -#include "iterator.h" -#include "size_fitter.h" -#include "value_marker.h" +#include "container.h" +#include "iterator.h" +#include "size_fitter.h" +#include "value_marker.h" diff --git a/library/cpp/containers/flat_hash/lib/concepts/container.h b/library/cpp/containers/flat_hash/lib/concepts/container.h index 586b21feba..eac1803b59 100644 --- a/library/cpp/containers/flat_hash/lib/concepts/container.h +++ b/library/cpp/containers/flat_hash/lib/concepts/container.h @@ -1,66 +1,66 @@ -#pragma once - -#include <type_traits> - -/* Concepts: - * Container - * RemovalContainer - */ -namespace NFlatHash::NConcepts { - -#define DCV(type) std::declval<type>() -#define DCT(object) decltype(object) - -template <class T, class = void> -struct Container : std::false_type {}; - -template <class T> -struct Container<T, std::void_t< - typename T::value_type, - typename T::size_type, - typename T::difference_type, - DCT(DCV(T).Node(DCV(typename T::size_type))), - DCT(DCV(const T).Node(DCV(typename T::size_type))), - DCT(DCV(const T).Size()), - DCT(DCV(const T).Taken()), - DCT(DCV(const T).Empty()), - DCT(DCV(const T).IsEmpty(DCV(typename T::size_type))), - DCT(DCV(const T).IsTaken(DCV(typename T::size_type))), - DCT(DCV(T).Swap(DCV(T&))), - DCT(DCV(const T).Clone(DCV(typename T::size_type)))>> - : std::conjunction<std::is_same<DCT(DCV(T).Node(DCV(typename T::size_type))), - typename T::value_type&>, - std::is_same<DCT(DCV(const T).Node(DCV(typename T::size_type))), - const typename T::value_type&>, - std::is_same<DCT(DCV(const T).Size()), typename T::size_type>, - std::is_same<DCT(DCV(const T).Taken()), typename T::size_type>, - std::is_same<DCT(DCV(const T).Empty()), typename T::size_type>, - std::is_same<DCT(DCV(const T).IsEmpty(DCV(typename T::size_type))), bool>, - std::is_same<DCT(DCV(const T).IsTaken(DCV(typename T::size_type))), bool>, - std::is_same<DCT(DCV(const T).Clone(DCV(typename T::size_type))), T>, - std::is_copy_constructible<T>, - std::is_move_constructible<T>, - std::is_copy_assignable<T>, - std::is_move_assignable<T>> {}; - -template <class T> -constexpr bool ContainerV = Container<T>::value; - -template <class T, class = void> -struct RemovalContainer : std::false_type {}; - -template <class T> -struct RemovalContainer<T, std::void_t< - DCT(DCV(T).DeleteNode(DCV(typename T::size_type))), - DCT(DCV(const T).IsDeleted(DCV(typename T::size_type)))>> - : std::conjunction<Container<T>, - std::is_same<DCT(DCV(const T).IsDeleted(DCV(typename T::size_type))), - bool>> {}; - -template <class T> -constexpr bool RemovalContainerV = RemovalContainer<T>::value; - -#undef DCV -#undef DCT - -} // namespace NFlatHash::NConcepts +#pragma once + +#include <type_traits> + +/* Concepts: + * Container + * RemovalContainer + */ +namespace NFlatHash::NConcepts { + +#define DCV(type) std::declval<type>() +#define DCT(object) decltype(object) + +template <class T, class = void> +struct Container : std::false_type {}; + +template <class T> +struct Container<T, std::void_t< + typename T::value_type, + typename T::size_type, + typename T::difference_type, + DCT(DCV(T).Node(DCV(typename T::size_type))), + DCT(DCV(const T).Node(DCV(typename T::size_type))), + DCT(DCV(const T).Size()), + DCT(DCV(const T).Taken()), + DCT(DCV(const T).Empty()), + DCT(DCV(const T).IsEmpty(DCV(typename T::size_type))), + DCT(DCV(const T).IsTaken(DCV(typename T::size_type))), + DCT(DCV(T).Swap(DCV(T&))), + DCT(DCV(const T).Clone(DCV(typename T::size_type)))>> + : std::conjunction<std::is_same<DCT(DCV(T).Node(DCV(typename T::size_type))), + typename T::value_type&>, + std::is_same<DCT(DCV(const T).Node(DCV(typename T::size_type))), + const typename T::value_type&>, + std::is_same<DCT(DCV(const T).Size()), typename T::size_type>, + std::is_same<DCT(DCV(const T).Taken()), typename T::size_type>, + std::is_same<DCT(DCV(const T).Empty()), typename T::size_type>, + std::is_same<DCT(DCV(const T).IsEmpty(DCV(typename T::size_type))), bool>, + std::is_same<DCT(DCV(const T).IsTaken(DCV(typename T::size_type))), bool>, + std::is_same<DCT(DCV(const T).Clone(DCV(typename T::size_type))), T>, + std::is_copy_constructible<T>, + std::is_move_constructible<T>, + std::is_copy_assignable<T>, + std::is_move_assignable<T>> {}; + +template <class T> +constexpr bool ContainerV = Container<T>::value; + +template <class T, class = void> +struct RemovalContainer : std::false_type {}; + +template <class T> +struct RemovalContainer<T, std::void_t< + DCT(DCV(T).DeleteNode(DCV(typename T::size_type))), + DCT(DCV(const T).IsDeleted(DCV(typename T::size_type)))>> + : std::conjunction<Container<T>, + std::is_same<DCT(DCV(const T).IsDeleted(DCV(typename T::size_type))), + bool>> {}; + +template <class T> +constexpr bool RemovalContainerV = RemovalContainer<T>::value; + +#undef DCV +#undef DCT + +} // namespace NFlatHash::NConcepts diff --git a/library/cpp/containers/flat_hash/lib/concepts/iterator.h b/library/cpp/containers/flat_hash/lib/concepts/iterator.h index 62822ed211..b9c1c24c82 100644 --- a/library/cpp/containers/flat_hash/lib/concepts/iterator.h +++ b/library/cpp/containers/flat_hash/lib/concepts/iterator.h @@ -1,20 +1,20 @@ -#pragma once - -#include <iterator> - -/* Concepts: - * Iterator - */ -namespace NFlatHash::NConcepts { - -template <class T, class = void> -struct Iterator : std::false_type {}; - -template <class T> -struct Iterator<T, std::void_t<typename std::iterator_traits<T>::iterator_category>> - : std::true_type {}; - -template <class T> -constexpr bool IteratorV = Iterator<T>::value; - -} // namespace NFlatHash::NConcepts +#pragma once + +#include <iterator> + +/* Concepts: + * Iterator + */ +namespace NFlatHash::NConcepts { + +template <class T, class = void> +struct Iterator : std::false_type {}; + +template <class T> +struct Iterator<T, std::void_t<typename std::iterator_traits<T>::iterator_category>> + : std::true_type {}; + +template <class T> +constexpr bool IteratorV = Iterator<T>::value; + +} // namespace NFlatHash::NConcepts diff --git a/library/cpp/containers/flat_hash/lib/concepts/size_fitter.h b/library/cpp/containers/flat_hash/lib/concepts/size_fitter.h index 21526c3756..83d1d31304 100644 --- a/library/cpp/containers/flat_hash/lib/concepts/size_fitter.h +++ b/library/cpp/containers/flat_hash/lib/concepts/size_fitter.h @@ -1,34 +1,34 @@ -#pragma once - -#include <type_traits> - -/* Concepts: - * SizeFitter - */ -namespace NFlatHash::NConcepts { - -#define DCV(type) std::declval<type>() -#define DCT(object) decltype(object) - -template <class T, class = void> -struct SizeFitter : std::false_type {}; - -template <class T> -struct SizeFitter<T, std::void_t< - DCT(DCV(const T).EvalIndex(DCV(size_t), DCV(size_t))), - DCT(DCV(const T).EvalSize(DCV(size_t))), - DCT(DCV(T).Update(DCV(size_t)))>> - : std::conjunction<std::is_same<DCT(DCV(const T).EvalIndex(DCV(size_t), DCV(size_t))), size_t>, - std::is_same<DCT(DCV(const T).EvalSize(DCV(size_t))), size_t>, - std::is_copy_constructible<T>, - std::is_move_constructible<T>, - std::is_copy_assignable<T>, - std::is_move_assignable<T>> {}; - -template <class T> -constexpr bool SizeFitterV = SizeFitter<T>::value; - -#undef DCV -#undef DCT - -} // namespace NFlatHash::NConcepts +#pragma once + +#include <type_traits> + +/* Concepts: + * SizeFitter + */ +namespace NFlatHash::NConcepts { + +#define DCV(type) std::declval<type>() +#define DCT(object) decltype(object) + +template <class T, class = void> +struct SizeFitter : std::false_type {}; + +template <class T> +struct SizeFitter<T, std::void_t< + DCT(DCV(const T).EvalIndex(DCV(size_t), DCV(size_t))), + DCT(DCV(const T).EvalSize(DCV(size_t))), + DCT(DCV(T).Update(DCV(size_t)))>> + : std::conjunction<std::is_same<DCT(DCV(const T).EvalIndex(DCV(size_t), DCV(size_t))), size_t>, + std::is_same<DCT(DCV(const T).EvalSize(DCV(size_t))), size_t>, + std::is_copy_constructible<T>, + std::is_move_constructible<T>, + std::is_copy_assignable<T>, + std::is_move_assignable<T>> {}; + +template <class T> +constexpr bool SizeFitterV = SizeFitter<T>::value; + +#undef DCV +#undef DCT + +} // namespace NFlatHash::NConcepts diff --git a/library/cpp/containers/flat_hash/lib/concepts/value_marker.h b/library/cpp/containers/flat_hash/lib/concepts/value_marker.h index 9e444fa6cc..9d1e9b210a 100644 --- a/library/cpp/containers/flat_hash/lib/concepts/value_marker.h +++ b/library/cpp/containers/flat_hash/lib/concepts/value_marker.h @@ -1,34 +1,34 @@ -#pragma once - -#include <type_traits> - -/* Concepts: - * ValueMarker - */ -namespace NFlatHash::NConcepts { - -#define DCV(type) std::declval<type>() -#define DCT(object) decltype(object) - -template <class T, class = void> -struct ValueMarker : std::false_type {}; - -template <class T> -struct ValueMarker<T, std::void_t< - typename T::value_type, - DCT(DCV(const T).Create()), - DCT(DCV(const T).Equals(DCV(const typename T::value_type&)))>> - : std::conjunction<std::is_constructible<typename T::value_type, DCT(DCV(const T).Create())>, - std::is_same<DCT(DCV(const T).Equals(DCV(const typename T::value_type&))), bool>, - std::is_copy_constructible<T>, - std::is_move_constructible<T>, - std::is_copy_assignable<T>, - std::is_move_assignable<T>> {}; - -template <class T> -constexpr bool ValueMarkerV = ValueMarker<T>::value; - -#undef DCV -#undef DCT - -} // namespace NFlatHash::NConcepts +#pragma once + +#include <type_traits> + +/* Concepts: + * ValueMarker + */ +namespace NFlatHash::NConcepts { + +#define DCV(type) std::declval<type>() +#define DCT(object) decltype(object) + +template <class T, class = void> +struct ValueMarker : std::false_type {}; + +template <class T> +struct ValueMarker<T, std::void_t< + typename T::value_type, + DCT(DCV(const T).Create()), + DCT(DCV(const T).Equals(DCV(const typename T::value_type&)))>> + : std::conjunction<std::is_constructible<typename T::value_type, DCT(DCV(const T).Create())>, + std::is_same<DCT(DCV(const T).Equals(DCV(const typename T::value_type&))), bool>, + std::is_copy_constructible<T>, + std::is_move_constructible<T>, + std::is_copy_assignable<T>, + std::is_move_assignable<T>> {}; + +template <class T> +constexpr bool ValueMarkerV = ValueMarker<T>::value; + +#undef DCV +#undef DCT + +} // namespace NFlatHash::NConcepts diff --git a/library/cpp/containers/flat_hash/lib/concepts/ya.make b/library/cpp/containers/flat_hash/lib/concepts/ya.make index b564f210bd..f82fc1d51c 100644 --- a/library/cpp/containers/flat_hash/lib/concepts/ya.make +++ b/library/cpp/containers/flat_hash/lib/concepts/ya.make @@ -1,9 +1,9 @@ -LIBRARY() - -OWNER(tender-bum) - -SRCS( - concepts.cpp -) - -END() +LIBRARY() + +OWNER(tender-bum) + +SRCS( + concepts.cpp +) + +END() diff --git a/library/cpp/containers/flat_hash/lib/containers.cpp b/library/cpp/containers/flat_hash/lib/containers.cpp index c437e06c1c..0853c23fc1 100644 --- a/library/cpp/containers/flat_hash/lib/containers.cpp +++ b/library/cpp/containers/flat_hash/lib/containers.cpp @@ -1 +1 @@ -#include "containers.h" +#include "containers.h" diff --git a/library/cpp/containers/flat_hash/lib/containers.h b/library/cpp/containers/flat_hash/lib/containers.h index 82c9861afa..82008f2f9c 100644 --- a/library/cpp/containers/flat_hash/lib/containers.h +++ b/library/cpp/containers/flat_hash/lib/containers.h @@ -1,45 +1,45 @@ -#pragma once - -#include "concepts/container.h" -#include "value_markers.h" - -#include <util/system/yassert.h> - -#include <util/generic/vector.h> -#include <util/generic/typetraits.h> -#include <util/generic/utility.h> - -#include <optional> - -namespace NFlatHash { - -/* FLAT CONTAINER */ - +#pragma once + +#include "concepts/container.h" +#include "value_markers.h" + +#include <util/system/yassert.h> + +#include <util/generic/vector.h> +#include <util/generic/typetraits.h> +#include <util/generic/utility.h> + +#include <optional> + +namespace NFlatHash { + +/* FLAT CONTAINER */ + template <class T, class Alloc = std::allocator<T>> -class TFlatContainer { -public: - using value_type = T; - using size_type = size_t; - using difference_type = ptrdiff_t; +class TFlatContainer { +public: + using value_type = T; + using size_type = size_t; + using difference_type = ptrdiff_t; using allocator_type = Alloc; using pointer = typename std::allocator_traits<allocator_type>::pointer; using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer; - -private: - class TCage { - enum ENodeStatus { - NS_EMPTY, - NS_TAKEN, - NS_DELETED - }; - - public: - TCage() noexcept = default; - - TCage(const TCage&) = default; - TCage(TCage&&) = default; - - TCage& operator=(const TCage& rhs) { + +private: + class TCage { + enum ENodeStatus { + NS_EMPTY, + NS_TAKEN, + NS_DELETED + }; + + public: + TCage() noexcept = default; + + TCage(const TCage&) = default; + TCage(TCage&&) = default; + + TCage& operator=(const TCage& rhs) { switch (rhs.Status_) { case NS_TAKEN: if constexpr (std::is_copy_assignable_v<value_type>) { @@ -57,258 +57,258 @@ private: default: Y_VERIFY(false, "Not implemented"); } - Status_ = rhs.Status_; - return *this; - } - // We never call it since all the TCage's are stored in vector - TCage& operator=(TCage&& rhs) = delete; - - template <class... Args> - void Emplace(Args&&... args) { - Y_ASSERT(Status_ == NS_EMPTY); - Value_.emplace(std::forward<Args>(args)...); - Status_ = NS_TAKEN; - } - - void Reset() noexcept { - Y_ASSERT(Status_ == NS_TAKEN); - Value_.reset(); - Status_ = NS_DELETED; - } - - value_type& Value() { - Y_ASSERT(Status_ == NS_TAKEN); - return *Value_; - } - - const value_type& Value() const { - Y_ASSERT(Status_ == NS_TAKEN); - return *Value_; - } - - bool IsEmpty() const noexcept { return Status_ == NS_EMPTY; } - bool IsTaken() const noexcept { return Status_ == NS_TAKEN; } - bool IsDeleted() const noexcept { return Status_ == NS_DELETED; } - - ENodeStatus Status() const noexcept { return Status_; } - - private: - std::optional<value_type> Value_; - ENodeStatus Status_ = NS_EMPTY; - }; - -public: + Status_ = rhs.Status_; + return *this; + } + // We never call it since all the TCage's are stored in vector + TCage& operator=(TCage&& rhs) = delete; + + template <class... Args> + void Emplace(Args&&... args) { + Y_ASSERT(Status_ == NS_EMPTY); + Value_.emplace(std::forward<Args>(args)...); + Status_ = NS_TAKEN; + } + + void Reset() noexcept { + Y_ASSERT(Status_ == NS_TAKEN); + Value_.reset(); + Status_ = NS_DELETED; + } + + value_type& Value() { + Y_ASSERT(Status_ == NS_TAKEN); + return *Value_; + } + + const value_type& Value() const { + Y_ASSERT(Status_ == NS_TAKEN); + return *Value_; + } + + bool IsEmpty() const noexcept { return Status_ == NS_EMPTY; } + bool IsTaken() const noexcept { return Status_ == NS_TAKEN; } + bool IsDeleted() const noexcept { return Status_ == NS_DELETED; } + + ENodeStatus Status() const noexcept { return Status_; } + + private: + std::optional<value_type> Value_; + ENodeStatus Status_ = NS_EMPTY; + }; + +public: explicit TFlatContainer(size_type initSize, const allocator_type& alloc = {}) : Buckets_(initSize, alloc) - , Taken_(0) + , Taken_(0) , Empty_(initSize) {} - - TFlatContainer(const TFlatContainer&) = default; - TFlatContainer(TFlatContainer&& rhs) - : Buckets_(std::move(rhs.Buckets_)) - , Taken_(rhs.Taken_) - , Empty_(rhs.Empty_) - { - rhs.Taken_ = 0; - rhs.Empty_ = 0; - } - - TFlatContainer& operator=(const TFlatContainer&) = default; - TFlatContainer& operator=(TFlatContainer&&) = default; - - value_type& Node(size_type idx) { return Buckets_[idx].Value(); } - const value_type& Node(size_type idx) const { return Buckets_[idx].Value(); } - - size_type Size() const noexcept { return Buckets_.size(); } - size_type Taken() const noexcept { return Taken_; } - size_type Empty() const noexcept { return Empty_; } - - template <class... Args> - void InitNode(size_type idx, Args&&... args) { - Buckets_[idx].Emplace(std::forward<Args>(args)...); - ++Taken_; - --Empty_; - } - - void DeleteNode(size_type idx) noexcept { - Buckets_[idx].Reset(); - --Taken_; - } - - bool IsEmpty(size_type idx) const { return Buckets_[idx].IsEmpty(); } - bool IsTaken(size_type idx) const { return Buckets_[idx].IsTaken(); } - bool IsDeleted(size_type idx) const { return Buckets_[idx].IsDeleted(); } - - void Swap(TFlatContainer& rhs) noexcept { - DoSwap(Buckets_, rhs.Buckets_); - DoSwap(Taken_, rhs.Taken_); - DoSwap(Empty_, rhs.Empty_); - } - + + TFlatContainer(const TFlatContainer&) = default; + TFlatContainer(TFlatContainer&& rhs) + : Buckets_(std::move(rhs.Buckets_)) + , Taken_(rhs.Taken_) + , Empty_(rhs.Empty_) + { + rhs.Taken_ = 0; + rhs.Empty_ = 0; + } + + TFlatContainer& operator=(const TFlatContainer&) = default; + TFlatContainer& operator=(TFlatContainer&&) = default; + + value_type& Node(size_type idx) { return Buckets_[idx].Value(); } + const value_type& Node(size_type idx) const { return Buckets_[idx].Value(); } + + size_type Size() const noexcept { return Buckets_.size(); } + size_type Taken() const noexcept { return Taken_; } + size_type Empty() const noexcept { return Empty_; } + + template <class... Args> + void InitNode(size_type idx, Args&&... args) { + Buckets_[idx].Emplace(std::forward<Args>(args)...); + ++Taken_; + --Empty_; + } + + void DeleteNode(size_type idx) noexcept { + Buckets_[idx].Reset(); + --Taken_; + } + + bool IsEmpty(size_type idx) const { return Buckets_[idx].IsEmpty(); } + bool IsTaken(size_type idx) const { return Buckets_[idx].IsTaken(); } + bool IsDeleted(size_type idx) const { return Buckets_[idx].IsDeleted(); } + + void Swap(TFlatContainer& rhs) noexcept { + DoSwap(Buckets_, rhs.Buckets_); + DoSwap(Taken_, rhs.Taken_); + DoSwap(Empty_, rhs.Empty_); + } + TFlatContainer Clone(size_type newSize) const { return TFlatContainer(newSize, Buckets_.get_allocator()); } - -private: + +private: TVector<TCage, allocator_type> Buckets_; - size_type Taken_; - size_type Empty_; -}; - -static_assert(NConcepts::ContainerV<TFlatContainer<int>>); -static_assert(NConcepts::RemovalContainerV<TFlatContainer<int>>); - -/* DENSE CONTAINER */ - + size_type Taken_; + size_type Empty_; +}; + +static_assert(NConcepts::ContainerV<TFlatContainer<int>>); +static_assert(NConcepts::RemovalContainerV<TFlatContainer<int>>); + +/* DENSE CONTAINER */ + template <class T, class EmptyMarker = NSet::TEqValueMarker<T>, class Alloc = std::allocator<T>> -class TDenseContainer { - static_assert(NConcepts::ValueMarkerV<EmptyMarker>); - -public: - using value_type = T; - using size_type = size_t; - using difference_type = ptrdiff_t; +class TDenseContainer { + static_assert(NConcepts::ValueMarkerV<EmptyMarker>); + +public: + using value_type = T; + using size_type = size_t; + using difference_type = ptrdiff_t; using allocator_type = Alloc; using pointer = typename std::allocator_traits<allocator_type>::pointer; using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer; - -public: + +public: TDenseContainer(size_type initSize, EmptyMarker emptyMarker = {}, const allocator_type& alloc = {}) : Buckets_(initSize, emptyMarker.Create(), alloc) - , Taken_(0) - , EmptyMarker_(std::move(emptyMarker)) {} - - TDenseContainer(const TDenseContainer&) = default; - TDenseContainer(TDenseContainer&&) = default; - - TDenseContainer& operator=(const TDenseContainer& rhs) { - Taken_ = rhs.Taken_; - EmptyMarker_ = rhs.EmptyMarker_; - if constexpr (std::is_copy_assignable_v<value_type>) { - Buckets_ = rhs.Buckets_; - } else { - auto tmp = rhs.Buckets_; - Buckets_.swap(tmp); - } - return *this; - } - TDenseContainer& operator=(TDenseContainer&&) = default; - - value_type& Node(size_type idx) { return Buckets_[idx]; } - const value_type& Node(size_type idx) const { return Buckets_[idx]; } - - size_type Size() const noexcept { return Buckets_.size(); } - size_type Taken() const noexcept { return Taken_; } - size_type Empty() const noexcept { return Size() - Taken(); } - - template <class... Args> - void InitNode(size_type idx, Args&&... args) { - Node(idx).~value_type(); - new (&Buckets_[idx]) value_type(std::forward<Args>(args)...); - ++Taken_; - } - - bool IsEmpty(size_type idx) const { return EmptyMarker_.Equals(Buckets_[idx]); } - bool IsTaken(size_type idx) const { return !IsEmpty(idx); } - - void Swap(TDenseContainer& rhs) - noexcept(noexcept(DoSwap(std::declval<EmptyMarker&>(), std::declval<EmptyMarker&>()))) - { - DoSwap(Buckets_, rhs.Buckets_); - DoSwap(EmptyMarker_, rhs.EmptyMarker_); - DoSwap(Taken_, rhs.Taken_); - } - + , Taken_(0) + , EmptyMarker_(std::move(emptyMarker)) {} + + TDenseContainer(const TDenseContainer&) = default; + TDenseContainer(TDenseContainer&&) = default; + + TDenseContainer& operator=(const TDenseContainer& rhs) { + Taken_ = rhs.Taken_; + EmptyMarker_ = rhs.EmptyMarker_; + if constexpr (std::is_copy_assignable_v<value_type>) { + Buckets_ = rhs.Buckets_; + } else { + auto tmp = rhs.Buckets_; + Buckets_.swap(tmp); + } + return *this; + } + TDenseContainer& operator=(TDenseContainer&&) = default; + + value_type& Node(size_type idx) { return Buckets_[idx]; } + const value_type& Node(size_type idx) const { return Buckets_[idx]; } + + size_type Size() const noexcept { return Buckets_.size(); } + size_type Taken() const noexcept { return Taken_; } + size_type Empty() const noexcept { return Size() - Taken(); } + + template <class... Args> + void InitNode(size_type idx, Args&&... args) { + Node(idx).~value_type(); + new (&Buckets_[idx]) value_type(std::forward<Args>(args)...); + ++Taken_; + } + + bool IsEmpty(size_type idx) const { return EmptyMarker_.Equals(Buckets_[idx]); } + bool IsTaken(size_type idx) const { return !IsEmpty(idx); } + + void Swap(TDenseContainer& rhs) + noexcept(noexcept(DoSwap(std::declval<EmptyMarker&>(), std::declval<EmptyMarker&>()))) + { + DoSwap(Buckets_, rhs.Buckets_); + DoSwap(EmptyMarker_, rhs.EmptyMarker_); + DoSwap(Taken_, rhs.Taken_); + } + TDenseContainer Clone(size_type newSize) const { return { newSize, EmptyMarker_, GetAllocator() }; } - -protected: + +protected: allocator_type GetAllocator() const { return Buckets_.get_allocator(); } protected: TVector<value_type, allocator_type> Buckets_; - size_type Taken_; - EmptyMarker EmptyMarker_; -}; - -static_assert(NConcepts::ContainerV<TDenseContainer<int>>); -static_assert(!NConcepts::RemovalContainerV<TDenseContainer<int>>); - -template <class T, class DeletedMarker = NSet::TEqValueMarker<T>, + size_type Taken_; + EmptyMarker EmptyMarker_; +}; + +static_assert(NConcepts::ContainerV<TDenseContainer<int>>); +static_assert(!NConcepts::RemovalContainerV<TDenseContainer<int>>); + +template <class T, class DeletedMarker = NSet::TEqValueMarker<T>, class EmptyMarker = NSet::TEqValueMarker<T>, class Alloc = std::allocator<T>> class TRemovalDenseContainer : private TDenseContainer<T, EmptyMarker, Alloc> { -private: - static_assert(NConcepts::ValueMarkerV<DeletedMarker>); - - using TBase = TDenseContainer<T, EmptyMarker>; - -public: - using typename TBase::value_type; - using typename TBase::size_type; - using typename TBase::difference_type; +private: + static_assert(NConcepts::ValueMarkerV<DeletedMarker>); + + using TBase = TDenseContainer<T, EmptyMarker>; + +public: + using typename TBase::value_type; + using typename TBase::size_type; + using typename TBase::difference_type; using typename TBase::allocator_type; using typename TBase::pointer; using typename TBase::const_pointer; - -public: - TRemovalDenseContainer( - size_type initSize, - DeletedMarker deletedMarker = {}, + +public: + TRemovalDenseContainer( + size_type initSize, + DeletedMarker deletedMarker = {}, EmptyMarker emptyMarker = {}, const allocator_type& alloc = {}) : TBase(initSize, std::move(emptyMarker), alloc) - , DeletedMarker_(std::move(deletedMarker)) - , Empty_(initSize) {} - - TRemovalDenseContainer(const TRemovalDenseContainer&) = default; - TRemovalDenseContainer(TRemovalDenseContainer&&) = default; - - TRemovalDenseContainer& operator=(const TRemovalDenseContainer&) = default; - TRemovalDenseContainer& operator=(TRemovalDenseContainer&&) = default; - - using TBase::Node; - using TBase::Size; - using TBase::Taken; - using TBase::InitNode; - using TBase::IsEmpty; - - size_type Empty() const noexcept { return Empty_; } - - template <class... Args> - void InitNode(size_type idx, Args&&... args) { - TBase::InitNode(idx, std::forward<Args>(args)...); - --Empty_; - } - - void DeleteNode(size_type idx) { - if constexpr (!std::is_trivially_destructible_v<value_type>) { - TBase::Node(idx).~value_type(); - } - new (&TBase::Node(idx)) value_type(DeletedMarker_.Create()); - --TBase::Taken_; - } - - bool IsTaken(size_type idx) const { return !IsDeleted(idx) && TBase::IsTaken(idx); } - bool IsDeleted(size_type idx) const { return DeletedMarker_.Equals(Node(idx)); } - - void Swap(TRemovalDenseContainer& rhs) - noexcept(noexcept(std::declval<TBase>().Swap(std::declval<TBase&>())) && - noexcept(DoSwap(std::declval<DeletedMarker&>(), std::declval<DeletedMarker&>()))) - { - TBase::Swap(rhs); - DoSwap(DeletedMarker_, rhs.DeletedMarker_); - DoSwap(Empty_, rhs.Empty_); - } - - TRemovalDenseContainer Clone(size_type newSize) const { + , DeletedMarker_(std::move(deletedMarker)) + , Empty_(initSize) {} + + TRemovalDenseContainer(const TRemovalDenseContainer&) = default; + TRemovalDenseContainer(TRemovalDenseContainer&&) = default; + + TRemovalDenseContainer& operator=(const TRemovalDenseContainer&) = default; + TRemovalDenseContainer& operator=(TRemovalDenseContainer&&) = default; + + using TBase::Node; + using TBase::Size; + using TBase::Taken; + using TBase::InitNode; + using TBase::IsEmpty; + + size_type Empty() const noexcept { return Empty_; } + + template <class... Args> + void InitNode(size_type idx, Args&&... args) { + TBase::InitNode(idx, std::forward<Args>(args)...); + --Empty_; + } + + void DeleteNode(size_type idx) { + if constexpr (!std::is_trivially_destructible_v<value_type>) { + TBase::Node(idx).~value_type(); + } + new (&TBase::Node(idx)) value_type(DeletedMarker_.Create()); + --TBase::Taken_; + } + + bool IsTaken(size_type idx) const { return !IsDeleted(idx) && TBase::IsTaken(idx); } + bool IsDeleted(size_type idx) const { return DeletedMarker_.Equals(Node(idx)); } + + void Swap(TRemovalDenseContainer& rhs) + noexcept(noexcept(std::declval<TBase>().Swap(std::declval<TBase&>())) && + noexcept(DoSwap(std::declval<DeletedMarker&>(), std::declval<DeletedMarker&>()))) + { + TBase::Swap(rhs); + DoSwap(DeletedMarker_, rhs.DeletedMarker_); + DoSwap(Empty_, rhs.Empty_); + } + + TRemovalDenseContainer Clone(size_type newSize) const { return { newSize, DeletedMarker_, TBase::EmptyMarker_, TBase::GetAllocator() }; - } - -private: - DeletedMarker DeletedMarker_; - size_type Empty_; -}; - -static_assert(NConcepts::ContainerV<TRemovalDenseContainer<int>>); -static_assert(NConcepts::RemovalContainerV<TRemovalDenseContainer<int>>); - -} // namespace NFlatHash + } + +private: + DeletedMarker DeletedMarker_; + size_type Empty_; +}; + +static_assert(NConcepts::ContainerV<TRemovalDenseContainer<int>>); +static_assert(NConcepts::RemovalContainerV<TRemovalDenseContainer<int>>); + +} // namespace NFlatHash diff --git a/library/cpp/containers/flat_hash/lib/expanders.cpp b/library/cpp/containers/flat_hash/lib/expanders.cpp index ab6bab81f3..6bed3c72f3 100644 --- a/library/cpp/containers/flat_hash/lib/expanders.cpp +++ b/library/cpp/containers/flat_hash/lib/expanders.cpp @@ -1 +1 @@ -#include "expanders.h" +#include "expanders.h" diff --git a/library/cpp/containers/flat_hash/lib/expanders.h b/library/cpp/containers/flat_hash/lib/expanders.h index 85fcda1d93..25b10e6bf1 100644 --- a/library/cpp/containers/flat_hash/lib/expanders.h +++ b/library/cpp/containers/flat_hash/lib/expanders.h @@ -1,25 +1,25 @@ -#pragma once - -#include <utility> - -namespace NFlatHash { - -struct TSimpleExpander { - static constexpr bool NeedGrow(size_t size, size_t buckets) noexcept { - return size >= buckets / 2; - } - - static constexpr bool WillNeedGrow(size_t size, size_t buckets) noexcept { - return NeedGrow(size + 1, buckets); - } - - static constexpr size_t EvalNewSize(size_t buckets) noexcept { - return buckets * 2; - } - - static constexpr size_t SuitableSize(size_t size) noexcept { - return size * 2 + 1; - } -}; - -} // namespace NFlatHash +#pragma once + +#include <utility> + +namespace NFlatHash { + +struct TSimpleExpander { + static constexpr bool NeedGrow(size_t size, size_t buckets) noexcept { + return size >= buckets / 2; + } + + static constexpr bool WillNeedGrow(size_t size, size_t buckets) noexcept { + return NeedGrow(size + 1, buckets); + } + + static constexpr size_t EvalNewSize(size_t buckets) noexcept { + return buckets * 2; + } + + static constexpr size_t SuitableSize(size_t size) noexcept { + return size * 2 + 1; + } +}; + +} // namespace NFlatHash diff --git a/library/cpp/containers/flat_hash/lib/fuzz/dense_map_fuzz/fuzz.cpp b/library/cpp/containers/flat_hash/lib/fuzz/dense_map_fuzz/fuzz.cpp index 7ddc13053f..9b4cb4c983 100644 --- a/library/cpp/containers/flat_hash/lib/fuzz/dense_map_fuzz/fuzz.cpp +++ b/library/cpp/containers/flat_hash/lib/fuzz/dense_map_fuzz/fuzz.cpp @@ -3,58 +3,58 @@ #include <library/cpp/containers/flat_hash/lib/probings.h> #include <library/cpp/containers/flat_hash/lib/size_fitters.h> #include <library/cpp/containers/flat_hash/lib/expanders.h> - + #include <library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/fuzz_common.h> - -#include <util/generic/hash.h> -#include <util/generic/xrange.h> -#include <util/generic/bt_exception.h> - -using namespace NFlatHash; - -namespace { - -template <class Key, class T> -using TDenseModMap = NFlatHash::TMap<Key, - T, - THash<Key>, - std::equal_to<Key>, - TRemovalDenseContainer<std::pair<const Key, T>, - NMap::TEqValueMarker<Key, T>, - NMap::TEqValueMarker<Key, T>>, - TDenseProbing, - TAndSizeFitter, - TSimpleExpander>; - -NFuzz::EActionType EvalType(ui8 data) { - return static_cast<NFuzz::EActionType>((data >> 5) & 0b111); -} - -ui8 EvalKey(ui8 data) { - return data & 0b11111; -} - -ui8 EvalValue() { - return RandomNumber<ui8>(); -} - -} // namespace - -#include <util/datetime/base.h> - -extern "C" int LLVMFuzzerTestOneInput(const ui8* const wireData, const size_t wireSize) { - THashMap<ui8, ui8> etalon; - // We assume, that markers can't be produced by EvalKey function. - TDenseModMap<ui8, ui8> testee(8, - (1 << 5), // Deleted marker - (1 << 6)); // Empty marker - - for (auto i : xrange(wireSize)) { - auto data = wireData[i]; - - NFuzz::MakeAction(etalon, testee, EvalKey(data), EvalValue(), EvalType(data)); - NFuzz::CheckInvariants(etalon, testee); - } - - return 0; -} + +#include <util/generic/hash.h> +#include <util/generic/xrange.h> +#include <util/generic/bt_exception.h> + +using namespace NFlatHash; + +namespace { + +template <class Key, class T> +using TDenseModMap = NFlatHash::TMap<Key, + T, + THash<Key>, + std::equal_to<Key>, + TRemovalDenseContainer<std::pair<const Key, T>, + NMap::TEqValueMarker<Key, T>, + NMap::TEqValueMarker<Key, T>>, + TDenseProbing, + TAndSizeFitter, + TSimpleExpander>; + +NFuzz::EActionType EvalType(ui8 data) { + return static_cast<NFuzz::EActionType>((data >> 5) & 0b111); +} + +ui8 EvalKey(ui8 data) { + return data & 0b11111; +} + +ui8 EvalValue() { + return RandomNumber<ui8>(); +} + +} // namespace + +#include <util/datetime/base.h> + +extern "C" int LLVMFuzzerTestOneInput(const ui8* const wireData, const size_t wireSize) { + THashMap<ui8, ui8> etalon; + // We assume, that markers can't be produced by EvalKey function. + TDenseModMap<ui8, ui8> testee(8, + (1 << 5), // Deleted marker + (1 << 6)); // Empty marker + + for (auto i : xrange(wireSize)) { + auto data = wireData[i]; + + NFuzz::MakeAction(etalon, testee, EvalKey(data), EvalValue(), EvalType(data)); + NFuzz::CheckInvariants(etalon, testee); + } + + return 0; +} diff --git a/library/cpp/containers/flat_hash/lib/fuzz/dense_map_fuzz/ya.make b/library/cpp/containers/flat_hash/lib/fuzz/dense_map_fuzz/ya.make index a43dba1f61..3a5d3d6d8c 100644 --- a/library/cpp/containers/flat_hash/lib/fuzz/dense_map_fuzz/ya.make +++ b/library/cpp/containers/flat_hash/lib/fuzz/dense_map_fuzz/ya.make @@ -1,19 +1,19 @@ -FUZZ() - -OWNER( - tender-bum -) - -SRCS( - fuzz.cpp -) - -PEERDIR( +FUZZ() + +OWNER( + tender-bum +) + +SRCS( + fuzz.cpp +) + +PEERDIR( library/cpp/containers/flat_hash/lib/fuzz/fuzz_common -) - -SIZE(LARGE) - -TAG(ya:fat) - -END() +) + +SIZE(LARGE) + +TAG(ya:fat) + +END() diff --git a/library/cpp/containers/flat_hash/lib/fuzz/flat_map_fuzz/fuzz.cpp b/library/cpp/containers/flat_hash/lib/fuzz/flat_map_fuzz/fuzz.cpp index 7730dc889b..7fb73af0e9 100644 --- a/library/cpp/containers/flat_hash/lib/fuzz/flat_map_fuzz/fuzz.cpp +++ b/library/cpp/containers/flat_hash/lib/fuzz/flat_map_fuzz/fuzz.cpp @@ -3,51 +3,51 @@ #include <library/cpp/containers/flat_hash/lib/probings.h> #include <library/cpp/containers/flat_hash/lib/size_fitters.h> #include <library/cpp/containers/flat_hash/lib/expanders.h> - + #include <library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/fuzz_common.h> - -#include <util/generic/hash.h> -#include <util/generic/xrange.h> -#include <util/generic/bt_exception.h> - -using namespace NFlatHash; - -namespace { - -template <class Key, class T> -using TFlatLinearModMap = NFlatHash::TMap<Key, - T, - THash<Key>, - std::equal_to<Key>, - TFlatContainer<std::pair<const Key, T>>, - TLinearProbing, - TAndSizeFitter, - TSimpleExpander>; - -NFuzz::EActionType EvalType(ui8 data) { - return static_cast<NFuzz::EActionType>((data >> 5) & 0b111); -} - -ui8 EvalKey(ui8 data) { - return data & 0b11111; -} - -ui8 EvalValue() { - return RandomNumber<ui8>(); -} - -} // namespace - -extern "C" int LLVMFuzzerTestOneInput(const ui8* const wireData, const size_t wireSize) { - THashMap<ui8, ui8> etalon; - TFlatLinearModMap<ui8, ui8> testee; - - for (auto i : xrange(wireSize)) { - auto data = wireData[i]; - - NFuzz::MakeAction(etalon, testee, EvalKey(data), EvalValue(), EvalType(data)); - NFuzz::CheckInvariants(etalon, testee); - } - - return 0; -} + +#include <util/generic/hash.h> +#include <util/generic/xrange.h> +#include <util/generic/bt_exception.h> + +using namespace NFlatHash; + +namespace { + +template <class Key, class T> +using TFlatLinearModMap = NFlatHash::TMap<Key, + T, + THash<Key>, + std::equal_to<Key>, + TFlatContainer<std::pair<const Key, T>>, + TLinearProbing, + TAndSizeFitter, + TSimpleExpander>; + +NFuzz::EActionType EvalType(ui8 data) { + return static_cast<NFuzz::EActionType>((data >> 5) & 0b111); +} + +ui8 EvalKey(ui8 data) { + return data & 0b11111; +} + +ui8 EvalValue() { + return RandomNumber<ui8>(); +} + +} // namespace + +extern "C" int LLVMFuzzerTestOneInput(const ui8* const wireData, const size_t wireSize) { + THashMap<ui8, ui8> etalon; + TFlatLinearModMap<ui8, ui8> testee; + + for (auto i : xrange(wireSize)) { + auto data = wireData[i]; + + NFuzz::MakeAction(etalon, testee, EvalKey(data), EvalValue(), EvalType(data)); + NFuzz::CheckInvariants(etalon, testee); + } + + return 0; +} diff --git a/library/cpp/containers/flat_hash/lib/fuzz/flat_map_fuzz/ya.make b/library/cpp/containers/flat_hash/lib/fuzz/flat_map_fuzz/ya.make index a43dba1f61..3a5d3d6d8c 100644 --- a/library/cpp/containers/flat_hash/lib/fuzz/flat_map_fuzz/ya.make +++ b/library/cpp/containers/flat_hash/lib/fuzz/flat_map_fuzz/ya.make @@ -1,19 +1,19 @@ -FUZZ() - -OWNER( - tender-bum -) - -SRCS( - fuzz.cpp -) - -PEERDIR( +FUZZ() + +OWNER( + tender-bum +) + +SRCS( + fuzz.cpp +) + +PEERDIR( library/cpp/containers/flat_hash/lib/fuzz/fuzz_common -) - -SIZE(LARGE) - -TAG(ya:fat) - -END() +) + +SIZE(LARGE) + +TAG(ya:fat) + +END() diff --git a/library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/fuzz_common.cpp b/library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/fuzz_common.cpp index aa87b16e98..efc2973d18 100644 --- a/library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/fuzz_common.cpp +++ b/library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/fuzz_common.cpp @@ -1 +1 @@ -#include "fuzz_common.h" +#include "fuzz_common.h" diff --git a/library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/fuzz_common.h b/library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/fuzz_common.h index fa1885990f..71a123d9cf 100644 --- a/library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/fuzz_common.h +++ b/library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/fuzz_common.h @@ -1,223 +1,223 @@ -#pragma once - -#include <util/generic/bt_exception.h> -#include <util/generic/vector.h> -#include <util/generic/xrange.h> - -#include <util/random/random.h> - -namespace NFlatHash::NFuzz { - -#define FUZZ_ASSERT(cond) \ - Y_ENSURE_EX(cond, TWithBackTrace<yexception>() << Y_STRINGIZE(cond) << " assertion failed ") - -#define FUZZ_ASSERT_THROW(cond, exc) \ - try { \ - cond; \ - FUZZ_ASSERT(false); \ - } catch (const exc&) { \ - } catch (...) { \ - FUZZ_ASSERT(false); \ - } - -enum EActionType { - AT_INSERT, - AT_CLEAR, - AT_REHASH, - AT_ATOP, - AT_AT, - AT_ITERATORS, - AT_ERASE, - AT_FIND -}; - -template <class EtalonMap, class TesteeMap, class Key, class Value> -void MakeAction(EtalonMap& etalon, TesteeMap& testee, Key&& key, Value&& value, EActionType type) { - switch (type) { - case AT_INSERT: { - auto itEt = etalon.insert({ key, value }); - if (itEt.second) { - FUZZ_ASSERT(!testee.contains(key)); - auto size = testee.size(); - auto bucket_count = testee.bucket_count(); - - auto itTs = testee.insert(std::make_pair(key, value)); - FUZZ_ASSERT(itTs.second); - FUZZ_ASSERT(itTs.first->first == key); - FUZZ_ASSERT(itTs.first->second == value); - FUZZ_ASSERT(size + 1 == testee.size()); - FUZZ_ASSERT(bucket_count <= testee.bucket_count()); - } else { - FUZZ_ASSERT(testee.contains(key)); - auto size = testee.size(); - auto bucket_count = testee.bucket_count(); - - auto itTs = testee.insert(std::make_pair(key, value)); - FUZZ_ASSERT(!itTs.second); - FUZZ_ASSERT(itTs.first->first == key); - FUZZ_ASSERT(itTs.first->second == itEt.first->second); - FUZZ_ASSERT(size == testee.size()); - FUZZ_ASSERT(bucket_count == testee.bucket_count()); - } - break; - } - case AT_CLEAR: { - auto bucket_count = testee.bucket_count(); - testee.clear(); - for (const auto& v : etalon) { - FUZZ_ASSERT(!testee.contains(v.first)); - } - FUZZ_ASSERT(testee.empty()); - FUZZ_ASSERT(testee.size() == 0); - FUZZ_ASSERT(testee.bucket_count() == bucket_count); - FUZZ_ASSERT(testee.load_factor() < std::numeric_limits<float>::epsilon()); - - etalon.clear(); - break; - } - case AT_REHASH: { - testee.rehash(key); - FUZZ_ASSERT(testee.bucket_count() >= key); - break; - } - case AT_ATOP: { - if (etalon.contains(key)) { - FUZZ_ASSERT(testee.contains(key)); - auto size = testee.size(); - auto bucket_count = testee.bucket_count(); - - FUZZ_ASSERT(testee[key] == etalon[key]); - - FUZZ_ASSERT(size == testee.size()); - FUZZ_ASSERT(bucket_count == testee.bucket_count()); - } else { - FUZZ_ASSERT(!testee.contains(key)); - auto size = testee.size(); - auto bucket_count = testee.bucket_count(); - - FUZZ_ASSERT(testee[key] == etalon[key]); - - FUZZ_ASSERT(size + 1 == testee.size()); - FUZZ_ASSERT(bucket_count <= testee.bucket_count()); - } - auto size = testee.size(); - auto bucket_count = testee.bucket_count(); - - etalon[key] = value; - testee[key] = value; - FUZZ_ASSERT(testee[key] == etalon[key]); - FUZZ_ASSERT(testee[key] == value); - - FUZZ_ASSERT(size == testee.size()); - FUZZ_ASSERT(bucket_count == testee.bucket_count()); - break; - } - case AT_AT: { - auto size = testee.size(); - auto bucket_count = testee.bucket_count(); - if (etalon.contains(key)) { - FUZZ_ASSERT(testee.contains(key)); - - FUZZ_ASSERT(testee.at(key) == etalon.at(key)); - testee.at(key) = value; - etalon.at(key) = value; - FUZZ_ASSERT(testee.at(key) == etalon.at(key)); - } else { - FUZZ_ASSERT(!testee.contains(key)); - FUZZ_ASSERT_THROW(testee.at(key) = value, std::out_of_range); - FUZZ_ASSERT(!testee.contains(key)); - } - FUZZ_ASSERT(size == testee.size()); - FUZZ_ASSERT(bucket_count == testee.bucket_count()); - break; - } - case AT_ITERATORS: { - auto itBeginTs = testee.begin(); - auto itEndTs = testee.end(); - FUZZ_ASSERT((size_t)std::distance(itBeginTs, itEndTs) == testee.size()); - FUZZ_ASSERT(std::distance(itBeginTs, itEndTs) == - std::distance(etalon.begin(), etalon.end())); - FUZZ_ASSERT(std::distance(testee.cbegin(), testee.cend()) == - std::distance(etalon.cbegin(), etalon.cend())); - break; - } - case AT_ERASE: { - if (etalon.contains(key)) { - FUZZ_ASSERT(testee.contains(key)); - auto size = testee.size(); - auto bucket_count = testee.bucket_count(); - - auto itTs = testee.find(key); - FUZZ_ASSERT(itTs->first == key); - FUZZ_ASSERT(itTs->second == etalon.at(key)); - - testee.erase(itTs); - FUZZ_ASSERT(size - 1 == testee.size()); - FUZZ_ASSERT(bucket_count == testee.bucket_count()); - etalon.erase(key); - } else { - FUZZ_ASSERT(!testee.contains(key)); - } - break; - } - case AT_FIND: { - auto itEt = etalon.find(key); - if (itEt != etalon.end()) { - FUZZ_ASSERT(testee.contains(key)); - - auto itTs = testee.find(key); - FUZZ_ASSERT(itTs != testee.end()); - FUZZ_ASSERT(itTs->first == key); - FUZZ_ASSERT(itTs->second == itEt->second); - - itTs->second = value; - itEt->second = value; - } else { - FUZZ_ASSERT(!testee.contains(key)); - - auto itTs = testee.find(key); - FUZZ_ASSERT(itTs == testee.end()); - } - break; - } - }; -} - -template <class EtalonMap, class TesteeMap> -void CheckInvariants(const EtalonMap& etalon, const TesteeMap& testee) { - using value_type = std::pair<typename TesteeMap::key_type, - typename TesteeMap::mapped_type>; - using size_type = typename TesteeMap::size_type; - - TVector<value_type> etalonVals{ etalon.begin(), etalon.end() }; - std::sort(etalonVals.begin(), etalonVals.end()); - TVector<value_type> testeeVals{ testee.begin(), testee.end() }; - std::sort(testeeVals.begin(), testeeVals.end()); - - FUZZ_ASSERT(testeeVals == etalonVals); - - FUZZ_ASSERT(testee.size() == etalon.size()); - FUZZ_ASSERT(testee.empty() == etalon.empty()); - FUZZ_ASSERT(testee.load_factor() < 0.5f + std::numeric_limits<float>::epsilon()); - FUZZ_ASSERT(testee.bucket_count() > testee.size()); - - size_type buckets = 0; - for (auto b : xrange(testee.bucket_count())) { - buckets += testee.bucket_size(b); - } - FUZZ_ASSERT(buckets == testee.size()); - - for (const auto& v : etalon) { - auto key = v.first; - auto value = v.second; - - FUZZ_ASSERT(testee.contains(key)); - FUZZ_ASSERT(testee.count(key) == 1); - - auto it = testee.find(key); - FUZZ_ASSERT(it->first == key); - FUZZ_ASSERT(it->second == value); - } -} - -} // namespace NFlatHash::NFuzz +#pragma once + +#include <util/generic/bt_exception.h> +#include <util/generic/vector.h> +#include <util/generic/xrange.h> + +#include <util/random/random.h> + +namespace NFlatHash::NFuzz { + +#define FUZZ_ASSERT(cond) \ + Y_ENSURE_EX(cond, TWithBackTrace<yexception>() << Y_STRINGIZE(cond) << " assertion failed ") + +#define FUZZ_ASSERT_THROW(cond, exc) \ + try { \ + cond; \ + FUZZ_ASSERT(false); \ + } catch (const exc&) { \ + } catch (...) { \ + FUZZ_ASSERT(false); \ + } + +enum EActionType { + AT_INSERT, + AT_CLEAR, + AT_REHASH, + AT_ATOP, + AT_AT, + AT_ITERATORS, + AT_ERASE, + AT_FIND +}; + +template <class EtalonMap, class TesteeMap, class Key, class Value> +void MakeAction(EtalonMap& etalon, TesteeMap& testee, Key&& key, Value&& value, EActionType type) { + switch (type) { + case AT_INSERT: { + auto itEt = etalon.insert({ key, value }); + if (itEt.second) { + FUZZ_ASSERT(!testee.contains(key)); + auto size = testee.size(); + auto bucket_count = testee.bucket_count(); + + auto itTs = testee.insert(std::make_pair(key, value)); + FUZZ_ASSERT(itTs.second); + FUZZ_ASSERT(itTs.first->first == key); + FUZZ_ASSERT(itTs.first->second == value); + FUZZ_ASSERT(size + 1 == testee.size()); + FUZZ_ASSERT(bucket_count <= testee.bucket_count()); + } else { + FUZZ_ASSERT(testee.contains(key)); + auto size = testee.size(); + auto bucket_count = testee.bucket_count(); + + auto itTs = testee.insert(std::make_pair(key, value)); + FUZZ_ASSERT(!itTs.second); + FUZZ_ASSERT(itTs.first->first == key); + FUZZ_ASSERT(itTs.first->second == itEt.first->second); + FUZZ_ASSERT(size == testee.size()); + FUZZ_ASSERT(bucket_count == testee.bucket_count()); + } + break; + } + case AT_CLEAR: { + auto bucket_count = testee.bucket_count(); + testee.clear(); + for (const auto& v : etalon) { + FUZZ_ASSERT(!testee.contains(v.first)); + } + FUZZ_ASSERT(testee.empty()); + FUZZ_ASSERT(testee.size() == 0); + FUZZ_ASSERT(testee.bucket_count() == bucket_count); + FUZZ_ASSERT(testee.load_factor() < std::numeric_limits<float>::epsilon()); + + etalon.clear(); + break; + } + case AT_REHASH: { + testee.rehash(key); + FUZZ_ASSERT(testee.bucket_count() >= key); + break; + } + case AT_ATOP: { + if (etalon.contains(key)) { + FUZZ_ASSERT(testee.contains(key)); + auto size = testee.size(); + auto bucket_count = testee.bucket_count(); + + FUZZ_ASSERT(testee[key] == etalon[key]); + + FUZZ_ASSERT(size == testee.size()); + FUZZ_ASSERT(bucket_count == testee.bucket_count()); + } else { + FUZZ_ASSERT(!testee.contains(key)); + auto size = testee.size(); + auto bucket_count = testee.bucket_count(); + + FUZZ_ASSERT(testee[key] == etalon[key]); + + FUZZ_ASSERT(size + 1 == testee.size()); + FUZZ_ASSERT(bucket_count <= testee.bucket_count()); + } + auto size = testee.size(); + auto bucket_count = testee.bucket_count(); + + etalon[key] = value; + testee[key] = value; + FUZZ_ASSERT(testee[key] == etalon[key]); + FUZZ_ASSERT(testee[key] == value); + + FUZZ_ASSERT(size == testee.size()); + FUZZ_ASSERT(bucket_count == testee.bucket_count()); + break; + } + case AT_AT: { + auto size = testee.size(); + auto bucket_count = testee.bucket_count(); + if (etalon.contains(key)) { + FUZZ_ASSERT(testee.contains(key)); + + FUZZ_ASSERT(testee.at(key) == etalon.at(key)); + testee.at(key) = value; + etalon.at(key) = value; + FUZZ_ASSERT(testee.at(key) == etalon.at(key)); + } else { + FUZZ_ASSERT(!testee.contains(key)); + FUZZ_ASSERT_THROW(testee.at(key) = value, std::out_of_range); + FUZZ_ASSERT(!testee.contains(key)); + } + FUZZ_ASSERT(size == testee.size()); + FUZZ_ASSERT(bucket_count == testee.bucket_count()); + break; + } + case AT_ITERATORS: { + auto itBeginTs = testee.begin(); + auto itEndTs = testee.end(); + FUZZ_ASSERT((size_t)std::distance(itBeginTs, itEndTs) == testee.size()); + FUZZ_ASSERT(std::distance(itBeginTs, itEndTs) == + std::distance(etalon.begin(), etalon.end())); + FUZZ_ASSERT(std::distance(testee.cbegin(), testee.cend()) == + std::distance(etalon.cbegin(), etalon.cend())); + break; + } + case AT_ERASE: { + if (etalon.contains(key)) { + FUZZ_ASSERT(testee.contains(key)); + auto size = testee.size(); + auto bucket_count = testee.bucket_count(); + + auto itTs = testee.find(key); + FUZZ_ASSERT(itTs->first == key); + FUZZ_ASSERT(itTs->second == etalon.at(key)); + + testee.erase(itTs); + FUZZ_ASSERT(size - 1 == testee.size()); + FUZZ_ASSERT(bucket_count == testee.bucket_count()); + etalon.erase(key); + } else { + FUZZ_ASSERT(!testee.contains(key)); + } + break; + } + case AT_FIND: { + auto itEt = etalon.find(key); + if (itEt != etalon.end()) { + FUZZ_ASSERT(testee.contains(key)); + + auto itTs = testee.find(key); + FUZZ_ASSERT(itTs != testee.end()); + FUZZ_ASSERT(itTs->first == key); + FUZZ_ASSERT(itTs->second == itEt->second); + + itTs->second = value; + itEt->second = value; + } else { + FUZZ_ASSERT(!testee.contains(key)); + + auto itTs = testee.find(key); + FUZZ_ASSERT(itTs == testee.end()); + } + break; + } + }; +} + +template <class EtalonMap, class TesteeMap> +void CheckInvariants(const EtalonMap& etalon, const TesteeMap& testee) { + using value_type = std::pair<typename TesteeMap::key_type, + typename TesteeMap::mapped_type>; + using size_type = typename TesteeMap::size_type; + + TVector<value_type> etalonVals{ etalon.begin(), etalon.end() }; + std::sort(etalonVals.begin(), etalonVals.end()); + TVector<value_type> testeeVals{ testee.begin(), testee.end() }; + std::sort(testeeVals.begin(), testeeVals.end()); + + FUZZ_ASSERT(testeeVals == etalonVals); + + FUZZ_ASSERT(testee.size() == etalon.size()); + FUZZ_ASSERT(testee.empty() == etalon.empty()); + FUZZ_ASSERT(testee.load_factor() < 0.5f + std::numeric_limits<float>::epsilon()); + FUZZ_ASSERT(testee.bucket_count() > testee.size()); + + size_type buckets = 0; + for (auto b : xrange(testee.bucket_count())) { + buckets += testee.bucket_size(b); + } + FUZZ_ASSERT(buckets == testee.size()); + + for (const auto& v : etalon) { + auto key = v.first; + auto value = v.second; + + FUZZ_ASSERT(testee.contains(key)); + FUZZ_ASSERT(testee.count(key) == 1); + + auto it = testee.find(key); + FUZZ_ASSERT(it->first == key); + FUZZ_ASSERT(it->second == value); + } +} + +} // namespace NFlatHash::NFuzz diff --git a/library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/ya.make b/library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/ya.make index 78559dda57..ecb590e116 100644 --- a/library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/ya.make +++ b/library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/ya.make @@ -1,11 +1,11 @@ -LIBRARY() - -OWNER(tender-bum) - -SRCS(fuzz_common.cpp) - -PEERDIR( +LIBRARY() + +OWNER(tender-bum) + +SRCS(fuzz_common.cpp) + +PEERDIR( library/cpp/containers/flat_hash/lib -) - -END() +) + +END() diff --git a/library/cpp/containers/flat_hash/lib/fuzz/ya.make b/library/cpp/containers/flat_hash/lib/fuzz/ya.make index 24b7df1a4e..dbf2183be5 100644 --- a/library/cpp/containers/flat_hash/lib/fuzz/ya.make +++ b/library/cpp/containers/flat_hash/lib/fuzz/ya.make @@ -1,7 +1,7 @@ -OWNER(tender-bum) - -RECURSE( - flat_map_fuzz - dense_map_fuzz - fuzz_common -) +OWNER(tender-bum) + +RECURSE( + flat_map_fuzz + dense_map_fuzz + fuzz_common +) diff --git a/library/cpp/containers/flat_hash/lib/iterator.cpp b/library/cpp/containers/flat_hash/lib/iterator.cpp index 437a096e6b..7c5c206cc3 100644 --- a/library/cpp/containers/flat_hash/lib/iterator.cpp +++ b/library/cpp/containers/flat_hash/lib/iterator.cpp @@ -1 +1 @@ -#include "iterator.h" +#include "iterator.h" diff --git a/library/cpp/containers/flat_hash/lib/iterator.h b/library/cpp/containers/flat_hash/lib/iterator.h index 17adfd4033..f6b1e74355 100644 --- a/library/cpp/containers/flat_hash/lib/iterator.h +++ b/library/cpp/containers/flat_hash/lib/iterator.h @@ -1,99 +1,99 @@ -#pragma once - -#include "concepts/container.h" - -#include <util/system/yassert.h> - -#include <iterator> - -namespace NFlatHash { - -template <class Container, class T> -class TIterator { -private: - static_assert(NConcepts::ContainerV<std::decay_t<Container>>); - -public: - using iterator_category = std::forward_iterator_tag; - using value_type = T; - using difference_type = ptrdiff_t; - using pointer = typename std::add_pointer<T>::type; - using reference = typename std::add_lvalue_reference<T>::type; - -private: - using size_type = typename Container::size_type; - -public: - TIterator(Container* cont) - : Cont_(cont) - , Idx_(0) - { - if (!cont->IsTaken(Idx_)) { - Next(); - } - } - - TIterator(Container* cont, size_type idx) - : Cont_(cont) - , Idx_(idx) {} - - template <class C, class U, class = std::enable_if_t<std::is_convertible<C*, Container*>::value && - std::is_convertible<U, T>::value>> - TIterator(const TIterator<C, U>& rhs) - : Cont_(rhs.Cont_) - , Idx_(rhs.Idx_) {} - - TIterator(const TIterator&) = default; - - TIterator& operator=(const TIterator&) = default; - - TIterator& operator++() { - Next(); - return *this; - } - TIterator operator++(int) { - auto idx = Idx_; - Next(); - return { Cont_, idx }; - } - - reference operator*() { - return Cont_->Node(Idx_); - } - - pointer operator->() { - return &Cont_->Node(Idx_); - } - +#pragma once + +#include "concepts/container.h" + +#include <util/system/yassert.h> + +#include <iterator> + +namespace NFlatHash { + +template <class Container, class T> +class TIterator { +private: + static_assert(NConcepts::ContainerV<std::decay_t<Container>>); + +public: + using iterator_category = std::forward_iterator_tag; + using value_type = T; + using difference_type = ptrdiff_t; + using pointer = typename std::add_pointer<T>::type; + using reference = typename std::add_lvalue_reference<T>::type; + +private: + using size_type = typename Container::size_type; + +public: + TIterator(Container* cont) + : Cont_(cont) + , Idx_(0) + { + if (!cont->IsTaken(Idx_)) { + Next(); + } + } + + TIterator(Container* cont, size_type idx) + : Cont_(cont) + , Idx_(idx) {} + + template <class C, class U, class = std::enable_if_t<std::is_convertible<C*, Container*>::value && + std::is_convertible<U, T>::value>> + TIterator(const TIterator<C, U>& rhs) + : Cont_(rhs.Cont_) + , Idx_(rhs.Idx_) {} + + TIterator(const TIterator&) = default; + + TIterator& operator=(const TIterator&) = default; + + TIterator& operator++() { + Next(); + return *this; + } + TIterator operator++(int) { + auto idx = Idx_; + Next(); + return { Cont_, idx }; + } + + reference operator*() { + return Cont_->Node(Idx_); + } + + pointer operator->() { + return &Cont_->Node(Idx_); + } + const pointer operator->() const { return &Cont_->Node(Idx_); } - bool operator==(const TIterator& rhs) const noexcept { - Y_ASSERT(Cont_ == rhs.Cont_); - return Idx_ == rhs.Idx_; - } - - bool operator!=(const TIterator& rhs) const noexcept { - return !operator==(rhs); - } - -private: - void Next() { - // Container provider ensures that it's not empty. - do { - ++Idx_; - } while (Idx_ != Cont_->Size() && !Cont_->IsTaken(Idx_)); - } - -private: - template <class C, class U> - friend class TIterator; - - Container* Cont_ = nullptr; - -protected: - size_type Idx_ = 0; -}; - -} // namespace NFlatHash + bool operator==(const TIterator& rhs) const noexcept { + Y_ASSERT(Cont_ == rhs.Cont_); + return Idx_ == rhs.Idx_; + } + + bool operator!=(const TIterator& rhs) const noexcept { + return !operator==(rhs); + } + +private: + void Next() { + // Container provider ensures that it's not empty. + do { + ++Idx_; + } while (Idx_ != Cont_->Size() && !Cont_->IsTaken(Idx_)); + } + +private: + template <class C, class U> + friend class TIterator; + + Container* Cont_ = nullptr; + +protected: + size_type Idx_ = 0; +}; + +} // namespace NFlatHash diff --git a/library/cpp/containers/flat_hash/lib/map.cpp b/library/cpp/containers/flat_hash/lib/map.cpp index a8fa3b1325..b323fbb46d 100644 --- a/library/cpp/containers/flat_hash/lib/map.cpp +++ b/library/cpp/containers/flat_hash/lib/map.cpp @@ -1 +1 @@ -#include "map.h" +#include "map.h" diff --git a/library/cpp/containers/flat_hash/lib/map.h b/library/cpp/containers/flat_hash/lib/map.h index d6a861b17b..f77c318a61 100644 --- a/library/cpp/containers/flat_hash/lib/map.h +++ b/library/cpp/containers/flat_hash/lib/map.h @@ -1,39 +1,39 @@ -#pragma once - -#include "table.h" -#include "concepts/iterator.h" - -#include <util/generic/algorithm.h> +#pragma once + +#include "table.h" +#include "concepts/iterator.h" + +#include <util/generic/algorithm.h> #include <util/generic/mapfindptr.h> -namespace NFlatHash { - -namespace NPrivate { - -struct TMapKeyGetter { - template <class T> - static constexpr auto& Apply(T& t) noexcept { return t.first; }; - - template <class T> - static constexpr const auto& Apply(const T& t) noexcept { return t.first; }; -}; - -} // namespace NPrivate - -template <class Key, - class T, - class Hash, - class KeyEqual, - class Container, - class Probing, - class SizeFitter, - class Expander> -class TMap : private TTable<Hash, - KeyEqual, - Container, - NPrivate::TMapKeyGetter, - Probing, - SizeFitter, +namespace NFlatHash { + +namespace NPrivate { + +struct TMapKeyGetter { + template <class T> + static constexpr auto& Apply(T& t) noexcept { return t.first; }; + + template <class T> + static constexpr const auto& Apply(const T& t) noexcept { return t.first; }; +}; + +} // namespace NPrivate + +template <class Key, + class T, + class Hash, + class KeyEqual, + class Container, + class Probing, + class SizeFitter, + class Expander> +class TMap : private TTable<Hash, + KeyEqual, + Container, + NPrivate::TMapKeyGetter, + Probing, + SizeFitter, Expander>, public TMapOps<TMap<Key, T, @@ -43,191 +43,191 @@ class TMap : private TTable<Hash, Probing, SizeFitter, Expander>> -{ -private: - using TBase = TTable<Hash, - KeyEqual, - Container, - NPrivate::TMapKeyGetter, - Probing, - SizeFitter, - Expander>; - - static_assert(std::is_same<std::pair<const Key, T>, typename Container::value_type>::value); - -public: - using key_type = Key; - using mapped_type = T; - using typename TBase::value_type; - using typename TBase::size_type; - using typename TBase::difference_type; - using typename TBase::hasher; - using typename TBase::key_equal; - using typename TBase::reference; - using typename TBase::const_reference; - using typename TBase::iterator; - using typename TBase::const_iterator; +{ +private: + using TBase = TTable<Hash, + KeyEqual, + Container, + NPrivate::TMapKeyGetter, + Probing, + SizeFitter, + Expander>; + + static_assert(std::is_same<std::pair<const Key, T>, typename Container::value_type>::value); + +public: + using key_type = Key; + using mapped_type = T; + using typename TBase::value_type; + using typename TBase::size_type; + using typename TBase::difference_type; + using typename TBase::hasher; + using typename TBase::key_equal; + using typename TBase::reference; + using typename TBase::const_reference; + using typename TBase::iterator; + using typename TBase::const_iterator; using typename TBase::allocator_type; using typename TBase::pointer; using typename TBase::const_pointer; - -private: - static constexpr size_type INIT_SIZE = 8; - -public: - TMap() : TBase(INIT_SIZE) {} - - template <class... Rest> - TMap(size_type initSize, Rest&&... rest) : TBase(initSize, std::forward<Rest>(rest)...) {} - - template <class I, class... Rest> - TMap(I first, I last, - std::enable_if_t<NConcepts::IteratorV<I>, size_type> initSize = INIT_SIZE, - Rest&&... rest) - : TBase(initSize, std::forward<Rest>(rest)...) - { - insert(first, last); - } - - template <class... Rest> - TMap(std::initializer_list<value_type> il, size_type initSize = INIT_SIZE, Rest&&... rest) - : TBase(initSize, std::forward<Rest>(rest)...) - { - insert(il.begin(), il.end()); - } - + +private: + static constexpr size_type INIT_SIZE = 8; + +public: + TMap() : TBase(INIT_SIZE) {} + + template <class... Rest> + TMap(size_type initSize, Rest&&... rest) : TBase(initSize, std::forward<Rest>(rest)...) {} + + template <class I, class... Rest> + TMap(I first, I last, + std::enable_if_t<NConcepts::IteratorV<I>, size_type> initSize = INIT_SIZE, + Rest&&... rest) + : TBase(initSize, std::forward<Rest>(rest)...) + { + insert(first, last); + } + + template <class... Rest> + TMap(std::initializer_list<value_type> il, size_type initSize = INIT_SIZE, Rest&&... rest) + : TBase(initSize, std::forward<Rest>(rest)...) + { + insert(il.begin(), il.end()); + } + TMap(std::initializer_list<value_type> il, size_type initSize = INIT_SIZE) : TBase(initSize) { insert(il.begin(), il.end()); } - TMap(const TMap&) = default; - TMap(TMap&&) = default; - - TMap& operator=(const TMap&) = default; - TMap& operator=(TMap&&) = default; - - // Iterators - using TBase::begin; - using TBase::cbegin; - using TBase::end; - using TBase::cend; - - // Capacity - using TBase::empty; - using TBase::size; - - // Modifiers - using TBase::clear; - using TBase::insert; - using TBase::emplace; - using TBase::emplace_hint; - using TBase::erase; - using TBase::swap; - - template <class V> - std::pair<iterator, bool> insert_or_assign(const key_type& k, V&& v) { - return InsertOrAssignImpl(k, std::forward<V>(v)); - } - template <class V> - std::pair<iterator, bool> insert_or_assign(key_type&& k, V&& v) { - return InsertOrAssignImpl(std::move(k), std::forward<V>(v)); - } - - template <class V> - iterator insert_or_assign(const_iterator, const key_type& k, V&& v) { // TODO(tender-bum) - return insert_or_assign(k, std::forward<V>(v)).first; - } - template <class V> - iterator insert_or_assign(const_iterator, key_type&& k, V&& v) { // TODO(tender-bum) - return insert_or_assign(std::move(k), std::forward<V>(v)).first; - } - - template <class... Args> - std::pair<iterator, bool> try_emplace(const key_type& key, Args&&... args) { - return TryEmplaceImpl(key, std::forward<Args>(args)...); - } - template <class... Args> - std::pair<iterator, bool> try_emplace(key_type&& key, Args&&... args) { - return TryEmplaceImpl(std::move(key), std::forward<Args>(args)...); - } - - template <class... Args> - iterator try_emplace(const_iterator, const key_type& key, Args&&... args) { // TODO(tender-bum) - return try_emplace(key, std::forward<Args>(args)...).first; - } - template <class... Args> - iterator try_emplace(const_iterator, key_type&& key, Args&&... args) { // TODO(tender-bum) - return try_emplace(std::move(key), std::forward<Args>(args)...).first; - } - - // Lookup - using TBase::count; - using TBase::find; - using TBase::contains; - - template <class K> - mapped_type& at(const K& key) { - auto it = find(key); - if (it == end()) { - throw std::out_of_range{ "no such key in map" }; - } - return it->second; - } - - template <class K> - const mapped_type& at(const K& key) const { return const_cast<TMap*>(this)->at(key); } - - template <class K> - Y_FORCE_INLINE mapped_type& operator[](K&& key) { - return TBase::TryCreate(key, [&](size_type idx) { - TBase::Buckets_.InitNode(idx, std::forward<K>(key), mapped_type{}); - }).first->second; - } - - // Bucket interface - using TBase::bucket_count; - using TBase::bucket_size; - - // Hash policy - using TBase::load_factor; - using TBase::rehash; - using TBase::reserve; - - // Observers - using TBase::hash_function; - using TBase::key_eq; - - friend bool operator==(const TMap& lhs, const TMap& rhs) { - return lhs.size() == rhs.size() && AllOf(lhs, [&rhs](const auto& v) { - auto it = rhs.find(v.first); - return it != rhs.end() && *it == v; - }); - } - - friend bool operator!=(const TMap& lhs, const TMap& rhs) { return !(lhs == rhs); } - -private: - template <class K, class... Args> - std::pair<iterator, bool> TryEmplaceImpl(K&& key, Args&&... args) { - return TBase::TryCreate(key, [&](size_type idx) { - TBase::Buckets_.InitNode( - idx, - std::piecewise_construct, - std::forward_as_tuple(std::forward<K>(key)), - std::forward_as_tuple(std::forward<Args>(args)...)); - }); - } - - template <class K, class V> - std::pair<iterator, bool> InsertOrAssignImpl(K&& key, V&& v) { - auto p = try_emplace(std::forward<K>(key), std::forward<V>(v)); - if (!p.second) { - p.first->second = std::forward<V>(v); - } - return p; - } -}; - -} // namespace NFlatHash + TMap(const TMap&) = default; + TMap(TMap&&) = default; + + TMap& operator=(const TMap&) = default; + TMap& operator=(TMap&&) = default; + + // Iterators + using TBase::begin; + using TBase::cbegin; + using TBase::end; + using TBase::cend; + + // Capacity + using TBase::empty; + using TBase::size; + + // Modifiers + using TBase::clear; + using TBase::insert; + using TBase::emplace; + using TBase::emplace_hint; + using TBase::erase; + using TBase::swap; + + template <class V> + std::pair<iterator, bool> insert_or_assign(const key_type& k, V&& v) { + return InsertOrAssignImpl(k, std::forward<V>(v)); + } + template <class V> + std::pair<iterator, bool> insert_or_assign(key_type&& k, V&& v) { + return InsertOrAssignImpl(std::move(k), std::forward<V>(v)); + } + + template <class V> + iterator insert_or_assign(const_iterator, const key_type& k, V&& v) { // TODO(tender-bum) + return insert_or_assign(k, std::forward<V>(v)).first; + } + template <class V> + iterator insert_or_assign(const_iterator, key_type&& k, V&& v) { // TODO(tender-bum) + return insert_or_assign(std::move(k), std::forward<V>(v)).first; + } + + template <class... Args> + std::pair<iterator, bool> try_emplace(const key_type& key, Args&&... args) { + return TryEmplaceImpl(key, std::forward<Args>(args)...); + } + template <class... Args> + std::pair<iterator, bool> try_emplace(key_type&& key, Args&&... args) { + return TryEmplaceImpl(std::move(key), std::forward<Args>(args)...); + } + + template <class... Args> + iterator try_emplace(const_iterator, const key_type& key, Args&&... args) { // TODO(tender-bum) + return try_emplace(key, std::forward<Args>(args)...).first; + } + template <class... Args> + iterator try_emplace(const_iterator, key_type&& key, Args&&... args) { // TODO(tender-bum) + return try_emplace(std::move(key), std::forward<Args>(args)...).first; + } + + // Lookup + using TBase::count; + using TBase::find; + using TBase::contains; + + template <class K> + mapped_type& at(const K& key) { + auto it = find(key); + if (it == end()) { + throw std::out_of_range{ "no such key in map" }; + } + return it->second; + } + + template <class K> + const mapped_type& at(const K& key) const { return const_cast<TMap*>(this)->at(key); } + + template <class K> + Y_FORCE_INLINE mapped_type& operator[](K&& key) { + return TBase::TryCreate(key, [&](size_type idx) { + TBase::Buckets_.InitNode(idx, std::forward<K>(key), mapped_type{}); + }).first->second; + } + + // Bucket interface + using TBase::bucket_count; + using TBase::bucket_size; + + // Hash policy + using TBase::load_factor; + using TBase::rehash; + using TBase::reserve; + + // Observers + using TBase::hash_function; + using TBase::key_eq; + + friend bool operator==(const TMap& lhs, const TMap& rhs) { + return lhs.size() == rhs.size() && AllOf(lhs, [&rhs](const auto& v) { + auto it = rhs.find(v.first); + return it != rhs.end() && *it == v; + }); + } + + friend bool operator!=(const TMap& lhs, const TMap& rhs) { return !(lhs == rhs); } + +private: + template <class K, class... Args> + std::pair<iterator, bool> TryEmplaceImpl(K&& key, Args&&... args) { + return TBase::TryCreate(key, [&](size_type idx) { + TBase::Buckets_.InitNode( + idx, + std::piecewise_construct, + std::forward_as_tuple(std::forward<K>(key)), + std::forward_as_tuple(std::forward<Args>(args)...)); + }); + } + + template <class K, class V> + std::pair<iterator, bool> InsertOrAssignImpl(K&& key, V&& v) { + auto p = try_emplace(std::forward<K>(key), std::forward<V>(v)); + if (!p.second) { + p.first->second = std::forward<V>(v); + } + return p; + } +}; + +} // namespace NFlatHash diff --git a/library/cpp/containers/flat_hash/lib/probings.cpp b/library/cpp/containers/flat_hash/lib/probings.cpp index 985101189c..f10c6af113 100644 --- a/library/cpp/containers/flat_hash/lib/probings.cpp +++ b/library/cpp/containers/flat_hash/lib/probings.cpp @@ -1 +1 @@ -#include "probings.h" +#include "probings.h" diff --git a/library/cpp/containers/flat_hash/lib/probings.h b/library/cpp/containers/flat_hash/lib/probings.h index 5760ff58c3..886be59cff 100644 --- a/library/cpp/containers/flat_hash/lib/probings.h +++ b/library/cpp/containers/flat_hash/lib/probings.h @@ -1,45 +1,45 @@ -#pragma once - -#include <type_traits> - -namespace NFlatHash { - -class TLinearProbing { -public: - template <class SizeFitter, class F> - static auto FindBucket(SizeFitter sf, size_t idx, size_t sz, F f) { - idx = sf.EvalIndex(idx, sz); - while (!f(idx)) { - idx = sf.EvalIndex(++idx, sz); - } - return idx; - } -}; - -class TQuadraticProbing { -public: - template <class SizeFitter, class F> - static auto FindBucket(SizeFitter sf, size_t idx, size_t sz, F f) { - idx = sf.EvalIndex(idx, sz); - size_t k = 0; - while (!f(idx)) { - idx = sf.EvalIndex(idx + 2 * ++k - 1, sz); - } - return idx; - } -}; - -class TDenseProbing { -public: - template <class SizeFitter, class F> - static auto FindBucket(SizeFitter sf, size_t idx, size_t sz, F f) { - idx = sf.EvalIndex(idx, sz); - size_t k = 0; - while (!f(idx)) { - idx = sf.EvalIndex(idx + ++k, sz); - } - return idx; - } -}; - -} // NFlatHash +#pragma once + +#include <type_traits> + +namespace NFlatHash { + +class TLinearProbing { +public: + template <class SizeFitter, class F> + static auto FindBucket(SizeFitter sf, size_t idx, size_t sz, F f) { + idx = sf.EvalIndex(idx, sz); + while (!f(idx)) { + idx = sf.EvalIndex(++idx, sz); + } + return idx; + } +}; + +class TQuadraticProbing { +public: + template <class SizeFitter, class F> + static auto FindBucket(SizeFitter sf, size_t idx, size_t sz, F f) { + idx = sf.EvalIndex(idx, sz); + size_t k = 0; + while (!f(idx)) { + idx = sf.EvalIndex(idx + 2 * ++k - 1, sz); + } + return idx; + } +}; + +class TDenseProbing { +public: + template <class SizeFitter, class F> + static auto FindBucket(SizeFitter sf, size_t idx, size_t sz, F f) { + idx = sf.EvalIndex(idx, sz); + size_t k = 0; + while (!f(idx)) { + idx = sf.EvalIndex(idx + ++k, sz); + } + return idx; + } +}; + +} // NFlatHash diff --git a/library/cpp/containers/flat_hash/lib/set.cpp b/library/cpp/containers/flat_hash/lib/set.cpp index 506937a165..aa2f9c58e1 100644 --- a/library/cpp/containers/flat_hash/lib/set.cpp +++ b/library/cpp/containers/flat_hash/lib/set.cpp @@ -1 +1 @@ -#include "set.h" +#include "set.h" diff --git a/library/cpp/containers/flat_hash/lib/set.h b/library/cpp/containers/flat_hash/lib/set.h index 65b42b9915..5266293c6c 100644 --- a/library/cpp/containers/flat_hash/lib/set.h +++ b/library/cpp/containers/flat_hash/lib/set.h @@ -1,147 +1,147 @@ -#pragma once - -#include "table.h" -#include "concepts/iterator.h" - -#include <util/generic/algorithm.h> - -namespace NFlatHash { - -namespace NPrivate { - -struct TSimpleKeyGetter { - template <class T> - static constexpr auto& Apply(T& t) noexcept { return t; }; - - template <class T> - static constexpr const auto& Apply(const T& t) noexcept { return t; }; -}; - -} // namespace NPrivate - -template <class Key, - class Hash, - class KeyEqual, - class Container, - class Probing, - class SizeFitter, - class Expander> -class TSet : private TTable<Hash, - KeyEqual, - Container, - NPrivate::TSimpleKeyGetter, - Probing, - SizeFitter, - Expander, - std::add_const> -{ -private: - using TBase = TTable<Hash, - KeyEqual, - Container, - NPrivate::TSimpleKeyGetter, - Probing, - SizeFitter, - Expander, - std::add_const>; - - static_assert(std::is_same_v<Key, typename Container::value_type>); - -public: - using key_type = Key; - using typename TBase::value_type; - using typename TBase::size_type; - using typename TBase::difference_type; - using typename TBase::hasher; - using typename TBase::key_equal; - using typename TBase::reference; - using typename TBase::const_reference; - using typename TBase::iterator; - using typename TBase::const_iterator; +#pragma once + +#include "table.h" +#include "concepts/iterator.h" + +#include <util/generic/algorithm.h> + +namespace NFlatHash { + +namespace NPrivate { + +struct TSimpleKeyGetter { + template <class T> + static constexpr auto& Apply(T& t) noexcept { return t; }; + + template <class T> + static constexpr const auto& Apply(const T& t) noexcept { return t; }; +}; + +} // namespace NPrivate + +template <class Key, + class Hash, + class KeyEqual, + class Container, + class Probing, + class SizeFitter, + class Expander> +class TSet : private TTable<Hash, + KeyEqual, + Container, + NPrivate::TSimpleKeyGetter, + Probing, + SizeFitter, + Expander, + std::add_const> +{ +private: + using TBase = TTable<Hash, + KeyEqual, + Container, + NPrivate::TSimpleKeyGetter, + Probing, + SizeFitter, + Expander, + std::add_const>; + + static_assert(std::is_same_v<Key, typename Container::value_type>); + +public: + using key_type = Key; + using typename TBase::value_type; + using typename TBase::size_type; + using typename TBase::difference_type; + using typename TBase::hasher; + using typename TBase::key_equal; + using typename TBase::reference; + using typename TBase::const_reference; + using typename TBase::iterator; + using typename TBase::const_iterator; using typename TBase::allocator_type; using typename TBase::pointer; using typename TBase::const_pointer; - -private: - static constexpr size_type INIT_SIZE = 8; - -public: - TSet() : TBase(INIT_SIZE) {} - - template <class... Rest> - TSet(size_type initSize, Rest&&... rest) : TBase(initSize, std::forward<Rest>(rest)...) {} - - template <class I, class... Rest> - TSet(I first, I last, - std::enable_if_t<NConcepts::IteratorV<I>, size_type> initSize = INIT_SIZE, - Rest&&... rest) - : TBase(initSize, std::forward<Rest>(rest)...) - { - insert(first, last); - } - - template <class... Rest> - TSet(std::initializer_list<value_type> il, size_type initSize = INIT_SIZE, Rest&&... rest) - : TBase(initSize, std::forward<Rest>(rest)...) - { - insert(il.begin(), il.end()); - } - + +private: + static constexpr size_type INIT_SIZE = 8; + +public: + TSet() : TBase(INIT_SIZE) {} + + template <class... Rest> + TSet(size_type initSize, Rest&&... rest) : TBase(initSize, std::forward<Rest>(rest)...) {} + + template <class I, class... Rest> + TSet(I first, I last, + std::enable_if_t<NConcepts::IteratorV<I>, size_type> initSize = INIT_SIZE, + Rest&&... rest) + : TBase(initSize, std::forward<Rest>(rest)...) + { + insert(first, last); + } + + template <class... Rest> + TSet(std::initializer_list<value_type> il, size_type initSize = INIT_SIZE, Rest&&... rest) + : TBase(initSize, std::forward<Rest>(rest)...) + { + insert(il.begin(), il.end()); + } + TSet(std::initializer_list<value_type> il, size_type initSize = INIT_SIZE) : TBase(initSize) { insert(il.begin(), il.end()); } - TSet(const TSet&) = default; - TSet(TSet&&) = default; - - TSet& operator=(const TSet&) = default; - TSet& operator=(TSet&&) = default; - - // Iterators - using TBase::begin; - using TBase::cbegin; - using TBase::end; - using TBase::cend; - - // Capacity - using TBase::empty; - using TBase::size; - - // Modifiers - using TBase::clear; - using TBase::insert; - using TBase::emplace; - using TBase::emplace_hint; - using TBase::erase; - using TBase::swap; - - // Lookup - using TBase::count; - using TBase::find; - using TBase::contains; - - // Bucket interface - using TBase::bucket_count; - using TBase::bucket_size; - - // Hash policy - using TBase::load_factor; - using TBase::rehash; - using TBase::reserve; - - // Observers - using TBase::hash_function; - using TBase::key_eq; - - friend bool operator==(const TSet& lhs, const TSet& rhs) { - return lhs.size() == rhs.size() && AllOf(lhs, [&rhs](const auto& v) { - return rhs.contains(v); - }); - } - - friend bool operator!=(const TSet& lhs, const TSet& rhs) { return !(lhs == rhs); } -}; - -} // namespace NFlatHash + TSet(const TSet&) = default; + TSet(TSet&&) = default; + + TSet& operator=(const TSet&) = default; + TSet& operator=(TSet&&) = default; + + // Iterators + using TBase::begin; + using TBase::cbegin; + using TBase::end; + using TBase::cend; + + // Capacity + using TBase::empty; + using TBase::size; + + // Modifiers + using TBase::clear; + using TBase::insert; + using TBase::emplace; + using TBase::emplace_hint; + using TBase::erase; + using TBase::swap; + + // Lookup + using TBase::count; + using TBase::find; + using TBase::contains; + + // Bucket interface + using TBase::bucket_count; + using TBase::bucket_size; + + // Hash policy + using TBase::load_factor; + using TBase::rehash; + using TBase::reserve; + + // Observers + using TBase::hash_function; + using TBase::key_eq; + + friend bool operator==(const TSet& lhs, const TSet& rhs) { + return lhs.size() == rhs.size() && AllOf(lhs, [&rhs](const auto& v) { + return rhs.contains(v); + }); + } + + friend bool operator!=(const TSet& lhs, const TSet& rhs) { return !(lhs == rhs); } +}; + +} // namespace NFlatHash diff --git a/library/cpp/containers/flat_hash/lib/size_fitters.cpp b/library/cpp/containers/flat_hash/lib/size_fitters.cpp index e6b1422f9a..f1431c27e3 100644 --- a/library/cpp/containers/flat_hash/lib/size_fitters.cpp +++ b/library/cpp/containers/flat_hash/lib/size_fitters.cpp @@ -1 +1 @@ -#include "size_fitters.h" +#include "size_fitters.h" diff --git a/library/cpp/containers/flat_hash/lib/size_fitters.h b/library/cpp/containers/flat_hash/lib/size_fitters.h index e6541bc918..86bd617342 100644 --- a/library/cpp/containers/flat_hash/lib/size_fitters.h +++ b/library/cpp/containers/flat_hash/lib/size_fitters.h @@ -1,47 +1,47 @@ -#pragma once - -#include "concepts/size_fitter.h" - -#include <util/system/yassert.h> -#include <util/generic/bitops.h> - -namespace NFlatHash { - -class TAndSizeFitter { -public: - size_t EvalIndex(size_t hs, size_t sz) const noexcept { - Y_ASSERT(Mask_ == sz - 1); - return (hs & Mask_); - } - - size_t EvalSize(size_t sz) const noexcept { - return FastClp2(sz); - } - - void Update(size_t sz) noexcept { - Y_ASSERT((sz & (sz - 1)) == 0); - Mask_ = sz - 1; - } - -private: - size_t Mask_ = 0; -}; - -static_assert(NConcepts::SizeFitterV<TAndSizeFitter>); - -class TModSizeFitter { -public: - constexpr size_t EvalIndex(size_t hs, size_t sz) const noexcept { - return hs % sz; - } - - constexpr size_t EvalSize(size_t sz) const noexcept { - return sz; - } - - constexpr void Update(size_t) noexcept {} -}; - -static_assert(NConcepts::SizeFitterV<TModSizeFitter>); - -} // NFlatHash +#pragma once + +#include "concepts/size_fitter.h" + +#include <util/system/yassert.h> +#include <util/generic/bitops.h> + +namespace NFlatHash { + +class TAndSizeFitter { +public: + size_t EvalIndex(size_t hs, size_t sz) const noexcept { + Y_ASSERT(Mask_ == sz - 1); + return (hs & Mask_); + } + + size_t EvalSize(size_t sz) const noexcept { + return FastClp2(sz); + } + + void Update(size_t sz) noexcept { + Y_ASSERT((sz & (sz - 1)) == 0); + Mask_ = sz - 1; + } + +private: + size_t Mask_ = 0; +}; + +static_assert(NConcepts::SizeFitterV<TAndSizeFitter>); + +class TModSizeFitter { +public: + constexpr size_t EvalIndex(size_t hs, size_t sz) const noexcept { + return hs % sz; + } + + constexpr size_t EvalSize(size_t sz) const noexcept { + return sz; + } + + constexpr void Update(size_t) noexcept {} +}; + +static_assert(NConcepts::SizeFitterV<TModSizeFitter>); + +} // NFlatHash diff --git a/library/cpp/containers/flat_hash/lib/table.cpp b/library/cpp/containers/flat_hash/lib/table.cpp index 8969a5cd1f..e89d72ad94 100644 --- a/library/cpp/containers/flat_hash/lib/table.cpp +++ b/library/cpp/containers/flat_hash/lib/table.cpp @@ -1 +1 @@ -#include "table.h" +#include "table.h" diff --git a/library/cpp/containers/flat_hash/lib/table.h b/library/cpp/containers/flat_hash/lib/table.h index 640e9fcc7d..b84a052be7 100644 --- a/library/cpp/containers/flat_hash/lib/table.h +++ b/library/cpp/containers/flat_hash/lib/table.h @@ -1,314 +1,314 @@ -#pragma once - -#include "iterator.h" -#include "concepts/container.h" -#include "concepts/size_fitter.h" - -#include <util/generic/utility.h> - -#include <functional> - -namespace NFlatHash { - -namespace NPrivate { - -template <class T> -struct TTypeIdentity { using type = T; }; - -} // namespace NPrivate - -template < - class Hash, - class KeyEqual, - class Container, - class KeyGetter, - class Probing, - class SizeFitter, - class Expander, - // Used in the TSet to make iterator behave as const_iterator - template <class> class IteratorModifier = NPrivate::TTypeIdentity> -class TTable { -private: - static_assert(NConcepts::ContainerV<Container>); - static_assert(NConcepts::SizeFitterV<SizeFitter>); - - template <class C, class V> - class TIteratorImpl : public TIterator<C, V> { - private: - using TBase = TIterator<C, V>; - friend class TTable; - - using TBase::TBase; - - public: - TIteratorImpl() : TBase(nullptr, 0) {} - }; - -public: - using value_type = typename Container::value_type; - using size_type = typename Container::size_type; - using difference_type = typename Container::difference_type; - using hasher = Hash; - using key_equal = KeyEqual; - - using reference = value_type&; - using const_reference = const value_type&; - - using iterator = TIteratorImpl<typename IteratorModifier<Container>::type, - typename IteratorModifier<value_type>::type>; - using const_iterator = TIteratorImpl<const Container, const value_type>; +#pragma once + +#include "iterator.h" +#include "concepts/container.h" +#include "concepts/size_fitter.h" + +#include <util/generic/utility.h> + +#include <functional> + +namespace NFlatHash { + +namespace NPrivate { + +template <class T> +struct TTypeIdentity { using type = T; }; + +} // namespace NPrivate + +template < + class Hash, + class KeyEqual, + class Container, + class KeyGetter, + class Probing, + class SizeFitter, + class Expander, + // Used in the TSet to make iterator behave as const_iterator + template <class> class IteratorModifier = NPrivate::TTypeIdentity> +class TTable { +private: + static_assert(NConcepts::ContainerV<Container>); + static_assert(NConcepts::SizeFitterV<SizeFitter>); + + template <class C, class V> + class TIteratorImpl : public TIterator<C, V> { + private: + using TBase = TIterator<C, V>; + friend class TTable; + + using TBase::TBase; + + public: + TIteratorImpl() : TBase(nullptr, 0) {} + }; + +public: + using value_type = typename Container::value_type; + using size_type = typename Container::size_type; + using difference_type = typename Container::difference_type; + using hasher = Hash; + using key_equal = KeyEqual; + + using reference = value_type&; + using const_reference = const value_type&; + + using iterator = TIteratorImpl<typename IteratorModifier<Container>::type, + typename IteratorModifier<value_type>::type>; + using const_iterator = TIteratorImpl<const Container, const value_type>; using allocator_type = typename Container::allocator_type; using pointer = typename Container::pointer; using const_pointer = typename Container::const_pointer; - -private: - TTable(Container buckets) - : Buckets_(std::move(buckets)) - { - SizeFitter_.Update(bucket_count()); - } - - static constexpr size_type INIT_SIZE = 8; - -public: - template <class... Rest> - TTable(size_type initSize, Rest&&... rest) - : Buckets_(initSize == 0 ? INIT_SIZE : SizeFitter_.EvalSize(initSize), - std::forward<Rest>(rest)...) - { - SizeFitter_.Update(bucket_count()); - } - - TTable(const TTable&) = default; - TTable(TTable&& rhs) - : SizeFitter_(std::move(rhs.SizeFitter_)) - , Buckets_(std::move(rhs.Buckets_)) - , Hasher_(std::move(rhs.Hasher_)) - , KeyEqual_(std::move(rhs.KeyEqual_)) - { - TTable tmp{ Buckets_.Clone(INIT_SIZE) }; - tmp.swap(rhs); - } - - TTable& operator=(const TTable&) = default; - TTable& operator=(TTable&& rhs) { - TTable tmp(std::move(rhs)); - swap(tmp); - return *this; - } - - // Iterators - iterator begin() { return &Buckets_; } - const_iterator begin() const { return const_cast<TTable*>(this)->begin(); } - const_iterator cbegin() const { return begin(); } - - iterator end() { return { &Buckets_, bucket_count() }; } - const_iterator end() const { return const_cast<TTable*>(this)->end(); } - const_iterator cend() const { return end(); } - - // Capacity - bool empty() const noexcept { return size() == 0; } - size_type size() const noexcept { return Buckets_.Taken(); } - - // Modifiers - void clear() { - Container tmp(Buckets_.Clone(bucket_count())); - Buckets_.Swap(tmp); - } - - std::pair<iterator, bool> insert(const value_type& value) { return InsertImpl(value); } - std::pair<iterator, bool> insert(value_type&& value) { return InsertImpl(std::move(value)); } - - template <class T> - std::enable_if_t<!std::is_same_v<std::decay_t<T>, value_type>, - std::pair<iterator, bool>> insert(T&& value) { - return insert(value_type(std::forward<T>(value))); - } - - iterator insert(const_iterator, const value_type& value) { // TODO(tender-bum) - return insert(value).first; - } - iterator insert(const_iterator, value_type&& value) { // TODO(tender-bum) - return insert(std::move(value)).first; - } - - template <class T> - iterator insert(const_iterator, T&& value) { // TODO(tender-bum) - return insert(value_type(std::forward<T>(value))).first; - } - - template <class InputIt> - void insert(InputIt first, InputIt last) { - while (first != last) { - insert(*first++); - } - } - - void insert(std::initializer_list<value_type> il) { - insert(il.begin(), il.end()); - } - - template <class... Args> - std::pair<iterator, bool> emplace(Args&&... args) { - return insert(value_type(std::forward<Args>(args)...)); - } - - template <class... Args> - iterator emplace_hint(const_iterator, Args&&... args) { // TODO(tender-bum) - return emplace(std::forward<Args>(args)...).first; - } - - void erase(const_iterator pos) { - static_assert(NConcepts::RemovalContainerV<Container>, - "That kind of table doesn't allow erasing. Use another table instead."); - if constexpr (NConcepts::RemovalContainerV<Container>) { - Buckets_.DeleteNode(pos.Idx_); - } - } - - void erase(const_iterator f, const_iterator l) { - while (f != l) { - auto nxt = f; - ++nxt; - erase(f); - f = nxt; - } - } - - template <class K> - std::enable_if_t<!std::is_convertible_v<K, iterator> && !std::is_convertible_v<K, const_iterator>, - size_type> erase(const K& key) { - auto it = find(key); - if (it != end()) { - erase(it); - return 1; - } - return 0; - } - - void swap(TTable& rhs) - noexcept(noexcept(std::declval<Container>().Swap(std::declval<Container&>()))) - { - DoSwap(SizeFitter_, rhs.SizeFitter_); - Buckets_.Swap(rhs.Buckets_); - DoSwap(Hasher_, rhs.Hasher_); - DoSwap(KeyEqual_, rhs.KeyEqual_); - } - - // Lookup - template <class K> - size_type count(const K& key) const { return contains(key); } - - template <class K> - iterator find(const K& key) { - size_type hs = hash_function()(key); - auto idx = FindProperBucket(hs, key); - if (Buckets_.IsTaken(idx)) { - return { &Buckets_, idx }; - } - return end(); - } - - template <class K> - const_iterator find(const K& key) const { return const_cast<TTable*>(this)->find(key); } - - template <class K> - bool contains(const K& key) const { - size_type hs = hash_function()(key); - return Buckets_.IsTaken(FindProperBucket(hs, key)); - } - - // Bucket interface - size_type bucket_count() const noexcept { return Buckets_.Size(); } - size_type bucket_size(size_type idx) const { return Buckets_.IsTaken(idx); } - - // Hash policy - float load_factor() const noexcept { - return (float)(bucket_count() - Buckets_.Empty()) / bucket_count(); - } - - void rehash(size_type sz) { - if (sz != 0) { - auto newBuckets = SizeFitter_.EvalSize(sz); - size_type occupied = bucket_count() - Buckets_.Empty(); - if (Expander::NeedGrow(occupied, newBuckets)) { - newBuckets = Max(newBuckets, SizeFitter_.EvalSize(Expander::SuitableSize(size()))); - } - RehashImpl(newBuckets); - } else { - RehashImpl(SizeFitter_.EvalSize(Expander::SuitableSize(size()))); - } - } - - void reserve(size_type sz) { rehash(sz); } // TODO(tender-bum) - - // Observers - constexpr auto hash_function() const noexcept { return Hasher_; } - constexpr auto key_eq() const noexcept { return KeyEqual_; } - -public: - template <class T> - std::pair<iterator, bool> InsertImpl(T&& value) { - return TryCreate(KeyGetter::Apply(value), [&](size_type idx) { - Buckets_.InitNode(idx, std::forward<T>(value)); - }); - } - - template <class T, class F> - Y_FORCE_INLINE std::pair<iterator, bool> TryCreate(const T& key, F nodeInit) { - size_type hs = hash_function()(key); - size_type idx = FindProperBucket(hs, key); - if (!Buckets_.IsTaken(idx)) { - if (Expander::WillNeedGrow(bucket_count() - Buckets_.Empty(), bucket_count())) { - RehashImpl(); - idx = FindProperBucket(hs, key); - } - nodeInit(idx); - return { iterator{ &Buckets_, idx }, true }; - } - return { iterator{ &Buckets_, idx }, false }; - } - - template <class K> - size_type FindProperBucket(size_type hs, const K& key) const { - return Probing::FindBucket(SizeFitter_, hs, bucket_count(), [&](size_type idx) { - if constexpr (NConcepts::RemovalContainerV<Container>) { - return Buckets_.IsEmpty(idx) || - Buckets_.IsTaken(idx) && key_eq()(KeyGetter::Apply(Buckets_.Node(idx)), key); - } else { - return Buckets_.IsEmpty(idx) || key_eq()(KeyGetter::Apply(Buckets_.Node(idx)), key); - } - }); - } - - void RehashImpl() { - if constexpr (NConcepts::RemovalContainerV<Container>) { - size_type occupied = bucket_count() - Buckets_.Empty(); - if (size() < occupied / 2) { - rehash(bucket_count()); // Just clearing all deleted elements - } else { - RehashImpl(SizeFitter_.EvalSize(Expander::EvalNewSize(bucket_count()))); - } - } else { - RehashImpl(SizeFitter_.EvalSize(Expander::EvalNewSize(bucket_count()))); - } - } - - void RehashImpl(size_type newSize) { - TTable tmp = Buckets_.Clone(newSize); - for (auto& value : *this) { - size_type hs = hash_function()(KeyGetter::Apply(value)); - tmp.Buckets_.InitNode( - tmp.FindProperBucket(hs, KeyGetter::Apply(value)), std::move_if_noexcept(value)); - } - swap(tmp); - } - -public: - SizeFitter SizeFitter_; - Container Buckets_; - hasher Hasher_; - key_equal KeyEqual_; -}; - -} // namespace NFlatHash + +private: + TTable(Container buckets) + : Buckets_(std::move(buckets)) + { + SizeFitter_.Update(bucket_count()); + } + + static constexpr size_type INIT_SIZE = 8; + +public: + template <class... Rest> + TTable(size_type initSize, Rest&&... rest) + : Buckets_(initSize == 0 ? INIT_SIZE : SizeFitter_.EvalSize(initSize), + std::forward<Rest>(rest)...) + { + SizeFitter_.Update(bucket_count()); + } + + TTable(const TTable&) = default; + TTable(TTable&& rhs) + : SizeFitter_(std::move(rhs.SizeFitter_)) + , Buckets_(std::move(rhs.Buckets_)) + , Hasher_(std::move(rhs.Hasher_)) + , KeyEqual_(std::move(rhs.KeyEqual_)) + { + TTable tmp{ Buckets_.Clone(INIT_SIZE) }; + tmp.swap(rhs); + } + + TTable& operator=(const TTable&) = default; + TTable& operator=(TTable&& rhs) { + TTable tmp(std::move(rhs)); + swap(tmp); + return *this; + } + + // Iterators + iterator begin() { return &Buckets_; } + const_iterator begin() const { return const_cast<TTable*>(this)->begin(); } + const_iterator cbegin() const { return begin(); } + + iterator end() { return { &Buckets_, bucket_count() }; } + const_iterator end() const { return const_cast<TTable*>(this)->end(); } + const_iterator cend() const { return end(); } + + // Capacity + bool empty() const noexcept { return size() == 0; } + size_type size() const noexcept { return Buckets_.Taken(); } + + // Modifiers + void clear() { + Container tmp(Buckets_.Clone(bucket_count())); + Buckets_.Swap(tmp); + } + + std::pair<iterator, bool> insert(const value_type& value) { return InsertImpl(value); } + std::pair<iterator, bool> insert(value_type&& value) { return InsertImpl(std::move(value)); } + + template <class T> + std::enable_if_t<!std::is_same_v<std::decay_t<T>, value_type>, + std::pair<iterator, bool>> insert(T&& value) { + return insert(value_type(std::forward<T>(value))); + } + + iterator insert(const_iterator, const value_type& value) { // TODO(tender-bum) + return insert(value).first; + } + iterator insert(const_iterator, value_type&& value) { // TODO(tender-bum) + return insert(std::move(value)).first; + } + + template <class T> + iterator insert(const_iterator, T&& value) { // TODO(tender-bum) + return insert(value_type(std::forward<T>(value))).first; + } + + template <class InputIt> + void insert(InputIt first, InputIt last) { + while (first != last) { + insert(*first++); + } + } + + void insert(std::initializer_list<value_type> il) { + insert(il.begin(), il.end()); + } + + template <class... Args> + std::pair<iterator, bool> emplace(Args&&... args) { + return insert(value_type(std::forward<Args>(args)...)); + } + + template <class... Args> + iterator emplace_hint(const_iterator, Args&&... args) { // TODO(tender-bum) + return emplace(std::forward<Args>(args)...).first; + } + + void erase(const_iterator pos) { + static_assert(NConcepts::RemovalContainerV<Container>, + "That kind of table doesn't allow erasing. Use another table instead."); + if constexpr (NConcepts::RemovalContainerV<Container>) { + Buckets_.DeleteNode(pos.Idx_); + } + } + + void erase(const_iterator f, const_iterator l) { + while (f != l) { + auto nxt = f; + ++nxt; + erase(f); + f = nxt; + } + } + + template <class K> + std::enable_if_t<!std::is_convertible_v<K, iterator> && !std::is_convertible_v<K, const_iterator>, + size_type> erase(const K& key) { + auto it = find(key); + if (it != end()) { + erase(it); + return 1; + } + return 0; + } + + void swap(TTable& rhs) + noexcept(noexcept(std::declval<Container>().Swap(std::declval<Container&>()))) + { + DoSwap(SizeFitter_, rhs.SizeFitter_); + Buckets_.Swap(rhs.Buckets_); + DoSwap(Hasher_, rhs.Hasher_); + DoSwap(KeyEqual_, rhs.KeyEqual_); + } + + // Lookup + template <class K> + size_type count(const K& key) const { return contains(key); } + + template <class K> + iterator find(const K& key) { + size_type hs = hash_function()(key); + auto idx = FindProperBucket(hs, key); + if (Buckets_.IsTaken(idx)) { + return { &Buckets_, idx }; + } + return end(); + } + + template <class K> + const_iterator find(const K& key) const { return const_cast<TTable*>(this)->find(key); } + + template <class K> + bool contains(const K& key) const { + size_type hs = hash_function()(key); + return Buckets_.IsTaken(FindProperBucket(hs, key)); + } + + // Bucket interface + size_type bucket_count() const noexcept { return Buckets_.Size(); } + size_type bucket_size(size_type idx) const { return Buckets_.IsTaken(idx); } + + // Hash policy + float load_factor() const noexcept { + return (float)(bucket_count() - Buckets_.Empty()) / bucket_count(); + } + + void rehash(size_type sz) { + if (sz != 0) { + auto newBuckets = SizeFitter_.EvalSize(sz); + size_type occupied = bucket_count() - Buckets_.Empty(); + if (Expander::NeedGrow(occupied, newBuckets)) { + newBuckets = Max(newBuckets, SizeFitter_.EvalSize(Expander::SuitableSize(size()))); + } + RehashImpl(newBuckets); + } else { + RehashImpl(SizeFitter_.EvalSize(Expander::SuitableSize(size()))); + } + } + + void reserve(size_type sz) { rehash(sz); } // TODO(tender-bum) + + // Observers + constexpr auto hash_function() const noexcept { return Hasher_; } + constexpr auto key_eq() const noexcept { return KeyEqual_; } + +public: + template <class T> + std::pair<iterator, bool> InsertImpl(T&& value) { + return TryCreate(KeyGetter::Apply(value), [&](size_type idx) { + Buckets_.InitNode(idx, std::forward<T>(value)); + }); + } + + template <class T, class F> + Y_FORCE_INLINE std::pair<iterator, bool> TryCreate(const T& key, F nodeInit) { + size_type hs = hash_function()(key); + size_type idx = FindProperBucket(hs, key); + if (!Buckets_.IsTaken(idx)) { + if (Expander::WillNeedGrow(bucket_count() - Buckets_.Empty(), bucket_count())) { + RehashImpl(); + idx = FindProperBucket(hs, key); + } + nodeInit(idx); + return { iterator{ &Buckets_, idx }, true }; + } + return { iterator{ &Buckets_, idx }, false }; + } + + template <class K> + size_type FindProperBucket(size_type hs, const K& key) const { + return Probing::FindBucket(SizeFitter_, hs, bucket_count(), [&](size_type idx) { + if constexpr (NConcepts::RemovalContainerV<Container>) { + return Buckets_.IsEmpty(idx) || + Buckets_.IsTaken(idx) && key_eq()(KeyGetter::Apply(Buckets_.Node(idx)), key); + } else { + return Buckets_.IsEmpty(idx) || key_eq()(KeyGetter::Apply(Buckets_.Node(idx)), key); + } + }); + } + + void RehashImpl() { + if constexpr (NConcepts::RemovalContainerV<Container>) { + size_type occupied = bucket_count() - Buckets_.Empty(); + if (size() < occupied / 2) { + rehash(bucket_count()); // Just clearing all deleted elements + } else { + RehashImpl(SizeFitter_.EvalSize(Expander::EvalNewSize(bucket_count()))); + } + } else { + RehashImpl(SizeFitter_.EvalSize(Expander::EvalNewSize(bucket_count()))); + } + } + + void RehashImpl(size_type newSize) { + TTable tmp = Buckets_.Clone(newSize); + for (auto& value : *this) { + size_type hs = hash_function()(KeyGetter::Apply(value)); + tmp.Buckets_.InitNode( + tmp.FindProperBucket(hs, KeyGetter::Apply(value)), std::move_if_noexcept(value)); + } + swap(tmp); + } + +public: + SizeFitter SizeFitter_; + Container Buckets_; + hasher Hasher_; + key_equal KeyEqual_; +}; + +} // namespace NFlatHash diff --git a/library/cpp/containers/flat_hash/lib/ut/containers_ut.cpp b/library/cpp/containers/flat_hash/lib/ut/containers_ut.cpp index 9d39a43f90..b17b30fa80 100644 --- a/library/cpp/containers/flat_hash/lib/ut/containers_ut.cpp +++ b/library/cpp/containers/flat_hash/lib/ut/containers_ut.cpp @@ -1,410 +1,410 @@ #include <library/cpp/containers/flat_hash/lib/containers.h> - + #include <library/cpp/testing/unittest/registar.h> - -#include <util/generic/algorithm.h> -#include <util/random/random.h> -#include <util/random/shuffle.h> - -using namespace NFlatHash; - -namespace { - constexpr size_t INIT_SIZE = 128; - - struct TDummy { - static size_t Count; - - TDummy() { ++Count; } - TDummy(const TDummy&) { ++Count; } - ~TDummy() { --Count; } - }; - size_t TDummy::Count = 0; - - struct TAlmostDummy { - static size_t Count; - - TAlmostDummy(int j = 0) : Junk(j) { ++Count; } - TAlmostDummy(const TAlmostDummy& d) : Junk(d.Junk) { ++Count; } - ~TAlmostDummy() { --Count; } - - bool operator==(const TAlmostDummy& r) const { return Junk == r.Junk; }; - bool operator!=(const TAlmostDummy& r) const { return !operator==(r); }; - - int Junk; - }; - size_t TAlmostDummy::Count = 0; - - struct TNotSimple { - enum class EType { - Value, - Empty, - Deleted - } Type_ = EType::Value; - - TString Junk = "something"; // to prevent triviality propagation - int Value = 0; - - static int CtorCalls; - static int DtorCalls; - static int CopyCtorCalls; - static int MoveCtorCalls; - - TNotSimple() { - ++CtorCalls; - } - explicit TNotSimple(int value) - : Value(value) - { - ++CtorCalls; - } - - TNotSimple(const TNotSimple& rhs) { - ++CopyCtorCalls; - Value = rhs.Value; - Type_ = rhs.Type_; - } - TNotSimple(TNotSimple&& rhs) { - ++MoveCtorCalls; - Value = rhs.Value; - Type_ = rhs.Type_; - } - - ~TNotSimple() { - ++DtorCalls; - } - - TNotSimple& operator=(const TNotSimple& rhs) { - ++CopyCtorCalls; - Value = rhs.Value; - Type_ = rhs.Type_; - return *this; - } - TNotSimple& operator=(TNotSimple&& rhs) { - ++MoveCtorCalls; - Value = rhs.Value; - Type_ = rhs.Type_; - return *this; - } - - static TNotSimple Empty() { - TNotSimple ret; - ret.Type_ = EType::Empty; - return ret; - } - - static TNotSimple Deleted() { - TNotSimple ret; - ret.Type_ = EType::Deleted; - return ret; - } - - bool operator==(const TNotSimple& rhs) const noexcept { - return Value == rhs.Value; - } - - static void ResetStats() { - CtorCalls = 0; - DtorCalls = 0; - CopyCtorCalls = 0; - MoveCtorCalls = 0; - } - }; - - int TNotSimple::CtorCalls = 0; - int TNotSimple::DtorCalls = 0; - int TNotSimple::CopyCtorCalls = 0; - int TNotSimple::MoveCtorCalls = 0; - - struct TNotSimpleEmptyMarker { - using value_type = TNotSimple; - - value_type Create() const { - return TNotSimple::Empty(); - } - - bool Equals(const value_type& rhs) const { - return rhs.Type_ == TNotSimple::EType::Empty; - } - }; - - struct TNotSimpleDeletedMarker { - using value_type = TNotSimple; - - value_type Create() const { - return TNotSimple::Deleted(); - } - - bool Equals(const value_type& rhs) const { - return rhs.Type_ == TNotSimple::EType::Deleted; - } - }; - - template <class Container> - void CheckContainersEqual(const Container& a, const Container& b) { - UNIT_ASSERT_EQUAL(a.Size(), b.Size()); - UNIT_ASSERT_EQUAL(a.Taken(), b.Empty()); - for (typename Container::size_type i = 0; i < a.Size(); ++i) { - if (a.IsTaken(i)) { - UNIT_ASSERT(b.IsTaken(i)); - UNIT_ASSERT_EQUAL(a.Node(i), b.Node(i)); - } - } - } - - template <class Container, class... Args> - void SmokingTest(typename Container::size_type size, Args&&... args) { - using size_type = typename Container::size_type; - using value_type = typename Container::value_type; - - Container cont(size, std::forward<Args>(args)...); - UNIT_ASSERT_EQUAL(cont.Size(), size); - UNIT_ASSERT_EQUAL(cont.Taken(), 0); - - for (size_type i = 0; i < cont.Size(); ++i) { - UNIT_ASSERT(cont.IsEmpty(i)); - UNIT_ASSERT(!cont.IsTaken(i)); - } - - // Filling the container till half - TVector<size_type> toInsert(cont.Size()); - Iota(toInsert.begin(), toInsert.end(), 0); - Shuffle(toInsert.begin(), toInsert.end()); - toInsert.resize(toInsert.size() / 2); - for (auto i : toInsert) { - UNIT_ASSERT(cont.IsEmpty(i)); - UNIT_ASSERT(!cont.IsTaken(i)); - value_type value(RandomNumber<size_type>(cont.Size())); - cont.InitNode(i, value); - UNIT_ASSERT(!cont.IsEmpty(i)); - UNIT_ASSERT(cont.IsTaken(i)); - UNIT_ASSERT_EQUAL(cont.Node(i), value); - } - UNIT_ASSERT_EQUAL(cont.Taken(), toInsert.size()); - - // Copy construction test - auto cont2 = cont; - CheckContainersEqual(cont, cont2); - - // Copy assignment test - cont2 = cont2.Clone(0); - UNIT_ASSERT_EQUAL(cont2.Size(), 0); - UNIT_ASSERT_EQUAL(cont2.Taken(), 0); - - // Copy assignment test - cont2 = cont; - CheckContainersEqual(cont, cont2); - - // Move construction test - auto cont3 = std::move(cont2); - UNIT_ASSERT_EQUAL(cont2.Size(), 0); - CheckContainersEqual(cont, cont3); - - // Move assignment test - cont2 = std::move(cont3); - UNIT_ASSERT_EQUAL(cont3.Size(), 0); - CheckContainersEqual(cont, cont2); - } -} - -Y_UNIT_TEST_SUITE(TFlatContainerTest) { - Y_UNIT_TEST(SmokingTest) { - SmokingTest<TFlatContainer<int>>(INIT_SIZE); - } - - Y_UNIT_TEST(SmokingTestNotSimpleType) { - TNotSimple::ResetStats(); - SmokingTest<TFlatContainer<TNotSimple>>(INIT_SIZE); - - UNIT_ASSERT_EQUAL(TNotSimple::CtorCalls + TNotSimple::CopyCtorCalls + TNotSimple::MoveCtorCalls, - TNotSimple::DtorCalls); - UNIT_ASSERT_EQUAL(TNotSimple::CtorCalls, INIT_SIZE / 2 /* created while filling */); - UNIT_ASSERT_EQUAL(TNotSimple::DtorCalls, INIT_SIZE / 2 /* removed filling temporary */ - + INIT_SIZE / 2 /* removed while cloning */ - + INIT_SIZE /* 3 containers dtors */); - UNIT_ASSERT_EQUAL(TNotSimple::CopyCtorCalls, INIT_SIZE / 2 /* 3 created while filling */ - + INIT_SIZE / 2 /* created while copy constructing */ - + INIT_SIZE / 2/* created while copy assigning */); - UNIT_ASSERT_EQUAL(TNotSimple::MoveCtorCalls, 0); - } - - Y_UNIT_TEST(DummyHalfSizeTest) { - using TContainer = TFlatContainer<TDummy>; - using size_type = typename TContainer::size_type; - - { - TContainer cont(INIT_SIZE); - UNIT_ASSERT_EQUAL(TDummy::Count, 0); - - TVector<size_type> toInsert(cont.Size()); - Iota(toInsert.begin(), toInsert.end(), 0); - Shuffle(toInsert.begin(), toInsert.end()); - toInsert.resize(toInsert.size() / 2); - for (auto i : toInsert) { - UNIT_ASSERT(cont.IsEmpty(i)); - UNIT_ASSERT(!cont.IsTaken(i)); - cont.InitNode(i); - UNIT_ASSERT_EQUAL(TDummy::Count, cont.Taken()); - UNIT_ASSERT(!cont.IsEmpty(i)); - UNIT_ASSERT(cont.IsTaken(i)); - } - UNIT_ASSERT_EQUAL(cont.Taken(), cont.Size() / 2); - UNIT_ASSERT_EQUAL(TDummy::Count, cont.Taken()); - } - UNIT_ASSERT_EQUAL(TDummy::Count, 0); - } - - Y_UNIT_TEST(DeleteTest) { - using TContainer = TFlatContainer<TDummy>; - using size_type = typename TContainer::size_type; - - TContainer cont(INIT_SIZE); - auto idx = RandomNumber<size_type>(INIT_SIZE); - UNIT_ASSERT(!cont.IsTaken(idx)); - UNIT_ASSERT(!cont.IsDeleted(idx)); - UNIT_ASSERT_EQUAL(TDummy::Count, 0); - - cont.InitNode(idx); - UNIT_ASSERT_EQUAL(cont.Taken(), 1); - UNIT_ASSERT(cont.IsTaken(idx)); - UNIT_ASSERT(!cont.IsDeleted(idx)); - UNIT_ASSERT_EQUAL(TDummy::Count, 1); - - cont.DeleteNode(idx); - UNIT_ASSERT(!cont.IsTaken(idx)); - UNIT_ASSERT(cont.IsDeleted(idx)); - UNIT_ASSERT_EQUAL(TDummy::Count, 0); - } -} - -Y_UNIT_TEST_SUITE(TDenseContainerTest) { - Y_UNIT_TEST(SmokingTest) { - SmokingTest<TDenseContainer<int, NSet::TStaticValueMarker<-1>>>(INIT_SIZE); - } - - Y_UNIT_TEST(NotSimpleTypeSmokingTest) { - TNotSimple::ResetStats(); - SmokingTest<TDenseContainer<TNotSimple, TNotSimpleEmptyMarker>>(INIT_SIZE); - - UNIT_ASSERT_EQUAL(TNotSimple::CtorCalls + TNotSimple::CopyCtorCalls + TNotSimple::MoveCtorCalls, - TNotSimple::DtorCalls); - UNIT_ASSERT_EQUAL(TNotSimple::CtorCalls, INIT_SIZE / 2 /* created while filling */ - + 2 /* created by empty marker */); - UNIT_ASSERT_EQUAL(TNotSimple::DtorCalls, 1 /* removed empty marker temporary */ - + INIT_SIZE /* half removed while resetting in container, - half removed inserted temporary */ - + INIT_SIZE /* removed while cloning */ - + 1 /* removed empty marker temporary */ - + INIT_SIZE * 2 /* 3 containers dtors */); - UNIT_ASSERT_EQUAL(TNotSimple::CopyCtorCalls, INIT_SIZE /* created while constructing */ - + INIT_SIZE / 2 /* 3 created while filling */ - + INIT_SIZE /* created while copy constructing */ - + INIT_SIZE /* created while copy assigning */); - UNIT_ASSERT_EQUAL(TNotSimple::MoveCtorCalls, 0); - } - - Y_UNIT_TEST(RemovalContainerSmokingTest) { - SmokingTest<TRemovalDenseContainer<int, NSet::TStaticValueMarker<-1>, - NSet::TStaticValueMarker<-2>>>(INIT_SIZE); - } - - Y_UNIT_TEST(NotSimpleTypeRemovalContainerSmokingTest) { - TNotSimple::ResetStats(); - SmokingTest<TRemovalDenseContainer<TNotSimple, TNotSimpleEmptyMarker, - TNotSimpleDeletedMarker>>(INIT_SIZE); - - UNIT_ASSERT_EQUAL(TNotSimple::CtorCalls + TNotSimple::CopyCtorCalls + TNotSimple::MoveCtorCalls, - TNotSimple::DtorCalls); - UNIT_ASSERT_EQUAL(TNotSimple::CtorCalls, INIT_SIZE / 2 /* created while filling */ - + 2 /* created by empty marker */); - UNIT_ASSERT_EQUAL(TNotSimple::DtorCalls, 1 /* removed empty marker temporary */ - + INIT_SIZE /* half removed while resetting in container, - half removed inserted temporary */ - + INIT_SIZE /* removed while cloning */ - + 1 /* removed empty marker temporary */ - + INIT_SIZE * 2 /* 3 containers dtors */); - UNIT_ASSERT_EQUAL(TNotSimple::CopyCtorCalls, INIT_SIZE /* created while constructing */ - + INIT_SIZE / 2 /* 3 created while filling */ - + INIT_SIZE /* created while copy constructing */ - + INIT_SIZE /* created while copy assigning */); - UNIT_ASSERT_EQUAL(TNotSimple::MoveCtorCalls, 0); - } - - Y_UNIT_TEST(DummyHalfSizeTest) { - using TContainer = TDenseContainer<TAlmostDummy, NSet::TEqValueMarker<TAlmostDummy>>; - using size_type = typename TContainer::size_type; - - { - TContainer cont(INIT_SIZE, TAlmostDummy{-1}); - UNIT_ASSERT_EQUAL(TAlmostDummy::Count, cont.Size() + 1); // 1 for empty marker - - TVector<size_type> toInsert(cont.Size()); - Iota(toInsert.begin(), toInsert.end(), 0); - Shuffle(toInsert.begin(), toInsert.end()); - toInsert.resize(toInsert.size() / 2); - for (auto i : toInsert) { - UNIT_ASSERT(cont.IsEmpty(i)); - UNIT_ASSERT(!cont.IsTaken(i)); - cont.InitNode(i, (int)RandomNumber<size_type>(cont.Size())); - UNIT_ASSERT_EQUAL(TAlmostDummy::Count, cont.Size() + 1); - UNIT_ASSERT(!cont.IsEmpty(i)); - UNIT_ASSERT(cont.IsTaken(i)); - } - UNIT_ASSERT_EQUAL(cont.Taken(), toInsert.size()); - UNIT_ASSERT_EQUAL(TAlmostDummy::Count, cont.Size() + 1); - } - UNIT_ASSERT_EQUAL(TAlmostDummy::Count, 0); - } - - Y_UNIT_TEST(DeleteTest) { - using TContainer = TRemovalDenseContainer<TAlmostDummy, NSet::TEqValueMarker<TAlmostDummy>, - NSet::TEqValueMarker<TAlmostDummy>>; - using size_type = typename TContainer::size_type; - - TContainer cont(INIT_SIZE, TAlmostDummy{ -2 }, TAlmostDummy{ -1 }); - auto idx = RandomNumber<size_type>(cont.Size()); - UNIT_ASSERT(!cont.IsTaken(idx)); - UNIT_ASSERT(!cont.IsDeleted(idx)); - UNIT_ASSERT_EQUAL(TAlmostDummy::Count, cont.Size() + 2); // 2 for markers - - cont.InitNode(idx, (int)RandomNumber<size_type>(cont.Size())); - UNIT_ASSERT_EQUAL(cont.Taken(), 1); - UNIT_ASSERT(cont.IsTaken(idx)); - UNIT_ASSERT(!cont.IsDeleted(idx)); - UNIT_ASSERT_EQUAL(TAlmostDummy::Count, cont.Size() + 2); - - cont.DeleteNode(idx); - UNIT_ASSERT(!cont.IsTaken(idx)); - UNIT_ASSERT(cont.IsDeleted(idx)); - UNIT_ASSERT_EQUAL(TAlmostDummy::Count, cont.Size() + 2); - } - - Y_UNIT_TEST(FancyInitsTest) { - { - using TContainer = TDenseContainer<int>; - TContainer cont{ INIT_SIZE, -1 }; - } - { - using TContainer = TDenseContainer<int, NSet::TStaticValueMarker<-1>>; - TContainer cont{ INIT_SIZE }; - static_assert(!std::is_constructible_v<TContainer, size_t, int>); - } - { - using TContainer = TDenseContainer<int, NSet::TEqValueMarker<int>>; - TContainer cont{ INIT_SIZE, -1 }; - TContainer cont2{ INIT_SIZE, NSet::TEqValueMarker<int>{ -1 } }; - } - { - using TContainer = TRemovalDenseContainer<int>; - TContainer cont{ INIT_SIZE, -1, -2 }; - TContainer cont2{ INIT_SIZE, NSet::TEqValueMarker<int>{ -1 }, - NSet::TEqValueMarker<int>{ -2 } }; - } - { - using TContainer = TRemovalDenseContainer<int, NSet::TStaticValueMarker<-1>, - NSet::TStaticValueMarker<-1>>; - TContainer cont{ INIT_SIZE }; - static_assert(!std::is_constructible_v<TContainer, size_t, int>); - static_assert(!std::is_constructible_v<TContainer, size_t, int, int>); - } - } -} + +#include <util/generic/algorithm.h> +#include <util/random/random.h> +#include <util/random/shuffle.h> + +using namespace NFlatHash; + +namespace { + constexpr size_t INIT_SIZE = 128; + + struct TDummy { + static size_t Count; + + TDummy() { ++Count; } + TDummy(const TDummy&) { ++Count; } + ~TDummy() { --Count; } + }; + size_t TDummy::Count = 0; + + struct TAlmostDummy { + static size_t Count; + + TAlmostDummy(int j = 0) : Junk(j) { ++Count; } + TAlmostDummy(const TAlmostDummy& d) : Junk(d.Junk) { ++Count; } + ~TAlmostDummy() { --Count; } + + bool operator==(const TAlmostDummy& r) const { return Junk == r.Junk; }; + bool operator!=(const TAlmostDummy& r) const { return !operator==(r); }; + + int Junk; + }; + size_t TAlmostDummy::Count = 0; + + struct TNotSimple { + enum class EType { + Value, + Empty, + Deleted + } Type_ = EType::Value; + + TString Junk = "something"; // to prevent triviality propagation + int Value = 0; + + static int CtorCalls; + static int DtorCalls; + static int CopyCtorCalls; + static int MoveCtorCalls; + + TNotSimple() { + ++CtorCalls; + } + explicit TNotSimple(int value) + : Value(value) + { + ++CtorCalls; + } + + TNotSimple(const TNotSimple& rhs) { + ++CopyCtorCalls; + Value = rhs.Value; + Type_ = rhs.Type_; + } + TNotSimple(TNotSimple&& rhs) { + ++MoveCtorCalls; + Value = rhs.Value; + Type_ = rhs.Type_; + } + + ~TNotSimple() { + ++DtorCalls; + } + + TNotSimple& operator=(const TNotSimple& rhs) { + ++CopyCtorCalls; + Value = rhs.Value; + Type_ = rhs.Type_; + return *this; + } + TNotSimple& operator=(TNotSimple&& rhs) { + ++MoveCtorCalls; + Value = rhs.Value; + Type_ = rhs.Type_; + return *this; + } + + static TNotSimple Empty() { + TNotSimple ret; + ret.Type_ = EType::Empty; + return ret; + } + + static TNotSimple Deleted() { + TNotSimple ret; + ret.Type_ = EType::Deleted; + return ret; + } + + bool operator==(const TNotSimple& rhs) const noexcept { + return Value == rhs.Value; + } + + static void ResetStats() { + CtorCalls = 0; + DtorCalls = 0; + CopyCtorCalls = 0; + MoveCtorCalls = 0; + } + }; + + int TNotSimple::CtorCalls = 0; + int TNotSimple::DtorCalls = 0; + int TNotSimple::CopyCtorCalls = 0; + int TNotSimple::MoveCtorCalls = 0; + + struct TNotSimpleEmptyMarker { + using value_type = TNotSimple; + + value_type Create() const { + return TNotSimple::Empty(); + } + + bool Equals(const value_type& rhs) const { + return rhs.Type_ == TNotSimple::EType::Empty; + } + }; + + struct TNotSimpleDeletedMarker { + using value_type = TNotSimple; + + value_type Create() const { + return TNotSimple::Deleted(); + } + + bool Equals(const value_type& rhs) const { + return rhs.Type_ == TNotSimple::EType::Deleted; + } + }; + + template <class Container> + void CheckContainersEqual(const Container& a, const Container& b) { + UNIT_ASSERT_EQUAL(a.Size(), b.Size()); + UNIT_ASSERT_EQUAL(a.Taken(), b.Empty()); + for (typename Container::size_type i = 0; i < a.Size(); ++i) { + if (a.IsTaken(i)) { + UNIT_ASSERT(b.IsTaken(i)); + UNIT_ASSERT_EQUAL(a.Node(i), b.Node(i)); + } + } + } + + template <class Container, class... Args> + void SmokingTest(typename Container::size_type size, Args&&... args) { + using size_type = typename Container::size_type; + using value_type = typename Container::value_type; + + Container cont(size, std::forward<Args>(args)...); + UNIT_ASSERT_EQUAL(cont.Size(), size); + UNIT_ASSERT_EQUAL(cont.Taken(), 0); + + for (size_type i = 0; i < cont.Size(); ++i) { + UNIT_ASSERT(cont.IsEmpty(i)); + UNIT_ASSERT(!cont.IsTaken(i)); + } + + // Filling the container till half + TVector<size_type> toInsert(cont.Size()); + Iota(toInsert.begin(), toInsert.end(), 0); + Shuffle(toInsert.begin(), toInsert.end()); + toInsert.resize(toInsert.size() / 2); + for (auto i : toInsert) { + UNIT_ASSERT(cont.IsEmpty(i)); + UNIT_ASSERT(!cont.IsTaken(i)); + value_type value(RandomNumber<size_type>(cont.Size())); + cont.InitNode(i, value); + UNIT_ASSERT(!cont.IsEmpty(i)); + UNIT_ASSERT(cont.IsTaken(i)); + UNIT_ASSERT_EQUAL(cont.Node(i), value); + } + UNIT_ASSERT_EQUAL(cont.Taken(), toInsert.size()); + + // Copy construction test + auto cont2 = cont; + CheckContainersEqual(cont, cont2); + + // Copy assignment test + cont2 = cont2.Clone(0); + UNIT_ASSERT_EQUAL(cont2.Size(), 0); + UNIT_ASSERT_EQUAL(cont2.Taken(), 0); + + // Copy assignment test + cont2 = cont; + CheckContainersEqual(cont, cont2); + + // Move construction test + auto cont3 = std::move(cont2); + UNIT_ASSERT_EQUAL(cont2.Size(), 0); + CheckContainersEqual(cont, cont3); + + // Move assignment test + cont2 = std::move(cont3); + UNIT_ASSERT_EQUAL(cont3.Size(), 0); + CheckContainersEqual(cont, cont2); + } +} + +Y_UNIT_TEST_SUITE(TFlatContainerTest) { + Y_UNIT_TEST(SmokingTest) { + SmokingTest<TFlatContainer<int>>(INIT_SIZE); + } + + Y_UNIT_TEST(SmokingTestNotSimpleType) { + TNotSimple::ResetStats(); + SmokingTest<TFlatContainer<TNotSimple>>(INIT_SIZE); + + UNIT_ASSERT_EQUAL(TNotSimple::CtorCalls + TNotSimple::CopyCtorCalls + TNotSimple::MoveCtorCalls, + TNotSimple::DtorCalls); + UNIT_ASSERT_EQUAL(TNotSimple::CtorCalls, INIT_SIZE / 2 /* created while filling */); + UNIT_ASSERT_EQUAL(TNotSimple::DtorCalls, INIT_SIZE / 2 /* removed filling temporary */ + + INIT_SIZE / 2 /* removed while cloning */ + + INIT_SIZE /* 3 containers dtors */); + UNIT_ASSERT_EQUAL(TNotSimple::CopyCtorCalls, INIT_SIZE / 2 /* 3 created while filling */ + + INIT_SIZE / 2 /* created while copy constructing */ + + INIT_SIZE / 2/* created while copy assigning */); + UNIT_ASSERT_EQUAL(TNotSimple::MoveCtorCalls, 0); + } + + Y_UNIT_TEST(DummyHalfSizeTest) { + using TContainer = TFlatContainer<TDummy>; + using size_type = typename TContainer::size_type; + + { + TContainer cont(INIT_SIZE); + UNIT_ASSERT_EQUAL(TDummy::Count, 0); + + TVector<size_type> toInsert(cont.Size()); + Iota(toInsert.begin(), toInsert.end(), 0); + Shuffle(toInsert.begin(), toInsert.end()); + toInsert.resize(toInsert.size() / 2); + for (auto i : toInsert) { + UNIT_ASSERT(cont.IsEmpty(i)); + UNIT_ASSERT(!cont.IsTaken(i)); + cont.InitNode(i); + UNIT_ASSERT_EQUAL(TDummy::Count, cont.Taken()); + UNIT_ASSERT(!cont.IsEmpty(i)); + UNIT_ASSERT(cont.IsTaken(i)); + } + UNIT_ASSERT_EQUAL(cont.Taken(), cont.Size() / 2); + UNIT_ASSERT_EQUAL(TDummy::Count, cont.Taken()); + } + UNIT_ASSERT_EQUAL(TDummy::Count, 0); + } + + Y_UNIT_TEST(DeleteTest) { + using TContainer = TFlatContainer<TDummy>; + using size_type = typename TContainer::size_type; + + TContainer cont(INIT_SIZE); + auto idx = RandomNumber<size_type>(INIT_SIZE); + UNIT_ASSERT(!cont.IsTaken(idx)); + UNIT_ASSERT(!cont.IsDeleted(idx)); + UNIT_ASSERT_EQUAL(TDummy::Count, 0); + + cont.InitNode(idx); + UNIT_ASSERT_EQUAL(cont.Taken(), 1); + UNIT_ASSERT(cont.IsTaken(idx)); + UNIT_ASSERT(!cont.IsDeleted(idx)); + UNIT_ASSERT_EQUAL(TDummy::Count, 1); + + cont.DeleteNode(idx); + UNIT_ASSERT(!cont.IsTaken(idx)); + UNIT_ASSERT(cont.IsDeleted(idx)); + UNIT_ASSERT_EQUAL(TDummy::Count, 0); + } +} + +Y_UNIT_TEST_SUITE(TDenseContainerTest) { + Y_UNIT_TEST(SmokingTest) { + SmokingTest<TDenseContainer<int, NSet::TStaticValueMarker<-1>>>(INIT_SIZE); + } + + Y_UNIT_TEST(NotSimpleTypeSmokingTest) { + TNotSimple::ResetStats(); + SmokingTest<TDenseContainer<TNotSimple, TNotSimpleEmptyMarker>>(INIT_SIZE); + + UNIT_ASSERT_EQUAL(TNotSimple::CtorCalls + TNotSimple::CopyCtorCalls + TNotSimple::MoveCtorCalls, + TNotSimple::DtorCalls); + UNIT_ASSERT_EQUAL(TNotSimple::CtorCalls, INIT_SIZE / 2 /* created while filling */ + + 2 /* created by empty marker */); + UNIT_ASSERT_EQUAL(TNotSimple::DtorCalls, 1 /* removed empty marker temporary */ + + INIT_SIZE /* half removed while resetting in container, + half removed inserted temporary */ + + INIT_SIZE /* removed while cloning */ + + 1 /* removed empty marker temporary */ + + INIT_SIZE * 2 /* 3 containers dtors */); + UNIT_ASSERT_EQUAL(TNotSimple::CopyCtorCalls, INIT_SIZE /* created while constructing */ + + INIT_SIZE / 2 /* 3 created while filling */ + + INIT_SIZE /* created while copy constructing */ + + INIT_SIZE /* created while copy assigning */); + UNIT_ASSERT_EQUAL(TNotSimple::MoveCtorCalls, 0); + } + + Y_UNIT_TEST(RemovalContainerSmokingTest) { + SmokingTest<TRemovalDenseContainer<int, NSet::TStaticValueMarker<-1>, + NSet::TStaticValueMarker<-2>>>(INIT_SIZE); + } + + Y_UNIT_TEST(NotSimpleTypeRemovalContainerSmokingTest) { + TNotSimple::ResetStats(); + SmokingTest<TRemovalDenseContainer<TNotSimple, TNotSimpleEmptyMarker, + TNotSimpleDeletedMarker>>(INIT_SIZE); + + UNIT_ASSERT_EQUAL(TNotSimple::CtorCalls + TNotSimple::CopyCtorCalls + TNotSimple::MoveCtorCalls, + TNotSimple::DtorCalls); + UNIT_ASSERT_EQUAL(TNotSimple::CtorCalls, INIT_SIZE / 2 /* created while filling */ + + 2 /* created by empty marker */); + UNIT_ASSERT_EQUAL(TNotSimple::DtorCalls, 1 /* removed empty marker temporary */ + + INIT_SIZE /* half removed while resetting in container, + half removed inserted temporary */ + + INIT_SIZE /* removed while cloning */ + + 1 /* removed empty marker temporary */ + + INIT_SIZE * 2 /* 3 containers dtors */); + UNIT_ASSERT_EQUAL(TNotSimple::CopyCtorCalls, INIT_SIZE /* created while constructing */ + + INIT_SIZE / 2 /* 3 created while filling */ + + INIT_SIZE /* created while copy constructing */ + + INIT_SIZE /* created while copy assigning */); + UNIT_ASSERT_EQUAL(TNotSimple::MoveCtorCalls, 0); + } + + Y_UNIT_TEST(DummyHalfSizeTest) { + using TContainer = TDenseContainer<TAlmostDummy, NSet::TEqValueMarker<TAlmostDummy>>; + using size_type = typename TContainer::size_type; + + { + TContainer cont(INIT_SIZE, TAlmostDummy{-1}); + UNIT_ASSERT_EQUAL(TAlmostDummy::Count, cont.Size() + 1); // 1 for empty marker + + TVector<size_type> toInsert(cont.Size()); + Iota(toInsert.begin(), toInsert.end(), 0); + Shuffle(toInsert.begin(), toInsert.end()); + toInsert.resize(toInsert.size() / 2); + for (auto i : toInsert) { + UNIT_ASSERT(cont.IsEmpty(i)); + UNIT_ASSERT(!cont.IsTaken(i)); + cont.InitNode(i, (int)RandomNumber<size_type>(cont.Size())); + UNIT_ASSERT_EQUAL(TAlmostDummy::Count, cont.Size() + 1); + UNIT_ASSERT(!cont.IsEmpty(i)); + UNIT_ASSERT(cont.IsTaken(i)); + } + UNIT_ASSERT_EQUAL(cont.Taken(), toInsert.size()); + UNIT_ASSERT_EQUAL(TAlmostDummy::Count, cont.Size() + 1); + } + UNIT_ASSERT_EQUAL(TAlmostDummy::Count, 0); + } + + Y_UNIT_TEST(DeleteTest) { + using TContainer = TRemovalDenseContainer<TAlmostDummy, NSet::TEqValueMarker<TAlmostDummy>, + NSet::TEqValueMarker<TAlmostDummy>>; + using size_type = typename TContainer::size_type; + + TContainer cont(INIT_SIZE, TAlmostDummy{ -2 }, TAlmostDummy{ -1 }); + auto idx = RandomNumber<size_type>(cont.Size()); + UNIT_ASSERT(!cont.IsTaken(idx)); + UNIT_ASSERT(!cont.IsDeleted(idx)); + UNIT_ASSERT_EQUAL(TAlmostDummy::Count, cont.Size() + 2); // 2 for markers + + cont.InitNode(idx, (int)RandomNumber<size_type>(cont.Size())); + UNIT_ASSERT_EQUAL(cont.Taken(), 1); + UNIT_ASSERT(cont.IsTaken(idx)); + UNIT_ASSERT(!cont.IsDeleted(idx)); + UNIT_ASSERT_EQUAL(TAlmostDummy::Count, cont.Size() + 2); + + cont.DeleteNode(idx); + UNIT_ASSERT(!cont.IsTaken(idx)); + UNIT_ASSERT(cont.IsDeleted(idx)); + UNIT_ASSERT_EQUAL(TAlmostDummy::Count, cont.Size() + 2); + } + + Y_UNIT_TEST(FancyInitsTest) { + { + using TContainer = TDenseContainer<int>; + TContainer cont{ INIT_SIZE, -1 }; + } + { + using TContainer = TDenseContainer<int, NSet::TStaticValueMarker<-1>>; + TContainer cont{ INIT_SIZE }; + static_assert(!std::is_constructible_v<TContainer, size_t, int>); + } + { + using TContainer = TDenseContainer<int, NSet::TEqValueMarker<int>>; + TContainer cont{ INIT_SIZE, -1 }; + TContainer cont2{ INIT_SIZE, NSet::TEqValueMarker<int>{ -1 } }; + } + { + using TContainer = TRemovalDenseContainer<int>; + TContainer cont{ INIT_SIZE, -1, -2 }; + TContainer cont2{ INIT_SIZE, NSet::TEqValueMarker<int>{ -1 }, + NSet::TEqValueMarker<int>{ -2 } }; + } + { + using TContainer = TRemovalDenseContainer<int, NSet::TStaticValueMarker<-1>, + NSet::TStaticValueMarker<-1>>; + TContainer cont{ INIT_SIZE }; + static_assert(!std::is_constructible_v<TContainer, size_t, int>); + static_assert(!std::is_constructible_v<TContainer, size_t, int, int>); + } + } +} diff --git a/library/cpp/containers/flat_hash/lib/ut/iterator_ut.cpp b/library/cpp/containers/flat_hash/lib/ut/iterator_ut.cpp index 10111b74da..0b77bf043f 100644 --- a/library/cpp/containers/flat_hash/lib/ut/iterator_ut.cpp +++ b/library/cpp/containers/flat_hash/lib/ut/iterator_ut.cpp @@ -1,85 +1,85 @@ #include <library/cpp/containers/flat_hash/lib/iterator.h> #include <library/cpp/containers/flat_hash/lib/containers.h> - + #include <library/cpp/testing/unittest/registar.h> - -#include <util/random/random.h> -#include <util/generic/algorithm.h> - -using namespace NFlatHash; - -namespace { - constexpr size_t INIT_SIZE = 128; - - template <class Container> - void SmokingTest(Container& cont) { - using value_type = typename Container::value_type; - using iterator = TIterator<Container, value_type>; - using size_type = typename Container::size_type; - - iterator f(&cont), l(&cont, cont.Size()); - UNIT_ASSERT_EQUAL(f, l); - UNIT_ASSERT_EQUAL((size_type)std::distance(f, l), cont.Taken()); - - TVector<std::pair<size_type, value_type>> toAdd{ - { 0, (int)RandomNumber<size_type>(INIT_SIZE) }, - { 1 + RandomNumber<size_type>(INIT_SIZE - 2), (int)RandomNumber<size_type>(INIT_SIZE) }, - { INIT_SIZE - 1, (int)RandomNumber<size_type>(INIT_SIZE) } - }; - - for (const auto& p : toAdd) { - UNIT_ASSERT(cont.IsEmpty(p.first)); - cont.InitNode(p.first, p.second); - } - UNIT_ASSERT_EQUAL(cont.Size(), INIT_SIZE); - f = iterator{ &cont }; - l = iterator{ &cont, INIT_SIZE }; - UNIT_ASSERT_UNEQUAL(f, l); - UNIT_ASSERT_EQUAL((size_type)std::distance(f, l), cont.Taken()); - - TVector<value_type> added(f, l); - UNIT_ASSERT(::Equal(toAdd.begin(), toAdd.end(), added.begin(), [](const auto& p, auto v) { - return p.second == v; - })); - } - - template <class Container> - void ConstTest(Container& cont) { - using value_type = typename Container::value_type; - using iterator = TIterator<Container, value_type>; - using const_iterator = TIterator<const Container, const value_type>; - - iterator it{ &cont, INIT_SIZE / 2 }; - const_iterator cit1{ it }; - const_iterator cit2{ &cont, INIT_SIZE / 2 }; - - UNIT_ASSERT_EQUAL(cit1, cit2); - - static_assert(std::is_same<decltype(*it), value_type&>::value); - static_assert(std::is_same<decltype(*cit1), const value_type&>::value); - } -} - -Y_UNIT_TEST_SUITE(TIteratorTest) { - Y_UNIT_TEST(SmokingTest) { - { - TFlatContainer<int> cont(INIT_SIZE); - SmokingTest(cont); - } - { - TDenseContainer<int, NSet::TStaticValueMarker<-1>> cont(INIT_SIZE); - SmokingTest(cont); - } - } - - Y_UNIT_TEST(ConstTest) { - { - TFlatContainer<int> cont(INIT_SIZE); - ConstTest(cont); - } - { - TDenseContainer<int, NSet::TStaticValueMarker<-1>> cont(INIT_SIZE); - ConstTest(cont); - } - } -} + +#include <util/random/random.h> +#include <util/generic/algorithm.h> + +using namespace NFlatHash; + +namespace { + constexpr size_t INIT_SIZE = 128; + + template <class Container> + void SmokingTest(Container& cont) { + using value_type = typename Container::value_type; + using iterator = TIterator<Container, value_type>; + using size_type = typename Container::size_type; + + iterator f(&cont), l(&cont, cont.Size()); + UNIT_ASSERT_EQUAL(f, l); + UNIT_ASSERT_EQUAL((size_type)std::distance(f, l), cont.Taken()); + + TVector<std::pair<size_type, value_type>> toAdd{ + { 0, (int)RandomNumber<size_type>(INIT_SIZE) }, + { 1 + RandomNumber<size_type>(INIT_SIZE - 2), (int)RandomNumber<size_type>(INIT_SIZE) }, + { INIT_SIZE - 1, (int)RandomNumber<size_type>(INIT_SIZE) } + }; + + for (const auto& p : toAdd) { + UNIT_ASSERT(cont.IsEmpty(p.first)); + cont.InitNode(p.first, p.second); + } + UNIT_ASSERT_EQUAL(cont.Size(), INIT_SIZE); + f = iterator{ &cont }; + l = iterator{ &cont, INIT_SIZE }; + UNIT_ASSERT_UNEQUAL(f, l); + UNIT_ASSERT_EQUAL((size_type)std::distance(f, l), cont.Taken()); + + TVector<value_type> added(f, l); + UNIT_ASSERT(::Equal(toAdd.begin(), toAdd.end(), added.begin(), [](const auto& p, auto v) { + return p.second == v; + })); + } + + template <class Container> + void ConstTest(Container& cont) { + using value_type = typename Container::value_type; + using iterator = TIterator<Container, value_type>; + using const_iterator = TIterator<const Container, const value_type>; + + iterator it{ &cont, INIT_SIZE / 2 }; + const_iterator cit1{ it }; + const_iterator cit2{ &cont, INIT_SIZE / 2 }; + + UNIT_ASSERT_EQUAL(cit1, cit2); + + static_assert(std::is_same<decltype(*it), value_type&>::value); + static_assert(std::is_same<decltype(*cit1), const value_type&>::value); + } +} + +Y_UNIT_TEST_SUITE(TIteratorTest) { + Y_UNIT_TEST(SmokingTest) { + { + TFlatContainer<int> cont(INIT_SIZE); + SmokingTest(cont); + } + { + TDenseContainer<int, NSet::TStaticValueMarker<-1>> cont(INIT_SIZE); + SmokingTest(cont); + } + } + + Y_UNIT_TEST(ConstTest) { + { + TFlatContainer<int> cont(INIT_SIZE); + ConstTest(cont); + } + { + TDenseContainer<int, NSet::TStaticValueMarker<-1>> cont(INIT_SIZE); + ConstTest(cont); + } + } +} diff --git a/library/cpp/containers/flat_hash/lib/ut/probings_ut.cpp b/library/cpp/containers/flat_hash/lib/ut/probings_ut.cpp index 7d709fdaa5..593f8cbb1b 100644 --- a/library/cpp/containers/flat_hash/lib/ut/probings_ut.cpp +++ b/library/cpp/containers/flat_hash/lib/ut/probings_ut.cpp @@ -1,34 +1,34 @@ #include <library/cpp/containers/flat_hash/lib/probings.h> - + #include <library/cpp/testing/unittest/registar.h> - -using namespace NFlatHash; - -namespace { - struct TDummySizeFitter { - constexpr auto EvalIndex(size_t idx, size_t) const { - return idx; - } - }; - + +using namespace NFlatHash; + +namespace { + struct TDummySizeFitter { + constexpr auto EvalIndex(size_t idx, size_t) const { + return idx; + } + }; + constexpr TDummySizeFitter SIZE_FITTER; - - auto atLeast13 = [](size_t idx) { return idx >= 13; }; -} - -Y_UNIT_TEST_SUITE(TProbingsTest) { - Y_UNIT_TEST(LinearProbingTest) { - using TProbing = TLinearProbing; - UNIT_ASSERT_EQUAL(TProbing::FindBucket(SIZE_FITTER, 1, 0, atLeast13), 13); - } - - Y_UNIT_TEST(QuadraticProbingTest) { - using TProbing = TQuadraticProbing; - UNIT_ASSERT_EQUAL(TProbing::FindBucket(SIZE_FITTER, 1, 0, atLeast13), 17); - } - - Y_UNIT_TEST(DenseProbingTest) { - using TProbing = TDenseProbing; - UNIT_ASSERT_EQUAL(TProbing::FindBucket(SIZE_FITTER, 1, 0, atLeast13), 16); - } -} + + auto atLeast13 = [](size_t idx) { return idx >= 13; }; +} + +Y_UNIT_TEST_SUITE(TProbingsTest) { + Y_UNIT_TEST(LinearProbingTest) { + using TProbing = TLinearProbing; + UNIT_ASSERT_EQUAL(TProbing::FindBucket(SIZE_FITTER, 1, 0, atLeast13), 13); + } + + Y_UNIT_TEST(QuadraticProbingTest) { + using TProbing = TQuadraticProbing; + UNIT_ASSERT_EQUAL(TProbing::FindBucket(SIZE_FITTER, 1, 0, atLeast13), 17); + } + + Y_UNIT_TEST(DenseProbingTest) { + using TProbing = TDenseProbing; + UNIT_ASSERT_EQUAL(TProbing::FindBucket(SIZE_FITTER, 1, 0, atLeast13), 16); + } +} diff --git a/library/cpp/containers/flat_hash/lib/ut/size_fitters_ut.cpp b/library/cpp/containers/flat_hash/lib/ut/size_fitters_ut.cpp index 52084e734b..4167947ece 100644 --- a/library/cpp/containers/flat_hash/lib/ut/size_fitters_ut.cpp +++ b/library/cpp/containers/flat_hash/lib/ut/size_fitters_ut.cpp @@ -1,51 +1,51 @@ #include <library/cpp/containers/flat_hash/lib/size_fitters.h> - + #include <library/cpp/testing/unittest/registar.h> - -using namespace NFlatHash; - -Y_UNIT_TEST_SUITE(TAndSizeFitterTest) { - Y_UNIT_TEST(EvalSizeTest) { - TAndSizeFitter sf; - UNIT_ASSERT_EQUAL(sf.EvalSize(5), 8); - UNIT_ASSERT_EQUAL(sf.EvalSize(8), 8); - UNIT_ASSERT_EQUAL(sf.EvalSize(13), 16); - UNIT_ASSERT_EQUAL(sf.EvalSize(25), 32); - for (size_t i = 1; i < 100; ++i) { - UNIT_ASSERT_EQUAL(sf.EvalSize(i), FastClp2(i)); - } - } - - Y_UNIT_TEST(EvalIndexTest) { - TAndSizeFitter sf; - for (size_t j = 1; j < 10; ++j) { - sf.Update(1 << j); - for (size_t i = 0; i < 100; ++i) { - UNIT_ASSERT_EQUAL(sf.EvalIndex(i, 1 << j), i & ((1 << j) - 1)); - } - } - } -} - -Y_UNIT_TEST_SUITE(TModSizeFitterTest) { - Y_UNIT_TEST(EvalSizeTest) { - TModSizeFitter sf; - UNIT_ASSERT_EQUAL(sf.EvalSize(5), 5); - UNIT_ASSERT_EQUAL(sf.EvalSize(8), 8); - UNIT_ASSERT_EQUAL(sf.EvalSize(13), 13); - UNIT_ASSERT_EQUAL(sf.EvalSize(25), 25); - for (size_t i = 1; i < 100; ++i) { - UNIT_ASSERT_EQUAL(sf.EvalSize(i), i); - } - } - - Y_UNIT_TEST(EvalIndexTest) { - TModSizeFitter sf; - for (size_t j = 1; j < 10; ++j) { - sf.Update(1 << j); // just for integrity - for (size_t i = 0; i < 100; ++i) { - UNIT_ASSERT_EQUAL(sf.EvalIndex(i, 1 << j), i % (1 << j)); - } - } - } -} + +using namespace NFlatHash; + +Y_UNIT_TEST_SUITE(TAndSizeFitterTest) { + Y_UNIT_TEST(EvalSizeTest) { + TAndSizeFitter sf; + UNIT_ASSERT_EQUAL(sf.EvalSize(5), 8); + UNIT_ASSERT_EQUAL(sf.EvalSize(8), 8); + UNIT_ASSERT_EQUAL(sf.EvalSize(13), 16); + UNIT_ASSERT_EQUAL(sf.EvalSize(25), 32); + for (size_t i = 1; i < 100; ++i) { + UNIT_ASSERT_EQUAL(sf.EvalSize(i), FastClp2(i)); + } + } + + Y_UNIT_TEST(EvalIndexTest) { + TAndSizeFitter sf; + for (size_t j = 1; j < 10; ++j) { + sf.Update(1 << j); + for (size_t i = 0; i < 100; ++i) { + UNIT_ASSERT_EQUAL(sf.EvalIndex(i, 1 << j), i & ((1 << j) - 1)); + } + } + } +} + +Y_UNIT_TEST_SUITE(TModSizeFitterTest) { + Y_UNIT_TEST(EvalSizeTest) { + TModSizeFitter sf; + UNIT_ASSERT_EQUAL(sf.EvalSize(5), 5); + UNIT_ASSERT_EQUAL(sf.EvalSize(8), 8); + UNIT_ASSERT_EQUAL(sf.EvalSize(13), 13); + UNIT_ASSERT_EQUAL(sf.EvalSize(25), 25); + for (size_t i = 1; i < 100; ++i) { + UNIT_ASSERT_EQUAL(sf.EvalSize(i), i); + } + } + + Y_UNIT_TEST(EvalIndexTest) { + TModSizeFitter sf; + for (size_t j = 1; j < 10; ++j) { + sf.Update(1 << j); // just for integrity + for (size_t i = 0; i < 100; ++i) { + UNIT_ASSERT_EQUAL(sf.EvalIndex(i, 1 << j), i % (1 << j)); + } + } + } +} diff --git a/library/cpp/containers/flat_hash/lib/ut/table_ut.cpp b/library/cpp/containers/flat_hash/lib/ut/table_ut.cpp index dda4ba3fd0..ea511e2c6a 100644 --- a/library/cpp/containers/flat_hash/lib/ut/table_ut.cpp +++ b/library/cpp/containers/flat_hash/lib/ut/table_ut.cpp @@ -3,409 +3,409 @@ #include <library/cpp/containers/flat_hash/lib/probings.h> #include <library/cpp/containers/flat_hash/lib/size_fitters.h> #include <library/cpp/containers/flat_hash/lib/table.h> - + #include <library/cpp/testing/unittest/registar.h> - -#include <util/generic/algorithm.h> -#include <util/random/random.h> -#include <util/random/shuffle.h> - -using namespace NFlatHash; - -namespace { - template <class T> - struct TJustType { - using type = T; - }; - - template <class... Ts> - struct TTypePack {}; - - template <class F, class... Ts> - constexpr void ForEachType(F&& f, TTypePack<Ts...>) { - ApplyToMany(std::forward<F>(f), TJustType<Ts>{}...); - } - -/* Usage example: - * - * TForEachType<int, float, TString>::Apply([](auto t) { - * using T = GET_TYPE(t); - * }); - * So T would be: - * int on #0 iteration - * float on #1 iteration - * TString on #2 iteration - */ -#define GET_TYPE(ti) typename decltype(ti)::type - - constexpr size_t INIT_SIZE = 32; - constexpr size_t BIG_INIT_SIZE = 128; - - template <class T> - struct TSimpleKeyGetter { - static constexpr T& Apply(T& t) { return t; } - static constexpr const T& Apply(const T& t) { return t; } - }; - - template <class T, - class KeyEqual = std::equal_to<T>, - class ValueEqual = std::equal_to<T>, - class KeyGetter = TSimpleKeyGetter<T>, - class F, - class... Containers> - void ForEachTable(F f, TTypePack<Containers...> cs) { - ForEachType([&](auto p) { - using TProbing = GET_TYPE(p); - - ForEachType([&](auto sf) { - using TSizeFitter = GET_TYPE(sf); - - ForEachType([&](auto t) { - using TContainer = GET_TYPE(t); - static_assert(std::is_same_v<typename TContainer::value_type, T>); - - using TTable = TTable<THash<T>, - KeyEqual, - TContainer, - KeyGetter, - TProbing, - TSizeFitter, - TSimpleExpander>; - - f(TJustType<TTable>{}); - }, cs); - }, TTypePack<TAndSizeFitter, TModSizeFitter>{}); - }, TTypePack<TLinearProbing, TQuadraticProbing, TDenseProbing>{}); - } - - using TAtomContainers = TTypePack<TFlatContainer<int>, - TDenseContainer<int, NSet::TStaticValueMarker<-1>>>; - using TContainers = TTypePack<TFlatContainer<int>, - TDenseContainer<int, NSet::TStaticValueMarker<-1>>>; - using TRemovalContainers = TTypePack<TFlatContainer<int>, - TRemovalDenseContainer<int, NSet::TStaticValueMarker<-2>, - NSet::TStaticValueMarker<-1>>>; -} - -Y_UNIT_TEST_SUITE(TCommonTableAtomsTest) { - Y_UNIT_TEST(InitTest) { - ForEachTable<int>([](auto t) { - GET_TYPE(t) table{ INIT_SIZE }; - - UNIT_ASSERT(table.empty()); - UNIT_ASSERT_EQUAL(table.size(), 0); - UNIT_ASSERT_EQUAL(table.bucket_count(), INIT_SIZE); - UNIT_ASSERT_EQUAL(table.bucket_size(RandomNumber<size_t>(INIT_SIZE)), 0); - }, TAtomContainers{}); - } - - Y_UNIT_TEST(IteratorTest) { - ForEachTable<int>([](auto t) { - GET_TYPE(t) table{ INIT_SIZE }; - - auto first = table.begin(); - auto last = table.end(); - UNIT_ASSERT_EQUAL(first, last); - UNIT_ASSERT_EQUAL(std::distance(first, last), 0); - - auto cFirst = table.cbegin(); - auto cLast = table.cend(); - UNIT_ASSERT_EQUAL(cFirst, cLast); - UNIT_ASSERT_EQUAL(std::distance(cFirst, cLast), 0); - }, TAtomContainers{}); - } - - Y_UNIT_TEST(ContainsAndCountTest) { - ForEachTable<int>([](auto t) { - GET_TYPE(t) table{ INIT_SIZE }; - - for (int i = 0; i < 100; ++i) { - UNIT_ASSERT_EQUAL(table.count(i), 0); - UNIT_ASSERT(!table.contains(i)); - } - }, TAtomContainers{}); - } - - Y_UNIT_TEST(FindTest) { - ForEachTable<int>([](auto t) { - GET_TYPE(t) table{ INIT_SIZE }; - - for (int i = 0; i < 100; ++i) { - auto it = table.find(i); - UNIT_ASSERT_EQUAL(it, table.end()); - } - }, TAtomContainers{}); - } -} - -Y_UNIT_TEST_SUITE(TCommonTableTest) { - Y_UNIT_TEST(InsertTest) { - ForEachTable<int>([](auto t) { - GET_TYPE(t) table{ INIT_SIZE }; - - UNIT_ASSERT(table.empty()); - UNIT_ASSERT_EQUAL(table.size(), 0); - - int toInsert = RandomNumber<size_t>(100); - UNIT_ASSERT_EQUAL(table.count(toInsert), 0); - UNIT_ASSERT(!table.contains(toInsert)); - - auto p = table.insert(toInsert); - UNIT_ASSERT_EQUAL(p.first, table.begin()); - UNIT_ASSERT(p.second); - - UNIT_ASSERT(!table.empty()); - UNIT_ASSERT_EQUAL(table.size(), 1); - UNIT_ASSERT_EQUAL(table.count(toInsert), 1); - UNIT_ASSERT(table.contains(toInsert)); - - auto it = table.find(toInsert); - UNIT_ASSERT_UNEQUAL(it, table.end()); - UNIT_ASSERT_EQUAL(it, table.begin()); - UNIT_ASSERT_EQUAL(*it, toInsert); - - auto p2 = table.insert(toInsert); - UNIT_ASSERT_EQUAL(p.first, p2.first); - UNIT_ASSERT(!p2.second); - - UNIT_ASSERT_EQUAL(table.size(), 1); - UNIT_ASSERT_EQUAL(table.count(toInsert), 1); - UNIT_ASSERT(table.contains(toInsert)); - }, TContainers{}); - } - - Y_UNIT_TEST(ClearTest) { - ForEachTable<int>([](auto t) { - GET_TYPE(t) table{ INIT_SIZE }; - - TVector<int> toInsert(INIT_SIZE); - Iota(toInsert.begin(), toInsert.end(), 0); - ShuffleRange(toInsert); - toInsert.resize(INIT_SIZE / 3); - - for (auto i : toInsert) { - auto p = table.insert(i); - UNIT_ASSERT_EQUAL(*p.first, i); - UNIT_ASSERT(p.second); - } - UNIT_ASSERT_EQUAL(table.size(), toInsert.size()); - UNIT_ASSERT_EQUAL((size_t)std::distance(table.begin(), table.end()), toInsert.size()); - - for (auto i : toInsert) { - UNIT_ASSERT(table.contains(i)); - UNIT_ASSERT_EQUAL(table.count(i), 1); - } - - auto bc = table.bucket_count(); - table.clear(); - UNIT_ASSERT(table.empty()); - UNIT_ASSERT_EQUAL(table.bucket_count(), bc); - - for (auto i : toInsert) { - UNIT_ASSERT(!table.contains(i)); - UNIT_ASSERT_EQUAL(table.count(i), 0); - } - - table.insert(toInsert.front()); - UNIT_ASSERT(!table.empty()); - }, TContainers{}); - } - - Y_UNIT_TEST(CopyMoveTest) { - ForEachTable<int>([](auto t) { - GET_TYPE(t) table{ INIT_SIZE }; - - TVector<int> toInsert(INIT_SIZE); - Iota(toInsert.begin(), toInsert.end(), 0); - ShuffleRange(toInsert); - toInsert.resize(INIT_SIZE / 3); - - for (auto i : toInsert) { - auto p = table.insert(i); - UNIT_ASSERT_EQUAL(*p.first, i); - UNIT_ASSERT(p.second); - } - UNIT_ASSERT_EQUAL(table.size(), toInsert.size()); - UNIT_ASSERT_EQUAL((size_t)std::distance(table.begin(), table.end()), toInsert.size()); - - for (auto i : toInsert) { - UNIT_ASSERT(table.contains(i)); - UNIT_ASSERT_EQUAL(table.count(i), 1); - } - - // Copy construction test - auto table2 = table; - UNIT_ASSERT_EQUAL(table2.size(), table.size()); - UNIT_ASSERT_EQUAL((size_t)std::distance(table2.begin(), table2.end()), table.size()); - for (auto i : table) { - UNIT_ASSERT(table2.contains(i)); - UNIT_ASSERT_EQUAL(table2.count(i), 1); - } - - table2.clear(); - UNIT_ASSERT(table2.empty()); - - // Copy assignment test - table2 = table; - UNIT_ASSERT_EQUAL(table2.size(), table.size()); - UNIT_ASSERT_EQUAL((size_t)std::distance(table2.begin(), table2.end()), table.size()); - for (auto i : table) { - UNIT_ASSERT(table2.contains(i)); - UNIT_ASSERT_EQUAL(table2.count(i), 1); - } - - // Move construction test - auto table3 = std::move(table2); - UNIT_ASSERT(table2.empty()); - UNIT_ASSERT(table2.bucket_count() > 0); - - UNIT_ASSERT_EQUAL(table3.size(), table.size()); - UNIT_ASSERT_EQUAL((size_t)std::distance(table3.begin(), table3.end()), table.size()); - for (auto i : table) { - UNIT_ASSERT(table3.contains(i)); - UNIT_ASSERT_EQUAL(table3.count(i), 1); - } - - table2.insert(toInsert.front()); - UNIT_ASSERT(!table2.empty()); - UNIT_ASSERT_EQUAL(table2.size(), 1); - UNIT_ASSERT_UNEQUAL(table2.bucket_count(), 0); - - // Move assignment test - table2 = std::move(table3); - UNIT_ASSERT(table3.empty()); - UNIT_ASSERT(table3.bucket_count() > 0); - - UNIT_ASSERT_EQUAL(table2.size(), table.size()); - UNIT_ASSERT_EQUAL((size_t)std::distance(table2.begin(), table2.end()), table.size()); - for (auto i : table) { - UNIT_ASSERT(table2.contains(i)); - UNIT_ASSERT_EQUAL(table2.count(i), 1); - } - - table3.insert(toInsert.front()); - UNIT_ASSERT(!table3.empty()); - UNIT_ASSERT_EQUAL(table3.size(), 1); - UNIT_ASSERT_UNEQUAL(table3.bucket_count(), 0); - }, TContainers{}); - } - - Y_UNIT_TEST(RehashTest) { - ForEachTable<int>([](auto t) { - GET_TYPE(t) table{ INIT_SIZE }; - - TVector<int> toInsert(INIT_SIZE); - Iota(toInsert.begin(), toInsert.end(), 0); - ShuffleRange(toInsert); - toInsert.resize(INIT_SIZE / 3); - - for (auto i : toInsert) { - table.insert(i); - } - - auto bc = table.bucket_count(); - table.rehash(bc * 2); - UNIT_ASSERT(bc * 2 <= table.bucket_count()); - - UNIT_ASSERT_EQUAL(table.size(), toInsert.size()); - UNIT_ASSERT_EQUAL((size_t)std::distance(table.begin(), table.end()), toInsert.size()); - for (auto i : toInsert) { - UNIT_ASSERT(table.contains(i)); - UNIT_ASSERT_EQUAL(table.count(i), 1); - } - - TVector<int> tmp(table.begin(), table.end()); - Sort(toInsert.begin(), toInsert.end()); - Sort(tmp.begin(), tmp.end()); - - UNIT_ASSERT_VALUES_EQUAL(tmp, toInsert); - - table.rehash(0); - UNIT_ASSERT_EQUAL(table.size(), toInsert.size()); - UNIT_ASSERT(table.bucket_count() > table.size()); - - table.clear(); - UNIT_ASSERT(table.empty()); - table.rehash(INIT_SIZE); - UNIT_ASSERT(table.bucket_count() >= INIT_SIZE); - - table.rehash(0); - UNIT_ASSERT(table.bucket_count() > 0); - }, TContainers{}); - } - - Y_UNIT_TEST(EraseTest) { - ForEachTable<int>([](auto t) { - GET_TYPE(t) table{ INIT_SIZE }; - - int value = RandomNumber<ui32>(); - table.insert(value); - UNIT_ASSERT_EQUAL(table.size(), 1); - UNIT_ASSERT_EQUAL(table.count(value), 1); - - auto it = table.find(value); - table.erase(it); - - UNIT_ASSERT_EQUAL(table.size(), 0); - UNIT_ASSERT_EQUAL(table.count(value), 0); - - table.insert(value); - UNIT_ASSERT_EQUAL(table.size(), 1); - UNIT_ASSERT_EQUAL(table.count(value), 1); - - table.erase(value); - - UNIT_ASSERT_EQUAL(table.size(), 0); - UNIT_ASSERT_EQUAL(table.count(value), 0); - - table.insert(value); - UNIT_ASSERT_EQUAL(table.size(), 1); - UNIT_ASSERT_EQUAL(table.count(value), 1); - - table.erase(table.find(value), table.end()); - - UNIT_ASSERT_EQUAL(table.size(), 0); - UNIT_ASSERT_EQUAL(table.count(value), 0); - - table.erase(value); - - UNIT_ASSERT_EQUAL(table.size(), 0); - UNIT_ASSERT_EQUAL(table.count(value), 0); - }, TRemovalContainers{}); - } - - Y_UNIT_TEST(EraseBigTest) { - ForEachTable<int>([](auto t) { - GET_TYPE(t) table{ BIG_INIT_SIZE }; - - for (int i = 0; i < 1000; ++i) { - for (int j = 0; j < static_cast<int>(BIG_INIT_SIZE); ++j) { - table.emplace(j); - } - for (int j = 0; j < static_cast<int>(BIG_INIT_SIZE); ++j) { - table.erase(j); - } - } - UNIT_ASSERT(table.bucket_count() <= BIG_INIT_SIZE * 8); - }, TRemovalContainers{}); - } - - Y_UNIT_TEST(ConstructWithSizeTest) { - ForEachTable<int>([](auto t) { - GET_TYPE(t) table{ 1000 }; - UNIT_ASSERT(table.bucket_count() >= 1000); - - int value = RandomNumber<ui32>(); - table.insert(value); - UNIT_ASSERT_EQUAL(table.size(), 1); - UNIT_ASSERT_EQUAL(table.count(value), 1); - UNIT_ASSERT(table.bucket_count() >= 1000); - - table.rehash(10); - UNIT_ASSERT_EQUAL(table.size(), 1); - UNIT_ASSERT_EQUAL(table.count(value), 1); - UNIT_ASSERT(table.bucket_count() < 1000); - UNIT_ASSERT(table.bucket_count() >= 10); - }, TContainers{}); - } -} + +#include <util/generic/algorithm.h> +#include <util/random/random.h> +#include <util/random/shuffle.h> + +using namespace NFlatHash; + +namespace { + template <class T> + struct TJustType { + using type = T; + }; + + template <class... Ts> + struct TTypePack {}; + + template <class F, class... Ts> + constexpr void ForEachType(F&& f, TTypePack<Ts...>) { + ApplyToMany(std::forward<F>(f), TJustType<Ts>{}...); + } + +/* Usage example: + * + * TForEachType<int, float, TString>::Apply([](auto t) { + * using T = GET_TYPE(t); + * }); + * So T would be: + * int on #0 iteration + * float on #1 iteration + * TString on #2 iteration + */ +#define GET_TYPE(ti) typename decltype(ti)::type + + constexpr size_t INIT_SIZE = 32; + constexpr size_t BIG_INIT_SIZE = 128; + + template <class T> + struct TSimpleKeyGetter { + static constexpr T& Apply(T& t) { return t; } + static constexpr const T& Apply(const T& t) { return t; } + }; + + template <class T, + class KeyEqual = std::equal_to<T>, + class ValueEqual = std::equal_to<T>, + class KeyGetter = TSimpleKeyGetter<T>, + class F, + class... Containers> + void ForEachTable(F f, TTypePack<Containers...> cs) { + ForEachType([&](auto p) { + using TProbing = GET_TYPE(p); + + ForEachType([&](auto sf) { + using TSizeFitter = GET_TYPE(sf); + + ForEachType([&](auto t) { + using TContainer = GET_TYPE(t); + static_assert(std::is_same_v<typename TContainer::value_type, T>); + + using TTable = TTable<THash<T>, + KeyEqual, + TContainer, + KeyGetter, + TProbing, + TSizeFitter, + TSimpleExpander>; + + f(TJustType<TTable>{}); + }, cs); + }, TTypePack<TAndSizeFitter, TModSizeFitter>{}); + }, TTypePack<TLinearProbing, TQuadraticProbing, TDenseProbing>{}); + } + + using TAtomContainers = TTypePack<TFlatContainer<int>, + TDenseContainer<int, NSet::TStaticValueMarker<-1>>>; + using TContainers = TTypePack<TFlatContainer<int>, + TDenseContainer<int, NSet::TStaticValueMarker<-1>>>; + using TRemovalContainers = TTypePack<TFlatContainer<int>, + TRemovalDenseContainer<int, NSet::TStaticValueMarker<-2>, + NSet::TStaticValueMarker<-1>>>; +} + +Y_UNIT_TEST_SUITE(TCommonTableAtomsTest) { + Y_UNIT_TEST(InitTest) { + ForEachTable<int>([](auto t) { + GET_TYPE(t) table{ INIT_SIZE }; + + UNIT_ASSERT(table.empty()); + UNIT_ASSERT_EQUAL(table.size(), 0); + UNIT_ASSERT_EQUAL(table.bucket_count(), INIT_SIZE); + UNIT_ASSERT_EQUAL(table.bucket_size(RandomNumber<size_t>(INIT_SIZE)), 0); + }, TAtomContainers{}); + } + + Y_UNIT_TEST(IteratorTest) { + ForEachTable<int>([](auto t) { + GET_TYPE(t) table{ INIT_SIZE }; + + auto first = table.begin(); + auto last = table.end(); + UNIT_ASSERT_EQUAL(first, last); + UNIT_ASSERT_EQUAL(std::distance(first, last), 0); + + auto cFirst = table.cbegin(); + auto cLast = table.cend(); + UNIT_ASSERT_EQUAL(cFirst, cLast); + UNIT_ASSERT_EQUAL(std::distance(cFirst, cLast), 0); + }, TAtomContainers{}); + } + + Y_UNIT_TEST(ContainsAndCountTest) { + ForEachTable<int>([](auto t) { + GET_TYPE(t) table{ INIT_SIZE }; + + for (int i = 0; i < 100; ++i) { + UNIT_ASSERT_EQUAL(table.count(i), 0); + UNIT_ASSERT(!table.contains(i)); + } + }, TAtomContainers{}); + } + + Y_UNIT_TEST(FindTest) { + ForEachTable<int>([](auto t) { + GET_TYPE(t) table{ INIT_SIZE }; + + for (int i = 0; i < 100; ++i) { + auto it = table.find(i); + UNIT_ASSERT_EQUAL(it, table.end()); + } + }, TAtomContainers{}); + } +} + +Y_UNIT_TEST_SUITE(TCommonTableTest) { + Y_UNIT_TEST(InsertTest) { + ForEachTable<int>([](auto t) { + GET_TYPE(t) table{ INIT_SIZE }; + + UNIT_ASSERT(table.empty()); + UNIT_ASSERT_EQUAL(table.size(), 0); + + int toInsert = RandomNumber<size_t>(100); + UNIT_ASSERT_EQUAL(table.count(toInsert), 0); + UNIT_ASSERT(!table.contains(toInsert)); + + auto p = table.insert(toInsert); + UNIT_ASSERT_EQUAL(p.first, table.begin()); + UNIT_ASSERT(p.second); + + UNIT_ASSERT(!table.empty()); + UNIT_ASSERT_EQUAL(table.size(), 1); + UNIT_ASSERT_EQUAL(table.count(toInsert), 1); + UNIT_ASSERT(table.contains(toInsert)); + + auto it = table.find(toInsert); + UNIT_ASSERT_UNEQUAL(it, table.end()); + UNIT_ASSERT_EQUAL(it, table.begin()); + UNIT_ASSERT_EQUAL(*it, toInsert); + + auto p2 = table.insert(toInsert); + UNIT_ASSERT_EQUAL(p.first, p2.first); + UNIT_ASSERT(!p2.second); + + UNIT_ASSERT_EQUAL(table.size(), 1); + UNIT_ASSERT_EQUAL(table.count(toInsert), 1); + UNIT_ASSERT(table.contains(toInsert)); + }, TContainers{}); + } + + Y_UNIT_TEST(ClearTest) { + ForEachTable<int>([](auto t) { + GET_TYPE(t) table{ INIT_SIZE }; + + TVector<int> toInsert(INIT_SIZE); + Iota(toInsert.begin(), toInsert.end(), 0); + ShuffleRange(toInsert); + toInsert.resize(INIT_SIZE / 3); + + for (auto i : toInsert) { + auto p = table.insert(i); + UNIT_ASSERT_EQUAL(*p.first, i); + UNIT_ASSERT(p.second); + } + UNIT_ASSERT_EQUAL(table.size(), toInsert.size()); + UNIT_ASSERT_EQUAL((size_t)std::distance(table.begin(), table.end()), toInsert.size()); + + for (auto i : toInsert) { + UNIT_ASSERT(table.contains(i)); + UNIT_ASSERT_EQUAL(table.count(i), 1); + } + + auto bc = table.bucket_count(); + table.clear(); + UNIT_ASSERT(table.empty()); + UNIT_ASSERT_EQUAL(table.bucket_count(), bc); + + for (auto i : toInsert) { + UNIT_ASSERT(!table.contains(i)); + UNIT_ASSERT_EQUAL(table.count(i), 0); + } + + table.insert(toInsert.front()); + UNIT_ASSERT(!table.empty()); + }, TContainers{}); + } + + Y_UNIT_TEST(CopyMoveTest) { + ForEachTable<int>([](auto t) { + GET_TYPE(t) table{ INIT_SIZE }; + + TVector<int> toInsert(INIT_SIZE); + Iota(toInsert.begin(), toInsert.end(), 0); + ShuffleRange(toInsert); + toInsert.resize(INIT_SIZE / 3); + + for (auto i : toInsert) { + auto p = table.insert(i); + UNIT_ASSERT_EQUAL(*p.first, i); + UNIT_ASSERT(p.second); + } + UNIT_ASSERT_EQUAL(table.size(), toInsert.size()); + UNIT_ASSERT_EQUAL((size_t)std::distance(table.begin(), table.end()), toInsert.size()); + + for (auto i : toInsert) { + UNIT_ASSERT(table.contains(i)); + UNIT_ASSERT_EQUAL(table.count(i), 1); + } + + // Copy construction test + auto table2 = table; + UNIT_ASSERT_EQUAL(table2.size(), table.size()); + UNIT_ASSERT_EQUAL((size_t)std::distance(table2.begin(), table2.end()), table.size()); + for (auto i : table) { + UNIT_ASSERT(table2.contains(i)); + UNIT_ASSERT_EQUAL(table2.count(i), 1); + } + + table2.clear(); + UNIT_ASSERT(table2.empty()); + + // Copy assignment test + table2 = table; + UNIT_ASSERT_EQUAL(table2.size(), table.size()); + UNIT_ASSERT_EQUAL((size_t)std::distance(table2.begin(), table2.end()), table.size()); + for (auto i : table) { + UNIT_ASSERT(table2.contains(i)); + UNIT_ASSERT_EQUAL(table2.count(i), 1); + } + + // Move construction test + auto table3 = std::move(table2); + UNIT_ASSERT(table2.empty()); + UNIT_ASSERT(table2.bucket_count() > 0); + + UNIT_ASSERT_EQUAL(table3.size(), table.size()); + UNIT_ASSERT_EQUAL((size_t)std::distance(table3.begin(), table3.end()), table.size()); + for (auto i : table) { + UNIT_ASSERT(table3.contains(i)); + UNIT_ASSERT_EQUAL(table3.count(i), 1); + } + + table2.insert(toInsert.front()); + UNIT_ASSERT(!table2.empty()); + UNIT_ASSERT_EQUAL(table2.size(), 1); + UNIT_ASSERT_UNEQUAL(table2.bucket_count(), 0); + + // Move assignment test + table2 = std::move(table3); + UNIT_ASSERT(table3.empty()); + UNIT_ASSERT(table3.bucket_count() > 0); + + UNIT_ASSERT_EQUAL(table2.size(), table.size()); + UNIT_ASSERT_EQUAL((size_t)std::distance(table2.begin(), table2.end()), table.size()); + for (auto i : table) { + UNIT_ASSERT(table2.contains(i)); + UNIT_ASSERT_EQUAL(table2.count(i), 1); + } + + table3.insert(toInsert.front()); + UNIT_ASSERT(!table3.empty()); + UNIT_ASSERT_EQUAL(table3.size(), 1); + UNIT_ASSERT_UNEQUAL(table3.bucket_count(), 0); + }, TContainers{}); + } + + Y_UNIT_TEST(RehashTest) { + ForEachTable<int>([](auto t) { + GET_TYPE(t) table{ INIT_SIZE }; + + TVector<int> toInsert(INIT_SIZE); + Iota(toInsert.begin(), toInsert.end(), 0); + ShuffleRange(toInsert); + toInsert.resize(INIT_SIZE / 3); + + for (auto i : toInsert) { + table.insert(i); + } + + auto bc = table.bucket_count(); + table.rehash(bc * 2); + UNIT_ASSERT(bc * 2 <= table.bucket_count()); + + UNIT_ASSERT_EQUAL(table.size(), toInsert.size()); + UNIT_ASSERT_EQUAL((size_t)std::distance(table.begin(), table.end()), toInsert.size()); + for (auto i : toInsert) { + UNIT_ASSERT(table.contains(i)); + UNIT_ASSERT_EQUAL(table.count(i), 1); + } + + TVector<int> tmp(table.begin(), table.end()); + Sort(toInsert.begin(), toInsert.end()); + Sort(tmp.begin(), tmp.end()); + + UNIT_ASSERT_VALUES_EQUAL(tmp, toInsert); + + table.rehash(0); + UNIT_ASSERT_EQUAL(table.size(), toInsert.size()); + UNIT_ASSERT(table.bucket_count() > table.size()); + + table.clear(); + UNIT_ASSERT(table.empty()); + table.rehash(INIT_SIZE); + UNIT_ASSERT(table.bucket_count() >= INIT_SIZE); + + table.rehash(0); + UNIT_ASSERT(table.bucket_count() > 0); + }, TContainers{}); + } + + Y_UNIT_TEST(EraseTest) { + ForEachTable<int>([](auto t) { + GET_TYPE(t) table{ INIT_SIZE }; + + int value = RandomNumber<ui32>(); + table.insert(value); + UNIT_ASSERT_EQUAL(table.size(), 1); + UNIT_ASSERT_EQUAL(table.count(value), 1); + + auto it = table.find(value); + table.erase(it); + + UNIT_ASSERT_EQUAL(table.size(), 0); + UNIT_ASSERT_EQUAL(table.count(value), 0); + + table.insert(value); + UNIT_ASSERT_EQUAL(table.size(), 1); + UNIT_ASSERT_EQUAL(table.count(value), 1); + + table.erase(value); + + UNIT_ASSERT_EQUAL(table.size(), 0); + UNIT_ASSERT_EQUAL(table.count(value), 0); + + table.insert(value); + UNIT_ASSERT_EQUAL(table.size(), 1); + UNIT_ASSERT_EQUAL(table.count(value), 1); + + table.erase(table.find(value), table.end()); + + UNIT_ASSERT_EQUAL(table.size(), 0); + UNIT_ASSERT_EQUAL(table.count(value), 0); + + table.erase(value); + + UNIT_ASSERT_EQUAL(table.size(), 0); + UNIT_ASSERT_EQUAL(table.count(value), 0); + }, TRemovalContainers{}); + } + + Y_UNIT_TEST(EraseBigTest) { + ForEachTable<int>([](auto t) { + GET_TYPE(t) table{ BIG_INIT_SIZE }; + + for (int i = 0; i < 1000; ++i) { + for (int j = 0; j < static_cast<int>(BIG_INIT_SIZE); ++j) { + table.emplace(j); + } + for (int j = 0; j < static_cast<int>(BIG_INIT_SIZE); ++j) { + table.erase(j); + } + } + UNIT_ASSERT(table.bucket_count() <= BIG_INIT_SIZE * 8); + }, TRemovalContainers{}); + } + + Y_UNIT_TEST(ConstructWithSizeTest) { + ForEachTable<int>([](auto t) { + GET_TYPE(t) table{ 1000 }; + UNIT_ASSERT(table.bucket_count() >= 1000); + + int value = RandomNumber<ui32>(); + table.insert(value); + UNIT_ASSERT_EQUAL(table.size(), 1); + UNIT_ASSERT_EQUAL(table.count(value), 1); + UNIT_ASSERT(table.bucket_count() >= 1000); + + table.rehash(10); + UNIT_ASSERT_EQUAL(table.size(), 1); + UNIT_ASSERT_EQUAL(table.count(value), 1); + UNIT_ASSERT(table.bucket_count() < 1000); + UNIT_ASSERT(table.bucket_count() >= 10); + }, TContainers{}); + } +} diff --git a/library/cpp/containers/flat_hash/lib/ut/ya.make b/library/cpp/containers/flat_hash/lib/ut/ya.make index 5ffbfb2dd8..04d65a8c6e 100644 --- a/library/cpp/containers/flat_hash/lib/ut/ya.make +++ b/library/cpp/containers/flat_hash/lib/ut/ya.make @@ -1,17 +1,17 @@ -UNITTEST() - -OWNER(tender-bum) - -SRCS( - size_fitters_ut.cpp - probings_ut.cpp - containers_ut.cpp - iterator_ut.cpp - table_ut.cpp -) - -PEERDIR( +UNITTEST() + +OWNER(tender-bum) + +SRCS( + size_fitters_ut.cpp + probings_ut.cpp + containers_ut.cpp + iterator_ut.cpp + table_ut.cpp +) + +PEERDIR( library/cpp/containers/flat_hash/lib -) - -END() +) + +END() diff --git a/library/cpp/containers/flat_hash/lib/value_markers.h b/library/cpp/containers/flat_hash/lib/value_markers.h index d8edb58c23..99351586b5 100644 --- a/library/cpp/containers/flat_hash/lib/value_markers.h +++ b/library/cpp/containers/flat_hash/lib/value_markers.h @@ -1,130 +1,130 @@ -#pragma once - -#include "concepts/value_marker.h" - -#include <type_traits> -#include <tuple> - -namespace NFlatHash { - -namespace NSet { - -template <auto Value> -struct TStaticValueMarker { - using value_type = decltype(Value); - - constexpr auto Create() const noexcept { - return Value; - } - - template <class U> - bool Equals(const U& rhs) const { - return Value == rhs; - } -}; - -static_assert(NConcepts::ValueMarkerV<TStaticValueMarker<5>>); - -template <class T> -class TEqValueMarker { -public: - using value_type = T; - - template <class V, class = std::enable_if_t<std::is_constructible_v<T, std::decay_t<V>>>> - TEqValueMarker(V&& v) : Value_(std::forward<V>(v)) {} - - TEqValueMarker(const TEqValueMarker&) = default; - TEqValueMarker(TEqValueMarker&&) = default; - - TEqValueMarker& operator=(const TEqValueMarker&) = default; - TEqValueMarker& operator=(TEqValueMarker&&) = default; - - const T& Create() const noexcept { - return Value_; - } - - template <class U> - bool Equals(const U& rhs) const { - return Value_ == rhs; - } - -private: - T Value_; -}; - -static_assert(NConcepts::ValueMarkerV<TEqValueMarker<int>>); - -} // namespace NSet - -namespace NMap { - -template <auto Key, class T> -class TStaticValueMarker { - static_assert(std::is_default_constructible_v<T>); - -public: - using value_type = std::pair<decltype(Key), T>; - - TStaticValueMarker() = default; - - TStaticValueMarker(const TStaticValueMarker&) {} - TStaticValueMarker(TStaticValueMarker&&) {} - - TStaticValueMarker& operator=(const TStaticValueMarker&) noexcept { return *this; } - TStaticValueMarker& operator=(TStaticValueMarker&&) noexcept { return *this; } - - std::pair<decltype(Key), const T&> Create() const noexcept { return { Key, Value_ }; } - - template <class U> - bool Equals(const U& rhs) const { - return Key == rhs.first; - } - -private: - T Value_; -}; - -static_assert(NConcepts::ValueMarkerV<TStaticValueMarker<5, int>>); - -template <class Key, class T> -class TEqValueMarker { - static_assert(std::is_default_constructible_v<T>); - -public: - using value_type = std::pair<Key, T>; - - template <class V, class = std::enable_if_t<std::is_constructible_v<Key, std::decay_t<V>>>> - TEqValueMarker(V&& v) : Key_(std::forward<V>(v)) {} - - TEqValueMarker(const TEqValueMarker& vm) - : Key_(vm.Key_) {} - TEqValueMarker(TEqValueMarker&& vm) noexcept(std::is_nothrow_move_constructible_v<Key> - && std::is_nothrow_constructible_v<T>) - : Key_(std::move(vm.Key_)) {} - - TEqValueMarker& operator=(const TEqValueMarker& vm) { - Key_ = vm.Key_; - return *this; - } - TEqValueMarker& operator=(TEqValueMarker&& vm) noexcept(std::is_nothrow_move_assignable_v<Key>) { - Key_ = std::move(vm.Key_); - return *this; - } - - auto Create() const noexcept { return std::tie(Key_, Value_); } - - template <class U> - bool Equals(const U& rhs) const { - return Key_ == rhs.first; - } - -private: - Key Key_; - T Value_; -}; - -static_assert(NConcepts::ValueMarkerV<TEqValueMarker<int, int>>); - -} // namespace NMap - -} // namespace NFlatHash +#pragma once + +#include "concepts/value_marker.h" + +#include <type_traits> +#include <tuple> + +namespace NFlatHash { + +namespace NSet { + +template <auto Value> +struct TStaticValueMarker { + using value_type = decltype(Value); + + constexpr auto Create() const noexcept { + return Value; + } + + template <class U> + bool Equals(const U& rhs) const { + return Value == rhs; + } +}; + +static_assert(NConcepts::ValueMarkerV<TStaticValueMarker<5>>); + +template <class T> +class TEqValueMarker { +public: + using value_type = T; + + template <class V, class = std::enable_if_t<std::is_constructible_v<T, std::decay_t<V>>>> + TEqValueMarker(V&& v) : Value_(std::forward<V>(v)) {} + + TEqValueMarker(const TEqValueMarker&) = default; + TEqValueMarker(TEqValueMarker&&) = default; + + TEqValueMarker& operator=(const TEqValueMarker&) = default; + TEqValueMarker& operator=(TEqValueMarker&&) = default; + + const T& Create() const noexcept { + return Value_; + } + + template <class U> + bool Equals(const U& rhs) const { + return Value_ == rhs; + } + +private: + T Value_; +}; + +static_assert(NConcepts::ValueMarkerV<TEqValueMarker<int>>); + +} // namespace NSet + +namespace NMap { + +template <auto Key, class T> +class TStaticValueMarker { + static_assert(std::is_default_constructible_v<T>); + +public: + using value_type = std::pair<decltype(Key), T>; + + TStaticValueMarker() = default; + + TStaticValueMarker(const TStaticValueMarker&) {} + TStaticValueMarker(TStaticValueMarker&&) {} + + TStaticValueMarker& operator=(const TStaticValueMarker&) noexcept { return *this; } + TStaticValueMarker& operator=(TStaticValueMarker&&) noexcept { return *this; } + + std::pair<decltype(Key), const T&> Create() const noexcept { return { Key, Value_ }; } + + template <class U> + bool Equals(const U& rhs) const { + return Key == rhs.first; + } + +private: + T Value_; +}; + +static_assert(NConcepts::ValueMarkerV<TStaticValueMarker<5, int>>); + +template <class Key, class T> +class TEqValueMarker { + static_assert(std::is_default_constructible_v<T>); + +public: + using value_type = std::pair<Key, T>; + + template <class V, class = std::enable_if_t<std::is_constructible_v<Key, std::decay_t<V>>>> + TEqValueMarker(V&& v) : Key_(std::forward<V>(v)) {} + + TEqValueMarker(const TEqValueMarker& vm) + : Key_(vm.Key_) {} + TEqValueMarker(TEqValueMarker&& vm) noexcept(std::is_nothrow_move_constructible_v<Key> + && std::is_nothrow_constructible_v<T>) + : Key_(std::move(vm.Key_)) {} + + TEqValueMarker& operator=(const TEqValueMarker& vm) { + Key_ = vm.Key_; + return *this; + } + TEqValueMarker& operator=(TEqValueMarker&& vm) noexcept(std::is_nothrow_move_assignable_v<Key>) { + Key_ = std::move(vm.Key_); + return *this; + } + + auto Create() const noexcept { return std::tie(Key_, Value_); } + + template <class U> + bool Equals(const U& rhs) const { + return Key_ == rhs.first; + } + +private: + Key Key_; + T Value_; +}; + +static_assert(NConcepts::ValueMarkerV<TEqValueMarker<int, int>>); + +} // namespace NMap + +} // namespace NFlatHash diff --git a/library/cpp/containers/flat_hash/lib/ya.make b/library/cpp/containers/flat_hash/lib/ya.make index c3fa4a364b..afaa69110b 100644 --- a/library/cpp/containers/flat_hash/lib/ya.make +++ b/library/cpp/containers/flat_hash/lib/ya.make @@ -1,17 +1,17 @@ -LIBRARY() - -OWNER(tender-bum) - -SRCS( - containers.cpp - expanders.cpp - iterator.cpp - map.cpp - probings.cpp - set.cpp - size_fitters.cpp - table.cpp - value_markers.cpp -) - -END() +LIBRARY() + +OWNER(tender-bum) + +SRCS( + containers.cpp + expanders.cpp + iterator.cpp + map.cpp + probings.cpp + set.cpp + size_fitters.cpp + table.cpp + value_markers.cpp +) + +END() diff --git a/library/cpp/containers/flat_hash/ut/flat_hash_ut.cpp b/library/cpp/containers/flat_hash/ut/flat_hash_ut.cpp index c368c63d33..2b9d6a1dc2 100644 --- a/library/cpp/containers/flat_hash/ut/flat_hash_ut.cpp +++ b/library/cpp/containers/flat_hash/ut/flat_hash_ut.cpp @@ -1,68 +1,68 @@ #include <library/cpp/containers/flat_hash/flat_hash.h> - + #include <library/cpp/testing/unittest/registar.h> - -using namespace NFH; - -namespace { - -constexpr size_t TEST_INIT_SIZE = 25; -constexpr std::initializer_list<int> SET_INPUT_SAMPLE{1, 2, 3, 4, 5}; -const std::initializer_list<std::pair<const int, TString>> MAP_INPUT_SAMPLE{ - {1, "a"}, - {2, "b"}, - {3, "c"}, - {4, "d"}, - {5, "e"} -}; - -} // namespace - -template <class Map> -class TMapTest : public TTestBase { + +using namespace NFH; + +namespace { + +constexpr size_t TEST_INIT_SIZE = 25; +constexpr std::initializer_list<int> SET_INPUT_SAMPLE{1, 2, 3, 4, 5}; +const std::initializer_list<std::pair<const int, TString>> MAP_INPUT_SAMPLE{ + {1, "a"}, + {2, "b"}, + {3, "c"}, + {4, "d"}, + {5, "e"} +}; + +} // namespace + +template <class Map> +class TMapTest : public TTestBase { void AllocatorTest(); - void SmokingTest() { - Map mp; - mp.emplace(5, "abc"); - - UNIT_ASSERT_EQUAL(mp.size(), 1); - UNIT_ASSERT(mp.contains(5)); - - auto it = mp.find(5); - UNIT_ASSERT_EQUAL(mp.begin(), it); - UNIT_ASSERT(!mp.empty()); - } - - void CopyConstructionTest() { - Map st(MAP_INPUT_SAMPLE); - auto st2 = st; - - UNIT_ASSERT(!st.empty()); - UNIT_ASSERT(!st2.empty()); - UNIT_ASSERT_EQUAL(st, st2); - } - - void MoveConstructionTest() { - Map st(MAP_INPUT_SAMPLE); - auto st2 = std::move(st); - - UNIT_ASSERT(st.empty()); - UNIT_ASSERT(!st2.empty()); - UNIT_ASSERT_UNEQUAL(st, st2); - } - - void CopyAssignmentTest() { - Map st(MAP_INPUT_SAMPLE); - Map st2; - UNIT_ASSERT_UNEQUAL(st, st2); - UNIT_ASSERT(st2.empty()); - - st2 = st; - UNIT_ASSERT_EQUAL(st, st2); - UNIT_ASSERT(!st2.empty()); - } - + void SmokingTest() { + Map mp; + mp.emplace(5, "abc"); + + UNIT_ASSERT_EQUAL(mp.size(), 1); + UNIT_ASSERT(mp.contains(5)); + + auto it = mp.find(5); + UNIT_ASSERT_EQUAL(mp.begin(), it); + UNIT_ASSERT(!mp.empty()); + } + + void CopyConstructionTest() { + Map st(MAP_INPUT_SAMPLE); + auto st2 = st; + + UNIT_ASSERT(!st.empty()); + UNIT_ASSERT(!st2.empty()); + UNIT_ASSERT_EQUAL(st, st2); + } + + void MoveConstructionTest() { + Map st(MAP_INPUT_SAMPLE); + auto st2 = std::move(st); + + UNIT_ASSERT(st.empty()); + UNIT_ASSERT(!st2.empty()); + UNIT_ASSERT_UNEQUAL(st, st2); + } + + void CopyAssignmentTest() { + Map st(MAP_INPUT_SAMPLE); + Map st2; + UNIT_ASSERT_UNEQUAL(st, st2); + UNIT_ASSERT(st2.empty()); + + st2 = st; + UNIT_ASSERT_EQUAL(st, st2); + UNIT_ASSERT(!st2.empty()); + } + void DoubleCopyAssignmentTest() { Map st(MAP_INPUT_SAMPLE); Map st2; @@ -78,63 +78,63 @@ class TMapTest : public TTestBase { UNIT_ASSERT(!st2.empty()); } - void MoveAssignmentTest() { - Map st(MAP_INPUT_SAMPLE); - Map st2; - UNIT_ASSERT_UNEQUAL(st, st2); - UNIT_ASSERT(st2.empty()); - - st2 = std::move(st); - UNIT_ASSERT_UNEQUAL(st, st2); - UNIT_ASSERT(!st2.empty()); - UNIT_ASSERT(st.empty()); - } - - void InsertOrAssignTest() { - Map mp; - - auto p = mp.insert_or_assign(5, "abc"); - UNIT_ASSERT_EQUAL(p.first, mp.begin()); - UNIT_ASSERT(p.second); - UNIT_ASSERT_EQUAL(p.first->first, 5); - UNIT_ASSERT_EQUAL(p.first->second, "abc"); - - auto p2 = mp.insert_or_assign(5, "def"); - UNIT_ASSERT_EQUAL(p.first, p2.first); - UNIT_ASSERT(!p2.second); - UNIT_ASSERT_EQUAL(p2.first->first, 5); - UNIT_ASSERT_EQUAL(p2.first->second, "def"); - } - - void TryEmplaceTest() { - Map mp; - - auto p = mp.try_emplace(5, "abc"); - UNIT_ASSERT_EQUAL(p.first, mp.begin()); - UNIT_ASSERT(p.second); - UNIT_ASSERT_EQUAL(p.first->first, 5); - UNIT_ASSERT_EQUAL(p.first->second, "abc"); - - auto p2 = mp.try_emplace(5, "def"); - UNIT_ASSERT_EQUAL(p.first, p2.first); - UNIT_ASSERT(!p2.second); - UNIT_ASSERT_EQUAL(p2.first->first, 5); - UNIT_ASSERT_EQUAL(p.first->second, "abc"); - } - - UNIT_TEST_SUITE_DEMANGLE(TMapTest); + void MoveAssignmentTest() { + Map st(MAP_INPUT_SAMPLE); + Map st2; + UNIT_ASSERT_UNEQUAL(st, st2); + UNIT_ASSERT(st2.empty()); + + st2 = std::move(st); + UNIT_ASSERT_UNEQUAL(st, st2); + UNIT_ASSERT(!st2.empty()); + UNIT_ASSERT(st.empty()); + } + + void InsertOrAssignTest() { + Map mp; + + auto p = mp.insert_or_assign(5, "abc"); + UNIT_ASSERT_EQUAL(p.first, mp.begin()); + UNIT_ASSERT(p.second); + UNIT_ASSERT_EQUAL(p.first->first, 5); + UNIT_ASSERT_EQUAL(p.first->second, "abc"); + + auto p2 = mp.insert_or_assign(5, "def"); + UNIT_ASSERT_EQUAL(p.first, p2.first); + UNIT_ASSERT(!p2.second); + UNIT_ASSERT_EQUAL(p2.first->first, 5); + UNIT_ASSERT_EQUAL(p2.first->second, "def"); + } + + void TryEmplaceTest() { + Map mp; + + auto p = mp.try_emplace(5, "abc"); + UNIT_ASSERT_EQUAL(p.first, mp.begin()); + UNIT_ASSERT(p.second); + UNIT_ASSERT_EQUAL(p.first->first, 5); + UNIT_ASSERT_EQUAL(p.first->second, "abc"); + + auto p2 = mp.try_emplace(5, "def"); + UNIT_ASSERT_EQUAL(p.first, p2.first); + UNIT_ASSERT(!p2.second); + UNIT_ASSERT_EQUAL(p2.first->first, 5); + UNIT_ASSERT_EQUAL(p.first->second, "abc"); + } + + UNIT_TEST_SUITE_DEMANGLE(TMapTest); UNIT_TEST(AllocatorTest); - UNIT_TEST(SmokingTest); - UNIT_TEST(CopyConstructionTest); - UNIT_TEST(MoveConstructionTest); - UNIT_TEST(CopyAssignmentTest); + UNIT_TEST(SmokingTest); + UNIT_TEST(CopyConstructionTest); + UNIT_TEST(MoveConstructionTest); + UNIT_TEST(CopyAssignmentTest); UNIT_TEST(DoubleCopyAssignmentTest); - UNIT_TEST(MoveAssignmentTest); - UNIT_TEST(InsertOrAssignTest); - UNIT_TEST(TryEmplaceTest); - UNIT_TEST_SUITE_END(); -}; - + UNIT_TEST(MoveAssignmentTest); + UNIT_TEST(InsertOrAssignTest); + UNIT_TEST(TryEmplaceTest); + UNIT_TEST_SUITE_END(); +}; + template <> void TMapTest<TFlatHashMap<int, TString>>::AllocatorTest() { using Map = TFlatHashMap<int, TString>; @@ -147,112 +147,112 @@ void TMapTest<TDenseHashMapStaticMarker<int, TString, -1>>::AllocatorTest() { Map mp(3, NFlatHash::NMap::TStaticValueMarker<-1, TString>(), typename Map::allocator_type()); } -using TFlatHashMapTest = TMapTest<TFlatHashMap<int, TString>>; -using TDenseHashMapTest = TMapTest<TDenseHashMapStaticMarker<int, TString, -1>>; - -UNIT_TEST_SUITE_REGISTRATION(TFlatHashMapTest); -UNIT_TEST_SUITE_REGISTRATION(TDenseHashMapTest); - - -template <class Set> -class TSetTest : public TTestBase { +using TFlatHashMapTest = TMapTest<TFlatHashMap<int, TString>>; +using TDenseHashMapTest = TMapTest<TDenseHashMapStaticMarker<int, TString, -1>>; + +UNIT_TEST_SUITE_REGISTRATION(TFlatHashMapTest); +UNIT_TEST_SUITE_REGISTRATION(TDenseHashMapTest); + + +template <class Set> +class TSetTest : public TTestBase { void AllocatorTest(); - void DefaultConstructTest() { - Set st; - - UNIT_ASSERT(st.empty()); - UNIT_ASSERT_EQUAL(st.size(), 0); - UNIT_ASSERT(st.bucket_count() > 0); - UNIT_ASSERT_EQUAL(st.begin(), st.end()); - UNIT_ASSERT(st.load_factor() < std::numeric_limits<float>::epsilon()); - } - - void InitCapacityConstructTest() { - Set st(TEST_INIT_SIZE); - - UNIT_ASSERT(st.empty()); - UNIT_ASSERT_EQUAL(st.size(), 0); - UNIT_ASSERT(st.bucket_count() >= TEST_INIT_SIZE); - UNIT_ASSERT_EQUAL(st.begin(), st.end()); - UNIT_ASSERT(st.load_factor() < std::numeric_limits<float>::epsilon()); - } - - void IteratorsConstructTest() { - Set st(SET_INPUT_SAMPLE.begin(), SET_INPUT_SAMPLE.end()); - - UNIT_ASSERT(!st.empty()); - UNIT_ASSERT_EQUAL(st.size(), SET_INPUT_SAMPLE.size()); - UNIT_ASSERT(st.bucket_count() >= st.size()); - UNIT_ASSERT_UNEQUAL(st.begin(), st.end()); - UNIT_ASSERT_EQUAL(static_cast<size_t>(std::distance(st.begin(), st.end())), st.size()); - UNIT_ASSERT(st.load_factor() > 0); - } - - void InitializerListConstructTest() { - Set st(SET_INPUT_SAMPLE); - - UNIT_ASSERT(!st.empty()); - UNIT_ASSERT(st.size() > 0); - UNIT_ASSERT(st.bucket_count() > 0); - UNIT_ASSERT_UNEQUAL(st.begin(), st.end()); - UNIT_ASSERT_EQUAL(static_cast<size_t>(std::distance(st.begin(), st.end())), st.size()); - UNIT_ASSERT(st.load_factor() > 0); - } - - void CopyConstructionTest() { - Set st(SET_INPUT_SAMPLE); - auto st2 = st; - - UNIT_ASSERT(!st.empty()); - UNIT_ASSERT(!st2.empty()); - UNIT_ASSERT_EQUAL(st, st2); - } - - void MoveConstructionTest() { - Set st(SET_INPUT_SAMPLE); - auto st2 = std::move(st); - - UNIT_ASSERT(st.empty()); - UNIT_ASSERT(!st2.empty()); - UNIT_ASSERT_UNEQUAL(st, st2); - } - - void CopyAssignmentTest() { - Set st(SET_INPUT_SAMPLE); - Set st2; - UNIT_ASSERT_UNEQUAL(st, st2); - UNIT_ASSERT(st2.empty()); - - st2 = st; - UNIT_ASSERT_EQUAL(st, st2); - UNIT_ASSERT(!st2.empty()); - } - - void MoveAssignmentTest() { - Set st(SET_INPUT_SAMPLE); - Set st2; - UNIT_ASSERT_UNEQUAL(st, st2); - UNIT_ASSERT(st2.empty()); - - st2 = std::move(st); - UNIT_ASSERT_UNEQUAL(st, st2); - UNIT_ASSERT(!st2.empty()); - UNIT_ASSERT(st.empty()); - } - - UNIT_TEST_SUITE_DEMANGLE(TSetTest); + void DefaultConstructTest() { + Set st; + + UNIT_ASSERT(st.empty()); + UNIT_ASSERT_EQUAL(st.size(), 0); + UNIT_ASSERT(st.bucket_count() > 0); + UNIT_ASSERT_EQUAL(st.begin(), st.end()); + UNIT_ASSERT(st.load_factor() < std::numeric_limits<float>::epsilon()); + } + + void InitCapacityConstructTest() { + Set st(TEST_INIT_SIZE); + + UNIT_ASSERT(st.empty()); + UNIT_ASSERT_EQUAL(st.size(), 0); + UNIT_ASSERT(st.bucket_count() >= TEST_INIT_SIZE); + UNIT_ASSERT_EQUAL(st.begin(), st.end()); + UNIT_ASSERT(st.load_factor() < std::numeric_limits<float>::epsilon()); + } + + void IteratorsConstructTest() { + Set st(SET_INPUT_SAMPLE.begin(), SET_INPUT_SAMPLE.end()); + + UNIT_ASSERT(!st.empty()); + UNIT_ASSERT_EQUAL(st.size(), SET_INPUT_SAMPLE.size()); + UNIT_ASSERT(st.bucket_count() >= st.size()); + UNIT_ASSERT_UNEQUAL(st.begin(), st.end()); + UNIT_ASSERT_EQUAL(static_cast<size_t>(std::distance(st.begin(), st.end())), st.size()); + UNIT_ASSERT(st.load_factor() > 0); + } + + void InitializerListConstructTest() { + Set st(SET_INPUT_SAMPLE); + + UNIT_ASSERT(!st.empty()); + UNIT_ASSERT(st.size() > 0); + UNIT_ASSERT(st.bucket_count() > 0); + UNIT_ASSERT_UNEQUAL(st.begin(), st.end()); + UNIT_ASSERT_EQUAL(static_cast<size_t>(std::distance(st.begin(), st.end())), st.size()); + UNIT_ASSERT(st.load_factor() > 0); + } + + void CopyConstructionTest() { + Set st(SET_INPUT_SAMPLE); + auto st2 = st; + + UNIT_ASSERT(!st.empty()); + UNIT_ASSERT(!st2.empty()); + UNIT_ASSERT_EQUAL(st, st2); + } + + void MoveConstructionTest() { + Set st(SET_INPUT_SAMPLE); + auto st2 = std::move(st); + + UNIT_ASSERT(st.empty()); + UNIT_ASSERT(!st2.empty()); + UNIT_ASSERT_UNEQUAL(st, st2); + } + + void CopyAssignmentTest() { + Set st(SET_INPUT_SAMPLE); + Set st2; + UNIT_ASSERT_UNEQUAL(st, st2); + UNIT_ASSERT(st2.empty()); + + st2 = st; + UNIT_ASSERT_EQUAL(st, st2); + UNIT_ASSERT(!st2.empty()); + } + + void MoveAssignmentTest() { + Set st(SET_INPUT_SAMPLE); + Set st2; + UNIT_ASSERT_UNEQUAL(st, st2); + UNIT_ASSERT(st2.empty()); + + st2 = std::move(st); + UNIT_ASSERT_UNEQUAL(st, st2); + UNIT_ASSERT(!st2.empty()); + UNIT_ASSERT(st.empty()); + } + + UNIT_TEST_SUITE_DEMANGLE(TSetTest); UNIT_TEST(AllocatorTest); - UNIT_TEST(DefaultConstructTest); - UNIT_TEST(InitCapacityConstructTest); - UNIT_TEST(IteratorsConstructTest); - UNIT_TEST(InitializerListConstructTest); - UNIT_TEST(CopyConstructionTest); - UNIT_TEST(MoveConstructionTest); - UNIT_TEST(CopyAssignmentTest); - UNIT_TEST(MoveAssignmentTest); - UNIT_TEST_SUITE_END(); -}; - + UNIT_TEST(DefaultConstructTest); + UNIT_TEST(InitCapacityConstructTest); + UNIT_TEST(IteratorsConstructTest); + UNIT_TEST(InitializerListConstructTest); + UNIT_TEST(CopyConstructionTest); + UNIT_TEST(MoveConstructionTest); + UNIT_TEST(CopyAssignmentTest); + UNIT_TEST(MoveAssignmentTest); + UNIT_TEST_SUITE_END(); +}; + template <> void TSetTest<TFlatHashSet<int>>::AllocatorTest() { using Map = TFlatHashSet<int>; @@ -266,7 +266,7 @@ void TSetTest<TDenseHashSetStaticMarker<int, -1>>::AllocatorTest() { } using TFlatHashSetTest = TSetTest<TFlatHashSet<int, THash<int>>>; -using TDenseHashSetTest = TSetTest<TDenseHashSetStaticMarker<int, -1>>; - -UNIT_TEST_SUITE_REGISTRATION(TFlatHashSetTest); -UNIT_TEST_SUITE_REGISTRATION(TDenseHashSetTest); +using TDenseHashSetTest = TSetTest<TDenseHashSetStaticMarker<int, -1>>; + +UNIT_TEST_SUITE_REGISTRATION(TFlatHashSetTest); +UNIT_TEST_SUITE_REGISTRATION(TDenseHashSetTest); diff --git a/library/cpp/containers/flat_hash/ut/ya.make b/library/cpp/containers/flat_hash/ut/ya.make index 08cfd4f593..1d33d36120 100644 --- a/library/cpp/containers/flat_hash/ut/ya.make +++ b/library/cpp/containers/flat_hash/ut/ya.make @@ -1,13 +1,13 @@ -UNITTEST() - -OWNER(tender-bum) - -SRCS( - flat_hash_ut.cpp -) - -PEERDIR( +UNITTEST() + +OWNER(tender-bum) + +SRCS( + flat_hash_ut.cpp +) + +PEERDIR( library/cpp/containers/flat_hash -) - -END() +) + +END() diff --git a/library/cpp/containers/flat_hash/ya.make b/library/cpp/containers/flat_hash/ya.make index 30717c9065..612e2c1cde 100644 --- a/library/cpp/containers/flat_hash/ya.make +++ b/library/cpp/containers/flat_hash/ya.make @@ -1,13 +1,13 @@ -LIBRARY() - -OWNER(tender-bum) - -PEERDIR( +LIBRARY() + +OWNER(tender-bum) + +PEERDIR( library/cpp/containers/flat_hash/lib -) - -SRCS( - flat_hash.cpp -) - -END() +) + +SRCS( + flat_hash.cpp +) + +END() diff --git a/library/cpp/containers/intrusive_avl_tree/avltree.h b/library/cpp/containers/intrusive_avl_tree/avltree.h index 124e606261..a58c63b07c 100644 --- a/library/cpp/containers/intrusive_avl_tree/avltree.h +++ b/library/cpp/containers/intrusive_avl_tree/avltree.h @@ -188,10 +188,10 @@ public: } inline ~TAvlTree() noexcept { - Clear(); - } - - inline void Clear() noexcept { + Clear(); + } + + inline void Clear() noexcept { for (iterator it = Begin(); it != End();) { (it++)->TTreeItem::Unlink(); } diff --git a/library/cpp/containers/sorted_vector/sorted_vector.h b/library/cpp/containers/sorted_vector/sorted_vector.h index 28beeb2b09..123539af9e 100644 --- a/library/cpp/containers/sorted_vector/sorted_vector.h +++ b/library/cpp/containers/sorted_vector/sorted_vector.h @@ -13,7 +13,7 @@ namespace NSorted { namespace NPrivate { template <class TPredicate> - struct TEqual { + struct TEqual { template<typename TValueType1, typename TValueType2> inline bool operator()(const TValueType1& l, const TValueType2& r) const { TPredicate comp; @@ -22,7 +22,7 @@ namespace NSorted { }; template <typename TValueType, class TPredicate, class TKeyExtractor> - struct TKeyCompare { + struct TKeyCompare { inline bool operator()(const TValueType& l, const TValueType& r) const { TKeyExtractor extractKey; return TPredicate()(extractKey(l), extractKey(r)); diff --git a/library/cpp/coroutine/listener/listen.cpp b/library/cpp/coroutine/listener/listen.cpp index 5f4b65f977..3d4e711d1d 100644 --- a/library/cpp/coroutine/listener/listen.cpp +++ b/library/cpp/coroutine/listener/listen.cpp @@ -57,7 +57,7 @@ private: : Parent_(parent) , C_(nullptr) , ListenSocket_(socket(addr->Addr()->sa_family, SOCK_STREAM, 0)) - , Addr_(std::move(addr)) + , Addr_(std::move(addr)) { if (ListenSocket_ == INVALID_SOCKET) { ythrow TSystemError() << "can not create socket"; diff --git a/library/cpp/deprecated/accessors/accessors_impl.h b/library/cpp/deprecated/accessors/accessors_impl.h index 6b62603487..6b2b987351 100644 --- a/library/cpp/deprecated/accessors/accessors_impl.h +++ b/library/cpp/deprecated/accessors/accessors_impl.h @@ -44,7 +44,7 @@ namespace NAccessors { } }; - using TGet = std::conditional_t<THasBegin<Tb>::value, TByBegin<Tb>, TBybegin<Tb>>; + using TGet = std::conditional_t<THasBegin<Tb>::value, TByBegin<Tb>, TBybegin<Tb>>; static const TElementType* Get(const Tb& b) { return TGet::Get(b); @@ -94,7 +94,7 @@ namespace NAccessors { } }; - using TGet = std::conditional_t<THasEnd<Tb>::value, TByEnd<Tb>, TByend<Tb>>; + using TGet = std::conditional_t<THasEnd<Tb>::value, TByEnd<Tb>, TByend<Tb>>; static const TElementType* Get(const Tb& b) { return TGet::Get(b); @@ -151,10 +151,10 @@ namespace NAccessors { }; using TDo = std::conditional_t< - THasClear<Tb>::value, + THasClear<Tb>::value, TByClear<Tb>, std::conditional_t< - THasclear<Tb>::value, + THasclear<Tb>::value, TByclear<Tb>, TByNone<Tb>>>; @@ -196,10 +196,10 @@ namespace NAccessors { }; using TDo = std::conditional_t< - THasReserve<Tb>::value, + THasReserve<Tb>::value, TByReserve<Tb>, std::conditional_t< - THasreserve<Tb>::value, + THasreserve<Tb>::value, TByreserve<Tb>, TByNone<Tb>>>; @@ -227,7 +227,7 @@ namespace NAccessors { } }; - using TDo = std::conditional_t<THasResize<Tb>::value, TByResize<Tb>, TByresize<Tb>>; + using TDo = std::conditional_t<THasResize<Tb>::value, TByResize<Tb>, TByresize<Tb>>; static void Do(Tb& b, size_t sz) { TDo::Do(b, sz); @@ -268,10 +268,10 @@ namespace NAccessors { }; using TDo = std::conditional_t< - THasAppend<Tb>::value, + THasAppend<Tb>::value, TByAppend<Tb>, std::conditional_t< - THasappend<Tb>::value, + THasappend<Tb>::value, TByappend<Tb>, TBypush_back<Tb>>>; @@ -326,13 +326,13 @@ namespace NAccessors { }; using TDo = std::conditional_t< - THasAppend<Tb>::value, + THasAppend<Tb>::value, TByAppend<Tb>, std::conditional_t< - THasappend<Tb>::value, + THasappend<Tb>::value, TByappend<Tb>, std::conditional_t< - THasinsert<Tb>::value, + THasinsert<Tb>::value, TByinsert<Tb>, TByNone<Tb>>>>; @@ -395,10 +395,10 @@ namespace NAccessors { }; using TDo = std::conditional_t< - THasAssign<Tb>::value, + THasAssign<Tb>::value, TByAssign<Tb>, std::conditional_t< - THasassign<Tb>::value, + THasassign<Tb>::value, TByassign<Tb>, std::conditional_t< TMemoryTraits<Tb>::OwnsMemory, diff --git a/library/cpp/linear_regression/linear_regression_ut.cpp b/library/cpp/linear_regression/linear_regression_ut.cpp index fc266e1616..e71a16b67a 100644 --- a/library/cpp/linear_regression/linear_regression_ut.cpp +++ b/library/cpp/linear_regression/linear_regression_ut.cpp @@ -31,7 +31,7 @@ Y_UNIT_TEST_SUITE(TLinearRegressionTest) { deviationCalculator.Add(arguments[i], weights[i]); } - double actualMean = InnerProduct(arguments, weights) / Accumulate(weights, 0.0); + double actualMean = InnerProduct(arguments, weights) / Accumulate(weights, 0.0); double actualDeviation = 0.; for (size_t i = 0; i < arguments.size(); ++i) { double deviation = arguments[i] - actualMean; @@ -47,7 +47,7 @@ Y_UNIT_TEST_SUITE(TLinearRegressionTest) { UNIT_ASSERT(IsValidFloat(meanCalculator.GetSumWeights())); UNIT_ASSERT(IsValidFloat(deviationCalculator.GetSumWeights())); UNIT_ASSERT_DOUBLES_EQUAL(meanCalculator.GetSumWeights(), deviationCalculator.GetSumWeights(), 0); - UNIT_ASSERT_DOUBLES_EQUAL(meanCalculator.GetSumWeights(), Accumulate(weights, 0.0), 0); + UNIT_ASSERT_DOUBLES_EQUAL(meanCalculator.GetSumWeights(), Accumulate(weights, 0.0), 0); ValueIsCorrect(deviationCalculator.GetDeviation(), actualDeviation, 1e-5); @@ -94,8 +94,8 @@ Y_UNIT_TEST_SUITE(TLinearRegressionTest) { covariationCalculator.Add(firstValues[i], secondValues[i], weights[i]); } - const double firstValuesMean = InnerProduct(firstValues, weights) / Accumulate(weights, 0.0); - const double secondValuesMean = InnerProduct(secondValues, weights) / Accumulate(weights, 0.0); + const double firstValuesMean = InnerProduct(firstValues, weights) / Accumulate(weights, 0.0); + const double secondValuesMean = InnerProduct(secondValues, weights) / Accumulate(weights, 0.0); double actualCovariation = 0.; for (size_t i = 0; i < argumentsCount; ++i) { @@ -110,7 +110,7 @@ Y_UNIT_TEST_SUITE(TLinearRegressionTest) { UNIT_ASSERT_DOUBLES_EQUAL(covariationCalculator.GetSecondValueMean(), secondValuesMean, 1e-10); UNIT_ASSERT(IsValidFloat(covariationCalculator.GetSumWeights())); - UNIT_ASSERT_DOUBLES_EQUAL(covariationCalculator.GetSumWeights(), Accumulate(weights, 0.0), 0); + UNIT_ASSERT_DOUBLES_EQUAL(covariationCalculator.GetSumWeights(), Accumulate(weights, 0.0), 0); ValueIsCorrect(covariationCalculator.GetCovariation(), actualCovariation, 1e-5); @@ -170,7 +170,7 @@ Y_UNIT_TEST_SUITE(TLinearRegressionTest) { } if (!regularizationThreshold) { - UNIT_ASSERT(predictedSumSquaredErrors < Accumulate(weights, 0.0) * randomError * randomError); + UNIT_ASSERT(predictedSumSquaredErrors < Accumulate(weights, 0.0) * randomError * randomError); } UNIT_ASSERT_DOUBLES_EQUAL(predictedSumSquaredErrors, sumSquaredErrors, 1e-8); } @@ -227,7 +227,7 @@ Y_UNIT_TEST_SUITE(TLinearRegressionTest) { } UNIT_ASSERT_DOUBLES_EQUAL(model.GetIntercept(), intercept, 1e-2); - const double expectedSumSquaredErrors = randomError * randomError * Accumulate(weights, 0.0); + const double expectedSumSquaredErrors = randomError * randomError * Accumulate(weights, 0.0); UNIT_ASSERT_DOUBLES_EQUAL(lrSolver.SumSquaredErrors(), expectedSumSquaredErrors, expectedSumSquaredErrors * 0.01); } diff --git a/library/cpp/pop_count/popcount.h b/library/cpp/pop_count/popcount.h index ad26fff2c5..3d67737ed2 100644 --- a/library/cpp/pop_count/popcount.h +++ b/library/cpp/pop_count/popcount.h @@ -1,6 +1,6 @@ #pragma once -#include <util/generic/typelist.h> +#include <util/generic/typelist.h> #include <util/system/cpu_id.h> #include <util/system/defaults.h> #include <util/system/hi_lo.h> diff --git a/library/cpp/threading/skip_list/compare.h b/library/cpp/threading/skip_list/compare.h index 91ecf1e895..ac98b3e1ce 100644 --- a/library/cpp/threading/skip_list/compare.h +++ b/library/cpp/threading/skip_list/compare.h @@ -39,7 +39,7 @@ namespace NThreading { struct TBigCompareSelector { template <typename T> static inline int Compare(const T& l, const T& r) { - return TSmallCompareSelector<THascompare<T>::value>::Compare(l, r); + return TSmallCompareSelector<THascompare<T>::value>::Compare(l, r); } }; @@ -52,7 +52,7 @@ namespace NThreading { }; template <typename T> - struct TCompareSelector: public TBigCompareSelector<THasCompare<T>::value> { + struct TCompareSelector: public TBigCompareSelector<THasCompare<T>::value> { }; } diff --git a/library/cpp/threading/skip_list/skiplist.h b/library/cpp/threading/skip_list/skiplist.h index c1e35951ca..914a7c6ee7 100644 --- a/library/cpp/threading/skip_list/skiplist.h +++ b/library/cpp/threading/skip_list/skiplist.h @@ -172,7 +172,7 @@ namespace NThreading { TNode* Prev[MaxHeight]; template <typename TValue> - using TComparerReturnType = std::invoke_result_t<TComparer, const T&, const TValue&>; + using TComparerReturnType = std::invoke_result_t<TComparer, const T&, const TValue&>; public: TSkipList(TAllocator& allocator, const TComparer& comparer = TComparer()) diff --git a/library/cpp/xml/document/xml-document-decl.h b/library/cpp/xml/document/xml-document-decl.h index 6fdf078e5c..bfda1fb7e6 100644 --- a/library/cpp/xml/document/xml-document-decl.h +++ b/library/cpp/xml/document/xml-document-decl.h @@ -99,8 +99,8 @@ namespace NXml { }; public: - TConstNodes(const TConstNodes& nodes); - TConstNodes& operator=(const TConstNodes& nodes); + TConstNodes(const TConstNodes& nodes); + TConstNodes& operator=(const TConstNodes& nodes); TConstNodes(TConstNodesRef ref); TConstNodes& operator=(TConstNodesRef ref); diff --git a/library/cpp/xml/document/xml-document.cpp b/library/cpp/xml/document/xml-document.cpp index bd27136bf5..18a554d732 100644 --- a/library/cpp/xml/document/xml-document.cpp +++ b/library/cpp/xml/document/xml-document.cpp @@ -331,14 +331,14 @@ namespace NXml { SaveInternal(stream, enc, options); } - TConstNodes::TConstNodes(const TConstNodes& nodes) + TConstNodes::TConstNodes(const TConstNodes& nodes) : SizeValue(nodes.Size()) , Doc(nodes.Doc) , Obj(nodes.Obj) { } - TConstNodes& TConstNodes::operator=(const TConstNodes& nodes) { + TConstNodes& TConstNodes::operator=(const TConstNodes& nodes) { if (this != &nodes) { SizeValue = nodes.Size(); Doc = nodes.Doc; diff --git a/util/digest/numeric.h b/util/digest/numeric.h index 6bbdd894cf..e20bd908e4 100644 --- a/util/digest/numeric.h +++ b/util/digest/numeric.h @@ -1,6 +1,6 @@ #pragma once -#include <util/generic/typelist.h> +#include <util/generic/typelist.h> #include <util/system/defaults.h> /* diff --git a/util/draft/holder_vector.h b/util/draft/holder_vector.h index 942f4b718b..1c62055bd9 100644 --- a/util/draft/holder_vector.h +++ b/util/draft/holder_vector.h @@ -41,15 +41,15 @@ public: } } - void PushBack(std::unique_ptr<T> t) { + void PushBack(std::unique_ptr<T> t) { PushBack(t.release()); } - void PushBack(THolder<T> t) { + void PushBack(THolder<T> t) { PushBack(t.Release()); } - void Reset(size_t i, THolder<T> t) { + void Reset(size_t i, THolder<T> t) { T* current = (*this)[i]; if (current) { Y_ASSERT(current != t.Get()); diff --git a/util/draft/holder_vector_ut.cpp b/util/draft/holder_vector_ut.cpp index 9f3b9a919c..f64393860a 100644 --- a/util/draft/holder_vector_ut.cpp +++ b/util/draft/holder_vector_ut.cpp @@ -45,7 +45,7 @@ Y_UNIT_TEST_SUITE(THolderVectorTest) { ints.Resize(2); THolder<int> holder(new int(1)); - ints.Reset(0, std::move(holder)); + ints.Reset(0, std::move(holder)); UNIT_ASSERT_VALUES_EQUAL(*ints[0], 1); UNIT_ASSERT(!holder); } diff --git a/util/generic/algorithm.h b/util/generic/algorithm.h index 221e4c6ad0..badfb88993 100644 --- a/util/generic/algorithm.h +++ b/util/generic/algorithm.h @@ -454,27 +454,27 @@ static inline void Rotate(T f, T m, T l) { } template <typename It, typename Val> -Val Accumulate(It begin, It end, Val val) { - // std::move since C++20 - return std::accumulate(begin, end, std::move(val)); +Val Accumulate(It begin, It end, Val val) { + // std::move since C++20 + return std::accumulate(begin, end, std::move(val)); } template <typename It, typename Val, typename BinOp> -Val Accumulate(It begin, It end, Val val, BinOp binOp) { - // std::move since C++20 - return std::accumulate(begin, end, std::move(val), binOp); +Val Accumulate(It begin, It end, Val val, BinOp binOp) { + // std::move since C++20 + return std::accumulate(begin, end, std::move(val), binOp); } -template <typename C, typename Val> -Val Accumulate(const C& c, Val val) { - // std::move since C++20 - return Accumulate(std::begin(c), std::end(c), std::move(val)); +template <typename C, typename Val> +Val Accumulate(const C& c, Val val) { + // std::move since C++20 + return Accumulate(std::begin(c), std::end(c), std::move(val)); } -template <typename C, typename Val, typename BinOp> -Val Accumulate(const C& c, Val val, BinOp binOp) { - // std::move since C++20 - return Accumulate(std::begin(c), std::end(c), std::move(val), binOp); +template <typename C, typename Val, typename BinOp> +Val Accumulate(const C& c, Val val, BinOp binOp) { + // std::move since C++20 + return Accumulate(std::begin(c), std::end(c), std::move(val), binOp); } template <typename It1, typename It2, typename Val> @@ -549,19 +549,19 @@ auto MinElementBy(const C& c, F&& func) { return MinElementBy(std::begin(c), std::end(c), std::forward<F>(func)); } -template <class TOp, class... TArgs> -void ApplyToMany(TOp op, TArgs&&... args) { +template <class TOp, class... TArgs> +void ApplyToMany(TOp op, TArgs&&... args) { int dummy[] = {((void)op(std::forward<TArgs>(args)), 0)...}; - Y_UNUSED(dummy); -} - + Y_UNUSED(dummy); +} + template <class TI, class TOp> -inline void ForEach(TI f, TI l, TOp op) { +inline void ForEach(TI f, TI l, TOp op) { std::for_each(f, l, op); } -namespace NPrivate { - template <class T, class TOp, size_t... Is> +namespace NPrivate { + template <class T, class TOp, size_t... Is> constexpr bool AllOfImpl(T&& t, TOp&& op, std::index_sequence<Is...>) { #if _LIBCPP_STD_VER >= 17 return (true && ... && op(std::get<Is>(std::forward<T>(t)))); @@ -592,13 +592,13 @@ namespace NPrivate { #if _LIBCPP_STD_VER >= 17 (..., op(std::get<Is>(std::forward<T>(t)))); #else - ::ApplyToMany(std::forward<TOp>(op), std::get<Is>(std::forward<T>(t))...); + ::ApplyToMany(std::forward<TOp>(op), std::get<Is>(std::forward<T>(t))...); #endif - } -} - + } +} + // check that TOp return true for all of element from tuple T -template <class T, class TOp> +template <class T, class TOp> constexpr ::TEnableIfTuple<T, bool> AllOf(T&& t, TOp&& op) { return ::NPrivate::AllOfImpl( std::forward<T>(t), @@ -617,12 +617,12 @@ constexpr ::TEnableIfTuple<T, bool> AnyOf(T&& t, TOp&& op) { template <class T, class TOp> constexpr ::TEnableIfTuple<T> ForEach(T&& t, TOp&& op) { - ::NPrivate::ForEachImpl( - std::forward<T>(t), - std::forward<TOp>(op), - std::make_index_sequence<std::tuple_size<std::decay_t<T>>::value>{}); -} - + ::NPrivate::ForEachImpl( + std::forward<T>(t), + std::forward<TOp>(op), + std::make_index_sequence<std::tuple_size<std::decay_t<T>>::value>{}); +} + template <class T1, class T2, class O> static inline void Transform(T1 b, T1 e, T2 o, O f) { std::transform(b, e, o, f); diff --git a/util/generic/algorithm_ut.cpp b/util/generic/algorithm_ut.cpp index 632677a3c4..8d732fcc0c 100644 --- a/util/generic/algorithm_ut.cpp +++ b/util/generic/algorithm_ut.cpp @@ -696,12 +696,12 @@ Y_UNIT_TEST_SUITE(TAlgorithm) { MinElementBy(empty, functor); } - Y_UNIT_TEST(TestApplyToMany) { - int res = 0; - ApplyToMany([&res](auto v) { res += v; }, 1, 2, 3, 4, 5); - UNIT_ASSERT_EQUAL(res, 15); - - struct TVisitor { + Y_UNIT_TEST(TestApplyToMany) { + int res = 0; + ApplyToMany([&res](auto v) { res += v; }, 1, 2, 3, 4, 5); + UNIT_ASSERT_EQUAL(res, 15); + + struct TVisitor { TVisitor(int& acc) : Acc(acc) { @@ -712,20 +712,20 @@ Y_UNIT_TEST_SUITE(TAlgorithm) { void operator()(int v) { Acc += v * 2; }; - int& Acc; - }; + int& Acc; + }; TString s{"8-800-555-35-35"}; ApplyToMany(TVisitor{res = 0}, 1, s, 5, s); - UNIT_ASSERT_EQUAL(res, 12 + 2 * static_cast<int>(s.size())); - } - - Y_UNIT_TEST(TestTupleForEach) { + UNIT_ASSERT_EQUAL(res, 12 + 2 * static_cast<int>(s.size())); + } + + Y_UNIT_TEST(TestTupleForEach) { ForEach(std::tuple<>{}, [&](auto) { UNIT_ASSERT(false); }); - auto t = std::make_tuple(5, 6, 2, 3, 6); - ForEach(t, [](auto& v) { v *= -1; }); - UNIT_ASSERT_EQUAL(t, std::make_tuple(-5, -6, -2, -3, -6)); - } - + auto t = std::make_tuple(5, 6, 2, 3, 6); + ForEach(t, [](auto& v) { v *= -1; }); + UNIT_ASSERT_EQUAL(t, std::make_tuple(-5, -6, -2, -3, -6)); + } + Y_UNIT_TEST(TestTupleAllOf) { UNIT_ASSERT(AllOf(std::tuple<>{}, [](auto) { return false; })); UNIT_ASSERT(!AllOf(std::make_tuple(1, 2, 0, 4, 5), [&](auto v) { UNIT_ASSERT_LT(v, 3); return 0 != v; })); diff --git a/util/generic/bitops.h b/util/generic/bitops.h index a1862b1d61..2db15fc59b 100644 --- a/util/generic/bitops.h +++ b/util/generic/bitops.h @@ -1,7 +1,7 @@ #pragma once #include "ylimits.h" -#include "typelist.h" +#include "typelist.h" #include <util/system/compiler.h> #include <util/system/yassert.h> @@ -208,7 +208,7 @@ namespace NBitOps { template <typename T> static inline T FastClp2(T t) noexcept { Y_ASSERT(t > 0); - using TCvt = typename ::TUnsignedInts::template TSelectBy<TSizeOfPredicate<sizeof(T)>::template TResult>::type; + using TCvt = typename ::TUnsignedInts::template TSelectBy<TSizeOfPredicate<sizeof(T)>::template TResult>::type; return 1 + ::NBitOps::NPrivate::TClp2Helper<sizeof(TCvt) * 4, T>::Calc(static_cast<TCvt>(t)); } @@ -226,7 +226,7 @@ Y_CONST_FUNCTION constexpr bool IsPowerOf2(T v) noexcept { template <typename T> static inline unsigned GetValueBitCount(T value) noexcept { Y_ASSERT(value > 0); - using TCvt = typename ::TUnsignedInts::template TSelectBy<TSizeOfPredicate<sizeof(T)>::template TResult>::type; + using TCvt = typename ::TUnsignedInts::template TSelectBy<TSizeOfPredicate<sizeof(T)>::template TResult>::type; return ::NBitOps::NPrivate::GetValueBitCountImpl(static_cast<TCvt>(value)); } @@ -236,7 +236,7 @@ static inline unsigned GetValueBitCount(T value) noexcept { template <typename T> static inline unsigned CountTrailingZeroBits(T value) noexcept { Y_ASSERT(value > 0); - using TCvt = typename ::TUnsignedInts::template TSelectBy<TSizeOfPredicate<sizeof(T)>::template TResult>::type; + using TCvt = typename ::TUnsignedInts::template TSelectBy<TSizeOfPredicate<sizeof(T)>::template TResult>::type; return ::NBitOps::NPrivate::CountTrailingZeroBitsImpl(static_cast<TCvt>(value)); } diff --git a/util/generic/hash.h b/util/generic/hash.h index c6478487d5..e46db21fa9 100644 --- a/util/generic/hash.h +++ b/util/generic/hash.h @@ -615,10 +615,10 @@ public: deinitialize_buckets(buckets); } - size_type size() const noexcept { + size_type size() const noexcept { return num_elements; } - size_type max_size() const noexcept { + size_type max_size() const noexcept { return size_type(-1); } @@ -1521,13 +1521,13 @@ public: // See hash_ut.cpp public: - size_type size() const noexcept { + size_type size() const noexcept { return rep.size(); } - yssize_t ysize() const noexcept { + yssize_t ysize() const noexcept { return (yssize_t)rep.size(); } - size_type max_size() const noexcept { + size_type max_size() const noexcept { return rep.max_size(); } diff --git a/util/generic/intrlist.h b/util/generic/intrlist.h index 26967cea57..b5d3f2051b 100644 --- a/util/generic/intrlist.h +++ b/util/generic/intrlist.h @@ -857,7 +857,7 @@ public: } template <class TFunctor> - inline void ForEach(TFunctor&& functor) const noexcept(noexcept(functor(std::declval<TListItem>().Node()))) { + inline void ForEach(TFunctor&& functor) const noexcept(noexcept(functor(std::declval<TListItem>().Node()))) { TListItem* i = Begin_; while (i) { diff --git a/util/generic/is_in.h b/util/generic/is_in.h index 59d687dc7a..4f175ea5eb 100644 --- a/util/generic/is_in.h +++ b/util/generic/is_in.h @@ -17,7 +17,7 @@ namespace NIsInHelper { Y_HAS_SUBTYPE(key_type, KeyType); template <class T> - using TIsAssocCont = TConjunction<THasFindMethod<T>, THasConstIterator<T>, THasKeyType<T>>; + using TIsAssocCont = TConjunction<THasFindMethod<T>, THasConstIterator<T>, THasKeyType<T>>; template <class C, class T, bool isAssoc> struct TIsInTraits { diff --git a/util/generic/maybe.h b/util/generic/maybe.h index b47d6f4cab..34d21aebcd 100644 --- a/util/generic/maybe.h +++ b/util/generic/maybe.h @@ -1,8 +1,8 @@ #pragma once #include <utility> - -#include "maybe_traits.h" + +#include "maybe_traits.h" #include "yexception.h" #include <util/system/align.h> @@ -37,17 +37,17 @@ constexpr bool operator==(TNothing, TNothing) noexcept { template <class T, class Policy /*= ::NMaybe::TPolicyUndefinedExcept*/> class TMaybe: private TMaybeBase<T> { public: - using TInPlace = NMaybe::TInPlace; - -private: - static_assert(!std::is_same<std::remove_cv_t<T>, TNothing>::value, - "Instantiation of TMaybe with a TNothing type is ill-formed"); - static_assert(!std::is_same<std::remove_cv_t<T>, TInPlace>::value, - "Instantiation of TMaybe with a TInPlace type is ill-formed"); - static_assert(!std::is_reference<T>::value, - "Instantiation of TMaybe with reference type is ill-formed"); - static_assert(std::is_destructible<T>::value, - "Instantiation of TMaybe with non-destructible type is ill-formed"); + using TInPlace = NMaybe::TInPlace; + +private: + static_assert(!std::is_same<std::remove_cv_t<T>, TNothing>::value, + "Instantiation of TMaybe with a TNothing type is ill-formed"); + static_assert(!std::is_same<std::remove_cv_t<T>, TInPlace>::value, + "Instantiation of TMaybe with a TInPlace type is ill-formed"); + static_assert(!std::is_reference<T>::value, + "Instantiation of TMaybe with reference type is ill-formed"); + static_assert(std::is_destructible<T>::value, + "Instantiation of TMaybe with non-destructible type is ill-formed"); template <class U> struct TConstructibleFromMaybeSomehow { @@ -72,66 +72,66 @@ private: std::is_assignable<T&, const TMaybe<U, Policy>&&>::value; }; - template <class U> + template <class U> struct TImplicitCopyCtor { public: static constexpr bool value = std::is_constructible<T, const U&>::value && std::is_convertible<const U&, T>::value && !TConstructibleFromMaybeSomehow<U>::value; }; - - template <class U> + + template <class U> struct TExplicitCopyCtor { public: static constexpr bool value = std::is_constructible<T, const U&>::value && !std::is_convertible<const U&, T>::value && !TConstructibleFromMaybeSomehow<U>::value; }; - - template <class U> + + template <class U> struct TImplicitMoveCtor { public: static constexpr bool value = std::is_constructible<T, U&&>::value && std::is_convertible<U&&, T>::value && !TConstructibleFromMaybeSomehow<U>::value; }; - - template <class U> + + template <class U> struct TExplicitMoveCtor { public: static constexpr bool value = std::is_constructible<T, U&&>::value && !std::is_convertible<U&&, T>::value && !TConstructibleFromMaybeSomehow<U>::value; }; - - template <class U> + + template <class U> struct TCopyAssignable { public: static constexpr bool value = std::is_constructible<T, const U&>::value && std::is_assignable<T&, const U&>::value && !TAssignableFromMaybeSomehow<U>::value; }; - - template <class U> + + template <class U> struct TMoveAssignable { public: static constexpr bool value = std::is_constructible<T, U&&>::value && std::is_assignable<T&, U&&>::value && !TAssignableFromMaybeSomehow<U>::value; }; - + template <class U> struct TImplicitAnyCtor { public: using UDec = std::decay_t<U>; - + static constexpr bool value = std::is_constructible<T, U>::value && std::is_convertible<U, T>::value && !std::is_same<UDec, TInPlace>::value && !std::is_same<UDec, TMaybe>::value; }; - - template <class U> + + template <class U> struct TExplicitAnyCtor { public: using UDec = std::decay_t<U>; @@ -140,7 +140,7 @@ private: !std::is_same<UDec, TInPlace>::value && !std::is_same<UDec, TMaybe>::value; }; - + template <class U> struct TAssignableFromAny { public: @@ -151,23 +151,23 @@ private: (!std::is_scalar<T>::value || !std::is_same<UDec, T>::value); }; - using TBase = TMaybeBase<T>; + using TBase = TMaybeBase<T>; + +public: + using value_type = T; + using TValueType = value_type; -public: - using value_type = T; - using TValueType = value_type; + TMaybe() noexcept = default; - TMaybe() noexcept = default; + constexpr TMaybe(const TMaybe&) = default; + constexpr TMaybe(TMaybe&&) = default; - constexpr TMaybe(const TMaybe&) = default; - constexpr TMaybe(TMaybe&&) = default; - - template <class... Args> - constexpr explicit TMaybe(TInPlace, Args&&... args) + template <class... Args> + constexpr explicit TMaybe(TInPlace, Args&&... args) : TBase(TInPlace{}, std::forward<Args>(args)...) { } - + template <class U, class... TArgs> constexpr explicit TMaybe(TInPlace, std::initializer_list<U> il, TArgs&&... args) : TBase(TInPlace{}, il, std::forward<TArgs>(args)...) @@ -177,77 +177,77 @@ public: constexpr TMaybe(TNothing) noexcept { } - template <class U, class = std::enable_if_t<TImplicitCopyCtor<U>::value>> - TMaybe(const TMaybe<U, Policy>& right) { - if (right.Defined()) { + template <class U, class = std::enable_if_t<TImplicitCopyCtor<U>::value>> + TMaybe(const TMaybe<U, Policy>& right) { + if (right.Defined()) { new (Data()) T(right.GetRef()); - this->Defined_ = true; + this->Defined_ = true; } } - template <class U, std::enable_if_t<TExplicitCopyCtor<U>::value, bool> = false> - explicit TMaybe(const TMaybe<U, Policy>& right) { - if (right.Defined()) { + template <class U, std::enable_if_t<TExplicitCopyCtor<U>::value, bool> = false> + explicit TMaybe(const TMaybe<U, Policy>& right) { + if (right.Defined()) { new (Data()) T(right.GetRef()); - this->Defined_ = true; + this->Defined_ = true; } } - template <class U, class = std::enable_if_t<TImplicitMoveCtor<U>::value>> - TMaybe(TMaybe<U, Policy>&& right) noexcept(std::is_nothrow_constructible<T, U&&>::value) { - if (right.Defined()) { + template <class U, class = std::enable_if_t<TImplicitMoveCtor<U>::value>> + TMaybe(TMaybe<U, Policy>&& right) noexcept(std::is_nothrow_constructible<T, U&&>::value) { + if (right.Defined()) { new (Data()) T(std::move(right.GetRef())); - this->Defined_ = true; + this->Defined_ = true; } } - template <class U, std::enable_if_t<TExplicitMoveCtor<U>::value, bool> = false> - explicit TMaybe(TMaybe<U, Policy>&& right) noexcept(std::is_nothrow_constructible<T, U&&>::value) { - if (right.Defined()) { + template <class U, std::enable_if_t<TExplicitMoveCtor<U>::value, bool> = false> + explicit TMaybe(TMaybe<U, Policy>&& right) noexcept(std::is_nothrow_constructible<T, U&&>::value) { + if (right.Defined()) { new (Data()) T(std::move(right.GetRef())); - this->Defined_ = true; + this->Defined_ = true; } } - template <class U = T, class = std::enable_if_t<TImplicitAnyCtor<U>::value>> - constexpr TMaybe(U&& right) + template <class U = T, class = std::enable_if_t<TImplicitAnyCtor<U>::value>> + constexpr TMaybe(U&& right) : TBase(TInPlace{}, std::forward<U>(right)) { } - - template <class U = T, std::enable_if_t<TExplicitAnyCtor<U>::value, bool> = false> - constexpr explicit TMaybe(U&& right) + + template <class U = T, std::enable_if_t<TExplicitAnyCtor<U>::value, bool> = false> + constexpr explicit TMaybe(U&& right) : TBase(TInPlace{}, std::forward<U>(right)) { } - - ~TMaybe() = default; - constexpr TMaybe& operator=(const TMaybe&) = default; - constexpr TMaybe& operator=(TMaybe&&) = default; + ~TMaybe() = default; - TMaybe& operator=(TNothing) noexcept { + constexpr TMaybe& operator=(const TMaybe&) = default; + constexpr TMaybe& operator=(TMaybe&&) = default; + + TMaybe& operator=(TNothing) noexcept { Clear(); return *this; } - template <class U = T> - std::enable_if_t<TAssignableFromAny<U>::value, TMaybe&> operator=(U&& right) { + template <class U = T> + std::enable_if_t<TAssignableFromAny<U>::value, TMaybe&> operator=(U&& right) { if (Defined()) { - *Data() = std::forward<U>(right); + *Data() = std::forward<U>(right); } else { - Init(std::forward<U>(right)); + Init(std::forward<U>(right)); } return *this; } - template <class U> - std::enable_if_t<TCopyAssignable<U>::value, + template <class U> + std::enable_if_t<TCopyAssignable<U>::value, TMaybe&> operator=(const TMaybe<U, Policy>& right) { if (right.Defined()) { if (Defined()) { - *Data() = right.GetRef(); + *Data() = right.GetRef(); } else { Init(right.GetRef()); } @@ -258,15 +258,15 @@ public: return *this; } - template <class U> - std::enable_if_t<TMoveAssignable<U>::value, + template <class U> + std::enable_if_t<TMoveAssignable<U>::value, TMaybe&> operator=(TMaybe<U, Policy>&& right) noexcept( std::is_nothrow_assignable<T&, U&&>::value&& std::is_nothrow_constructible<T, U&&>::value) - { + { if (right.Defined()) { if (Defined()) { - *Data() = std::move(right.GetRef()); + *Data() = std::move(right.GetRef()); } else { Init(std::move(right.GetRef())); } @@ -277,39 +277,39 @@ public: return *this; } - template <typename... Args> - T& ConstructInPlace(Args&&... args) { - Clear(); - Init(std::forward<Args>(args)...); - return *Data(); - } - - void Clear() noexcept { + template <typename... Args> + T& ConstructInPlace(Args&&... args) { + Clear(); + Init(std::forward<Args>(args)...); + return *Data(); + } + + void Clear() noexcept { if (Defined()) { - this->Defined_ = false; + this->Defined_ = false; Data()->~T(); } } - constexpr bool Defined() const noexcept { - return this->Defined_; + constexpr bool Defined() const noexcept { + return this->Defined_; } Y_PURE_FUNCTION constexpr bool Empty() const noexcept { return !Defined(); } - void CheckDefined() const { + void CheckDefined() const { if (Y_UNLIKELY(!Defined())) { Policy::OnEmpty(typeid(TValueType)); } } - const T* Get() const noexcept { + const T* Get() const noexcept { return Defined() ? Data() : nullptr; } - T* Get() noexcept { + T* Get() noexcept { return Defined() ? Data() : nullptr; } @@ -353,27 +353,27 @@ public: return std::move(GetRef()); } - constexpr const T* operator->() const { + constexpr const T* operator->() const { return &GetRef(); } - constexpr T* operator->() { + constexpr T* operator->() { return &GetRef(); } - constexpr const T& GetOrElse(const T& elseValue) const { + constexpr const T& GetOrElse(const T& elseValue) const { return Defined() ? *Data() : elseValue; } - constexpr T& GetOrElse(T& elseValue) { + constexpr T& GetOrElse(T& elseValue) { return Defined() ? *Data() : elseValue; } - constexpr const TMaybe& OrElse(const TMaybe& elseValue) const noexcept { + constexpr const TMaybe& OrElse(const TMaybe& elseValue) const noexcept { return Defined() ? *this : elseValue; } - constexpr TMaybe& OrElse(TMaybe& elseValue) { + constexpr TMaybe& OrElse(TMaybe& elseValue) { return Defined() ? *this : elseValue; } @@ -383,7 +383,7 @@ public: } constexpr explicit operator bool() const noexcept { - return Defined(); + return Defined(); } void Save(IOutputStream* out) const { @@ -392,7 +392,7 @@ public: ::Save<bool>(out, defined); if (defined) { - ::Save(out, *Data()); + ::Save(out, *Data()); } } @@ -406,13 +406,13 @@ public: ConstructInPlace(); } - ::Load(in, *Data()); + ::Load(in, *Data()); } else { Clear(); } } - void Swap(TMaybe& other) { + void Swap(TMaybe& other) { if (this->Defined_ == other.Defined_) { if (this->Defined_) { ::DoSwap(this->Data_, other.Data_); @@ -428,23 +428,23 @@ public: } } - void swap(TMaybe& other) { + void swap(TMaybe& other) { Swap(other); } private: - constexpr const T* Data() const noexcept { - return std::addressof(this->Data_); + constexpr const T* Data() const noexcept { + return std::addressof(this->Data_); } - constexpr T* Data() noexcept { - return std::addressof(this->Data_); + constexpr T* Data() noexcept { + return std::addressof(this->Data_); } template <typename... Args> - void Init(Args&&... args) { + void Init(Args&&... args) { new (Data()) T(std::forward<Args>(args)...); - this->Defined_ = true; + this->Defined_ = true; } }; @@ -712,7 +712,7 @@ constexpr bool operator>=(const U& value, const TMaybe<T, TPolicy>& maybe) { class IOutputStream; template <class T, class TPolicy> -inline IOutputStream& operator<<(IOutputStream& out, const TMaybe<T, TPolicy>& maybe) { +inline IOutputStream& operator<<(IOutputStream& out, const TMaybe<T, TPolicy>& maybe) { if (maybe.Defined()) { out << *maybe; } else { diff --git a/util/generic/maybe_traits.h b/util/generic/maybe_traits.h index d507d8fa34..9e9f56955e 100644 --- a/util/generic/maybe_traits.h +++ b/util/generic/maybe_traits.h @@ -1,173 +1,173 @@ -#pragma once - +#pragma once + #include <memory> -#include <type_traits> -#include <initializer_list> - -namespace NMaybe { - struct TInPlace {}; - - template <class T, bool = std::is_trivially_destructible<T>::value> - struct TStorageBase { - constexpr TStorageBase() noexcept +#include <type_traits> +#include <initializer_list> + +namespace NMaybe { + struct TInPlace {}; + + template <class T, bool = std::is_trivially_destructible<T>::value> + struct TStorageBase { + constexpr TStorageBase() noexcept : NullState_('\0') { } - - template <class... Args> - constexpr TStorageBase(TInPlace, Args&&... args) - : Data_(std::forward<Args>(args)...) + + template <class... Args> + constexpr TStorageBase(TInPlace, Args&&... args) + : Data_(std::forward<Args>(args)...) , Defined_(true) { } - - ~TStorageBase() = default; - - union { - char NullState_; - T Data_; - }; - bool Defined_ = false; - }; - - template <class T> - struct TStorageBase<T, false> { - constexpr TStorageBase() noexcept + + ~TStorageBase() = default; + + union { + char NullState_; + T Data_; + }; + bool Defined_ = false; + }; + + template <class T> + struct TStorageBase<T, false> { + constexpr TStorageBase() noexcept : NullState_('\0') { } - - template <class... Args> - constexpr TStorageBase(TInPlace, Args&&... args) - : Data_(std::forward<Args>(args)...) + + template <class... Args> + constexpr TStorageBase(TInPlace, Args&&... args) + : Data_(std::forward<Args>(args)...) , Defined_(true) { } - - ~TStorageBase() { - if (this->Defined_) { - this->Data_.~T(); - } - } - - union { - char NullState_; - T Data_; - }; - bool Defined_ = false; - }; - - // -------------------- COPY CONSTRUCT -------------------- - - template <class T, bool = std::is_trivially_copy_constructible<T>::value> + + ~TStorageBase() { + if (this->Defined_) { + this->Data_.~T(); + } + } + + union { + char NullState_; + T Data_; + }; + bool Defined_ = false; + }; + + // -------------------- COPY CONSTRUCT -------------------- + + template <class T, bool = std::is_trivially_copy_constructible<T>::value> struct TCopyBase: TStorageBase<T> { - using TStorageBase<T>::TStorageBase; - }; - - template <class T> + using TStorageBase<T>::TStorageBase; + }; + + template <class T> struct TCopyBase<T, false>: TStorageBase<T> { - using TStorageBase<T>::TStorageBase; - - constexpr TCopyBase() = default; - constexpr TCopyBase(const TCopyBase& rhs) { - if (rhs.Defined_) { - new (std::addressof(this->Data_)) T(rhs.Data_); - this->Defined_ = true; - } - } - constexpr TCopyBase(TCopyBase&&) = default; - TCopyBase& operator=(const TCopyBase&) = default; - TCopyBase& operator=(TCopyBase&&) = default; - }; - - // -------------------- MOVE CONSTRUCT -------------------- - - template <class T, bool = std::is_trivially_move_constructible<T>::value> + using TStorageBase<T>::TStorageBase; + + constexpr TCopyBase() = default; + constexpr TCopyBase(const TCopyBase& rhs) { + if (rhs.Defined_) { + new (std::addressof(this->Data_)) T(rhs.Data_); + this->Defined_ = true; + } + } + constexpr TCopyBase(TCopyBase&&) = default; + TCopyBase& operator=(const TCopyBase&) = default; + TCopyBase& operator=(TCopyBase&&) = default; + }; + + // -------------------- MOVE CONSTRUCT -------------------- + + template <class T, bool = std::is_trivially_move_constructible<T>::value> struct TMoveBase: TCopyBase<T> { - using TCopyBase<T>::TCopyBase; - }; - - template <class T> + using TCopyBase<T>::TCopyBase; + }; + + template <class T> struct TMoveBase<T, false>: TCopyBase<T> { - using TCopyBase<T>::TCopyBase; - - constexpr TMoveBase() noexcept = default; - constexpr TMoveBase(const TMoveBase&) = default; - constexpr TMoveBase(TMoveBase&& rhs) noexcept(std::is_nothrow_move_constructible<T>::value) { - if (rhs.Defined_) { - new (std::addressof(this->Data_)) T(std::move(rhs.Data_)); - this->Defined_ = true; - } - } - TMoveBase& operator=(const TMoveBase&) = default; - TMoveBase& operator=(TMoveBase&&) = default; - }; - - // -------------------- COPY ASSIGN -------------------- - - template <class T, bool = std::is_trivially_copy_assignable<T>::value> + using TCopyBase<T>::TCopyBase; + + constexpr TMoveBase() noexcept = default; + constexpr TMoveBase(const TMoveBase&) = default; + constexpr TMoveBase(TMoveBase&& rhs) noexcept(std::is_nothrow_move_constructible<T>::value) { + if (rhs.Defined_) { + new (std::addressof(this->Data_)) T(std::move(rhs.Data_)); + this->Defined_ = true; + } + } + TMoveBase& operator=(const TMoveBase&) = default; + TMoveBase& operator=(TMoveBase&&) = default; + }; + + // -------------------- COPY ASSIGN -------------------- + + template <class T, bool = std::is_trivially_copy_assignable<T>::value> struct TCopyAssignBase: TMoveBase<T> { - using TMoveBase<T>::TMoveBase; - }; - - template <class T> + using TMoveBase<T>::TMoveBase; + }; + + template <class T> struct TCopyAssignBase<T, false>: TMoveBase<T> { - using TMoveBase<T>::TMoveBase; - - constexpr TCopyAssignBase() noexcept = default; - constexpr TCopyAssignBase(const TCopyAssignBase&) = default; - constexpr TCopyAssignBase(TCopyAssignBase&&) = default; - TCopyAssignBase& operator=(const TCopyAssignBase& rhs) { - if (this->Defined_) { - if (rhs.Defined_) { - this->Data_ = rhs.Data_; - } else { - this->Data_.~T(); - this->Defined_ = false; - } - } else if (rhs.Defined_) { - new (std::addressof(this->Data_)) T(rhs.Data_); - this->Defined_ = true; - } - return *this; - } - TCopyAssignBase& operator=(TCopyAssignBase&&) = default; - }; - - // -------------------- MOVE ASSIGN -------------------- - - template <class T, bool = std::is_trivially_copy_assignable<T>::value> + using TMoveBase<T>::TMoveBase; + + constexpr TCopyAssignBase() noexcept = default; + constexpr TCopyAssignBase(const TCopyAssignBase&) = default; + constexpr TCopyAssignBase(TCopyAssignBase&&) = default; + TCopyAssignBase& operator=(const TCopyAssignBase& rhs) { + if (this->Defined_) { + if (rhs.Defined_) { + this->Data_ = rhs.Data_; + } else { + this->Data_.~T(); + this->Defined_ = false; + } + } else if (rhs.Defined_) { + new (std::addressof(this->Data_)) T(rhs.Data_); + this->Defined_ = true; + } + return *this; + } + TCopyAssignBase& operator=(TCopyAssignBase&&) = default; + }; + + // -------------------- MOVE ASSIGN -------------------- + + template <class T, bool = std::is_trivially_copy_assignable<T>::value> struct TMoveAssignBase: TCopyAssignBase<T> { - using TCopyAssignBase<T>::TCopyAssignBase; - }; - - template <class T> + using TCopyAssignBase<T>::TCopyAssignBase; + }; + + template <class T> struct TMoveAssignBase<T, false>: TCopyAssignBase<T> { - using TCopyAssignBase<T>::TCopyAssignBase; - - constexpr TMoveAssignBase() noexcept = default; - constexpr TMoveAssignBase(const TMoveAssignBase&) = default; - constexpr TMoveAssignBase(TMoveAssignBase&&) = default; - TMoveAssignBase& operator=(const TMoveAssignBase&) = default; - TMoveAssignBase& operator=(TMoveAssignBase&& rhs) noexcept( + using TCopyAssignBase<T>::TCopyAssignBase; + + constexpr TMoveAssignBase() noexcept = default; + constexpr TMoveAssignBase(const TMoveAssignBase&) = default; + constexpr TMoveAssignBase(TMoveAssignBase&&) = default; + TMoveAssignBase& operator=(const TMoveAssignBase&) = default; + TMoveAssignBase& operator=(TMoveAssignBase&& rhs) noexcept( std::is_nothrow_move_assignable<T>::value&& std::is_nothrow_move_constructible<T>::value) - { - if (this->Defined_) { - if (rhs.Defined_) { - this->Data_ = std::move(rhs.Data_); - } else { - this->Data_.~T(); - this->Defined_ = false; - } - } else if (rhs.Defined_) { - new (std::addressof(this->Data_)) T(std::move(rhs.Data_)); - this->Defined_ = true; - } - return *this; - } - }; -} - -template <class T> -using TMaybeBase = NMaybe::TMoveAssignBase<T>; + { + if (this->Defined_) { + if (rhs.Defined_) { + this->Data_ = std::move(rhs.Data_); + } else { + this->Data_.~T(); + this->Defined_ = false; + } + } else if (rhs.Defined_) { + new (std::addressof(this->Data_)) T(std::move(rhs.Data_)); + this->Defined_ = true; + } + return *this; + } + }; +} + +template <class T> +using TMaybeBase = NMaybe::TMoveAssignBase<T>; diff --git a/util/generic/maybe_ut.cpp b/util/generic/maybe_ut.cpp index 8eb9de6426..2c1a425c5e 100644 --- a/util/generic/maybe_ut.cpp +++ b/util/generic/maybe_ut.cpp @@ -21,24 +21,24 @@ public: }; Y_UNIT_TEST_SUITE(TMaybeTest) { - Y_UNIT_TEST(TestStatic) { - using T1 = TMaybe<int>; - static_assert(std::is_trivially_copy_constructible<T1>::value, ""); - static_assert(std::is_trivially_destructible<T1>::value, ""); - - using T2 = TMaybe<TString*>; - static_assert(std::is_trivially_copy_constructible<T2>::value, ""); - static_assert(std::is_trivially_destructible<T2>::value, ""); - - using T3 = TMaybe<TMaybe<double>>; - static_assert(std::is_trivially_copy_constructible<T3>::value, ""); - static_assert(std::is_trivially_destructible<T3>::value, ""); - - using T4 = TMaybe<TString>; - static_assert(!std::is_trivially_copy_constructible<T4>::value, ""); - static_assert(!std::is_trivially_destructible<T4>::value, ""); - } - + Y_UNIT_TEST(TestStatic) { + using T1 = TMaybe<int>; + static_assert(std::is_trivially_copy_constructible<T1>::value, ""); + static_assert(std::is_trivially_destructible<T1>::value, ""); + + using T2 = TMaybe<TString*>; + static_assert(std::is_trivially_copy_constructible<T2>::value, ""); + static_assert(std::is_trivially_destructible<T2>::value, ""); + + using T3 = TMaybe<TMaybe<double>>; + static_assert(std::is_trivially_copy_constructible<T3>::value, ""); + static_assert(std::is_trivially_destructible<T3>::value, ""); + + using T4 = TMaybe<TString>; + static_assert(!std::is_trivially_copy_constructible<T4>::value, ""); + static_assert(!std::is_trivially_destructible<T4>::value, ""); + } + Y_UNIT_TEST(TestWarning) { TMaybe<size_t> x; TStringStream ss; @@ -136,9 +136,9 @@ Y_UNIT_TEST_SUITE(TMaybeTest) { UNIT_ASSERT(m5 == TMaybe<int>()); UNIT_ASSERT(m5 == Nothing()); UNIT_ASSERT(m5 != TMaybe<int>(5)); - - m5 = {}; - UNIT_ASSERT(m5.Empty()); + + m5 = {}; + UNIT_ASSERT(m5.Empty()); } Y_UNIT_TEST(TestInPlace) { @@ -964,40 +964,40 @@ Y_UNIT_TEST_SUITE(TMaybeTest) { UNIT_ASSERT_EQUAL(testStructMaybe.GetRef().From_, TestStruct::FromValue); UNIT_ASSERT_EQUAL(testStructMaybe.GetRef().Value_, 23); } - - Y_UNIT_TEST(TestMaybeConvertion) { - struct TSrc {}; - struct TDst { - bool FromMaybeConstructorApplied; - - explicit TDst(TSrc) + + Y_UNIT_TEST(TestMaybeConvertion) { + struct TSrc {}; + struct TDst { + bool FromMaybeConstructorApplied; + + explicit TDst(TSrc) : FromMaybeConstructorApplied(false) { } - - explicit TDst(TMaybe<TSrc>) + + explicit TDst(TMaybe<TSrc>) : FromMaybeConstructorApplied(true) { } - - TDst& operator=(TSrc) { - FromMaybeConstructorApplied = false; - return *this; - } - TDst& operator=(TMaybe<TSrc>) { - FromMaybeConstructorApplied = true; - return *this; - } - }; - - auto m = TMaybe<TDst>(TMaybe<TSrc>()); - UNIT_ASSERT(m.Defined()); - UNIT_ASSERT(m->FromMaybeConstructorApplied); - - m = TMaybe<TSrc>(); - UNIT_ASSERT(m.Defined()); - UNIT_ASSERT(m->FromMaybeConstructorApplied); - } + + TDst& operator=(TSrc) { + FromMaybeConstructorApplied = false; + return *this; + } + TDst& operator=(TMaybe<TSrc>) { + FromMaybeConstructorApplied = true; + return *this; + } + }; + + auto m = TMaybe<TDst>(TMaybe<TSrc>()); + UNIT_ASSERT(m.Defined()); + UNIT_ASSERT(m->FromMaybeConstructorApplied); + + m = TMaybe<TSrc>(); + UNIT_ASSERT(m.Defined()); + UNIT_ASSERT(m->FromMaybeConstructorApplied); + } Y_UNIT_TEST(TestOnEmptyException) { TMaybe<TStringBuf> v; diff --git a/util/generic/overloaded.cpp b/util/generic/overloaded.cpp index 7372126e41..fb6ff88d31 100644 --- a/util/generic/overloaded.cpp +++ b/util/generic/overloaded.cpp @@ -1 +1 @@ -#include "overloaded.h" +#include "overloaded.h" diff --git a/util/generic/overloaded.h b/util/generic/overloaded.h index 848d48c712..96a97e44bc 100644 --- a/util/generic/overloaded.h +++ b/util/generic/overloaded.h @@ -1,5 +1,5 @@ -#pragma once - +#pragma once + /** * Construct an ad-hoc object with an overloaded `operator()`. * @@ -47,10 +47,10 @@ * ``` */ -template <class... Fs> +template <class... Fs> struct TOverloaded: Fs... { - using Fs::operator()...; -}; - -template <class... Fs> -TOverloaded(Fs...) -> TOverloaded<Fs...>; + using Fs::operator()...; +}; + +template <class... Fs> +TOverloaded(Fs...) -> TOverloaded<Fs...>; diff --git a/util/generic/overloaded_ut.cpp b/util/generic/overloaded_ut.cpp index 43893808e5..f3d73895ad 100644 --- a/util/generic/overloaded_ut.cpp +++ b/util/generic/overloaded_ut.cpp @@ -1,55 +1,55 @@ #include <util/generic/overloaded.h> - + #include <library/cpp/testing/unittest/registar.h> - -#include <util/generic/variant.h> -#include <util/generic/algorithm.h> - -#include <tuple> - -namespace { - struct TType1 {}; - struct TType2 {}; - struct TType3 {}; -} - -Y_UNIT_TEST_SUITE(TOverloadedTest) { - Y_UNIT_TEST(StaticTest) { - auto f = TOverloaded{ - [](const TType1&) {}, - [](const TType2&) {}, + +#include <util/generic/variant.h> +#include <util/generic/algorithm.h> + +#include <tuple> + +namespace { + struct TType1 {}; + struct TType2 {}; + struct TType3 {}; +} + +Y_UNIT_TEST_SUITE(TOverloadedTest) { + Y_UNIT_TEST(StaticTest) { + auto f = TOverloaded{ + [](const TType1&) {}, + [](const TType2&) {}, [](const TType3&) {}}; - using F = decltype(f); - static_assert(std::is_invocable_v<F, TType1>); - static_assert(std::is_invocable_v<F, TType2>); - static_assert(std::is_invocable_v<F, TType3>); - static_assert(!std::is_invocable_v<F, int>); - static_assert(!std::is_invocable_v<F, double>); - } - - Y_UNIT_TEST(VariantTest) { + using F = decltype(f); + static_assert(std::is_invocable_v<F, TType1>); + static_assert(std::is_invocable_v<F, TType2>); + static_assert(std::is_invocable_v<F, TType3>); + static_assert(!std::is_invocable_v<F, int>); + static_assert(!std::is_invocable_v<F, double>); + } + + Y_UNIT_TEST(VariantTest) { std::variant<int, double, TType1> v = 5; - int res = 0; + int res = 0; std::visit(TOverloaded{ [&](int val) { res = val; }, [&](double) { res = -1; }, [&](TType1) { res = -1; }}, v); UNIT_ASSERT_VALUES_EQUAL(res, 5); - } - - Y_UNIT_TEST(TupleTest) { + } + + Y_UNIT_TEST(TupleTest) { std::tuple<int, double, bool, int> t{5, 3.14, true, 20}; - TString res; - - ForEach(t, TOverloaded{ + TString res; + + ForEach(t, TOverloaded{ [&](int val) { res += "(int) " + ToString(val) + ' '; }, [&](double val) { res += "(double) " + ToString(val) + ' '; }, [&](bool val) { res += "(bool) " + ToString(val) + ' '; }, }); - + UNIT_ASSERT_VALUES_EQUAL(res, "(int) 5 (double) 3.14 (bool) 1 (int) 20 "); - } + } Y_UNIT_TEST(ImplicitConversionsTest) { using TTestVariant = std::variant<int, double, char>; @@ -79,4 +79,4 @@ Y_UNIT_TEST_SUITE(TOverloadedTest) { UNIT_ASSERT_VALUES_EQUAL(matchAsDouble(TTestVariant{12345}), 12345.0); UNIT_ASSERT_VALUES_EQUAL(matchAsDouble(TTestVariant{'X'}), 88.0); } -} +} diff --git a/util/generic/ptr_ut.cpp b/util/generic/ptr_ut.cpp index 29bee493b5..c2dcff23f6 100644 --- a/util/generic/ptr_ut.cpp +++ b/util/generic/ptr_ut.cpp @@ -204,9 +204,9 @@ void TPointerTest::TestMakeHolder() { { struct TRec { int X, Y; - TRec(int x, int y) - : X(x) - , Y(y) + TRec(int x, int y) + : X(x) + , Y(y) { } }; diff --git a/util/generic/serialized_enum_ut.cpp b/util/generic/serialized_enum_ut.cpp index 6420f83c27..3a94e1d471 100644 --- a/util/generic/serialized_enum_ut.cpp +++ b/util/generic/serialized_enum_ut.cpp @@ -20,7 +20,7 @@ Y_UNIT_TEST_SUITE(TestSerializedEnum) { enum EEmpty { }; - UNIT_ASSERT_C((TTypeList<int, unsigned>::THave<typename TSelectEnumRepresentationType<EEmpty>::TType>::value), "empty enum using signed or unsigned integer underlying type"); + UNIT_ASSERT_C((TTypeList<int, unsigned>::THave<typename TSelectEnumRepresentationType<EEmpty>::TType>::value), "empty enum using signed or unsigned integer underlying type"); using TRepresentationTypeList = TTypeList<int, unsigned, long long, unsigned long long>; @@ -29,22 +29,22 @@ Y_UNIT_TEST_SUITE(TestSerializedEnum) { Two = 2, Five = 5, }; - UNIT_ASSERT(TRepresentationTypeList::THave<typename TSelectEnumRepresentationType<ERegular>::TType>::value); + UNIT_ASSERT(TRepresentationTypeList::THave<typename TSelectEnumRepresentationType<ERegular>::TType>::value); enum class ESmall: unsigned char { Six = 6, }; - UNIT_ASSERT(TRepresentationTypeList::THave<typename TSelectEnumRepresentationType<ESmall>::TType>::value); + UNIT_ASSERT(TRepresentationTypeList::THave<typename TSelectEnumRepresentationType<ESmall>::TType>::value); enum class EHugeUnsigned: ui64 { Value = 0, }; - UNIT_ASSERT(TRepresentationTypeList::THave<typename TSelectEnumRepresentationType<EHugeUnsigned>::TType>::value); + UNIT_ASSERT(TRepresentationTypeList::THave<typename TSelectEnumRepresentationType<EHugeUnsigned>::TType>::value); enum class EHugeSigned: i64 { Value = -2, }; - UNIT_ASSERT(TRepresentationTypeList::THave<typename TSelectEnumRepresentationType<EHugeSigned>::TType>::value); + UNIT_ASSERT(TRepresentationTypeList::THave<typename TSelectEnumRepresentationType<EHugeSigned>::TType>::value); } Y_UNIT_TEST(MappedArrayView) { diff --git a/util/generic/strbase.h b/util/generic/strbase.h index 56c974cca9..ab39fc7537 100644 --- a/util/generic/strbase.h +++ b/util/generic/strbase.h @@ -556,7 +556,7 @@ public: return CopyImpl(pc, n, pos); } - inline size_t copy(TCharType* pc, size_t n) const noexcept { + inline size_t copy(TCharType* pc, size_t n) const noexcept { return CopyImpl(pc, n, 0); } diff --git a/util/generic/typelist.h b/util/generic/typelist.h index 06eaded7ab..5ce26ab97c 100644 --- a/util/generic/typelist.h +++ b/util/generic/typelist.h @@ -2,8 +2,8 @@ #include <util/system/types.h> -#include <util/generic/typetraits.h> - +#include <util/generic/typetraits.h> + #include <type_traits> template <class... R> @@ -12,25 +12,25 @@ struct TTypeList; namespace NTL { template <unsigned N, typename TL> struct TGetImpl { - using type = typename TGetImpl<N - 1, typename TL::TTail>::type; + using type = typename TGetImpl<N - 1, typename TL::TTail>::type; }; template <typename TL> struct TGetImpl<0u, TL> { - using type = typename TL::THead; + using type = typename TL::THead; }; } template <> struct TTypeList<> { - static constexpr size_t Length = 0; + static constexpr size_t Length = 0; - template <class> - using THave = std::false_type; + template <class> + using THave = std::false_type; template <template <class> class P> struct TSelectBy { - using type = TTypeList<>; + using type = TTypeList<>; }; }; @@ -41,17 +41,17 @@ struct TTypeList<H, R...> { using THead = H; using TTail = TTypeList<R...>; - static constexpr size_t Length = 1 + sizeof...(R); + static constexpr size_t Length = 1 + sizeof...(R); template <class V> - using THave = TDisjunction<std::is_same<H, V>, typename TTail::template THave<V>>; + using THave = TDisjunction<std::is_same<H, V>, typename TTail::template THave<V>>; template <unsigned N> - using TGet = typename ::NTL::TGetImpl<N, TTypeList<H, R...>>::type; + using TGet = typename ::NTL::TGetImpl<N, TTypeList<H, R...>>::type; template <template <class> class P> struct TSelectBy { - using type = std::conditional_t<P<THead>::value, THead, typename TTail::template TSelectBy<P>::type>; + using type = std::conditional_t<P<THead>::value, THead, typename TTail::template TSelectBy<P>::type>; }; }; @@ -60,11 +60,11 @@ template <class T> struct TTypeList<T, TNone>: public TTypeList<T> { }; -using TCommonSignedInts = TTypeList<signed char, signed short, signed int, signed long, signed long long>; -using TCommonUnsignedInts = TTypeList<unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long, bool>; -using TFixedWidthSignedInts = TTypeList<i8, i16, i32, i64>; -using TFixedWidthUnsignedInts = TTypeList<ui8, ui16, ui32, ui64>; -using TFloats = TTypeList<float, double, long double>; +using TCommonSignedInts = TTypeList<signed char, signed short, signed int, signed long, signed long long>; +using TCommonUnsignedInts = TTypeList<unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long, bool>; +using TFixedWidthSignedInts = TTypeList<i8, i16, i32, i64>; +using TFixedWidthUnsignedInts = TTypeList<ui8, ui16, ui32, ui64>; +using TFloats = TTypeList<float, double, long double>; namespace NTL { template <class T1, class T2> @@ -72,19 +72,19 @@ namespace NTL { template <class... R1, class... R2> struct TConcat<TTypeList<R1...>, TTypeList<R2...>> { - using type = TTypeList<R1..., R2...>; + using type = TTypeList<R1..., R2...>; }; template <bool isSigned, class T, class TS, class TU> struct TTypeSelectorBase { - using TSignedInts = typename TConcat<TTypeList<T>, TS>::type; + using TSignedInts = typename TConcat<TTypeList<T>, TS>::type; using TUnsignedInts = TU; }; template <class T, class TS, class TU> struct TTypeSelectorBase<false, T, TS, TU> { using TSignedInts = TS; - using TUnsignedInts = typename TConcat<TTypeList<T>, TU>::type; + using TUnsignedInts = typename TConcat<TTypeList<T>, TU>::type; }; template <class T, class TS, class TU> @@ -101,14 +101,14 @@ using TUnsignedInts = NTL::T2::TUnsignedInts; template <unsigned sizeOf> struct TSizeOfPredicate { template <class T> - using TResult = TBoolConstant<sizeof(T) == sizeOf>; + using TResult = TBoolConstant<sizeof(T) == sizeOf>; }; - -template <typename T> -using TFixedWidthSignedInt = typename TFixedWidthSignedInts::template TSelectBy<TSizeOfPredicate<sizeof(T)>::template TResult>::type; - -template <typename T> -using TFixedWidthUnsignedInt = typename TFixedWidthUnsignedInts::template TSelectBy<TSizeOfPredicate<sizeof(T)>::template TResult>::type; + +template <typename T> +using TFixedWidthSignedInt = typename TFixedWidthSignedInts::template TSelectBy<TSizeOfPredicate<sizeof(T)>::template TResult>::type; + +template <typename T> +using TFixedWidthUnsignedInt = typename TFixedWidthUnsignedInts::template TSelectBy<TSizeOfPredicate<sizeof(T)>::template TResult>::type; template <typename T> using TFixedWidthFloat = typename TFloats::template TSelectBy<TSizeOfPredicate<sizeof(T)>::template TResult>::type; diff --git a/util/generic/typelist_ut.cpp b/util/generic/typelist_ut.cpp index 4c674bf0cb..eeabfa97b1 100644 --- a/util/generic/typelist_ut.cpp +++ b/util/generic/typelist_ut.cpp @@ -34,11 +34,11 @@ public: struct TC {}; void TestHave() { using TListType = TTypeList<TA, TB*, const TC&>; - UNIT_ASSERT(TListType::THave<TA>::value); - UNIT_ASSERT(TListType::THave<TB*>::value); - UNIT_ASSERT(!TListType::THave<TB>::value); - UNIT_ASSERT(TListType::THave<const TC&>::value); - UNIT_ASSERT(!TListType::THave<TC&>::value); + UNIT_ASSERT(TListType::THave<TA>::value); + UNIT_ASSERT(TListType::THave<TB*>::value); + UNIT_ASSERT(!TListType::THave<TB>::value); + UNIT_ASSERT(TListType::THave<const TC&>::value); + UNIT_ASSERT(!TListType::THave<TC&>::value); } template <class T> @@ -55,7 +55,7 @@ public: template <template <class...> class TT, class... R> struct TIsNArgTemplate<TT<R...>>: std::true_type {}; - + template <class> struct TAnyType: std::true_type {}; @@ -68,10 +68,10 @@ public: void TestSelectBy() { using TListType = TTypeList<TA, TB, TMyMap<TA*, TB>, TMyVector<TA>, TC>; - UNIT_ASSERT_TYPES_EQUAL(TListType::TSelectBy<TAnyType>::type, TA); - UNIT_ASSERT_TYPES_EQUAL(TListType::TSelectBy<TIs1ArgTemplate>::type, TMyVector<TA>); + UNIT_ASSERT_TYPES_EQUAL(TListType::TSelectBy<TAnyType>::type, TA); + UNIT_ASSERT_TYPES_EQUAL(TListType::TSelectBy<TIs1ArgTemplate>::type, TMyVector<TA>); using TMyMapPTATB = TMyMap<TA*, TB>; - UNIT_ASSERT_TYPES_EQUAL(TListType::TSelectBy<TIsNArgTemplate>::type, TMyMapPTATB); + UNIT_ASSERT_TYPES_EQUAL(TListType::TSelectBy<TIsNArgTemplate>::type, TMyMapPTATB); } void TestFloatList() { diff --git a/util/generic/typetraits.h b/util/generic/typetraits.h index a1c7fa35c2..d165bd1a06 100644 --- a/util/generic/typetraits.h +++ b/util/generic/typetraits.h @@ -9,74 +9,74 @@ #include <stlfwd> #if _LIBCPP_STD_VER >= 17 -template <bool B> +template <bool B> using TBoolConstant = std::bool_constant<B>; #else template <bool B> struct TBoolConstant: std::integral_constant<bool, B> {}; #endif - + #if _LIBCPP_STD_VER >= 17 -template <class B> +template <class B> using TNegation = std::negation<B>; #else template <class B> struct TNegation: ::TBoolConstant<!bool(B::value)> {}; #endif - -namespace NPrivate { - template <class... Bs> - constexpr bool ConjunctionImpl() { + +namespace NPrivate { + template <class... Bs> + constexpr bool ConjunctionImpl() { bool bs[] = {(bool)Bs::value...}; - for (auto b : bs) { - if (!b) { - return false; - } - } - return true; - } - - template <class... Bs> - constexpr bool DisjunctionImpl() { + for (auto b : bs) { + if (!b) { + return false; + } + } + return true; + } + + template <class... Bs> + constexpr bool DisjunctionImpl() { bool bs[] = {(bool)Bs::value...}; - for (auto b : bs) { - if (b) { - return true; - } - } - return false; - } -} - + for (auto b : bs) { + if (b) { + return true; + } + } + return false; + } +} + #if _LIBCPP_STD_VER >= 17 && !defined(_MSC_VER) // Disable std::conjunction for MSVC by analogy with std::disjunction. -template <class... Bs> +template <class... Bs> using TConjunction = std::conjunction<Bs...>; #else template <class... Bs> struct TConjunction: ::TBoolConstant<::NPrivate::ConjunctionImpl<Bs...>()> {}; #endif - + #if _LIBCPP_STD_VER >= 17 && !defined(_MSC_VER) // Disable std::disjunction for MSVC. // It reduces build time (500 -> 20 seconds) and memory consumption (20 GB -> less than 1 GB) // for some files (notably search/dssm_boosting/dssm_boosting_calcer.cpp). -template <class... Bs> +template <class... Bs> using TDisjunction = std::disjunction<Bs...>; #else template <class... Bs> struct TDisjunction: ::TBoolConstant<::NPrivate::DisjunctionImpl<Bs...>()> {}; #endif - + #if _LIBCPP_STD_VER >= 17 template <class... Bs> using TVoidT = std::void_t<Bs...>; #else -template <class...> -using TVoidT = void; +template <class...> +using TVoidT = void; #endif - -template <class T> + +template <class T> struct TPodTraits { enum { IsPod = false @@ -160,7 +160,7 @@ class TTypeTraits<void>: public TTypeTraitsBase<void> {}; : std::integral_constant<bool, TClassHas##name<T>::value> {}; \ template <class T> \ struct THas##name \ - : TBaseHas##name<T, std::is_class<T>::value || std::is_union<T>::value> {} + : TBaseHas##name<T, std::is_class<T>::value || std::is_union<T>::value> {} #define Y_HAS_MEMBER_IMPL_1(name) Y_HAS_MEMBER_IMPL_2(name, name) @@ -170,7 +170,7 @@ class TTypeTraits<void>: public TTypeTraitsBase<void> {}; * metaprogramming. * * Macro accept one or two parameters, when used with two parameters e.g. `Y_HAS_MEMBER(xyz, ABC)` - * will define class `THasABC` with static member `value` of type bool. Usage with one parameter + * will define class `THasABC` with static member `value` of type bool. Usage with one parameter * e.g. `Y_HAS_MEMBER(xyz)` will produce the same result as `Y_HAS_MEMBER(xyz, xyz)`. * * @code @@ -179,13 +179,13 @@ class TTypeTraits<void>: public TTypeTraitsBase<void> {}; * Y_HAS_MEMBER(push_front, PushFront); * * template <typename T, typename U> - * std::enable_if_t<THasPushFront<T>::value, void> + * std::enable_if_t<THasPushFront<T>::value, void> * PushFront(T& container, const U value) { * container.push_front(x); * } * * template <typename T, typename U> - * std::enable_if_t<!THasPushFront<T>::value, void> + * std::enable_if_t<!THasPushFront<T>::value, void> * PushFront(T& container, const U value) { * container.insert(container.begin(), x); * } @@ -207,7 +207,7 @@ class TTypeTraits<void>: public TTypeTraitsBase<void> {}; * metaprogramming. * * Macro accept one or two parameters, when used with two parameters e.g. `Y_HAS_SUBTYPE(xyz, ABC)` - * will define class `THasABC` with static member `value` of type bool. Usage with one parameter + * will define class `THasABC` with static member `value` of type bool. Usage with one parameter * e.g. `Y_HAS_SUBTYPE(xyz)` will produce the same result as `Y_HAS_SUBTYPE(xyz, xyz)`. * * @code @@ -217,7 +217,7 @@ class TTypeTraits<void>: public TTypeTraitsBase<void> {}; * * template <typename T> * using TIsAssocCont = std::conditional_t< - * THasFindMethod<T>::value && THasConstIterator<T>::value && THasKeyType<T>::value, + * THasFindMethod<T>::value && THasConstIterator<T>::value && THasKeyType<T>::value, * std::true_type, * std::false_type, * >; @@ -262,11 +262,11 @@ struct TIsPointerToConstMemberFunction<R (T::*)(Args..., ...) const&>: std::true template <class R, class T, class... Args> struct TIsPointerToConstMemberFunction<R (T::*)(Args..., ...) const&&>: std::true_type { }; - -template <template <class...> class T, class U> + +template <template <class...> class T, class U> struct TIsSpecializationOf: std::false_type {}; - -template <template <class...> class T, class... Ts> + +template <template <class...> class T, class... Ts> struct TIsSpecializationOf<T, T<Ts...>>: std::true_type {}; /* diff --git a/util/generic/typetraits_ut.cpp b/util/generic/typetraits_ut.cpp index 24b7febc6f..e7571c75ec 100644 --- a/util/generic/typetraits_ut.cpp +++ b/util/generic/typetraits_ut.cpp @@ -2,9 +2,9 @@ #include <library/cpp/testing/unittest/registar.h> -#include <vector> -#include <tuple> - +#include <vector> +#include <tuple> + namespace { enum ETestEnum { }; @@ -450,12 +450,12 @@ static_assert(std::is_same<i8, TFixedWidthSignedInt<ui8>>::value, ""); static_assert(std::is_same<i16, TFixedWidthSignedInt<ui16>>::value, ""); static_assert(std::is_same<i32, TFixedWidthSignedInt<ui32>>::value, ""); static_assert(std::is_same<i64, TFixedWidthSignedInt<ui64>>::value, ""); - -// test for TIsSpecializationOf -static_assert(TIsSpecializationOf<std::vector, std::vector<int>>::value, ""); -static_assert(TIsSpecializationOf<std::tuple, std::tuple<int, double, char>>::value, ""); -static_assert(!TIsSpecializationOf<std::vector, std::tuple<int, double, char>>::value, ""); -static_assert(!TIsSpecializationOf<std::pair, std::vector<int>>::value, ""); + +// test for TIsSpecializationOf +static_assert(TIsSpecializationOf<std::vector, std::vector<int>>::value, ""); +static_assert(TIsSpecializationOf<std::tuple, std::tuple<int, double, char>>::value, ""); +static_assert(!TIsSpecializationOf<std::vector, std::tuple<int, double, char>>::value, ""); +static_assert(!TIsSpecializationOf<std::pair, std::vector<int>>::value, ""); // test for TIsIterable static_assert(TIsIterable<std::vector<int>>::value, ""); diff --git a/util/generic/utility.h b/util/generic/utility.h index 75f63400d7..43b98eeafc 100644 --- a/util/generic/utility.h +++ b/util/generic/utility.h @@ -69,27 +69,27 @@ namespace NSwapCheck { Y_HAS_MEMBER(swap); Y_HAS_MEMBER(Swap); - template <class T, class = void> - struct TSwapSelector { - static inline void Swap(T& l, T& r) noexcept(std::is_nothrow_move_constructible<T>::value&& - std::is_nothrow_move_assignable<T>::value) { - T tmp(std::move(l)); - l = std::move(r); - r = std::move(tmp); + template <class T, class = void> + struct TSwapSelector { + static inline void Swap(T& l, T& r) noexcept(std::is_nothrow_move_constructible<T>::value&& + std::is_nothrow_move_assignable<T>::value) { + T tmp(std::move(l)); + l = std::move(r); + r = std::move(tmp); } }; - template <class T> - struct TSwapSelector<T, std::enable_if_t<THasSwap<T>::value>> { - static inline void Swap(T& l, T& r) noexcept(noexcept(l.Swap(r))) { - l.Swap(r); + template <class T> + struct TSwapSelector<T, std::enable_if_t<THasSwap<T>::value>> { + static inline void Swap(T& l, T& r) noexcept(noexcept(l.Swap(r))) { + l.Swap(r); } }; - template <class T> - struct TSwapSelector<T, std::enable_if_t<THasswap<T>::value && !THasSwap<T>::value>> { - static inline void Swap(T& l, T& r) noexcept(noexcept(l.swap(r))) { - l.swap(r); + template <class T> + struct TSwapSelector<T, std::enable_if_t<THasswap<T>::value && !THasSwap<T>::value>> { + static inline void Swap(T& l, T& r) noexcept(noexcept(l.swap(r))) { + l.swap(r); } }; } @@ -98,7 +98,7 @@ namespace NSwapCheck { * DoSwap better than ::Swap in member functions... */ template <class T> -static inline void DoSwap(T& l, T& r) noexcept(noexcept(NSwapCheck::TSwapSelector<T>::Swap(l, r))) { +static inline void DoSwap(T& l, T& r) noexcept(noexcept(NSwapCheck::TSwapSelector<T>::Swap(l, r))) { NSwapCheck::TSwapSelector<T>::Swap(l, r); } diff --git a/util/generic/variant.h b/util/generic/variant.h index 9313f3cfa8..749fc75090 100644 --- a/util/generic/variant.h +++ b/util/generic/variant.h @@ -13,11 +13,11 @@ public: v.valueless_by_exception() ? 0 : std::visit([](const auto& value) { return ComputeHash(value); }, v)); } }; - -template <> + +template <> struct THash<std::monostate> { -public: +public: constexpr size_t operator()(std::monostate) const noexcept { return 1; } -}; +}; diff --git a/util/memory/blob.cpp b/util/memory/blob.cpp index d805cffa1b..91da5cadca 100644 --- a/util/memory/blob.cpp +++ b/util/memory/blob.cpp @@ -77,11 +77,11 @@ public: { } - TStringBlobBase(TString&& s) noexcept - : S_(std::move(s)) - { - } - + TStringBlobBase(TString&& s) noexcept + : S_(std::move(s)) + { + } + ~TStringBlobBase() override = default; void Ref() noexcept override { @@ -390,10 +390,10 @@ TBlob TBlob::FromBuffer(TBuffer& in) { return ConstructFromBuffer<TAtomicCounter>(in); } -template <class TCounter, class S> -TBlob ConstructFromString(S&& s) { +template <class TCounter, class S> +TBlob ConstructFromString(S&& s) { using TBase = TStringBlobBase<TCounter>; - auto base = MakeHolder<TBase>(std::forward<S>(s)); + auto base = MakeHolder<TBase>(std::forward<S>(s)); TBlob ret(base->String().data(), base->String().size(), base.Get()); Y_UNUSED(base.Release()); @@ -405,14 +405,14 @@ TBlob TBlob::FromStringSingleThreaded(const TString& s) { return ConstructFromString<TSimpleCounter>(s); } -TBlob TBlob::FromStringSingleThreaded(TString&& s) { - return ConstructFromString<TSimpleCounter>(std::move(s)); -} - +TBlob TBlob::FromStringSingleThreaded(TString&& s) { + return ConstructFromString<TSimpleCounter>(std::move(s)); +} + TBlob TBlob::FromString(const TString& s) { return ConstructFromString<TAtomicCounter>(s); } - -TBlob TBlob::FromString(TString&& s) { - return ConstructFromString<TAtomicCounter>(std::move(s)); -} + +TBlob TBlob::FromString(TString&& s) { + return ConstructFromString<TAtomicCounter>(std::move(s)); +} diff --git a/util/memory/blob.h b/util/memory/blob.h index 73de03bb53..20c02a68df 100644 --- a/util/memory/blob.h +++ b/util/memory/blob.h @@ -294,18 +294,18 @@ public: /// @details The input object becomes empty. static TBlob FromBuffer(TBuffer& in); - /// Creates a blob from TString with a single-threaded (non atomic) refcounter. + /// Creates a blob from TString with a single-threaded (non atomic) refcounter. static TBlob FromStringSingleThreaded(const TString& s); - /// Creates a blob from TString with a single-threaded (non atomic) refcounter. Doesn't copy its content. - static TBlob FromStringSingleThreaded(TString&& s); - - /// Creates a blob from TString with a multi-threaded (atomic) refcounter. + /// Creates a blob from TString with a single-threaded (non atomic) refcounter. Doesn't copy its content. + static TBlob FromStringSingleThreaded(TString&& s); + + /// Creates a blob from TString with a multi-threaded (atomic) refcounter. static TBlob FromString(const TString& s); - /// Creates a blob from TString with a multi-threaded (atomic) refcounter. Doesn't copy its content. - static TBlob FromString(TString&& s); - + /// Creates a blob from TString with a multi-threaded (atomic) refcounter. Doesn't copy its content. + static TBlob FromString(TString&& s); + private: inline void Ref() noexcept { if (S_.Base) { diff --git a/util/network/address.cpp b/util/network/address.cpp index 2d632796f3..a81a9e6994 100644 --- a/util/network/address.cpp +++ b/util/network/address.cpp @@ -131,7 +131,7 @@ TString NAddr::PrintHostAndPort(const IRemoteAddr& addr) { } IRemoteAddrPtr NAddr::GetSockAddr(SOCKET s) { - auto addr = MakeHolder<TOpaqueAddr>(); + auto addr = MakeHolder<TOpaqueAddr>(); if (getsockname(s, addr->MutableAddr(), addr->LenPtr()) < 0) { ythrow TSystemError() << "getsockname() failed"; diff --git a/util/network/address.h b/util/network/address.h index 7d1d3f7b53..448fcac0c9 100644 --- a/util/network/address.h +++ b/util/network/address.h @@ -15,7 +15,7 @@ namespace NAddr { virtual socklen_t Len() const = 0; }; - using IRemoteAddrPtr = THolder<IRemoteAddr>; + using IRemoteAddrPtr = THolder<IRemoteAddr>; using IRemoteAddrRef = TAtomicSharedPtr<NAddr::IRemoteAddr>; IRemoteAddrPtr GetSockAddr(SOCKET s); diff --git a/util/string/split.h b/util/string/split.h index 14e93e89c2..bc46d9e64c 100644 --- a/util/string/split.h +++ b/util/string/split.h @@ -264,18 +264,18 @@ namespace NSplitTargetHasPushBack { Y_HAS_MEMBER(push_back, PushBack); } -template <class T, class = void> -struct TConsumerBackInserter; +template <class T, class = void> +struct TConsumerBackInserter; template <class T> -struct TConsumerBackInserter<T, std::enable_if_t<NSplitTargetHasPushBack::TClassHasPushBack<T>::value>> { +struct TConsumerBackInserter<T, std::enable_if_t<NSplitTargetHasPushBack::TClassHasPushBack<T>::value>> { static void DoInsert(T* C, const typename T::value_type& i) { C->push_back(i); } }; template <class T> -struct TConsumerBackInserter<T, std::enable_if_t<!NSplitTargetHasPushBack::TClassHasPushBack<T>::value>> { +struct TConsumerBackInserter<T, std::enable_if_t<!NSplitTargetHasPushBack::TClassHasPushBack<T>::value>> { static void DoInsert(T* C, const typename T::value_type& i) { C->insert(C->end(), i); } @@ -290,7 +290,7 @@ struct TContainerConsumer { template <class I> inline bool Consume(I* b, I* d, I* /*e*/) { - TConsumerBackInserter<T>::DoInsert(C, typename T::value_type(b, d)); + TConsumerBackInserter<T>::DoInsert(C, typename T::value_type(b, d)); return true; } @@ -307,7 +307,7 @@ struct TContainerConvertingConsumer { template <class I> inline bool Consume(I* b, I* d, I* /*e*/) { - TConsumerBackInserter<T>::DoInsert(C, FromString<typename T::value_type>(TStringBuf(b, d))); + TConsumerBackInserter<T>::DoInsert(C, FromString<typename T::value_type>(TStringBuf(b, d))); return true; } diff --git a/util/system/event_ut.cpp b/util/system/event_ut.cpp index 944a4c6e87..2506cb7a91 100644 --- a/util/system/event_ut.cpp +++ b/util/system/event_ut.cpp @@ -101,7 +101,7 @@ Y_UNIT_TEST_SUITE(EventTest) { TManualEvent event[limit]; TThreadPool queue; queue.Start(limit); - TVector<THolder<IObjectInQueue>> tasks; + TVector<THolder<IObjectInQueue>> tasks; for (size_t i = 0; i < limit; ++i) { tasks.emplace_back(MakeHolder<TSignalTask>(event[i])); UNIT_ASSERT(queue.Add(tasks.back().Get())); @@ -115,16 +115,16 @@ Y_UNIT_TEST_SUITE(EventTest) { /** Test for a problem: http://nga.at.yandex-team.ru/5772 */ Y_UNIT_TEST(DestructorBeforeSignalFinishTest) { return; - TVector<THolder<IObjectInQueue>> tasks; + TVector<THolder<IObjectInQueue>> tasks; for (size_t i = 0; i < 1000; ++i) { - auto owner = MakeHolder<TOwnerTask>(); + auto owner = MakeHolder<TOwnerTask>(); tasks.emplace_back(MakeHolder<TSignalTask>(*owner->Ev)); - tasks.emplace_back(std::move(owner)); + tasks.emplace_back(std::move(owner)); } TThreadPool queue; queue.Start(4); - for (auto& task : tasks) { + for (auto& task : tasks) { UNIT_ASSERT(queue.Add(task.Get())); } queue.Stop(); diff --git a/util/system/fasttime.cpp b/util/system/fasttime.cpp index db4d894072..057a814f0a 100644 --- a/util/system/fasttime.cpp +++ b/util/system/fasttime.cpp @@ -57,7 +57,7 @@ namespace { return (((TTime)1000000) * (TTime)tv.tv_sec) + (TTime)tv.tv_usec; } - static inline THolder<TDynamicLibrary> OpenLibc() { + static inline THolder<TDynamicLibrary> OpenLibc() { const char* libs[] = { "/lib/libc.so.8", "/lib/libc.so.7", @@ -66,7 +66,7 @@ namespace { for (auto& lib : libs) { try { - return MakeHolder<TDynamicLibrary>(lib); + return MakeHolder<TDynamicLibrary>(lib); } catch (...) { // ¯\_(ツ)_/¯ } @@ -83,7 +83,7 @@ namespace { return Lib.Get(); } - THolder<TDynamicLibrary> Lib; + THolder<TDynamicLibrary> Lib; TFunc Func; }; diff --git a/util/system/filemap_ut.cpp b/util/system/filemap_ut.cpp index 722fd2237b..73f109dc88 100644 --- a/util/system/filemap_ut.cpp +++ b/util/system/filemap_ut.cpp @@ -164,10 +164,10 @@ Y_UNIT_TEST_SUITE(TFileMapTest) { file.Close(); // Make 16 maps of our file, which would require 16*128M = 2Gb and exceed our 1Gb limit - TVector<THolder<TFileMap>> maps; + TVector<THolder<TFileMap>> maps; for (int i = 0; i < 16; ++i) { - maps.emplace_back(MakeHolder<TFileMap>(FileName_, TMemoryMapCommon::oRdOnly | TMemoryMapCommon::oNotGreedy)); + maps.emplace_back(MakeHolder<TFileMap>(FileName_, TMemoryMapCommon::oRdOnly | TMemoryMapCommon::oNotGreedy)); maps.back()->Map(i * sizeof(page), sizeof(page)); } diff --git a/util/system/tls.cpp b/util/system/tls.cpp index 4d06470b65..c2f1a04a14 100644 --- a/util/system/tls.cpp +++ b/util/system/tls.cpp @@ -208,7 +208,7 @@ namespace { } private: - using TPTSRef = THolder<TPerThreadStorage>; + using TPTSRef = THolder<TPerThreadStorage>; TMutex Lock_; THashMap<TThread::TId, TPTSRef> Datas_; }; diff --git a/util/system/tls.h b/util/system/tls.h index c9ad6b4a71..3c4f56dbeb 100644 --- a/util/system/tls.h +++ b/util/system/tls.h @@ -61,7 +61,7 @@ //...later somewhere in cpp... TMyWriter*& writerRef = ThreadLocalWriter.Get(); if (writerRef == nullptr) { - THolder<TMyWriter> threadLocalWriter( new TMyWriter( + THolder<TMyWriter> threadLocalWriter( new TMyWriter( *Session, MinLogError, MaxRps, diff --git a/util/system/types.cpp b/util/system/types.cpp index 2af2d90a48..11cc72aee3 100644 --- a/util/system/types.cpp +++ b/util/system/types.cpp @@ -15,4 +15,4 @@ static_assert(sizeof(i64) == 8, "incorrect i64 type"); static_assert(sizeof(size_t) == sizeof(ssize_t), "incorrect ssize_t"); -static_assert(TTypeList<ui32, ui64>::THave<size_t>::value, "incorrect size_t"); +static_assert(TTypeList<ui32, ui64>::THave<size_t>::value, "incorrect size_t"); diff --git a/util/thread/factory.cpp b/util/thread/factory.cpp index 50a51680e2..48e898f32d 100644 --- a/util/thread/factory.cpp +++ b/util/thread/factory.cpp @@ -66,8 +66,8 @@ namespace { }; } -THolder<IThread> IThreadFactory::Run(std::function<void()> func) { - THolder<IThread> ret(DoCreate()); +THolder<IThread> IThreadFactory::Run(std::function<void()> func) { + THolder<IThread> ret(DoCreate()); ret->Run(new ::TThreadFactoryFuncObj(func)); diff --git a/util/thread/factory.h b/util/thread/factory.h index 2330435d11..561fcbac88 100644 --- a/util/thread/factory.h +++ b/util/thread/factory.h @@ -47,15 +47,15 @@ public: virtual ~IThreadFactory() = default; // XXX: rename to Start - inline THolder<IThread> Run(IThreadAble* func) { - THolder<IThread> ret(DoCreate()); + inline THolder<IThread> Run(IThreadAble* func) { + THolder<IThread> ret(DoCreate()); ret->Run(func); return ret; } - THolder<IThread> Run(std::function<void()> func); + THolder<IThread> Run(std::function<void()> func); private: virtual IThread* DoCreate() = 0; diff --git a/util/thread/factory_ut.cpp b/util/thread/factory_ut.cpp index 352c7c90a6..647d96c901 100644 --- a/util/thread/factory_ut.cpp +++ b/util/thread/factory_ut.cpp @@ -29,7 +29,7 @@ private: TRunAble r; { - THolder<IThreadFactory::IThread> thr = SystemThreadFactory()->Run(&r); + THolder<IThreadFactory::IThread> thr = SystemThreadFactory()->Run(&r); thr->Join(); } @@ -45,7 +45,7 @@ private: pool.Start(0); - THolder<IThreadFactory::IThread> thr = pool.Run(&r); + THolder<IThreadFactory::IThread> thr = pool.Run(&r); thr->Join(); } diff --git a/util/thread/lfqueue.h b/util/thread/lfqueue.h index 647c03fb3c..ab523631e4 100644 --- a/util/thread/lfqueue.h +++ b/util/thread/lfqueue.h @@ -362,7 +362,7 @@ public: template <class T, class TCounter> class TAutoLockFreeQueue { public: - using TRef = THolder<T>; + using TRef = THolder<T>; inline ~TAutoLockFreeQueue() { TRef tmp; diff --git a/util/thread/pool.cpp b/util/thread/pool.cpp index 6f99c21e59..05fad02e9b 100644 --- a/util/thread/pool.cpp +++ b/util/thread/pool.cpp @@ -68,7 +68,7 @@ TThreadFactoryHolder::TThreadFactoryHolder() noexcept class TThreadPool::TImpl: public TIntrusiveListItem<TImpl>, public IThreadFactory::IThreadAble { using TTsr = IThreadPool::TTsr; using TJobQueue = TFastQueue<IObjectInQueue*>; - using TThreadRef = THolder<IThreadFactory::IThread>; + using TThreadRef = THolder<IThreadFactory::IThread>; public: inline TImpl(TThreadPool* parent, size_t thrnum, size_t maxqueue, const TParams& params) @@ -415,7 +415,7 @@ public: private: TImpl* Impl_; - THolder<IThreadFactory::IThread> Thread_; + THolder<IThreadFactory::IThread> Thread_; }; inline TImpl(TAdaptiveThreadPool* parent, const TParams& params) @@ -647,8 +647,8 @@ namespace { THolder<IObjectInQueue> Owned; public: - TOwnedObjectInQueue(THolder<IObjectInQueue> owned) - : Owned(std::move(owned)) + TOwnedObjectInQueue(THolder<IObjectInQueue> owned) + : Owned(std::move(owned)) { } @@ -663,12 +663,12 @@ void IThreadPool::SafeAdd(IObjectInQueue* obj) { Y_ENSURE_EX(Add(obj), TThreadPoolException() << TStringBuf("can not add object to queue")); } -void IThreadPool::SafeAddAndOwn(THolder<IObjectInQueue> obj) { +void IThreadPool::SafeAddAndOwn(THolder<IObjectInQueue> obj) { Y_ENSURE_EX(AddAndOwn(std::move(obj)), TThreadPoolException() << TStringBuf("can not add to queue and own")); } -bool IThreadPool::AddAndOwn(THolder<IObjectInQueue> obj) { - auto owner = MakeHolder<TOwnedObjectInQueue>(std::move(obj)); +bool IThreadPool::AddAndOwn(THolder<IObjectInQueue> obj) { + auto owner = MakeHolder<TOwnedObjectInQueue>(std::move(obj)); bool added = Add(owner.Get()); if (added) { Y_UNUSED(owner.Release()); diff --git a/util/thread/pool.h b/util/thread/pool.h index 84e6e694fb..d1ea3a67cb 100644 --- a/util/thread/pool.h +++ b/util/thread/pool.h @@ -153,7 +153,7 @@ public: Y_ENSURE_EX(AddFunc(std::forward<T>(func)), TThreadPoolException() << TStringBuf("can not add function to queue")); } - void SafeAddAndOwn(THolder<IObjectInQueue> obj); + void SafeAddAndOwn(THolder<IObjectInQueue> obj); /** * Add object to queue, run ojb->Proccess in other threads. @@ -173,7 +173,7 @@ public: return added; } - bool AddAndOwn(THolder<IObjectInQueue> obj) Y_WARN_UNUSED_RESULT; + bool AddAndOwn(THolder<IObjectInQueue> obj) Y_WARN_UNUSED_RESULT; virtual void Start(size_t threadCount, size_t queueSizeLimit = 0) = 0; /** Wait for completion of all scheduled objects, and then exit */ virtual void Stop() noexcept = 0; @@ -377,7 +377,7 @@ private: TSlave* Slave_; }; -inline void Delete(THolder<IThreadPool> q) { +inline void Delete(THolder<IThreadPool> q) { if (q.Get()) { q->Stop(); } diff --git a/util/thread/pool_ut.cpp b/util/thread/pool_ut.cpp index 0fa57af1d0..893770d0c4 100644 --- a/util/thread/pool_ut.cpp +++ b/util/thread/pool_ut.cpp @@ -24,7 +24,7 @@ struct TThreadPoolTest { } void Process(void*) override { - THolder<TTask> This(this); + THolder<TTask> This(this); TGuard<TSpinLock> guard(Test->Lock); Test->R ^= Value; diff --git a/util/ysaveload.h b/util/ysaveload.h index 5527df5847..02efb4049b 100644 --- a/util/ysaveload.h +++ b/util/ysaveload.h @@ -5,7 +5,7 @@ #include <util/generic/string.h> #include <util/generic/yexception.h> #include <util/generic/typetraits.h> -#include <util/generic/algorithm.h> +#include <util/generic/algorithm.h> #include <util/stream/output.h> #include <util/stream/input.h> @@ -128,15 +128,15 @@ struct TSerializerTakingIntoAccountThePodType { } }; -namespace NHasSaveLoad { - Y_HAS_MEMBER(SaveLoad); -} - -template <class T, class = void> -struct TSerializerMethodSelector; - -template <class T> -struct TSerializerMethodSelector<T, std::enable_if_t<NHasSaveLoad::THasSaveLoad<T>::value>> { +namespace NHasSaveLoad { + Y_HAS_MEMBER(SaveLoad); +} + +template <class T, class = void> +struct TSerializerMethodSelector; + +template <class T> +struct TSerializerMethodSelector<T, std::enable_if_t<NHasSaveLoad::THasSaveLoad<T>::value>> { static inline void Save(IOutputStream* out, const T& t) { //assume Save clause do not change t (const_cast<T&>(t)).SaveLoad(out); @@ -153,7 +153,7 @@ struct TSerializerMethodSelector<T, std::enable_if_t<NHasSaveLoad::THasSaveLoad< }; template <class T> -struct TSerializerMethodSelector<T, std::enable_if_t<!NHasSaveLoad::THasSaveLoad<T>::value>> { +struct TSerializerMethodSelector<T, std::enable_if_t<!NHasSaveLoad::THasSaveLoad<T>::value>> { static inline void Save(IOutputStream* out, const T& t) { t.Save(out); } @@ -420,24 +420,24 @@ public: } }; -template <class T> +template <class T> struct TTupleSerializer { - template <class F, class Tuple, size_t... Indices> - static inline void ReverseUseless(F&& f, Tuple&& t, std::index_sequence<Indices...>) { - ApplyToMany( - std::forward<F>(f), - // We need to do this trick because we don't want to break backward compatibility. - // Tuples are being packed in reverse order. - std::get<std::tuple_size<T>::value - Indices - 1>(std::forward<Tuple>(t))...); + template <class F, class Tuple, size_t... Indices> + static inline void ReverseUseless(F&& f, Tuple&& t, std::index_sequence<Indices...>) { + ApplyToMany( + std::forward<F>(f), + // We need to do this trick because we don't want to break backward compatibility. + // Tuples are being packed in reverse order. + std::get<std::tuple_size<T>::value - Indices - 1>(std::forward<Tuple>(t))...); } - static inline void Save(IOutputStream* stream, const T& t) { - ReverseUseless([&](const auto& v) { ::Save(stream, v); }, t, + static inline void Save(IOutputStream* stream, const T& t) { + ReverseUseless([&](const auto& v) { ::Save(stream, v); }, t, std::make_index_sequence<std::tuple_size<T>::value>{}); } - static inline void Load(IInputStream* stream, T& t) { - ReverseUseless([&](auto& v) { ::Load(stream, v); }, t, + static inline void Load(IInputStream* stream, T& t) { + ReverseUseless([&](auto& v) { ::Load(stream, v); }, t, std::make_index_sequence<std::tuple_size<T>::value>{}); } }; @@ -641,15 +641,15 @@ public: #ifndef __NVCC__ -namespace NPrivate { - template <class Variant, class T, size_t I> - void LoadVariantAlternative(IInputStream* is, Variant& v) { - T loaded; - ::Load(is, loaded); - v.template emplace<I>(std::move(loaded)); - } -} - +namespace NPrivate { + template <class Variant, class T, size_t I> + void LoadVariantAlternative(IInputStream* is, Variant& v) { + T loaded; + ::Load(is, loaded); + v.template emplace<I>(std::move(loaded)); + } +} + template <typename... Args> struct TSerializer<std::variant<Args...>> { using TVar = std::variant<Args...>; @@ -664,21 +664,21 @@ struct TSerializer<std::variant<Args...>> { } static void Load(IInputStream* is, TVar& v) { - ui8 index; - ::Load(is, index); + ui8 index; + ::Load(is, index); if (Y_UNLIKELY(index >= sizeof...(Args))) { ::NPrivate::ThrowUnexpectedVariantTagException(index); - } - LoadImpl(is, v, index, std::index_sequence_for<Args...>{}); + } + LoadImpl(is, v, index, std::index_sequence_for<Args...>{}); } - -private: - template <size_t... Is> - static void LoadImpl(IInputStream* is, TVar& v, ui8 index, std::index_sequence<Is...>) { + +private: + template <size_t... Is> + static void LoadImpl(IInputStream* is, TVar& v, ui8 index, std::index_sequence<Is...>) { using TLoader = void (*)(IInputStream*, TVar & v); - constexpr TLoader loaders[] = {::NPrivate::LoadVariantAlternative<TVar, Args, Is>...}; - loaders[index](is, v); - } + constexpr TLoader loaders[] = {::NPrivate::LoadVariantAlternative<TVar, Args, Is>...}; + loaders[index](is, v); + } }; #endif @@ -693,14 +693,14 @@ static inline void SaveLoad(IInputStream* in, T& t) { Load(in, t); } -template <class S, class... Ts> -static inline void SaveMany(S* s, const Ts&... t) { - ApplyToMany([&](const auto& v) { Save(s, v); }, t...); +template <class S, class... Ts> +static inline void SaveMany(S* s, const Ts&... t) { + ApplyToMany([&](const auto& v) { Save(s, v); }, t...); } -template <class S, class... Ts> -static inline void LoadMany(S* s, Ts&... t) { - ApplyToMany([&](auto& v) { Load(s, v); }, t...); +template <class S, class... Ts> +static inline void LoadMany(S* s, Ts&... t) { + ApplyToMany([&](auto& v) { Load(s, v); }, t...); } #define Y_SAVELOAD_DEFINE(...) \ diff --git a/ydb/core/actorlib_impl/test_protocols_ut.cpp b/ydb/core/actorlib_impl/test_protocols_ut.cpp index 6d93aae59f..2e622406a0 100644 --- a/ydb/core/actorlib_impl/test_protocols_ut.cpp +++ b/ydb/core/actorlib_impl/test_protocols_ut.cpp @@ -181,7 +181,7 @@ Y_UNIT_TEST_SUITE(TestProtocols) { const TActorContext& ctx, NAddr::IRemoteAddrPtr address) noexcept override { - Address = std::move(address); + Address = std::move(address); ConnectSocket(this, ctx, Address); } @@ -277,7 +277,7 @@ Y_UNIT_TEST_SUITE(TestProtocols) { const TActorContext& ctx, NAddr::IRemoteAddrPtr address) noexcept override { - ConnectSocket(this, ctx, std::move(address)); + ConnectSocket(this, ctx, std::move(address)); } void CatchResolveError( diff --git a/ydb/core/tablet_flat/flat_stat_table.h b/ydb/core/tablet_flat/flat_stat_table.h index b13953a2cb..8a892b8a67 100644 --- a/ydb/core/tablet_flat/flat_stat_table.h +++ b/ydb/core/tablet_flat/flat_stat_table.h @@ -18,8 +18,8 @@ public: , Heap(TIterKeyGreater{ this }) {} - void Add(THolder<TScreenedPartIndexIterator> pi) { - Iterators.PushBack(std::move(pi)); + void Add(THolder<TScreenedPartIndexIterator> pi) { + Iterators.PushBack(std::move(pi)); TScreenedPartIndexIterator* it = Iterators.back(); if (it->IsValid()) { NextRowCount += it->GetRowCountDelta(); diff --git a/ydb/core/viewer/json_tabletinfo.h b/ydb/core/viewer/json_tabletinfo.h index 82542572f0..32546865a1 100644 --- a/ydb/core/viewer/json_tabletinfo.h +++ b/ydb/core/viewer/json_tabletinfo.h @@ -43,7 +43,7 @@ struct TWhiteboardInfo<TEvWhiteboard::TEvTabletStateResponse> { }; template <> -struct TWhiteboardMergerComparator<NKikimrWhiteboard::TTabletStateInfo> { +struct TWhiteboardMergerComparator<NKikimrWhiteboard::TTabletStateInfo> { bool operator ()(const NKikimrWhiteboard::TTabletStateInfo& a, const NKikimrWhiteboard::TTabletStateInfo& b) const { return std::make_tuple(a.GetGeneration(), a.GetChangeTime()) < std::make_tuple(b.GetGeneration(), b.GetChangeTime()); } diff --git a/ydb/core/viewer/wb_merge.h b/ydb/core/viewer/wb_merge.h index 14188d9b37..27fd3c8f67 100644 --- a/ydb/core/viewer/wb_merge.h +++ b/ydb/core/viewer/wb_merge.h @@ -18,7 +18,7 @@ template <typename ResponseType> struct TWhiteboardInfo; template <typename ResponseType> -struct TWhiteboardMergerComparator { +struct TWhiteboardMergerComparator { bool operator ()(const ResponseType& a, const ResponseType& b) const { return a.GetChangeTime() < b.GetChangeTime(); } diff --git a/ydb/core/ymq/http/parser.rl6 b/ydb/core/ymq/http/parser.rl6 index dabedef733..b617c334a3 100644 --- a/ydb/core/ymq/http/parser.rl6 +++ b/ydb/core/ymq/http/parser.rl6 @@ -177,7 +177,7 @@ void TParametersParser::Append(const TString& name, const TString& value) { %% write init; Y_UNUSED(ts); - Y_UNUSED(act); + Y_UNUSED(act); const unsigned char* p = (const unsigned char*)name.data(); const unsigned char* pe = p + name.size(); diff --git a/ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h b/ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h index bc3a1ab5c9..d9feede204 100644 --- a/ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h +++ b/ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h @@ -790,7 +790,7 @@ public: auto& context = ctx.Codegen->GetContext(); const auto type = Type::getInt128Ty(context); const auto ptrType = PointerType::getUnqual(StructType::get(context)); - static_assert(std::is_same<std::invoke_result_t<decltype(&TDerived::DoCalculate), TDerived, TComputationContext&>, NUdf::TUnboxedValuePod>(), "DoCalculate must return pod!"); + static_assert(std::is_same<std::invoke_result_t<decltype(&TDerived::DoCalculate), TDerived, TComputationContext&>, NUdf::TUnboxedValuePod>(), "DoCalculate must return pod!"); const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TDerived::DoCalculate)); const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block); if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) { diff --git a/ydb/library/yql/public/udf/udf_helpers.h b/ydb/library/yql/public/udf/udf_helpers.h index 252e5a6cdf..2be9443559 100644 --- a/ydb/library/yql/public/udf/udf_helpers.h +++ b/ydb/library/yql/public/udf/udf_helpers.h @@ -317,7 +317,7 @@ public: template<typename TUdfType> void GetAllFunctionsImpl(IFunctionNamesSink& names) const { auto r = names.Add(TUdfType::Name()); - if (THasTTypeAwareMarker<TUdfType>::value) { + if (THasTTypeAwareMarker<TUdfType>::value) { r->SetTypeAwareness(); } } diff --git a/ydb/library/yql/public/udf/udf_string_ref.h b/ydb/library/yql/public/udf/udf_string_ref.h index 899a435e84..75a82b81e6 100644 --- a/ydb/library/yql/public/udf/udf_string_ref.h +++ b/ydb/library/yql/public/udf/udf_string_ref.h @@ -166,10 +166,10 @@ private: }; template<typename TStringType> - using TGetData = std::conditional_t<THasData<TStringType>::value, TByData<TStringType>, TBydata<TStringType>>; + using TGetData = std::conditional_t<THasData<TStringType>::value, TByData<TStringType>, TBydata<TStringType>>; template<typename TStringType> - using TGetSize = std::conditional_t<THasSize<TStringType>::value, TBySize<TStringType>, TBysize<TStringType>>; + using TGetSize = std::conditional_t<THasSize<TStringType>::value, TBySize<TStringType>, TBysize<TStringType>>; }; UDF_ASSERT_TYPE_SIZE(TStringRef, 16); |