예제 #1
0
 public EnumMember CreateEnumMember(EnumMember <TInt, TIntProvider> member)
 {
     return(new UntypedEnumMember <TInt, TIntProvider>(member));
 }
예제 #2
0
 internal bool TryParse([NotNull] string formattedValue, bool ignoreCase, out EnumMember <TInt, TIntProvider> result)
 {
     return(_formatValueMap.TryGetValue(formattedValue, out result) || ignoreCase && FormatIgnoreCase.TryGetValue(formattedValue, out result));
 }
예제 #3
0
        public EnumCache([NotNull] Type enumType, [NotNull] IEnumInfo <TInt, TIntProvider> enumInfo)
        {
            if (!enumType.IsEnum)
            {
                throw new NotEnumTypeException(enumType);
            }
            _enumTypeName       = enumType.Name;
            EnumInfo            = enumInfo;
            _hasCustomValidator = enumInfo.HasCustomValidator;
            IsFlagEnum          = enumType.IsDefined(typeof(FlagsAttribute), false);

            FieldInfo[] fields = enumType.GetFields(BindingFlags.Public | BindingFlags.Static);
            _valueMap = new Dictionary <TInt, EnumMember <TInt, TIntProvider> >(fields.Length);
            if (fields.Length == 0)
            {
                return;
            }
            List <EnumMember <TInt, TIntProvider> > duplicateValues = null;

            // This is necessary due to a .NET reflection bug with retrieving Boolean Enums values
            Dictionary <string, TInt> fieldDictionary = null;
            bool isBoolean = typeof(TInt) == typeof(bool);

            if (isBoolean)
            {
                fieldDictionary = new Dictionary <string, TInt>();
                TInt[]   values = (TInt[])Enum.GetValues(enumType);
                string[] names  = Enum.GetNames(enumType);

                for (int i = 0; i < names.Length; ++i)
                {
                    fieldDictionary.Add(names[i], values[i]);
                }
            }

            foreach (FieldInfo field in fields)
            {
                string name  = field.Name;
                TInt   value = isBoolean
                                                                ? fieldDictionary[name]
                                                                : (TInt)field.GetValue(null);
                Collections.AttributeCollection attributes = new Collections.AttributeCollection(Attribute.GetCustomAttributes(field, false));
                EnumMember <TInt, TIntProvider> member     = new EnumMember <TInt, TIntProvider>(value, name, attributes, this);

                if (_valueMap.TryGetValue(value, out EnumMember <TInt, TIntProvider> existing))
                {
                    if (attributes.Has <PrimaryEnumMemberAttribute>())
                    {
                        _valueMap[value] = member;
                        member           = existing;
                    }

                    (duplicateValues ??= new List <EnumMember <TInt, TIntProvider> >()).Add(member);
                }
                else
                {
                    _valueMap.Add(value, member);
                    // Is Power of Two
                    if (Provider.BitCount(value) == 1)
                    {
                        AllFlags = Provider.Or(AllFlags, value);
                    }
                }
            }

            bool isInOrder = true;
            TInt previous  = default(TInt);
            bool isFirst   = true;

            foreach (TInt key in _valueMap.Select(pair => pair.Key))
            {
                if (isFirst)
                {
                    _minDefined = key;
                    isFirst     = false;
                }
                else if (previous.IsGreaterThan(key))
                {
                    isInOrder = false;
                    break;
                }

                previous = key;
            }

            if (isInOrder)
            {
                _maxDefined = previous;
            }
            else
            {
                // Makes sure is in increasing value order, due to no removals
                KeyValuePair <TInt, EnumMember <TInt, TIntProvider> >[] values = _valueMap.ToArray();
                Array.Sort(values, (first, second) => first.Key.CompareTo(second.Key));
                _valueMap = new Dictionary <TInt, EnumMember <TInt, TIntProvider> >(_valueMap.Count);

                foreach (KeyValuePair <TInt, EnumMember <TInt, TIntProvider> > pair in values)
                {
                    _valueMap.Add(pair.Key, pair.Value);
                }

                _maxDefined = values[values.Length - 1].Key;
                _minDefined = values[0].Key;
            }

            _isContiguous = Provider.Subtract(_maxDefined, Provider.Create(_valueMap.Count - 1)).Equals(_minDefined);

            if (duplicateValues == null)
            {
                return;
            }
            duplicateValues.TrimExcess();
            // Makes sure is in increasing order
            duplicateValues.Sort((first, second) => first.Value.CompareTo(second.Value));
            _duplicateValues          = duplicateValues;
            _duplicateValues.Capacity = _duplicateValues.Count;
        }
예제 #4
0
 internal UntypedEnumMember(EnumMember <TInt, TIntProvider> member)
     : base(member)
 {
 }