source: branches/PersistentDataStructures/HeuristicLab.Data/3.3/ValueTypeArray.cs @ 14657

Last change on this file since 14657 was 14657, checked in by epitzer, 4 years ago

#2727 add generic MetaInfo to AMT e.g. for tracking Count in facades

File size: 7.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections;
24using System.Collections.Generic;
25using System.Drawing;
26using System.Linq;
27using System.Text;
28using HeuristicLab.Common;
29using HeuristicLab.Core;
30using HeuristicLab.Data.PersistentDataStructures.Adaptations;
31using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32
33namespace HeuristicLab.Data {
34  [Item("ValueTypeArray", "An abstract base class for representing arrays of value types.")]
35  [StorableClass]
36  public abstract class ValueTypeArray<T> : Item, IValueTypeArray<T> where T : struct {
37    private const int maximumToStringLength = 100;
38
39    public static new Image StaticItemImage {
40      get { return HeuristicLab.Common.Resources.VSImageLibrary.Class; }
41    }
42
43    [Storable(AllowOneWay = true, Name = "array")]
44    protected T[] oldArrayValuePersistence { set { historyArray = new HistoryArray<T>(value); } }
45
46    [Storable(AllowOneWay = true, Name = "elementNames")]
47    protected List<string> oldElementNamesValuePersistence { set { historyElementNames = new HistoryList<string>(value); } }
48
49    [Storable]
50    protected HistoryArray<T> historyArray;
51
52    [Storable]
53    protected HistoryList<string> historyElementNames;
54
55    public virtual IEnumerable<string> ElementNames {
56      get { return this.historyElementNames; }
57      set {
58        if (ReadOnly) throw new NotSupportedException("ElementNames cannot be set. ValueTypeArray is read-only.");
59        if (value == null || !value.Any())
60          historyElementNames = new HistoryList<string>();
61        else if (value.Count() > Length)
62          throw new ArgumentException("The number of element names must not exceed the array length.");
63        else
64          historyElementNames = new HistoryList<string>(value);
65        OnElementNamesChanged();
66      }
67    }
68
69    public virtual int Length {
70      get { return historyArray.Length; }
71      #region Mono Compatibility
72      // this setter should be protected, but the Mono compiler couldn't handle it
73      set {
74        if (ReadOnly) throw new NotSupportedException("Length cannot be set. ValueTypeArray is read-only.");
75        if (value != Length) {
76          historyArray.Resize(value);
77          while (historyElementNames.Count > value)
78            historyElementNames.RemoveAt(historyElementNames.Count - 1);
79          OnElementNamesChanged();
80          OnReset();
81        }
82      }
83      #endregion
84    }
85
86    [Storable]
87    protected bool resizable = true;
88    public bool Resizable {
89      get { return resizable; }
90      set {
91        if (resizable != value) {
92          resizable = value;
93          OnResizableChanged();
94        }
95      }
96    }
97
98
99    public virtual T this[int index] {
100      get { return historyArray[index]; }
101      set {
102        if (ReadOnly) throw new NotSupportedException("Item cannot be set. ValueTypeArray is read-only.");
103        if (!value.Equals(historyArray[index])) {
104          historyArray[index] = value;
105          OnItemChanged(index);
106        }
107      }
108    }
109
110    [Storable]
111    protected bool readOnly;
112    public virtual bool ReadOnly {
113      get { return readOnly; }
114    }
115
116    [StorableHook(HookType.AfterDeserialization)]
117    private void AfterDeserialization() {
118      if (historyElementNames == null) { historyElementNames = new HistoryList<string>(); }
119    }
120
121    [StorableConstructor]
122    protected ValueTypeArray(bool deserializing) : base(deserializing) { }
123    protected ValueTypeArray(ValueTypeArray<T> original, Cloner cloner)
124      : base(original, cloner) {
125      this.historyArray = (HistoryArray<T>)original.historyArray.Clone();
126      this.readOnly = original.readOnly;
127      this.resizable = original.resizable;
128      this.historyElementNames = (HistoryList<string>)original.historyElementNames.Clone();
129    }
130    protected ValueTypeArray() {
131      historyArray = new HistoryArray<T>(0);
132      readOnly = false;
133      resizable = true;
134      historyElementNames = new HistoryList<string>();
135    }
136    protected ValueTypeArray(int length) {
137      historyArray = new HistoryArray<T>(length);
138      readOnly = false;
139      resizable = true;
140      historyElementNames = new HistoryList<string>();
141    }
142    protected ValueTypeArray(T[] elements) {
143      if (elements == null) throw new ArgumentNullException();
144      historyArray = new HistoryArray<T>(elements);
145      readOnly = false;
146      resizable = true;
147      historyElementNames = new HistoryList<string>();
148    }
149    private ValueTypeArray(HistoryArray<T> values, HistoryList<string> historyElementNames) {
150      this.historyArray = values;
151      this.historyElementNames = historyElementNames;
152    }
153
154    public virtual IValueTypeArray AsReadOnly() {
155      ValueTypeArray<T> readOnlyValueTypeArray = (ValueTypeArray<T>)this.Clone();
156      readOnlyValueTypeArray.readOnly = true;
157      return readOnlyValueTypeArray;
158    }
159
160    public T[] CloneAsArray() {
161      return historyArray.ToArray();
162    }
163
164    public override string ToString() {
165      if (historyArray.Length == 0) return "[]";
166
167      StringBuilder sb = new StringBuilder();
168      sb.Append("[");
169      sb.Append(historyArray[0].ToString());
170      for (int i = 1; i < historyArray.Length; i++) {
171        sb.Append(";").Append(historyArray[i].ToString());
172        if (sb.Length > maximumToStringLength) {
173          sb.Append("...");
174          break;
175        }
176      }
177      sb.Append("]");
178      return sb.ToString();
179    }
180
181    public virtual IEnumerator<T> GetEnumerator() {
182      return historyArray.Cast<T>().GetEnumerator();
183    }
184
185    IEnumerator IEnumerable.GetEnumerator() {
186      return GetEnumerator();
187    }
188
189    public event EventHandler ResizableChanged;
190    protected virtual void OnResizableChanged() {
191      EventHandler handler = ResizableChanged;
192      if (handler != null)
193        handler(this, EventArgs.Empty);
194    }
195    public event EventHandler ElementNamesChanged;
196    protected virtual void OnElementNamesChanged() {
197      EventHandler handler = ElementNamesChanged;
198      if (handler != null)
199        handler(this, EventArgs.Empty);
200    }
201
202    public event EventHandler<EventArgs<int>> ItemChanged;
203    protected virtual void OnItemChanged(int index) {
204      if (ItemChanged != null)
205        ItemChanged(this, new EventArgs<int>(index));
206      if (index < maximumToStringLength)
207        OnToStringChanged();
208    }
209    public event EventHandler Reset;
210    protected virtual void OnReset() {
211      if (Reset != null)
212        Reset(this, EventArgs.Empty);
213      OnToStringChanged();
214    }
215
216    public void CreateSnapshot() {
217      historyArray.CreateSnapshot();
218      historyElementNames.CreateSnapshot();
219    }
220
221    public IEnumerable<ValueTypeArray<T>> GetHistory() {
222      foreach (var vta in historyArray.GetHistory().Zip(historyElementNames.GetHistory(), (v, n) => new {v, n})) {
223        var clone = (ValueTypeArray<T>)Clone();
224        clone.historyArray = vta.v;
225        clone.historyElementNames = vta.n;
226        yield return clone;
227      }
228    }
229  }
230}
Note: See TracBrowser for help on using the repository browser.