|
18 | 18 |
|
19 | 19 | #include <concepts>
|
20 | 20 |
|
21 |
| -#include "containers/array.h" |
22 | 21 | #include "marker/unsafe.h"
|
23 | 22 | #include "num/__private/float_ordering.h"
|
24 | 23 | #include "num/__private/intrinsics.h"
|
|
27 | 26 | #include "num/signed_integer.h"
|
28 | 27 | #include "num/unsigned_integer.h"
|
29 | 28 |
|
| 29 | +namespace sus::containers { |
| 30 | +template <class T, size_t N> |
| 31 | + requires(N <= PTRDIFF_MAX) |
| 32 | +class Array; |
| 33 | +} |
| 34 | + |
30 | 35 | #define _sus__float_storage(PrimitiveT) \
|
31 | 36 | /** The inner primitive value, in case it needs to be unwrapped from the \
|
32 | 37 | * type. Avoid using this member except to convert when a consumer requires \
|
|
696 | 701 | return r; \
|
697 | 702 | }
|
698 | 703 |
|
699 |
| -#define _sus__float_endian(T, PrimitiveT, UnsignedIntT) \ |
| 704 | +#define _sus__float_endian(T, Bytes, UnsignedIntT) \ |
700 | 705 | /** Return the memory representation of this floating point number as a byte \
|
701 | 706 | * array in big-endian (network) byte order. \
|
702 | 707 | */ \
|
703 |
| - constexpr ::sus::Array<u8, sizeof(PrimitiveT)> to_be_bytes() \ |
704 |
| - const& noexcept { \ |
| 708 | + template <std::same_as<::sus::containers::Array<u8, Bytes>> Array = \ |
| 709 | + ::sus::containers::Array<u8, Bytes>> \ |
| 710 | + constexpr Array to_be_bytes() const& noexcept { \ |
705 | 711 | return to_bits().to_be_bytes(); \
|
706 | 712 | } \
|
707 | 713 | /** Return the memory representation of this floating point number as a byte \
|
708 | 714 | * array in little-endian byte order. \
|
709 | 715 | */ \
|
710 |
| - constexpr ::sus::Array<u8, sizeof(PrimitiveT)> to_le_bytes() \ |
711 |
| - const& noexcept { \ |
| 716 | + template <std::same_as<::sus::containers::Array<u8, Bytes>> Array = \ |
| 717 | + ::sus::containers::Array<u8, Bytes>> \ |
| 718 | + constexpr Array to_le_bytes() const& noexcept { \ |
712 | 719 | return to_bits().to_le_bytes(); \
|
713 | 720 | } \
|
714 | 721 | /** Return the memory representation of this floating point number as a byte \
|
|
717 | 724 | * As the target platform's native endianness is used, portable code should \
|
718 | 725 | * use `to_be_bytes()` or `to_le_bytes()`, as appropriate, instead. \
|
719 | 726 | */ \
|
720 |
| - constexpr ::sus::Array<u8, sizeof(PrimitiveT)> to_ne_bytes() \ |
721 |
| - const& noexcept { \ |
| 727 | + template <std::same_as<::sus::containers::Array<u8, Bytes>> Array = \ |
| 728 | + ::sus::containers::Array<u8, Bytes>> \ |
| 729 | + constexpr Array to_ne_bytes() const& noexcept { \ |
722 | 730 | return to_bits().to_ne_bytes(); \
|
723 | 731 | } \
|
724 | 732 | /** Create a floating point value from its representation as a byte array in \
|
725 | 733 | * big endian. \
|
726 | 734 | * \
|
727 | 735 | * See `##T##::from_bits()` for why this function is not constexpr. \
|
728 | 736 | */ \
|
729 |
| - static T from_be_bytes( \ |
730 |
| - const ::sus::Array<u8, sizeof(PrimitiveT)>& bytes) noexcept { \ |
| 737 | + template <std::same_as<::sus::containers::Array<u8, Bytes>> Array = \ |
| 738 | + ::sus::containers::Array<u8, Bytes>> \ |
| 739 | + static T from_be_bytes(const Array& bytes) noexcept { \ |
731 | 740 | return T::from_bits(UnsignedIntT::from_be_bytes(bytes)); \
|
732 | 741 | } \
|
733 | 742 | /** Create a floating point value from its representation as a byte array in \
|
734 | 743 | * big endian. \
|
735 | 744 | * \
|
736 | 745 | * See `##T##::from_bits()` for why this function is not constexpr. \
|
737 | 746 | */ \
|
738 |
| - static T from_le_bytes( \ |
739 |
| - const ::sus::Array<u8, sizeof(PrimitiveT)>& bytes) noexcept { \ |
| 747 | + template <std::same_as<::sus::containers::Array<u8, Bytes>> Array = \ |
| 748 | + ::sus::containers::Array<u8, Bytes>> \ |
| 749 | + static T from_le_bytes(const Array& bytes) noexcept { \ |
740 | 750 | return T::from_bits(UnsignedIntT::from_le_bytes(bytes)); \
|
741 | 751 | } \
|
742 | 752 | /** Create a floating point value from its representation as a byte array in \
|
|
748 | 758 | * \
|
749 | 759 | * See `##T##::from_bits()` for why this function is not constexpr. \
|
750 | 760 | */ \
|
751 |
| - static T from_ne_bytes( \ |
752 |
| - const ::sus::Array<u8, sizeof(PrimitiveT)>& bytes) noexcept { \ |
| 761 | + template <std::same_as<::sus::containers::Array<u8, Bytes>> Array = \ |
| 762 | + ::sus::containers::Array<u8, Bytes>> \ |
| 763 | + static T from_ne_bytes(const Array& bytes) noexcept { \ |
753 | 764 | return T::from_bits(UnsignedIntT::from_ne_bytes(bytes)); \
|
754 | 765 | }
|
755 | 766 |
|
756 | 767 | // to_be_bytes, to_le_bytes, to_ne_bytes
|
757 | 768 |
|
758 |
| -#define _sus__float(T, PrimitiveT, UnsignedIntT) \ |
759 |
| - _sus__float_storage(PrimitiveT); \ |
760 |
| - _sus__float_constants(T, PrimitiveT); \ |
761 |
| - _sus__float_construct(T, PrimitiveT); \ |
762 |
| - _sus__float_comparison(T); \ |
763 |
| - _sus__float_unary_ops(T); \ |
764 |
| - _sus__float_binary_ops(T); \ |
765 |
| - _sus__float_mutable_ops(T); \ |
766 |
| - _sus__float_abs(T, PrimitiveT); \ |
767 |
| - _sus__float_math(T, PrimitiveT); \ |
768 |
| - _sus__float_fract_trunc(T); \ |
769 |
| - _sus__float_convert_to(T, PrimitiveT); \ |
770 |
| - _sus__float_bytes(T, UnsignedIntT); \ |
771 |
| - _sus__float_category(T); \ |
772 |
| - _sus__float_clamp(T); \ |
773 |
| - _sus__float_euclid(T, PrimitiveT); \ |
774 |
| - _sus__float_endian(T, PrimitiveT, UnsignedIntT); \ |
| 769 | +#define _sus__float(T, PrimitiveT, UnsignedIntT) \ |
| 770 | + _sus__float_storage(PrimitiveT); \ |
| 771 | + _sus__float_constants(T, PrimitiveT); \ |
| 772 | + _sus__float_construct(T, PrimitiveT); \ |
| 773 | + _sus__float_comparison(T); \ |
| 774 | + _sus__float_unary_ops(T); \ |
| 775 | + _sus__float_binary_ops(T); \ |
| 776 | + _sus__float_mutable_ops(T); \ |
| 777 | + _sus__float_abs(T, PrimitiveT); \ |
| 778 | + _sus__float_math(T, PrimitiveT); \ |
| 779 | + _sus__float_fract_trunc(T); \ |
| 780 | + _sus__float_convert_to(T, PrimitiveT); \ |
| 781 | + _sus__float_bytes(T, UnsignedIntT); \ |
| 782 | + _sus__float_category(T); \ |
| 783 | + _sus__float_clamp(T); \ |
| 784 | + _sus__float_euclid(T, PrimitiveT); \ |
| 785 | + _sus__float_endian(T, sizeof(PrimitiveT), UnsignedIntT); \ |
775 | 786 | static_assert(true)
|
0 commit comments