uTL
micro Template library
idx_dev.h
Go to the documentation of this file.
1 
22 #ifndef __utl_dev_idx_dev_h__
23 #define __utl_dev_idx_dev_h__
24 
25 #include <utl/core/impl.h>
26 #include <utl/core/crtp.h>
27 #include <utl/dev/dev_iterators.h>
28 #include <utl/meta/meta.h>
29 
30 namespace utl {
31 
36 
55  template <typename impl_t, typename data_t, typename idx_t, size_t N>
56  class idx_dev {
57  _CRTP_IMPL(impl_t);
59 
61  public:
62  using data_type = data_t;
63  using pointer_type= data_t*;
64  using idx_type = idx_t;
66  using type = idx_dev_t;
67 
71  protected:
73  ~idx_dev () = default;
74  idx_dev () = default;
75  idx_dev(const idx_dev_t&) = delete;
76  idx_dev_t& operator= (const idx_dev_t&) = delete;
77 
81  private:
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); }
89 
93  public:
104  size_t get (data_t& data, idx_t cursor) {
105  return get_ (data, cursor);
106  }
107 
116  size_t get (data_t* data, size_t n, idx_t cursor) {
117  return get_ (data, n, cursor);
118  }
119 
129  size_t put (const data_t& data, idx_t cursor) {
130  return put_ (data, cursor);
131  }
132 
141  size_t put (const data_t* data, size_t n, idx_t cursor) {
142  return put_ (data, n, cursor);
143  }
144 
149  idx_t cursor () const { return cursor_(); }
156  idx_t cursor (idx_t idx) { return cursor_(idx); }
158 
162 
169  template <typename _Dst_t>
170  idx_dev_t& operator>> (_Dst_t& dst) {
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_());
174  return *this;
175  }
177  template <typename _Dst_t>
178  idx_dev_t& operator>> (_Dst_t* dst) = delete;
179 
181  idx_dev_t& operator>> (data_t& dst) {
182  get_ (dst, cursor_());
183  return *this;
184  }
186 
190 
197  template <typename _Src_t>
198  idx_dev_t& operator<< (_Src_t& src) {
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_());
202  return *this;
203  }
205  template <typename _Src_t>
206  idx_dev_t& operator<< (_Src_t* src) = delete;
207 
209  idx_dev_t& operator<< (const data_t& src) {
210  put_ (src, cursor_());
211  return *this;
212  }
214 
218  data_t& operator[] (const idx_t idx) {
220  iterator it(this, idx);
221  return *it;
222  }
224 
228  public:
230  using iterator = idxdev_it <idx_dev_t, data_t*, N>;
231  using const_iterator = idxdev_it <idx_dev_t, const data_t*, N>;
232 
234  iterator begin () noexcept { return iterator(this, iterator::beg); }
235  const_iterator begin () const noexcept { return const_iterator(this, iterator::beg); }
236  const_iterator cbegin () const noexcept { return const_iterator(this, iterator::beg); }
239  iterator end () noexcept { return iterator(this, iterator::eos); }
240  const_iterator end () const noexcept { return const_iterator(this, iterator::eos); }
241  const_iterator cend () const noexcept { return const_iterator(this, iterator::eos); }
244  };
245 
246 
255  template <typename data_t, typename idx_t, size_t N>
256  class idx_dev <virtual_tag, data_t, idx_t, N> {
258 
260  public:
261  using data_type = data_t;
262  using pointer_type= data_t*;
263  using idx_type = idx_t;
265  using type = idx_dev_t;
266 
270  public:
272  virtual ~idx_dev () = default;
273  protected:
274  idx_dev () = default;
275  idx_dev(const idx_dev_t&) = delete;
276  idx_dev_t& operator= (const idx_dev_t&) = delete;
277 
280  private:
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;
288 
292  public:
303  size_t get (data_t& data, idx_t cursor) {
304  return get_ (data, cursor);
305  }
306 
315  size_t get (data_t* data, size_t n, idx_t cursor) {
316  return get_ (data, n, cursor);
317  }
318 
328  size_t put (const data_t& data, idx_t cursor) {
329  return put_ (data, cursor);
330  }
331 
340  size_t put (const data_t* data, size_t n, idx_t cursor) {
341  return put_ (data, n, cursor);
342  }
343 
348  idx_t cursor () const { return cursor_(); }
355  idx_t cursor (idx_t idx) { return cursor_(idx); }
357 
361 
368  template <typename _Dst_t>
369  idx_dev_t& operator>> (_Dst_t& dst) {
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_());
373  return *this;
374  }
376  template <typename _Dst_t>
377  idx_dev_t& operator>> (_Dst_t* dst) = delete;
378 
380  idx_dev_t& operator>> (data_t& dst) {
381  get_ (dst, cursor_());
382  return *this;
383  }
385 
389 
396  template <typename _Src_t>
397  idx_dev_t& operator<< (_Src_t& src) {
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_());
401  return *this;
402  }
404  template <typename _Src_t>
405  idx_dev_t& operator<< (_Src_t* src) = delete;
406 
408  idx_dev_t& operator<< (const data_t& src) {
409  put_ (src, cursor_());
410  return *this;
411  }
413 
417  data_t& operator[] (const idx_t idx) {
419  iterator it(this, idx);
420  return *it;
421  }
423 
427  public:
429  using iterator = idxdev_it <idx_dev_t, data_t*, N>;
430  using const_iterator = idxdev_it <idx_dev_t, const data_t*, N>;
431 
433  iterator begin () noexcept { return iterator(this, iterator::beg); }
434  const_iterator begin () const noexcept { return const_iterator(this, iterator::beg); }
435  const_iterator cbegin () const noexcept { return const_iterator(this, iterator::beg); }
438  iterator end () noexcept { return iterator(this, iterator::eos); }
439  const_iterator end () const noexcept { return const_iterator(this, iterator::eos); }
440  const_iterator cend () const noexcept { return const_iterator(this, iterator::eos); }
443  };
444 
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) {
452  // Object type
453  // requires std::is_default_constructible<_Tp>::value;
454  requires !std::is_copy_constructible<_Tp>::value;
455  requires !std::is_copy_assignable<_Tp>::value;
456  // Methods
457  {t.get(v, 0)} -> size_t;
458  {t.get(&v, 1, 0)} -> size_t;
459  {t.put(v, 0)} -> size_t;
460  {t.put(&v, 1, 0)} -> size_t;
461  // Operators
462  t >> v;
463  t << v;
464  {t[typename _Tp::idx_type{}]} -> typename _Tp::data_type&;
465  // Iterators
466  requires idxdev_iterator_c<typename _Tp::iterator>;
467  typename _Tp::const_iterator; //XXX: change to concept: is_idxdev_iterator<_Tp>
468  //requires idxdev_iterator_c<typename _Tp::const_iterator>;
469  { t.begin()} -> typename _Tp::iterator;
470  // {ct.begin()} -> typename _Tp::const_iterator;
471  // { t.cbegin()} -> typename _Tp::const_iterator;
472  { t.end()} -> typename _Tp::iterator;
473  // {ct.end()} -> typename _Tp::const_iterator;
474  // { t.cend()} -> typename _Tp::const_iterator;
475  };
476  #else
477  namespace idx_dev_details {
478  using std::declval;
479 
480  // main api members
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>()));
483  // operators
484  //template <class _Tp> using try_extract_t= decltype (declval<_Tp>() >> declval<typename _Tp::data_type&>());
485  // iterator members
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());
492 
494  template <typename _Tp, typename =void>
495  struct is_idx_dev_ : false_ {};
496 
498  template <typename _Tp>
499  struct is_idx_dev_ <_Tp,
500  void_t <
501  typename _Tp::data_type,
502  typename _Tp::pointer_type,
503  typename _Tp::iterator,
504  typename _Tp::const_iterator,
505  use_if_same_t <try_get1_t <_Tp>, size_t>,
506  use_if_same_t <try_get2_t <_Tp>, size_t>,
507  //if_same_t <try_extract_t<_Tp>,typename _Tp&>,
508  use_if_same_t <try_begin_t<_Tp>, typename _Tp::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>,
511  use_if_same_t <try_end_t<_Tp>, typename _Tp::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>
514  >
515  > : true_ {};
516  }
522  template <typename _Tp>
524  #endif
525 
527 }
529 
530 #endif /* #ifndef __utl_dev_idx_dev_h__ */
Include all meta library.
Primary template to catch any non input device types.
Definition: idx_dev.h:495
idx_t cursor(idx_t idx)
Set the cursor position.
Definition: idx_dev.h:355
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
size_t get_(data_t *data, size_t n, idx_t idx)
Definition: idx_dev.h:83
void void_t
void_t type alias
Definition: detection.h:55
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
A virtual base class specialization.
Definition: idx_dev.h:256
idx_t cursor() const
Return the current cursor position.
Definition: idx_dev.h:149
const_iterator begin() const noexcept
Definition: idx_dev.h:434
decltype(declval< _Tp >().begin()) try_begin_t
Definition: idx_dev.h:486
iterator begin() noexcept
.begin implementation
Definition: idx_dev.h:433
idx_dev()=default
A default constructor from derived only.
idxdev_it< idx_dev_t, data_t *, N > iterator
Iterator.
Definition: idx_dev.h:230
data_t & operator[](const idx_t idx)
Definition: idx_dev.h:219
bool_< true > true_
The type used as a compile-time boolean with true value.
Definition: integral.h:68
idx_dev_t & operator=(const idx_dev_t &)=delete
idx_t cursor() const
Return the current cursor position.
Definition: idx_dev.h:348
size_t put_(const data_t &data, idx_t idx)
Definition: idx_dev.h:84
const_iterator cbegin() const noexcept
Definition: idx_dev.h:435
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
size_t get_(data_t &data, idx_t idx)
Definition: idx_dev.h:82
meta::eval< meta::enable_if< meta::same_< _T1, _T2 >::value, _Ret > > use_if_same_t
Definition: stl.h:55
decltype(declval< const _Tp >().begin()) tryc_begin_t
Definition: idx_dev.h:487
_CRTP_IMPL(impl_t)
iterator begin() noexcept
.begin implementation
Definition: idx_dev.h:234
const_iterator end() const noexcept
Definition: idx_dev.h:439
Abstract base class for indexed devices.
Definition: idx_dev.h:56
decltype(declval< const _Tp >().cend()) try_cend_t
Definition: idx_dev.h:491
bool_< false > false_
The type used as a compile-time boolean with false value.
Definition: integral.h:69
decltype(declval< _Tp >().get(declval< typename _Tp::data_type * >(), declval< size_t >())) try_get2_t
Definition: idx_dev.h:482
std::size_t size_t
Definition: types.h:37
STL&#39;s core language concepts.
Definition: _1wire.h:30
iterator end() noexcept
Definition: idx_dev.h:239
idx_t idx_type
Definition: idx_dev.h:64
idx_dev< impl_t, data_t, idx_t, N > idx_dev_t
class type syntactic sugar
Definition: idx_dev.h:58
decltype(declval< const _Tp >().begin()) tryc_end_t
Definition: idx_dev.h:490
decltype(declval< _Tp >().begin()) try_end_t
Definition: idx_dev.h:489
const_iterator cend() const noexcept
Definition: idx_dev.h:241
decltype(declval< const _Tp >().cbegin()) try_cbegin_t
Definition: idx_dev.h:488
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
idx_dev_t & operator>>(_Dst_t &dst)
Template operator>> implementation for for all by value/ref parameters.
Definition: idx_dev.h:170
const_iterator cend() const noexcept
Definition: idx_dev.h:440
idxdev_it< idx_dev_t, data_t *, N > iterator
Iterator.
Definition: idx_dev.h:429
void cursor_(idx_t idx)
Definition: idx_dev.h:87
Iterator collection for devices.
idxdev_it< idx_dev_t, const data_t *, N > const_iterator
Const iterator.
Definition: idx_dev.h:430
decltype(declval< _Tp >().get(declval< typename _Tp::data_type & >())) try_get1_t
Definition: idx_dev.h:481
size_t put_(const data_t *data, size_t n, idx_t idx)
Definition: idx_dev.h:85
const_iterator end() const noexcept
Definition: idx_dev.h:240
~idx_dev()=default
Allow destructor from derived only.
constexpr bool Idx_dev
Definition: idx_dev.h:523
virtual support tag type
Definition: crtp.h:40
const_iterator cbegin() const noexcept
Definition: idx_dev.h:236
idx_t cursor(idx_t idx)
Set the cursor position.
Definition: idx_dev.h:156
idx_t cursor_() const
Definition: idx_dev.h:86
data_t data_type
Export types as index device concept demands.
Definition: idx_dev.h:261
idx_dev_t & operator<<(_Src_t &src)
Template operator<< implementation for for all by value/ref parameters.
Definition: idx_dev.h:198
idxdev_it< idx_dev_t, const data_t *, N > const_iterator
Const iterator.
Definition: idx_dev.h:231
data_t data_type
Export types as index device concept demands.
Definition: idx_dev.h:62
Implementation detail main forward header.
data_t * pointer_type
Definition: idx_dev.h:63
const_iterator begin() const noexcept
Definition: idx_dev.h:235