mirror of
https://github.com/matrix-construct/construct
synced 2024-09-29 12:18:54 +02:00
ircd::simd: Add various ircd::buffer convenience overloads to interface.
This commit is contained in:
parent
d10576a03e
commit
d4de92c61f
4 changed files with 132 additions and 0 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue