| //@ compile-flags: -Copt-level=3 | |
| #![crate_type = "lib"] | |
| use std::ops::{Range, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive}; | |
| macro_rules! tests { | |
| ($range_ty:ty, $get_func_name:ident, $index_func_name:ident) => { | |
| #[no_mangle] | |
| pub fn $get_func_name(slice: &str, range: $range_ty) -> Option<&str> { | |
| slice.get(range) | |
| } | |
| #[no_mangle] | |
| pub fn $index_func_name(slice: &str, range: $range_ty) -> &str { | |
| &slice[range] | |
| } | |
| }; | |
| } | |
| // 7 comparisons required: | |
| // start <= end && end <= len | |
| // && (start == len || | |
| // ( (start == 0 || bytes[start] >= -0x40) | |
| // && (end == len || bytes[end] >= -0x40))) | |
| // CHECK-LABEL: @get_range | |
| // CHECK-COUNT-7: %{{.+}} = icmp | |
| // CHECK-NOT: %{{.+}} = icmp | |
| // CHECK: ret | |
| // CHECK-LABEL: @index_range | |
| // CHECK-COUNT-7: %{{.+}} = icmp | |
| // CHECK-NOT: %{{.+}} = icmp | |
| // CHECK: ret | |
| tests!(Range<usize>, get_range, index_range); | |
| // 7 comparisons required: | |
| // end < len && start <= end + 1 | |
| // && (start == 0 || start >= len || bytes[start] >= -0x40) | |
| // && ( end + 1 >= len || bytes[end + 1] >= -0x40) | |
| // CHECK-LABEL: @get_range_inclusive | |
| // CHECK-COUNT-7: %{{.+}} = icmp | |
| // CHECK-NOT: %{{.+}} = icmp | |
| // CHECK: ret | |
| // CHECK-LABEL: @index_range_inclusive | |
| // CHECK-COUNT-7: %{{.+}} = icmp | |
| // CHECK-NOT: %{{.+}} = icmp | |
| // CHECK: ret | |
| tests!(RangeInclusive<usize>, get_range_inclusive, index_range_inclusive); | |
| // 4 comparisons required: | |
| // end == 0 || (end >= len && end == len) || bytes[end] >= -0x40 | |
| // CHECK-LABEL: @get_range_to | |
| // CHECK-COUNT-4: %{{.+}} = icmp | |
| // CHECK-NOT: %{{.+}} = icmp | |
| // CHECK: ret | |
| // CHECK-LABEL: @index_range_to | |
| // CHECK-COUNT-4: %{{.+}} = icmp | |
| // CHECK-NOT: %{{.+}} = icmp | |
| // CHECK: ret | |
| tests!(RangeTo<usize>, get_range_to, index_range_to); | |
| // 3 comparisons required: | |
| // end < len && (end + 1 >= len || bytes[end + 1] >= -0x40) | |
| // CHECK-LABEL: @get_range_to_inclusive | |
| // CHECK-COUNT-3: %{{.+}} = icmp | |
| // CHECK-NOT: %{{.+}} = icmp | |
| // CHECK: ret | |
| // CHECK-LABEL: @index_range_to_inclusive | |
| // CHECK-COUNT-3: %{{.+}} = icmp | |
| // CHECK-NOT: %{{.+}} = icmp | |
| // CHECK: ret | |
| tests!(RangeToInclusive<usize>, get_range_to_inclusive, index_range_to_inclusive); | |
| // 4 comparisons required: | |
| // start == 0 || (start >= len && start == len) || bytes[start] >= -0x40) | |
| // CHECK-LABEL: @get_range_from | |
| // CHECK-COUNT-4: %{{.+}} = icmp | |
| // CHECK-NOT: %{{.+}} = icmp | |
| // CHECK: ret | |
| // CHECK-LABEL: @index_range_from | |
| // CHECK-COUNT-4: %{{.+}} = icmp | |
| // CHECK-NOT: %{{.+}} = icmp | |
| // CHECK: ret | |
| tests!(RangeFrom<usize>, get_range_from, index_range_from); |