mirror of
https://github.com/matrix-construct/construct
synced 2024-06-30 15:58:20 +02:00
ircd::simd: Add various ircd::buffer convenience overloads to interface.
This commit is contained in:
parent
d10576a03e
commit
d4de92c61f
|
@ -24,6 +24,28 @@ namespace ircd::simd
|
||||||
class input_t,
|
class input_t,
|
||||||
class lambda>
|
class lambda>
|
||||||
block_t accumulate(const input_t *, const u64x2, block_t, lambda&&) noexcept;
|
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
|
/// Streaming accumulation
|
||||||
|
|
|
@ -61,6 +61,40 @@ namespace ircd::simd
|
||||||
class lambda>
|
class lambda>
|
||||||
typename for_each_variable_stride<block_t, lambda>::type
|
typename for_each_variable_stride<block_t, lambda>::type
|
||||||
for_each(const char *, const u64x2, lambda&&) noexcept;
|
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
|
/// Streaming consumer
|
||||||
|
|
|
@ -61,6 +61,40 @@ namespace ircd::simd
|
||||||
class lambda>
|
class lambda>
|
||||||
typename generate_variable_stride<block_t, lambda>::type
|
typename generate_variable_stride<block_t, lambda>::type
|
||||||
generate(char *, const u64x2, lambda&&) noexcept;
|
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
|
/// Streaming generator
|
||||||
|
|
|
@ -56,6 +56,48 @@ namespace ircd::simd
|
||||||
class lambda>
|
class lambda>
|
||||||
typename transform_variable_stride<block_t, lambda>::type
|
typename transform_variable_stride<block_t, lambda>::type
|
||||||
transform(char *, const char *, const u64x2, lambda&&) noexcept;
|
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
|
/// Streaming transform
|
||||||
|
|
Loading…
Reference in a new issue