---
title: llarp/util/meta/traits.hpp

---

# llarp/util/meta/traits.hpp



## Namespaces

| Name           |
| -------------- |
| **[llarp](Namespaces/namespacellarp.md)** <br>[crypto.hpp] |
| **[llarp::traits](Namespaces/namespacellarp_1_1traits.md)**  |
| **[llarp::traits::Switch](Namespaces/namespacellarp_1_1traits_1_1Switch.md)**  |
| **[llarp::traits::select](Namespaces/namespacellarp_1_1traits_1_1select.md)**  |
| **[llarp::traits::detail](Namespaces/namespacellarp_1_1traits_1_1detail.md)**  |

## Classes

|                | Name           |
| -------------- | -------------- |
| struct | **[llarp::traits::Bottom](Classes/structllarp_1_1traits_1_1Bottom.md)** <br>Represents the empty type.  |
| struct | **[llarp::traits::Tag](Classes/structllarp_1_1traits_1_1Tag.md)** <br>Int tag.  |
| struct | **[llarp::traits::is_pointy](Classes/structllarp_1_1traits_1_1is__pointy.md)** <br>Type trait representing whether a type is pointer-like.  |
| struct | **[llarp::traits::is_pointy< T, std::conditional_t< false, std::void_t< decltype(*std::declval< T >())>, void > >](Classes/structllarp_1_1traits_1_1is__pointy_3_01T_00_01std_1_1conditional__t_3_01false_00_01std_1_1void_eb57b2cb5c14b68c2058ea7df87d2d54.md)**  |
| struct | **[llarp::traits::is_container](Classes/structllarp_1_1traits_1_1is__container.md)** <br>Type trait representing whether a type is an STL-style container.  |
| struct | **[llarp::traits::is_container< T, std::conditional_t< false, std::void_t< typename T::value_type, typename T::size_type, typename T::iterator, typename T::const_iterator, decltype(std::declval< T >().size()), decltype(std::declval< T >().begin()), decltype(std::declval< T >().end()), decltype(std::declval< T >().cbegin()), decltype(std::declval< T >().cend()) >, void > >](Classes/structllarp_1_1traits_1_1is__container_3_01T_00_01std_1_1conditional__t_3_01false_00_01std_1.md)**  |
| struct | **[llarp::traits::Switch::Switch](Classes/structllarp_1_1traits_1_1Switch_1_1Switch.md)**  |
| struct | **[llarp::traits::Switch::Switch< 0u, T, Types... >](Classes/structllarp_1_1traits_1_1Switch_1_1Switch_3_010u_00_01T_00_01Types_8_8_8_01_4.md)**  |
| struct | **[llarp::traits::Switch::Switch< Selector, Tn, Types... >](Classes/structllarp_1_1traits_1_1Switch_1_1Switch_3_01Selector_00_01Tn_00_01Types_8_8_8_01_4.md)**  |
| class | **[llarp::traits::select::False](Classes/classllarp_1_1traits_1_1select_1_1False.md)** <br>This provides a way to do a compile-type dispatch based on type traits.  |
| class | **[llarp::traits::select::Case](Classes/classllarp_1_1traits_1_1select_1_1Case.md)** <br>a case in the selection  |
| struct | **[llarp::traits::select::Case::Selector](Classes/structllarp_1_1traits_1_1select_1_1Case_1_1Selector.md)**  |
| struct | **[llarp::traits::select::SelectHelper](Classes/structllarp_1_1traits_1_1select_1_1SelectHelper.md)** <br>implementation helper  |
| struct | **[llarp::traits::select::Select](Classes/structllarp_1_1traits_1_1select_1_1Select.md)**  |




## Source code

