idx_dev.h
Go to the documentation of this file.
#ifndef __utl_dev_idx_dev_h__
#define __utl_dev_idx_dev_h__
#include <utl/core/impl.h>
#include <utl/core/crtp.h>
#include <utl/dev/dev_iterators.h>
#include <utl/meta/meta.h>
namespace utl {
template <typename impl_t, typename data_t, typename idx_t, size_t N>
class idx_dev {
_CRTP_IMPL(impl_t);
using idx_dev_t = idx_dev <impl_t, data_t, idx_t, N>;
public:
using data_type = data_t;
using pointer_type= data_t*;
using idx_type = idx_t;
using type = idx_dev_t;
protected:
~idx_dev () = default;
idx_dev () = default;
idx_dev(const idx_dev_t&) = delete;
idx_dev_t& operator= (const idx_dev_t&) = delete;
private:
size_t get_ (data_t& data, idx_t idx) { return impl().get_(data, idx); }
size_t get_ (data_t* data, size_t n, idx_t idx) { return impl().get_(data, n, idx); }
size_t put_ (const data_t& data, idx_t idx) { return impl().put_(data, idx); }
size_t put_ (const data_t* data, size_t n, idx_t idx) { return impl().put_ (data, n, idx); }
idx_t cursor_ () const { return impl().cursor_(); }
void cursor_ (idx_t idx) { impl().cursor_(idx); }
public:
size_t get (data_t& data, idx_t cursor) {
return get_ (data, cursor);
}
size_t get (data_t* data, size_t n, idx_t cursor) {
return get_ (data, n, cursor);
}
size_t put (const data_t& data, idx_t cursor) {
return put_ (data, cursor);
}
size_t put (const data_t* data, size_t n, idx_t cursor) {
return put_ (data, n, cursor);
}
idx_t cursor () const { return cursor_(); }
idx_t cursor (idx_t idx) { return cursor_(idx); }
template <typename _Dst_t>
idx_dev_t& operator>> (_Dst_t& dst) {
static_assert ((sizeof (_Dst_t)%sizeof(data_t) == 0),
"Target size must be a integer multiple of device's data size");
get_ (reinterpret_cast<data_t*>(&dst), sizeof(_Dst_t)/sizeof(data_t), cursor_());
return *this;
}
template <typename _Dst_t>
idx_dev_t& operator>> (_Dst_t* dst) = delete;
idx_dev_t& operator>> (data_t& dst) {
get_ (dst, cursor_());
return *this;
}
template <typename _Src_t>
idx_dev_t& operator<< (_Src_t& src) {
static_assert ((sizeof (_Src_t)%sizeof(data_t) == 0),
"Source size must be a integer multiple of device's data size");
put_ (reinterpret_cast<data_t*>(&src), sizeof (_Src_t)/sizeof(data_t), cursor_());
return *this;
}
template <typename _Src_t>
idx_dev_t& operator<< (_Src_t* src) = delete;
idx_dev_t& operator<< (const data_t& src) {
put_ (src, cursor_());
return *this;
}
data_t& operator[] (const idx_t idx) {
iterator it(this, idx);
return *it;
}
public:
using iterator = idxdev_it <idx_dev_t, data_t*, N>;
using const_iterator = idxdev_it <idx_dev_t, const data_t*, N>;
iterator begin () noexcept { return iterator(this, iterator::beg); }
const_iterator begin () const noexcept { return const_iterator(this, iterator::beg); }
const_iterator cbegin () const noexcept { return const_iterator(this, iterator::beg); }
iterator end () noexcept { return iterator(this, iterator::eos); }
const_iterator end () const noexcept { return const_iterator(this, iterator::eos); }
const_iterator cend () const noexcept { return const_iterator(this, iterator::eos); }
};
template <typename data_t, typename idx_t, size_t N>
class idx_dev <virtual_tag, data_t, idx_t, N> {
using idx_dev_t = idx_dev <virtual_tag, data_t, idx_t, N>;
public:
using data_type = data_t;
using pointer_type= data_t*;
using idx_type = idx_t;
using type = idx_dev_t;
public:
virtual ~idx_dev () = default;
protected:
idx_dev () = default;
idx_dev(const idx_dev_t&) = delete;
idx_dev_t& operator= (const idx_dev_t&) = delete;
private:
virtual size_t get_ (data_t&, idx_t) =0;
virtual size_t get_ (data_t*, size_t n, idx_t) =0;
virtual size_t put_ (const data_t&, idx_t) =0;
virtual size_t put_ (const data_t*, size_t n, idx_t) =0;
virtual idx_t cursor_ () const =0;
virtual void cursor_ (idx_t) =0;
public:
size_t get (data_t& data, idx_t cursor) {
return get_ (data, cursor);
}
size_t get (data_t* data, size_t n, idx_t cursor) {
return get_ (data, n, cursor);
}
size_t put (const data_t& data, idx_t cursor) {
return put_ (data, cursor);
}
size_t put (const data_t* data, size_t n, idx_t cursor) {
return put_ (data, n, cursor);
}
idx_t cursor () const { return cursor_(); }
idx_t cursor (idx_t idx) { return cursor_(idx); }
template <typename _Dst_t>
idx_dev_t& operator>> (_Dst_t& dst) {
static_assert ((sizeof (_Dst_t)%sizeof(data_t) == 0),
"Target size must be an integer multiple of device's data size");
get_ (reinterpret_cast<data_t*>(&dst), sizeof(_Dst_t)/sizeof(data_t), cursor_());
return *this;
}
template <typename _Dst_t>
idx_dev_t& operator>> (_Dst_t* dst) = delete;
idx_dev_t& operator>> (data_t& dst) {
get_ (dst, cursor_());
return *this;
}
template <typename _Src_t>
idx_dev_t& operator<< (_Src_t& src) {
static_assert ((sizeof (_Src_t)%sizeof(data_t) == 0),
"Source size must be an integer multiple of device's data size");
put_ (reinterpret_cast<data_t*>(&src), sizeof (_Src_t)/sizeof(data_t), cursor_());
return *this;
}
template <typename _Src_t>
idx_dev_t& operator<< (_Src_t* src) = delete;
idx_dev_t& operator<< (const data_t& src) {
put_ (src, cursor_());
return *this;
}
data_t& operator[] (const idx_t idx) {
iterator it(this, idx);
return *it;
}
public:
using iterator = idxdev_it <idx_dev_t, data_t*, N>;
using const_iterator = idxdev_it <idx_dev_t, const data_t*, N>;
iterator begin () noexcept { return iterator(this, iterator::beg); }
const_iterator begin () const noexcept { return const_iterator(this, iterator::beg); }
const_iterator cbegin () const noexcept { return const_iterator(this, iterator::beg); }
iterator end () noexcept { return iterator(this, iterator::eos); }
const_iterator end () const noexcept { return const_iterator(this, iterator::eos); }
const_iterator cend () const noexcept { return const_iterator(this, iterator::eos); }
};
#if defined _utl_have_concepts
template <typename _Tp>
concept bool Idx_dev = requires (_Tp t, const _Tp ct, typename _Tp::data_type v) {
// Object type
// requires std::is_default_constructible<_Tp>::value;
requires !std::is_copy_constructible<_Tp>::value;
requires !std::is_copy_assignable<_Tp>::value;
// Methods
{t.get(v, 0)} -> size_t;
{t.get(&v, 1, 0)} -> size_t;
{t.put(v, 0)} -> size_t;
{t.put(&v, 1, 0)} -> size_t;
// Operators
t >> v;
t << v;
{t[typename _Tp::idx_type{}]} -> typename _Tp::data_type&;
// Iterators
requires idxdev_iterator_c<typename _Tp::iterator>;
typename _Tp::const_iterator; //XXX: change to concept: is_idxdev_iterator<_Tp>
//requires idxdev_iterator_c<typename _Tp::const_iterator>;
{ t.begin()} -> typename _Tp::iterator;
// {ct.begin()} -> typename _Tp::const_iterator;
// { t.cbegin()} -> typename _Tp::const_iterator;
{ t.end()} -> typename _Tp::iterator;
// {ct.end()} -> typename _Tp::const_iterator;
// { t.cend()} -> typename _Tp::const_iterator;
};
#else
namespace idx_dev_details {
using std::declval;
// main api members
template <class _Tp> using try_get1_t = decltype (declval<_Tp>().get (declval<typename _Tp::data_type&>()));
template <class _Tp> using try_get2_t = decltype (declval<_Tp>().get (declval<typename _Tp::data_type*>(), declval<size_t>()));
// operators
//template <class _Tp> using try_extract_t= decltype (declval<_Tp>() >> declval<typename _Tp::data_type&>());
// iterator members
template <class _Tp> using try_begin_t = decltype (declval<_Tp>().begin());
template <class _Tp> using tryc_begin_t = decltype (declval<const _Tp>().begin());
template <class _Tp> using try_cbegin_t = decltype (declval<const _Tp>().cbegin());
template <class _Tp> using try_end_t = decltype (declval<_Tp>().begin());
template <class _Tp> using tryc_end_t = decltype (declval<const _Tp>().begin());
template <class _Tp> using try_cend_t = decltype (declval<const _Tp>().cend());
template <typename _Tp, typename =void>
struct is_idx_dev_ : false_ {};
template <typename _Tp>
struct is_idx_dev_ <_Tp,
void_t <
typename _Tp::data_type,
typename _Tp::pointer_type,
typename _Tp::iterator,
typename _Tp::const_iterator,
use_if_same_t <try_get1_t <_Tp>, size_t>,
use_if_same_t <try_get2_t <_Tp>, size_t>,
//if_same_t <try_extract_t<_Tp>,typename _Tp&>,
use_if_same_t <try_begin_t<_Tp>, typename _Tp::iterator>,
use_if_same_t <tryc_begin_t<_Tp>, typename _Tp::const_iterator>,
use_if_same_t <try_cbegin_t<_Tp>, typename _Tp::const_iterator>,
use_if_same_t <try_end_t<_Tp>, typename _Tp::iterator>,
use_if_same_t <tryc_end_t<_Tp>, typename _Tp::const_iterator>,
use_if_same_t <try_cend_t<_Tp>, typename _Tp::const_iterator>
>
> : true_ {};
}
template <typename _Tp>
constexpr bool Idx_dev = idx_dev_details::is_idx_dev_ <_Tp>::value;
#endif
}
#endif /* #ifndef __utl_dev_idx_dev_h__ */
utl::idx_dev< virtual_tag, data_t, idx_t, N >::idx_type
idx_t idx_type
Definition: idx_dev.h:263
meta.h
Include all meta library.
utl::idx_dev_details::is_idx_dev_
Primary template to catch any non input device types.
Definition: idx_dev.h:495
utl::idx_dev< virtual_tag, data_t, idx_t, N >::cursor
idx_t cursor(idx_t idx)
Set the cursor position.
Definition: idx_dev.h:355
utl::idx_dev< virtual_tag, data_t, idx_t, N >::put
size_t put(const data_t &data, idx_t cursor)
Put interface. This function should send a single data_t object to device.
Definition: idx_dev.h:328
utl::idx_dev::get_
size_t get_(data_t *data, size_t n, idx_t idx)
Definition: idx_dev.h:83
utl::meta::void_t
void void_t
void_t type alias
Definition: detection.h:55
utl::idx_dev::put
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.
Definition: idx_dev.h:141
utl::idx_dev< virtual_tag, data_t, idx_t, N >
A virtual base class specialization.
Definition: idx_dev.h:256
utl::idx_dev::cursor
idx_t cursor() const
Return the current cursor position.
Definition: idx_dev.h:149
utl::idx_dev< virtual_tag, data_t, idx_t, N >::begin
const_iterator begin() const noexcept
Definition: idx_dev.h:434
utl::idx_dev_details::try_begin_t
decltype(declval< _Tp >().begin()) try_begin_t
Definition: idx_dev.h:486
utl::idx_dev< virtual_tag, data_t, idx_t, N >::begin
iterator begin() noexcept
.begin implementation
Definition: idx_dev.h:433
utl::idx_dev::idx_dev
idx_dev()=default
A default constructor from derived only.
utl::idx_dev::iterator
idxdev_it< idx_dev_t, data_t *, N > iterator
Iterator.
Definition: idx_dev.h:230
utl::idx_dev::operator[]
data_t & operator[](const idx_t idx)
Definition: idx_dev.h:219
utl::meta::true_
bool_< true > true_
The type used as a compile-time boolean with true value.
Definition: integral.h:68
crtp.h
utl::idx_dev::operator=
idx_dev_t & operator=(const idx_dev_t &)=delete
utl::idx_dev< virtual_tag, data_t, idx_t, N >::cursor
idx_t cursor() const
Return the current cursor position.
Definition: idx_dev.h:348
utl::idx_dev::put_
size_t put_(const data_t &data, idx_t idx)
Definition: idx_dev.h:84
utl::idx_dev< virtual_tag, data_t, idx_t, N >::cbegin
const_iterator cbegin() const noexcept
Definition: idx_dev.h:435
utl::idx_dev::put
size_t put(const data_t &data, idx_t cursor)
Put interface. This function should send a single data_t object to device.
Definition: idx_dev.h:129
utl::idx_dev::get_
size_t get_(data_t &data, idx_t idx)
Definition: idx_dev.h:82
utl::use_if_same_t
meta::eval< meta::enable_if< meta::same_< _T1, _T2 >::value, _Ret > > use_if_same_t
Definition: stl.h:55
utl::idx_dev_details::tryc_begin_t
decltype(declval< const _Tp >().begin()) tryc_begin_t
Definition: idx_dev.h:487
utl::idx_dev::_CRTP_IMPL
_CRTP_IMPL(impl_t)
utl::idx_dev::begin
iterator begin() noexcept
.begin implementation
Definition: idx_dev.h:234
utl::idx_dev< virtual_tag, data_t, idx_t, N >::end
const_iterator end() const noexcept
Definition: idx_dev.h:439
utl::idx_dev< virtual_tag, data_t, idx_t, N >::pointer_type
data_t * pointer_type
Definition: idx_dev.h:262
utl::idx_dev
Abstract base class for indexed devices.
Definition: idx_dev.h:56
utl::idx_dev_details::try_cend_t
decltype(declval< const _Tp >().cend()) try_cend_t
Definition: idx_dev.h:491
utl::meta::false_
bool_< false > false_
The type used as a compile-time boolean with false value.
Definition: integral.h:69
utl::idx_dev_details::try_get2_t
decltype(declval< _Tp >().get(declval< typename _Tp::data_type * >(), declval< size_t >())) try_get2_t
Definition: idx_dev.h:482
utl::idx_dev< virtual_tag, data_t, idx_t, N >::end
iterator end() noexcept
Definition: idx_dev.h:438
utl::size_t
std::size_t size_t
Definition: types.h:37
utl
STL&#39;s core language concepts.
Definition: _1wire.h:30
utl::idx_dev::end
iterator end() noexcept
Definition: idx_dev.h:239
utl::idx_dev::idx_type
idx_t idx_type
Definition: idx_dev.h:64
utl::idx_dev::idx_dev_t
idx_dev< impl_t, data_t, idx_t, N > idx_dev_t
class type syntactic sugar
Definition: idx_dev.h:58
utl::idx_dev_details::tryc_end_t
decltype(declval< const _Tp >().begin()) tryc_end_t
Definition: idx_dev.h:490
utl::idx_dev_details::try_end_t
decltype(declval< _Tp >().begin()) try_end_t
Definition: idx_dev.h:489
utl::idx_dev::cend
const_iterator cend() const noexcept
Definition: idx_dev.h:241
utl::idx_dev_details::try_cbegin_t
decltype(declval< const _Tp >().cbegin()) try_cbegin_t
Definition: idx_dev.h:488
utl::idx_dev< virtual_tag, data_t, idx_t, N >::put
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.
Definition: idx_dev.h:340
utl::idx_dev::operator>>
idx_dev_t & operator>>(_Dst_t &dst)
Template operator>> implementation for for all by value/ref parameters.
Definition: idx_dev.h:170
utl::idx_dev< virtual_tag, data_t, idx_t, N >::cend
const_iterator cend() const noexcept
Definition: idx_dev.h:440
utl::idx_dev< virtual_tag, data_t, idx_t, N >::iterator
idxdev_it< idx_dev_t, data_t *, N > iterator
Iterator.
Definition: idx_dev.h:429
utl::idx_dev::cursor_
void cursor_(idx_t idx)
Definition: idx_dev.h:87
dev_iterators.h
Iterator collection for devices.
utl::idx_dev< virtual_tag, data_t, idx_t, N >::const_iterator
idxdev_it< idx_dev_t, const data_t *, N > const_iterator
Const iterator.
Definition: idx_dev.h:430
utl::idx_dev_details::try_get1_t
decltype(declval< _Tp >().get(declval< typename _Tp::data_type & >())) try_get1_t
Definition: idx_dev.h:481
utl::idx_dev::put_
size_t put_(const data_t *data, size_t n, idx_t idx)
Definition: idx_dev.h:85
utl::idx_dev::end
const_iterator end() const noexcept
Definition: idx_dev.h:240
utl::idx_dev::~idx_dev
~idx_dev()=default
Allow destructor from derived only.
utl::Idx_dev
constexpr bool Idx_dev
Definition: idx_dev.h:523
utl::virtual_tag
virtual support tag type
Definition: crtp.h:40
utl::idx_dev::cbegin
const_iterator cbegin() const noexcept
Definition: idx_dev.h:236
utl::idx_dev::cursor
idx_t cursor(idx_t idx)
Set the cursor position.
Definition: idx_dev.h:156
utl::idx_dev::cursor_
idx_t cursor_() const
Definition: idx_dev.h:86
utl::idx_dev< virtual_tag, data_t, idx_t, N >::data_type
data_t data_type
Export types as index device concept demands.
Definition: idx_dev.h:261
utl::idx_dev::operator<<
idx_dev_t & operator<<(_Src_t &src)
Template operator<< implementation for for all by value/ref parameters.
Definition: idx_dev.h:198
utl::idx_dev::const_iterator
idxdev_it< idx_dev_t, const data_t *, N > const_iterator
Const iterator.
Definition: idx_dev.h:231
utl::idx_dev::data_type
data_t data_type
Export types as index device concept demands.
Definition: idx_dev.h:62
impl.h
Implementation detail main forward header.
utl::idx_dev::pointer_type
data_t * pointer_type
Definition: idx_dev.h:63
utl::idx_dev::begin
const_iterator begin() const noexcept
Definition: idx_dev.h:235