diff --git a/doc/tutorial/sequence_file/sequence_file_solution3.cpp b/doc/tutorial/sequence_file/sequence_file_solution3.cpp index 7dd22046fb..22d0765313 100644 --- a/doc/tutorial/sequence_file/sequence_file_solution3.cpp +++ b/doc/tutorial/sequence_file/sequence_file_solution3.cpp @@ -54,6 +54,7 @@ write_file_dummy_struct go{}; #include #include #include +#include #include #include @@ -80,10 +81,9 @@ int main() | length_filter // apply length filter | std::views::take(2) // take first two records | seqan3::views::get // select only ID from record - | seqan3::views::convert // mark ID to be moved out of record + | seqan3::views::move // mark ID to be moved out of record | seqan3::views::to>; // convert to container // Note that you need to know the type of id (std::string) - // Converting to && prevents the IDs from being copied seqan3::debug_stream << ids << '\n'; } diff --git a/include/seqan3/alignment/matrix/detail/aligned_sequence_builder.hpp b/include/seqan3/alignment/matrix/detail/aligned_sequence_builder.hpp index 7fb6ea3fce..339157c1ad 100644 --- a/include/seqan3/alignment/matrix/detail/aligned_sequence_builder.hpp +++ b/include/seqan3/alignment/matrix/detail/aligned_sequence_builder.hpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include @@ -128,8 +128,8 @@ class aligned_sequence_builder * \param[in] sec_rng The second range to build the aligned sequence for. */ constexpr aligned_sequence_builder(fst_sequence_t fst_rng, sec_sequence_t sec_rng) : - fst_rng{views::all(std::forward(fst_rng))}, - sec_rng{views::all(std::forward(sec_rng))} + fst_rng{views::type_reduce(std::forward(fst_rng))}, + sec_rng{views::type_reduce(std::forward(sec_rng))} {} //!\} @@ -216,8 +216,8 @@ class aligned_sequence_builder } } - all_view fst_rng; //!< A view over the first range. - all_view sec_rng; //!< A view over the second range. + type_reduce_view fst_rng; //!< A view over the first range. + type_reduce_view sec_rng; //!< A view over the second range. }; /*!\name Type deduction guides diff --git a/include/seqan3/alignment/pairwise/align_result_selector.hpp b/include/seqan3/alignment/pairwise/align_result_selector.hpp index c493146b1b..f28b036b43 100644 --- a/include/seqan3/alignment/pairwise/align_result_selector.hpp +++ b/include/seqan3/alignment/pairwise/align_result_selector.hpp @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include namespace seqan3::detail @@ -54,7 +54,7 @@ template struct alignment_type { //!\brief The alignment type with gap decorator. - using type = std::tuple>, gap_decorator>>; + using type = std::tuple>, gap_decorator>>; }; /*!\brief Helper metafunction to select the alignment result type based on the configuration. diff --git a/include/seqan3/alignment/pairwise/alignment_configurator.hpp b/include/seqan3/alignment/pairwise/alignment_configurator.hpp index bd07cd2d6b..703597268e 100644 --- a/include/seqan3/alignment/pairwise/alignment_configurator.hpp +++ b/include/seqan3/alignment/pairwise/alignment_configurator.hpp @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include namespace seqan3::detail @@ -223,8 +223,8 @@ struct alignment_configurator using first_seq_t = std::tuple_element_t<0, value_type_t>; using second_seq_t = std::tuple_element_t<1, value_type_t>; - using wrapped_first_t = all_view; - using wrapped_second_t = all_view; + using wrapped_first_t = type_reduce_view; + using wrapped_second_t = type_reduce_view; // The alignment executor passes a chunk over an indexed sequence pair range to the alignment algorithm. using indexed_sequence_pair_range_t = typename chunked_indexed_sequence_pairs::type; diff --git a/include/seqan3/alignment/pairwise/execution/alignment_executor_two_way.hpp b/include/seqan3/alignment/pairwise/execution/alignment_executor_two_way.hpp index 6b29bb1f9b..19d74a0e9e 100644 --- a/include/seqan3/alignment/pairwise/execution/alignment_executor_two_way.hpp +++ b/include/seqan3/alignment/pairwise/execution/alignment_executor_two_way.hpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include diff --git a/include/seqan3/alignment/pairwise/execution/execution_handler_sequential.hpp b/include/seqan3/alignment/pairwise/execution/execution_handler_sequential.hpp index efda055d9e..845f8cc5ae 100644 --- a/include/seqan3/alignment/pairwise/execution/execution_handler_sequential.hpp +++ b/include/seqan3/alignment/pairwise/execution/execution_handler_sequential.hpp @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include diff --git a/include/seqan3/core/simd/view_to_simd.hpp b/include/seqan3/core/simd/view_to_simd.hpp index afcba4ce3f..06d1d7e328 100644 --- a/include/seqan3/core/simd/view_to_simd.hpp +++ b/include/seqan3/core/simd/view_to_simd.hpp @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include @@ -137,7 +137,7 @@ class view_to_simd : public std::ranges::view_interface //!\endcond constexpr view_to_simd(other_urng_t && urng, scalar_type const padding_value = alphabet_size) : - view_to_simd{views::all(std::forward(urng)), padding_value} + view_to_simd{views::type_reduce(std::forward(urng)), padding_value} {} //!\} @@ -637,7 +637,7 @@ struct to_simd_fn static_assert(semialphabet>>, "The value type of the inner ranges must model seqan3::semialphabet."); - return view_to_simd, simd_t>{std::forward(urange), padding_value}; + return view_to_simd, simd_t>{std::forward(urange), padding_value}; } /*!\brief Call the view's constructor with the underlying std::ranges::viewable_range as argument. @@ -656,7 +656,7 @@ struct to_simd_fn static_assert(semialphabet>>, "The value type of the inner ranges must model seqan3::semialphabet."); - return view_to_simd, simd_t>{std::forward(urange)}; + return view_to_simd, simd_t>{std::forward(urange)}; } //!\brief Overloaded bit-operator to allow chaining with other ranges. diff --git a/include/seqan3/core/type_traits/function.hpp b/include/seqan3/core/type_traits/function.hpp index 903b6b5b53..bcf3c1db3a 100644 --- a/include/seqan3/core/type_traits/function.hpp +++ b/include/seqan3/core/type_traits/function.hpp @@ -23,3 +23,27 @@ * \returns true or false. */ #define SEQAN3_IS_CONSTEXPR(...) std::integral_constant::value + +// ---------------------------------------------------------------------------- +// multi_invocable +// ---------------------------------------------------------------------------- + +namespace seqan3::detail +{ + +/*!\brief A type that can conveniently inherit multiple invocables and acts as a union over them. + * \tparam invocable_ts The types to inherit from. + * \ingroup type_traits + */ +template +struct multi_invocable : invocable_ts... +{ + //!\brief Inherit the function call operators. + using invocable_ts::operator()...; +}; + +//!\brief Deduction guides for seqan3::detail::multi_invocable. +template +multi_invocable(invocable_ts...) -> multi_invocable; + +} // namespace seqan3::detail diff --git a/include/seqan3/io/alignment_file/format_sam_base.hpp b/include/seqan3/io/alignment_file/format_sam_base.hpp index cf6aa3f2a6..850604e3f7 100644 --- a/include/seqan3/io/alignment_file/format_sam_base.hpp +++ b/include/seqan3/io/alignment_file/format_sam_base.hpp @@ -136,7 +136,7 @@ class format_sam_base }; /*!\brief Checks for known reference ids or adds a new reference is and assigns a reference id to `ref_id`. - * \tparam ref_id_type The type of the reference id (usually a views::all over ref_id_tmp_type). + * \tparam ref_id_type The type of the reference id (usually a views::type_reduce over ref_id_tmp_type). * \tparam ref_id_tmp_type The type of the temporary parsed id (same_as type as reference ids in header). * \tparam header_type The type of the alignment header. * \tparam ref_seqs_type A tag whether the reference information were given or not (std::ignore or not). diff --git a/include/seqan3/io/alignment_file/header.hpp b/include/seqan3/io/alignment_file/header.hpp index b7bd63000f..d3631e8a9d 100644 --- a/include/seqan3/io/alignment_file/header.hpp +++ b/include/seqan3/io/alignment_file/header.hpp @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include namespace seqan3 @@ -93,7 +93,7 @@ class alignment_file_header //!\brief The key's type of ref_dict. using key_type = std::conditional_t>, std::span const>, - all_view>>; + type_reduce_view>>; //!\brief The pointer to reference ids information (non-owning if reference information is given). ref_ids_ptr_t ref_ids_ptr{new ref_ids_type{}, ref_ids_deleter_default}; diff --git a/include/seqan3/range/container/concatenated_sequences.hpp b/include/seqan3/range/container/concatenated_sequences.hpp index 2f1dfd1dce..f6b54455dc 100644 --- a/include/seqan3/range/container/concatenated_sequences.hpp +++ b/include/seqan3/range/container/concatenated_sequences.hpp @@ -15,13 +15,12 @@ #include #include -#include - #include #include #include #include #include +#include #include #include #include @@ -50,13 +49,13 @@ namespace seqan3::detail template struct concatenated_sequences_reference_proxy : public std::conditional_t() | ranges::view::const_ | views::slice(0,1)), + decltype(std::declval() | views::as_const | views::slice(0,1)), decltype(std::declval() | views::slice(0,1))> { //!\brief The base type. using base_t = std::conditional_t() | ranges::view::const_ | views::slice(0,1)), + decltype(std::declval() | views::as_const | views::slice(0,1)), decltype(std::declval() | views::slice(0,1))>; //!\brief Inherit the base type's constructors. @@ -565,7 +564,7 @@ class concatenated_sequences const_reference operator[](size_type const i) const { assert(i < size()); - return data_values | ranges::view::const_ | views::slice(data_delimiters[i], data_delimiters[i+1]); + return data_values | views::as_const | views::slice(data_delimiters[i], data_delimiters[i+1]); } /*!\brief Return the first element as a view. Calling front on an empty container is undefined. @@ -640,7 +639,7 @@ class concatenated_sequences //!\copydoc concat() const_reference concat() const { - return data_values | ranges::view::const_ | views::slice(static_cast(0), concat_size()); + return data_values | views::as_const | views::slice(static_cast(0), concat_size()); } /*!\brief Provides direct, unsafe access to underlying data structures. diff --git a/include/seqan3/range/decorator/gap_decorator.hpp b/include/seqan3/range/decorator/gap_decorator.hpp index 37f39956f8..89578db740 100644 --- a/include/seqan3/range/decorator/gap_decorator.hpp +++ b/include/seqan3/range/decorator/gap_decorator.hpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include @@ -137,7 +137,7 @@ class gap_decorator std::same_as, remove_cvref_t> && std::ranges::viewable_range // at end, otherwise it competes with the move ctor //!\endcond - gap_decorator(other_range_t && range) : ungapped_view{views::all(std::forward(range))} + gap_decorator(other_range_t && range) : ungapped_view{views::type_reduce(std::forward(range))} {} // TODO (@smehringer) only works for copyable views. Has to be changed once views are not required to be copyable anymore. // !\} @@ -557,7 +557,7 @@ class gap_decorator } //!\brief Stores a (copy of a) view to the ungapped, underlying sequence. - decltype(views::all(std::declval())) ungapped_view{}; + decltype(views::type_reduce(std::declval())) ungapped_view{}; //!\brief Set storing the anchor gaps. anchor_set_type anchors{}; diff --git a/include/seqan3/range/views/as_const.hpp b/include/seqan3/range/views/as_const.hpp new file mode 100644 index 0000000000..de602445c2 --- /dev/null +++ b/include/seqan3/range/views/as_const.hpp @@ -0,0 +1,90 @@ +// ----------------------------------------------------------------------------------------------------- +// Copyright (c) 2006-2019, Knut Reinert & Freie Universität Berlin +// Copyright (c) 2016-2019, 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 Hannes Hauswedell + * \brief Provides seqan3::views::as_const. + */ + +#pragma once + +#include +#include + +namespace seqan3::detail +{ + +//!\brief Function object for seqan3::views::as_const. +struct as_const_fn +{ + //!\brief Operator that returns rvalues as rvalues. + template + t operator()(t const && arg) const + { + return std::move(arg); + } + + //!\brief Operator that returns lvalue references as lvalue-to-const-references. + template + t const & operator()(t const & arg) const + { + return arg; + } +}; + +} // namespace seqan3::detail + +namespace seqan3::views +{ + +/*!\name General purpose views + * \{ + */ + +/*!\brief A view that provides only `const &` to elements of the underlying range. + * \tparam urng_t The type of the range being processed. See below for requirements. [template parameter is + * omitted in pipe notation] + * \param[in] urange The range being processed. [parameter is omitted in pipe notation] + * \returns A range of `const`-protected elements. + * \ingroup views + * + * \details + * + * \header_file{seqan3/range/views/as_const.hpp} + * + * ### View properties + * + * + * | Concepts and traits | `urng_t` (underlying range type) | `rrng_t` (returned range type) | + * |----------------------------------|:-------------------------------------:|:--------------------------------------------------:| + * | std::ranges::input_range | *required* | *preserved* | + * | std::ranges::forward_range | | *preserved* | + * | std::ranges::bidirectional_range | | *preserved* | + * | std::ranges::random_access_range | | *preserved* | + * | std::ranges::contiguous_range | | *preserved* | + * | | | | + * | std::ranges::viewable_range | *required* | *guaranteed* | + * | std::ranges::view | | *guaranteed* | + * | std::ranges::sized_range | | *preserved* | + * | std::ranges::common_range | | *preserved* | + * | std::ranges::output_range | | *lost* | + * | seqan3::const_iterable_range | | *preserved* | + * | std::semiregular | | *preserved* | + * | | | | + * | std::ranges::range_reference_t | | `t &` -> `t const &` but `t` -> `t` | + * + * See the \link views views submodule documentation \endlink for detailed descriptions of the view properties. + * + * ### Example + * + * \include test/snippet/range/views/as_const.cpp + * \hideinitializer + */ +inline auto const as_const = std::views::transform(seqan3::detail::as_const_fn{}); +//!\} + +} // namespace seqan3::views diff --git a/include/seqan3/range/views/interleave.hpp b/include/seqan3/range/views/interleave.hpp index 0393a8d06c..aa8a53d217 100644 --- a/include/seqan3/range/views/interleave.hpp +++ b/include/seqan3/range/views/interleave.hpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include @@ -100,7 +100,7 @@ class view_interleave : public std::ranges::view_interface //!\cond - requires std::constructible_from()))> && + requires std::constructible_from()))> && std::constructible_from()))> //!\endcond view_interleave(orng_t && _urange, size_t const _step_size, oirng_t && _inserted_range) : - view_interleave{views::all(std::forward(_urange)), _step_size, views::persist(std::forward(_inserted_range))} + view_interleave{views::type_reduce(std::forward(_urange)), _step_size, views::persist(std::forward(_inserted_range))} {} //!\} @@ -254,7 +254,7 @@ template , reference_t> //!\endcond view_interleave(urng_t &&, size_t, inserted_rng_t &&) - -> view_interleave())), decltype(views::persist(std::declval()))>; + -> view_interleave())), decltype(views::persist(std::declval()))>; // ============================================================================ // interleave_fn (adaptor definition) diff --git a/include/seqan3/range/views/move.hpp b/include/seqan3/range/views/move.hpp new file mode 100644 index 0000000000..4e6c09ef04 --- /dev/null +++ b/include/seqan3/range/views/move.hpp @@ -0,0 +1,75 @@ +// ----------------------------------------------------------------------------------------------------- +// Copyright (c) 2006-2019, Knut Reinert & Freie Universität Berlin +// Copyright (c) 2016-2019, 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 Hannes Hauswedell + * \brief Provides seqan3::views::move. + */ + +#pragma once + +#include +#include + +namespace seqan3::views +{ + +/*!\name General purpose views + * \{ + */ + +/*!\brief A view that turns lvalue-references into rvalue-references. + * \tparam urng_t The type of the range being processed. See below for requirements. [template parameter is + * omitted in pipe notation] + * \param[in] urange The range being processed. [parameter is omitted in pipe notation] + * \returns A range whose elements will be moved from. + * \ingroup views + * + * \details + * + * \header_file{seqan3/range/views/move.hpp} + * + * ### View properties + * + * + * | Concepts and traits | `urng_t` (underlying range type) | `rrng_t` (returned range type) | + * |----------------------------------|:-------------------------------------:|:--------------------------------------------------:| + * | std::ranges::input_range | *required* | *preserved* | + * | std::ranges::forward_range | | *preserved* | + * | std::ranges::bidirectional_range | | *preserved* | + * | std::ranges::random_access_range | | *preserved* | + * | std::ranges::contiguous_range | | *preserved* | + * | | | | + * | std::ranges::viewable_range | *required* | *guaranteed* | + * | std::ranges::view | | *guaranteed* | + * | std::ranges::sized_range | | *preserved* | + * | std::ranges::common_range | | *preserved* | + * | std::ranges::output_range | | *lost* | + * | seqan3::const_iterable_range | | *preserved* | + * | std::semiregular | | *preserved* | + * | | | | + * | std::ranges::range_reference_t | | `t &` -> `t &&` but `t` -> `t` | + * + * See the \link views views submodule documentation \endlink for detailed descriptions of the view properties. + * + * ### Example + * + * This is a slightly more verbose version of calling `std::ranges::move` on the range. + * + * \include test/snippet/range/views/move.cpp + * + * A more useful example can be found in \link sequence_file_section_fun_with_ranges the tutorial \endlink. + * \hideinitializer + */ +inline auto const move = std::views::transform(detail::multi_invocable +{ + [] (auto && arg) -> remove_cvref_t { return std::move(arg); }, + [] (auto & arg) -> decltype(auto) { return std::move(arg); } +}); +//!\} + +} // namespace seqan3::views diff --git a/include/seqan3/range/views/view_all.hpp b/include/seqan3/range/views/type_reduce.hpp similarity index 78% rename from include/seqan3/range/views/view_all.hpp rename to include/seqan3/range/views/type_reduce.hpp index 66b2d90ab5..3c2dd3149c 100644 --- a/include/seqan3/range/views/view_all.hpp +++ b/include/seqan3/range/views/type_reduce.hpp @@ -7,7 +7,7 @@ /*!\file * \author Hannes Hauswedell - * \brief Provides seqan3::views::all. + * \brief Provides seqan3::views::type_reduce. */ #pragma once @@ -25,16 +25,16 @@ namespace seqan3::detail { // ============================================================================ -// all_fn (adaptor definition) +// type_reduce_fn (adaptor definition) // ============================================================================ -/*!\brief View adaptor definition for views::all. +/*!\brief View adaptor definition for views::type_reduce. */ -class all_fn : public adaptor_base +class type_reduce_fn : public adaptor_base { private: //!\brief Type of the CRTP-base. - using base_t = adaptor_base; + using base_t = adaptor_base; public: //!\brief Inherit the base class's Constructors. @@ -51,7 +51,7 @@ class all_fn : public adaptor_base static constexpr auto impl(urng_t && urange) { static_assert(std::ranges::viewable_range, - "The views::all adaptor can only be passed viewable_ranges, i.e. Views or &-to-non-View."); + "The views::type_reduce adaptor can only be passed viewable_ranges, i.e. Views or &-to-non-View."); // views are always passed as-is if constexpr (std::ranges::view>) @@ -94,7 +94,7 @@ class all_fn : public adaptor_base } // namespace seqan3::detail // ============================================================================ -// views::all (adaptor instance definition) +// views::type_reduce (adaptor instance definition) // ============================================================================ namespace seqan3::views @@ -104,16 +104,16 @@ namespace seqan3::views * \{ */ -/*!\brief A view adaptor that behaves like std::views::all, but type erases contiguous ranges. +/*!\brief A view adaptor that behaves like std::views::all, but type erases certain ranges. * \tparam urng_t The type of the range being processed. See below for requirements. [template parameter is * omitted in pipe notation] * \param[in] urange The range being processed. [parameter is omitted in pipe notation] - * \returns Either `std::basic_string_view{urange}`, or `std::span{urange}`, or `std::views::all(urange)`. + * \returns The range turned into a view. * \ingroup views * * \details * - * \header_file{seqan3/range/views/view_all.hpp} + * \header_file{seqan3/range/views/view_type_reduce.hpp} * * ### View properties * @@ -124,37 +124,38 @@ namespace seqan3::views * | std::ranges::bidirectional_range | | *preserved* | * | std::ranges::random_access_range | | *preserved* | * | std::ranges::contiguous_range | | *preserved* | - * | | | | + * | | | | * | std::ranges::viewable_range | *required* | *guaranteed* | * | std::ranges::view | | *guaranteed* | * | std::ranges::sized_range | | *preserved* | * | std::ranges::common_range | | *preserved* | * | std::ranges::output_range | | *preserved* | * | seqan3::const_iterable_range | | *preserved* | - * | | | | + * | | | | * | std::ranges::range_reference_t | | seqan3::reference_t | * * See the \link views views submodule documentation \endlink for detailed descriptions of the view properties. * * ### Return type * - * | `urng_t` (underlying range type) | `rrng_t` (returned range type) | - * |:--------------------------------------------------------------------------------------:|:-------------------------------:| - * | `std::basic_string const &` *or* `std::basic_string_view` | `std::basic_string_view` | - * | `seqan3::forwarding_range && std::ranges::sized_range && std::ranges::contiguous_range` | `std::span` | - * | `seqan3::forwarding_range && std::ranges::sized_range && std::ranges::random_access_range` | `std::ranges::subrange` | - * | *else* | *implementation defined type* | + * | `urng_t` (underlying range type) | `rrng_t` (returned range type) | + * |:----------------------------------------------------------------------------------------------:|:-------------------------------:| + * | `std::ranges::view` | `urng_t` | + * | `std::basic_string const &` *or* `std::basic_string_view` | `std::basic_string_view` | + * | `seqan3::forwarding_range && std::ranges::sized_range && std::ranges::contiguous_range` | `std::span` | + * | `seqan3::forwarding_range && std::ranges::sized_range && std::ranges::random_access_range` | `std::ranges::subrange` | + * | *else* | `std::ranges::ref_view` | * - * This adaptor is different from std::views::take in that it performs type erasure for some underlying ranges. - * It returns exactly the type specified above. + * This adaptor is different from std::views::all in that it performs type erasure for some underlying ranges; + * std::views::all always returns `std::ranges::ref_view` or the type itself if it already is a view. * * ### Example * -* \include test/snippet/range/views/view_all.cpp +* \include test/snippet/range/views/type_reduce.cpp * * \hideinitializer */ -inline constexpr auto all = detail::all_fn{}; +inline constexpr auto type_reduce = detail::type_reduce_fn{}; //!\} @@ -162,7 +163,7 @@ inline constexpr auto all = detail::all_fn{}; namespace seqan3 { -//!\brief Deduces the return value of seqan3::views::all. +//!\brief Deduces the return value of seqan3::views::type_reduce. template -using all_view = decltype(views::all(std::declval())); +using type_reduce_view = decltype(views::type_reduce(std::declval())); } diff --git a/test/performance/range/views/view_all_benchmark.cpp b/test/performance/range/views/view_all_benchmark.cpp index 6fb78e83cb..a43a47ed38 100644 --- a/test/performance/range/views/view_all_benchmark.cpp +++ b/test/performance/range/views/view_all_benchmark.cpp @@ -12,7 +12,7 @@ #include -#include +#include using namespace seqan3; @@ -57,22 +57,22 @@ void sequential_read(benchmark::State & state) BENCHMARK_TEMPLATE(sequential_read, std::string, void); BENCHMARK_TEMPLATE(sequential_read, std::string, decltype(std::views::all)); BENCHMARK_TEMPLATE(sequential_read, std::string, decltype(::ranges::view::all)); -BENCHMARK_TEMPLATE(sequential_read, std::string, decltype(seqan3::views::all)); +BENCHMARK_TEMPLATE(sequential_read, std::string, decltype(seqan3::views::type_reduce)); BENCHMARK_TEMPLATE(sequential_read, std::vector, void); BENCHMARK_TEMPLATE(sequential_read, std::vector, decltype(std::views::all)); BENCHMARK_TEMPLATE(sequential_read, std::vector, decltype(::ranges::view::all)); -BENCHMARK_TEMPLATE(sequential_read, std::vector, decltype(seqan3::views::all)); +BENCHMARK_TEMPLATE(sequential_read, std::vector, decltype(seqan3::views::type_reduce)); BENCHMARK_TEMPLATE(sequential_read, std::deque, void); BENCHMARK_TEMPLATE(sequential_read, std::deque, decltype(std::views::all)); BENCHMARK_TEMPLATE(sequential_read, std::deque, decltype(::ranges::view::all)); -BENCHMARK_TEMPLATE(sequential_read, std::deque, decltype(seqan3::views::all)); +BENCHMARK_TEMPLATE(sequential_read, std::deque, decltype(seqan3::views::type_reduce)); BENCHMARK_TEMPLATE(sequential_read, std::list, void); BENCHMARK_TEMPLATE(sequential_read, std::list, decltype(std::views::all)); BENCHMARK_TEMPLATE(sequential_read, std::list, decltype(::ranges::view::all)); -BENCHMARK_TEMPLATE(sequential_read, std::list, decltype(seqan3::views::all)); +BENCHMARK_TEMPLATE(sequential_read, std::list, decltype(seqan3::views::type_reduce)); // ============================================================================ // run diff --git a/test/snippet/range/views/as_const.cpp b/test/snippet/range/views/as_const.cpp new file mode 100644 index 0000000000..ca8892cd7a --- /dev/null +++ b/test/snippet/range/views/as_const.cpp @@ -0,0 +1,21 @@ +#include + +#include +#include + +template +void foobar(rng_t const & range) +{ + range[0] = 'A'; +} + +int main() +{ + std::string s{"CCC"}; + auto v0 = std::views::all(s); + foobar(v0); // this is valid and will update s to "ACC" + // because const-ness of view does not protect elements + + auto v1 = seqan3::views::as_const(s); + // foobar(v1); // this is invalid, views::as_const protects elements +} diff --git a/test/snippet/range/views/move.cpp b/test/snippet/range/views/move.cpp new file mode 100644 index 0000000000..f55e9c7edb --- /dev/null +++ b/test/snippet/range/views/move.cpp @@ -0,0 +1,19 @@ +#include + +#include +#include + +int main() +{ + std::vector vec_in{"ABC", "DEF", "GEH"}; + + std::vector vec_out0{}; + vec_out0.resize(3); + std::ranges::copy(vec_in, // copies strings from in to out + vec_out0.begin()); + + std::vector vec_out1{}; + vec_out1.resize(3); + std::ranges::copy(vec_in | seqan3::views::move, // moves strings from in to out + vec_out1.begin()); +} diff --git a/test/snippet/range/views/type_reduce.cpp b/test/snippet/range/views/type_reduce.cpp new file mode 100644 index 0000000000..594430f980 --- /dev/null +++ b/test/snippet/range/views/type_reduce.cpp @@ -0,0 +1,16 @@ +#include +#include + +#include +#include + +int main() +{ + std::string const vec{"foobar"}; + auto v = vec | seqan3::views::type_reduce; // pipe notation; v is of type std::string_view + seqan3::debug_stream << v << '\n'; // "foobar" + + std::vector vec2{1, 2, 3}; + auto v2 = seqan3::views::type_reduce(vec2); // functional notation; v2 is of type std::span + seqan3::debug_stream << v2 << '\n'; // "[1, 2, 3]" +} diff --git a/test/snippet/range/views/view_all.cpp b/test/snippet/range/views/view_all.cpp deleted file mode 100644 index 511b0098df..0000000000 --- a/test/snippet/range/views/view_all.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include - -#include -#include // provides views::all, attention not ! - -int main() -{ - std::string vec{"foobar"}; - auto v = vec | seqan3::views::all; // pipe notation; v is of type std::string_view - seqan3::debug_stream << v << '\n'; // "foobar" - - std::vector vec2{1, 2, 3}; - auto v2 = seqan3::views::all(vec2); // functional notation; v is of type std::span - seqan3::debug_stream << v2 << '\n'; // "[1, 2, 3]" -} diff --git a/test/unit/alignment/pairwise/align_result_selector_test.cpp b/test/unit/alignment/pairwise/align_result_selector_test.cpp index 6d6533aec5..c00855ef4a 100644 --- a/test/unit/alignment/pairwise/align_result_selector_test.cpp +++ b/test/unit/alignment/pairwise/align_result_selector_test.cpp @@ -20,7 +20,7 @@ #include #include #include -#include +#include using namespace seqan3; @@ -74,7 +74,7 @@ TEST(alignment_selector, align_result_selector_with_vector) auto cfg = align_cfg::edit | align_cfg::result{with_alignment}; using _t = alignment_result::type>; - using gapped_seq_t = gap_decorator &>>; + using gapped_seq_t = gap_decorator &>>; EXPECT_TRUE((std::is_same_v().id()), uint32_t>)); EXPECT_TRUE((std::is_same_v().score()), int32_t>)); diff --git a/test/unit/alignment/pairwise/execution/alignment_executor_two_way_test.cpp b/test/unit/alignment/pairwise/execution/alignment_executor_two_way_test.cpp index e3a5e48508..2f44a825a3 100644 --- a/test/unit/alignment/pairwise/execution/alignment_executor_two_way_test.cpp +++ b/test/unit/alignment/pairwise/execution/alignment_executor_two_way_test.cpp @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include #include diff --git a/test/unit/alignment/pairwise/execution/execution_handler_template.hpp b/test/unit/alignment/pairwise/execution/execution_handler_template.hpp index ff3ed45f7f..19711ba564 100644 --- a/test/unit/alignment/pairwise/execution/execution_handler_template.hpp +++ b/test/unit/alignment/pairwise/execution/execution_handler_template.hpp @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include #include diff --git a/test/unit/core/simd/view_to_simd_test.cpp b/test/unit/core/simd/view_to_simd_test.cpp index d99def141a..f2ea8635fd 100644 --- a/test/unit/core/simd/view_to_simd_test.cpp +++ b/test/unit/core/simd/view_to_simd_test.cpp @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -87,7 +87,7 @@ class view_to_simd_test : public ::testing::Test std::vector transformed_simd_vec{}; std::vector transformed_simd_vec_padded{}; - using view_to_simd_type = detail::view_to_simd &>, simd_t>; + using view_to_simd_type = detail::view_to_simd &>, simd_t>; }; using test_types = ::testing::Types, simd_type_t>, @@ -113,7 +113,7 @@ TYPED_TEST_CASE(view_to_simd_test, test_types); TEST(view_to_simd, concept_check) { using cmp_type = std::vector; - using test_type = detail::view_to_simd, simd_type_t>; + using test_type = detail::view_to_simd, simd_type_t>; using iter_t = decltype(std::ranges::begin(std::declval())); EXPECT_TRUE(std::input_iterator); @@ -135,7 +135,7 @@ TEST(view_to_simd, concept_check) TEST(view_to_simd, iter_concept) { using cmp_type = std::vector; - using test_type = detail::view_to_simd, simd_type_t>; + using test_type = detail::view_to_simd, simd_type_t>; using iter_t = std::ranges::iterator_t; using sent_t = std::ranges::sentinel_t; diff --git a/test/unit/range/views/CMakeLists.txt b/test/unit/range/views/CMakeLists.txt index 8942663619..4bc1f53f27 100644 --- a/test/unit/range/views/CMakeLists.txt +++ b/test/unit/range/views/CMakeLists.txt @@ -1,7 +1,7 @@ add_subdirectories() seqan3_test(adaptor_base_test.cpp) -seqan3_test(view_all_test.cpp) +seqan3_test(view_as_const_test.cpp) seqan3_test(view_async_input_buffer_test.cpp) seqan3_test(view_char_to_test.cpp) seqan3_test(view_complement_test.cpp) @@ -11,10 +11,12 @@ seqan3_test(view_enforce_random_access_test.cpp) seqan3_test(view_pairwise_combine_test.cpp) seqan3_test(view_drop_test.cpp) seqan3_test(view_istreambuf_test.cpp) +seqan3_test(view_move_test.cpp) seqan3_test(view_persist_test.cpp) seqan3_test(view_rank_to_test.cpp) seqan3_test(view_repeat_n_test.cpp) seqan3_test(view_repeat_test.cpp) +seqan3_test(view_type_reduce_test.cpp) seqan3_test(view_slice_test.cpp) seqan3_test(view_take_test.cpp) seqan3_test(view_take_until_test.cpp) diff --git a/test/unit/range/views/view_as_const_test.cpp b/test/unit/range/views/view_as_const_test.cpp new file mode 100644 index 0000000000..7aa5c36b5c --- /dev/null +++ b/test/unit/range/views/view_as_const_test.cpp @@ -0,0 +1,72 @@ +// ----------------------------------------------------------------------------------------------------- +// Copyright (c) 2006-2019, Knut Reinert & Freie Universität Berlin +// Copyright (c) 2016-2019, 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 +#include +#include +#include +#include +#include + +using seqan3::operator""_dna5; + +TEST(view_as_const, basic) +{ + std::string vec{"ACTTTGATA"}; + + // pipe notation + auto v = vec | seqan3::views::as_const; + EXPECT_TRUE((std::ranges::equal(vec, v))); + + // function notation + auto v2(seqan3::views::as_const(vec)); + EXPECT_TRUE((std::ranges::equal(vec, v2))); + + // combinability + seqan3::dna5_vector vec2{"ACGTA"_dna5}; + seqan3::dna5_vector v3 = vec2 + | seqan3::views::complement + | seqan3::views::as_const + | seqan3::views::to; + EXPECT_EQ("TGCAT"_dna5, v3); +} + +TEST(view_as_const, concepts) +{ + std::string vec{"ACTTTGATA"}; + auto v1 = vec | seqan3::views::as_const; + EXPECT_TRUE(std::ranges::input_range); + EXPECT_TRUE(std::ranges::forward_range); + EXPECT_TRUE(std::ranges::bidirectional_range); + EXPECT_TRUE(std::ranges::random_access_range); + EXPECT_TRUE(std::ranges::view); + EXPECT_TRUE(std::ranges::sized_range); + EXPECT_TRUE(std::ranges::common_range); + EXPECT_TRUE(seqan3::const_iterable_range); + EXPECT_FALSE((std::ranges::output_range)); + + EXPECT_TRUE((std::is_same_v)); + + auto v2 = vec | seqan3::views::to_lower | seqan3::views::as_const; // to_lower generates values + EXPECT_TRUE(std::ranges::input_range); + EXPECT_TRUE(std::ranges::forward_range); + EXPECT_TRUE(std::ranges::bidirectional_range); + EXPECT_TRUE(std::ranges::random_access_range); + EXPECT_TRUE(std::ranges::view); + EXPECT_TRUE(std::ranges::sized_range); + EXPECT_TRUE(std::ranges::common_range); + EXPECT_TRUE(seqan3::const_iterable_range); + EXPECT_FALSE((std::ranges::output_range)); + + EXPECT_TRUE((std::is_same_v)); // don't add const-ness to values +} diff --git a/test/unit/range/views/view_interleave_test.cpp b/test/unit/range/views/view_interleave_test.cpp index 4c274c25f8..93034954b9 100644 --- a/test/unit/range/views/view_interleave_test.cpp +++ b/test/unit/range/views/view_interleave_test.cpp @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include @@ -29,27 +29,27 @@ TEST(view_interleave, basic) size_t cmpsize = 18; // pipe notation - // explicitly call views::all - auto v0 = views::all(u) | views::interleave(s, views::all(i)); + // explicitly call views::type_reduce + auto v0 = views::type_reduce(u) | views::interleave(s, views::type_reduce(i)); EXPECT_TRUE(ranges::equal(cmp, v0)); EXPECT_EQ(cmpsize, v0.size()); - // don't call views::all + // don't call views::type_reduce auto v1 = u | views::interleave(s, i); EXPECT_TRUE(ranges::equal(cmp, v1)); // function notation - // explicitly call views::all - auto v2{views::interleave(views::all(u), s, views::all(i))}; + // explicitly call views::type_reduce + auto v2{views::interleave(views::type_reduce(u), s, views::type_reduce(i))}; EXPECT_TRUE(ranges::equal(cmp, v2)); - // don't call views::all + // don't call views::type_reduce auto v3{views::interleave(u, s, i)}; EXPECT_TRUE(ranges::equal(cmp, v3)); //combinability - // explicitly call views::all - auto v4 = views::all(u) | views::interleave(s, views::all(i)) | std::views::reverse | views::take(5); + // explicitly call views::type_reduce + auto v4 = views::type_reduce(u) | views::interleave(s, views::type_reduce(i)) | std::views::reverse | views::take(5); EXPECT_TRUE(ranges::equal(cmp_rev, v4)); - // don't call views::all + // don't call views::type_reduce auto v5 = u | views::interleave(s, i) | std::views::reverse | views::take(5); EXPECT_TRUE(ranges::equal(cmp_rev, v5)); } @@ -60,7 +60,7 @@ TEST(view_interleave, concepts) std::string u{"FOOBARBAXBAT"}; std::string i{"in"}; size_t s = 3; - auto v1 = detail::view_interleave(views::all(u), s, views::all(i)); + auto v1 = detail::view_interleave(views::type_reduce(u), s, views::type_reduce(i)); EXPECT_TRUE(std::ranges::input_range); EXPECT_TRUE(std::ranges::forward_range); diff --git a/test/unit/range/views/view_move_test.cpp b/test/unit/range/views/view_move_test.cpp new file mode 100644 index 0000000000..be509cc62a --- /dev/null +++ b/test/unit/range/views/view_move_test.cpp @@ -0,0 +1,72 @@ +// ----------------------------------------------------------------------------------------------------- +// Copyright (c) 2006-2019, Knut Reinert & Freie Universität Berlin +// Copyright (c) 2016-2019, 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 +#include +#include +#include +#include +#include + +using seqan3::operator""_dna5; + +TEST(view_move, basic) +{ + std::string vec{"ACTTTGATA"}; + + // pipe notation + auto v = vec | seqan3::views::move; + EXPECT_TRUE((std::ranges::equal(vec, v))); // equality comparison does not move + + // function notation + auto v2(seqan3::views::move(vec)); + EXPECT_TRUE((std::ranges::equal(vec, v2))); // equality comparison does not move + + // combinability + seqan3::dna5_vector vec2{"ACGTA"_dna5}; + seqan3::dna5_vector v3 = vec2 + | seqan3::views::complement + | seqan3::views::move // NOP, because already temporaries + | seqan3::views::to; + EXPECT_EQ("TGCAT"_dna5, v3); +} + +TEST(view_move, concepts) +{ + std::string vec{"ACTTTGATA"}; + auto v1 = vec | seqan3::views::move; + EXPECT_TRUE(std::ranges::input_range); + EXPECT_TRUE(std::ranges::forward_range); + EXPECT_TRUE(std::ranges::bidirectional_range); + EXPECT_TRUE(std::ranges::random_access_range); + EXPECT_TRUE(std::ranges::view); + EXPECT_TRUE(std::ranges::sized_range); + EXPECT_TRUE(std::ranges::common_range); + EXPECT_TRUE(seqan3::const_iterable_range); + EXPECT_FALSE((std::ranges::output_range)); + + EXPECT_TRUE((std::is_same_v)); + + auto v2 = vec | seqan3::views::to_lower | seqan3::views::move; // to_lower generates values + EXPECT_TRUE(std::ranges::input_range); + EXPECT_TRUE(std::ranges::forward_range); + EXPECT_TRUE(std::ranges::bidirectional_range); + EXPECT_TRUE(std::ranges::random_access_range); + EXPECT_TRUE(std::ranges::view); + EXPECT_TRUE(std::ranges::sized_range); + EXPECT_TRUE(std::ranges::common_range); + EXPECT_TRUE(seqan3::const_iterable_range); + EXPECT_FALSE((std::ranges::output_range)); + + EXPECT_TRUE((std::is_same_v)); // don't add const-ness to values +} diff --git a/test/unit/range/views/view_all_test.cpp b/test/unit/range/views/view_type_reduce_test.cpp similarity index 83% rename from test/unit/range/views/view_all_test.cpp rename to test/unit/range/views/view_type_reduce_test.cpp index 82eca62222..0f7097345f 100644 --- a/test/unit/range/views/view_all_test.cpp +++ b/test/unit/range/views/view_type_reduce_test.cpp @@ -13,7 +13,7 @@ #include -#include +#include #include #include #include @@ -24,12 +24,12 @@ using namespace seqan3; // test templates // ============================================================================ -TEST(view_all, string_overload) +TEST(type_reduce, string_overload) { { std::string urange{"foobar"}; - auto v = views::all(urange); + auto v = views::type_reduce(urange); EXPECT_FALSE((std::same_as)); // only returns string_view for string const EXPECT_TRUE((std::ranges::equal(v, urange))); @@ -39,7 +39,7 @@ TEST(view_all, string_overload) std::string urange_{"foobar"}; std::string_view urange{urange_}; - auto v = views::all(urange); + auto v = views::type_reduce(urange); EXPECT_TRUE((std::same_as)); EXPECT_TRUE((std::ranges::equal(v, urange))); @@ -48,19 +48,19 @@ TEST(view_all, string_overload) { std::string const urange{"foobar"}; - auto v = views::all(urange); + auto v = views::type_reduce(urange); EXPECT_TRUE((std::same_as)); EXPECT_TRUE((std::ranges::equal(v, urange))); } } -TEST(view_all, contiguous_overload) +TEST(type_reduce, contiguous_overload) { { std::vector urange{1, 2, 3, 4, 5, 6}; - auto v = views::all(urange); + auto v = views::type_reduce(urange); EXPECT_TRUE((std::same_as>)); EXPECT_TRUE((std::ranges::equal(v, urange))); @@ -69,30 +69,30 @@ TEST(view_all, contiguous_overload) { std::array urange{1, 2, 3, 4, 5, 6}; - auto v = views::all(urange); + auto v = views::type_reduce(urange); EXPECT_TRUE((std::same_as>)); EXPECT_TRUE((std::ranges::equal(v, urange))); } } -TEST(view_all, random_access_overload) +TEST(type_reduce, random_access_overload) { std::deque urange{1, 2, 3, 4, 5, 6}; - auto v = views::all(urange); + auto v = views::type_reduce(urange); EXPECT_TRUE((std::same_as::iterator, typename std::deque::iterator>>)); EXPECT_TRUE((std::ranges::equal(v, urange))); } -TEST(view_all, generic_overload) +TEST(type_reduce, generic_overload) { { // bidirectional container std::list urange{1, 2, 3, 4, 5, 6}; - auto v = views::all(urange); + auto v = views::type_reduce(urange); EXPECT_TRUE((std::same_as &>>)); EXPECT_TRUE((std::ranges::equal(v, urange))); @@ -102,7 +102,7 @@ TEST(view_all, generic_overload) std::array urange{1, 2, 3, 4, 5, 6}; auto v = urange | std::views::filter([] (int) { return true; }); - auto v2 = views::all(v); + auto v2 = views::type_reduce(v); EXPECT_TRUE((std::same_as>)); EXPECT_TRUE((std::ranges::equal(v2, urange)));