Skip to content

Commit 3f018ee

Browse files
author
John Wellbelove
committed
Fixed floating point etl::unaligned_type
1 parent e6c7e23 commit 3f018ee

File tree

3 files changed

+452
-68
lines changed

3 files changed

+452
-68
lines changed

include/etl/unaligned_type.h

Lines changed: 247 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ SOFTWARE.
4040
#include "endianness.h"
4141
#include "iterator.h"
4242
#include "algorithm.h"
43+
#include "bit.h"
4344

4445
#include <string.h>
4546

@@ -367,15 +368,15 @@ namespace etl
367368
//*************************************************************************
368369
/// Unaligned copy
369370
//*************************************************************************
370-
template <typename U, size_t Size = sizeof(U)>
371+
template <typename U, size_t Size = sizeof(U), typename Enable = void>
371372
struct unaligned_copy;
372373

373374
//*******************************************
374375
/// Unaligned copy
375376
/// Size == 1
376377
//*******************************************
377378
template <typename U>
378-
struct unaligned_copy<U, 1U>
379+
struct unaligned_copy<U, 1U, void>
379380
{
380381
//*******************************
381382
static ETL_CONSTEXPR14 void copy(T value, pointer store)
@@ -401,7 +402,7 @@ namespace etl
401402
/// Size == 2
402403
//*******************************************
403404
template <typename U>
404-
struct unaligned_copy<U, 2U>
405+
struct unaligned_copy<U, 2U, typename etl::enable_if<etl::is_integral<U>::value>::type>
405406
{
406407
//*******************************
407408
static ETL_CONSTEXPR14 void copy(T value, unsigned char* store)
@@ -452,9 +453,10 @@ namespace etl
452453
//*******************************************
453454
/// Unaligned copy
454455
/// Size == 4
456+
/// Integrals
455457
//*******************************************
456458
template <typename U>
457-
struct unaligned_copy<U, 4U>
459+
struct unaligned_copy<U, 4U, typename etl::enable_if<etl::is_integral<U>::value>::type>
458460
{
459461
static ETL_CONSTEXPR14 void copy(T value, unsigned char* store)
460462
{
@@ -513,12 +515,57 @@ namespace etl
513515
}
514516
};
515517

518+
//*******************************************
519+
/// Unaligned copy
520+
/// Size == 4
521+
/// Floating point
522+
//*******************************************
523+
template <typename U>
524+
struct unaligned_copy<U, 4U, typename etl::enable_if<etl::is_floating_point<U>::value>::type>
525+
{
526+
static void copy(T value, unsigned char* store)
527+
{
528+
memcpy(store, &value, 4U);
529+
530+
if (Endian != etl::endianness::value())
531+
{
532+
etl::reverse(store, store + 4U);
533+
}
534+
}
535+
536+
//*******************************
537+
static void copy(const_pointer store, T& value)
538+
{
539+
unsigned char temp[4U];
540+
memcpy(temp, store, 4U);
541+
542+
if (Endian != etl::endianness::value())
543+
{
544+
etl::reverse(temp, temp + 4U);
545+
}
546+
547+
memcpy(&value, temp, 4U);
548+
}
549+
550+
//*******************************
551+
static ETL_CONSTEXPR14 void copy(const_pointer src, int endian_src, unsigned char* dst)
552+
{
553+
memcpy(dst, src, 4U);
554+
555+
if (Endian != endian_src)
556+
{
557+
etl::reverse(dst, dst + 4U);
558+
}
559+
}
560+
};
561+
516562
//*******************************************
517563
/// Unaligned copy
518564
/// Size == 8
565+
/// Integrals
519566
//*******************************************
520567
template <typename U>
521-
struct unaligned_copy<U, 8U>
568+
struct unaligned_copy<U, 8U, typename etl::enable_if<etl::is_integral<U>::value>::type>
522569
{
523570
static ETL_CONSTEXPR14 void copy(T value, unsigned char* store)
524571
{
@@ -600,6 +647,138 @@ namespace etl
600647
}
601648
}
602649
};
650+
651+
//*******************************************
652+
/// Unaligned copy
653+
/// Size == 8
654+
/// Floating point
655+
//*******************************************
656+
template <typename U>
657+
struct unaligned_copy<U, 8U, typename etl::enable_if<etl::is_floating_point<U>::value>::type>
658+
{
659+
static void copy(T value, unsigned char* store)
660+
{
661+
memcpy(store, &value, 8U);
662+
663+
if (Endian != etl::endianness::value())
664+
{
665+
etl::reverse(store, store + 8U);
666+
}
667+
}
668+
669+
//*******************************
670+
static void copy(const_pointer store, T& value)
671+
{
672+
unsigned char temp[8U];
673+
memcpy(temp, store, 8U);
674+
675+
if (Endian != etl::endianness::value())
676+
{
677+
etl::reverse(temp, temp + 8U);
678+
}
679+
680+
memcpy(&value, temp, 8U);
681+
}
682+
683+
//*******************************
684+
static ETL_CONSTEXPR14 void copy(const_pointer src, int endian_src, unsigned char* dst)
685+
{
686+
memcpy(dst, src, 8U);
687+
688+
if (Endian != endian_src)
689+
{
690+
etl::reverse(dst, dst + 8U);
691+
}
692+
}
693+
};
694+
695+
//*******************************************
696+
/// Unaligned copy
697+
/// Size == 12
698+
/// Floating point
699+
//*******************************************
700+
template <typename U>
701+
struct unaligned_copy<U, 12U, typename etl::enable_if<etl::is_floating_point<U>::value>::type>
702+
{
703+
static void copy(T value, unsigned char* store)
704+
{
705+
memcpy(store, &value, 12U);
706+
707+
if (Endian != etl::endianness::value())
708+
{
709+
etl::reverse(store, store + 12U);
710+
}
711+
}
712+
713+
//*******************************
714+
static void copy(const_pointer store, T& value)
715+
{
716+
unsigned char temp[12U];
717+
memcpy(temp, store, 12U);
718+
719+
if (Endian != etl::endianness::value())
720+
{
721+
etl::reverse(temp, temp + 12U);
722+
}
723+
724+
memcpy(&value, temp, 12U);
725+
}
726+
727+
//*******************************
728+
static ETL_CONSTEXPR14 void copy(const_pointer src, int endian_src, unsigned char* dst)
729+
{
730+
memcpy(dst, src, 12U);
731+
732+
if (Endian != endian_src)
733+
{
734+
etl::reverse(dst, dst + 12U);
735+
}
736+
}
737+
};
738+
739+
//*******************************************
740+
/// Unaligned copy
741+
/// Size == 16
742+
/// Floating point
743+
//*******************************************
744+
template <typename U>
745+
struct unaligned_copy<U, 16U, typename etl::enable_if<etl::is_floating_point<U>::value>::type>
746+
{
747+
static void copy(T value, unsigned char* store)
748+
{
749+
memcpy(store, &value, 16U);
750+
751+
if (Endian != etl::endianness::value())
752+
{
753+
etl::reverse(store, store + 16U);
754+
}
755+
}
756+
757+
//*******************************
758+
static void copy(const_pointer store, T& value)
759+
{
760+
unsigned char temp[16U];
761+
memcpy(temp, store, 16U);
762+
763+
if (Endian != etl::endianness::value())
764+
{
765+
etl::reverse(temp, temp + 16U);
766+
}
767+
768+
memcpy(&value, temp, 16U);
769+
}
770+
771+
//*******************************
772+
static ETL_CONSTEXPR14 void copy(const_pointer src, int endian_src, unsigned char* dst)
773+
{
774+
memcpy(dst, src, 16U);
775+
776+
if (Endian != endian_src)
777+
{
778+
etl::reverse(dst, dst + 16U);
779+
}
780+
}
781+
};
603782
};
604783

