mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-26 17:41:59 +00:00
dbms: added more bitwise functions [#CONV-2944].
This commit is contained in:
parent
1383bfd005
commit
95060b1a47
@ -12,39 +12,69 @@ namespace DB
|
||||
|
||||
/** Арифметические функции: +, -, *, /, %,
|
||||
* intDiv (целочисленное деление), унарный минус.
|
||||
* Битовые функции: |, &, ^, ~.
|
||||
*/
|
||||
|
||||
template<typename A, typename B>
|
||||
struct PlusImpl
|
||||
template<typename A, typename B, typename Op>
|
||||
struct BinaryOperationImpl
|
||||
{
|
||||
typedef typename NumberTraits::ResultOfAdditionMultiplication<A, B>::Type ResultType;
|
||||
typedef typename Op::ResultType ResultType;
|
||||
|
||||
static void vector_vector(const std::vector<A> & a, const std::vector<B> & b, std::vector<ResultType> & c)
|
||||
{
|
||||
/// Далее везде, static_cast - чтобы не было неправильного результата в выражениях вида Int64 c = UInt32(a) * Int32(-1).
|
||||
|
||||
size_t size = a.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
c[i] = static_cast<ResultType>(a[i]) + b[i];
|
||||
c[i] = Op::apply(a[i], b[i]);
|
||||
}
|
||||
|
||||
static void vector_constant(const std::vector<A> & a, B b, std::vector<ResultType> & c)
|
||||
{
|
||||
size_t size = a.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
c[i] = static_cast<ResultType>(a[i]) + b;
|
||||
c[i] = Op::apply(a[i], b);
|
||||
}
|
||||
|
||||
static void constant_vector(A a, const std::vector<B> & b, std::vector<ResultType> & c)
|
||||
{
|
||||
size_t size = b.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
c[i] = static_cast<ResultType>(a) + b[i];
|
||||
c[i] = Op::apply(a, b[i]);
|
||||
}
|
||||
|
||||
static void constant_constant(A a, B b, ResultType & c)
|
||||
{
|
||||
c = static_cast<ResultType>(a) + b;
|
||||
c = Op::apply(a, b);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename A, typename Op>
|
||||
struct UnaryOperationImpl
|
||||
{
|
||||
typedef typename Op::ResultType ResultType;
|
||||
|
||||
static void vector(const std::vector<A> & a, std::vector<ResultType> & c)
|
||||
{
|
||||
size_t size = a.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
c[i] = Op::apply(a[i]);
|
||||
}
|
||||
|
||||
static void constant(A a, ResultType & c)
|
||||
{
|
||||
c = Op::apply(a);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename A, typename B>
|
||||
struct PlusImpl
|
||||
{
|
||||
typedef typename NumberTraits::ResultOfAdditionMultiplication<A, B>::Type ResultType;
|
||||
|
||||
static inline ResultType apply(A a, B b)
|
||||
{
|
||||
/// Далее везде, static_cast - чтобы не было неправильного результата в выражениях вида Int64 c = UInt32(a) * Int32(-1).
|
||||
return static_cast<ResultType>(a) + b;
|
||||
}
|
||||
};
|
||||
|
||||
@ -53,30 +83,9 @@ struct MultiplyImpl
|
||||
{
|
||||
typedef typename NumberTraits::ResultOfAdditionMultiplication<A, B>::Type ResultType;
|
||||
|
||||
static void vector_vector(const std::vector<A> & a, const std::vector<B> & b, std::vector<ResultType> & c)
|
||||
static inline ResultType apply(A a, B b)
|
||||
{
|
||||
size_t size = a.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
c[i] = static_cast<ResultType>(a[i]) * b[i];
|
||||
}
|
||||
|
||||
static void vector_constant(const std::vector<A> & a, B b, std::vector<ResultType> & c)
|
||||
{
|
||||
size_t size = a.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
c[i] = static_cast<ResultType>(a[i]) * b;
|
||||
}
|
||||
|
||||
static void constant_vector(A a, const std::vector<B> & b, std::vector<ResultType> & c)
|
||||
{
|
||||
size_t size = b.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
c[i] = static_cast<ResultType>(a) * b[i];
|
||||
}
|
||||
|
||||
static void constant_constant(A a, B b, ResultType & c)
|
||||
{
|
||||
c = static_cast<ResultType>(a) * b;
|
||||
return static_cast<ResultType>(a) * b;
|
||||
}
|
||||
};
|
||||
|
||||
@ -85,30 +94,9 @@ struct MinusImpl
|
||||
{
|
||||
typedef typename NumberTraits::ResultOfSubtraction<A, B>::Type ResultType;
|
||||
|
||||
static void vector_vector(const std::vector<A> & a, const std::vector<B> & b, std::vector<ResultType> & c)
|
||||
static inline ResultType apply(A a, B b)
|
||||
{
|
||||
size_t size = a.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
c[i] = static_cast<ResultType>(a[i]) - b[i];
|
||||
}
|
||||
|
||||
static void vector_constant(const std::vector<A> & a, B b, std::vector<ResultType> & c)
|
||||
{
|
||||
size_t size = a.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
c[i] = static_cast<ResultType>(a[i]) - b;
|
||||
}
|
||||
|
||||
static void constant_vector(A a, const std::vector<B> & b, std::vector<ResultType> & c)
|
||||
{
|
||||
size_t size = b.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
c[i] = static_cast<ResultType>(a) - b[i];
|
||||
}
|
||||
|
||||
static void constant_constant(A a, B b, ResultType & c)
|
||||
{
|
||||
c = static_cast<ResultType>(a) - b;
|
||||
return static_cast<ResultType>(a) - b;
|
||||
}
|
||||
};
|
||||
|
||||
@ -117,30 +105,9 @@ struct DivideFloatingImpl
|
||||
{
|
||||
typedef typename NumberTraits::ResultOfFloatingPointDivision<A, B>::Type ResultType;
|
||||
|
||||
static void vector_vector(const std::vector<A> & a, const std::vector<B> & b, std::vector<ResultType> & c)
|
||||
static inline ResultType apply(A a, B b)
|
||||
{
|
||||
size_t size = a.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
c[i] = static_cast<ResultType>(a[i]) / b[i];
|
||||
}
|
||||
|
||||
static void vector_constant(const std::vector<A> & a, B b, std::vector<ResultType> & c)
|
||||
{
|
||||
size_t size = a.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
c[i] = static_cast<ResultType>(a[i]) / b;
|
||||
}
|
||||
|
||||
static void constant_vector(A a, const std::vector<B> & b, std::vector<ResultType> & c)
|
||||
{
|
||||
size_t size = b.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
c[i] = static_cast<ResultType>(a) / b[i];
|
||||
}
|
||||
|
||||
static void constant_constant(A a, B b, ResultType & c)
|
||||
{
|
||||
c = static_cast<ResultType>(a) / b;
|
||||
return static_cast<ResultType>(a) / b;
|
||||
}
|
||||
};
|
||||
|
||||
@ -157,40 +124,10 @@ struct DivideIntegralImpl
|
||||
{
|
||||
typedef typename NumberTraits::ResultOfIntegerDivision<A, B>::Type ResultType;
|
||||
|
||||
static void vector_vector(const std::vector<A> & a, const std::vector<B> & b, std::vector<ResultType> & c)
|
||||
{
|
||||
size_t size = a.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
throwIfZero(b[i]);
|
||||
c[i] = static_cast<ResultType>(a[i]) / b[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void vector_constant(const std::vector<A> & a, B b, std::vector<ResultType> & c)
|
||||
{
|
||||
size_t size = a.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
static inline ResultType apply(A a, B b)
|
||||
{
|
||||
throwIfZero(b);
|
||||
c[i] = static_cast<ResultType>(a[i]) / b;
|
||||
}
|
||||
}
|
||||
|
||||
static void constant_vector(A a, const std::vector<B> & b, std::vector<ResultType> & c)
|
||||
{
|
||||
size_t size = b.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
throwIfZero(b[i]);
|
||||
c[i] = static_cast<ResultType>(a) / b[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void constant_constant(A a, B b, ResultType & c)
|
||||
{
|
||||
throwIfZero(b);
|
||||
c = static_cast<ResultType>(a) / b;
|
||||
return static_cast<ResultType>(a) / b;
|
||||
}
|
||||
};
|
||||
|
||||
@ -199,43 +136,10 @@ struct ModuloImpl
|
||||
{
|
||||
typedef typename NumberTraits::ResultOfModulo<A, B>::Type ResultType;
|
||||
|
||||
static void vector_vector(const std::vector<A> & a, const std::vector<B> & b, std::vector<ResultType> & c)
|
||||
{
|
||||
size_t size = a.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
throwIfZero(typename NumberTraits::ToInteger<A>::Type(b[i]));
|
||||
c[i] = typename NumberTraits::ToInteger<A>::Type(a[i])
|
||||
% typename NumberTraits::ToInteger<A>::Type(b[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void vector_constant(const std::vector<A> & a, B b, std::vector<ResultType> & c)
|
||||
{
|
||||
size_t size = a.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
static inline ResultType apply(A a, B b)
|
||||
{
|
||||
throwIfZero(typename NumberTraits::ToInteger<A>::Type(b));
|
||||
c[i] = typename NumberTraits::ToInteger<A>::Type(a[i])
|
||||
% typename NumberTraits::ToInteger<A>::Type(b);
|
||||
}
|
||||
}
|
||||
|
||||
static void constant_vector(A a, const std::vector<B> & b, std::vector<ResultType> & c)
|
||||
{
|
||||
size_t size = b.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
throwIfZero(typename NumberTraits::ToInteger<A>::Type(b[i]));
|
||||
c[i] = typename NumberTraits::ToInteger<A>::Type(a)
|
||||
% typename NumberTraits::ToInteger<A>::Type(b[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void constant_constant(A a, B b, ResultType & c)
|
||||
{
|
||||
throwIfZero(typename NumberTraits::ToInteger<A>::Type(b));
|
||||
c = typename NumberTraits::ToInteger<A>::Type(a)
|
||||
return typename NumberTraits::ToInteger<A>::Type(a)
|
||||
% typename NumberTraits::ToInteger<A>::Type(b);
|
||||
}
|
||||
};
|
||||
@ -245,39 +149,9 @@ struct BitwiseAndImpl
|
||||
{
|
||||
typedef typename NumberTraits::ResultOfBitwise<A, B>::Type ResultType;
|
||||
|
||||
static void vector_vector(const std::vector<A> & a, const std::vector<B> & b, std::vector<ResultType> & c)
|
||||
static inline ResultType apply(A a, B b)
|
||||
{
|
||||
size_t size = a.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
c[i] = static_cast<ResultType>(a[i])
|
||||
& static_cast<ResultType>(b[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void vector_constant(const std::vector<A> & a, B b, std::vector<ResultType> & c)
|
||||
{
|
||||
size_t size = a.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
c[i] = static_cast<ResultType>(a[i])
|
||||
& static_cast<ResultType>(b);
|
||||
}
|
||||
}
|
||||
|
||||
static void constant_vector(A a, const std::vector<B> & b, std::vector<ResultType> & c)
|
||||
{
|
||||
size_t size = b.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
c[i] = static_cast<ResultType>(a)
|
||||
& static_cast<ResultType>(b[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void constant_constant(A a, B b, ResultType & c)
|
||||
{
|
||||
c = static_cast<ResultType>(a)
|
||||
return static_cast<ResultType>(a)
|
||||
& static_cast<ResultType>(b);
|
||||
}
|
||||
};
|
||||
@ -287,40 +161,22 @@ struct BitwiseOrImpl
|
||||
{
|
||||
typedef typename NumberTraits::ResultOfBitwise<A, B>::Type ResultType;
|
||||
|
||||
static void vector_vector(const std::vector<A> & a, const std::vector<B> & b, std::vector<ResultType> & c)
|
||||
static inline ResultType apply(A a, B b)
|
||||
{
|
||||
size_t size = a.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
c[i] = static_cast<ResultType>(a[i])
|
||||
| static_cast<ResultType>(b[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void vector_constant(const std::vector<A> & a, B b, std::vector<ResultType> & c)
|
||||
{
|
||||
size_t size = a.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
c[i] = static_cast<ResultType>(a[i])
|
||||
return static_cast<ResultType>(a)
|
||||
| static_cast<ResultType>(b);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static void constant_vector(A a, const std::vector<B> & b, std::vector<ResultType> & c)
|
||||
template<typename A, typename B>
|
||||
struct BitwiseXorImpl
|
||||
{
|
||||
size_t size = b.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
c[i] = static_cast<ResultType>(a)
|
||||
| static_cast<ResultType>(b[i]);
|
||||
}
|
||||
}
|
||||
typedef typename NumberTraits::ResultOfBitwise<A, B>::Type ResultType;
|
||||
|
||||
static void constant_constant(A a, B b, ResultType & c)
|
||||
static inline ResultType apply(A a, B b)
|
||||
{
|
||||
c = static_cast<ResultType>(a)
|
||||
| static_cast<ResultType>(b);
|
||||
return static_cast<ResultType>(a)
|
||||
^ static_cast<ResultType>(b);
|
||||
}
|
||||
};
|
||||
|
||||
@ -329,21 +185,26 @@ struct NegateImpl
|
||||
{
|
||||
typedef typename NumberTraits::ResultOfNegate<A>::Type ResultType;
|
||||
|
||||
static void vector(const std::vector<A> & a, std::vector<ResultType> & c)
|
||||
static inline ResultType apply(A a)
|
||||
{
|
||||
size_t size = a.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
c[i] = -a[i];
|
||||
return -a;
|
||||
}
|
||||
};
|
||||
|
||||
static void constant(A a, ResultType & c)
|
||||
template<typename A>
|
||||
struct BitwiseNotImpl
|
||||
{
|
||||
c = -a;
|
||||
typedef typename NumberTraits::ResultOfBitwiseNot<A>::Type ResultType;
|
||||
|
||||
static inline ResultType apply(A a)
|
||||
{
|
||||
return ~static_cast<ResultType>(a);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <template <typename, typename> class Impl, typename Name>
|
||||
|
||||
template <template <typename, typename> class Op, typename Name>
|
||||
class FunctionBinaryArithmetic : public IFunction
|
||||
{
|
||||
private:
|
||||
@ -353,7 +214,7 @@ private:
|
||||
if (dynamic_cast<const T1 *>(&*arguments[1]))
|
||||
{
|
||||
type_res = new typename DataTypeFromFieldType<
|
||||
typename Impl<typename T0::FieldType, typename T1::FieldType>::ResultType>::Type;
|
||||
typename Op<typename T0::FieldType, typename T1::FieldType>::ResultType>::Type;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -388,27 +249,27 @@ private:
|
||||
{
|
||||
if (ColumnVector<T1> * col_right = dynamic_cast<ColumnVector<T1> *>(&*block.getByPosition(arguments[1]).column))
|
||||
{
|
||||
typedef typename Impl<T0, T1>::ResultType ResultType;
|
||||
typedef typename Op<T0, T1>::ResultType ResultType;
|
||||
|
||||
ColumnVector<ResultType> * col_res = new ColumnVector<ResultType>;
|
||||
block.getByPosition(result).column = col_res;
|
||||
|
||||
typename ColumnVector<ResultType>::Container_t & vec_res = col_res->getData();
|
||||
vec_res.resize(col_left->getData().size());
|
||||
Impl<T0, T1>::vector_vector(col_left->getData(), col_right->getData(), vec_res);
|
||||
BinaryOperationImpl<T0, T1, Op<T0, T1> >::vector_vector(col_left->getData(), col_right->getData(), vec_res);
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (ColumnConst<T1> * col_right = dynamic_cast<ColumnConst<T1> *>(&*block.getByPosition(arguments[1]).column))
|
||||
{
|
||||
typedef typename Impl<T0, T1>::ResultType ResultType;
|
||||
typedef typename Op<T0, T1>::ResultType ResultType;
|
||||
|
||||
ColumnVector<ResultType> * col_res = new ColumnVector<ResultType>;
|
||||
block.getByPosition(result).column = col_res;
|
||||
|
||||
typename ColumnVector<ResultType>::Container_t & vec_res = col_res->getData();
|
||||
vec_res.resize(col_left->getData().size());
|
||||
Impl<T0, T1>::vector_constant(col_left->getData(), col_right->getData(), vec_res);
|
||||
BinaryOperationImpl<T0, T1, Op<T0, T1> >::vector_constant(col_left->getData(), col_right->getData(), vec_res);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -421,23 +282,23 @@ private:
|
||||
{
|
||||
if (ColumnVector<T1> * col_right = dynamic_cast<ColumnVector<T1> *>(&*block.getByPosition(arguments[1]).column))
|
||||
{
|
||||
typedef typename Impl<T0, T1>::ResultType ResultType;
|
||||
typedef typename Op<T0, T1>::ResultType ResultType;
|
||||
|
||||
ColumnVector<ResultType> * col_res = new ColumnVector<ResultType>;
|
||||
block.getByPosition(result).column = col_res;
|
||||
|
||||
typename ColumnVector<ResultType>::Container_t & vec_res = col_res->getData();
|
||||
vec_res.resize(col_left->size());
|
||||
Impl<T0, T1>::constant_vector(col_left->getData(), col_right->getData(), vec_res);
|
||||
BinaryOperationImpl<T0, T1, Op<T0, T1> >::constant_vector(col_left->getData(), col_right->getData(), vec_res);
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (ColumnConst<T1> * col_right = dynamic_cast<ColumnConst<T1> *>(&*block.getByPosition(arguments[1]).column))
|
||||
{
|
||||
typedef typename Impl<T0, T1>::ResultType ResultType;
|
||||
typedef typename Op<T0, T1>::ResultType ResultType;
|
||||
|
||||
ResultType res = 0;
|
||||
Impl<T0, T1>::constant_constant(col_left->getData(), col_right->getData(), res);
|
||||
BinaryOperationImpl<T0, T1, Op<T0, T1> >::constant_constant(col_left->getData(), col_right->getData(), res);
|
||||
|
||||
ColumnConst<ResultType> * col_res = new ColumnConst<ResultType>(col_left->size(), res);
|
||||
block.getByPosition(result).column = col_res;
|
||||
@ -544,7 +405,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
template <template <typename> class Impl, typename Name>
|
||||
template <template <typename> class Op, typename Name>
|
||||
class FunctionUnaryArithmetic : public IFunction
|
||||
{
|
||||
private:
|
||||
@ -554,7 +415,7 @@ private:
|
||||
if (dynamic_cast<const T0 *>(&*arguments[0]))
|
||||
{
|
||||
result = new typename DataTypeFromFieldType<
|
||||
typename Impl<typename T0::FieldType>::ResultType>::Type;
|
||||
typename Op<typename T0::FieldType>::ResultType>::Type;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -565,23 +426,23 @@ private:
|
||||
{
|
||||
if (ColumnVector<T0> * col = dynamic_cast<ColumnVector<T0> *>(&*block.getByPosition(arguments[0]).column))
|
||||
{
|
||||
typedef typename Impl<T0>::ResultType ResultType;
|
||||
typedef typename Op<T0>::ResultType ResultType;
|
||||
|
||||
ColumnVector<ResultType> * col_res = new ColumnVector<ResultType>;
|
||||
block.getByPosition(result).column = col_res;
|
||||
|
||||
typename ColumnVector<ResultType>::Container_t & vec_res = col_res->getData();
|
||||
vec_res.resize(col->getData().size());
|
||||
Impl<T0>::vector(col->getData(), vec_res);
|
||||
UnaryOperationImpl<T0, Op<T0> >::vector(col->getData(), vec_res);
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (ColumnConst<T0> * col = dynamic_cast<ColumnConst<T0> *>(&*block.getByPosition(arguments[0]).column))
|
||||
{
|
||||
typedef typename Impl<T0>::ResultType ResultType;
|
||||
typedef typename Op<T0>::ResultType ResultType;
|
||||
|
||||
ResultType res = 0;
|
||||
Impl<T0>::constant(col->getData(), res);
|
||||
UnaryOperationImpl<T0, Op<T0> >::constant(col->getData(), res);
|
||||
|
||||
ColumnConst<ResultType> * col_res = new ColumnConst<ResultType>(col->size(), res);
|
||||
block.getByPosition(result).column = col_res;
|
||||
@ -651,9 +512,11 @@ struct NameMultiply { static const char * get() { return "multiply"; } };
|
||||
struct NameDivideFloating { static const char * get() { return "divide"; } };
|
||||
struct NameDivideIntegral { static const char * get() { return "intDiv"; } };
|
||||
struct NameModulo { static const char * get() { return "modulo"; } };
|
||||
struct NameNegate { static const char * get() { return "negate"; } };
|
||||
struct NameBitwiseAnd { static const char * get() { return "bitwiseAnd"; } };
|
||||
struct NameBitwiseOr { static const char * get() { return "bitwiseOr"; } };
|
||||
struct NameNegate { static const char * get() { return "negate"; } };
|
||||
struct NameBitwiseXor { static const char * get() { return "bitwiseXor"; } };
|
||||
struct NameBitwiseNot { static const char * get() { return "bitwiseNot"; } };
|
||||
|
||||
typedef FunctionBinaryArithmetic<PlusImpl, NamePlus> FunctionPlus;
|
||||
typedef FunctionBinaryArithmetic<MinusImpl, NameMinus> FunctionMinus;
|
||||
@ -661,9 +524,12 @@ typedef FunctionBinaryArithmetic<MultiplyImpl, NameMultiply> FunctionMultipl
|
||||
typedef FunctionBinaryArithmetic<DivideFloatingImpl, NameDivideFloating> FunctionDivideFloating;
|
||||
typedef FunctionBinaryArithmetic<DivideIntegralImpl, NameDivideIntegral> FunctionDivideIntegral;
|
||||
typedef FunctionBinaryArithmetic<ModuloImpl, NameModulo> FunctionModulo;
|
||||
typedef FunctionUnaryArithmetic<NegateImpl, NameNegate> FunctionNegate;
|
||||
typedef FunctionBinaryArithmetic<BitwiseAndImpl, NameBitwiseAnd> FunctionBitwiseAnd;
|
||||
typedef FunctionBinaryArithmetic<BitwiseOrImpl, NameBitwiseOr> FunctionBitwiseOr;
|
||||
typedef FunctionUnaryArithmetic<NegateImpl, NameNegate> FunctionNegate;
|
||||
typedef FunctionBinaryArithmetic<BitwiseXorImpl, NameBitwiseXor> FunctionBitwiseXor;
|
||||
typedef FunctionUnaryArithmetic<BitwiseNotImpl, NameBitwiseNot> FunctionBitwiseNot;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -164,6 +164,14 @@ namespace NumberTraits
|
||||
typename Traits<B>::Bits>::type>::type>::Type Type;
|
||||
};
|
||||
|
||||
template <typename A> struct ResultOfBitwiseNot
|
||||
{
|
||||
typedef typename Construct<
|
||||
typename Traits<A>::Sign,
|
||||
Integer,
|
||||
typename Traits<A>::Bits>::Type Type;
|
||||
};
|
||||
|
||||
/** Перед применением оператора % и побитовых операций, операнды приводятся к целым числам. */
|
||||
template <typename A> struct ToInteger
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user