|
2 | 2 | //! |
3 | 3 | //! The `cpp!` macro doesn't work here, because of technical limitations it can only run one build |
4 | 4 | //! per crate. (Examples and binaries are built separately from `lib.rs`.) |
5 | | -//! To add C++ code here, use /* ... */ code comment blocks. |
| 5 | +//! To add C++ code here, use /* ... */ code comment blocks, or just skip it. |
| 6 | +//! |
| 7 | +//! ### Potential Resolutions |
| 8 | +//! |
| 9 | +//! There isn't a clear equivalent of list initializers in Rust, so if we decided the initializer |
| 10 | +//! list overloads were inexpressible in Rust, all overloads would be compatible. (And initializer |
| 11 | +//! lists could be supported using the slice or iterator overloads.) |
| 12 | +
|
| 13 | +#![feature(splat, tuple_trait, c_size_t)] |
| 14 | +#![allow(incomplete_features)] |
| 15 | +#![allow(unused_braces)] |
| 16 | + |
| 17 | +use splat_overload::overload; |
| 18 | +use std::ffi::c_size_t; |
| 19 | + |
| 20 | +/// A wrapper struct to hold the returned C++ pointer, with the `T` fake generic type. |
| 21 | +/// We also fake the C++ list pointer with a Rust vector to help with type checking. |
| 22 | +#[expect(dead_code, reason = "Incompatible overloads can't be used")] |
| 23 | +struct StdForwardListT(Vec<T>); |
| 24 | + |
| 25 | +/// Workaround for missing generic support in the `overload!` macro. |
| 26 | +type T = std::ffi::c_size_t; |
6 | 27 |
|
7 | | -fn main() { |
8 | | - const _: () = panic!("There are no failing overloads for C++ `std::forward_list` yet"); |
| 28 | +// This overload set has overloads which are incompatible when `T` is `c_size_t`. |
| 29 | +overload! { |
| 30 | + impl StdForwardListT { |
| 31 | + /// Construct a list with `count` default-constructed items. |
| 32 | + fn new(_count: c_size_t) -> StdForwardListT { |
| 33 | + todo!() |
| 34 | + } |
| 35 | + |
| 36 | + /// Construct a list filled with `count` instances of the given value. |
| 37 | + fn new(_value: T, _count: c_size_t) -> StdForwardListT { |
| 38 | + todo!() |
| 39 | + } |
| 40 | + |
| 41 | + /// Construct a list from the supplied item. |
| 42 | + /// |
| 43 | + /// ### Incompatibilities |
| 44 | + /// |
| 45 | + /// This overload has the same types as `new(count)` when `T` is `c_size_t`, but different |
| 46 | + /// semantics: |
| 47 | + /// - `new(count)` fills the list with the default value of `T` repeated`count` times. |
| 48 | + /// - `new(value)` fills the list with one instance of `value`. |
| 49 | + fn new(_value: T) -> StdForwardListT { |
| 50 | + todo!() |
| 51 | + } |
| 52 | + |
| 53 | + /// Construct a list from the supplied 2 items. |
| 54 | + /// |
| 55 | + /// ### Incompatibilities |
| 56 | + /// |
| 57 | + /// This overload has the same types as `new(value, count)` when `T` is `c_size_t`, but different |
| 58 | + /// semantics: |
| 59 | + /// - `new(value, count)` fills the list with `count` instances of `value`. |
| 60 | + /// - `new(a, b)` fills the list with two values: `a` and `b`. |
| 61 | + fn new(_a: T, _b: T) -> StdForwardListT { |
| 62 | + todo!() |
| 63 | + } |
| 64 | + } |
9 | 65 | } |
| 66 | + |
| 67 | +/// A wrapper struct to hold the returned C++ pointer, with the `U` fake generic type. |
| 68 | +/// We also fake the C++ list pointer with a Rust vector to help with type checking. |
| 69 | +#[expect(dead_code, reason = "Incompatible overloads can't be used")] |
| 70 | +struct StdForwardListU(Vec<U>); |
| 71 | + |
| 72 | +/// Workaround for missing generic support in the `overload!` macro. |
| 73 | +type U = StdForwardListU; |
| 74 | + |
| 75 | +// This overload set has overloads which are compatible, but have poor ergonomics, |
| 76 | +// when `U` is `StdForwardListU` (which is possible with some boxed types). |
| 77 | +overload! { |
| 78 | + impl StdForwardListU { |
| 79 | + /// Clone list items into a new list from a shared list reference. |
| 80 | + fn newer(_other: &StdForwardListU) -> StdForwardListU where U: Clone { |
| 81 | + todo!() |
| 82 | + } |
| 83 | + |
| 84 | + /// Move list items into a new list from a mutable list reference. |
| 85 | + fn newer(_other: &mut StdForwardListU) -> StdForwardListU { |
| 86 | + todo!() |
| 87 | + } |
| 88 | + |
| 89 | + /// Construct a list from the supplied item. |
| 90 | + /// |
| 91 | + /// ### Potential Overlap |
| 92 | + /// |
| 93 | + /// This overload has similar types to `new(&/&mut other)` when `U` is `StdForwardListU`, |
| 94 | + /// but different semantics: |
| 95 | + /// - `new(&/&mut other)` clones or moves the list items into a new list. |
| 96 | + /// - `new(value)` fills the list with one instance of `value`. |
| 97 | + /// |
| 98 | + /// Due to the references, this is technically compatible. But the ergonomics are likely |
| 99 | + /// to be poor, particularly when auto-ref and auto-deref are used. |
| 100 | + fn newer(_a: U) -> StdForwardListU { |
| 101 | + todo!() |
| 102 | + } |
| 103 | + } |
| 104 | +} |
| 105 | + |
| 106 | +/// A wrapper struct to hold the returned C++ pointer, with the `V` fake generic type. |
| 107 | +/// We also fake the C++ list pointer with a Rust vector to help with type checking. |
| 108 | +#[expect(dead_code, reason = "Incompatible overloads can't be used")] |
| 109 | +struct StdForwardListV(Vec<V>); |
| 110 | + |
| 111 | +/// Workaround for missing generic support in the `overload!` macro. |
| 112 | +/// Currently this type alias fails compilation very early due to cycle checking, but with |
| 113 | +/// generics the *possibility* of an identical impl existing is enough to make compilation fail, |
| 114 | +/// even if it can't be implemented in practice. |
| 115 | +//type V<'v> = &'v mut dyn Iterator<Item = V<'v>>; |
| 116 | +type V = Box<dyn Iterator<Item = VCycleBreaker>>; |
| 117 | +type VCycleBreaker = (); |
| 118 | + |
| 119 | +// This overload set has overloads which are incompatible when `V` is |
| 120 | +// `&mut dyn Iterator<Item = V>`. This is a contrived example, but trait solving would fail anyway. |
| 121 | +overload! { |
| 122 | + impl StdForwardListV { |
| 123 | + /// Construct a list from an iterator. |
| 124 | + fn newest(_iter: &mut dyn Iterator<Item = V>) -> StdForwardListV { |
| 125 | + todo!() |
| 126 | + } |
| 127 | + |
| 128 | + /// Construct a list from the supplied items. |
| 129 | + /// |
| 130 | + /// ### Incompatibilities |
| 131 | + /// |
| 132 | + /// This overload has the same type as `new(iter)` when `V` is |
| 133 | + /// `&mut dyn Iterator<Item = V>`, but different semantics: |
| 134 | + /// - `new(iter)` constructs a list from the items in the iterator. |
| 135 | + /// - `new(a)` constructs a list from a single item (where the item is an iterator). |
| 136 | + fn newest(_a: V) -> StdForwardListV { |
| 137 | + todo!() |
| 138 | + } |
| 139 | + } |
| 140 | +} |
| 141 | + |
| 142 | +pub fn main() {} |
0 commit comments