-
Notifications
You must be signed in to change notification settings - Fork 82
Howto: Write a View
See Ranges for an explanation of what a view is.
All of these HowTos require:
- GCC >= 6 or Clang >= 3.7
- an up-to-date cone of the range-v3 git repository
- building your apps with
-std=c++14 -I/path/to/range-v3/include
- SeqAn is not required
- for Section 2 you can use
-fconcepts
and activate the respective checks
A small tutorial to write basic views as combinations/modifications of existing views. Everyone working on SeqAn3 should understand this.
std::string s{"ACGTTTATGT"};
// make reverse complement view
auto comp_view = // TODO: implement
std::cout << comp_view << '\n'; // should print [A,C,A,T,A,A,A,C,G,T]
// create infix from [1, 6)
auto comp_view_inf = // TODO: implement
std::cout << comp_view_inf << '\n'; // should print [C,A,T,A,A]
// transform back
auto orig_inf = // TODO: implement
std::cout << orig_inf << '\n'; // should print [T,T,A,T,G]
βVisit the HowToβ
std::string s{"ACGTTTATGTTTACGT"};
auto v = // TODO: implement
std::cout << v << '\n'; // should print [T,F,M,F,T,X]
βView the HowToβ
What is commonly referred to as a view, consists of multiple entities:
- the actual class (template) that meets the requirements of
view_concept
and at least alsoinput_range_concept
; by convention of the range-v3 it is calledview_foo
for the view called "foo" - a "generator class" that overloads the
()
and|
operators that facilitate the "piping" capabilities and return an instance of 1.; by convention of range-v3 it is calledfoo_fn
- an instance of the generator class that is the only actual user-facing part of the view; by convention of range-v3 it is called
foo
, in the namespaceview
, i.e.view::foo
If the view you are creating is just a combination of existing views, you may not need to implement 1. or even 2. We will cover an example below.
We want to create a view, that works on input ranges of uint64_t
and always adds the number 42
, i.e. we want the following to work:
int main()
{
std::vector<uint64_t> in{1, 4, 6, 89, 56, 45, 7};
for (auto && i : in | view::add_constant)
std::cout << i << ' ';
std::cout << '\n'; // should print: 43 47 64 131 98 87 49
// combine it with other views:
for (auto && i : in | view::add_constant | ranges::view::take(3))
std::cout << i << ' ';
std::cout << '\n'; // should print: 43 47 64
}
We will first develop a full solution and then see how we can use existing ranges to simplify this.
- A generic solution to this problem, independent of SeqAn and without using SeqAn specifics
-
The full solution with an implementation of
view_add_constant
,add_constant_fn
andview::add_constant
-
A smaller solution with an implementation of
view_add_constant
andadd_constant_fn
omitted.
Now, we will do the same as above, but this time our view will take a variable that is to be added (it could be a number other than 42, but it isn't of course):
int main()
{
std::vector<uint64_t> in{1, 4, 6, 89, 56, 45, 7};
for (auto && i : in | view::add_number(42))
std::cout << i << ' ';
std::cout << '\n'; // should print: 43 47 64 131 98 87 49
// combine it with other views:
for (auto && i : in | view::add_number(42) | ranges::view::take(3))
std::cout << i << ' ';
std::cout << '\n'; // should print: 43 47 64
}
Again, we will first develop a full solution and then see how we can use existing ranges to simplify this.
-
The full solution with an implementation of
view_add_number
,add_number_fn
andview::add_number
-
A smaller solution with an implementation of
view_add_number
omitted, but not as minimal as before (we needadd_number_fn
).