parse: change parsing functions to modify the data view
This commit is contained in:
parent
44760c6869
commit
5fedbdbdfe
@ -14,7 +14,7 @@
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static cruft::srgba4f
|
||||
parse_hex (cruft::view<const char*> str)
|
||||
parse_hex (cruft::view<const char*> &str)
|
||||
{
|
||||
if (str.size () != strlen ("#012345"))
|
||||
throw std::invalid_argument ("expected length of 7");
|
||||
@ -36,6 +36,7 @@ parse_hex (cruft::view<const char*> str)
|
||||
uint8_t g = cruft::ascii::from_hex (str[3]) << 4u | cruft::ascii::from_hex (str[4]);
|
||||
uint8_t b = cruft::ascii::from_hex (str[5]) << 4u | cruft::ascii::from_hex (str[6]);
|
||||
|
||||
str = str.consume (7);
|
||||
return cruft::srgba<4,uint8_t> { r, g, b, 255 }.template cast<float> ();
|
||||
}
|
||||
|
||||
@ -44,7 +45,7 @@ parse_hex (cruft::view<const char*> str)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
cruft::srgba4f
|
||||
cruft::parse<cruft::srgba4f> (cruft::view<const char*> str)
|
||||
cruft::parse<cruft::srgba4f> (cruft::view<const char*> &str)
|
||||
{
|
||||
return parse_hex (str);
|
||||
}
|
@ -19,7 +19,7 @@ static unsigned
|
||||
default_parallelism (void)
|
||||
{
|
||||
if (auto var = getenv ("JOB_THREADS")) {
|
||||
return cruft::parse<unsigned> (var);
|
||||
return cruft::from_string<unsigned> (var);
|
||||
}
|
||||
|
||||
return std::thread::hardware_concurrency ();
|
||||
@ -31,7 +31,7 @@ static unsigned
|
||||
default_depth (void)
|
||||
{
|
||||
if (auto var = getenv ("JOB_DEPTH")) {
|
||||
return cruft::parse<unsigned> (var);
|
||||
return cruft::from_string<unsigned> (var);
|
||||
}
|
||||
|
||||
return 1024;
|
||||
|
82
parse.cpp
82
parse.cpp
@ -3,7 +3,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2017 Danny Robson <danny@nerdcruft.net>
|
||||
* Copyright 2017-2018 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#include "parse.hpp"
|
||||
@ -30,14 +30,16 @@ template <> struct c_traits<long double> { static constexpr auto func = strtold;
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
T
|
||||
c_iparse (const char *first, const char *last)
|
||||
c_iparse (cruft::view<char const*> &data)
|
||||
{
|
||||
auto tail = const_cast<char *> (last);
|
||||
auto val = c_traits<T>::func (first, &tail, 0);
|
||||
auto head = const_cast<char *> (data.begin ());
|
||||
auto tail = head;
|
||||
auto val = c_traits<T>::func (head, &tail, 0);
|
||||
|
||||
if (tail != last)
|
||||
throw std::invalid_argument ("unable to parse");
|
||||
if (tail == head)
|
||||
throw std::invalid_argument ("unable to parse integer");
|
||||
|
||||
data = data.consume (tail);
|
||||
return val;
|
||||
}
|
||||
|
||||
@ -45,14 +47,16 @@ c_iparse (const char *first, const char *last)
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
T
|
||||
c_fparse (const char *first, const char *last)
|
||||
c_fparse (cruft::view<char const*> &data)
|
||||
{
|
||||
auto tail = const_cast<char *> (last);
|
||||
auto val = c_traits<T>::func (first, &tail);
|
||||
auto head = const_cast<char *> (data.begin ());
|
||||
auto tail = head;
|
||||
auto val = c_traits<T>::func (head, &tail);
|
||||
|
||||
if (tail != last)
|
||||
throw std::invalid_argument ("unable to parse");
|
||||
if (tail == head)
|
||||
throw std::invalid_argument ("unable to parse float");
|
||||
|
||||
data = data.consume (tail);
|
||||
return val;
|
||||
}
|
||||
|
||||
@ -60,46 +64,38 @@ c_fparse (const char *first, const char *last)
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define C_PARSE(T, KLASS) \
|
||||
template <> \
|
||||
T \
|
||||
cruft::parse<T> (cruft::view<const char *> str) \
|
||||
{ \
|
||||
return c_ ## KLASS ## parse<T> (std::cbegin (str), std::cend (str)); \
|
||||
#define C_PARSE(T, KLASS) \
|
||||
template <> \
|
||||
T \
|
||||
cruft::parse<T> ( \
|
||||
cruft::view<const char *> &str \
|
||||
) { \
|
||||
return c_ ## KLASS ## parse<T> (str); \
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_PARSE(long, i)
|
||||
C_PARSE(long long, i)
|
||||
C_PARSE(unsigned long, i)
|
||||
C_PARSE(long, i)
|
||||
C_PARSE(long long, i)
|
||||
C_PARSE(unsigned long, i)
|
||||
C_PARSE(unsigned long long, i)
|
||||
|
||||
C_PARSE(float, f)
|
||||
C_PARSE(double, f)
|
||||
C_PARSE(float, f)
|
||||
C_PARSE(double, f)
|
||||
C_PARSE(long double, f)
|
||||
|
||||
|
||||
template <>
|
||||
int
|
||||
cruft::parse<int> (cruft::view<const char*> str)
|
||||
{
|
||||
auto intermediate = cruft::parse<long> (str);
|
||||
return cruft::cast::lossless<int> (intermediate);
|
||||
#define C_PARSE_WITH_CAST(FINAL, USED) \
|
||||
template<> \
|
||||
FINAL \
|
||||
cruft::parse<FINAL> (cruft::view<char const*> &str) { \
|
||||
auto remain = str; \
|
||||
auto res = parse<USED> (remain); \
|
||||
if (res > std::numeric_limits<FINAL>::max ()) \
|
||||
throw std::invalid_argument ("overflow during parse"); \
|
||||
\
|
||||
str = remain; \
|
||||
return cruft::cast::narrow<FINAL> (res); \
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
unsigned
|
||||
cruft::parse<unsigned> (cruft::view<const char*> str)
|
||||
{
|
||||
return cruft::cast::narrow<unsigned> (parse<unsigned long> (str));
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
unsigned short
|
||||
cruft::parse<unsigned short> (cruft::view<const char*> str)
|
||||
{
|
||||
return cruft::cast::narrow<unsigned short> (parse<unsigned long> (str));
|
||||
}
|
||||
C_PARSE_WITH_CAST(unsigned int, unsigned long)
|
||||
|
55
parse.hpp
55
parse.hpp
@ -3,43 +3,40 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2017 Danny Robson <danny@nerdcruft.net>
|
||||
* Copyright 2017-2018 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#ifndef CRUFT_UTIL_PARSE_HPP
|
||||
#define CRUFT_UTIL_PARSE_HPP
|
||||
#pragma once
|
||||
|
||||
#include "view.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <iterator>
|
||||
|
||||
|
||||
namespace cruft {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
/// extracts an instance of a native type T from the string [first, last).
|
||||
/// Extracts an instance of a native type T from the string [first, last).
|
||||
///
|
||||
/// throws std::invalid_argument when the type cannot be parsed.
|
||||
template <typename T>
|
||||
T parse (cruft::view<const char *>);
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
T parse (const char *str)
|
||||
{
|
||||
return parse<T> (make_view (str));
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
/// Throws std::invalid_argument when the type cannot be parsed.
|
||||
///
|
||||
/// The view is modified in place to reflect the unused data.
|
||||
template <typename T>
|
||||
T
|
||||
parse (const std::string &str)
|
||||
{
|
||||
return parse<T> (make_view (str));
|
||||
}
|
||||
}
|
||||
parse (cruft::view<const char *> &);
|
||||
|
||||
#endif
|
||||
|
||||
/// Parses a prefix string to obtain an instance of T.
|
||||
///
|
||||
/// This only differs from `parse` in that it throws if the entire string
|
||||
/// isn't consumed during the parse, rather than reporting the remaining
|
||||
/// data.
|
||||
template <typename T>
|
||||
T
|
||||
from_string (cruft::view<const char*> data)
|
||||
{
|
||||
T res = parse<T> (data);
|
||||
if (!data.empty ())
|
||||
throw std::invalid_argument ("unable to parse");
|
||||
return std::move (res);
|
||||
}
|
||||
|
||||
template <typename T> T from_string (const char *data) { return from_string<T> (cruft::view (data)); }
|
||||
template <typename T> T from_string (std::string const &data) { return from_string<T> (cruft::view (data)); }
|
||||
}
|
||||
|
@ -8,11 +8,11 @@ main (void)
|
||||
{
|
||||
cruft::TAP::logger tap;
|
||||
|
||||
tap.expect_eq (cruft::parse<long> ("1"), 1L, "parsing long '1'");
|
||||
tap.expect_throw<std::invalid_argument> ([] () { cruft::parse<long> ("a"); }, "parsing long 'a'");
|
||||
tap.expect_eq (cruft::from_string<long> ("1"), 1L, "parsing long '1'");
|
||||
tap.expect_throw<std::invalid_argument> ([] () { cruft::from_string<long> ("a"); }, "parsing long 'a'");
|
||||
|
||||
tap.expect_eq (cruft::parse<float> ("1"), 1.f, "parsing float '1'");
|
||||
tap.expect_throw<std::invalid_argument> ([] () { cruft::parse<float> ("a"); }, "parsing float 'a'");
|
||||
tap.expect_eq (cruft::from_string<float> ("1"), 1.f, "parsing float '1'");
|
||||
tap.expect_throw<std::invalid_argument> ([] () { cruft::from_string<float> ("a"); }, "parsing float 'a'");
|
||||
|
||||
return tap.status ();
|
||||
}
|
Loading…
Reference in New Issue
Block a user