Commit ec6b42f6 authored by Armin Sobhani's avatar Armin Sobhani
Browse files

add complement algorithm along with unit tests

parent 3b4c5fe6
//----------------------------------------------------------------------------//
// Copyright (c) 2018 Armin Sobhani <arminms@gmail.com>
//
// Distributed under the Boost Software License Version 1.0.
// (See accompanying ${file} LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//----------------------------------------------------------------------------//
#ifndef BOOST_BIOSEQ_ALGORITHM_COMPLEMENT_HPP
#define BOOST_BIOSEQ_ALGORITHM_COMPLEMENT_HPP
#include <boost/assert.hpp>
#include <boost/concept_check.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/concepts.hpp>
#include <algorithm>
#include <array>
namespace boost {
namespace bioseq {
//----------------------------------------------------------------------------//
// template<class SinglePassRange, class OutputIterator>
// inline OutputIterator complement(const SinglePassRange& rng, OutputIterator out)
// {
// BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
// typedef typename std::iterator_traits<typename range_iterator<SinglePassRange>::type>::value_type base_type;
// // std::array<base_type, 128> cmplmnt = { 0, 1, 2};
// base_type cmplmnt[] =
// "--------------------------------"
// " !-#$%&-()*+,-./0123456789:;<=>?"
// "@TVGHEFCDIJMLKNOPQYSAUBWXRZ[-]^_"
// "`tvghefcdijmlknopqysaubwxrz{|}~";
// return std::transform(
// boost::begin(rng)
// , boost::end(rng)
// , out
// , [ &cmplmnt ] (base_type b)
// { return cmplmnt[b]; } );
// }
//----------------------------------------------------------------------------//
template<class SinglePassRange, class OutputIterator>
inline OutputIterator complement(const SinglePassRange& rng, OutputIterator out)
{
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type
i = boost::begin(rng), e = boost::end(rng);
typename std::iterator_traits<decltype(i)>::value_type cmplmnt[] =
"--------------------------------"
" !-#$%&-()*+,-./0123456789:;<=>?"
"@TVGHEFCDIJMLKNOPQYSAUBWXRZ[-]^_"
"`tvghefcdijmlknopqysaubwxrz{|}~";
for( ; i != e; ++out, ++i )
*out = cmplmnt[*i];
return out;
}
//----------------------------------------------------------------------------//
} // end bioseq namespace
} // end boost namespace
#endif // BOOST_BIOSEQ_ALGORITHM_COMPLEMENT_HPP
\ No newline at end of file
......@@ -21,6 +21,7 @@
#include <boost/bioseq/type_traits.hpp>
#include <boost/bioseq/sequence.hpp>
#include <boost/bioseq/algorithm/complement.hpp>
#include "perf.hpp"
#include "rss.hpp"
......@@ -61,20 +62,22 @@ int main(int argc, char *argv[])
rc.reserve(PERF_N);
t.start();
boost::push_back(
rc
// boost::push_back(
// rc
// // , rs | boost::adaptors::transformed(
// // [] (char b) { if ('A' == b) return 'T';
// // else if ('T' == b) return 'A';
// // else if ('C' == b) return 'G';
// // else if ('G' == b) return 'C';
// // else return b ; } )
// , rs | boost::adaptors::transformed(
// [] (char b) { if ('A' == b) return 'T';
// else if ('T' == b) return 'A';
// else if ('C' == b) return 'G';
// else if ('G' == b) return 'C';
// else return b ; } )
// [ &cmplmnt ] (char b) { return cmplmnt[b]; } )
, rs | boost::adaptors::transformed(
[ &cmplmnt ] (char b) { return cmplmnt[b]; } )
// | boost::adaptors::reversed);
| boost::adaptors::reversed);
bsq::complement(rs | boost::adaptors::reversed, std::back_inserter(rc));
t.stop();
// std::cout << "out: " << rc.data() << std::endl;
......
......@@ -52,3 +52,4 @@ add_bioseq_test("boost.compute.sequence" test_bc_sequence.cpp)
add_bioseq_test("name.component" test_name_component.cpp)
add_bioseq_test("description.component" test_description_component.cpp)
add_bioseq_test("io.fasta" test_io_fasta.cpp)
add_bioseq_test("algorithm.complement" test_algorithm_complement.cpp)
//----------------------------------------------------------------------------//
// Copyright (c) 2018 Armin Sobhani <arminms@gmail.com>
//
// Distributed under the Boost Software License Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//----------------------------------------------------------------------------//
#define BOOST_TEST_MODULE TestComplementAlgorithm
#include <boost/mpl/list.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/bioseq/type_traits.hpp>
#include <boost/bioseq/sequence.hpp>
#include <boost/bioseq/algorithm/complement.hpp>
namespace bsq = boost::bioseq;
template<class CharT, class Allocator> using bsq_string
= std::basic_string<CharT, std::char_traits<CharT>, Allocator>;
typedef
bsq::sequence_host
<
char
, std::allocator
, bsq_string
> str_seq;
typedef
bsq::sequence_host
<
char
, std::allocator
, std::vector
> vec_seq;
// adding sequence types to the test list
typedef boost::mpl::list<str_seq, vec_seq> seq_type;
BOOST_AUTO_TEST_CASE_TEMPLATE(complement, T, seq_type)
{
T iupac("ACGTUWSMKRYBDHVN-");
T tilde;
bsq::complement(iupac, std::back_inserter(tilde));
BOOST_CHECK_EQUAL( iupac.data(), "ACGTUWSMKRYBDHVN-" );
BOOST_CHECK_EQUAL( tilde.data(), "TGCAUWSKMYRVHDBN-" );
}
BOOST_AUTO_TEST_CASE_TEMPLATE(complement_overright, T, seq_type)
{
T iupac("ACGTUWSMKRYBDHVN-");
auto ret = bsq::complement(iupac, iupac.begin());
BOOST_CHECK_EQUAL( iupac.data(), "TGCAUWSKMYRVHDBN-" );
BOOST_CHECK_EQUAL( *(--ret), '-');
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment