Поправьте меня, если я ошибаюсь, но по-моему происходящее не имеет вообще никакого отношения к разбирательству по поводу авторских прав на Nginx. Потому что такое разбирательство должно идти через суд в гражданско-правовом порядке, да и происходить оно должно в США, где и зарегистрирована компания Nginx. Т. е. независимо от результата уголовного дела никому никакие права не переидут, а Рамблеру ничего не достанется. Единственное, что может быть результатом этого дела — это посадка Сысоева и его компаньонов. Судя по всему, силовики просто выбивают деньги из Сысоева, которых у него теперь много. А Рамблер тут вообще даже и ни при чем, они просто соучастники, возможно даже невольные.
Так в том то и дело, что код итераторов — он только кажется тупым, а на самом деле он довольно сложен. Начать с того, что надо определить, каким требованиям будет соответствовать возвращаемый итератор. А после этого аккуратно реализовать все требуемые операции. В реальности это обычно встречается только в библиотеках, а в прикладном коде почти никогда, потому что сильно сложно и муторно. Ranges решают эту проблему. Использовать их для таких вещей в прикладном коде очень просто.
Тут нет заказчиков, исполнителей, ТЗ, и прочего. Тут есть обсуждение ranges и для чего они нужны. Я надеюсь теперь стало понятно, что имелось в изначальном тексте.
Ну т. е. мы пришли к пониманию, что задача определения собственных итераторов даже для таких простых вещей, как добавление const, довольно трудна и занимает десятки строк кода?
Ну т. е., помимо формулировки задачи, вы же понимаете, что ваше решение приведет к тому, что рано или поздно пользователи вашего класса наткнуться на то, что хотя бы вот такой простой код не будет работать, хотя все ожидают, что он должен работать:
for (auto it = storage.begin(), end = storage.end(); it != end; it++) {
}
А еще на вашем итераторе не будут работать такие базовые вещи, как например std::advance, что тоже вызовет мягко говоря удивление у пользователей.
Там вообще-то есть специальное уточнение: «Т. е. вернуть пару итераторов,...». Ваш класс не является итератором в терминологии STL. С таким же успехом можно было бы добавить метод «const SomeObject* object_at_index(size_t i) const» и считать, что задача выполнена.
Да тут собственно хоть используй оператор, хоть не используй, все равно ничего не понятно будет, если читающий не понимает что такое ranges и как они используются. От того, что будет «return ranges::view::transform(objects_, fn);» ничего принципиально не изменится. С итераторами на самом деле все точно так же: не понимая концепции итераторов код понять практически невозможно.
range — это по сути пара итераторов, begin и end. Итератор в C++17 может сам по себе иметь индексированный доступ. Плюс есть еще sized range — это range, для которого еще определена операция size, для получения размера с константной сложностью.
Ваш итератор не будет работать со стандартными алгоритмами. Вот такое не будет компилироваться:
auto res = std::find_if(storage.begin(), storage.end(), [](auto && ptr) { return ptr->x == 20; });
А еще ваш итератор удовлетворяет критериям только ForwardIterator, но не BidirectionalIterator или RandomAccessIterator, т. е. будет работать только с частью алгоритмов (когда вы сделаете его пригодным для использования с алгоритмами), а с некоторыми алгоритмами будет работать медленнее, чем можно было бы.
«Общее правило: код — который генерируется в процессе разработки, тестирования, сборки/компиляции, рантайма — должен находиться в gitignore»
Хорошее общее правило: код, который генерируется в процессе разработки, тестирования, сборки, компиляции и запуска, должен находиться в каталоге сборке, который лежит отдельно от каталога с исходным кодом. Генерировать что-то внутри каталога с исходным кодом, а тем более класть туда результаты сборки — это плохой стиль.
Вы меня конечно извините, но в решении первой задачи что это за непонятная последовательность значений с нигде не определенным символом V, разделенная знаком <=> (равносильно)? Ну и как бы «нетрудно понять, что это 0» — это не совсем формально. =)
Я бы предложил улучшить ваш код следующим образом. Можно попробовать расположить данные в виде Struct Of Arrays, но писать код так, как будто у вас Array of Structs. Для этого с фигурами надо работать через специальный wrapper, который будет получать данные из массивов. Интересно было бы замерить производительность такой версии, по идее она должна быть такой же, как и версии с прямым доступам к массивам. Выглядеть это будет примерно так:
class ShapeRef;
struct ShapesData {
friend class ShapeRef;
public:
ShapeRef getShape(size_t i);
private:
// векторы данных будут закрытыми
std::vector<math::Vec2> positions;
...
};
class ShapeRef {
public:
ShapeRef(ShapesData & d, size_t i):
data{d}, index{i} {}
const math::Vec2 & getPosition() const {
return data.positions[index];
}
void setPosition(const math::Vec2 & pos) {
data.positions[index] = pos;
}
// методы для доступа к остальным данным фигур
private:
ShapesData & data;
size_t index;
};
inline ShapeRef ShapesData::getShape(size_t i) {
return ShapeRef(*this, i);
}
Судя по всему, «заблокировано» только имя хоста, и некоторые провайдеры просто выдают неверный IP для имени s3.amazonaws.com, по крайней мере это происходит у новосибирского «Электронного города» («Новотелеком», работает через ТТК вроде бы). Проблема решается использованием публичных DNS серверов (например гугловского 8.8.8.8) вместо DNS серверов провайдеров. Правильный IP: 54.231.81.91
Извините, но с вами невозможно вести конструктивную дискуссию. Вы не в состоянии ответить на конкретный вопрос и теряете нить дискуссии, при это от меня еще требуете ответов на ваши простыни, не относящиеся к обсуждаемому вопросу. Всего хорошего. Я честно пытался.
Враньё. Речь шла обо всём, а тот факт, что я обобщил stl до всей libc++ — это не моё допущение, а автора комментария.
Еще раз. Какое именно использование glibc внутри STL вы имели ввиду, когда говорили «не более, чем генерик-интерфейсом к glibc»? В предыдущем своем посте вы сказали, что это относилось только к строкам и стримам. Теперь опять появилось «речь шла обо всем». Вы путаетесь в показаниях.
Строка определяется операциями, из которых все(которые пахнут оптимизацией) являются обёртками над string/mem/io из либц.
Ну вот, оказалось, что «строки являются оберткой над glibc» превращается в «операции конверсии строк в числа являются обертками над glibc». Ну здравствуйте, капитан очевидность. И сразу все высказывание теряет значимость, потому что очевидно всем и ни на что не влияет.
Ага, отлично, значит речь шла о строках и стримах.
Во-первых, что же там такое в этих строках libstdc++ используется из glibc, что вы их называете «не более, чем генерик-интерфейсом к glibc»?
Во-вторых, вместо того, чтобы просто дать конкретный ответ вроде «извините, со всей libstdc++ я погорячился, я имел в виду только что строки и стримы явзяются генерик-интерфейсом к glibc», вы выкатили какую-то просто невероятную простыню из потока сознания про какую-то генеральную линию партии. За это и минусы.
Вам ставят минусы и никто не отвечает, потому что вы несете какой-то откровенный бред из лозунгов. Вот например: «Возьмём гццешную стл(одно из самых, если не самая) — является не более, чем генерик-интерфейсом к glibc». Основная часть STL — это стандартные контейнеры и алгоритмы. О каком использовании glibc в них вы вообще говорите?
А еще на вашем итераторе не будут работать такие базовые вещи, как например std::advance, что тоже вызовет мягко говоря удивление у пользователей.
А еще ваш итератор удовлетворяет критериям только ForwardIterator, но не BidirectionalIterator или RandomAccessIterator, т. е. будет работать только с частью алгоритмов (когда вы сделаете его пригодным для использования с алгоритмами), а с некоторыми алгоритмами будет работать медленнее, чем можно было бы.
Хорошее общее правило: код, который генерируется в процессе разработки, тестирования, сборки, компиляции и запуска, должен находиться в каталоге сборке, который лежит отдельно от каталога с исходным кодом. Генерировать что-то внутри каталога с исходным кодом, а тем более класть туда результаты сборки — это плохой стиль.
Еще раз. Какое именно использование glibc внутри STL вы имели ввиду, когда говорили «не более, чем генерик-интерфейсом к glibc»? В предыдущем своем посте вы сказали, что это относилось только к строкам и стримам. Теперь опять появилось «речь шла обо всем». Вы путаетесь в показаниях.
Ну вот, оказалось, что «строки являются оберткой над glibc» превращается в «операции конверсии строк в числа являются обертками над glibc». Ну здравствуйте, капитан очевидность. И сразу все высказывание теряет значимость, потому что очевидно всем и ни на что не влияет.
Во-первых, что же там такое в этих строках libstdc++ используется из glibc, что вы их называете «не более, чем генерик-интерфейсом к glibc»?
Во-вторых, вместо того, чтобы просто дать конкретный ответ вроде «извините, со всей libstdc++ я погорячился, я имел в виду только что строки и стримы явзяются генерик-интерфейсом к glibc», вы выкатили какую-то просто невероятную простыню из потока сознания про какую-то генеральную линию партии. За это и минусы.