/*! * \file invoke.h * \brief Template meta-programming utilities for callables * * Copyright (C) 2018 Christos Choutouridis * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more detail. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef __utl_meta_invoke_h__ #define __utl_meta_invoke_h__ #include #include #include #include /*! * \ingroup meta * \defgroup invoke * */ //! @{ namespace utl { namespace meta{ /*! * \name meta::invoke * * A meta-programming invoke() analogous. A \c meta::invocable shall contain a nested * template type named \b apply which is bind to actual invocable meta-function. * * - We can use \c wrap<> or even better \c quote<> in order to wrap a metafunction to a type (metafunction class) * - We can pass these wrapped types to other metafunctions * - We can \c invoke<> the inner \c apply from a wrapped metafunction class. */ //! @{ /*! * identity, identity_t. */ //! @{ template struct identity { #if defined (UTL_WORKAROUND_CWG_1558) // redirect unused Ts... via void_t template using apply = first_of<_Tp, void_t>; //!< identity is invokable, must also have apply #else template using apply = _Tp; //!< identity is invokable, must also have apply #endif using type = _Tp; //!< identity }; //! identity type alias template using identity_t = eval>; //! @} /*! * invoke, invoke_t */ //! @{ /*! * Invoke the nested apply meta-function from \c Fn with the arguments \c Args. * \note * This is an analogous to the std::invoke() */ template using invoke = typename Fn::template apply; /*! * Evaluate the invocation of the nested apply metafunction from \p Fn * with the arguments \p Args. */ template using invoke_t = eval< invoke >; //! @} //! wrap //! @{ /*! * wrap is a higher-order primitive that wraps an n-ary Metafunction * to create a corresponding Metafunction Class (Invocable). This way * we can pass Metafunctions as types to other metafunctions and let * them \c invoke the inner templated apply */ template