contract BinarySearch { /// Finds the position of _value in the sorted list _data. /// Note that "internal" is important here, because storage references only work for internal or private functions function find(uint256[] storage _data, uint256 _value) internal returns (uint256 o_position) { return find(_data, 0, _data.length, _value); } function find( uint256[] storage _data, uint256 _begin, uint256 _len, uint256 _value ) private returns (uint256 o_position) { if (_len == 0 || (_len == 1 && _data[_begin] != _value)) return type(uint256).max; // failure uint256 halfLen = _len / 2; uint256 v = _data[_begin + halfLen]; if (_value < v) return find(_data, _begin, halfLen, _value); else if (_value > v) return find(_data, _begin + halfLen + 1, halfLen - 1, _value); else return _begin + halfLen; } } contract Store is BinarySearch { uint256[] data; function add(uint256 v) public { data.push(0); data[data.length - 1] = v; } function find(uint256 v) public returns (uint256) { return find(data, v); } } // ==== // compileViaYul: also // ---- // find(uint256): 7 -> -1 // add(uint256): 7 -> // find(uint256): 7 -> 0 // add(uint256): 11 -> // add(uint256): 17 -> // add(uint256): 27 -> // add(uint256): 31 -> // add(uint256): 32 -> // add(uint256): 66 -> // add(uint256): 177 -> // find(uint256): 7 -> 0 // find(uint256): 27 -> 3 // find(uint256): 32 -> 5 // find(uint256): 176 -> -1 // find(uint256): 0 -> -1 // find(uint256): 400 -> -1