summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2020-10-25 12:56:57 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2020-10-25 12:56:57 +0000
commitb677e823d0c2c82624c45aa7d7e82ea4d946cbde (patch)
treeeeb9da3e89a71f85ec6a36b6602c36c006631dca
parentTidy CppNamed reference IO (diff)
downloadslicer-b677e823d0c2c82624c45aa7d7e82ea4d946cbde.tar.bz2
slicer-b677e823d0c2c82624c45aa7d7e82ea4d946cbde.tar.xz
slicer-b677e823d0c2c82624c45aa7d7e82ea4d946cbde.zip
First cut constexpr hooks and metadata
-rw-r--r--slicer/db/sqlCommon.cpp20
-rw-r--r--slicer/json/serializer.cpp6
-rw-r--r--slicer/slicer/Jamfile.jam1
-rw-r--r--slicer/slicer/enumMap.h1
-rw-r--r--slicer/slicer/hookMap.h1
-rw-r--r--slicer/slicer/metadata-test.cpp15
-rw-r--r--slicer/slicer/metadata.cpp48
-rw-r--r--slicer/slicer/metadata.h96
-rw-r--r--slicer/slicer/modelParts.cpp1
-rw-r--r--slicer/slicer/modelParts.h6
-rw-r--r--slicer/slicer/modelPartsTypes.h3
-rw-r--r--slicer/slicer/modelPartsTypes.impl.h19
-rw-r--r--slicer/test/Jamfile.jam1
-rw-r--r--slicer/test/preprocessor.cpp26
-rw-r--r--slicer/tool/Jamfile.jam1
-rw-r--r--slicer/tool/icemetadata.cpp45
-rw-r--r--slicer/tool/icemetadata.h40
-rw-r--r--slicer/tool/parser.cpp170
-rw-r--r--slicer/tool/parser.h24
-rw-r--r--slicer/xml/serializer.cpp32
20 files changed, 353 insertions, 203 deletions
diff --git a/slicer/db/sqlCommon.cpp b/slicer/db/sqlCommon.cpp
index ecce6cc..7ef0046 100644
--- a/slicer/db/sqlCommon.cpp
+++ b/slicer/db/sqlCommon.cpp
@@ -4,41 +4,39 @@
#include <sqlExceptions.h>
namespace Slicer {
- const std::string md_pkey = "db:pkey";
- const std::string md_auto = "db:auto";
- const std::string md_ignore = "db:ignore";
- const std::string md_global_ignore = "ignore";
+ constexpr std::string_view md_pkey {"db:pkey"};
+ constexpr std::string_view md_auto {"db:auto"};
+ constexpr std::string_view md_ignore {"db:ignore"};
+ constexpr std::string_view md_global_ignore {"ignore"};
bool
isPKey(const HookCommon * h)
{
- return metaDataFlagSet(h->GetMetadata(), md_pkey) && isBind(h);
+ return h->GetMetadata().flagSet(md_pkey) && isBind(h);
}
bool
isAuto(const HookCommon * h)
{
- return metaDataFlagSet(h->GetMetadata(), md_auto) && isBind(h);
+ return h->GetMetadata().flagSet(md_auto) && isBind(h);
}
bool
isNotAuto(const HookCommon * h)
{
- return metaDataFlagNotSet(h->GetMetadata(), md_auto) && isBind(h);
+ return h->GetMetadata().flagNotSet(md_auto) && isBind(h);
}
bool
isBind(const HookCommon * h)
{
- return metaDataFlagNotSet(h->GetMetadata(), md_global_ignore)
- && metaDataFlagNotSet(h->GetMetadata(), md_ignore);
+ return h->GetMetadata().flagNotSet(md_global_ignore) && h->GetMetadata().flagNotSet(md_ignore);
}
bool
isValue(const HookCommon * h)
{
- return metaDataFlagNotSet(h->GetMetadata(), md_auto) && metaDataFlagNotSet(h->GetMetadata(), md_pkey)
- && isBind(h);
+ return h->GetMetadata().flagNotSet(md_auto) && h->GetMetadata().flagNotSet(md_pkey) && isBind(h);
}
void
diff --git a/slicer/json/serializer.cpp b/slicer/json/serializer.cpp
index 0fa736c..aaf1999 100644
--- a/slicer/json/serializer.cpp
+++ b/slicer/json/serializer.cpp
@@ -164,7 +164,7 @@ namespace Slicer {
}
}
modelPart->Create();
- if (metaDataFlagSet(modelPart->GetMetadata(), md_object)) {
+ if (modelPart->GetMetadata().flagSet(md_object)) {
for (const auto & element : o) {
auto emp = modelPart->GetAnonChild();
emp->Create();
@@ -278,7 +278,7 @@ namespace Slicer {
break;
case ModelPartType::Dictionary:
if (mp->HasValue()) {
- if (metaDataFlagSet(mp->GetMetadata(), md_object)) {
+ if (mp->GetMetadata().flagSet(md_object)) {
mp->OnEachChild(
[capture0 = &std::get<json::Object>(*n).insert({name, json::Object()}).first->second](
auto &&, auto && PH2, auto &&) {
@@ -327,7 +327,7 @@ namespace Slicer {
});
break;
case ModelPartType::Dictionary:
- if (metaDataFlagSet(mp->GetMetadata(), md_object)) {
+ if (mp->GetMetadata().flagSet(md_object)) {
*n = json::Object();
mp->OnEachChild([n](auto &&, auto && PH2, auto &&) {
return JsonSerializer::ModelTreeIterateDictObj(n, PH2);
diff --git a/slicer/slicer/Jamfile.jam b/slicer/slicer/Jamfile.jam
index 38a0c66..ab6420e 100644
--- a/slicer/slicer/Jamfile.jam
+++ b/slicer/slicer/Jamfile.jam
@@ -4,6 +4,7 @@ lib stdc++fs ;
obj enum-test : enum-test.cpp ;
obj hook-test : hook-test.cpp : <use>..//adhocutil <implicit-dependency>common ;
+obj metadata-test : metadata-test.cpp : <use>..//adhocutil <implicit-dependency>common ;
obj common : common.ice : <toolset>tidy:<checker>none ;
diff --git a/slicer/slicer/enumMap.h b/slicer/slicer/enumMap.h
index a7b42c2..a6f941d 100644
--- a/slicer/slicer/enumMap.h
+++ b/slicer/slicer/enumMap.h
@@ -38,6 +38,7 @@ namespace Slicer {
return nullptr;
}
+ protected:
const Node * begin {};
const Node * end {};
};
diff --git a/slicer/slicer/hookMap.h b/slicer/slicer/hookMap.h
index 5b99f96..153f9c0 100644
--- a/slicer/slicer/hookMap.h
+++ b/slicer/slicer/hookMap.h
@@ -126,6 +126,7 @@ namespace Slicer {
return _end;
}
+ protected:
const HookPtr * _begin {};
const HookPtr * _end {};
};
diff --git a/slicer/slicer/metadata-test.cpp b/slicer/slicer/metadata-test.cpp
new file mode 100644
index 0000000..2d3215a
--- /dev/null
+++ b/slicer/slicer/metadata-test.cpp
@@ -0,0 +1,15 @@
+#include "metadata.h"
+
+constexpr Slicer::MetaDataImpl<4> md {{{
+ "slicer:yes",
+ "slicer:no",
+ "slicer:sub:scope",
+ "notslicer:dontcare",
+}}};
+
+static_assert(md.flagSet("slicer:yes"));
+static_assert(md.flagSet("slicer:no"));
+static_assert(md.flagNotSet("slicer:chickens"));
+static_assert(md.value("slicer:").has_value());
+static_assert(md.value("slicer:").value() == "yes");
+static_assert(!md.value("nope:").has_value());
diff --git a/slicer/slicer/metadata.cpp b/slicer/slicer/metadata.cpp
deleted file mode 100644
index 6429cc8..0000000
--- a/slicer/slicer/metadata.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-#include "metadata.h"
-#include <boost/algorithm/string/classification.hpp>
-#include <boost/algorithm/string/predicate.hpp>
-#include <boost/algorithm/string/split.hpp>
-
-bool
-Slicer::metaDataFlagSet(const std::list<std::string> & md, const std::string & flag)
-{
- return std::find(md.cbegin(), md.cend(), flag) != md.cend();
-}
-
-bool
-Slicer::metaDataFlagNotSet(const std::list<std::string> & md, const std::string & flag)
-{
- return std::find(md.cbegin(), md.cend(), flag) == md.cend();
-}
-
-std::list<std::string>
-Slicer::metaDataValues(const std::string & prefix, const std::list<std::string> & metadata)
-{
- std::list<std::string> mds;
- for (const auto & md : metadata) {
- if (boost::algorithm::starts_with(md, prefix)) {
- mds.push_back(md.substr(prefix.length()));
- }
- }
- return mds;
-}
-
-std::vector<std::string>
-Slicer::metaDataSplit(const std::string & metadata)
-{
- std::vector<std::string> parts;
- // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
- boost::algorithm::split(parts, metadata, boost::algorithm::is_any_of(":"), boost::algorithm::token_compress_off);
- return parts;
-}
-
-std::optional<std::string>
-Slicer::metaDataValue(const std::string & prefix, const std::list<std::string> & metadata)
-{
- for (const auto & md : metadata) {
- if (boost::algorithm::starts_with(md, prefix)) {
- return md.substr(prefix.length());
- }
- }
- return std::optional<std::string>();
-}
diff --git a/slicer/slicer/metadata.h b/slicer/slicer/metadata.h
index e604658..ced234f 100644
--- a/slicer/slicer/metadata.h
+++ b/slicer/slicer/metadata.h
@@ -1,21 +1,97 @@
#ifndef SLICER_METADATA_H
#define SLICER_METADATA_H
-#include <list>
+#include <algorithm>
+#include <array>
#include <optional>
#include <string>
#include <vector>
+#include <visibility.h>
namespace Slicer {
-#pragma GCC visibility push(default)
- // Flags
- bool metaDataFlagSet(const std::list<std::string> &, const std::string & flag);
- bool metaDataFlagNotSet(const std::list<std::string> &, const std::string & flag);
- // Values
- std::optional<std::string> metaDataValue(const std::string & prefix, const std::list<std::string> & metadata);
- std::list<std::string> metaDataValues(const std::string & prefix, const std::list<std::string> & metadata);
- std::vector<std::string> metaDataSplit(const std::string & metadata);
-#pragma GCC visibility pop
+ template<typename Iter = std::array<std::string_view, 1>::const_iterator> class DLL_PUBLIC MetaData {
+ public:
+ using Value = std::string_view;
+
+ constexpr MetaData() = default;
+
+ // Flags
+ constexpr inline bool
+ flagSet(std::string_view flag) const
+ {
+ return find(flag) != _end;
+ }
+
+ constexpr inline bool
+ flagNotSet(std::string_view flag) const
+ {
+ return find(flag) == _end;
+ }
+
+ // Values
+ constexpr std::optional<std::string_view>
+ value(std::string_view prefix) const
+ {
+ for (auto mditr = _begin; mditr != _end; mditr++) {
+ const std::string_view md {*mditr};
+ if (md.substr(0, prefix.length()) == prefix) {
+ return md.substr(prefix.length());
+ }
+ }
+ return {};
+ }
+
+ std::vector<std::string_view>
+ values(std::string_view prefix) const
+ {
+ std::vector<std::string_view> mds;
+ for (auto mditr = _begin; mditr != _end; mditr++) {
+ const std::string_view md {*mditr};
+ if (md.substr(0, prefix.length()) == prefix) {
+ mds.push_back(md.substr(prefix.length()));
+ }
+ }
+ return mds;
+ }
+
+ constexpr auto
+ begin() const
+ {
+ return _begin;
+ }
+ constexpr auto
+ end() const
+ {
+ return _end;
+ }
+
+ protected:
+ Iter _begin {};
+ Iter _end {};
+
+ constexpr Iter
+ find(Value v) const
+ {
+ for (auto mdptr = _begin; mdptr != _end; mdptr++) {
+ if (*mdptr == v) {
+ return mdptr;
+ }
+ }
+ return _end;
+ }
+ };
+
+ template<std::size_t N> class DLL_PUBLIC MetaDataImpl : public MetaData<> {
+ public:
+ using Arr = std::array<Value, N>;
+ constexpr inline MetaDataImpl(Arr a) : arr(std::move(a))
+ {
+ _begin = arr.begin();
+ _end = arr.end();
+ }
+
+ Arr arr;
+ };
}
#endif
diff --git a/slicer/slicer/modelParts.cpp b/slicer/slicer/modelParts.cpp
index ccfd647..bbb142a 100644
--- a/slicer/slicer/modelParts.cpp
+++ b/slicer/slicer/modelParts.cpp
@@ -1,7 +1,6 @@
#include "modelParts.h"
namespace Slicer {
- const Metadata emptyMetadata;
void
ModelPart::Create()
{
diff --git a/slicer/slicer/modelParts.h b/slicer/slicer/modelParts.h
index bcc6a05..1596ad8 100644
--- a/slicer/slicer/modelParts.h
+++ b/slicer/slicer/modelParts.h
@@ -1,9 +1,9 @@
#ifndef SLICER_MODELPARTS_H
#define SLICER_MODELPARTS_H
+#include "metadata.h"
#include <Ice/Config.h>
#include <functional>
-#include <list>
#include <optional>
#include <stdexcept>
#include <vector>
@@ -73,8 +73,8 @@ namespace Slicer {
using ChildHandler = std::function<void(const std::string &, ModelPartPtr, const HookCommon *)>;
using ClassRef = std::function<ModelPartPtr(void *)>;
using HookFilter = std::function<bool(const HookCommon *)>;
- using Metadata = std::list<std::string>;
- DLL_PUBLIC extern const Metadata emptyMetadata;
+ using Metadata = MetaData<>;
+ constexpr Metadata emptyMetadata;
enum class ModelPartType {
Null,
diff --git a/slicer/slicer/modelPartsTypes.h b/slicer/slicer/modelPartsTypes.h
index a95b5c5..eff56b7 100644
--- a/slicer/slicer/modelPartsTypes.h
+++ b/slicer/slicer/modelPartsTypes.h
@@ -146,7 +146,7 @@ namespace Slicer {
template<typename MT, typename MP> class DLL_PRIVATE Hook;
- template<typename MT, typename MP> class DLL_PRIVATE HookMetadata;
+ template<typename MT, typename MP, std::size_t> class DLL_PRIVATE HookMetadata;
void OnEachChild(const ChildHandler & ch) override;
@@ -161,7 +161,6 @@ namespace Slicer {
template<typename R> DLL_PRIVATE ChildRef GetChildRefFromRange(const R & range, const HookFilter & flt);
static const Hooks<T> & hooks();
- static const Metadata metadata;
};
template<typename T>
diff --git a/slicer/slicer/modelPartsTypes.impl.h b/slicer/slicer/modelPartsTypes.impl.h
index 409a4ed..f8e2a65 100644
--- a/slicer/slicer/modelPartsTypes.impl.h
+++ b/slicer/slicer/modelPartsTypes.impl.h
@@ -444,13 +444,6 @@ namespace Slicer {
}
}
- template<typename T>
- const Metadata &
- ModelPartForComplex<T>::GetMetadata() const
- {
- return metadata;
- }
-
template<typename T> class DLL_PRIVATE ModelPartForComplex<T>::HookBase : public HookCommon {
public:
using HookCommon::HookCommon;
@@ -484,12 +477,16 @@ namespace Slicer {
};
template<typename T>
- template<typename MT, typename MP>
+ template<typename MT, typename MP, std::size_t N>
class DLL_PRIVATE ModelPartForComplex<T>::HookMetadata : public ModelPartForComplex<T>::template Hook<MT, MP> {
public:
- HookMetadata(MT T::*member, std::string_view n, std::string_view nl, const std::string * ns, Metadata md) :
- Hook<MT, MP>(member, n, nl, ns), hookMetadata(std::move(md))
+ template<typename... MD>
+ constexpr HookMetadata(
+ MT T::*member, std::string_view n, std::string_view nl, const std::string * ns, MD &&... md) :
+ Hook<MT, MP>(member, n, nl, ns),
+ hookMetadata {{std::forward<MD>(md)...}}
{
+ static_assert(sizeof...(MD) == N, "Wrong amount of metadata");
}
[[nodiscard]] const Metadata &
@@ -499,7 +496,7 @@ namespace Slicer {
}
private:
- const Metadata hookMetadata;
+ const MetaDataImpl<N> hookMetadata;
};
// ModelPartForClass
diff --git a/slicer/test/Jamfile.jam b/slicer/test/Jamfile.jam
index 6801a77..74b03ee 100644
--- a/slicer/test/Jamfile.jam
+++ b/slicer/test/Jamfile.jam
@@ -59,7 +59,6 @@ run preprocessor.cpp
<library>..//adhocutil
<include>..
<library>../tool//slicer-compiler
- <dependency>types
:
preprocess
;
diff --git a/slicer/test/preprocessor.cpp b/slicer/test/preprocessor.cpp
index 2513f99..21ed5f1 100644
--- a/slicer/test/preprocessor.cpp
+++ b/slicer/test/preprocessor.cpp
@@ -49,14 +49,34 @@ processAll(Slicer::Slicer & s)
BOOST_REQUIRE_EQUAL(total(), s.Components());
}
-BOOST_AUTO_TEST_CASE(slicer_test_counts_path)
+BOOST_AUTO_TEST_CASE(slicer_metadata_split_empty, *boost::unit_test::timeout(5))
+{
+ BOOST_CHECK(Slicer::IceMetaData::split("").empty());
+}
+
+BOOST_AUTO_TEST_CASE(slicer_metadata_split_single, *boost::unit_test::timeout(5))
+{
+ auto md {Slicer::IceMetaData::split("string")};
+ BOOST_REQUIRE_EQUAL(md.size(), 1);
+ BOOST_CHECK_EQUAL(md.front(), "string");
+}
+
+BOOST_AUTO_TEST_CASE(slicer_metadata_split_many, *boost::unit_test::timeout(5))
+{
+ auto md {Slicer::IceMetaData::split("string:and:some:other:values")};
+ BOOST_REQUIRE_EQUAL(md.size(), 5);
+ BOOST_CHECK_EQUAL(md.front(), "string");
+ BOOST_CHECK_EQUAL(md.back(), "values");
+}
+
+BOOST_AUTO_TEST_CASE(slicer_test_counts_path, *boost::unit_test::timeout(5))
{
Slicer::Slicer s;
s.cppPath = "/dev/null";
processAll(s);
}
-BOOST_AUTO_TEST_CASE(slicer_test_counts_filestar)
+BOOST_AUTO_TEST_CASE(slicer_test_counts_filestar, *boost::unit_test::timeout(5))
{
FILE * file = fopen("/dev/null", "a");
BOOST_REQUIRE(file);
@@ -66,7 +86,7 @@ BOOST_AUTO_TEST_CASE(slicer_test_counts_filestar)
fclose(file);
}
-BOOST_AUTO_TEST_CASE(slicer_test_counts_nullfilestar)
+BOOST_AUTO_TEST_CASE(slicer_test_counts_nullfilestar, *boost::unit_test::timeout(5))
{
Slicer::Slicer s;
processAll(s);
diff --git a/slicer/tool/Jamfile.jam b/slicer/tool/Jamfile.jam
index 98067b9..4ee2d76 100644
--- a/slicer/tool/Jamfile.jam
+++ b/slicer/tool/Jamfile.jam
@@ -5,6 +5,7 @@ lib stdc++fs ;
lib slice-parser ;
lib slicer-compiler :
+ icemetadata.cpp
parser.cpp
:
<library>slice-parser
diff --git a/slicer/tool/icemetadata.cpp b/slicer/tool/icemetadata.cpp
new file mode 100644
index 0000000..422b17e
--- /dev/null
+++ b/slicer/tool/icemetadata.cpp
@@ -0,0 +1,45 @@
+#include "icemetadata.h"
+#include <boost/algorithm/string/predicate.hpp>
+
+namespace Slicer {
+ IceMetaData::IceMetaData() { }
+ IceMetaData::IceMetaData(Slice::StringList && a) : arr {std::forward<Slice::StringList>(a)}
+ {
+ _begin = arr.begin();
+ _end = arr.end();
+ }
+
+ std::vector<std::string_view>
+ IceMetaData::split(std::string_view metaData)
+ {
+ std::vector<std::string_view> output;
+
+ for (size_t first = 0; first < metaData.size();) {
+ const auto second = metaData.find(':', first);
+
+ if (first != second) {
+ output.emplace_back(metaData.substr(first, second - first));
+ }
+
+ if (second == std::string_view::npos) {
+ break;
+ }
+
+ first = second + 1;
+ }
+
+ return output;
+ }
+
+ size_t
+ IceMetaData::countSlicerMetaData() const
+ {
+ return std::count_if(_begin, _end, isSlicerMetaData);
+ }
+
+ bool
+ IceMetaData::hasSlicerMetaData() const
+ {
+ return std::any_of(_begin, _end, isSlicerMetaData);
+ }
+}
diff --git a/slicer/tool/icemetadata.h b/slicer/tool/icemetadata.h
new file mode 100644
index 0000000..90bfe5e
--- /dev/null
+++ b/slicer/tool/icemetadata.h
@@ -0,0 +1,40 @@
+#ifndef SLICER_TOOL_METADATA_H
+#define SLICER_TOOL_METADATA_H
+
+#include <Slice/Parser.h>
+#include <c++11Helpers.h>
+#include <list>
+#include <metadata.h>
+
+namespace Slicer {
+ class DLL_PUBLIC IceMetaData : public MetaData<Slice::StringList::const_iterator> {
+ public:
+ static constexpr std::string_view slicer_prefix {"slicer:"};
+
+ explicit IceMetaData();
+ explicit IceMetaData(Slice::StringList && arr);
+
+ SPECIAL_MEMBERS_DELETE(IceMetaData);
+
+ [[nodiscard]] static std::vector<std::string_view> split(std::string_view metaData);
+
+ bool hasSlicerMetaData() const;
+ size_t countSlicerMetaData() const;
+
+ constexpr bool static isSlicerMetaData(std::string_view md)
+ {
+ return md.substr(0, slicer_prefix.length()) == slicer_prefix;
+ }
+
+ auto
+ getSlicerMetaData() const
+ {
+ return values(slicer_prefix);
+ }
+
+ private:
+ Slice::StringList arr;
+ };
+}
+
+#endif
diff --git a/slicer/tool/parser.cpp b/slicer/tool/parser.cpp
index 87c48f3..ef9139d 100644
--- a/slicer/tool/parser.cpp
+++ b/slicer/tool/parser.cpp
@@ -8,7 +8,6 @@
#include <boost/algorithm/string/trim.hpp>
#include <common.h>
#include <fprintbf.h>
-#include <metadata.h>
#include <safeMapFind.h>
namespace fs = std::filesystem;
@@ -99,7 +98,7 @@ namespace Slicer {
const Count & count;
};
- SplitString::SplitString(const std::string & in, const char * by)
+ SplitString::SplitString(std::string_view in, std::string_view by)
{
boost::algorithm::split(*this, in, boost::algorithm::is_any_of(by), boost::algorithm::token_compress_off);
}
@@ -212,7 +211,8 @@ namespace Slicer {
fprintbf(cpp, "#include <%s>\n", fs::path(topLevelFile.filename()).replace_extension(".h").string());
for (const auto & m : u->modules()) {
- for (const auto & i : metaDataValues("slicer:include:", m->getMetaData())) {
+ IceMetaData md {m->getMetaData()};
+ for (const auto & i : md.values("slicer:include:")) {
fprintbf(cpp, "#include <%s>\n", i);
}
}
@@ -254,7 +254,7 @@ namespace Slicer {
}
void
- Slicer::defineRoot(const std::string & type, const std::string & name, const Slice::TypePtr & stype) const
+ Slicer::defineRoot(const std::string & type, std::string_view name, const Slice::TypePtr & stype) const
{
if (stype->isLocal()) {
fprintbf(cpp, "template<>\n");
@@ -298,14 +298,15 @@ namespace Slicer {
visitComplexDataMembers(decl.get(), c->allDataMembers());
fprintbf(cpp, "template<> DLL_PUBLIC\n");
- auto typeId = metaDataValue("slicer:typeid:", c->getMetaData());
+ const IceMetaData md {c->getMetaData()};
+ auto typeId = md.value("slicer:typeid:");
fprintbf(cpp, "const std::string ModelPartForClass< %s >::typeIdProperty(\"%s\");\n\n", decl->typeId(),
typeId ? *typeId : "slicer-typeid");
- auto name = metaDataValue("slicer:root:", c->getMetaData());
+ auto name = md.value("slicer:root:");
defineRoot(typeToString(decl), name ? *name : c->name(), decl);
- auto typeName = metaDataValue("slicer:typename:", c->getMetaData());
+ auto typeName = md.value("slicer:typename:");
fprintbf(cpp, "template<> DLL_PUBLIC\n");
fprintbf(cpp, "const std::string * ModelPartForClass< %s >::className = nullptr;\n", decl->typeId());
fprintbf(cpp, "template<> DLL_PUBLIC\n");
@@ -322,17 +323,19 @@ namespace Slicer {
}
fprintbf(cpp, "\n}\n");
- fprintbf(cpp, "template<> DLL_PUBLIC\nconst Metadata ModelPartForComplex< %s >::metadata ", c->scoped());
- copyMetadata(c->getMetaData());
- fprintbf(cpp, ";\n\n");
+ fprintbf(cpp, "template<> DLL_PUBLIC\nconst Metadata & ModelPartForComplex< %s >::GetMetadata() const {\n\
+ static constexpr MetaDataImpl<%d> md {{{",
+ c->scoped(), md.values("slicer:").size());
+ copyMetadata(md);
+ fprintbf(cpp, "}}}; return md;}\n\n");
- if (auto implementation = metaDataValue("slicer:implementation:", c->getMetaData())) {
+ if (auto implementation = md.value("slicer:implementation:")) {
fprintbf(cpp, "\ttemplate<> void ModelPartForClass<%s>::Create() {\n", c->scoped());
fprintf(cpp, "\t\tBOOST_ASSERT(this->Model);\n");
fprintbf(cpp, "\t\t*this->Model = std::make_shared<%s>();\n}\n\n", CppName {*implementation});
}
- if (auto cmp = metaDataValue("slicer:custommodelpart:", c->getMetaData())) {
+ if (auto cmp = md.value("slicer:custommodelpart:")) {
fprintbf(cpp, "CUSTOMMODELPARTFOR(%s, %s< %s >, %s);\n\n", Slice::typeToString(decl),
getBasicModelPart(decl), c->scoped(), CppName {*cmp});
}
@@ -363,14 +366,17 @@ namespace Slicer {
fprintbf(cpp, "// Struct %s\n", c->name());
visitComplexDataMembers(c.get(), c->dataMembers());
- auto name = metaDataValue("slicer:root:", c->getMetaData());
+ const IceMetaData md {c->getMetaData()};
+ auto name = md.value("slicer:root:");
defineRoot(c->scoped(), name ? *name : c->name(), c);
- fprintbf(cpp, "template<> DLL_PUBLIC\nconst Metadata ModelPartForComplex< %s >::metadata ", c->scoped());
- copyMetadata(c->getMetaData());
- fprintbf(cpp, ";\n\n");
+ fprintbf(cpp, "template<> DLL_PUBLIC\nconst Metadata & ModelPartForComplex< %s >::GetMetadata() const {\n\
+ static constexpr MetaDataImpl<%d> md {{{",
+ c->scoped(), md.values("slicer:").size());
+ copyMetadata(md);
+ fprintbf(cpp, "}}}; return md;}\n\n");
- defineMODELPART(c->scoped(), c, c->getMetaData());
+ defineMODELPART(c->scoped(), c, md);
return true;
}
@@ -389,7 +395,10 @@ namespace Slicer {
size_t en = 0;
for (const auto & dm : dataMembers) {
- auto name = metaDataValue("slicer:name:", dm->getMetaData()).value_or(dm->name());
+ const IceMetaData md {getAllMetadata(dm)};
+ auto name = std::string {md.value("slicer:name:").value_or(dm->name())};
+ auto lname = std::string {name};
+ boost::algorithm::to_lower(lname);
fprintbf(cpp, "\tconst std::string hstr%d_%d { \"%s\" };\n", components, en, name);
auto c = Slice::ContainedPtr::dynamicCast(dm->container());
@@ -398,15 +407,17 @@ namespace Slicer {
t = Slice::ClassDefPtr::dynamicCast(dm->container())->declaration();
}
auto type = dm->type();
- fprintbf(cpp, "\t%s C%d::%s<", hasMetadata(dm->getMetaData()) ? "static" : "constexpr", components,
- hasMetadata(dm->getMetaData()) ? "HookMetadata" : "Hook");
+ fprintbf(cpp, "\tconstexpr C%d::%s<", components, md.countSlicerMetaData() ? "HookMetadata" : "Hook");
fprintbf(cpp, " %s, ", Slice::typeToString(type, dm->optional()));
- createNewModelPartPtrFor(type, dm, getAllMetadata(dm));
- fprintbf(cpp, " > hook%d_%d {&%s, \"%s\", \"%s\", &hstr%d_%d", components, en, dm->scoped(), name,
- boost::algorithm::to_lower_copy(name), components, en);
- if (hasMetadata(dm->getMetaData())) {
- fprintbf(cpp, ", Metadata ");
- copyMetadata(dm->getMetaData());
+ createNewModelPartPtrFor(type, dm, md);
+ if (auto n = md.countSlicerMetaData()) {
+ fprintbf(cpp, ", %d", n);
+ }
+ fprintbf(cpp, " > hook%d_%d {&%s, \"%s\", \"%s\", &hstr%d_%d", components, en, dm->scoped(), name, lname,
+ components, en);
+ if (md.hasSlicerMetaData()) {
+ fprintbf(cpp, ",");
+ copyMetadata(md);
}
fprintbf(cpp, "};\n");
en++;
@@ -437,9 +448,12 @@ namespace Slicer {
}
fprintbf(cpp, "// Enumeration %s\n", e->name());
- fprintbf(cpp, "template<> DLL_PUBLIC\nconst Metadata ModelPartForEnum< %s >::metadata ", e->scoped());
- copyMetadata(e->getMetaData());
- fprintbf(cpp, ";\n\n");
+ const IceMetaData md {e->getMetaData()};
+ fprintbf(cpp, "template<> DLL_PUBLIC\nconst Metadata & ModelPartForEnum< %s >::GetMetadata() const {\n\
+ static constexpr MetaDataImpl<%d> md {{{",
+ e->scoped(), md.values("slicer:").size());
+ copyMetadata(md);
+ fprintbf(cpp, "}}}; return md;}\n\n");
size_t en = 0;
for (const auto & ee : e->enumerators()) {
@@ -457,11 +471,11 @@ namespace Slicer {
"enumerations%d; }\n",
e->scoped(), e->scoped(), components);
- auto name = metaDataValue("slicer:root:", e->getMetaData());
+ auto name = md.value("slicer:root:");
const Slice::TypePtr t = e;
defineRoot(e->scoped(), name ? *name : e->name(), t);
- defineMODELPART(e->scoped(), e, e->getMetaData());
+ defineMODELPART(e->scoped(), e, md);
}
void
@@ -484,7 +498,8 @@ namespace Slicer {
"ChildRef ModelPartForSequence< %s >::GetChildRef(const std::string & name, const HookFilter & flt, "
"bool matchCase)\n{\n",
s->scoped());
- auto iname = metaDataValue("slicer:item:", s->getMetaData());
+ const IceMetaData md {s->getMetaData()};
+ auto iname = md.value("slicer:item:");
if (iname) {
fprintbf(cpp,
"\tif (!name.empty() && !optionalCaseEq(name, \"%s\", matchCase)) { throw "
@@ -498,18 +513,20 @@ namespace Slicer {
fprintbf(cpp, "\treturn GetAnonChildRef(flt);\n}\n\n");
fprintbf(cpp, "template<> DLL_PUBLIC\n");
- auto ename = metaDataValue("slicer:element:", s->getMetaData());
+ auto ename = md.value("slicer:element:");
fprintbf(cpp, "const std::string ModelPartForSequence< %s >::elementName(\"%s\");\n\n", s->scoped(),
ename ? *ename : "element");
- auto name = metaDataValue("slicer:root:", s->getMetaData());
+ auto name = md.value("slicer:root:");
defineRoot(s->scoped(), name ? *name : s->name(), s);
- fprintbf(cpp, "template<> DLL_PUBLIC\nconst Metadata ModelPartForSequence< %s >::metadata ", s->scoped());
- copyMetadata(s->getMetaData());
- fprintbf(cpp, ";\n\n");
+ fprintbf(cpp, "template<> DLL_PUBLIC\nconst Metadata & ModelPartForSequence< %s >::GetMetadata() const {\n\
+ static constexpr MetaDataImpl<%d> md {{{",
+ s->scoped(), md.values("slicer:").size());
+ copyMetadata(md);
+ fprintbf(cpp, "}}}; return md;}\n\n");
- defineMODELPART(s->scoped(), s, s->getMetaData());
+ defineMODELPART(s->scoped(), s, md);
}
void
@@ -528,21 +545,24 @@ namespace Slicer {
fprintbf(cpp, "// Dictionary %s\n", d->name());
externType(d->keyType());
externType(d->valueType());
- auto iname = metaDataValue("slicer:item:", d->getMetaData());
+ const IceMetaData md {d->getMetaData()};
+ auto iname = md.value("slicer:item:");
fprintbf(cpp, "template<> DLL_PUBLIC\n");
fprintbf(cpp, "const std::string ModelPartForDictionary< %s >::pairName(\"%s\");\n\n", d->scoped(),
iname ? *iname : "element");
fprintbf(cpp, "using C%d = ModelPartForComplex< %s::value_type >;\n", components, d->scoped());
- auto addHook = [&](const std::string & name, const char * element, const Slice::TypePtr & t) {
+ auto addHook = [&](std::string_view name, const char * element, const Slice::TypePtr & t) {
+ auto lname = std::string {name};
+ boost::algorithm::to_lower(lname);
fprintbf(cpp, "\tconst std::string hstr%d_%d { \"%s\" };\n", components, element, name);
fprintbf(cpp, "\tconstexpr C%d::Hook< const %s, ", components, Slice::typeToString(t));
createNewModelPartPtrFor(t);
fprintbf(cpp, " > hook%d_%s {&%s::value_type::%s, \"%s\", \"%s\", &hstr%d_%s};\n", components, element,
- d->scoped(), element, name, boost::algorithm::to_lower_copy(name), components, element);
+ d->scoped(), element, name, lname, components, element);
};
- addHook(metaDataValue("slicer:key:", d->getMetaData()).value_or("key"), "first", d->keyType());
- addHook(metaDataValue("slicer:value:", d->getMetaData()).value_or("value"), "second", d->valueType());
+ addHook(md.value("slicer:key:").value_or("key"), "first", d->keyType());
+ addHook(md.value("slicer:value:").value_or("value"), "second", d->valueType());
fprintbf(cpp, "constexpr const HooksImpl< %s::value_type, 2 > hooks%d {{{\n", d->scoped(), components);
fprintbf(cpp, " &hook%d_first,\n", components);
@@ -551,19 +571,23 @@ namespace Slicer {
fprintbf(cpp, "\ttemplate<> const Hooks< %s::value_type > & C%d::hooks() { return hooks%d; }\n", d->scoped(),
components, components);
- auto name = metaDataValue("slicer:root:", d->getMetaData());
+ auto name = md.value("slicer:root:");
defineRoot(d->scoped(), name ? *name : d->name(), d);
- fprintbf(cpp, "template<> DLL_PUBLIC\nconst Metadata ModelPartForDictionary< %s >::metadata ", d->scoped());
- copyMetadata(d->getMetaData());
- fprintbf(cpp, ";\n\n");
+ fprintbf(cpp, "template<> DLL_PUBLIC\nconst Metadata & ModelPartForDictionary< %s >::GetMetadata() const {\n\
+ static constexpr MetaDataImpl<%d> md {{{",
+ d->scoped(), md.values("slicer:").size());
+ copyMetadata(md);
+ fprintbf(cpp, "}}}; return md;}\n\n");
- fprintbf(cpp, "template<> DLL_PUBLIC\nconst Metadata ModelPartForComplex<%s::value_type>::metadata ",
- d->scoped());
- copyMetadata(d->getMetaData());
- fprintbf(cpp, ";\n\n");
+ fprintbf(cpp,
+ "template<> DLL_PUBLIC\nconst Metadata & ModelPartForComplex< %s::value_type >::GetMetadata() const {\n\
+ static constexpr MetaDataImpl<%d> md {{{",
+ d->scoped(), md.values("slicer:").size());
+ copyMetadata(md);
+ fprintbf(cpp, "}}}; return md;}\n\n");
- defineMODELPART(d->scoped(), d, d->getMetaData());
+ defineMODELPART(d->scoped(), d, md);
}
void
@@ -590,14 +614,14 @@ namespace Slicer {
void
Slicer::createNewModelPartPtrFor(
- const Slice::TypePtr & type, const Slice::DataMemberPtr & dm, const Slice::StringList & md) const
+ const Slice::TypePtr & type, const Slice::DataMemberPtr & dm, const IceMetaData & md) const
{
auto conversions = getConversions(md);
if (dm && !conversions.empty()) {
createModelPartForConverted(
type, boost::algorithm::trim_right_copy_if(dm->container()->thisScope(), ispunct), dm);
}
- else if (auto cmp = metaDataValue("slicer:custommodelpart:", md)) {
+ else if (auto cmp = md.value("slicer:custommodelpart:")) {
fprintbf(cpp, "%s", CppName {*cmp});
}
else {
@@ -629,30 +653,15 @@ namespace Slicer {
throw CompilerError("Unknown basic type");
}
- bool
- Slicer::hasMetadata(const std::list<std::string> & metadata) const
- {
- for (const auto & md : metadata) {
- if (boost::algorithm::starts_with(md, "slicer:")) {
- return true;
- }
- }
- return false;
- }
-
void
- Slicer::copyMetadata(const std::list<std::string> & metadata) const
+ Slicer::copyMetadata(const IceMetaData & metadata) const
{
- fprintbf(cpp, "{\n");
- for (const auto & md : metadata) {
- if (boost::algorithm::starts_with(md, "slicer:")) {
- fprintbf(cpp, "\t\"%s\",\n", md.c_str() + 7);
- }
+ for (const auto & md : metadata.getSlicerMetaData()) {
+ fprintbf(cpp, "\t\"%s\",\n", md);
}
- fprintbf(cpp, "}");
}
- Slice::StringList
+ IceMetaData
Slicer::getAllMetadata(const Slice::DataMemberPtr & dm)
{
auto metadata = dm->getMetaData();
@@ -662,20 +671,19 @@ namespace Slicer {
typec = cd->definition();
}
if (typec) {
- auto typeMetadata = typec->getMetaData();
- std::copy(typeMetadata.begin(), typeMetadata.end(), std::back_inserter(metadata));
+ metadata.merge(typec->getMetaData());
}
}
- return metadata;
+ return IceMetaData {std::move(metadata)};
}
Slicer::Conversions
- Slicer::getConversions(const std::list<std::string> & dm)
+ Slicer::getConversions(const IceMetaData & md)
{
Conversions rtn;
- auto conversions = metaDataValues("slicer:conversion:", dm);
+ auto conversions = md.values("slicer:conversion:");
for (const auto & conversion : conversions) {
- auto split = metaDataSplit(conversion);
+ auto split = IceMetaData::split(conversion);
if (split.size() < 3) {
throw CompilerError("conversion needs at least 3 parts type:toModelFunc:toExchangeFunc[:options]");
}
@@ -685,9 +693,9 @@ namespace Slicer {
}
void
- Slicer::defineMODELPART(const std::string & type, const Slice::TypePtr & stype, const Slice::StringList & metadata)
+ Slicer::defineMODELPART(const std::string & type, const Slice::TypePtr & stype, const IceMetaData & metadata)
{
- if (auto cmp = metaDataValue("slicer:custommodelpart:", metadata)) {
+ if (auto cmp = metadata.value("slicer:custommodelpart:")) {
fprintbf(cpp, "CUSTOMMODELPARTFOR(%s, %s< %s >, %s);\n\n", type, getBasicModelPart(stype), type,
CppName {*cmp});
}
diff --git a/slicer/tool/parser.h b/slicer/tool/parser.h
index 517c0e3..40c8b28 100644
--- a/slicer/tool/parser.h
+++ b/slicer/tool/parser.h
@@ -1,6 +1,7 @@
#ifndef SLICER_PARSER_H
#define SLICER_PARSER_H
+#include "icemetadata.h"
#include <Slice/Parser.h>
#include <filesystem>
#include <visibility.h>
@@ -8,18 +9,18 @@
namespace Slicer {
class SplitString : public std::vector<std::string> {
public:
- SplitString(const std::string & in, const char *);
+ SplitString(std::string_view in, std::string_view split);
using std::vector<std::string>::vector;
};
struct CppName : public SplitString {
- inline CppName(const std::string & in) : SplitString(in, ".") { }
+ inline CppName(std::string_view in) : SplitString {in, "."} { }
};
class DLL_PUBLIC Slicer : public Slice::ParserVisitor {
public:
struct Args : public SplitString {
- inline Args(const std::string & in) : SplitString(in, ",") { }
+ inline Args(std::string_view in) : SplitString {in, ","} { }
using SplitString::SplitString;
};
@@ -66,23 +67,20 @@ namespace Slicer {
private:
void createModelPartForConverted(
const Slice::TypePtr & type, const std::string & container, const Slice::DataMemberPtr & dm) const;
- void createNewModelPartPtrFor(const Slice::TypePtr & type,
- const Slice::DataMemberPtr & dm = Slice::DataMemberPtr(),
- const Slice::StringList & md = Slice::StringList()) const;
+ void createNewModelPartPtrFor(const Slice::TypePtr & type, const Slice::DataMemberPtr & dm = {},
+ const IceMetaData & md = IceMetaData {}) const;
[[nodiscard]] std::string getBasicModelPart(const Slice::TypePtr & type) const;
- void defineMODELPART(
- const std::string & type, const Slice::TypePtr & stype, const Slice::StringList & metadata);
+ void defineMODELPART(const std::string & type, const Slice::TypePtr & stype, const IceMetaData & metadata);
void visitComplexDataMembers(const Slice::ConstructedPtr & t, const Slice::DataMemberList &) const;
void defineConversions(const Slice::DataMemberPtr & dm) const;
- void defineRoot(const std::string & type, const std::string & name, const Slice::TypePtr & stype) const;
+ void defineRoot(const std::string & type, std::string_view name, const Slice::TypePtr & stype) const;
void externType(const Slice::TypePtr &) const;
- [[nodiscard]] bool hasMetadata(const std::list<std::string> & metadata) const;
- void copyMetadata(const std::list<std::string> & metadata) const;
- static Slice::StringList getAllMetadata(const Slice::DataMemberPtr & dm);
- static Conversions getConversions(const Slice::StringList & metadata);
+ void copyMetadata(const IceMetaData & metadata) const;
+ static IceMetaData getAllMetadata(const Slice::DataMemberPtr & dm);
+ static Conversions getConversions(const IceMetaData & metadata);
std::set<std::string> definedTypes;
#pragma GCC visibility pop
diff --git a/slicer/xml/serializer.cpp b/slicer/xml/serializer.cpp
index fbda026..afdb636 100644
--- a/slicer/xml/serializer.cpp
+++ b/slicer/xml/serializer.cpp
@@ -17,11 +17,11 @@ NAMEDFACTORY("application/xml", Slicer::XmlStreamDeserializer, Slicer::StreamDes
namespace Slicer {
using namespace std::placeholders;
- const std::string md_attribute = "xml:attribute";
- const std::string md_text = "xml:text";
- const std::string md_bare = "xml:bare";
- const std::string md_attributes = "xml:attributes";
- const std::string md_elements = "xml:elements";
+ constexpr std::string_view md_attribute {"xml:attribute"};
+ constexpr std::string_view md_text {"xml:text"};
+ constexpr std::string_view md_bare {"xml:bare"};
+ constexpr std::string_view md_attributes {"xml:attributes"};
+ constexpr std::string_view md_elements {"xml:elements"};
const std::string keyName = "key";
const std::string valueName = "value";
using ElementCreatorF = xmlpp::Element * (xmlpp::Element::*)(const Glib::ustring &, const Glib::ustring &);
@@ -240,13 +240,13 @@ namespace Slicer {
}
}
smp->Create();
- if (metaDataFlagSet(smpr.ChildMetaData(), md_attributes)) {
+ if (smpr.ChildMetaData().flagSet(md_attributes)) {
auto attrs(element->get_attributes());
if (!attrs.empty()) {
DocumentTreeIterateDictAttrs(attrs, smp);
}
}
- else if (metaDataFlagSet(smpr.ChildMetaData(), md_elements)) {
+ else if (smpr.ChildMetaData().flagSet(md_elements)) {
DocumentTreeIterateDictElements(element, smp);
}
else {
@@ -271,11 +271,11 @@ namespace Slicer {
while (node) {
if (auto element = dynamic_cast<const xmlpp::Element *>(node)) {
auto smpr = mp->GetChildRef(element->get_name(), [](const auto & h) {
- return metaDataFlagNotSet(h->GetMetadata(), md_attribute);
+ return h->GetMetadata().flagNotSet(md_attribute);
});
if (smpr) {
auto smp = smpr.Child();
- if (metaDataFlagSet(smpr.ChildMetaData(), md_bare)) {
+ if (smpr.ChildMetaData().flagSet(md_bare)) {
smp = smp->GetAnonChild();
}
if (smp) {
@@ -285,7 +285,7 @@ namespace Slicer {
}
else if (auto attribute = dynamic_cast<const xmlpp::Attribute *>(node)) {
auto smp = mp->GetChild(attribute->get_name(), [](const auto & h) {
- return metaDataFlagSet(h->GetMetadata(), md_attribute);
+ return h->GetMetadata().flagSet(md_attribute);
});
if (smp) {
smp->Create();
@@ -297,7 +297,7 @@ namespace Slicer {
ModelPartPtr smp;
if (!content->is_white_space()) {
smp = mp->GetAnonChild([](const auto & h) {
- return metaDataFlagSet(h->GetMetadata(), md_text);
+ return h->GetMetadata().flagSet(md_text);
});
}
if (smp) {
@@ -324,20 +324,20 @@ namespace Slicer {
if (name.empty()) {
return;
}
- if (hp && metaDataFlagSet(hp->GetMetadata(), md_attribute)) {
+ if (hp && hp->GetMetadata().flagSet(md_attribute)) {
mp->GetValue(XmlAttributeValueTarget(n, name));
}
- else if (hp && metaDataFlagSet(hp->GetMetadata(), md_text)) {
+ else if (hp && hp->GetMetadata().flagSet(md_text)) {
mp->GetValue(XmlContentValueTarget(n));
}
- else if (hp && metaDataFlagSet(hp->GetMetadata(), md_attributes)) {
+ else if (hp && hp->GetMetadata().flagSet(md_attributes)) {
ModelTreeIterateDictAttrs(n->add_child_element(name), mp);
}
- else if (hp && metaDataFlagSet(hp->GetMetadata(), md_elements)) {
+ else if (hp && hp->GetMetadata().flagSet(md_elements)) {
ModelTreeIterateDictElements(n->add_child_element(name), mp);
}
else {
- if (hp && metaDataFlagSet(hp->GetMetadata(), md_bare)) {
+ if (hp && hp->GetMetadata().flagSet(md_bare)) {
ModelTreeProcessElement(n, mp, [name](auto && PH1, auto &&) {
return PH1->add_child_element(name);
});