Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are there const overloads of mutating Boost.Range algorithms?

The documentation (and the implementation) of Boost.Range shows overloads of the mutating algorithms that take const refs as arguments. For instance Boost.Range's Sort documentation shows:

template<class RandomAccessRange>
RandomAccessRange& sort(RandomAccessRange& rng);

template<class RandomAccessRange>
const RandomAccessRange& sort(const RandomAccessRange& rng);

template<class RandomAccessRange, class BinaryPredicate>
RandomAccessRange& sort(RandomAccessRange& rng, BinaryPredicate pred);

template<class RandomAccessRange, class BinaryPredicate>
const RandomAccessRange& sort(const RandomAccessRange& rng, BinaryPredicate pred);

What is the point of overloads 2 and 4? Sure it's nice to be able to pass temporaries, but then const& makes this point kinda of moot. Rvalue-references would be most welcome, but it is my understanding that their support in Boost.Range is too invasive, and is "deferred" to the adoption of Range.V3 (it would be nice if meanwhile it were part of Boost).

like image 498
akim Avatar asked May 30 '17 14:05

akim


1 Answers

template<class T>
struct span_t {
  T* b =0;
  T* e =0;
  T* begin() const { return b; }
  T* end() const { return e; }
  std::size_t size() const { return end()-begin(); }
  bool empty() const { return size()==0; }
  T& operator[](std::size_t i) const { return b[i]; }
  span_t()=default;
  span_t(span_t const&)=default;
  span_t& operator=(span_t const&)=default;
  span_t( T* s, T* f ):b(s),e(f) {}
  span_t( T* s, std::size_t l):span_t(s, s+l) {}
};

This is a (practical and useful) random access range.

All of its methods (except operator=) are const. You can sort it.

Not all ranges propogate const from the range to the elements in the range.

like image 67
Yakk - Adam Nevraumont Avatar answered Sep 23 '22 03:09

Yakk - Adam Nevraumont