Skip to content

Commit

Permalink
Merge pull request #1866 from marehr/patch22
Browse files Browse the repository at this point in the history
[FIX] cxx20: return-type-requirement is not a type-constraint
  • Loading branch information
smehringer committed Jun 16, 2020
2 parents b479913 + d9ec22a commit 2ea3a70
Show file tree
Hide file tree
Showing 19 changed files with 281 additions and 160 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,13 @@ SEQAN3_CONCEPT aligned_sequence =
requires { typename detail::unaligned_seq_t<t>; } &&
requires (t v, detail::unaligned_seq_t<t> unaligned)
{
{ insert_gap(v, std::ranges::begin(v)) } -> std::ranges::iterator_t<t>; // global functions for generic usability
{ insert_gap(v, std::ranges::begin(v), 2) } -> std::ranges::iterator_t<t>;
{ erase_gap(v, std::ranges::begin(v)) } -> std::ranges::iterator_t<t>;
{ erase_gap(v, std::ranges::begin(v), std::ranges::end(v)) } -> std::ranges::iterator_t<t>;
{ assign_unaligned(v, unaligned) } -> void;
// global functions for generic usability
SEQAN3_RETURN_TYPE_CONTRAINT(insert_gap(v, std::ranges::begin(v)), std::same_as, std::ranges::iterator_t<t>);
SEQAN3_RETURN_TYPE_CONTRAINT(insert_gap(v, std::ranges::begin(v), 2), std::same_as, std::ranges::iterator_t<t>);
SEQAN3_RETURN_TYPE_CONTRAINT(erase_gap(v, std::ranges::begin(v)), std::same_as, std::ranges::iterator_t<t>);
SEQAN3_RETURN_TYPE_CONTRAINT(erase_gap(v, std::ranges::begin(v), std::ranges::end(v)),
std::same_as, std::ranges::iterator_t<t>);
SEQAN3_RETURN_TYPE_CONTRAINT(assign_unaligned(v, unaligned), std::same_as, void);
};
//!\endcond

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,14 @@ SEQAN3_CONCEPT two_dimensional_matrix_iterator =
{ it.coordinate() };
{ cit.coordinate() };

requires std::same_as<decltype(it += offset), std::remove_reference_t<iter_t> &>;
requires std::same_as<decltype(it + offset), std::remove_reference_t<iter_t>>;
requires std::same_as<decltype(offset + it), std::remove_reference_t<iter_t>>;
requires std::same_as<decltype(it -= offset), std::remove_reference_t<iter_t> &>;
requires std::same_as<decltype(it - offset), std::remove_reference_t<iter_t>>;
requires std::same_as<decltype(cit - offset), std::remove_reference_t<iter_t>>;
requires std::same_as<decltype(it.coordinate()), matrix_coordinate>;
requires std::same_as<decltype(cit.coordinate()), matrix_coordinate>;
SEQAN3_RETURN_TYPE_CONTRAINT(it += offset, std::same_as, std::remove_reference_t<iter_t> &);
SEQAN3_RETURN_TYPE_CONTRAINT(it + offset, std::same_as, std::remove_reference_t<iter_t>);
SEQAN3_RETURN_TYPE_CONTRAINT(offset + it, std::same_as, std::remove_reference_t<iter_t>);
SEQAN3_RETURN_TYPE_CONTRAINT(it -= offset, std::same_as, std::remove_reference_t<iter_t> &);
SEQAN3_RETURN_TYPE_CONTRAINT(it - offset, std::same_as, std::remove_reference_t<iter_t>);
SEQAN3_RETURN_TYPE_CONTRAINT(cit - offset, std::same_as, std::remove_reference_t<iter_t>);
SEQAN3_RETURN_TYPE_CONTRAINT(it.coordinate(), std::same_as, matrix_coordinate);
SEQAN3_RETURN_TYPE_CONTRAINT(cit.coordinate(), std::same_as, matrix_coordinate);
};
//!\endcond
} // namespace seqan3::detail
12 changes: 9 additions & 3 deletions include/seqan3/alignment/matrix/matrix_concept.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,23 @@ SEQAN3_CONCEPT matrix = requires(remove_cvref_t<matrix_t> m)
/*!\fn size_type cols() const noexcept;
* \brief The number of columns in the matrix.
*/
{ m.cols() } -> typename remove_cvref_t<matrix_t>::size_type;
//!\cond
SEQAN3_RETURN_TYPE_CONTRAINT(m.cols(), std::same_as, typename remove_cvref_t<matrix_t>::size_type);
//!\endcond

