Skip to content

Commit 6140842

Browse files
committed
Add a Reusable ChainableEnvironment and optimize the EnvironmentMap
CURA-13049
1 parent fd7cd2f commit 6140842

3 files changed

Lines changed: 95 additions & 41 deletions

File tree

conandata.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
version: "1.0.0"
1+
version: "1.1.0"

include/cura-formulae-engine/ast/ast.h

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
#pragma once
22

3-
#include "cura-formulae-engine/eval.h"
4-
5-
#include <zeus/expected.hpp>
6-
73
#include <functional>
84
#include <string>
95
#include <unordered_set>
6+
#include <zeus/expected.hpp>
7+
8+
#include "cura-formulae-engine/eval.h"
109

1110
namespace CuraFormulaeEngine::eval
1211
{
@@ -36,10 +35,13 @@ class EnvironmentMap : public Environment
3635
{
3736
private:
3837
std::unordered_map<std::string, eval::Value> environment_ = {};
39-
public:
4038

39+
public:
4140
EnvironmentMap() = default;
42-
explicit EnvironmentMap(const std::unordered_map<std::string, eval::Value>& map) : environment_(map) {}
41+
explicit EnvironmentMap(const std::unordered_map<std::string, eval::Value>& map)
42+
: environment_(map)
43+
{
44+
}
4345
~EnvironmentMap() override = default;
4446

4547
[[nodiscard]] std::optional<eval::Value> get(const std::string& key) const noexcept override;
@@ -52,31 +54,58 @@ class EnvironmentMap : public Environment
5254

5355
void set(const std::string& key, const eval::Value& value) noexcept;
5456

55-
[[nodiscard]] EnvironmentMap clone() const noexcept;
57+
void add(const std::unordered_map<std::string, eval::Value> values);
5658

59+
[[nodiscard]] EnvironmentMap clone() const noexcept;
5760
};
5861

59-
class LocalEnvironment : public Environment
62+
class ChainableEnvironment : public Environment
6063
{
64+
private:
65+
const Environment* shadow_environment_{ nullptr };
66+
6167
public:
68+
explicit ChainableEnvironment(const Environment* shadow_environment = nullptr)
69+
: shadow_environment_(shadow_environment)
70+
{
71+
}
72+
~ChainableEnvironment() override = default;
6273

63-
LocalEnvironment() = default;
64-
explicit LocalEnvironment(const Environment* shadow_environment_)
65-
: shadow_environment_(shadow_environment_)
74+
[[nodiscard]] std::optional<eval::Value> get(const std::string& key) const noexcept override final;
75+
76+
[[nodiscard]] bool has(const std::string& key) const noexcept override final;
77+
78+
[[nodiscard]] std::unordered_map<std::string, eval::Value> getAll() const noexcept override final;
79+
80+
protected:
81+
[[nodiscard]] virtual std::optional<eval::Value> getImpl(const std::string& key) const noexcept = 0;
82+
83+
[[nodiscard]] virtual bool hasImpl(const std::string& key) const noexcept = 0;
84+
85+
[[nodiscard]] virtual std::unordered_map<std::string, eval::Value> getAllImpl() const noexcept = 0;
86+
};
87+
88+
class LocalEnvironment : public ChainableEnvironment
89+
{
90+
private:
91+
EnvironmentMap local_environment_;
92+
93+
public:
94+
explicit LocalEnvironment(const Environment* shadow_environment = nullptr)
95+
: ChainableEnvironment(shadow_environment)
6696
{
6797
}
6898
~LocalEnvironment() override = default;
6999

70-
EnvironmentMap local_environment_ = {};
71-
const Environment* shadow_environment_;
72-
73-
[[nodiscard]] std::optional<eval::Value> get(const std::string& key) const noexcept override;
100+
[[nodiscard]] std::optional<eval::Value> getImpl(const std::string& key) const noexcept override;
74101

75-
[[nodiscard]] bool has(const std::string& key) const noexcept override;
102+
[[nodiscard]] bool hasImpl(const std::string& key) const noexcept override;
76103

77-
[[nodiscard]] std::unordered_map<std::string, eval::Value> getAll() const noexcept override;
104+
[[nodiscard]] std::unordered_map<std::string, eval::Value> getAllImpl() const noexcept override;
78105

79106
void set(const std::string& key, const eval::Value& value);
107+
108+
void add(const std::unordered_map<std::string, eval::Value> values);
80109
};
81110

82111
} // namespace CuraFormulaeEngine::env
@@ -123,7 +152,8 @@ struct Expr
123152
[[nodiscard]] virtual bool deepEq(const Expr& other) const = 0;
124153

