---
title: llarp/util/formattable.hpp

---

# llarp/util/formattable.hpp



## Namespaces

| Name           |
| -------------- |
| **[llarp](Namespaces/namespacellarp.md)** <br>[crypto.hpp] |
| **[fmt](Namespaces/namespacefmt.md)**  |

## Classes

|                | Name           |
| -------------- | -------------- |
| struct | **[llarp::is_scoped_enum](Classes/structllarp_1_1is__scoped__enum.md)**  |
| struct | **[llarp::is_scoped_enum< T, true >](Classes/structllarp_1_1is__scoped__enum_3_01T_00_01true_01_4.md)**  |
| struct | **[fmt::formatter< fs::path >](Classes/structfmt_1_1formatter_3_01fs_1_1path_01_4.md)**  |
| struct | **[fmt::formatter< T, char, std::enable_if_t< llarp::IsToStringFormattable< T > > >](Classes/structfmt_1_1formatter_3_01T_00_01char_00_01std_1_1enable__if__t_3_01llarp_1_1IsToStringFormattable_3_01T_01_4_01_4_01_4.md)**  |




## Source code

```cpp
#pragma once

#include <fmt/format.h>
#include <type_traits>

// Formattable types can specialize this to true and will get automatic fmt formattering support via
// their .ToString() method.

namespace llarp
{
  // Types can opt-in to being formatting via .ToString() by specializing this to true.  This also
  // allows scoped enums by instead looking for a call to `ToString(val)` (and so there should be a
  // ToString function in the same namespace as the scoped enum to pick it up via ADL).
  template <typename T>
  constexpr bool IsToStringFormattable = false;

  // e.g.:
  // template <> inline constexpr bool IsToStringFormattable<MyType> = true;

#ifdef __cpp_lib_is_scoped_enum
  using std::is_scoped_enum;
  using std::is_scoped_enum_v;
#else
  template <typename T, bool = std::is_enum_v<T>>
  struct is_scoped_enum : std::false_type
  {};

  template <typename T>
  struct is_scoped_enum<T, true>
      : std::bool_constant<!std::is_convertible_v<T, std::underlying_type_t<T>>>
  {};

  template <typename T>
  constexpr bool is_scoped_enum_v = is_scoped_enum<T>::value;
#endif

}  // namespace llarp

#if !defined(USE_GHC_FILESYSTEM) && FMT_VERSION >= 80102

// Native support in fmt added after fmt 8.1.1
#include <fmt/std.h>

#else

#include <llarp/util/fs.hpp>

namespace fmt
{
  template <>
  struct formatter<fs::path> : formatter<std::string_view>
  {
    template <typename FormatContext>
    auto
    format(const fs::path& p, FormatContext& ctx) const
    {
      return formatter<std::string_view>::format(p.string(), ctx);
    }
  };
}  // namespace fmt

#endif

namespace fmt
{
  template <typename T>
  struct formatter<T, char, std::enable_if_t<llarp::IsToStringFormattable<T>>>
      : formatter<std::string_view>
  {
    template <typename FormatContext>
    auto
    format(const T& val, FormatContext& ctx) const
    {
      if constexpr (llarp::is_scoped_enum_v<T>)
        return formatter<std::string_view>::format(ToString(val), ctx);
      else
        return formatter<std::string_view>::format(val.ToString(), ctx);
    }
  };

}  // namespace fmt
```


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

Updated on 2023-01-20 at 18:12:19 +0000
