Skip to content

Prototypes:dna.hpp

Hannes Hauswedell edited this page Mar 6, 2017 · 4 revisions

dna.hpp

#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'});

}

Open questions

  • 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

dna4_container.hpp

#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
Clone this wiki locally