libcode-query/code/query/expression.hxx
2024-12-25 02:11:14 +01:00

96 lines
1.5 KiB
C++

#ifndef code__query__expression_hxx_
#define code__query__expression_hxx_
#include <code/query/concepts.hxx>
#include <code/query/error.hxx>
#include <code/query/source-location.hxx>
#include <code/query/types.hxx>
#include <code/query/visitor.hxx>
namespace code::query
{
class expression_t
{
public:
template<Expression E>
expression_t(E e)
: container_{make_shared<container_t<E>>(move(e))}
{}
source_location_t const&
origin() const;
friend
void
accept(expression_t const& e, visitor_t& v);
friend
string
to_string(expression_t const& e);
private:
struct abstract_t
{
virtual
~abstract_t() noexcept = default;
virtual
source_location_t const&
origin_() const = 0;
virtual
void
accept_(visitor_t& v) const = 0;
virtual
string
to_string_() const = 0;
};
template<Expression E>
struct container_t
: abstract_t
{
explicit
container_t(E e)
: e{move(e)}
{}
~container_t() noexcept override
{}
source_location_t const&
origin_() const override
{
return e.origin();
}
void
accept_(visitor_t& v) const override
{
if (auto c = dynamic_cast<basic_visitor_t<E>*>(&v); c) {
c->visit(e);
return;
}
v.visit_default();
}
string
to_string_() const override
{
return to_string(e);
}
E e;
};
shared_ptr<abstract_t const> container_;
};
} // namespace code::query
#endif