88#include < bitset>
99#include < chrono>
1010#include < cstddef>
11- #include < cstring>
1211#include < iterator>
1312#include < span>
1413#include < string>
@@ -156,16 +155,17 @@ namespace msgpack23 {
156155 constexpr counting_inserter operator ++(int ) {
157156 return *this ;
158157 }
158+
159159 private:
160160 std::size_t *size_{};
161161 };
162162
163163 template <typename T>
164164 concept byte_type = std::same_as<T, std::byte>
165- or std::same_as<T, char >
166- or std::same_as<T, unsigned char >
167- or std::same_as<T, std::uint8_t >
168- or std::same_as<T, std::int8_t >;
165+ or std::same_as<T, char >
166+ or std::same_as<T, unsigned char >
167+ or std::same_as<T, std::uint8_t >
168+ or std::same_as<T, std::int8_t >;
169169
170170 template <byte_type B, std::output_iterator<B> Iter>
171171 class Packer final {
@@ -478,7 +478,7 @@ namespace msgpack23 {
478478
479479 template <typename Container>
480480 Packer (std::back_insert_iterator<Container>) ->
481- Packer<typename Container::value_type, std::back_insert_iterator<Container>>;
481+ Packer<typename Container::value_type, std::back_insert_iterator<Container> >;
482482
483483 template <typename T, typename P>
484484 concept packable_object = requires (T t, P p)
@@ -526,7 +526,7 @@ namespace msgpack23 {
526526 return static_cast <FormatConstants>(std::to_integer<std::uint8_t >(current ()));
527527 }
528528
529- template <typename T, std::enable_if_t <std::is_unsigned_v<T>, int > = 0 >
529+ template <typename T, std::enable_if_t <std::is_unsigned_v<T>, int > = 0 >
530530 [[nodiscard]] T read_integral () {
531531 if (position_ + sizeof (T) > data_.size ()) {
532532 throw std::out_of_range (" Unpacker doesn't have enough data." );
@@ -1006,15 +1006,15 @@ namespace msgpack23 {
10061006 };
10071007
10081008 template <typename T>
1009- Unpacker (std::span<T const >) -> Unpacker<std::remove_const_t <T>>;
1009+ Unpacker (std::span<T const >) -> Unpacker<std::remove_const_t <T> >;
10101010
10111011 template <typename T>
10121012 concept container = requires (T b) {
10131013 typename T::value_type;
10141014 } && byte_type<typename T::value_type>;
10151015
10161016 template <container Container>
1017- Unpacker (Container const &)-> Unpacker<typename Container::value_type>;
1017+ Unpacker (Container const &) -> Unpacker<typename Container::value_type>;
10181018
10191019 template <typename T, typename U>
10201020 concept unpackable_object = requires (T t, U u)
@@ -1040,4 +1040,28 @@ namespace msgpack23 {
10401040 obj.unpack (unpacker);
10411041 return obj;
10421042 }
1043+
1044+ template <typename T>
1045+ struct span_value_type ;
1046+
1047+ template <typename T>
1048+ requires requires { typename std::ranges::range_value_t <T>; }
1049+ struct span_value_type <T> {
1050+ using type = std::ranges::range_value_t <T>;
1051+ };
1052+
1053+ template <typename T>
1054+ using span_value_type_t = typename span_value_type<T>::type;
1055+
1056+ template <typename T>
1057+ concept span_convertible = std::ranges::contiguous_range<T>
1058+ && std::ranges::sized_range<T>
1059+ && byte_type<std::remove_const_t <span_value_type_t <T>>>;
1060+
1061+ template <typename UnpackableObject, span_convertible Container>
1062+ requires unpackable_object<UnpackableObject, Unpacker<std::remove_const_t <span_value_type_t <Container>>>>
1063+ [[nodiscard]] UnpackableObject unpack (Container const & data) {
1064+ using B = std::remove_const_t <span_value_type_t <Container>>;
1065+ return unpack<B, UnpackableObject>(std::span<B const >{data});
1066+ }
10431067}
0 commit comments