input buffer adapter accepts const buffer

This commit is contained in:
Mindaugas
2019-01-10 20:48:03 +02:00
parent b10f86da00
commit 65f90637df
6 changed files with 52 additions and 12 deletions

View File

@@ -4,10 +4,13 @@
* ability to create non default constructible objects, by defining private default constructor and making `friend class bitsery::Access;` to access it.
It is not necessary to enforce class invariant immediately, because internal object representation will be overriden anyway.
### Improvements
* `StdSmartPtr` supports `std::unique_ptr` with custom deleter.
* `*InputBufferAdapter`(all) can also accept const buffer;
### Bug fixes
* fixed deserialization in `bitsery/ext/std_map{set}` when target container is not empty.
* added missing template parameters for specializations on `std` containers in multiple files in `bitsery/ext/*`.
* fixed `StdSmartPtr` to correctly work with `std::unique_ptr` when it has custom deleter.
# [4.4.0](https://github.com/fraillt/bitsery/compare/v4.3.0...v4.4.0) (2019-01-08)

View File

@@ -31,9 +31,16 @@ namespace bitsery {
//base class that stores container iterators, and is required for session support (for reading sessions data)
template<typename Buffer>
class BufferIterators {
protected:
using TIterator = typename traits::BufferAdapterTraits<Buffer>::TIterator;
static constexpr bool isConstBuffer = std::is_const<Buffer>::value;
using BuffNonConst = typename std::remove_const<Buffer>::type;
protected:
using TIterator = typename std::conditional<isConstBuffer,
typename traits::BufferAdapterTraits<BuffNonConst>::TConstIterator,
typename traits::BufferAdapterTraits<BuffNonConst>::TIterator>::type;
static_assert(details::IsDefined<TIterator>::value,
"Please define BufferAdapterTraits or include from <bitsery/traits/...>");
BufferIterators(TIterator begin, TIterator end)
: posIt{begin},
endIt{end} {
@@ -48,16 +55,15 @@ namespace bitsery {
template<typename Buffer>
class InputBufferAdapter : public BufferIterators<Buffer> {
public:
using TIterator = typename BufferIterators<Buffer>::TIterator;
using TValue = typename traits::BufferAdapterTraits<Buffer>::TValue;
using TValue = typename traits::BufferAdapterTraits<typename std::remove_const<Buffer>::type>::TValue;
static_assert(details::IsDefined<TValue>::value,
"Please define BufferAdapterTraits or include from <bitsery/traits/...>");
static_assert(traits::ContainerTraits<Buffer>::isContiguous,
static_assert(traits::ContainerTraits<typename std::remove_const<Buffer>::type>::isContiguous,
"BufferAdapter only works with contiguous containers");
InputBufferAdapter(TIterator begin, TIterator end)
: BufferIterators<Buffer>(begin, end) {
InputBufferAdapter(TIterator begin, TIterator endIt)
: BufferIterators<Buffer>(begin, endIt) {
}
InputBufferAdapter(TIterator begin, size_t size)
@@ -104,13 +110,13 @@ namespace bitsery {
public:
using TIterator = typename BufferIterators<Buffer>::TIterator;
using TValue = typename traits::BufferAdapterTraits<Buffer>::TValue;
using TValue = typename traits::BufferAdapterTraits<typename std::remove_const<Buffer>::type>::TValue;
static_assert(details::IsDefined<TValue>::value,
"Please define BufferAdapterTraits or include from <bitsery/traits/...>");
static_assert(traits::ContainerTraits<Buffer>::isContiguous,
static_assert(traits::ContainerTraits<typename std::remove_const<Buffer>::type>::isContiguous,
"BufferAdapter only works with contiguous containers");
UnsafeInputBufferAdapter(TIterator begin, TIterator end) : BufferIterators<Buffer>(begin, end) {
UnsafeInputBufferAdapter(TIterator beginIt, TIterator endIt) : BufferIterators<Buffer>(beginIt, endIt) {
}
UnsafeInputBufferAdapter(TIterator begin, size_t size)

View File

@@ -56,7 +56,7 @@ namespace bitsery {
int& operator*() {
return data;
}
int data;
int data{};
};
template <typename T>

View File

@@ -74,6 +74,7 @@ namespace bitsery {
template <typename T, bool Resizable = ContainerTraits<T>::isResizable>
struct StdContainerForBufferAdapter {
using TIterator = typename T::iterator;
using TConstIterator = typename T::const_iterator;
using TValue = typename ContainerTraits<T>::TValue;
};
@@ -90,6 +91,7 @@ namespace bitsery {
container.resize((std::max)(newSize, container.capacity()));
}
using TIterator = typename T::iterator;
using TConstIterator = typename T::const_iterator;
using TValue = typename ContainerTraits<T>::TValue;
};

View File

@@ -155,6 +155,7 @@ namespace bitsery {
}
using TIterator = details::NotDefinedType;
using TConstIterator = details::NotDefinedType;
using TValue = typename ContainerTraits<T>::TValue;
};
@@ -162,6 +163,7 @@ namespace bitsery {
template <typename T, size_t N>
struct BufferAdapterTraits<T[N]> {
using TIterator = T*;
using TConstIterator = const T*;
using TValue = T;
};
@@ -169,12 +171,14 @@ namespace bitsery {
template <typename T>
struct BufferAdapterTraits<const T*> {
using TIterator = const T*;
using TConstIterator = const T*;
using TValue = T;
};
template <typename T>
struct BufferAdapterTraits<T*> {
using TIterator = T*;
using TConstIterator = const T*;
using TValue = T;
};

View File

@@ -153,3 +153,28 @@ TEST(DataReading, WhenReaderHasErrorsAllOperationsReadsReturnZero) {
EXPECT_THAT(r2[1], Eq(0u));
EXPECT_THAT(r3, Eq(0u));
}
TEST(DataReading, ConstBufferAllAdapters) {
//create and write to buffer
uint16_t data = 7549;
Buffer bufWrite{};
Writer bw{bufWrite};
bw.writeBytes<2>(data);
bw.flush();
const Buffer buf{bufWrite};
//read from buffer
using Adapter1 = bitsery::InputBufferAdapter<const Buffer>;
using Adapter2 = bitsery::UnsafeInputBufferAdapter<const Buffer>;
bitsery::AdapterReader<Adapter1, bitsery::DefaultConfig> r1{Adapter1{buf.begin(), buf.end()}};
bitsery::AdapterReader<Adapter2, bitsery::DefaultConfig> r2{Adapter2{buf.begin(), buf.end()}};
uint16_t res1{};
r1.readBytes<2>(res1);
uint16_t res2{};
r2.readBytes<2>(res2);
EXPECT_THAT(res1, Eq(data));
EXPECT_THAT(res2, Eq(data));
}