Skip to content

Instantly share code, notes, and snippets.

@sundy-li
Created August 9, 2021 07:05
Show Gist options
  • Save sundy-li/263b13a0f0beededb8954e4342a42281 to your computer and use it in GitHub Desktop.
Save sundy-li/263b13a0f0beededb8954e4342a42281 to your computer and use it in GitHub Desktop.
rust-const-generics
// Copyright 2020-2021 The Datafuse Authors.
//
// SPDX-License-Identifier: Apache-2.0.
mod modulo;
use std::marker::PhantomData;
use crate::prelude::*;
use crate::DFNumericType;
trait IDataType {
type Type: DFNumericType;
}
struct Condition<A, B, const FLAG: bool> {
a: PhantomData<A>,
b: PhantomData<B>,
}
impl<A, B> IDataType for Condition<A, B, true>
where
A: IDataType,
B: IDataType,
{
type Type = A::Type;
}
impl<A, B> IDataType for Condition<A, B, false>
where
A: IDataType,
B: IDataType,
{
type Type = B::Type;
}
trait ISize {
const SIZE: usize;
}
impl<A, B> ISize for Condition<A, B, true>
where
A: DFNumericType,
B: DFNumericType,
{
const SIZE: usize = <A as DFNumericType>::SIZE;
}
impl<A, B> ISize for Condition<A, B, false>
where
A: DFNumericType,
B: DFNumericType,
{
const SIZE: usize = <B as DFNumericType>::SIZE;
}
struct Construct<const IS_SIGN: bool, const IS_FLOATING: bool, const SIZE: usize>;
impl IDataType for Construct<false, false, 1> {
type Type = UInt8Type;
}
impl IDataType for Construct<false, false, 2> {
type Type = UInt16Type;
}
impl IDataType for Construct<false, false, 4> {
type Type = UInt32Type;
}
impl IDataType for Construct<false, false, 8> {
type Type = UInt64Type;
}
// impl IDataType for Construct<false, false, 16> {
// type Type = UInt128Type;
// }
// impl IDataType for Construct<false, false, 32> {
// type Type = UInt256Type;
// }
impl IDataType for Construct<false, true, 1> {
type Type = Float32Type;
}
impl IDataType for Construct<false, true, 2> {
type Type = Float32Type;
}
impl IDataType for Construct<false, true, 4> {
type Type = Float32Type;
}
impl IDataType for Construct<false, true, 8> {
type Type = Float64Type;
}
impl IDataType for Construct<true, false, 1> {
type Type = Int8Type;
}
impl IDataType for Construct<true, false, 2> {
type Type = Int16Type;
}
impl IDataType for Construct<true, false, 4> {
type Type = Int32Type;
}
impl IDataType for Construct<true, false, 8> {
type Type = Int64Type;
}
// impl IDataType for Construct<true, false, 16> {
// type Type = Int128Type;
// }
// impl IDataType for Construct<true, false, 32> {
// type Type = Int256Type;
// }
impl IDataType for Construct<true, true, 1> {
type Type = Float32Type;
}
impl IDataType for Construct<true, true, 2> {
type Type = Float32Type;
}
impl IDataType for Construct<true, true, 4> {
type Type = Float32Type;
}
impl IDataType for Construct<true, true, 8> {
type Type = Float64Type;
}
#[cfg(test)]
mod test {
use super::IDataType;
use super::ResultOfModulo;
use super::UInt8Type;
#[test]
fn aa() {
type C = <ResultOfModulo<UInt8Type, UInt8Type> as IDataType>::Type;
}
}
// Copyright 2020-2021 The Datafuse Authors.
//
// SPDX-License-Identifier: Apache-2.0.
use std::marker::PhantomData;
use super::Condition;
use super::Construct;
use super::IDataType;
use crate::prelude::*;
struct ResultOfModulo<A, B> {
a: PhantomData<A>,
b: PhantomData<B>,
}
impl<A, B> ResultOfModulo<A, B>
where
A: DFNumericType,
B: DFNumericType,
{
}
trait IModuloDataType {
const SIGN: bool;
const SIZE: usize;
type Type0: DFNumericType;
type Type: DFNumericType;
}
// template <typename A, typename B> struct ResultOfModulo
// {
// static constexpr bool result_is_signed = is_signed_v<A>;
// /// If modulo of division can yield negative number, we need larger type to accommodate it.
// /// Example: toInt32(-199) % toUInt8(200) will return -199 that does not fit in Int8, only in Int16.
// static constexpr size_t size_of_result = result_is_signed ? nextSize(sizeof(B)) : sizeof(B);
// using Type0 = typename Construct<result_is_signed, false, size_of_result>::Type;
// using Type = std::conditional_t<std::is_floating_point_v<A> || std::is_floating_point_v<B>, Float64, Type0>;
// };
impl<A, B> IModuloDataType for ResultOfModulo<A, B>
where
A: DFNumericType,
B: DFNumericType,
{
// A::SIGN
// SIZE_OF_RESULT : Condition<A, B, A::SIGN>
// Type0: <Construct<{ <A as DFNumericType>::SIGN }, false, 4> as IDataType>::Type;
const SIGN: bool = A::SIGN;
const SIZE: usize = if A::SIGN {
if A::SIZE <= 8 {
A::SIZE * 2
} else {
8
}
} else {
B::SIZE
};
type Type0 = <Construct<{ <A as DFNumericType>::SIGN }, true, 4> as IDataType>::Type;
type Type = <Construct<{ <UInt8Type as DFNumericType>::SIGN }, true, 4> as IDataType>::Type;
}
//UInt16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment