- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
CompoundExpression*
CompoundExpression::newBinaryExpression(
	BasicBinaryOperation::Type operation,
	const Expression *x,
	const Expression *y
) {
	vector<Expression::const_pointer> params(2);
	params[0] = x;
	params[1] = y;
	
	// integer power optimization
	if (operation == BasicBinaryOperation::POWER) {
		if (y->isNumber()) {
			Number::const_pointer number_y = dynamic_cast<typeof number_y>(y);
			if (number_y != NULL && number_y->isIntegerNumber()) {
				IntegerNumber::const_pointer integer_y = dynamic_cast<typeof integer_y>(number_y);
				if (integer_y != NULL) {
					operation = BasicBinaryOperation::INT_POWER;
					return new CompoundExpression(BinaryOperation::getOperation(operation), params);
				}
			}
		}
	}
	
	// x^(y/n), where 'n' is odd integer
	// transform to '(x^y)^(1/n)'
	if (operation == BasicBinaryOperation::POWER) {
		if (y->isCompoundExpression()) {
			auto compoundExpressionY = dynamic_cast<CompoundExpression::const_pointer>(y);
			if (compoundExpressionY != NULL && compoundExpressionY->operation->isBinary()) {
				auto innerOperation = compoundExpressionY->operation;
				auto binaryOperation = dynamic_cast<BinaryOperation const *>(innerOperation);
				if (binaryOperation != NULL && binaryOperation->getType() == BasicBinaryOperation::DIVIDE) {
					Expression::const_pointer   numerator = compoundExpressionY->params[0];
					Expression::const_pointer denominator = compoundExpressionY->params[1];
					if (denominator->isNumber()) {
						auto numberDenominator = dynamic_cast<Number::const_pointer>(denominator);
						if (numberDenominator != NULL && numberDenominator->isIntegerNumber()) {
							auto integerDenominator = dynamic_cast<IntegerNumber::const_pointer>(numberDenominator);
							if (integerDenominator != NULL && (integerDenominator->intValue() % 2) != 0) {
								auto base = CompoundExpression::newBinaryExpression(BasicBinaryOperation::POWER, x, numerator);
								return CompoundExpression::newBinaryExpression(BasicBinaryOperation::NTH_ROOT, integerDenominator, base);
							}
						}
					}
				}
			}
		}
	}
	return new CompoundExpression(BinaryOperation::getOperation(operation), params);
}
                                 
        
            Моё. Потребовалось воткнуть оптимизацию арифметического выражения некоторого вида. В результате родился вот такой костыль.
        
        
Тут на лицо какая-то пессимизация.
давным давно я заглянул в сырцы GCC на предмет как там делаются оптимизации. после этого, то ГК сверху это не костыль - это ангельские крылья в сравнении.
что я хочу сказать. оптимизации основаны на эвристиках. любой набор эвристик будет выглядеть плохо. больше оптимизиций/эвристик - хуже будет смотреться.
> dynamic_cast
> dynamic_cast
> dynamic_cast
> dynamic_cast
> dynamic_cast
Соптимизировавший.