605784
template <typename T, int Endian_>
@@ -610,89 +789,89 @@ namespace etl
610789

611790
#if ETL_HAS_CONSTEXPR_ENDIANNESS
612791
// Host order
613-
typedef unaligned_type<char, etl::endianness::value()> host_char_t;
614-
typedef unaligned_type<signed char, etl::endianness::value()> host_schar_t;
615-
typedef unaligned_type<unsigned char, etl::endianness::value()> host_uchar_t;
616-
typedef unaligned_type<short, etl::endianness::value()> host_short_t;
617-
typedef unaligned_type<unsigned short, etl::endianness::value()> host_ushort_t;
618-
typedef unaligned_type<int, etl::endianness::value()> host_int_t;
619-
typedef unaligned_type<unsigned int, etl::endianness::value()> host_uint_t;
620-
typedef unaligned_type<long, etl::endianness::value()> host_long_t;
621-
typedef unaligned_type<unsigned long, etl::endianness::value()> host_ulong_t;
622-
typedef unaligned_type<long long, etl::endianness::value()> host_long_long_t;
792+
typedef unaligned_type<char, etl::endianness::value()> host_char_t;
793+
typedef unaligned_type<signed char, etl::endianness::value()> host_schar_t;
794+
typedef unaligned_type<unsigned char, etl::endianness::value()> host_uchar_t;
795+
typedef unaligned_type<short, etl::endianness::value()> host_short_t;
796+
typedef unaligned_type<unsigned short, etl::endianness::value()> host_ushort_t;
797+
typedef unaligned_type<int, etl::endianness::value()> host_int_t;
798+
typedef unaligned_type<unsigned int, etl::endianness::value()> host_uint_t;
799+
typedef unaligned_type<long, etl::endianness::value()> host_long_t;
800+
typedef unaligned_type<unsigned long, etl::endianness::value()> host_ulong_t;
801+
typedef unaligned_type<long long, etl::endianness::value()> host_long_long_t;
623802
typedef unaligned_type<unsigned long long, etl::endianness::value()> host_ulong_long_t;
624803
#if ETL_USING_8BIT_TYPES
625-
typedef unaligned_type<int8_t, etl::endianness::value()> host_int8_t;
626-
typedef unaligned_type<uint8_t, etl::endianness::value()> host_uint8_t;
804+
typedef unaligned_type<int8_t, etl::endianness::value()> host_int8_t;
805+
typedef unaligned_type<uint8_t, etl::endianness::value()> host_uint8_t;
627806
#endif
628-
typedef unaligned_type<int16_t, etl::endianness::value()> host_int16_t;
629-
typedef unaligned_type<uint16_t, etl::endianness::value()> host_uint16_t;
630-
typedef unaligned_type<int32_t, etl::endianness::value()> host_int32_t;
631-
typedef unaligned_type<uint32_t, etl::endianness::value()> host_uint32_t;
807+
typedef unaligned_type<int16_t, etl::endianness::value()> host_int16_t;
808+
typedef unaligned_type<uint16_t, etl::endianness::value()> host_uint16_t;
809+
typedef unaligned_type<int32_t, etl::endianness::value()> host_int32_t;
810+
typedef unaligned_type<uint32_t, etl::endianness::value()> host_uint32_t;
632811
#if ETL_USING_64BIT_TYPES
633-
typedef unaligned_type<int64_t, etl::endianness::value()> host_int64_t;
634-
typedef unaligned_type<uint64_t, etl::endianness::value()> host_uint64_t;
812+
typedef unaligned_type<int64_t, etl::endianness::value()> host_int64_t;
813+
typedef unaligned_type<uint64_t, etl::endianness::value()> host_uint64_t;
635814
#endif
636-
typedef unaligned_type<float, etl::endianness::value()> host_float_t;
637-
typedef unaligned_type<double, etl::endianness::value()> host_double_t;
638-
typedef unaligned_type<long double, etl::endianness::value()> host_long_double_t;
815+
typedef unaligned_type<float, etl::endianness::value()> host_float_t;
816+
typedef unaligned_type<double, etl::endianness::value()> host_double_t;
817+
typedef unaligned_type<long double, etl::endianness::value()> host_long_double_t;
639818
#endif
640819

