diff options
| author | bors <bors@rust-lang.org> | 2013-07-29 14:01:24 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-07-29 14:01:24 -0700 |
| commit | d34016d1098bbd5e74fe18b99c4222b4fe709087 (patch) | |
| tree | dbd2700988d03b0781e3f381a4c5a98c9eac78fd /src/libstd | |
| parent | 2830d7d0135f188260f1762e6a47c347e9a603e2 (diff) | |
| parent | 11aad20cf879f508a339c2af2bad901446f4fb3a (diff) | |
| download | rust-d34016d1098bbd5e74fe18b99c4222b4fe709087.tar.gz rust-d34016d1098bbd5e74fe18b99c4222b4fe709087.zip | |
auto merge of #8109 : blake2-ppc/rust/extern-fn-clone, r=thestinger
Implement Clone and DeepClone for functions with 0 to 8 arguments. `extern fn()` is implicitly copyable so it's simple, except there is no way to implement it generically over #n function arguments. Allows deriving of Clone on structs containing `extern "Rust" fn`.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/clone.rs | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/libstd/clone.rs b/src/libstd/clone.rs index d7220fdeb60..bd5bfb197b2 100644 --- a/src/libstd/clone.rs +++ b/src/libstd/clone.rs @@ -97,6 +97,26 @@ clone_impl!(()) clone_impl!(bool) clone_impl!(char) +macro_rules! extern_fn_clone( + ($($A:ident),*) => ( + impl<$($A,)* ReturnType> Clone for extern "Rust" fn($($A),*) -> ReturnType { + /// Return a copy of a function pointer + #[inline] + fn clone(&self) -> extern "Rust" 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) + /// A trait distinct from `Clone` which represents "deep copies" of things like /// managed boxes which would otherwise not be copied. pub trait DeepClone { @@ -157,6 +177,26 @@ deep_clone_impl!(()) deep_clone_impl!(bool) deep_clone_impl!(char) +macro_rules! extern_fn_deep_clone( + ($($A:ident),*) => ( + impl<$($A,)* ReturnType> DeepClone for extern "Rust" fn($($A),*) -> ReturnType { + /// Return a copy of a function pointer + #[inline] + fn deep_clone(&self) -> extern "Rust" fn($($A),*) -> ReturnType { *self } + } + ) +) + +extern_fn_deep_clone!() +extern_fn_deep_clone!(A) +extern_fn_deep_clone!(A, B) +extern_fn_deep_clone!(A, B, C) +extern_fn_deep_clone!(A, B, C, D) +extern_fn_deep_clone!(A, B, C, D, E) +extern_fn_deep_clone!(A, B, C, D, E, F) +extern_fn_deep_clone!(A, B, C, D, E, F, G) +extern_fn_deep_clone!(A, B, C, D, E, F, G, H) + #[test] fn test_owned_clone() { let a = ~5i; @@ -195,3 +235,21 @@ fn test_borrowed_clone() { let z: &int = (&y).clone(); assert_eq!(*z, 5); } + +#[test] +fn test_extern_fn_clone() { + trait Empty {} + impl Empty for int {} + + fn test_fn_a() -> float { 1.0 } + fn test_fn_b<T: Empty>(x: T) -> T { x } + fn test_fn_c(_: int, _: float, _: ~[int], _: int, _: int, _: int) {} + + let _ = test_fn_a.clone(); + let _ = test_fn_b::<int>.clone(); + let _ = test_fn_c.clone(); + + let _ = test_fn_a.deep_clone(); + let _ = test_fn_b::<int>.deep_clone(); + let _ = test_fn_c.deep_clone(); +} |
