OASIS
Open Algebra Software
Loading...
Searching...
No Matches
RecursiveCast.hpp
Go to the documentation of this file.
1//
2// Created by Matthew McCall on 10/14/24.
3//
4
5#ifndef OASIS_RECURSIVECAST_HPP
6#define OASIS_RECURSIVECAST_HPP
7
8#include "Expression.hpp"
9
10namespace Oasis {
11
12template <IExpression T>
13 requires DerivedFromBinaryExpression<T>
15{
16 T dummy;
17 return [&other]<template <typename, typename> typename DerivedT, typename MostSigOpT, typename LeastSigOpT>(BinaryExpression<DerivedT, MostSigOpT, LeastSigOpT>&) -> std::unique_ptr<T> {
18 if (!other.Is<DerivedT>()) {
19 return nullptr;
20 }
21
22 const std::unique_ptr<Expression> otherGeneralized = other.Generalize();
23 const auto& otherBinaryExpression = static_cast<const DerivedT<Expression, Expression>&>(*otherGeneralized);
24
25 auto specializedMostSigOp = RecursiveCast<MostSigOpT>(otherBinaryExpression.GetMostSigOp());
26 auto specializedLeastSigOp = RecursiveCast<LeastSigOpT>(otherBinaryExpression.GetLeastSigOp());
27
28 if (specializedMostSigOp && specializedLeastSigOp) {
29 return std::make_unique<T>(*specializedMostSigOp, *specializedLeastSigOp);
30 }
31
32 if (!(other.GetCategory() & Commutative)) {
33 return nullptr;
34 }
35
36 auto otherWithSwappedOps
37 = otherBinaryExpression.SwapOperands();
38
39 specializedMostSigOp = RecursiveCast<MostSigOpT>(otherWithSwappedOps.GetMostSigOp());
40 specializedLeastSigOp = RecursiveCast<LeastSigOpT>(otherWithSwappedOps.GetLeastSigOp());
41
42 if (specializedMostSigOp && specializedLeastSigOp) {
43 return std::make_unique<T>(*specializedMostSigOp, *specializedLeastSigOp);
44 }
45
46 return nullptr;
47 }(dummy);
48}
49
50template <IExpression T>
51 requires DerivedFromUnaryExpression<T>
53{
54 T dummy;
55 return [&other]<template <typename> typename DerivedT, typename OpT>(UnaryExpression<DerivedT, OpT>&) -> std::unique_ptr<T> {
56 if (!other.Is<DerivedT>()) {
57 return nullptr;
58 }
59
60 const std::unique_ptr<Expression> otherGeneralized = other.Generalize();
61 const auto& otherUnaryExpression = static_cast<const DerivedT<Expression>&>(*otherGeneralized);
62
63 auto specializedOp = RecursiveCast<OpT>(otherUnaryExpression.GetOperand());
64 if (specializedOp) {
65 return std::make_unique<T>(*specializedOp);
66 }
67
68 return nullptr;
69 }(dummy);
70}
71
72template <IExpression T>
74{
76 return other.Copy();
77 else
78 return other.Is<T>() ? std::make_unique<T>(dynamic_cast<const T&>(other)) : nullptr;
79}
80
81}
82
83#endif // OASIS_RECURSIVECAST_HPP
A binary expression.
Definition BinaryExpression.hpp:79
An expression.
Definition Expression.hpp:56
Definition UnaryExpression.hpp:14
T is_same_v
Definition Add.hpp:11
auto RecursiveCast(const Expression &other) -> std::unique_ptr< T >
Definition RecursiveCast.hpp:14
@ Commutative
Definition Expression.hpp:44