Prebuilt number range generators?



  • I am looking for information on how to build a container "like" object that will work with std algorithm functions. Basically the container would have a begin/end set of iterators and could be set to start, end, and increment based on user supplied values.

    gen_container<int> con(1,5,1);
    

    So con would be able to be used like this:

    for(auto val: con)
        qInfo() << val;
    or
    std::for_each(con.begin(), con.end(), [](const int val){
        qInfo() << val;
    });
    

    Internally the container would not contain any data. It would only return a value based upon the iterator index up to a max range (begin != end). It would be really useful to be able to set the increment.

    Right now I am using this method:

    vector<int> iter(x);
    iota(iter.begin(), iter.end(), 0);
    

    So I use a vector as my container for now. This wastes memory and is not a good method for large ranges. Ideally it would be able to handle huge numbers without consuming memory.

    I have looked around and found a couple of articles on how to build containers:
    https://medium.com/@vgasparyan1995/how-to-write-an-stl-compatible-container-fc5b994462c6
    https://stdcxx.apache.org/doc/stdlibug/16-3.html
    These seem to have a lot of boiler plate code to them. Maybe there is no way to get around this. I was hoping there was something in boost or a template for a generic container.



  • To make both of your examples working, you just need to implement begin() and end() in your container, and returned iterator should behave like you want it to, i.e. return sequential numbers and turn into end after sequence end. No need to bother with allocators and other unrelated stuff.



  • Apparently rangev3 is going to be a standard part of c++20.

    I think I will play with this library. I hope it supports floats as well.

    Edit: Found this too.


  • Qt Champions 2018

    @fcarney I think the experimental Coroutine TS is also worth a look.

    Disclaimer: I only heard a presentation, I have not used that so far.



  • Ooh, this is interesting too. Why bother with a container when all you want is the iterator.



  • Because sometimes iterator is not enough, e.g. you cannot use range for with just iterator. You may also want to look at irange from Boost



  • @Konstantin-Tokarev said in Prebuilt number range generators?:

    you cannot use range for with just iterator

    Yeah, I was just thinking that. But that could be solved easily by slapping an object together with the iterators. It seems like the iterators are the important thing.



  • @fcarney said in Prebuilt number range generators?:

    solved easily by slapping an object together with the iterators

    class FakeContainer{
    
        boost::counting_iterator<int> m_begin;
        boost::counting_iterator<int> m_end;
    
    public:
        FakeContainer()=delete;
        FakeContainer(int start, int end)
            :m_begin(start),
             m_end(end)
        {
    
        }
    
        boost::counting_iterator<int> begin(){
            return m_begin;
        }
        boost::counting_iterator<int> end(){
            return m_end;
        }
    };
    

    Testing:

    FakeContainer fc(10,15);
        for(auto x: fc){
            qInfo() << x;
        }
    

    Output:

    10
    11
    12
    13
    14
    


  • @Konstantin-Tokarev said in Prebuilt number range generators?:

    irange

    Thanks for the irange suggestion:

        for(auto x: boost::irange(10,20)){
            qInfo() << x;
        }
    

    out:

    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.