From a4c44cab889ba8f7bb107b048cb5eaf0e5e77672 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 31 May 2020 14:02:54 +0300 Subject: [PATCH] treewide: update concepts language from the Concepts TS to C++20 Seastar recently lost support for the experimental Concepts Technical Specification (TS) and gained support for C++20 concepts. Re-enable concepts in Scylla by updating our use of concepts to the C++20 standard. This change: - peels off uses of the GCC6_CONCEPT macro - removes inclusions of - replaces function-style concepts (no longer supported) with equation-style concepts - semicolons added and removed as needed - deprecated std::is_pod replaced by recommended replacement - updates return type constraints to use concepts instead of type names (either std::same_as or std::convertible_to, with std::same_as chosen when possible) No attempt is made to improve the concepts; this is a specification update only. Message-Id: <20200531110254.2555854-1-avi@scylladb.com> --- CMakeLists.txt | 4 -- atomic_cell.hh | 1 - clustering_bounds_comparator.hh | 8 +-- collection_mutation.cc | 10 +-- concrete_types.hh | 62 +++++++++---------- configure.py | 4 -- counters.hh | 8 +-- cql3/query_options.hh | 20 +++--- cql3/result_set.hh | 11 +--- cql3/statements/select_statement.cc | 8 +-- data/cell.hh | 10 ++- data/cell_impl.hh | 14 ++--- db/commitlog/commitlog.cc | 2 +- flat_mutation_reader.hh | 91 +++++++++++----------------- hashing.hh | 41 ++++++------- idl-compiler.py | 2 +- imr/alloc.hh | 6 +- imr/compound.hh | 19 +++--- imr/concepts.hh | 9 +-- imr/fundamental.hh | 33 +++++----- imr/utils.hh | 8 +-- lua.cc | 32 +++++----- mutation_compactor.hh | 64 +++++++------------ mutation_fragment.hh | 89 ++++++++++----------------- mutation_partition_view.cc | 4 +- mutation_partition_view.hh | 6 +- mutation_reader.cc | 44 ++++++-------- mutation_reader.hh | 8 +-- mutation_writer/feed_writers.hh | 4 +- partition_version.cc | 26 +++----- querier.hh | 8 +-- query-result-reader.hh | 6 +- range.hh | 5 +- schema_upgrader.hh | 4 +- serializer_impl.hh | 6 +- service/migration_manager.hh | 8 +-- service/pager/query_pager.hh | 2 +- service/pager/query_pagers.cc | 2 +- sstables/checksum_utils.hh | 15 ++--- sstables/compaction.cc | 12 +--- sstables/compress.cc | 24 ++------ sstables/data_consume_context.hh | 5 +- sstables/mc/writer.cc | 30 ++++----- sstables/partition.cc | 24 +++----- sstables/sstables.hh | 27 ++++----- sstables/types.hh | 12 ++-- sstables/writer.hh | 48 ++++++--------- table_helper.hh | 3 +- test/lib/sstable_utils.hh | 2 +- thrift/handler.cc | 8 +-- types.cc | 2 +- utils/crc.hh | 2 +- utils/enum_option.hh | 7 +-- utils/fragment_range.hh | 30 +++------ utils/fragmented_temporary_buffer.hh | 18 +++--- utils/linearizing_input_stream.hh | 8 +-- utils/loading_shared_values.hh | 5 +- utils/log_heap.hh | 9 +-- utils/reusable_buffer.hh | 13 ++-- utils/serialization.hh | 13 ++-- utils/with_relational_operators.hh | 10 ++- 61 files changed, 397 insertions(+), 619 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d7c324d233..471d5390a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -134,10 +134,6 @@ add_executable(scylla ${SEASTAR_SOURCE_FILES} ${SCYLLA_SOURCE_FILES}) -# Note that since CLion does not undestand GCC6 concepts, we always disable them (even if users configure otherwise). -# CLion seems to have trouble with `-U` (macro undefinition), so we do it this way instead. -list(REMOVE_ITEM SEASTAR_CFLAGS "-DHAVE_GCC6_CONCEPTS") - # If the Seastar pkg-config information is available, append to the default flags. # # For ease of browsing the source code, we always pretend that DPDK is enabled. diff --git a/atomic_cell.hh b/atomic_cell.hh index 9cab0b1d89..7ec1815c02 100644 --- a/atomic_cell.hh +++ b/atomic_cell.hh @@ -29,7 +29,6 @@ #include #include #include -#include #include "data/cell.hh" #include "data/schema_info.hh" #include "imr/utils.hh" diff --git a/clustering_bounds_comparator.hh b/clustering_bounds_comparator.hh index 2ddd7cb2f4..64e9fa77c2 100644 --- a/clustering_bounds_comparator.hh +++ b/clustering_bounds_comparator.hh @@ -122,26 +122,26 @@ public: return {_empty_prefix, bound_kind::incl_end}; } template typename R> - GCC6_CONCEPT( requires Range ) + requires Range static bound_view from_range_start(const R& range) { return range.start() ? bound_view(range.start()->value(), range.start()->is_inclusive() ? bound_kind::incl_start : bound_kind::excl_start) : bottom(); } template typename R> - GCC6_CONCEPT( requires Range ) + requires Range static bound_view from_range_end(const R& range) { return range.end() ? bound_view(range.end()->value(), range.end()->is_inclusive() ? bound_kind::incl_end : bound_kind::excl_end) : top(); } template typename R> - GCC6_CONCEPT( requires Range ) + requires Range static std::pair from_range(const R& range) { return {from_range_start(range), from_range_end(range)}; } template typename R> - GCC6_CONCEPT( requires Range ) + requires Range static std::optional::bound> to_range_bound(const bound_view& bv) { if (&bv._prefix.get() == &_empty_prefix) { return {}; diff --git a/collection_mutation.cc b/collection_mutation.cc index bc0eb0ad9f..22d65bcc88 100644 --- a/collection_mutation.cc +++ b/collection_mutation.cc @@ -61,7 +61,7 @@ bool collection_mutation_view::is_empty() const { } template -GCC6_CONCEPT(requires std::is_invocable_r_v) +requires std::is_invocable_r_v static bool is_any_live(const atomic_cell_value_view& data, tombstone tomb, gc_clock::time_point now, F&& read_cell_type_info) { auto in = collection_mutation_input_stream(data); auto has_tomb = in.read_trivial(); @@ -108,7 +108,7 @@ bool collection_mutation_view::is_any_live(const abstract_type& type, tombstone } template -GCC6_CONCEPT(requires std::is_invocable_r_v) +requires std::is_invocable_r_v static api::timestamp_type last_update(const atomic_cell_value_view& data, F&& read_cell_type_info) { auto in = collection_mutation_input_stream(data); api::timestamp_type max = api::missing_timestamp; @@ -313,7 +313,7 @@ collection_mutation collection_mutation_view_description::serialize(const abstra } template -GCC6_CONCEPT(requires std::is_base_of_v>) +requires std::is_base_of_v> static collection_mutation_view_description merge(collection_mutation_view_description a, collection_mutation_view_description b, C&& key_type) { using element_type = std::pair; @@ -375,7 +375,7 @@ collection_mutation merge(const abstract_type& type, collection_mutation_view a, } template -GCC6_CONCEPT(requires std::is_base_of_v>) +requires std::is_base_of_v> static collection_mutation_view_description difference(collection_mutation_view_description a, collection_mutation_view_description b, C&& key_type) { @@ -421,7 +421,7 @@ collection_mutation difference(const abstract_type& type, collection_mutation_vi } template -GCC6_CONCEPT(requires std::is_invocable_r_v, F, collection_mutation_input_stream&>) +requires std::is_invocable_r_v, F, collection_mutation_input_stream&> static collection_mutation_view_description deserialize_collection_mutation(collection_mutation_input_stream& in, F&& read_kv) { collection_mutation_view_description ret; diff --git a/concrete_types.hh b/concrete_types.hh index e11d143fad..c80e5dd081 100644 --- a/concrete_types.hh +++ b/concrete_types.hh @@ -152,41 +152,39 @@ struct uuid_type_impl final : public concrete_type { template using visit_ret_type = std::invoke_result_t; -GCC6_CONCEPT( -template concept bool CanHandleAllTypes = requires(Func f) { - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; - { f(*static_cast(nullptr)) } -> visit_ret_type; +template concept CanHandleAllTypes = requires(Func f) { + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; }; -) template -GCC6_CONCEPT(requires CanHandleAllTypes) +requires CanHandleAllTypes static inline visit_ret_type visit(const abstract_type& t, Func&& f) { switch (t.get_kind()) { case abstract_type::kind::ascii: diff --git a/configure.py b/configure.py index 9ed0165f90..4d1e324082 100755 --- a/configure.py +++ b/configure.py @@ -473,8 +473,6 @@ arg_parser.add_argument('--python', action='store', dest='python', default='pyth help='Python3 path') arg_parser.add_argument('--split-dwarf', dest='split_dwarf', action='store_true', default=False, help='use of split dwarf (https://gcc.gnu.org/wiki/DebugFission) to speed up linking') -arg_parser.add_argument('--enable-gcc6-concepts', dest='gcc6_concepts', action='store_true', default=False, - help='enable experimental support for C++ Concepts as implemented in GCC 6') arg_parser.add_argument('--enable-alloc-failure-injector', dest='alloc_failure_injector', action='store_true', default=False, help='enable allocation failure injection') arg_parser.add_argument('--with-antlr3', dest='antlr3_exec', action='store', default=None, @@ -1250,8 +1248,6 @@ def configure_seastar(build_dir, mode): if args.dpdk: seastar_cmake_args += ['-DSeastar_DPDK=ON', '-DSeastar_DPDK_MACHINE=wsm'] - if args.gcc6_concepts: - seastar_cmake_args += ['-DSeastar_GCC6_CONCEPTS=ON'] if args.split_dwarf: seastar_cmake_args += ['-DSeastar_SPLIT_DWARF=ON'] if args.alloc_failure_injector: diff --git a/counters.hh b/counters.hh index dafa1e774e..c728eaf833 100644 --- a/counters.hh +++ b/counters.hh @@ -156,10 +156,10 @@ private: // Shared logic for applying counter_shards and counter_shard_views. // T is either counter_shard or basic_counter_shard_view. template - GCC6_CONCEPT(requires requires(T shard) { - { shard.value() } -> int64_t; - { shard.logical_clock() } -> int64_t; - }) + requires requires(T shard) { + { shard.value() } -> std::same_as; + { shard.logical_clock() } -> std::same_as; + } counter_shard& do_apply(T&& other) noexcept { auto other_clock = other.logical_clock(); if (_logical_clock < other_clock) { diff --git a/cql3/query_options.hh b/cql3/query_options.hh index ddf4c42074..8b06380b26 100644 --- a/cql3/query_options.hh +++ b/cql3/query_options.hh @@ -41,7 +41,7 @@ #pragma once -#include +#include #include "timestamp.hh" #include "bytes.hh" #include "db/consistency_level_type.hh" @@ -97,11 +97,11 @@ private: * @param values_ranges a vector of values ranges for each statement in the batch. */ template - GCC6_CONCEPT( requires requires (OneMutationDataRange range) { + requires requires (OneMutationDataRange range) { std::begin(range); std::end(range); - } && ( requires (OneMutationDataRange range) { { *range.begin() } -> raw_value_view; } || - requires (OneMutationDataRange range) { { *range.begin() } -> raw_value; } ) ) + } && ( requires (OneMutationDataRange range) { { *range.begin() } -> std::convertible_to; } || + requires (OneMutationDataRange range) { { *range.begin() } -> std::convertible_to; } ) explicit query_options(query_options&& o, std::vector values_ranges); public: @@ -145,11 +145,11 @@ public: * @param values_ranges a vector of values ranges for each statement in the batch. */ template - GCC6_CONCEPT( requires requires (OneMutationDataRange range) { + requires requires (OneMutationDataRange range) { std::begin(range); std::end(range); - } && ( requires (OneMutationDataRange range) { { *range.begin() } -> raw_value_view; } || - requires (OneMutationDataRange range) { { *range.begin() } -> raw_value; } ) ) + } && ( requires (OneMutationDataRange range) { { *range.begin() } -> std::convertible_to; } || + requires (OneMutationDataRange range) { { *range.begin() } -> std::convertible_to; } ) static query_options make_batch_options(query_options&& o, std::vector values_ranges) { return query_options(std::move(o), std::move(values_ranges)); } @@ -251,11 +251,11 @@ private: }; template -GCC6_CONCEPT( requires requires (OneMutationDataRange range) { +requires requires (OneMutationDataRange range) { std::begin(range); std::end(range); -} && ( requires (OneMutationDataRange range) { { *range.begin() } -> raw_value_view; } || - requires (OneMutationDataRange range) { { *range.begin() } -> raw_value; } ) ) +} && ( requires (OneMutationDataRange range) { { *range.begin() } -> std::convertible_to; } || + requires (OneMutationDataRange range) { { *range.begin() } -> std::convertible_to; } ) query_options::query_options(query_options&& o, std::vector values_ranges) : query_options(std::move(o)) { diff --git a/cql3/result_set.hh b/cql3/result_set.hh index 47b3a5d821..2e11b1ac51 100644 --- a/cql3/result_set.hh +++ b/cql3/result_set.hh @@ -50,7 +50,6 @@ #include "result_generator.hh" -#include namespace cql3 { @@ -150,17 +149,13 @@ public: const std::vector& partition_key_bind_indices() const; }; -GCC6_CONCEPT( - template -concept bool ResultVisitor = requires(Visitor& visitor) { +concept ResultVisitor = requires(Visitor& visitor) { visitor.start_row(); visitor.accept_value(std::optional()); visitor.end_row(); }; -) - class result_set { ::shared_ptr _metadata; std::deque> _rows; @@ -199,7 +194,7 @@ public: const std::deque>& rows() const; template - GCC6_CONCEPT(requires ResultVisitor) + requires ResultVisitor void visit(Visitor&& visitor) const { auto column_count = get_metadata().column_count(); for (auto& row : _rows) { @@ -264,7 +259,7 @@ public: } template - GCC6_CONCEPT(requires ResultVisitor) + requires ResultVisitor void visit(Visitor&& visitor) const { if (_result_set) { _result_set->visit(std::forward(visitor)); diff --git a/cql3/statements/select_statement.cc b/cql3/statements/select_statement.cc index ea3b5596a2..d1d4866943 100644 --- a/cql3/statements/select_statement.cc +++ b/cql3/statements/select_statement.cc @@ -428,9 +428,7 @@ select_statement::do_execute(service::storage_proxy& proxy, } template -GCC6_CONCEPT( - requires (std::is_same_v || std::is_same_v) -) +requires (std::is_same_v || std::is_same_v) static KeyType generate_base_key_from_index_pk(const partition_key& index_pk, const std::optional& index_ck, const schema& base_schema, const schema& view_schema) { const auto& base_columns = std::is_same_v ? base_schema.partition_key_columns() : base_schema.clustering_key_columns(); @@ -844,9 +842,7 @@ indexed_table_select_statement::indexed_table_select_statement(schema_ptr schema } template -GCC6_CONCEPT( - requires (std::is_same_v || std::is_same_v) -) +requires (std::is_same_v || std::is_same_v) static void append_base_key_to_index_ck(std::vector& exploded_index_ck, const KeyType& base_key, const column_definition& index_cdef) { auto key_view = base_key.view(); auto begin = key_view.begin(); diff --git a/data/cell.hh b/data/cell.hh index 1da72b0964..f6835faffd 100644 --- a/data/cell.hh +++ b/data/cell.hh @@ -292,12 +292,10 @@ public: /// \arg data needs to remain valid as long as the writer is in use. /// \returns imr::WriterAllocator for cell::structure. template>>> - GCC6_CONCEPT( - requires std::is_nothrow_move_constructible_v> && - std::is_nothrow_copy_constructible_v> && - std::is_nothrow_copy_assignable_v> && - std::is_nothrow_move_assignable_v> - ) + requires std::is_nothrow_move_constructible_v> && + std::is_nothrow_copy_constructible_v> && + std::is_nothrow_copy_assignable_v> && + std::is_nothrow_move_assignable_v> static auto make_collection(FragmentRange data) noexcept { return [data = std::move(data)] (auto&& serializer, auto&& allocations) noexcept { return serializer diff --git a/data/cell_impl.hh b/data/cell_impl.hh index d42d3f3436..af24ccf33e 100644 --- a/data/cell_impl.hh +++ b/data/cell_impl.hh @@ -86,12 +86,10 @@ public: { } template - GCC6_CONCEPT( - requires (imr::is_sizer_for_v - && std::is_same_v) - || (imr::is_serializer_for_v - && std::is_same_v) - ) + requires (imr::is_sizer_for_v + && std::is_same_v) + || (imr::is_serializer_for_v + && std::is_same_v) auto operator()(Serializer serializer, Allocator allocations) { auto after_size = serializer.serialize(_value_size); if (_force_internal || _value_size <= cell::maximum_internal_storage_length) { @@ -134,14 +132,14 @@ public: inline value_writer cell::variable_value::write(size_t value_size, bool force_internal) noexcept { - GCC6_CONCEPT(static_assert(imr::WriterAllocator, structure>)); + static_assert(imr::WriterAllocator, structure>); return value_writer(empty_fragment_range(), value_size, force_internal); } template inline value_writer> cell::variable_value::write(FragmentRange&& value, bool force_internal) noexcept { - GCC6_CONCEPT(static_assert(imr::WriterAllocator>, structure>)); + static_assert(imr::WriterAllocator>, structure>); return value_writer>(std::forward(value), value.size_bytes(), force_internal); } diff --git a/db/commitlog/commitlog.cc b/db/commitlog/commitlog.cc index 2e279b044b..591d964997 100644 --- a/db/commitlog/commitlog.cc +++ b/db/commitlog/commitlog.cc @@ -109,7 +109,7 @@ public: return _c.process(reinterpret_cast(data), size); } template - GCC6_CONCEPT(requires FragmentRange) + requires FragmentRange void process_fragmented(const FragmentedBuffer& buffer) { return _c.process_fragmented(buffer); } diff --git a/flat_mutation_reader.hh b/flat_mutation_reader.hh index 1769192576..f8f2d8f256 100644 --- a/flat_mutation_reader.hh +++ b/flat_mutation_reader.hh @@ -29,7 +29,6 @@ #include "mutation_fragment.hh" #include "tracing/trace_state.hh" -#include #include #include #include "db/timeout_clock.hh" @@ -41,31 +40,27 @@ using seastar::future; class mutation_source; class reader_permit; -GCC6_CONCEPT( - template - concept bool FlatMutationReaderConsumer() { - return requires(Consumer c, mutation_fragment mf) { - { c(std::move(mf)) } -> stop_iteration; - }; - } -) - -GCC6_CONCEPT( - template - concept bool FlattenedConsumer() { - return StreamedMutationConsumer() && requires(T obj, const dht::decorated_key& dk) { - obj.consume_new_partition(dk); - obj.consume_end_of_partition(); - }; - } - - template - concept bool FlattenedConsumerFilter = requires(T filter, const dht::decorated_key& dk, const mutation_fragment& mf) { - { filter(dk) } -> bool; - { filter(mf) } -> bool; - { filter.on_end_of_stream() } -> void; +template +concept FlatMutationReaderConsumer = + requires(Consumer c, mutation_fragment mf) { + { c(std::move(mf)) } -> std::same_as; + }; + + +template +concept FlattenedConsumer = + StreamedMutationConsumer && requires(T obj, const dht::decorated_key& dk) { + { obj.consume_new_partition(dk) }; + { obj.consume_end_of_partition() }; + }; + +template +concept FlattenedConsumerFilter = + requires(T filter, const dht::decorated_key& dk, const mutation_fragment& mf) { + { filter(dk) } -> std::same_as; + { filter(mf) } -> std::same_as; + { filter.on_end_of_stream() } -> std::same_as; }; -) /* * Allows iteration on mutations using mutation_fragments. @@ -149,9 +144,7 @@ public: } template - GCC6_CONCEPT( - requires FlatMutationReaderConsumer() - ) + requires FlatMutationReaderConsumer // Stops when consumer returns stop_iteration::yes or end of stream is reached. // Next call will start from the next mutation_fragment in the stream. future<> consume_pausable(Consumer consumer, db::timeout_clock::time_point timeout) { @@ -169,9 +162,7 @@ public: } template - GCC6_CONCEPT( - requires FlatMutationReaderConsumer() && FlattenedConsumerFilter - ) + requires FlatMutationReaderConsumer && FlattenedConsumerFilter // A variant of consume_pausable() that expects to be run in // a seastar::thread. // Partitions for which filter(decorated_key) returns false are skipped @@ -246,9 +237,7 @@ public: }; public: template - GCC6_CONCEPT( - requires FlattenedConsumer() - ) + requires FlattenedConsumer // Stops when consumer returns stop_iteration::yes from consume_end_of_partition or end of stream is reached. // Next call will receive fragments from the next partition. // When consumer returns stop_iteration::yes from methods other than consume_end_of_partition then the read @@ -270,9 +259,7 @@ public: } template - GCC6_CONCEPT( - requires FlattenedConsumer() && FlattenedConsumerFilter - ) + requires FlattenedConsumer && FlattenedConsumerFilter // A variant of consumee() that expects to be run in a seastar::thread. // Partitions for which filter(decorated_key) returns false are skipped // entirely and never reach the consumer. @@ -333,17 +320,13 @@ public: } template - GCC6_CONCEPT( - requires FlatMutationReaderConsumer() - ) + requires FlatMutationReaderConsumer auto consume_pausable(Consumer consumer, db::timeout_clock::time_point timeout) { return _impl->consume_pausable(std::move(consumer), timeout); } template - GCC6_CONCEPT( - requires FlattenedConsumer() - ) + requires FlattenedConsumer auto consume(Consumer consumer, db::timeout_clock::time_point timeout) { return _impl->consume(std::move(consumer), timeout); } @@ -394,17 +377,13 @@ public: }; template - GCC6_CONCEPT( - requires FlattenedConsumer() && FlattenedConsumerFilter - ) + requires FlattenedConsumer && FlattenedConsumerFilter auto consume_in_thread(Consumer consumer, Filter filter, db::timeout_clock::time_point timeout) { return _impl->consume_in_thread(std::move(consumer), std::move(filter), timeout); } template - GCC6_CONCEPT( - requires FlattenedConsumer() - ) + requires FlattenedConsumer auto consume_in_thread(Consumer consumer, db::timeout_clock::time_point timeout) { return consume_in_thread(std::move(consumer), no_filter{}, timeout); } @@ -528,11 +507,11 @@ flat_mutation_reader make_flat_mutation_reader(Args &&... args) { // The consumer will stop iff StopCondition returns true, in particular // reaching the end of stream alone won't stop the reader. template -GCC6_CONCEPT(requires requires(StopCondition stop, ConsumeMutationFragment consume_mf, ConsumeEndOfStream consume_eos, mutation_fragment mf) { - { stop() } -> bool; - { consume_mf(std::move(mf)) } -> void; - { consume_eos() } -> future<>; -}) +requires requires(StopCondition stop, ConsumeMutationFragment consume_mf, ConsumeEndOfStream consume_eos, mutation_fragment mf) { + { stop() } -> std::same_as; + { consume_mf(std::move(mf)) } -> std::same_as; + { consume_eos() } -> std::same_as>; +} future<> consume_mutation_fragments_until( flat_mutation_reader& r, StopCondition&& stop, @@ -555,9 +534,7 @@ future<> consume_mutation_fragments_until( // Creates a stream which is like r but with transformation applied to the elements. template -GCC6_CONCEPT( - requires StreamedMutationTranformer() -) +requires StreamedMutationTranformer flat_mutation_reader transform(flat_mutation_reader r, T t) { class transforming_reader : public flat_mutation_reader::impl { flat_mutation_reader _reader; diff --git a/hashing.hh b/hashing.hh index 59026fd4f7..cdc6272412 100644 --- a/hashing.hh +++ b/hashing.hh @@ -24,10 +24,10 @@ #include #include #include +#include #include #include #include "seastarx.hh" -#include // // This hashing differs from std::hash<> in that it decouples knowledge about @@ -42,14 +42,11 @@ // appending_hash is machine-independent. // -GCC6_CONCEPT( - template - concept bool Hasher() { - return requires(H& h, const char* ptr, size_t size) { - { h.update(ptr, size) } -> void; - }; - } -) +template +concept Hasher = + requires(H& h, const char* ptr, size_t size) { + { h.update(ptr, size) } -> std::same_as; + }; class hasher { public: @@ -57,13 +54,13 @@ public: virtual void update(const char* ptr, size_t size) = 0; }; -GCC6_CONCEPT(static_assert(Hasher());) +static_assert(Hasher); template struct appending_hash; template -GCC6_CONCEPT(requires Hasher()) +requires Hasher inline void feed_hash(H& h, const T& value, Args&&... args) { appending_hash()(h, value, std::forward(args)...); @@ -72,7 +69,7 @@ void feed_hash(H& h, const T& value, Args&&... args) { template struct appending_hash::value>> { template - GCC6_CONCEPT(requires Hasher()) + requires Hasher void operator()(H& h, T value) const { auto value_le = cpu_to_le(value); h.update(reinterpret_cast(&value_le), sizeof(T)); @@ -82,7 +79,7 @@ struct appending_hash::value>> { template<> struct appending_hash { template - GCC6_CONCEPT(requires Hasher()) + requires Hasher void operator()(H& h, bool value) const { feed_hash(h, static_cast(value)); } @@ -91,7 +88,7 @@ struct appending_hash { template struct appending_hash::value>> { template - GCC6_CONCEPT(requires Hasher()) + requires Hasher void operator()(H& h, const T& value) const { feed_hash(h, static_cast>(value)); } @@ -100,7 +97,7 @@ struct appending_hash::value>> { template struct appending_hash> { template - GCC6_CONCEPT(requires Hasher()) + requires Hasher void operator()(H& h, const std::optional& value) const { if (value) { feed_hash(h, true); @@ -114,7 +111,7 @@ struct appending_hash> { template struct appending_hash { template - GCC6_CONCEPT(requires Hasher()) + requires Hasher void operator()(H& h, const char (&value) [N]) const { feed_hash(h, N); h.update(value, N); @@ -124,7 +121,7 @@ struct appending_hash { template struct appending_hash> { template - GCC6_CONCEPT(requires Hasher()) + requires Hasher void operator()(H& h, const std::vector& value) const { feed_hash(h, value.size()); for (auto&& v : value) { @@ -136,7 +133,7 @@ struct appending_hash> { template struct appending_hash> { template - GCC6_CONCEPT(requires Hasher()) + requires Hasher void operator()(H& h, const std::map& value) const { feed_hash(h, value.size()); for (auto&& e : value) { @@ -149,7 +146,7 @@ struct appending_hash> { template<> struct appending_hash { template - GCC6_CONCEPT(requires Hasher()) + requires Hasher void operator()(H& h, const sstring& v) const { feed_hash(h, v.size()); h.update(reinterpret_cast(v.cbegin()), v.size() * sizeof(sstring::value_type)); @@ -159,7 +156,7 @@ struct appending_hash { template<> struct appending_hash { template - GCC6_CONCEPT(requires Hasher()) + requires Hasher void operator()(H& h, const std::string& v) const { feed_hash(h, v.size()); h.update(reinterpret_cast(v.data()), v.size() * sizeof(std::string::value_type)); @@ -169,7 +166,7 @@ struct appending_hash { template struct appending_hash> { template - GCC6_CONCEPT(requires Hasher()) + requires Hasher void operator()(H& h, std::chrono::duration v) const { feed_hash(h, v.count()); } @@ -178,7 +175,7 @@ struct appending_hash> { template struct appending_hash> { template - GCC6_CONCEPT(requires Hasher()) + requires Hasher void operator()(H& h, std::chrono::time_point v) const { feed_hash(h, v.time_since_epoch().count()); } diff --git a/idl-compiler.py b/idl-compiler.py index f2b6714e70..eae8bc9100 100755 --- a/idl-compiler.py +++ b/idl-compiler.py @@ -449,7 +449,7 @@ def add_param_writer_basic_type(name, base_state, typ, var_type="", var_index=No if allow_fragmented: writer += Template(reindent(4, """ template - GCC6_CONCEPT(requires FragmentRange) + requires FragmentRange after_${base_state}__$name write_fragmented_$name$var_type(FragmentedBuffer&& fragments) && { $set_varient_index serialize_fragmented(_out, std::forward(fragments)); diff --git a/imr/alloc.hh b/imr/alloc.hh index d5a43c402a..2535bce5d4 100644 --- a/imr/alloc.hh +++ b/imr/alloc.hh @@ -64,15 +64,13 @@ public: } }; -GCC6_CONCEPT( template -concept bool ContextFactory = requires(const T factory, const uint8_t* ptr) { +concept ContextFactory = requires(const T factory, const uint8_t* ptr) { { factory.create(ptr) } noexcept; }; static_assert(ContextFactory, "no_context_factory_t has to meet ContextFactory constraints"); -) /// LSA migrator for IMR objects /// @@ -81,7 +79,7 @@ static_assert(ContextFactory, /// of type `Structure`. The deserialisation context needed to invoke the mover /// is going to be created by the provided context factory `CtxFactory`. template -GCC6_CONCEPT(requires ContextFactory) +requires ContextFactory class lsa_migrate_fn final : public migrate_fn_type, CtxFactory { public: using structure = Structure; diff --git a/imr/compound.hh b/imr/compound.hh index 59ecc8dae2..c8928f084d 100644 --- a/imr/compound.hh +++ b/imr/compound.hh @@ -23,8 +23,7 @@ #include #include - -#include +#include #include "utils/meta.hh" @@ -54,9 +53,9 @@ public: } template - GCC6_CONCEPT(requires requires(const Context& ctx) { + requires requires(const Context& ctx) { { ctx.template context_for() } noexcept; - }) + } auto get(const Context& ctx = no_context) noexcept { return Type::make_view(_ptr, ctx.template context_for(_ptr)); } @@ -75,9 +74,9 @@ public: } public: template - GCC6_CONCEPT(requires requires(const Context& ctx) { - { ctx.template is_present() } noexcept -> bool; - }) + requires requires(const Context& ctx) { + { ctx.template is_present() } noexcept -> std::same_as; + } static size_t serialized_object_size(const uint8_t* in, const Context& context) noexcept { return context.template is_present() ? Type::serialized_object_size(in, context) @@ -237,9 +236,9 @@ public: public: template - GCC6_CONCEPT(requires requires(const Context& ctx) { - { ctx.template active_alternative_of() } noexcept -> alternative_index; - }) + requires requires(const Context& ctx) { + { ctx.template active_alternative_of() } noexcept -> std::same_as; + } static size_t serialized_object_size(const uint8_t* in, const Context& context) noexcept { return choose_alternative(context.template active_alternative_of(), [&] (auto object) noexcept { using alternative = std::remove_pointer_t; diff --git a/imr/concepts.hh b/imr/concepts.hh index 4b7b438c52..b8650937e2 100644 --- a/imr/concepts.hh +++ b/imr/concepts.hh @@ -21,6 +21,7 @@ #pragma once +#include #include "imr/alloc.hh" #include "imr/compound.hh" #include "imr/fundamental.hh" @@ -59,11 +60,9 @@ using default_sizer_t = decltype(Structure::get_sizer()); template using default_serializer_t = decltype(Structure::get_serializer(nullptr)); -GCC6_CONCEPT( - /// A simple writer that accepts only sizer or serializer as an argument. template -concept bool WriterSimple = requires(Writer writer, default_sizer_t sizer, +concept WriterSimple = requires(Writer writer, default_sizer_t sizer, default_serializer_t serializer) { writer(sizer); @@ -72,7 +71,7 @@ concept bool WriterSimple = requires(Writer writer, default_sizer_t s /// A writer that accepts both sizer or serializer and a memory allocator. template -concept bool WriterAllocator = requires(Writer writer, default_sizer_t sizer, +concept WriterAllocator = requires(Writer writer, default_sizer_t sizer, default_serializer_t serializer, imr::alloc::object_allocator::sizer alloc_sizer, imr::alloc::object_allocator::serializer alloc_serializer) @@ -81,6 +80,4 @@ concept bool WriterAllocator = requires(Writer writer, default_sizer_t #include -#include #include "bytes.hh" #include "utils/meta.hh" @@ -37,7 +36,7 @@ namespace imr { namespace internal { template -GCC6_CONCEPT(requires std::is_pod::value && sizeof(CharT) == 1) +requires std::is_standard_layout_v && std::is_trivial_v && (sizeof(CharT) == 1) inline T read_pod(const CharT* in) noexcept { T obj; std::copy_n(in, sizeof(T), reinterpret_cast(&obj)); @@ -45,7 +44,7 @@ inline T read_pod(const CharT* in) noexcept { } template -GCC6_CONCEPT(requires std::is_pod::value && sizeof(CharT) == 1) +requires std::is_standard_layout_v && std::is_trivial_v && (sizeof(CharT) == 1) inline void write_pod(T obj, CharT* out) noexcept { std::copy_n(reinterpret_cast(&obj), sizeof(T), out); } @@ -157,7 +156,7 @@ public: /// /// Represents a fixed-size POD value. template -GCC6_CONCEPT(requires std::is_pod::value) +requires std::is_standard_layout_v && std::is_trivial_v struct pod { using underlying = Type; enum : size_t { @@ -237,18 +236,18 @@ struct buffer { using basic_view = std::conditional_t; template - GCC6_CONCEPT(requires requires(const Context& ctx) { - { ctx.template size_of() } noexcept -> size_t; - }) + requires requires(const Context& ctx) { + { ctx.template size_of() } noexcept -> std::same_as; + } static view make_view(const uint8_t* in, const Context& context) noexcept { auto ptr = reinterpret_cast(in); return bytes_view(ptr, context.template size_of()); } template - GCC6_CONCEPT(requires requires(const Context& ctx) { - { ctx.template size_of() } noexcept -> size_t; - }) + requires requires(const Context& ctx) { + { ctx.template size_of() } noexcept -> std::same_as; + } static mutable_view make_view(uint8_t* in, const Context& context) noexcept { auto ptr = reinterpret_cast(in); return bytes_mutable_view(ptr, context.template size_of()); @@ -256,9 +255,9 @@ struct buffer { public: template - GCC6_CONCEPT(requires requires(const Context& ctx) { - { ctx.template size_of() } noexcept -> size_t; - }) + requires requires(const Context& ctx) { + { ctx.template size_of() } noexcept -> std::same_as; + } static size_t serialized_object_size(const uint8_t*, const Context& context) noexcept { return context.template size_of(); } @@ -268,9 +267,9 @@ public: } template - GCC6_CONCEPT(requires requires (Serializer ser, uint8_t* ptr) { + requires requires (Serializer ser, uint8_t* ptr) { { ser(ptr) } noexcept; - }) + } static size_t size_when_serialized(size_t size, Serializer&&) noexcept { return size; } @@ -297,9 +296,9 @@ public: } template - GCC6_CONCEPT(requires requires (Serializer ser, uint8_t* ptr) { + requires requires (Serializer ser, uint8_t* ptr) { { ser(ptr) } noexcept; - }) + } static size_t serialize(uint8_t* out, size_t size, Serializer&& serializer) noexcept { std::forward(serializer)(out); return size; diff --git a/imr/utils.hh b/imr/utils.hh index 6b6c1d81f3..d169e97ce9 100644 --- a/imr/utils.hh +++ b/imr/utils.hh @@ -148,9 +148,9 @@ public: /// \note This function could be deprecated once the IMR starts supporting /// copying IMR objects. template - GCC6_CONCEPT(requires requires (RawWriter wr, uint8_t* ptr) { + requires requires (RawWriter wr, uint8_t* ptr) { { wr(ptr) } noexcept; - }) + } static object make_raw(size_t len, RawWriter&& wr, allocation_strategy::migrate_fn migrate = &imr::alloc::default_lsa_migrate_fn::migrate_fn) { object obj; auto ptr = static_cast(current_allocator().alloc(migrate, sizeof(void*) + len, 1)); @@ -163,7 +163,7 @@ public: /// Create an IMR objects template - GCC6_CONCEPT(requires WriterAllocator) + requires WriterAllocator static object make(Writer&& object_writer, MigrateFn* migrate = &imr::alloc::default_lsa_migrate_fn::migrate_fn) { static_assert(std::is_same_v); @@ -171,7 +171,7 @@ public: } private: template - GCC6_CONCEPT(requires WriterAllocator) + requires WriterAllocator static object do_make(Writer&& object_writer, allocation_strategy::migrate_fn migrate) { struct alloc_deleter { size_t _size; diff --git a/lua.cc b/lua.cc index 544ca08c61..461dcc9469 100644 --- a/lua.cc +++ b/lua.cc @@ -220,19 +220,17 @@ struct lua_table { template using lua_visit_ret_type = std::invoke_result_t; -GCC6_CONCEPT( template -concept bool CanHandleRawLuaTypes = requires(Func f) { - { f(*static_cast(nullptr)) } -> lua_visit_ret_type; - { f(*static_cast(nullptr)) } -> lua_visit_ret_type; - { f(*static_cast(nullptr)) } -> lua_visit_ret_type; - { f(*static_cast(nullptr)) } -> lua_visit_ret_type; - { f(*static_cast(nullptr)) } -> lua_visit_ret_type; +concept CanHandleRawLuaTypes = requires(Func f) { + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; }; -) template -GCC6_CONCEPT(requires CanHandleRawLuaTypes) +requires CanHandleRawLuaTypes static auto visit_lua_raw_value(lua_State* l, int index, Func&& f) { switch (lua_type(l, index)) { case LUA_TNONE: @@ -275,19 +273,17 @@ static auto visit_decimal(const big_decimal &v, Func&& f) { return f(r.convert_to()); } -GCC6_CONCEPT( template -concept bool CanHandleLuaTypes = requires(Func f) { - { f(*static_cast(nullptr)) } -> lua_visit_ret_type; - { f(*static_cast(nullptr)) } -> lua_visit_ret_type; - { f(*static_cast(nullptr)) } -> lua_visit_ret_type; - { f(*static_cast(nullptr)) } -> lua_visit_ret_type; - { f(*static_cast(nullptr)) } -> lua_visit_ret_type; +concept CanHandleLuaTypes = requires(Func f) { + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; + { f(*static_cast(nullptr)) } -> std::same_as>; }; -) template -GCC6_CONCEPT(requires CanHandleLuaTypes) +requires CanHandleLuaTypes static auto visit_lua_value(lua_State* l, int index, Func&& f) { struct visitor { lua_State* l; diff --git a/mutation_compactor.hh b/mutation_compactor.hh index b73154f3c8..a861792ba0 100644 --- a/mutation_compactor.hh +++ b/mutation_compactor.hh @@ -41,19 +41,17 @@ enum class compact_for_sstables { yes, }; -GCC6_CONCEPT( - template - concept bool CompactedFragmentsConsumer = requires(T obj, tombstone t, const dht::decorated_key& dk, static_row sr, - clustering_row cr, range_tombstone rt, tombstone current_tombstone, row_tombstone current_row_tombstone, bool is_alive) { - obj.consume_new_partition(dk); - obj.consume(t); - { obj.consume(std::move(sr), current_tombstone, is_alive) } -> stop_iteration; - { obj.consume(std::move(cr), current_row_tombstone, is_alive) } -> stop_iteration; - { obj.consume(std::move(rt)) } -> stop_iteration; - { obj.consume_end_of_partition() } -> stop_iteration; - obj.consume_end_of_stream(); - }; -) +template +concept CompactedFragmentsConsumer = requires(T obj, tombstone t, const dht::decorated_key& dk, static_row sr, + clustering_row cr, range_tombstone rt, tombstone current_tombstone, row_tombstone current_row_tombstone, bool is_alive) { + obj.consume_new_partition(dk); + obj.consume(t); + { obj.consume(std::move(sr), current_tombstone, is_alive) } -> std::same_as; + { obj.consume(std::move(cr), current_row_tombstone, is_alive) } -> std::same_as; + { obj.consume(std::move(rt)) } -> std::same_as; + { obj.consume_end_of_partition() } -> std::same_as; + obj.consume_end_of_stream(); +}; struct detached_compaction_state { ::partition_start partition_start; @@ -265,9 +263,7 @@ public: } template - GCC6_CONCEPT( - requires CompactedFragmentsConsumer && CompactedFragmentsConsumer - ) + requires CompactedFragmentsConsumer && CompactedFragmentsConsumer void consume(tombstone t, Consumer& consumer, GCConsumer& gc_consumer) { _range_tombstones.set_partition_tombstone(t); if (!only_live()) { @@ -280,9 +276,7 @@ public: } template - GCC6_CONCEPT( - requires CompactedFragmentsConsumer && CompactedFragmentsConsumer - ) + requires CompactedFragmentsConsumer && CompactedFragmentsConsumer stop_iteration consume(static_row&& sr, Consumer& consumer, GCConsumer& gc_consumer) { _last_static_row = static_row(_schema, sr); auto current_tombstone = _range_tombstones.get_partition_tombstone(); @@ -307,9 +301,7 @@ public: } template - GCC6_CONCEPT( - requires CompactedFragmentsConsumer && CompactedFragmentsConsumer - ) + requires CompactedFragmentsConsumer && CompactedFragmentsConsumer stop_iteration consume(clustering_row&& cr, Consumer& consumer, GCConsumer& gc_consumer) { auto current_tombstone = _range_tombstones.tombstone_for_row(cr.key()); auto t = cr.tomb(); @@ -365,9 +357,7 @@ public: } template - GCC6_CONCEPT( - requires CompactedFragmentsConsumer && CompactedFragmentsConsumer - ) + requires CompactedFragmentsConsumer && CompactedFragmentsConsumer stop_iteration consume(range_tombstone&& rt, Consumer& consumer, GCConsumer& gc_consumer) { _range_tombstones.apply(rt); // FIXME: drop tombstone if it is fully covered by other range tombstones @@ -384,9 +374,7 @@ public: } template - GCC6_CONCEPT( - requires CompactedFragmentsConsumer && CompactedFragmentsConsumer - ) + requires CompactedFragmentsConsumer && CompactedFragmentsConsumer stop_iteration consume_end_of_partition(Consumer& consumer, GCConsumer& gc_consumer) { if (!_empty_partition_in_gc_consumer) { gc_consumer.consume_end_of_partition(); @@ -411,9 +399,7 @@ public: } template - GCC6_CONCEPT( - requires CompactedFragmentsConsumer && CompactedFragmentsConsumer - ) + requires CompactedFragmentsConsumer && CompactedFragmentsConsumer auto consume_end_of_stream(Consumer& consumer, GCConsumer& gc_consumer) { if (_dk) { _last_dk = *_dk; @@ -437,9 +423,7 @@ public: /// partition-header and static row if there are clustering rows or range /// tombstones left in the partition. template - GCC6_CONCEPT( - requires CompactedFragmentsConsumer - ) + requires CompactedFragmentsConsumer void start_new_page(uint32_t row_limit, uint32_t partition_limit, gc_clock::time_point query_time, @@ -480,9 +464,7 @@ public: }; template -GCC6_CONCEPT( - requires CompactedFragmentsConsumer && CompactedFragmentsConsumer -) +requires CompactedFragmentsConsumer && CompactedFragmentsConsumer class compact_mutation { lw_shared_ptr> _state; Consumer _consumer; @@ -541,9 +523,7 @@ public: }; template -GCC6_CONCEPT( - requires CompactedFragmentsConsumer -) +requires CompactedFragmentsConsumer struct compact_for_query : compact_mutation { using compact_mutation::compact_mutation; }; @@ -554,9 +534,7 @@ using compact_for_mutation_query_state = compact_for_query_state; template -GCC6_CONCEPT( - requires CompactedFragmentsConsumer && CompactedFragmentsConsumer -) +requires CompactedFragmentsConsumer && CompactedFragmentsConsumer struct compact_for_compaction : compact_mutation { using compact_mutation::compact_mutation; }; diff --git a/mutation_fragment.hh b/mutation_fragment.hh index d22e1097d1..8b4020b423 100644 --- a/mutation_fragment.hh +++ b/mutation_fragment.hh @@ -25,7 +25,6 @@ #include "position_in_partition.hh" #include -#include #include #include "seastar/core/future-util.hh" @@ -246,59 +245,44 @@ public: friend std::ostream& operator<<(std::ostream& is, const partition_end& row); }; -GCC6_CONCEPT( template -concept bool MutationFragmentConsumer() { - return requires(T t, static_row sr, clustering_row cr, range_tombstone rt, partition_start ph, partition_end pe) { - { t.consume(std::move(sr)) } -> ReturnType; - { t.consume(std::move(cr)) } -> ReturnType; - { t.consume(std::move(rt)) } -> ReturnType; - { t.consume(std::move(ph)) } -> ReturnType; - { t.consume(std::move(pe)) } -> ReturnType; +concept MutationFragmentConsumer = + requires(T t, static_row sr, clustering_row cr, range_tombstone rt, partition_start ph, partition_end pe) { + { t.consume(std::move(sr)) } -> std::same_as; + { t.consume(std::move(cr)) } -> std::same_as; + { t.consume(std::move(rt)) } -> std::same_as; + { t.consume(std::move(ph)) } -> std::same_as; + { t.consume(std::move(pe)) } -> std::same_as; }; -} -) -GCC6_CONCEPT( template -concept bool FragmentConsumerReturning() { - return requires(T t, static_row sr, clustering_row cr, range_tombstone rt, tombstone tomb) { - { t.consume(std::move(sr)) } -> ReturnType; - { t.consume(std::move(cr)) } -> ReturnType; - { t.consume(std::move(rt)) } -> ReturnType; +concept FragmentConsumerReturning = + requires(T t, static_row sr, clustering_row cr, range_tombstone rt, tombstone tomb) { + { t.consume(std::move(sr)) } -> std::same_as; + { t.consume(std::move(cr)) } -> std::same_as; + { t.consume(std::move(rt)) } -> std::same_as; }; -} -) -GCC6_CONCEPT( template -concept bool FragmentConsumer() { - return FragmentConsumerReturning() || FragmentConsumerReturning>(); -} -) +concept FragmentConsumer = + FragmentConsumerReturning || FragmentConsumerReturning>; -GCC6_CONCEPT( template -concept bool StreamedMutationConsumer() { - return FragmentConsumer() && requires(T t, static_row sr, clustering_row cr, range_tombstone rt, tombstone tomb) { +concept StreamedMutationConsumer = + FragmentConsumer && requires(T t, static_row sr, clustering_row cr, range_tombstone rt, tombstone tomb) { t.consume(tomb); t.consume_end_of_stream(); }; -} -) -GCC6_CONCEPT( template -concept bool MutationFragmentVisitor() { - return requires(T t, const static_row& sr, const clustering_row& cr, const range_tombstone& rt, const partition_start& ph, const partition_end& eop) { - { t(sr) } -> ReturnType; - { t(cr) } -> ReturnType; - { t(rt) } -> ReturnType; - { t(ph) } -> ReturnType; - { t(eop) } -> ReturnType; +concept MutationFragmentVisitor = + requires(T t, const static_row& sr, const clustering_row& cr, const range_tombstone& rt, const partition_start& ph, const partition_end& eop) { + { t(sr) } -> std::same_as; + { t(cr) } -> std::same_as; + { t(rt) } -> std::same_as; + { t(ph) } -> std::same_as; + { t(eop) } -> std::same_as; }; -} -) class mutation_fragment { public: @@ -446,9 +430,7 @@ public: void apply(const schema& s, mutation_fragment&& mf); template - GCC6_CONCEPT( - requires MutationFragmentConsumer().consume(std::declval()))>() - ) + requires MutationFragmentConsumer().consume(std::declval()))> decltype(auto) consume(Consumer& consumer) && { switch (_kind) { case kind::static_row: @@ -466,9 +448,7 @@ public: } template - GCC6_CONCEPT( - requires MutationFragmentVisitor()(std::declval()))>() - ) + requires MutationFragmentVisitor()(std::declval()))> decltype(auto) visit(Visitor&& visitor) const { switch (_kind) { case kind::static_row: @@ -630,14 +610,11 @@ public: friend std::ostream& operator<<(std::ostream& out, const range_tombstone_stream&); }; -GCC6_CONCEPT( - // F gets a stream element as an argument and returns the new value which replaces that element - // in the transformed stream. - template - concept bool StreamedMutationTranformer() { - return requires(F f, mutation_fragment mf, schema_ptr s) { - { f(std::move(mf)) } -> mutation_fragment; - { f(s) } -> schema_ptr; - }; - } -) +// F gets a stream element as an argument and returns the new value which replaces that element +// in the transformed stream. +template +concept StreamedMutationTranformer = + requires(F f, mutation_fragment mf, schema_ptr s) { + { f(std::move(mf)) } -> std::same_as; + { f(s) } -> std::same_as; + }; diff --git a/mutation_partition_view.cc b/mutation_partition_view.cc index d4fe38bd7f..16283f0cf5 100644 --- a/mutation_partition_view.cc +++ b/mutation_partition_view.cc @@ -47,7 +47,7 @@ using namespace db; -GCC6_CONCEPT(static_assert(MutationViewVisitor);) +static_assert(MutationViewVisitor); mutation_partition_view_virtual_visitor::~mutation_partition_view_virtual_visitor() = default; @@ -208,7 +208,7 @@ row_marker read_row_marker(boost::variant -GCC6_CONCEPT(requires MutationViewVisitor) +requires MutationViewVisitor void mutation_partition_view::do_accept(const column_mapping& cm, Visitor& visitor) const { auto in = _in; auto mpv = ser::deserialize(in, boost::type()); diff --git a/mutation_partition_view.hh b/mutation_partition_view.hh index 444368524b..909c036c95 100644 --- a/mutation_partition_view.hh +++ b/mutation_partition_view.hh @@ -32,9 +32,8 @@ class mutation_partition_view; class partition_builder; class converting_mutation_partition_applier; -GCC6_CONCEPT( template -concept bool MutationViewVisitor = requires (T& visitor, tombstone t, atomic_cell ac, +concept MutationViewVisitor = requires (T& visitor, tombstone t, atomic_cell ac, collection_mutation_view cmv, range_tombstone rt, position_in_partition_view pipv, row_tombstone row_tomb, row_marker rm) { @@ -47,7 +46,6 @@ concept bool MutationViewVisitor = requires (T& visitor, tombstone t, atomic_cel visitor.accept_row_cell(column_id(), std::move(ac)); visitor.accept_row_cell(column_id(), cmv); }; -) class mutation_partition_view_virtual_visitor { public: @@ -70,7 +68,7 @@ private: { } template - GCC6_CONCEPT(requires MutationViewVisitor) + requires MutationViewVisitor void do_accept(const column_mapping&, Visitor& visitor) const; public: static mutation_partition_view from_stream(utils::input_stream v) { diff --git a/mutation_reader.cc b/mutation_reader.cc index aa8d37d1ec..804c188b21 100644 --- a/mutation_reader.cc +++ b/mutation_reader.cc @@ -36,22 +36,20 @@ static constexpr size_t merger_small_vector_size = 4; template using merger_vector = utils::small_vector; -GCC6_CONCEPT( - template - concept bool FragmentProducer = requires(Producer p, dht::partition_range part_range, position_range pos_range, - db::timeout_clock::time_point timeout) { - // The returned fragments are expected to have the same - // position_in_partition. Iterators and references are expected - // to be valid until the next call to operator()(). - { p(timeout) } -> future::iterator>>; - // These have the same semantics as their - // flat_mutation_reader counterparts. - { p.next_partition() }; - { p.fast_forward_to(part_range, timeout) } -> future<>; - { p.fast_forward_to(pos_range, timeout) } -> future<>; - { p.buffer_size() } -> size_t; - }; -) +template +concept FragmentProducer = requires(Producer p, dht::partition_range part_range, position_range pos_range, + db::timeout_clock::time_point timeout) { + // The returned fragments are expected to have the same + // position_in_partition. Iterators and references are expected + // to be valid until the next call to operator()(). + { p(timeout) } -> std::same_as::iterator>>>; + // These have the same semantics as their + // flat_mutation_reader counterparts. + { p.next_partition() }; + { p.fast_forward_to(part_range, timeout) } -> std::same_as>; + { p.fast_forward_to(pos_range, timeout) } -> std::same_as>; + { p.buffer_size() } -> std::same_as; +}; /** * Merge mutation-fragments produced by producer. @@ -68,9 +66,7 @@ GCC6_CONCEPT( * fast_forward_to() and next_partition(), as appropriate. */ template -GCC6_CONCEPT( - requires FragmentProducer -) +requires FragmentProducer class mutation_fragment_merger { using iterator = merger_vector::iterator; @@ -692,12 +688,10 @@ class restricting_mutation_reader : public flat_mutation_reader::impl { static const ssize_t new_reader_base_cost{16 * 1024}; template - GCC6_CONCEPT( - requires std::is_move_constructible::value - && requires(Function fn, flat_mutation_reader& reader) { - fn(reader); - } - ) + requires std::is_move_constructible::value + && requires(Function fn, flat_mutation_reader& reader) { + fn(reader); + } decltype(auto) with_reader(Function fn, db::timeout_clock::time_point timeout) { if (auto* state = std::get_if(&_state)) { return fn(state->reader); diff --git a/mutation_reader.hh b/mutation_reader.hh index eb787e8a15..46392a30ad 100644 --- a/mutation_reader.hh +++ b/mutation_reader.hh @@ -83,11 +83,9 @@ flat_mutation_reader make_combined_reader(schema_ptr schema, mutation_reader::forwarding fwd_mr = mutation_reader::forwarding::yes); template -GCC6_CONCEPT( - requires requires(MutationFilter mf, const dht::decorated_key& dk) { - { mf(dk) } -> bool; - } -) +requires requires(MutationFilter mf, const dht::decorated_key& dk) { + { mf(dk) } -> std::same_as; +} class filtering_reader : public flat_mutation_reader::impl { flat_mutation_reader _rd; MutationFilter _filter; diff --git a/mutation_writer/feed_writers.hh b/mutation_writer/feed_writers.hh index 1ac36c5296..de9fb64fbc 100644 --- a/mutation_writer/feed_writers.hh +++ b/mutation_writer/feed_writers.hh @@ -27,9 +27,7 @@ namespace mutation_writer { using reader_consumer = noncopyable_function (flat_mutation_reader)>; template -GCC6_CONCEPT( - requires MutationFragmentConsumer>() -) +requires MutationFragmentConsumer> future<> feed_writer(flat_mutation_reader&& rd, Writer&& wr) { return do_with(std::move(rd), std::move(wr), [] (flat_mutation_reader& rd, Writer& wr) { return rd.fill_buffer(db::no_timeout).then([&rd, &wr] { diff --git a/partition_version.cc b/partition_version.cc index 1831716247..3a8b2ab49c 100644 --- a/partition_version.cc +++ b/partition_version.cc @@ -84,34 +84,26 @@ size_t partition_version::size_in_allocator(const schema& s, allocation_strategy namespace { -GCC6_CONCEPT( - // A functor which transforms objects from Domain into objects from CoDomain template -concept bool Mapper() { - return requires(U obj, const Domain& src) { - { obj(src) } -> const CoDomain&; +concept Mapper = + requires(U obj, const Domain& src) { + { obj(src) } -> std::convertible_to; }; -} // A functor which merges two objects from Domain into one. The result is stored in the first argument. template -concept bool Reducer() { - return requires(U obj, Domain& dst, const Domain& src) { - { obj(dst, src) } -> void; +concept Reducer = + requires(U obj, Domain& dst, const Domain& src) { + { obj(dst, src) } -> std::same_as; }; -} - -) // Calculates the value of particular part of mutation_partition represented by // the version chain starting from v. // |map| extracts the part from each version. // |reduce| Combines parts from the two versions. template -GCC6_CONCEPT( -requires Mapper() && Reducer() -) +requires Mapper && Reducer inline Result squashed(const partition_version_ref& v, Map&& map, Initial&& initial, Reduce&& reduce) { const partition_version* this_v = &*v; partition_version* it = v->last(); @@ -124,9 +116,7 @@ inline Result squashed(const partition_version_ref& v, Map&& map, Initial&& init } template -GCC6_CONCEPT( -requires Mapper() && Reducer() -) +requires Mapper && Reducer inline Result squashed(const partition_version_ref& v, Map&& map, Reduce&& reduce) { return squashed(v, map, [] (auto&& o) -> decltype(auto) { return std::forward(o); }, diff --git a/querier.hh b/querier.hh index 6377b419e4..4f81056c10 100644 --- a/querier.hh +++ b/querier.hh @@ -74,9 +74,7 @@ public: /// or std::nullopt if the last row wasn't a clustering row, and whatever the /// consumer's `consume_end_of_stream()` method returns. template -GCC6_CONCEPT( - requires CompactedFragmentsConsumer -) +requires CompactedFragmentsConsumer auto consume_page(flat_mutation_reader& reader, lw_shared_ptr> compaction_state, const query::partition_slice& slice, @@ -175,9 +173,7 @@ public: } template - GCC6_CONCEPT( - requires CompactedFragmentsConsumer - ) + requires CompactedFragmentsConsumer auto consume_page(Consumer&& consumer, uint32_t row_limit, uint32_t partition_limit, diff --git a/query-result-reader.hh b/query-result-reader.hh index 178a5eac6e..0e19579ad3 100644 --- a/query-result-reader.hh +++ b/query-result-reader.hh @@ -136,9 +136,8 @@ struct result_visitor { void accept_partition_end(const result_row_view& static_row) {} }; -GCC6_CONCEPT( template -concept bool ResultVisitor = requires(Visitor visitor, const partition_key& pkey, +concept ResultVisitor = requires(Visitor visitor, const partition_key& pkey, uint32_t row_count, const clustering_key& ckey, const result_row_view& static_row, const result_row_view& row) { @@ -148,7 +147,6 @@ concept bool ResultVisitor = requires(Visitor visitor, const partition_key& pkey visitor.accept_new_row(static_row, row); visitor.accept_partition_end(static_row); }; -) class result_view { ser::query_result_view _v; @@ -170,7 +168,7 @@ public: } template - GCC6_CONCEPT(requires ResultVisitor) + requires ResultVisitor void consume(const partition_slice& slice, Visitor&& visitor) const { for (auto&& p : _v.partitions()) { auto rows = p.rows(); diff --git a/range.hh b/range.hh index d447a9bb65..7e94527735 100644 --- a/range.hh +++ b/range.hh @@ -28,7 +28,6 @@ #include #include #include -#include template class range_bound { @@ -698,10 +697,8 @@ std::ostream& operator<<(std::ostream& out, const nonwrapping_range& r) { template using range = wrapping_range; -GCC6_CONCEPT( template typename T, typename U> -concept bool Range = std::is_same, wrapping_range>::value || std::is_same, nonwrapping_range>::value; -) +concept Range = std::is_same, wrapping_range>::value || std::is_same, nonwrapping_range>::value; // Allow using range in a hash table. The hash function 31 * left + // right is the same one used by Cassandra's AbstractBounds.hashCode(). diff --git a/schema_upgrader.hh b/schema_upgrader.hh index 3b7d0f2ee9..2fd677fb3f 100644 --- a/schema_upgrader.hh +++ b/schema_upgrader.hh @@ -69,6 +69,4 @@ public: } }; -GCC6_CONCEPT( -static_assert(StreamedMutationTranformer()); -) +static_assert(StreamedMutationTranformer); diff --git a/serializer_impl.hh b/serializer_impl.hh index de710b3f58..cda120e6c3 100644 --- a/serializer_impl.hh +++ b/serializer_impl.hh @@ -442,7 +442,7 @@ public: return bytes_view(reinterpret_cast(_stream.begin()), _stream.size()); } else { using iterator_type = typename Stream::iterator_type ; - GCC6_CONCEPT(static_assert(FragmentRange>)); + static_assert(FragmentRange>); return seastar::with_serialized_stream(_stream, seastar::make_visitor( [&] (typename seastar::memory_input_stream::simple stream) { return buffer_view(bytes_view(reinterpret_cast(stream.begin()), @@ -507,7 +507,7 @@ struct serializer { } } template - GCC6_CONCEPT(requires FragmentRange) + requires FragmentRange static void write_fragmented(Output& out, FragmentedBuffer&& fragments) { safe_serialize_as_uint32(out, uint32_t(fragments.size_bytes())); using boost::range::for_each; @@ -535,7 +535,7 @@ void serialize(Output& out, const bytes_ostream& v) { serializer::write(out, v); } template -GCC6_CONCEPT(requires FragmentRange) +requires FragmentRange void serialize_fragmented(Output& out, FragmentedBuffer&& v) { serializer::write_fragmented(out, std::forward(v)); } diff --git a/service/migration_manager.hh b/service/migration_manager.hh index bbcd5a78e1..91ed831191 100644 --- a/service/migration_manager.hh +++ b/service/migration_manager.hh @@ -55,10 +55,8 @@ namespace service { -GCC6_CONCEPT( - template - concept bool MergeableMutation = std::is_same::value || std::is_same::value; -) +template +concept MergeableMutation = std::is_same::value || std::is_same::value; class migration_manager : public seastar::async_sharded_service { private: @@ -100,7 +98,7 @@ public: future<> merge_schema_from(netw::msg_addr src, const std::vector& mutations); template - GCC6_CONCEPT(requires MergeableMutation) + requires MergeableMutation future<> merge_schema_in_background(netw::msg_addr src, const std::vector& mutations) { return with_gate(_background_tasks, [this, src, &mutations] { return merge_schema_from(src, mutations); diff --git a/service/pager/query_pager.hh b/service/pager/query_pager.hh index bc083c6c8d..e7e9d26713 100644 --- a/service/pager/query_pager.hh +++ b/service/pager/query_pager.hh @@ -150,7 +150,7 @@ protected: do_fetch_page(uint32_t page_size, gc_clock::time_point now, db::timeout_clock::time_point timeout); template - GCC6_CONCEPT(requires query::ResultVisitor) + requires query::ResultVisitor void handle_result(Visitor&& visitor, const foreign_ptr>& results, uint32_t page_size, gc_clock::time_point now); diff --git a/service/pager/query_pagers.cc b/service/pager/query_pagers.cc index 4554347b0f..dc3d0574f1 100644 --- a/service/pager/query_pagers.cc +++ b/service/pager/query_pagers.cc @@ -305,7 +305,7 @@ public: }; template - GCC6_CONCEPT(requires query::ResultVisitor) + requires query::ResultVisitor void query_pager::handle_result( Visitor&& visitor, const foreign_ptr>& results, diff --git a/sstables/checksum_utils.hh b/sstables/checksum_utils.hh index 925e0aa96b..4edd9a984b 100644 --- a/sstables/checksum_utils.hh +++ b/sstables/checksum_utils.hh @@ -22,24 +22,21 @@ #pragma once #include -#include #include "libdeflate/libdeflate.h" #include "utils/gz/crc_combine.hh" -GCC6_CONCEPT( template -concept bool ChecksumUtils = requires(const char* input, size_t size, uint32_t checksum) { - { Checksum::init_checksum() } -> uint32_t; - { Checksum::checksum(input, size) } -> uint32_t; - { Checksum::checksum(checksum, input, size) } -> uint32_t; - { Checksum::checksum_combine(checksum, checksum, size) } -> uint32_t; +concept ChecksumUtils = requires(const char* input, size_t size, uint32_t checksum) { + { Checksum::init_checksum() } -> std::same_as; + { Checksum::checksum(input, size) } -> std::same_as; + { Checksum::checksum(checksum, input, size) } -> std::same_as; + { Checksum::checksum_combine(checksum, checksum, size) } -> std::same_as; // Tells whether checksum_combine() should be preferred over checksum(). // For same checksummers it's faster to re-feed the buffer to checksum() than to // combine the checksum of the buffer. - { Checksum::prefer_combine() } -> bool; + { Checksum::prefer_combine() } -> std::same_as; }; -) struct adler32_utils { inline static uint32_t init_checksum() { diff --git a/sstables/compaction.cc b/sstables/compaction.cc index 8e53124615..2e7557bbb9 100644 --- a/sstables/compaction.cc +++ b/sstables/compaction.cc @@ -504,9 +504,7 @@ private: virtual flat_mutation_reader make_sstable_reader() const = 0; template - GCC6_CONCEPT( - requires CompactedFragmentsConsumer - ) + requires CompactedFragmentsConsumer future<> setup(GCConsumer gc_consumer) { auto ssts = make_lw_shared(_cf.get_compaction_strategy().make_sstable_set(_schema)); sstring formatted_msg = "["; @@ -661,9 +659,7 @@ public: } template - GCC6_CONCEPT( - requires CompactedFragmentsConsumer - ) + requires CompactedFragmentsConsumer static future run(std::unique_ptr c, GCConsumer gc_consumer = GCConsumer()); friend class compacting_sstable_writer; @@ -1304,9 +1300,7 @@ public: }; template -GCC6_CONCEPT( - requires CompactedFragmentsConsumer -) +requires CompactedFragmentsConsumer future compaction::run(std::unique_ptr c, GCConsumer gc_consumer) { return seastar::async([c = std::move(c), gc_consumer = std::move(gc_consumer)] () mutable { auto consumer = c->setup(std::move(gc_consumer)); diff --git a/sstables/compress.cc b/sstables/compress.cc index a0870b3902..49d40748b8 100644 --- a/sstables/compress.cc +++ b/sstables/compress.cc @@ -344,9 +344,7 @@ compression::locate(uint64_t position, const compression::segmented_offsets::acc } template -GCC6_CONCEPT( - requires ChecksumUtils -) +requires ChecksumUtils class compressed_file_data_source_impl : public data_source_impl { std::optional> _input_stream; sstables::compression* _compression_metadata; @@ -453,9 +451,7 @@ public: }; template -GCC6_CONCEPT( - requires ChecksumUtils -) +requires ChecksumUtils class compressed_file_data_source : public data_source { public: compressed_file_data_source(file f, sstables::compression* cm, @@ -466,9 +462,7 @@ public: }; template -GCC6_CONCEPT( - requires ChecksumUtils -) +requires ChecksumUtils inline input_stream make_compressed_file_input_stream( file f, sstables::compression *cm, uint64_t offset, size_t len, file_input_stream_options options) @@ -489,9 +483,7 @@ enum class compressed_checksum_mode { // where the buffer flushed will be compressed and its checksum computed, then // the result passed to a regular output stream. template -GCC6_CONCEPT( - requires ChecksumUtils -) +requires ChecksumUtils class compressed_file_data_sink_impl : public data_sink_impl { output_stream _out; sstables::compression* _compression_metadata; @@ -555,9 +547,7 @@ public: }; template -GCC6_CONCEPT( - requires ChecksumUtils -) +requires ChecksumUtils class compressed_file_data_sink : public data_sink { public: compressed_file_data_sink(file f, sstables::compression* cm, sstables::local_compression lc, file_output_stream_options options) @@ -566,9 +556,7 @@ public: }; template -GCC6_CONCEPT( - requires ChecksumUtils -) +requires ChecksumUtils inline output_stream make_compressed_file_output_stream(file f, file_output_stream_options options, sstables::compression* cm, const compression_parameters& cp) { diff --git a/sstables/data_consume_context.hh b/sstables/data_consume_context.hh index 61ca5efa83..c8799d4f0a 100644 --- a/sstables/data_consume_context.hh +++ b/sstables/data_consume_context.hh @@ -26,7 +26,6 @@ #include #include -#include #include "shared_sstable.hh" #include "row.hh" @@ -64,9 +63,7 @@ data_consume_rows(const schema&, shared_sstable, typename DataConsumeRowsContext // Moreover, the sstable object used for the sstable::data_consume_rows() // call which created this data_consume_context, must also be kept alive. template -GCC6_CONCEPT( - requires ConsumeRowsContext() -) +requires ConsumeRowsContext class data_consume_context { shared_sstable _sst; std::unique_ptr _ctx; diff --git a/sstables/mc/writer.cc b/sstables/mc/writer.cc index fe19c8d3b5..46cbb92992 100644 --- a/sstables/mc/writer.cc +++ b/sstables/mc/writer.cc @@ -191,7 +191,7 @@ public: }; template -GCC6_CONCEPT(requires Writer()) +requires Writer static void write(W& out, const clustering_block& block) { write_vint(out, block.header); for (const auto& [value, type]: block.values) { @@ -200,7 +200,7 @@ static void write(W& out, const clustering_block& block) { } template -GCC6_CONCEPT(requires Writer()) +requires Writer void write_clustering_prefix(W& out, const schema& s, const clustering_key_prefix& prefix, ephemerally_full_prefix is_ephemerally_full) { clustering_blocks_input_range range{s, prefix, is_ephemerally_full}; @@ -301,7 +301,7 @@ public: }; template -GCC6_CONCEPT(requires Writer()) +requires Writer void write_missing_columns(W& out, const indexed_columns& columns, const row& row) { for (const auto value: missing_columns_input_range{columns, row}) { write_vint(out, value); @@ -309,7 +309,7 @@ void write_missing_columns(W& out, const indexed_columns& columns, const row& ro } template -GCC6_CONCEPT(requires Writer()) +requires Writer void write_unsigned_delta_vint(W& out, T value, T base) { using unsigned_type = std::make_unsigned_t; unsigned_type unsigned_delta = static_cast(value) - static_cast(base); @@ -321,25 +321,25 @@ void write_unsigned_delta_vint(W& out, T value, T base) { } template -GCC6_CONCEPT(requires Writer()) +requires Writer void write_delta_timestamp(W& out, api::timestamp_type timestamp, const encoding_stats& enc_stats) { write_unsigned_delta_vint(out, timestamp, enc_stats.min_timestamp); } template -GCC6_CONCEPT(requires Writer()) +requires Writer void write_delta_ttl(W& out, gc_clock::duration ttl, const encoding_stats& enc_stats) { write_unsigned_delta_vint(out, ttl.count(), enc_stats.min_ttl.count()); } template -GCC6_CONCEPT(requires Writer()) +requires Writer void write_delta_local_deletion_time(W& out, int64_t local_deletion_time, const encoding_stats& enc_stats) { write_unsigned_delta_vint(out, local_deletion_time, enc_stats.min_local_deletion_time.time_since_epoch().count()); } template -GCC6_CONCEPT(requires Writer()) +requires Writer void write_delta_local_deletion_time(W& out, gc_clock::time_point ldt, const encoding_stats& enc_stats) { write_unsigned_delta_vint(out, ldt.time_since_epoch().count(), enc_stats.min_local_deletion_time.time_since_epoch().count()); } @@ -519,13 +519,11 @@ static bound_kind_m get_kind(const rt_marker& marker) { return marker.kind; } -GCC6_CONCEPT( template -concept bool Clustered = requires(T t) { - { t.key() } -> const clustering_key_prefix&; - { get_kind(t) } -> bound_kind_m; +concept Clustered = requires(T t) { + { t.key() } -> std::convertible_to; + { get_kind(t) } -> std::same_as; }; -) // Used for writing SSTables in 'mc' format. class writer : public sstable_writer::writer_impl { @@ -706,9 +704,7 @@ private: void write_clustered(const rt_marker& marker, uint64_t prev_row_size); template - GCC6_CONCEPT( - requires Clustered - ) + requires Clustered void write_clustered(const T& clustered) { clustering_info info {clustered.key(), get_kind(clustered)}; maybe_set_pi_first_clustering(info); @@ -1279,7 +1275,7 @@ stop_iteration writer::consume(clustering_row&& cr) { // Write clustering prefix along with its bound kind and, if not full, its size template -GCC6_CONCEPT(requires Writer()) +requires Writer static void write_clustering_prefix(W& writer, bound_kind_m kind, const schema& s, const clustering_key_prefix& clustering) { assert(kind != bound_kind_m::static_clustering); diff --git a/sstables/partition.cc b/sstables/partition.cc index 907c3e3321..74f1ba6fb2 100644 --- a/sstables/partition.cc +++ b/sstables/partition.cc @@ -28,7 +28,6 @@ #include "unimplemented.hh" #include "dht/i_partitioner.hh" #include -#include #include "index_reader.hh" #include "counters.hh" #include "utils/data_input.hh" @@ -76,22 +75,19 @@ position_in_partition_view get_slice_upper_bound(const schema& s, const query::p return position_in_partition_view::for_range_end(ranges.back()); } -GCC6_CONCEPT( template -concept bool RowConsumer() { - return requires(T t, +concept RowConsumer = + requires(T t, const partition_key& pk, position_range cr, db::timeout_clock::time_point timeout) { - { t.io_priority() } -> const io_priority_class&; - { t.is_mutation_end() } -> bool; - { t.setup_for_partition(pk) } -> void; - { t.push_ready_fragments() } -> void; - { t.maybe_skip() } -> std::optional; - { t.fast_forward_to(std::move(cr), timeout) } -> std::optional; + { t.io_priority() } -> std::convertible_to; + { t.is_mutation_end() } -> std::same_as; + { t.setup_for_partition(pk) } -> std::same_as; + { t.push_ready_fragments() } -> std::same_as; + { t.maybe_skip() } -> std::same_as>; + { t.fast_forward_to(std::move(cr), timeout) } -> std::same_as>; }; -} -) /* * Helper method to set or reset the range tombstone start bound according to the @@ -127,9 +123,7 @@ void set_range_tombstone_start_from_end_open_marker(Consumer& c, const schema& s } template -GCC6_CONCEPT( - requires RowConsumer() -) +requires RowConsumer class sstable_mutation_reader : public mp_row_consumer_reader { Consumer _consumer; bool _will_likely_slice = false; diff --git a/sstables/sstables.hh b/sstables/sstables.hh index 0e00c09968..f1fadf15dd 100644 --- a/sstables/sstables.hh +++ b/sstables/sstables.hh @@ -85,26 +85,21 @@ struct foreign_sstable_open_info; struct sstable_open_info; class sstables_manager; -GCC6_CONCEPT( template -concept bool ConsumeRowsContext() { - return requires(T c, indexable_element el, size_t s) { - { c.consume_input() } -> future<>; - { c.reset(el) } -> void; - { c.fast_forward_to(s, s) } -> future<>; - { c.position() } -> uint64_t; - { c.skip_to(s) } -> future<>; - { c.reader_position() } -> const sstables::reader_position_tracker&; - { c.eof() } -> bool; - { c.close() } -> future<>; +concept ConsumeRowsContext = + requires(T c, indexable_element el, size_t s) { + { c.consume_input() } -> std::same_as>; + { c.reset(el) } -> std::same_as; + { c.fast_forward_to(s, s) } -> std::same_as>; + { c.position() } -> std::same_as; + { c.skip_to(s) } -> std::same_as>; + { c.reader_position() } -> std::same_as; + { c.eof() } -> std::same_as; + { c.close() } -> std::same_as>; }; -} -) template -GCC6_CONCEPT( - requires ConsumeRowsContext() -) +requires ConsumeRowsContext class data_consume_context; class index_reader; diff --git a/sstables/types.hh b/sstables/types.hh index 444b832201..149c57452f 100644 --- a/sstables/types.hh +++ b/sstables/types.hh @@ -21,7 +21,6 @@ #pragma once -#include #include "disk_types.hh" #include #include "bytes.hh" @@ -49,14 +48,11 @@ static inline bytes_view to_bytes_view(const temporary_buffer& b) { namespace sstables { -GCC6_CONCEPT( template -concept bool Writer() { - return requires(T& wr, const char* data, size_t size) { - { wr.write(data, size) } -> void; +concept Writer = + requires(T& wr, const char* data, size_t size) { + { wr.write(data, size) } -> std::same_as; }; -} -) struct commitlog_interval { db::replay_position start; @@ -249,7 +245,7 @@ template uint64_t serialized_size(sstable_version_types v, const T& object); template -GCC6_CONCEPT(requires Writer()) +requires Writer typename std::enable_if_t::value && !std::is_enum::value, void> write(sstable_version_types v, W& out, const T& t); diff --git a/sstables/writer.hh b/sstables/writer.hh index 1ed214feba..418ba15a2f 100644 --- a/sstables/writer.hh +++ b/sstables/writer.hh @@ -127,9 +127,7 @@ serialized_size(sstable_version_types v, const T& object) { } template -GCC6_CONCEPT( - requires ChecksumUtils -) +requires ChecksumUtils class checksummed_file_data_sink_impl : public data_sink_impl { data_sink _out; struct checksum& _c; @@ -167,9 +165,7 @@ public: }; template -GCC6_CONCEPT( - requires ChecksumUtils -) +requires ChecksumUtils class checksummed_file_data_sink : public data_sink { public: checksummed_file_data_sink(file f, struct checksum& cinfo, uint32_t& full_file_checksum, file_output_stream_options options) @@ -177,9 +173,7 @@ public: }; template -GCC6_CONCEPT( - requires ChecksumUtils -) +requires ChecksumUtils inline output_stream make_checksummed_file_output_stream(file f, struct checksum& cinfo, uint32_t& full_file_checksum, file_output_stream_options options) { auto buffer_size = options.buffer_size; @@ -187,9 +181,7 @@ output_stream make_checksummed_file_output_stream(file f, struct checksum& } template -GCC6_CONCEPT( - requires ChecksumUtils -) +requires ChecksumUtils class checksummed_file_writer : public file_writer { checksum _c; uint32_t _full_checksum; @@ -217,7 +209,7 @@ using adler32_checksummed_file_writer = checksummed_file_writer; using crc32_checksummed_file_writer = checksummed_file_writer; template -GCC6_CONCEPT(requires Writer()) +requires Writer inline void write_vint_impl(W& out, T value) { using vint_type = std::conditional_t, unsigned_vint, signed_vint>; std::array encoding_buffer; @@ -226,24 +218,24 @@ inline void write_vint_impl(W& out, T value) { } template -GCC6_CONCEPT(requires Writer()) +requires Writer void write_unsigned_vint(W& out, uint64_t value) { return write_vint_impl(out, value); } template -GCC6_CONCEPT(requires Writer()) +requires Writer void write_signed_vint(W& out, int64_t value) { return write_vint_impl(out, value); } template -GCC6_CONCEPT(requires Writer()) +requires Writer typename std::enable_if_t> write_vint(W& out, T t) = delete; template -GCC6_CONCEPT(requires Writer()) +requires Writer inline void write_vint(W& out, T value) { static_assert(std::is_integral_v, "Non-integral values can't be written using write_vint"); return std::is_unsigned_v ? write_unsigned_vint(out, value) : write_signed_vint(out, value); @@ -251,7 +243,7 @@ inline void write_vint(W& out, T value) { template -GCC6_CONCEPT(requires Writer()) +requires Writer inline typename std::enable_if_t::value, void> write(sstable_version_types v, W& out, T i) { auto *nr = reinterpret_cast *>(&i); @@ -261,7 +253,7 @@ write(sstable_version_types v, W& out, T i) { } template -GCC6_CONCEPT(requires Writer()) +requires Writer inline typename std::enable_if_t::value, void> write(sstable_version_types v, W& out, T i) { write(v, out, static_cast::type>(i)); @@ -269,7 +261,7 @@ write(sstable_version_types v, W& out, T i) { template -GCC6_CONCEPT(requires Writer()) +requires Writer inline void write(sstable_version_types v, W& out, bool i) { write(v, out, static_cast(i)); } @@ -283,13 +275,13 @@ inline void write(sstable_version_types v, file_writer& out, double d) { template -GCC6_CONCEPT(requires Writer()) +requires Writer inline void write(sstable_version_types v, W& out, const bytes& s) { out.write(s); } template -GCC6_CONCEPT(requires Writer()) +requires Writer inline void write(sstable_version_types v, W& out, bytes_view s) { out.write(reinterpret_cast(s.data()), s.size()); } @@ -302,20 +294,20 @@ inline void write(sstable_version_types v, file_writer& out, bytes_ostream s) { template -GCC6_CONCEPT(requires Writer()) +requires Writer inline void write(sstable_version_types v, W& out, const First& first, const Second& second, Rest&&... rest) { write(v, out, first); write(v, out, second, std::forward(rest)...); } template -GCC6_CONCEPT(requires Writer()) +requires Writer inline void write(sstable_version_types v, W& out, const vint& t) { write_vint(out, t.value); } template -GCC6_CONCEPT(requires Writer()) +requires Writer typename std::enable_if_t::value && !std::is_enum::value, void> write(sstable_version_types v, W& out, const T& t) { // describe_type() is not const correct, so cheat here: @@ -534,7 +526,7 @@ void write_column_name(sstable_version_types v, Writer& out, const schema& s, co } template -GCC6_CONCEPT(requires Writer()) +requires Writer void write_cell_value(W& out, const abstract_type& type, bytes_view value) { if (!value.empty()) { if (type.value_length_if_fixed()) { @@ -547,7 +539,7 @@ void write_cell_value(W& out, const abstract_type& type, bytes_view value) { } template -GCC6_CONCEPT(requires Writer()) +requires Writer void write_cell_value(W& out, const abstract_type& type, atomic_cell_value_view value) { if (!value.empty()) { if (!type.value_length_if_fixed()) { @@ -559,7 +551,7 @@ void write_cell_value(W& out, const abstract_type& type, atomic_cell_value_view } template -GCC6_CONCEPT(requires Writer()) +requires Writer void write_counter_value(counter_cell_view ccv, W& out, sstable_version_types v, WriteLengthFunc&& write_len_func) { auto shard_count = ccv.shard_count(); static constexpr auto header_entry_size = sizeof(int16_t); diff --git a/table_helper.hh b/table_helper.hh index 88355b52a0..c167ac40c6 100644 --- a/table_helper.hh +++ b/table_helper.hh @@ -22,7 +22,6 @@ #pragma once -#include #include "cql3/statements/prepared_statement.hh" #include "service/migration_manager.hh" @@ -89,7 +88,7 @@ public: * @param opt_maker_args opt_maker arguments */ template - GCC6_CONCEPT( requires seastar::CanInvoke ) + requires seastar::CanInvoke future<> insert(service::query_state& qs, OptMaker opt_maker, Args... opt_maker_args) { return insert(qs, noncopyable_function([opt_maker = std::move(opt_maker), args = std::make_tuple(std::move(opt_maker_args)...)] () mutable { return apply(opt_maker, std::move(args)); diff --git a/test/lib/sstable_utils.hh b/test/lib/sstable_utils.hh index 66ac88d28b..701ac523ea 100644 --- a/test/lib/sstable_utils.hh +++ b/test/lib/sstable_utils.hh @@ -245,7 +245,7 @@ inline auto replacer_fn_no_op() { } template -GCC6_CONCEPT( requires requires (AsyncAction aa, sstables::sstable::version_types& c) { { aa(c) } -> future<>; } ) +requires requires (AsyncAction aa, sstables::sstable::version_types& c) { { aa(c) } -> std::same_as>; } inline future<> for_each_sstable_version(AsyncAction action) { return seastar::do_for_each(all_sstable_versions, std::move(action)); diff --git a/thrift/handler.cc b/thrift/handler.cc index caf3ea7c98..9371d0b0b7 100644 --- a/thrift/handler.cc +++ b/thrift/handler.cc @@ -188,14 +188,12 @@ std::string bytes_to_string(query::result_bytes_view v) { } namespace thrift { -GCC6_CONCEPT( template -concept bool Aggregator = +concept Aggregator = requires() { typename T::type; } && requires(T aggregator, typename T::type* aggregation, const bytes& name, const query::result_atomic_cell_view& cell) { - { aggregator.on_column(aggregation, name, cell) } -> void; + { aggregator.on_column(aggregation, name, cell) } -> std::same_as; }; -) } enum class query_order { no, yes }; @@ -1607,7 +1605,7 @@ private: }; template - GCC6_CONCEPT( requires thrift::Aggregator ) + requires thrift::Aggregator class column_visitor : public Aggregator { const schema& _s; const query::partition_slice& _slice; diff --git a/types.cc b/types.cc index 05217c5f37..3c23054b34 100644 --- a/types.cc +++ b/types.cc @@ -724,7 +724,7 @@ bool abstract_type::is_string() const { } template -GCC6_CONCEPT(requires CanHandleAllTypes) +requires CanHandleAllTypes static bool find(const abstract_type& t, const Predicate& f) { struct visitor { const Predicate& f; diff --git a/utils/crc.hh b/utils/crc.hh index 73a41a79f0..ed041e17d3 100644 --- a/utils/crc.hh +++ b/utils/crc.hh @@ -217,7 +217,7 @@ public: #endif template - GCC6_CONCEPT(requires FragmentRange) + requires FragmentRange void process_fragmented(const FragmentedBuffer& buffer) { using boost::range::for_each; for_each(buffer, [this] (bytes_view bv) { diff --git a/utils/enum_option.hh b/utils/enum_option.hh index f1f6671602..2b637b545f 100644 --- a/utils/enum_option.hh +++ b/utils/enum_option.hh @@ -26,13 +26,11 @@ #include #include -#include #include #include -GCC6_CONCEPT( template -concept bool HasMapInterface = requires(T t) { +concept HasMapInterface = requires(T t) { typename std::remove_reference::type::mapped_type; typename std::remove_reference::type::key_type; typename std::remove_reference::type::value_type; @@ -42,7 +40,6 @@ concept bool HasMapInterface = requires(T t) { t.cbegin(); t.cend(); }; -) /// A Boost program option holding an enum value. /// @@ -74,7 +71,7 @@ concept bool HasMapInterface = requires(T t) { /// ("vec", po::value>>()->multitoken(), "Type vector"); /// } template -GCC6_CONCEPT(requires HasMapInterface) +requires HasMapInterface class enum_option { using map_t = typename std::remove_reference::type; typename map_t::mapped_type _value; diff --git a/utils/fragment_range.hh b/utils/fragment_range.hh index 9e1d1837dc..a2874214e9 100644 --- a/utils/fragment_range.hh +++ b/utils/fragment_range.hh @@ -21,17 +21,15 @@ #pragma once +#include #include #include -#include #include "bytes.hh" enum class mutable_view { no, yes, }; -GCC6_CONCEPT( - /// Fragmented buffer /// /// Concept `FragmentedBuffer` is satisfied by any class that is a range of @@ -39,18 +37,16 @@ GCC6_CONCEPT( /// size of the buffer. The interfaces accepting `FragmentedBuffer` will attempt /// to avoid unnecessary linearisation. template -concept bool FragmentRange = requires (T range) { +concept FragmentRange = requires (T range) { typename T::fragment_type; requires std::is_same_v || std::is_same_v; - { *range.begin() } -> typename T::fragment_type; - { *range.end() } -> typename T::fragment_type; - { range.size_bytes() } -> size_t; - { range.empty() } -> bool; // returns true iff size_bytes() == 0. + { *range.begin() } -> std::convertible_to; + { *range.end() } -> std::convertible_to; + { range.size_bytes() } -> std::convertible_to; + { range.empty() } -> std::same_as; // returns true iff size_bytes() == 0. }; -) - template struct is_fragment_range : std::false_type { }; @@ -68,9 +64,7 @@ static constexpr bool is_fragment_range_v = is_fragment_range::value; /// adaptors below, i.e. it allows treating all fragment ranges /// uniformly as views. template -GCC6_CONCEPT( - requires FragmentRange -) +requires FragmentRange class fragment_range_view { const T* _range; public: @@ -127,16 +121,12 @@ struct empty_fragment_range { bool empty() const { return true; } }; -GCC6_CONCEPT( - static_assert(FragmentRange); static_assert(FragmentRange>); static_assert(FragmentRange>); -) - template -GCC6_CONCEPT(requires FragmentRange) +requires FragmentRange bytes linearized(const FragmentedBuffer& buffer) { bytes b(bytes::initialized_later(), buffer.size_bytes()); @@ -149,9 +139,9 @@ bytes linearized(const FragmentedBuffer& buffer) } template -GCC6_CONCEPT(requires FragmentRange && requires (Function fn, bytes_view bv) { +requires FragmentRange && requires (Function fn, bytes_view bv) { fn(bv); -}) +} decltype(auto) with_linearized(const FragmentedBuffer& buffer, Function&& fn) { bytes b; diff --git a/utils/fragmented_temporary_buffer.hh b/utils/fragmented_temporary_buffer.hh index f1c6db798f..c9e5ad206e 100644 --- a/utils/fragmented_temporary_buffer.hh +++ b/utils/fragmented_temporary_buffer.hh @@ -239,7 +239,7 @@ public: return !(*this == other); } }; -GCC6_CONCEPT(static_assert(FragmentRange)); +static_assert(FragmentRange); inline fragmented_temporary_buffer::operator view() const noexcept { @@ -251,12 +251,10 @@ inline fragmented_temporary_buffer::operator view() const noexcept namespace fragmented_temporary_buffer_concepts { -GCC6_CONCEPT( template -concept bool ExceptionThrower = requires(T obj, size_t n) { +concept ExceptionThrower = requires(T obj, size_t n) { obj.throw_out_of_range(n, n); }; -) } @@ -279,7 +277,7 @@ private: } template - GCC6_CONCEPT(requires fragmented_temporary_buffer_concepts::ExceptionThrower) + requires fragmented_temporary_buffer_concepts::ExceptionThrower void check_out_of_range(ExceptionThrower& exceptions, size_t n) { if (__builtin_expect(bytes_left() < n, false)) { exceptions.throw_out_of_range(n, bytes_left()); @@ -328,7 +326,7 @@ public: throw std::out_of_range(format("attempted to read {:d} bytes from a {:d} byte buffer", attempted_read, actual_left)); } }; - GCC6_CONCEPT(static_assert(fragmented_temporary_buffer_concepts::ExceptionThrower)); + static_assert(fragmented_temporary_buffer_concepts::ExceptionThrower); istream(const vector_type& fragments, size_t total_size) noexcept : _current(fragments.begin()) @@ -350,7 +348,7 @@ public: } template - GCC6_CONCEPT(requires fragmented_temporary_buffer_concepts::ExceptionThrower) + requires fragmented_temporary_buffer_concepts::ExceptionThrower T read(ExceptionThrower&& exceptions = default_exception_thrower()) { auto new_end = _current_position + sizeof(T); if (__builtin_expect(new_end > _current_end, false)) { @@ -363,7 +361,7 @@ public: } template - GCC6_CONCEPT(requires fragmented_temporary_buffer_concepts::ExceptionThrower) + requires fragmented_temporary_buffer_concepts::ExceptionThrower Output read_to(size_t n, Output out, ExceptionThrower&& exceptions = default_exception_thrower()) { auto new_end = _current_position + n; if (__builtin_expect(new_end <= _current_end, true)) { @@ -386,7 +384,7 @@ public: } template - GCC6_CONCEPT(requires fragmented_temporary_buffer_concepts::ExceptionThrower) + requires fragmented_temporary_buffer_concepts::ExceptionThrower view read_view(size_t n, ExceptionThrower&& exceptions = default_exception_thrower()) { auto new_end = _current_position + n; if (__builtin_expect(new_end <= _current_end, true)) { @@ -407,7 +405,7 @@ public: } template - GCC6_CONCEPT(requires fragmented_temporary_buffer_concepts::ExceptionThrower) + requires fragmented_temporary_buffer_concepts::ExceptionThrower bytes_view read_bytes_view(size_t n, bytes_ostream& linearization_buffer, ExceptionThrower&& exceptions = default_exception_thrower()) { auto new_end = _current_position + n; if (__builtin_expect(new_end <= _current_end, true)) { diff --git a/utils/linearizing_input_stream.hh b/utils/linearizing_input_stream.hh index bc79d9010d..083d2b098b 100644 --- a/utils/linearizing_input_stream.hh +++ b/utils/linearizing_input_stream.hh @@ -32,9 +32,7 @@ namespace utils { // Facilitates transparently reading from a fragmented range. template -GCC6_CONCEPT( - requires FragmentRange -) +requires FragmentRange class linearizing_input_stream { using iterator = typename T::iterator; using fragment_type = typename T::fragment_type; @@ -111,9 +109,7 @@ public: } template - GCC6_CONCEPT( - requires std::is_trivial_v - ) + requires std::is_trivial_v Type read_trivial() { auto [bv, linearized] = do_read(sizeof(Type)); auto ret = net::ntoh(*reinterpret_cast*>(bv.begin())); diff --git a/utils/loading_shared_values.hh b/utils/loading_shared_values.hh index 1404baf4e8..3c1b8c84fb 100644 --- a/utils/loading_shared_values.hh +++ b/utils/loading_shared_values.hh @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -54,12 +53,12 @@ template, typename Stats = do_nothing_loading_shared_values_stats, size_t InitialBucketsCount = 16> -GCC6_CONCEPT( requires requires () { +requires requires () { Stats::inc_hits(); Stats::inc_misses(); Stats::inc_blocks(); Stats::inc_evictions(); -}) +} class loading_shared_values { public: using key_type = Key; diff --git a/utils/log_heap.hh b/utils/log_heap.hh index d7ee0ad305..83224e3e31 100644 --- a/utils/log_heap.hh +++ b/utils/log_heap.hh @@ -26,7 +26,6 @@ #include #include #include -#include #include "seastarx.hh" namespace bi = boost::intrusive; @@ -132,11 +131,9 @@ struct log_heap_element_traits { * precision decreasing as values get larger. */ template -GCC6_CONCEPT( - requires requires() { - typename log_heap_element_traits; - } -) +requires requires() { + typename log_heap_element_traits; +} class log_heap final { // Ensure that (value << sub_bucket_index) in bucket_of() doesn't overflow static_assert(pow2_rank_constexpr(opts.max_size - opts.min_size + 1) + opts.sub_bucket_shift < std::numeric_limits::digits, "overflow"); diff --git a/utils/reusable_buffer.hh b/utils/reusable_buffer.hh index 227ea4b7a9..a584c36bf4 100644 --- a/utils/reusable_buffer.hh +++ b/utils/reusable_buffer.hh @@ -22,7 +22,6 @@ #pragma once #include -#include #include "bytes.hh" #include "bytes_ostream.hh" @@ -120,9 +119,9 @@ public: /// size of the buffer (less than or equal the previously specified maximum /// length). template - GCC6_CONCEPT(requires requires(Function fn, bytes_mutable_view view) { - { fn(view) } -> size_t; - }) + requires requires(Function fn, bytes_mutable_view view) { + { fn(view) } -> std::convertible_to; + } bytes_ostream make_buffer(size_t maximum_length, Function&& fn) { bytes_ostream output; bytes_mutable_view view = [&] { @@ -142,9 +141,9 @@ public: } template - GCC6_CONCEPT(requires requires(Function fn, bytes_mutable_view view) { - { fn(view) } -> size_t; - }) + requires requires(Function fn, bytes_mutable_view view) { + { fn(view) } -> std::same_as; + } fragmented_temporary_buffer make_fragmented_temporary_buffer(size_t maximum_length, size_t maximum_fragment_size, Function&& fn) { std::vector> fragments; bytes_mutable_view view = [&] { diff --git a/utils/serialization.hh b/utils/serialization.hh index 4f860d74ee..7375772cce 100644 --- a/utils/serialization.hh +++ b/utils/serialization.hh @@ -40,7 +40,6 @@ #include -#include #include #include #include "bytes.hh" @@ -60,9 +59,9 @@ static constexpr size_t serialize_int64_size = 8; namespace internal_impl { template -GCC6_CONCEPT(requires std::is_integral::value && std::is_integral::value && requires (CharOutputIterator it) { +requires std::is_integral::value && std::is_integral::value && requires (CharOutputIterator it) { *it++ = 'a'; -}) +} inline void serialize_int(CharOutputIterator& out, IntegerType val) { ExplicitIntegerType nval = net::hton(ExplicitIntegerType(val)); @@ -109,9 +108,9 @@ void serialize_bool(CharOutputIterator& out, bool val) { // For now we'll just assume those aren't in the string... // TODO: fix the compatibility with Java even in this case. template -GCC6_CONCEPT(requires requires (CharOutputIterator it) { +requires requires (CharOutputIterator it) { *it++ = 'a'; -}) +} inline void serialize_string(CharOutputIterator& out, const sstring& s) { // Java specifies that nulls in the string need to be replaced by the @@ -132,9 +131,9 @@ void serialize_string(CharOutputIterator& out, const sstring& s) { } template -GCC6_CONCEPT(requires requires (CharOutputIterator it) { +requires requires (CharOutputIterator it) { *it++ = 'a'; -}) +} inline void serialize_string(CharOutputIterator& out, const char* s) { // TODO: like above, need to change UTF-8 when above 16-bit. diff --git a/utils/with_relational_operators.hh b/utils/with_relational_operators.hh index af17e32cbe..f8cc195f87 100644 --- a/utils/with_relational_operators.hh +++ b/utils/with_relational_operators.hh @@ -21,22 +21,20 @@ #pragma once -#include #include +#include -GCC6_CONCEPT( template -concept bool HasTriCompare = +concept HasTriCompare = requires(const T& t) { - { t.compare(t) } -> int; + { t.compare(t) } -> std::same_as; } && std::is_same, int>::value; //FIXME: #1449 -) template class with_relational_operators { private: template - GCC6_CONCEPT( requires HasTriCompare ) + requires HasTriCompare int do_compare(const U& t) const { return static_cast(this)->compare(t); }