upd: [imp] remove {fmt} completely

This commit is contained in:
mutouyun 2022-11-28 22:22:22 +08:00
parent f8691a3a80
commit 03d352c238
11 changed files with 97 additions and 118 deletions

View File

@ -10,10 +10,10 @@
#include <cstdint> #include <cstdint>
#include <cstddef> // std::byte (since C++17) #include <cstddef> // std::byte (since C++17)
#include "fmt/format.h"
#include "libimp/def.h" #include "libimp/def.h"
#include "libimp/detect_plat.h" #include "libimp/detect_plat.h"
#include "libimp/span.h"
#include "libimp/fmt.h"
#if defined(LIBIMP_CPP_17) && defined(__cpp_lib_byte) #if defined(LIBIMP_CPP_17) && defined(__cpp_lib_byte)
#define LIBIMP_CPP_LIB_BYTE_ #define LIBIMP_CPP_LIB_BYTE_
@ -155,15 +155,27 @@ U *byte_cast(byte const *p) noexcept {
return reinterpret_cast<U *>(p); return reinterpret_cast<U *>(p);
} }
LIBIMP_NAMESPACE_END_ /// @brief Converts a span into a view of its underlying bytes.
/// @see https://en.cppreference.com/w/cpp/container/span/as_bytes
template <> template <typename T,
struct fmt::formatter<::LIBIMP::byte> { typename Byte = typename std::conditional<std::is_const<T>::value, byte const, byte>::type>
constexpr auto parse(format_parse_context& ctx) const { auto as_bytes(span<T> s) noexcept -> span<Byte> {
return ctx.end(); return {byte_cast(s.data()), s.size_bytes()};
} }
template <typename FormatContext>
auto format(::LIBIMP::byte b, FormatContext &ctx) { /// @brief Custom defined fmt_to_string method for imp::fmt
return format_to(ctx.out(), "{:#04x}", static_cast<std::uint8_t>(b)); namespace detail {
inline std::string tag_invoke(decltype(::LIBIMP::fmt_to_string), ::LIBIMP::byte b) {
return ::LIBIMP::to_string(static_cast<std::uint8_t>(b), "02x");
} }
};
template <typename T,
typename = std::enable_if_t<std::is_same<std::decay_t<T>, ::LIBIMP::byte>::value>>
std::string tag_invoke(fmt_to_string_t, fmt_ref<T> arg) noexcept {
return ::LIBIMP::to_string(static_cast<std::uint8_t>(arg.param), arg.fstr);
}
} // namespace detail
LIBIMP_NAMESPACE_END_

View File

