add MetaEnv implementation
This commit is contained in:
parent
d7c4364255
commit
efe922f835
@ -32,6 +32,7 @@ target_sources(nf7_core
|
||||
clock.hh
|
||||
dealer.hh
|
||||
logger.hh
|
||||
meta_env.hh
|
||||
version.hh
|
||||
)
|
||||
|
||||
@ -50,6 +51,7 @@ target_sources(nf7_core_test
|
||||
uv/file_test.cc
|
||||
uv/parallelism_test.cc
|
||||
clock_test.cc
|
||||
meta_env_test.cc
|
||||
)
|
||||
target_link_libraries(nf7_core_test
|
||||
PRIVATE
|
||||
|
91
core/meta_env.hh
Normal file
91
core/meta_env.hh
Normal file
@ -0,0 +1,91 @@
|
||||
// No copyright
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "iface/subsys/meta_env.hh"
|
||||
|
||||
namespace nf7::core {
|
||||
|
||||
class NullMetaEnv : public subsys::MetaEnv {
|
||||
public:
|
||||
static inline const auto kInstance = std::make_shared<NullMetaEnv>();
|
||||
|
||||
public:
|
||||
NullMetaEnv() noexcept : subsys::MetaEnv("nf7::core::NullMetaEnv") { }
|
||||
|
||||
public:
|
||||
Env* FindOr(std::string_view) const noexcept override { return nullptr; }
|
||||
std::optional<Pair> FindOr(uint64_t) const noexcept override { return std::nullopt; }
|
||||
std::vector<Pair> FetchAll() const override { return {}; }
|
||||
std::shared_ptr<subsys::MetaEnv> parent() const noexcept override { return nullptr; }
|
||||
};
|
||||
|
||||
class MetaEnv : public subsys::MetaEnv {
|
||||
public:
|
||||
using SharedPair = std::pair<std::string, std::shared_ptr<Env>>;
|
||||
|
||||
private:
|
||||
static std::vector<SharedPair>&& Sort(std::vector<SharedPair>&& v) noexcept {
|
||||
std::sort(v.begin(), v.end(),
|
||||
[](const auto& a, const auto& b) { return a.first < b.first; });
|
||||
return v;
|
||||
}
|
||||
|
||||
public:
|
||||
explicit MetaEnv(std::vector<SharedPair>&& children,
|
||||
const std::weak_ptr<subsys::MetaEnv>& parent = {}) noexcept
|
||||
: subsys::MetaEnv("nf7::core::MetaEnv"),
|
||||
children_(Sort(std::move(children))),
|
||||
parent_(parent) {
|
||||
assert(std::all_of(children_.begin(), children_.end(),
|
||||
[](auto& x) { return x.second; }));
|
||||
}
|
||||
|
||||
public:
|
||||
Env* FindOr(std::string_view name) const noexcept override {
|
||||
const auto itr = std::lower_bound(
|
||||
children_.cbegin(), children_.cend(), name,
|
||||
[](const auto& a, const auto& b) { return a.first < b; });
|
||||
if (children_.cend() == itr || itr->first != name) {
|
||||
return nullptr;
|
||||
}
|
||||
return itr->second.get();
|
||||
}
|
||||
std::optional<Pair> FindOr(uint64_t index) const noexcept override {
|
||||
if (index >= children_.size()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const auto& child = children_[index];
|
||||
return Pair {child.first, *child.second};
|
||||
}
|
||||
|
||||
std::vector<Pair> FetchAll() const override
|
||||
try {
|
||||
std::vector<Pair> ret;
|
||||
ret.reserve(children_.size());
|
||||
for (const auto& child : children_) {
|
||||
ret.emplace_back(child.first, *child.second);
|
||||
}
|
||||
return ret;
|
||||
} catch (const std::bad_alloc&) {
|
||||
throw MemoryException {};
|
||||
}
|
||||
|
||||
public:
|
||||
std::shared_ptr<subsys::MetaEnv> parent() const noexcept override {
|
||||
return parent_.lock();
|
||||
}
|
||||
|
||||
private:
|
||||
const std::vector<SharedPair> children_;
|
||||
const std::weak_ptr<subsys::MetaEnv> parent_;
|
||||
};
|
||||
|
||||
} // namespace nf7::core
|
74
core/meta_env_test.cc
Normal file
74
core/meta_env_test.cc
Normal file
@ -0,0 +1,74 @@
|
||||
// No copyright
|
||||
#include "core/meta_env.hh"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "iface/env.hh"
|
||||
|
||||
|
||||
static inline std::shared_ptr<nf7::Env> MakeEmptyEnv() {
|
||||
return std::make_shared<nf7::SimpleEnv>(nf7::SimpleEnv::FactoryMap {});
|
||||
}
|
||||
static inline bool MatchPair(const std::optional<nf7::subsys::MetaEnv::Pair>& a,
|
||||
const nf7::subsys::MetaEnv::Pair& b) {
|
||||
return a && a->first == b.first && &a->second == &b.second;
|
||||
}
|
||||
|
||||
TEST(MetaEnv, FindOrByName) {
|
||||
const auto a = MakeEmptyEnv();
|
||||
const auto b = MakeEmptyEnv();
|
||||
const auto c = MakeEmptyEnv();
|
||||
|
||||
nf7::core::MetaEnv sut {
|
||||
{
|
||||
{"b", b},
|
||||
{"c", c},
|
||||
{"a", a},
|
||||
},
|
||||
};
|
||||
|
||||
EXPECT_EQ(sut.FindOr(""), nullptr);
|
||||
EXPECT_EQ(sut.FindOr("a"), a.get());
|
||||
EXPECT_EQ(sut.FindOr("b"), b.get());
|
||||
EXPECT_EQ(sut.FindOr("c"), c.get());
|
||||
EXPECT_EQ(sut.FindOr("d"), nullptr);
|
||||
}
|
||||
|
||||
TEST(MetaEnv, FindOrByIndex) {
|
||||
const auto a = MakeEmptyEnv();
|
||||
const auto b = MakeEmptyEnv();
|
||||
const auto c = MakeEmptyEnv();
|
||||
|
||||
nf7::core::MetaEnv sut {
|
||||
{
|
||||
{"b", b},
|
||||
{"c", c},
|
||||
{"a", a},
|
||||
},
|
||||
};
|
||||
|
||||
EXPECT_TRUE(MatchPair(sut.FindOr(0), {"a", *a}));
|
||||
EXPECT_TRUE(MatchPair(sut.FindOr(1), {"b", *b}));
|
||||
EXPECT_TRUE(MatchPair(sut.FindOr(2), {"c", *c}));
|
||||
EXPECT_EQ(sut.FindOr(3), std::nullopt);
|
||||
}
|
||||
|
||||
TEST(MetaEnv, FetchAll) {
|
||||
const auto a = MakeEmptyEnv();
|
||||
const auto b = MakeEmptyEnv();
|
||||
const auto c = MakeEmptyEnv();
|
||||
|
||||
nf7::core::MetaEnv sut {
|
||||
{
|
||||
{"b", b},
|
||||
{"c", c},
|
||||
{"a", a},
|
||||
},
|
||||
};
|
||||
|
||||
const auto all = sut.FetchAll();
|
||||
EXPECT_EQ(all.size(), 3);
|
||||
EXPECT_TRUE(MatchPair(all[0], {"a", *a}));
|
||||
EXPECT_TRUE(MatchPair(all[1], {"b", *b}));
|
||||
EXPECT_TRUE(MatchPair(all[2], {"c", *c}));
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user