mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-05 14:37:37 +00:00
constify CStr
methods
This commit is contained in:
parent
9bbbf60b04
commit
cb02b647dc
@ -121,10 +121,10 @@ enum FromBytesWithNulErrorKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FromBytesWithNulError {
|
impl FromBytesWithNulError {
|
||||||
fn interior_nul(pos: usize) -> FromBytesWithNulError {
|
const fn interior_nul(pos: usize) -> FromBytesWithNulError {
|
||||||
FromBytesWithNulError { kind: FromBytesWithNulErrorKind::InteriorNul(pos) }
|
FromBytesWithNulError { kind: FromBytesWithNulErrorKind::InteriorNul(pos) }
|
||||||
}
|
}
|
||||||
fn not_nul_terminated() -> FromBytesWithNulError {
|
const fn not_nul_terminated() -> FromBytesWithNulError {
|
||||||
FromBytesWithNulError { kind: FromBytesWithNulErrorKind::NotNulTerminated }
|
FromBytesWithNulError { kind: FromBytesWithNulErrorKind::NotNulTerminated }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,7 +299,8 @@ impl CStr {
|
|||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
#[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
|
#[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
|
||||||
pub fn from_bytes_until_nul(bytes: &[u8]) -> Result<&CStr, FromBytesUntilNulError> {
|
#[rustc_const_unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
|
||||||
|
pub const fn from_bytes_until_nul(bytes: &[u8]) -> Result<&CStr, FromBytesUntilNulError> {
|
||||||
let nul_pos = memchr::memchr(0, bytes);
|
let nul_pos = memchr::memchr(0, bytes);
|
||||||
match nul_pos {
|
match nul_pos {
|
||||||
Some(nul_pos) => {
|
Some(nul_pos) => {
|
||||||
@ -348,7 +349,8 @@ impl CStr {
|
|||||||
/// assert!(cstr.is_err());
|
/// assert!(cstr.is_err());
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
|
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
|
||||||
pub fn from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError> {
|
#[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")]
|
||||||
|
pub const fn from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError> {
|
||||||
let nul_pos = memchr::memchr(0, bytes);
|
let nul_pos = memchr::memchr(0, bytes);
|
||||||
match nul_pos {
|
match nul_pos {
|
||||||
Some(nul_pos) if nul_pos + 1 == bytes.len() => {
|
Some(nul_pos) if nul_pos + 1 == bytes.len() => {
|
||||||
@ -497,7 +499,8 @@ impl CStr {
|
|||||||
#[must_use = "this returns the result of the operation, \
|
#[must_use = "this returns the result of the operation, \
|
||||||
without modifying the original"]
|
without modifying the original"]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn to_bytes(&self) -> &[u8] {
|
#[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")]
|
||||||
|
pub const fn to_bytes(&self) -> &[u8] {
|
||||||
let bytes = self.to_bytes_with_nul();
|
let bytes = self.to_bytes_with_nul();
|
||||||
// SAFETY: to_bytes_with_nul returns slice with length at least 1
|
// SAFETY: to_bytes_with_nul returns slice with length at least 1
|
||||||
unsafe { bytes.get_unchecked(..bytes.len() - 1) }
|
unsafe { bytes.get_unchecked(..bytes.len() - 1) }
|
||||||
@ -524,7 +527,8 @@ impl CStr {
|
|||||||
#[must_use = "this returns the result of the operation, \
|
#[must_use = "this returns the result of the operation, \
|
||||||
without modifying the original"]
|
without modifying the original"]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn to_bytes_with_nul(&self) -> &[u8] {
|
#[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")]
|
||||||
|
pub const fn to_bytes_with_nul(&self) -> &[u8] {
|
||||||
// SAFETY: Transmuting a slice of `c_char`s to a slice of `u8`s
|
// SAFETY: Transmuting a slice of `c_char`s to a slice of `u8`s
|
||||||
// is safe on all supported targets.
|
// is safe on all supported targets.
|
||||||
unsafe { &*(&self.inner as *const [c_char] as *const [u8]) }
|
unsafe { &*(&self.inner as *const [c_char] as *const [u8]) }
|
||||||
@ -547,7 +551,8 @@ impl CStr {
|
|||||||
/// assert_eq!(cstr.to_str(), Ok("foo"));
|
/// assert_eq!(cstr.to_str(), Ok("foo"));
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "cstr_to_str", since = "1.4.0")]
|
#[stable(feature = "cstr_to_str", since = "1.4.0")]
|
||||||
pub fn to_str(&self) -> Result<&str, str::Utf8Error> {
|
#[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")]
|
||||||
|
pub const fn to_str(&self) -> Result<&str, str::Utf8Error> {
|
||||||
// N.B., when `CStr` is changed to perform the length check in `.to_bytes()`
|
// N.B., when `CStr` is changed to perform the length check in `.to_bytes()`
|
||||||
// instead of in `from_ptr()`, it may be worth considering if this should
|
// instead of in `from_ptr()`, it may be worth considering if this should
|
||||||
// be rewritten to do the UTF-8 check inline with the length calculation
|
// be rewritten to do the UTF-8 check inline with the length calculation
|
||||||
|
@ -157,6 +157,7 @@
|
|||||||
#![feature(const_slice_from_ref)]
|
#![feature(const_slice_from_ref)]
|
||||||
#![feature(const_slice_index)]
|
#![feature(const_slice_index)]
|
||||||
#![feature(const_is_char_boundary)]
|
#![feature(const_is_char_boundary)]
|
||||||
|
#![feature(const_cstr_methods)]
|
||||||
//
|
//
|
||||||
// Language features:
|
// Language features:
|
||||||
#![feature(abi_unadjusted)]
|
#![feature(abi_unadjusted)]
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch
|
// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch
|
||||||
|
|
||||||
use crate::cmp;
|
use crate::cmp;
|
||||||
|
use crate::intrinsics;
|
||||||
use crate::mem;
|
use crate::mem;
|
||||||
|
|
||||||
const LO_USIZE: usize = usize::repeat_u8(0x01);
|
const LO_USIZE: usize = usize::repeat_u8(0x01);
|
||||||
@ -35,13 +36,31 @@ fn repeat_byte(b: u8) -> usize {
|
|||||||
/// Returns the first index matching the byte `x` in `text`.
|
/// Returns the first index matching the byte `x` in `text`.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn memchr(x: u8, text: &[u8]) -> Option<usize> {
|
pub const fn memchr(x: u8, text: &[u8]) -> Option<usize> {
|
||||||
|
#[inline]
|
||||||
|
fn rt_impl(x: u8, text: &[u8]) -> Option<usize> {
|
||||||
// Fast path for small slices
|
// Fast path for small slices
|
||||||
if text.len() < 2 * USIZE_BYTES {
|
if text.len() < 2 * USIZE_BYTES {
|
||||||
return text.iter().position(|elt| *elt == x);
|
return text.iter().position(|elt| *elt == x);
|
||||||
}
|
}
|
||||||
|
|
||||||
memchr_general_case(x, text)
|
memchr_general_case(x, text)
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn const_impl(x: u8, bytes: &[u8]) -> Option<usize> {
|
||||||
|
let mut i = 0;
|
||||||
|
while i < bytes.len() {
|
||||||
|
if bytes[i] == x {
|
||||||
|
return Some(i);
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
// SAFETY: The const and runtime versions have identical behavior
|
||||||
|
unsafe { intrinsics::const_eval_select((x, text), const_impl, rt_impl) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn memchr_general_case(x: u8, text: &[u8]) -> Option<usize> {
|
fn memchr_general_case(x: u8, text: &[u8]) -> Option<usize> {
|
||||||
|
Loading…
Reference in New Issue
Block a user