повысить сериализацию mpfr_float

Я хотел бы сериализовать пользовательский класс, содержащий boost::multiprecision::mpfr_float в качестве члена. Он говорит здесь в документации Boost.Serialization что тип T является сериализуемым, если и только если хотя бы одно из 5 свойств истинно, и здесь в документации Multiprecision, что класс number имеет сквозную поддержку, которая требует сериализуемости базового бэкенда.

Для типа Boost.Multiprecision mpfr_float я знаю:

  1. Это не примитивный тип.
  2. Это тип класса, но для него не определены функции serialize.
  3. Это не указатель на Serializable тип.
  4. Это не ссылка на сериализуемый тип.
  5. Это не собственный массив C++ типа Serializable.

Итак, похоже, что если я хочу сериализовать тип mpfr_float, я должен предоставить функцию serialize для этого типа.

Мой вопрос таков: как я могу расширить тип mpfr_float для сериализации, самостоятельно написав функцию serialize? Я думаю, что мне нужно получить доступ к серверной части mpfr и поиграть с базовыми данными, и я не знаю, как действовать дальше. Советы от кого-то с опытом сериализации ранее несериализованных классов Boost будут очень признательны.


Заключительное решение

Основываясь на ответе sehe, я пришел к решению, которое отлично работает с точностью 100 и 1000:

namespace boost { namespace serialization { // insert this code to the appropriate namespaces


/**
 Save a mpfr_float type to a boost archive.
 */
template <typename Archive>
void save(Archive& ar, ::boost::multiprecision::backends::mpfr_float_backend<0> const& r, unsigned /*version*/)
{
    std::string tmp = r.str(0, std::ios::fixed);// 0 indicates use full precision
    ar & tmp;
}

/**
 Load a mpfr_float type from a boost archive.
 */
template <typename Archive>
void load(Archive& ar, ::boost::multiprecision::backends::mpfr_float_backend<0>& r, unsigned /*version*/)
{
    std::string tmp;
    ar & tmp;
    r = tmp.c_str();
}

} } // re: namespaces

Это решение удовлетворяет потребность из пункта (2) выше, в котором указывалось на необходимость добавления функций serialize. Спасибо за помощь.


person ofloveandhate    schedule 24.02.2015    source источник


Ответы (2)


Поддержка сквозного доступа подразумевает, что вам действительно нужно добавить сериализацию для типа backend.

Вы можете использовать тот же подход, который я показал в этом ответе:

где я показываю, как (де) сериализовать mpq_rational

person sehe    schedule 24.02.2015
comment
Я считаю, что это упомянутое решение действительно решит мою проблему. Я поиграю с вашим решением, а затем соглашусь. спасибо за быстрый ответ! - person ofloveandhate; 25.02.2015

Если вы используете версию 4.0.0 или выше, вы можете использовать mpfr_fpif_export и mpfr_fpif_import для ее сериализации/десериализации.

using realtype = number<mpfr_float_backend<100, allocate_stack>>;

#define MPFR_BUFFER_SIZE 1000

    namespace boost {
        namespace serialization {
            template<class Archive>
            void save(Archive& ar, const realtype& x, const boost::serialization::version_type&) {
                static char buffer[MPFR_BUFFER_SIZE];
                FILE* fid = fmemopen(buffer, MPFR_BUFFER_SIZE, "wb+");
                mpfr_fpif_export(fid, const_cast<mpfr_ptr>(x.backend().data()));
                fseek(fid, 0L, SEEK_END);
                long length = ftell(fid);
                ar& length;
                ar& boost::serialization::make_array(buffer, length);
                fclose(fid);
            }

            template<class Archive>
            void load(Archive& ar, realtype& x, const boost::serialization::version_type&) {
                static char buffer[MPFR_BUFFER_SIZE];
                long length = 0;

                ar& length;
                ar& boost::serialization::make_array(buffer, length);

                FILE* fid = fmemopen(buffer, length, "r");
                mpfr_fpif_import(x.backend().data(), fid);
                fclose(fid);
            }

            template<class Archive>
            inline void
                serialize(Archive& ar, realtype& t, const unsigned int file_version) {
                split_free(ar, t, file_version);
            }
        }
    }
person Zhen    schedule 04.01.2020