641820
// Little Endian
642-
typedef unaligned_type<char, etl::endian::little> le_char_t;
643-
typedef unaligned_type<signed char, etl::endian::little> le_schar_t;
644-
typedef unaligned_type<unsigned char, etl::endian::little> le_uchar_t;
645-
typedef unaligned_type<short, etl::endian::little> le_short_t;
646-
typedef unaligned_type<unsigned short, etl::endian::little> le_ushort_t;
647-
typedef unaligned_type<int, etl::endian::little> le_int_t;
648-
typedef unaligned_type<unsigned int, etl::endian::little> le_uint_t;
649-
typedef unaligned_type<long, etl::endian::little> le_long_t;
650-
typedef unaligned_type<unsigned long, etl::endian::little> le_ulong_t;
651-
typedef unaligned_type<long long, etl::endian::little> le_long_long_t;
821+
typedef unaligned_type<char, etl::endian::little> le_char_t;
822+
typedef unaligned_type<signed char, etl::endian::little> le_schar_t;
823+
typedef unaligned_type<unsigned char, etl::endian::little> le_uchar_t;
824+
typedef unaligned_type<short, etl::endian::little> le_short_t;
825+
typedef unaligned_type<unsigned short, etl::endian::little> le_ushort_t;
826+
typedef unaligned_type<int, etl::endian::little> le_int_t;
827+
typedef unaligned_type<unsigned int, etl::endian::little> le_uint_t;
828+
typedef unaligned_type<long, etl::endian::little> le_long_t;
829+
typedef unaligned_type<unsigned long, etl::endian::little> le_ulong_t;
830+
typedef unaligned_type<long long, etl::endian::little> le_long_long_t;
652831
typedef unaligned_type<unsigned long long, etl::endian::little> le_ulong_long_t;
653832
#if ETL_USING_8BIT_TYPES
654-
typedef unaligned_type<int8_t, etl::endian::little> le_int8_t;
655-
typedef unaligned_type<uint8_t, etl::endian::little> le_uint8_t;
833+
typedef unaligned_type<int8_t, etl::endian::little> le_int8_t;
834+
typedef unaligned_type<uint8_t, etl::endian::little> le_uint8_t;
656835
#endif
657-
typedef unaligned_type<int16_t, etl::endian::little> le_int16_t;
658-
typedef unaligned_type<uint16_t, etl::endian::little> le_uint16_t;
659-
typedef unaligned_type<int32_t, etl::endian::little> le_int32_t;
660-
typedef unaligned_type<uint32_t, etl::endian::little> le_uint32_t;
836+
typedef unaligned_type<int16_t, etl::endian::little> le_int16_t;
837+
typedef unaligned_type<uint16_t, etl::endian::little> le_uint16_t;
838+
typedef unaligned_type<int32_t, etl::endian::little> le_int32_t;
839+
typedef unaligned_type<uint32_t, etl::endian::little> le_uint32_t;
661840
#if ETL_USING_64BIT_TYPES
662-
typedef unaligned_type<int64_t, etl::endian::little> le_int64_t;
663-
typedef unaligned_type<uint64_t, etl::endian::little> le_uint64_t;
841+
typedef unaligned_type<int64_t, etl::endian::little> le_int64_t;
842+
typedef unaligned_type<uint64_t, etl::endian::little> le_uint64_t;
664843
#endif
665-
typedef unaligned_type<float, etl::endian::little> le_float_t;
666-
typedef unaligned_type<double, etl::endian::little> le_double_t;
667-
typedef unaligned_type<long double, etl::endian::little> le_long_double_t;
844+
typedef unaligned_type<float, etl::endian::little> le_float_t;
845+
typedef unaligned_type<double, etl::endian::little> le_double_t;
846+
typedef unaligned_type<long double, etl::endian::little> le_long_double_t;
668847