```cpp
#pragma once

#include <cstddef>
#include <type_traits>
#include <utility>
#include <tuple>

namespace llarp
{
  namespace traits
  {
    struct Bottom
    {};

    template <size_t N>
    struct Tag
    {
      char arr[N + 1];
    };

    template <typename T, typename _ = void>
    struct is_pointy : public std::false_type
    {};

    // We take the following things:
    // - has element_type typedef
    // - has dereference operator
    // - has arrow operator
    template <typename T>
    struct is_pointy<T, std::conditional_t<false, std::void_t<decltype(*std::declval<T>())>, void>>
        : public std::true_type
    {};

    template <typename T, typename _ = void>
    struct is_container : public std::false_type
    {};

    // We take that the container has begin, end and size methods to be a
    // container.
    // clang-format off
    template < typename T >
    struct is_container<
        T,
        std::conditional_t<
            false,
            std::void_t< typename T::value_type,
                    typename T::size_type,
                    typename T::iterator,
                    typename T::const_iterator,
                    decltype(std::declval<T>().size()),
                    decltype(std::declval<T>().begin()),
                    decltype(std::declval<T>().end()),
                    decltype(std::declval<T>().cbegin()),
                    decltype(std::declval<T>().cend()) >,
            void > > : public std::true_type
    {
    };
    // clang-format on

    namespace Switch
    {
      template <size_t Selector, typename... Types>
      struct Switch
      {
        using Type = Bottom;
      };

      template <typename T, typename... Types>
      struct Switch<0u, T, Types...>
      {
        using Type = T;
      };

      template <size_t Selector, typename Tn, typename... Types>
      struct Switch<Selector, Tn, Types...>
      {
        using Type = typename Switch<Selector - 1, Types...>::Type;
      };

    }  // namespace Switch

    namespace select
    {

      template <typename>
      class False : public std::false_type
      {};

      template <template <typename...> class Trait = False>
      class Case
      {
       public:
        template <typename Type>
        struct Selector : public Trait<Type>::type
        {};

        using Type = Case;
      };

      // clang-format off

      template < typename T,
                 template < typename... > class Trait1,
                 template < typename... > class Trait2,
                 template < typename... > class Trait3,
                 template < typename... > class Trait4,
                 template < typename... > class Trait5,
                 template < typename... > class Trait6,
                 template < typename... > class Trait7,
                 template < typename... > class Trait8,
                 template < typename... > class Trait9 >
      struct SelectHelper {
          enum {
              Selector = (
                  Trait1<T>::value ? 1 :
                  Trait2<T>::value ? 2 :
                  Trait3<T>::value ? 3 :
                  Trait4<T>::value ? 4 :
                  Trait5<T>::value ? 5 :
                  Trait6<T>::value ? 6 :
                  Trait7<T>::value ? 7 :
                  Trait8<T>::value ? 8 :
                  Trait9<T>::value ? 9 : 0
              )
          };

          using Type = typename Switch::Switch<
                Selector,
                Case<>,
                Case<Trait1>,
                Case<Trait2>,
                Case<Trait3>,
                Case<Trait4>,
                Case<Trait5>,
                Case<Trait6>,
                Case<Trait7>,
                Case<Trait8>,
                Case<Trait9>
          >::Type;
      };

      template< typename Type,
                template < typename... > class Trait1,
                template < typename... > class Trait2 = False,
                template < typename... > class Trait3 = False,
                template < typename... > class Trait4 = False,
                template < typename... > class Trait5 = False,
                template < typename... > class Trait6 = False,
                template < typename... > class Trait7 = False,
                template < typename... > class Trait8 = False,
                template < typename... > class Trait9 = False >
      struct Select : public SelectHelper< Type,
                                           Trait1,
                                           Trait2,
                                           Trait3,
                                           Trait4,
                                           Trait5,
                                           Trait6,
                                           Trait7,
                                           Trait8,
                                           Trait9 >::Type
      {
          enum {
              Selector = SelectHelper< Type,
                                       Trait1,
                                       Trait2,
                                       Trait3,
                                       Trait4,
                                       Trait5,
                                       Trait6,
                                       Trait7,
                                       Trait8,
                                       Trait9 >::Selector
          };

          using SelectorType = std::integral_constant<int, Selector>;
      };

      // clang-format on
    }  // namespace select

    namespace detail
    {
      template <typename T, typename F, size_t... Is>
      void
      for_each(T&& t, F f, std::index_sequence<Is...>)
      {
        auto l = {(f(std::get<Is>(t)), 0)...};
        (void)l;
      }
    }  // namespace detail

    template <typename... Ts, typename F>
    void
    for_each_in_tuple(std::tuple<Ts...> const& t, F f)
    {
      detail::for_each(t, f, std::make_index_sequence<sizeof...(Ts)>());
    }

  }  // namespace traits
}  // namespace llarp
```


-------------------------------

Updated on 2022-04-18 at 19:54:46 +0000
