-
Notifications
You must be signed in to change notification settings - Fork 24
Description
Proposal
Problem statement
Currently, the best way to evaluate the length of a CStr is cs.to_bytes().len(). This is not ergonomic, and may not be the best option when CStr becomes a thin pointer.
Motivating examples or use cases
For both a fat and thin CStr, this will provide a more intuitive method to get the length. When CStr becomes thin, CStr::count_bytes will be able to call strlen directly without going through the less direct to_bytes > to_bytes_with_nul > slice::from_raw_parts > len.
Solution sketch
Add a method CStr::count_bytes that returns its length. Currently, we can use a self.inner.len() - 1 to get the length of the string, which is a constant time operation. Once CStr becomes thin, this will become an O(1) call to strlen - we just need to make it clear in documentation that this will have a performance regression at some point (as we do for the to_bytes() methods).
The API is simple:
impl CStr {
pub fn count_bytes(&self) -> usize {
self.inner.len()
}
}Once thin, this will become:
impl CStr {
pub fn count_bytes(&self) -> usize {
strlen(self.inner_ptr)
}
}Alternatives
The status quo: accessing length via .to_bytes().len(). This ACP intends to improve upon this option.
constness
Currenly CStr::from_ptr uses a version of strlen that calls libc's implementation normally, or a naive Rust implementation when const. This works via const_eval_select which to my knowledge hasn't been okayed for internal use. So, we will not be able to make CStr::count_bytes const stable until either that happens, or we decide our naive strlen is always OK (making CStr::new const is also blocked by this, or by the switch to a thin pointer).
My current implementation gates the constness under const_cstr_from_ptr which has the same const-stable blocker.
cc @oli-obk because of your comment onconst_eval_select here rust-lang/rust#107624 (comment) (I believe this is the RFC: rust-lang/rfcs#3352)
Naming
The name count_bytes is up for some bikeshedding.
Links and related work
- @BurntSushi pointed out the lack of a
CStr::lenmethod when stabilizingCStr::is_empty: Tracking Issue for CStr::is_empty rust#102444 (comment) - I put together a table the time complexity for different
CStrmethods based on whether or not we haveconst_eval_select, here: Stabilizeconst_cstr_methodsrust#107624 (comment)
What happens now?
This issue is part of the libs-api team API change proposal process. Once this issue is filed the libs-api team will review open proposals as capability becomes available. Current response times do not have a clear estimate, but may be up to several months.