From 86395f53634b3ef1ce76a7f1e5edfdb61f8ffd80 Mon Sep 17 00:00:00 2001 From: Ben Longbons Date: Sat, 25 Oct 2014 15:24:26 -0700 Subject: Fix header ranking --- src/io/cxxstdio_enums.hpp | 77 -------- src/io/dir.hpp | 2 - src/io/extract.cpp | 220 ++++++++++++++++++++++ src/io/extract.hpp | 232 ++++++++++++++++++++++++ src/io/extract_test.cpp | 452 ++++++++++++++++++++++++++++++++++++++++++++++ src/io/fd.hpp | 2 - src/io/fwd.hpp | 6 + src/io/read.cpp | 2 +- src/io/read.hpp | 2 - src/io/write.hpp | 2 - 10 files changed, 911 insertions(+), 86 deletions(-) delete mode 100644 src/io/cxxstdio_enums.hpp create mode 100644 src/io/extract.cpp create mode 100644 src/io/extract.hpp create mode 100644 src/io/extract_test.cpp (limited to 'src/io') diff --git a/src/io/cxxstdio_enums.hpp b/src/io/cxxstdio_enums.hpp deleted file mode 100644 index 6f428e8..0000000 --- a/src/io/cxxstdio_enums.hpp +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once -// cxxstdio_enums.hpp - Opt-in integer formatting support for enums. -// -// Copyright © 2014 Ben Longbons -// -// This file is part of The Mana World (Athena server) -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "fwd.hpp" - -#include - -#include "../generic/enum.hpp" - - -namespace tmwa -{ -namespace e -{ -enum class BF : uint16_t; -enum class EPOS : uint16_t; -enum class MapCell : uint8_t; -enum class Opt0 : uint16_t; - -inline -auto decay_for_printf(BF v) -> typename remove_enum::type { return typename remove_enum::type(v); } -inline -auto decay_for_printf(EPOS v) -> typename remove_enum::type { return typename remove_enum::type(v); } -inline -auto decay_for_printf(MapCell v) -> typename remove_enum::type { return typename remove_enum::type(v); } -inline -auto decay_for_printf(Opt0 v) -> typename remove_enum::type { return typename remove_enum::type(v); } -} - -namespace magic -{ -enum class SPELLARG : uint8_t; - -inline -auto decay_for_printf(SPELLARG v) -> typename remove_enum::type { return typename remove_enum::type(v); } -} - -enum class BL : uint8_t; -enum class ByteCode : uint8_t; -enum class ItemLook : uint16_t; -enum class MS : uint8_t; -enum class SP : uint16_t; -enum class SkillID : uint16_t; -enum class StatusChange : uint16_t; - -inline -auto decay_for_printf(BL v) -> typename remove_enum::type { return typename remove_enum::type(v); } -inline -auto decay_for_printf(ByteCode v) -> typename remove_enum::type { return typename remove_enum::type(v); } -inline -auto decay_for_printf(ItemLook v) -> typename remove_enum::type { return typename remove_enum::type(v); } -inline -auto decay_for_printf(MS v) -> typename remove_enum::type { return typename remove_enum::type(v); } -inline -auto decay_for_printf(SP v) -> typename remove_enum::type { return typename remove_enum::type(v); } -inline -auto decay_for_printf(SkillID v) -> typename remove_enum::type { return typename remove_enum::type(v); } -inline -auto decay_for_printf(StatusChange v) -> typename remove_enum::type { return typename remove_enum::type(v); } -} // namespace tmwa diff --git a/src/io/dir.hpp b/src/io/dir.hpp index 071f309..f6fedbf 100644 --- a/src/io/dir.hpp +++ b/src/io/dir.hpp @@ -20,8 +20,6 @@ #include "fwd.hpp" -#include "../strings/fwd.hpp" - #include "fd.hpp" diff --git a/src/io/extract.cpp b/src/io/extract.cpp new file mode 100644 index 0000000..55d3980 --- /dev/null +++ b/src/io/extract.cpp @@ -0,0 +1,220 @@ +#include "extract.hpp" +// extract.cpp - a simple, hierarchical, tokenizer +// +// Copyright © 2013-2014 Ben Longbons +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include + +#include "../strings/astring.hpp" +#include "../strings/xstring.hpp" +#include "../strings/vstring.hpp" + +#include "../poison.hpp" + + +// TODO also pass an io::LineSpan around. +namespace tmwa +{ +bool extract(XString str, XString *rv) +{ + *rv = str; + return true; +} + +bool extract(XString str, RString *rv) +{ + *rv = str; + return true; +} + +bool extract(XString str, AString *rv) +{ + *rv = str; + return true; +} + +bool extract(XString str, std::chrono::nanoseconds *ns) +{ + std::chrono::nanoseconds::rep rep; + if (extract(str, &rep)) + { + *ns = std::chrono::nanoseconds(rep); + return true; + } + if (str.endswith("ns"_s)) + { + if (extract(str.xrslice_h("ns"_s.size()), &rep)) + { + *ns = std::chrono::nanoseconds(rep); + return true; + } + return false; + } + std::chrono::microseconds bigger; + if (extract(str, &bigger)) + { + *ns = bigger; + return *ns == bigger; + } + return false; +} +bool extract(XString str, std::chrono::microseconds *us) +{ + std::chrono::microseconds::rep rep; + if (extract(str, &rep)) + { + *us = std::chrono::microseconds(rep); + return true; + } + if (str.endswith("us"_s)) + { + if (extract(str.xrslice_h("us"_s.size()), &rep)) + { + *us = std::chrono::microseconds(rep); + return true; + } + return false; + } + std::chrono::milliseconds bigger; + if (extract(str, &bigger)) + { + *us = bigger; + return *us == bigger; + } + return false; +} +bool extract(XString str, std::chrono::milliseconds *ms) +{ + std::chrono::milliseconds::rep rep; + if (extract(str, &rep)) + { + *ms = std::chrono::milliseconds(rep); + return true; + } + if (str.endswith("ms"_s)) + { + if (extract(str.xrslice_h("ms"_s.size()), &rep)) + { + *ms = std::chrono::milliseconds(rep); + return true; + } + return false; + } + std::chrono::seconds bigger; + if (extract(str, &bigger)) + { + *ms = bigger; + return *ms == bigger; + } + return false; +} +bool extract(XString str, std::chrono::seconds *s) +{ + std::chrono::seconds::rep rep; + if (extract(str, &rep)) + { + *s = std::chrono::seconds(rep); + return true; + } + if (str.endswith("s"_s)) + { + if (extract(str.xrslice_h("s"_s.size()), &rep)) + { + *s = std::chrono::seconds(rep); + return true; + } + return false; + } + std::chrono::minutes bigger; + if (extract(str, &bigger)) + { + *s = bigger; + return *s == bigger; + } + return false; +} +bool extract(XString str, std::chrono::minutes *min) +{ + std::chrono::minutes::rep rep; + if (extract(str, &rep)) + { + *min = std::chrono::minutes(rep); + return true; + } + if (str.endswith("min"_s)) + { + if (extract(str.xrslice_h("min"_s.size()), &rep)) + { + *min = std::chrono::minutes(rep); + return true; + } + return false; + } + std::chrono::hours bigger; + if (extract(str, &bigger)) + { + *min = bigger; + return *min == bigger; + } + return false; +} +bool extract(XString str, std::chrono::hours *h) +{ + std::chrono::hours::rep rep; + if (extract(str, &rep)) + { + *h = std::chrono::hours(rep); + return true; + } + if (str.endswith("h"_s)) + { + if (extract(str.xrslice_h("h"_s.size()), &rep)) + { + *h = std::chrono::hours(rep); + return true; + } + return false; + } + std::chrono::duration> bigger; + if (extract(str, &bigger)) + { + *h = bigger; + return *h == bigger; + } + return false; +} +bool extract(XString str, std::chrono::duration> *d) +{ + std::chrono::duration>::rep rep; + if (extract(str, &rep)) + { + *d = std::chrono::duration>(rep); + return true; + } + if (str.endswith("d"_s)) + { + if (extract(str.xrslice_h("d"_s.size()), &rep)) + { + *d = std::chrono::duration>(rep); + return true; + } + return false; + } + return false; +} +} // namespace tmwa diff --git a/src/io/extract.hpp b/src/io/extract.hpp new file mode 100644 index 0000000..174243e --- /dev/null +++ b/src/io/extract.hpp @@ -0,0 +1,232 @@ +#pragma once +// extract.hpp - a simple, hierarchical, tokenizer +// +// Copyright © 2012-2013 Ben Longbons +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "fwd.hpp" + +#include +#include + +#include +#include +#include + +#include "../ints/wrap.hpp" + +#include "../strings/xstring.hpp" + +#include "../compat/time_t.hpp" + +#include "../generic/enum.hpp" + + +namespace tmwa +{ +template +bool do_extract(XString str, T t); + +template::value && !std::is_same::value && !std::is_same::value>::type> +bool extract(XString str, T *iv) +{ + if (!str || str.size() > 20) + return false; + if (!((str.front() == '-' && std::is_signed::value) + || ('0' <= str.front() && str.front() <= '9'))) + return false; + // needs a NUL, but can't always be given one. TODO VString? + char buf[20 + 1]; + std::copy(str.begin(), str.end(), buf); + buf[str.size()] = '\0'; + + char *end; + errno = 0; + if (std::is_signed::value) + { + long long v = strtoll(buf, &end, 10); + if (errno || *end) + return false; + *iv = v; + return *iv == v; + } + else + { + unsigned long long v = strtoull(buf, &end, 10); + if (errno || *end) + return false; + *iv = v; + return *iv == v; + } +} + +inline +bool extract(XString str, TimeT *tv) +{ + return extract(str, &tv->value); +} + +template::value>::type> +bool extract_as_int(XString str, T *iv) +{ + typedef typename underlying_type::type U; + U v; + // defer to integer version + if (!extract(str, &v)) + return false; + // TODO check bounds using enum min/max as in SSCANF + *iv = static_cast(v); + return true; +} + +bool extract(XString str, XString *rv); +bool extract(XString str, RString *rv); +bool extract(XString str, AString *rv); + +template +bool extract(XString str, VString *out) +{ + if (str.size() > N) + return false; + *out = str; + return true; +} + +inline +bool extract(XString str, LString exact) +{ + return str == exact; +} + +template +class LStripper +{ +public: + T impl; +}; + +template +LStripper lstripping(T v) +{ + return {v}; +} + +template +bool extract(XString str, LStripper out) +{ + return extract(str.lstrip(), out.impl); +} + +// basically just a std::tuple +// but it provides its data members publically +template +class Record; +template +class Record +{ +}; +template +class Record +{ +public: + F frist; + Record rest; +public: + Record(F f, R... r) + : frist(f), rest(r...) + {} +}; +template +Record record(T... t) +{ + return Record(t...); +} +template +Record record(T... t) +{ + static_assert(0 < n && n < sizeof...(T), "don't be silly"); + return Record(t...); +} + +template +bool extract(XString str, Record) +{ + return !str; +} + +template +bool extract(XString str, Record rec) +{ + XString::iterator s = std::find(str.begin(), str.end(), split); + XString::iterator s2 = s; + if (s2 != str.end()) + ++s2; + XString head = str.xislice_h(s); + XString tail = str.xislice_t(s2); + if (s == str.end()) + return (extract(head, rec.frist) && n <= 1) + || (!head && n <= 0); + + return (extract(head, rec.frist) || n <= 0) + && extract(tail, rec.rest); +} + +template +struct VRecord +{ + std::vector *arr; +}; + +template +VRecord vrec(std::vector *arr) +{ + return {arr}; +} + +template +bool extract(XString str, VRecord rec) +{ + if (!str) + return true; + XString::iterator s = std::find(str.begin(), str.end(), split); + rec.arr->emplace_back(); + if (s == str.end()) + return extract(str, &rec.arr->back()); + return extract(str.xislice_h(s), &rec.arr->back()) + && extract(str.xislice_t(s + 1), rec); +} + +template +bool do_extract(XString str, T t) +{ + return extract(str, t); +} + +template +bool extract(XString str, Wrapped *w) +{ + return extract(str, &w->_value); +} + +bool extract(XString str, std::chrono::nanoseconds *ns); +bool extract(XString str, std::chrono::microseconds *us); +bool extract(XString str, std::chrono::milliseconds *ms); +bool extract(XString str, std::chrono::seconds *s); +bool extract(XString str, std::chrono::minutes *min); +bool extract(XString str, std::chrono::hours *h); +bool extract(XString str, std::chrono::duration> *d); +} // namespace tmwa diff --git a/src/io/extract_test.cpp b/src/io/extract_test.cpp new file mode 100644 index 0000000..ee4cb08 --- /dev/null +++ b/src/io/extract_test.cpp @@ -0,0 +1,452 @@ +#include "extract.hpp" +// extract_test.cpp - Testsuite for a simple, hierarchical, tokenizer +// +// Copyright © 2013 Ben Longbons +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include + +#include "../strings/xstring.hpp" + +#include "../net/timer.t.hpp" + +#include "../mmo/strs.hpp" + +#include "../high/extract_mmo.hpp" + +#include "../poison.hpp" + + +namespace tmwa +{ +TEST(extract, record_int) +{ + int x, y, z; + x = y = z = 0; + EXPECT_FALSE(extract("1 2 3 4 "_s, record<' '>(&x, &y, &z))); + EXPECT_EQ(1, x); + EXPECT_EQ(2, y); + EXPECT_EQ(3, z); + x = y = z = 0; + EXPECT_FALSE(extract("1 2 3 4"_s, record<' '>(&x, &y, &z))); + EXPECT_EQ(1, x); + EXPECT_EQ(2, y); + EXPECT_EQ(3, z); + x = y = z = 0; + EXPECT_TRUE(extract("1 2 3 "_s, record<' '>(&x, &y, &z))); + EXPECT_EQ(1, x); + EXPECT_EQ(2, y); + EXPECT_EQ(3, z); + x = y = z = 0; + EXPECT_TRUE(extract("1 2 3"_s, record<' '>(&x, &y, &z))); + EXPECT_EQ(1, x); + EXPECT_EQ(2, y); + EXPECT_EQ(3, z); + x = y = z = 0; + EXPECT_FALSE(extract("1 2 "_s, record<' '>(&x, &y, &z))); + EXPECT_EQ(1, x); + EXPECT_EQ(2, y); + EXPECT_EQ(0, z); + x = y = z = 0; + EXPECT_FALSE(extract("1 2"_s, record<' '>(&x, &y, &z))); + EXPECT_EQ(1, x); + EXPECT_EQ(2, y); + EXPECT_EQ(0, z); + x = y = z = 0; + EXPECT_FALSE(extract("1 "_s, record<' '>(&x, &y, &z))); + EXPECT_EQ(1, x); + EXPECT_EQ(0, y); + EXPECT_EQ(0, z); + x = y = z = 0; + EXPECT_FALSE(extract("1"_s, record<' '>(&x, &y, &z))); + EXPECT_EQ(1, x); + EXPECT_EQ(0, y); + EXPECT_EQ(0, z); + x = y = z = 0; + EXPECT_FALSE(extract(" "_s, record<' '>(&x, &y, &z))); + EXPECT_EQ(0, x); + EXPECT_EQ(0, y); + EXPECT_EQ(0, z); + x = y = z = 0; + EXPECT_FALSE(extract(""_s, record<' '>(&x, &y, &z))); + EXPECT_EQ(0, x); + EXPECT_EQ(0, y); + EXPECT_EQ(0, z); + x = y = z = 0; + + EXPECT_FALSE(extract("1 2 3 4 "_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ(1, x); + EXPECT_EQ(2, y); + EXPECT_EQ(3, z); + x = y = z = 0; + EXPECT_FALSE(extract("1 2 3 4"_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ(1, x); + EXPECT_EQ(2, y); + EXPECT_EQ(3, z); + x = y = z = 0; + EXPECT_TRUE(extract("1 2 3 "_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ(1, x); + EXPECT_EQ(2, y); + EXPECT_EQ(3, z); + x = y = z = 0; + EXPECT_TRUE(extract("1 2 3"_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ(1, x); + EXPECT_EQ(2, y); + EXPECT_EQ(3, z); + x = y = z = 0; + EXPECT_TRUE(extract("1 2 "_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ(1, x); + EXPECT_EQ(2, y); + EXPECT_EQ(0, z); + x = y = z = 0; + EXPECT_TRUE(extract("1 2"_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ(1, x); + EXPECT_EQ(2, y); + EXPECT_EQ(0, z); + x = y = z = 0; + EXPECT_FALSE(extract("1 "_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ(1, x); + EXPECT_EQ(0, y); + EXPECT_EQ(0, z); + x = y = z = 0; + EXPECT_FALSE(extract("1"_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ(1, x); + EXPECT_EQ(0, y); + EXPECT_EQ(0, z); + x = y = z = 0; + EXPECT_FALSE(extract(" "_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ(0, x); + EXPECT_EQ(0, y); + EXPECT_EQ(0, z); + x = y = z = 0; + EXPECT_FALSE(extract(""_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ(0, x); + EXPECT_EQ(0, y); + EXPECT_EQ(0, z); + x = y = z = 0; + + EXPECT_FALSE(extract("1 2 3 4 "_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ(1, x); + EXPECT_EQ(2, y); + EXPECT_EQ(3, z); + x = y = z = 0; + EXPECT_FALSE(extract("1 2 3 4"_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ(1, x); + EXPECT_EQ(2, y); + EXPECT_EQ(3, z); + x = y = z = 0; + EXPECT_TRUE(extract("1 2 3 "_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ(1, x); + EXPECT_EQ(2, y); + EXPECT_EQ(3, z); + x = y = z = 0; + EXPECT_TRUE(extract("1 2 3"_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ(1, x); + EXPECT_EQ(2, y); + EXPECT_EQ(3, z); + x = y = z = 0; + EXPECT_TRUE(extract("1 2 "_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ(1, x); + EXPECT_EQ(2, y); + EXPECT_EQ(0, z); + x = y = z = 0; + EXPECT_TRUE(extract("1 2"_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ(1, x); + EXPECT_EQ(2, y); + EXPECT_EQ(0, z); + x = y = z = 0; + EXPECT_TRUE(extract("1 "_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ(1, x); + EXPECT_EQ(0, y); + EXPECT_EQ(0, z); + x = y = z = 0; + EXPECT_TRUE(extract("1"_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ(1, x); + EXPECT_EQ(0, y); + EXPECT_EQ(0, z); + x = y = z = 0; + EXPECT_FALSE(extract(" "_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ(0, x); + EXPECT_EQ(0, y); + EXPECT_EQ(0, z); + x = y = z = 0; + EXPECT_FALSE(extract(""_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ(0, x); + EXPECT_EQ(0, y); + EXPECT_EQ(0, z); + x = y = z = 0; +} + +TEST(extract, record_str) +{ + XString x, y, z; + x = y = z = ""_s; + EXPECT_FALSE(extract("1 2 3 4 "_s, record<' '>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ("3"_s, z); + x = y = z = ""_s; + EXPECT_FALSE(extract("1 2 3 4"_s, record<' '>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ("3"_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 2 3 "_s, record<' '>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ("3"_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 2 3"_s, record<' '>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ("3"_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 2 "_s, record<' '>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_FALSE(extract("1 2"_s, record<' '>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_FALSE(extract("1 "_s, record<' '>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ(""_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_FALSE(extract("1"_s, record<' '>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ(""_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_FALSE(extract(" "_s, record<' '>(&x, &y, &z))); + EXPECT_EQ(""_s, x); + EXPECT_EQ(""_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_FALSE(extract(""_s, record<' '>(&x, &y, &z))); + EXPECT_EQ(""_s, x); + EXPECT_EQ(""_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + + EXPECT_FALSE(extract("1 2 3 4 "_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ("3"_s, z); + x = y = z = ""_s; + EXPECT_FALSE(extract("1 2 3 4"_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ("3"_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 2 3 "_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ("3"_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 2 3"_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ("3"_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 2 "_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 2"_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 "_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ(""_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_FALSE(extract("1"_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ(""_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract(" "_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ(""_s, x); + EXPECT_EQ(""_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_FALSE(extract(""_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ(""_s, x); + EXPECT_EQ(""_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + + EXPECT_FALSE(extract("1 2 3 4 "_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ("3"_s, z); + x = y = z = ""_s; + EXPECT_FALSE(extract("1 2 3 4"_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ("3"_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 2 3 "_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ("3"_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 2 3"_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ("3"_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 2 "_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 2"_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 "_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ(""_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1"_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ(""_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract(" "_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ(""_s, x); + EXPECT_EQ(""_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract(""_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ(""_s, x); + EXPECT_EQ(""_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; +} + +TEST(extract, mapname) +{ + MapName map; + EXPECT_TRUE(extract("abc"_s, &map)); + EXPECT_EQ(map, "abc"_s); + EXPECT_TRUE(extract("abc.gat"_s, &map)); + EXPECT_EQ(map, "abc"_s); + EXPECT_TRUE(extract("abcdefghijklmno"_s, &map)); + EXPECT_EQ(map, "abcdefghijklmno"_s); + EXPECT_TRUE(extract("abcdefghijklmno.gat"_s, &map)); + EXPECT_EQ(map, "abcdefghijklmno"_s); +} + +TEST(extract, chrono) +{ + std::chrono::nanoseconds ns; + std::chrono::microseconds us; + std::chrono::milliseconds ms; + std::chrono::seconds s; + std::chrono::minutes min; + std::chrono::hours h; + std::chrono::duration> d; + + EXPECT_TRUE(extract("1"_s, &ns)); + EXPECT_EQ(ns, 1_ns); + EXPECT_TRUE(extract("3ns"_s, &ns)); + EXPECT_EQ(ns, 3_ns); + EXPECT_TRUE(extract("4us"_s, &ns)); + EXPECT_EQ(ns, 4_us); + EXPECT_TRUE(extract("5ms"_s, &ns)); + EXPECT_EQ(ns, 5_ms); + EXPECT_TRUE(extract("6s"_s, &ns)); + EXPECT_EQ(ns, 6_s); + EXPECT_TRUE(extract("7min"_s, &ns)); + EXPECT_EQ(ns, 7_min); + EXPECT_TRUE(extract("8h"_s, &ns)); + EXPECT_EQ(ns, 8_h); + EXPECT_TRUE(extract("9d"_s, &ns)); + EXPECT_EQ(ns, 9_d); + + EXPECT_TRUE(extract("1"_s, &us)); + EXPECT_EQ(us, 1_us); + EXPECT_TRUE(extract("4us"_s, &us)); + EXPECT_EQ(us, 4_us); + EXPECT_TRUE(extract("5ms"_s, &us)); + EXPECT_EQ(us, 5_ms); + EXPECT_TRUE(extract("6s"_s, &us)); + EXPECT_EQ(us, 6_s); + EXPECT_TRUE(extract("7min"_s, &us)); + EXPECT_EQ(us, 7_min); + EXPECT_TRUE(extract("8h"_s, &us)); + EXPECT_EQ(us, 8_h); + EXPECT_TRUE(extract("9d"_s, &us)); + EXPECT_EQ(us, 9_d); + + EXPECT_TRUE(extract("1"_s, &ms)); + EXPECT_EQ(ms, 1_ms); + EXPECT_TRUE(extract("5ms"_s, &ms)); + EXPECT_EQ(ms, 5_ms); + EXPECT_TRUE(extract("6s"_s, &ms)); + EXPECT_EQ(ms, 6_s); + EXPECT_TRUE(extract("7min"_s, &ms)); + EXPECT_EQ(ms, 7_min); + EXPECT_TRUE(extract("8h"_s, &ms)); + EXPECT_EQ(ms, 8_h); + EXPECT_TRUE(extract("9d"_s, &ms)); + EXPECT_EQ(ms, 9_d); + + EXPECT_TRUE(extract("1"_s, &s)); + EXPECT_EQ(s, 1_s); + EXPECT_TRUE(extract("6s"_s, &s)); + EXPECT_EQ(s, 6_s); + EXPECT_TRUE(extract("7min"_s, &s)); + EXPECT_EQ(s, 7_min); + EXPECT_TRUE(extract("8h"_s, &s)); + EXPECT_EQ(s, 8_h); + EXPECT_TRUE(extract("9d"_s, &s)); + EXPECT_EQ(s, 9_d); + + EXPECT_TRUE(extract("1"_s, &min)); + EXPECT_EQ(min, 1_min); + EXPECT_TRUE(extract("7min"_s, &min)); + EXPECT_EQ(min, 7_min); + EXPECT_TRUE(extract("8h"_s, &min)); + EXPECT_EQ(min, 8_h); + EXPECT_TRUE(extract("9d"_s, &min)); + EXPECT_EQ(min, 9_d); + + EXPECT_TRUE(extract("1"_s, &h)); + EXPECT_EQ(h, 1_h); + EXPECT_TRUE(extract("8h"_s, &h)); + EXPECT_EQ(h, 8_h); + EXPECT_TRUE(extract("9d"_s, &h)); + EXPECT_EQ(h, 9_d); + + EXPECT_TRUE(extract("1"_s, &d)); + EXPECT_EQ(d, 1_d); + EXPECT_TRUE(extract("9d"_s, &d)); + EXPECT_EQ(d, 9_d); +} +} // namespace tmwa diff --git a/src/io/fd.hpp b/src/io/fd.hpp index d04d5bf..03a8b44 100644 --- a/src/io/fd.hpp +++ b/src/io/fd.hpp @@ -23,8 +23,6 @@ #include #include -#include "../strings/fwd.hpp" - #include "../diagnostics.hpp" diff --git a/src/io/fwd.hpp b/src/io/fwd.hpp index deeb08c..99268f4 100644 --- a/src/io/fwd.hpp +++ b/src/io/fwd.hpp @@ -20,6 +20,12 @@ #include "../sanity.hpp" +#include "../ints/fwd.hpp" // rank 1 +#include "../strings/fwd.hpp" // rank 1 +#include "../compat/fwd.hpp" // rank 2 +#include "../generic/fwd.hpp" // rank 3 +// io/fwd.hpp is rank 4 + namespace tmwa { diff --git a/src/io/read.cpp b/src/io/read.cpp index f3ed293..30620a1 100644 --- a/src/io/read.cpp +++ b/src/io/read.cpp @@ -25,7 +25,7 @@ #include "../strings/zstring.hpp" #include "../strings/literal.hpp" -#include "../io/cxxstdio.hpp" +#include "cxxstdio.hpp" #include "../poison.hpp" diff --git a/src/io/read.hpp b/src/io/read.hpp index 1ec26ca..c1c4882 100644 --- a/src/io/read.hpp +++ b/src/io/read.hpp @@ -20,8 +20,6 @@ #include "fwd.hpp" -#include "../strings/fwd.hpp" - #include "dir.hpp" #include "fd.hpp" diff --git a/src/io/write.hpp b/src/io/write.hpp index 1ab05f3..d7d3699 100644 --- a/src/io/write.hpp +++ b/src/io/write.hpp @@ -22,8 +22,6 @@ #include -#include "../strings/fwd.hpp" - #include "dir.hpp" #include "fd.hpp" -- cgit v1.2.3-70-g09d2