Skip to content

Commit

Permalink
re #442: ensure leading + is accepted
Browse files Browse the repository at this point in the history
  • Loading branch information
biojppm committed Jun 21, 2024
1 parent 7e1b8fe commit ad804f8
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 6 deletions.
30 changes: 24 additions & 6 deletions src/c4/yml/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1604,31 +1604,49 @@ inline void write(NodeRef *n, T const& v)
n->set_val_serialized(v);
}

namespace detail {
// SFINAE overloads for skipping leading + which cannot be read by the charconv functions
template<class T>
C4_ALWAYS_INLINE auto read_skip_plus(csubstr val, T *v)
-> typename std::enable_if<std::is_arithmetic<T>::value, bool>::type
{
if(val.begins_with('+'))
val = val.sub(1);
return from_chars(val, v);
}
template<class T>
C4_ALWAYS_INLINE auto read_skip_plus(csubstr val, T *v)
-> typename std::enable_if< ! std::is_arithmetic<T>::value, bool>::type
{
return from_chars(val, v);
}
} // namespace detail

/** convert the val of a scalar node to a particular type, by
* forwarding its val to @ref from_chars<T>(). The full string is
* used.
* @return false if the conversion failed */
template<class T>
typename std::enable_if< ! std::is_floating_point<T>::value, bool>::type
inline read(NodeRef const& n, T *v)
inline auto read(NodeRef const& n, T *v)
-> typename std::enable_if< ! std::is_floating_point<T>::value, bool>::type
{
csubstr val = n.val();
if(val.empty())
return false;
return from_chars(val, v);
return detail::read_skip_plus(val, v);
}
/** convert the val of a scalar node to a particular type, by
* forwarding its val to @ref from_chars<T>(). The full string is
* used.
* @return false if the conversion failed */
template<class T>
typename std::enable_if< ! std::is_floating_point<T>::value, bool>::type
inline read(ConstNodeRef const& n, T *v)
inline auto read(ConstNodeRef const& n, T *v)
-> typename std::enable_if< ! std::is_floating_point<T>::value, bool>::type
{
csubstr val = n.val();
if(val.empty())
return false;
return from_chars(val, v);
return detail::read_skip_plus(val, v);
}

/** convert the val of a scalar node to a floating point type, by
Expand Down
4 changes: 4 additions & 0 deletions src/c4/yml/tree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ bool from_chars_float(csubstr buf, T *C4_RESTRICT val)
{
return true;
}
else if(C4_UNLIKELY(buf.begins_with('+')))
{
return from_chars(buf.sub(1), val);
}
else if(C4_UNLIKELY(buf == ".nan" || buf == ".NaN" || buf == ".NAN"))
{
*val = std::numeric_limits<T>::quiet_NaN();
Expand Down

0 comments on commit ad804f8

Please sign in to comment.