#pragma once #include namespace ir { template struct range { using iterator = IterT; using value_type = typename std::iterator_traits::value_type; using reference = typename std::iterator_traits::reference; private: iterator b; iterator e; public: explicit range(iterator b, iterator e) : b(b), e(e) {} iterator begin() { return b; } iterator end() { return e; } iterator begin() const { return b; } iterator end() const { return e; } auto size() const { return std::distance(b, e); } auto empty() const { return b == e; } }; //! create `range` object from iterator pair [begin, end) template range make_range(IterT b, IterT e) { return range(b, e); } //! create `range` object from a container who has `begin()` and `end()` methods template range make_range(ContainerT &c) { return make_range(c.begin(), c.end()); } //! create `range` object from a container who has `begin()` and `end()` methods template range make_range(const ContainerT &c) { return make_range(c.begin(), c.end()); } } // namespace ir