mirror of
https://github.com/fraillt/bitsery.git
synced 2026-06-08 08:13:56 +00:00
150 lines
6.0 KiB
C++
150 lines
6.0 KiB
C++
//MIT License
|
|
//
|
|
//Copyright (c) 2017 Mindaugas Vinkelis
|
|
//
|
|
//Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
//of this software and associated documentation files (the "Software"), to deal
|
|
//in the Software without restriction, including without limitation the rights
|
|
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
//copies of the Software, and to permit persons to whom the Software is
|
|
//furnished to do so, subject to the following conditions:
|
|
//
|
|
//The above copyright notice and this permission notice shall be included in all
|
|
//copies or substantial portions of the Software.
|
|
//
|
|
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
//SOFTWARE.
|
|
|
|
#ifndef BITSERY_DETAILS_BRIEF_SYNTAX_COMMON_H
|
|
#define BITSERY_DETAILS_BRIEF_SYNTAX_COMMON_H
|
|
|
|
#include "../traits/core/traits.h"
|
|
#include <limits>
|
|
|
|
namespace bitsery {
|
|
namespace brief_syntax {
|
|
|
|
//these function overloads is required to apply maxSize, and optimize for fundamental types
|
|
//for contigous arrays of fundamenal types, memcpy will be applied
|
|
|
|
template<typename S, typename T, typename std::enable_if<
|
|
details::IsFundamentalType<typename traits::ContainerTraits<T>::TValue>::value
|
|
&& traits::ContainerTraits<T>::isResizable
|
|
>::type * = nullptr>
|
|
void processContainer(S &s, T &c, size_t maxSize = std::numeric_limits<size_t>::max()) {
|
|
using TValue = typename traits::ContainerTraits<T>::TValue;
|
|
s.template container<sizeof(TValue)>(c, maxSize);
|
|
}
|
|
|
|
template<typename S, typename T, typename std::enable_if<
|
|
!details::IsFundamentalType<typename traits::ContainerTraits<T>::TValue>::value
|
|
&& traits::ContainerTraits<T>::isResizable
|
|
>::type * = nullptr>
|
|
void processContainer(S &s, T &c, size_t maxSize = std::numeric_limits<size_t>::max()) {
|
|
s.container(c, maxSize);
|
|
}
|
|
|
|
template<typename S, typename T, typename std::enable_if<
|
|
details::IsFundamentalType<typename traits::ContainerTraits<T>::TValue>::value
|
|
&& !traits::ContainerTraits<T>::isResizable
|
|
>::type * = nullptr>
|
|
void processContainer(S &s, T &c) {
|
|
using TValue = typename traits::ContainerTraits<T>::TValue;
|
|
s.template container<sizeof(TValue)>(c);
|
|
}
|
|
|
|
template<typename S, typename T, typename std::enable_if<
|
|
!details::IsFundamentalType<typename traits::ContainerTraits<T>::TValue>::value
|
|
&& !traits::ContainerTraits<T>::isResizable
|
|
>::type * = nullptr>
|
|
void processContainer(S &s, T &c) {
|
|
s.container(c);
|
|
}
|
|
|
|
//overloads for text processing to apply maxSize
|
|
|
|
template<typename S, typename T, typename std::enable_if<
|
|
traits::ContainerTraits<T>::isResizable>::type * = nullptr>
|
|
void processText(S &s, T &c, size_t maxSize = std::numeric_limits<size_t>::max()) {
|
|
using TValue = typename traits::ContainerTraits<T>::TValue;
|
|
s.template text<sizeof(TValue)>(c, maxSize);
|
|
}
|
|
|
|
template<typename S, typename T, typename std::enable_if<
|
|
!traits::ContainerTraits<T>::isResizable>::type * = nullptr>
|
|
void processText(S &s, T &c) {
|
|
using TValue = typename traits::ContainerTraits<T>::TValue;
|
|
s.template text<sizeof(TValue)>(c);
|
|
}
|
|
|
|
|
|
//all wrapper functions, that modify behaviour, should inherit from this
|
|
struct ModFnc {
|
|
|
|
};
|
|
|
|
//this type is used to differentiate between container and text behaviour
|
|
template<typename T, size_t N, bool isText>
|
|
struct CArray : public ModFnc {
|
|
CArray(T (&data_)[N]) : data{data_} {};
|
|
T (&data)[N];
|
|
};
|
|
|
|
template<typename S, typename T, size_t N>
|
|
void serialize(S &s, CArray<T, N, true> &str) {
|
|
processText(s, str.data);
|
|
}
|
|
|
|
template<typename S, typename T, size_t N>
|
|
void serialize(S &s, CArray<T, N, false> &obj) {
|
|
processContainer(s, obj.data);
|
|
}
|
|
|
|
//used to set max container size
|
|
template<typename T>
|
|
struct MaxSize : public ModFnc {
|
|
MaxSize(T &data_, size_t maxSize_) : data{data_}, maxSize{maxSize_} {};
|
|
T &data;
|
|
size_t maxSize;
|
|
};
|
|
|
|
//if container, then call procesContainer, this memcpy for fundamental types contiguous container
|
|
template<typename S, typename T>
|
|
void processMaxSize(S &s, T& data, size_t maxSize, std::true_type) {
|
|
processContainer(s, data, maxSize);
|
|
}
|
|
|
|
//overload for const T&
|
|
template<typename S, typename T>
|
|
void processMaxSize(S &s, const T& data, size_t maxSize, std::true_type) {
|
|
processContainer(s, const_cast<T&>(data), maxSize);
|
|
}
|
|
|
|
|
|
//try to call serialize overload with maxsize, extensions use this technique
|
|
template<typename S, typename T>
|
|
void processMaxSize(S &s, T& data, size_t maxSize, std::false_type) {
|
|
serialize(s, data, maxSize);
|
|
}
|
|
|
|
//overload for const T&
|
|
template<typename S, typename T>
|
|
void processMaxSize(S &s, const T& data, size_t maxSize, std::false_type) {
|
|
serialize(s, const_cast<T&>(data), maxSize);
|
|
}
|
|
|
|
template<typename S, typename T>
|
|
void serialize(S &s, const MaxSize<T> &ms) {
|
|
processMaxSize(s, ms.data, ms.maxSize, details::IsContainerTraitsDefined<typename std::decay<T>::type>{});
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
#endif //BITSERY_DETAILS_BRIEF_SYNTAX_COMMON_H
|