25 #ifndef CRYPTO3_PACK_HPP
26 #define CRYPTO3_PACK_HPP
28 #include <nil/crypto3/detail/type_traits.hpp>
29 #include <nil/crypto3/detail/stream_endian.hpp>
30 #include <nil/crypto3/detail/exploder.hpp>
31 #include <nil/crypto3/detail/imploder.hpp>
32 #include <nil/crypto3/detail/predef.hpp>
34 #include <boost/assert.hpp>
35 #include <boost/static_assert.hpp>
37 #ifndef CRYPTO3_NO_OPTIMIZATION
39 #include <boost/endian.hpp>
40 #include <boost/utility/enable_if.hpp>
47 #ifndef CRYPTO3_NO_OPTIMIZATION
49 template<
int UnitBits,
int InputBits,
int OutputBits,
typename InT,
typename OutT>
50 struct host_can_memcpy {
51 constexpr
static const bool value = !(UnitBits % CHAR_BIT) && InputBits >= UnitBits &&
52 OutputBits >= UnitBits &&
sizeof(InT) * CHAR_BIT == InputBits &&
53 sizeof(OutT) * CHAR_BIT == OutputBits;
56 template<
typename Endianness,
int InputBits,
int OutputBits,
typename InT,
typename OutT>
58 constexpr
static const bool value = InputBits == OutputBits &&
sizeof(InT) ==
sizeof(OutT);
61 template<
int UnitBits,
int InputBits,
int OutputBits,
typename InT,
typename OutT>
62 struct can_memcpy<stream_endian::host_unit<UnitBits>, InputBits, OutputBits, InT, OutT>
63 : host_can_memcpy<UnitBits, InputBits, OutputBits, InT, OutT> {};
65 #ifdef BOOST_ENDIAN_LITTLE_BYTE_AVAILABLE
66 template<
int UnitBits,
int InputBits,
int OutputBits,
typename InT,
typename OutT>
67 struct can_memcpy<stream_endian::little_unit_big_bit<UnitBits>, InputBits, OutputBits, InT, OutT>
68 : host_can_memcpy<UnitBits, InputBits, OutputBits, InT, OutT> {};
69 template<
int UnitBits,
int InputBits,
int OutputBits,
typename InT,
typename OutT>
70 struct can_memcpy<stream_endian::little_unit_little_bit<UnitBits>, InputBits, OutputBits, InT, OutT>
71 : host_can_memcpy<UnitBits, InputBits, OutputBits, InT, OutT> {};
74 #ifdef CRYPTO3_TARGET_CPU_IS_BIG_ENDIAN
75 template<
int UnitBits,
int InputBits,
int OutputBits,
typename InT,
typename OutT>
76 struct can_memcpy<stream_endian::big_unit_big_bit<UnitBits>, InputBits, OutputBits, InT, OutT>
77 : host_can_memcpy<UnitBits, InputBits, OutputBits, InT, OutT> {};
78 template<
int UnitBits,
int InputBits,
int OutputBits,
typename InT,
typename OutT>
79 struct can_memcpy<stream_endian::big_unit_little_bit<UnitBits>, InputBits, OutputBits, InT, OutT>
80 : host_can_memcpy<UnitBits, InputBits, OutputBits, InT, OutT> {};
85 template<
typename Endianness,
int InputBits,
int OutputBits,
bool Explode = (InputBits > OutputBits),
86 bool Implode = (InputBits < OutputBits)>
89 template<
typename Endianness,
int Bits>
92 template<
typename InIter,
typename OutIter>
93 inline static void pack_n(InIter in,
size_t in_n, OutIter out) {
94 std::copy(in, in + in_n, out);
97 template<
typename InIter,
typename OutIter>
98 inline static void pack(InIter in, InIter in_e, OutIter out) {
99 std::copy(in, in_e, out);
103 template<
typename Endianness,
int InputBits,
int OutputBits>
104 struct real_packer<Endianness, InputBits, OutputBits, true, false> {
108 template<
typename InIter,
typename OutIter>
109 inline static void pack_n(InIter in,
size_t in_n, OutIter out) {
111 typedef typename std::iterator_traits<InIter>::value_type InValue;
112 InValue
const value = *in++;
117 template<
typename InIter,
typename OutIter>
118 inline static void pack(InIter in, InIter in_e, OutIter out) {
120 typedef typename std::iterator_traits<InIter>::value_type InValue;
121 InValue
const value = *in++;
127 template<
typename Endianness,
int InputBits,
int OutputBits>
128 struct real_packer<Endianness, InputBits, OutputBits, false, true> {
132 template<
typename InIter,
typename OutIter>
133 inline static void pack_n(InIter in,
size_t in_n, OutIter out) {
134 size_t out_n = in_n / (OutputBits / InputBits);
137 OutValue value = OutValue();
143 template<
typename InIter,
typename OutIter>
144 inline static void pack(InIter in, InIter in_e, OutIter out) {
147 OutValue value = OutValue();
154 template<
typename Endianness,
int InputBits,
int OutputBits>
155 struct packer : real_packer<Endianness, InputBits, OutputBits> {
157 #ifndef CRYPTO3_NO_OPTIMIZATION
161 template<
typename InT,
typename OutT>
163 typename std::enable_if<can_memcpy<Endianness, InputBits, OutputBits, InT, OutT>::value>::type
164 pack_n(InT
const *in,
size_t n, OutT *out) {
165 std::memcpy(out, in, n *
sizeof(InT));
168 template<
typename InT,
typename OutT>
170 typename std::enable_if<can_memcpy<Endianness, InputBits, OutputBits, InT, OutT>::value>::type
172 std::memcpy(out, in, n *
sizeof(InT));
178 template<
typename Endianness,
int InValueBits,
int OutValueBits,
typename InputIterator1,
179 typename InputIterator2>
180 inline void pack_n(InputIterator1 in,
size_t in_n, InputIterator2 out) {
185 template<
typename Endianness,
int InValueBits,
int OutValueBits,
typename InputIterator1,
186 typename InputIterator2>
187 inline void pack_n(InputIterator1 in,
size_t in_n, InputIterator2 out,
size_t out_n) {
188 BOOST_ASSERT(in_n * InValueBits == out_n * OutValueBits);
189 pack_n<Endianness, InValueBits, OutValueBits>(in, in_n, out);
192 template<
typename Endianness,
int InValueBits,
int OutValueBits,
typename InputIterator1,
193 typename InputIterator2>
194 inline void pack(InputIterator1 b1, InputIterator1 e1, std::random_access_iterator_tag, InputIterator2 b2) {
195 pack_n<Endianness, InValueBits, OutValueBits>(b1, e1 - b1, b2);
198 template<
typename Endianness,
int InValueBits,
int OutValueBits,
typename InputIterator1,
typename CatT1,
199 typename InputIterator2,
200 typename =
typename std::enable_if<detail::is_iterator<InputIterator1>::value>::type,
201 typename =
typename std::enable_if<detail::is_iterator<InputIterator2>::value>::type>
202 inline void pack(InputIterator1 b1, InputIterator1 e1, CatT1, InputIterator2 b2) {
207 template<
typename Endianness,
int InValueBits,
int OutValueBits,
typename InputIterator1,
208 typename InputIterator2,
209 typename =
typename std::enable_if<detail::is_iterator<InputIterator2>::value>::type>
210 inline void pack(InputIterator1 b1, InputIterator1 e1, InputIterator2 b2) {
211 typedef typename std::iterator_traits<InputIterator1>::iterator_category cat1;
213 pack<Endianness, InValueBits, OutValueBits>(b1, e1, cat1(), b2);
216 template<
typename Endianness,
int InValueBits,
int OutValueBits,
typename InputIterator1,
217 typename InputIterator2>
218 inline void pack(InputIterator1 b1, InputIterator1 e1, std::random_access_iterator_tag, InputIterator2 b2,
219 InputIterator2 e2, std::random_access_iterator_tag) {
220 pack_n<Endianness, InValueBits, OutValueBits>(b1, e1 - b1, b2, e2 - b2);
223 template<
typename Endianness,
int InValueBits,
int OutValueBits,
typename InputIterator1,
typename CatT1,
224 typename InputIterator2,
typename CatT2>
225 inline void pack(InputIterator1 b1, InputIterator1 e1, CatT1, InputIterator2 b2, InputIterator2, CatT2) {
226 pack<Endianness, InValueBits, OutValueBits>(b1, e1, b2);
229 template<
typename Endianness,
int InValueBits,
int OutValueBits,
typename InputIterator1,
230 typename InputIterator2>
231 inline void pack(InputIterator1 b1, InputIterator1 e1, InputIterator2 b2, InputIterator2 e2) {
232 typedef typename std::iterator_traits<InputIterator1>::iterator_category cat1;
233 typedef typename std::iterator_traits<InputIterator2>::iterator_category cat2;
234 pack<Endianness, InValueBits, OutValueBits>(b1, e1, cat1(), b2, e2, cat2());
237 template<
typename Endianness,
int InValueBits,
int OutValueBits,
typename InputType,
typename OutputType>
238 inline void pack(
const InputType &in, OutputType &out) {
239 pack_n<Endianness, InValueBits, OutValueBits>(in.begin(), in.size(), out.begin(), out.size());
242 template<
typename Endianness,
int InValueBits,
int OutValueBits,
typename InputIterator,
244 typename =
typename std::enable_if<!std::is_arithmetic<OutputType>::value>::type>
245 inline void pack(InputIterator first, InputIterator last, OutputType &out) {
246 pack_n<Endianness, InValueBits, OutValueBits>(first, std::distance(first, last), out.begin(),
void pack_n(InputIterator in, std::size_t in_n, OutputIterator out)
Packs in_n input elements starting from in into output elements beginning from out.
Definition: block/include/nil/crypto3/detail/pack.hpp:776
void pack(InputIterator first, InputIterator last, std::random_access_iterator_tag, OutputIterator out)
Packs elements from the range [first, last) into elements starting from out. Works for input containe...
Definition: block/include/nil/crypto3/detail/pack.hpp:835
void pack_n(InputIterator1 in, size_t in_n, InputIterator2 out, size_t out_n)
Definition: passhash/include/nil/crypto3/detail/pack.hpp:187
void pack(InputIterator first, InputIterator last, OutputType &out)
Definition: passhash/include/nil/crypto3/detail/pack.hpp:245
constexpr static const bool value
Definition: block/include/nil/crypto3/detail/pack.hpp:91
exploder forms a sequence of output values represented in OutputEndianness endianness from an input v...
Definition: block/include/nil/crypto3/detail/exploder.hpp:148
constexpr static const bool value
Definition: block/include/nil/crypto3/detail/pack.hpp:72
imploder processes a sequence of input values represented in InputEndianness endianness into an outpu...
Definition: block/include/nil/crypto3/detail/imploder.hpp:122
T type
Definition: block/include/nil/crypto3/detail/exploder.hpp:64
This packer deals with arbitrary input and output (but not bool) data elements.
Definition: block/include/nil/crypto3/detail/pack.hpp:444
static std::enable_if< can_memcpy< Endianness, InputBits, OutputBits, InT, OutT >::value >::type pack_n(InT const *in, size_t n, OutT *out)
Definition: passhash/include/nil/crypto3/detail/pack.hpp:164
static std::enable_if< can_memcpy< Endianness, InputBits, OutputBits, InT, OutT >::value >::type pack_n(InT *in, size_t n, OutT *out)
Definition: passhash/include/nil/crypto3/detail/pack.hpp:171
static void pack_n(InIter in, size_t in_n, OutIter out)
Definition: passhash/include/nil/crypto3/detail/pack.hpp:93
static void pack(InIter in, InIter in_e, OutIter out)
Definition: passhash/include/nil/crypto3/detail/pack.hpp:98
Real_packer is used to transform input data divided into chunks of the bit size InputValueBits repres...
Definition: block/include/nil/crypto3/detail/pack.hpp:144