Core/Serialization: Add type tag parameters

This commit is contained in:
Lynix
2018-03-20 20:56:06 +01:00
parent 3165dbe095
commit 69f079fcc8
39 changed files with 128 additions and 90 deletions

View File

@@ -10,6 +10,7 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Enums.hpp>
#include <Nazara/Core/SerializationContext.hpp>
#include <Nazara/Core/TypeTag.hpp>
#include <functional>
#include <string>
#include <tuple>
@@ -37,19 +38,22 @@ namespace Nz
};
template<typename T>
struct TypeTag {};
bool Serialize(SerializationContext& context, T&& value);
inline bool Serialize(SerializationContext& context, bool value);
inline bool Serialize(SerializationContext& context, const std::string& value);
inline bool Serialize(SerializationContext& context, bool value, TypeTag<bool>);
inline bool Serialize(SerializationContext& context, const std::string& value, TypeTag<std::string>);
template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value, bool> Serialize(SerializationContext& context, T value);
inline bool Unserialize(SerializationContext& context, bool* value);
inline bool Unserialize(SerializationContext& context, std::string* value);
std::enable_if_t<std::is_arithmetic<T>::value, bool> Serialize(SerializationContext& context, T value, TypeTag<T>);
template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value, bool> Unserialize(SerializationContext& context, T* value);
bool Unserialize(SerializationContext& context, T* value);
inline bool Unserialize(SerializationContext& context, bool* value, TypeTag<bool>);
inline bool Unserialize(SerializationContext& context, std::string* value, TypeTag<std::string>);
template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value, bool> Unserialize(SerializationContext& context, T* value, TypeTag<T>);
}
#include <Nazara/Core/Algorithm.inl>

View File

