Created
August 9, 2021 07:05
-
-
Save sundy-li/263b13a0f0beededb8954e4342a42281 to your computer and use it in GitHub Desktop.
rust-const-generics
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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