コード例 #1
0
            public Enumerator(XDictionary <TKey, TValue> content)
            {
                this.content = content;

                number = 0;
                index  = -1;
            }
コード例 #2
0
 internal ValuesCollection(XDictionary <TKey, TValue> content, TKey key)
 {
     this.content = content;
     this.key     = key;
     hashCode     = content.GetHashCode(key);
     length       = -1;
 }
コード例 #3
0
ファイル: EmitHelper.cs プロジェクト: zxbe/Swifter
        private static void SwitchObject <T>(this ILGenerator ILGen,
                                             Action <ILGenerator> LdcValue,
                                             LocalBuilder HashCodeLocal,
                                             Action <ILGenerator> CallEquals,
                                             XDictionary <int, List <CaseInfo <T> > > Cases,
                                             Label DefaultLabel,
                                             Action <ILGenerator, T> ldcCase,
                                             int Begin,
                                             int Index,
                                             int End)
        {
            if (Begin > End)
            {
                return;
            }

            if (Begin == End)
            {
                ILGen.LoadLocal(HashCodeLocal);
                ILGen.LoadConstant(Cases.GetEntry(Begin).Key);
                ILGen.Emit(OpCodes.Bne_Un, DefaultLabel);

                foreach (var Item in Cases.GetEntry(Begin).Value)
                {
                    LdcValue(ILGen);
                    ldcCase(ILGen, Item.Value);
                    CallEquals(ILGen);
                    ILGen.Emit(OpCodes.Brtrue, Item.Label);
                }

                ILGen.Emit(OpCodes.Br, DefaultLabel);

                return;
            }

            if (Begin + 1 == End)
            {
                var EndLabel = ILGen.DefineLabel();

                ILGen.LoadLocal(HashCodeLocal);
                ILGen.LoadConstant(Cases.GetEntry(Begin).Key);
                ILGen.Emit(OpCodes.Bne_Un, EndLabel);

                foreach (var Item in Cases.GetEntry(Begin).Value)
                {
                    LdcValue(ILGen);
                    ldcCase(ILGen, Item.Value);
                    CallEquals(ILGen);
                    ILGen.Emit(OpCodes.Brtrue, Item.Label);
                }


                ILGen.MarkLabel(EndLabel);

                ILGen.LoadLocal(HashCodeLocal);
                ILGen.LoadConstant(Cases.GetEntry(End).Key);
                ILGen.Emit(OpCodes.Bne_Un, DefaultLabel);

                foreach (var Item in Cases.GetEntry(End).Value)
                {
                    LdcValue(ILGen);
                    ldcCase(ILGen, Item.Value);
                    CallEquals(ILGen);
                    ILGen.Emit(OpCodes.Brtrue, Item.Label);
                }

                ILGen.Emit(OpCodes.Br, DefaultLabel);

                return;
            }

            var GtLabel = ILGen.DefineLabel();

            ILGen.LoadLocal(HashCodeLocal);
            ILGen.LoadConstant(Cases.GetEntry(Index).Key);
            ILGen.Emit(OpCodes.Bgt, GtLabel);

            SwitchObject(
                ILGen,
                LdcValue,
                HashCodeLocal,
                CallEquals,
                Cases,
                DefaultLabel,
                ldcCase,
                Begin,
                (Begin + Index) / 2,
                Index);

            ILGen.MarkLabel(GtLabel);

            SwitchObject(
                ILGen,
                LdcValue,
                HashCodeLocal,
                CallEquals,
                Cases,
                DefaultLabel,
                ldcCase,
                Index + 1,
                (Index + 1 + End) / 2,
                End);
        }
コード例 #4
0
ファイル: EmitHelper.cs プロジェクト: zxbe/Swifter
        /// <summary>
        /// 生成指定类型的 Switch 代码块。
        /// </summary>
        /// <typeparam name="T">指定类型</typeparam>
        /// <param name="iLGen">ILGenerator IL 指令生成器</param>
        /// <param name="emitLdcValue">生成加载 Switch 参数的指令的委托</param>
        /// <param name="getHashCodeMethod">获取 HashCode 值的方法,参数签名: int(T)</param>
        /// <param name="equalsMethod">比例两个值的方法,参数签名: bool (T, T)</param>
        /// <param name="cases">case 标签块集合</param>
        /// <param name="defaultLabel">默认标签块</param>
        /// <param name="ldcCaseValue">生成加载指定 Case 块值的指定的委托</param>
        public static void Switch <T>(this ILGenerator iLGen,
                                      Action <ILGenerator> emitLdcValue,
                                      MethodInfo getHashCodeMethod,
                                      MethodInfo equalsMethod,
                                      CaseInfo <T>[] cases,
                                      Label defaultLabel,
                                      Action <ILGenerator, T> ldcCaseValue)
        {
            cases = (CaseInfo <T>[])cases.Clone();

            if (getHashCodeMethod.IsStatic)
            {
                for (int i = 0; i < cases.Length; i++)
                {
                    cases[i].HashCode = (int)getHashCodeMethod.Invoke(null, new object[] { cases[i].Value });
                }
            }
            else
            {
                for (int i = 0; i < cases.Length; i++)
                {
                    cases[i].HashCode = (int)getHashCodeMethod.Invoke(cases[i].Value, null);
                }
            }

            Array.Sort(cases);

            var GroupedCases = new XDictionary <int, List <CaseInfo <T> > >();

            foreach (var Item in cases)
            {
                List <CaseInfo <T> > Items;

                GroupedCases.TryGetValue(Item.HashCode, out Items);

                if (Items == null)
                {
                    Items = new List <CaseInfo <T> >();

                    Items.Add(Item);

                    GroupedCases.Add(Item.HashCode, Items);
                }
                else
                {
                    Items.Add(Item);
                }
            }

            var HashCodeLocal = iLGen.DeclareLocal(typeof(int));

            emitLdcValue(iLGen);
            iLGen.Emit(OpCodes.Call, getHashCodeMethod);
            iLGen.StoreLocal(HashCodeLocal);

            SwitchObject(
                iLGen,
                emitLdcValue,
                HashCodeLocal,
                (EqILGen) =>
            {
                EqILGen.Emit(OpCodes.Call, equalsMethod);
            },
                GroupedCases,
                defaultLabel,
                ldcCaseValue,
                0,
                (GroupedCases.Count - 1) / 2,
                GroupedCases.Count - 1);
        }