On 10/30/2012 12:50 PM, David Kimmel wrote:
I tried it out, yes you can get make_iterator_range with next to work. I like boost::next but for what I wanted it does not seem to work appropriately. Your example of "make_iterator_range(boost::next(b.begin, wSize), v.end())" will only skip the first "wSize" elements. What I want is a range that contains at most wSize elements (if possible) - taking them from after (and containing) a start index.
Even my second attempt with this approach (commented out lines) does not work because next does not check to see if it is past end. Perhaps if there is a "min" method I could pass the "boost::next(v.begin() + (start-1), window)" and "v.end()".
typedef vector<int> Vector; Vector v = { 1, 2, 3, 4, 5, 6, 7, 8 , 9, 10, 11 };
cout << "--" << endl; for(auto i : v) { cout << i << " "; } cout << "\n--\n" << endl;
const int start = 10; const int window = 4;
auto r = boost::make_iterator_range(boost::next(v.begin(), start-1), v.end()); auto r2 = boost::make_iterator_range(boost::prior(r.end(), window), r.end());
//auto r = boost::make_iterator_range(v.begin() + (start-1), boost::next(v.begin() + (start-1), window) ); //auto r2 = boost::make_iterator_range(boost::prior(r.end(), window), r.end());
cout << "\n--\nr: "; for(auto i : r) { cout << i << " "; }
cout << "\n--\nr2: "; for(auto i : r2) { cout << i << " "; }
cout << "\n--\n" << endl;
Our application has lots of this type of index/range manipulation. So much in fact it was worth factoring out a open/closed integer range interval class(similar to boost ICL's): class Interval { public: static Interval makeInclusive(int first, int last); static Interval makeExclusive(int begin, int end); static Interval makeInclusiveNormalized(int val1, int val2); static Interval makeExclusiveNormalized(int val1, int val2); static Interval makeSized(int begin, int size); template<class CONTAINER> static Interval makeSized(const CONTAINER& c) { return makeSized(0, c.size()); } int indexBegin() const { return m_begin; } int indexEnd () const { return m_end; } bool empty() const { return m_end == m_begin; } std::size_t size() const { return m_end - m_begin; } ... }; Interval intersection(const Interval& lhs, const Interval& rhs); ... This separates the index math from the final range traversal while providing higher level expression of the intent. Then we can construct a boost::adaptors::sliced using: inline boost::adaptors::sliced slicedFrom(const Interval& i) { return boost::adaptors::sliced(i.indexBegin(), i.indexEnd()); } and use it: int main() { std::vector<float> v(42); Interval vi = Interval::makeSized(v); Interval i = Interval::makeExclusive(37, 93); boost::fill(v | slicedFrom(intersection(vi, i)), 123.456f); return 0; } Jeff