// SPDX-License-Identifier: UNLICENSED pragma solidity =0.8.18; library DynamicArray { struct Bytes32Array { uint256 length; bytes __data; } function push(Bytes32Array memory array, bytes32 item) internal pure { ++array.length; array.__data = abi.encodePacked(array.__data, item); } function toArray(Bytes32Array memory array) internal pure returns (bytes32[] memory) { return abi.decode(abi.encodePacked(array.length, array.__data), (bytes32[])); } function includes(Bytes32Array memory array, bytes32 item) internal pure returns (bool) { return indexOf(array, item) != type(uint256).max; } function indexOf(Bytes32Array memory array, bytes32 item) internal pure returns (uint256) { return _indexOf(array, item); } // ---------------------------------------------------------------------------------------------- struct Uint256Array { uint256 length; bytes __data; } function push(Uint256Array memory array, uint256 item) internal pure { ++array.length; array.__data = abi.encodePacked(array.__data, item); } function toArray(Uint256Array memory array) internal pure returns (uint256[] memory) { return abi.decode(abi.encodePacked(array.length, array.__data), (uint256[])); } function includes(Uint256Array memory array, uint256 item) internal pure returns (bool) { return indexOf(array, item) != type(uint256).max; } function indexOf(Uint256Array memory array, uint256 item) internal pure returns (uint256) { return _indexOf(Bytes32Array(array.length, array.__data), bytes32(item)); } // ---------------------------------------------------------------------------------------------- struct AddressArray { uint256 length; bytes __data; } function push(AddressArray memory array, address item) internal pure { ++array.length; array.__data = abi.encodePacked(array.__data, abi.encode(item)); } function toArray(AddressArray memory array) internal pure returns (address[] memory) { return abi.decode(abi.encodePacked(array.length, array.__data), (address[])); } function includes(AddressArray memory array, address item) internal pure returns (bool) { return indexOf(array, item) != type(uint256).max; } function indexOf(AddressArray memory array, address item) internal pure returns (uint256) { return _indexOf(Bytes32Array(array.length, array.__data), bytes32(uint256(uint160(item)) << 96)); } // ---------------------------------------------------------------------------------------------- function _indexOf(Bytes32Array memory array, bytes32 item) private pure returns (uint256) { bytes memory data = array.__data; for (uint256 i = 0; i < array.length; ++i) { bytes32 piece; uint256 pos; unchecked { pos = i * 32; } assembly { piece := mload(add(data, pos)) } if (piece == item) { return i; } } return type(uint256).max; } }