Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stdlib] Rename List.size to List._len and refactor usage of the field to use the public API #3814

Closed
wants to merge 34 commits into from
Closed
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
6d5e0fd
Rename List.size to List._len adding getattr and setattr for size
martinvuyk Nov 27, 2024
4419121
add length attribute overload
martinvuyk Nov 27, 2024
b6e9e36
fix detail
martinvuyk Nov 27, 2024
720e043
fix detail
martinvuyk Nov 27, 2024
0f43949
try removing all uses of list.size
martinvuyk Dec 4, 2024
2c7857d
fix uses of buf.size
martinvuyk Dec 4, 2024
1cc618e
fix pixi.toml diff
martinvuyk Dec 4, 2024
4c4e1fe
fix pixi.toml diff
martinvuyk Dec 4, 2024
6c178fb
fix details
martinvuyk Dec 4, 2024
8e88d34
fix details
martinvuyk Dec 4, 2024
5bc5722
fix details
martinvuyk Dec 4, 2024
e236c6f
Merge remote-tracking branch 'upstream/nightly' into make-list-size-p…
martinvuyk Dec 10, 2024
abc6e26
fix details
martinvuyk Dec 10, 2024
554a0b6
fix details
martinvuyk Dec 10, 2024
a3bfe40
fix details
martinvuyk Dec 10, 2024
d7bf8c3
Merge remote-tracking branch 'upstream/nightly' into make-list-size-p…
martinvuyk Dec 31, 2024
64cd704
fix after merge
martinvuyk Dec 31, 2024
f97b7e9
fix allocation
martinvuyk Dec 31, 2024
a8f2cd9
fix detail
martinvuyk Dec 31, 2024
6113bc2
fix detail
martinvuyk Dec 31, 2024
b25008d
fix bug in pathlib
martinvuyk Jan 2, 2025
1abb34b
Merge remote-tracking branch 'upstream/main' into make-list-size-private
martinvuyk Feb 2, 2025
2f32763
add changelog examples
martinvuyk Feb 2, 2025
7276562
fix change implementations to use the public API
martinvuyk Feb 2, 2025
d361412
mojo format
martinvuyk Feb 2, 2025
a9a2609
fix assert message
martinvuyk Feb 2, 2025
498f4d3
fix details
martinvuyk Feb 2, 2025
58b81a5
fix more uses of string buffer constructor
martinvuyk Feb 2, 2025
87a1a53
fix more uses of string buffer constructor
martinvuyk Feb 2, 2025
44625b9
Merge remote-tracking branch 'upstream/main' into make-list-size-private
martinvuyk Feb 25, 2025
fc70e1e
fix detail
martinvuyk Feb 25, 2025
f67cc53
Merge remote-tracking branch 'upstream/main' into make-list-size-private
martinvuyk Feb 26, 2025
ffab93a
fix iadd length to use byte_length
martinvuyk Feb 26, 2025
0b12853
revert: fix iadd length to use byte_length
martinvuyk Feb 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ what we publish.
- `StringRef` is being deprecated. Use `StringSlice` instead.
- Changed `sys.argv()` to return list of `StringSlice`.
- removed `StringRef.startswith()` and `StringRef.endswith()`
- Direct access to `List.size` has been removed. Use the public API instead.

### 🛠️ Fixed

