TagFile refinements

- Use a custom prefix system for tagfiles - f for a file, p for a page, t for a tag
- Add a hex tag that reads and writes a number as hex
- Ensure booleans are always read and written as alpha
This commit is contained in:
2023-01-07 13:55:04 -05:00
parent 26db220f15
commit 71f9dd0043
2 changed files with 63 additions and 40 deletions

View File

@@ -35,12 +35,12 @@ protected:
template<typename T>
static void readValueFrom(std::istream& file, T& to) {
file >> to;
file >> std::boolalpha >> to;
}
template<typename T>
static void writeValueTo(std::ostream& file, const T& from) {
file << from;
file << std::boolalpha << from;
}
template<typename A, typename B>
@@ -111,7 +111,7 @@ public:
};
template<typename Self>
class cTagFile_MultiPage : public cTagFile_Page {
class pMultiPage : public cTagFile_Page {
std::shared_ptr<Self> next;
public:
using cTagFile_Page::cTagFile_Page;
@@ -164,10 +164,10 @@ public:
void writeTo(std::ostream& file);
};
template<typename T> class cTagFile_ArrayTag;
template<typename T> class tArrayTag;
template<typename T>
class cTagFile_BasicTag : public cTagFile_Tag {
class tBasicTag : public cTagFile_Tag {
T value;
public:
using cTagFile_Tag::cTagFile_Tag;
@@ -180,7 +180,7 @@ public:
file << '\n';
}
operator T() const { return value; }
cTagFile_BasicTag operator=(const T& new_value) { value = new_value; return *this; }
tBasicTag operator=(const T& new_value) { value = new_value; return *this; }
T& operator*() { return value; }
const T& operator*() const { return value; }
T* operator->() { return &value; }
@@ -190,7 +190,30 @@ public:
};
template<typename T>
class cTagFile_OptionalTag : public cTagFile_Tag {
class tHexTag : public cTagFile_Tag {
T value;
public:
using cTagFile_Tag::cTagFile_Tag;
void readFrom(const std::string&, std::istream& file) override {
readValueFrom(file, value);
}
void writeTo(const std::string& key, std::ostream& file) override {
file << key << ' ' << std::hex;
writeValueTo(file, value);
file << std::dec << '\n';
}
operator T() const { return value; }
tHexTag operator=(const T& new_value) { value = new_value; return *this; }
T& operator*() { return value; }
const T& operator*() const { return value; }
T* operator->() { return &value; }
const T* operator->() const { return &value; }
bool operator==(const T& other) { return value == other; }
bool operator!=(const T& other) { return value != other; }
};
template<typename T>
class tOptionalTag : public cTagFile_Tag {
boost::optional<T> value;
public:
using cTagFile_Tag::cTagFile_Tag;
@@ -206,8 +229,8 @@ public:
}
}
const T& get() const { return *value; }
cTagFile_OptionalTag operator=(const T& new_value) { value = new_value; return *this; }
cTagFile_OptionalTag operator=(boost::none_t) { value.reset(); return *this; }
tOptionalTag operator=(const T& new_value) { value = new_value; return *this; }
tOptionalTag operator=(boost::none_t) { value.reset(); return *this; }
T& operator*() { return value; }
const T& operator*() const { return value; }
T* operator->() { return &value; }
@@ -219,7 +242,7 @@ public:
};
template<>
class cTagFile_OptionalTag<bool> : public cTagFile_Tag {
class tOptionalTag<bool> : public cTagFile_Tag {
bool value = false;
public:
using cTagFile_Tag::cTagFile_Tag;
@@ -232,7 +255,7 @@ public:
}
}
const bool& get() const { return value; }
cTagFile_OptionalTag operator=(const bool& new_value) { value = new_value; return *this; }
tOptionalTag operator=(const bool& new_value) { value = new_value; return *this; }
bool& operator*() { return value; }
const bool& operator*() const { return value; }
bool operator==(const bool& other) { return value == other; }
@@ -242,7 +265,7 @@ public:
};
template<typename T>
class cTagFile_ArrayTag : public cTagFile_Tag {
class tArrayTag : public cTagFile_Tag {
std::vector<T> values;
public:
using cTagFile_Tag::cTagFile_Tag;

View File

@@ -11,54 +11,54 @@
#include "catch.hpp"
template<typename T>
std::ostream& operator<<(std::ostream& os, const cTagFile_BasicTag<T>& tag) {
std::ostream& operator<<(std::ostream& os, const tBasicTag<T>& tag) {
return os << T(tag);
}
class cSampleTagFilePage1 : public cTagFile_Page {
class pSamplePage1 : public cTagFile_Page {
public:
using cTagFile_Page::cTagFile_Page;
cTagFile_BasicTag<int> a{*this, "A"}, b{*this, "B"}, c{*this, "C"};
tBasicTag<int> a{*this, "A"}, b{*this, "B"}, c{*this, "C"};
};
class cSampleTagFilePage2 : public cTagFile_Page {
class pSamplePage2 : public cTagFile_Page {
public:
using cTagFile_Page::cTagFile_Page;
cTagFile_BasicTag<std::string> x{*this, "X"}, y{*this, "Y"}, z{*this, "Z"};
tBasicTag<std::string> x{*this, "X"}, y{*this, "Y"}, z{*this, "Z"};
};
class cSampleTagFile : public cTagFile {
class fSampleTagFile : public cTagFile {
public:
cSampleTagFilePage1 p1{*this};
cSampleTagFilePage2 p2{*this};
pSamplePage1 p1{*this};
pSamplePage2 p2{*this};
};
class cComplexTagFilePage : public cTagFile_Page {
class pComplexPage : public cTagFile_Page {
public:
using cTagFile_Page::cTagFile_Page;
cTagFile_BasicTag<int> id{*this, "ID"};
cTagFile_ArrayTag<std::string> strings{*this, "STRING"};
cTagFile_ArrayTag<std::pair<int, int>> locations{*this, "LOC"};
cTagFile_OptionalTag<int> filter{*this, "FILTER"};
cTagFile_OptionalTag<int> count{*this, "COUNT"};
cTagFile_OptionalTag<bool> yes{*this, "YES"};
cTagFile_OptionalTag<bool> no{*this, "NO"};
cTagFile_BasicTag<bool> enable{*this, "ENABLE"};
tBasicTag<int> id{*this, "ID"};
tArrayTag<std::string> strings{*this, "STRING"};
tArrayTag<std::pair<int, int>> locations{*this, "LOC"};
tOptionalTag<int> filter{*this, "FILTER"};
tOptionalTag<int> count{*this, "COUNT"};
tOptionalTag<bool> yes{*this, "YES"};
tOptionalTag<bool> no{*this, "NO"};
tBasicTag<bool> enable{*this, "ENABLE"};
};
class cTagFileSampleMultiPage : public cTagFile_MultiPage<cTagFileSampleMultiPage> {
class pSampleMultiPage : public pMultiPage<pSampleMultiPage> {
public:
using cTagFile_MultiPage::cTagFile_MultiPage;
cTagFile_BasicTag<char> id{*this, "ID"};
cTagFile_BasicTag<int> value{*this, "VALUE"};
cTagFile_BasicTag<std::string> comment{*this, "COMMENT"};
using pMultiPage::pMultiPage;
tBasicTag<char> id{*this, "ID"};
tBasicTag<int> value{*this, "VALUE"};
tBasicTag<std::string> comment{*this, "COMMENT"};
};
class cComplexTagFile : public cTagFile {
class fComplexTagFile : public cTagFile {
public:
cSampleTagFilePage1 p1{*this};
cComplexTagFilePage p2{*this};
cTagFileSampleMultiPage p3{*this};
pSamplePage1 p1{*this};
pComplexPage p2{*this};
pSampleMultiPage p3{*this};
};
TEST_CASE("Simple tag file") {
@@ -71,7 +71,7 @@ TEST_CASE("Simple tag file") {
"Y foo\n"
"Z Blah!\n"
;
cSampleTagFile content;
fSampleTagFile content;
SECTION("output") {
std::ostringstream file;
content.p1.a = 12;
@@ -123,7 +123,7 @@ TEST_CASE("Complex tag file") {
"VALUE 90\n"
"COMMENT \"It's great!\"\n"
;
cComplexTagFile content;
fComplexTagFile content;
SECTION("output") {
std::ostringstream file;
content.p1.a = 12;