!Compile: Some device rework
This commit is contained in:
parent
1ac1e0bf73
commit
2f18447bca
File diff suppressed because it is too large
Load Diff
286
include/utl/dev/ostream_dev.h
Normal file
286
include/utl/dev/ostream_dev.h
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
/*!
|
||||||
|
* \file utl/dev/ostream_dev.h
|
||||||
|
* \brief Abstract base class interface for output devices of utl.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018 Christos Choutouridis
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef __utl_dev_ostream_dev_h__
|
||||||
|
#define __utl_dev_ostream_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 {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \ingroup Device Interface
|
||||||
|
* \brief Abstract base classes for output stream devices
|
||||||
|
*/
|
||||||
|
//!@{
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief
|
||||||
|
* Template base class for output stream devices using CRTP
|
||||||
|
*
|
||||||
|
* This class force a common interface for output stream devices.
|
||||||
|
* By using this common interface the class implements
|
||||||
|
* - Stream-like inserting operator
|
||||||
|
* - Output iterator
|
||||||
|
* - Const output iterator
|
||||||
|
* to inherit to implementation.
|
||||||
|
*
|
||||||
|
* \param impl_t The CRTP type (the derived/implementation class typename).
|
||||||
|
* \param data_t The devices base type of data
|
||||||
|
*/
|
||||||
|
template <typename impl_t, typename data_t>
|
||||||
|
class ostream_dev {
|
||||||
|
_CRTP_IMPL(impl_t);
|
||||||
|
using ostream_dev_t = ostream_dev <impl_t, data_t>; //!< class type syntactic sugar
|
||||||
|
|
||||||
|
//! Export types as output device concept demands
|
||||||
|
//! @{
|
||||||
|
public:
|
||||||
|
using data_type = data_t;
|
||||||
|
using pointer_type = data_t*;
|
||||||
|
//!@}
|
||||||
|
using type = ostream_dev_t; //!< Export type as identity meta-function
|
||||||
|
/*!
|
||||||
|
* \name Constructor / Destructor
|
||||||
|
*/
|
||||||
|
//!@{
|
||||||
|
protected:
|
||||||
|
~ostream_dev () = default; //!< \brief Allow destructor from derived only
|
||||||
|
ostream_dev () = default; //!< \brief A default constructor from derived only
|
||||||
|
ostream_dev(const ostream_dev_t&) = delete; //!< No copies
|
||||||
|
ostream_dev_t& operator= (const ostream_dev_t&) = delete; //!< No copy assignments
|
||||||
|
//!@}
|
||||||
|
|
||||||
|
//! \name Common output device interface requirements
|
||||||
|
//!@{
|
||||||
|
private:
|
||||||
|
size_t put_ (const data_t& data) { return impl().put_ (data); }
|
||||||
|
size_t put_ (const data_t* data, size_t n) {
|
||||||
|
return impl().put_ (data, n);
|
||||||
|
}
|
||||||
|
//!@}
|
||||||
|
/*!
|
||||||
|
* \name Common output device interface
|
||||||
|
*/
|
||||||
|
//!@{
|
||||||
|
public:
|
||||||
|
/*!
|
||||||
|
* \brief
|
||||||
|
* Put interface. This function should send a single
|
||||||
|
* data_t object to device.
|
||||||
|
* \param data The data to send
|
||||||
|
* \return The number of transmitted data items
|
||||||
|
* \note
|
||||||
|
* A successful call should return 1
|
||||||
|
*/
|
||||||
|
size_t put (const data_t& data) {
|
||||||
|
return put_ (data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief
|
||||||
|
* Put interface. This function should send a stream of
|
||||||
|
* data_t objects to device.
|
||||||
|
* \param data Pointer to buffer indenting write to device.
|
||||||
|
* \param n The number of data of type data_t to send
|
||||||
|
* \return The number of transmitted items.
|
||||||
|
*/
|
||||||
|
size_t put (const data_t* data, size_t n) {
|
||||||
|
return put_ (data, n);
|
||||||
|
}
|
||||||
|
//!@}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \name Stream operator << interface
|
||||||
|
*/
|
||||||
|
//!@{
|
||||||
|
public:
|
||||||
|
/*!
|
||||||
|
* \brief
|
||||||
|
* Template operator<< implementation for for all by value/ref parameters
|
||||||
|
* \note
|
||||||
|
* In the case _Src_t size is not an exact multiple of data_t size
|
||||||
|
* the write data will be truncated and there may be data loss.
|
||||||
|
* \param src Reference to source data
|
||||||
|
* \return Reference to this device for chaining
|
||||||
|
*/
|
||||||
|
template <typename _Src_t>
|
||||||
|
ostream_dev_t& operator<< (const _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<const data_t*>(&src), sizeof(_Src_t)/sizeof(data_t));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
//! Overload to disallow pointer types as source
|
||||||
|
template <typename _Src_t>
|
||||||
|
ostream_dev_t& operator<< (_Src_t* src) = delete;
|
||||||
|
|
||||||
|
//! Overload for single data_t object
|
||||||
|
ostream_dev_t& operator<< (const data_t& src) {
|
||||||
|
put_ (src);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
//ToDo: Add support for c-string, utl::string, ...
|
||||||
|
//!@}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \name STL-like Output iterator interface
|
||||||
|
*/
|
||||||
|
//!@{
|
||||||
|
using iterator = ostreamdev_it <ostream_dev_t, data_t>; //!< Iterator
|
||||||
|
using const_iterator = ostreamdev_it <const ostream_dev_t, data_t>; //!< Const iterator
|
||||||
|
|
||||||
|
//!@{ .begin implementation
|
||||||
|
iterator begin () noexcept { return iterator(this); }
|
||||||
|
const_iterator begin () const noexcept { return const_iterator(this); }
|
||||||
|
const_iterator cbegin () const noexcept { return const_iterator(this); }
|
||||||
|
//!@}
|
||||||
|
//!@{ .end implementation
|
||||||
|
iterator end () noexcept { return iterator(); }
|
||||||
|
const_iterator end () const noexcept { return const_iterator(); }
|
||||||
|
const_iterator cend () const noexcept { return const_iterator(); }
|
||||||
|
//!@}
|
||||||
|
//!@}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <typename data_t>
|
||||||
|
class ostream_dev<virtual_tag, data_t> {
|
||||||
|
using ostream_dev_t = ostream_dev <virtual_tag, data_t>; //!< class type syntactic sugar
|
||||||
|
|
||||||
|
//! Export types as output device concept demands
|
||||||
|
//! @{
|
||||||
|
public:
|
||||||
|
using data_type = data_t;
|
||||||
|
using pointer_type = data_t*;
|
||||||
|
//!@}
|
||||||
|
using type = ostream_dev_t; //!< Export type as identity meta-function
|
||||||
|
/*!
|
||||||
|
* \name Constructor / Destructor
|
||||||
|
*/
|
||||||
|
//!@{
|
||||||
|
public:
|
||||||
|
virtual ~ostream_dev () = default; //!< \brief Virtual destructor
|
||||||
|
protected:
|
||||||
|
ostream_dev () = default; //!< \brief A default constructor from derived only
|
||||||
|
ostream_dev(const ostream_dev_t&) = delete; //!< No copies
|
||||||
|
ostream_dev_t& operator= (const ostream_dev_t&) = delete; //!< No copy assignments
|
||||||
|
//!@}
|
||||||
|
|
||||||
|
//! \name Common output device interface requirements
|
||||||
|
//!@{
|
||||||
|
private:
|
||||||
|
virtual size_t put_ (const data_t& data) =0;
|
||||||
|
virtual size_t put_ (const data_t* data, size_t n) =0;
|
||||||
|
//!@}
|
||||||
|
/*!
|
||||||
|
* \name Common output device interface
|
||||||
|
*/
|
||||||
|
//!@{
|
||||||
|
public:
|
||||||
|
/*!
|
||||||
|
* \brief
|
||||||
|
* Put interface. This function should send a single
|
||||||
|
* data_t object to device.
|
||||||
|
* \param data The data to send
|
||||||
|
* \return The number of transmitted data items
|
||||||
|
* \note
|
||||||
|
* A successful call should return 1
|
||||||
|
*/
|
||||||
|
size_t put (const data_t& data) {
|
||||||
|
return put_ (data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief
|
||||||
|
* Put interface. This function should send a stream of
|
||||||
|
* data_t objects to device.
|
||||||
|
* \param data Pointer to buffer indenting write to device.
|
||||||
|
* \param n The number of data of type data_t to send
|
||||||
|
* \return The number of transmitted items.
|
||||||
|
*/
|
||||||
|
size_t put (const data_t* data, size_t n) {
|
||||||
|
return put_ (data, n);
|
||||||
|
}
|
||||||
|
//!@}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \name Stream operator << interface
|
||||||
|
*/
|
||||||
|
//!@{
|
||||||
|
public:
|
||||||
|
/*!
|
||||||
|
* \brief
|
||||||
|
* Template operator<< implementation for for all by value/ref parameters
|
||||||
|
* \note
|
||||||
|
* In the case _Src_t size is not an exact multiple of data_t size
|
||||||
|
* the write data will be truncated and there may be data loss.
|
||||||
|
* \param src Reference to source data
|
||||||
|
* \return Reference to this device for chaining
|
||||||
|
*/
|
||||||
|
template <typename _Src_t>
|
||||||
|
ostream_dev_t& operator<< (const _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<const data_t*>(&src), sizeof(_Src_t)/sizeof(data_t));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
//! Overload to disallow pointer types as source
|
||||||
|
template <typename _Src_t>
|
||||||
|
ostream_dev_t& operator<< (_Src_t* src) = delete;
|
||||||
|
|
||||||
|
//! Overload for single data_t object
|
||||||
|
ostream_dev_t& operator<< (const data_t& src) {
|
||||||
|
put_ (src);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
//!@}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \name STL-like Output iterator interface
|
||||||
|
*/
|
||||||
|
//!@{
|
||||||
|
using iterator = ostreamdev_it <ostream_dev_t, data_t>; //!< Iterator
|
||||||
|
using const_iterator = ostreamdev_it <const ostream_dev_t, data_t>; //!< Const iterator
|
||||||
|
|
||||||
|
//!@{ .begin implementation
|
||||||
|
iterator begin () noexcept { return iterator(this); }
|
||||||
|
const_iterator begin () const noexcept { return const_iterator(this); }
|
||||||
|
const_iterator cbegin () const noexcept { return const_iterator(this); }
|
||||||
|
//!@}
|
||||||
|
//!@{ .end implementation
|
||||||
|
iterator end () noexcept { return iterator(); }
|
||||||
|
const_iterator end () const noexcept { return const_iterator(); }
|
||||||
|
const_iterator cend () const noexcept { return const_iterator(); }
|
||||||
|
//!@}
|
||||||
|
//!@}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//!@}
|
||||||
|
} //namespace utl
|
||||||
|
|
||||||
|
#endif /* #ifndef __utl_dev_out_dev_h__ */
|
@ -21,16 +21,16 @@
|
|||||||
#ifndef __utl_dev_out_dev_h__
|
#ifndef __utl_dev_out_dev_h__
|
||||||
#define __utl_dev_out_dev_h__
|
#define __utl_dev_out_dev_h__
|
||||||
|
|
||||||
#include <utl/impl/impl.h>
|
#include <utl/core/impl.h>
|
||||||
#include <utl/helper/crtp.h>
|
#include <utl/core/crtp.h>
|
||||||
#include <utl/meta/sfinae.h>
|
|
||||||
#include <utl/dev/dev_iterators.h>
|
#include <utl/dev/dev_iterators.h>
|
||||||
|
#include <utl/meta/meta.h>
|
||||||
|
|
||||||
namespace utl {
|
namespace utl {
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \ingroup Device Interface
|
* \ingroup Device Interface
|
||||||
* \brief Abstract base class for output devices
|
* \brief Abstract base classes for output devices
|
||||||
*/
|
*/
|
||||||
//!@{
|
//!@{
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ namespace utl {
|
|||||||
put_ (reinterpret_cast<data_t*>(&src), sizeof(_Src_t)/sizeof(data_t));
|
put_ (reinterpret_cast<data_t*>(&src), sizeof(_Src_t)/sizeof(data_t));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
//! specialization to disallow pointer types as source
|
//! Overload to disallow pointer types as source
|
||||||
template <typename _Src_t>
|
template <typename _Src_t>
|
||||||
out_dev_t& operator<< (_Src_t* src) = delete;
|
out_dev_t& operator<< (_Src_t* src) = delete;
|
||||||
|
|
||||||
@ -150,7 +150,7 @@ namespace utl {
|
|||||||
*/
|
*/
|
||||||
//!@{
|
//!@{
|
||||||
using iterator = outdev_it <out_dev_t, data_t*, streamsize>; //!< Iterator
|
using iterator = outdev_it <out_dev_t, data_t*, streamsize>; //!< Iterator
|
||||||
using const_iterator = outdev_it <out_dev_t, const data_t*, streamsize>; //!< Const iterator
|
using const_iterator = outdev_it <const out_dev_t, data_t*, streamsize>; //!< Const iterator
|
||||||
|
|
||||||
//!@{ .begin implementation
|
//!@{ .begin implementation
|
||||||
iterator begin () noexcept { return iterator(this, iterator::beg); }
|
iterator begin () noexcept { return iterator(this, iterator::beg); }
|
||||||
@ -249,7 +249,7 @@ namespace utl {
|
|||||||
put_ (reinterpret_cast<data_t*>(&src), sizeof(_Src_t)/sizeof(data_t));
|
put_ (reinterpret_cast<data_t*>(&src), sizeof(_Src_t)/sizeof(data_t));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
//! specialization to disallow pointer types as source
|
//! Overload to disallow pointer types as source
|
||||||
template <typename _Src_t>
|
template <typename _Src_t>
|
||||||
out_dev_t& operator<< (_Src_t* src) = delete;
|
out_dev_t& operator<< (_Src_t* src) = delete;
|
||||||
|
|
||||||
@ -265,7 +265,7 @@ namespace utl {
|
|||||||
*/
|
*/
|
||||||
//!@{
|
//!@{
|
||||||
using iterator = outdev_it <out_dev_t, data_t*, streamsize>; //!< Iterator
|
using iterator = outdev_it <out_dev_t, data_t*, streamsize>; //!< Iterator
|
||||||
using const_iterator = outdev_it <out_dev_t, const data_t*, streamsize>; //!< Const iterator
|
using const_iterator = outdev_it <const out_dev_t, data_t*, streamsize>; //!< Const iterator
|
||||||
|
|
||||||
//!@{ .begin implementation
|
//!@{ .begin implementation
|
||||||
iterator begin () noexcept { return iterator(this, iterator::beg); }
|
iterator begin () noexcept { return iterator(this, iterator::beg); }
|
||||||
@ -289,7 +289,6 @@ namespace utl {
|
|||||||
template <typename _Tp>
|
template <typename _Tp>
|
||||||
concept bool Out_dev = requires (_Tp t, const _Tp ct, typename _Tp::data_type v) {
|
concept bool Out_dev = requires (_Tp t, const _Tp ct, typename _Tp::data_type v) {
|
||||||
// Object type
|
// Object type
|
||||||
// requires std::is_default_constructible<_Tp>::value;
|
|
||||||
requires !std::is_copy_constructible<_Tp>::value;
|
requires !std::is_copy_constructible<_Tp>::value;
|
||||||
requires !std::is_copy_assignable<_Tp>::value;
|
requires !std::is_copy_assignable<_Tp>::value;
|
||||||
// Methods
|
// Methods
|
||||||
@ -298,15 +297,15 @@ namespace utl {
|
|||||||
// Operators
|
// Operators
|
||||||
t << v;
|
t << v;
|
||||||
// Iterators
|
// Iterators
|
||||||
typename _Tp::const_iterator; //XXX: change to concept: is_idxdev_iterator<_Tp>
|
typename _Tp::const_iterator;
|
||||||
requires Outdev_it<typename _Tp::iterator>;
|
requires Outdev_it<typename _Tp::iterator>;
|
||||||
// requires Outdev_it<typename _Tp::const_iterator>;
|
requires Outdev_it<typename _Tp::const_iterator>;
|
||||||
{ t.begin() } -> typename _Tp::iterator;
|
{ t.begin() } -> typename _Tp::iterator;
|
||||||
{ct.begin()} -> typename _Tp::const_iterator;
|
{ct.begin()} -> typename _Tp::const_iterator;
|
||||||
// { t.cbegin()} -> typename _Tp::const_iterator;
|
{ t.cbegin()} -> typename _Tp::const_iterator;
|
||||||
{ t.end() } -> typename _Tp::iterator;
|
{ t.end() } -> typename _Tp::iterator;
|
||||||
// {ct.end()} -> typename _Tp::const_iterator;
|
{ct.end()} -> typename _Tp::const_iterator;
|
||||||
// { t.cend()} -> typename _Tp::const_iterator;
|
{ t.cend()} -> typename _Tp::const_iterator;
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
namespace out_dev_details {
|
namespace out_dev_details {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user