/*
 * Copyright (c) 1997
 * Silicon Graphics Computer Systems, Inc.
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Silicon Graphics makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 */

/* NOTE: This is an internal header file, included by other STL headers.
 *   You should not attempt to use it directly.
 */

# include <stdio.h>
# include <iostream.h>

__STL_BEGIN_NAMESPACE

#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
#pragma set woff 1174
#endif

// Set buf_start, buf_end, and buf_ptr appropriately, filling tmp_buf
// if necessary.  Assumes path_end[leaf_index] and leaf_pos are correct.
// Results in a valid buf_ptr if the iterator can be legitimately
// dereferenced.
template <class charT, class Alloc>
void __rope_iterator_base<charT,Alloc>::setbuf
(__rope_iterator_base<charT,Alloc> &x)
{
    const RopeBase * leaf = x.path_end[x.leaf_index];
    size_t leaf_pos = x.leaf_pos;
    size_t pos = x.current_pos;

    switch(leaf -> tag) {
	case RopeBase::leaf:
	    x.buf_start = ((__rope_RopeLeaf<charT,Alloc> *)leaf) -> data;
	    x.buf_ptr = x.buf_start + (pos - leaf_pos);
	    x.buf_end = x.buf_start + leaf -> size;
	    break;
	case RopeBase::function:
	case RopeBase::substringfn:
	    {
		size_t len = iterator_buf_len;
		size_t buf_start_pos = leaf_pos;
		size_t leaf_end = leaf_pos + leaf -> size;
		char_producer<charT> *fn =
			((__rope_RopeFunction<charT,Alloc> *)leaf) -> fn;

		if (buf_start_pos + len <= pos) {
		    buf_start_pos = pos - len/4;
		    if (buf_start_pos + len > leaf_end) {
			buf_start_pos = leaf_end - len;
		    }
		}
		if (buf_start_pos + len > leaf_end) {
		    len = leaf_end - buf_start_pos;
		}
		(*fn)(buf_start_pos - leaf_pos, len, x.tmp_buf);
		x.buf_ptr = x.tmp_buf + (pos - buf_start_pos);
		x.buf_start = x.tmp_buf;
		x.buf_end = x.tmp_buf + len;
	    }
	    break;
	default:
	    __stl_assert(0);
    }
}

// Set path and buffer inside a rope iterator.  We assume that 
// pos and root are already set.
template <class charT, class Alloc>
void __rope_iterator_base<charT,Alloc>::setcache
(__rope_iterator_base<charT,Alloc> &x)
{
    const RopeBase * path[RopeBase::max_rope_depth+1];
    const RopeBase * curr_rope;
    int curr_depth = -1;  /* index into path    */
    size_t curr_start_pos = 0;
    size_t pos = x.current_pos;
    unsigned char dirns = 0;	// Bit vector indicating right turns in the path

    __stl_assert(pos <= x.root -> size);
    if (pos >= x.root -> size) {
	x.buf_ptr = 0;
	return;
    }
    curr_rope = x.root;
    if (0 != curr_rope -> c_string) {
	/* Treat the root as a leaf. */
	x.buf_start = curr_rope -> c_string;
	x.buf_end = curr_rope -> c_string + curr_rope -> size;
	x.buf_ptr = curr_rope -> c_string + pos;
	x.path_end[0] = curr_rope;
	x.leaf_index = 0;
	x.leaf_pos = 0;
	return;
    }
    for(;;) {
	++curr_depth;
	__stl_assert(curr_depth <= RopeBase::max_rope_depth);
	path[curr_depth] = curr_rope;
	switch(curr_rope -> tag) {
	  case RopeBase::leaf:
	  case RopeBase::function:
	  case RopeBase::substringfn:
	    x.leaf_pos = curr_start_pos;
	    goto done;
	  case RopeBase::concat:
	    {
		__rope_RopeConcatenation<charT,Alloc> *c =
			(__rope_RopeConcatenation<charT,Alloc> *)curr_rope;
		RopeBase * left = c -> left;
		size_t left_len = left -> size;
		
		dirns <<= 1;
		if (pos >= curr_start_pos + left_len) {
		    dirns |= 1;
		    curr_rope = c -> right;
		    curr_start_pos += left_len;
		} else {
		    curr_rope = left;
		}
	    }
	    break;
	}
    }
  done:
    // Copy last section of path into path_end.
      {
	int i = -1;
	int j = curr_depth  + 1 - path_cache_len;

	if (j < 0) j = 0;
	while (j <= curr_depth) {
	    x.path_end[++i] = path[j++];
	}
	x.leaf_index = i;
      }
      x.path_directions = dirns;
    setbuf(x);
}

// Specialized version of the above.  Assumes that
// the path cache is valid for the previous position.
template <class charT, class Alloc>
void __rope_iterator_base<charT,Alloc>::setcache_for_incr
(__rope_iterator_base<charT,Alloc> &x)
{
    int current_index = x.leaf_index;
    const RopeBase * current_node = x.path_end[current_index];
    size_t len = current_node -> size;
    size_t node_start_pos = x.leaf_pos;
    unsigned char dirns = x.path_directions;
    __rope_RopeConcatenation<charT,Alloc> * c;

    __stl_assert(x.current_pos <= x.root -> size);
    if (x.current_pos - node_start_pos < len) {
	/* More stuff in this leaf, we just didn't cache it. */
	setbuf(x);
	return;
    }
    __stl_assert(node_start_pos + len == x.current_pos);
    //  node_start_pos is starting position of last_node.
    while (--current_index >= 0) {
	if (!(dirns & 1) /* Path turned left */) break;
	current_node = x.path_end[current_index];
	c = (__rope_RopeConcatenation<charT,Alloc> *)current_node;
	// Otherwise we were in the right child.  Thus we should pop
	// the concatenation node.
	node_start_pos -= c -> left -> size;
	dirns >>= 1;
    }
    if (current_index < 0) {
	// We underflowed the cache. Punt.
	setcache(x);
	return;
    }
    current_node = x.path_end[current_index];
    c = (__rope_RopeConcatenation<charT,Alloc> *)current_node;
    // current_node is a concatenation node.  We are positioned on the first
    // character in its right child.
    // node_start_pos is starting position of current_node.
    node_start_pos += c -> left -> size;
    current_node = c -> right;
    x.path_end[++current_index] = current_node;
    dirns |= 1;
    while (RopeBase::concat == current_node -> tag) {
	++current_index;
	if (path_cache_len == current_index) {
	    int i;
	    for (i = 0; i < path_cache_len-1; i++) {
		x.path_end[i] = x.path_end[i+1];
	    }
	    --current_index;
	}
	current_node =
	    ((__rope_RopeConcatenation<charT,Alloc> *)current_node) -> left;
	x.path_end[current_index] = current_node;
	dirns <<= 1;
	// node_start_pos is unchanged.
    }
    x.leaf_index = current_index;
    x.leaf_pos = node_start_pos;
    x.path_directions = dirns;
    setbuf(x);
}

