From e0d04206fec631bcb8202125bad4e6247939f5a7 Mon Sep 17 00:00:00 2001 From: marehr Date: Thu, 28 Jan 2021 23:46:23 +0100 Subject: [PATCH] [FEATURE] introduce new concepts seqan3::detail::(writable_)pairwise_alignment This PR finishes task https://github.com/seqan/product_backlog/issues/60 by implementing seqan3::detail::(writable_)pairwise_alignment. --- .../detail/pairwise_alignment_concept.hpp | 94 +++++++++++++++ include/seqan3/core/platform.hpp | 9 ++ test/unit/alignment/detail/CMakeLists.txt | 1 + .../pairwise_alignment_concept_test.cpp | 109 ++++++++++++++++++ 4 files changed, 213 insertions(+) create mode 100644 include/seqan3/alignment/detail/pairwise_alignment_concept.hpp create mode 100644 test/unit/alignment/detail/CMakeLists.txt create mode 100644 test/unit/alignment/detail/pairwise_alignment_concept_test.cpp diff --git a/include/seqan3/alignment/detail/pairwise_alignment_concept.hpp b/include/seqan3/alignment/detail/pairwise_alignment_concept.hpp new file mode 100644 index 00000000000..782a6cce363 --- /dev/null +++ b/include/seqan3/alignment/detail/pairwise_alignment_concept.hpp @@ -0,0 +1,94 @@ +// ----------------------------------------------------------------------------------------------------- +// Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin +// Copyright (c) 2016-2020, Knut Reinert & MPI für molekulare Genetik +// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License +// shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md +// ----------------------------------------------------------------------------------------------------- + +/*!\file + * \brief Provides seqan3::detail::pairwise_alignment and seqan3::detail::writable_pairwise_alignment. + * \author Marcel Ehrhardt + */ + +#pragma once + +#include + +#include +#if SEQAN3_WORKAROUND_ISSUE_286 +#include +#endif // SEQAN3_WORKAROUND_ISSUE_286 + +namespace seqan3::detail +{ + +/*!\interface seqan3::detail::pairwise_alignment < > + * \extends seqan3::pair_like + * \ingroup alignment + * \brief A concept that models a pairwise alignment type. + * + * \details + * + * A pairwise alignment is a seqan3::pair_like of two seqan3::aligned_sequence's. + */ +//!\cond +template +SEQAN3_CONCEPT pairwise_alignment = + pair_like && +#if SEQAN3_WORKAROUND_ISSUE_286 + aligned_sequence< + // simulate that tuple_element transfers const over to it's inner members. + transfer_type_modifier_onto_t< + std::remove_reference_t, + std::tuple_element_t<0, std::remove_cvref_t> + > + > && + aligned_sequence< + // simulate that tuple_element transfers const over to it's inner members. + transfer_type_modifier_onto_t< + std::remove_reference_t, + std::tuple_element_t<1, std::remove_cvref_t> + > + >; +#else // ^^^ workaround / no workaround vvv + aligned_sequence>> && + aligned_sequence>>; +#endif // SEQAN3_WORKAROUND_ISSUE_286 + +//!\endcond + +/*!\interface seqan3::detail::writable_pairwise_alignment < > + * \extends seqan3::detail::pairwise_alignment + * \ingroup alignment + * \brief A concept that models a writable pairwise alignment type. + * + * \details + * + * A writable pairwise alignment is a seqan3::pair_like of two seqan3::writable_aligned_sequence's. + */ +//!\cond +template +SEQAN3_CONCEPT writable_pairwise_alignment = + pairwise_alignment && +#if SEQAN3_WORKAROUND_ISSUE_286 + writable_aligned_sequence< + // simulate that tuple_element transfers const over to it's inner members. + transfer_type_modifier_onto_t< + std::remove_reference_t, + std::tuple_element_t<0, std::remove_cvref_t> + > + > && + writable_aligned_sequence< + // simulate that tuple_element transfers const over to it's inner members. + transfer_type_modifier_onto_t< + std::remove_reference_t, + std::tuple_element_t<1, std::remove_cvref_t> + > + >; +#else // ^^^ workaround / no workaround vvv + writable_aligned_sequence>> && + writable_aligned_sequence>>; +#endif // SEQAN3_WORKAROUND_ISSUE_286 +//!\endcond + +} // namespace seqan3::detail diff --git a/include/seqan3/core/platform.hpp b/include/seqan3/core/platform.hpp index 60fc5098821..4bf4ccd3947 100644 --- a/include/seqan3/core/platform.hpp +++ b/include/seqan3/core/platform.hpp @@ -223,6 +223,15 @@ # define SEQAN3_WORKAROUND_VIEW_PERFORMANCE 1 #endif +//!\brief See https://github.com/seqan/product_backlog/issues/286 +#ifndef SEQAN3_WORKAROUND_ISSUE_286 +# if defined(__GNUC__) && (__GNUC__ <= 9) +# define SEQAN3_WORKAROUND_ISSUE_286 1 +# else +# define SEQAN3_WORKAROUND_ISSUE_286 0 +# endif +#endif + //!\brief See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87113 #ifndef SEQAN3_WORKAROUND_GCC_87113 # if defined(__GNUC_MINOR__) && ((__GNUC__ == 7) || ((__GNUC__ == 8) && (__GNUC_MINOR__ < 3))) diff --git a/test/unit/alignment/detail/CMakeLists.txt b/test/unit/alignment/detail/CMakeLists.txt new file mode 100644 index 00000000000..32d0b988959 --- /dev/null +++ b/test/unit/alignment/detail/CMakeLists.txt @@ -0,0 +1 @@ +seqan3_test(pairwise_alignment_concept_test.cpp) diff --git a/test/unit/alignment/detail/pairwise_alignment_concept_test.cpp b/test/unit/alignment/detail/pairwise_alignment_concept_test.cpp new file mode 100644 index 00000000000..e637eaa1b1a --- /dev/null +++ b/test/unit/alignment/detail/pairwise_alignment_concept_test.cpp @@ -0,0 +1,109 @@ +// ----------------------------------------------------------------------------------------------------- +// Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin +// Copyright (c) 2016-2020, Knut Reinert & MPI für molekulare Genetik +// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License +// shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md +// ----------------------------------------------------------------------------------------------------- + +#include + +#include +#include +#include +#include + +TEST(pairwise_alignment_concept, std_pair_gapped_sequences) +{ + using gapped_sequence1_t = std::vector>; + using gapped_sequence2_t = std::vector>; + using alignment_t = std::pair; + + EXPECT_FALSE((seqan3::detail::pairwise_alignment)); + EXPECT_FALSE((seqan3::detail::pairwise_alignment)); + EXPECT_TRUE((seqan3::detail::pairwise_alignment)); + EXPECT_TRUE((seqan3::detail::pairwise_alignment)); + EXPECT_TRUE((seqan3::detail::pairwise_alignment)); + EXPECT_TRUE((seqan3::detail::pairwise_alignment)); + EXPECT_TRUE((seqan3::detail::pairwise_alignment)); + EXPECT_TRUE((seqan3::detail::pairwise_alignment)); +} + +TEST(pairwise_alignment_concept, std_tuple_gapped_sequences) +{ + using gapped_sequence1_t = std::vector> const; + using gapped_sequence2_t = std::vector>; + using alignment_t = std::tuple; + + EXPECT_FALSE((seqan3::detail::pairwise_alignment)); + EXPECT_FALSE((seqan3::detail::pairwise_alignment)); + EXPECT_TRUE((seqan3::detail::pairwise_alignment)); + EXPECT_TRUE((seqan3::detail::pairwise_alignment)); + EXPECT_TRUE((seqan3::detail::pairwise_alignment)); + EXPECT_TRUE((seqan3::detail::pairwise_alignment)); + EXPECT_TRUE((seqan3::detail::pairwise_alignment)); + EXPECT_TRUE((seqan3::detail::pairwise_alignment)); +} + +TEST(pairwise_alignment_concept, std_tuple_gap_sequence) +{ + using gap_sequence1_t = std::vector const; + using gap_sequence2_t = std::vector; + using alignment_t = std::tuple; + + EXPECT_FALSE((seqan3::detail::pairwise_alignment)); + EXPECT_FALSE((seqan3::detail::pairwise_alignment)); + EXPECT_TRUE((seqan3::detail::pairwise_alignment)); + EXPECT_TRUE((seqan3::detail::pairwise_alignment)); + EXPECT_TRUE((seqan3::detail::pairwise_alignment)); + EXPECT_TRUE((seqan3::detail::pairwise_alignment)); + EXPECT_TRUE((seqan3::detail::pairwise_alignment)); + EXPECT_TRUE((seqan3::detail::pairwise_alignment)); +} + +TEST(writable_pairwise_alignment_concept, std_pair_gapped_sequences) +{ + using gapped_sequence1_t = std::vector>; + using gapped_sequence2_t = std::vector>; + using alignment_t = std::pair; + + EXPECT_FALSE((seqan3::detail::writable_pairwise_alignment)); + EXPECT_FALSE((seqan3::detail::writable_pairwise_alignment)); + EXPECT_TRUE((seqan3::detail::writable_pairwise_alignment)); + EXPECT_FALSE((seqan3::detail::writable_pairwise_alignment)); + EXPECT_TRUE((seqan3::detail::writable_pairwise_alignment)); + EXPECT_FALSE((seqan3::detail::writable_pairwise_alignment)); + EXPECT_TRUE((seqan3::detail::writable_pairwise_alignment)); + EXPECT_FALSE((seqan3::detail::writable_pairwise_alignment)); +} + +TEST(writable_pairwise_alignment_concept, std_tuple_gapped_sequences) +{ + using gapped_sequence1_t = std::vector>; + using gapped_sequence2_t = std::vector> const; + using alignment_t = std::tuple; + + EXPECT_FALSE((seqan3::detail::writable_pairwise_alignment)); + EXPECT_FALSE((seqan3::detail::writable_pairwise_alignment)); + EXPECT_FALSE((seqan3::detail::writable_pairwise_alignment)); + EXPECT_FALSE((seqan3::detail::writable_pairwise_alignment)); + EXPECT_FALSE((seqan3::detail::writable_pairwise_alignment)); + EXPECT_FALSE((seqan3::detail::writable_pairwise_alignment)); + EXPECT_FALSE((seqan3::detail::writable_pairwise_alignment)); + EXPECT_FALSE((seqan3::detail::writable_pairwise_alignment)); +} + +TEST(writable_pairwise_alignment_concept, std_tuple_gap_sequence) +{ + using gap_sequence1_t = std::vector; + using gap_sequence2_t = std::vector const; + using alignment_t = std::tuple; + + EXPECT_FALSE((seqan3::detail::writable_pairwise_alignment)); + EXPECT_FALSE((seqan3::detail::writable_pairwise_alignment)); + EXPECT_FALSE((seqan3::detail::writable_pairwise_alignment)); + EXPECT_FALSE((seqan3::detail::writable_pairwise_alignment)); + EXPECT_FALSE((seqan3::detail::writable_pairwise_alignment)); + EXPECT_FALSE((seqan3::detail::writable_pairwise_alignment)); + EXPECT_FALSE((seqan3::detail::writable_pairwise_alignment)); + EXPECT_FALSE((seqan3::detail::writable_pairwise_alignment)); +}