#include "./numerical.h"

template class std::vector<double>;

template <>
bool applyNamedChange(double &obj, char const *key, double weight, double value)
{
  if (key[0] == '=' && key[1] == 0) {
    obj = weight * value + (1.0 - weight) * obj;
    return true;
  }
  if (key[0] == '+' && key[1] == 0) {
    obj += weight * value;
    return true;
  }
  if (key[0] == '*' && key[1] == 'e' && key[2] == 'x' && key[3] == 'p' && key[4] == 0) {
    obj *= exp(weight * value);
    return true;
  }
  return false;
}

template <>
bool applyNamedChange(float &obj, char const *key, double weight, double value)
{
  double obj2 = obj;
  if (applyNamedChange(obj2, key, weight, value)) {
    obj = obj2;
    return true;
  }
  return false;
}

template <>
bool applyNamedChange(U32 &obj, char const *key, double weight, double value)
{
  double obj2 = obj;
  if (applyNamedChange(obj2, key, weight, value)) {
    obj = (U32)round(obj2);
    return true;
  }
  return false;
}

template <>
bool applyNamedChange(S32 &obj, char const *key, double weight, double value)
{
  double obj2 = obj;
  if (applyNamedChange(obj2, key, weight, value)) {
    obj = (S32)round(obj2);
    return true;
  }
  return false;
}

template <>
bool applyNamedChange(U64 &obj, char const *key, double weight, double value)
{
  double obj2 = obj;
  if (applyNamedChange(obj2, key, weight, value)) {
    obj = (U64)round(obj2);
    return true;
  }
  return false;
}

template <>
bool applyNamedChange(S64 &obj, char const *key, double weight, double value)
{
  double obj2 = obj;
  if (applyNamedChange(obj2, key, weight, value)) {
    obj = (S64)round(obj2);
    return true;
  }
  return false;
}

template <>
bool applyNamedChange(bool &obj, char const *key, double weight, double value)
{
  if (key[0] == '=' && key[1] == 0) {
    obj = (bool)value;
    return true;
  }
  return false;
}

template <>
bool applyNamedChange(string &obj, char const *key, double weight, double value)
{
  return false;
}

template <>
bool applyNamedChange(std::complex<double> &obj, char const *key, double weight, double value)
{
  if (key[0] == '=' && key[1] == 0) {
    obj = weight * value + (1.0 - weight) * obj;
    return true;
  }
  return false;
}