template <class charT, class Alloc>
void __rope_iterator_base<charT,Alloc>::incr(size_t n) {
    current_pos += n;
    if (0 != buf_ptr) {
        size_t chars_left = buf_end - buf_ptr;
        if (chars_left > n) {
            buf_ptr += n;
        } else if (chars_left == n) {
            buf_ptr += n;
            setcache_for_incr(*this);
        } else {
            buf_ptr = 0;
        }
    }
}

template <class charT, class Alloc>
void __rope_iterator_base<charT,Alloc>::decr(size_t n) {
    if (0 != buf_ptr) {
        size_t chars_left = buf_ptr - buf_start;
        if (chars_left >= n) {
            buf_ptr -= n;
        } else {
            buf_ptr = 0;
        }
    }
    current_pos -= n;
}

template <class charT, class Alloc>
void __rope_iterator<charT,Alloc>::check() {
    if (root_rope -> tree_ptr != root) {
        // Rope was modified.  Get things fixed up.
        RopeBase::unref(root);
        root = root_rope -> tree_ptr;
        RopeBase::ref(root);
        buf_ptr = 0;
    }
}

template <class charT, class Alloc>
inline __rope_const_iterator<charT, Alloc>::__rope_const_iterator
(const __rope_iterator<charT,Alloc> & x)
: __rope_iterator_base<charT,Alloc>(x) { }

template <class charT, class Alloc>
inline __rope_iterator<charT,Alloc>::__rope_iterator
(rope<charT,Alloc>& r, size_t pos)
        : __rope_iterator_base<charT,Alloc>(r.tree_ptr, pos), root_rope(&r) {
    RopeBase::ref(root);
}

template <class charT, class Alloc>
inline size_t rope<charT,Alloc>::char_ptr_len(const charT *s)
{
    const charT *p = s;

    while (!is0(*p)) { ++p; }
    return(p - s);
}

template <class charT, class Alloc>
rope<charT,Alloc>::RopeLeaf *
rope<charT,Alloc>::RopeLeaf_from_char_ptr(__GC_CONST charT *s, size_t size)
{
    RopeLeaf *t = LAlloc::allocate();

    t -> tag = RopeBase::leaf;
    if (__is_basic_char_type((charT *)0)) {
	// already eos terminated.
	t -> c_string = s;
    } else {
	t -> c_string = 0;
    }
    t -> is_balanced = true;
    t -> depth = 0;
    t -> size = size;
    t -> data = s;
#   ifndef __GC
	t -> refcount = 1;
	t -> init_refcount_lock();
#   endif
    return (t);
}

# ifdef __GC
template <class charT, class Alloc>
void __rope_RopeBase<charT,Alloc>::fn_finalization_proc(void * tree, void *)
{
    delete ((__rope_RopeFunction<charT,Alloc> *)tree) -> fn;
}
# endif

template <class charT, class Alloc>
rope<charT,Alloc>::RopeFunction *
rope<charT,Alloc>::RopeFunction_from_fn
(char_producer<charT> *fn, size_t size, bool delete_fn)
{
    if (0 == size) return 0;
    RopeFunction *t = FAlloc::allocate();
    t -> tag = RopeBase::function;
    t -> c_string = 0;
    t -> is_balanced = true;
    t -> depth = 0;
    t -> size = size;
    t -> fn = fn;
#   ifdef __GC
	if (delete_fn) {
	    GC_REGISTER_FINALIZER(t, RopeBase::fn_finalization_proc, 0, 0, 0);
	}
#   else
	t -> delete_when_done = delete_fn;
	t -> refcount = 1;
	t -> init_refcount_lock();
#   endif
    return (t);
}

#ifndef __GC

template <class charT, class Alloc>
inline void __rope_RopeBase<charT,Alloc>::free_c_string()
{
    charT * cstr = c_string;
    if (0 != cstr) {
	size_t sz = size + 1;
	destroy(cstr, cstr + sz);
	DataAlloc::deallocate(cstr, sz);
    }
}

template <class charT, class Alloc>
inline void __rope_RopeBase<charT,Alloc>::free_string(charT* s, size_t n)
{
    if (!__is_basic_char_type((charT *)0)) {
	destroy(s, s + n);
    }
    DataAlloc::deallocate(s, rounded_up_size(n));
}

template <class charT, class Alloc>
void __rope_RopeBase<charT,Alloc>::free_tree()
{
    switch(tag) {
	case leaf:
	    {
	        __rope_RopeLeaf<charT,Alloc> * l =
			(__rope_RopeLeaf<charT,Alloc> *)this;
		charT * d = l -> data;
		
		if (d != c_string) {
		    free_c_string();
		}
		free_string(d, size);
		LAlloc::deallocate(l);
	    }
	    break;
	case concat:
	    {
		__rope_RopeConcatenation<charT,Alloc> * c =
			(__rope_RopeConcatenation<charT,Alloc> *)this;
		__rope_RopeBase * left = c -> left;
		__rope_RopeBase * right = c -> right;
		free_c_string();
		left -> unref_nonnil();
		right -> unref_nonnil();
		CAlloc::deallocate(c);
	    }
	    break;
	case function:
	    {
		__rope_RopeFunction<charT,Alloc> * fn =
		  	(__rope_RopeFunction<charT,Alloc> *)this;
	        free_c_string();
	        if ( fn -> delete_when_done) {
		    delete fn -> fn;
	        }
	        FAlloc::deallocate(fn);
	        break;
	    }
	case substringfn:
	    {
	        __rope_RopeSubstring<charT,Alloc> * ss =
			(__rope_RopeSubstring<charT,Alloc> *)this;
		__rope_RopeBase *base = ss -> base;
		free_c_string();
		base -> unref_nonnil();
		SAlloc::deallocate(ss);
		break;
	    }
    }
}
#else

