Range packing.
This commit is contained in:
parent
3d7ba40289
commit
b48eddb8d0
@ -23,29 +23,78 @@
|
|||||||
|
|
||||||
#include "builtin_packable_types.h"
|
#include "builtin_packable_types.h"
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
namespace msgpack {
|
namespace msgpack {
|
||||||
namespace detail {} // namespace detail
|
namespace detail {
|
||||||
|
|
||||||
|
//
|
||||||
|
template <typename T>
|
||||||
|
concept packable_array = std::ranges::input_range<T>
|
||||||
|
&& builtin_packable<std::ranges::range_value_t<T>>;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept packable_range = std::ranges::input_range<T>
|
concept tuple_like = requires(T t) { typename std::tuple_size<T>::type; };
|
||||||
&& builtin_packable<std::ranges::range_value_t<T>>;
|
|
||||||
|
template <typename T>
|
||||||
|
concept key_value_pairlike = requires(T t) {
|
||||||
|
typename std::tuple_size<T>::type;
|
||||||
|
} && std::tuple_size_v<T> == 2;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept packable_map =
|
||||||
|
std::ranges::input_range<T>
|
||||||
|
&& key_value_pairlike<std::ranges::range_value_t<T>>
|
||||||
|
&& builtin_packable<
|
||||||
|
std::tuple_element_t<0, std::ranges::range_value_t<T>>>
|
||||||
|
&& builtin_packable<
|
||||||
|
std::tuple_element_t<1, std::ranges::range_value_t<T>>>;
|
||||||
|
|
||||||
|
template <typename>
|
||||||
|
struct desc_traits;
|
||||||
|
|
||||||
|
template <packable_map T>
|
||||||
|
struct desc_traits<T> {
|
||||||
|
using type = map_desc;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <packable_array T>
|
||||||
|
struct desc_traits<T> {
|
||||||
|
using type = array_desc;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept packable_range = detail::packable_array<T> || detail::packable_map<T>;
|
||||||
|
|
||||||
template <packable_range T>
|
template <packable_range T>
|
||||||
struct builtin_packer<T> : builtin_packer_base {
|
struct builtin_packer<T> : builtin_packer_base {
|
||||||
|
using desc_type = detail::desc_traits<T>::type;
|
||||||
|
|
||||||
static constexpr std::size_t rep_size(T const& value) {
|
static constexpr std::size_t rep_size(T const& value) {
|
||||||
return std::ranges::size(value);
|
return std::ranges::size(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static constexpr auto desc(T const& value) {
|
||||||
|
return desc_type(rep_size(value));
|
||||||
|
}
|
||||||
|
|
||||||
static constexpr auto marker(T const& value) {
|
static constexpr auto marker(T const& value) {
|
||||||
array_desc desc(rep_size(value));
|
return builtin_packer<desc_type>::marker(desc(value));
|
||||||
return builtin_packer<array_desc>::marker(desc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr void pack(T const& value, auto& packer) noexcept {
|
static constexpr void pack(T const& value, auto& packer) noexcept {
|
||||||
packer.pack(array_desc(rep_size(value)));
|
packer.pack(desc(value));
|
||||||
for (auto const& element : value) {
|
if constexpr (detail::packable_map<T>) {
|
||||||
packer.pack(element);
|
for (auto const& [key, value] : value) {
|
||||||
|
packer.pack(key);
|
||||||
|
packer.pack(value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (auto const& element : value) {
|
||||||
|
packer.pack(element);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -76,3 +76,11 @@ cc_binary(
|
|||||||
],
|
],
|
||||||
deps = ["test_deps"],
|
deps = ["test_deps"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
cc_binary(
|
||||||
|
name = "code",
|
||||||
|
srcs = [
|
||||||
|
"test_code.cpp",
|
||||||
|
],
|
||||||
|
deps = ["test_deps"],
|
||||||
|
)
|
||||||
|
|||||||
17
tests/msgpack/test_code.cpp
Normal file
17
tests/msgpack/test_code.cpp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#include <array>
|
||||||
|
#include <map>
|
||||||
|
#include <parselink/msgpack/core/packer.h>
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
std::map<int, std::string_view> args{};
|
||||||
|
for (int i = 0; i < argc; ++i) {
|
||||||
|
args.emplace(i, argv[i]);
|
||||||
|
}
|
||||||
|
std::array<std::byte, 500> buff;
|
||||||
|
msgpack::packer packer(buff);
|
||||||
|
packer.pack(args);
|
||||||
|
for (auto b : packer.subspan()) {
|
||||||
|
printf("%c", char(b));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user