/*!\fn size_type rows() const noexcept;
* \brief The number of rows in the matrix.
*/
{ m.rows() } -> typename remove_cvref_t<matrix_t>::size_type;
//!\cond
SEQAN3_RETURN_TYPE_CONTRAINT(m.rows(), std::same_as, typename remove_cvref_t<matrix_t>::size_type);
//!\endcond

/*!\fn reference at(matrix_coordinate coordinate) noexcept;
* \brief A reference to the entry of the matrix at the given coordinate.
*/
{ m.at(matrix_coordinate{}) } -> typename remove_cvref_t<matrix_t>::reference;
//!\cond
SEQAN3_RETURN_TYPE_CONTRAINT(m.at(matrix_coordinate{}), std::same_as, typename remove_cvref_t<matrix_t>::reference);
//!\endcond

//!\cond
};
Expand Down
10 changes: 5 additions & 5 deletions include/seqan3/alphabet/concept.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ struct char_is_valid_for_fn
{
{ impl(priority_tag<3>{}, a, dummy{}) };
requires noexcept(impl(priority_tag<3>{}, a));
requires std::convertible_to<decltype(impl(priority_tag<3>{}, a)), bool>;
SEQAN3_RETURN_TYPE_CONTRAINT(impl(priority_tag<3>{}, a), std::convertible_to, bool);
}
//!\endcond
constexpr bool operator()(alphabet_char_t<alph_t> const a) const noexcept
Expand Down Expand Up @@ -539,8 +539,8 @@ struct assign_char_strictly_to_fn
//!\cond
requires requires (alph_t a, seqan3::alphabet_char_t<alph_t> r)
{
{ seqan3::assign_char_to(r, a) } -> alph_t;
{ seqan3::char_is_valid_for<alph_t>(r) } -> bool;
SEQAN3_RETURN_TYPE_CONTRAINT(seqan3::assign_char_to(r, a), std::convertible_to, alph_t);
SEQAN3_RETURN_TYPE_CONTRAINT(seqan3::char_is_valid_for<alph_t>(r), std::same_as, bool);
}
//!\endcond
decltype(auto) operator()(seqan3::alphabet_char_t<alph_t> const r, alph_t & a) const
Expand All @@ -556,8 +556,8 @@ struct assign_char_strictly_to_fn
//!\cond
requires requires (alph_t a, seqan3::alphabet_char_t<alph_t> r)
{
{ seqan3::assign_char_to(r, a) } -> alph_t;
{ seqan3::char_is_valid_for<alph_t>(r) } -> bool;
SEQAN3_RETURN_TYPE_CONTRAINT(seqan3::assign_char_to(r, a), std::convertible_to, alph_t);
SEQAN3_RETURN_TYPE_CONTRAINT(seqan3::char_is_valid_for<alph_t>(r), std::same_as, bool);
}
//!\endcond
auto operator()(seqan3::alphabet_char_t<alph_t> const r, alph_t && a) const
Expand Down
4 changes: 2 additions & 2 deletions include/seqan3/argument_parser/validators.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ SEQAN3_CONCEPT validator = std::copyable<remove_cvref_t<validator_type>> &&
{
typename std::remove_reference_t<validator_type>::option_value_type;

{ validator(value) } -> void;
{ validator.get_help_page_message() } -> std::string;
SEQAN3_RETURN_TYPE_CONTRAINT(validator(value), std::same_as, void);
SEQAN3_RETURN_TYPE_CONTRAINT(validator.get_help_page_message(), std::same_as, std::string);
};
//!\endcond

Expand Down
4 changes: 2 additions & 2 deletions include/seqan3/core/char_operations/predicate_detail.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ SEQAN3_CONCEPT char_predicate = requires
std::remove_reference_t<condition_t>::msg;

