File: semialphabet_any.cpp

package info (click to toggle)
seqan3 3.2.0%2Bds-6%2Bdeb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 19,776 kB
  • sloc: cpp: 159,121; makefile: 1,290; sh: 414; ansic: 321; xml: 229; javascript: 98; perl: 29; python: 27; php: 25
file content (82 lines) | stat: -rw-r--r-- 3,362 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// This example illustrates how we can reduce the usage of templates (or the amount of different instantiations) via
// type erasure. Having only one function generated for `algorithm()` is the only benefit of using `semialphabet_any`
// here. Of course this only makes sense for your application if the part of the program that is agnostic of the
// character representation (your equivalent of `algorithm()`) is substantially larger than the specific parts – and
// if compile-time and/or size of the exectuble are a concern.

#include <iostream>

#include <seqan3/alphabet/aminoacid/all.hpp>
#include <seqan3/alphabet/composite/semialphabet_any.hpp>
#include <seqan3/core/debug_stream.hpp>
#include <seqan3/utility/range/to.hpp>

using namespace seqan3::literals;

// Print is a template and gets instantiated two times because the behaviour is different for both types
template <typename rng_t>
void print(rng_t && r)
{
    seqan3::debug_stream << r << '\n';
}

// Algorithm is not a template, only one instance is generated by the compiler
// Type information is encoded via a run-time parameter
void algorithm(std::vector<seqan3::semialphabet_any<10>> & r, bool is_murphy)
{
    // Algorithm example that replaces rank 0 with rank 1
    for (auto & v : r)
        if (seqan3::to_rank(v) == 0)
            seqan3::assign_rank_to(1, v);

    // Here we reify the type for printing
    if (is_murphy)
        print(r
              | std::views::transform(
                  [](auto const & in)
                  {
                      return static_cast<seqan3::aa10murphy>(in);
                  }));
    else
        print(r
              | std::views::transform(
                  [](auto const & in)
                  {
                      return static_cast<seqan3::aa10li>(in);
                  }));
}

// Two instances of algo_pre exist
// They type erase the different arguments to the same type and encode the type information as a run-time parameter
void algo_pre(seqan3::aa10li_vector const & v)
{
    std::vector<seqan3::semialphabet_any<10>> tmp = v
                                                  | std::views::transform(
                                                        [](auto const & in)
                                                        {
                                                            return static_cast<seqan3::semialphabet_any<10>>(in);
                                                        })
                                                  | seqan3::ranges::to<std::vector>();
    algorithm(tmp, false);
}

void algo_pre(seqan3::aa10murphy_vector const & v)
{
    std::vector<seqan3::semialphabet_any<10>> tmp = v
                                                  | std::views::transform(
                                                        [](auto const & in)
                                                        {
                                                            return static_cast<seqan3::semialphabet_any<10>>(in);
                                                        })
                                                  | seqan3::ranges::to<std::vector>();
    algorithm(tmp, true);
}

int main()
{
    seqan3::aa10li_vector v1{"AVRSTXOUB"_aa10li};
    algo_pre(v1); // BIKBBBKCB

    seqan3::aa10murphy_vector v2{"AVRSTXOUB"_aa10murphy};
    algo_pre(v2); // BIKSSSKCB
}