From 7ba5f29533f8c62e432ee243245ccdb006be0661 Mon Sep 17 00:00:00 2001 From: Thomas Spriggs Date: Thu, 29 Nov 2018 11:42:05 +0000 Subject: [PATCH] Make map work without specifying the type This commit updates `ranget.map` so that the type is inferred from the return type of the function passed. This makes the usage of `map` less verbose and makes it more inline with other `ranget` operations like `filter`. --- src/goto-programs/goto_trace.cpp | 2 +- src/util/range.h | 17 +++++++++++------ unit/util/range.cpp | 6 +++--- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/goto-programs/goto_trace.cpp b/src/goto-programs/goto_trace.cpp index a832810a3a..97ecb3467d 100644 --- a/src/goto-programs/goto_trace.cpp +++ b/src/goto-programs/goto_trace.cpp @@ -441,7 +441,7 @@ void show_compact_goto_trace( { auto arg_strings = make_range(step.function_arguments) - .map([&ns, &step](const exprt &arg) { + .map([&ns, &step](const exprt &arg) { return from_expr(ns, step.function, arg); }); diff --git a/src/util/range.h b/src/util/range.h index 211287fd1a..f994430b82 100644 --- a/src/util/range.h +++ b/src/util/range.h @@ -15,6 +15,7 @@ Author: Romain Brenguier, romain.brenguier@diffblue.com #define CPROVER_UTIL_RANGE_H #include +#include #include #include @@ -300,13 +301,17 @@ public: return ranget>(filter_begin, filter_end); } - /// Template argument type `outputt` has to be specified when \p f is given as - /// a lambda. - template - ranget> - map(std::function f) + /// The type of elements contained in the resulting range is deduced from the + /// return type of \p `f`. + template + auto map(functiont &&f) -> ranget::type>> { - auto shared_f = std::make_shared(std::move(f)); + using outputt = typename std::result_of::type; + auto shared_f = std::make_shared< + std::function>( + std::forward(f)); auto map_begin = map_iteratort(begin(), end(), shared_f); auto map_end = map_iteratort(end(), end(), shared_f); diff --git a/unit/util/range.cpp b/unit/util/range.cpp index 0372ac6a33..7da825c42c 100644 --- a/unit/util/range.cpp +++ b/unit/util/range.cpp @@ -29,8 +29,8 @@ SCENARIO("range tests", "[core][util][range]") } THEN("Use map to compute individual lengths") { - auto length_range = make_range(list).map( - [](const std::string &s) { return s.length(); }); + auto length_range = + make_range(list).map([](const std::string &s) { return s.length(); }); auto it = length_range.begin(); REQUIRE(*it == 3); ++it; @@ -54,7 +54,7 @@ SCENARIO("range tests", "[core][util][range]") auto range = make_range(list) .filter([&](const std::string &s) -> bool { return s[0] == 'a'; }) - .map([&](const std::string &s) { return s.length(); }); + .map([&](const std::string &s) { return s.length(); }); // Note that everything is performed on the fly, so none of the filter // and map functions have been computed yet, and no intermediary container // is created.