endian_types использует span

This commit is contained in:
Andrei Astafev 2020-05-15 19:03:14 +03:00
parent dfaa03647f
commit 24cb2afb8e
3 changed files with 195 additions and 191 deletions

View File

@ -10,6 +10,7 @@ set(TRGT_cpp
set(TRGT_hpp
${CMAKE_CURRENT_SOURCE_DIR}/config.hpp
${CMAKE_CURRENT_SOURCE_DIR}/limits.hpp
${CMAKE_CURRENT_SOURCE_DIR}/span.hpp
${CMAKE_CURRENT_SOURCE_DIR}/endian_types.hpp
${CMAKE_CURRENT_SOURCE_DIR}/enum_bitmask_operations.hpp)

View File

@ -3,6 +3,8 @@
#pragma once
#include "span.hpp"
#include <cassert>
#include <cstdint>
#include <iostream>
@ -11,10 +13,7 @@
#include <QDebug>
#endif
// Both LittleEndianType and BigEndianType are manufactured primitives
// that are essentially immutable except for the assignment operators.
// All math logic happens outside of the class in the native format
// and an internal set/swap method is used to store the data.
// Основа здесь: https://github.com/tatewake/endian-template/
namespace myx {
@ -24,44 +23,20 @@ template< typename T >
class EndianTypesBase
{
protected:
#if _MSC_VER
#if defined ( _MSC_VER )
#pragma warning ( push )
#endif
static T swapBytes( const T& b )
{
T n;
switch ( sizeof( T ) )
{
case 8: // 64-bit
( reinterpret_cast< uint8_t* >( &n ) )[0] = ( reinterpret_cast< const uint8_t* >( &b ) )[7];
( reinterpret_cast< uint8_t* >( &n ) )[1] = ( reinterpret_cast< const uint8_t* >( &b ) )[6];
( reinterpret_cast< uint8_t* >( &n ) )[2] = ( reinterpret_cast< const uint8_t* >( &b ) )[5];
( reinterpret_cast< uint8_t* >( &n ) )[3] = ( reinterpret_cast< const uint8_t* >( &b ) )[4];
( reinterpret_cast< uint8_t* >( &n ) )[4] = ( reinterpret_cast< const uint8_t* >( &b ) )[3];
( reinterpret_cast< uint8_t* >( &n ) )[5] = ( reinterpret_cast< const uint8_t* >( &b ) )[2];
( reinterpret_cast< uint8_t* >( &n ) )[6] = ( reinterpret_cast< const uint8_t* >( &b ) )[1];
( reinterpret_cast< uint8_t* >( &n ) )[7] = ( reinterpret_cast< const uint8_t* >( &b ) )[0];
break;
case 4: // 32-bit
( reinterpret_cast< uint8_t* >( &n ) )[0] = ( reinterpret_cast< const uint8_t* >( &b ) )[3];
( reinterpret_cast< uint8_t* >( &n ) )[1] = ( reinterpret_cast< const uint8_t* >( &b ) )[2];
( reinterpret_cast< uint8_t* >( &n ) )[2] = ( reinterpret_cast< const uint8_t* >( &b ) )[1];
( reinterpret_cast< uint8_t* >( &n ) )[3] = ( reinterpret_cast< const uint8_t* >( &b ) )[0];
break;
case 2: // 16-bit
( reinterpret_cast< uint8_t* >( &n ) )[0] = ( reinterpret_cast< const uint8_t* >( &b ) )[1];
( reinterpret_cast< uint8_t* >( &n ) )[1] = ( reinterpret_cast< const uint8_t* >( &b ) )[0];
break;
default:
assert( 0 ); // Endian swap is only defined for 2, 4, and 8-byte types
break;
} // switch
myx::base::span< uint8_t > sn( reinterpret_cast< uint8_t* >( &n ), sizeof( T ) );
myx::base::span< const uint8_t > sb( reinterpret_cast< const uint8_t* >( &b ), sizeof( T ) );
std::reverse_copy( sb.begin(), sb.end(), sn.begin() );
return( n );
} // swapBytes
#if _MSC_VER
#if defined( _MSC_VER )
#pragma warning ( pop )
#endif
}; // class EndianTypesBase
@ -87,7 +62,7 @@ public:
// 1. Set an OE from a PE
// 2. Get a PE from an OE
// Storage in
explicit LittleEndianType( const T& b ) :
LittleEndianType( const T& b ) :
m_data( transform( b ) )
{}
template < typename U > explicit LittleEndianType( U const& b ) :
@ -148,7 +123,7 @@ public:
// 1. Set an OE from a PE
// 2. Get a PE from an OE
// Storage in
explicit BigEndianType( const T& b ) :
BigEndianType( const T& b ) :
m_data( transform( b ) )
{}
template < typename U > explicit BigEndianType( U const& b ) :

View File

@ -7,18 +7,41 @@
// Official repository: https://github.com/boostorg/beast
//
#ifndef BOOST_BEAST_CORE_SPAN_HPP
#define BOOST_BEAST_CORE_SPAN_HPP
#ifndef MYX_BASE_SPAN_HPP_
#define MYX_BASE_SPAN_HPP_
#include <boost/beast/core/detail/config.hpp>
#include <boost/beast/core/detail/type_traits.hpp>
#include <algorithm>
#include <iterator>
#include <string>
#include <type_traits>
namespace boost {
namespace beast {
namespace myx {
namespace base {
template< typename ... Ts > struct make_void { typedef void type;};
template< typename ... Ts > using void_t = typename make_void< Ts... >::type;
template< class T, class E, class = void >
struct is_contiguous_container : std::false_type {};
template< class T, class E >
struct is_contiguous_container< T, E, void_t<
decltype(
std::declval< std::size_t& >() = std::declval< T const& >().size(),
std::declval< E*& >() = std::declval< T& >().data() ),
typename std::enable_if<
std::is_same<
typename std::remove_cv< E >::type,
typename std::remove_cv<
typename std::remove_pointer<
decltype( std::declval< T& >().data() )
>::type
>::type
>::value
>::type > > : std::true_type
{};
/** A range of bytes expressed as a ContiguousContainer
@ -77,67 +100,64 @@ public:
@param size The number of elements pointed to by `data`
*/
span(T* data, std::size_t size)
: data_(data), size_(size)
span( T* data, std::size_t size ) :
data_( data ),
size_( size )
{
}
/** Constructor
@param container The container to construct from
*/
template<class ContiguousContainer
#if ! BOOST_BEAST_DOXYGEN
, class = typename std::enable_if<
detail::is_contiguous_container<
template< class ContiguousContainer,
class = typename std::enable_if<
is_contiguous_container<
ContiguousContainer, T >::value >::type
#endif
>
explicit
span(ContiguousContainer&& container)
: data_(container.data())
, size_(container.size())
span( ContiguousContainer&& container ) :
data_( container.data() ),
size_( container.size() )
{
}
#if ! BOOST_BEAST_DOXYGEN
template<class CharT, class Traits, class Allocator>
explicit
span(std::basic_string<CharT, Traits, Allocator>& s)
: data_(&s[0])
, size_(s.size())
{
}
template< class CharT, class Traits, class Allocator >
explicit
span(std::basic_string<CharT, Traits, Allocator> const& s)
: data_(s.data())
, size_(s.size())
span( std::basic_string< CharT, Traits, Allocator >& s ) :
data_( &s[0] ),
size_( s.size() )
{
}
#endif
template< class CharT, class Traits, class Allocator >
explicit
span( std::basic_string< CharT, Traits, Allocator > const& s ) :
data_( s.data() ),
size_( s.size() )
{
}
/** Assignment
@param container The container to assign from
*/
template< class ContiguousContainer >
#if BOOST_BEAST_DOXYGEN
span&
#else
typename std::enable_if<detail::is_contiguous_container<
typename std::enable_if< is_contiguous_container<
ContiguousContainer, T >::value,
span& >::type
#endif
operator=( ContiguousContainer&& container )
{
data_ = container.data();
size_ = container.size();
return *this;
return( *this );
}
#if ! BOOST_BEAST_DOXYGEN
template< class CharT, class Traits, class Allocator >
span&
operator=( std::basic_string<
@ -145,9 +165,10 @@ public:
{
data_ = &s[0];
size_ = s.size();
return *this;
return( *this );
}
template< class CharT, class Traits, class Allocator >
span&
operator=( std::basic_string<
@ -155,61 +176,68 @@ public:
{
data_ = s.data();
size_ = s.size();
return *this;
return( *this );
}
#endif
/// Returns `true` if the span is empty
bool
empty() const
{
return size_ == 0;
return( size_ == 0 );
}
/// Returns a pointer to the beginning of the span
T*
data() const
{
return data_;
return( data_ );
}
/// Returns the number of elements in the span
std::size_t
size() const
{
return size_;
return( size_ );
}
/// Returns an iterator to the beginning of the span
const_iterator
iterator
begin() const
{
return data_;
return( data_ );
}
/// Returns an iterator to the beginning of the span
const_iterator
cbegin() const
{
return data_;
return( data_ );
}
/// Returns an iterator to one past the end of the span
const_iterator
iterator
end() const
{
return data_ + size_;
return( data_ + size_ );
}
/// Returns an iterator to one past the end of the span
const_iterator
cend() const
{
return data_ + size_;
return( data_ + size_ );
}
};
}; // class span
} // beast
} // boost
} // namespace base
#endif
} // namespace myx
#endif // ifndef MYX_BASE_SPAN_HPP_