Refactor the API (possibly adding overhead) to fix a corner case
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 25/100
- Loại issue
- Tái cấu trúc
- Độ rõ ràng
- Khá rõ ràng
- Mức độ hoạt động
- Đình trệ
- Công nghệ
- cpp
- Lĩnh vực
- backend-api-design
Hướng nghiên cứu
Bắt đầu với các API push_type và pull_type của boost::coroutines2::coroutine, đặc biệt là begin(), operator(), các thao tác trên iterator và đối tượng tương ứng do framework tạo ra được mô tả trong issue. So sánh các bảng vòng đời hiện tại và được hình dung, sau đó xác định hành vi đối với phạm vi rỗng và giá trị cuối; issue không nêu tên tệp nguồn hay test nào, vì vậy việc xác định các điểm vào đó là một phần của công việc.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
According to the documentation:
- push_type does not enter coroutine-function on construction;
- the first call of push_type::operator() synthesizes a complementary pull_type and passes it as reference to coroutine-function
But what happens if:
push_type coro([](pull_type&){ return; });- the user finds that
bool(coro) == true(or:begin(coro) != end(coro)) so the user would like to performcoro(value_of_T)(or:*begin(coro) = value_of_T)
It seems the value will be lost.
The problem is: you don't know whether an output range is empty unless you push a value to it first.
(Edit: sorry for the mistake, it's the last value that will always be lost if the output range is not infinite.)
#include<boost/coroutine2/all.hpp>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<utility>
int main()
{
typedef boost::coroutines2::coroutine<std::string> coro_t;
struct FinalEOL {
~FinalEOL() {
std::cout << std::endl;
}
};
const int num = 5, width = 15;
coro_t::push_type writer(
[&](coro_t::pull_type& in) {
//// finish the last line when we leave by whatever means
//FinalEOL eol;
// pull values from upstream, lay them out 'num' to a line
//for (;;) {
// for (int i = 0; i < num; ++i) {
// // when we exhaust the input, stop
// if (!in) return;
// std::cout << std::setw(width) << in.get();
// // now that we've handled this item, advance to next
// in();
// }
// // after 'num' items, line break
// std::cout << std::endl;
//}
});
std::vector<std::string> words{
"peas", "porridge", "hot", "peas",
"porridge", "cold", "peas", "porridge",
"in", "the", "pot", "nine",
"days", "old" };
//std::copy(begin(words), end(words), begin(writer));
// safe version of std::copy that takes care of end(dest)
auto [words_it, writer_it] = std::pair{ begin(words),begin(writer) };
for (; words_it != end(words) && writer_it != end(writer); ++words_it, ++writer_it)
{
*writer_it = *words_it;
}
// print remaining words; the first word is lost
for (; words_it != end(words); ++words_it)
{
std::cout << *words_it << "\t";
}
}
An applicable approach would be to resume the coroutine in begin(coro) like https://github.com/lewissbaker/cppcoro#generatort .
Here is the current API and the imagined API:
current API:
| pull_type | framework-generated push_type for pull_type | push_type | framework-generated pull_type for push_type | |
|---|---|---|---|---|
| constructor | enter coroutine-function | |||
| operator() iterator::operator++() |
resume coroutine-function | suspend coroutine-function | ||
| get() | transfer data | transfer data | ||
| operator() iterator::operator=() |
transfer data, suspend coroutine-function | (first time: transfer data, enter coroutine-function) transfer data, resume coroutine-function |
imagined API:
| pull_type | framework-generated push_type for pull_type | push_type | framework-generated pull_type for push_type | |
|---|---|---|---|---|
| constructor | ||||
| start() begin(coro) |
①enter coroutine-function | ② | ⒈enter coroutine-function | ⒉suspend coroutine-function |
| advance() iterator::operator++() |
⑥⑩resume coroutine-function | ④⑧suspend coroutine-function | ⒋⒏resume coroutine-function | ⒍⒑suspend coroutine-function |
| get() | ⑤⑨transfer data | ⒌⒐transfer data | ||
| set() iterator::operator=() |
③⑦transfer data | ⒊⒎transfer data |
Note that in the column of push_type: if after ⒊transfer data instead of ⒋resume coroutine-function you ⒋abandon the coroutine, then the value_of_T will still be lost. But this time it is the user of API to blame, not the framework.
These are what you can do:
| utility | current API | imagined API |
|---|---|---|
merge pipe and source into sourcevoid(pull_type<T1>,push_type<T2>) + pull_type<T1> -> pull_type<T2> |
trivial for loop | trivial for loop |
merge pipe and source into sourceT2(T1) + pull_type<T1> -> pull_type<T2> |
trivial for loop | trivial for loop |
merge pipe and sink into sinkvoid(pull_type<T1>,push_type<T2>) + push_type<T2> -> push_type<T1> |
trivial for loop | trivial for loop |
merge pipe and sink into sinkT2(T1) + push_type<T2> -> push_type<T1> |
trivial for loop | trivial for loop |
merge source and sink and stops when either one exhaustsstd::pair<source_it_t, sink_it_t> safe_copy(source_begin, source_end, sink_begin, sink_end) |
the first value of source will be lost if sink is an empty range | trivial for loop the user will not lose the first value of source because if sink is an empty range then we have begin(sink) == end(sink) after construction and start()/begin(sink) |
- Ngôn ngữ chính
- C++
- Star
- 139
- Fork
- 44
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Chuẩn bị môi trường
Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của boostorg/coroutine2
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 50/100
boostorg/coroutine2#54 ·
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 25/100
boostorg/coroutine2#53 ·
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 20/100
boostorg/coroutine2#49 ·
Tất cả issue của boostorg/coroutine2
Issue tương tự
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 91/100
FujiNetWIFI/fujinet-firmware#2045 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
(S1 - Need confirmation)
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
CleverRaven/Cataclysm-DDA#89159 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
area:libnvmpi bug P3
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
gjrtimmer/jetson-nvmpi#33 ·
-
bug(wasi_crypto): ArrayOutput::pull reports the wrong all-pulled flagCó thể đã có người làm @Yashbhu đã nhận hôm nay. Đang mở
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 84/100
Maintainer thường phản hồi trong vòng 1 ngày
-
bug question
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 62/100