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

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

#2727 completely replace basic array with array mapped trie in ValueTypeArray and descendants

File size: 6.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]
47    protected HistoryArray<T> historyArray;
48
49    [Storable]
50    protected List<string> elementNames;
51    public virtual IEnumerable<string> ElementNames {
52      get { return this.elementNames; }
53      set {
54        if (ReadOnly) throw new NotSupportedException("ElementNames cannot be set. ValueTypeArray is read-only.");
55        if (value == null || !value.Any())
56          elementNames = new List<string>();
57        else if (value.Count() > Length)
58          throw new ArgumentException("The number of element names must not exceed the array length.");
59        else
60          elementNames = new List<string>(value);
61        OnElementNamesChanged();
62      }
63    }
64
65    public virtual int Length {
66      get { return historyArray.Length; }
67      #region Mono Compatibility
68      // this setter should be protected, but the Mono compiler couldn't handle it
69      set {
70        if (ReadOnly) throw new NotSupportedException("Length cannot be set. ValueTypeArray is read-only.");
71        if (value != Length) {
72          historyArray.Resize(value);
73          while (elementNames.Count > value)
74            elementNames.RemoveAt(elementNames.Count - 1);
75          OnElementNamesChanged();
76          OnReset();
77        }
78      }
79      #endregion
80    }
81
82    [Storable]
83    protected bool resizable = true;
84    public bool Resizable {
85      get { return resizable; }
86      set {
87        if (resizable != value) {
88          resizable = value;
89          OnResizableChanged();
90        }
91      }
92    }
93
94
95    public virtual T this[int index] {
96      get { return historyArray[index]; }
97      set {
98        if (ReadOnly) throw new NotSupportedException("Item cannot be set. ValueTypeArray is read-only.");
99        if (!value.Equals(historyArray[index])) {
100          historyArray[index] = value;
101          OnItemChanged(index);
102        }
103      }
104    }
105
106    [Storable]
107    protected bool readOnly;
108    public virtual bool ReadOnly {
109      get { return readOnly; }
110    }
111
112    [StorableHook(HookType.AfterDeserialization)]
113    private void AfterDeserialization() {
114      if (elementNames == null) { elementNames = new List<string>(); }
115    }
116
117    [StorableConstructor]
118    protected ValueTypeArray(bool deserializing) : base(deserializing) { }
119    protected ValueTypeArray(ValueTypeArray<T> original, Cloner cloner)
120      : base(original, cloner) {
121      this.historyArray = (HistoryArray<T>)original.historyArray.Clone();
122      this.readOnly = original.readOnly;
123      this.resizable = original.resizable;
124      this.elementNames = new List<string>(original.elementNames);
125    }
126    protected ValueTypeArray() {
127      historyArray = new HistoryArray<T>(0);
128      readOnly = false;
129      resizable = true;
130      elementNames = new List<string>();
131    }
132    protected ValueTypeArray(int length) {
133      historyArray = new HistoryArray<T>(length);
134      readOnly = false;
135      resizable = true;
136      elementNames = new List<string>();
137    }
138    protected ValueTypeArray(T[] elements) {
139      if (elements == null) throw new ArgumentNullException();
140      historyArray = new HistoryArray<T>(elements);
141      readOnly = false;
142      resizable = true;
143      elementNames = new List<string>();
144    }
145
146    public virtual IValueTypeArray AsReadOnly() {
147      ValueTypeArray<T> readOnlyValueTypeArray = (ValueTypeArray<T>)this.Clone();
148      readOnlyValueTypeArray.readOnly = true;
149      return readOnlyValueTypeArray;
150    }
151
152    public T[] CloneAsArray() {
153      return historyArray.ToArray();
154    }
155
156    public override string ToString() {
157      if (historyArray.Length == 0) return "[]";
158
159      StringBuilder sb = new StringBuilder();
160      sb.Append("[");
161      sb.Append(historyArray[0].ToString());
162      for (int i = 1; i < historyArray.Length; i++) {
163        sb.Append(";").Append(historyArray[i].ToString());
164        if (sb.Length > maximumToStringLength) {
165          sb.Append("...");
166          break;
167        }
168      }
169      sb.Append("]");
170      return sb.ToString();
171    }
172
173    public virtual IEnumerator<T> GetEnumerator() {
174      return historyArray.Cast<T>().GetEnumerator();
175    }
176
177    IEnumerator IEnumerable.GetEnumerator() {
178      return GetEnumerator();
179    }
180
181    public event EventHandler ResizableChanged;
182    protected virtual void OnResizableChanged() {
183      EventHandler handler = ResizableChanged;
184      if (handler != null)
185        handler(this, EventArgs.Empty);
186    }
187    public event EventHandler ElementNamesChanged;
188    protected virtual void OnElementNamesChanged() {
189      EventHandler handler = ElementNamesChanged;
190      if (handler != null)
191        handler(this, EventArgs.Empty);
192    }
193
194    public event EventHandler<EventArgs<int>> ItemChanged;
195    protected virtual void OnItemChanged(int index) {
196      if (ItemChanged != null)
197        ItemChanged(this, new EventArgs<int>(index));
198      if (index < maximumToStringLength)
199        OnToStringChanged();
200    }
201    public event EventHandler Reset;
202    protected virtual void OnReset() {
203      if (Reset != null)
204        Reset(this, EventArgs.Empty);
205      OnToStringChanged();
206    }
207  }
208}
Note: See TracBrowser for help on using the repository browser.