pragma solidity ^0.4.24; contract test { mapping (uint256 => uint256[]) setIds; function insert(uint256 id, address addr) external returns (uint256) { uint256 temp = uint256(addr); uint256 memberIndex = getSetLength(id); for (uint i = 0; i < setIds[id].length; i++) { require(addr != address(setIds[id][i])); } temp |= memberIndex<<160; setIds[id].push(temp); return memberIndex; } function contains(uint256 setId, address addr) public view returns(uint96 memberIndex, address id, bool doesContain) { for (uint96 i = 0; i < setIds[setId].length; i++) { if (addr == address(setIds[setId][i])) { id = address(setIds[setId][i]); memberIndex = uint96(setIds[setId][i]>>160); doesContain = true; } else { doesContain = false; } } } function remove(uint256 setId, address addr) external { for (uint96 i = 0; i < setIds[setId].length; i++) { if (addr == address(setIds[setId][i])) { delete setIds[setId][i]; } } } function getSetLength(uint256 setId) public view returns (uint256) { return setIds[setId].length; } function deleteSet(uint256 setId) external returns (bool didDelete) { delete setIds[setId]; didDelete = true; } } /*/ library AddressSet { struct Set { address[] members; mapping(address => uint) memberIndices; } /// @dev Inserts an element into a set. If the element already exists in the set, the function is a no-op. /// @param self The set to insert into. /// @param other The element to insert. function insert(Set storage self, address other) public { if (!contains(self, other)) { self.memberIndices[other] = self.members.push(other); } } /// @dev Removes an element from a set. If the element does not exist in the set, the function is a no-op. /// @param self The set to remove from. /// @param other The element to remove. function remove(Set storage self, address other) public { if (contains(self, other)) { // replace other with the last element self.members[self.memberIndices[other] - 1] = self.members[length(self) - 1]; // reflect this change in the indices self.memberIndices[self.members[self.memberIndices[other] - 1]] = self.memberIndices[other]; delete self.memberIndices[other]; // remove the last element self.members.length--; } } /// @dev Checks set membership. /// @param self The set to check membership in. /// @param other The element to check membership of. /// @return true if the element is in the set, false otherwise. function contains(Set storage self, address other) public view returns (bool) { return ( // solium-disable-line operator-whitespace self.memberIndices[other] > 0 && self.members.length >= self.memberIndices[other] && self.members[self.memberIndices[other] - 1] == other ); } /// @dev Returns the number of elements in a set. /// @param self The set to check the length of. /// @return The number of elements in the set. function length(Set storage self) public view returns (uint) { return self.members.length; } } contract AddressSetTest { using AddressSet for AddressSet.Set; AddressSet.Set internal mySet; function insert(address other) public { mySet.insert(other); } function remove(address other) public { mySet.remove(other); } function contains(address other) public view returns (bool) { return mySet.contains(other); } function length() public view returns (uint) { return mySet.length(); } function members() public view returns (address[]) { return mySet.members; } function reset() public { delete mySet; } } /*/ //pack address w/member index of type uint96 //store as uint256 //map address => uintid //insert //check <160bit == address //append array
0.4.24