Skip to content

Prototypes:dna.hpp

Hannes Hauswedell edited this page Feb 1, 2017 · 4 revisions

dna.hpp

#pragma once

#include "alphabet.hpp"

namespace seqan3
{

struct dna
{
    using inner_type = uint8_t;

    enum val : inner_type
    {
        A,
        C,
        G,
        T,
        UNKNOWN = A
    };

    inner_type 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;

    // compatibility to char TODO explicit or implicit?
    constexpr dna(char const c) :
        value{char_to_value[static_cast<inner_type>(c)]}
    {}

    constexpr dna & operator=(char const c)
    {
        value = char_to_value[static_cast<inner_type>(c)];
    }

    explicit constexpr operator char() const
    {
        return value_to_char[value];
    }

    // conversion tables
    static constexpr uint8_t value_size{4};

    static constexpr char value_to_char[value_size]
    {
        'A',
        'C',
        'G',
        'T'
    };

    static constexpr val char_to_value[256]
    {
         // similar to https://github.com/seqan/seqan/blob/master/include/seqan/basic/alphabet_residue_tabs.h#L76
         // possibly with enum values instead
    };

    /* comparison operators */
    constexpr bool operator ==(dna const & rhs) const noexcept
    {
        return value == rhs.value;
    }

    constexpr bool operator !=(dna const & rhs) const noexcept
    {
        return value != rhs.value;
    }

    constexpr bool operator <(dna const & rhs) const noexcept
    {
        return value < rhs.value;
    }

    constexpr bool operator >(dna const & rhs) const noexcept
    {
        return value > rhs.value;
    }

    constexpr bool operator <=(dna const & rhs) const noexcept
    {
        return value <= rhs.value;
    }

    constexpr bool operator >=(dna const & rhs) const noexcept
    {
        return value >= rhs.value;
    }
};

// shall fulfill Alphabet concept
static_assert(Alphabet<dna>);
static_assert(dna{'A'} == dna{});
static_assert(static_cast<char>(dna{'A'}) == 'A');
static_assert(dna{'A'} == '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
Clone this wiki locally