File api_signatures.hpp¶
File List > backends > cxx > include > zmbt > expr > api_signatures.hpp
Go to the documentation of this file
#ifndef ZMBT_EXPR_EXPRESSION_API_SIGNATURES_HPP_
#define ZMBT_EXPR_EXPRESSION_API_SIGNATURES_HPP_
#include <cstddef>
#include <initializer_list>
#include <boost/json.hpp>
#include "zmbt/reflect/serialization.hpp"
#include "keyword.hpp"
#include "expression.hpp"
namespace zmbt {
namespace lang {
namespace detail {
boost::json::value handle_list_init(std::initializer_list<Expression> set);
}
template <Keyword K>
struct SignatureBase : public Expression
{
SignatureBase() : Expression(encodeNested(K, {}))
{}
operator boost::json::value() const // allowing implicit on expr::*
{
return Expression::operator boost::json::value();
}
};
template <Keyword K>
struct SignatureConst : public SignatureBase<K>
{
using SignatureBase<K>::SignatureBase;
};
template <Keyword K>
struct SignatureUnary : public SignatureBase<K>
{
using SignatureBase<K>::SignatureBase;
};
template <Keyword K>
struct SignatureBinary : public SignatureBase<K>
{
using SignatureBase<K>::SignatureBase;
Expression operator()(Expression const& param) const
{
return Expression(Expression::encodeNested(K, {param}));
}
Expression operator()(Expression && param) const
{
return Expression(Expression::encodeNested(K, {std::move(param)}));
}
Expression operator()(std::initializer_list<Expression> param) const
{
return Expression(Expression::encodeNested(K, {detail::handle_list_init(param)}));
}
};
template <>
struct SignatureBinary<Keyword::PreProc> : public SignatureBase<Keyword::PreProc>
{
using SignatureBase<Keyword::PreProc>::SignatureBase;
Expression operator()(boost::json::string_view const param) const
{
return Expression(Expression::encodePreProc(zmbt::format("$[%s]", param).c_str()));
}
Expression operator()(std::size_t const param) const
{
return Expression(Expression::encodePreProc(zmbt::format("$[%s]", param).c_str()));
}
};
template <Keyword K>
struct SignatureVariadic : public SignatureBase<K>
{
private:
static Expression encodeVariadic(std::initializer_list<zmbt::lang::Expression> params)
{
return Expression(Expression::encodeNested(K, params));
}
public:
using SignatureBase<K>::SignatureBase;
using E = Expression;
Expression operator()() const {
return encodeVariadic({});
}
Expression operator()(E const& p0) const {
return encodeVariadic({p0});
}
Expression operator()(E const& p0, E const& p1) const {
return encodeVariadic({p0, p1});
}
Expression operator()(E const& p0, E const& p1, E const& p2) const {
return encodeVariadic({p0, p1, p2});
}
Expression operator()(E const& p0, E const& p1, E const& p2, E const& p3) const {
return encodeVariadic({p0, p1, p2, p3});
}
Expression operator()(E const& p0, E const& p1, E const& p2, E const& p3, E const& p4) const {
return encodeVariadic({p0, p1, p2, p3, p4});
}
Expression operator()(E const& p0, E const& p1, E const& p2, E const& p3, E const& p4, E const& p5) const {
return encodeVariadic({p0, p1, p2, p3, p4, p5});
}
Expression operator()(E const& p0, E const& p1, E const& p2, E const& p3, E const& p4, E const& p5, E const& p6) const {
return encodeVariadic({p0, p1, p2, p3, p4, p5, p6});
}
Expression operator()(E const& p0, E const& p1, E const& p2, E const& p3, E const& p4, E const& p5, E const& p6, E const& p7) const {
return encodeVariadic({p0, p1, p2, p3, p4, p5, p6, p7});
}
template <class... T>
Expression operator()(E const& p0, E const& p1, E const& p2, E const& p3, E const& p4, E const& p5, E const& p6, E const& p7, T&&... rest) const {
return encodeVariadic({p0, p1, p2, p3, p4, p5, p6, p7, zmbt::json_from(rest)...});
}
};
struct SignatureOp : public SignatureBase<Keyword::Op>
{
using SignatureBase<Keyword::Op>::SignatureBase;
Expression operator()(Expression const& type, Expression const& expr) const
{
return Expression(Expression::encodeNested(Keyword::Op, {type + expr}));
}
template <class T>
Expression operator()(type_tag<T> tag, Expression const& expr) const
{
Operator const op{tag};
return Expression(Expression::encodeNested(Keyword::Op, {op.annotation() + expr}));
}
};
struct SignatureCast : public SignatureBinary<Keyword::Cast>
{
using SignatureBinary<Keyword::Cast>::SignatureBinary;
using SignatureBinary<Keyword::Cast>::operator();
template <class T>
Expression operator()(type_tag<T> tag) const
{
Operator const op{tag};
return Expression(Expression::encodeNested(Keyword::Cast, {op.annotation()}));
}
};
struct SignatureUncast : public SignatureBinary<Keyword::Uncast>
{
using SignatureBinary<Keyword::Uncast>::SignatureBinary;
using SignatureBinary<Keyword::Uncast>::operator();
template <class T>
Expression operator()(type_tag<T> tag) const
{
Operator const op{tag};
return Expression(Expression::encodeNested(Keyword::Uncast, {op.annotation()}));
}
};
struct SignatureErr : public SignatureBase<Keyword::Err>
{
using SignatureBase<Keyword::Err>::SignatureBase;
Expression operator()(boost::json::object payload) const
{
return Expression(Expression::encodeNested(Keyword::Err, {payload}));
}
Expression operator()(boost::json::string_view msg, boost::json::string_view ctx = "") const
{
return make_error("", msg, ctx);
}
template <class T>
Expression operator()(type_tag<T>, boost::json::string_view msg = "", boost::json::string_view ctx = "") const
{
return make_error(zmbt::type_name<T>(), msg, ctx);
}
private:
Expression make_error(boost::json::string_view type, boost::json::string_view msg, boost::json::string_view ctx) const;
};
} // namespace lang
} // namespace zmbt
#endif // ZMBT_EXPR_EXPRESSION_API_SIGNATURES_HPP_