|
#ifndef matrix_utils_hpp |
|
#define matrix_utils_hpp |
|
|
|
#include <vector> |
|
#include <array> |
|
#include <type_traits> |
|
#include <fstream> |
|
|
|
#include <boost/archive/xml_iarchive.hpp> |
|
#include <boost/archive/xml_oarchive.hpp> |
|
#include <boost/archive/text_oarchive.hpp> |
|
#include <boost/archive/text_iarchive.hpp> |
|
#include <boost/archive/binary_iarchive.hpp> |
|
#include <boost/archive/binary_oarchive.hpp> |
|
#include <boost/filesystem/path.hpp> |
|
#include <boost/serialization/serialization.hpp> |
|
#include <boost/serialization/nvp.hpp> |
|
#include <boost/serialization/string.hpp> |
|
#include <boost/serialization/vector.hpp> |
|
|
|
#include <msgpack.hpp> |
|
|
|
namespace Matrix |
|
{ |
|
namespace Util |
|
{ |
|
extern void* enabler; |
|
|
|
template < |
|
class Matrix, class Value = typename Matrix::Scalar, |
|
template < Value, class A = std::allocator<Value> > |
|
class Container = std::vector, |
|
typename std::enable_if_t< |
|
Matrix::RowsAtCompileTime == -1 || Matrix::ColsAtCompileTime == -1 |
|
>*& = enabler |
|
> |
|
auto to_stl(const Matrix& matrix) -> decltype(auto) |
|
{ |
|
return Container<Value>(matrix.data(), matrix.data() + matrix.size()); |
|
} |
|
|
|
template < |
|
class Matrix, class Value = typename Matrix::Scalar, |
|
template < Value, std::size_t N > |
|
class Container = std::array, |
|
typename std::enable_if_t< |
|
Matrix::RowsAtCompileTime != -1 && Matrix::ColsAtCompileTime != -1 |
|
>*& = enabler |
|
> |
|
auto to_stl(const Matrix& matrix) -> decltype(auto) |
|
{ |
|
Container<Value, Matrix::RowsAtCompileTime * Matrix::ColsAtCompileTime > ret {}; |
|
|
|
for ( std::size_t i = 0; i < ret.size(); ++i ) |
|
{ |
|
ret[i] = *(matrix.data() + i); |
|
} |
|
|
|
return ret; |
|
} |
|
|
|
template < class Origin, class Value = typename Origin::Scalar > |
|
struct Helper // for eigen |
|
{ |
|
Helper() {} |
|
|
|
Helper(const Origin& origin) |
|
: _cols(origin.cols()), _data(to_stl(origin)) |
|
{} |
|
|
|
template <class To = Origin > |
|
To origin() |
|
{ |
|
return To::Map(_data.data(), _data.size() / _cols, _cols); |
|
} |
|
|
|
const char* root() const |
|
{ |
|
return _root_name.c_str(); |
|
} |
|
|
|
MSGPACK_DEFINE(_cols, _data); |
|
|
|
private: |
|
std::size_t _cols; |
|
std::vector<Value> _data; |
|
std::string _root_name { "matrix" }; |
|
|
|
friend class boost::serialization::access; |
|
|
|
template < class Archive > |
|
void serialize(Archive& ar, unsigned int version) |
|
{ |
|
static_cast< void >(version); // no use |
|
ar & boost::serialization::make_nvp("cols", _cols); |
|
ar & boost::serialization::make_nvp("data", _data); |
|
} |
|
}; |
|
|
|
template < class Origin > |
|
void save(const Origin& origin, const std::string& save_path) |
|
{ |
|
boost::filesystem::path path(save_path); |
|
Helper<Origin> helper(origin); |
|
|
|
if ( path.extension() == ".mpac" ) |
|
{ |
|
std::ofstream ofs(save_path, std::ios_base::binary); |
|
msgpack::sbuffer sbuf; |
|
msgpack::pack(sbuf, helper); |
|
ofs.write(sbuf.data(), sbuf.size()); |
|
} |
|
else if ( path.extension() == ".bin" ) |
|
{ |
|
std::ofstream ofs(save_path, std::ios_base::binary); |
|
boost::archive::binary_oarchive oar(ofs); |
|
oar << helper; |
|
} |
|
else if ( path.extension() == ".xml" ) |
|
{ |
|
std::ofstream ofs(save_path); |
|
boost::archive::xml_oarchive oar(ofs); |
|
oar << boost::serialization::make_nvp(helper.root(), helper); |
|
} |
|
else // save as text |
|
{ |
|
std::ofstream ofs(save_path); |
|
boost::archive::text_oarchive oar(ofs); |
|
oar << helper; |
|
} |
|
} |
|
|
|
template < class Origin > |
|
void load(Origin& origin, const std::string& load_path) |
|
{ |
|
boost::filesystem::path path(load_path); |
|
Helper<Origin> helper; |
|
|
|
if ( path.extension() == ".mpac" ) |
|
{ |
|
std::ifstream ifs(load_path, std::ios_base::binary); |
|
std::istreambuf_iterator<char> first(ifs); |
|
std::istreambuf_iterator<char> last; |
|
std::string data(first, last); |
|
|
|
msgpack::unpacked msg; |
|
msgpack::unpack(msg, data.data(), data.size()); |
|
msgpack::object obj = msg.get(); |
|
|
|
helper = obj.as<decltype(helper)>(); |
|
origin = std::move(helper.origin()); |
|
} |
|
else if ( path.extension() == ".bin" ) |
|
{ |
|
std::ifstream ifs(load_path, std::ios_base::binary); |
|
boost::archive::binary_iarchive iar(ifs); |
|
|
|
iar >> helper; |
|
origin = std::move(helper.origin()); |
|
} |
|
else if ( path.extension() == ".xml" ) |
|
{ |
|
std::ifstream ifs(load_path); |
|
boost::archive::xml_iarchive iar(ifs); |
|
|
|
iar >> boost::serialization::make_nvp(helper.root(), helper); |
|
origin = std::move(helper.origin()); |
|
} |
|
else // load as text |
|
{ |
|
std::ifstream ifs(load_path); |
|
boost::archive::text_iarchive iar(ifs); |
|
|
|
iar >> helper; |
|
origin = std::move(helper.origin()); |
|
} |
|
} |
|
} // Util |
|
} // Matrix |
|
|
|
#endif // matrix_utils_hpp |