Skip to content

Prototypes:alphabet.hpp

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

alphabet.hpp:

#pragma once

#include <iostream>
#include <string>

namespace seqan3
{

// ------------------------------------------------------------------
// concept
// ------------------------------------------------------------------

template <typename t>
concept bool alphabet_concept = requires (t v1, t v2)
{
    // StL concepts
    requires std::is_pod_v<t> == true;
    requires std::is_swappable_v<t> == true;

    // actual data member
    v1.value;
    requires std::is_same_v<decltype(v1.value), char> == true;

    // required static members //tODO more details
    t::value_size;
    t::rank_to_value;
    t::value_to_rank;
//     t::convert(char const) -> char;

    // conversion from/to char
    //tODO

    // required comparison operators
    { v1 == v2 } -> bool;
    { v1 != v2 } -> bool;
    { v1 <  v2 } -> bool;
    { v1 >  v2 } -> bool;
    { v1 <= v2 } -> bool;
    { v1 >= v2 } -> bool;
};

} // namespace seqan3

alphabet_container.hpp:

#pragma once

#include <algorithm>
#include <iostream>
#include <string>

#include "alphabet.hpp"

namespace seqan3
{

// ------------------------------------------------------------------
// alphabet_traits
// ------------------------------------------------------------------

template <alphabet_concept alphabet_type>
struct alphabet_traits : public std::char_traits<char>
{
    using char_type = alphabet_type;
    using int_type = uint8_t;
    using off_type = std::streamoff;
    using pos_type = std::streampos;
    using state_type = std::mbstate_t;

    static constexpr void assign(char_type & r, char_type const & a) noexcept
    {
        r.value = a.value;
    }
    static char_type* assign(char_type * p, std::size_t count, char_type a)
    {
        std::for_each(p, p + count, [&a] (char_type & c) { c.value = a.value; });
        return p;
    }

    static constexpr bool eq(char_type a, char_type b) noexcept
    {
        return a == b;
    };

    static constexpr bool lt(char_type a, char_type b) noexcept
    {
        return a < b;
    };

    static char_type* move(char_type * dest, const char_type* src, std::size_t count)
    {
        for (std::size_t i = 0; i < count; ++i)
            assign(dest[i], src[i]);

        return dest;
    }

    static char_type* copy(char_type * dest, const char_type* src, std::size_t count)
    {
        std::copy(src, src + count, dest);
        return dest;
    }

    static constexpr int compare(const char_type* s1, const char_type* s2, std::size_t count)
    {
        for (std::size_t i = 0; i < count; ++i)
        {
            if (s1[i] < s2[i])
                return -1;
            if (s1[i] > s2[i])
                return 1;
        }
        return 0;
    }

    static constexpr std::size_t length(const char_type* s)
    {
        for (std::size_t i = 0; true; ++i)
            if (s[i] == 0)
                return i;
    }

    static constexpr const char_type* find(const char_type* p, std::size_t count, char_type const & ch)
    {
        for (std::size_t i = 0; i < count; ++i)
            if (p[i] == ch)
                return p[i];
    }

    static constexpr char_type to_char_type(int_type i) noexcept
    {
        return char_type::rank_to_value(i);
    }

    static constexpr int_type to_int_type(char_type c) noexcept
    {
        return char_type::value_to_rank(c);
    }

    static constexpr bool eq_int_type(int_type i1, int_type i2) noexcept
    {
        return i1 == i2;
    }

    static constexpr int_type eof() noexcept
    {
        return 0;
    }

    static constexpr int_type not_eof(int_type i) noexcept
    {
        if (i < char_type::value_size)
            return i;
        else
            return 0;
    }
};

// ------------------------------------------------------------------
// ostream operator
// ------------------------------------------------------------------

template <alphabet_concept alphabet_type, typename traits_type>
std::ostream& operator<<(std::ostream & os, std::basic_string<alphabet_type, traits_type> const & str)
{
    for (auto c : str)
        os << c;
    return os;
}

template <alphabet_concept alphabet_type>
std::ostream& operator<<(std::ostream & os, std::vector<alphabet_type> const & str)
{
    for (auto c : str)
        os << c;
    return os;
}

// ------------------------------------------------------------------
// container conversion
// ------------------------------------------------------------------

// to char string or vector or...
template <typename target_type, typename source_type>
    requires std::is_same_v<typename target_type::value_type, char> && alphabet_concept<typename source_type::value_type>
void convert(target_type & target, source_type const & source)
{
    target.resize(source.size());
    std::copy(source.begin(), source.end(), target.begin());
}

// to other alphabet container
template <typename target_type, typename source_type>
    requires alphabet_concept<typename target_type::value_type> && alphabet_concept<typename source_type::value_type>
void convert(target_type & target, source_type const & source)
{
    using source_alph = typename source_type::value_type;
    using target_alph = typename target_type::value_type;
    target.resize(source.size());
    std::transform(source.begin(), source.end(), target.begin(), [] (source_alph const s)
    {
        return target_alph{s};
    });
}
Clone this wiki locally