From d18a279e696655f8e2c4072c7ad0ea4aecb16fdf Mon Sep 17 00:00:00 2001 From: Kyle Knoepfel Date: Fri, 31 Jul 2026 15:42:10 -0500 Subject: [PATCH 1/3] Resolve performance-unnecessary-value-param clang-tidy warning --- .clang-tidy | 2 +- .../storage_associative_write_container.cpp | 4 +- phlex/app/load_module.cpp | 2 +- phlex/core/framework_graph.cpp | 11 ++- phlex/core/framework_graph.hpp | 50 ++++++----- phlex/core/glue.cpp | 3 +- phlex/core/glue.hpp | 74 +++++++++------ phlex/core/graph_proxy.hpp | 90 +++++++++++-------- phlex/core/index_router.cpp | 19 ++-- phlex/core/index_router.hpp | 8 +- phlex/core/make_computational_edges.cpp | 10 +-- phlex/core/registration_api.cpp | 6 +- phlex/core/registration_api.hpp | 54 +++++------ phlex/core/store_counters.cpp | 2 +- phlex/core/store_counters.hpp | 2 +- phlex/detail/plugin_macros.hpp | 15 ++-- phlex/driver.hpp | 2 +- phlex/metaprogramming/delegate.hpp | 35 ++++---- phlex/model/data_layer_hierarchy.cpp | 2 +- phlex/model/data_layer_hierarchy.hpp | 2 +- phlex/model/fixed_hierarchy.cpp | 12 ++- phlex/model/fixed_hierarchy.hpp | 10 +-- phlex/model/flush_gate.cpp | 5 +- phlex/model/flush_gate.hpp | 2 +- phlex/module.hpp | 2 +- phlex/source.hpp | 2 +- plugins/layer_generator.cpp | 2 +- plugins/layer_generator.hpp | 2 +- plugins/python/src/modulewrap.cpp | 14 +-- plugins/python/src/pymodule.cpp | 4 +- plugins/python/src/wrap.hpp | 4 +- test/flush_gate_test.cpp | 13 +-- 32 files changed, 261 insertions(+), 204 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index eaa135f08..c9894f1bc 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -98,7 +98,7 @@ CheckOptions: - key: performance-move-const-arg.CheckTriviallyCopyableMove value: '1' - key: performance-unnecessary-value-param.AllowedTypes - value: '' + value: 'data_cell_cursor;handle' # Modernize settings - key: modernize-use-override.AllowOverrideAndFinal diff --git a/form/storage/storage_associative_write_container.cpp b/form/storage/storage_associative_write_container.cpp index 71d9438c3..b08f0dec2 100644 --- a/form/storage/storage_associative_write_container.cpp +++ b/form/storage/storage_associative_write_container.cpp @@ -2,6 +2,8 @@ #include "storage_associative_write_container.hpp" +#include + using namespace form::detail::experimental; Storage_Associative_Write_Container::Storage_Associative_Write_Container(std::string const& name) : @@ -26,5 +28,5 @@ std::string const& Storage_Associative_Write_Container::col_name() { return m_cN void Storage_Associative_Write_Container::setParent( std::shared_ptr parent) { - m_parent = parent; + m_parent = std::move(parent); } diff --git a/phlex/app/load_module.cpp b/phlex/app/load_module.cpp index 2878030e6..e4d1e1ef5 100644 --- a/phlex/app/load_module.cpp +++ b/phlex/app/load_module.cpp @@ -50,7 +50,7 @@ namespace phlex::detail { void operator()(driver_proxy proxy, configuration const& config, driver_bundle* out) const { - fn(proxy, config, out); + fn(std::move(proxy), config, out); } }; diff --git a/phlex/core/framework_graph.cpp b/phlex/core/framework_graph.cpp index 13106d486..6943aed7e 100644 --- a/phlex/core/framework_graph.cpp +++ b/phlex/core/framework_graph.cpp @@ -43,7 +43,7 @@ namespace phlex::detail { tbb::flow::unlimited, [this](ready_flushes_then_emit const& input) -> data_cell_index_ptr { auto&& [ready_flushes, index_to_emit] = input; - return index_router_.route(index_to_emit, std::move(ready_flushes)); + return index_router_.route(index_to_emit, ready_flushes); }}, hierarchy_node_{graph_, tbb::flow::unlimited, @@ -82,7 +82,7 @@ namespace phlex::detail { if (shutdown_on_error_) { // When in an error state, we need to sanely pop the layer stack and wait for any tasks to finish. auto remaining_flushes = cell_tracker_.report_and_evict_ready_flushes(nullptr); - index_router_.drain(std::move(remaining_flushes)); + index_router_.drain(remaining_flushes); graph_.wait_for_all(); } } @@ -213,13 +213,13 @@ namespace phlex::detail { } // Index-router finalization makes edges between the index-set nodes and the provider nodes. - finalize_router(std::move(provider_input_ports), std::move(multilayer_join_index_ports)); + finalize_router(std::move(provider_input_ports), multilayer_join_index_ports); } // FIXME: Much, if not all, of this logic should be moved to the index_router. void framework_graph::finalize_router( index_router::provider_input_ports_t provider_input_ports, - std::map multilayer_join_index_ports) + std::map const& multilayer_join_index_ports) { std::set unfold_input_layer_names; @@ -248,7 +248,6 @@ namespace phlex::detail { unfold_input_layer_names.end()), unfold_output_layer_names); index_router_.register_unfold_count_per_input_layer(std::move(unfold_count_per_input_layer)); - index_router_.finalize( - graph_, std::move(provider_input_ports), std::move(multilayer_join_index_ports)); + index_router_.finalize(graph_, std::move(provider_input_ports), multilayer_join_index_ports); } } diff --git a/phlex/core/framework_graph.hpp b/phlex/core/framework_graph.hpp index 67369b54c..3fd6ed344 100644 --- a/phlex/core/framework_graph.hpp +++ b/phlex/core/framework_graph.hpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -56,7 +57,8 @@ namespace phlex::detail { requires requires(std::shared_ptr generator, std::vector sources) { { driver_proxy{sources}.driver(generator) } -> std::same_as; } - void add_driver(std::shared_ptr generator) + void add_driver( + std::shared_ptr generator) // NOLINT(performance-unnecessary-value-param) { add_driver(driver_proxy().driver(std::move(generator))); } @@ -76,7 +78,7 @@ namespace phlex::detail { return {config, graph_, nodes_, registration_errors_}; } - detail::driver_proxy driver_proxy(std::vector strings = {}) + detail::driver_proxy driver_proxy(std::vector const& strings = {}) { return detail::driver_proxy{nodes_.sources_for(strings)}; } @@ -87,54 +89,57 @@ namespace phlex::detail { // right? template - auto fold(std::string name, + auto fold(std::string_view name, is_fold_like auto f, concurrency c = concurrency::serial, std::string partition = "job", InitArgs&&... init_args) { - return make_glue().fold(std::move(name), - std::move(f), - c, - std::move(partition), - std::forward(init_args)...); + return make_glue().fold( + name, std::move(f), c, std::move(partition), std::forward(init_args)...); } template - auto unfold(std::string name, + auto unfold(std::string_view name, is_predicate_like auto pred, auto unf, concurrency c, std::string destination_data_layer) { return make_glue().unfold( - std::move(name), std::move(pred), std::move(unf), c, std::move(destination_data_layer)); + name, std::move(pred), std::move(unf), c, std::move(destination_data_layer)); } - auto observe(std::string name, is_observer_like auto f, concurrency c = concurrency::serial) + auto observe(std::string_view name, + is_observer_like auto f, + concurrency c = concurrency::serial) { - return make_glue().observe(std::move(name), std::move(f), c); + return make_glue().observe(name, std::move(f), c); } - auto predicate(std::string name, is_predicate_like auto f, concurrency c = concurrency::serial) + auto predicate(std::string_view name, + is_predicate_like auto f, + concurrency c = concurrency::serial) { - return make_glue().predicate(std::move(name), std::move(f), c); + return make_glue().predicate(name, std::move(f), c); } - auto transform(std::string name, is_transform_like auto f, concurrency c = concurrency::serial) + auto transform(std::string_view name, + is_transform_like auto f, + concurrency c = concurrency::serial) { - return make_glue().transform(std::move(name), std::move(f), c); + return make_glue().transform(name, std::move(f), c); } - auto provide(std::string name, auto f, concurrency c = concurrency::serial) + auto provide(std::string_view name, auto f, concurrency c = concurrency::serial) { - return make_glue().provide(std::move(name), std::move(f), c); + return make_glue().provide(name, std::move(f), c); } template Source, typename... Args> - void add_source(std::string name, Args&&... args) + void add_source(std::string_view name, Args&&... args) { - return make_glue().template add_source(std::move(name), std::forward(args)...); + return make_glue().template add_source(name, std::forward(args)...); } template @@ -184,8 +189,9 @@ namespace phlex::detail { void throw_if_registration_errors() const; void make_filter_edges(); void make_bookkeeping_edges(); - void finalize_router(index_router::provider_input_ports_t provider_input_ports, - std::map multilayer_join_index_ports); + void finalize_router( + index_router::provider_input_ports_t provider_input_ports, + std::map const& multilayer_join_index_ports); enum class driver_mode { default_driver, deferred_driver }; explicit framework_graph(driver_mode mode, int max_parallelism); diff --git a/phlex/core/glue.cpp b/phlex/core/glue.cpp index d8d78261e..f07c9e6db 100644 --- a/phlex/core/glue.cpp +++ b/phlex/core/glue.cpp @@ -3,9 +3,10 @@ #include #include +#include namespace phlex::detail::internal { - void verify_name(std::string const& name, configuration const* config) + void verify_name(std::string_view name, configuration const* config) { if (not name.empty()) { return; diff --git a/phlex/core/glue.hpp b/phlex/core/glue.hpp index b9b098368..e79e9a0f8 100644 --- a/phlex/core/glue.hpp +++ b/phlex/core/glue.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -25,7 +26,7 @@ namespace phlex { namespace phlex::detail { struct node_catalog; namespace internal { - PHLEX_CORE_EXPORT void verify_name(std::string const& name, configuration const* config); + PHLEX_CORE_EXPORT void verify_name(std::string_view name, configuration const* config); } // ============================================================================== @@ -52,14 +53,19 @@ namespace phlex::detail { { } + // 'f' is a by-value sink: it is moved into algorithm_bits. The clang-tidy + // warning to take it by const reference is a false positive. template - auto fold( - std::string name, auto f, concurrency c, std::string partition, InitArgs&&... init_args) + auto fold(std::string_view name, + auto f, // NOLINT(performance-unnecessary-value-param) + concurrency c, + std::string partition, + InitArgs&&... init_args) { internal::verify_name(name, config_); return fold_api{config_, - std::move(name), - algorithm_bits(bound_obj_, std::move(f)), + name, + algorithm_bits(std::move(bound_obj_), std::move(f)), c, graph_, nodes_, @@ -68,59 +74,75 @@ namespace phlex::detail { std::forward(init_args)...}; } + // 'f' is a by-value sink: it is moved into algorithm_bits. The clang-tidy + // warning to take it by const reference is a false positive. template - auto observe(std::string name, FT f, concurrency c) + auto observe(std::string_view name, + FT f, // NOLINT(performance-unnecessary-value-param) + concurrency c) { internal::verify_name(name, config_); return make_registration(config_, - std::move(name), - algorithm_bits{bound_obj_, std::move(f)}, + name, + algorithm_bits{std::move(bound_obj_), std::move(f)}, c, graph_, nodes_, errors_); } + // 'f' is a by-value sink: it is moved into algorithm_bits. The clang-tidy + // warning to take it by const reference is a false positive. template - auto provide(std::string name, FT f, concurrency c) + auto provide(std::string_view name, + FT f, // NOLINT(performance-unnecessary-value-param) + concurrency c) { internal::verify_name(name, config_); return provider_api{config_, - std::move(name), - algorithm_bits{bound_obj_, std::move(f)}, + name, + algorithm_bits{std::move(bound_obj_), std::move(f)}, c, graph_, nodes_, errors_}; } + // 'f' is a by-value sink: it is moved into algorithm_bits. The clang-tidy + // warning to take it by const reference is a false positive. template - auto transform(std::string name, FT f, concurrency c) + auto transform(std::string_view name, + FT f, // NOLINT(performance-unnecessary-value-param) + concurrency c) { internal::verify_name(name, config_); return make_registration(config_, - std::move(name), - algorithm_bits{bound_obj_, std::move(f)}, + name, + algorithm_bits{std::move(bound_obj_), std::move(f)}, c, graph_, nodes_, errors_); } + // 'f' is a by-value sink: it is moved into algorithm_bits. The clang-tidy + // warning to take it by const reference is a false positive. template - auto predicate(std::string name, FT f, concurrency c) + auto predicate(std::string_view name, + FT f, // NOLINT(performance-unnecessary-value-param) + concurrency c) { internal::verify_name(name, config_); return make_registration(config_, - std::move(name), - algorithm_bits{bound_obj_, std::move(f)}, + name, + algorithm_bits{std::move(bound_obj_), std::move(f)}, c, graph_, nodes_, errors_); } - auto unfold(std::string name, + auto unfold(std::string_view name, auto predicate, auto unfold, concurrency c, @@ -130,7 +152,7 @@ namespace phlex::detail { internal::verify_name(name, config_); return unfold_api{ config_, - std::move(name), + name, std::move(predicate), std::move(unfold), c, @@ -140,23 +162,23 @@ namespace phlex::detail { std::move(destination_data_layer)}; } - auto output(std::string name, is_output_like auto f, concurrency c = concurrency::serial) + auto output(std::string_view name, is_output_like auto f, concurrency c = concurrency::serial) { return output_api{nodes_.registrar_for(errors_), config_, - std::move(name), + name, graph_, - delegate(bound_obj_, f), + delegate(std::move(bound_obj_), f), c}; } template Source, typename... Args> - void add_source(std::string name, Args&&... args) + void add_source(std::string_view name, Args&&... args) { - auto [_, inserted] = - nodes_.sources.try_emplace(name, std::make_unique(std::forward(args)...)); + auto [_, inserted] = nodes_.sources.try_emplace( + std::string{name}, std::make_unique(std::forward(args)...)); if (not inserted) { - internal::add_to_error_messages(errors_, "Source", name); // From registrar.hpp + internal::add_to_error_messages(errors_, "Source", std::string{name}); // From registrar.hpp } } diff --git a/phlex/core/graph_proxy.hpp b/phlex/core/graph_proxy.hpp index 596c488a1..e851551bd 100644 --- a/phlex/core/graph_proxy.hpp +++ b/phlex/core/graph_proxy.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -47,48 +48,60 @@ namespace phlex::detail { /// Returns a new proxy through which member functions of that object may /// be registered as algorithm nodes. template - graph_proxy make(Args&&... args) + graph_proxy make(Args&&... args) const requires(not is_bound_object); + // In the registration methods below, 'f' is a by-value sink: it is ultimately + // moved into algorithm_bits. The clang-tidy warning to take it by const + // reference is a false positive. + /// @brief Registers a fold algorithm node. template - auto fold(std::string name, - is_fold_like auto f, + auto fold(std::string_view name, + is_fold_like auto f, // NOLINT(performance-unnecessary-value-param) concurrency c = concurrency::serial, std::string partition = "job", - InitArgs&&... init_args); + InitArgs&&... init_args) const; /// @brief Registers an observer node. - auto observe(std::string name, is_observer_like auto f, concurrency c = concurrency::serial); + auto observe(std::string_view name, + is_observer_like auto f, // NOLINT(performance-unnecessary-value-param) + concurrency c = concurrency::serial) const; /// @brief Registers a predicate node. - auto predicate(std::string name, is_predicate_like auto f, concurrency c = concurrency::serial); + auto predicate(std::string_view name, + is_predicate_like auto f, // NOLINT(performance-unnecessary-value-param) + concurrency c = concurrency::serial) const; /// @brief Registers a provider node. - auto provide(std::string name, is_provider_like auto f, concurrency c = concurrency::serial); + auto provide(std::string_view name, + is_provider_like auto f, // NOLINT(performance-unnecessary-value-param) + concurrency c = concurrency::serial) const; /// @brief Registers a transform node. - auto transform(std::string name, is_transform_like auto f, concurrency c = concurrency::serial); + auto transform(std::string_view name, + is_transform_like auto f, // NOLINT(performance-unnecessary-value-param) + concurrency c = concurrency::serial) const; /// @brief Registers an unfold node. template - auto unfold(std::string name, + auto unfold(std::string_view name, is_predicate_like auto pred, auto unf, std::string destination_data_layer, - concurrency c = concurrency::serial); + concurrency c = concurrency::serial) const; /// @brief Registers a source (used by the framework to create provider nodes) template Source, typename... Args> - void add_source(std::string name, Args&&... args) + void add_source(std::string_view name, Args&&... args) const requires(not is_bound_object); /// @brief Registers an output node. - auto output(std::string name, is_output_like auto f, concurrency c = concurrency::serial); + auto output(std::string_view name, is_output_like auto f, concurrency c = concurrency::serial); protected: template