From 90c2240b41cffc11a85b9a56fccfae13a655d99a Mon Sep 17 00:00:00 2001 From: Martin Helmut Fieber Date: Mon, 28 Dec 2020 00:07:10 +0100 Subject: [PATCH] First draft of a TOML facade to abstract underlying data structure for config --- src/core/Core/Config/Command.hpp | 2 +- src/core/Core/Config/Parameter.hpp | 2 +- src/tests/Helpers/{TOML.cpp => Toml.cpp} | 4 +- src/tests/Helpers/{TOML.hpp => Toml.hpp} | 0 .../Tests/Core/Config/CommandBuilder.unit.cpp | 2 +- src/toms/CMakeLists.txt | 10 ++ src/toms/Toms.hpp | 3 + src/toms/Toms/Value.cpp | 66 +++++++++ src/toms/Toms/Value.hpp | 128 ++++++++++++++++++ 9 files changed, 212 insertions(+), 5 deletions(-) rename src/tests/Helpers/{TOML.cpp => Toml.cpp} (96%) rename src/tests/Helpers/{TOML.hpp => Toml.hpp} (100%) create mode 100644 src/toms/CMakeLists.txt create mode 100644 src/toms/Toms.hpp create mode 100644 src/toms/Toms/Value.cpp create mode 100644 src/toms/Toms/Value.hpp diff --git a/src/core/Core/Config/Command.hpp b/src/core/Core/Config/Command.hpp index ceba32c..e2e3b8a 100644 --- a/src/core/Core/Config/Command.hpp +++ b/src/core/Core/Config/Command.hpp @@ -27,7 +27,7 @@ struct Command { explicit Command(std::string name) : Name(std::move(name)) { } -}; +} __attribute__((aligned(128))); } // namespace Litr::Config diff --git a/src/core/Core/Config/Parameter.hpp b/src/core/Core/Config/Parameter.hpp index 39116b3..1b5092d 100644 --- a/src/core/Core/Config/Parameter.hpp +++ b/src/core/Core/Config/Parameter.hpp @@ -21,7 +21,7 @@ struct Parameter { explicit Parameter(std::string name) : Name(std::move(name)) { } -}; +} __attribute__((aligned(128))); } // namespace Litr::Config diff --git a/src/tests/Helpers/TOML.cpp b/src/tests/Helpers/Toml.cpp similarity index 96% rename from src/tests/Helpers/TOML.cpp rename to src/tests/Helpers/Toml.cpp index d5ffb2b..c22e0f1 100644 --- a/src/tests/Helpers/TOML.cpp +++ b/src/tests/Helpers/Toml.cpp @@ -1,7 +1,7 @@ -#include "TOML.hpp" - #include +#include "Toml.hpp" + std::pair CreateTOMLMock(const std::string& name, const std::string& toml) { std::string rFile{fmt::format(R"([{}] {})", name, toml)}; diff --git a/src/tests/Helpers/TOML.hpp b/src/tests/Helpers/Toml.hpp similarity index 100% rename from src/tests/Helpers/TOML.hpp rename to src/tests/Helpers/Toml.hpp diff --git a/src/tests/Tests/Core/Config/CommandBuilder.unit.cpp b/src/tests/Tests/Core/Config/CommandBuilder.unit.cpp index a004788..a65c34b 100644 --- a/src/tests/Tests/Core/Config/CommandBuilder.unit.cpp +++ b/src/tests/Tests/Core/Config/CommandBuilder.unit.cpp @@ -3,7 +3,7 @@ #include #include "Core/Error/Handler.hpp" -#include "Helpers/TOML.hpp" +#include "Helpers/Toml.hpp" TEST_SUITE("Config::CommandBuilder") { TEST_CASE("Initiates a Command on construction") { diff --git a/src/toms/CMakeLists.txt b/src/toms/CMakeLists.txt new file mode 100644 index 0000000..27f8862 --- /dev/null +++ b/src/toms/CMakeLists.txt @@ -0,0 +1,10 @@ +set(NAME "Toms") + +include(${CMAKE_SOURCE_DIR}/cmake/StaticAnalyzers.cmake) + +add_library(${NAME} STATIC Toms.hpp Toms/Value.cpp Toms/Value.hpp) + +target_include_directories(${NAME} PUBLIC ${CMAKE_SOURCE_DIR}/src/toms) +set_target_properties(${NAME} PROPERTIES LINKER_LANGUAGE CXX) +target_compile_features(${NAME} PRIVATE cxx_std_17) +target_link_libraries(${NAME} PRIVATE project_warnings tsl::ordered_map toml11::toml11) diff --git a/src/toms/Toms.hpp b/src/toms/Toms.hpp new file mode 100644 index 0000000..932478e --- /dev/null +++ b/src/toms/Toms.hpp @@ -0,0 +1,3 @@ +#pragma once + +#include "Toms/Value.hpp" diff --git a/src/toms/Toms/Value.cpp b/src/toms/Toms/Value.cpp new file mode 100644 index 0000000..cf3d1f6 --- /dev/null +++ b/src/toms/Toms/Value.cpp @@ -0,0 +1,66 @@ +#include "Value.hpp" + +namespace Litr::Toms { + +Value::Value(const std::string& path) { + try { + m_Data = toml::parse(path); + } catch (const toml::syntax_error& err) { + const toml::source_location& location{err.location()}; + m_HasError = true; + m_Line = location.line(); + m_Column = location.column(); + m_Content = location.line_str(); + } +} + +Value::Value(const toml::value& data) + : m_Data(data), + m_Line(data.location().line()), + m_Column(data.location().column()), + m_Content(data.location().line_str()) { +} + +Value Value::Find(const std::string& key) const { + return Value(toml::find(m_Data, key)); +} + +bool Value::Contains(const std::string& key) const { + return m_Data.contains(key); +} + +bool Value::IsTable() const { + return m_Data.is_table(); +} + +bool Value::IsString() const { + return m_Data.is_string(); +} + +bool Value::IsArray() const { + return m_Data.is_array(); +} + +Value Value::AsTable() const { + return Value(m_Data.as_table()); +} + +std::string Value::AsString() const { + return m_Data.as_string(); +} + +std::vector Value::AsArray() const { + std::vector target{}; + std::copy(m_Data.as_array().begin(), m_Data.as_array().end(), std::back_inserter(target)); + return target; +} + +Value Value::At(size_t key) const { + return Value(m_Data.at(key)); +} + +Value Value::At(const std::string& key) const { + return Value(m_Data.at(key)); +} + +} // namespace Litr::Toms diff --git a/src/toms/Toms/Value.hpp b/src/toms/Toms/Value.hpp new file mode 100644 index 0000000..85d33da --- /dev/null +++ b/src/toms/Toms/Value.hpp @@ -0,0 +1,128 @@ +#pragma once + +#include +#include + +#include +#include +#include + +namespace Litr::Toms { + +template +class ValueIterator { + public: + using ValueType = typename V::ValueType; + using PointerType = ValueType*; + using ReferenceType = ValueType&; + + public: + explicit ValueIterator(PointerType ptr) : m_Ptr(ptr) {} + + // Prefix increment + ValueIterator& operator++() { + m_Ptr++; + return *this; + } + + // Postfix increment + ValueIterator operator++(int) { + ValueIterator iterator{*this}; + ++(*this); + return iterator; + } + + // Prefix decrement + ValueIterator& operator--() { + m_Ptr--; + return *this; + } + + // Postfix decrement + ValueIterator operator--(int) { + ValueIterator iterator{*this}; + --(*this); + return iterator; + } + + ReferenceType operator[](int index) { + return *(m_Ptr + index); + } + + PointerType operator->() { + return m_Ptr; + } + + ReferenceType operator*() { + return *m_Ptr; + } + + bool operator==(const ValueIterator& other) const { + return m_Ptr == other.m_Ptr; + } + + bool operator!=(const ValueIterator& other) const { + return !(*this == other); + } + + private: + PointerType m_Ptr; +}; + +class Value { + public: + using T = toml::basic_value; + using ValueType = T; + using Iterator = ValueIterator; + + Value() = default; + explicit Value(const std::string& path); + explicit Value(const toml::value& data); + + [[nodiscard]] Value Find(const std::string& key) const; + [[nodiscard]] bool Contains(const std::string& key) const; + + [[nodiscard]] bool IsTable() const; + [[nodiscard]] bool IsString() const; + [[nodiscard]] bool IsArray() const; + + [[nodiscard]] Value AsTable() const; + [[nodiscard]] std::string AsString() const; + [[nodiscard]] std::vector AsArray() const; + + [[nodiscard]] Value At(size_t key) const; + [[nodiscard]] Value At(const std::string& key) const; + + [[nodiscard]] uint32_t GetLine() const { return m_Line; } + [[nodiscard]] uint32_t GetColumn() const { return m_Column; } + [[nodiscard]] std::string GetContent() const { return m_Content; } + + [[nodiscard]] bool HasError() const { return m_HasError; } + [[nodiscard]] size_t Size() const { return m_Data->size(); } + + Value operator[](size_t index) const { + return At(index); + } + + Value operator[](size_t index) { + return At(index); + } + + Iterator begin() { + return Iterator(m_Data); + } + + Iterator end() { + return Iterator(m_Data + Size()); + } + + private: + bool m_HasError{false}; + + T* m_Data{}; + uint32_t m_Line{}; + uint32_t m_Column{}; + std::string m_Content{}; +}; + +} // namespace Litr::Toms