-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathAddressSetLib.sol
117 lines (100 loc) · 2.74 KB
/
AddressSetLib.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
pragma solidity ^0.4.10;
/// @title Library implementing an array type which allows O(1) lookups on values.
/// @author Piper Merriam <[email protected]>, Eric Olszewski <[email protected]>
/// Adapted from https://github.com/ethpm/ethereum-indexed-enumerable-set-lib/blob/master/contracts/IndexedEnumerableSetLib.sol
library AddressSetLib {
struct AddressSet {
address[] values;
mapping(address => bool) exists;
mapping(address => uint) indices;
}
modifier inBounds(AddressSet storage self, uint index) {
require(index < self.values.length);
_;
}
modifier notEmpty(AddressSet storage self) {
require(self.values.length != 0);
_;
}
function get(AddressSet storage self, uint index) public constant
inBounds(self, index)
returns (address)
{
return self.values[index];
}
function set(AddressSet storage self, uint index, address value) public
inBounds(self, index)
returns (bool)
{
if (self.exists[value])
return false;
self.values[index] = value;
self.exists[value] = true;
self.indices[value] = index;
return true;
}
function add(AddressSet storage self, address value) public
returns (bool)
{
if (self.exists[value])
return false;
self.indices[value] = self.values.length;
self.values.push(value);
self.exists[value] = true;
return true;
}
function remove(AddressSet storage self, address value) public
returns (bool)
{
if (!self.exists[value])
return false;
uint index = indexOf(self, value);
pop(self, index);
return true;
}
function pop(AddressSet storage self, uint index) public
inBounds(self, index)
returns (address)
{
address value = get(self, index);
if (index != self.values.length - 1) {
address lastValue = last(self);
self.exists[lastValue] = false;
set(self, index, lastValue);
self.indices[lastValue] = index;
}
self.values.length -= 1;
delete self.indices[value];
delete self.exists[value];
return value;
}
function first(AddressSet storage self) public constant
notEmpty(self)
returns (address)
{
return get(self, 0);
}
function last(AddressSet storage self) public constant
notEmpty(self)
returns (address)
{
return get(self, self.values.length - 1);
}
function indexOf(AddressSet storage self, address value) public constant
returns (uint)
{
if (!self.exists[value])
return uint(-1);
return self.indices[value];
}
function contains(AddressSet storage self, address value) public constant
returns (bool)
{
return self.exists[value];
}
function size(AddressSet storage self) public constant
returns (uint)
{
return self.values.length;
}
}