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:
@@ -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;
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user