Submission 3f058ba1...
/**
* This file is part of the 1st Solidity Gas Golfing Contest.
*
* This work is licensed under Creative Commons Attribution ShareAlike 3.0.
* https://creativecommons.org/licenses/by-sa/3.0/
*
* Author: Jordi Baylina
*/
pragma solidity 0.4.24;
contract IndexOf {
/**
* @dev Returns the index of the first occurrence of `needle` in `haystack`,
* or -1 if `needle` is not found in `haystack`.
*
* Input strings may be of any length <2^255.
*
* @param haystack The string to search.
* @param needle The string to search for.
* @return The index of `needle` in `haystack`, or -1 if not found.
*/
function indexOf(string haystack, string needle) external pure returns(int) {
haystack;
needle;
assembly {
let _haystack := add(calldataload(4), 4)
let _needle := add(calldataload(36), 4)
function checkNeedle(haystackP, niddleP, niddleLen, mask) -> found {
found := 1
let niddlePEnd
for {
niddlePEnd := sub(add(niddleP, niddleLen), 31)
} and(lt(niddleP, niddlePEnd), found) {
haystackP := add(haystackP, 32)
niddleP := add(niddleP, 32)
} {
found := eq(calldataload(haystackP), calldataload(niddleP))
}
niddlePEnd := add(niddlePEnd,31)
if and(lt(niddleP, niddlePEnd), found) {
let v1 := and(calldataload(haystackP), mask)
let v2 := and(calldataload(niddleP), mask)
found := eq(v1, v2)
}
}
let needleStart := add(_needle, 32)
let l1 := calldataload(_haystack)
let l2 := calldataload(_needle)
if eq(l2,0) {
mstore(0,0)
return(0,0x20)
}
if eq(l1,0) {
mstore(0,0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
return(0,0x20)
}
if gt(l2, l1) {
mstore(0,0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
return(0,0x20)
}
let mask := not(sub(exp(0x100, sub(32,and(l2, 0x1F))),1))
let c := and(calldataload(add(_needle,1)), 0xff)
c := add(mul(c, 0x100), c)
c := add(mul(c, 0x10000), c)
c := add(mul(c, 0x100000000), c)
c := add(mul(c, 0x10000000000000000), c)
c := add(mul(c, 0x100000000000000000000000000000000), c)
for {
let p := add(_haystack, 32)
let pend := sub(add(p,l1), sub(l2, 1))
} lt(p, pend) {
p := add(p, 32)
} {
let s := calldataload(p)
let x := xor(s,c)
x := or(div(x, 16), x)
x := or(div(x, 4), x)
x := or(div(x, 1), x)
x := and(not(x), 0x0101010101010101010101010101010101010101010101010101010101010101)
if gt(x, 0) {
if gt(and(x, 0xffffffffffffffffffffffffffffffff00000000000000000000000000000000), 0) {
if gt(and(x, 0xffffffffffffffff000000000000000000000000000000000000000000000000), 0) {
if gt(and(x, 0xffffffff00000000000000000000000000000000000000000000000000000000), 0) {
if gt(and(x, 0xffff000000000000000000000000000000000000000000000000000000000000), 0) {
if gt(and(x, 0xff00000000000000000000000000000000000000000000000000000000000000), 0) {
if checkNeedle(p, needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 32))) return(0,0x20) }
}
if gt(and(x, 0x00ff000000000000000000000000000000000000000000000000000000000000), 0) {
if checkNeedle(add(p,1), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 31))) return(0,0x20) }
}
}
if gt(and(x, 0x0000ffff00000000000000000000000000000000000000000000000000000000), 0) {
if gt(and(x, 0x0000ff0000000000000000000000000000000000000000000000000000000000), 0) {
if checkNeedle(add(p,2), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 30))) return(0,0x20) }
}
if gt(and(x, 0x000000ff00000000000000000000000000000000000000000000000000000000), 0) {
if checkNeedle(add(p,3), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 29))) return(0,0x20) }
}
}
}
if gt(and(x, 0x00000000ffffffff000000000000000000000000000000000000000000000000), 0) {
if gt(and(x, 0x00000000ffff0000000000000000000000000000000000000000000000000000), 0) {
if gt(and(x, 0x00000000ff000000000000000000000000000000000000000000000000000000), 0) {
if checkNeedle(add(p,4), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 28))) return(0,0x20) }
}
if gt(and(x, 0x0000000000ff0000000000000000000000000000000000000000000000000000), 0) {
if checkNeedle(add(p,5), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 27))) return(0,0x20) }
}
}
if gt(and(x, 0x000000000000ffff000000000000000000000000000000000000000000000000), 0) {
if gt(and(x, 0x000000000000ff00000000000000000000000000000000000000000000000000), 0) {
if checkNeedle(add(p,6), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 26))) return(0,0x20) }
}
if gt(and(x, 0x00000000000000ff000000000000000000000000000000000000000000000000), 0) {
if checkNeedle(add(p,7), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 25))) return(0,0x20) }
}
}
}
}
if gt(and(x, 0x0000000000000000ffffffffffffffff00000000000000000000000000000000), 0) {
if gt(and(x, 0x0000000000000000ffffffff0000000000000000000000000000000000000000), 0) {
if gt(and(x, 0x0000000000000000ffff00000000000000000000000000000000000000000000), 0) {
if gt(and(x, 0x0000000000000000ff0000000000000000000000000000000000000000000000), 0) {
if checkNeedle(add(p,8), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 24))) return(0,0x20) }
}
if gt(and(x, 0x000000000000000000ff00000000000000000000000000000000000000000000), 0) {
if checkNeedle(add(p,9), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 23))) return(0,0x20) }
}
}
if gt(and(x, 0x00000000000000000000ffff0000000000000000000000000000000000000000), 0) {
if gt(and(x, 0x00000000000000000000ff000000000000000000000000000000000000000000), 0) {
if checkNeedle(add(p,10), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 22))) return(0,0x20) }
}
if gt(and(x, 0x0000000000000000000000ff0000000000000000000000000000000000000000), 0) {
if checkNeedle(add(p,11), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 21))) return(0,0x20) }
}
}
}
if gt(and(x, 0x000000000000000000000000ffffffff00000000000000000000000000000000), 0) {
if gt(and(x, 0x000000000000000000000000ffff000000000000000000000000000000000000), 0) {
if gt(and(x, 0x000000000000000000000000ff00000000000000000000000000000000000000), 0) {
if checkNeedle(add(p,12), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 20))) return(0,0x20) }
}
if gt(and(x, 0x00000000000000000000000000ff000000000000000000000000000000000000), 0) {
if checkNeedle(add(p,13), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 19))) return(0,0x20) }
}
}
if gt(and(x, 0x0000000000000000000000000000ffff00000000000000000000000000000000), 0) {
if gt(and(x, 0x0000000000000000000000000000ff0000000000000000000000000000000000), 0) {
if checkNeedle(add(p,14), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 18))) return(0,0x20) }
}
if gt(and(x, 0x000000000000000000000000000000ff00000000000000000000000000000000), 0) {
if checkNeedle(add(p,15), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 17))) return(0,0x20) }
}
}
}
}
}
if gt(and(x, 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff), 0) {
if gt(and(x, 0x00000000000000000000000000000000ffffffffffffffff0000000000000000), 0) {
if gt(and(x, 0x00000000000000000000000000000000ffffffff000000000000000000000000), 0) {
if gt(and(x, 0x00000000000000000000000000000000ffff0000000000000000000000000000), 0) {
if gt(and(x, 0x00000000000000000000000000000000ff000000000000000000000000000000), 0) {
if checkNeedle(add(p,16), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 16))) return(0,0x20) }
}
if gt(and(x, 0x0000000000000000000000000000000000ff0000000000000000000000000000), 0) {
if checkNeedle(add(p,17), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 15))) return(0,0x20) }
}
}
if gt(and(x, 0x000000000000000000000000000000000000ffff000000000000000000000000), 0) {
if gt(and(x, 0x000000000000000000000000000000000000ff00000000000000000000000000), 0) {
if checkNeedle(add(p,18), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 14))) return(0,0x20) }
}
if gt(and(x, 0x00000000000000000000000000000000000000ff000000000000000000000000), 0) {
if checkNeedle(add(p,19), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 13))) return(0,0x20) }
}
}
}
if gt(and(x, 0x0000000000000000000000000000000000000000ffffffff0000000000000000), 0) {
if gt(and(x, 0x0000000000000000000000000000000000000000ffff00000000000000000000), 0) {
if gt(and(x, 0x0000000000000000000000000000000000000000ff0000000000000000000000), 0) {
if checkNeedle(add(p,20), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 12))) return(0,0x20) }
}
if gt(and(x, 0x000000000000000000000000000000000000000000ff00000000000000000000), 0) {
if checkNeedle(add(p,21), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 11))) return(0,0x20) }
}
}
if gt(and(x, 0x00000000000000000000000000000000000000000000ffff0000000000000000), 0) {
if gt(and(x, 0x00000000000000000000000000000000000000000000ff000000000000000000), 0) {
if checkNeedle(add(p,22), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 10))) return(0,0x20) }
}
if gt(and(x, 0x0000000000000000000000000000000000000000000000ff0000000000000000), 0) {
if checkNeedle(add(p,23), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 9))) return(0,0x20) }
}
}
}
}
if gt(and(x, 0x000000000000000000000000000000000000000000000000ffffffffffffffff), 0) {
if gt(and(x, 0x000000000000000000000000000000000000000000000000ffffffff00000000), 0) {
if gt(and(x, 0x000000000000000000000000000000000000000000000000ffff000000000000), 0) {
if gt(and(x, 0x000000000000000000000000000000000000000000000000ff00000000000000), 0) {
if checkNeedle(add(p,24), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 8))) return(0,0x20) }
}
if gt(and(x, 0x00000000000000000000000000000000000000000000000000ff000000000000), 0) {
if checkNeedle(add(p,25), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 7))) return(0,0x20) }
}
}
if gt(and(x, 0x0000000000000000000000000000000000000000000000000000ffff00000000), 0) {
if gt(and(x, 0x0000000000000000000000000000000000000000000000000000ff0000000000), 0) {
if checkNeedle(add(p,26), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 6))) return(0,0x20) }
}
if gt(and(x, 0x000000000000000000000000000000000000000000000000000000ff00000000), 0) {
if checkNeedle(add(p,27), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 5))) return(0,0x20) }
}
}
}
if gt(and(x, 0x00000000000000000000000000000000000000000000000000000000ffffffff), 0) {
if gt(and(x, 0x00000000000000000000000000000000000000000000000000000000ffff0000), 0) {
if gt(and(x, 0x00000000000000000000000000000000000000000000000000000000ff000000), 0) {
if checkNeedle(add(p,28), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 4))) return(0,0x20) }
}
if gt(and(x, 0x0000000000000000000000000000000000000000000000000000000000ff0000), 0) {
if checkNeedle(add(p,29), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 3))) return(0,0x20) }
}
}
if gt(and(x, 0x000000000000000000000000000000000000000000000000000000000000ffff), 0) {
if gt(and(x, 0x000000000000000000000000000000000000000000000000000000000000ff00), 0) {
if checkNeedle(add(p,30), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 2))) return(0,0x20) }
}
if gt(and(x, 0x00000000000000000000000000000000000000000000000000000000000000ff), 0) {
if checkNeedle(add(p,31), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 1))) return(0,0x20) }
}
}
}
}
}
}
}
mstore(0,0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
return(0,0x20)
}
}
}