-
Notifications
You must be signed in to change notification settings - Fork 82
Prototypes:dna.hpp
Hannes Hauswedell edited this page Mar 6, 2017
·
4 revisions
#pragma once
#include "../alphabet.hpp"
namespace seqan3
{
struct dna
{
char value;
// Rule-of-five
dna() = default;
constexpr dna(dna const &) = default;
constexpr dna(dna &&) = default;
constexpr dna & operator =(dna const &) = default;
constexpr dna & operator =(dna &&) = default;
// implicit compatibility to char
constexpr dna(char const c) :
value{convert(c)}
{}
constexpr dna & operator =(char const c)
{
value = convert(c);
return *this;
}
constexpr operator char() const
{
return value;
}
// conversion tables
static constexpr uint8_t value_size{4};
static constexpr char rank_to_value[value_size]
{
'A',
'C',
'G',
'T'
};
static constexpr uint8_t value_to_rank[256]
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //1
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //2
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //3
0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, //4
// , A, B, C, D, E, D, G, H, I, J, K, L, M, N, O,
0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //5
// P, Q, R, S, T, U, V, W, X, Y, Z, , , , ,
0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, //6
// , a, b, c, d, e, f, g, h, i, j, k, l, m, n, o,
0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //7
// p, q, r, s, t, u, v, w, x, y, z, , , , ,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //8
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //9
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //10
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //11
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //12
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //13
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //14
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 //15
};
// TODO is this slower than making another table?
static constexpr char convert(char const c)
{
return rank_to_value[value_to_rank[c]];
}
};
// shall fulfill Alphabet concept
static_assert(alphabet_concept<dna>);
static_assert(static_cast<char>(dna{'A'}) == 'A');
static_assert(dna{'A'} == 'A');
static_assert(dna{'N'} == dna{'A'});
static_assert(dna{'A'} < dna{'C'});
}
- should we have the enum at all?
- if yes, should the base type be the enum?
- or do we want to use a strongly typed enum instead of the char constructor?
- if yes, we need to keep in mind that this always implies another scope, makes it harder to read
#pragma once
#include <iostream>
#include <string>
#include <vector>
#include "../alphabet.hpp"
#include "../alphabet_container.hpp"
#include "dna4.hpp"
// ------------------------------------------------------------------
// traits
// ------------------------------------------------------------------
namespace std
{
template<>
struct char_traits<seqan3::dna> : seqan3::alphabet_traits<seqan3::dna>
{
};
//TODO regex traits
} // namespace std
// ------------------------------------------------------------------
// containers
// ------------------------------------------------------------------
namespace seqan3
{
using dna_string = std::basic_string<dna, std::char_traits<dna>>;
using dna_vector = std::vector<dna>;
} // namespace seqan3
// ------------------------------------------------------------------
// literals
// -----------------------------------------------------------------
namespace seqan3::literal
{
inline dna_string operator "" _dna(const char * s, std::size_t n)
{
dna_string r;
r.resize(n);
std::transform(s, s + n, r.begin(), [] (const char & c)
{
return dna{c};
});
return r;
}
} // namespace seqan3::literal