template <class charT, class Alloc>
inline void __rope_RopeBase<charT,Alloc>::free_string(charT* s, size_t n)
{}

#endif


// Concatenate a C string onto a leaf rope by copying the rope data.
// Used for short ropes.
template <class charT, class Alloc>
rope<charT,Alloc>::RopeLeaf *
rope<charT,Alloc>::leaf_concat_char_iter
		(RopeLeaf * r, const charT * iter, size_t len)
{
    size_t old_len = r -> size;
    charT * new_data = (charT *)
	DataAlloc::allocate(rounded_up_size(old_len + len));
    RopeLeaf * result;
    
    uninitialized_copy_n(r -> data, old_len, new_data);
    uninitialized_copy_n(iter, len, new_data + old_len);
    __cond_store_eos(new_data[old_len + len]);
    __STL_TRY {
	result = RopeLeaf_from_char_ptr(new_data, old_len + len);
    }
    __STL_UNWIND(RopeBase::free_string(new_data, old_len + len));
    return result;
}

#ifndef __GC
// As above, but it's OK to clobber original if refcount is 1
template <class charT, class Alloc>
rope<charT,Alloc>::RopeLeaf *
rope<charT,Alloc>::destr_leaf_concat_char_iter
		(RopeLeaf * r, const charT * iter, size_t len)
{
    __stl_assert(r -> refcount >= 1);
    if (r -> refcount > 1) return leaf_concat_char_iter(r, iter, len);
    size_t old_len = r -> size;
    if (allocated_capacity(old_len) >= old_len + len) {
	// The space has been partially initialized for the standard
	// character types.  But that doesn't matter for those types.
	uninitialized_copy_n(iter, len, r -> data + old_len);
	if (__is_basic_char_type((charT *)0)) {
	    __cond_store_eos(r -> data[old_len + len]);
	    __stl_assert(r -> c_string == r -> data);
	} else if (r -> c_string != r -> data && 0 != r -> c_string) {
	    r -> free_c_string();
	    r -> c_string = 0;
	}
	r -> size = old_len + len;
	__stl_assert(r -> refcount == 1);
	r -> refcount = 2;
	return r;
    } else {
	RopeLeaf * result = leaf_concat_char_iter(r, iter, len);
	__stl_assert(result -> refcount == 1);
	return result;
    }
}
#endif

// Assumes left and right are not 0.
// Does not increment (nor decrement on exception) child reference counts.
// Result has ref count 1.
template <class charT, class Alloc>
rope<charT,Alloc>::RopeBase *
rope<charT,Alloc>::tree_concat (RopeBase * left, RopeBase * right)
{
    RopeConcatenation * result = CAlloc::allocate();
    unsigned char child_depth = left -> depth;
    size_t rsize;

    result -> tag = RopeBase::concat;
    result -> c_string = 0;
    result -> is_balanced = false;
    result -> size = rsize = left -> size + right -> size;
    if (right -> depth > child_depth) child_depth = right -> depth;
    unsigned char depth = (unsigned char)(child_depth + 1);
    result -> depth = depth;
    result -> left = left;
    result -> right = right;
#   ifndef __GC
	result -> refcount = 1;
	result -> init_refcount_lock();
#   endif
    if (depth > 20 && (rsize < 1000 || depth > RopeBase::max_rope_depth)) {
	RopeBase * balanced;

	__STL_TRY {
	   balanced = balance(result);
#          ifndef __GC
	     if (result != balanced) {
		__stl_assert(1 == result -> refcount
			     && 1 == balanced -> refcount);
	     }
#          endif
	   result -> unref_nonnil();
        }
	__STL_UNWIND(CAlloc::deallocate(result));
		// In case of exception, we need to deallocate
		// otherwise dangling result node.  But caller
		// still owns its children.  Thus unref is
		// inappropriate.
	return balanced;
    } else {
	return result;
    }
}

template <class charT, class Alloc>
rope<charT,Alloc>::RopeBase * rope<charT,Alloc>::concat_char_iter
		(RopeBase * r, const charT *s, size_t slen)
{
    RopeBase *result;
    if (0 == slen) {
	ref(r);
	return r;
    }
    if (0 == r) return RopeLeaf_from_unowned_char_ptr(s, slen);
    if (RopeBase::leaf == r -> tag && r -> size + slen <= copy_max) {
	result = leaf_concat_char_iter((RopeLeaf *)r, s, slen);
#       ifndef __GC
	  __stl_assert(1 == result -> refcount);
#       endif
	return result;
    }
    if (RopeBase::concat == r -> tag
	&& RopeBase::leaf == ((RopeConcatenation *)r) -> right -> tag) {
	RopeLeaf *right = (RopeLeaf *)(((RopeConcatenation *)r) -> right);
	if (right -> size + slen <= copy_max) {
	  RopeBase * left = ((RopeConcatenation *)r) -> left;
	  RopeBase * nright = leaf_concat_char_iter((RopeLeaf *)right, s, slen);
	  left -> ref_nonnil();
	  __STL_TRY {
	    result = tree_concat(left, nright);
          }
	  __STL_UNWIND(unref(left); unref(nright));
#         ifndef __GC
	    __stl_assert(1 == result -> refcount);
#         endif
	  return result;
	}
    }
    RopeBase * nright = RopeLeaf_from_unowned_char_ptr(s, slen);
    __STL_TRY {
      r -> ref_nonnil();
      result = tree_concat(r, nright);
    }
    __STL_UNWIND(unref(r); unref(nright));
#   ifndef __GC
      __stl_assert(1 == result -> refcount);
#   endif
    return result;
}

