21 #ifndef __utl_dev_out_dev_h__ 22 #define __utl_dev_out_dev_h__ 53 template <
typename impl_t,
typename data_t,
size_t streamsize =0>
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);
99 size_t put (
const data_t& data) {
111 size_t put (
const data_t* data,
size_t n) {
112 return put_ (data, n);
130 template <
typename _Src_t>
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));
138 template <
typename _Src_t>
176 template <
typename data_t,
size_t streamsize>
214 virtual size_t put_ (
const data_t& data) = 0;
224 virtual size_t put_ (
const data_t* data,
size_t n) = 0;
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); }
245 template <
typename _Src_t>
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));
253 template <
typename _Src_t>
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) {
292 requires !std::is_copy_constructible<_Tp>::value;
293 requires !std::is_copy_assignable<_Tp>::value;
296 {t.put(&v,
sizeof(v))} ->
size_t;
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;
311 namespace out_dev_details {
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*>(),
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());
328 template <
typename _Tp,
typename =
void>
332 template <
typename _Tp>
335 typename _Tp::data_type,
336 typename _Tp::pointer_type,
337 typename _Tp::iterator,
338 typename _Tp::const_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>,
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>
356 template <
typename _Tp>
A virtual base class specialization.
const_iterator cbegin() const noexcept
void void_t
void_t type alias
const_iterator begin() const noexcept
decltype(declval< _Tp >().put(declval< const typename _Tp::data_type * >(), declval< size_t >())) try_put2_t
size_t put(const data_t *data, size_t n)
Put interface. This function should send a stream of data_t objects to device.
out_dev< impl_t, data_t, streamsize > out_dev_t
class type syntactic sugar
decltype(declval< _Tp >().put(declval< const typename _Tp::data_type & >())) try_put1_t
meta::eval< meta::enable_if< meta::same_< _T1, _T2 >::value, _Ret > > use_if_same_t
iterator begin() noexcept
.begin implementation
decltype(declval< const _Tp >().begin()) tryc_end_t
size_t put_(const data_t &data)
outdev_it< out_dev_t, data_t *, streamsize > iterator
Iterator.
Output device iterator type. We "future call" interface methods from owner class to provide iterator ...
Primary template to catch any non output device types.
const_iterator end() const noexcept
decltype(declval< const _Tp >().cbegin()) try_cbegin_t
decltype(declval< const _Tp >().cend()) try_cend_t
STL's core language concepts.
decltype(declval< _Tp >().begin()) try_begin_t
decltype(declval< _Tp >().begin()) try_end_t
Points the first item (relative address)
size_t put(const data_t *data, size_t n)
const_iterator cend() const noexcept
size_t put(const data_t &data)
Put interface. This function should send a single data_t object to device.
outdev_it< const out_dev_t, data_t *, streamsize > const_iterator
Const iterator.
const_iterator cbegin() const noexcept
out_dev_t & operator=(const out_dev_t &)=delete
Iterator collection for devices.
iterator begin() noexcept
.begin implementation
size_t put_(const data_t *data, size_t n)
decltype(declval< const _Tp >().begin()) tryc_begin_t
out_dev_t & operator<<(_Src_t &src)
Template operator<< implementation for for all by value/ref parameters.
const_iterator cend() const noexcept
const_iterator begin() const noexcept
size_t put(const data_t &data)
~out_dev()=default
Allow destructor from derived only.
const_iterator end() const noexcept
Implementation detail main forward header.
out_dev()=default
A default constructor from derived only.
Abstract base classes for output devices.