125154
/**
126-
* @brief Traverses the expression tree and applies the visitor function to each node.
155+
* @brief Traverses the expression tree and applies the visitor function to
156+
* each node.
127157
*
128158
* @param visitor The visitor function to apply to each node.
129159
*/

src/ast/ast.cpp

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ namespace CuraFormulaeEngine::env
55

66
std::optional<eval::Value> EnvironmentMap::get(const std::string& key) const noexcept
77
{
8-
if (!has(key))
8+
auto iterator = environment_.find(key);
9+
if (iterator == environment_.end())
910
{
1011
return std::nullopt;
1112
}
12-
return environment_.at(key);
13+
return iterator->second;
1314
}
1415

1516
bool EnvironmentMap::has(const std::string& key) const noexcept
@@ -32,44 +33,67 @@ void EnvironmentMap::set(const std::string& key, const eval::Value& value) noexc
3233
environment_.insert_or_assign(key, value);
3334
}
3435

36+
void EnvironmentMap::add(const std::unordered_map<std::string, eval::Value> values)
37+
{
38+
environment_.insert(values.begin(), values.end());
39+
}
40+
3541
EnvironmentMap EnvironmentMap::clone() const noexcept
3642
{
37-
return EnvironmentMap{environment_};
43+
return EnvironmentMap{ environment_ };
3844
}
3945

40-
std::optional<eval::Value> LocalEnvironment::get(const std::string& key) const noexcept
46+
std::optional<eval::Value> LocalEnvironment::getImpl(const std::string& key) const noexcept
4147
{
42-
if (local_environment_.has(key))
43-
{
44-
return local_environment_.get(key);
45-
}
46-
if (shadow_environment_ && shadow_environment_->has(key))
48+
return local_environment_.get(key);
49+
}
50+
51+
bool LocalEnvironment::hasImpl(const std::string& key) const noexcept
52+
{
53+
return local_environment_.has(key);
54+
}
55+
56+
std::unordered_map<std::string, eval::Value> LocalEnvironment::getAllImpl() const noexcept
57+
{
58+
return local_environment_.getAll();
59+
}
60+
61+
void LocalEnvironment::set(const std::string& key, const eval::Value& value)
62+
{
63+
local_environment_.set(key, value);
64+
}
65+
66+
void LocalEnvironment::add(const std::unordered_map<std::string, eval::Value> values)
67+
{
68+
local_environment_.add(values);
69+
}
70+
71+
std::optional<eval::Value> ChainableEnvironment::get(const std::string& key) const noexcept
72+
{
73+
std::optional<eval::Value> value = getImpl(key);
74+
if (! value.has_value() && shadow_environment_)
4775
{
48-
return shadow_environment_->get(key);
76+
value = shadow_environment_->get(key);
4977
}
50-
return std::nullopt;
78+
return value;
5179
}
5280

53-
bool LocalEnvironment::has(const std::string& key) const noexcept
81+
bool ChainableEnvironment::has(const std::string& key) const noexcept
5482
{
55-
return local_environment_.has(key) || (shadow_environment_ && shadow_environment_->has(key));
83+
return hasImpl(key) || (shadow_environment_ && shadow_environment_->has(key));
5684
}
5785

58-
std::unordered_map<std::string, eval::Value> LocalEnvironment::getAll() const noexcept
86+
std::unordered_map<std::string, eval::Value> ChainableEnvironment::getAll() const noexcept
5987
{
6088
std::unordered_map<std::string, eval::Value> all;
61-
if (shadow_environment_) {
89+
if (shadow_environment_)
90+
{
6291
all = shadow_environment_->getAll();
6392
}
6493

65-
auto scoped = local_environment_.getAll();
94+
auto scoped = getAllImpl();
6695
all.insert(scoped.begin(), scoped.end());
6796
return all;
6897
}
6998

70-
void LocalEnvironment::set(const std::string& key, const eval::Value& value)
71-
{
72-
local_environment_.set(key, value);
73-
}
74-
75-
} // namespace CuraFormulaeEngine::env
99+
} // namespace CuraFormulaeEngine::env

0 commit comments

Comments
 (0)