Browse Source

Restoring authorship annotation for <pechatnov@yandex-team.ru>. Commit 1 of 2.

pechatnov 3 years ago
parent
commit
8e9b2f8bbf

+ 1 - 1
contrib/python/ya.make

@@ -1078,7 +1078,7 @@ RECURSE(
     tornado
     tornado-opentracing
     toro
-    tqdm
+    tqdm 
     trace_event
     traceback2
     traitlets

+ 100 - 100
library/cpp/iterator/README.md

@@ -1,100 +1,100 @@
-# Functools library
-
-Эта библиотека предоставляет функции `Enumerate`, `Zip`, `Map`, `Filter`, `Concatenate` и `CartesianProduct`.
-
-`Enumerate`, `Zip`, `Map`, `Filter` повторяют логику одноименных функций из python.
-
-Важный момент:
- * Итераторы данных view почти во всех случаях (кроме Map, там зависит от маппера) возвращают `std::tuple` **по значению** (при этом шаблонные параметры всегда, когда это уместно, ссылки). 
-   <br> Так что нет никакого смысла делать `for (const auto& [i, x] : Enumerate(c))`. 
-   <br> Лучше всегда `for (auto [i, x] : Enumerate(c))` (`x` в этом случае будет ссылкой и работать с ним можно как со ссылкой) или `for (const auto [i, x] : Enumerate(c))`.
-
-Предоставляемые гарантии:
- * Работа для всех контейнеров, для которых работает range-based for (для `Enumerate`, `Zip`, `Concatenate`, `CartesianProduct`).
-   Для `Map` и `Filter` есть требование на то, что первый и последний итераторы контейнера имеют один тип
- * В том числе работает для обычных массивов (`int a[] = {1, 2, 3}; Enumerate(a)`).
- * Поддержка rvalue для контейнеров, предикатов и функций-мапперов (`Filter([](auto x){...}, TVector{1, 2, 3})`).
-   В этом случае объекты сохраняются внутри view.
- * Проброс элементов контейнеров по неконстантной ссылке
- * `TView::iterator` - можно полагаться, что этот тип есть и корректен
- * `TIterator::iterator_category` - можно полагаться, что этот тип есть и определен.
-
-
-На что гарантий нет:
- * Любые изменения контейнеров, меняющие размер или инвалидирующие их итераторы, инвалидируют созданные view
- * Не принимает списки инициализации (`Enumerate({1, 2, 3})`), так как неизвестен желаемый тип контейнера.
- * В классах реализации оставлены публичные члены вида `.Field_`, чтобы не загромождать реализацию
-   Тем не менее эти поля не гарантированы, могут стать приватными или исчезнуть
- * Для всех итераторов определены вложенные типы: `value_type`, `pointer`, `reference`.
-   Тем не менее не рекомендуется их использовать в связи с их неоднозначностью.
-   `value_type` может быть как обычным типом, так и ссылкой. Может быть `std::tuple<T1, T2>`,
-   а может `std::tuple<T1&, const T2&>`.
-   Если возникает необходимость в этих типах, то возможно, стоит упростить код и вообще не использовать эти view.
-   Если очень хочется можно использовать `delctype(*container.begin())`.
-
-
-Производительность:
- * Бенчмарки времени компиляции и скорости выполнения, а так же сравнение с range-v3 и другими существующими реализациями
-   доступны в [репозитории где ведется разработка](https://github.com/yuri-pechatnov/cpp_functools/tree/master "functools").
-
-
-
-Q: Оверхед?
-A: По выполнению: на Enumerate, Zip, Map - нулевой. Где-то x1.5 на Filter, и x3 на Concatenate и CartesianProduct. Но если в теле цикла происходит хоть что-то существенное, то это пренебрежимо мало.
-   По компиляции: сложно рассчитать как оно скажется в реальном большом проекте, но приблизительно не более x1.5 на один цикл.
-
-Q: А зачем свой велосипед?
-A: ((https://pechatnov.at.yandex-team.ru/67 Ответ в этом посте)).
-
-Q: А почему вот здесь плохо написано, надо же по-другому?
-A: Код несколько раз переписывался и согласовывался ((https://st.yandex-team.ru/IGNIETFERRO-973 более полугода)). А допиливать его внутреннюю реализацию после коммита никто не мешает и дальше.
-
-
-Сигнатуры и эквиваленты:
-
-
-```cpp
-//! In all comments variables ending with '_'
-//! are considered as invisible for {...} block.
-
-//! Usage: for (auto [i, x] : Enumerate(container)) {...}
-//! Equivalent: { std::size_t i_ = 0; for (auto& x : container) { const std::size_t i = i_; {...}; ++i_; }}
-template <typename TContainerOrRef>
-auto Enumerate(TContainerOrRef&& container);
-
-//! Usage: for (auto x : Map(mapperFunc, container)) {...}
-//! Equivalent: for (auto iter_ = std::begin(container); iter_ != std::end(container); ++iter_) {
-//!                 auto x = mapperFunc(*iter_); {...}; }
-template <typename TMapper, typename TContainerOrRef>
-auto Map(TMapper&& mapper, TContainerOrRef&& container);
-
-//! Usage: for (auto x : Filter(predicate, container)) {...}
-//! Equivalent: for (auto x : container) { if (predicate(x)) {...}}
-template <typename TPredicate, typename TContainerOrRef>
-auto Filter(TPredicate&& predicate, TContainerOrRef&& container);
-
-//! Usage: for (auto [ai, bi] : Zip(a, b)) {...}
-//! Equivalent: { auto ia_ = std::begin(a); auto ib_ = std::begin(b);
-//!               for (; ia_ != std::end(a) && ib_ != std::end(b); ++ia_, ++ib_) {
-//!                   auto&& ai = *ia_; auto&& bi = *ib_; {...}
-//!               }}
-template <typename... TContainers>
-auto Zip(TContainers&&... containers);
-
-//! Usage: for (auto x : Reversed(container)) {...}
-//! Equivalent: for (auto iter_ = std::rbegin(container); iter_ != std::rend(container); ++iter_) {
-//!                 auto x = *iter_; {...}}
-template <typename TContainerOrRef>
-auto Reversed(TContainerOrRef&& container);
-
-//! Usage: for (auto x : Concatenate(a, b)) {...}
-//! Equivalent: { for (auto x : a) {...} for (auto x : b) {...} }
-//! (if there is no static variables in {...})
-template <typename TFirstContainer, typename... TContainers>
-auto Concatenate(TFirstContainer&& container, TContainers&&... containers);
-
-//! Usage: for (auto [ai, bi] : CartesianProduct(a, b)) {...}
-//! Equivalent: for (auto& ai : a) { for (auto& bi : b) {...} }
-template <typename... TContainers>
-auto CartesianProduct(TContainers&&... containers);
-```
+# Functools library 
+ 
+Эта библиотека предоставляет функции `Enumerate`, `Zip`, `Map`, `Filter`, `Concatenate` и `CartesianProduct`. 
+ 
+`Enumerate`, `Zip`, `Map`, `Filter` повторяют логику одноименных функций из python. 
+ 
+Важный момент: 
+ * Итераторы данных view почти во всех случаях (кроме Map, там зависит от маппера) возвращают `std::tuple` **по значению** (при этом шаблонные параметры всегда, когда это уместно, ссылки).  
+   <br> Так что нет никакого смысла делать `for (const auto& [i, x] : Enumerate(c))`.  
+   <br> Лучше всегда `for (auto [i, x] : Enumerate(c))` (`x` в этом случае будет ссылкой и работать с ним можно как со ссылкой) или `for (const auto [i, x] : Enumerate(c))`. 
+ 
+Предоставляемые гарантии: 
+ * Работа для всех контейнеров, для которых работает range-based for (для `Enumerate`, `Zip`, `Concatenate`, `CartesianProduct`). 
+   Для `Map` и `Filter` есть требование на то, что первый и последний итераторы контейнера имеют один тип 
+ * В том числе работает для обычных массивов (`int a[] = {1, 2, 3}; Enumerate(a)`). 
+ * Поддержка rvalue для контейнеров, предикатов и функций-мапперов (`Filter([](auto x){...}, TVector{1, 2, 3})`). 
+   В этом случае объекты сохраняются внутри view. 
+ * Проброс элементов контейнеров по неконстантной ссылке 
+ * `TView::iterator` - можно полагаться, что этот тип есть и корректен 
+ * `TIterator::iterator_category` - можно полагаться, что этот тип есть и определен. 
+ 
+ 
+На что гарантий нет: 
+ * Любые изменения контейнеров, меняющие размер или инвалидирующие их итераторы, инвалидируют созданные view 
+ * Не принимает списки инициализации (`Enumerate({1, 2, 3})`), так как неизвестен желаемый тип контейнера. 
+ * В классах реализации оставлены публичные члены вида `.Field_`, чтобы не загромождать реализацию 
+   Тем не менее эти поля не гарантированы, могут стать приватными или исчезнуть 
+ * Для всех итераторов определены вложенные типы: `value_type`, `pointer`, `reference`. 
+   Тем не менее не рекомендуется их использовать в связи с их неоднозначностью. 
+   `value_type` может быть как обычным типом, так и ссылкой. Может быть `std::tuple<T1, T2>`, 
+   а может `std::tuple<T1&, const T2&>`. 
+   Если возникает необходимость в этих типах, то возможно, стоит упростить код и вообще не использовать эти view. 
+   Если очень хочется можно использовать `delctype(*container.begin())`. 
+ 
+ 
+Производительность: 
+ * Бенчмарки времени компиляции и скорости выполнения, а так же сравнение с range-v3 и другими существующими реализациями 
+   доступны в [репозитории где ведется разработка](https://github.com/yuri-pechatnov/cpp_functools/tree/master "functools"). 
+ 
+ 
+ 
+Q: Оверхед? 
+A: По выполнению: на Enumerate, Zip, Map - нулевой. Где-то x1.5 на Filter, и x3 на Concatenate и CartesianProduct. Но если в теле цикла происходит хоть что-то существенное, то это пренебрежимо мало. 
+   По компиляции: сложно рассчитать как оно скажется в реальном большом проекте, но приблизительно не более x1.5 на один цикл. 
+ 
+Q: А зачем свой велосипед? 
+A: ((https://pechatnov.at.yandex-team.ru/67 Ответ в этом посте)). 
+ 
+Q: А почему вот здесь плохо написано, надо же по-другому? 
+A: Код несколько раз переписывался и согласовывался ((https://st.yandex-team.ru/IGNIETFERRO-973 более полугода)). А допиливать его внутреннюю реализацию после коммита никто не мешает и дальше. 
+ 
+ 
+Сигнатуры и эквиваленты: 
+ 
+ 
+```cpp 
+//! In all comments variables ending with '_' 
+//! are considered as invisible for {...} block. 
+ 
+//! Usage: for (auto [i, x] : Enumerate(container)) {...} 
+//! Equivalent: { std::size_t i_ = 0; for (auto& x : container) { const std::size_t i = i_; {...}; ++i_; }} 
+template <typename TContainerOrRef> 
+auto Enumerate(TContainerOrRef&& container); 
+ 
+//! Usage: for (auto x : Map(mapperFunc, container)) {...} 
+//! Equivalent: for (auto iter_ = std::begin(container); iter_ != std::end(container); ++iter_) { 
+//!                 auto x = mapperFunc(*iter_); {...}; } 
+template <typename TMapper, typename TContainerOrRef> 
+auto Map(TMapper&& mapper, TContainerOrRef&& container); 
+ 
+//! Usage: for (auto x : Filter(predicate, container)) {...} 
+//! Equivalent: for (auto x : container) { if (predicate(x)) {...}} 
+template <typename TPredicate, typename TContainerOrRef> 
+auto Filter(TPredicate&& predicate, TContainerOrRef&& container); 
+ 
+//! Usage: for (auto [ai, bi] : Zip(a, b)) {...} 
+//! Equivalent: { auto ia_ = std::begin(a); auto ib_ = std::begin(b); 
+//!               for (; ia_ != std::end(a) && ib_ != std::end(b); ++ia_, ++ib_) { 
+//!                   auto&& ai = *ia_; auto&& bi = *ib_; {...} 
+//!               }} 
+template <typename... TContainers> 
+auto Zip(TContainers&&... containers); 
+ 
+//! Usage: for (auto x : Reversed(container)) {...} 
+//! Equivalent: for (auto iter_ = std::rbegin(container); iter_ != std::rend(container); ++iter_) { 
+//!                 auto x = *iter_; {...}} 
+template <typename TContainerOrRef> 
+auto Reversed(TContainerOrRef&& container); 
+ 
+//! Usage: for (auto x : Concatenate(a, b)) {...} 
+//! Equivalent: { for (auto x : a) {...} for (auto x : b) {...} } 
+//! (if there is no static variables in {...}) 
+template <typename TFirstContainer, typename... TContainers> 
+auto Concatenate(TFirstContainer&& container, TContainers&&... containers); 
+ 
+//! Usage: for (auto [ai, bi] : CartesianProduct(a, b)) {...} 
+//! Equivalent: for (auto& ai : a) { for (auto& bi : b) {...} } 
+template <typename... TContainers> 
+auto CartesianProduct(TContainers&&... containers); 
+``` 

+ 1 - 1
library/cpp/iterator/cartesian_product.cpp

@@ -1 +1 @@
-#include "cartesian_product.h"
+#include "cartesian_product.h" 

+ 112 - 112
library/cpp/iterator/cartesian_product.h

@@ -1,115 +1,115 @@
-#pragma once
-
-#include <util/generic/store_policy.h>
-
-#include <tuple>
-
-
-namespace NPrivate {
-
-    template <typename... TContainers>
-    struct TCartesianMultiplier {
-        template <std::size_t... I>
-        struct TCartesianMultiplierWithIndex {
-        private:
-            using THolders = std::tuple<TAutoEmbedOrPtrPolicy<TContainers>...>;
-            using TValue = std::tuple<decltype(*std::begin(std::declval<TContainers&>()))...>;
-            using TIteratorState = std::tuple<int, decltype(std::begin(std::declval<TContainers&>()))...>;
-            using TSentinelState = std::tuple<int, decltype(std::end(std::declval<TContainers&>()))...>;
-
-            struct TIterator;
-            struct TSentinelCandidate {
-                TSentinelState Iterators_;
-                THolders* HoldersPtr_;
-            };
-            using TSentinel = std::conditional_t<std::is_same_v<TIteratorState, TSentinelState>,
-                                                 TIterator, TSentinelCandidate>;
-
-            struct TIterator {
-            private:
-                //! Return value is true when iteration is not finished
-                template <std::size_t position = sizeof...(TContainers)>
-                void IncrementIteratorsTuple() {
-                    auto& currentIterator = std::get<position>(Iterators_);
-                    ++currentIterator;
-
-                    if (currentIterator != std::end(*std::get<position - 1>(*HoldersPtr_).Ptr())) {
-                        return;
-                    } else {
-                        currentIterator = std::begin(*std::get<position - 1>(*HoldersPtr_).Ptr());
-                        if constexpr (position != 1) {
-                            IncrementIteratorsTuple<position - 1>();
-                        } else {
-                            std::get<0>(Iterators_) = 1;
-                        }
-                    }
-                }
-            public:
-                using difference_type = std::ptrdiff_t;
-                using value_type = TValue;
-                using pointer = TValue*;
-                using reference = TValue&;
-                using iterator_category = std::input_iterator_tag;
-
-                TValue operator*() {
-                    return {*std::get<I + 1>(Iterators_)...};
-                }
-                TValue operator*() const {
-                    return {*std::get<I + 1>(Iterators_)...};
-                }
-                void operator++() {
-                    IncrementIteratorsTuple();
-                }
-                bool operator!=(const TSentinel& other) const {
-                    // not finished iterator VS sentinel (most frequent case)
-                    if (std::get<0>(Iterators_) != std::get<0>(other.Iterators_)) {
-                        return true;
-                    }
-                    // do not compare sentinels and finished iterators
-                    if (std::get<0>(other.Iterators_)) {
-                        return false;
-                    }
-                    // compare not finished iterators
-                    return ((std::get<I + 1>(Iterators_) != std::get<I + 1>(other.Iterators_)) || ...);
-                }
-                bool operator==(const TSentinel& other) const {
-                    return !(*this != other);
-                }
-
-                TIteratorState Iterators_;
-                THolders* HoldersPtr_;
-            };
-        public:
-            using iterator = TIterator;
-            using const_iterator = TIterator;
+#pragma once 
+ 
+#include <util/generic/store_policy.h> 
+ 
+#include <tuple> 
+ 
+ 
+namespace NPrivate { 
+ 
+    template <typename... TContainers> 
+    struct TCartesianMultiplier { 
+        template <std::size_t... I> 
+        struct TCartesianMultiplierWithIndex { 
+        private: 
+            using THolders = std::tuple<TAutoEmbedOrPtrPolicy<TContainers>...>; 
+            using TValue = std::tuple<decltype(*std::begin(std::declval<TContainers&>()))...>; 
+            using TIteratorState = std::tuple<int, decltype(std::begin(std::declval<TContainers&>()))...>; 
+            using TSentinelState = std::tuple<int, decltype(std::end(std::declval<TContainers&>()))...>; 
+ 
+            struct TIterator; 
+            struct TSentinelCandidate { 
+                TSentinelState Iterators_; 
+                THolders* HoldersPtr_; 
+            }; 
+            using TSentinel = std::conditional_t<std::is_same_v<TIteratorState, TSentinelState>, 
+                                                 TIterator, TSentinelCandidate>; 
+ 
+            struct TIterator { 
+            private: 
+                //! Return value is true when iteration is not finished 
+                template <std::size_t position = sizeof...(TContainers)> 
+                void IncrementIteratorsTuple() { 
+                    auto& currentIterator = std::get<position>(Iterators_); 
+                    ++currentIterator; 
+ 
+                    if (currentIterator != std::end(*std::get<position - 1>(*HoldersPtr_).Ptr())) { 
+                        return; 
+                    } else { 
+                        currentIterator = std::begin(*std::get<position - 1>(*HoldersPtr_).Ptr()); 
+                        if constexpr (position != 1) { 
+                            IncrementIteratorsTuple<position - 1>(); 
+                        } else { 
+                            std::get<0>(Iterators_) = 1; 
+                        } 
+                    } 
+                } 
+            public: 
+                using difference_type = std::ptrdiff_t; 
+                using value_type = TValue; 
+                using pointer = TValue*; 
+                using reference = TValue&; 
+                using iterator_category = std::input_iterator_tag; 
+ 
+                TValue operator*() { 
+                    return {*std::get<I + 1>(Iterators_)...}; 
+                } 
+                TValue operator*() const { 
+                    return {*std::get<I + 1>(Iterators_)...}; 
+                } 
+                void operator++() { 
+                    IncrementIteratorsTuple(); 
+                } 
+                bool operator!=(const TSentinel& other) const { 
+                    // not finished iterator VS sentinel (most frequent case) 
+                    if (std::get<0>(Iterators_) != std::get<0>(other.Iterators_)) { 
+                        return true; 
+                    } 
+                    // do not compare sentinels and finished iterators 
+                    if (std::get<0>(other.Iterators_)) { 
+                        return false; 
+                    } 
+                    // compare not finished iterators 
+                    return ((std::get<I + 1>(Iterators_) != std::get<I + 1>(other.Iterators_)) || ...); 
+                } 
+                bool operator==(const TSentinel& other) const { 
+                    return !(*this != other); 
+                } 
+ 
+                TIteratorState Iterators_; 
+                THolders* HoldersPtr_; 
+            }; 
+        public: 
+            using iterator = TIterator; 
+            using const_iterator = TIterator; 
             using value_type = typename TIterator::value_type;
             using reference = typename TIterator::reference;
             using const_reference = typename TIterator::reference;
-
-            TIterator begin() const {
-                bool isEmpty = !((std::begin(*std::get<I>(Holders_).Ptr()) != std::end(*std::get<I>(Holders_).Ptr())) && ...);
-                return {TIteratorState{int(isEmpty), std::begin(*std::get<I>(Holders_).Ptr())...}, &Holders_};
-            }
-
-            TSentinel end() const {
-                return {TSentinelState{1, std::end(*std::get<I>(Holders_).Ptr())...}, &Holders_};
-            }
-
-            mutable THolders Holders_;
-        };
-
-        template <std::size_t... I>
-        static auto CartesianMultiply(TContainers&&... containers, std::index_sequence<I...>) {
-            return TCartesianMultiplierWithIndex<I...>{{std::forward<TContainers>(containers)...}};
-        }
-    };
-
-}
-
-//! Usage: for (auto [ai, bi] : CartesianProduct(a, b)) {...}
-//! Equivalent: for (auto& ai : a) { for (auto& bi : b) {...} }
-template <typename... TContainers>
-auto CartesianProduct(TContainers&&... containers) {
-    return NPrivate::TCartesianMultiplier<TContainers...>::CartesianMultiply(
-        std::forward<TContainers>(containers)..., std::make_index_sequence<sizeof...(TContainers)>{});
-}
+ 
+            TIterator begin() const { 
+                bool isEmpty = !((std::begin(*std::get<I>(Holders_).Ptr()) != std::end(*std::get<I>(Holders_).Ptr())) && ...); 
+                return {TIteratorState{int(isEmpty), std::begin(*std::get<I>(Holders_).Ptr())...}, &Holders_}; 
+            } 
+ 
+            TSentinel end() const { 
+                return {TSentinelState{1, std::end(*std::get<I>(Holders_).Ptr())...}, &Holders_}; 
+            } 
+ 
+            mutable THolders Holders_; 
+        }; 
+ 
+        template <std::size_t... I> 
+        static auto CartesianMultiply(TContainers&&... containers, std::index_sequence<I...>) { 
+            return TCartesianMultiplierWithIndex<I...>{{std::forward<TContainers>(containers)...}}; 
+        } 
+    }; 
+ 
+} 
+ 
+//! Usage: for (auto [ai, bi] : CartesianProduct(a, b)) {...} 
+//! Equivalent: for (auto& ai : a) { for (auto& bi : b) {...} } 
+template <typename... TContainers> 
+auto CartesianProduct(TContainers&&... containers) { 
+    return NPrivate::TCartesianMultiplier<TContainers...>::CartesianMultiply( 
+        std::forward<TContainers>(containers)..., std::make_index_sequence<sizeof...(TContainers)>{}); 
+} 

+ 1 - 1
library/cpp/iterator/concatenate.cpp

@@ -1 +1 @@
-#include "concatenate.h"
+#include "concatenate.h" 

+ 131 - 131
library/cpp/iterator/concatenate.h

@@ -1,136 +1,136 @@
-#pragma once
-
-#include <util/generic/store_policy.h>
-
-#include <iterator>
-#include <tuple>
-
-
-namespace NPrivate {
-
-    template <typename TValue_, typename... TContainers>
-    struct TConcatenator {
-        template <std::size_t... I>
-        struct TConcatenatorWithIndex {
-        private:
-            using THolders = std::tuple<TAutoEmbedOrPtrPolicy<TContainers>...>;
-            using TValue = TValue_;
-            using TIteratorState = std::tuple<decltype(std::begin(std::declval<TContainers&>()))...>;
-            using TSentinelState = std::tuple<decltype(std::end(std::declval<TContainers&>()))...>;
-
-            struct TIterator;
-            struct TSentinelCandidate {
-                TSentinelState Iterators_;
-                std::size_t Position_;
-                THolders* HoldersPtr_;
-            };
-            using TSentinel = std::conditional_t<std::is_same_v<TIteratorState, TSentinelState>,
-                                                 TIterator, TSentinelCandidate>;
-
-            struct TIterator {
-            private:
-                friend struct TConcatenatorWithIndex<I...>;
-
-                // important, that it is a static function, compiler better optimizes such code
-                template <std::size_t index = 0, typename TMaybeConstIteratorState>
-                static TValue GetCurrentValue(std::size_t position, TMaybeConstIteratorState& iterators) {
-                    if constexpr (index >= sizeof...(TContainers)) {
-                        // never happened when use of iterator is correct
-                        return *std::get<0>(iterators);
-                    } else {
-                        if (position == index) {
-                            return *std::get<index>(iterators);
-                        } else {
-                            return GetCurrentValue<index + 1>(position, iterators);
-                        }
-                    }
-                }
-
-                template <bool needIncrement, std::size_t index = 0>
-                void MaybeIncrementIteratorAndSkipExhaustedContainers() {
-                    if constexpr (index >= sizeof...(TContainers)) {
-                        return;
-                    } else {
-                        if (Position_ == index) {
-                            if constexpr (needIncrement) {
-                                ++std::get<index>(Iterators_);
-                            }
-                            if (!(std::get<index>(Iterators_) != std::end(*std::get<index>(*HoldersPtr_).Ptr()))) {
-                                ++Position_;
-                                MaybeIncrementIteratorAndSkipExhaustedContainers<false, index + 1>();
-                            }
-                        } else {
-                            MaybeIncrementIteratorAndSkipExhaustedContainers<needIncrement, index + 1>();
-                        }
-                    }
-                }
-            public:
-                using difference_type = std::ptrdiff_t;
-                using value_type = TValue;
-                using pointer = std::remove_reference_t<TValue>*;
-                using reference = std::remove_reference_t<TValue>&;
-                using iterator_category = std::input_iterator_tag;
-
-                TValue operator*() {
-                    return GetCurrentValue(Position_, Iterators_);
-                }
-                TValue operator*() const {
-                    return GetCurrentValue(Position_, Iterators_);
-                }
+#pragma once 
+ 
+#include <util/generic/store_policy.h> 
+ 
+#include <iterator> 
+#include <tuple> 
+ 
+ 
+namespace NPrivate { 
+ 
+    template <typename TValue_, typename... TContainers> 
+    struct TConcatenator { 
+        template <std::size_t... I> 
+        struct TConcatenatorWithIndex { 
+        private: 
+            using THolders = std::tuple<TAutoEmbedOrPtrPolicy<TContainers>...>; 
+            using TValue = TValue_; 
+            using TIteratorState = std::tuple<decltype(std::begin(std::declval<TContainers&>()))...>; 
+            using TSentinelState = std::tuple<decltype(std::end(std::declval<TContainers&>()))...>; 
+ 
+            struct TIterator; 
+            struct TSentinelCandidate { 
+                TSentinelState Iterators_; 
+                std::size_t Position_; 
+                THolders* HoldersPtr_; 
+            }; 
+            using TSentinel = std::conditional_t<std::is_same_v<TIteratorState, TSentinelState>, 
+                                                 TIterator, TSentinelCandidate>; 
+ 
+            struct TIterator { 
+            private: 
+                friend struct TConcatenatorWithIndex<I...>; 
+ 
+                // important, that it is a static function, compiler better optimizes such code 
+                template <std::size_t index = 0, typename TMaybeConstIteratorState> 
+                static TValue GetCurrentValue(std::size_t position, TMaybeConstIteratorState& iterators) { 
+                    if constexpr (index >= sizeof...(TContainers)) { 
+                        // never happened when use of iterator is correct 
+                        return *std::get<0>(iterators); 
+                    } else { 
+                        if (position == index) { 
+                            return *std::get<index>(iterators); 
+                        } else { 
+                            return GetCurrentValue<index + 1>(position, iterators); 
+                        } 
+                    } 
+                } 
+ 
+                template <bool needIncrement, std::size_t index = 0> 
+                void MaybeIncrementIteratorAndSkipExhaustedContainers() { 
+                    if constexpr (index >= sizeof...(TContainers)) { 
+                        return; 
+                    } else { 
+                        if (Position_ == index) { 
+                            if constexpr (needIncrement) { 
+                                ++std::get<index>(Iterators_); 
+                            } 
+                            if (!(std::get<index>(Iterators_) != std::end(*std::get<index>(*HoldersPtr_).Ptr()))) { 
+                                ++Position_; 
+                                MaybeIncrementIteratorAndSkipExhaustedContainers<false, index + 1>(); 
+                            } 
+                        } else { 
+                            MaybeIncrementIteratorAndSkipExhaustedContainers<needIncrement, index + 1>(); 
+                        } 
+                    } 
+                } 
+            public: 
+                using difference_type = std::ptrdiff_t; 
+                using value_type = TValue; 
+                using pointer = std::remove_reference_t<TValue>*; 
+                using reference = std::remove_reference_t<TValue>&; 
+                using iterator_category = std::input_iterator_tag; 
+ 
+                TValue operator*() { 
+                    return GetCurrentValue(Position_, Iterators_); 
+                } 
+                TValue operator*() const { 
+                    return GetCurrentValue(Position_, Iterators_); 
+                } 
                 TIterator& operator++() {
-                    MaybeIncrementIteratorAndSkipExhaustedContainers<true>();
+                    MaybeIncrementIteratorAndSkipExhaustedContainers<true>(); 
                     return *this;
-                }
-                bool operator!=(const TSentinel& other) const {
-                    // give compiler an opportunity to optimize sentinel case (-70% of time)
-                    if (other.Position_ == sizeof...(TContainers)) {
-                        return Position_ < sizeof...(TContainers);
-                    } else {
-                        return (Position_ != other.Position_ ||
-                                ((std::get<I>(Iterators_) != std::get<I>(other.Iterators_)) || ...));
-                    }
-                }
-                bool operator==(const TSentinel& other) const {
-                    return !(*this != other);
-                }
-
-                TIteratorState Iterators_;
-                std::size_t Position_;
-                THolders* HoldersPtr_;
-            };
-        public:
-            using iterator = TIterator;
-            using const_iterator = TIterator;
+                } 
+                bool operator!=(const TSentinel& other) const { 
+                    // give compiler an opportunity to optimize sentinel case (-70% of time) 
+                    if (other.Position_ == sizeof...(TContainers)) { 
+                        return Position_ < sizeof...(TContainers); 
+                    } else { 
+                        return (Position_ != other.Position_ || 
+                                ((std::get<I>(Iterators_) != std::get<I>(other.Iterators_)) || ...)); 
+                    } 
+                } 
+                bool operator==(const TSentinel& other) const { 
+                    return !(*this != other); 
+                } 
+ 
+                TIteratorState Iterators_; 
+                std::size_t Position_; 
+                THolders* HoldersPtr_; 
+            }; 
+        public: 
+            using iterator = TIterator; 
+            using const_iterator = TIterator; 
             using value_type = typename TIterator::value_type;
             using reference = typename TIterator::reference;
             using const_reference = typename TIterator::reference;
-
-            TIterator begin() const {
-                TIterator iterator{TIteratorState{std::begin(*std::get<I>(Holders_).Ptr())...}, 0, &Holders_};
-                iterator.template MaybeIncrementIteratorAndSkipExhaustedContainers<false>();
-                return iterator;
-            }
-
-            TSentinel end() const {
-                return {TSentinelState{std::end(*std::get<I>(Holders_).Ptr())...}, sizeof...(TContainers), &Holders_};
-            }
-
-            mutable THolders Holders_;
-        };
-
-        template <std::size_t... I>
-        static auto Concatenate(TContainers&&... containers, std::index_sequence<I...>) {
-            return TConcatenatorWithIndex<I...>{{std::forward<TContainers>(containers)...}};
-        }
-    };
-
-}
-
-
-//! Usage: for (auto x : Concatenate(a, b)) {...}
-template <typename TFirstContainer, typename... TContainers>
-auto Concatenate(TFirstContainer&& container, TContainers&&... containers) {
-    return NPrivate::TConcatenator<decltype(*std::begin(container)), TFirstContainer, TContainers...>::Concatenate(
-        std::forward<TFirstContainer>(container), std::forward<TContainers>(containers)...,
-        std::make_index_sequence<sizeof...(TContainers) + 1>{});
-}
+ 
+            TIterator begin() const { 
+                TIterator iterator{TIteratorState{std::begin(*std::get<I>(Holders_).Ptr())...}, 0, &Holders_}; 
+                iterator.template MaybeIncrementIteratorAndSkipExhaustedContainers<false>(); 
+                return iterator; 
+            } 
+ 
+            TSentinel end() const { 
+                return {TSentinelState{std::end(*std::get<I>(Holders_).Ptr())...}, sizeof...(TContainers), &Holders_}; 
+            } 
+ 
+            mutable THolders Holders_; 
+        }; 
+ 
+        template <std::size_t... I> 
+        static auto Concatenate(TContainers&&... containers, std::index_sequence<I...>) { 
+            return TConcatenatorWithIndex<I...>{{std::forward<TContainers>(containers)...}}; 
+        } 
+    }; 
+ 
+} 
+ 
+ 
+//! Usage: for (auto x : Concatenate(a, b)) {...} 
+template <typename TFirstContainer, typename... TContainers> 
+auto Concatenate(TFirstContainer&& container, TContainers&&... containers) { 
+    return NPrivate::TConcatenator<decltype(*std::begin(container)), TFirstContainer, TContainers...>::Concatenate( 
+        std::forward<TFirstContainer>(container), std::forward<TContainers>(containers)..., 
+        std::make_index_sequence<sizeof...(TContainers) + 1>{}); 
+} 

+ 1 - 1
library/cpp/iterator/enumerate.cpp

@@ -1 +1 @@
-#include "enumerate.h"
+#include "enumerate.h" 

+ 79 - 79
library/cpp/iterator/enumerate.h

@@ -1,82 +1,82 @@
-#pragma once
-
-#include <util/generic/store_policy.h>
-
-#include <limits>
-#include <tuple>
-
-
-namespace NPrivate {
-
-    template <typename TContainer>
-    struct TEnumerator {
-    private:
-        using TStorage = TAutoEmbedOrPtrPolicy<TContainer>;
-        using TValue = std::tuple<const std::size_t, decltype(*std::begin(std::declval<TContainer&>()))>;
-        using TIteratorState = decltype(std::begin(std::declval<TContainer&>()));
-        using TSentinelState = decltype(std::end(std::declval<TContainer&>()));
-
-        static constexpr bool TrivialSentinel = std::is_same_v<TIteratorState, TSentinelState>;
-
-        struct TIterator;
-        struct TSentinelCandidate {
-            TSentinelState Iterator_;
-        };
-        using TSentinel = std::conditional_t<TrivialSentinel, TIterator, TSentinelCandidate>;
-
-        struct TIterator {
-            using difference_type = std::ptrdiff_t;
-            using value_type = TValue;
-            using pointer = TValue*;
-            using reference = TValue&;
-            using iterator_category = std::input_iterator_tag;
-
-            TValue operator*() {
-                return {Index_, *Iterator_};
-            }
-            TValue operator*() const {
-                return {Index_, *Iterator_};
-            }
-            void operator++() {
-                ++Index_;
-                ++Iterator_;
-            }
-            bool operator!=(const TSentinel& other) const {
-                return Iterator_ != other.Iterator_;
-            }
-            bool operator==(const TSentinel& other) const {
-                return Iterator_ == other.Iterator_;
-            }
-
-            std::size_t Index_;
-            TIteratorState Iterator_;
-        };
-    public:
-        using iterator = TIterator;
-        using const_iterator = TIterator;
+#pragma once 
+ 
+#include <util/generic/store_policy.h> 
+ 
+#include <limits> 
+#include <tuple> 
+ 
+ 
+namespace NPrivate { 
+ 
+    template <typename TContainer> 
+    struct TEnumerator { 
+    private: 
+        using TStorage = TAutoEmbedOrPtrPolicy<TContainer>; 
+        using TValue = std::tuple<const std::size_t, decltype(*std::begin(std::declval<TContainer&>()))>; 
+        using TIteratorState = decltype(std::begin(std::declval<TContainer&>())); 
+        using TSentinelState = decltype(std::end(std::declval<TContainer&>())); 
+ 
+        static constexpr bool TrivialSentinel = std::is_same_v<TIteratorState, TSentinelState>; 
+ 
+        struct TIterator; 
+        struct TSentinelCandidate { 
+            TSentinelState Iterator_; 
+        }; 
+        using TSentinel = std::conditional_t<TrivialSentinel, TIterator, TSentinelCandidate>; 
+ 
+        struct TIterator { 
+            using difference_type = std::ptrdiff_t; 
+            using value_type = TValue; 
+            using pointer = TValue*; 
+            using reference = TValue&; 
+            using iterator_category = std::input_iterator_tag; 
+ 
+            TValue operator*() { 
+                return {Index_, *Iterator_}; 
+            } 
+            TValue operator*() const { 
+                return {Index_, *Iterator_}; 
+            } 
+            void operator++() { 
+                ++Index_; 
+                ++Iterator_; 
+            } 
+            bool operator!=(const TSentinel& other) const { 
+                return Iterator_ != other.Iterator_; 
+            } 
+            bool operator==(const TSentinel& other) const { 
+                return Iterator_ == other.Iterator_; 
+            } 
+ 
+            std::size_t Index_; 
+            TIteratorState Iterator_; 
+        }; 
+    public: 
+        using iterator = TIterator; 
+        using const_iterator = TIterator; 
         using value_type = typename TIterator::value_type;
         using reference = typename TIterator::reference;
         using const_reference = typename TIterator::reference;
-
-        TIterator begin() const {
-            return {0, std::begin(*Storage_.Ptr())};
-        }
-
-        TSentinel end() const {
-            if constexpr (TrivialSentinel) {
-                return TIterator{std::numeric_limits<std::size_t>::max(), std::end(*Storage_.Ptr())};
-            } else {
-                return TSentinel{std::end(*Storage_.Ptr())};
-            }
-        }
-
-        mutable TStorage Storage_;
-    };
-
-}
-
-//! Usage: for (auto [i, x] : Enumerate(container)) {...}
-template <typename TContainerOrRef>
-auto Enumerate(TContainerOrRef&& container) {
-    return NPrivate::TEnumerator<TContainerOrRef>{std::forward<TContainerOrRef>(container)};
-}
+ 
+        TIterator begin() const { 
+            return {0, std::begin(*Storage_.Ptr())}; 
+        } 
+ 
+        TSentinel end() const { 
+            if constexpr (TrivialSentinel) { 
+                return TIterator{std::numeric_limits<std::size_t>::max(), std::end(*Storage_.Ptr())}; 
+            } else { 
+                return TSentinel{std::end(*Storage_.Ptr())}; 
+            } 
+        } 
+ 
+        mutable TStorage Storage_; 
+    }; 
+ 
+} 
+ 
+//! Usage: for (auto [i, x] : Enumerate(container)) {...} 
+template <typename TContainerOrRef> 
+auto Enumerate(TContainerOrRef&& container) { 
+    return NPrivate::TEnumerator<TContainerOrRef>{std::forward<TContainerOrRef>(container)}; 
+} 

+ 1 - 1
library/cpp/iterator/filtering.cpp

@@ -1 +1 @@
-#include "filtering.h"
+#include "filtering.h" 

+ 37 - 37
library/cpp/iterator/filtering.h

@@ -1,10 +1,10 @@
 #pragma once
 
-#include <util/generic/iterator_range.h>
-#include <util/generic/store_policy.h>
+#include <util/generic/iterator_range.h> 
+#include <util/generic/store_policy.h> 
 #include <iterator>
 
-
+ 
 template <class TIterator, class TCondition>
 class TFilteringIterator {
 public:
@@ -19,7 +19,7 @@ public:
     TFilteringIterator(TIterator it, TIterator last, const TCondition& condition)
         : Iter(it)
         , Last(last)
-        , Condition(condition)
+        , Condition(condition) 
     {
         Grep();
     }
@@ -56,47 +56,47 @@ private:
     TCondition Condition;
 };
 
-
-template <class TContainer, class TCondition>
-class TFilteringRange {
-    using TContainerStorage = TAutoEmbedOrPtrPolicy<TContainer>;
-    using TConditionStorage = TAutoEmbedOrPtrPolicy<TCondition>;
-    using TRawIterator = decltype(std::begin(std::declval<TContainer&>()));
-    using TConditionWrapper = std::reference_wrapper<std::remove_reference_t<TCondition>>;
-public:
+ 
+template <class TContainer, class TCondition> 
+class TFilteringRange { 
+    using TContainerStorage = TAutoEmbedOrPtrPolicy<TContainer>; 
+    using TConditionStorage = TAutoEmbedOrPtrPolicy<TCondition>; 
+    using TRawIterator = decltype(std::begin(std::declval<TContainer&>())); 
+    using TConditionWrapper = std::reference_wrapper<std::remove_reference_t<TCondition>>; 
+public: 
     //TODO: make TIterator typedef private
-    using TIterator = TFilteringIterator<TRawIterator, TConditionWrapper>;
+    using TIterator = TFilteringIterator<TRawIterator, TConditionWrapper>; 
 
-    using iterator = TIterator;
-    using const_iterator = TIterator;
+    using iterator = TIterator; 
+    using const_iterator = TIterator; 
     using value_type = typename TIterator::value_type;
     using reference = typename TIterator::reference;
-
-    TFilteringRange(TContainer&& container, TCondition&& predicate)
-        : Container(std::forward<TContainer>(container))
-        , Condition(std::forward<TCondition>(predicate))
-    {}
-
-    TIterator begin() const {
-        return {std::begin(*Container.Ptr()), std::end(*Container.Ptr()), {*Condition.Ptr()}};
-    }
-
-    TIterator end() const {
-        return {std::end(*Container.Ptr()), std::end(*Container.Ptr()), {*Condition.Ptr()}};
-    }
-
-private:
-    mutable TContainerStorage Container;
-    mutable TConditionStorage Condition;
-};
-
-
+ 
+    TFilteringRange(TContainer&& container, TCondition&& predicate) 
+        : Container(std::forward<TContainer>(container)) 
+        , Condition(std::forward<TCondition>(predicate)) 
+    {} 
+ 
+    TIterator begin() const { 
+        return {std::begin(*Container.Ptr()), std::end(*Container.Ptr()), {*Condition.Ptr()}}; 
+    } 
+ 
+    TIterator end() const { 
+        return {std::end(*Container.Ptr()), std::end(*Container.Ptr()), {*Condition.Ptr()}}; 
+    } 
+ 
+private: 
+    mutable TContainerStorage Container; 
+    mutable TConditionStorage Condition; 
+}; 
+ 
+ 
 template <class TIterator, class TCondition>
 auto MakeFilteringRange(TIterator begin, TIterator end, const TCondition& condition) {
     return MakeIteratorRange(TFilteringIterator<TIterator, TCondition>(begin, end, condition), TFilteringIterator<TIterator, TCondition>(end, end, condition));
 }
 
 template <class TContainer, class TCondition>
-auto MakeFilteringRange(TContainer&& container, TCondition&& condition) {
-    return TFilteringRange<TContainer, TCondition>(std::forward<TContainer>(container), std::forward<TCondition>(condition));
+auto MakeFilteringRange(TContainer&& container, TCondition&& condition) { 
+    return TFilteringRange<TContainer, TCondition>(std::forward<TContainer>(container), std::forward<TCondition>(condition)); 
 }

Some files were not shown because too many files changed in this diff