From bc7c4304ab2af12e782945f139eb73e4842b9d68 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 13 Sep 2015 18:11:10 +0300 Subject: [PATCH] Implement more traits for function pointers --- src/libcore/clone.rs | 42 ------------------- src/libcore/ptr.rs | 98 ++++++++++++++++++++++++++++++++------------ 2 files changed, 71 insertions(+), 69 deletions(-) diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs index a13160b3a19ee..979ddd454121d 100644 --- a/src/libcore/clone.rs +++ b/src/libcore/clone.rs @@ -86,45 +86,3 @@ clone_impl! { f64 } clone_impl! { () } clone_impl! { bool } clone_impl! { char } - -macro_rules! extern_fn_clone { - ($($A:ident),*) => ( - #[stable(feature = "rust1", since = "1.0.0")] - impl<$($A,)* ReturnType> Clone for extern "Rust" fn($($A),*) -> ReturnType { - /// Returns a copy of a function pointer. - #[inline] - fn clone(&self) -> extern "Rust" fn($($A),*) -> ReturnType { *self } - } - - #[stable(feature = "rust1", since = "1.0.0")] - impl<$($A,)* ReturnType> Clone for extern "C" fn($($A),*) -> ReturnType { - /// Returns a copy of a function pointer. - #[inline] - fn clone(&self) -> extern "C" fn($($A),*) -> ReturnType { *self } - } - - #[stable(feature = "rust1", since = "1.0.0")] - impl<$($A,)* ReturnType> Clone for unsafe extern "Rust" fn($($A),*) -> ReturnType { - /// Returns a copy of a function pointer. - #[inline] - fn clone(&self) -> unsafe extern "Rust" fn($($A),*) -> ReturnType { *self } - } - - #[stable(feature = "rust1", since = "1.0.0")] - impl<$($A,)* ReturnType> Clone for unsafe extern "C" fn($($A),*) -> ReturnType { - /// Returns a copy of a function pointer. - #[inline] - fn clone(&self) -> unsafe extern "C" fn($($A),*) -> ReturnType { *self } - } - ) -} - -extern_fn_clone! {} -extern_fn_clone! { A } -extern_fn_clone! { A, B } -extern_fn_clone! { A, B, C } -extern_fn_clone! { A, B, C, D } -extern_fn_clone! { A, B, C, D, E } -extern_fn_clone! { A, B, C, D, E, F } -extern_fn_clone! { A, B, C, D, E, F, G } -extern_fn_clone! { A, B, C, D, E, F, G, H } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 83bdaf0923e80..406a5dffdb084 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -20,6 +20,7 @@ use clone::Clone; use intrinsics; use ops::Deref; use fmt; +use hash; use option::Option::{self, Some, None}; use marker::{PhantomData, Send, Sized, Sync}; use mem; @@ -308,40 +309,83 @@ impl Clone for *mut T { } } -// Equality for extern "C" fn pointers -mod externfnpointers { - use cmp::PartialEq; +// Impls for function pointers +macro_rules! fnptr_impls_safety_abi { + ($FnTy: ty, $($Arg: ident),*) => { + #[stable(feature = "rust1", since = "1.0.0")] + impl Clone for $FnTy { + #[inline] + fn clone(&self) -> Self { + *self + } + } - #[stable(feature = "rust1", since = "1.0.0")] - impl<_R> PartialEq for extern "C" fn() -> _R { - #[inline] - fn eq(&self, other: &extern "C" fn() -> _R) -> bool { - let self_ = *self as usize; - let other_ = *other as usize; - self_ == other_ + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl PartialEq for $FnTy { + #[inline] + fn eq(&self, other: &Self) -> bool { + *self as usize == *other as usize + } } - } - macro_rules! fnptreq { - ($($p:ident),*) => { - #[stable(feature = "rust1", since = "1.0.0")] - impl<_R,$($p),*> PartialEq for extern "C" fn($($p),*) -> _R { - #[inline] - fn eq(&self, other: &extern "C" fn($($p),*) -> _R) -> bool { - let self_ = *self as usize; - - let other_ = *other as usize; - self_ == other_ - } + + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl Eq for $FnTy {} + + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl PartialOrd for $FnTy { + #[inline] + fn partial_cmp(&self, other: &Self) -> Option { + (*self as usize).partial_cmp(&(*other as usize)) + } + } + + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl Ord for $FnTy { + #[inline] + fn cmp(&self, other: &Self) -> Ordering { + (*self as usize).cmp(&(*other as usize)) + } + } + + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl hash::Hash for $FnTy { + fn hash(&self, state: &mut HH) { + state.write_usize(*self as usize) + } + } + + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl fmt::Pointer for $FnTy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Pointer::fmt(&(*self as *const ()), f) + } + } + + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl fmt::Debug for $FnTy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Pointer::fmt(&(*self as *const ()), f) } } } - fnptreq! { A } - fnptreq! { A,B } - fnptreq! { A,B,C } - fnptreq! { A,B,C,D } - fnptreq! { A,B,C,D,E } } +macro_rules! fnptr_impls_args { + ($($Arg: ident),*) => { + fnptr_impls_safety_abi! { extern "Rust" fn($($Arg),*) -> Ret, $($Arg),* } + fnptr_impls_safety_abi! { extern "C" fn($($Arg),*) -> Ret, $($Arg),* } + fnptr_impls_safety_abi! { unsafe extern "Rust" fn($($Arg),*) -> Ret, $($Arg),* } + fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),*) -> Ret, $($Arg),* } + } +} + +fnptr_impls_args! { } +fnptr_impls_args! { A } +fnptr_impls_args! { A, B } +fnptr_impls_args! { A, B, C } +fnptr_impls_args! { A, B, C, D } +fnptr_impls_args! { A, B, C, D, E } + // Comparison for pointers #[stable(feature = "rust1", since = "1.0.0")] impl Ord for *const T {