@ -14,10 +14,10 @@
#include <ctime> // std::tm #include <ctime> // std::tm
#include "libimp/def.h" #include "libimp/def.h"
#include "libimp/fmt_cpo.h"
#include "libimp/span.h" #include "libimp/span.h"
#include "libimp/detect_plat.h" #include "libimp/detect_plat.h"
#include "libimp/export.h" #include "libimp/export.h"
#include "libimp/generic.h"
LIBIMP_NAMESPACE_BEG_ LIBIMP_NAMESPACE_BEG_
@ -35,19 +35,6 @@ 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> template <typename... A>
std::string fmt(A &&...args) { std::string fmt(A &&...args) {
std::string joined; std::string joined;

32
include/libimp/fmt_cpo.h Normal file
View File

@ -0,0 +1,32 @@
/**
* @file libimp/fmt_cpo.h
* @author mutouyun (orz@orzz.org)
* @brief String formatting CPO.
* @date 2022-11-28
*/
#pragma once
#include <string>
#include "libimp/def.h"
#include "libimp/generic.h"
LIBIMP_NAMESPACE_BEG_
/**
* @brief Supports custom fmt_to_string methods for imp::fmt.
*/
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 {};
LIBIMP_NAMESPACE_END_

View File

@ -10,8 +10,6 @@
#include <string> #include <string>
#include <cstdint> #include <cstdint>
#include "fmt/format.h"
#include "libimp/def.h" #include "libimp/def.h"
#include "libimp/detect_plat.h" #include "libimp/detect_plat.h"
#include "libimp/export.h" #include "libimp/export.h"
@ -75,10 +73,6 @@ struct default_traits<T, std::enable_if_t<std::is_integral<T>::value>> {
static std::string format(result<T> const &r) noexcept { static std::string format(result<T> const &r) noexcept {
return fmt(*r); return fmt(*r);
} }
template <typename Out>
static auto format(result<T> const &r, Out &&out) noexcept {
return format_to(out, format(r));
}
}; };
template <typename T> template <typename T>
@ -97,10 +91,6 @@ struct default_traits<T, std::enable_if_t<std::is_pointer<T>::value>> {
} }
return fmt(static_cast<void *>(*r), ", code = ", r.code_value()); return fmt(static_cast<void *>(*r), ", code = ", r.code_value());
} }
template <typename Out>
static auto format(result<T> const &r, Out &&out) noexcept {
return format_to(out, format(r));
}
}; };
} // namespace detail_result } // namespace detail_result
@ -168,35 +158,14 @@ public:
/// @brief Custom defined fmt_to_string method for imp::fmt /// @brief Custom defined fmt_to_string method for imp::fmt
namespace detail { namespace detail {
inline std::string tag_invoke(decltype(::LIBIMP::fmt_to_string), result_code r) noexcept { inline std::string tag_invoke(decltype(::LIBIMP::fmt_to_string), result_code r) {
return fmt("[", (r ? "succ" : "fail"), ", value = ", *r, "]"); return fmt("[", (r ? "succ" : "fail"), ", value = ", *r, "]");
} }
template <typename T, typename D> template <typename T, typename D>
std::string tag_invoke(decltype(::LIBIMP::fmt_to_string), result<T, D> r) noexcept { std::string tag_invoke(decltype(::LIBIMP::fmt_to_string), result<T, D> r) {
return fmt("[", (r ? "succ" : "fail"), ", value = ", result<T, D>::default_traits_t::format(r), "]"); return fmt("[", (r ? "succ" : "fail"), ", value = ", result<T, D>::default_traits_t::format(r), "]");
} }
} // namespace detail } // namespace detail
LIBIMP_NAMESPACE_END_ LIBIMP_NAMESPACE_END_
template <typename T, typename D>
struct fmt::formatter<::LIBIMP::result<T, D>> {
constexpr auto parse(format_parse_context& ctx) const {
return ctx.end();
}
template <typename FormatContext>
auto format(::LIBIMP::result<T, D> r, FormatContext &ctx) {
return format_to(::LIBIMP::result<T, D>::default_traits_t::format(r,
format_to(ctx.out(), "[{}, value = ", r ? "succ" : "fail")), "]");
}
};
template <>
struct fmt::formatter<::LIBIMP::result_code>
: formatter<::LIBIMP::result<::LIBIMP::result_type>> {
template <typename FormatContext>
auto format(::LIBIMP::result_code r, FormatContext &ctx) {
return format_to(ctx.out(), "[{}, value = {}]", (r ? "succ" : "fail"), *r);
}
};

View File

@ -17,11 +17,9 @@
#include <cstdint> #include <cstdint>
#include <initializer_list> #include <initializer_list>
#include "fmt/format.h"
#include "libimp/def.h" #include "libimp/def.h"
#include "libimp/detect_plat.h" #include "libimp/detect_plat.h"
#include "libimp/byte.h" #include "libimp/fmt_cpo.h"
#if defined(LIBIMP_CPP_20) && defined(__cpp_lib_span) #if defined(LIBIMP_CPP_20) && defined(__cpp_lib_span)
#include <span> #include <span>
@ -222,15 +220,6 @@ bool operator==(span<T> a, span<U> b) noexcept {
return true; return true;
} }
/// @brief Converts a span into a view of its underlying bytes.
/// @see https://en.cppreference.com/w/cpp/container/span/as_bytes
template <typename T,
typename Byte = typename std::conditional<std::is_const<T>::value, byte const, byte>::type>
auto as_bytes(span<T> s) noexcept -> span<Byte> {
return {byte_cast(s.data()), s.size_bytes()};
}
/// @brief Constructs an object of type T and wraps it in a span. /// @brief Constructs an object of type T and wraps it in a span.
/// Before C++17, template argument deduction for class templates was not supported. /// Before C++17, template argument deduction for class templates was not supported.
/// @see https://en.cppreference.com/w/cpp/language/template_argument_deduction /// @see https://en.cppreference.com/w/cpp/language/template_argument_deduction
@ -278,22 +267,20 @@ inline auto make_span(std::string const &str) noexcept -> span<char const> {
return {str.data(), str.size()}; return {str.data(), str.size()};
} }
LIBIMP_NAMESPACE_END_ /// @brief Custom defined fmt_to_string method for imp::fmt
namespace detail {
template <typename T> template <typename T>
struct fmt::formatter<::LIBIMP::span<T>> { std::string tag_invoke(decltype(::LIBIMP::fmt_to_string), span<T> s) {
constexpr auto parse(format_parse_context& ctx) const {
return ctx.end();
}
template <typename FormatContext>
auto format(::LIBIMP::span<T> s, FormatContext &ctx) {
if (s.empty()) { if (s.empty()) {
return format_to(ctx.out(), ""); return {};
} }
auto appender = format_to(ctx.out(), "{}", s[0]); auto appender = fmt(s[0]);
for (std::size_t i = 1; i < s.size(); ++i) { for (std::size_t i = 1; i < s.size(); ++i) {
appender = format_to(appender, " {}", s[i]); appender += fmt(' ', s[i]);
} }
return appender; return appender;
} }
};
} // namespace detail
LIBIMP_NAMESPACE_END_

