22 #ifndef __utl_dev_idx_dev_h__ 23 #define __utl_dev_idx_dev_h__ 55 template <
typename impl_t,
typename data_t,
typename idx_t,
size_t N>
82 size_t get_ (data_t& data, idx_t idx) {
return impl().get_(data, idx); }
83 size_t get_ (data_t* data,
size_t n, idx_t idx) {
return impl().get_(data, n, idx); }
84 size_t put_ (
const data_t& data, idx_t idx) {
return impl().put_(data, idx); }
85 size_t put_ (
const data_t* data,
size_t n, idx_t idx) {
return impl().put_ (data, n, idx); }
86 idx_t
cursor_ ()
const {
return impl().cursor_(); }
87 void cursor_ (idx_t idx) { impl().cursor_(idx); }
104 size_t get (data_t& data, idx_t
cursor) {
116 size_t get (data_t* data,
size_t n, idx_t
cursor) {
141 size_t put (
const data_t* data,
size_t n, idx_t
cursor) {
169 template <
typename _Dst_t>
171 static_assert ((
sizeof (_Dst_t)%
sizeof(data_t) == 0),
172 "Target size must be a integer multiple of device's data size");
173 get_ (reinterpret_cast<data_t*>(&dst),
sizeof(_Dst_t)/
sizeof(data_t),
cursor_());
177 template <
typename _Dst_t>
197 template <
typename _Src_t>
199 static_assert ((
sizeof (_Src_t)%
sizeof(data_t) == 0),
200 "Source size must be a integer multiple of device's data size");
201 put_ (reinterpret_cast<data_t*>(&src),
sizeof (_Src_t)/
sizeof(data_t),
cursor_());
205 template <
typename _Src_t>
230 using iterator = idxdev_it <idx_dev_t, data_t*, N>;
255 template <
typename data_t,
typename idx_t,
size_t N>
281 virtual size_t get_ (data_t&, idx_t) =0;
282 virtual size_t get_ (data_t*,
size_t n, idx_t) =0;
283 virtual size_t put_ (
const data_t&, idx_t) =0;
284 virtual size_t put_ (
const data_t*,
size_t n, idx_t) =0;
285 virtual idx_t
cursor_ ()
const =0;
286 virtual void cursor_ (idx_t) =0;
303 size_t get (data_t& data, idx_t
cursor) {
315 size_t get (data_t* data,
size_t n, idx_t
cursor) {
340 size_t put (
const data_t* data,
size_t n, idx_t
cursor) {
368 template <
typename _Dst_t>
370 static_assert ((
sizeof (_Dst_t)%
sizeof(data_t) == 0),
371 "Target size must be an integer multiple of device's data size");
372 get_ (reinterpret_cast<data_t*>(&dst),
sizeof(_Dst_t)/
sizeof(data_t),
cursor_());
376 template <
typename _Dst_t>
396 template <
typename _Src_t>
398 static_assert ((
sizeof (_Src_t)%
sizeof(data_t) == 0),
399 "Source size must be an integer multiple of device's data size");
400 put_ (reinterpret_cast<data_t*>(&src),
sizeof (_Src_t)/
sizeof(data_t),
cursor_());
404 template <
typename _Src_t>
429 using iterator = idxdev_it <idx_dev_t, data_t*, N>;
448 #if defined _utl_have_concepts 450 template <
typename _Tp>
451 concept
bool Idx_dev = requires (_Tp t,
const _Tp ct,
typename _Tp::data_type v) {
454 requires !std::is_copy_constructible<_Tp>::value;
455 requires !std::is_copy_assignable<_Tp>::value;
458 {t.get(&v, 1, 0)} ->
size_t;
460 {t.put(&v, 1, 0)} ->
size_t;
464 {t[
typename _Tp::idx_type{}]} ->
typename _Tp::data_type&;
466 requires idxdev_iterator_c<typename _Tp::iterator>;
467 typename _Tp::const_iterator;
469 { t.begin()} ->
typename _Tp::iterator;
472 { t.end()} ->
typename _Tp::iterator;
477 namespace idx_dev_details {
481 template <
class _Tp>
using try_get1_t = decltype (declval<_Tp>().
get (declval<typename _Tp::data_type&>()));
482 template <
class _Tp>
using try_get2_t = decltype (declval<_Tp>().
get (declval<typename _Tp::data_type*>(), declval<size_t>()));
486 template <
class _Tp>
using try_begin_t = decltype (declval<_Tp>().begin());
487 template <
class _Tp>
using tryc_begin_t = decltype (declval<const _Tp>().begin());
488 template <
class _Tp>
using try_cbegin_t = decltype (declval<const _Tp>().cbegin());
489 template <
class _Tp>
using try_end_t = decltype (declval<_Tp>().begin());
490 template <
class _Tp>
using tryc_end_t = decltype (declval<const _Tp>().begin());
491 template <
class _Tp>
using try_cend_t = decltype (declval<const _Tp>().cend());
494 template <
typename _Tp,
typename =
void>
498 template <
typename _Tp>
501 typename _Tp::data_type,
502 typename _Tp::pointer_type,
503 typename _Tp::iterator,
504 typename _Tp::const_iterator,
509 use_if_same_t <tryc_begin_t<_Tp>, typename _Tp::const_iterator>,
510 use_if_same_t <try_cbegin_t<_Tp>, typename _Tp::const_iterator>,
512 use_if_same_t <tryc_end_t<_Tp>, typename _Tp::const_iterator>,
513 use_if_same_t <try_cend_t<_Tp>, typename _Tp::const_iterator>
522 template <
typename _Tp>
Primary template to catch any non input device types.
idx_t cursor(idx_t idx)
Set the cursor position.
size_t put(const data_t &data, idx_t cursor)
Put interface. This function should send a single data_t object to device.
size_t get_(data_t *data, size_t n, idx_t idx)
void void_t
void_t type alias
size_t put(const data_t *data, size_t n, idx_t cursor)
Put interface. This function should send a stream of data_t objects to device.
A virtual base class specialization.
idx_t cursor() const
Return the current cursor position.
const_iterator begin() const noexcept
decltype(declval< _Tp >().begin()) try_begin_t
iterator begin() noexcept
.begin implementation
idx_dev()=default
A default constructor from derived only.
idxdev_it< idx_dev_t, data_t *, N > iterator
Iterator.
data_t & operator[](const idx_t idx)
idx_dev_t & operator=(const idx_dev_t &)=delete
idx_t cursor() const
Return the current cursor position.
size_t put_(const data_t &data, idx_t idx)
const_iterator cbegin() const noexcept
size_t put(const data_t &data, idx_t cursor)
Put interface. This function should send a single data_t object to device.
size_t get_(data_t &data, idx_t idx)
meta::eval< meta::enable_if< meta::same_< _T1, _T2 >::value, _Ret > > use_if_same_t
decltype(declval< const _Tp >().begin()) tryc_begin_t
iterator begin() noexcept
.begin implementation
const_iterator end() const noexcept
Abstract base class for indexed devices.
decltype(declval< const _Tp >().cend()) try_cend_t
decltype(declval< _Tp >().get(declval< typename _Tp::data_type * >(), declval< size_t >())) try_get2_t
STL's core language concepts.
idx_dev< impl_t, data_t, idx_t, N > idx_dev_t
class type syntactic sugar
decltype(declval< const _Tp >().begin()) tryc_end_t
decltype(declval< _Tp >().begin()) try_end_t
const_iterator cend() const noexcept
decltype(declval< const _Tp >().cbegin()) try_cbegin_t
size_t put(const data_t *data, size_t n, idx_t cursor)
Put interface. This function should send a stream of data_t objects to device.
idx_dev_t & operator>>(_Dst_t &dst)
Template operator>> implementation for for all by value/ref parameters.
const_iterator cend() const noexcept
idxdev_it< idx_dev_t, data_t *, N > iterator
Iterator.
Iterator collection for devices.
idxdev_it< idx_dev_t, const data_t *, N > const_iterator
Const iterator.
decltype(declval< _Tp >().get(declval< typename _Tp::data_type & >())) try_get1_t
size_t put_(const data_t *data, size_t n, idx_t idx)
const_iterator end() const noexcept
~idx_dev()=default
Allow destructor from derived only.
const_iterator cbegin() const noexcept
idx_t cursor(idx_t idx)
Set the cursor position.
data_t data_type
Export types as index device concept demands.
idx_dev_t & operator<<(_Src_t &src)
Template operator<< implementation for for all by value/ref parameters.
idxdev_it< idx_dev_t, const data_t *, N > const_iterator
Const iterator.
data_t data_type
Export types as index device concept demands.
Implementation detail main forward header.
const_iterator begin() const noexcept