@@ -12,6 +12,7 @@
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Stream.hpp>
#include <climits>
#include <utility>
#include <Nazara/Core/Debug.hpp>
namespace Nz
@@ -199,6 +200,13 @@ namespace Nz
template<typename T> struct PointedType<T* volatile> {typedef T type;};
template<typename T> struct PointedType<T* const volatile> {typedef T type;};
template<typename T>
bool Serialize(SerializationContext& context, T&& value)
{
return Serialize(context, std::forward<T>(value), TypeTag<std::decay_t<T>>());
}
/*!
* \ingroup core
* \brief Serializes a boolean
@@ -209,7 +217,7 @@ namespace Nz
*
* \see Serialize, Unserialize
*/
inline bool Serialize(SerializationContext& context, bool value)
inline bool Serialize(SerializationContext& context, bool value, TypeTag<bool>)
{
if (context.currentBitPos == 8)
{
@@ -221,7 +229,7 @@ namespace Nz
context.currentByte |= 1 << context.currentBitPos;
if (++context.currentBitPos >= 8)
return Serialize<UInt8>(context, context.currentByte);
return Serialize(context, context.currentByte, TypeTag<UInt8>());
else
return true;
}
@@ -234,9 +242,9 @@ namespace Nz
* \param context Context for the serialization
* \param value String to serialize
*/
bool Serialize(SerializationContext& context, const std::string& value)
bool Serialize(SerializationContext& context, const std::string& value, TypeTag<std::string>)
{
if (!Serialize(context, UInt32(value.size())))
if (!Serialize(context, UInt32(value.size()), TypeTag<UInt32>()))
return false;
return context.stream->Write(value.data(), value.size()) == value.size();
@@ -253,7 +261,7 @@ namespace Nz
* \see Serialize, Unserialize
*/
template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value, bool> Serialize(SerializationContext& context, T value)
std::enable_if_t<std::is_arithmetic<T>::value, bool> Serialize(SerializationContext& context, T value, TypeTag<T>)
{
// Flush bits in case a writing is in progress
context.FlushBits();
@@ -264,6 +272,13 @@ namespace Nz
return context.stream->Write(&value, sizeof(T)) == sizeof(T);
}
template<typename T>
bool Unserialize(SerializationContext& context, T* value)
{
return Unserialize(context, value, TypeTag<T>());
}
/*!
* \ingroup core
* \brief Unserializes a boolean
@@ -274,11 +289,11 @@ namespace Nz
*
* \see Serialize, Unserialize
*/
inline bool Unserialize(SerializationContext& context, bool* value)
inline bool Unserialize(SerializationContext& context, bool* value, TypeTag<bool>)
{
if (context.currentBitPos == 8)
{
if (!Unserialize(context, &context.currentByte))
if (!Unserialize(context, &context.currentByte, TypeTag<UInt8>()))
return false;
context.currentBitPos = 0;
@@ -299,10 +314,10 @@ namespace Nz
* \param context Context of unserialization
* \param string std::string to unserialize
*/
bool Unserialize(SerializationContext& context, std::string* string)
bool Unserialize(SerializationContext& context, std::string* string, TypeTag<std::string>)
{
UInt32 size;
if (!Unserialize(context, &size))
if (!Unserialize(context, &size, TypeTag<UInt32>()))
return false;
string->resize(size);
@@ -322,7 +337,7 @@ namespace Nz
* \see Serialize, Unserialize
*/
template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value, bool> Unserialize(SerializationContext& context, T* value)
std::enable_if_t<std::is_arithmetic<T>::value, bool> Unserialize(SerializationContext& context, T* value, TypeTag<T>)
{
NazaraAssert(value, "Invalid data pointer");

View File

@@ -90,7 +90,7 @@ namespace Nz
{
m_context.currentBitPos = 8; //< To prevent Serialize to flush bits itself
if (!Serialize<UInt8>(m_context, m_context.currentByte))
if (!Serialize(m_context, m_context.currentByte))
return false;
}

View File

@@ -71,8 +71,8 @@ namespace Nz
static float Hue2RGB(float v1, float v2, float vH);
};
inline bool Serialize(SerializationContext& context, const Color& color);
inline bool Unserialize(SerializationContext& context, Color* color);
inline bool Serialize(SerializationContext& context, const Color& color, TypeTag<Color>);
inline bool Unserialize(SerializationContext& context, Color* color, TypeTag<Color>);
}
std::ostream& operator<<(std::ostream& out, const Nz::Color& color);

View File

@@ -617,7 +617,7 @@ namespace Nz
* \param context Serialization context
* \param color Input color
*/
inline bool Serialize(SerializationContext& context, const Color& color)
inline bool Serialize(SerializationContext& context, const Color& color, TypeTag<Color>)
{
if (!Serialize(context, color.r))
return false;
@@ -641,7 +641,7 @@ namespace Nz
* \param context Serialization context
* \param color Output color
*/
inline bool Unserialize(SerializationContext& context, Color* color)
inline bool Unserialize(SerializationContext& context, Color* color, TypeTag<Color>)
{
if (!Unserialize(context, &color->r))
return false;

View File

@@ -10,6 +10,7 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Config.hpp>
#include <Nazara/Core/Endianness.hpp>
#include <Nazara/Core/TypeTag.hpp>
namespace Nz
{

View File

@@ -9,6 +9,7 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Endianness.hpp>
#include <Nazara/Core/TypeTag.hpp>
#include <cstdarg>
#include <iosfwd>
#include <memory>
@@ -328,8 +329,8 @@ namespace Nz
class AbstractHash;
inline bool HashAppend(AbstractHash* hash, const String& string);
NAZARA_CORE_API bool Serialize(SerializationContext& context, const String& string);
NAZARA_CORE_API bool Unserialize(SerializationContext& context, String* string);
NAZARA_CORE_API bool Serialize(SerializationContext& context, const String& string, TypeTag<String>);
NAZARA_CORE_API bool Unserialize(SerializationContext& context, String* string, TypeTag<String>);
}
namespace std

View File

@@ -0,0 +1,16 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_TYPETAG_HPP
#define NAZARA_TYPETAG_HPP
namespace Nz
{
template<typename T>
struct TypeTag {};
}
#endif // NAZARA_TYPETAG_HPP