View File

@ -13,7 +13,7 @@
#include "libimp/def.h" #include "libimp/def.h"
#include "libimp/export.h" #include "libimp/export.h"
#include "libimp/result.h" #include "libimp/result.h"
#include "libimp/fmt.h" #include "libimp/fmt_cpo.h"
LIBIMP_NAMESPACE_BEG_ LIBIMP_NAMESPACE_BEG_
namespace sys { namespace sys {
@ -73,12 +73,3 @@ inline std::string tag_invoke(decltype(::LIBIMP::fmt_to_string), error r) noexce
} // namespace sys } // namespace sys
LIBIMP_NAMESPACE_END_ LIBIMP_NAMESPACE_END_
template <>
struct fmt::formatter<::LIBIMP::sys::error>
: formatter<std::string> {
template <typename FormatContext>
auto format(::LIBIMP::sys::error r, FormatContext &ctx) {
return format_to(ctx.out(), ::LIBIMP::sys::error_msg(r.code()));
}
};

View File

@ -29,8 +29,6 @@ target_include_directories(${PROJECT_NAME}
PUBLIC ${LIBIPC_PROJECT_DIR}/include PUBLIC ${LIBIPC_PROJECT_DIR}/include
PRIVATE ${LIBIPC_PROJECT_DIR}/src) PRIVATE ${LIBIPC_PROJECT_DIR}/src)
target_link_libraries(${PROJECT_NAME} PUBLIC fmt)
install( install(
TARGETS ${PROJECT_NAME} TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin RUNTIME DESTINATION bin

View File

@ -3,6 +3,7 @@
#include "libimp/byte.h" #include "libimp/byte.h"
#include "libimp/span.h" #include "libimp/span.h"
#include "libimp/fmt.h"
TEST(byte, construct) { TEST(byte, construct) {
{ {
@ -38,13 +39,13 @@ TEST(byte, compare) {
TEST(byte, fmt) { TEST(byte, fmt) {
{ {
imp::byte b1, b2(31); imp::byte b1, b2(31);
EXPECT_EQ(fmt::format("{}", b1), "0x00"); EXPECT_EQ(imp::fmt(b1), "00");
EXPECT_EQ(fmt::format("{}", b2), "0x1f"); EXPECT_EQ(imp::fmt(b2), "1f");
EXPECT_EQ(imp::fmt(imp::spec("03X")(b2)), "01F");
} }
{ {
imp::byte bs[] {31, 32, 33, 34, 35, 36, 37, 38}; imp::byte bs[] {31, 32, 33, 34, 35, 36, 37, 38};
EXPECT_EQ(fmt::format("{}", imp::make_span(bs)), EXPECT_EQ(imp::fmt(imp::make_span(bs)), "1f 20 21 22 23 24 25 26");
"0x1f 0x20 0x21 0x22 0x23 0x24 0x25 0x26");
} }
} }

View File

@ -2,9 +2,9 @@
#include <sstream> #include <sstream>
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "fmt/format.h"
#include "libimp/result.h" #include "libimp/result.h"
#include "libimp/fmt.h"
TEST(result, ok) { TEST(result, ok) {
imp::result_code ret; imp::result_code ret;
@ -59,23 +59,23 @@ TEST(result, compare) {
TEST(result, fmt) { TEST(result, fmt) {
{ {
imp::result_code r1; imp::result_code r1;
EXPECT_EQ(fmt::format("{}", r1), "[fail, value = 0]"); EXPECT_EQ(imp::fmt(r1), "[fail, value = 0]");
imp::result_code r2(true, 65537); imp::result_code r2(true, 65537);
EXPECT_EQ(fmt::format("{}", r2), "[succ, value = 65537]"); EXPECT_EQ(imp::fmt(r2), "[succ, value = 65537]");
imp::result_code r3(0); imp::result_code r3(0);
EXPECT_EQ(fmt::format("{}", r3), "[succ, value = 0]"); EXPECT_EQ(imp::fmt(r3), "[succ, value = 0]");
} }
{ {
imp::result<int> r1 {false, -123}; imp::result<int> r1 {false, -123};
EXPECT_EQ(fmt::format("{}", r1), fmt::format("[fail, value = {}]", -123)); EXPECT_EQ(imp::fmt(r1), imp::fmt("[fail, value = ", -123, "]"));
imp::result<void *> r2 {&r1}; imp::result<void *> r2 {&r1};
EXPECT_EQ(fmt::format("{}", r2), imp::fmt("[succ, value = ", (void *)&r1, "]")); EXPECT_EQ(imp::fmt(r2), imp::fmt("[succ, value = ", (void *)&r1, "]"));
int aaa {}; int aaa {};
imp::result<int *> r3 {&aaa}; imp::result<int *> r3 {&aaa};
EXPECT_EQ(fmt::format("{}", r3), imp::fmt("[succ, value = ", (void *)&aaa, "]")); EXPECT_EQ(imp::fmt(r3), imp::fmt("[succ, value = ", (void *)&aaa, "]"));
imp::result<int *> r4 {nullptr}; imp::result<int *> r4 {nullptr};
EXPECT_EQ(fmt::format("{}", r4), imp::fmt("[fail, value = ", nullptr, ", code = 0]")); EXPECT_EQ(imp::fmt(r4), imp::fmt("[fail, value = ", nullptr, ", code = 0]"));
r4 = {nullptr, 1234}; r4 = {nullptr, 1234};
EXPECT_EQ(fmt::format("{}", r4), imp::fmt("[fail, value = ", nullptr, ", code = 1234]")); EXPECT_EQ(imp::fmt(r4), imp::fmt("[fail, value = ", nullptr, ", code = 1234]"));
} }
} }

View File

@ -6,6 +6,8 @@
#include "libimp/span.h" #include "libimp/span.h"
#include "libimp/countof.h" #include "libimp/countof.h"
#include "libimp/byte.h"
#include "libimp/fmt.h"
TEST(span, to_address) { TEST(span, to_address) {
int *a = new int; int *a = new int;
@ -56,6 +58,6 @@ TEST(span, span) {
} }
TEST(span, fmt) { TEST(span, fmt) {
EXPECT_EQ(fmt::format("{}", imp::span<int>{}), ""); EXPECT_EQ(imp::fmt(imp::span<int>{}), "");
EXPECT_EQ(fmt::format("{}", imp::make_span({1, 3, 2, 4, 5, 6, 7})), "1 3 2 4 5 6 7"); EXPECT_EQ(imp::fmt(imp::make_span({1, 3, 2, 4, 5, 6, 7})), "1 3 2 4 5 6 7");
} }

View File

@ -3,11 +3,11 @@
#include <string> #include <string>
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "fmt/format.h"
#include "libimp/system.h" #include "libimp/system.h"
#include "libimp/detect_plat.h" #include "libimp/detect_plat.h"
#include "libimp/codecvt.h" #include "libimp/codecvt.h"
#include "libimp/fmt.h"
#if defined(LIBIMP_OS_WIN) #if defined(LIBIMP_OS_WIN)
#include <Windows.h> #include <Windows.h>
@ -25,11 +25,11 @@ TEST(system, error_code) {
imp::sys::error e_obj {err}; imp::sys::error e_obj {err};
EXPECT_EQ(err.value(), e_obj.value()); EXPECT_EQ(err.value(), e_obj.value());
auto e_msg = fmt::format("{}", imp::sys::error_msg(imp::sys::error_code())); auto e_msg = imp::fmt(imp::sys::error_msg(imp::sys::error_code()));
std::stringstream ss; std::stringstream ss;
ss << imp::sys::error{}; ss << imp::sys::error{};
EXPECT_EQ(e_msg, ss.str()); EXPECT_EQ(e_msg, ss.str());
EXPECT_EQ(e_msg, fmt::format("{}", imp::sys::error())); EXPECT_EQ(e_msg, imp::fmt(imp::sys::error()));
std::cout << e_msg << "\n"; std::cout << e_msg << "\n";
} }