1 package org.djunits.value;
2
3 import org.djunits.unit.Unit;
4 import org.djunits.value.base.Scalar;
5 import org.djunits.value.storage.Storage;
6 import org.djunits.value.storage.StorageType;
7 import org.djutils.exceptions.Throw;
8
9
10
11
12
13
14
15
16
17
18
19
20
21 public abstract class IndexedValue<U extends Unit<U>, S extends Scalar<U, S>,
22 T extends IndexedValue<U, S, T, D>, D extends Storage<D>> implements Value<U, T>
23 {
24
25 private static final long serialVersionUID = 20190927L;
26
27
28 private U displayUnit;
29
30
31 private boolean copyOnWrite = false;
32
33
34 private boolean mutable = false;
35
36
37
38
39
40 public IndexedValue(final U displayUnit)
41 {
42 Throw.whenNull(displayUnit, "display unit cannot be null");
43 this.displayUnit = displayUnit;
44 }
45
46 @Override
47 public final U getDisplayUnit()
48 {
49 return this.displayUnit;
50 }
51
52 @Override
53 public void setDisplayUnit(final U newUnit)
54 {
55 Throw.whenNull(newUnit, "newUnit may not be null");
56 this.displayUnit = newUnit;
57 }
58
59
60
61
62
63 protected abstract D getData();
64
65
66
67
68
69 protected abstract void setData(D data);
70
71
72
73
74
75 public final StorageType getStorageType()
76 {
77 return getData().getStorageType();
78 }
79
80
81
82
83
84 protected final void checkCopyOnWrite()
85 {
86 Throw.when(!this.mutable, ValueRuntimeException.class, "Immutable Vector cannot be modified");
87 if (isCopyOnWrite())
88 {
89 setData(getData().copy());
90 setCopyOnWrite(false);
91 }
92 }
93
94
95
96
97
98 protected final boolean isCopyOnWrite()
99 {
100 return this.copyOnWrite;
101 }
102
103
104
105
106
107 protected final void setCopyOnWrite(final boolean copyOnWrite)
108 {
109 this.copyOnWrite = copyOnWrite;
110 }
111
112
113
114
115
116 public final boolean isMutable()
117 {
118 return this.mutable;
119 }
120
121
122
123
124
125 protected final void setMutable(final boolean mutable)
126 {
127 this.mutable = mutable;
128 }
129
130
131
132
133
134 public final T immutable()
135 {
136 if (isMutable())
137 {
138 setCopyOnWrite(true);
139 }
140 T result = clone();
141 result.setCopyOnWrite(false);
142 result.setMutable(false);
143 return result;
144 }
145
146
147
148
149
150 public final T mutable()
151 {
152 if (isMutable())
153 {
154 setCopyOnWrite(true);
155 }
156 T result = clone();
157 result.setCopyOnWrite(true);
158 result.setMutable(true);
159 return result;
160 }
161
162
163
164
165
166 public final boolean isDense()
167 {
168 return getData().isDense();
169 }
170
171
172
173
174
175 public final boolean isSparse()
176 {
177 return getData().isSparse();
178 }
179
180
181
182
183
184 public final int cardinality()
185 {
186 return getData().cardinality();
187 }
188
189
190
191
192
193
194 public abstract T toDense();
195
196
197
198
199
200
201 public abstract T toSparse();
202
203
204
205
206
207 public abstract Class<S> getScalarClass();
208
209 @SuppressWarnings("unchecked")
210 @Override
211 public T clone()
212 {
213 try
214 {
215 T result = (T) super.clone();
216 result.setData(getData().copy());
217 result.setCopyOnWrite(false);
218 return result;
219 }
220 catch (CloneNotSupportedException exception)
221 {
222 throw new RuntimeException(exception);
223 }
224 }
225
226 }