#ifndef __PLASP__PDDL__EXPRESSIONS__BINARY_H #define __PLASP__PDDL__EXPRESSIONS__BINARY_H #include #include #include #include namespace plasp { namespace pddl { namespace expressions { //////////////////////////////////////////////////////////////////////////////////////////////////// // // Binary // //////////////////////////////////////////////////////////////////////////////////////////////////// template class Binary: public ExpressionCRTP { public: template static std::unique_ptr parse(Context &context, ExpressionContext &expressionContext, ExpressionParser parseExpression); public: const std::array &arguments() const; private: template void setArgument(const Expression *argument); template void setArgument(ExpressionPointer &&argument); std::array m_arguments; std::array m_argumentStorage; }; //////////////////////////////////////////////////////////////////////////////////////////////////// template template std::unique_ptr Binary::parse(Context &context, ExpressionContext &expressionContext, ExpressionParser parseExpression) { auto &parser = context.parser; const auto position = parser.position(); if (!parser.testAndSkip("(") || !parser.testIdentifierAndSkip(Derived::Identifier)) { parser.seek(position); return nullptr; } auto expression = std::make_unique(); // Assume that expression identifier (imply, exists, etc.) is already parsed // Parse arguments of the expression expression->Binary::setArgument<0>(parseExpression(context, expressionContext)); expression->Binary::setArgument<1>(parseExpression(context, expressionContext)); parser.expect(")"); return expression; } //////////////////////////////////////////////////////////////////////////////////////////////////// template template void Binary::setArgument(const Expression *expression) { static_assert(i <= 2, "Index out of range"); m_argumentStorage[i] = nullptr; m_arguments[i] = expression; } //////////////////////////////////////////////////////////////////////////////////////////////////// template template void Binary::setArgument(ExpressionPointer &&expression) { static_assert(i <= 2, "Index out of range"); m_argumentStorage[i] = std::move(expression); m_arguments[i] = m_argumentStorage[i].get(); } //////////////////////////////////////////////////////////////////////////////////////////////////// template const std::array &Binary::arguments() const { return m_arguments; } //////////////////////////////////////////////////////////////////////////////////////////////////// } } } #endif