Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

Refactor the API (possibly adding overhead) to fix a corner case

Đang mở
#37 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

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:

  1. push_type does not enter coroutine-function on construction;
  2. 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 perform coro(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 source
void(pull_type<T1>,push_type<T2>) + pull_type<T1> -> pull_type<T2>
trivial for loop trivial for loop
merge pipe and source into source
T2(T1) + pull_type<T1> -> pull_type<T2>
trivial for loop trivial for loop
merge pipe and sink into sink
void(pull_type<T1>,push_type<T2>) + push_type<T2> -> push_type<T1>
trivial for loop trivial for loop
merge pipe and sink into sink
T2(T1) + push_type<T2> -> push_type<T1>
trivial for loop trivial for loop
merge source and sink and stops when either one exhausts
std::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

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. 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.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của boostorg/coroutine2

Tất cả issue của boostorg/coroutine2

Issue tương tự

Thêm issue về C++

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.