Initial commit.
Final release of the project Anonymizer (2015). Project settings for the Qt Creator (ver. 3.6).
This commit is contained in:
360
3rdparty/include/cereal/details/helpers.hpp
vendored
Normal file
360
3rdparty/include/cereal/details/helpers.hpp
vendored
Normal file
@ -0,0 +1,360 @@
|
||||
/*! \file helpers.hpp
|
||||
\brief Internal helper functionality
|
||||
\ingroup Internal */
|
||||
/*
|
||||
Copyright (c) 2014, Randolph Voorhies, Shane Grant
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of cereal nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL RANDOLPH VOORHIES OR SHANE GRANT BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef CEREAL_DETAILS_HELPERS_HPP_
|
||||
#define CEREAL_DETAILS_HELPERS_HPP_
|
||||
|
||||
#include <type_traits>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <cereal/macros.hpp>
|
||||
#include <cereal/details/static_object.hpp>
|
||||
|
||||
namespace cereal
|
||||
{
|
||||
// ######################################################################
|
||||
//! An exception class thrown when things go wrong at runtime
|
||||
/*! @ingroup Utility */
|
||||
struct Exception : public std::runtime_error
|
||||
{
|
||||
explicit Exception( const std::string & what_ ) : std::runtime_error(what_) {}
|
||||
explicit Exception( const char * what_ ) : std::runtime_error(what_) {}
|
||||
};
|
||||
|
||||
// ######################################################################
|
||||
//! The size type used by cereal
|
||||
/*! To ensure compatability between 32, 64, etc bit machines, we need to use
|
||||
a fixed size type instead of size_t, which may vary from machine to
|
||||
machine. */
|
||||
using size_type = uint64_t;
|
||||
|
||||
// forward decls
|
||||
class BinaryOutputArchive;
|
||||
class BinaryInputArchive;
|
||||
|
||||
// ######################################################################
|
||||
namespace detail
|
||||
{
|
||||
struct NameValuePairCore {}; //!< Traits struct for NVPs
|
||||
}
|
||||
|
||||
//! For holding name value pairs
|
||||
/*! This pairs a name (some string) with some value such that an archive
|
||||
can potentially take advantage of the pairing.
|
||||
|
||||
In serialization functions, NameValuePairs are usually created like so:
|
||||
@code{.cpp}
|
||||
struct MyStruct
|
||||
{
|
||||
int a, b, c, d, e;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive( CEREAL_NVP(a),
|
||||
CEREAL_NVP(b),
|
||||
CEREAL_NVP(c),
|
||||
CEREAL_NVP(d),
|
||||
CEREAL_NVP(e) );
|
||||
}
|
||||
};
|
||||
@endcode
|
||||
|
||||
Alternatively, you can give you data members custom names like so:
|
||||
@code{.cpp}
|
||||
struct MyStruct
|
||||
{
|
||||
int a, b, my_embarrassing_variable_name, d, e;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive( CEREAL_NVP(a),
|
||||
CEREAL_NVP(b),
|
||||
cereal::make_nvp("var", my_embarrassing_variable_name) );
|
||||
CEREAL_NVP(d),
|
||||
CEREAL_NVP(e) );
|
||||
}
|
||||
};
|
||||
@endcode
|
||||
|
||||
There is a slight amount of overhead to creating NameValuePairs, so there
|
||||
is a third method which will elide the names when they are not used by
|
||||
the Archive:
|
||||
|
||||
@code{.cpp}
|
||||
struct MyStruct
|
||||
{
|
||||
int a, b;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive( cereal::make_nvp<Archive>(a),
|
||||
cereal::make_nvp<Archive>(b) );
|
||||
}
|
||||
};
|
||||
@endcode
|
||||
|
||||
This third method is generally only used when providing generic type
|
||||
support. Users writing their own serialize functions will normally
|
||||
explicitly control whether they want to use NVPs or not.
|
||||
|
||||
@internal */
|
||||
template <class T>
|
||||
class NameValuePair : detail::NameValuePairCore
|
||||
{
|
||||
private:
|
||||
// If we get passed an array, keep the type as is, otherwise store
|
||||
// a reference if we were passed an l value reference, else copy the value
|
||||
using Type = typename std::conditional<std::is_array<typename std::remove_reference<T>::type>::value,
|
||||
typename std::remove_cv<T>::type,
|
||||
typename std::conditional<std::is_lvalue_reference<T>::value,
|
||||
T,
|
||||
typename std::decay<T>::type>::type>::type;
|
||||
|
||||
// prevent nested nvps
|
||||
static_assert( !std::is_base_of<detail::NameValuePairCore, T>::value,
|
||||
"Cannot pair a name to a NameValuePair" );
|
||||
|
||||
NameValuePair & operator=( NameValuePair const & ) = delete;
|
||||
|
||||
public:
|
||||
//! Constructs a new NameValuePair
|
||||
/*! @param n The name of the pair
|
||||
@param v The value to pair. Ideally this should be an l-value reference so that
|
||||
the value can be both loaded and saved to. If you pass an r-value reference,
|
||||
the NameValuePair will store a copy of it instead of a reference. Thus you should
|
||||
only pass r-values in cases where this makes sense, such as the result of some
|
||||
size() call.
|
||||
@internal */
|
||||
NameValuePair( char const * n, T && v ) : name(n), value(std::forward<T>(v)) {}
|
||||
|
||||
char const * name;
|
||||
Type value;
|
||||
};
|
||||
|
||||
//! A specialization of make_nvp<> that simply forwards the value for binary archives
|
||||
/*! @relates NameValuePair
|
||||
@internal */
|
||||
template<class Archive, class T> inline
|
||||
typename
|
||||
std::enable_if<std::is_same<Archive, ::cereal::BinaryInputArchive>::value ||
|
||||
std::is_same<Archive, ::cereal::BinaryOutputArchive>::value,
|
||||
T && >::type
|
||||
make_nvp( const char *, T && value )
|
||||
{
|
||||
return std::forward<T>(value);
|
||||
}
|
||||
|
||||
//! A specialization of make_nvp<> that actually creates an nvp for non-binary archives
|
||||
/*! @relates NameValuePair
|
||||
@internal */
|
||||
template<class Archive, class T> inline
|
||||
typename
|
||||
std::enable_if<!std::is_same<Archive, ::cereal::BinaryInputArchive>::value &&
|
||||
!std::is_same<Archive, ::cereal::BinaryOutputArchive>::value,
|
||||
NameValuePair<T> >::type
|
||||
make_nvp( const char * name, T && value)
|
||||
{
|
||||
return {name, std::forward<T>(value)};
|
||||
}
|
||||
|
||||
//! Convenience for creating a templated NVP
|
||||
/*! For use in inteneral generic typing functions which have an
|
||||
Archive type declared
|
||||
@internal */
|
||||
#define CEREAL_NVP_(name, value) ::cereal::make_nvp<Archive>(name, value)
|
||||
|
||||
// ######################################################################
|
||||
//! A wrapper around data that can be serialized in a binary fashion
|
||||
/*! This class is used to demarcate data that can safely be serialized
|
||||
as a binary chunk of data. Individual archives can then choose how
|
||||
best represent this during serialization.
|
||||
|
||||
@internal */
|
||||
template <class T>
|
||||
struct BinaryData
|
||||
{
|
||||
//! Internally store the pointer as a void *, keeping const if created with
|
||||
//! a const pointer
|
||||
using PT = typename std::conditional<std::is_const<typename std::remove_pointer<T>::type>::value,
|
||||
const void *,
|
||||
void *>::type;
|
||||
|
||||
BinaryData( T && d, uint64_t s ) : data(std::forward<T>(d)), size(s) {}
|
||||
|
||||
PT data; //!< pointer to beginning of data
|
||||
uint64_t size; //!< size in bytes
|
||||
};
|
||||
|
||||
// ######################################################################
|
||||
namespace detail
|
||||
{
|
||||
// base classes for type checking
|
||||
/* The rtti virtual function only exists to enable an archive to
|
||||
be used in a polymorphic fashion, if necessary. See the
|
||||
archive adapters for an example of this */
|
||||
class OutputArchiveBase { private: virtual void rtti(){} };
|
||||
class InputArchiveBase { private: virtual void rtti(){} };
|
||||
|
||||
// forward decls for polymorphic support
|
||||
template <class Archive, class T> struct polymorphic_serialization_support;
|
||||
struct adl_tag;
|
||||
|
||||
// used during saving pointers
|
||||
static const int32_t msb_32bit = 0x80000000;
|
||||
static const int32_t msb2_32bit = 0x40000000;
|
||||
}
|
||||
|
||||
// ######################################################################
|
||||
//! A wrapper around size metadata
|
||||
/*! This class provides a way for archives to have more flexibility over how
|
||||
they choose to serialize size metadata for containers. For some archive
|
||||
types, the size may be implicitly encoded in the output (e.g. JSON) and
|
||||
not need an explicit entry. Specializing serialize or load/save for
|
||||
your archive and SizeTags allows you to choose what happens.
|
||||
|
||||
@internal */
|
||||
template <class T>
|
||||
class SizeTag
|
||||
{
|
||||
private:
|
||||
// Store a reference if passed an lvalue reference, otherwise
|
||||
// make a copy of the data
|
||||
using Type = typename std::conditional<std::is_lvalue_reference<T>::value,
|
||||
T,
|
||||
typename std::decay<T>::type>::type;
|
||||
|
||||
SizeTag & operator=( SizeTag const & ) = delete;
|
||||
|
||||
public:
|
||||
SizeTag( T && sz ) : size(std::forward<T>(sz)) {}
|
||||
|
||||
Type size;
|
||||
};
|
||||
|
||||
// ######################################################################
|
||||
//! A wrapper around a key and value for serializing data into maps.
|
||||
/*! This class just provides a grouping of keys and values into a struct for
|
||||
human readable archives. For example, XML archives will use this wrapper
|
||||
to write maps like so:
|
||||
|
||||
@code{.xml}
|
||||
<mymap>
|
||||
<item0>
|
||||
<key>MyFirstKey</key>
|
||||
<value>MyFirstValue</value>
|
||||
</item0>
|
||||
<item1>
|
||||
<key>MySecondKey</key>
|
||||
<value>MySecondValue</value>
|
||||
</item1>
|
||||
</mymap>
|
||||
@endcode
|
||||
|
||||
\sa make_map_item
|
||||
@internal */
|
||||
template <class Key, class Value>
|
||||
struct MapItem
|
||||
{
|
||||
using KeyType = typename std::conditional<
|
||||
std::is_lvalue_reference<Key>::value,
|
||||
Key,
|
||||
typename std::decay<Key>::type>::type;
|
||||
|
||||
using ValueType = typename std::conditional<
|
||||
std::is_lvalue_reference<Value>::value,
|
||||
Value,
|
||||
typename std::decay<Value>::type>::type;
|
||||
|
||||
//! Construct a MapItem from a key and a value
|
||||
/*! @internal */
|
||||
MapItem( Key && key_, Value && value_ ) : key(std::forward<Key>(key_)), value(std::forward<Value>(value_)) {}
|
||||
|
||||
MapItem & operator=( MapItem const & ) = delete;
|
||||
|
||||
KeyType key;
|
||||
ValueType value;
|
||||
|
||||
//! Serialize the MapItem with the NVPs "key" and "value"
|
||||
template <class Archive> inline
|
||||
void CEREAL_SERIALIZE_FUNCTION_NAME(Archive & archive)
|
||||
{
|
||||
archive( make_nvp<Archive>("key", key),
|
||||
make_nvp<Archive>("value", value) );
|
||||
}
|
||||
};
|
||||
|
||||
//! Create a MapItem so that human readable archives will group keys and values together
|
||||
/*! @internal
|
||||
@relates MapItem */
|
||||
template <class KeyType, class ValueType> inline
|
||||
MapItem<KeyType, ValueType> make_map_item(KeyType && key, ValueType && value)
|
||||
{
|
||||
return {std::forward<KeyType>(key), std::forward<ValueType>(value)};
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
//! Tag for Version, which due to its anonymous namespace, becomes a different
|
||||
//! type in each translation unit
|
||||
/*! This allows CEREAL_CLASS_VERSION to be safely called in a header file */
|
||||
namespace{ struct version_binding_tag {}; }
|
||||
|
||||
// ######################################################################
|
||||
//! Version information class
|
||||
/*! This is the base case for classes that have not been explicitly
|
||||
registered */
|
||||
template <class T, class BindingTag = version_binding_tag> struct Version
|
||||
{
|
||||
static const std::uint32_t version = 0;
|
||||
// we don't need to explicitly register these types since they
|
||||
// always get a version number of 0
|
||||
};
|
||||
|
||||
//! Holds all registered version information
|
||||
struct Versions
|
||||
{
|
||||
std::unordered_map<std::size_t, std::uint32_t> mapping;
|
||||
|
||||
std::uint32_t find( std::size_t hash, std::uint32_t version )
|
||||
{
|
||||
const auto result = mapping.emplace( hash, version );
|
||||
return result.first->second;
|
||||
}
|
||||
}; // struct Versions
|
||||
} // namespace detail
|
||||
} // namespace cereal
|
||||
|
||||
#endif // CEREAL_DETAILS_HELPERS_HPP_
|
437
3rdparty/include/cereal/details/polymorphic_impl.hpp
vendored
Normal file
437
3rdparty/include/cereal/details/polymorphic_impl.hpp
vendored
Normal file
@ -0,0 +1,437 @@
|
||||
/*! \file polymorphic_impl.hpp
|
||||
\brief Internal polymorphism support
|
||||
\ingroup Internal */
|
||||
/*
|
||||
Copyright (c) 2014, Randolph Voorhies, Shane Grant
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of cereal nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL RANDOLPH VOORHIES OR SHANE GRANT BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* This code is heavily inspired by the boost serialization implementation by the following authors
|
||||
|
||||
(C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
(C) Copyright 2006 David Abrahams - http://www.boost.org.
|
||||
|
||||
See /boost/serialization/export.hpp and /boost/archive/detail/register_archive.hpp for their
|
||||
implementation.
|
||||
*/
|
||||
#ifndef CEREAL_DETAILS_POLYMORPHIC_IMPL_HPP_
|
||||
#define CEREAL_DETAILS_POLYMORPHIC_IMPL_HPP_
|
||||
|
||||
#include <cereal/details/static_object.hpp>
|
||||
#include <cereal/types/memory.hpp>
|
||||
#include <cereal/types/string.hpp>
|
||||
#include <functional>
|
||||
#include <typeindex>
|
||||
#include <map>
|
||||
|
||||
//! Binds a polymorhic type to all registered archives
|
||||
/*! This binds a polymorphic type to all compatible registered archives that
|
||||
have been registered with CEREAL_REGISTER_ARCHIVE. This must be called
|
||||
after all archives are registered (usually after the archives themselves
|
||||
have been included). */
|
||||
#define CEREAL_BIND_TO_ARCHIVES(T) \
|
||||
namespace cereal { \
|
||||
namespace detail { \
|
||||
template<> \
|
||||
struct init_binding<T> { \
|
||||
static bind_to_archives<T> const & b; \
|
||||
static void unused() { (void)b; } \
|
||||
}; \
|
||||
bind_to_archives<T> const & init_binding<T>::b = \
|
||||
::cereal::detail::StaticObject< \
|
||||
bind_to_archives<T> \
|
||||
>::getInstance().bind(); \
|
||||
}} /* end namespaces */
|
||||
|
||||
namespace cereal
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
//! Binds a compile time type with a user defined string
|
||||
template <class T>
|
||||
struct binding_name {};
|
||||
|
||||
//! A structure holding a map from type_indices to output serializer functions
|
||||
/*! A static object of this map should be created for each registered archive
|
||||
type, containing entries for every registered type that describe how to
|
||||
properly cast the type to its real type in polymorphic scenarios for
|
||||
shared_ptr, weak_ptr, and unique_ptr. */
|
||||
template <class Archive>
|
||||
struct OutputBindingMap
|
||||
{
|
||||
//! A serializer function
|
||||
/*! Serializer functions return nothing and take an archive as
|
||||
their first parameter (will be cast properly inside the function,
|
||||
and a pointer to actual data (contents of smart_ptr's get() function)
|
||||
as their second parameter */
|
||||
typedef std::function<void(void*, void const *)> Serializer;
|
||||
|
||||
//! Struct containing the serializer functions for all pointer types
|
||||
struct Serializers
|
||||
{
|
||||
Serializer shared_ptr, //!< Serializer function for shared/weak pointers
|
||||
unique_ptr; //!< Serializer function for unique pointers
|
||||
};
|
||||
|
||||
//! A map of serializers for pointers of all registered types
|
||||
std::map<std::type_index, Serializers> map;
|
||||
};
|
||||
|
||||
//! An empty noop deleter
|
||||
template<class T> struct EmptyDeleter { void operator()(T *) const {} };
|
||||
|
||||
//! A structure holding a map from type name strings to input serializer functions
|
||||
/*! A static object of this map should be created for each registered archive
|
||||
type, containing entries for every registered type that describe how to
|
||||
properly cast the type to its real type in polymorphic scenarios for
|
||||
shared_ptr, weak_ptr, and unique_ptr. */
|
||||
template <class Archive>
|
||||
struct InputBindingMap
|
||||
{
|
||||
//! Shared ptr serializer function
|
||||
/*! Serializer functions return nothing and take an archive as
|
||||
their first parameter (will be cast properly inside the function,
|
||||
and a shared_ptr (or unique_ptr for the unique case) of any base
|
||||
type. Internally it will properly be loaded and cast to the
|
||||
correct type. */
|
||||
typedef std::function<void(void*, std::shared_ptr<void> & )> SharedSerializer;
|
||||
//! Unique ptr serializer function
|
||||
typedef std::function<void(void*, std::unique_ptr<void, EmptyDeleter<void>> & )> UniqueSerializer;
|
||||
|
||||
//! Struct containing the serializer functions for all pointer types
|
||||
struct Serializers
|
||||
{
|
||||
SharedSerializer shared_ptr; //!< Serializer function for shared/weak pointers
|
||||
UniqueSerializer unique_ptr; //!< Serializer function for unique pointers
|
||||
};
|
||||
|
||||
//! A map of serializers for pointers of all registered types
|
||||
std::map<std::string, Serializers> map;
|
||||
};
|
||||
|
||||
// forward decls for archives from cereal.hpp
|
||||
class InputArchiveBase;
|
||||
class OutputArchiveBase;
|
||||
|
||||
//! Creates a binding (map entry) between an input archive type and a polymorphic type
|
||||
/*! Bindings are made when types are registered, assuming that at least one
|
||||
archive has already been registered. When this struct is created,
|
||||
it will insert (at run time) an entry into a map that properly handles
|
||||
casting for serializing polymorphic objects */
|
||||
template <class Archive, class T> struct InputBindingCreator
|
||||
{
|
||||
//! Initialize the binding
|
||||
InputBindingCreator()
|
||||
{
|
||||
auto & map = StaticObject<InputBindingMap<Archive>>::getInstance().map;
|
||||
auto key = std::string(binding_name<T>::name());
|
||||
auto lb = map.lower_bound(key);
|
||||
|
||||
if (lb != map.end() && lb->first == key)
|
||||
return;
|
||||
|
||||
typename InputBindingMap<Archive>::Serializers serializers;
|
||||
|
||||
serializers.shared_ptr =
|
||||
[](void * arptr, std::shared_ptr<void> & dptr)
|
||||
{
|
||||
Archive & ar = *static_cast<Archive*>(arptr);
|
||||
std::shared_ptr<T> ptr;
|
||||
|
||||
ar( CEREAL_NVP_("ptr_wrapper", ::cereal::memory_detail::make_ptr_wrapper(ptr)) );
|
||||
|
||||
dptr = ptr;
|
||||
};
|
||||
|
||||
serializers.unique_ptr =
|
||||
[](void * arptr, std::unique_ptr<void, EmptyDeleter<void>> & dptr)
|
||||
{
|
||||
Archive & ar = *static_cast<Archive*>(arptr);
|
||||
std::unique_ptr<T> ptr;
|
||||
|
||||
ar( CEREAL_NVP_("ptr_wrapper", ::cereal::memory_detail::make_ptr_wrapper(ptr)) );
|
||||
|
||||
dptr.reset(ptr.release());
|
||||
};
|
||||
|
||||
map.insert( lb, { std::move(key), std::move(serializers) } );
|
||||
}
|
||||
};
|
||||
|
||||
//! Creates a binding (map entry) between an output archive type and a polymorphic type
|
||||
/*! Bindings are made when types are registered, assuming that at least one
|
||||
archive has already been registered. When this struct is created,
|
||||
it will insert (at run time) an entry into a map that properly handles
|
||||
casting for serializing polymorphic objects */
|
||||
template <class Archive, class T> struct OutputBindingCreator
|
||||
{
|
||||
//! Writes appropriate metadata to the archive for this polymorphic type
|
||||
static void writeMetadata(Archive & ar)
|
||||
{
|
||||
// Register the polymorphic type name with the archive, and get the id
|
||||
char const * name = binding_name<T>::name();
|
||||
std::uint32_t id = ar.registerPolymorphicType(name);
|
||||
|
||||
// Serialize the id
|
||||
ar( CEREAL_NVP_("polymorphic_id", id) );
|
||||
|
||||
// If the msb of the id is 1, then the type name is new, and we should serialize it
|
||||
if( id & detail::msb_32bit )
|
||||
{
|
||||
std::string namestring(name);
|
||||
ar( CEREAL_NVP_("polymorphic_name", namestring) );
|
||||
}
|
||||
}
|
||||
|
||||
//! Holds a properly typed shared_ptr to the polymorphic type
|
||||
class PolymorphicSharedPointerWrapper
|
||||
{
|
||||
public:
|
||||
/*! Wrap a raw polymorphic pointer in a shared_ptr to its true type
|
||||
|
||||
The wrapped pointer will not be responsible for ownership of the held pointer
|
||||
so it will not attempt to destroy it; instead the refcount of the wrapped
|
||||
pointer will be tied to a fake 'ownership pointer' that will do nothing
|
||||
when it ultimately goes out of scope.
|
||||
|
||||
The main reason for doing this, other than not to destroy the true object
|
||||
with our wrapper pointer, is to avoid meddling with the internal reference
|
||||
count in a polymorphic type that inherits from std::enable_shared_from_this.
|
||||
|
||||
@param dptr A void pointer to the contents of the shared_ptr to serialize */
|
||||
PolymorphicSharedPointerWrapper( void const * dptr ) : refCount()
|
||||
{
|
||||
#ifdef _LIBCPP_VERSION
|
||||
// libc++ needs this hacky workaround, see http://llvm.org/bugs/show_bug.cgi?id=18843
|
||||
wrappedPtr = std::shared_ptr<T const>(
|
||||
std::const_pointer_cast<T const>(
|
||||
std::shared_ptr<T>( refCount, static_cast<T *>(const_cast<void *>(dptr) ))));
|
||||
#else // NOT _LIBCPP_VERSION
|
||||
wrappedPtr = std::shared_ptr<T const>( refCount, static_cast<T const *>(dptr) );
|
||||
#endif // _LIBCPP_VERSION
|
||||
}
|
||||
|
||||
//! Get the wrapped shared_ptr */
|
||||
inline std::shared_ptr<T const> const & operator()() const { return wrappedPtr; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<void> refCount; //!< The ownership pointer
|
||||
std::shared_ptr<T const> wrappedPtr; //!< The wrapped pointer
|
||||
};
|
||||
|
||||
//! Does the actual work of saving a polymorphic shared_ptr
|
||||
/*! This function will properly create a shared_ptr from the void * that is passed in
|
||||
before passing it to the archive for serialization.
|
||||
|
||||
In addition, this will also preserve the state of any internal enable_shared_from_this mechanisms
|
||||
|
||||
@param ar The archive to serialize to
|
||||
@param dptr Pointer to the actual data held by the shared_ptr */
|
||||
static inline void savePolymorphicSharedPtr( Archive & ar, void const * dptr, std::true_type /* has_shared_from_this */ )
|
||||
{
|
||||
::cereal::memory_detail::EnableSharedStateHelper<T> state( static_cast<T *>(const_cast<void *>(dptr)) );
|
||||
PolymorphicSharedPointerWrapper psptr( dptr );
|
||||
ar( CEREAL_NVP_("ptr_wrapper", memory_detail::make_ptr_wrapper( psptr() ) ) );
|
||||
}
|
||||
|
||||
//! Does the actual work of saving a polymorphic shared_ptr
|
||||
/*! This function will properly create a shared_ptr from the void * that is passed in
|
||||
before passing it to the archive for serialization.
|
||||
|
||||
This version is for types that do not inherit from std::enable_shared_from_this.
|
||||
|
||||
@param ar The archive to serialize to
|
||||
@param dptr Pointer to the actual data held by the shared_ptr */
|
||||
static inline void savePolymorphicSharedPtr( Archive & ar, void const * dptr, std::false_type /* has_shared_from_this */ )
|
||||
{
|
||||
PolymorphicSharedPointerWrapper psptr( dptr );
|
||||
ar( CEREAL_NVP_("ptr_wrapper", memory_detail::make_ptr_wrapper( psptr() ) ) );
|
||||
}
|
||||
|
||||
//! Initialize the binding
|
||||
OutputBindingCreator()
|
||||
{
|
||||
auto & map = StaticObject<OutputBindingMap<Archive>>::getInstance().map;
|
||||
auto key = std::type_index(typeid(T));
|
||||
auto lb = map.lower_bound(key);
|
||||
|
||||
if (lb != map.end() && lb->first == key)
|
||||
return;
|
||||
|
||||
typename OutputBindingMap<Archive>::Serializers serializers;
|
||||
|
||||
serializers.shared_ptr =
|
||||
[&](void * arptr, void const * dptr)
|
||||
{
|
||||
Archive & ar = *static_cast<Archive*>(arptr);
|
||||
|
||||
writeMetadata(ar);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
savePolymorphicSharedPtr( ar, dptr, ::cereal::traits::has_shared_from_this<T>::type() ); // MSVC doesn't like typename here
|
||||
#else // not _MSC_VER
|
||||
savePolymorphicSharedPtr( ar, dptr, typename ::cereal::traits::has_shared_from_this<T>::type() );
|
||||
#endif // _MSC_VER
|
||||
};
|
||||
|
||||
serializers.unique_ptr =
|
||||
[&](void * arptr, void const * dptr)
|
||||
{
|
||||
Archive & ar = *static_cast<Archive*>(arptr);
|
||||
|
||||
writeMetadata(ar);
|
||||
|
||||
std::unique_ptr<T const, EmptyDeleter<T const>> const ptr(static_cast<T const *>(dptr));
|
||||
|
||||
ar( CEREAL_NVP_("ptr_wrapper", memory_detail::make_ptr_wrapper(ptr)) );
|
||||
};
|
||||
|
||||
map.insert( { std::move(key), std::move(serializers) } );
|
||||
}
|
||||
};
|
||||
|
||||
//! Used to help out argument dependent lookup for finding potential overloads
|
||||
//! of instantiate_polymorphic_binding
|
||||
struct adl_tag {};
|
||||
|
||||
//! Tag for init_binding, bind_to_archives and instantiate_polymorphic_binding. Due to the use of anonymous
|
||||
//! namespace it becomes a different type in each translation unit.
|
||||
namespace { struct polymorphic_binding_tag {}; }
|
||||
|
||||
//! Causes the static object bindings between an archive type and a serializable type T
|
||||
template <class Archive, class T>
|
||||
struct create_bindings
|
||||
{
|
||||
static const InputBindingCreator<Archive, T> &
|
||||
load(std::true_type)
|
||||
{
|
||||
return cereal::detail::StaticObject<InputBindingCreator<Archive, T>>::getInstance();
|
||||
}
|
||||
|
||||
static const OutputBindingCreator<Archive, T> &
|
||||
save(std::true_type)
|
||||
{
|
||||
return cereal::detail::StaticObject<OutputBindingCreator<Archive, T>>::getInstance();
|
||||
}
|
||||
|
||||
inline static void load(std::false_type) {}
|
||||
inline static void save(std::false_type) {}
|
||||
};
|
||||
|
||||
//! When specialized, causes the compiler to instantiate its parameter
|
||||
template <void(*)()>
|
||||
struct instantiate_function {};
|
||||
|
||||
/*! This struct is used as the return type of instantiate_polymorphic_binding
|
||||
for specific Archive types. When the compiler looks for overloads of
|
||||
instantiate_polymorphic_binding, it will be forced to instantiate this
|
||||
struct during overload resolution, even though it will not be part of a valid
|
||||
overload */
|
||||
template <class Archive, class T>
|
||||
struct polymorphic_serialization_support
|
||||
{
|
||||
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
|
||||
//! Creates the appropriate bindings depending on whether the archive supports
|
||||
//! saving or loading
|
||||
virtual CEREAL_DLL_EXPORT void instantiate() CEREAL_USED;
|
||||
#else // NOT _MSC_VER
|
||||
//! Creates the appropriate bindings depending on whether the archive supports
|
||||
//! saving or loading
|
||||
static CEREAL_DLL_EXPORT void instantiate() CEREAL_USED;
|
||||
//! This typedef causes the compiler to instantiate this static function
|
||||
typedef instantiate_function<instantiate> unused;
|
||||
#endif // _MSC_VER
|
||||
};
|
||||
|
||||
// instantiate implementation
|
||||
template <class Archive, class T>
|
||||
CEREAL_DLL_EXPORT void polymorphic_serialization_support<Archive,T>::instantiate()
|
||||
{
|
||||
create_bindings<Archive,T>::save( std::integral_constant<bool,
|
||||
std::is_base_of<detail::OutputArchiveBase, Archive>::value &&
|
||||
traits::is_output_serializable<T, Archive>::value>{} );
|
||||
|
||||
create_bindings<Archive,T>::load( std::integral_constant<bool,
|
||||
std::is_base_of<detail::InputArchiveBase, Archive>::value &&
|
||||
traits::is_input_serializable<T, Archive>::value>{} );
|
||||
}
|
||||
|
||||
//! Begins the binding process of a type to all registered archives
|
||||
/*! Archives need to be registered prior to this struct being instantiated via
|
||||
the CEREAL_REGISTER_ARCHIVE macro. Overload resolution will then force
|
||||
several static objects to be made that allow us to bind together all
|
||||
registered archive types with the parameter type T. */
|
||||
template <class T, class Tag = polymorphic_binding_tag>
|
||||
struct bind_to_archives
|
||||
{
|
||||
//! Binding for non abstract types
|
||||
void bind(std::false_type) const
|
||||
{
|
||||
instantiate_polymorphic_binding((T*) 0, 0, Tag{}, adl_tag{});
|
||||
}
|
||||
|
||||
//! Binding for abstract types
|
||||
void bind(std::true_type) const
|
||||
{ }
|
||||
|
||||
//! Binds the type T to all registered archives
|
||||
/*! If T is abstract, we will not serialize it and thus
|
||||
do not need to make a binding */
|
||||
bind_to_archives const & bind() const
|
||||
{
|
||||
static_assert( std::is_polymorphic<T>::value,
|
||||
"Attempting to register non polymorphic type" );
|
||||
bind( std::is_abstract<T>() );
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
//! Used to hide the static object used to bind T to registered archives
|
||||
template <class T, class Tag = polymorphic_binding_tag>
|
||||
struct init_binding;
|
||||
|
||||
//! Base case overload for instantiation
|
||||
/*! This will end up always being the best overload due to the second
|
||||
parameter always being passed as an int. All other overloads will
|
||||
accept pointers to archive types and have lower precedence than int.
|
||||
|
||||
Since the compiler needs to check all possible overloads, the
|
||||
other overloads created via CEREAL_REGISTER_ARCHIVE, which will have
|
||||
lower precedence due to requring a conversion from int to (Archive*),
|
||||
will cause their return types to be instantiated through the static object
|
||||
mechanisms even though they are never called.
|
||||
|
||||
See the documentation for the other functions to try and understand this */
|
||||
template <class T, typename BindingTag>
|
||||
void instantiate_polymorphic_binding( T*, int, BindingTag, adl_tag ) {}
|
||||
} // namespace detail
|
||||
} // namespace cereal
|
||||
|
||||
#endif // CEREAL_DETAILS_POLYMORPHIC_IMPL_HPP_
|
90
3rdparty/include/cereal/details/static_object.hpp
vendored
Normal file
90
3rdparty/include/cereal/details/static_object.hpp
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
/*! \file static_object.hpp
|
||||
\brief Internal polymorphism static object support
|
||||
\ingroup Internal */
|
||||
/*
|
||||
Copyright (c) 2014, Randolph Voorhies, Shane Grant
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of cereal nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL RANDOLPH VOORHIES OR SHANE GRANT BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef CEREAL_DETAILS_STATIC_OBJECT_HPP_
|
||||
#define CEREAL_DETAILS_STATIC_OBJECT_HPP_
|
||||
|
||||
//! Prevent link optimization from removing non-referenced static objects
|
||||
/*! Especially for polymorphic support, we create static objects which
|
||||
may not ever be explicitly referenced. Most linkers will detect this
|
||||
and remove the code causing various unpleasant runtime errors. These
|
||||
macros, adopted from Boost (see force_include.hpp) prevent this
|
||||
(C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt) */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define CEREAL_DLL_EXPORT __declspec(dllexport)
|
||||
# define CEREAL_USED
|
||||
#else // clang or gcc
|
||||
# define CEREAL_DLL_EXPORT
|
||||
# define CEREAL_USED __attribute__ ((__used__))
|
||||
#endif
|
||||
|
||||
namespace cereal
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
//! A static, pre-execution object
|
||||
/*! This class will create a single copy (singleton) of some
|
||||
type and ensures that merely referencing this type will
|
||||
cause it to be instantiated and initialized pre-execution.
|
||||
For example, this is used heavily in the polymorphic pointer
|
||||
serialization mechanisms to bind various archive types with
|
||||
different polymorphic classes */
|
||||
template <class T>
|
||||
class CEREAL_DLL_EXPORT StaticObject
|
||||
{
|
||||
private:
|
||||
//! Forces instantiation at pre-execution time
|
||||
static void instantiate( T const & ) {}
|
||||
|
||||
static T & create()
|
||||
{
|
||||
static T t;
|
||||
instantiate(instance);
|
||||
return t;
|
||||
}
|
||||
|
||||
StaticObject( StaticObject const & /*other*/ ) {}
|
||||
|
||||
public:
|
||||
static T & getInstance()
|
||||
{
|
||||
return create();
|
||||
}
|
||||
|
||||
private:
|
||||
static T & instance;
|
||||
};
|
||||
|
||||
template <class T> T & StaticObject<T>::instance = StaticObject<T>::create();
|
||||
} // namespace detail
|
||||
} // namespace cereal
|
||||
|
||||
#endif // CEREAL_DETAILS_STATIC_OBJECT_HPP_
|
1325
3rdparty/include/cereal/details/traits.hpp
vendored
Normal file
1325
3rdparty/include/cereal/details/traits.hpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
84
3rdparty/include/cereal/details/util.hpp
vendored
Normal file
84
3rdparty/include/cereal/details/util.hpp
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
/*! \file util.hpp
|
||||
\brief Internal misc utilities
|
||||
\ingroup Internal */
|
||||
/*
|
||||
Copyright (c) 2014, Randolph Voorhies, Shane Grant
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of cereal nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL RANDOLPH VOORHIES OR SHANE GRANT BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef CEREAL_DETAILS_UTIL_HPP_
|
||||
#define CEREAL_DETAILS_UTIL_HPP_
|
||||
|
||||
#include <typeinfo>
|
||||
#include <string>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
namespace cereal
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
//! Demangles the type encoded in a string
|
||||
/*! @internal */
|
||||
inline std::string demangle( std::string const & name )
|
||||
{ return name; }
|
||||
|
||||
//! Gets the demangled name of a type
|
||||
/*! @internal */
|
||||
template <class T> inline
|
||||
std::string demangledName()
|
||||
{ return typeid( T ).name(); }
|
||||
} // namespace util
|
||||
} // namespace cereal
|
||||
#else // clang or gcc
|
||||
#include <cxxabi.h>
|
||||
#include <cstdlib>
|
||||
namespace cereal
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
//! Demangles the type encoded in a string
|
||||
/*! @internal */
|
||||
inline std::string demangle(std::string mangledName)
|
||||
{
|
||||
int status = 0;
|
||||
char *demangledName = nullptr;
|
||||
std::size_t len;
|
||||
|
||||
demangledName = abi::__cxa_demangle(mangledName.c_str(), 0, &len, &status);
|
||||
|
||||
std::string retName(demangledName);
|
||||
free(demangledName);
|
||||
|
||||
return retName;
|
||||
}
|
||||
|
||||
//! Gets the demangled name of a type
|
||||
/*! @internal */
|
||||
template<class T> inline
|
||||
std::string demangledName()
|
||||
{ return demangle(typeid(T).name()); }
|
||||
}
|
||||
} // namespace cereal
|
||||
#endif // clang or gcc branch of _MSC_VER
|
||||
#endif // CEREAL_DETAILS_UTIL_HPP_
|
Reference in New Issue
Block a user