58 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			58 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#pragma once
 | 
						|
 | 
						|
#include "move.hpp"
 | 
						|
#include "type_traits.hpp"
 | 
						|
#include <format>
 | 
						|
#include <string_view>
 | 
						|
 | 
						|
namespace util {
 | 
						|
 | 
						|
template <typename... Ts>
 | 
						|
inline constexpr auto format(std::string_view fmt, Ts&&... args)
 | 
						|
    -> std::string {
 | 
						|
#if defined(__cpp_if_consteval) && defined(doesnt_work_yet_in_clang_14)
 | 
						|
  if
 | 
						|
    consteval { return std::format(fmt, args...); }
 | 
						|
  else {
 | 
						|
    return std::vformat(fmt, std::make_format_args(std::forward<Ts>(args)...));
 | 
						|
  }
 | 
						|
#else
 | 
						|
  return std::vformat(fmt, std::make_format_args(std::forward<Ts>(args)...));
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
template <typename T, typename Context>
 | 
						|
using has_formatter =
 | 
						|
    std::is_constructible<typename Context::template formatter_type<T>>;
 | 
						|
 | 
						|
template <typename T>
 | 
						|
    using is_formattable = has_formatter<T, std::format_context>;
 | 
						|
 | 
						|
    template <typename T>
 | 
						|
    inline constexpr bool is_formattable_v = is_formattable<T>::value;
 | 
						|
 | 
						|
    template <typename T>
 | 
						|
    concept formattable = is_formattable_v<T>;
 | 
						|
}  // namespace util
 | 
						|
 | 
						|
#include <optional>
 | 
						|
 | 
						|
template<util::formattable F>
 | 
						|
struct std::formatter<std::optional<F>> : public std::formatter<F> {
 | 
						|
  template <typename FormatContext>
 | 
						|
  auto format(const std::optional<F>& option, FormatContext& ctx)
 | 
						|
      -> decltype(ctx.out()) {
 | 
						|
        auto fmt = ctx.out();
 | 
						|
 | 
						|
        if (option.has_value()) {
 | 
						|
            fmt = std::format_to(fmt, "Some(");
 | 
						|
            ctx.advance_to(fmt);
 | 
						|
            fmt = std::formatter<F>::format(option.value(), ctx);
 | 
						|
            *fmt++ = ')';
 | 
						|
        } else {
 | 
						|
            fmt = std::format_to(fmt, "None");
 | 
						|
        }
 | 
						|
 | 
						|
        return fmt;
 | 
						|
      }
 | 
						|
}; |