From 49f7ecfd36d6e03dd7eb8b1e391a7d9c7c2c4899 Mon Sep 17 00:00:00 2001 From: Enrico Seiler Date: Mon, 26 Feb 2024 18:45:29 +0100 Subject: [PATCH 1/2] [MISC] Workaround: PR2165 --- include/seqan3/io/record.hpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/include/seqan3/io/record.hpp b/include/seqan3/io/record.hpp index 3ca560b744..c4c9b4e4cf 100644 --- a/include/seqan3/io/record.hpp +++ b/include/seqan3/io/record.hpp @@ -188,6 +188,10 @@ struct fields template struct record : detail::transfer_template_args_onto_t { +public: + //!\brief A specialisation of std::tuple. + using base_type = detail::transfer_template_args_onto_t; + private: //!\brief Auxiliary functions for clear(). template @@ -210,10 +214,13 @@ struct record : detail::transfer_template_args_onto_t (clear_element(args), ...); }; -public: - //!\brief A specialisation of std::tuple. - using base_type = detail::transfer_template_args_onto_t; + //!\brief Returns the tuple as the underlying std::tuple type. + base_type & as_base() noexcept + { + return *this; + } +public: /*!\name Constructors, destructor and assignment * \{ */ @@ -232,9 +239,12 @@ struct record : detail::transfer_template_args_onto_t "You must give as many IDs as types to seqan3::record."); //!\brief Clears containers that provide `.clear()` and (re-)initialises all other elements with `= {}`. - void clear() noexcept(noexcept(std::apply(expander, std::declval()))) + void clear() noexcept(noexcept(std::apply(expander, std::declval().as_base()))) { - std::apply(expander, *this); + // PR2165 / __cpp_lib_tuple_like (C++23): std::apply requires tuple-like. + // In C++23, this means std::array, std::pair, std::tuple, and std::ranges::subranges. Nothing else. + // https://en.cppreference.com/w/cpp/utility/tuple/tuple-like + std::apply(expander, as_base()); } protected: From 4311ad5a61cd93e6223f67e238e9eac2bbf091c9 Mon Sep 17 00:00:00 2001 From: Enrico Seiler Date: Mon, 26 Feb 2024 19:43:09 +0100 Subject: [PATCH 2/2] [MISC] Workaround: GCC Bug 114013 --- include/seqan3/core/platform.hpp | 11 +++++ .../detail/search_scheme_precomputed.hpp | 45 ++++++++++--------- test/documentation/seqan3_doxygen_cfg.in | 3 +- 3 files changed, 37 insertions(+), 22 deletions(-) diff --git a/include/seqan3/core/platform.hpp b/include/seqan3/core/platform.hpp index aec8b8aad8..a1b81729f1 100644 --- a/include/seqan3/core/platform.hpp +++ b/include/seqan3/core/platform.hpp @@ -238,6 +238,17 @@ static_assert(sdsl::sdsl_version_major == 3, "Only version 3 of the SDSL is supp # endif #endif +/*!\brief Workaround for variable template specialisations not being emitted. + * \see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114013 + */ +#ifndef SEQAN3_WORKAROUND_GCC_114013 +# if SEQAN3_COMPILER_IS_GCC && (__GNUC__ == 14) +# define SEQAN3_WORKAROUND_GCC_114013 constexpr +# else +# define SEQAN3_WORKAROUND_GCC_114013 inline constexpr +# endif +#endif + /*!\brief This is needed to support CentOS 7 or RHEL 7; Newer CentOS's include a more modern default-gcc version making * this macro obsolete. * diff --git a/include/seqan3/search/detail/search_scheme_precomputed.hpp b/include/seqan3/search/detail/search_scheme_precomputed.hpp index eddabbacff..85e1bfa409 100644 --- a/include/seqan3/search/detail/search_scheme_precomputed.hpp +++ b/include/seqan3/search/detail/search_scheme_precomputed.hpp @@ -24,7 +24,7 @@ template struct search { //!\brief Type for storing the length of blocks - typedef std::array blocks_length_type; + using blocks_length_type = std::array; //!\brief Order of blocks std::array pi; @@ -46,7 +46,7 @@ struct search struct search_dyn { //!\brief Type for storing the length of blocks - typedef std::vector blocks_length_type; + using blocks_length_type = std::vector; //!\brief Order of blocks std::vector pi; @@ -81,60 +81,63 @@ using search_scheme_dyn_type = std::vector; * seems to be a good greedy approach. */ template -inline constexpr int optimum_search_scheme{0}; +SEQAN3_WORKAROUND_GCC_114013 int optimum_search_scheme{0}; //!\cond template <> -inline constexpr search_scheme_type<1, 1> optimum_search_scheme<0, 0>{{{{1}, {0}, {0}}}}; +SEQAN3_WORKAROUND_GCC_114013 search_scheme_type<1, 1> optimum_search_scheme<0, 0>{{{{1}, {0}, {0}}}}; template <> -inline constexpr search_scheme_type<2, 2> optimum_search_scheme<0, 1>{ +SEQAN3_WORKAROUND_GCC_114013 search_scheme_type<2, 2> optimum_search_scheme<0, 1>{ {{{1, 2}, {0, 0}, {0, 1}}, {{2, 1}, {0, 1}, {0, 1}}}}; template <> -inline constexpr search_scheme_type<2, 2> optimum_search_scheme<1, 1>{ +SEQAN3_WORKAROUND_GCC_114013 search_scheme_type<2, 2> optimum_search_scheme<1, 1>{ {{{1, 2}, {0, 1}, {0, 1}}, {{2, 1}, {0, 1}, {0, 1}}}}; template <> -inline constexpr search_scheme_type<3, 4> optimum_search_scheme<0, 2>{{{{1, 2, 3, 4}, {0, 0, 1, 1}, {0, 0, 2, 2}}, - {{3, 2, 1, 4}, {0, 0, 0, 0}, {0, 1, 1, 2}}, - {{4, 3, 2, 1}, {0, 0, 0, 2}, {0, 1, 2, 2}}}}; +SEQAN3_WORKAROUND_GCC_114013 search_scheme_type<3, 4> optimum_search_scheme<0, 2>{ + {{{1, 2, 3, 4}, {0, 0, 1, 1}, {0, 0, 2, 2}}, + {{3, 2, 1, 4}, {0, 0, 0, 0}, {0, 1, 1, 2}}, + {{4, 3, 2, 1}, {0, 0, 0, 2}, {0, 1, 2, 2}}}}; template <> -inline constexpr search_scheme_type<3, 4> optimum_search_scheme<1, 2>{{{{1, 2, 3, 4}, {0, 0, 0, 1}, {0, 0, 2, 2}}, - {{3, 2, 1, 4}, {0, 0, 1, 1}, {0, 1, 1, 2}}, - {{4, 3, 2, 1}, {0, 0, 0, 2}, {0, 1, 2, 2}}}}; +SEQAN3_WORKAROUND_GCC_114013 search_scheme_type<3, 4> optimum_search_scheme<1, 2>{ + {{{1, 2, 3, 4}, {0, 0, 0, 1}, {0, 0, 2, 2}}, + {{3, 2, 1, 4}, {0, 0, 1, 1}, {0, 1, 1, 2}}, + {{4, 3, 2, 1}, {0, 0, 0, 2}, {0, 1, 2, 2}}}}; template <> -inline constexpr search_scheme_type<3, 4> optimum_search_scheme<2, 2>{{{{4, 3, 2, 1}, {0, 0, 1, 2}, {0, 0, 2, 2}}, - {{2, 3, 4, 1}, {0, 0, 0, 2}, {0, 1, 1, 2}}, - {{1, 2, 3, 4}, {0, 0, 0, 2}, {0, 1, 2, 2}}}}; +SEQAN3_WORKAROUND_GCC_114013 search_scheme_type<3, 4> optimum_search_scheme<2, 2>{ + {{{4, 3, 2, 1}, {0, 0, 1, 2}, {0, 0, 2, 2}}, + {{2, 3, 4, 1}, {0, 0, 0, 2}, {0, 1, 1, 2}}, + {{1, 2, 3, 4}, {0, 0, 0, 2}, {0, 1, 2, 2}}}}; +// TODO: benchmark whether the first search is really the fastest one (see \details of optimum_search_scheme) template <> -inline constexpr search_scheme_type<4, 5> optimum_search_scheme<0, 3>{ - {// TODO: benchmark whether the first search is really the fastest one (see \details of optimum_search_scheme) - {{5, 4, 3, 2, 1}, {0, 0, 0, 0, 0}, {0, 0, 3, 3, 3}}, +SEQAN3_WORKAROUND_GCC_114013 search_scheme_type<4, 5> optimum_search_scheme<0, 3>{ + {{{5, 4, 3, 2, 1}, {0, 0, 0, 0, 0}, {0, 0, 3, 3, 3}}, {{3, 4, 5, 2, 1}, {0, 0, 1, 1, 1}, {0, 1, 1, 2, 3}}, {{2, 3, 4, 5, 1}, {0, 0, 0, 2, 2}, {0, 1, 2, 2, 3}}, {{1, 2, 3, 4, 5}, {0, 0, 0, 0, 3}, {0, 2, 2, 3, 3}}}}; template <> -inline constexpr search_scheme_type<4, 5> optimum_search_scheme<1, 3>{ +SEQAN3_WORKAROUND_GCC_114013 search_scheme_type<4, 5> optimum_search_scheme<1, 3>{ {{{5, 4, 3, 2, 1}, {0, 0, 0, 0, 1}, {0, 0, 3, 3, 3}}, {{3, 4, 5, 2, 1}, {0, 0, 1, 1, 1}, {0, 1, 1, 2, 3}}, {{2, 3, 4, 5, 1}, {0, 0, 0, 2, 2}, {0, 1, 2, 2, 3}}, {{1, 2, 3, 4, 5}, {0, 0, 0, 0, 3}, {0, 2, 2, 3, 3}}}}; template <> -inline constexpr search_scheme_type<4, 5> optimum_search_scheme<2, 3>{ +SEQAN3_WORKAROUND_GCC_114013 search_scheme_type<4, 5> optimum_search_scheme<2, 3>{ {{{5, 4, 3, 2, 1}, {0, 0, 0, 0, 2}, {0, 0, 3, 3, 3}}, {{3, 4, 5, 2, 1}, {0, 0, 1, 1, 2}, {0, 1, 1, 2, 3}}, {{2, 3, 4, 5, 1}, {0, 0, 0, 2, 2}, {0, 1, 2, 2, 3}}, {{1, 2, 3, 4, 5}, {0, 0, 0, 0, 3}, {0, 2, 2, 3, 3}}}}; template <> -inline constexpr search_scheme_type<4, 5> optimum_search_scheme<3, 3>{ +SEQAN3_WORKAROUND_GCC_114013 search_scheme_type<4, 5> optimum_search_scheme<3, 3>{ {{{5, 4, 3, 2, 1}, {0, 0, 0, 0, 3}, {0, 0, 3, 3, 3}}, {{3, 4, 5, 2, 1}, {0, 0, 1, 1, 3}, {0, 1, 1, 2, 3}}, {{2, 3, 4, 5, 1}, {0, 0, 0, 2, 3}, {0, 1, 2, 2, 3}}, diff --git a/test/documentation/seqan3_doxygen_cfg.in b/test/documentation/seqan3_doxygen_cfg.in index bc18d57383..5b498980d1 100644 --- a/test/documentation/seqan3_doxygen_cfg.in +++ b/test/documentation/seqan3_doxygen_cfg.in @@ -354,7 +354,8 @@ PREDEFINED = CEREAL_SERIALIZE_FUNCTION_NAME=serialize \ __cpp_lib_three_way_comparison=1 \ SEQAN3_WORKAROUND_LITERAL=constexpr EXPAND_AS_DEFINED = SEQAN3_CPO_OVERLOAD_BODY \ - SEQAN3_CPO_OVERLOAD + SEQAN3_CPO_OVERLOAD \ + SEQAN3_WORKAROUND_GCC_114013 SKIP_FUNCTION_MACROS = NO #--------------------------------------------------------------------------- # Configuration options related to external references