Expand Down
2 changes: 1 addition & 1 deletion pixi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ benchmarks = { cmd = ["./stdlib/scripts/run-benchmarks.sh"], env = { MODULAR_MOJ
[dependencies]
python = ">=3.9,<3.13"
lit = "*"
max = "*"
max = "*"
4 changes: 2 additions & 2 deletions stdlib/src/builtin/file.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ struct FileHandle:
"""Reads data from a file and sets the file handle seek position. If
size is left as the default of -1, it will read to the end of the file.
Setting size to a number larger than what's in the file will set
String.size to the total number of bytes, and read all the data.
the String length to the total number of bytes, and read all the data.

Args:
size: Requested number of bytes to read (Default: -1 = EOF).
Expand Down Expand Up @@ -284,7 +284,7 @@ struct FileHandle:
"""Reads data from a file and sets the file handle seek position. If
size is left as default of -1, it will read to the end of the file.
Setting size to a number larger than what's in the file will be handled
and set the List.size to the total number of bytes in the file.
and set the List length to the total number of bytes in the file.

Args:
size: Requested number of bytes to read (Default: -1 = EOF).
Expand Down
14 changes: 4 additions & 10 deletions stdlib/src/builtin/string_literal.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -381,17 +381,11 @@ struct StringLiteral(
# inline the string slice constructor to work around an elaborator
# memory leak.
# return self.as_string_slice()
var string = String()
var length = self.byte_length()
var buffer = String._buffer_type()
var new_capacity = length + 1
buffer._realloc(new_capacity)
buffer.size = new_capacity
var data: UnsafePointer[UInt8] = self.unsafe_ptr()
memcpy(buffer.data, data, length)
(buffer.data + length).init_pointee_move(0)
string._buffer = buffer^
return string
var buffer = String._buffer_type(capacity=length + 1)
buffer.extend(self.as_bytes())
buffer.append(0)
return String(buffer^)

@no_inline
fn __repr__(self) -> String:
Expand Down
111 changes: 50 additions & 61 deletions stdlib/src/collections/list.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ struct List[T: CollectionElement, hint_trivial_type: Bool = False](
# Fields
var data: UnsafePointer[T]
"""The underlying storage for the list."""
var size: Int
var _len: Int
"""The number of elements in the list."""
var capacity: Int
"""The amount of elements that can fit in the list without resizing it."""
Expand All @@ -111,7 +111,7 @@ struct List[T: CollectionElement, hint_trivial_type: Bool = False](
fn __init__(out self):
"""Constructs an empty list."""
self.data = UnsafePointer[T]()
self.size = 0
self._len = 0
self.capacity = 0

fn copy(self) -> Self:
Expand All @@ -132,7 +132,7 @@ struct List[T: CollectionElement, hint_trivial_type: Bool = False](
capacity: The requested capacity of the list.
"""
self.data = UnsafePointer[T].alloc(capacity)
self.size = 0
self._len = 0
self.capacity = capacity

@implicit
Expand Down Expand Up @@ -165,7 +165,7 @@ struct List[T: CollectionElement, hint_trivial_type: Bool = False](
__get_mvalue_as_litref(elements)
)

self.size = length
self._len = length

@implicit
fn __init__(out self, span: Span[T]):
Expand All @@ -187,7 +187,7 @@ struct List[T: CollectionElement, hint_trivial_type: Bool = False](
capacity: The capacity of the list.
"""
self.data = ptr
self.size = length
self._len = length
self.capacity = capacity

fn __moveinit__(out self, owned existing: Self):
Expand All @@ -197,7 +197,7 @@ struct List[T: CollectionElement, hint_trivial_type: Bool = False](
existing: The existing list.
"""
self.data = existing.data
self.size = existing.size
self._len = existing._len
self.capacity = existing.capacity

fn __copyinit__(out self, existing: Self):
Expand All @@ -215,7 +215,7 @@ struct List[T: CollectionElement, hint_trivial_type: Bool = False](

@parameter
if not hint_trivial_type:
for i in range(self.size):
for i in range(len(self)):
(self.data + i).destroy_pointee()
self.data.free()

Expand Down Expand Up @@ -372,13 +372,14 @@ struct List[T: CollectionElement, hint_trivial_type: Bool = False](
# Trait implementations
# ===-------------------------------------------------------------------===#

@always_inline("nodebug")
fn __len__(self) -> Int:
"""Gets the number of elements in the list.

Returns:
The number of elements in the list.
"""
return self.size
return self._len

fn __bool__(self) -> Bool:
"""Checks whether the list has any elements or not.
Expand Down Expand Up @@ -414,7 +415,9 @@ struct List[T: CollectionElement, hint_trivial_type: Bool = False](
Returns:
A string representation of the list.
"""
var output = String()
# at least 1 byte per item e.g.: [a, b, c, d] = 4 + 2 * 3 + [] + null
var l = len(self)
var output = String(capacity=l + 2 * (l - 1) * int(l > 1) + 3)
self.write_to(output)
return output^

Expand Down Expand Up @@ -481,11 +484,12 @@ struct List[T: CollectionElement, hint_trivial_type: Bool = False](
fn _realloc(mut self, new_capacity: Int):
var new_data = UnsafePointer[T].alloc(new_capacity)

_move_pointee_into_many_elements[hint_trivial_type](
dest=new_data,
src=self.data,
size=self.size,
)
@parameter
if hint_trivial_type:
memcpy(new_data, self.data, len(self))
else:
for i in range(len(self)):
(self.data + i).move_pointee_into(new_data + i)

if self.data:
self.data.free()
Expand All @@ -502,10 +506,10 @@ struct List[T: CollectionElement, hint_trivial_type: Bool = False](
If there is no capacity left, resizes to twice the current capacity.
Except for 0 capacity where it sets 1.
"""
if self.size >= self.capacity:
if self._len >= self.capacity:
self._realloc(self.capacity * 2 | int(self.capacity == 0))
(self.data + self.size).init_pointee_move(value^)
self.size += 1
(self.data + self._len).init_pointee_move(value^)
self._len += 1

fn insert(mut self, i: Int, owned value: T):
"""Inserts a value to the list at the given index.
Expand All @@ -515,7 +519,7 @@ struct List[T: CollectionElement, hint_trivial_type: Bool = False](
i: The index for the value.
value: The value to insert.
"""
debug_assert(i <= self.size, "insert index out of range")
debug_assert(i <= len(self), "insert index out of range")

var normalized_idx = i
if i < 0:
Expand Down Expand Up @@ -576,7 +580,7 @@ struct List[T: CollectionElement, hint_trivial_type: Bool = False](
# visible outside this function if a `__moveinit__()` constructor were
# to throw (not currently possible AFAIK though) part way through the
# logic below.
other.size = 0
other._len = 0

var dest_ptr = self.data + len(self)

Expand All @@ -593,7 +597,7 @@ struct List[T: CollectionElement, hint_trivial_type: Bool = False](

# Update the size now that all new elements have been moved into this
# list.
self.size = final_size
self._len = final_size

fn extend[
D: DType, //
Expand All @@ -609,9 +613,9 @@ struct List[T: CollectionElement, hint_trivial_type: Bool = False](
Notes:
If there is no capacity left, resizes to `len(self) + value.size`.
"""
self.reserve(self.size + value.size)
(self.data + self.size).store(value)
self.size += value.size
self.reserve(self._len + value.size)
(self.data + self._len).store(value)
self._len += value.size

fn extend[
D: DType, //
Expand All @@ -630,10 +634,10 @@ struct List[T: CollectionElement, hint_trivial_type: Bool = False](
If there is no capacity left, resizes to `len(self) + count`.
"""
debug_assert(count <= value.size, "count must be <= value.size")
self.reserve(self.size + count)
self.reserve(self._len + count)
var v_ptr = UnsafePointer.address_of(value).bitcast[Scalar[D]]()
memcpy(self.data + self.size, v_ptr, count)
self.size += count
memcpy(self.data + self._len, v_ptr, count)
self._len += count

fn extend[
D: DType, //
Expand All @@ -649,9 +653,9 @@ struct List[T: CollectionElement, hint_trivial_type: Bool = False](
Notes:
If there is no capacity left, resizes to `len(self) + len(value)`.
"""
self.reserve(self.size + len(value))
memcpy(self.data + self.size, value.unsafe_ptr(), len(value))
self.size += len(value)
self.reserve(self._len + len(value))
memcpy(self.data + self._len, value.unsafe_ptr(), len(value))
self._len += len(value)

fn pop(mut self, i: Int = -1) -> T:
"""Pops a value from the list at the given index.
Expand All @@ -662,17 +666,17 @@ struct List[T: CollectionElement, hint_trivial_type: Bool = False](
Returns:
The popped value.
"""
debug_assert(-len(self) <= i < len(self), "pop index out of range")
debug_assert(-self._len <= i < self._len, "pop index out of range")

var normalized_idx = i
if i < 0:
normalized_idx += len(self)
normalized_idx += self._len

var ret_val = (self.data + normalized_idx).take_pointee()
for j in range(normalized_idx + 1, self.size):
for j in range(normalized_idx + 1, self._len):
(self.data + j).move_pointee_into(self.data + j - 1)
self.size -= 1
if self.size * 4 < self.capacity:
self._len -= 1
if self._len * 4 < self.capacity:
if self.capacity > 1:
self._realloc(self.capacity // 2)
return ret_val^
Expand Down Expand Up @@ -701,13 +705,13 @@ struct List[T: CollectionElement, hint_trivial_type: Bool = False](
new_size: The new size.
value: The value to use to populate new elements.
"""
if new_size <= self.size:
if new_size <= self._len:
self.resize(new_size)
else:
self.reserve(new_size)
for i in range(self.size, new_size):
for i in range(self._len, new_size):
(self.data + i).init_pointee_copy(value)
self.size = new_size
self._len = new_size

fn resize(mut self, new_size: Int):
"""Resizes the list to the given new size.
Expand All @@ -718,16 +722,16 @@ struct List[T: CollectionElement, hint_trivial_type: Bool = False](
Args:
new_size: The new size.
"""
if self.size < new_size:
if len(self) < new_size:
abort(
"You are calling List.resize with a new_size bigger than the"
" current size. If you want to make the List bigger, provide a"
" value to fill the new slots with. If not, make sure the new"
" size is smaller than the current size."
)
for i in range(new_size, self.size):
for i in range(new_size, len(self)):
(self.data + i).destroy_pointee()
self.size = new_size
self._len = new_size
self.reserve(new_size)

fn reverse(mut self):
Expand Down Expand Up @@ -809,9 +813,9 @@ struct List[T: CollectionElement, hint_trivial_type: Bool = False](

fn clear(mut self):
"""Clears the elements in the list."""
for i in range(self.size):
for i in range(self._len):
(self.data + i).destroy_pointee()
self.size = 0
self._len = 0

fn steal_data(mut self) -> UnsafePointer[T]:
"""Take ownership of the underlying pointer from the list.
Expand All @@ -821,7 +825,7 @@ struct List[T: CollectionElement, hint_trivial_type: Bool = False](
"""
var ptr = self.data
self.data = UnsafePointer[T]()
self.size = 0
self._len = 0
self.capacity = 0
return ptr

Expand Down Expand Up @@ -863,11 +867,11 @@ struct List[T: CollectionElement, hint_trivial_type: Bool = False](
var normalized_idx = idx

debug_assert(
-self.size <= normalized_idx < self.size,
-len(self) <= normalized_idx < len(self),
"index: ",
normalized_idx,
" is out of bounds for `List` of size: ",
self.size,
" is out of bounds for `List` of length: ",
len(self),
)
if normalized_idx < 0:
normalized_idx += len(self)
Expand Down Expand Up @@ -1003,18 +1007,3 @@ struct List[T: CollectionElement, hint_trivial_type: Bool = False](

fn _clip(value: Int, start: Int, end: Int) -> Int:
return max(start, min(value, end))


fn _move_pointee_into_many_elements[
T: CollectionElement, //, hint_trivial_type: Bool
](dest: UnsafePointer[T], src: UnsafePointer[T], size: Int):
@parameter
if hint_trivial_type:
memcpy(
dest=dest.bitcast[Int8](),
src=src.bitcast[Int8](),
count=size * sizeof[T](),
)
else:
for i in range(size):
(src + i).move_pointee_into(dest + i)
3 changes: 1 addition & 2 deletions stdlib/src/collections/string/format.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,7 @@ struct _FormatCurlyEntry(CollectionElement, CollectionElementNew):
entries, size_estimation = Self._create_entries(fmt_src, len_pos_args)
var fmt_len = fmt_src.byte_length()
var buf = String._buffer_type(capacity=fmt_len + size_estimation)
buf.size = 1
buf.unsafe_set(0, 0)
buf.append(0)
var res = String(buf^)
var offset = 0
var ptr = fmt_src.unsafe_ptr()
Expand Down
Loading
Loading