SpECTRE Documentation Coverage Report
Current view: top level - Utilities/TypeTraits - IsCallable.hpp Hit Total Coverage
Commit: 3c072f0ce967e2e56649d3fa12aa2a0e4fe2a42e Lines: 5 6 83.3 %
Date: 2024-04-23 20:50:18
Legend: Lines: hit not hit

          Line data    Source code
       1           0 : // Distributed under the MIT License.
       2             : // See LICENSE.txt for details.
       3             : 
       4             : #pragma once
       5             : 
       6             : #include <type_traits>
       7             : 
       8             : namespace tt {
       9             : /// @{
      10             : /// \ingroup TypeTraitsGroup
      11             : /// \brief Check if a type `T` is callable, i.e. `T(Args...)` is evaluable.
      12             : ///
      13             : /// \details
      14             : /// Inherits from std::true_type if `TT` has the call operator, operator()
      15             : /// defined with arguments `TArgs...`, otherwise inherits from std::false_type.
      16             : ///
      17             : /// \usage
      18             : /// For any type `TT` and types `TArgs_i`,
      19             : /// \code
      20             : /// using result = tt::is_callable<TT, TArgs_0, TArgs_1, TArgs_2>;
      21             : /// \endcode
      22             : ///
      23             : /// \metareturns
      24             : /// std::bool_constant
      25             : ///
      26             : /// \semantics
      27             : /// If the type `TT` defines operator() with arguments `TArgs...`, then
      28             : /// \code
      29             : /// typename result::type = std::true_type;
      30             : /// \endcode
      31             : /// otherwise
      32             : /// \code
      33             : /// typename result::type = std::false_type;
      34             : /// \endcode
      35             : ///
      36             : /// \example
      37             : /// \snippet Test_IsCallable.cpp is_callable_example
      38             : /// \see std::is_callable
      39             : /// \tparam TT the class to check
      40             : /// \tparam TArgs the args passed to operator()
      41             : template <typename TT, typename... TArgs>
      42           1 : class is_callable {
      43             :   // The reason we have private before public here is that we have static member
      44             :   // functions and since this is meant to be a super lightweight helper class
      45             :   // it's better to break convention than increase code size.
      46             :  private:
      47             :   /// \cond
      48             :   // We pass an int here to disambiguate the two possible templates and have the
      49             :   // compiler prefer the first one. If it cannot be used because there's no
      50             :   // call operator, then it uses the second one.
      51             :   template <typename T, typename... Args>
      52             :   static auto test_callable(int)
      53             :       -> decltype(std::declval<T>()(std::declval<Args>()...), std::true_type());
      54             : 
      55             :   template <typename, typename...>
      56             :   static auto test_callable(...) -> std::false_type;
      57             :   /// \endcond
      58             : 
      59             :  public:
      60             :   /// `true` if callable, `false` otherwise
      61           1 :   static constexpr bool value = decltype(test_callable<TT, TArgs...>(0))::value;
      62             :   /// `std::true_type` if callable, `std::false_type` otherwise
      63           1 :   using type = std::integral_constant<bool, value>;
      64             : };
      65             : /// \see is_callable
      66             : template <typename T, typename... Args>
      67           1 : constexpr bool is_callable_v = is_callable<T, Args...>::value;
      68             : 
      69             : /// \see is_callable
      70             : template <typename T, typename... Args>
      71           1 : using is_callable_t = typename is_callable<T, Args...>::type;
      72             : /// @}
      73             : }  // namespace tt

Generated by: LCOV version 1.14