//The msg type can be added with a std::string.
{ std::string{} + std::remove_reference_t<condition_t>::msg } ->
decltype(std::remove_reference_t<condition_t>::msg);
SEQAN3_RETURN_TYPE_CONTRAINT(std::string{} + std::remove_reference_t<condition_t>::msg,
std::convertible_to, decltype(std::remove_reference_t<condition_t>::msg));
};
//!\endcond

Expand Down
15 changes: 10 additions & 5 deletions include/seqan3/core/concept/tuple.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace seqan3::detail
template <typename tuple_t>
SEQAN3_CONCEPT tuple_size = requires (tuple_t v)
{
{ std::tuple_size<tuple_t>::value } -> size_t;
SEQAN3_RETURN_TYPE_CONTRAINT(std::tuple_size<tuple_t>::value, std::convertible_to, size_t);
};
//!\endcond

Expand All @@ -49,14 +49,19 @@ SEQAN3_CONCEPT tuple_get = requires (tuple_t & v, tuple_t const & v_c)
requires std::tuple_size_v<tuple_t> > 0;

typename std::tuple_element<0, tuple_t>::type;
{ get<0>(v) } -> typename std::tuple_element<0, tuple_t>::type;

SEQAN3_RETURN_TYPE_CONTRAINT(get<0>(v), std::convertible_to, typename std::tuple_element<0, tuple_t>::type);
// requires weakly_assignable_from<decltype(get<0>(v)), typename std::tuple_element<0, tuple_t>::type>;
//TODO check that the previous returns something that can be assigned to
// unfortunately std::assignable_from requires lvalue-reference, but we want to accept xvalues too (returned proxies)
{ get<0>(v_c) } -> typename std::tuple_element<0, tuple_t>::type;
{ get<0>(std::move(v)) } -> typename std::tuple_element<0, tuple_t>::type;
// unfortunately std::assignable_from requires lvalue-reference, but we want to accept xvalues too (returned
// proxies)
SEQAN3_RETURN_TYPE_CONTRAINT(get<0>(v_c), std::convertible_to, typename std::tuple_element<0, tuple_t>::type);
SEQAN3_RETURN_TYPE_CONTRAINT(get<0>(std::move(v)),
std::convertible_to, typename std::tuple_element<0, tuple_t>::type);
// TODO: The return type for std::tuple is wrong until gcc-8.0, for gcc > 8.0 this is fixed.
{ get<0>(std::move(v_c)) };// -> typename std::tuple_element<0, tuple_t>::type const &&;
// SEQAN3_RETURN_TYPE_CONTRAINT(get<0>(std::move(v_c)),
// std::convertible_to, typename std::tuple_element<0, tuple_t>::type const &&);
};
//!\endcond

Expand Down
9 changes: 9 additions & 0 deletions include/seqan3/core/platform.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,15 @@
# error "SeqAn3 requires C++ Concepts, either vie the TS (flag: -fconcepts) or via C++20 (flag: -std=c++2a / -std=c++20)."
#endif

//!\brief Same as writing `{expression} -> concept_name<type1[, ...]>` in a concept definition.
#if defined(__GNUC__) && (__GNUC__ < 10)
# define SEQAN3_RETURN_TYPE_CONTRAINT(expression, concept_name, ...) \
{expression}; requires concept_name<decltype(expression), __VA_ARGS__>
#else
# define SEQAN3_RETURN_TYPE_CONTRAINT(expression, concept_name, ...) \
{expression} -> concept_name<__VA_ARGS__>
#endif

// filesystem [required]
#if !__has_include(<filesystem>)
# if !__has_include(<experimental/filesystem>)
Expand Down
36 changes: 21 additions & 15 deletions include/seqan3/core/simd/concept.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,25 +40,31 @@ SEQAN3_CONCEPT simd_concept = requires (simd_t a, simd_t b)
requires std::integral<decltype(simd_traits<std::remove_reference_t<simd_t>>::max_length)>;

// assume array access that returns a scalar_type type
{ a[0] } -> typename simd_traits<std::remove_reference_t<simd_t>>::scalar_type;
SEQAN3_RETURN_TYPE_CONTRAINT(a[0], std::convertible_to, typename simd_traits<std::remove_reference_t<simd_t>>::scalar_type);

