si: change the SI code to a parser
This commit is contained in:
parent
34ab275578
commit
020d3c0aaf
@ -606,6 +606,7 @@ if (TESTS)
|
|||||||
rational
|
rational
|
||||||
region
|
region
|
||||||
roots/bisection
|
roots/bisection
|
||||||
|
si
|
||||||
signal
|
signal
|
||||||
singleton
|
singleton
|
||||||
stream
|
stream
|
||||||
|
49
si.cpp
49
si.cpp
@ -3,16 +3,51 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*
|
*
|
||||||
* Copyright 2011 Danny Robson <danny@nerdcruft.net>
|
* Copyright 2019 Danny Robson <danny@nerdcruft.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "si.hpp"
|
#include "si.hpp"
|
||||||
|
|
||||||
uintmax_t to_KiB (uintmax_t bytes) { return bytes >> 10; }
|
#include "std.hpp"
|
||||||
uintmax_t to_MiB (uintmax_t bytes) { return bytes >> 20; }
|
#include "parse.hpp"
|
||||||
uintmax_t to_GiB (uintmax_t bytes) { return bytes >> 30; }
|
|
||||||
|
|
||||||
uintmax_t from_KiB (uintmax_t bytes) { return bytes << 10; }
|
#include <cruft/util/preprocessor.hpp>
|
||||||
uintmax_t from_MiB (uintmax_t bytes) { return bytes << 20; }
|
|
||||||
uintmax_t from_GiB (uintmax_t bytes) { return bytes << 30; }
|
|
||||||
|
|
||||||
|
#include <charconv>
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename ValueT>
|
||||||
|
cruft::expected<ValueT, std::errc>
|
||||||
|
cruft::si::parse (cruft::view<char const*> const src)
|
||||||
|
{
|
||||||
|
auto remain = src;
|
||||||
|
ValueT dst = cruft::parse<ValueT> (remain);
|
||||||
|
|
||||||
|
switch (remain.size ()) {
|
||||||
|
case 0:
|
||||||
|
return dst;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
switch (remain[0]) {
|
||||||
|
case 'K': case 'k': return dst * 1024;
|
||||||
|
case 'M': case 'm': return dst * 1024 * 1024;
|
||||||
|
case 'G': case 'g': return dst * 1024 * 1024 * 1024;
|
||||||
|
case 'T': case 't': return dst * 1024 * 1024 * 1024 * 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return cruft::unexpected (std::errc::invalid_argument);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define INSTANTIATE(KLASS) template cruft::expected<KLASS,std::errc> cruft::si::parse (cruft::view<char const*>);
|
||||||
|
|
||||||
|
|
||||||
|
MAP0 (INSTANTIATE,
|
||||||
|
u16, u32, u64,
|
||||||
|
i16, i32, i64,
|
||||||
|
f32, f64
|
||||||
|
)
|
||||||
|
21
si.hpp
21
si.hpp
@ -3,20 +3,19 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*
|
*
|
||||||
* Copyright 2011 Danny Robson <danny@nerdcruft.net>
|
* Copyright 2019 Danny Robson <danny@nerdcruft.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __UTIL_SI_HPP
|
#pragma once
|
||||||
#define __UTIL_SI_HPP
|
|
||||||
|
|
||||||
#include <cstdint>
|
#include "expected.hpp"
|
||||||
|
#include "view.hpp"
|
||||||
|
|
||||||
uintmax_t to_KiB (uintmax_t bytes);
|
#include <system_error>
|
||||||
uintmax_t to_MiB (uintmax_t bytes);
|
|
||||||
uintmax_t to_GiB (uintmax_t bytes);
|
|
||||||
|
|
||||||
uintmax_t from_KiB (uintmax_t bytes);
|
namespace cruft::si {
|
||||||
uintmax_t from_MiB (uintmax_t bytes);
|
template <typename ValueT>
|
||||||
uintmax_t from_GiB (uintmax_t bytes);
|
expected<ValueT, std::errc>
|
||||||
|
parse (cruft::view<char const*>);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
33
test/si.cpp
Normal file
33
test/si.cpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#include "tap.hpp"
|
||||||
|
#include "si.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
int main ()
|
||||||
|
{
|
||||||
|
cruft::TAP::logger tap;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
char const *str;
|
||||||
|
std::size_t val;
|
||||||
|
} const TESTS[] = {
|
||||||
|
{ "0", 0u },
|
||||||
|
{ "1", 1u },
|
||||||
|
{ "1K", 1024u },
|
||||||
|
{ "1M", 1024u * 1024u },
|
||||||
|
{ "1G" , 1024u * 1024u * 1024u },
|
||||||
|
{ "1T", 1024ul * 1024u * 1024u * 1024u },
|
||||||
|
{ "3M", 3u * 1024u * 1024u },
|
||||||
|
{ "3k", 3u * 1024u },
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto const &t: TESTS) {
|
||||||
|
auto res = cruft::si::parse<std::size_t> (t.str);
|
||||||
|
if (!res) {
|
||||||
|
tap.fail ("SI parsing %!", t.str);
|
||||||
|
} else {
|
||||||
|
tap.expect_eq (t.val, *res, "SI parsing '%!'", t.str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tap.status ();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user