#ifndef __GC
template <class charT, class Alloc>
rope<charT,Alloc>::RopeBase * rope<charT,Alloc>
::destr_concat_char_iter
		(RopeBase * r, const charT *s, size_t slen)
{
    RopeBase *result;
    if (0 == r) return RopeLeaf_from_unowned_char_ptr(s, slen);
    size_t count = r -> refcount;
    size_t orig_size = r -> size;
    __stl_assert(count >= 1);
    if (count > 1) return concat_char_iter(r, s, slen);
    if (0 == slen) {
	r -> refcount = 2;      // One more than before
	return r;
    }
    if (orig_size + slen <= copy_max && RopeBase::leaf == r -> tag) {
	result = destr_leaf_concat_char_iter((RopeLeaf *)r, s, slen);
	return result;
    }
    if (RopeBase::concat == r -> tag) {
	RopeLeaf *right = (RopeLeaf *)(((RopeConcatenation *)r) -> right);
	if (RopeBase::leaf == right -> tag
	    && right -> size + slen <= copy_max) {
	  RopeBase * new_right = destr_leaf_concat_char_iter(right, s, slen);
	  if (right == new_right) {
	      __stl_assert(new_right -> refcount == 2);
	      new_right -> refcount = 1;
	  } else {
	      __stl_assert(new_right -> refcount >= 1);
	      right -> unref_nonnil();
	  }
	  __stl_assert(r -> refcount == 1);
	  r -> refcount = 2;    // One more than before.
	  ((RopeConcatenation *)r) -> right = new_right;
	  r -> size = orig_size + slen;
	  if (0 != r -> c_string) {
	      r -> free_c_string();
	      r -> c_string = 0;
	  }
	  return r;
	}
    }
    RopeBase *right = RopeLeaf_from_unowned_char_ptr(s, slen);
    r -> ref_nonnil();
    __STL_TRY {
      result = tree_concat(r, right);
    }
    __STL_UNWIND(unref(r); unref(right))
    __stl_assert(1 == result -> refcount);
    return result;
}
#endif /* !__GC */

template <class charT, class Alloc>
rope<charT,Alloc>::RopeBase *
rope<charT,Alloc>::concat(RopeBase * left, RopeBase * right)
{
    if (0 == left) {
	ref(right);
	return right;
    }
    if (0 == right) {
	left -> ref_nonnil();
	return left;
    }
    if (RopeBase::leaf == right -> tag) {
	if (RopeBase::leaf == left -> tag) {
	  if (right -> size + left -> size <= copy_max) {
	    return leaf_concat_char_iter((RopeLeaf *)left,
					 ((RopeLeaf *)right) -> data,
					 right -> size);
	  }
	} else if (RopeBase::concat == left -> tag
		   && RopeBase::leaf ==
		      ((RopeConcatenation *)left) -> right -> tag) {
	  RopeLeaf * leftright =
		    (RopeLeaf *)(((RopeConcatenation *)left) -> right); 
	  if (leftright -> size + right -> size <= copy_max) {
	    RopeBase * leftleft = ((RopeConcatenation *)left) -> left;
	    RopeBase * rest = leaf_concat_char_iter(leftright,
					   ((RopeLeaf *)right) -> data,
					   right -> size);
	    leftleft -> ref_nonnil();
	    __STL_TRY {
	      return(tree_concat(leftleft, rest));
            }
	    __STL_UNWIND(unref(leftleft); unref(rest))
	  }
	}
    }
    left -> ref_nonnil();
    right -> ref_nonnil();
    __STL_TRY {
      return(tree_concat(left, right));
    }
    __STL_UNWIND(unref(left); unref(right));
}

template <class charT, class Alloc>
rope<charT,Alloc>::RopeBase *
rope<charT,Alloc>::substring(RopeBase * base, size_t start, size_t endp1)
{
    if (0 == base) return 0;
    size_t len = base -> size;
    size_t adj_endp1;
    const size_t lazy_threshold = 128;
    
    if (endp1 >= len) {
	if (0 == start) {
	    base -> ref_nonnil();
	    return base;
	} else {
	    adj_endp1 = len;
	}
    } else {
	adj_endp1 = endp1;
    }
    switch(base -> tag) {
	case RopeBase::concat:
	    {
		RopeConcatenation *c = (RopeConcatenation *)base;
		RopeBase *left = c -> left;
		RopeBase *right = c -> right;
		size_t left_len = left -> size;
		RopeBase * result;

		if (adj_endp1 <= left_len) {
		    return substring(left, start, endp1);
		} else if (start >= left_len) {
		    return substring(right, start - left_len,
				  adj_endp1 - left_len);
		}
		self_destruct_ptr left_result(substring(left, start,
							left_len));
		self_destruct_ptr right_result(
				substring(right, 0, endp1 - left_len));
		result = concat(left_result, right_result);
#               ifndef __GC
		  __stl_assert(1 == result -> refcount);
#               endif
		return result;
	    }
	case RopeBase::leaf:
	    {
		RopeLeaf * l = (RopeLeaf *)base;
		RopeLeaf * result;
		size_t result_len;
		if (start >= adj_endp1) return 0;
		result_len = adj_endp1 - start;
		if (result_len > lazy_threshold) goto lazy;
#               ifdef __GC
		    const charT *section = l -> data + start;
		    result = RopeLeaf_from_char_ptr(section, result_len);
		    result -> c_string = 0;  // Not eos terminated.
#               else
		    // We should sometimes create substring node instead.
		    result = RopeLeaf_from_unowned_char_ptr(
					l -> data + start, result_len);
#               endif
		return result;
	    }
	case RopeBase::substringfn:
	    // Avoid introducing mutiple layers of substring nodes.
	    {
		RopeSubstring *old = (RopeSubstring *)base;
		size_t result_len;
		if (start >= adj_endp1) return 0;
		result_len = adj_endp1 - start;
		if (result_len > lazy_threshold) {
		    RopeSubstring * space = SAlloc::allocate();
		    RopeSubstring * result =
			new(space) RopeSubstring(old -> base,
						 start + old -> start,
						 adj_endp1 - start);
		    return result;
		} // else fall through:
	    }
	case RopeBase::function:
	    {
		RopeFunction * f = (RopeFunction *)base;
		charT *section;
		size_t result_len;
		if (start >= adj_endp1) return 0;
		result_len = adj_endp1 - start;

		if (result_len > lazy_threshold) goto lazy;
		section = (charT *)
			DataAlloc::allocate(rounded_up_size(result_len));
		__STL_TRY {
		  (*(f -> fn))(start, result_len, section);
                }
		__STL_UNWIND(RopeBase::free_string(section, result_len));
		__cond_store_eos(section[result_len]);
		return RopeLeaf_from_char_ptr(section, result_len);
	    }
    }
    /*NOTREACHED*/
    __stl_assert(false);
  lazy:
    {
	// Create substring node.
	RopeSubstring * space = SAlloc::allocate();
	RopeSubstring * result = new(space) RopeSubstring(base, start,
							  adj_endp1 - start);
	return result;
    }
}

