-
Notifications
You must be signed in to change notification settings - Fork 82
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};
});
}