mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-06-05 22:20:52 +02:00
Add tests for std::span adaptor
This commit is contained in:
parent
388891edad
commit
77045f13bb
@ -20,6 +20,8 @@ LIST (APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/")
|
|||||||
SET (GNUCXX_STD_SUPPORT_VERSION "4.3")
|
SET (GNUCXX_STD_SUPPORT_VERSION "4.3")
|
||||||
|
|
||||||
OPTION (MSGPACK_CXX11 "Using c++11 compiler" OFF)
|
OPTION (MSGPACK_CXX11 "Using c++11 compiler" OFF)
|
||||||
|
OPTION (MSGPACK_CXX17 "Using c++17 compiler" OFF)
|
||||||
|
OPTION (MSGPACK_CXX20 "Using c++20 compiler (experimental)" OFF)
|
||||||
OPTION (MSGPACK_32BIT "32bit compile" OFF)
|
OPTION (MSGPACK_32BIT "32bit compile" OFF)
|
||||||
|
|
||||||
IF (MSGPACK_USE_X3_PARSE)
|
IF (MSGPACK_USE_X3_PARSE)
|
||||||
|
@ -37,7 +37,7 @@ public:
|
|||||||
m_data.resize(static_cast<std::size_t>(s) + 1);
|
m_data.resize(static_cast<std::size_t>(s) + 1);
|
||||||
m_data[0] = static_cast<char>(t);
|
m_data[0] = static_cast<char>(t);
|
||||||
}
|
}
|
||||||
ext(ext_ref const&);
|
explicit ext(ext_ref const&);
|
||||||
int8_t type() const {
|
int8_t type() const {
|
||||||
return static_cast<int8_t>(m_data[0]);
|
return static_cast<int8_t>(m_data[0]);
|
||||||
}
|
}
|
||||||
@ -167,6 +167,7 @@ public:
|
|||||||
if (m_size < x.m_size) return false;
|
if (m_size < x.m_size) return false;
|
||||||
return std::memcmp(m_ptr, x.m_ptr, m_size) > 0;
|
return std::memcmp(m_ptr, x.m_ptr, m_size) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char* m_ptr;
|
const char* m_ptr;
|
||||||
uint32_t m_size;
|
uint32_t m_size;
|
||||||
|
@ -46,7 +46,7 @@ IF (MSGPACK_USE_X3_PARSE)
|
|||||||
)
|
)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
IF (MSGPACK_CXX11 OR MSGPACK_CXX17)
|
IF (MSGPACK_CXX11 OR MSGPACK_CXX17 OR MSGPACK_CXX20)
|
||||||
LIST (APPEND check_PROGRAMS
|
LIST (APPEND check_PROGRAMS
|
||||||
iterator_cpp11.cpp
|
iterator_cpp11.cpp
|
||||||
msgpack_cpp11.cpp
|
msgpack_cpp11.cpp
|
||||||
@ -60,12 +60,18 @@ IF (MSGPACK_CXX11 OR MSGPACK_CXX17)
|
|||||||
)
|
)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
IF (MSGPACK_CXX17)
|
IF (MSGPACK_CXX17 OR MSGPACK_CXX20)
|
||||||
LIST (APPEND check_PROGRAMS
|
LIST (APPEND check_PROGRAMS
|
||||||
msgpack_cpp17.cpp
|
msgpack_cpp17.cpp
|
||||||
)
|
)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
IF (MSGPACK_CXX20)
|
||||||
|
LIST (APPEND check_PROGRAMS
|
||||||
|
msgpack_cpp20.cpp
|
||||||
|
)
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
FOREACH (source_file ${check_PROGRAMS})
|
FOREACH (source_file ${check_PROGRAMS})
|
||||||
GET_FILENAME_COMPONENT (source_file_we ${source_file} NAME_WE)
|
GET_FILENAME_COMPONENT (source_file_we ${source_file} NAME_WE)
|
||||||
ADD_EXECUTABLE (
|
ADD_EXECUTABLE (
|
||||||
|
@ -488,7 +488,7 @@ TEST(MSGPACK_BOOST, object_with_zone_variant_ext_ref)
|
|||||||
msgpack::type::variant val2 = obj.as<msgpack::type::variant>();
|
msgpack::type::variant val2 = obj.as<msgpack::type::variant>();
|
||||||
// Converted as msgpack::type::ext.
|
// Converted as msgpack::type::ext.
|
||||||
EXPECT_TRUE(val2.is_ext());
|
EXPECT_TRUE(val2.is_ext());
|
||||||
EXPECT_EQ(val2.as_ext(), e);
|
EXPECT_EQ(val2.as_ext(), msgpack::type::ext(e));
|
||||||
EXPECT_NO_THROW(boost::get<msgpack::type::ext>(val2));
|
EXPECT_NO_THROW(boost::get<msgpack::type::ext>(val2));
|
||||||
// msgpack::type::ext_ref and msgpack::type::ext are different.
|
// msgpack::type::ext_ref and msgpack::type::ext are different.
|
||||||
EXPECT_FALSE(val1 == val2);
|
EXPECT_FALSE(val1 == val2);
|
||||||
|
@ -262,11 +262,19 @@ struct set_allocator : std::allocator<Key> {
|
|||||||
using std::allocator<Key>::allocator;
|
using std::allocator<Key>::allocator;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Key, class T>
|
// C++ named requirement Allocator implies that the first template type
|
||||||
struct map_allocator : std::allocator<std::pair<const Key, T>> {
|
// parameter matches the value type of the allocator. There might be additional
|
||||||
using std::allocator<std::pair<const Key, T>>::allocator;
|
// parameters, but the first one must match the type.
|
||||||
|
// That's why this helper with exactly one template parameter representing
|
||||||
|
// a whole key-value pair is required
|
||||||
|
template <typename KeyValuePair>
|
||||||
|
struct map_allocator_impl : std::allocator<KeyValuePair> {
|
||||||
|
using std::allocator<KeyValuePair>::allocator;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class Key, class T>
|
||||||
|
using map_allocator = map_allocator_impl<std::pair<const Key, T>>;
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct allocator : std::allocator<T> {
|
struct allocator : std::allocator<T> {
|
||||||
using std::allocator<T>::allocator;
|
using std::allocator<T>::allocator;
|
||||||
|
138
test/msgpack_cpp20.cpp
Normal file
138
test/msgpack_cpp20.cpp
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
#include <msgpack.hpp>
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wconversion"
|
||||||
|
#endif //defined(__GNUC__)
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif //defined(__GNUC__)
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// To avoid link error
|
||||||
|
TEST(MSGPACK_CPP20, dummy)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(MSGPACK_USE_CPP03) && __cplusplus > 201703
|
||||||
|
|
||||||
|
#if MSGPACK_HAS_INCLUDE(<span>)
|
||||||
|
|
||||||
|
template <typename Byte>
|
||||||
|
bool operator==(const std::span<const Byte>& lhs, const std::span<const Byte>& rhs)
|
||||||
|
{
|
||||||
|
if (lhs.size() != rhs.size())
|
||||||
|
return false;
|
||||||
|
for (std::size_t i = 0; i < lhs.size(); ++i)
|
||||||
|
if (lhs[i] != rhs[i])
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Byte>
|
||||||
|
bool operator==(const std::span<const Byte>& lhs, const std::vector<Byte>& rhs)
|
||||||
|
{
|
||||||
|
return lhs == std::span<const Byte>{rhs.data(), rhs.size()};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Byte>
|
||||||
|
bool operator==(const std::vector<Byte>& lhs, const std::span<const Byte>& rhs)
|
||||||
|
{
|
||||||
|
return std::span<const Byte>{lhs.data(), lhs.size()} == rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MSGPACK_TEST_SPAN_BYTE_PACK_CONVERT(byte_t, display_name) \
|
||||||
|
TEST(MSGPACK_CPP20, span_##display_name##_pack_convert) \
|
||||||
|
{ \
|
||||||
|
std::stringstream ss; \
|
||||||
|
byte_t raw_data[] = { \
|
||||||
|
(byte_t)(0x01), (byte_t)(0x02), (byte_t)(0x7f), (byte_t)(0x80), (byte_t)(0xff) \
|
||||||
|
}; \
|
||||||
|
std::span<const byte_t> val1{raw_data, sizeof(raw_data)}; \
|
||||||
|
\
|
||||||
|
msgpack::pack(ss, val1); \
|
||||||
|
std::string const& str = ss.str(); \
|
||||||
|
\
|
||||||
|
char packed[] = { char(0xc4), char(0x05), char(0x01), char(0x02), char(0x7f), char(0x80), char(0xff) }; \
|
||||||
|
EXPECT_EQ(str.size(), sizeof(packed)); \
|
||||||
|
for (size_t i = 0; i != sizeof(packed); ++i) { \
|
||||||
|
EXPECT_EQ(str[i], packed[i]); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
msgpack::object_handle oh; \
|
||||||
|
msgpack::unpack(oh, str.data(), str.size()); \
|
||||||
|
{ \
|
||||||
|
auto val2 = oh.get().as<std::vector<byte_t>>(); \
|
||||||
|
EXPECT_TRUE(val1 == val2); \
|
||||||
|
} \
|
||||||
|
{ \
|
||||||
|
auto val2 = oh.get().as<std::span<const byte_t>>(); \
|
||||||
|
EXPECT_TRUE(val1 == val2); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
|
||||||
|
#define MSGPACK_TEST_SPAN_BYTE_OBJECT(byte_t, display_name) \
|
||||||
|
TEST(MSGPACK_CPP20, span_##display_name##_object) \
|
||||||
|
{ \
|
||||||
|
byte_t raw_data[] = { \
|
||||||
|
(byte_t)(0x01), (byte_t)(0x02), (byte_t)(0x7f), (byte_t)(0x80), (byte_t)(0xff) \
|
||||||
|
}; \
|
||||||
|
std::span<const byte_t> val1{raw_data, sizeof(raw_data)}; \
|
||||||
|
\
|
||||||
|
/* Caller needs to manage val1's lifetime. The Data is not copied. */ \
|
||||||
|
msgpack::object obj(val1); \
|
||||||
|
\
|
||||||
|
{ \
|
||||||
|
auto val2 = obj.as<std::vector<byte_t>>(); \
|
||||||
|
EXPECT_TRUE(val1 == val2); \
|
||||||
|
} \
|
||||||
|
{ \
|
||||||
|
auto val2 = obj.as<std::span<const byte_t>>(); \
|
||||||
|
EXPECT_TRUE(val1 == val2); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
|
||||||
|
#define MSGPACK_TEST_SPAN_BYTE_OBJECT_WITH_ZONE(byte_t, display_name) \
|
||||||
|
TEST(MSGPACK_CPP20, span_##display_name##_object_with_zone) \
|
||||||
|
{ \
|
||||||
|
msgpack::zone z; \
|
||||||
|
byte_t raw_data[] = { \
|
||||||
|
(byte_t)(0x01), (byte_t)(0x02), (byte_t)(0x7f), (byte_t)(0x80), (byte_t)(0xff) \
|
||||||
|
}; \
|
||||||
|
std::span<const byte_t> val1(raw_data, sizeof(raw_data)); \
|
||||||
|
\
|
||||||
|
msgpack::object obj(val1, z); \
|
||||||
|
\
|
||||||
|
{ \
|
||||||
|
auto val2 = obj.as<std::vector<byte_t>>(); \
|
||||||
|
EXPECT_TRUE(val1 == val2); \
|
||||||
|
} \
|
||||||
|
{ \
|
||||||
|
auto val2 = obj.as<std::span<const byte_t>>(); \
|
||||||
|
EXPECT_TRUE(val1 == val2); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
|
||||||
|
#define MSGPACK_TEST_SPAN_BYTE(byte_t, display_name) \
|
||||||
|
MSGPACK_TEST_SPAN_BYTE_PACK_CONVERT(byte_t, display_name) \
|
||||||
|
MSGPACK_TEST_SPAN_BYTE_OBJECT(byte_t, display_name) \
|
||||||
|
MSGPACK_TEST_SPAN_BYTE_OBJECT_WITH_ZONE(byte_t, display_name) \
|
||||||
|
|
||||||
|
MSGPACK_TEST_SPAN_BYTE(std::byte, byte)
|
||||||
|
MSGPACK_TEST_SPAN_BYTE(char, char)
|
||||||
|
MSGPACK_TEST_SPAN_BYTE(unsigned char, unsigned_char)
|
||||||
|
|
||||||
|
#undef MSGPACK_TEST_SPAN_BYTE
|
||||||
|
#undef MSGPACK_TEST_SPAN_BYTE_OBJECT_WITH_ZONE
|
||||||
|
#undef MSGPACK_TEST_SPAN_BYTE_OBJECT
|
||||||
|
#undef MSGPACK_TEST_SPAN_BYTE_PACK_CONVERT
|
||||||
|
|
||||||
|
#endif // MSGPACK_HAS_INCLUDE(<span>)
|
||||||
|
|
||||||
|
#endif // !defined(MSGPACK_USE_CPP03) && __cplusplus > 201703
|
@ -18,13 +18,20 @@ namespace test {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
struct allocator {
|
struct allocator {
|
||||||
typedef typename std::allocator<T>::value_type value_type;
|
typedef typename std::allocator<T>::value_type value_type;
|
||||||
|
typedef typename std::allocator<T>::size_type size_type;
|
||||||
|
typedef typename std::allocator<T>::difference_type difference_type;
|
||||||
|
template <class U> struct rebind { typedef allocator<U> other; };
|
||||||
|
#if __cplusplus <= 201703
|
||||||
typedef typename std::allocator<T>::pointer pointer;
|
typedef typename std::allocator<T>::pointer pointer;
|
||||||
typedef typename std::allocator<T>::reference reference;
|
typedef typename std::allocator<T>::reference reference;
|
||||||
typedef typename std::allocator<T>::const_pointer const_pointer;
|
typedef typename std::allocator<T>::const_pointer const_pointer;
|
||||||
typedef typename std::allocator<T>::const_reference const_reference;
|
typedef typename std::allocator<T>::const_reference const_reference;
|
||||||
typedef typename std::allocator<T>::size_type size_type;
|
#else // __cplusplus <= 201703
|
||||||
typedef typename std::allocator<T>::difference_type difference_type;
|
typedef value_type* pointer;
|
||||||
template <class U> struct rebind { typedef allocator<U> other; };
|
typedef value_type& reference;
|
||||||
|
typedef const value_type* const_pointer;
|
||||||
|
typedef const value_type& const_reference;
|
||||||
|
#endif // __cplusplus <= 201703
|
||||||
#if defined(MSGPACK_USE_CPP03)
|
#if defined(MSGPACK_USE_CPP03)
|
||||||
allocator() throw() {}
|
allocator() throw() {}
|
||||||
allocator (const allocator& alloc) throw()
|
allocator (const allocator& alloc) throw()
|
||||||
@ -45,11 +52,21 @@ struct allocator {
|
|||||||
template <class U>
|
template <class U>
|
||||||
allocator (const allocator<U>& alloc) noexcept
|
allocator (const allocator<U>& alloc) noexcept
|
||||||
:alloc_(alloc.alloc_) {}
|
:alloc_(alloc.alloc_) {}
|
||||||
|
#if __cplusplus <= 201703
|
||||||
template <class U, class... Args>
|
template <class U, class... Args>
|
||||||
void construct (U* p, Args&&... args) {
|
void construct (U* p, Args&&... args) {
|
||||||
return alloc_.construct(p, std::forward<Args>(args)...);
|
return alloc_.construct(p, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
size_type max_size() const noexcept { return alloc_.max_size(); }
|
size_type max_size() const noexcept { return alloc_.max_size(); }
|
||||||
|
#else // __cplusplus <= 201703
|
||||||
|
template <class U, class... Args>
|
||||||
|
void construct (U* p, Args&&... args) {
|
||||||
|
return std::allocator_traits<decltype(alloc_)>::construct(alloc_, p, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
size_type max_size() const noexcept {
|
||||||
|
return std::allocator_traits<decltype(alloc_)>::max_size(alloc_);
|
||||||
|
}
|
||||||
|
#endif // __cplusplus <= 201703
|
||||||
#endif // defined(MSGPACK_USE_CPP03)
|
#endif // defined(MSGPACK_USE_CPP03)
|
||||||
pointer allocate (size_type n) {
|
pointer allocate (size_type n) {
|
||||||
return alloc_.allocate(n);
|
return alloc_.allocate(n);
|
||||||
@ -57,9 +74,16 @@ struct allocator {
|
|||||||
void deallocate (pointer p, size_type n) {
|
void deallocate (pointer p, size_type n) {
|
||||||
return alloc_.deallocate(p, n);
|
return alloc_.deallocate(p, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if __cplusplus <= 201703
|
||||||
void destroy (pointer p) {
|
void destroy (pointer p) {
|
||||||
alloc_.destroy(p);
|
alloc_.destroy(p);
|
||||||
}
|
}
|
||||||
|
#else // __cplusplus <= 201703
|
||||||
|
void destroy (pointer p) {
|
||||||
|
std::allocator_traits<decltype(alloc_)>::destroy(alloc_, p);
|
||||||
|
}
|
||||||
|
#endif // __cplusplus <= 201703
|
||||||
|
|
||||||
std::allocator<T> alloc_;
|
std::allocator<T> alloc_;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user