669848
// Big Endian
670-
typedef unaligned_type<char, etl::endian::big> be_char_t;
671-
typedef unaligned_type<signed char, etl::endian::big> be_schar_t;
672-
typedef unaligned_type<unsigned char, etl::endian::big> be_uchar_t;
673-
typedef unaligned_type<short, etl::endian::big> be_short_t;
674-
typedef unaligned_type<unsigned short, etl::endian::big> be_ushort_t;
675-
typedef unaligned_type<int, etl::endian::big> be_int_t;
676-
typedef unaligned_type<unsigned int, etl::endian::big> be_uint_t;
677-
typedef unaligned_type<long, etl::endian::big> be_long_t;
678-
typedef unaligned_type<unsigned long, etl::endian::big> be_ulong_t;
679-
typedef unaligned_type<long long, etl::endian::big> be_long_long_t;
849+
typedef unaligned_type<char, etl::endian::big> be_char_t;
850+
typedef unaligned_type<signed char, etl::endian::big> be_schar_t;
851+
typedef unaligned_type<unsigned char, etl::endian::big> be_uchar_t;
852+
typedef unaligned_type<short, etl::endian::big> be_short_t;
853+
typedef unaligned_type<unsigned short, etl::endian::big> be_ushort_t;
854+
typedef unaligned_type<int, etl::endian::big> be_int_t;
855+
typedef unaligned_type<unsigned int, etl::endian::big> be_uint_t;
856+
typedef unaligned_type<long, etl::endian::big> be_long_t;
857+
typedef unaligned_type<unsigned long, etl::endian::big> be_ulong_t;
858+
typedef unaligned_type<long long, etl::endian::big> be_long_long_t;
680859
typedef unaligned_type<unsigned long long, etl::endian::big> be_ulong_long_t;
681860
#if ETL_USING_8BIT_TYPES
682-
typedef unaligned_type<int8_t, etl::endian::big> be_int8_t;
683-
typedef unaligned_type<uint8_t, etl::endian::big> be_uint8_t;
861+
typedef unaligned_type<int8_t, etl::endian::big> be_int8_t;
862+
typedef unaligned_type<uint8_t, etl::endian::big> be_uint8_t;
684863
#endif
685-
typedef unaligned_type<int16_t, etl::endian::big> be_int16_t;
686-
typedef unaligned_type<uint16_t, etl::endian::big> be_uint16_t;
687-
typedef unaligned_type<int32_t, etl::endian::big> be_int32_t;
688-
typedef unaligned_type<uint32_t, etl::endian::big> be_uint32_t;
864+
typedef unaligned_type<int16_t, etl::endian::big> be_int16_t;
865+
typedef unaligned_type<uint16_t, etl::endian::big> be_uint16_t;
866+
typedef unaligned_type<int32_t, etl::endian::big> be_int32_t;
867+
typedef unaligned_type<uint32_t, etl::endian::big> be_uint32_t;
689868
#if ETL_USING_64BIT_TYPES
690-
typedef unaligned_type<int64_t, etl::endian::big> be_int64_t;
691-
typedef unaligned_type<uint64_t, etl::endian::big> be_uint64_t;
869+
typedef unaligned_type<int64_t, etl::endian::big> be_int64_t;
870+
typedef unaligned_type<uint64_t, etl::endian::big> be_uint64_t;
692871
#endif
693-
typedef unaligned_type<float, etl::endian::big> be_float_t;
694-
typedef unaligned_type<double, etl::endian::big> be_double_t;
695-
typedef unaligned_type<long double, etl::endian::big> be_long_double_t;
872+
typedef unaligned_type<float, etl::endian::big> be_float_t;
873+
typedef unaligned_type<double, etl::endian::big> be_double_t;
874+
typedef unaligned_type<long double, etl::endian::big> be_long_double_t;
696875

697876
// Network Order
698877
typedef be_char_t net_char_t;

0 commit comments

Comments
 (0)