#pragma once
#include <cstddef>
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#include "clock.hpp"
#include "condition/base.hpp"
#include "context_allocator.hpp"
#include "exclusion/common.hpp"
#include "matcher/base.hpp"
#include "object_store.hpp"
#include "target_address.hpp"
namespace ddwaf {
class expression {
public:
struct cache_type {
bool result{false};
memory::vector<condition_cache> conditions;
};
expression() = default;
explicit expression(std::vector<std::unique_ptr<base_condition>> &&conditions)
: conditions_(std::move(conditions))
{}
bool eval(cache_type &cache, const object_store &store, const object_set_ref &objects_excluded,
const matcher_mapper &dynamic_matchers, ddwaf::timer &deadline) const;
void get_addresses(std::unordered_map<target_index, std::string> &addresses) const
{
for (const auto &cond : conditions_) { cond->get_addresses(addresses); }
}
static std::vector<condition_match> get_matches(cache_type &cache)
{
std::vector<condition_match> matches;
matches.reserve(cache.conditions.size());
for (auto &cond_cache : cache.conditions) {
if (cond_cache.match.has_value()) {
matches.emplace_back(cond_cache.match.value());
}
}
return matches;
}
static bool get_result(cache_type &cache) { return cache.result; }
[[nodiscard]] bool empty() const { return conditions_.empty(); }
[[nodiscard]] std::size_t size() const { return conditions_.size(); }
protected:
std::vector<std::unique_ptr<base_condition>> conditions_;
};
}