Да, собственно, почти такое решение я и нашел... вечером выложу подробнее код, чтобы закрыть тему.
Сообразил, что не обязательно ждать пока приду домой и забрал код из репозитория.
Вот, вроде бы, так работает.
Дефайны в начале
Код:
#define FLOAT_TYPE float
#define FLOAT_PRECISION 0.000002
Объявление
Код:
class CORE_API FireFloat
{
public:
Три конструктора: пустой, копирования, и от любого типа. Минус этого в том, что в конструкторе имеется приведение к нужному типу, потому умрут все варнинги, связанные с некорректным присвоением (типа Truncation from double to float).
Код:
FireFloat()
{
val = 0;
}
template<class T>
FireFloat(const T &v)
{
val = (FLOAT_TYPE)v;
}
FireFloat(const FireFloat &v)
{
val = v.val;
}
оператор приведения
Код:
operator FIRE_INLINE FLOAT_TYPE() const
{
return val;
}
все обычные операторы
Код:
FireFloat& operator++()
{
val++;
return *this;
}
FireFloat operator++(int)
{
return val++;
}
FireFloat& operator--()
{
val--;
return *this;
}
FireFloat operator--(int)
{
return val--;
}
template<class T>
FireFloat& operator+=(const T &v)
{
val += v;
return *this;
}
template<class T>
FireFloat& operator-=(const T &v)
{
val -= v;
return *this;
}
template<class T>
FireFloat& operator*=(const T &v)
{
val *= v;
return *this;
}
template<class T>
FireFloat& operator/=(const T &v)
{
val /= v;
return *this;
}
template<class T>
FireFloat operator+(const T &v) const
{
return val+v;
}
template<class T>
FireFloat operator-(const T &v) const
{
return val-v;
}
template<class T>
FireFloat operator*(const T &v) const
{
return val*v;
}
template<class T>
FireFloat operator/(const T &v) const
{
return val/v;
}
Пропатченные операторы сравнения
Код:
template<class T>
bool FIRE_INLINE operator==(const T &v) const
{
return (val-v<=FLOAT_PRECISION && val-v>=-FLOAT_PRECISION);
}
template<class T>
bool FIRE_INLINE operator!=(const T &v) const
{
return !(this->operator== <T>(v));
}
template<class T>
bool FIRE_INLINE operator<(const T &v) const
{
return (v-val>FLOAT_PRECISION);
}
template<class T>
bool FIRE_INLINE operator>(const T &v) const
{
return !(this->operator< <T>(v) || this->operator==<T>(v));
}
template<class T>
bool FIRE_INLINE operator<=(const T &v) const
{
return (this->operator< <T>(v) || this->operator==<T>(v));
}
template<class T>
bool FIRE_INLINE operator>=(const T &v) const
{
return !(this->operator< <T>(v));
}
Поле
Код:
private:
FLOAT_TYPE val;
};
Собственно, был замечен только один минус этого решения, и с ним мы смогли смириться.
Вылетел объявленный для другого типа (вектора) operator*(Ffloat, Vector) - скалярное умножение константы на вектор. Произошло это по очень простой причине. Пока Ffloat был всего лишь тайпдефом встроенного флота, строчка типа
выполнялась очень просто - 11 приводилось к float'у и вызывался оператор вектора. А теперь 11 приводится к FireFloat'у и, соответсвенно, вызвается его оператор умножения, возвращающий не Vector, как было раньше, а FireFloat.
Вот. А, в целом, прозрачный тип неплохо удался, и пока нас всех устраивает.
Всем спасибо за попытки помочь и особенно grigsoft'у за его решение, совпавшее с моим
PS. Пусть вас не смущает слово FIRE, так часто встречающееся - это название нашего проекта. Я просто целиком копипастил код, ибо лень править
![Smile :) :)](https://cdn.jsdelivr.net/joypixels/assets/8.0/png/unicode/64/1f642.png)