internal FMultiRngString(string str, int sidx, int eidx, FMultiRngString next) : this(str, sidx, eidx)
        {
            this.next = next;
            last      = next;

            next.last = null;
        }
            public bool MoveNext()
            {
                if (str == null)
                {
                    str = curr.str;
                }
                else if (++cidx < eidx)
                {
                    FMultiRngString next = curr.next;
                    if (next != null)
                    {
                        curr = next;

                        str =
                            joinCharacter > 0
                            ? null
                            : next.str;

                        cidx = next.sidx;
                        eidx = next.eidx;
                    }
                    else
                    {
                        return(false);
                    }
                }

                return(true);
            }
        public bool ValueEquals(FMultiRngString other)
        {
            if (this == other)
            {
                return(true);
            }
            else if (other == null)
            {
                return(false);
            }

            FMultiRngString left = this;

            do
            {
                if (left.next == null != (other.next == null))
                {
                    return(false);
                }

                if (left.str != other.str ||
                    left.sidx != other.sidx ||
                    left.eidx != other.eidx)
                {
                    return(false);
                }

                left  = left.next;
                other = other.next;
            }while (left != null);

            return(true);
        }
        internal FMultiRngString(string str, int sidx, int eidx)
        {
            this.str  = str;
            this.sidx = sidx;
            this.eidx = eidx;

            next = this;
            last = this;
        }
        private void AddLastInternal(FMultiRngString add)
        {
            FMultiRngString lastNode = last;

            lastNode.next = add;

            last     = add;
            add.last = null;
        }
            public void Reset()
            {
                FMultiRngString first = this.first;

                cidx = first.sidx - 1;
                eidx = first.eidx;
                str  = first.str;

                curr = first;
            }
            public Enumerator(FMultiRngString first, char joinCharacter)
            {
                this.first         = first;
                this.joinCharacter = joinCharacter;

                str  = first.str;
                cidx = first.sidx - 1;
                eidx = first.eidx;

                curr = first;
            }
        public override int GetHashCode()
        {
            int sidx     = this.sidx;
            int hashcode = str.GetFixedHashcode(sidx, eidx - sidx);

            for (FMultiRngString n = next; n != null; n = n.next)
            {
                sidx     = n.sidx;
                hashcode = IntHash.CombineMOD(hashcode, str.GetFixedHashcode(sidx, n.eidx - sidx));
            }

            return(hashcode);
        }
        /// <summary>
        /// Caculate total nodes count & string length
        /// </summary>
        /// <returns>nodes count, total string length</returns>
        public void FullSize(out int nodes, out int totalLength)
        {
            int sidx = this.sidx;
            int eidx = this.eidx;

            int length = eidx - sidx;
            int cnt    = 0;

            FMultiRngString t = next;

            for (; t != null; t = t.next)
            {
                cnt++;
                length += t.eidx - t.sidx;
            }

            nodes       = cnt;
            totalLength = length;
        }
        private void Dispose(bool disposing)
        {
            if (disposing)
            {
                str  = null;
                sidx = 0;
                eidx = 0;
            }

            // 모든 레퍼런스를 삭제
            FMultiRngString p = this;

            while (p.next != null)
            {
                FMultiRngString n = p.next;
                p.next = null;

                p = n;
            }
        }
        public string ToString(char joinCharacter)
        {
            FullSize(out int nodes, out int len);

            StringBuilder sb = new StringBuilder(nodes + len);

            ApeendTo(sb);

            FMultiRngString t = next;

            for (; t != null; t = t.next)
            {
                if (joinCharacter > 0)
                {
                    sb.Append(joinCharacter);
                }

                t.ApeendTo(sb);
            }

            return(sb.ToString());
        }
 public void Dispose()
 {
     first = null;
     curr  = null;
     str   = null;
 }