template<class charT>
class __rope_flatten_char_consumer : public __rope_char_consumer<charT> {
    private:
	charT * buf_ptr;
    public:
	charT * buffer;
	__rope_flatten_char_consumer(charT * buffer) {
	    buf_ptr = buffer;
	};
	~__rope_flatten_char_consumer() {}
	bool operator() (const charT* leaf, size_t n) {
	    uninitialized_copy_n(leaf, n, buf_ptr);
	    buf_ptr += n;
	    return true;
	}
};
	    
template<class charT>
class __rope_find_char_char_consumer : public __rope_char_consumer<charT> {
    private:
	charT pattern;
    public:
	size_t count;  // Number of nonmatching characters
	__rope_find_char_char_consumer(charT p) : pattern(p), count(0) {}
	~__rope_find_char_char_consumer() {}
	bool operator() (const charT* leaf, size_t n) {
	    size_t i;
	    for (i = 0; i < n; i++) {
		if (leaf[i] == pattern) {
		    count += i; return false;
		}
	    }
	    count += n; return true;
	}
};
	    
template<class charT>
class __rope_insert_char_consumer : public __rope_char_consumer<charT> {
    private:
	typedef ostream insert_ostream;
	insert_ostream & o;
    public:
	charT * buffer;
	__rope_insert_char_consumer(insert_ostream & writer) : o(writer) {};
	~__rope_insert_char_consumer() { };
		// Caller is presumed to own the ostream
	bool operator() (const charT* leaf, size_t n);
		// Returns true to continue traversal.
};
	    
template<class charT>
bool __rope_insert_char_consumer<charT>::operator()
					(const charT * leaf, size_t n)
{
    size_t i;
    //  We assume that formatting is set up correctly for each element.
    for (i = 0; i < n; i++) o << leaf[i];
    return true;
}

inline bool __rope_insert_char_consumer<char>::operator()
					(const char * leaf, size_t n)
{
    size_t i;
    for (i = 0; i < n; i++) o.put(leaf[i]);
    return true;
}

#if !defined(_MSC_VER) && !defined(__BORLANDC__)
// I couldn't get this to work work with the VC++ version of basic_ostream.
inline bool __rope_insert_char_consumer<wchar_t>::operator()
					(const wchar_t * leaf, size_t n)
{
    size_t i;
    for (i = 0; i < n; i++) o.put(leaf[i]);
    return true;
}
#endif /* !_MSC_VER  && !BORLAND */

template <class charT, class Alloc>
bool rope<charT, Alloc>::apply_to_pieces(
				__rope_char_consumer<charT>& c,
				const RopeBase * r,
				size_t begin, size_t end)
{
    if (0 == r) return true;
    switch(r -> tag) {
	case RopeBase::concat:
	    {
		RopeConcatenation *conc = (RopeConcatenation *)r;
		RopeBase *left = conc -> left;
		size_t left_len = left -> size;
		if (begin < left_len) {
		    size_t left_end = min(left_len, end);
		    if (!apply_to_pieces(c, left, begin, left_end)) {
			return false;
		    }
		}
		if (end > left_len) {
		    RopeBase *right = conc -> right;
		    size_t right_start = max(left_len, begin);
		    if (!apply_to_pieces(c, right,
					 right_start - left_len,
					 end - left_len)) {
			return false;
		    }
		}
	    }
	    return true;
	case RopeBase::leaf:
	    {
		RopeLeaf * l = (RopeLeaf *)r;
		return c(l -> data + begin, end - begin);
	    }
	case RopeBase::function:
	case RopeBase::substringfn:
	    {
		RopeFunction * f = (RopeFunction *)r;
		size_t len = end - begin;
		bool result;
		charT * buffer = DataAlloc::allocate(len);
		__STL_TRY {
		  (*(f -> fn))(begin, end, buffer);
		  result = c(buffer, len);
                  DataAlloc::deallocate(buffer, len);
                }
		__STL_UNWIND(DataAlloc::deallocate(buffer, len))
		return result;
	    }
	default:
	    __stl_assert(false);
	    /*NOTREACHED*/
	    return false;
    }
}

inline void __rope_fill(ostream& o, size_t n)
{
    char f = o.fill();
    size_t i;

    for (i = 0; i < n; i++) o.put(f);
}
    

template <class charT> inline bool __rope_is_simple(charT *) { return false; }
inline bool __rope_is_simple(char *) { return true; }
inline bool __rope_is_simple(wchar_t *) { return true; }


template<class charT, class Alloc>
ostream& operator<< (ostream& o, const rope<charT, Alloc>& r)
{
    size_t w = o.width();
    bool left = bool(o.flags() & ios::left);
    size_t pad_len;
    size_t rope_len = r.size();
    __rope_insert_char_consumer<charT> c(o);
    bool is_simple = __rope_is_simple((charT *)0);
    
    if (rope_len < w) {
	pad_len = w - rope_len;
    } else {
	pad_len = 0;
    }
    if (!is_simple) o.width(w/rope_len);
    __STL_TRY {
      if (is_simple && !left && pad_len > 0) {
	__rope_fill(o, pad_len);
      }
      r.apply_to_pieces(0, r.size(), c);
      if (is_simple && left && pad_len > 0) {
	__rope_fill(o, pad_len);
      }
      if (!is_simple)
        o.width(w);
    }
    __STL_UNWIND(if (!is_simple) o.width(w))
    return o;
}

template <class charT, class Alloc>
charT *
rope<charT,Alloc>::flatten(RopeBase * r,
				 size_t start, size_t len,
				 charT * buffer)
{
    __rope_flatten_char_consumer<charT> c(buffer);
    apply_to_pieces(c, r, start, start + len);
    return(buffer + len);
}

template <class charT, class Alloc>
size_t
rope<charT,Alloc>::find(charT pattern, size_t start) const
{
    __rope_find_char_char_consumer<charT> c(pattern);
    apply_to_pieces(c, tree_ptr, start, size());
    return start + c.count;
}

