0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-06-28 14:58:20 +02:00

ircd::simd: Add various ircd::buffer convenience overloads to interface.

This commit is contained in:
Jason Volk 2020-10-10 00:24:30 -07:00
parent d10576a03e
commit d4de92c61f
4 changed files with 132 additions and 0 deletions

View file

@ -24,6 +24,28 @@ namespace ircd::simd
class input_t,
class lambda>
block_t accumulate(const input_t *, const u64x2, block_t, lambda&&) noexcept;
template<class block_t,
class lambda>
block_t accumulate(const const_buffer &, block_t, lambda&&) noexcept;
}
/// Streaming accumulation
///
template<class block_t,
class lambda>
inline block_t
ircd::simd::accumulate(const const_buffer &buf,
block_t val,
lambda&& closure)
noexcept
{
const u64x2 max
{
0, size(buf),
};
return accumulate(data(buf), max, val, std::forward<lambda>(closure));
}
/// Streaming accumulation

View file

@ -61,6 +61,40 @@ namespace ircd::simd
class lambda>
typename for_each_variable_stride<block_t, lambda>::type
for_each(const char *, const u64x2, lambda&&) noexcept;
template<class block_t,
class lambda>
const_buffer
for_each(const const_buffer &, lambda&&) noexcept;
}
/// Streaming consumer
///
/// Convenience wrapper using const_buffer. This will forward to the
/// appropriate overload. The return buffer is a view on the input buffer
/// from the beginning up to the resulting counter value.
///
template<class block_t,
class lambda>
inline ircd::const_buffer
ircd::simd::for_each(const const_buffer &buf,
lambda&& closure)
noexcept
{
const u64x2 max
{
0, size(buf)
};
const auto res
{
for_each(data(buf), max, std::forward<lambda>(closure))
};
return const_buffer
{
data(buf), res[1]
};
}
/// Streaming consumer

View file

@ -61,6 +61,40 @@ namespace ircd::simd
class lambda>
typename generate_variable_stride<block_t, lambda>::type
generate(char *, const u64x2, lambda&&) noexcept;
template<class block_t,
class lambda>
mutable_buffer
generate(const mutable_buffer &, lambda&&) noexcept;
}
/// Streaming generator
///
/// Convenience wrapper using mutable_buffer. This will forward to the
/// appropriate overload. The return buffer is a view on the input buffer
/// from the beginning up to the resulting counter value.
///
template<class block_t,
class lambda>
inline ircd::mutable_buffer
ircd::simd::generate(const mutable_buffer &buf,
lambda&& closure)
noexcept
{
const u64x2 max
{
size(buf), 0
};
const auto res
{
generate(data(buf), max, std::forward<lambda>(closure))
};
return mutable_buffer
{
data(buf), res[0]
};
}
/// Streaming generator

View file

@ -56,6 +56,48 @@ namespace ircd::simd
class lambda>
typename transform_variable_stride<block_t, lambda>::type
transform(char *, const char *, const u64x2, lambda&&) noexcept;
template<class block_t,
class lambda>
pair<mutable_buffer, const_buffer>
transform(const pair<mutable_buffer, const_buffer> &, lambda&&) noexcept;
}
/// Streaming transform
///
/// Convenience wrapper using ircd::buffer. This will forward to the
/// appropriate overload. The return buffers are views on the output and input
/// buffers with a size of the respective resulting counter values. Unless
/// the closure broke the loop early the result buffers will be the same as
/// the input (contents having transformed of course).
///
template<class block_t,
class lambda>
inline std::pair<ircd::mutable_buffer, ircd::const_buffer>
ircd::simd::transform(const std::pair<mutable_buffer, const_buffer> &buf,
lambda&& closure)
noexcept
{
const auto &[output, input]
{
buf
};
const u64x2 max
{
size(output), size(input),
};
const auto res
{
transform(data(output), data(input), max, std::forward<lambda>(closure))
};
return std::pair<mutable_buffer, const_buffer>
{
{ data(output), res[0] },
{ data(input), res[1] },
};
}
/// Streaming transform