[PATCH] D50021: [ADT] Add a static function pointer type
David Blaikie via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 30 15:46:36 PDT 2018
I'd probably still vote in favor of a lambda, even if it made the iterator
type unutterable - do you have an example where that makes things
especially difficult to read?
On Mon, Jul 30, 2018 at 3:37 PM Hamza Sood via Phabricator via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> hamzasood created this revision.
> hamzasood added reviewers: dexonsmith, fhahn, chandlerc, timshen.
> Herald added a subscriber: llvm-commits.
>
> This patch adds a simple type that lets you create a functor from a
> function at compile time.
>
> While working on Clang, I needed a way to create an
> `llvm::filter_iterator` that filters based on the dynamic type as
> determined by `llvm::isa`. As far as I'm aware, the best way to do this
> currently (without lambdas as they'd make the iterator type unutterable) is:
>
> llvm::make_filter_range(MyRange, static_cast<bool(*)(Base
> *)>(&isa<Derived>))
>
> That's problematic because the iterator object ends up storing a function
> pointer; if the compiler can't follow the iterator's path from creation to
> use then it probably won't be able to get round the unnecessary
> indirection. This new type solves that by storing the function address as
> part of the object type, so there's no runtime overhead.
>
>
> Repository:
> rL LLVM
>
> https://reviews.llvm.org/D50021
>
> Files:
> include/llvm/ADT/STLExtras.h
> unittests/ADT/STLExtrasTest.cpp
>
>
> Index: unittests/ADT/STLExtrasTest.cpp
> ===================================================================
> --- unittests/ADT/STLExtrasTest.cpp
> +++ unittests/ADT/STLExtrasTest.cpp
> @@ -364,4 +364,21 @@
> EXPECT_EQ(5, count);
> }
>
> +int g() { return 42; }
> +void g(int &&) { }
> +
> +TEST(STLExtrasTest, static_fptr) {
> + {
> + static_fptr<int(), g> obj;
> + EXPECT_EQ(obj(), 42);
> + }
> +
> + // Check for perfect forwarding of the parameters.
> + {
> + static_fptr<void(int &&), g> obj;
> + int i = 0;
> + obj(std::move(i));
> + }
> +}
> +
> } // namespace
> Index: include/llvm/ADT/STLExtras.h
> ===================================================================
> --- include/llvm/ADT/STLExtras.h
> +++ include/llvm/ADT/STLExtras.h
> @@ -135,6 +135,26 @@
> operator bool() const { return callback; }
> };
>
> +/// A simple functor that just calls a function specified at compile time.
> +/// Unlike storing a function pointer, this has zero runtime overhead
> because
> +/// the function address is part of the object type.
> +///
> +/// Example usage:
> +/// void f();
> +///
> +/// static_fptr<void(), f> obj;
> +/// obj();
> +template<typename T, T *Fn,
> + typename = typename
> std::enable_if<std::is_function<T>::value>::type>
> +struct static_fptr {
> + template<typename... Args>
> + auto operator()(Args &&... args) const
> + noexcept(noexcept(Fn(std::forward<Args>(args)...)))
> + -> decltype(Fn(std::forward<Args>(args)...)) {
> + return Fn(std::forward<Args>(args)...);
> + }
> +};
> +
> // deleter - Very very very simple method that is used to invoke operator
> // delete on something. It is used like this:
> //
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180730/4caca891/attachment.html>
More information about the llvm-commits
mailing list