1 | //! Platform-independent platform abstraction |
2 | //! |
3 | //! This is the platform-independent portion of the standard library's |
4 | //! platform abstraction layer, whereas `std::sys` is the |
5 | //! platform-specific portion. |
6 | //! |
7 | //! The relationship between `std::sys_common`, `std::sys` and the |
8 | //! rest of `std` is complex, with dependencies going in all |
9 | //! directions: `std` depending on `sys_common`, `sys_common` |
10 | //! depending on `sys`, and `sys` depending on `sys_common` and `std`. |
11 | //! This is because `sys_common` not only contains platform-independent code, |
12 | //! but also code that is shared between the different platforms in `sys`. |
13 | //! Ideally all that shared code should be moved to `sys::common`, |
14 | //! and the dependencies between `std`, `sys_common` and `sys` all would form a dag. |
15 | //! Progress on this is tracked in #84187. |
16 | |
17 | #![allow (missing_docs)] |
18 | #![allow (missing_debug_implementations)] |
19 | |
20 | #[cfg (test)] |
21 | mod tests; |
22 | |
23 | pub mod backtrace; |
24 | pub mod fs; |
25 | pub mod io; |
26 | pub mod lazy_box; |
27 | pub mod process; |
28 | pub mod thread_local_dtor; |
29 | pub mod thread_parking; |
30 | pub mod wstr; |
31 | pub mod wtf8; |
32 | |
33 | cfg_if::cfg_if! { |
34 | if #[cfg(target_os = "windows" )] { |
35 | pub use crate::sys::thread_local_key; |
36 | } else { |
37 | pub mod thread_local_key; |
38 | } |
39 | } |
40 | |
41 | cfg_if::cfg_if! { |
42 | if #[cfg(any( |
43 | all(unix, not(target_os = "l4re" )), |
44 | windows, |
45 | target_os = "hermit" , |
46 | target_os = "solid_asp3" |
47 | ))] { |
48 | pub mod net; |
49 | } else { |
50 | pub use crate::sys::net; |
51 | } |
52 | } |
53 | |
54 | // common error constructors |
55 | |
56 | /// A trait for viewing representations from std types |
57 | #[doc (hidden)] |
58 | #[allow (dead_code)] // not used on all platforms |
59 | pub trait AsInner<Inner: ?Sized> { |
60 | fn as_inner(&self) -> &Inner; |
61 | } |
62 | |
63 | /// A trait for viewing representations from std types |
64 | #[doc (hidden)] |
65 | #[allow (dead_code)] // not used on all platforms |
66 | pub trait AsInnerMut<Inner: ?Sized> { |
67 | fn as_inner_mut(&mut self) -> &mut Inner; |
68 | } |
69 | |
70 | /// A trait for extracting representations from std types |
71 | #[doc (hidden)] |
72 | pub trait IntoInner<Inner> { |
73 | fn into_inner(self) -> Inner; |
74 | } |
75 | |
76 | /// A trait for creating std types from internal representations |
77 | #[doc (hidden)] |
78 | pub trait FromInner<Inner> { |
79 | fn from_inner(inner: Inner) -> Self; |
80 | } |
81 | |
82 | // Computes (value*numer)/denom without overflow, as long as both |
83 | // (numer*denom) and the overall result fit into i64 (which is the case |
84 | // for our time conversions). |
85 | #[allow (dead_code)] // not used on all platforms |
86 | pub fn mul_div_u64(value: u64, numer: u64, denom: u64) -> u64 { |
87 | let q: u64 = value / denom; |
88 | let r: u64 = value % denom; |
89 | // Decompose value as (value/denom*denom + value%denom), |
90 | // substitute into (value*numer)/denom and simplify. |
91 | // r < denom, so (denom*numer) is the upper bound of (r*numer) |
92 | q * numer + r * numer / denom |
93 | } |
94 | |