mirror of
https://github.com/USCiLab/cereal.git
synced 2025-07-20 18:22:00 +02:00
Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a56bad8bbb | ||
![]() |
b4703c47ec | ||
![]() |
2c647d87d4 | ||
![]() |
f7deca361c | ||
![]() |
cb6c6ac1f0 | ||
![]() |
864c2fc370 | ||
![]() |
66d74f8cb9 | ||
![]() |
d1fcec807b | ||
![]() |
f3e31f32f7 | ||
![]() |
83b6fa06a0 | ||
![]() |
b2d68c522b | ||
![]() |
ddd4672447 | ||
![]() |
5b37553aa9 | ||
![]() |
343473b752 | ||
![]() |
45e40375b6 |
10
.github/workflows/ci-macos.yml
vendored
10
.github/workflows/ci-macos.yml
vendored
@ -10,18 +10,18 @@ jobs:
|
||||
include:
|
||||
- CMAKE_OPTIONS: '-DWITH_WERROR=OFF -DSKIP_PORTABILITY_TEST=ON -DSKIP_PERFORMANCE_COMPARISON=ON'
|
||||
COMPILER: 'clang++'
|
||||
XCODE_VERSION: 11
|
||||
NAME: macos-latest-clang-xcode11
|
||||
XCODE_VERSION: 15
|
||||
NAME: macos-latest-clang-xcode15
|
||||
|
||||
- CMAKE_OPTIONS: '-DWITH_WERROR=OFF -DSKIP_PORTABILITY_TEST=ON -DSKIP_PERFORMANCE_COMPARISON=ON'
|
||||
COMPILER: 'clang++'
|
||||
XCODE_VERSION: 12
|
||||
NAME: macos-latest-clang-xcode12
|
||||
XCODE_VERSION: 16
|
||||
NAME: macos-latest-clang-xcode16
|
||||
name: ${{ matrix.name }}
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- uses: maxim-lobanov/setup-xcode@v1
|
||||
with:
|
||||
|
135
.github/workflows/ci.yml
vendored
135
.github/workflows/ci.yml
vendored
@ -4,7 +4,6 @@ on: [push, pull_request]
|
||||
jobs:
|
||||
test_cereal_linux:
|
||||
runs-on: ubuntu-latest
|
||||
container: ${{ matrix.CONTAINER }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@ -164,75 +163,75 @@ jobs:
|
||||
name: ${{ matrix.name }}
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Check out the repo
|
||||
uses: actions/checkout@v4
|
||||
- name: install deps and test
|
||||
shell: bash
|
||||
env:
|
||||
CMAKE_OPTIONS: ${{ matrix.CMAKE_OPTIONS }}
|
||||
COMPILER: ${{ matrix.COMPILER }}
|
||||
EXTRA_APT_PACKAGES: ${{ matrix.EXTRA_APT_PACKAGES }}
|
||||
LLVM_APT_SOURCE: ${{ matrix.LLVM_APT_SOURCE }}
|
||||
run: |
|
||||
set -ex
|
||||
apt-get update -y
|
||||
DEBIAN_FRONTEND=noninteractive TZ=America/Los_Angeles apt-get install -y software-properties-common wget python3-pip make apt-transport-https
|
||||
uses: addnab/docker-run-action@v3
|
||||
with:
|
||||
image: ${{ matrix.CONTAINER }}
|
||||
options: -v ${{ github.workspace }}:/var/workspace
|
||||
shell: bash
|
||||
run: |
|
||||
set -ex
|
||||
apt-get update -y
|
||||
DEBIAN_FRONTEND=noninteractive TZ=America/Los_Angeles apt-get install -y software-properties-common wget python3-pip make apt-transport-https
|
||||
|
||||
# Add apt repositories for older Ubuntu
|
||||
. /etc/os-release
|
||||
if [[ "${VERSION_ID}" == "16.04" ]]; then
|
||||
add-apt-repository ppa:ubuntu-toolchain-r/test -y
|
||||
add-apt-repository ppa:mhier/libboost-latest -y
|
||||
fi
|
||||
|
||||
if [[ "${LLVM_APT_SOURCE}" != "" ]]; then
|
||||
wget -qO - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
|
||||
add-apt-repository "${LLVM_APT_SOURCE}"
|
||||
fi
|
||||
|
||||
apt-get update -y
|
||||
|
||||
# Install apt packages
|
||||
apt-get install libboost-serialization-dev libboost-dev ${EXTRA_APT_PACKAGES} -y
|
||||
pip3 install cmake
|
||||
|
||||
# Set compiler and env variables
|
||||
export CXX=${COMPILER}
|
||||
${CXX} --version
|
||||
DEPS_DIR="${PWD}/deps"
|
||||
mkdir -p "${DEPS_DIR}"
|
||||
pushd "${DEPS_DIR}"
|
||||
JOBS=2
|
||||
|
||||
# Install the right version of libc++
|
||||
LLVM_INSTALL=${DEPS_DIR}/llvm/install
|
||||
# if in linux and compiler clang and llvm not installed
|
||||
if [[ "${CXX}" == "clang"* && -n "$(ls -A ${LLVM_INSTALL})" ]]; then
|
||||
if [[ "${CXX}" == "clang++-3.6" ]]; then LLVM_VERSION="3.6.2";
|
||||
elif [[ "${CXX}" == "clang++-3.7" ]]; then LLVM_VERSION="3.7.1";
|
||||
elif [[ "${CXX}" == "clang++-3.8" ]]; then LLVM_VERSION="3.8.1";
|
||||
elif [[ "${CXX}" == "clang++-3.9" ]]; then LLVM_VERSION="3.9.1";
|
||||
# Add apt repositories for older Ubuntu
|
||||
. /etc/os-release
|
||||
if [[ "${VERSION_ID}" == "16.04" ]]; then
|
||||
add-apt-repository ppa:ubuntu-toolchain-r/test -y
|
||||
add-apt-repository ppa:mhier/libboost-latest -y
|
||||
fi
|
||||
LLVM_URL="http://llvm.org/releases/${LLVM_VERSION}/llvm-${LLVM_VERSION}.src.tar.xz"
|
||||
LIBCXX_URL="http://llvm.org/releases/${LLVM_VERSION}/libcxx-${LLVM_VERSION}.src.tar.xz"
|
||||
LIBCXXABI_URL="http://llvm.org/releases/${LLVM_VERSION}/libcxxabi-${LLVM_VERSION}.src.tar.xz"
|
||||
mkdir -p llvm llvm/build llvm/projects/libcxx llvm/projects/libcxxabi
|
||||
wget -O - ${LLVM_URL} | tar --strip-components=1 -xJ -C llvm
|
||||
wget -O - ${LIBCXX_URL} | tar --strip-components=1 -xJ -C llvm/projects/libcxx
|
||||
wget -O - ${LIBCXXABI_URL} | tar --strip-components=1 -xJ -C llvm/projects/libcxxabi
|
||||
(cd llvm/build && cmake .. -DCMAKE_INSTALL_PREFIX=${LLVM_INSTALL})
|
||||
(cd llvm/build/projects/libcxx && make install -j2)
|
||||
(cd llvm/build/projects/libcxxabi && make install -j2)
|
||||
export CXXFLAGS="-isystem ${LLVM_INSTALL}/include/c++/v1"
|
||||
export LDFLAGS="-L ${LLVM_INSTALL}/lib -l c++ -l c++abi"
|
||||
export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${LLVM_INSTALL}/lib"
|
||||
fi
|
||||
|
||||
popd
|
||||
if [[ "${{ matrix.LLVM_APT_SOURCE }}" != "" ]]; then
|
||||
wget -qO - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
|
||||
add-apt-repository "${{ matrix.LLVM_APT_SOURCE }}"
|
||||
fi
|
||||
|
||||
# Build cereal and test
|
||||
cmake --version
|
||||
mkdir build && cd build
|
||||
cmake ${CMAKE_OPTIONS} .. && make -j4 VERBOSE=1
|
||||
ctest . --output-on-failure
|
||||
apt-get update -y
|
||||
|
||||
# Install apt packages
|
||||
apt-get install libboost-serialization-dev libboost-dev ${{ matrix.EXTRA_APT_PACKAGES }} -y
|
||||
pip3 install --upgrade "pip < 21.0"
|
||||
pip3 install cmake
|
||||
|
||||
# Set compiler and env variables
|
||||
cd /var/workspace
|
||||
export CXX=${{ matrix.COMPILER }}
|
||||
${CXX} --version
|
||||
DEPS_DIR="${PWD}/deps"
|
||||
mkdir -p "${DEPS_DIR}"
|
||||
pushd "${DEPS_DIR}"
|
||||
JOBS=2
|
||||
|
||||
# Install the right version of libc++
|
||||
LLVM_INSTALL=${DEPS_DIR}/llvm/install
|
||||
# if in linux and compiler clang and llvm not installed
|
||||
if [[ "${CXX}" == "clang"* && -n "$(ls -A ${LLVM_INSTALL})" ]]; then
|
||||
if [[ "${CXX}" == "clang++-3.6" ]]; then LLVM_VERSION="3.6.2";
|
||||
elif [[ "${CXX}" == "clang++-3.7" ]]; then LLVM_VERSION="3.7.1";
|
||||
elif [[ "${CXX}" == "clang++-3.8" ]]; then LLVM_VERSION="3.8.1";
|
||||
elif [[ "${CXX}" == "clang++-3.9" ]]; then LLVM_VERSION="3.9.1";
|
||||
fi
|
||||
LLVM_URL="http://llvm.org/releases/${LLVM_VERSION}/llvm-${LLVM_VERSION}.src.tar.xz"
|
||||
LIBCXX_URL="http://llvm.org/releases/${LLVM_VERSION}/libcxx-${LLVM_VERSION}.src.tar.xz"
|
||||
LIBCXXABI_URL="http://llvm.org/releases/${LLVM_VERSION}/libcxxabi-${LLVM_VERSION}.src.tar.xz"
|
||||
mkdir -p llvm llvm/build llvm/projects/libcxx llvm/projects/libcxxabi
|
||||
wget -O - ${LLVM_URL} | tar --strip-components=1 -xJ -C llvm
|
||||
wget -O - ${LIBCXX_URL} | tar --strip-components=1 -xJ -C llvm/projects/libcxx
|
||||
wget -O - ${LIBCXXABI_URL} | tar --strip-components=1 -xJ -C llvm/projects/libcxxabi
|
||||
(cd llvm/build && cmake .. -DCMAKE_INSTALL_PREFIX=${LLVM_INSTALL})
|
||||
(cd llvm/build/projects/libcxx && make install -j2)
|
||||
(cd llvm/build/projects/libcxxabi && make install -j2)
|
||||
export CXXFLAGS="-isystem ${LLVM_INSTALL}/include/c++/v1"
|
||||
export LDFLAGS="-L ${LLVM_INSTALL}/lib -l c++ -l c++abi"
|
||||
export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${LLVM_INSTALL}/lib"
|
||||
fi
|
||||
|
||||
popd
|
||||
|
||||
# Build cereal and test
|
||||
cmake --version
|
||||
mkdir build && cd build
|
||||
cmake ${{ matrix.CMAKE_OPTIONS }} .. && make -j4 VERBOSE=1
|
||||
ctest . --output-on-failure
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -28,6 +28,8 @@
|
||||
*.pdb
|
||||
*.idb
|
||||
*\build_*
|
||||
.vs/
|
||||
CMakeSettings.json
|
||||
|
||||
# misc files mostly used for testing
|
||||
out.txt
|
||||
|
@ -6,9 +6,13 @@ if(PROJECT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||
set(CEREAL_MASTER_PROJECT ON)
|
||||
endif()
|
||||
|
||||
|
||||
if(APPLE)
|
||||
option(SKIP_PORTABILITY_TEST "Skip portability (32 bit) tests" ON)
|
||||
option(SKIP_PORTABILITY_TEST "Skip portability (32 bit) tests" OFF)
|
||||
include(CheckCXXCompilerFlag)
|
||||
set(CMAKE_REQUIRED_FLAGS "-m32")
|
||||
check_cxx_compiler_flag("-m32" COMPILER_SUPPORT_M32)
|
||||
unset(CMAKE_REQUIRED_FLAGS)
|
||||
if(NOT COMPILER_SUPPORT_M32)
|
||||
set(SKIP_PORTABILITY_TEST ON CACHE BOOL "Skip portability (32 bit) tests" FORCE)
|
||||
endif()
|
||||
|
||||
option(BUILD_DOC "Build documentation" ON)
|
||||
@ -87,9 +91,15 @@ if(CEREAL_INSTALL)
|
||||
${configFile}
|
||||
INSTALL_DESTINATION ${configInstallDestination}
|
||||
)
|
||||
write_basic_package_version_file(
|
||||
${versionFile}
|
||||
COMPATIBILITY SameMajorVersion
|
||||
if(${CMAKE_VERSION} VERSION_GREATER 3.13)
|
||||
write_basic_package_version_file("${versionFile}" COMPATIBILITY SameMajorVersion ARCH_INDEPENDENT)
|
||||
else()
|
||||
write_basic_package_version_file("${versionFile}" COMPATIBILITY SameMajorVersion)
|
||||
endif()
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc
|
||||
@ONLY
|
||||
)
|
||||
|
||||
install(FILES ${configFile} ${versionFile} DESTINATION ${configInstallDestination})
|
||||
@ -98,6 +108,10 @@ if(CEREAL_INSTALL)
|
||||
NAMESPACE "cereal::"
|
||||
DESTINATION ${configInstallDestination}
|
||||
)
|
||||
install(
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
|
8
cereal.pc.in
Normal file
8
cereal.pc.in
Normal file
@ -0,0 +1,8 @@
|
||||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
|
||||
|
||||
Name: @PROJECT_NAME@
|
||||
Description: cereal is a header-only C++11 serialization library
|
||||
URL: https://uscilab.github.io/cereal/
|
||||
Version: @PROJECT_VERSION@
|
||||
Cflags: -I"${includedir}"
|
@ -188,7 +188,7 @@ namespace cereal
|
||||
|
||||
auto base64string = base64::encode( reinterpret_cast<const unsigned char *>( data ), size );
|
||||
saveValue( base64string );
|
||||
};
|
||||
}
|
||||
|
||||
//! @}
|
||||
/*! @name Internal Functionality
|
||||
@ -261,6 +261,13 @@ namespace cereal
|
||||
//! Saves a nullptr to the current node
|
||||
void saveValue(std::nullptr_t) { itsWriter.Null(); }
|
||||
|
||||
template <class T> inline
|
||||
typename std::enable_if<!std::is_same<T, int64_t>::value && std::is_same<T, long long>::value, void>::type
|
||||
saveValue(T val) { itsWriter.Int64(val); }
|
||||
template <class T> inline
|
||||
typename std::enable_if<!std::is_same<T, uint64_t>::value && std::is_same<T, unsigned long long>::value, void>::type
|
||||
saveValue(T val) { itsWriter.Uint64(val); }
|
||||
|
||||
private:
|
||||
// Some compilers/OS have difficulty disambiguating the above for various flavors of longs, so we provide
|
||||
// special overloads to handle these cases.
|
||||
@ -310,6 +317,8 @@ namespace cereal
|
||||
!std::is_same<T, unsigned long>::value,
|
||||
!std::is_same<T, std::int64_t>::value,
|
||||
!std::is_same<T, std::uint64_t>::value,
|
||||
!std::is_same<T, long long>::value,
|
||||
!std::is_same<T, unsigned long long>::value,
|
||||
(sizeof(T) >= sizeof(long double) || sizeof(T) >= sizeof(long long))> = traits::sfinae> inline
|
||||
void saveValue(T const & t)
|
||||
{
|
||||
@ -465,7 +474,7 @@ namespace cereal
|
||||
|
||||
std::memcpy( data, decoded.data(), decoded.size() );
|
||||
itsNextName = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
private:
|
||||
//! @}
|
||||
@ -659,6 +668,12 @@ namespace cereal
|
||||
//! Loads a nullptr from the current node
|
||||
void loadValue(std::nullptr_t&) { search(); CEREAL_RAPIDJSON_ASSERT(itsIteratorStack.back().value().IsNull()); ++itsIteratorStack.back(); }
|
||||
|
||||
template <class T> inline
|
||||
typename std::enable_if<!std::is_same<T, int64_t>::value && std::is_same<T, long long>::value, void>::type
|
||||
loadValue(T & val) { search(); val = itsIteratorStack.back().value().GetInt64(); ++itsIteratorStack.back(); }
|
||||
template <class T> inline
|
||||
typename std::enable_if<!std::is_same<T, uint64_t>::value && std::is_same<T, unsigned long long>::value, void>::type
|
||||
loadValue(T & val) { search(); val = itsIteratorStack.back().value().GetUint64(); ++itsIteratorStack.back(); }
|
||||
// Special cases to handle various flavors of long, which tend to conflict with
|
||||
// the int32_t or int64_t on various compiler/OS combinations. MSVC doesn't need any of this.
|
||||
#ifndef _MSC_VER
|
||||
@ -714,6 +729,8 @@ namespace cereal
|
||||
!std::is_same<T, unsigned long>::value,
|
||||
!std::is_same<T, std::int64_t>::value,
|
||||
!std::is_same<T, std::uint64_t>::value,
|
||||
!std::is_same<T, long long>::value,
|
||||
!std::is_same<T, unsigned long long>::value,
|
||||
(sizeof(T) >= sizeof(long double) || sizeof(T) >= sizeof(long long))> = traits::sfinae>
|
||||
inline void loadValue(T & val)
|
||||
{
|
||||
|
@ -136,7 +136,7 @@ namespace cereal
|
||||
*/
|
||||
//! @{
|
||||
|
||||
//! Sets the precision used for floaing point numbers
|
||||
//! Sets the precision used for floating point numbers
|
||||
Options & precision( int value ){ itsPrecision = value; return * this; }
|
||||
//! Whether to indent each line of XML
|
||||
Options & indent( bool enable ){ itsIndent = enable; return *this; }
|
||||
|
@ -176,7 +176,7 @@ namespace cereal
|
||||
a serialization function. Classes with no data members are considered to be
|
||||
empty. Be warned that if this is enabled and you attempt to serialize an
|
||||
empty class with improperly formed serialize or load/save functions, no
|
||||
static error will occur - the error will propogate silently and your
|
||||
static error will occur - the error will propagate silently and your
|
||||
intended serialization functions may not be called. You can manually
|
||||
ensure that your classes that have custom serialization are correct
|
||||
by using the traits is_output_serializable and is_input_serializable
|
||||
@ -391,7 +391,7 @@ namespace cereal
|
||||
point to the same data.
|
||||
|
||||
@internal
|
||||
@param sharedPointer The shared pointer itself (the adress is taked via get()).
|
||||
@param sharedPointer The shared pointer itself (the address is taken via get()).
|
||||
The archive takes a copy to prevent the memory location to be freed
|
||||
as long as the address is used as id. This is needed to prevent CVE-2020-11105.
|
||||
@return A key that uniquely identifies the pointer */
|
||||
@ -820,7 +820,7 @@ namespace cereal
|
||||
|
||||
@internal
|
||||
@param id The unique id that was serialized for the polymorphic type
|
||||
@return The string identifier for the tyep */
|
||||
@return The string identifier for the type */
|
||||
inline std::string getPolymorphicName(std::uint32_t const id)
|
||||
{
|
||||
auto name = itsPolymorphicTypeMap.find( id );
|
||||
@ -837,7 +837,7 @@ namespace cereal
|
||||
|
||||
@internal
|
||||
@param id The unique identifier for the polymorphic type
|
||||
@param name The name associated with the tyep */
|
||||
@param name The name associated with the type */
|
||||
inline void registerPolymorphicName(std::uint32_t const id, std::string const & name)
|
||||
{
|
||||
std::uint32_t const stripped_id = id & ~detail::msb_32bit;
|
||||
|
@ -64,7 +64,7 @@
|
||||
#define CEREAL_BIND_TO_ARCHIVES_UNUSED_FUNCTION static void unused() { (void)b; }
|
||||
#endif
|
||||
|
||||
//! Binds a polymorhic type to all registered archives
|
||||
//! Binds a polymorphic 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
|
||||
@ -277,8 +277,8 @@ namespace cereal
|
||||
|
||||
// Find all chainable unregistered relations
|
||||
/* The strategy here is to process only the nodes in the class hierarchy graph that have been
|
||||
affected by the new insertion. The aglorithm iteratively processes a node an ensures that it
|
||||
is updated with all new shortest length paths. It then rocesses the parents of the active node,
|
||||
affected by the new insertion. The algorithm iteratively processes a node an ensures that it
|
||||
is updated with all new shortest length paths. It then processes the parents of the active node,
|
||||
with the knowledge that all children have already been processed.
|
||||
|
||||
Note that for the following, we'll use the nomenclature of parent and child to not confuse with
|
||||
@ -335,7 +335,7 @@ namespace cereal
|
||||
auto parentChildPath = checkRelation( parent, child );
|
||||
|
||||
// Search all paths from the child to its own children (finalChild),
|
||||
// looking for a shorter parth from parent to finalChild
|
||||
// looking for a shorter path from parent to finalChild
|
||||
for( auto const & finalChildPair : baseMap[child] )
|
||||
{
|
||||
const auto finalChild = finalChildPair.first;
|
||||
@ -812,7 +812,7 @@ namespace cereal
|
||||
|
||||
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*),
|
||||
lower precedence due to requiring 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.
|
||||
|
||||
|
@ -141,7 +141,7 @@
|
||||
#endif
|
||||
|
||||
//! Checks if C++14 is available
|
||||
#if __cplusplus >= 201402L
|
||||
#if (__cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L))
|
||||
#define CEREAL_HAS_CPP14
|
||||
#endif
|
||||
|
||||
|
@ -42,7 +42,7 @@ namespace cereal
|
||||
&& std::is_arithmetic<T>::value, void>::type
|
||||
CEREAL_SAVE_FUNCTION_NAME( Archive & ar, std::array<T, N> const & array )
|
||||
{
|
||||
ar( binary_data( array.data(), sizeof(array) ) );
|
||||
ar( binary_data( array.data(), N*sizeof(T) ) );
|
||||
}
|
||||
|
||||
//! Loading for std::array primitive types
|
||||
@ -52,7 +52,7 @@ namespace cereal
|
||||
&& std::is_arithmetic<T>::value, void>::type
|
||||
CEREAL_LOAD_FUNCTION_NAME( Archive & ar, std::array<T, N> & array )
|
||||
{
|
||||
ar( binary_data( array.data(), sizeof(array) ) );
|
||||
ar( binary_data( array.data(), N*sizeof(T) ) );
|
||||
}
|
||||
|
||||
//! Saving for std::array all other types
|
||||
|
@ -286,7 +286,7 @@ namespace cereal
|
||||
{
|
||||
// Storage type for the pointer - since we can't default construct this type,
|
||||
// we'll allocate it using std::aligned_storage and use a custom deleter
|
||||
using ST = typename std::aligned_storage<sizeof(T), CEREAL_ALIGNOF(T)>::type;
|
||||
using AlignedStorage = typename std::aligned_storage<sizeof(T), CEREAL_ALIGNOF(T)>::type;
|
||||
|
||||
// Valid flag - set to true once construction finishes
|
||||
// This prevents us from calling the destructor on
|
||||
@ -296,13 +296,13 @@ namespace cereal
|
||||
// Allocate our storage, which we will treat as
|
||||
// uninitialized until initialized with placement new
|
||||
using NonConstT = typename std::remove_const<T>::type;
|
||||
std::shared_ptr<NonConstT> ptr(reinterpret_cast<NonConstT *>(new ST()),
|
||||
std::shared_ptr<NonConstT> ptr(reinterpret_cast<NonConstT *>(new AlignedStorage()),
|
||||
[=]( NonConstT * t )
|
||||
{
|
||||
if( *valid )
|
||||
t->~T();
|
||||
|
||||
delete reinterpret_cast<ST *>( t );
|
||||
delete reinterpret_cast<AlignedStorage*>( t );
|
||||
} );
|
||||
|
||||
// Register the pointer
|
||||
@ -377,11 +377,11 @@ namespace cereal
|
||||
using NonConstT = typename std::remove_const<T>::type;
|
||||
// Storage type for the pointer - since we can't default construct this type,
|
||||
// we'll allocate it using std::aligned_storage
|
||||
using ST = typename std::aligned_storage<sizeof(NonConstT), CEREAL_ALIGNOF(NonConstT)>::type;
|
||||
using AlignedStorage = typename std::aligned_storage<sizeof(NonConstT), CEREAL_ALIGNOF(NonConstT)>::type;
|
||||
|
||||
// Allocate storage - note the ST type so that deleter is correct if
|
||||
// Allocate storage - note the AlignedStorage type so that deleter is correct if
|
||||
// an exception is thrown before we are initialized
|
||||
std::unique_ptr<ST> stPtr( new ST() );
|
||||
std::unique_ptr<AlignedStorage> stPtr( new AlignedStorage() );
|
||||
|
||||
// Use wrapper to enter into "data" nvp of ptr_wrapper
|
||||
memory_detail::LoadAndConstructLoadWrapper<Archive, NonConstT> loadWrapper( reinterpret_cast<NonConstT *>( stPtr.get() ) );
|
||||
|
@ -258,7 +258,7 @@ random_value(std::mt19937 & gen)
|
||||
{
|
||||
std::string s(std::uniform_int_distribution<int>(3, 30)(gen), ' ');
|
||||
for(char & c : s)
|
||||
c = std::uniform_int_distribution<char>(' ', '~')(gen);
|
||||
c = static_cast<char>( std::uniform_int_distribution<int>(' ', '~')(gen) );
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -277,7 +277,7 @@ std::string random_binary_string(std::mt19937 & gen)
|
||||
{
|
||||
std::string s(N, ' ');
|
||||
for(auto & c : s )
|
||||
c = std::uniform_int_distribution<char>('0', '1')(gen);
|
||||
c = static_cast<char>( std::uniform_int_distribution<int>( '0', '1' )(gen) );
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -714,7 +714,7 @@ int main()
|
||||
std::ifstream ss("xml_ordering.out");
|
||||
cereal::XMLInputArchive ar(ss);
|
||||
|
||||
// Output prodered out of order, try to load in order 1 2 3 4
|
||||
// Output out of order, try to load in order 1 2 3 4
|
||||
double one;
|
||||
double two;
|
||||
double three;
|
||||
|
@ -77,7 +77,7 @@ CEREAL_SETUP_ARCHIVE_TRAITS(Archive, Archive)
|
||||
struct Test
|
||||
{
|
||||
template <class Archive>
|
||||
void serialzize( Archive & )
|
||||
void serialize( Archive & )
|
||||
{
|
||||
std::cout << "hey there" << std::endl;
|
||||
}
|
||||
|
@ -31,22 +31,26 @@ TEST_SUITE_BEGIN("array");
|
||||
|
||||
TEST_CASE("binary_array")
|
||||
{
|
||||
test_array<cereal::BinaryInputArchive, cereal::BinaryOutputArchive>();
|
||||
test_array<cereal::BinaryInputArchive, cereal::BinaryOutputArchive, 0>();
|
||||
test_array<cereal::BinaryInputArchive, cereal::BinaryOutputArchive, 100>();
|
||||
}
|
||||
|
||||
TEST_CASE("portable_binary_array")
|
||||
{
|
||||
test_array<cereal::PortableBinaryInputArchive, cereal::PortableBinaryOutputArchive>();
|
||||
test_array<cereal::PortableBinaryInputArchive, cereal::PortableBinaryOutputArchive, 0>();
|
||||
test_array<cereal::PortableBinaryInputArchive, cereal::PortableBinaryOutputArchive, 100>();
|
||||
}
|
||||
|
||||
TEST_CASE("xml_array")
|
||||
{
|
||||
test_array<cereal::XMLInputArchive, cereal::XMLOutputArchive>();
|
||||
test_array<cereal::XMLInputArchive, cereal::XMLOutputArchive, 0>();
|
||||
test_array<cereal::XMLInputArchive, cereal::XMLOutputArchive, 100>();
|
||||
}
|
||||
|
||||
TEST_CASE("json_array")
|
||||
{
|
||||
test_array<cereal::JSONInputArchive, cereal::JSONOutputArchive>();
|
||||
test_array<cereal::JSONInputArchive, cereal::JSONOutputArchive, 0>();
|
||||
test_array<cereal::JSONInputArchive, cereal::JSONOutputArchive, 100>();
|
||||
}
|
||||
|
||||
TEST_SUITE_END();
|
||||
|
@ -28,7 +28,7 @@
|
||||
#define CEREAL_TEST_ARRAY_H_
|
||||
#include "common.hpp"
|
||||
|
||||
template <class IArchive, class OArchive> inline
|
||||
template <class IArchive, class OArchive, size_t N> inline
|
||||
void test_array()
|
||||
{
|
||||
std::random_device rd;
|
||||
@ -36,23 +36,23 @@ void test_array()
|
||||
|
||||
for(int ii=0; ii<100; ++ii)
|
||||
{
|
||||
std::array<int, 100> o_podarray;
|
||||
std::array<int, N> o_podarray;
|
||||
for(auto & elem : o_podarray)
|
||||
elem = random_value<int>(gen);
|
||||
|
||||
std::array<StructInternalSerialize, 100> o_iserarray;
|
||||
std::array<StructInternalSerialize, N> o_iserarray;
|
||||
for(auto & elem : o_iserarray)
|
||||
elem = StructInternalSerialize( random_value<int>(gen), random_value<int>(gen) );
|
||||
|
||||
std::array<StructInternalSplit, 100> o_isplarray;
|
||||
std::array<StructInternalSplit, N> o_isplarray;
|
||||
for(auto & elem : o_isplarray)
|
||||
elem = StructInternalSplit( random_value<int>(gen), random_value<int>(gen) );
|
||||
|
||||
std::array<StructExternalSerialize, 100> o_eserarray;
|
||||
std::array<StructExternalSerialize, N> o_eserarray;
|
||||
for(auto & elem : o_eserarray)
|
||||
elem = StructExternalSerialize( random_value<int>(gen), random_value<int>(gen) );
|
||||
|
||||
std::array<StructExternalSplit, 100> o_esplarray;
|
||||
std::array<StructExternalSplit, N> o_esplarray;
|
||||
for(auto & elem : o_esplarray)
|
||||
elem = StructExternalSplit( random_value<int>(gen), random_value<int>(gen) );
|
||||
|
||||
@ -67,11 +67,11 @@ void test_array()
|
||||
oar(o_esplarray);
|
||||
}
|
||||
|
||||
std::array<int, 100> i_podarray;
|
||||
std::array<StructInternalSerialize, 100> i_iserarray;
|
||||
std::array<StructInternalSplit, 100> i_isplarray;
|
||||
std::array<StructExternalSerialize, 100> i_eserarray;
|
||||
std::array<StructExternalSplit, 100> i_esplarray;
|
||||
std::array<int, N> i_podarray;
|
||||
std::array<StructInternalSerialize, N> i_iserarray;
|
||||
std::array<StructInternalSplit, N> i_isplarray;
|
||||
std::array<StructExternalSerialize, N> i_eserarray;
|
||||
std::array<StructExternalSplit, N> i_esplarray;
|
||||
|
||||
std::istringstream is(os.str());
|
||||
{
|
||||
|
@ -62,7 +62,7 @@ void test_map()
|
||||
|
||||
std::map<int8_t, StructExternalSplit> o_esplmap;
|
||||
for(int j=0; j<100; ++j)
|
||||
o_esplmap.insert({random_value<char>(gen), { random_value<int>(gen), random_value<int>(gen) }});
|
||||
o_esplmap.insert({random_value<int8_t>(gen), { random_value<int>(gen), random_value<int>(gen) }});
|
||||
|
||||
std::ostringstream os;
|
||||
{
|
||||
|
@ -71,7 +71,7 @@ void test_multimap()
|
||||
std::multimap<int8_t, StructExternalSplit> o_esplmultimap;
|
||||
for(int j=0; j<100; ++j)
|
||||
{
|
||||
auto key = random_value<char>(gen);
|
||||
auto key = random_value<int8_t>(gen);
|
||||
o_esplmultimap.insert({key, { random_value<int>(gen), random_value<int>(gen) }});
|
||||
o_esplmultimap.insert({key, { random_value<int>(gen), random_value<int>(gen) }});
|
||||
}
|
||||
|
@ -49,4 +49,14 @@ TEST_CASE("json_pod")
|
||||
test_pod<cereal::JSONInputArchive, cereal::JSONOutputArchive>();
|
||||
}
|
||||
|
||||
TEST_CASE("xml_pod_serialization")
|
||||
{
|
||||
test_pod_serialization<cereal::XMLInputArchive, cereal::XMLOutputArchive>();
|
||||
}
|
||||
|
||||
TEST_CASE("json_pod_serialization")
|
||||
{
|
||||
test_pod_serialization<cereal::JSONInputArchive, cereal::JSONOutputArchive>();
|
||||
}
|
||||
|
||||
TEST_SUITE_END();
|
||||
|
@ -144,4 +144,72 @@ void test_pod()
|
||||
}
|
||||
}
|
||||
|
||||
template <class IArchive, class OArchive, class T1, class T2>
|
||||
void test_pod_serialization(std::mt19937& gen)
|
||||
{
|
||||
T1 const o_t1 = random_value<T1>(gen);
|
||||
T2 const o_t2 = o_t1;
|
||||
|
||||
std::ostringstream os1;
|
||||
{
|
||||
OArchive oar(os1);
|
||||
oar(o_t1);
|
||||
}
|
||||
|
||||
std::ostringstream os2;
|
||||
{
|
||||
OArchive oar(os2);
|
||||
oar(o_t2);
|
||||
}
|
||||
|
||||
CHECK_EQ(os1.str(), os2.str());
|
||||
|
||||
T1 i_t1 = T1();
|
||||
T2 i_t2 = T2();
|
||||
CHECK_EQ(os1.str(), os2.str());
|
||||
std::istringstream is1(os1.str());
|
||||
{
|
||||
IArchive iar(is1);
|
||||
iar(i_t1);
|
||||
}
|
||||
CHECK_EQ(o_t1, i_t1);
|
||||
|
||||
std::istringstream is2(os2.str());
|
||||
{
|
||||
IArchive iar(is2);
|
||||
iar(i_t2);
|
||||
}
|
||||
CHECK_EQ(o_t2, i_t2);
|
||||
}
|
||||
|
||||
template <class IArchive, class OArchive>
|
||||
void test_pod_serialization()
|
||||
{
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
for (size_t i = 0; i < 100; ++i) {
|
||||
test_pod_serialization<IArchive, OArchive, int8_t, int16_t>(gen);
|
||||
test_pod_serialization<IArchive, OArchive, uint8_t, uint16_t>(gen);
|
||||
|
||||
test_pod_serialization<IArchive, OArchive, int8_t, int32_t>(gen);
|
||||
test_pod_serialization<IArchive, OArchive, uint8_t, uint32_t>(gen);
|
||||
|
||||
test_pod_serialization<IArchive, OArchive, int8_t, int64_t>(gen);
|
||||
test_pod_serialization<IArchive, OArchive, uint8_t, uint64_t>(gen);
|
||||
|
||||
test_pod_serialization<IArchive, OArchive, int8_t, long>(gen);
|
||||
test_pod_serialization<IArchive, OArchive, uint8_t, unsigned long>(gen);
|
||||
|
||||
test_pod_serialization<IArchive, OArchive, int8_t, long long>(gen);
|
||||
test_pod_serialization<IArchive, OArchive, uint8_t, unsigned long long>(
|
||||
gen);
|
||||
|
||||
test_pod_serialization<IArchive, OArchive, int8_t, int>(gen);
|
||||
test_pod_serialization<IArchive, OArchive, uint8_t, unsigned int>(gen);
|
||||
|
||||
test_pod_serialization<IArchive, OArchive, int8_t, short>(gen);
|
||||
test_pod_serialization<IArchive, OArchive, uint8_t, unsigned short>(gen);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CEREAL_TEST_POD_H_
|
||||
|
@ -54,7 +54,7 @@ void test_unordered_map()
|
||||
|
||||
std::unordered_map<int8_t, StructExternalSplit> o_esplunordered_map;
|
||||
for(int j=0; j<100; ++j)
|
||||
o_esplunordered_map.insert({random_value<char>(gen), { random_value<int>(gen), random_value<int>(gen) }});
|
||||
o_esplunordered_map.insert({random_value<int8_t>(gen), { random_value<int>(gen), random_value<int>(gen) }});
|
||||
|
||||
std::ostringstream os;
|
||||
{
|
||||
|
@ -71,7 +71,7 @@ void test_unordered_multimap()
|
||||
std::unordered_multimap<int8_t, StructExternalSplit> o_esplunordered_multimap;
|
||||
for(int j=0; j<100; ++j)
|
||||
{
|
||||
auto key = random_value<char>(gen);
|
||||
auto key = random_value<int8_t>(gen);
|
||||
o_esplunordered_multimap.insert({key, { random_value<int>(gen), random_value<int>(gen) }});
|
||||
o_esplunordered_multimap.insert({key, { random_value<int>(gen), random_value<int>(gen) }});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user