-
Notifications
You must be signed in to change notification settings - Fork 82
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
introduce new seqan3::detail::transfer_type_modifier_onto (#2365)
* [FEATURE] introduce new seqan3::detail::transfer_type_modifier_onto * [FEATURE] use new seqan3::detail::transfer_type_modifier_onto * Update include/seqan3/core/detail/transfer_type_modifier_onto.hpp Co-authored-by: Jörg Winkler <[email protected]> * Update include/seqan3/core/detail/transfer_type_modifier_onto.hpp * Update include/seqan3/core/detail/transfer_type_modifier_onto.hpp Co-authored-by: Enrico Seiler <[email protected]> * Update include/seqan3/core/detail/transfer_type_modifier_onto.hpp Co-authored-by: Enrico Seiler <[email protected]> Co-authored-by: Jörg Winkler <[email protected]> Co-authored-by: Enrico Seiler <[email protected]>
- Loading branch information
1 parent
b9ed109
commit e7e0430
Showing
4 changed files
with
218 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70 changes: 70 additions & 0 deletions
70
include/seqan3/core/detail/transfer_type_modifier_onto.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// ----------------------------------------------------------------------------------------------------- | ||
// 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 | ||
* \author Marcel Ehrhardt <marcel.ehrhardt AT fu-berlin.de> | ||
* \brief Provides type traits seqan3::detail::transfer_type_modifier_onto. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <seqan3/std/type_traits> | ||
|
||
#include <seqan3/core/platform.hpp> | ||
|
||
namespace seqan3::detail | ||
{ | ||
|
||
/*!\brief Transfers the type modifier `&`, `&&` and `const` (and any combination) to the target type. | ||
* \implements seqan3::transformation_trait | ||
* \tparam source_t The type you wish to transfer the type modifier from. | ||
* \tparam target_t The type you wish to transfer the type modifier to. | ||
* \ingroup core | ||
* If the `target_t` already has a type modifier, e.g. `const`, it will keep that type modifier. | ||
* | ||
* If the resulting type would have the type modifier `&&` and `&` at the same time, it follows the rule of reference | ||
* collapsing, that means `&` will be preferred. | ||
* \sa https://en.cppreference.com/w/cpp/language/reference#Reference_collapsing | ||
*/ | ||
template <typename source_t, typename target_t> | ||
struct transfer_type_modifier_onto | ||
{ | ||
private: | ||
//!\brief Transfers the `const` type modifier to the target type. | ||
using maybe_const_target_t = std::conditional_t<std::is_const_v<std::remove_reference_t<source_t>> || | ||
std::is_const_v<std::remove_reference_t<target_t>>, | ||
std::add_const_t<std::remove_cvref_t<target_t>>, | ||
std::remove_cvref_t<target_t>>; | ||
|
||
//!\brief Transfers the `&&` type modifier to the target type. | ||
using maybe_rvalue_reference_t = std::conditional_t<std::is_rvalue_reference_v<source_t> || | ||
std::is_rvalue_reference_v<target_t>, | ||
std::add_rvalue_reference_t<maybe_const_target_t>, | ||
maybe_const_target_t>; | ||
|
||
//!\brief Transfers the `&` type modifier to the target type. | ||
using maybe_lvalue_reference_target_t = std::conditional_t<std::is_lvalue_reference_v<source_t> || | ||
std::is_lvalue_reference_v<target_t>, | ||
std::add_lvalue_reference_t<maybe_rvalue_reference_t>, | ||
maybe_rvalue_reference_t>; | ||
public: | ||
|
||
//!\brief Transfers the type modifier `&`, `&&` and `const` (and any combination) to the target type. | ||
using type = maybe_lvalue_reference_target_t; | ||
}; | ||
|
||
/*!\brief Transfers the type modifier `&`, `&&` and `const` (and any combination) to the target type | ||
* (transformation_trait shortcut). | ||
* \tparam source_t The type you wish to transfer the type modifier from. | ||
* \tparam target_t The type you wish to transfer the type modifier to. | ||
* \see seqan3::detail::transfer_type_modifier_onto | ||
* \relates seqan3::detail::transfer_type_modifier_onto | ||
*/ | ||
template <typename source_t, typename target_t> | ||
using transfer_type_modifier_onto_t = typename transfer_type_modifier_onto<source_t, target_t>::type; | ||
|
||
} // namespace seqan3::detail |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
142 changes: 142 additions & 0 deletions
142
test/unit/core/detail/transfer_type_modifier_onto_test.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
// ----------------------------------------------------------------------------------------------------- | ||
// 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 <gtest/gtest.h> | ||
|
||
#include <seqan3/core/detail/transfer_type_modifier_onto.hpp> | ||
#include <seqan3/test/expect_same_type.hpp> | ||
|
||
TEST(transfer_type_modifier_onto, type) | ||
{ | ||
// target type has no modifier | ||
EXPECT_SAME_TYPE(double, (typename seqan3::detail::transfer_type_modifier_onto<int, double>::type)); | ||
EXPECT_SAME_TYPE(double &, (typename seqan3::detail::transfer_type_modifier_onto<int &, double>::type)); | ||
EXPECT_SAME_TYPE(double &&, (typename seqan3::detail::transfer_type_modifier_onto<int &&, double>::type)); | ||
EXPECT_SAME_TYPE(double const, (typename seqan3::detail::transfer_type_modifier_onto<int const, double>::type)); | ||
EXPECT_SAME_TYPE(double const &, (typename seqan3::detail::transfer_type_modifier_onto<int const &, double>::type)); | ||
EXPECT_SAME_TYPE(double const &&, | ||
(typename seqan3::detail::transfer_type_modifier_onto<int const &&, double>::type)); | ||
|
||
// target type has lvalue reference modifier | ||
EXPECT_SAME_TYPE(double &, (typename seqan3::detail::transfer_type_modifier_onto<int, double &>::type)); | ||
EXPECT_SAME_TYPE(double & /*&*/, (typename seqan3::detail::transfer_type_modifier_onto<int &, double &>::type)); | ||
EXPECT_SAME_TYPE(double & /*&&*/, (typename seqan3::detail::transfer_type_modifier_onto<int &&, double &>::type)); | ||
EXPECT_SAME_TYPE(double const &, (typename seqan3::detail::transfer_type_modifier_onto<int const, double &>::type)); | ||
EXPECT_SAME_TYPE(double const & /*&*/, | ||
(typename seqan3::detail::transfer_type_modifier_onto<int const &, double &>::type)); | ||
EXPECT_SAME_TYPE(double const & /*&&*/, | ||
(typename seqan3::detail::transfer_type_modifier_onto<int const &&, double &>::type)); | ||
|
||
// target type has rvalue reference modifier | ||
EXPECT_SAME_TYPE(double &&, (typename seqan3::detail::transfer_type_modifier_onto<int, double &&>::type)); | ||
EXPECT_SAME_TYPE(double /*&&*/ &, (typename seqan3::detail::transfer_type_modifier_onto<int &, double &&>::type)); | ||
EXPECT_SAME_TYPE(double && /*&&*/, (typename seqan3::detail::transfer_type_modifier_onto<int &&, double &&>::type)); | ||
EXPECT_SAME_TYPE(double const &&, | ||
(typename seqan3::detail::transfer_type_modifier_onto<int const, double &&>::type)); | ||
EXPECT_SAME_TYPE(double const /*&&*/ &, | ||
(typename seqan3::detail::transfer_type_modifier_onto<int const &, double &&>::type)); | ||
EXPECT_SAME_TYPE(double const /*&&*/ &&, | ||
(typename seqan3::detail::transfer_type_modifier_onto<int const &&, double &&>::type)); | ||
|
||
// target type has const modifier | ||
EXPECT_SAME_TYPE(double const, (typename seqan3::detail::transfer_type_modifier_onto<int, double const>::type)); | ||
EXPECT_SAME_TYPE(double const &, (typename seqan3::detail::transfer_type_modifier_onto<int &, double const>::type)); | ||
EXPECT_SAME_TYPE(double const &&, | ||
(typename seqan3::detail::transfer_type_modifier_onto<int &&, double const>::type)); | ||
EXPECT_SAME_TYPE(double /*const*/ const, | ||
(typename seqan3::detail::transfer_type_modifier_onto<int const, double const>::type)); | ||
EXPECT_SAME_TYPE(double /*const*/ const &, | ||
(typename seqan3::detail::transfer_type_modifier_onto<int const &, double const>::type)); | ||
EXPECT_SAME_TYPE(double /*const*/ const &&, | ||
(typename seqan3::detail::transfer_type_modifier_onto<int const &&, double const>::type)); | ||
|
||
// target type has const lvalue reference modifier | ||
EXPECT_SAME_TYPE(double const &, (typename seqan3::detail::transfer_type_modifier_onto<int, double const &>::type)); | ||
EXPECT_SAME_TYPE(double const & /*&*/, | ||
(typename seqan3::detail::transfer_type_modifier_onto<int &, double const &>::type)); | ||
EXPECT_SAME_TYPE(double const & /*&&*/, | ||
(typename seqan3::detail::transfer_type_modifier_onto<int &&, double const &>::type)); | ||
EXPECT_SAME_TYPE(double /*const*/ const &, | ||
(typename seqan3::detail::transfer_type_modifier_onto<int const, double const &>::type)); | ||
EXPECT_SAME_TYPE(double /*const*/ const & /*&*/, | ||
(typename seqan3::detail::transfer_type_modifier_onto<int const &, double const &>::type)); | ||
EXPECT_SAME_TYPE(double /*const*/ const & /*&&*/, | ||
(typename seqan3::detail::transfer_type_modifier_onto<int const &&, double const &>::type)); | ||
|
||
// target type has const rvalue reference modifier | ||
EXPECT_SAME_TYPE(double const &&, | ||
(typename seqan3::detail::transfer_type_modifier_onto<int, double const &&>::type)); | ||
EXPECT_SAME_TYPE(double const /*&&*/ &, | ||
(typename seqan3::detail::transfer_type_modifier_onto<int &, double const &&>::type)); | ||
EXPECT_SAME_TYPE(double const && /*&&*/, | ||
(typename seqan3::detail::transfer_type_modifier_onto<int &&, double const &&>::type)); | ||
EXPECT_SAME_TYPE(double /*const*/ const &&, | ||
(typename seqan3::detail::transfer_type_modifier_onto<int const, double const &&>::type)); | ||
EXPECT_SAME_TYPE(double /*const*/ const /*&&*/ &, | ||
(typename seqan3::detail::transfer_type_modifier_onto<int const &, double const &&>::type)); | ||
EXPECT_SAME_TYPE(double /*const*/ const /*&&*/ &&, | ||
(typename seqan3::detail::transfer_type_modifier_onto<int const &&, double const &&>::type)); | ||
} | ||
|
||
TEST(transfer_type_modifier_onto, type_t_helper) | ||
{ | ||
// target type has no modifier | ||
EXPECT_SAME_TYPE(double, (seqan3::detail::transfer_type_modifier_onto_t<int, double>)); | ||
EXPECT_SAME_TYPE(double &, (seqan3::detail::transfer_type_modifier_onto_t<int &, double>)); | ||
EXPECT_SAME_TYPE(double &&, (seqan3::detail::transfer_type_modifier_onto_t<int &&, double>)); | ||
EXPECT_SAME_TYPE(double const, (seqan3::detail::transfer_type_modifier_onto_t<int const, double>)); | ||
EXPECT_SAME_TYPE(double const &, (seqan3::detail::transfer_type_modifier_onto_t<int const &, double>)); | ||
EXPECT_SAME_TYPE(double const &&, (seqan3::detail::transfer_type_modifier_onto_t<int const &&, double>)); | ||
|
||
// target type has lvalue reference modifier | ||
EXPECT_SAME_TYPE(double &, (seqan3::detail::transfer_type_modifier_onto_t<int, double &>)); | ||
EXPECT_SAME_TYPE(double & /*&*/, (seqan3::detail::transfer_type_modifier_onto_t<int &, double &>)); | ||
EXPECT_SAME_TYPE(double & /*&&*/, (seqan3::detail::transfer_type_modifier_onto_t<int &&, double &>)); | ||
EXPECT_SAME_TYPE(double const &, (seqan3::detail::transfer_type_modifier_onto_t<int const, double &>)); | ||
EXPECT_SAME_TYPE(double const & /*&*/, (seqan3::detail::transfer_type_modifier_onto_t<int const &, double &>)); | ||
EXPECT_SAME_TYPE(double const & /*&&*/, (seqan3::detail::transfer_type_modifier_onto_t<int const &&, double &>)); | ||
|
||
// target type has rvalue reference modifier | ||
EXPECT_SAME_TYPE(double &&, (seqan3::detail::transfer_type_modifier_onto_t<int, double &&>)); | ||
EXPECT_SAME_TYPE(double /*&&*/ &, (seqan3::detail::transfer_type_modifier_onto_t<int &, double &&>)); | ||
EXPECT_SAME_TYPE(double && /*&&*/, (seqan3::detail::transfer_type_modifier_onto_t<int &&, double &&>)); | ||
EXPECT_SAME_TYPE(double const &&, (seqan3::detail::transfer_type_modifier_onto_t<int const, double &&>)); | ||
EXPECT_SAME_TYPE(double const /*&&*/ &, (seqan3::detail::transfer_type_modifier_onto_t<int const &, double &&>)); | ||
EXPECT_SAME_TYPE(double const /*&&*/ &&, (seqan3::detail::transfer_type_modifier_onto_t<int const &&, double &&>)); | ||
|
||
// target type has const modifier | ||
EXPECT_SAME_TYPE(double const, (seqan3::detail::transfer_type_modifier_onto_t<int, double const>)); | ||
EXPECT_SAME_TYPE(double const &, (seqan3::detail::transfer_type_modifier_onto_t<int &, double const>)); | ||
EXPECT_SAME_TYPE(double const &&, (seqan3::detail::transfer_type_modifier_onto_t<int &&, double const>)); | ||
EXPECT_SAME_TYPE(double /*const*/ const, (seqan3::detail::transfer_type_modifier_onto_t<int const, double const>)); | ||
EXPECT_SAME_TYPE(double /*const*/ const &, | ||
(seqan3::detail::transfer_type_modifier_onto_t<int const &, double const>)); | ||
EXPECT_SAME_TYPE(double /*const*/ const &&, | ||
(seqan3::detail::transfer_type_modifier_onto_t<int const &&, double const>)); | ||
|
||
// target type has const lvalue reference modifier | ||
EXPECT_SAME_TYPE(double const &, (seqan3::detail::transfer_type_modifier_onto_t<int, double const &>)); | ||
EXPECT_SAME_TYPE(double const & /*&*/, (seqan3::detail::transfer_type_modifier_onto_t<int &, double const &>)); | ||
EXPECT_SAME_TYPE(double const & /*&&*/, (seqan3::detail::transfer_type_modifier_onto_t<int &&, double const &>)); | ||
EXPECT_SAME_TYPE(double /*const*/ const &, | ||
(seqan3::detail::transfer_type_modifier_onto_t<int const, double const &>)); | ||
EXPECT_SAME_TYPE(double /*const*/ const & /*&*/, | ||
(seqan3::detail::transfer_type_modifier_onto_t<int const &, double const &>)); | ||
EXPECT_SAME_TYPE(double /*const*/ const & /*&&*/, | ||
(seqan3::detail::transfer_type_modifier_onto_t<int const &&, double const &>)); | ||
|
||
// target type has const rvalue reference modifier | ||
EXPECT_SAME_TYPE(double const &&, (seqan3::detail::transfer_type_modifier_onto_t<int, double const &&>)); | ||
EXPECT_SAME_TYPE(double const /*&&*/ &, (seqan3::detail::transfer_type_modifier_onto_t<int &, double const &&>)); | ||
EXPECT_SAME_TYPE(double const && /*&&*/, (seqan3::detail::transfer_type_modifier_onto_t<int &&, double const &&>)); | ||
EXPECT_SAME_TYPE(double /*const*/ const &&, | ||
(seqan3::detail::transfer_type_modifier_onto_t<int const, double const &&>)); | ||
EXPECT_SAME_TYPE(double /*const*/ const /*&&*/ &, | ||
(seqan3::detail::transfer_type_modifier_onto_t<int const &, double const &&>)); | ||
EXPECT_SAME_TYPE(double /*const*/ const /*&&*/ &&, | ||
(seqan3::detail::transfer_type_modifier_onto_t<int const &&, double const &&>)); | ||
} |