From d66ad3743bbddba48e4fbb061db7db290e8adac6 Mon Sep 17 00:00:00 2001 From: Green Sky Date: Fri, 21 Jul 2023 20:24:23 +0200 Subject: [PATCH] initial config module --- CMakeLists.txt | 17 ++++++ LICENSE | 24 ++++++++ README.md | 3 + solanaceae/util/config_model.hpp | 40 +++++++++++++ solanaceae/util/config_model.inl | 96 ++++++++++++++++++++++++++++++++ 5 files changed, 180 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 LICENSE create mode 100644 README.md create mode 100644 solanaceae/util/config_model.hpp create mode 100644 solanaceae/util/config_model.inl diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..36d0d4c --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.9 FATAL_ERROR) + +project(solanaceae) + +add_library(solanaceae_util + ./solanaceae/util/config_model.hpp + ./solanaceae/util/config_model.inl + + ./solanaceae/util/simple_config_model.hpp + ./solanaceae/util/simple_config_model.cpp +) + +target_include_directories(solanaceae_util PUBLIC .) +target_compile_features(solanaceae_util PUBLIC cxx_std_17) +#target_link_libraries(solanaceae_contact PUBLIC +#) + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2780797 --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +The Code is under the following License, if not stated otherwise: + +MIT License + +Copyright (c) 2023 Erik Scholz + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..426a624 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +`plant !` + +random utilities for solanaceae diff --git a/solanaceae/util/config_model.hpp b/solanaceae/util/config_model.hpp new file mode 100644 index 0000000..744df17 --- /dev/null +++ b/solanaceae/util/config_model.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include "./config_model.inl" + +// TODO: events? +struct ConfigModelI { + ~ConfigModelI(void) {} + + // interface + // level3 + // falls back to level2 value, if set + virtual void set(CM_ISV module, CM_ISV category, CM_ISV entry, const bool value) = 0; + virtual void set(CM_ISV module, CM_ISV category, CM_ISV entry, const int64_t value) = 0; + virtual void set(CM_ISV module, CM_ISV category, CM_ISV entry, const double value) = 0; + virtual void set(CM_ISV module, CM_ISV category, CM_ISV entry, CM_ISV value) = 0; + virtual bool has_bool(CM_ISV module, CM_ISV category, CM_ISV entry) = 0; + virtual bool has_int(CM_ISV module, CM_ISV category, CM_ISV entry) = 0; + virtual bool has_double(CM_ISV module, CM_ISV category, CM_ISV entry) = 0; + virtual bool has_string(CM_ISV module, CM_ISV category, CM_ISV entry) = 0; + virtual CM_InternalOptional get_bool(CM_ISV module, CM_ISV category, CM_ISV entry) = 0; + virtual CM_InternalOptional get_int(CM_ISV module, CM_ISV category, CM_ISV entry) = 0; + virtual CM_InternalOptional get_double(CM_ISV module, CM_ISV category, CM_ISV entry) = 0; + virtual CM_InternalOptional get_string(CM_ISV module, CM_ISV category, CM_ISV entry) = 0; + + // level2 + virtual void set(CM_ISV module, CM_ISV category, const bool value) = 0; + virtual void set(CM_ISV module, CM_ISV category, const int64_t value) = 0; + virtual void set(CM_ISV module, CM_ISV category, const double value) = 0; + virtual void set(CM_ISV module, CM_ISV category, CM_ISV value) = 0; + virtual bool has_bool(CM_ISV module, CM_ISV category) = 0; + virtual bool has_int(CM_ISV module, CM_ISV category) = 0; + virtual bool has_double(CM_ISV module, CM_ISV category) = 0; + virtual bool has_string(CM_ISV module, CM_ISV category) = 0; + virtual CM_InternalOptional get_bool(CM_ISV module, CM_ISV category) = 0; + virtual CM_InternalOptional get_int(CM_ISV module, CM_ISV category) = 0; + virtual CM_InternalOptional get_double(CM_ISV module, CM_ISV category) = 0; + virtual CM_InternalOptional get_string(CM_ISV module, CM_ISV category) = 0; +}; + + diff --git a/solanaceae/util/config_model.inl b/solanaceae/util/config_model.inl new file mode 100644 index 0000000..4efe6a7 --- /dev/null +++ b/solanaceae/util/config_model.inl @@ -0,0 +1,96 @@ +#pragma once + +#include +#include +#include +#include +#include + +struct CM_InternalStringView { + const char* start {nullptr}; + uint64_t extend {0}; + + // conversion helpers + CM_InternalStringView(const std::string_view sv) : start(sv.data()), extend(sv.size()) {} + template + CM_InternalStringView(const char (&str)[N]) : start(str), extend(N) {} + CM_InternalStringView(const std::string& str) : start(str.data()), extend(str.size()) {} + operator std::string() { return {start, start+extend}; } + operator std::string_view() { return {start, extend}; } +}; +static_assert(sizeof(CM_InternalStringView) == sizeof(const char*) + sizeof(uint64_t), "guarantee abi (hope)"); + +using CM_ISV = CM_InternalStringView; + +template +struct CM_InternalOptional { + bool has_value {false}; + union { + bool b; + int64_t i; + double d; + CM_InternalStringView s; + }; + + void set(bool v) { has_value = true; b = v; } + void set(int64_t v) { has_value = true; i = v; } + void set(double v) { has_value = true; d = v; } + void set(CM_InternalStringView v) { has_value = true; s = v; } + + CM_InternalOptional(T v) : CM_InternalOptional(std::optional{v}) {} // HACK: route through conv + + // conversion helpers + CM_InternalOptional(std::nullopt_t) : has_value(false) {} + + CM_InternalOptional(std::optional opt) : has_value(opt.has_value()) { if (opt.has_value()) set(opt.value()); } + CM_InternalOptional(std::optional opt) : has_value(opt.has_value()) { if (opt.has_value()) set(opt.value()); } + CM_InternalOptional(std::optional opt) : has_value(opt.has_value()) { if (opt.has_value()) set(opt.value()); } + CM_InternalOptional(std::optional opt) : has_value(opt.has_value()) { if (opt.has_value()) set(opt.value()); } + + //operator std::optional(void) const = delete; + + operator auto() const { + if (has_value) { + if constexpr (std::is_same_v) { + return std::optional{b}; + } else if constexpr (std::is_same_v) { + return std::optional{i}; + } else if constexpr (std::is_same_v) { + return std::optional{d}; + } else if constexpr (std::is_same_v) { + return std::optional{s}; + } + } + return std::optional{}; + } + + T value(void) { + assert(has_value); // use exceptions instead? + if constexpr (std::is_same_v) { + return b; + } else if constexpr (std::is_same_v) { + return i; + } else if constexpr (std::is_same_v) { + return d; + } else if constexpr (std::is_same_v) { + return s; + } + } + + T value_or(T&& other) { + if (has_value) { + if constexpr (std::is_same_v) { + return b; + } else if constexpr (std::is_same_v) { + return i; + } else if constexpr (std::is_same_v) { + return d; + } else if constexpr (std::is_same_v) { + return s; + } + } else { + return other; + } + } +}; +