template <class charT, class Alloc>
charT *
rope<charT,Alloc>::flatten(RopeBase * r, charT * buffer)
{
    if (0 == r) return buffer;
    switch(r -> tag) {
	case RopeBase::concat:
	    {
		RopeConcatenation *c = (RopeConcatenation *)r;
		RopeBase *left = c -> left;
		RopeBase *right = c -> right;
		charT * rest = flatten(left, buffer);
		return flatten(right, rest);
	    }
	case RopeBase::leaf:
	    {
		RopeLeaf * l = (RopeLeaf *)r;
		return copy_n(l -> data, l -> size, buffer).second;
	    }
	case RopeBase::function:
	case RopeBase::substringfn:
	    // We dont yet do anything with substring nodes.
	    // This needs to be fixed before ropefiles will work well.
	    {
		RopeFunction * f = (RopeFunction *)r;
		(*(f -> fn))(0, f -> size, buffer);
		return buffer + f -> size;
	    }
	default:
	    __stl_assert(false);
	    /*NOTREACHED*/
	    return 0;
    }
}


// This needs work for charT != char
template <class charT, class Alloc>
void
rope<charT,Alloc>::dump(RopeBase * r, int indent)
{
    for (int i = 0; i < indent; i++) putchar(' ');
    if (0 == r) {
	printf("NULL\n"); return;
    }
    if (RopeBase::concat == r -> tag) {
	RopeConcatenation *c = (RopeConcatenation *)r;
	RopeBase *left = c -> left;
	RopeBase *right = c -> right;

#       ifdef __GC
	  printf("Concatenation %p (depth = %d, len = %ld, %s balanced)\n",
		 r, r -> depth, r -> size, r -> is_balanced? "" : "not");
#       else
	  printf("Concatenation %p (rc = %ld, depth = %d, len = %ld, %s balanced)\n",
		 r, r -> refcount, r -> depth, r -> size,
		 r -> is_balanced? "" : "not");
#       endif
	dump(left, indent + 2);
	dump(right, indent + 2);
	return;
    } else {
	char * kind;

	switch (r -> tag) {
	    case RopeBase::leaf:
		kind = "Leaf";
		break;
	    case RopeBase::function:
		kind = "Function";
		break;
	    case RopeBase::substringfn:
		kind = "Function representing substring";
		break;
	    default:
		kind = "(corrupted kind field!)";
	}
#       ifdef __GC
	  printf("%s %p (depth = %d, len = %ld) ",
		 kind, r, r -> depth, r -> size);
#       else
	  printf("%s %p (rc = %ld, depth = %d, len = %ld) ",
		 kind, r, r -> refcount, r -> depth, r -> size);
#       endif
	if (__is_one_byte_char_type((charT *)0)) {
	    const int max_len = 40;
	    self_destruct_ptr prefix(substring(r, 0, max_len));
	    charT buffer[max_len + 1];
	    bool too_big = r -> size > prefix-> size;

	    flatten(prefix, buffer);
	    buffer[prefix -> size] = __eos((charT *)0); 
	    printf("%s%s\n", (char *)buffer, too_big? "...\n" : "\n");
	} else {
	    printf("\n");
	}
    }
}

template <class charT, class Alloc>
const unsigned long
rope<charT,Alloc>::min_len[__rope_RopeBase<charT,Alloc>::max_rope_depth + 1] = {
/* 0 */1, /* 1 */2, /* 2 */3, /* 3 */5, /* 4 */8, /* 5 */13, /* 6 */21,
/* 7 */34, /* 8 */55, /* 9 */89, /* 10 */144, /* 11 */233, /* 12 */377,
/* 13 */610, /* 14 */987, /* 15 */1597, /* 16 */2584, /* 17 */4181,
/* 18 */6765, /* 19 */10946, /* 20 */17711, /* 21 */28657, /* 22 */46368,
/* 23 */75025, /* 24 */121393, /* 25 */196418, /* 26 */317811,
/* 27 */514229, /* 28 */832040, /* 29 */1346269, /* 30 */2178309,
/* 31 */3524578, /* 32 */5702887, /* 33 */9227465, /* 34 */14930352,
/* 35 */24157817, /* 36 */39088169, /* 37 */63245986, /* 38 */102334155,
/* 39 */165580141, /* 40 */267914296, /* 41 */433494437,
/* 42 */701408733, /* 43 */1134903170, /* 44 */1836311903,
/* 45 */2971215073 };
// These are Fibonacci numbers < 2**32.

template <class charT, class Alloc>
rope<charT,Alloc>::RopeBase *
rope<charT,Alloc>::balance(RopeBase *r)
{
    RopeBase * forest[RopeBase::max_rope_depth + 1];
    RopeBase * result = 0;
    int i;
    // Inariant:
    // The concatenation of forest in descending order is equal to r.
    // forest[i].size >= min_len[i]
    // forest[i].depth = i
    // References from forest are included in refcount.

    for (i = 0; i <= RopeBase::max_rope_depth; ++i) forest[i] = 0;
    __STL_TRY {
      add_to_forest(r, forest);
      for (i = 0; i <= RopeBase::max_rope_depth; ++i) if (0 != forest[i]) {
#	ifndef __GC
	  self_destruct_ptr old(result);
#	endif
	result = concat(forest[i], result);
	forest[i] -> unref_nonnil();
#	if !defined(__GC) && defined(__STL_USE_EXCEPTIONS)
	  forest[i] = 0;
#	endif
      }
    }
    __STL_UNWIND(for(i = 0; i <= RopeBase::max_rope_depth; i++)
		 unref(forest[i]))
    if (result -> depth > RopeBase::max_rope_depth) abort();
    return(result);
}


template <class charT, class Alloc>
void
rope<charT,Alloc>::add_to_forest(RopeBase *r, RopeBase **forest)
{
    if (r -> is_balanced) {
	add_leaf_to_forest(r, forest);
	return;
    }
    __stl_assert(r -> tag == RopeBase::concat);
    {
	RopeConcatenation *c = (RopeConcatenation *)r;

	add_to_forest(c -> left, forest);
	add_to_forest(c -> right, forest);
    }
}


