diff --git a/include/log/catalog/arguments.hpp b/include/log/catalog/arguments.hpp new file mode 100644 index 00000000..eb1bf7ff --- /dev/null +++ b/include/log/catalog/arguments.hpp @@ -0,0 +1,59 @@ +#pragma once + +#include + +#include +#include +#include + +template struct encode_32; +template struct encode_64; +template struct encode_u32; +template struct encode_u64; + +namespace logging { +template +concept signed_packable = std::signed_integral> and + sizeof(T) <= sizeof(std::int64_t); + +template +concept unsigned_packable = + std::unsigned_integral> and + sizeof(T) <= sizeof(std::int64_t); + +template +concept float_packable = std::floating_point> and + sizeof(T) <= sizeof(std::int64_t); + +template +concept packable = + signed_packable or unsigned_packable or float_packable; + +template struct encoding; + +template struct encoding { + using encode_t = stdx::conditional_t, encode_64>; + using pack_t = stdx::conditional_t; +}; + +template struct encoding { + using encode_t = stdx::conditional_t, encode_u64>; + using pack_t = stdx::conditional_t; +}; + +template struct encoding { + using encode_t = stdx::conditional_t, encode_u64>; + using pack_t = stdx::conditional_t; +}; + +struct default_arg_packer { + template using pack_as_t = typename encoding::pack_t; + template using encode_as_t = typename encoding::encode_t; +}; +} // namespace logging diff --git a/include/log/catalog/builder.hpp b/include/log/catalog/builder.hpp index b57de704..02405c27 100644 --- a/include/log/catalog/builder.hpp +++ b/include/log/catalog/builder.hpp @@ -17,7 +17,7 @@ namespace logging::binary { } CONSTEVAL auto operator()(auto &&) const { - return logging::mipi::default_builder{}; + return logging::mipi::default_builder<>{}; } } get_builder; } // namespace logging::binary diff --git a/include/log/catalog/catalog.hpp b/include/log/catalog/catalog.hpp index c2371d35..8ee4709a 100644 --- a/include/log/catalog/catalog.hpp +++ b/include/log/catalog/catalog.hpp @@ -15,8 +15,3 @@ using module_id = std::uint32_t; template extern auto catalog() -> string_id; template extern auto module() -> module_id; - -template struct encode_32; -template struct encode_64; -template struct encode_u32; -template struct encode_u64; diff --git a/include/log/catalog/encoder.hpp b/include/log/catalog/encoder.hpp index 853bea23..872ddabf 100644 --- a/include/log/catalog/encoder.hpp +++ b/include/log/catalog/encoder.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include diff --git a/include/log/catalog/mipi_builder.hpp b/include/log/catalog/mipi_builder.hpp index dc299b15..61fb86d2 100644 --- a/include/log/catalog/mipi_builder.hpp +++ b/include/log/catalog/mipi_builder.hpp @@ -1,8 +1,10 @@ #pragma once +#include #include #include +#include #include #include #include @@ -16,46 +18,19 @@ namespace logging::mipi { template -concept signed_packable = std::signed_integral> and - sizeof(T) <= sizeof(std::int64_t); +concept packer = std::integral> and + requires { typename T::template encode_as_t; }; -template -concept unsigned_packable = - std::unsigned_integral> and - sizeof(T) <= sizeof(std::int64_t); - -template -concept packable = signed_packable or unsigned_packable; - -template struct encoding; - -template struct encoding { - using encode_t = stdx::conditional_t, encode_64>; - using pack_t = stdx::conditional_t; -}; +template struct builder; -template struct encoding { - using encode_t = stdx::conditional_t, encode_u64>; - using pack_t = stdx::conditional_t; -}; - -template using pack_as_t = typename encoding::pack_t; -template using encode_as_t = typename encoding::encode_t; - -template struct builder; - -template <> struct builder { +template struct builder { template static auto build(string_id id, module_id) { using namespace msg; return owning{"payload"_field = id}; } }; -template struct catalog_builder { +template struct catalog_builder { template static auto build(string_id id, module_id m, Ts... args) { using namespace msg; @@ -66,8 +41,16 @@ template struct catalog_builder { constexpr auto header_size = defn::catalog_msg_t::size::value; auto const pack_arg = [](V *p, T arg) -> V * { - auto const packed = stdx::to_le(stdx::as_unsigned( - static_cast>(stdx::to_underlying(arg)))); + typename P::template pack_as_t converted{}; + if constexpr (sizeof(stdx::to_underlying(arg)) == + sizeof(converted)) { + converted = stdx::bit_cast( + stdx::to_underlying(arg)); + } else { + converted = + static_cast(stdx::to_underlying(arg)); + } + auto const packed = stdx::to_le(stdx::as_unsigned(converted)); std::memcpy(p, &packed, sizeof(packed)); return p + stdx::sized8{sizeof(packed)}.in(); }; @@ -80,7 +63,7 @@ template struct catalog_builder { } }; -template <> struct builder { +template struct builder { template static auto build(string_id id, module_id m, Ts... args) { using namespace msg; @@ -88,40 +71,41 @@ template <> struct builder { constexpr auto header_size = defn::catalog_msg_t::size::value; constexpr auto payload_size = - stdx::sized8{(sizeof(id) + ... + sizeof(pack_as_t))} + stdx::sized8{(sizeof(id) + ... + + sizeof(typename P::template pack_as_t))} .in(); using storage_t = std::array; - return catalog_builder{}.template build(id, m, - args...); + return catalog_builder{}.template build( + id, m, args...); } else { constexpr auto header_size = defn::catalog_msg_t::size::value; constexpr auto payload_size = - (sizeof(id) + ... + sizeof(pack_as_t)); + (sizeof(id) + ... + sizeof(typename P::template pack_as_t)); using storage_t = std::array; - return catalog_builder{}.template build(id, m, - args...); + return catalog_builder{}.template build( + id, m, args...); } } }; -template <> struct builder { +template struct builder { template static auto build() { using namespace msg; return owning{"build_id"_field = Version}; } }; -template <> struct builder { +template struct builder { template static auto build() { using namespace msg; return owning{"build_id"_field = Version}; } }; -template <> struct builder { +template struct builder { template static auto build() { using namespace msg; constexpr auto header_size = @@ -141,13 +125,14 @@ template <> struct builder { } }; -struct default_builder { +template struct default_builder { template static auto build(string_id id, module_id m, Ts... args) { if constexpr (sizeof...(Ts) == 0u) { - return builder{}.template build(id, m); + return builder{}.template build(id, + m); } else { - return builder{}.template build( + return builder{}.template build( id, m, args...); } } @@ -155,18 +140,18 @@ struct default_builder { template auto build_version() { using namespace msg; if constexpr (S.empty() and stdx::bit_width(Version) <= 22) { - return builder{} + return builder{} .template build(); } else if constexpr (S.empty() and stdx::bit_width(Version) <= 54) { - return builder{} + return builder{} .template build(); } else { - return builder{} + return builder{} .template build(); } } template