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 memchr; |
28 | pub mod once; |
29 | pub mod process; |
30 | pub mod thread; |
31 | pub mod thread_info; |
32 | pub mod thread_local_dtor; |
33 | pub mod thread_parking; |
34 | pub mod wstr; |
35 | pub mod wtf8; |
36 | |
37 | cfg_if::cfg_if! { |
38 | if #[cfg(target_os = "windows" )] { |
39 | pub use crate::sys::thread_local_key; |
40 | } else { |
41 | pub mod thread_local_key; |
42 | } |
43 | } |
44 | |
45 | cfg_if::cfg_if! { |
46 | if #[cfg(any( |
47 | all(unix, not(target_os = "l4re" )), |
48 | windows, |
49 | target_os = "hermit" , |
50 | target_os = "solid_asp3" |
51 | ))] { |
52 | pub mod net; |
53 | } else { |
54 | pub use crate::sys::net; |
55 | } |
56 | } |
57 | |
58 | // common error constructors |
59 | |
60 | /// A trait for viewing representations from std types |
61 | #[doc (hidden)] |
62 | pub trait AsInner<Inner: ?Sized> { |
63 | fn as_inner(&self) -> &Inner; |
64 | } |
65 | |
66 | /// A trait for viewing representations from std types |
67 | #[doc (hidden)] |
68 | pub trait AsInnerMut<Inner: ?Sized> { |
69 | fn as_inner_mut(&mut self) -> &mut Inner; |
70 | } |
71 | |
72 | /// A trait for extracting representations from std types |
73 | #[doc (hidden)] |
74 | pub trait IntoInner<Inner> { |
75 | fn into_inner(self) -> Inner; |
76 | } |
77 | |
78 | /// A trait for creating std types from internal representations |
79 | #[doc (hidden)] |
80 | pub trait FromInner<Inner> { |
81 | fn from_inner(inner: Inner) -> Self; |
82 | } |
83 | |
84 | // Computes (value*numer)/denom without overflow, as long as both |
85 | // (numer*denom) and the overall result fit into i64 (which is the case |
86 | // for our time conversions). |
87 | #[allow (dead_code)] // not used on all platforms |
88 | pub fn mul_div_u64(value: u64, numer: u64, denom: u64) -> u64 { |
89 | let q: u64 = value / denom; |
90 | let r: u64 = value % denom; |
91 | // Decompose value as (value/denom*denom + value%denom), |
92 | // substitute into (value*numer)/denom and simplify. |
93 | // r < denom, so (denom*numer) is the upper bound of (r*numer) |
94 | q * numer + r * numer / denom |
95 | } |
96 | |