template <class charT, class Alloc>
void
rope<charT,Alloc>::add_leaf_to_forest(RopeBase *r, RopeBase **forest)
{
    RopeBase * insertee;   		// included in refcount
    RopeBase * too_tiny = 0;    	// included in refcount
    int i;  				// forest[0..i-1] is empty
    size_t s = r -> size;

    for (i = 0; s >= min_len[i+1]/* not this bucket */; ++i) {
	if (0 != forest[i]) {
#	    ifndef __GC
	      self_destruct_ptr old(too_tiny);
#	    endif
	    too_tiny = concat_and_set_balanced(forest[i], too_tiny);
	    forest[i] -> unref_nonnil();
	    forest[i] = 0;
	}
    }
    {
#	ifndef __GC
	  self_destruct_ptr old(too_tiny);
#	endif
	insertee = concat_and_set_balanced(too_tiny, r);
    }
    // Too_tiny dead, and no longer included in refcount.
    // Insertee is live and included.
    __stl_assert(is_almost_balanced(insertee));
    __stl_assert(insertee -> depth <= r -> depth + 1);
    for (;; ++i) {
	if (0 != forest[i]) {
#	    ifndef __GC
	      self_destruct_ptr old(insertee);
#	    endif
	    insertee = concat_and_set_balanced(forest[i], insertee);
	    forest[i] -> unref_nonnil();
	    forest[i] = 0;
	    __stl_assert(is_almost_balanced(insertee));
	}
	__stl_assert(min_len[i] <= insertee -> size);
	__stl_assert(forest[i] == 0);
	if (i == RopeBase::max_rope_depth
	    || insertee -> size < min_len[i+1]) {
	    forest[i] = insertee;
	    // refcount is OK since insertee is now dead.
	    return;
	}
    }
}

template <class charT, class Alloc>
charT
rope<charT,Alloc>::fetch(RopeBase *r, size_type i)
{
    __GC_CONST charT * cstr = r -> c_string;

    __stl_assert(i < r -> size);
    if (0 != cstr) return cstr[i]; 
    for(;;) {
      switch(r -> tag) {
	case RopeBase::concat:
	    {
		RopeConcatenation *c = (RopeConcatenation *)r;
		RopeBase *left = c -> left;
		size_t left_len = left -> size;

		if (i >= left_len) {
		    i -= left_len;
		    r = c -> right;
		} else {
		    r = left;
		}
	    }
	    break;
	case RopeBase::leaf:
	    {
		RopeLeaf * l = (RopeLeaf *)r;
		return l -> data[i];
	    }
	case RopeBase::function:
	case RopeBase::substringfn:
	    {
		RopeFunction * f = (RopeFunction *)r;
		charT result;

		(*(f -> fn))(i, 1, &result);
		return result;
	    }
      }
    }
}

# ifndef __GC
// Return a uniquely referenced character slot for the given
// position, or 0 if that's not possible.
template <class charT, class Alloc>
charT*
rope<charT,Alloc>::fetch_ptr(RopeBase *r, size_type i)
{
    RopeBase * clrstack[RopeBase::max_rope_depth];
    size_t csptr = 0;

    for(;;) {
      if (r -> refcount > 1) return 0;
      switch(r -> tag) {
	case RopeBase::concat:
	    {
		RopeConcatenation *c = (RopeConcatenation *)r;
		RopeBase *left = c -> left;
		size_t left_len = left -> size;

		if (c -> c_string != 0) clrstack[csptr++] = c;
		if (i >= left_len) {
		    i -= left_len;
		    r = c -> right;
		} else {
		    r = left;
		}
	    }
	    break;
	case RopeBase::leaf:
	    {
		RopeLeaf * l = (RopeLeaf *)r;
		if (l -> c_string != l -> data && l -> c_string != 0)
		    clrstack[csptr++] = l;
		while (csptr > 0) {
		    -- csptr;
		    RopeBase * d = clrstack[csptr];
		    d -> free_c_string();
		    d -> c_string = 0;
		}
		return l -> data + i;
	    }
	case RopeBase::function:
	case RopeBase::substringfn:
	    return 0;
      }
    }
}
# endif /* __GC */

// The following could be implemented trivially using
// lexicographical_compare_3way.
// We do a little more work to avoid dealing with rope iterators for
// flat strings.
template <class charT, class Alloc>
int
rope<charT,Alloc>::compare (const RopeBase *left, const RopeBase *right)
{
    size_t left_len;
    size_t right_len;

    if (0 == right) return 0 != left;
    if (0 == left) return -1;
    left_len = left -> size;
    right_len = right -> size;
    if (RopeBase::leaf == left -> tag) {
	RopeLeaf *l = (RopeLeaf *) left;
	if (RopeBase::leaf == right -> tag) {
	    RopeLeaf *r = (RopeLeaf *) right;
	    return lexicographical_compare_3way(
			l -> data, l -> data + left_len,
			r -> data, r -> data + right_len);
	} else {
	    const_iterator rstart(right, 0);
	    const_iterator rend(right, right_len);
	    return lexicographical_compare_3way(
			l -> data, l -> data + left_len,
			rstart, rend);
	}
    } else {
	const_iterator lstart(left, 0);
	const_iterator lend(left, left_len);
	if (RopeBase::leaf == right -> tag) {
	    RopeLeaf *r = (RopeLeaf *) right;
	    return lexicographical_compare_3way(
				   lstart, lend,
				   r -> data, r -> data + right_len);
	} else {
	    const_iterator rstart(right, 0);
	    const_iterator rend(right, right_len);
	    return lexicographical_compare_3way(
				   lstart, lend,
				   rstart, rend);
	}
    }
}

// Assignment to reference proxies.
template <class charT, class Alloc>
__rope_charT_ref_proxy<charT, Alloc>&
__rope_charT_ref_proxy<charT, Alloc>::operator= (charT c) {
    RopeBase * old = root -> tree_ptr;
#   ifndef __GC
	// First check for the case in which everything is uniquely
	// referenced.  In that case we can do this destructively.
	charT * charT_ptr = my_rope::fetch_ptr(old, pos);
	if (0 != charT_ptr) {
	    *charT_ptr = c;
	    return *this;
	}
#   endif
    self_destruct_ptr left(my_rope::substring(old, 0, pos));
    self_destruct_ptr right(my_rope::substring(old, pos+1, old -> size));
    self_destruct_ptr result_left(my_rope::destr_concat_char_iter(left, &c, 1));
#   ifndef __GC
      __stl_assert(left == result_left || 1 == result_left -> refcount);
#   endif
    RopeBase * result =
		my_rope::concat(result_left, right);
#   ifndef __GC
      __stl_assert(1 <= result -> refcount);
      RopeBase::unref(old);
#   endif
    root -> tree_ptr = result;
    return *this;
}

