diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-05-06 01:44:26 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-05-06 01:44:26 +0000 |
commit | 36ecb2ee9d5cfd001383d7cf7751d830f7c579d1 (patch) | |
tree | a25c18ded5389f992f8323ffb39e2160fee7e1a9 /docs | |
parent | f3a199b2aec6071529f902a3c5d07556c46a8ae1 (diff) |
Re-commit r208025, reverted in r208030, with a fix for a conformance issue
which GCC detects and Clang does not!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208033 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'docs')
-rw-r--r-- | docs/CodingStandards.rst | 2 | ||||
-rw-r--r-- | docs/ProgrammersManual.rst | 72 |
2 files changed, 74 insertions, 0 deletions
diff --git a/docs/CodingStandards.rst b/docs/CodingStandards.rst index 0fcca0330f4..edbef3ace53 100644 --- a/docs/CodingStandards.rst +++ b/docs/CodingStandards.rst @@ -108,6 +108,8 @@ unlikely to be supported by our host compilers. * Lambdas: N2927_ * But *not* ``std::function``, until Clang implements `MSVC-compatible RTTI`_. + In many cases, you may be able to use ``llvm::function_ref`` instead, and it + is a superior choice in those cases. * And *not* lambdas with default arguments. * ``decltype``: N2343_ diff --git a/docs/ProgrammersManual.rst b/docs/ProgrammersManual.rst index 473d95df78c..7e46ac4e8e6 100644 --- a/docs/ProgrammersManual.rst +++ b/docs/ProgrammersManual.rst @@ -263,6 +263,78 @@ almost never be stored or mentioned directly. They are intended solely for use when defining a function which should be able to efficiently accept concatenated strings. +.. _function_apis: + +Passing functions and other callable objects +-------------------------------------------- + +Sometimes you may want a function to be passed a callback object. In order to +support lambda expressions and other function objects, you should not use the +traditional C approach of taking a function pointer and an opaque cookie: + +.. code-block:: c++ + + void takeCallback(bool (*Callback)(Function *, void *), void *Cookie); + +Instead, use one of the following approaches: + +Function template +^^^^^^^^^^^^^^^^^ + +If you don't mind putting the definition of your function into a header file, +make it a function template that is templated on the callable type. + +.. code-block:: c++ + + template<typename Callable> + void takeCallback(Callable Callback) { + Callback(1, 2, 3); + } + +The ``function_ref`` class template +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The ``function_ref`` +(`doxygen <http://llvm.org/doxygen/classllvm_1_1function_ref.html>`__) class +template represents a reference to a callable object, templated over the type +of the callable. This is a good choice for passing a callback to a function, +if you don't need to hold onto the callback after the function returns. + +``function_ref<Ret(Param1, Param2, ...)>`` can be implicitly constructed from +any callable object that can be called with arguments of type ``Param1``, +``Param2``, ..., and returns a value that can be converted to type ``Ret``. +For example: + +.. code-block:: c++ + + void visitBasicBlocks(Function *F, function_ref<bool (BasicBlock*)> Callback) { + for (BasicBlock &BB : *F) + if (Callback(&BB)) + return; + } + +can be called using: + +.. code-block:: c++ + + visitBasicBlocks(F, [&](BasicBlock *BB) { + if (process(BB)) + return isEmpty(BB); + return false; + }); + +Note that a ``function_ref`` object contains pointers to external memory, so +it is not generally safe to store an instance of the class (unless you know +that the external storage will not be freed). +``function_ref`` is small enough that it should always be passed by value. + +``std::function`` +^^^^^^^^^^^^^^^^^ + +You cannot use ``std::function`` within LLVM code, because it is not supported +by all our target toolchains. + + .. _DEBUG: The ``DEBUG()`` macro and ``-debug`` option |