summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--slicer/slicer/metadata-test.cpp28
-rw-r--r--slicer/slicer/metadata.h87
-rw-r--r--slicer/tool/icemetadata.cpp7
-rw-r--r--slicer/tool/icemetadata.h10
4 files changed, 98 insertions, 34 deletions
diff --git a/slicer/slicer/metadata-test.cpp b/slicer/slicer/metadata-test.cpp
index a2cd6ec..1fe9cec 100644
--- a/slicer/slicer/metadata-test.cpp
+++ b/slicer/slicer/metadata-test.cpp
@@ -1,6 +1,23 @@
#include "metadata.h"
namespace test {
+ constexpr auto rc = [](std::string_view sv) {
+ return Slicer::MetaData<>::remove_colons(sv);
+ };
+ static_assert(rc("scope") == "scope");
+ static_assert(rc("scope:") == "scope");
+ static_assert(rc("scope::") == "scope");
+ static_assert(rc("scope:sub:") == "scope:sub");
+ static_assert(rc("scope:sub::") == "scope:sub");
+ static_assert(Slicer::MetaData<>::in_scope("scope", "scope"));
+ static_assert(!Slicer::MetaData<>::in_scope("scope2", "scope"));
+ static_assert(!Slicer::MetaData<>::in_scope("scope", "scope2"));
+ static_assert(Slicer::MetaData<>::in_scope("scope:sub", "scope"));
+ static_assert(Slicer::MetaData<>::in_scope("scope:sub:subsub", "scope"));
+ static_assert(Slicer::MetaData<>::in_scope("scope:sub:subsub", "scope:sub"));
+ static_assert(!Slicer::MetaData<>::in_scope("scope:sub2:subsub", "scope:sub"));
+ static_assert(!Slicer::MetaData<>::in_scope("scope:sub:subsub", "scope:sub2"));
+
constexpr Slicer::MetaDataImpl<4> md {{{
"slicer:yes",
"slicer:no",
@@ -8,10 +25,21 @@ namespace test {
"notslicer:dontcare",
}}};
+ static_assert(md.arr[0].first == "slicer:yes");
+ static_assert(md.arr[0].second == "slicer");
+ static_assert(md.arr[2].first == "slicer:sub:scope");
+ static_assert(md.arr[2].second == "slicer:sub");
+
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("slicer").has_value());
+ static_assert(md.value("slicer").value() == "yes");
+ static_assert(md.value("slicer:sub:").has_value());
+ static_assert(md.value("slicer:sub:").value() == "scope");
+ static_assert(md.value("slicer:sub").has_value());
+ static_assert(md.value("slicer:sub").value() == "scope");
static_assert(!md.value("nope:").has_value());
}
diff --git a/slicer/slicer/metadata.h b/slicer/slicer/metadata.h
index 5ca3781..455507a 100644
--- a/slicer/slicer/metadata.h
+++ b/slicer/slicer/metadata.h
@@ -1,19 +1,21 @@
#ifndef SLICER_METADATA_H
#define SLICER_METADATA_H
-#include <algorithm>
#include <array>
#include <optional>
-#include <string>
+#include <string_view>
+#include <type_traits>
#include <vector>
#include <visibility.h>
namespace Slicer {
- template<typename Iter = std::array<std::string_view, 1>::const_iterator> class DLL_PUBLIC MetaData {
+ template<bool FixedSize = true, typename Value = std::string_view> class DLL_PUBLIC MetaData {
public:
- using Value = std::string_view;
-
- constexpr MetaData() = default;
+ using Pair = std::pair<Value, std::string_view>;
+ using PairView = std::pair<std::string_view, std::string_view>;
+ template<size_t size = 0>
+ using ContainerBase = std::conditional_t<FixedSize, std::array<Pair, size>, std::vector<Pair>>;
+ using Iter = typename ContainerBase<>::const_iterator;
// Flags
[[nodiscard]] constexpr inline bool
@@ -32,60 +34,89 @@ namespace Slicer {
[[nodiscard]] 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());
+ remove_colons(prefix);
+ for (const auto & md : *this) {
+ // cppcheck-suppress useStlAlgorithm; (not constexpr)
+ if (md.second == prefix) {
+ return std::string_view(md.first).substr(prefix.length() + 1);
}
}
return {};
}
[[nodiscard]] std::vector<std::string_view>
- values(std::string_view prefix) const
+ values(std::string_view scope) const
{
+ remove_colons(scope);
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()));
+ for (const auto & md : *this) {
+ // cppcheck-suppress useStlAlgorithm; (not constexpr)
+ if (in_scope(md.first, scope)) {
+ mds.push_back(std::string_view(md.first).substr(scope.length() + 1));
}
}
return mds;
}
- [[nodiscard]] constexpr auto
+ [[nodiscard]] inline constexpr auto
begin() const
{
return _begin;
}
- [[nodiscard]] constexpr auto
+ [[nodiscard]] inline constexpr auto
end() const
{
return _end;
}
- protected:
- Iter _begin {};
- Iter _end {};
-
- [[nodiscard]] constexpr Iter
- find(Value v) const
+ [[nodiscard]] constexpr auto
+ find(std::string_view v) const
{
- for (auto mdptr = _begin; mdptr != _end; mdptr++) {
- if (*mdptr == v) {
- return mdptr;
+ for (const auto & md : *this) {
+ // cppcheck-suppress useStlAlgorithm; (not constexpr)
+ if (md.first == v) {
+ return &md;
}
}
return _end;
}
+
+ static constexpr inline auto
+ remove_colons(std::string_view & s)
+ {
+ if (auto c = s.find_last_not_of(':'); c != std::string_view::npos) {
+ s.remove_suffix(s.length() - 1 - c);
+ }
+ return s;
+ }
+
+ static constexpr inline auto
+ in_scope(std::string_view md, std::string_view scope)
+ {
+ return ((md.length() == scope.length() || (md.length() >= scope.length() && md[scope.length()] == ':'))
+ && md.compare(0, scope.length(), scope) == 0);
+ }
+
+ protected:
+ Iter _begin {};
+ Iter _end {};
};
template<std::size_t N> class DLL_PUBLIC MetaDataImpl : public MetaData<> {
public:
- using Arr = std::array<Value, N>;
- constexpr inline explicit MetaDataImpl(Arr a) : arr(std::move(a))
+ using Arr = ContainerBase<N>;
+ constexpr inline explicit MetaDataImpl(const std::array<std::string_view, N> & a) :
+ arr {[&a]() {
+ Arr arr;
+ auto out = arr.begin();
+ for (const auto & md : a) {
+ out->first = md;
+ out->second = out->first.substr(0, out->first.rfind(':'));
+ out++;
+ }
+ return arr;
+ }()}
{
_begin = arr.begin();
_end = arr.end();
diff --git a/slicer/tool/icemetadata.cpp b/slicer/tool/icemetadata.cpp
index 60bd5a3..64806d6 100644
--- a/slicer/tool/icemetadata.cpp
+++ b/slicer/tool/icemetadata.cpp
@@ -2,8 +2,13 @@
#include <boost/algorithm/string/predicate.hpp>
namespace Slicer {
- IceMetaData::IceMetaData(Slice::StringList && a) : arr {std::forward<Slice::StringList>(a)}
+ IceMetaData::IceMetaData(Slice::StringList && a)
{
+ arr.reserve(a.size());
+ std::transform(a.begin(), a.end(), std::back_inserter(arr), [](auto a) {
+ auto prefix = std::string_view(a).substr(0, a.rfind(':'));
+ return std::make_pair(std::move(a), prefix);
+ });
_begin = arr.begin();
_end = arr.end();
}
diff --git a/slicer/tool/icemetadata.h b/slicer/tool/icemetadata.h
index 07d4db2..bd00686 100644
--- a/slicer/tool/icemetadata.h
+++ b/slicer/tool/icemetadata.h
@@ -7,9 +7,9 @@
#include <metadata.h>
namespace Slicer {
- class DLL_PUBLIC IceMetaData : public MetaData<Slice::StringList::const_iterator> {
+ class DLL_PUBLIC IceMetaData : public MetaData<false, std::string> {
public:
- static constexpr std::string_view slicer_prefix {"slicer:"};
+ static constexpr std::string_view slicer_prefix {"slicer"};
explicit IceMetaData() = default;
explicit IceMetaData(Slice::StringList && arr);
@@ -22,9 +22,9 @@ namespace Slicer {
[[nodiscard]] bool hasSlicerMetaData() const;
[[nodiscard]] size_t countSlicerMetaData() const;
- [[nodiscard]] constexpr bool static isSlicerMetaData(std::string_view md)
+ [[nodiscard]] constexpr bool static isSlicerMetaData(PairView md)
{
- return md.substr(0, slicer_prefix.length()) == slicer_prefix;
+ return in_scope(md.first, slicer_prefix);
}
[[nodiscard]] auto
@@ -34,7 +34,7 @@ namespace Slicer {
}
private:
- Slice::StringList arr;
+ ContainerBase<> arr;
};
}