template <class charT, class Alloc>
inline __rope_charT_ref_proxy<charT, Alloc>::operator charT () const
{
    if (current_valid) {
	return current;
    } else {
        return my_rope::fetch(root->tree_ptr, pos);
    }
}
template <class charT, class Alloc>
__rope_charT_ptr_proxy<charT, Alloc>
__rope_charT_ref_proxy<charT, Alloc>::operator& () const {
    return __rope_charT_ptr_proxy<charT, Alloc>(*this);
}

template <class charT, class Alloc>
rope<charT, Alloc>::rope(size_t n, charT c)
{
    rope result;
    const size_t exponentiate_threshold = 32;
    size_t exponent;
    size_t rest;
    charT *rest_buffer;
    RopeBase * remainder;
    rope remainder_rope;

    if (0 == n) { tree_ptr = 0; return; }
    exponent = n / exponentiate_threshold;
    rest = n % exponentiate_threshold;
    if (0 == rest) {
	remainder = 0;
    } else {
	rest_buffer = DataAlloc::allocate(rounded_up_size(rest));
	uninitialized_fill_n(rest_buffer, rest, c);
	__cond_store_eos(rest_buffer[rest]);
	__STL_TRY {
	    remainder = RopeLeaf_from_char_ptr(rest_buffer, rest);
        }
	__STL_UNWIND(RopeBase::free_string(rest_buffer, rest))
    }
    remainder_rope.tree_ptr = remainder;
    if (exponent != 0) {
	charT * base_buffer =
		DataAlloc::allocate(rounded_up_size(exponentiate_threshold));
	RopeLeaf * base_leaf;
	rope base_rope;
	uninitialized_fill_n(base_buffer, exponentiate_threshold, c);
	__cond_store_eos(base_buffer[exponentiate_threshold]);
	__STL_TRY {
          base_leaf = RopeLeaf_from_char_ptr(base_buffer,
                                             exponentiate_threshold);
        }
	__STL_UNWIND(RopeBase::free_string(base_buffer, exponentiate_threshold))
	base_rope.tree_ptr = base_leaf;
 	if (1 == exponent) {
	  result = base_rope;
#         ifndef __GC
	    __stl_assert(1 == result -> tree_ptr -> refcount);
#         endif
	} else {
	  result = power(base_rope, exponent, concat_fn());
	}
	if (0 != remainder) {
	  result += remainder_rope;
	}
    } else {
	result = remainder_rope;
    }
    tree_ptr = result.tree_ptr;
    tree_ptr -> ref_nonnil();
}

template<class charT, class Alloc> charT rope<charT,Alloc>::empty_c_str[1];

# ifdef __STL_PTHREADS
    template<class charT, class Alloc>
    pthread_mutex_t rope<charT,Alloc>::swap_lock = PTHREAD_MUTEX_INITIALIZER;
# endif

template<class charT, class Alloc>
const charT * rope<charT,Alloc>::c_str() const {
    if (0 == tree_ptr) {
        empty_c_str[0] = __eos((charT *)0);  // Possibly redundant,
					     // but probably fast.
        return empty_c_str;
    }
    __GC_CONST charT * old_c_string = tree_ptr -> c_string;
    if (0 != old_c_string) return(old_c_string);
    size_t s = size();
    charT * result = DataAlloc::allocate(s + 1);
    flatten(tree_ptr, result);
    result[s] = __eos((charT *)0);
#   ifdef __GC
	tree_ptr -> c_string = result;
#   else
      if ((old_c_string = atomic_swap(&(tree_ptr -> c_string), result)) != 0) {
	// It must have been added in the interim.  Hence it had to have been
	// separately allocated.  Deallocate the old copy, since we just
	// replaced it.
	destroy(old_c_string, old_c_string + s + 1);
	DataAlloc::deallocate(old_c_string, s + 1);
      }
#   endif
    return(result);
}

template<class charT, class Alloc>
const charT * rope<charT,Alloc>::replace_with_c_str() {
    if (0 == tree_ptr) {
        empty_c_str[0] = __eos((charT *)0);
        return empty_c_str;
    }
    __GC_CONST charT * old_c_string = tree_ptr -> c_string;
    if (RopeBase::leaf == tree_ptr -> tag && 0 != old_c_string) {
	return(old_c_string);
    }
    size_t s = size();
    charT * result = DataAlloc::allocate(rounded_up_size(s));
    flatten(tree_ptr, result);
    result[s] = __eos((charT *)0);
    tree_ptr -> unref_nonnil();
    tree_ptr = RopeLeaf_from_char_ptr(result, s);
    return(result);
}

// Algorithm specializations.  More should be added.

#ifndef _MSC_VER
// I couldn't get this to work with VC++
template<class charT,class Alloc>
void
__rope_rotate(__rope_iterator<charT,Alloc> first,
              __rope_iterator<charT,Alloc> middle,
              __rope_iterator<charT,Alloc> last) {
    __stl_assert(first.container() == middle.container()
                 && middle.container() == last.container());
    rope<charT,Alloc>& r(first.container());
    rope<charT,Alloc> prefix = r.substr(0, first.index());
    rope<charT,Alloc> suffix = r.substr(last.index(), r.size() - last.index());
    rope<charT,Alloc> part1 = r.substr(middle.index(),
                                       last.index() - middle.index());
    rope<charT,Alloc> part2 = r.substr(first.index(),
                                       middle.index() - first.index());
    r = prefix;
    r += part1;
    r += part2;
    r += suffix;
}

inline void rotate(__rope_iterator<char,__ALLOC> first,
                   __rope_iterator<char,__ALLOC> middle,
                   __rope_iterator<char,__ALLOC> last) {
    __rope_rotate(first, middle, last);
}

# if 0
// Probably not useful for several reasons:
// - for SGIs 7.1 compiler and probably some others,
//   this forces lots of rope<wchar_t, ...> instantiations, creating a
//   code bloat and compile time problem.  (Fixed in 7.2.)
// - wchar_t is 4 bytes wide on most UNIX platforms, making it unattractive
//   for unicode strings.  Unsigned short may be a better character
//   type.
inline void rotate(__rope_iterator<wchar_t,__ALLOC> first,
                   __rope_iterator<wchar_t,__ALLOC> middle,
                   __rope_iterator<wchar_t,__ALLOC> last) {
    __rope_rotate(first, middle, last);
}
# endif
#endif /* _MSC_VER */

#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
#pragma reset woff 1174
#endif

__STL_END_NAMESPACE

// Local Variables:
// mode:C++
// End:
