Repository: fmtlib/fmt
File: include/fmt/std.h (C/C++)

Code before:
#    include <optional>
#  endif
#endif

// GCC 4 does not support FMT_HAS_INCLUDE.
#if FMT_HAS_INCLUDE(<cxxabi.h>) || defined(__GLIBCXX__)
#  include <cxxabi.h>
// Android NDK with gabi++ library on some architectures does not implement
// abi::__cxa_demangle().
#  ifndef __GABIXX_CXXABI_H__
#    define FMT_HAS_ABI_CXA_DEMANGLE
#  endif
#endif

// Check if typeid is available.
#ifndef FMT_USE_TYPEID
// __RTTI is for EDG compilers. In MSVC typeid is available without RTTI.
#  if defined(__GXX_RTTI) || FMT_HAS_FEATURE(cxx_rtti) || FMT_MSC_VERSION || \
      defined(__INTEL_RTTI__) || defined(__RTTI)
#    define FMT_USE_TYPEID 1
#  else
#    define FMT_USE_TYPEID 0
#  endif
#endif

#if !defined(FMT_DISABLE_STD_FILESYSTEM) && defined(__cpp_lib_filesystem)
FMT_BEGIN_NAMESPACE

namespace detail {

template <typename Char, typename PathChar> auto get_path_string(
  const std::filesystem::path& p, const std::basic_string<PathChar>& native) {
  if constexpr (std::is_same_v<Char, char> && std::is_same_v<PathChar, wchar_t>)
    return to_utf8<wchar_t>(native, to_utf8_error_policy::replace);
  else
    return p.string<Char>();
}

template <typename Char, typename PathChar>
void write_escaped_path(basic_memory_buffer<Char>& quoted,
                        const std::filesystem::path& p,
                        const std::basic_string<PathChar>& native) {
  if constexpr (std::is_same_v<Char, char> && std::is_same_v<PathChar, wchar_t>) {
    auto buf = basic_memory_buffer<wchar_t>();
    write_escaped_string<wchar_t>(std::back_inserter(buf), native);
    bool valid = to_utf8<wchar_t>::convert(quoted, {buf.data(), buf.size()});
    FMT_ASSERT(valid, "invalid utf16");
  } else if constexpr (std::is_same_v<Char, PathChar>) {
    write_escaped_string<std::filesystem::path::value_type>(
        std::back_inserter(quoted), native);
  } else {

Review comment (suggestion):
Let's follow the {fmt} convention and replace `FMT_DISABLE_STD_FILESYSTEM` with `FMT_CPP_LIB_FILESYSTEM` that is initialized to `__cpp_lib_filesystem` if the latter is defined and `FMT_CPP_LIB_FILESYSTEM` is not defined by the user:

```c++
#ifndef FMT_CPP_LIB_FILESYSTEM
# ifdef __cpp_lib_filesystem
#   define FMT_CPP_LIB_FILESYSTEM __cpp_lib_filesystem
# else
#   define FMT_CPP_LIB_FILESYSTEM 0
# endif
#endif

Then you can disable filesystem via `-DFMT_CPP_LIB_FILESYSTEM=0`.

And similarly with `__cpp_lib_variant`.

Code after:
#    include <optional>
#  endif
#endif

// GCC 4 does not support FMT_HAS_INCLUDE.
#if FMT_HAS_INCLUDE(<cxxabi.h>) || defined(__GLIBCXX__)
#  include <cxxabi.h>
// Android NDK with gabi++ library on some architectures does not implement
// abi::__cxa_demangle().
#  ifndef __GABIXX_CXXABI_H__
#    define FMT_HAS_ABI_CXA_DEMANGLE
#  endif
#endif

// Check if typeid is available.
#ifndef FMT_USE_TYPEID
// __RTTI is for EDG compilers. In MSVC typeid is available without RTTI.
#  if defined(__GXX_RTTI) || FMT_HAS_FEATURE(cxx_rtti) || FMT_MSC_VERSION || \
      defined(__INTEL_RTTI__) || defined(__RTTI)
#    define FMT_USE_TYPEID 1
#  else
#    define FMT_USE_TYPEID 0
#  endif
#endif

// For older Xcode versions, __cpp_lib_xxx flags are inaccurately defined.
#ifndef FMT_CPP_LIB_FILESYSTEM
#  ifdef __cpp_lib_filesystem
#    define FMT_CPP_LIB_FILESYSTEM __cpp_lib_filesystem
#  else
#    define FMT_CPP_LIB_FILESYSTEM 0
# endif
#endif

#ifndef FMT_CPP_LIB_VARIANT
#  ifdef __cpp_lib_variant
#    define FMT_CPP_LIB_VARIANT __cpp_lib_variant
#  else
#    define FMT_CPP_LIB_VARIANT 0
#  endif
#endif

#if FMT_CPP_LIB_FILESYSTEM
FMT_BEGIN_NAMESPACE

namespace detail {

template <typename Char, typename PathChar> auto get_path_string(
  const std::filesystem::path& p, const std::basic_string<PathChar>& native) {
  if constexpr (std::is_same_v<Char, char> && std::is_same_v<PathChar, wchar_t>)
    return to_utf8<wchar_t>(native, to_utf8_error_policy::replace);