.. _type_traits:

Type Traits
---------------

TooManyCooks offers some concepts / type traits in the ``tmc::traits`` namespace, accessible by including
``tmc/traits.hpp``. There are two groups of traits.

First, traits to let you work with values/awaitables/packaged tasks:

* if a type is awaitable or not
* if awaitable, what is the result type
* if a type is non-awaitable callable with no arguments
* if non-awaitable callable with no arguments, what is the return type
* (combining the above) the result of awaiting or calling a type

Example usage - a generic handler that can accept any value, awaitable, or packaged task:

.. code-block:: cpp

  template <typename T>
  void handler(T&& t) {
    if constexpr (tmc::traits::is_awaitable<T>) {
      process(co_await std::forward<T>(t));
    } else if constexpr (tmc::traits::is_callable<T>) {
      process(std::forward<T>(t)());
    } else {
      process(std::forward<T>(t));
    }
  }

Secondly, traits to let you work with ``tmc::task`` and functors:

* if a type is a task
* if a type is a void-returning or non-void-returning task
* if a type is a non-task functor
* if a type is a void-returning or non-void-returning non-task functor

For full info, see the documentation inline at:
`tmc/traits.hpp <https://github.com/tzcnt/TooManyCooks/blob/main/include/tmc/traits.hpp>`_
