diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 17:39:49 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 17:39:49 +0000 |
commit | a0aa2307322cd47bbf416810ac0292925e03be87 (patch) | |
tree | 37076262a026c4b48c8a0e84f44ff9187556ca35 /rust/vendor/num-iter | |
parent | Initial commit. (diff) | |
download | suricata-a0aa2307322cd47bbf416810ac0292925e03be87.tar.xz suricata-a0aa2307322cd47bbf416810ac0292925e03be87.zip |
Adding upstream version 1:7.0.3.upstream/1%7.0.3
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'rust/vendor/num-iter')
-rw-r--r-- | rust/vendor/num-iter/.cargo-checksum.json | 1 | ||||
-rw-r--r-- | rust/vendor/num-iter/Cargo.toml | 61 | ||||
-rw-r--r-- | rust/vendor/num-iter/LICENSE-APACHE | 201 | ||||
-rw-r--r-- | rust/vendor/num-iter/LICENSE-MIT | 25 | ||||
-rw-r--r-- | rust/vendor/num-iter/README.md | 64 | ||||
-rw-r--r-- | rust/vendor/num-iter/RELEASES.md | 88 | ||||
-rw-r--r-- | rust/vendor/num-iter/build.rs | 19 | ||||
-rw-r--r-- | rust/vendor/num-iter/src/lib.rs | 734 |
8 files changed, 1193 insertions, 0 deletions
diff --git a/rust/vendor/num-iter/.cargo-checksum.json b/rust/vendor/num-iter/.cargo-checksum.json new file mode 100644 index 0000000..dfc7c4e --- /dev/null +++ b/rust/vendor/num-iter/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"66957e317ffad0ea8f4865dd5dc4cbbdfe3254df4632292731c6791189eec2ef","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"3a6e646eef8d12624d3afd96fc7515fa37c2e6572f6f88ea64afaca354fd31f1","RELEASES.md":"9f688e94ed6e0f01ae149c501b4ea65b0193724f85f3da9ee11ca06ea2fe5358","build.rs":"ade351dc146cbd66e25a8fcf8a636400b16d8497a2c1b224c99f70896561329f","src/lib.rs":"66a19ec175770b508e1bd5fa5d5442b0e75676fc7fd605c8a9aad886c7f32998"},"package":"7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"}
\ No newline at end of file diff --git a/rust/vendor/num-iter/Cargo.toml b/rust/vendor/num-iter/Cargo.toml new file mode 100644 index 0000000..d05c283 --- /dev/null +++ b/rust/vendor/num-iter/Cargo.toml @@ -0,0 +1,61 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +name = "num-iter" +version = "0.1.43" +authors = ["The Rust Project Developers"] +build = "build.rs" +exclude = [ + "/bors.toml", + "/ci/*", + "/.github/*", +] +description = "External iterators for generic mathematics" +homepage = "https://github.com/rust-num/num-iter" +documentation = "https://docs.rs/num-iter" +readme = "README.md" +keywords = [ + "mathematics", + "numerics", +] +categories = [ + "algorithms", + "science", + "no-std", +] +license = "MIT OR Apache-2.0" +repository = "https://github.com/rust-num/num-iter" + +[package.metadata.docs.rs] +features = ["std"] + +[dependencies.num-integer] +version = "0.1.42" +default-features = false + +[dependencies.num-traits] +version = "0.2.11" +default-features = false + +[build-dependencies.autocfg] +version = "1" + +[features] +default = ["std"] +i128 = [ + "num-integer/i128", + "num-traits/i128", +] +std = [ + "num-integer/std", + "num-traits/std", +] diff --git a/rust/vendor/num-iter/LICENSE-APACHE b/rust/vendor/num-iter/LICENSE-APACHE new file mode 100644 index 0000000..16fe87b --- /dev/null +++ b/rust/vendor/num-iter/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/rust/vendor/num-iter/LICENSE-MIT b/rust/vendor/num-iter/LICENSE-MIT new file mode 100644 index 0000000..39d4bdb --- /dev/null +++ b/rust/vendor/num-iter/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/rust/vendor/num-iter/README.md b/rust/vendor/num-iter/README.md new file mode 100644 index 0000000..b4511c2 --- /dev/null +++ b/rust/vendor/num-iter/README.md @@ -0,0 +1,64 @@ +# num-iter + +[![crate](https://img.shields.io/crates/v/num-iter.svg)](https://crates.io/crates/num-iter) +[![documentation](https://docs.rs/num-iter/badge.svg)](https://docs.rs/num-iter) +[![minimum rustc 1.8](https://img.shields.io/badge/rustc-1.8+-red.svg)](https://rust-lang.github.io/rfcs/2495-min-rust-version.html) +[![build status](https://github.com/rust-num/num-iter/workflows/master/badge.svg)](https://github.com/rust-num/num-iter/actions) + +Generic `Range` iterators for Rust. + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +num-iter = "0.1" +``` + +and this to your crate root: + +```rust +extern crate num_iter; +``` + +## Features + +This crate can be used without the standard library (`#![no_std]`) by disabling +the default `std` feature. Use this in `Cargo.toml`: + +```toml +[dependencies.num-iter] +version = "0.1.35" +default-features = false +``` + +There is no functional difference with and without `std` at this time, but +there may be in the future. + +Implementations for `i128` and `u128` are only available with Rust 1.26 and +later. The build script automatically detects this, but you can make it +mandatory by enabling the `i128` crate feature. + +## Releases + +Release notes are available in [RELEASES.md](RELEASES.md). + +## Compatibility + +The `num-iter` crate is tested for rustc 1.8 and greater. + +## License + +Licensed under either of + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. diff --git a/rust/vendor/num-iter/RELEASES.md b/rust/vendor/num-iter/RELEASES.md new file mode 100644 index 0000000..c164e76 --- /dev/null +++ b/rust/vendor/num-iter/RELEASES.md @@ -0,0 +1,88 @@ +# Release 0.1.43 (2022-04-26) + +- [`Range`, `RangeInclusive`, and `RangeFrom` now implement `RangeBounds`][21] + from Rust 1.28 and later. + +**Contributors**: @chrismit3s, @cuviper + +[21]: https://github.com/rust-num/num-iter/pull/21 + +# Release 0.1.42 (2020-10-29) + +- [The "i128" feature now bypasses compiler probing][20]. The build script + used to probe anyway and panic if requested support wasn't found, but + sometimes this ran into bad corner cases with `autocfg`. + +**Contributors**: @cuviper + +[20]: https://github.com/rust-num/num-iter/pull/20 + +# Release 0.1.41 (2020-06-11) + +- [The new `RangeFrom` and `RangeFromStep` iterators][18] will count from a + given starting value, without any terminating value. + +**Contributors**: @cuviper, @sollyucko + +[18]: https://github.com/rust-num/num-iter/pull/18 + +# Release 0.1.40 (2020-01-09) + +- [Updated the `autocfg` build dependency to 1.0][14]. + +**Contributors**: @cuviper, @dingelish + +[14]: https://github.com/rust-num/num-iter/pull/14 + +# Release 0.1.39 (2019-05-21) + +- [Fixed feature detection on `no_std` targets][11]. + +**Contributors**: @cuviper + +[11]: https://github.com/rust-num/num-iter/pull/11 + +# Release 0.1.38 (2019-05-20) + +- Maintenance update -- no functional changes. + +**Contributors**: @cuviper, @ignatenkobrain + +# Release 0.1.37 (2018-05-11) + +- [Support for 128-bit integers is now automatically detected and enabled.][5] + Setting the `i128` crate feature now causes the build script to panic if such + support is not detected. + +**Contributors**: @cuviper + +[5]: https://github.com/rust-num/num-iter/pull/5 + +# Release 0.1.36 (2018-05-10) + +- [The iterators are now implemented for `i128` and `u128`][7] starting with + Rust 1.26, enabled by the new `i128` crate feature. + +**Contributors**: @cuviper + +[4]: https://github.com/rust-num/num-iter/pull/4 + +# Release 0.1.35 (2018-02-06) + +- [num-iter now has its own source repository][num-356] at [rust-num/num-iter][home]. +- [There is now a `std` feature][2], enabled by default, along with the implication + that building *without* this feature makes this a `#[no_std]` crate. + - There is no difference in the API at this time. + +**Contributors**: @cuviper + +[home]: https://github.com/rust-num/num-iter +[num-356]: https://github.com/rust-num/num/pull/356 +[2]: https://github.com/rust-num/num-iter/pull/2 + + +# Prior releases + +No prior release notes were kept. Thanks all the same to the many +contributors that have made this crate what it is! + diff --git a/rust/vendor/num-iter/build.rs b/rust/vendor/num-iter/build.rs new file mode 100644 index 0000000..4f39b83 --- /dev/null +++ b/rust/vendor/num-iter/build.rs @@ -0,0 +1,19 @@ +extern crate autocfg; + +use std::env; + +fn main() { + let autocfg = autocfg::new(); + + // If the "i128" feature is explicity requested, don't bother probing for it. + // It will still cause a build error if that was set improperly. + if env::var_os("CARGO_FEATURE_I128").is_some() || autocfg.probe_type("i128") { + autocfg::emit("has_i128"); + } + + // The RangeBounds trait was stabilized in 1.28, so from that version onwards we + // implement that trait. + autocfg.emit_rustc_version(1, 28); + + autocfg::rerun_path("build.rs"); +} diff --git a/rust/vendor/num-iter/src/lib.rs b/rust/vendor/num-iter/src/lib.rs new file mode 100644 index 0000000..74700d0 --- /dev/null +++ b/rust/vendor/num-iter/src/lib.rs @@ -0,0 +1,734 @@ +// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! External iterators for generic mathematics +//! +//! ## Compatibility +//! +//! The `num-iter` crate is tested for rustc 1.8 and greater. + +#![doc(html_root_url = "https://docs.rs/num-iter/0.1")] +#![no_std] +#[cfg(feature = "std")] +extern crate std; + +extern crate num_integer as integer; +extern crate num_traits as traits; + +use core::ops::{Add, Sub}; +use core::usize; +use integer::Integer; +use traits::{CheckedAdd, One, ToPrimitive, Zero}; + +#[cfg(rustc_1_28)] +use core::ops::{Bound, RangeBounds}; + +/// An iterator over the range [start, stop) +#[derive(Clone)] +pub struct Range<A> { + state: A, + stop: A, + one: A, +} + +/// Returns an iterator over the given range [start, stop) (that is, starting +/// at start (inclusive), and ending at stop (exclusive)). +/// +/// # Example +/// +/// ```rust +/// let array = [0, 1, 2, 3, 4]; +/// +/// for i in num_iter::range(0, 5) { +/// println!("{}", i); +/// assert_eq!(i, array[i]); +/// } +/// ``` +#[inline] +pub fn range<A>(start: A, stop: A) -> Range<A> +where + A: Add<A, Output = A> + PartialOrd + Clone + One, +{ + Range { + state: start, + stop: stop, + one: One::one(), + } +} + +#[inline] +#[cfg(has_i128)] +fn unsigned<T: ToPrimitive>(x: &T) -> Option<u128> { + match x.to_u128() { + None => match x.to_i128() { + Some(i) => Some(i as u128), + None => None, + }, + Some(u) => Some(u), + } +} + +#[inline] +#[cfg(not(has_i128))] +fn unsigned<T: ToPrimitive>(x: &T) -> Option<u64> { + match x.to_u64() { + None => match x.to_i64() { + Some(i) => Some(i as u64), + None => None, + }, + Some(u) => Some(u), + } +} + +#[cfg(rustc_1_28)] +impl<A> RangeBounds<A> for Range<A> { + fn start_bound(&self) -> Bound<&A> { + Bound::Included(&self.state) + } + + fn end_bound(&self) -> Bound<&A> { + Bound::Excluded(&self.stop) + } +} + +// FIXME: rust-lang/rust#10414: Unfortunate type bound +impl<A> Iterator for Range<A> +where + A: Add<A, Output = A> + PartialOrd + Clone + ToPrimitive, +{ + type Item = A; + + #[inline] + fn next(&mut self) -> Option<A> { + if self.state < self.stop { + let result = self.state.clone(); + self.state = self.state.clone() + self.one.clone(); + Some(result) + } else { + None + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + // Check for empty ranges first. + if self.state >= self.stop { + return (0, Some(0)); + } + + // Try to cast both ends to the largest unsigned primitive. + // Note that negative values will wrap to a large positive. + if let Some(a) = unsigned(&self.state) { + if let Some(b) = unsigned(&self.stop) { + // We've lost signs, but we already know state < stop, so + // a `wrapping_sub` will give the correct unsigned delta. + return match b.wrapping_sub(a).to_usize() { + Some(len) => (len, Some(len)), + None => (usize::MAX, None), + }; + } + } + + // Standard fallback for unbounded/unrepresentable bounds + (0, None) + } +} + +/// `Integer` is required to ensure the range will be the same regardless of +/// the direction it is consumed. +impl<A> DoubleEndedIterator for Range<A> +where + A: Integer + Clone + ToPrimitive, +{ + #[inline] + fn next_back(&mut self) -> Option<A> { + if self.stop > self.state { + self.stop = self.stop.clone() - self.one.clone(); + Some(self.stop.clone()) + } else { + None + } + } +} + +/// An iterator over the range [start, stop] +#[derive(Clone)] +pub struct RangeInclusive<A> { + range: Range<A>, + done: bool, +} + +/// Return an iterator over the range [start, stop] +#[inline] +pub fn range_inclusive<A>(start: A, stop: A) -> RangeInclusive<A> +where + A: Add<A, Output = A> + PartialOrd + Clone + One, +{ + RangeInclusive { + range: range(start, stop), + done: false, + } +} + +#[cfg(rustc_1_28)] +impl<A> RangeBounds<A> for RangeInclusive<A> { + fn start_bound(&self) -> Bound<&A> { + Bound::Included(&self.range.state) + } + + fn end_bound(&self) -> Bound<&A> { + Bound::Included(&self.range.stop) + } +} + +impl<A> Iterator for RangeInclusive<A> +where + A: Add<A, Output = A> + PartialOrd + Clone + ToPrimitive, +{ + type Item = A; + + #[inline] + fn next(&mut self) -> Option<A> { + match self.range.next() { + Some(x) => Some(x), + None => { + if !self.done && self.range.state == self.range.stop { + self.done = true; + Some(self.range.stop.clone()) + } else { + None + } + } + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + let (lo, hi) = self.range.size_hint(); + if self.done { + (lo, hi) + } else { + let lo = lo.saturating_add(1); + let hi = match hi { + Some(x) => x.checked_add(1), + None => None, + }; + (lo, hi) + } + } +} + +impl<A> DoubleEndedIterator for RangeInclusive<A> +where + A: Sub<A, Output = A> + Integer + Clone + ToPrimitive, +{ + #[inline] + fn next_back(&mut self) -> Option<A> { + if self.range.stop > self.range.state { + let result = self.range.stop.clone(); + self.range.stop = self.range.stop.clone() - self.range.one.clone(); + Some(result) + } else if !self.done && self.range.state == self.range.stop { + self.done = true; + Some(self.range.stop.clone()) + } else { + None + } + } +} + +/// An iterator over the range [start, stop) by `step`. It handles overflow by stopping. +#[derive(Clone)] +pub struct RangeStep<A> { + state: A, + stop: A, + step: A, + rev: bool, +} + +/// Return an iterator over the range [start, stop) by `step`. It handles overflow by stopping. +#[inline] +pub fn range_step<A>(start: A, stop: A, step: A) -> RangeStep<A> +where + A: CheckedAdd + PartialOrd + Clone + Zero, +{ + let rev = step < Zero::zero(); + RangeStep { + state: start, + stop: stop, + step: step, + rev: rev, + } +} + +impl<A> Iterator for RangeStep<A> +where + A: CheckedAdd + PartialOrd + Clone, +{ + type Item = A; + + #[inline] + fn next(&mut self) -> Option<A> { + if (self.rev && self.state > self.stop) || (!self.rev && self.state < self.stop) { + let result = self.state.clone(); + match self.state.checked_add(&self.step) { + Some(x) => self.state = x, + None => self.state = self.stop.clone(), + } + Some(result) + } else { + None + } + } +} + +/// An iterator over the range [start, stop] by `step`. It handles overflow by stopping. +#[derive(Clone)] +pub struct RangeStepInclusive<A> { + state: A, + stop: A, + step: A, + rev: bool, + done: bool, +} + +/// Return an iterator over the range [start, stop] by `step`. It handles overflow by stopping. +#[inline] +pub fn range_step_inclusive<A>(start: A, stop: A, step: A) -> RangeStepInclusive<A> +where + A: CheckedAdd + PartialOrd + Clone + Zero, +{ + let rev = step < Zero::zero(); + RangeStepInclusive { + state: start, + stop: stop, + step: step, + rev: rev, + done: false, + } +} + +impl<A> Iterator for RangeStepInclusive<A> +where + A: CheckedAdd + PartialOrd + Clone + PartialEq, +{ + type Item = A; + + #[inline] + fn next(&mut self) -> Option<A> { + if !self.done + && ((self.rev && self.state >= self.stop) || (!self.rev && self.state <= self.stop)) + { + let result = self.state.clone(); + match self.state.checked_add(&self.step) { + Some(x) => self.state = x, + None => self.done = true, + } + Some(result) + } else { + None + } + } +} + +/// An iterator over the infinite range starting at `start` +#[derive(Clone)] +pub struct RangeFrom<A> { + state: A, + one: A, +} + +/// Return an iterator over the infinite range starting at `start` and continuing forever. +/// +/// *Note*: Currently, the `Iterator` implementation is not checked for overflow. +/// If you use a finite-sized integer type and the integer overflows, +/// it might panic in debug mode or wrap around in release mode. +/// **This behavior is not guaranteed and may change at any time.** +#[inline] +pub fn range_from<A>(start: A) -> RangeFrom<A> +where + A: Add<A, Output = A> + Clone + One, +{ + RangeFrom { + state: start, + one: One::one(), + } +} + +#[cfg(rustc_1_28)] +impl<A> RangeBounds<A> for RangeFrom<A> { + fn start_bound(&self) -> Bound<&A> { + Bound::Included(&self.state) + } + + fn end_bound(&self) -> Bound<&A> { + Bound::Unbounded + } +} + +impl<A> Iterator for RangeFrom<A> +where + A: Add<A, Output = A> + Clone, +{ + type Item = A; + + #[inline] + fn next(&mut self) -> Option<A> { + let result = self.state.clone(); + self.state = self.state.clone() + self.one.clone(); + Some(result) + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + (usize::MAX, None) + } +} + +/// An iterator over the infinite range starting at `start` by `step` +#[derive(Clone)] +pub struct RangeStepFrom<A> { + state: A, + step: A, +} + +/// Return an iterator over the infinite range starting at `start` and continuing forever by `step`. +/// +/// *Note*: Currently, the `Iterator` implementation is not checked for overflow. +/// If you use a finite-sized integer type and the integer overflows, +/// it might panic in debug mode or wrap around in release mode. +/// **This behavior is not guaranteed and may change at any time.** +#[inline] +pub fn range_step_from<A>(start: A, step: A) -> RangeStepFrom<A> +where + A: Add<A, Output = A> + Clone, +{ + RangeStepFrom { + state: start, + step: step, + } +} + +impl<A> Iterator for RangeStepFrom<A> +where + A: Add<A, Output = A> + Clone, +{ + type Item = A; + + #[inline] + fn next(&mut self) -> Option<A> { + let result = self.state.clone(); + self.state = self.state.clone() + self.step.clone(); + Some(result) + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + (usize::MAX, None) + } +} + +#[cfg(test)] +mod tests { + use core::cmp::Ordering; + use core::iter; + use core::ops::{Add, Mul}; + use core::{isize, usize}; + use traits::{One, ToPrimitive}; + + #[test] + fn test_range() { + /// A mock type to check Range when ToPrimitive returns None + struct Foo; + + impl ToPrimitive for Foo { + fn to_i64(&self) -> Option<i64> { + None + } + fn to_u64(&self) -> Option<u64> { + None + } + } + + impl Add<Foo> for Foo { + type Output = Foo; + + fn add(self, _: Foo) -> Foo { + Foo + } + } + + impl PartialEq for Foo { + fn eq(&self, _: &Foo) -> bool { + true + } + } + + impl PartialOrd for Foo { + fn partial_cmp(&self, _: &Foo) -> Option<Ordering> { + None + } + } + + impl Clone for Foo { + fn clone(&self) -> Foo { + Foo + } + } + + impl Mul<Foo> for Foo { + type Output = Foo; + + fn mul(self, _: Foo) -> Foo { + Foo + } + } + + impl One for Foo { + fn one() -> Foo { + Foo + } + } + + assert!(super::range(0, 5).eq([0, 1, 2, 3, 4].iter().cloned())); + assert!(super::range(-10, -1).eq([-10, -9, -8, -7, -6, -5, -4, -3, -2].iter().cloned())); + assert!(super::range(0, 5).rev().eq([4, 3, 2, 1, 0].iter().cloned())); + assert_eq!(super::range(200, -5).count(), 0); + assert_eq!(super::range(200, -5).rev().count(), 0); + assert_eq!(super::range(200, 200).count(), 0); + assert_eq!(super::range(200, 200).rev().count(), 0); + + assert_eq!(super::range(0, 100).size_hint(), (100, Some(100))); + // this test is only meaningful when sizeof usize < sizeof u64 + assert_eq!( + super::range(usize::MAX - 1, usize::MAX).size_hint(), + (1, Some(1)) + ); + assert_eq!(super::range(-10, -1).size_hint(), (9, Some(9))); + assert_eq!( + super::range(isize::MIN, isize::MAX).size_hint(), + (usize::MAX, Some(usize::MAX)) + ); + } + + #[test] + #[cfg(has_i128)] + fn test_range_128() { + use core::{i128, u128}; + + assert!(super::range(0i128, 5).eq([0, 1, 2, 3, 4].iter().cloned())); + assert!(super::range(-10i128, -1).eq([-10, -9, -8, -7, -6, -5, -4, -3, -2].iter().cloned())); + assert!(super::range(0u128, 5) + .rev() + .eq([4, 3, 2, 1, 0].iter().cloned())); + + assert_eq!( + super::range(i128::MIN, i128::MIN + 1).size_hint(), + (1, Some(1)) + ); + assert_eq!( + super::range(i128::MAX - 1, i128::MAX).size_hint(), + (1, Some(1)) + ); + assert_eq!( + super::range(i128::MIN, i128::MAX).size_hint(), + (usize::MAX, None) + ); + + assert_eq!( + super::range(u128::MAX - 1, u128::MAX).size_hint(), + (1, Some(1)) + ); + assert_eq!( + super::range(0, usize::MAX as u128).size_hint(), + (usize::MAX, Some(usize::MAX)) + ); + assert_eq!( + super::range(0, usize::MAX as u128 + 1).size_hint(), + (usize::MAX, None) + ); + assert_eq!(super::range(0, i128::MAX).size_hint(), (usize::MAX, None)); + } + + #[test] + fn test_range_inclusive() { + assert!(super::range_inclusive(0, 5).eq([0, 1, 2, 3, 4, 5].iter().cloned())); + assert!(super::range_inclusive(0, 5) + .rev() + .eq([5, 4, 3, 2, 1, 0].iter().cloned())); + assert_eq!(super::range_inclusive(200, -5).count(), 0); + assert_eq!(super::range_inclusive(200, -5).rev().count(), 0); + assert!(super::range_inclusive(200, 200).eq(iter::once(200))); + assert!(super::range_inclusive(200, 200).rev().eq(iter::once(200))); + assert_eq!( + super::range_inclusive(isize::MIN, isize::MAX - 1).size_hint(), + (usize::MAX, Some(usize::MAX)) + ); + assert_eq!( + super::range_inclusive(isize::MIN, isize::MAX).size_hint(), + (usize::MAX, None) + ); + } + + #[test] + #[cfg(has_i128)] + fn test_range_inclusive_128() { + use core::i128; + + assert!(super::range_inclusive(0u128, 5).eq([0, 1, 2, 3, 4, 5].iter().cloned())); + assert!(super::range_inclusive(0u128, 5) + .rev() + .eq([5, 4, 3, 2, 1, 0].iter().cloned())); + assert_eq!(super::range_inclusive(200i128, -5).count(), 0); + assert_eq!(super::range_inclusive(200i128, -5).rev().count(), 0); + assert!(super::range_inclusive(200u128, 200).eq(iter::once(200))); + assert!(super::range_inclusive(200u128, 200) + .rev() + .eq(iter::once(200))); + assert_eq!( + super::range_inclusive(isize::MIN as i128, isize::MAX as i128 - 1).size_hint(), + (usize::MAX, Some(usize::MAX)) + ); + assert_eq!( + super::range_inclusive(isize::MIN as i128, isize::MAX as i128).size_hint(), + (usize::MAX, None) + ); + assert_eq!( + super::range_inclusive(isize::MIN as i128, isize::MAX as i128 + 1).size_hint(), + (usize::MAX, None) + ); + assert_eq!( + super::range_inclusive(i128::MIN, i128::MAX).size_hint(), + (usize::MAX, None) + ); + } + + #[test] + fn test_range_step() { + assert!(super::range_step(0, 20, 5).eq([0, 5, 10, 15].iter().cloned())); + assert!(super::range_step(20, 0, -5).eq([20, 15, 10, 5].iter().cloned())); + assert!(super::range_step(20, 0, -6).eq([20, 14, 8, 2].iter().cloned())); + assert!(super::range_step(200u8, 255, 50).eq([200u8, 250].iter().cloned())); + assert!(super::range_step(200, -5, 1).eq(iter::empty())); + assert!(super::range_step(200, 200, 1).eq(iter::empty())); + } + + #[test] + #[cfg(has_i128)] + fn test_range_step_128() { + use core::u128::MAX as UMAX; + + assert!(super::range_step(0u128, 20, 5).eq([0, 5, 10, 15].iter().cloned())); + assert!(super::range_step(20i128, 0, -5).eq([20, 15, 10, 5].iter().cloned())); + assert!(super::range_step(20i128, 0, -6).eq([20, 14, 8, 2].iter().cloned())); + assert!(super::range_step(UMAX - 55, UMAX, 50).eq([UMAX - 55, UMAX - 5].iter().cloned())); + assert!(super::range_step(200i128, -5, 1).eq(iter::empty())); + assert!(super::range_step(200i128, 200, 1).eq(iter::empty())); + } + + #[test] + fn test_range_step_inclusive() { + assert!(super::range_step_inclusive(0, 20, 5).eq([0, 5, 10, 15, 20].iter().cloned())); + assert!(super::range_step_inclusive(20, 0, -5).eq([20, 15, 10, 5, 0].iter().cloned())); + assert!(super::range_step_inclusive(20, 0, -6).eq([20, 14, 8, 2].iter().cloned())); + assert!(super::range_step_inclusive(200u8, 255, 50).eq([200u8, 250].iter().cloned())); + assert!(super::range_step_inclusive(200, -5, 1).eq(iter::empty())); + assert!(super::range_step_inclusive(200, 200, 1).eq(iter::once(200))); + } + + #[test] + #[cfg(has_i128)] + fn test_range_step_inclusive_128() { + use core::u128::MAX as UMAX; + + assert!(super::range_step_inclusive(0u128, 20, 5).eq([0, 5, 10, 15, 20].iter().cloned())); + assert!(super::range_step_inclusive(20i128, 0, -5).eq([20, 15, 10, 5, 0].iter().cloned())); + assert!(super::range_step_inclusive(20i128, 0, -6).eq([20, 14, 8, 2].iter().cloned())); + assert!(super::range_step_inclusive(UMAX - 55, UMAX, 50) + .eq([UMAX - 55, UMAX - 5].iter().cloned())); + assert!(super::range_step_inclusive(200i128, -5, 1).eq(iter::empty())); + assert!(super::range_step_inclusive(200i128, 200, 1).eq(iter::once(200))); + } + + #[test] + fn test_range_from() { + assert!(super::range_from(10u8) + .take(5) + .eq([10, 11, 12, 13, 14].iter().cloned())); + assert_eq!(super::range_from(10u8).size_hint(), (usize::MAX, None)); + } + + #[test] + fn test_range_step_from() { + assert!(super::range_step_from(10u8, 2u8) + .take(5) + .eq([10, 12, 14, 16, 18].iter().cloned())); + assert_eq!( + super::range_step_from(10u8, 2u8).size_hint(), + (usize::MAX, None) + ); + + assert!(super::range_step_from(10u8, 1u8) + .take(5) + .eq([10, 11, 12, 13, 14].iter().cloned())); + assert_eq!( + super::range_step_from(10u8, 1u8).size_hint(), + (usize::MAX, None) + ); + + assert!(super::range_step_from(10u8, 0u8) + .take(5) + .eq([10, 10, 10, 10, 10].iter().cloned())); + assert_eq!( + super::range_step_from(10u8, 0u8).size_hint(), + (usize::MAX, None) + ); + + assert!(super::range_step_from(10i8, 2i8) + .take(5) + .eq([10, 12, 14, 16, 18].iter().cloned())); + assert_eq!( + super::range_step_from(10i8, 2i8).size_hint(), + (usize::MAX, None) + ); + + assert!(super::range_step_from(10i8, 1i8) + .take(5) + .eq([10, 11, 12, 13, 14].iter().cloned())); + assert_eq!( + super::range_step_from(10i8, 1i8).size_hint(), + (usize::MAX, None) + ); + + assert!(super::range_step_from(10i8, 0i8) + .take(5) + .eq([10, 10, 10, 10, 10].iter().cloned())); + assert_eq!( + super::range_step_from(10i8, 0i8).size_hint(), + (usize::MAX, None) + ); + + assert!(super::range_step_from(10i8, -1i8) + .take(5) + .eq([10, 9, 8, 7, 6].iter().cloned())); + assert_eq!( + super::range_step_from(10i8, -1i8).size_hint(), + (usize::MAX, None) + ); + + assert!(super::range_step_from(10i8, -2i8) + .take(5) + .eq([10, 8, 6, 4, 2].iter().cloned())); + assert_eq!( + super::range_step_from(10i8, -2i8).size_hint(), + (usize::MAX, None) + ); + } +} |