add: [imp] tag_invoke for fmt

This commit is contained in:
mutouyun 2022-11-27 21:45:52 +08:00
parent bbbb03408d
commit 31e4c4d5e4
4 changed files with 66 additions and 3 deletions

View File

@ -17,6 +17,7 @@
#include "libimp/span.h"
#include "libimp/detect_plat.h"
#include "libimp/export.h"
#include "libimp/generic.h"
LIBIMP_NAMESPACE_BEG_
@ -34,17 +35,31 @@ auto spec(char const (&fstr)[N]) noexcept {
};
}
namespace detail {
struct fmt_to_string_t {
template <typename T>
std::string operator()(T &&arg) const {
return ::LIBIMP::tag_invoke(fmt_to_string_t{}, std::forward<T>(arg));
}
};
} // namespace detail
constexpr detail::fmt_to_string_t fmt_to_string {};
template <typename... A>
std::string fmt(A &&...args) {
std::string joined;
LIBIMP_UNUSED auto unfold = {
joined.append(to_string(std::forward<A>(args)))...
joined.append(fmt_to_string(std::forward<A>(args)))...
};
return joined;
}
/// @brief Return the string directly.
LIBIMP_EXPORT std::string const &to_string(std::string const &a) noexcept;
LIBIMP_EXPORT std::string to_string(std::string const &a) noexcept;
LIBIMP_EXPORT std::string to_string(std::string &&a) noexcept;
LIBIMP_EXPORT std::string to_string(std::string const &a, span<char const> fstr) noexcept;
/// @brief Character to string conversion.
@ -92,4 +107,16 @@ LIBIMP_EXPORT std::string to_string(std::chrono::time_point<Clock, Duration> con
return detail::time_to_string(std::chrono::system_clock::to_time_t(a), fstr);
}
/**
* @brief Predefined fmt_to_string method
*/
namespace detail {
template <typename T>
auto tag_invoke(fmt_to_string_t, T &&arg) noexcept
-> decltype(::LIBIMP::to_string(std::forward<T>(arg))) {
return ::LIBIMP::to_string(std::forward<T>(arg));
}
} // namespace detail
LIBIMP_NAMESPACE_END_

View File

@ -6,6 +6,8 @@
*/
#pragma once
#include <utility>
#include "libimp/def.h"
LIBIMP_NAMESPACE_BEG_
@ -17,4 +19,25 @@ LIBIMP_NAMESPACE_BEG_
template <typename...>
using void_t = void;
/**
* @brief A general pattern for supporting customisable functions
* @see https://www.open-std.org/jtc1/sc22/WG21/docs/papers/2019/p1895r0.pdf
*/
namespace detail {
void tag_invoke();
struct tag_invoke_t {
template <typename T, typename... A>
constexpr auto operator()(T tag, A &&...args) const
noexcept(noexcept(tag_invoke(std::forward<T>(tag), std::forward<A>(args)...)))
-> decltype(tag_invoke(std::forward<T>(tag), std::forward<A>(args)...)) {
return tag_invoke(std::forward<T>(tag), std::forward<A>(args)...);
}
};
} // namespace detail
constexpr detail::tag_invoke_t tag_invoke {};
LIBIMP_NAMESPACE_END_

View File

@ -17,6 +17,7 @@
#include "libimp/detect_plat.h"
#include "libimp/export.h"
#include "libimp/enum_cast.h"
#include "libimp/fmt.h"
LIBIMP_NAMESPACE_BEG_
namespace log {
@ -39,6 +40,14 @@ struct context {
LIBIMP_EXPORT std::string to_string(context &&) noexcept;
/**
* @brief Custom defined fmt_to_string method for imp::fmt
*/
template <typename T>
std::string tag_invoke(decltype(::LIBIMP::fmt_to_string), context &&arg) noexcept {
return ::LIBIMP::log::to_string(std::move(arg));
}
} // namespace log
namespace detail_log {

View File

@ -98,10 +98,14 @@ std::string sprintf(F fop, span<char const> fstr, span<char const> s, A a) noexc
} // namespace
std::string const &to_string(std::string const &a) noexcept {
std::string to_string(std::string const &a) noexcept {
return a;
}
std::string to_string(std::string &&a) noexcept {
return std::move(a);
}
std::string to_string(std::string const &a, span<char const> fstr) noexcept {
if (a.empty()) return {};
return ::LIBIMP::sprintf(fmt_of, fstr, "s", a.c_str());