Skip to content

Commit

Permalink
Implement more traits for function pointers
Browse files Browse the repository at this point in the history
  • Loading branch information
petrochenkov committed Sep 13, 2015
1 parent d89a10b commit bc7c430
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 69 deletions.
42 changes: 0 additions & 42 deletions src/libcore/clone.rs
Expand Up @@ -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 }
98 changes: 71 additions & 27 deletions src/libcore/ptr.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -308,40 +309,83 @@ impl<T: ?Sized> 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<Ret, $($Arg),*> 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<Ret, $($Arg),*> 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<Ret, $($Arg),*> Eq for $FnTy {}

#[stable(feature = "fnptr_impls", since = "1.4.0")]
impl<Ret, $($Arg),*> PartialOrd for $FnTy {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
(*self as usize).partial_cmp(&(*other as usize))
}
}

#[stable(feature = "fnptr_impls", since = "1.4.0")]
impl<Ret, $($Arg),*> 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<Ret, $($Arg),*> hash::Hash for $FnTy {
fn hash<HH: hash::Hasher>(&self, state: &mut HH) {
state.write_usize(*self as usize)
}
}

#[stable(feature = "fnptr_impls", since = "1.4.0")]
impl<Ret, $($Arg),*> 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<Ret, $($Arg),*> 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<T: ?Sized> Ord for *const T {
Expand Down

0 comments on commit bc7c430

Please sign in to comment.