Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add serialization for std::set (as there is for std::vector and std::map) #1658

Merged
merged 8 commits into from Jul 16, 2015
41 changes: 41 additions & 0 deletions hpx/runtime/serialization/set.hpp
@@ -0,0 +1,41 @@
// Copyright (c) 2015 Andreas Schaefer
//
// Distributed under 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)

#ifndef HPX_SERIALIZATION_SET_HPP
#define HPX_SERIALIZATION_SET_HPP

#include <hpx/runtime/serialization/serialize.hpp>

#include <set>

namespace hpx { namespace serialization
{
template <class T, class Compare, class Allocator>
void serialize(input_archive & ar, std::set<T, Compare, Allocator> & set, unsigned)
{
set.clear();
boost::uint64_t size;
ar >> size;
for (std::size_t i = 0; i < size; ++i) {
T t;
ar >> t;
set.insert(set.end(), std::move(t));
}
}

template <class T, class Compare, class Allocator>
void serialize(output_archive & ar, std::set<T, Compare, Allocator> & set, unsigned)
{
boost::uint64_t size = set.size();
ar << size;
if(set.empty()) return;
for (T const& i: set) {
ar << i;
}
}

}}

#endif
1 change: 0 additions & 1 deletion hpx/runtime/serialization/vector.hpp
Expand Up @@ -129,7 +129,6 @@ namespace hpx { namespace serialization
template <typename T, typename Allocator>
void serialize(output_archive & ar, std::vector<T, Allocator> & v, unsigned)
{
typedef typename std::vector<T>::size_type size_type;
ar << v.size(); //-V128
if(v.empty()) return;
save_impl(
Expand Down
1 change: 1 addition & 0 deletions tests/unit/serialization/CMakeLists.txt
Expand Up @@ -8,6 +8,7 @@ set(tests
serialization_builtins
serialization_complex
serialization_map
serialization_set
serialization_simple
serialization_smart_ptr
serialization_vector
Expand Down
184 changes: 184 additions & 0 deletions tests/unit/serialization/serialization_set.cpp
@@ -0,0 +1,184 @@
// Copyright (c) 2014 Thomas Heller
// Copyright (c) 2015 Andreas Schaefer
//
// Distributed under 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)

#include <hpx/runtime/serialization/serialize.hpp>
#include <hpx/runtime/serialization/set.hpp>

#include <hpx/runtime/serialization/input_archive.hpp>
#include <hpx/runtime/serialization/output_archive.hpp>

#include <hpx/util/lightweight_test.hpp>

template <typename CARGO>
struct DummyContainer
{
DummyContainer()
{}

DummyContainer(CARGO cargo) :
cargo(cargo)
{}

template <typename Archive>
void serialize(Archive & archive, unsigned)
{
archive & cargo;
}

bool operator<(const DummyContainer<CARGO> other) const
{
return cargo < other.cargo;
}

CARGO cargo;
};

void test_int()
{
{
std::vector<char> buffer;
hpx::serialization::output_archive oarchive(buffer);

std::set<int> os;
os.insert(-1000);
os.insert(12345);
os.insert(34567);
os.insert(-2000);
oarchive << os;

hpx::serialization::input_archive iarchive(buffer);
std::set<int> is;
iarchive >> is;
HPX_TEST_EQ(os.size(), is.size());

std::set<int>::iterator j = is.begin();
for(std::set<int>::iterator i = os.begin();
i != os.end();
++i, ++j)
{
HPX_TEST_EQ(*i, *j);
}
}
}

template <typename T>
void test(T min, T max)
{
{
std::vector<char> buffer;
hpx::serialization::output_archive oarchive(buffer);
std::set<T> os;
for(T c = min; c < max; ++c)
{
os.insert(c);
}
oarchive << os;
hpx::serialization::input_archive iarchive(buffer);
std::set<T> is;
iarchive >> is;
HPX_TEST_EQ(os.size(), is.size());

typename std::set<T>::iterator j = is.begin();
for(typename std::set<T>::iterator i = os.begin(); i != os.end(); ++i)
{
HPX_TEST_EQ(*i, *j);
++j;
}
}
{
std::vector<char> buffer;
hpx::serialization::output_archive oarchive(buffer);
std::set<DummyContainer<T> > os;
for(T c = min; c < max; ++c)
{
os.insert(c);
}
oarchive << os;
hpx::serialization::input_archive iarchive(buffer);
std::set<DummyContainer<T> > is;
iarchive >> is;
HPX_TEST_EQ(os.size(), is.size());

typename std::set<DummyContainer<T> >::iterator j = is.begin();
for(typename std::set<DummyContainer<T> >::iterator i = os.begin(); i != os.end(); ++i)
{
HPX_TEST_EQ(i->cargo, j->cargo);
++j;
}
}
}

template <typename T>
void test_fp(T min, T max)
{
{
std::vector<char> buffer;
hpx::serialization::output_archive oarchive(buffer);
std::set<T> os;
for(T c = min; c < max; c += static_cast<T>(0.5))
{
os.insert(c);
}
oarchive << os;
hpx::serialization::input_archive iarchive(buffer);
std::set<T> is;
iarchive >> is;
HPX_TEST_EQ(os.size(), is.size());

typename std::set<T>::iterator j = is.begin();
for(typename std::set<T>::iterator i = os.begin(); i != os.end(); ++i)
{
HPX_TEST_EQ(*i, *j);
++j;
}
}
{
std::vector<char> buffer;
hpx::serialization::output_archive oarchive(buffer);
std::set<DummyContainer<T> > os;
for(T c = min; c < max; c += static_cast<T>(0.5))
{
os.insert(c);
}
oarchive << os;
hpx::serialization::input_archive iarchive(buffer);
std::set<DummyContainer<T> > is;
iarchive >> is;
HPX_TEST_EQ(os.size(), is.size());

typename std::set<DummyContainer<T> >::iterator j = is.begin();
for(typename std::set<DummyContainer<T> >::iterator i = os.begin(); i != os.end(); ++i)
{
HPX_TEST_EQ(i->cargo, j->cargo);
++j;
}
}
}

int main()
{
test_int();
test<char>((std::numeric_limits<char>::min)(), (std::numeric_limits<char>::max)());
test<int>((std::numeric_limits<int>::min)(), (std::numeric_limits<int>::min)() + 100);
test<int>((std::numeric_limits<int>::max)() - 100, (std::numeric_limits<int>::max)());
test<int>(-100, 100);
test<unsigned>((std::numeric_limits<unsigned>::min)(), (std::numeric_limits<unsigned>::min)() + 100);
test<unsigned>((std::numeric_limits<unsigned>::max)() - 100, (std::numeric_limits<unsigned>::max)());
test<long>((std::numeric_limits<long>::min)(), (std::numeric_limits<long>::min)() + 100);
test<long>((std::numeric_limits<long>::max)() - 100, (std::numeric_limits<long>::max)());
test<long>(-100, 100);
test<unsigned long>((std::numeric_limits<unsigned long>::min)(), (std::numeric_limits<unsigned long>::min)() + 100);
test<unsigned long>((std::numeric_limits<unsigned long>::max)() - 100, (std::numeric_limits<unsigned long>::max)());
test_fp<float>((std::numeric_limits<float>::min)(), (std::numeric_limits<float>::min)() + 100);
test_fp<float>((std::numeric_limits<float>::max)() - 100, (std::numeric_limits<float>::max)()); //it's incorrect
// because floatmax() - 100 causes cancellations error, digits are not affected
test_fp<float>(-100, 100);
test<double>((std::numeric_limits<double>::min)(), (std::numeric_limits<double>::min)() + 100);
test<double>((std::numeric_limits<double>::max)() - 100, (std::numeric_limits<double>::max)()); //it's the same
test<double>(-100, 100);

return hpx::util::report_errors();
}