multiprecision/doc/tutorial_import_export.qbk

89 lines
5.2 KiB
Plaintext

[/
Copyright 2011 - 2020 John Maddock.
Copyright 2013 - 2019 Paul A. Bristow.
Copyright 2013 Christopher Kormanyos.
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).
]
[section:import_export Importing and Exporting Data to and from `cpp_int` and `cpp_bin_float`]
Any integer number type that uses `cpp_int_backend` as its implementation layer can import or export its bits via two non-member functions:
template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator,
expression_template_option ExpressionTemplates, class OutputIterator>
OutputIterator export_bits(
const number<const cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>& val,
OutputIterator out,
unsigned chunk_size,
bool msv_first = true);
template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator,
expression_template_option ExpressionTemplates, class Iterator>
number<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>&
import_bits(
number<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>& val,
Iterator i,
Iterator j,
unsigned chunk_size = 0,
bool msv_first = true);
These functions are designed for data-interchange with other storage formats, and since __cpp_bin_float uses __cpp_int internally,
by extension they can be used for floating-point numbers based on that backend as well (see example below).
Parameters and use are as follows:
template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator,
expression_template_option ExpressionTemplates, class OutputIterator>
OutputIterator export_bits(
const number<const cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>& val,
OutputIterator out,
unsigned chunk_size,
bool msv_first = true);
Exports the absolute value of `val` to OutputIterator `out`. The function will write `chunk_size` bits at a time
to the OutputIterator, and if `msv_first` is true, will write the most-significant block first. Byte and bit order
within each `chunk_size` block is always in the machines native format. Further, each block is stored in a
`std::uintmax_t` when it's assigned to `*out`.
[note Unfortunately, the standard's OutputIterator concept provides no means of deducing the type to output since
`std::iterator_traits<OutputIteratorType>::value_type` is type `void`. This is why the bit count for each block
has to be specified manually. It may also result in compiler warnings about the value being narrowed.]
[tip If you're exporting to non-native byte layout, then use
[@http://www.boost.org/doc/libs/release/libs/endian/doc/index.html Boost.Endian]
to create a custom OutputIterator that reverses the byte order of each chunk prior to actually storing the result.]
template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator,
expression_template_option ExpressionTemplates, class ForwardIterator>
number<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>&
import_bits(
number<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>& val,
ForwardIterator i,
ForwardIterator j,
unsigned chunk_size = 0,
bool msv_first = true);
Imports bits from the iterator range ['\[i,j)] and stores them in `val` to produce an unsigned result (if the result
is to be signed you will need to handle that separately). When `msv_first` is true, takes `*i` as the most significant
chunk. Assumes there are `chunk_size` bits in each value read from the iterator range, and that these are in machine native
bit/byte order. When `chunk_size` is zero, then assumes that each chunk contains
`std::numeric_limits<std::iterator_traits<ForwardIterator>::value_type>::digits`, note that this will give the wrong result
if dereferencing the iterators leads to a signed-integer type, [*and] the sign bit is significant (be particularly careful
if you expect type `char` to contain 8-bit values, as by default it will extract only 7-bits at a time if `char` is signed).
As with exporting, if the external data is to be in a non-native byte order (within each chunk), then you will need to create an iterator adaptor
that presents it in native order (see [@http://www.boost.org/doc/libs/release/libs/endian/doc/index.html Boost.Endian]).
[note
Note that this function is optimized for the case where the data can be `memcpy`ed from the source to the integer - in this case both
iterators much be pointers, and everything must be little-endian.]
[h4 Examples]
[IE1]
[IE2]
[endsect] [/section:import_export Importing and Exporting Data to and from `cpp_int` and `cpp_bin_float`]