uTL
micro Template library
out_dev.h
Go to the documentation of this file.
1 
21 #ifndef __utl_dev_out_dev_h__
22 #define __utl_dev_out_dev_h__
23 
24 #include <utl/core/impl.h>
25 #include <utl/core/crtp.h>
26 #include <utl/dev/dev_iterators.h>
27 #include <utl/meta/meta.h>
28 
29 namespace utl {
30 
35 
53  template <typename impl_t, typename data_t, size_t streamsize =0>
54  class out_dev {
55  _CRTP_IMPL(impl_t);
57 
60  public:
61  using data_type = data_t;
62  using pointer_type = data_t*;
64  using type = out_dev_t;
65 
69  protected:
71  ~out_dev () = default;
72  out_dev () = default;
73  out_dev(const out_dev_t&) = delete;
74  out_dev_t& operator= (const out_dev_t&) = delete;
75 
79  private:
80  size_t put_ (const data_t& data) { return impl().put_ (data); }
81  size_t put_ (const data_t* data, size_t n) {
82  return impl().put_ (data, n);
83  }
85 
88  public:
99  size_t put (const data_t& data) {
100  return put_ (data);
101  }
102 
111  size_t put (const data_t* data, size_t n) {
112  return put_ (data, n);
113  }
115 
119  public:
130  template <typename _Src_t>
131  out_dev_t& operator<< (_Src_t& src) {
132  static_assert ((sizeof (_Src_t)%sizeof(data_t) == 0),
133  "Source size must be an integer multiple of device's data size");
134  put_ (reinterpret_cast<data_t*>(&src), sizeof(_Src_t)/sizeof(data_t));
135  return *this;
136  }
138  template <typename _Src_t>
139  out_dev_t& operator<< (_Src_t* src) = delete;
140 
142  out_dev_t& operator<< (const data_t& src) {
143  put_ (src);
144  return *this;
145  }
147 
154 
156  iterator begin () noexcept { return iterator(this, iterator::beg); }
157  const_iterator begin () const noexcept { return const_iterator(this, iterator::beg); }
158  const_iterator cbegin () const noexcept { return const_iterator(this, iterator::beg); }
161  iterator end () noexcept { return iterator(this, iterator::eos); }
162  const_iterator end () const noexcept { return const_iterator(this, iterator::eos); }
163  const_iterator cend () const noexcept { return const_iterator(this, iterator::eos); }
166  };
167 
176  template <typename data_t, size_t streamsize>
177  class out_dev <virtual_tag, data_t, streamsize> {
179 
182  public:
183  using data_type = data_t;
184  using pointer_type = data_t*;
186  using type = out_dev_t;
187 
191  public:
193  virtual ~out_dev () = default;
194  protected:
195  out_dev () = default;
196  out_dev(const out_dev&) = delete;
197  out_dev_t& operator= (const out_dev_t&) = delete;
198 
203  private:
214  virtual size_t put_ (const data_t& data) = 0;
215 
224  virtual size_t put_ (const data_t* data, size_t n) = 0;
226 
229  public:
231  size_t put (const data_t& data) { return put_ (data); }
232  size_t put (const data_t* data, size_t n) { return put_ (data, n); }
234 
237  public:
245  template <typename _Src_t>
246  out_dev_t& operator<< (_Src_t& src) {
247  static_assert ((sizeof (_Src_t)%sizeof(data_t) == 0),
248  "Source size must be an integer multiple of device's data size");
249  put_ (reinterpret_cast<data_t*>(&src), sizeof(_Src_t)/sizeof(data_t));
250  return *this;
251  }
253  template <typename _Src_t>
254  out_dev_t& operator<< (_Src_t* src) = delete;
255 
257  out_dev_t& operator<< (const data_t& src) {
258  put_ (src);
259  return *this;
260  }
262 
269 
271  iterator begin () noexcept { return iterator(this, iterator::beg); }
272  const_iterator begin () const noexcept { return const_iterator(this, iterator::beg); }
273  const_iterator cbegin () const noexcept { return const_iterator(this, iterator::beg); }
276  iterator end () noexcept { return iterator(this, iterator::eos); }
277  const_iterator end () const noexcept { return const_iterator(this, iterator::eos); }
278  const_iterator cend () const noexcept { return const_iterator(this, iterator::eos); }
281  };
282 
283 
287  #if defined _utl_have_concepts
289  template <typename _Tp>
290  concept bool Out_dev = requires (_Tp t, const _Tp ct, typename _Tp::data_type v) {
291  // Object type
292  requires !std::is_copy_constructible<_Tp>::value;
293  requires !std::is_copy_assignable<_Tp>::value;
294  // Methods
295  {t.put(v)} -> size_t;
296  {t.put(&v, sizeof(v))} -> size_t;
297  // Operators
298  t << v;
299  // Iterators
300  typename _Tp::const_iterator;
301  requires Outdev_it<typename _Tp::iterator>;
302  requires Outdev_it<typename _Tp::const_iterator>;
303  { t.begin() } -> typename _Tp::iterator;
304  {ct.begin()} -> typename _Tp::const_iterator;
305  { t.cbegin()} -> typename _Tp::const_iterator;
306  { t.end() } -> typename _Tp::iterator;
307  {ct.end()} -> typename _Tp::const_iterator;
308  { t.cend()} -> typename _Tp::const_iterator;
309  };
310  #else
311  namespace out_dev_details {
312  using std::declval;
313 
314  template <class _Tp> using try_put1_t = decltype (declval<_Tp>().put (declval<const typename _Tp::data_type&>()));
315  template <class _Tp> using try_put2_t = decltype (declval<_Tp>().put (declval<const typename _Tp::data_type*>(),
316  declval<size_t>()));
317  // operators
318  //template <class _Tp> using try_insert_t= decltype (declval<_Tp>() << declval<typename _Tp::data_type&>());
319  // iterator members
320  template <class _Tp> using try_begin_t = decltype (declval<_Tp>().begin());
321  template <class _Tp> using tryc_begin_t = decltype (declval<const _Tp>().begin());
322  template <class _Tp> using try_cbegin_t = decltype (declval<const _Tp>().cbegin());
323  template <class _Tp> using try_end_t = decltype (declval<_Tp>().begin());
324  template <class _Tp> using tryc_end_t = decltype (declval<const _Tp>().begin());
325  template <class _Tp> using try_cend_t = decltype (declval<const _Tp>().cend());
326 
328  template <typename _Tp, typename =void>
329  struct is_out_dev_ : false_ { };
330 
332  template <typename _Tp>
333  struct is_out_dev_ <_Tp,
334  void_t <
335  typename _Tp::data_type,
336  typename _Tp::pointer_type,
337  typename _Tp::iterator,
338  typename _Tp::const_iterator,
339  use_if_same_t <try_put1_t <_Tp>, size_t>,
340  use_if_same_t <try_put2_t <_Tp>, size_t>,
341  //if_same_t <try_insert_t<_Tp>,_Tp&>,
342  use_if_same_t <try_begin_t<_Tp>, typename _Tp::iterator>,
343  use_if_same_t <tryc_begin_t<_Tp>, typename _Tp::const_iterator>,
344  use_if_same_t <try_cbegin_t<_Tp>, typename _Tp::const_iterator>,
345  use_if_same_t <try_end_t<_Tp>, typename _Tp::iterator>,
346  use_if_same_t <tryc_end_t<_Tp>, typename _Tp::const_iterator>,
347  use_if_same_t <try_cend_t<_Tp>, typename _Tp::const_iterator>
348  >
349  > : true_ { };
350  }
356  template <typename _Tp>
358  #endif
359 
362 } //namespace utl
363 
364 #endif /* #ifndef __utl_dev_out_dev_h__ */
data_t * pointer_type
Definition: out_dev.h:62
A virtual base class specialization.
Definition: out_dev.h:177
iterator end() noexcept
Definition: out_dev.h:161
Include all meta library.
const_iterator cbegin() const noexcept
Definition: out_dev.h:273
void void_t
void_t type alias
Definition: detection.h:55
const_iterator begin() const noexcept
Definition: out_dev.h:272
bool_< true > true_
The type used as a compile-time boolean with true value.
Definition: integral.h:68
_CRTP_IMPL(impl_t)
decltype(declval< _Tp >().put(declval< const typename _Tp::data_type * >(), declval< size_t >())) try_put2_t
Definition: out_dev.h:316
size_t put(const data_t *data, size_t n)
Put interface. This function should send a stream of data_t objects to device.
Definition: out_dev.h:111
out_dev< impl_t, data_t, streamsize > out_dev_t
class type syntactic sugar
Definition: out_dev.h:56
decltype(declval< _Tp >().put(declval< const typename _Tp::data_type & >())) try_put1_t
Definition: out_dev.h:314
meta::eval< meta::enable_if< meta::same_< _T1, _T2 >::value, _Ret > > use_if_same_t
Definition: stl.h:55
iterator begin() noexcept
.begin implementation
Definition: out_dev.h:156
decltype(declval< const _Tp >().begin()) tryc_end_t
Definition: out_dev.h:324
size_t put_(const data_t &data)
Definition: out_dev.h:80
outdev_it< out_dev_t, data_t *, streamsize > iterator
Iterator.
Definition: out_dev.h:152
Output device iterator type. We "future call" interface methods from owner class to provide iterator ...
Primary template to catch any non output device types.
Definition: out_dev.h:329
bool_< false > false_
The type used as a compile-time boolean with false value.
Definition: integral.h:69
const_iterator end() const noexcept
Definition: out_dev.h:277
constexpr bool Out_dev
Definition: out_dev.h:357
decltype(declval< const _Tp >().cbegin()) try_cbegin_t
Definition: out_dev.h:322
decltype(declval< const _Tp >().cend()) try_cend_t
Definition: out_dev.h:325
std::size_t size_t
Definition: types.h:37
STL&#39;s core language concepts.
Definition: _1wire.h:30
decltype(declval< _Tp >().begin()) try_begin_t
Definition: out_dev.h:320
decltype(declval< _Tp >().begin()) try_end_t
Definition: out_dev.h:323
Points the first item (relative address)
size_t put(const data_t *data, size_t n)
Definition: out_dev.h:232
const_iterator cend() const noexcept
Definition: out_dev.h:278
size_t put(const data_t &data)
Put interface. This function should send a single data_t object to device.
Definition: out_dev.h:99
outdev_it< const out_dev_t, data_t *, streamsize > const_iterator
Const iterator.
Definition: out_dev.h:153
const_iterator cbegin() const noexcept
Definition: out_dev.h:158
out_dev_t & operator=(const out_dev_t &)=delete
Iterator collection for devices.
iterator begin() noexcept
.begin implementation
Definition: out_dev.h:271
size_t put_(const data_t *data, size_t n)
Definition: out_dev.h:81
decltype(declval< const _Tp >().begin()) tryc_begin_t
Definition: out_dev.h:321
out_dev_t & operator<<(_Src_t &src)
Template operator<< implementation for for all by value/ref parameters.
Definition: out_dev.h:131
const_iterator cend() const noexcept
Definition: out_dev.h:163
virtual support tag type
Definition: crtp.h:40
const_iterator begin() const noexcept
Definition: out_dev.h:157
data_t data_type
Definition: out_dev.h:61
~out_dev()=default
Allow destructor from derived only.
const_iterator end() const noexcept
Definition: out_dev.h:162
Implementation detail main forward header.
out_dev()=default
A default constructor from derived only.
Abstract base classes for output devices.
Definition: out_dev.h:54