DAW JSON Link
Loading...
Searching...
No Matches
daw_fp_fallback.h
Go to the documentation of this file.
1// Copyright (c) Darrell Wright
2//
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
5//
6// Official repository: https://github.com/beached/daw_json_link
7//
8
9#pragma once
10
12
14
15#include <daw/daw_attributes.h>
16#include <daw/daw_cpp_feature_check.h>
17#include <daw/daw_not_null.h>
18
19#include <cstdlib>
20#include <string>
21#include <system_error>
22#include <type_traits>
23
24#if not defined( DAW_JSON_USE_STRTOD )
25#include <charconv>
26#endif
27
28namespace daw::json {
29 inline namespace DAW_JSON_VER {
30 namespace json_details {
32 template<typename Real, typename = void>
33 inline constexpr bool has_precise_fallback_v =
34 std::is_same_v<Real, float> or std::is_same_v<Real, double> or
35 std::is_same_v<Real, long double>;
36
37#if not defined( DAW_JSON_USE_STRTOD )
38 template<typename Real>
39 inline constexpr bool has_precise_fallback_v<
40 Real, std::void_t<decltype( std::from_chars(
41 std::declval<char const *>( ), std::declval<char const *>( ),
42 std::declval<Real &>( ) ) )>> = std::is_floating_point_v<Real>;
43#endif
44
49 template<typename Real>
50 DAW_ATTRIB_NOINLINE [[nodiscard]] Real
51 parse_with_strtod( daw::not_null<char const *> first,
52 daw::not_null<char const *> last ) {
53 static_assert( std::is_floating_point_v<Real>,
54 "Unexpected type passed to parse_with_strtod" );
55#if defined( DAW_JSON_USE_STRTOD )
56 (void)last;
57 char **end = nullptr;
58 if constexpr( std::is_same_v<Real, float> ) {
59 return static_cast<Real>( std::strtof( first, end ) );
60 } else if constexpr( std::is_same_v<Real, double> ) {
61 return static_cast<Real>( std::strtod( first, end ) );
62 } else {
63 return static_cast<Real>( std::strtold( first, end ) );
64 }
65#else
66 Real result;
67 auto fc_res = std::from_chars( first, last, result );
68 if( fc_res.ec == std::errc::result_out_of_range ) {
69 // from_chars reports the same error for overflow and underflow.
70 // Retry this cold path with a bounded, null-terminated token so
71 // subnormal values are not incorrectly returned as infinity.
72 auto const token = std::string( first.get( ), last.get( ) );
73 if constexpr( std::is_same_v<Real, float> ) {
74 return std::strtof( token.c_str( ), nullptr );
75 } else if constexpr( std::is_same_v<Real, double> ) {
76 return std::strtod( token.c_str( ), nullptr );
77 } else {
78 return static_cast<Real>( std::strtold( token.c_str( ), nullptr ) );
79 }
80 }
81 daw_json_ensure( fc_res.ec == std::errc( ),
82 ErrorReason::InvalidNumber );
83 return result;
84#endif
85 }
86 } // namespace json_details
87 } // namespace DAW_JSON_VER
88} // namespace daw::json
#define daw_json_ensure(Bool,...)
Ensure that Bool is true. If false pass rest of args to daw_json_error.
string_writer grows its string with resize_and_overwrite, leaving the new bytes uninitialized,...
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition version.h:20