aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/iterator/README.md
diff options
context:
space:
mode:
authorpechatnov <pechatnov@yandex-team.ru>2022-02-10 16:48:57 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:48:57 +0300
commit8e9b2f8bbf4a2320f539eef5b85555f42c065425 (patch)
tree189a13fe5128c85492e45518171a532ffa90ba03 /library/cpp/iterator/README.md
parent92040fb3ad117c48c87d591bf9fe916ffda61233 (diff)
downloadydb-8e9b2f8bbf4a2320f539eef5b85555f42c065425.tar.gz
Restoring authorship annotation for <pechatnov@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'library/cpp/iterator/README.md')
-rw-r--r--library/cpp/iterator/README.md200
1 files changed, 100 insertions, 100 deletions
diff --git a/library/cpp/iterator/README.md b/library/cpp/iterator/README.md
index cd92a284c9..77f0c29b92 100644
--- a/library/cpp/iterator/README.md
+++ b/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);
+```