Commit 5ee47dbf authored by Joseph Mirabel's avatar Joseph Mirabel
Browse files

[Serialization] Add remove_duplicate functions.

parent 16f35c3c
......@@ -19,11 +19,15 @@
#ifndef HPP_PINOCCHIO_SERIALIZATION_HH
# define HPP_PINOCCHIO_SERIALIZATION_HH
# include <set>
# include <type_traits>
# include <boost/serialization/split_free.hpp>
# include <boost/serialization/shared_ptr.hpp>
# include <boost/serialization/weak_ptr.hpp>
# include <hpp/pinocchio/fwd.hh>
# include <pinocchio/serialization/eigen.hpp>
namespace hpp {
namespace serialization {
......@@ -89,4 +93,124 @@ inline void serialize(Archive & ar, Eigen::Array<_Scalar,_Rows,_Cols,_Options,_M
} // namespace serialization
} // namespace boost
namespace hpp {
namespace serialization {
namespace remove_duplicate {
template<typename Key, typename Compare = std::less<Key> >
struct ptr_less : Compare {
inline bool operator() (Key const* t1, Key const* t2) { return Compare::operator() (*t1, *t2); }
};
template<typename Derived>
struct eigen_compare {
bool operator() (const Eigen::DenseBase<Derived>& a,
const Eigen::DenseBase<Derived>& b)
{
if (a.size() < b.size()) return true;
if (a.size() > b.size()) return false;
for(Eigen::Index i = 0; i < a.size(); ++i) {
if (a.derived().data()[i] < b.derived().data()[i]) return true;
if (a.derived().data()[i] > b.derived().data()[i]) return false;
}
return false;
}
};
template<typename Key, typename Compare = std::less<Key> >
struct archive {
typedef Compare compare_type;
typedef ptr_less<Key, Compare> ptr_compare_type;
std::set<Key const*, ptr_compare_type > datas;
};
typedef archive<::hpp::pinocchio::vector_t, eigen_compare<::hpp::pinocchio::vector_t> > vector_archive;
template<class Archive, typename Key, typename Compare = std::less<Key>>
inline void load_or_save_no_remove_duplicate_check (Archive& ar,
const char* name,
Key& key,
const unsigned int version)
{
(void) version;
Key* value = &key;
ar & boost::serialization::make_nvp(name, value);
}
template<class Archive, typename Key, typename Compare = std::less<Key>>
inline void save (Archive& ar,
std::set<Key const*, ptr_less<Key,Compare> >& set,
const char* name,
const Key& key,
const unsigned int version)
{
(void) version;
static_assert(Archive::is_saving::value, "Archive is saving");
auto result = set.insert(&key);
bool inserted = result.second;
Key const* k = (inserted ? &key : *result.first);
ar & boost::serialization::make_nvp(name, k);
}
template<class Archive, typename Key, typename Compare = std::less<Key>>
inline void serialize (Archive& ar,
std::set<Key const*, ptr_less<Key,Compare> >& set,
const char* name,
Key& key,
const unsigned int version)
{
if (Archive::is_saving::value) {
save(ar, set, name, key, version);
} else {
load_or_save_no_remove_duplicate_check(ar, name, key, version);
}
}
template <bool is_base>
struct serialiaze_impl {
template<typename Archive, typename Key, typename Compare = std::less<Key> >
static inline void run (Archive& ar,
const char* name,
Key& key,
const unsigned int version)
{
serialize(ar, static_cast<archive<Key, Compare>&>(ar).datas, name, key, version);
}
};
template <>
struct serialiaze_impl<false> {
template<typename Archive, typename Key, typename Compare = std::less<Key> >
static inline void run (Archive& ar,
const char* name,
Key& key,
const unsigned int version)
{
load_or_save_no_remove_duplicate_check(ar, name, key, version);
}
};
template<typename Archive, typename Key, typename Compare = std::less<Key>,
bool is_base = std::is_base_of<archive<Key, Compare>, Archive>::value >
inline void serialize (Archive& ar,
const char* name,
Key& key,
const unsigned int version)
{
serialiaze_impl<is_base>::template run<Archive, Key, Compare>(ar, name, key, version);
}
template<typename Archive>
inline void serialize_vector (Archive& ar,
const char* name,
::hpp::pinocchio::vector_t& key,
const unsigned int version)
{
serialize<Archive, ::hpp::pinocchio::vector_t, vector_archive::compare_type>
(ar, name, key, version);
}
} // namespace remove_duplicate
} // namespace pinocchio
} // namespace hpp
#endif // HPP_PINOCCHIO_SERIALIZATION_HH
......@@ -50,7 +50,10 @@ ADD_TESTCASE(urdf)
ADD_TESTCASE(liegroup-element)
ADD_TESTCASE(print)
ADD_TESTCASE(joint-bounds)
ADD_TESTCASE(serialization)
ADD_UNIT_TEST(serialization serialization.cc)
target_link_libraries(serialization PRIVATE
hpp-util::hpp-util pinocchio::pinocchio Boost::thread
${Boost_LIBRARIES})
FIND_PACKAGE(OpenMP)
IF(OPENMP_FOUND)
......
......@@ -48,3 +48,41 @@ BOOST_AUTO_TEST_CASE(empty_array)
BOOST_CHECK_EQUAL(empty_r.size(), 0);
}
template<typename base_archive = boost::archive::xml_oarchive>
struct oarchive :
base_archive, hpp::serialization::remove_duplicate::vector_archive
{
oarchive(std::ostream& is) : base_archive (is) {}
};
template<typename Archive>
void check_remove_duplicate_impl ()
{
vector_t a(5), b(a);
std::stringstream ss;
{
Archive oa(ss);
hpp::serialization::remove_duplicate::serialize_vector(oa, "a", a, 0);
hpp::serialization::remove_duplicate::serialize_vector(oa, "b", b, 0);
}
BOOST_TEST_MESSAGE(ss.str());
vector_t a_r, b_r;
{
boost::archive::xml_iarchive ia(ss);
hpp::serialization::remove_duplicate::serialize_vector(ia, "a", a, 0);
hpp::serialization::remove_duplicate::serialize_vector(ia, "b", b, 0);
}
BOOST_CHECK_EQUAL(a, a_r);
BOOST_CHECK_EQUAL(b, b_r);
}
BOOST_AUTO_TEST_CASE(check_remove_duplicate)
{
check_remove_duplicate_impl<boost::archive::xml_oarchive>();
check_remove_duplicate_impl<oarchive<boost::archive::xml_oarchive> >();
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment