Skip to content

Commit 6f8fd67

Browse files
lemiredalle
authored andcommitted
make it build
1 parent c526899 commit 6f8fd67

File tree

3 files changed

+205
-8
lines changed

3 files changed

+205
-8
lines changed

include/fast_float/digit_comparison.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ to_extended(T value) noexcept {
7272
binary_format<T>::minimum_exponent();
7373
equiv_uint bits;
7474
#if FASTFLOAT_HAS_BIT_CAST
75-
bits = std::bit_cast<equiv_uint>(value);
75+
bits = bit_cast<equiv_uint>(value);
7676
#else
7777
::memcpy(&bits, &value, sizeof(T));
7878
#endif

include/fast_float/float_common.h

Lines changed: 203 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,88 @@ struct is_supported_char_type
260260
> {
261261
};
262262

263+
union float_union {
264+
float f;
265+
uint32_t bits;
266+
};
267+
268+
union double_union {
269+
double f;
270+
uint64_t bits;
271+
};
272+
273+
template <typename T, typename U> constexpr T bit_cast(const U &u);
274+
275+
template <>
276+
fastfloat_really_inline constexpr float bit_cast(const uint32_t &u) {
277+
float_union fu;
278+
fu.bits = u;
279+
return fu.f;
280+
}
281+
282+
template <>
283+
fastfloat_really_inline constexpr double bit_cast(const uint64_t &u) {
284+
double_union fu;
285+
fu.bits = u;
286+
return fu.f;
287+
}
288+
289+
template <>
290+
fastfloat_really_inline constexpr uint32_t bit_cast(const float &u) {
291+
float_union fu;
292+
fu.f = u;
293+
return fu.bits;
294+
}
295+
296+
template <>
297+
fastfloat_really_inline constexpr uint64_t bit_cast(const double &u) {
298+
double_union fu;
299+
fu.f = u;
300+
return fu.bits;
301+
}
302+
303+
#ifdef __STDCPP_FLOAT16_T__
304+
union float16_union {
305+
std::float16_t f;
306+
uint16_t bits;
307+
};
308+
309+
template <>
310+
fastfloat_really_inline constexpr uint16_t bit_cast(const std::float16_t &u) {
311+
float16_union fu;
312+
fu.f = u;
313+
return fu.bits;
314+
}
315+
316+
template <>
317+
fastfloat_really_inline constexpr std::float16_t bit_cast(const uint16_t &u) {
318+
float16_union fu;
319+
fu.bits = u;
320+
return fu.f;
321+
}
322+
#endif // __STDCPP_FLOAT16_T__
323+
324+
#ifdef __STDCPP_BFLOAT16_T__
325+
union bfloat16_union {
326+
std::bfloat16_t f;
327+
uint16_t bits;
328+
};
329+
330+
template <>
331+
fastfloat_really_inline constexpr uint16_t bit_cast(const std::bfloat16_t &u) {
332+
bfloat16_union fu;
333+
fu.f = u;
334+
return fu.bits;
335+
}
336+
337+
template <>
338+
fastfloat_really_inline constexpr std::bfloat16_t bit_cast(const uint16_t &u) {
339+
bfloat16_union fu;
340+
fu.bits = u;
341+
return fu.f;
342+
}
343+
#endif // __STDCPP_BFLOAT16_T__
344+
263345
// Compares two ASCII strings in a case insensitive manner.
264346
template <typename UC>
265347
inline FASTFLOAT_CONSTEXPR14 bool
@@ -630,12 +712,13 @@ inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path() {
630712

631713
// credit: Jakub Jelínek
632714
#ifdef __STDCPP_FLOAT16_T__
633-
634715
template <typename U> struct binary_format_lookup_tables<std::float16_t, U> {
635-
static constexpr std::float16_t powers_of_ten[] = {};
636-
static constexpr uint64_t max_mantissa[] = {};
716+
static constexpr std::float16_t powers_of_ten[] = {1}; // todo: fix this
717+
static constexpr uint64_t max_mantissa[] = {1}; // todo: fix this
637718
};
638719

720+
#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE
721+
639722
template <typename U>
640723
constexpr std::float16_t
641724
binary_format_lookup_tables<std::float16_t, U>::powers_of_ten[];
@@ -644,6 +727,33 @@ template <typename U>
644727
constexpr uint64_t
645728
binary_format_lookup_tables<std::float16_t, U>::max_mantissa[];
646729

730+
#endif
731+
732+
template <>
733+
inline constexpr std::float16_t
734+
binary_format<std::float16_t>::exact_power_of_ten(int64_t power) {
735+
// Work around clang bug https://godbolt.org/z/zedh7rrhc
736+
return (void)powers_of_ten[0], powers_of_ten[power];
737+
}
738+
739+
template <>
740+
inline constexpr binary_format<std::float16_t>::equiv_uint
741+
binary_format<std::float16_t>::exponent_mask() {
742+
return 0x7C00;
743+
}
744+
745+
template <>
746+
inline constexpr binary_format<std::float16_t>::equiv_uint
747+
binary_format<std::float16_t>::mantissa_mask() {
748+
return 0x03FF;
749+
}
750+
751+
template <>
752+
inline constexpr binary_format<std::float16_t>::equiv_uint
753+
binary_format<std::float16_t>::hidden_bit_mask() {
754+
return 0x0400;
755+
}
756+
647757
template <>
648758
inline constexpr int binary_format<std::float16_t>::max_exponent_fast_path() {
649759
return 0;
@@ -655,6 +765,13 @@ binary_format<std::float16_t>::max_mantissa_fast_path() {
655765
return 0;
656766
}
657767

768+
template <>
769+
inline constexpr uint64_t
770+
binary_format<std::float16_t>::max_mantissa_fast_path(int64_t power) {
771+
// Work around clang bug https://godbolt.org/z/zedh7rrhc
772+
return (void)max_mantissa[0], max_mantissa[power];
773+
}
774+
658775
template <>
659776
inline constexpr int binary_format<std::float16_t>::min_exponent_fast_path() {
660777
return 0;
@@ -705,13 +822,13 @@ template <> constexpr size_t binary_format<std::float16_t>::max_digits() {
705822

706823
// credit: Jakub Jelínek
707824
#ifdef __STDCPP_BFLOAT16_T__
708-
709825
template <typename U> struct binary_format_lookup_tables<std::bfloat16_t, U> {
710-
static constexpr std::bfloat16_t powers_of_ten[] = {};
711-
712-
static constexpr uint64_t max_mantissa[] = {};
826+
static constexpr std::bfloat16_t powers_of_ten[] = {1}; // todo: fix this
827+
static constexpr uint64_t max_mantissa[] = {1}; // todo: fix this
713828
};
714829

830+
#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE
831+
715832
template <typename U>
716833
constexpr std::bfloat16_t
717834
binary_format_lookup_tables<std::bfloat16_t, U>::powers_of_ten[];
@@ -720,17 +837,51 @@ template <typename U>
720837
constexpr uint64_t
721838
binary_format_lookup_tables<std::bfloat16_t, U>::max_mantissa[];
722839

840+
#endif
841+
842+
template <>
843+
inline constexpr std::bfloat16_t
844+
binary_format<std::bfloat16_t>::exact_power_of_ten(int64_t power) {
845+
// Work around clang bug https://godbolt.org/z/zedh7rrhc
846+
return (void)powers_of_ten[0], powers_of_ten[power];
847+
}
848+
723849
template <>
724850
inline constexpr int binary_format<std::bfloat16_t>::max_exponent_fast_path() {
725851
return 0;
726852
}
727853

854+
template <>
855+
inline constexpr binary_format<std::bfloat16_t>::equiv_uint
856+
binary_format<std::bfloat16_t>::exponent_mask() {
857+
return 0x7F80;
858+
}
859+
860+
template <>
861+
inline constexpr binary_format<std::bfloat16_t>::equiv_uint
862+
binary_format<std::bfloat16_t>::mantissa_mask() {
863+
return 0x007F;
864+
}
865+
866+
template <>
867+
inline constexpr binary_format<std::bfloat16_t>::equiv_uint
868+
binary_format<std::bfloat16_t>::hidden_bit_mask() {
869+
return 0x0080;
870+
}
871+
728872
template <>
729873
inline constexpr uint64_t
730874
binary_format<std::bfloat16_t>::max_mantissa_fast_path() {
731875
return 0;
732876
}
733877

878+
template <>
879+
inline constexpr uint64_t
880+
binary_format<std::bfloat16_t>::max_mantissa_fast_path(int64_t power) {
881+
// Work around clang bug https://godbolt.org/z/zedh7rrhc
882+
return (void)max_mantissa[0], max_mantissa[power];
883+
}
884+
734885
template <>
735886
inline constexpr int binary_format<std::bfloat16_t>::min_exponent_fast_path() {
736887
return 0;
@@ -892,6 +1043,34 @@ to_float(bool negative, adjusted_mantissa am, T &value) {
8921043
#endif
8931044
}
8941045

1046+
#ifdef __STDCPP_FLOAT16_T__
1047+
template <>
1048+
fastfloat_really_inline void to_float<std::float16_t>(bool negative,
1049+
adjusted_mantissa am,
1050+
std::float16_t &value) {
1051+
constexpr int mantissa_bits =
1052+
binary_format<std::float16_t>::mantissa_explicit_bits();
1053+
value = bit_cast<std::float16_t>(
1054+
uint16_t(am.mantissa | (uint16_t(am.power2) << mantissa_bits) |
1055+
(negative ? 0x8000 : 0)));
1056+
}
1057+
1058+
#endif // __STDCPP_FLOAT16_T__
1059+
1060+
#ifdef __STDCPP_BFLOAT16_T__
1061+
template <>
1062+
fastfloat_really_inline void to_float<std::bfloat16_t>(bool negative,
1063+
adjusted_mantissa am,
1064+
std::bfloat16_t &value) {
1065+
constexpr int mantissa_bits =
1066+
binary_format<std::bfloat16_t>::mantissa_explicit_bits();
1067+
value = bit_cast<std::bfloat16_t>(
1068+
uint16_t(am.mantissa | (uint16_t(am.power2) << mantissa_bits) |
1069+
(negative ? 0x8000 : 0)));
1070+
}
1071+
1072+
#endif // __STDCPP_BFLOAT16_T__
1073+
8951074
template <typename = void> struct space_lut {
8961075
static constexpr bool value[] = {
8971076
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -944,10 +1123,12 @@ template <> constexpr char16_t const *str_const_nan<char16_t>() {
9441123
template <> constexpr char32_t const *str_const_nan<char32_t>() {
9451124
return U"nan";
9461125
}
1126+
9471127
#ifdef __cpp_char8_t
9481128
template <> constexpr char8_t const *str_const_nan<char8_t>() {
9491129
return u8"nan";
9501130
}
1131+
9511132
#endif
9521133

9531134
template <typename UC> constexpr UC const *str_const_inf();
@@ -965,10 +1146,12 @@ template <> constexpr char16_t const *str_const_inf<char16_t>() {
9651146
template <> constexpr char32_t const *str_const_inf<char32_t>() {
9661147
return U"infinity";
9671148
}
1149+
9681150
#ifdef __cpp_char8_t
9691151
template <> constexpr char8_t const *str_const_inf<char8_t>() {
9701152
return u8"infinity";
9711153
}
1154+
9721155
#endif
9731156

9741157
template <typename = void> struct int_luts {
@@ -1038,6 +1221,7 @@ fastfloat_really_inline constexpr uint64_t min_safe_u64(int base) {
10381221

10391222
static_assert(std::is_same<equiv_uint_t<double>, uint64_t>::value,
10401223
"equiv_uint should be uint64_t for double");
1224+
10411225
static_assert(std::is_same<equiv_uint_t<float>, uint32_t>::value,
10421226
"equiv_uint should be uint32_t for float");
10431227

@@ -1051,6 +1235,18 @@ static_assert(std::is_same<equiv_uint_t<std::float32_t>, uint32_t>::value,
10511235
"equiv_uint should be uint32_t for std::float32_t");
10521236
#endif
10531237

1238+
#ifdef __STDCPP_FLOAT16_T__
1239+
static_assert(
1240+
std::is_same<binary_format<std::float16_t>::equiv_uint, uint16_t>::value,
1241+
"equiv_uint should be uint16_t for std::float16_t");
1242+
#endif
1243+
1244+
#ifdef __STDCPP_BFLOAT16_T__
1245+
static_assert(
1246+
std::is_same<binary_format<std::bfloat16_t>::equiv_uint, uint16_t>::value,
1247+
"equiv_uint should be uint16_t for std::bfloat16_t");
1248+
#endif
1249+
10541250
constexpr chars_format operator~(chars_format rhs) noexcept {
10551251
using int_type = std::underlying_type<chars_format>::type;
10561252
return static_cast<chars_format>(~static_cast<int_type>(rhs));

tests/example_test.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ int main() {
122122
}
123123
std::cout << "parsed the number " << result << std::endl;
124124
#ifdef __STDCPP_FLOAT16_T__
125+
printf("16-bit float\n");
125126
// Parse as 16-bit float
126127
std::float16_t parsed_16{};
127128
input = "10000e-1452";

0 commit comments

Comments
 (0)