// require comparison operators
requires std::same_as<decltype(a == b), typename simd_traits<std::remove_reference_t<simd_t>>::mask_type>;
requires std::same_as<decltype(a != b), typename simd_traits<std::remove_reference_t<simd_t>>::mask_type>;
requires std::same_as<decltype(a < b), typename simd_traits<std::remove_reference_t<simd_t>>::mask_type>;
requires std::same_as<decltype(a > b), typename simd_traits<std::remove_reference_t<simd_t>>::mask_type>;
requires std::same_as<decltype(a <= b), typename simd_traits<std::remove_reference_t<simd_t>>::mask_type>;
requires std::same_as<decltype(a >= b), typename simd_traits<std::remove_reference_t<simd_t>>::mask_type>;
SEQAN3_RETURN_TYPE_CONTRAINT(a == b,
std::same_as, typename simd_traits<std::remove_reference_t<simd_t>>::mask_type);
SEQAN3_RETURN_TYPE_CONTRAINT(a != b,
std::same_as, typename simd_traits<std::remove_reference_t<simd_t>>::mask_type);
SEQAN3_RETURN_TYPE_CONTRAINT(a < b,
std::same_as, typename simd_traits<std::remove_reference_t<simd_t>>::mask_type);
SEQAN3_RETURN_TYPE_CONTRAINT(a > b,
std::same_as, typename simd_traits<std::remove_reference_t<simd_t>>::mask_type);
SEQAN3_RETURN_TYPE_CONTRAINT(a <= b,
std::same_as, typename simd_traits<std::remove_reference_t<simd_t>>::mask_type);
SEQAN3_RETURN_TYPE_CONTRAINT(a >= b,
std::same_as, typename simd_traits<std::remove_reference_t<simd_t>>::mask_type);

// require arithmetic operators
requires std::same_as<decltype(a + b), std::remove_reference_t<simd_t>>;
requires std::same_as<decltype(a - b), std::remove_reference_t<simd_t>>;
requires std::same_as<decltype(a * b), std::remove_reference_t<simd_t>>;
requires std::same_as<decltype(a / b), std::remove_reference_t<simd_t>>;
requires std::same_as<decltype(a += b), std::remove_reference_t<simd_t> &>;
requires std::same_as<decltype(a -= b), std::remove_reference_t<simd_t> &>;
requires std::same_as<decltype(a *= b), std::remove_reference_t<simd_t> &>;
requires std::same_as<decltype(a /= b), std::remove_reference_t<simd_t> &>;
SEQAN3_RETURN_TYPE_CONTRAINT(a + b, std::same_as, std::remove_reference_t<simd_t>);
SEQAN3_RETURN_TYPE_CONTRAINT(a - b, std::same_as, std::remove_reference_t<simd_t>);
SEQAN3_RETURN_TYPE_CONTRAINT(a * b, std::same_as, std::remove_reference_t<simd_t>);
SEQAN3_RETURN_TYPE_CONTRAINT(a / b, std::same_as, std::remove_reference_t<simd_t>);
SEQAN3_RETURN_TYPE_CONTRAINT(a += b, std::same_as, std::remove_reference_t<simd_t> &);
SEQAN3_RETURN_TYPE_CONTRAINT(a -= b, std::same_as, std::remove_reference_t<simd_t> &);
SEQAN3_RETURN_TYPE_CONTRAINT(a *= b, std::same_as, std::remove_reference_t<simd_t> &);
SEQAN3_RETURN_TYPE_CONTRAINT(a /= b, std::same_as, std::remove_reference_t<simd_t> &);
};
//!\endcond

Expand Down
38 changes: 19 additions & 19 deletions include/seqan3/io/alignment_file/output_format_concept.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,25 +95,25 @@ SEQAN3_CONCEPT alignment_file_output_format =
{
t::file_extensions;

{ v.write_alignment_record(stream,
options,
header,
seq,
qual,
id,
offset,
ref_seq,
ref_id,
ref_offset,
align,
cigar,
flag,
mapq,
mate,
tag_dict,
e_value,
bit_score
) } -> void;
SEQAN3_RETURN_TYPE_CONTRAINT(v.write_alignment_record(stream,
options,
header,
seq,
qual,
id,
offset,
ref_seq,
ref_id,
ref_offset,
align,
cigar,
flag,
mapq,
mate,
tag_dict,
e_value,
bit_score),
std::same_as, void);
};
//!\endcond

