0

I have class Range which holds a interval like <2,10> or <-50,900> and than I have RangeList and I want to have vector<long long> which represents multiple ranges. I don't need to have vector<Range> for some purpose.

But i want to make iterator that will go through ranges and it will retrun Range. Is it possible to define custom iterator that will work like that?

   class Range {
        long long lo;
        long long hi;
    }

    class RangeList {
    vector<long long> ranges;

    }

example

ranges={1, 50, 200, 700, 900, 1000};

so iterator will go through and it would return

first iteration

Range <1,50>

secondi teration

Range <200,700>

third teration

Range <900,100>

Thanks for any advice

  • 1
    Yes it's possible ;-) – Gojita Mar 25 '19 at 10:03
  • 1
    How about: `boost::tranform_iterator` [link](https://www.boost.org/doc/libs/1_66_0/libs/iterator/doc/html/iterator/specialized/transform.html)? – paler123 Mar 25 '19 at 10:05
  • 1
    It is possible but perhaps counterproductive. https://stackoverflow.com/questions/3582608/how-to-correctly-implement-custom-iterators-and-const-iterators – n. m. could be an AI Mar 25 '19 at 10:05
  • 1
    *Why* don't you want a `vector`? I'd be tempted to have `using Ranges = std::vector;`, and sidestep `RangeList` – Caleth Mar 25 '19 at 10:26
  • Ok thanks for your help, I will do it as you sa in vector, I am not allowed to use boost, but you are right :) thanks guys – StykPohlavsson Mar 25 '19 at 10:35
  • @StykPohlavsson: The Boost license is about as permissive as StackOverflow. If you're working in an environment that bans all outside code, you probably shouldn't be asking here. – MSalters Mar 25 '19 at 11:15

1 Answers1

1

I think i'd be a little more specific as I don't like to infer pairs from a sequential list of values (what happens if there's an odd number of values?)

#include <vector>
#include <iostream>

template<class Integer>
struct InclusiveRangeIter
{
    using iterator_category = std::forward_iterator_tag;
    using value_type = Integer;
    using reference = value_type&;
    using pointer = value_type*;
    using difference_type = Integer;

    constexpr InclusiveRangeIter(Integer current)
    : value_(current)
    {}

    constexpr bool operator==(InclusiveRangeIter const& other) const { return value_ == other.value_; }
    constexpr bool operator!=(InclusiveRangeIter const& other) const { return value_ != other.value_; }
    value_type operator*() const { return value_; }
    auto operator++() -> InclusiveRangeIter& { ++value_; return *this; }
    auto operator++(int) -> InclusiveRangeIter { auto copy = *this; ++value_; return copy; }


    Integer value_;
};

struct InclusiveRange 
{
    long long lo;
    long long hi;

    auto begin() const { return InclusiveRangeIter(lo); }
    auto end() const { return InclusiveRangeIter(hi + 1); }
};

int main()
{
    auto ranges = std::vector<InclusiveRange>
    {
        {1, 50}, {200, 700}, {900, 1000}
    };

    for (auto&& ir : ranges)
    {
        auto sep = false;
        for (auto&& v : ir)
        {
            if (sep) std::cout << ", ";
            std::cout << v;
            sep = true;
        }
        std::cout << '\n';
    }
}

https://coliru.stacked-crooked.com/a/2804de3d85ba4f0b

Richard Hodges
  • 68,278
  • 7
  • 90
  • 142