Mercurial > pub > ImplabNet
diff Implab/Automaton/EnumAlphabet.cs @ 164:ec35731ae299 ref20160224
Almost complete DFA refactoring
author | cin |
---|---|
date | Thu, 25 Feb 2016 02:11:13 +0300 |
parents | 0526412bbb26 |
children | c32688129f14 |
line wrap: on
line diff
--- a/Implab/Automaton/EnumAlphabet.cs Wed Feb 24 20:12:52 2016 +0300 +++ b/Implab/Automaton/EnumAlphabet.cs Thu Feb 25 02:11:13 2016 +0300 @@ -12,46 +12,49 @@ /// <typeparam name="T">Тип перечислений</typeparam> public class EnumAlphabet<T> : IndexedAlphabetBase<T> where T : struct, IConvertible { [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")] - static readonly T[] _symbols; - static readonly EnumAlphabet<T> _fullAlphabet; + static readonly Lazy<T[]> _symbols = new Lazy<T[]>(GetSymbols); + + [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")] + static readonly Lazy<EnumAlphabet<T>> _fullAlphabet = new Lazy<EnumAlphabet<T>>(CreateEnumAlphabet); + + static EnumAlphabet<T> CreateEnumAlphabet() { + var symbols = _symbols.Value; - [SuppressMessage("Microsoft.Design", "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] - static EnumAlphabet() { + if ( + symbols[symbols.Length - 1].ToInt32(CultureInfo.InvariantCulture) >= symbols.Length + || symbols[0].ToInt32(CultureInfo.InvariantCulture) != 0 + ) + throw new InvalidOperationException("The specified enumeration must be zero-based and continuously numbered"); + + return new EnumAlphabet<T>(symbols.Select(x => x.ToInt32(CultureInfo.InvariantCulture)).ToArray()); + } + + static T[] GetSymbols() { if (!typeof(T).IsEnum) throw new InvalidOperationException("Invalid generic parameter, enumeration is required"); if (Enum.GetUnderlyingType(typeof(T)) != typeof(Int32)) throw new InvalidOperationException("Only enums based on Int32 are supported"); - - _symbols = ((T[])Enum.GetValues(typeof(T))) + + return ((T[])Enum.GetValues(typeof(T))) .OrderBy(x => x.ToInt32(CultureInfo.InvariantCulture)) .ToArray(); - - if ( - _symbols[_symbols.Length - 1].ToInt32(CultureInfo.InvariantCulture) >= _symbols.Length - || _symbols[0].ToInt32(CultureInfo.InvariantCulture) != 0 - ) - throw new InvalidOperationException("The specified enumeration must be zero-based and continuously numbered"); - - _fullAlphabet = new EnumAlphabet<T>(_symbols.Select(x => x.ToInt32(CultureInfo.InvariantCulture)).ToArray()); } - - public static EnumAlphabet<T> FullAlphabet { get { - return _fullAlphabet; + return _fullAlphabet.Value; } } public EnumAlphabet() - : base(_symbols.Length) { + : base(_symbols.Value.Length) { } public EnumAlphabet(int[] map) : base(map) { - Debug.Assert(map.Length == _symbols.Length); + Debug.Assert(map.Length == _symbols.Value.Length); } @@ -60,7 +63,7 @@ } public override IEnumerable<T> InputSymbols { - get { return _symbols; } + get { return _symbols.Value; } } }