dx_core 0.3.0

Core functionality required by all the dx-rs crates. dx-rs is a DirectX wrapper for rust.
Documentation
/*
 * Copyright 2015 Joshua R. Rodgers
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#![macro_use]

pub trait EnumFlags<TFlag: ::std::ops::BitOr<TFlag> + ::std::ops::BitAnd<TFlag> + ::std::ops::BitXor<TFlag>> {
    fn has_flag<T: Into<TFlag>>(self, flag: T) -> bool;
    fn raw_value(self) -> i32;
}

#[macro_export]
macro_rules! enum_flags {
    ($name:ident : $flagsName:ident => $($flag:ident = $value:expr),+) => {
        #[repr(C)]
        #[derive(Debug, Copy, Clone, Hash)]
        pub enum $flagsName {
            $(
                $flag = $value
            ),+
        }

        #[repr(C)]
        #[derive(Debug, Copy, Clone, Hash)]
        pub struct $name(i32);

        impl $name {
            #[inline]
            fn none() -> $name {
                $name(0)
            }
        }

        impl Into<$name> for $flagsName {
            #[inline]
            fn into(self) -> $name {
                $name(self as i32)
            }
        }

        impl $crate::util::EnumFlags<$name> for $name {
            fn has_flag<T: Into<$name>>(self, flag: T) -> bool {
                let rhs: $name = flag.into();

                (self.0 & rhs.0) == rhs.0
            }

            fn raw_value(self) -> i32 {
                self.0
            }
        }

        impl<T: Into<$name>> ::std::ops::BitOr<T> for $name {
            type Output = $name;

            #[inline]
            fn bitor(self, rhs: T) -> $name {
                $name(self.0 | rhs.into().0)
            }
        }

        impl<T: Into<$name>> ::std::ops::BitOr<T> for $flagsName {
            type Output = $name;

            #[inline]
            fn bitor(self, rhs: T) -> $name {
                $name(Into::<$name>::into(self).0 | rhs.into().0)
            }
        }

        impl<T: Into<$name>> ::std::ops::BitXor<T> for $name {
            type Output = $name;

            #[inline]
            fn bitxor(self, rhs: T) -> $name {
                $name(self.0 ^ rhs.into().0)
            }
        }

        impl<T: Into<$name>> ::std::ops::BitXor<T> for $flagsName {
            type Output = $name;

            #[inline]
            fn bitxor(self, rhs: T) -> $name {
                $name(Into::<$name>::into(self).0 ^ rhs.into().0)
            }
        }

        impl<T: Into<$name>> ::std::ops::BitAnd<T> for $name {
            type Output = $name;

            #[inline]
            fn bitand(self, rhs: T) -> $name {
                $name(self.0 & rhs.into().0)
            }
        }

        impl<T: Into<$name>> ::std::ops::BitAnd<T> for $flagsName {
            type Output = $name;

            #[inline]
            fn bitand(self, rhs: T) -> $name {
                $name(Into::<$name>::into(self).0 & rhs.into().0)
            }
        }

        impl<T: Into<$name> + Copy> ::std::cmp::PartialEq<T> for $name {
            #[inline]
            fn eq(&self, other: &T) -> bool {
                Into::<$name>::into(*self).0 == Into::<$name>::into(*other).0
            }

            #[inline]
            fn ne(&self, other: &T) -> bool {
                Into::<$name>::into(*self).0 != Into::<$name>::into(*other).0
            }
        }

        impl ::std::cmp::Eq for $name {}

        impl<T: Into<$name> + Copy> ::std::cmp::PartialEq<T> for $flagsName {
            #[inline]
            fn eq(&self, other: &T) -> bool {
                Into::<$name>::into(*self).0 == Into::<$name>::into(*other).0
            }

            #[inline]
            fn ne(&self, other: &T) -> bool {
                Into::<$name>::into(*self).0 != Into::<$name>::into(*other).0
            }
        }

        impl ::std::cmp::Eq for $flagsName {}
    }
}