1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
//! `fn-ptr` is a utility crate for **introspecting** and **rewriting** function pointer types at compile time.
//!
//! It implements [`FnPtr`] for all function-pointer types:
//! - `fn(T) -> U`
//! - `unsafe fn(T) -> U`
//! - `extern "C-unwind" fn(T)`
//! - `unsafe extern "sysv64" fn() -> i32`
//!
//! ## Function pointer metadata
//!
//! [`FnPtr`] exposes metadata as associated types/consts.
//!
//! ```rust
//! use fn_ptr::{FnPtr, AbiValue};
//!
//! type F = extern "C" fn(i32, i32) -> i32;
//! assert_eq!(<F as FnPtr>::ARITY, 2);
//! assert_eq!(<F as FnPtr>::IS_SAFE, true);
//! assert_eq!(<F as FnPtr>::IS_EXTERN, true);
//! assert_eq!(<F as FnPtr>::ABI, AbiValue::C { unwind: false });
//! ```
//!
//! Ergonomic const functions are provided as well:
//!
//! ```rust
//! # type F = extern "C" fn(i32, i32) -> i32;
//! # use fn_ptr::{FnPtr, AbiValue};
//! const A: usize = fn_ptr::arity::<F>();
//! const SAFE: bool = fn_ptr::is_safe::<F>();
//! const EXT: bool = fn_ptr::is_extern::<F>();
//! const ABI: AbiValue = fn_ptr::abi::<F>();
//! ```
//!
//! ## Rewriting function-pointer types
//!
//! The crate provides type-level rewriting via traits:
//!
//! - **abi:** [`WithAbi`] / [`with_abi!`]
//! - **Safety:** [`WithSafety`] / [`with_safety!`] ([`make_safe!`], [`make_unsafe!`])
//! - **Output:** [`WithOutput`] / [`with_output!`]
//! - **Args:** [`WithArgs`] / [`with_args!`]
//!
//! ### Type-level transformations
//!
//! The macros compute a new function-pointer **type** while preserving everything else.
//!
//! ```rust
//! use fn_ptr::{with_abi, with_safety, with_output, with_args};
//!
//! type F = extern "C" fn(i32) -> i32;
//!
//! type F1 = with_abi!("sysv64", F); // extern "sysv64" fn(i32) -> i32
//! type F2 = with_safety!(unsafe, F); // unsafe extern "C" fn(i32) -> i32
//! type F3 = with_output!(u64, F); // extern "C" fn(i32) -> u64
//! type F4 = with_args!((u8, u16), F); // extern "C" fn(u8, u16) -> i32
//! ```
//!
//! ### Value-level casts
//!
//! The same transformations exist at the value level via methods on [`FnPtr`].
//! These casts are only [`transmuting`](core::mem::transmute) and do **not** the actual underlying function.
//!
//! ```rust
//! use fn_ptr::{FnPtr, abi};
//!
//! let f: fn(i32, i32) -> i32 = |a, b| a + b;
//!
//! // safety
//! let u: unsafe fn(i32, i32) -> i32 = f.as_unsafe();
//! let f2: fn(i32, i32) -> i32 = unsafe { u.as_safe() };
//!
//! // abi
//! let c: extern "C" fn(i32, i32) -> i32 = unsafe { f.with_abi::<abi!("C")>() };
//!
//! // output
//! let out: fn(i32, i32) -> u64 = unsafe { f.with_output::<u64>() };
//!
//! // args
//! let args: fn(u8, u16) -> i32 = unsafe { f.with_args::<(u8, u16)>() };
//!
//! # assert_eq!(f.addr(), f2.addr());
//! # assert_eq!(f.addr(), c.addr());
//! # assert_eq!(f.addr(), out.addr());
//! # assert_eq!(f.addr(), args.addr());
//! ```
//! ## How it works
//!
//! Implementations are generated by a large [macro](https://github.com/OpenByteDev/fn-ptr/blob/master/src/impl.rs). The rewrite macros are thin wrappers
//! over the traits [`WithAbi`], [`WithSafety`], [`WithOutput`], [`WithArgs`] (and the corresponding `*Impl` helper traits).
/// Module containing the Abi abstraction.
pub use AbiValue;
/// Module containing safety related marker types and traits.
pub use Safety;
/// Module containing abi related marker types and traits.
pub use Abi;
/// Module containing arity related marker types and traits.
pub use Arity;
/// Prelude for this crate.
pub use *;
pub use *;
pub use *;
pub use *;
/// Returns the number of arguments of a function pointer type.
pub const
/// Returns `true` for safe function pointers (`fn`).
pub const
/// Returns `true` for unsafe function pointers (`unsafe fn`).
pub const
/// Returns `true` if the function pointer uses an external abi.
pub const
/// Returns a runtime representation of the abi of the function pointer.
pub const