Skip to content

HowTo write a View add constant_full

Hannes Hauswedell edited this page Feb 13, 2018 · 18 revisions

view_add_constant

We start with the first part of the implementation:

#include <range/v3/all.hpp>
#include <iostream>

template <typename irng_t>
    requires /*input_range_concept<irng_t> &&*/
             std::is_same_v<std::decay_t<ranges::range_reference_t<irng_t>>, uint64_t>
class view_add_constant
{
private:
    /* data members == "the state" */
    irng_t const & irange;

    /* the iterator type */
    struct iterator_t : ranges::iterator_t<irng_t const>
    {
        using base = ranges::iterator_t<irng_t const>;

        iterator_t(base const & b) : base{b} {}

        uint64_t operator*() const
        {
            return *static_cast<base>(*this) + 42;
        }
    };
  • For convenience we have included all of range-v3; in production code, you will want to actually select your required headers
  • view_add_constant is a class template, because it needs to hold a reference to the original range it operates on; this range's type is passed in a as template parameter on which we enforce certain constraints. The most basic constraint is to enforce that it actually is an input range (we have commented this out for demonstration purposed, because the concept is not yet available in ranges – it is available in SeqAn, though, so if you write code in SeqAn, do check this!). The second constraint is that the input range is actually a range over uint64_t (possibly with reference or const).
  • It is important to remember that we always deal with the range_reference_t (not the range_value_t) as dereferencing an iterator or calling [] on a range returns something of the range_reference_t not the range_value_t (there reference type may or may not actually contain a &).
  • Please note that these constraints are specific to the view we are just creating. Other views will have different requirements on the reference type or even the range itself (e.g. it could be required to be a random_access_sequence_concept).
  • The only data member we have is the reference to original range. Since we know that we do not want to change the original values, i.e. we have a read-only view, we save a irng_t const & irange. Other views may very well want to expose the underlying range to modification, you would then have irng_t && irange member.
  • Next we define an iterator type. Since view_add_constant needs to satisfy basic range requirements, you need to be able to iterate over it. In our case we can stay close to the original and inherit from the original iterator. We are only overloading one operation: the dereference operation, i.e. actually getting the value. This is the place where we interject and add the constant 42. Note that this changes the return type of the operation (reference_t); it used to be uint64_t &
Clone this wiki locally