Expand Down
7 changes: 4 additions & 3 deletions include/seqan3/io/sequence_file/input_format_concept.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,10 @@ SEQAN3_CONCEPT sequence_file_input_format = requires (detail::sequence_file_inpu
{
t::file_extensions;

{ v.read_sequence_record(f, options, seq, id, qual) } -> void;
{ v.read_sequence_record(f, options, seq_qual, id, seq_qual) } -> void;
{ v.read_sequence_record(f, options, std::ignore, std::ignore, std::ignore) } -> void;
SEQAN3_RETURN_TYPE_CONTRAINT(v.read_sequence_record(f, options, seq, id, qual), std::same_as, void);
SEQAN3_RETURN_TYPE_CONTRAINT(v.read_sequence_record(f, options, seq_qual, id, seq_qual), std::same_as, void);
SEQAN3_RETURN_TYPE_CONTRAINT(v.read_sequence_record(f, options, std::ignore, std::ignore, std::ignore),
std::same_as, void);
};
//!\endcond

Expand Down
7 changes: 4 additions & 3 deletions include/seqan3/io/sequence_file/output_format_concept.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,10 @@ SEQAN3_CONCEPT sequence_file_output_format = requires (detail::sequence_file_out
{
t::file_extensions;

{ v.write_sequence_record(f, options, seq, id, qual) } -> void;
{ v.write_sequence_record(f, options, std::ignore, id, std::ignore) } -> void;
{ v.write_sequence_record(f, options, std::ignore, std::ignore, std::ignore) } -> void;
SEQAN3_RETURN_TYPE_CONTRAINT(v.write_sequence_record(f, options, seq, id, qual), std::same_as, void);
SEQAN3_RETURN_TYPE_CONTRAINT(v.write_sequence_record(f, options, std::ignore, id, std::ignore), std::same_as, void);
SEQAN3_RETURN_TYPE_CONTRAINT(v.write_sequence_record(f, options, std::ignore, std::ignore, std::ignore),
std::same_as, void);
// the last is required to be compile time valid, but should always throw at run-time.
};
//!\endcond
Expand Down
14 changes: 10 additions & 4 deletions include/seqan3/io/stream/concept.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#pragma once

#include <seqan3/std/concepts>
#include <iosfwd>
#include <type_traits>

Expand All @@ -38,8 +39,10 @@ SEQAN3_CONCEPT output_stream_over = std::is_base_of_v<std::ios_base, std::remove
typename std::remove_reference_t<stream_type>::pos_type;
typename std::remove_reference_t<stream_type>::off_type;

{ os << val } -> std::basic_ostream<typename std::remove_reference_t<stream_type>::char_type,
typename std::remove_reference_t<stream_type>::traits_type> &;
SEQAN3_RETURN_TYPE_CONTRAINT(os << val,
std::same_as,
std::basic_ostream<typename std::remove_reference_t<stream_type>::char_type,
typename std::remove_reference_t<stream_type>::traits_type> &);
};

template <typename stream_type>
Expand Down Expand Up @@ -105,8 +108,11 @@ SEQAN3_CONCEPT input_stream_over = std::is_base_of_v<std::ios_base, std::remove_
typename std::remove_reference_t<stream_type>::pos_type;
typename std::remove_reference_t<stream_type>::off_type;

{ is >> val } -> std::basic_istream<typename std::remove_reference_t<stream_type>::char_type,
typename std::remove_reference_t<stream_type>::traits_type> &;

SEQAN3_RETURN_TYPE_CONTRAINT(is >> val,
std::same_as,
std::basic_istream<typename std::remove_reference_t<stream_type>::char_type,
typename std::remove_reference_t<stream_type>::traits_type> &);
};

template <typename stream_type>
Expand Down
Loading

0 comments on commit 2ea3a70

Please sign in to comment.