core :: union_find
union–find algorithm using an efficient disjoint-set data structurebucketed_game :: bucketed_game
Game framework with an emphasis on efficient event coordinationaccept_scroll_and_zoom
			gamnit :: camera_control_android
Two fingers camera manipulation, pinch to zoom and slide to scrollgamnit :: camera_control_linux
Mouse wheel and middle mouse button to control camerapthreads :: concurrent_array_and_barrier
A basic usage example of the modulespthreads and pthreads::cocurrent_collections
			pthreads :: concurrent_collections
Introduces thread-safe concurrent collectionsserialization :: custom_serialization
Example of an ad hoc serializer that is tailored to transform business specific objects into customized representation.egl, sdl and x11
			FileServer action, which is a standard and minimal file server
			cocoa :: foundation
The Foundation Kit provides basic Objective-C classes and structuresfunctional_types.nit
			functional :: functional_types
This module provides functional type to represents various function forms.gtk :: gtk_assistant
gtk :: gtk_dialogs
HttpRequest class and services to create it
			app::http_request main service AsyncHttpRequest
			Serializable::inspect to show more useful information
			Iterator.
			actors :: mandelbrot
Example implemented from "The computer Language Benchmarks Game" - Mandelbrotmarkdown2 :: markdown_html_rendering
HTML rendering of Markdown documentsmarkdown2 :: markdown_latex_rendering
LaTeX rendering of Markdown documentsmarkdown2 :: markdown_man_rendering
Manpages rendering of Markdown documentsmarkdown2 :: markdown_md_rendering
Markdown rendering of Markdown documentsmore_collections :: more_collections
Highly specific, but useful, collections-related classes.mpi :: mpi_simple
curl :: native_curl
Binding of C libCurl which allow us to interact with network.app.nit on Android using a custom Java entry point
			nitcc_runtime :: nitcc_runtime
Runtime library required by parsers and lexers generated by nitccnlp :: nlp_server
glesv2 :: opengles2_hello_triangle
Basic example of OpenGL ES 2.0 usage using SDL 2performance_analysis :: performance_analysis
Services to gather information on the performance of events by categoriesrestful annotation documented at lib/nitcorn/restful.nit
			sax :: sax_locator
Interface for associating a SAX event with a document location.Locator.
			msgpack :: serialization_common
Serialization services forserialization_write and serialization_read
			serialization :: serialization_core
Abstract services to serialize Nit objects to different formatsdeserialize_json and JsonDeserializer
			msgpack :: serialization_write
Serialize full Nit objects to MessagePack formatserialize_to_json and JsonSerializer
			root to execute
			agent_simulation by refining the Agent class to make
			socket :: socket_simple_server
Simple server example using a non-blockingTCPServer
			EulerCamera and App::frame_core_draw to get a stereoscopic view
			gamnit :: texture_atlas_parser
Tool to parse XML texture atlas and generated Nit code to access subtextures
# All the array-based text representations
module flat
intrude import abstract_text
intrude import native
`{
#include <stdio.h>
#include <string.h>
`}
private class FlatSubstringsIter
	super Iterator[FlatText]
	var tgt: nullable FlatText
	redef fun item do
		assert is_ok
		return tgt.as(not null)
	end
	redef fun is_ok do return tgt != null
	redef fun next do tgt = null
end
redef class FlatText
	# First byte of the CString
	protected fun first_byte: Int do return 0
	# Last byte of the CString
	protected fun last_byte: Int do return first_byte + _byte_length - 1
	# Cache of the latest position (char) explored in the string
	var position: Int = 0
	# Cached position (bytes) in the CString underlying the String
	var bytepos: Int = 0
	# Index of the character `index` in `_items`
	fun char_to_byte_index(index: Int): Int do
		var dpos = index - _position
		var b = _bytepos
		var its = _items
		if dpos == 1 then
			if its[b] & 0x80 == 0x00 then
				b += 1
			else
				b += its.length_of_char_at(b)
			end
			_bytepos = b
			_position = index
			return b
		end
		if dpos == -1 then
			b = its.find_beginning_of_char_at(b - 1)
			_bytepos = b
			_position = index
			return b
		end
		if dpos == 0 then return b
		var ln = _length
		var pos = _position
		# Find best insertion point
		var delta_begin = index
		var delta_end = (ln - 1) - index
		var delta_cache = (pos - index).abs
		var min = delta_begin
		if delta_cache < min then min = delta_cache
		if delta_end < min then min = delta_end
		var ns_i: Int
		var my_i: Int
		if min == delta_cache then
			ns_i = _bytepos
			my_i = pos
		else if min == delta_begin then
			ns_i = first_byte
			my_i = 0
		else
			ns_i = its.find_beginning_of_char_at(last_byte)
			my_i = _length - 1
		end
		ns_i = its.char_to_byte_index_cached(index, my_i, ns_i)
		_position = index
		_bytepos = ns_i
		return ns_i
	end
	# By escaping `self` to HTML, how many more bytes will be needed ?
	fun chars_to_html_escape: Int do
		var its = _items
		var max = last_byte
		var pos = first_byte
		var endlen = 0
		while pos <= max do
			var c = its[pos]
			if c == u'<' then
				endlen += 3
			else if c == u'>' then
				endlen += 3
			else if c == u'&' then
				endlen += 4
			else if c == u'"' then
				endlen += 4
			else if c == u'\'' then
				endlen += 4
			else if c == 0x2F then
				endlen += 4
			end
			pos += 1
		end
		return endlen
	end
	redef fun html_escape
	do
		var extra = chars_to_html_escape
		if extra == 0 then return to_s
		var its = _items
		var max = last_byte
		var pos = first_byte
		var nlen = extra + _byte_length
		var nits = new CString(nlen)
		var outpos = 0
		while pos <= max do
			var c = its[pos]
			# Special codes:
			# Some HTML characters are used as meta-data, they need
			# to be replaced by an HTML-Escaped equivalent
			if c == u'<' then
				nits[outpos] = u'&'
				nits[outpos + 1] = u'l'
				nits[outpos + 2] = u't'
				nits[outpos + 3] = u';'
				outpos += 4
			else if c == u'>' then
				nits[outpos] = u'&'
				nits[outpos + 1] = u'g'
				nits[outpos + 2] = u't'
				nits[outpos + 3] = u';'
				outpos += 4
			else if c == u'&' then
				nits[outpos] = u'&'
				nits[outpos + 1] = u'a'
				nits[outpos + 2] = u'm'
				nits[outpos + 3] = u'p'
				nits[outpos + 4] = u';'
				outpos += 5
			else if c == u'"' then
				nits[outpos] = u'&'
				nits[outpos + 1] = u'#'
				nits[outpos + 2] = u'3'
				nits[outpos + 3] = u'4'
				nits[outpos + 4] = u';'
				outpos += 5
			else if c == u'\'' then
				nits[outpos] = u'&'
				nits[outpos + 1] = u'#'
				nits[outpos + 2] = u'3'
				nits[outpos + 3] = u'9'
				nits[outpos + 4] = u';'
				outpos += 5
			else if c == u'/' then
				nits[outpos] = u'&'
				nits[outpos + 1] = u'#'
				nits[outpos + 2] = u'4'
				nits[outpos + 3] = u'7'
				nits[outpos + 4] = u';'
				outpos += 5
			else
				nits[outpos] = c
				outpos += 1
			end
			pos += 1
		end
		var s = new FlatString.with_infos(nits, nlen, 0)
		return s
	end
	# By escaping `self` to C, how many more bytes will be needed ?
	#
	# This enables a double-optimization in `escape_to_c` since if this
	# method returns 0, then `self` does not need escaping and can be
	# returned as-is
	fun chars_to_escape_to_c: Int do
		var its = _items
		var max = last_byte
		var pos = first_byte
		var req_esc = 0
		while pos <= max do
			var c = its[pos]
			if c == u'\n' then
				req_esc += 1
			else if c == u'\t' then
				req_esc += 1
			else if c == u'"' then
				req_esc += 1
			else if c == u'\'' then
				req_esc += 1
			else if c == u'\\' then
				req_esc += 1
			else if c == u'?' then
				var j = pos + 1
				if j < length then
					var next = its[j]
					# We ignore `??'` because it will be escaped as `??\'`.
					if
						next == 0x21 or
						next == 0x28 or
						next == 0x29 or
						next == 0x2D or
						next == 0x2F or
						next == 0x3C or
						next == 0x3D or
						next == 0x3E
					then req_esc += 1
				end
			else if c < 32 then
				req_esc += 3
			end
			pos += 1
		end
		return req_esc
	end
	redef fun escape_to_c do
		var ln_extra = chars_to_escape_to_c
		if ln_extra == 0 then return self.to_s
		var its = _items
		var max = last_byte
		var nlen = _byte_length + ln_extra
		var nns = new CString(nlen)
		var pos = first_byte
		var opos = 0
		while pos <= max do
			var c = its[pos]
			# Special codes:
			#
			# Any byte with value < 32 is a control character
			# All their uses will be replaced by their octal
			# value in C.
			#
			# There are two exceptions however:
			#
			# * 0x09 => \t
			# * 0x0A => \n
			#
			# Aside from the code points above, the following are:
			#
			# * 0x22 => \"
			# * 0x27 => \'
			# * 0x5C => \\
			if c == u'\t' then
				nns[opos] = u'\\'
				nns[opos + 1] = u't'
				opos += 2
			else if c == u'\n' then
				nns[opos] = u'\\'
				nns[opos + 1] = u'n'
				opos += 2
			else if c == u'"' then
				nns[opos] = u'\\'
				nns[opos + 1] = u'"'
				opos += 2
			else if c == u'\'' then
				nns[opos] = u'\\'
				nns[opos + 1] = u'\''
				opos += 2
			else if c == u'\\' then
				nns[opos] = u'\\'
				nns[opos + 1] = u'\\'
				opos += 2
			else if c == u'?' then
				var j = pos + 1
				if j < length then
					var next = its[j]
					# We ignore `??'` because it will be escaped as `??\'`.
					if
						next == 0x21 or
						next == 0x28 or
						next == 0x29 or
						next == 0x2D or
						next == 0x2F or
						next == 0x3C or
						next == 0x3D or
						next == 0x3E
					then
						nns[opos] = 0x5C
						opos += 1
					end
				end
				nns[opos] = 0x3F
				opos += 1
			else if c < 32 then
				nns[opos] = u'\\'
				nns[opos + 1] = u'0'
				nns[opos + 2] = ((c & 0x38) >> 3) + u'0'
				nns[opos + 3] = (c & 0x07) + u'0'
				opos += 4
			else
				nns[opos] = c
				opos += 1
			end
			pos += 1
		end
		return nns.to_s_unsafe(nlen, copy=false, clean=false)
	end
	redef fun [](index) do
		var len = _length
		# Statistically:
		# * ~70% want the next char
		# * ~23% want the previous
		# * ~7% want the same char
		#
		# So it makes sense to shortcut early. And early is here.
		var dpos = index - _position
		var b = _bytepos
		if dpos == 1 and index < len - 1 then
			var its = _items
			var c = its[b]
			if c & 0x80 == 0x00 then
				# We want the next, and current is easy.
				# So next is easy to find!
				b += 1
				_position = index
				_bytepos = b
				# The rest will be done by `dpos==0` bellow.
				dpos = 0
			end
		else if dpos == -1 and index > 1 then
			var its = _items
			var c = its[b-1]
			if c & 0x80 == 0x00 then
				# We want the previous, and it is easy.
				b -= 1
				dpos = 0
				_position = index
				_bytepos = b
				return c.code_point
			end
		end
		if dpos == 0 then
			# We know what we want (+0 or +1) just get it now!
			var its = _items
			var c = its[b]
			if c & 0x80 == 0x00 then return c.code_point
			return items.char_at(b)
		end
		assert index >= 0 and index < len
		return fetch_char_at(index)
	end
	# Gets a `Char` at `index` in `self`
	#
	# WARNING: Use at your own risks as no bound-checking is done
	fun fetch_char_at(index: Int): Char do
		var i = char_to_byte_index(index)
		var items = _items
		var b = items[i]
		if b & 0x80 == 0x00 then return b.code_point
		return items.char_at(i)
	end
	# If `self` contains only digits and alpha <= 'f', return the corresponding integer.
	#
	#     assert "ff".to_hex == 255
	redef fun to_hex(pos, ln) do
		var res = 0
		if pos == null then pos = 0
		if ln == null then ln = length - pos
		pos = char_to_byte_index(pos)
		var its = _items
		var max = pos + ln
		for i in [pos .. max[ do
			res <<= 4
			res += its[i].code_point.from_hex
		end
		return res
	end
	redef fun copy_to_native(dst, n, src_off, dst_off) do
		_items.copy_to(dst, n, first_byte + src_off, dst_off)
	end
end
# Immutable strings of characters.
abstract class FlatString
	super FlatText
	super String
	# Index at which `self` begins in `_items`, inclusively
	redef var first_byte is noinit
	redef fun chars do return new FlatStringCharView(self)
	redef fun bytes do return new FlatStringByteView(self)
	redef fun to_cstring do
		var blen = _byte_length
		var new_items = new CString(blen + 1)
		_items.copy_to(new_items, blen, _first_byte, 0)
		new_items[blen] = 0
		return new_items
	end
	redef fun reversed do
		var b = new FlatBuffer.with_capacity(_byte_length + 1)
		var i = _length - 1
		while i >= 0 do
			b.add self.fetch_char_at(i)
			i -= 1
		end
		var s = b.to_s.as(FlatString)
		s._length = self._length
		return s
	end
	redef fun fast_cstring do return _items.fast_cstring(_first_byte)
	redef fun substring(from, count)
	do
		if count <= 0 then return ""
		if from < 0 then
			count += from
			if count <= 0 then return ""
			from = 0
		end
		var ln = _length
		if (count + from) > ln then count = ln - from
		if count <= 0 then return ""
		var end_index = from + count - 1
		return substring_impl(from, count, end_index)
	end
	private fun substring_impl(from, count, end_index: Int): String do
		var cache = _position
		var dfrom = (cache - from).abs
		var dend = (end_index - from).abs
		var bytefrom: Int
		var byteto: Int
		if dfrom < dend then
			bytefrom = char_to_byte_index(from)
			byteto = char_to_byte_index(end_index)
		else
			byteto = char_to_byte_index(end_index)
			bytefrom = char_to_byte_index(from)
		end
		var its = _items
		byteto += its.length_of_char_at(byteto) - 1
		var s = new FlatString.full(its, byteto - bytefrom + 1, bytefrom, count)
		return s
	end
	redef fun empty do return "".as(FlatString)
	redef fun to_upper
	do
		var outstr = new FlatBuffer.with_capacity(self._byte_length + 1)
		var mylen = _length
		var pos = 0
		while pos < mylen do
			outstr.add(chars[pos].to_upper)
			pos += 1
		end
		return outstr.to_s
	end
	redef fun to_lower
	do
		var outstr = new FlatBuffer.with_capacity(self._byte_length + 1)
		var mylen = _length
		var pos = 0
		while pos < mylen do
			outstr.add(chars[pos].to_lower)
			pos += 1
		end
		return outstr.to_s
	end
	redef fun output
	do
		for i in chars do i.output
	end
	##################################################
	#              String Specific Methods           #
	##################################################
	# Low-level creation of a new string with minimal data.
	#
	# `_items` will be used as is, without copy, to retrieve the characters of the string.
	# Aliasing issues is the responsibility of the caller.
	private new with_infos(items: CString, byte_length, from: Int)
	do
		var len = items.utf8_length(from, byte_length)
		if byte_length == len then return new ASCIIFlatString.full_data(items, byte_length, from, len)
		return new UnicodeFlatString.full_data(items, byte_length, from, len)
	end
	# Low-level creation of a new string with all the data.
	#
	# `_items` will be used as is, without copy, to retrieve the characters of the string.
	# Aliasing issues is the responsibility of the caller.
	private new full(items: CString, byte_length, from, length: Int)
	do
		if byte_length == length then return new ASCIIFlatString.full_data(items, byte_length, from, length)
		return new UnicodeFlatString.full_data(items, byte_length, from, length)
	end
	redef fun ==(other)
	do
		if not other isa FlatText then return super
		if self.object_id == other.object_id then return true
		var my_length = _byte_length
		if other._byte_length != my_length then return false
		var my_index = _first_byte
		var its_index = other.first_byte
		var last_iteration = my_index + my_length
		var its_items = other._items
		var my_items = self._items
		while my_index < last_iteration do
			if my_items[my_index] != its_items[its_index] then return false
			my_index += 1
			its_index += 1
		end
		return true
	end
	redef fun <(other)
	do
		if not other isa FlatText then return super
		if self.object_id == other.object_id then return false
		var myits = _items
		var itsits = other._items
		var mbt = _byte_length
		var obt = other.byte_length
		var minln = if mbt < obt then mbt else obt
		var mst = _first_byte
		var ost = other.first_byte
		for i in [0 .. minln[ do
			var my_curr_char = myits[mst]
			var its_curr_char = itsits[ost]
			if my_curr_char > its_curr_char then return false
			if my_curr_char < its_curr_char then return true
			mst += 1
			ost += 1
		end
		return mbt < obt
	end
	redef fun +(o) do
		var s = o.to_s
		var slen = s.byte_length
		var mlen = _byte_length
		var nlen = mlen + slen
		var mits = _items
		var mifrom = _first_byte
		if s isa FlatText then
			var sits = s._items
			var sifrom = s.first_byte
			var ns = new CString(nlen + 1)
			mits.copy_to(ns, mlen, mifrom, 0)
			sits.copy_to(ns, slen, sifrom, mlen)
			return new FlatString.full(ns, nlen, 0, _length + o.length)
		else
			abort
		end
	end
	redef fun *(i) do
		var mybtlen = _byte_length
		var new_byte_length = mybtlen * i
		var mylen = _length
		var newlen = mylen * i
		var its = _items
		var fb = _first_byte
		var ns = new CString(new_byte_length + 1)
		ns[new_byte_length] = 0
		var offset = 0
		while i > 0 do
			its.copy_to(ns, mybtlen, fb, offset)
			offset += mybtlen
			i -= 1
		end
		return new FlatString.full(ns, new_byte_length, 0, newlen)
	end
	redef fun hash
	do
		if hash_cache == null then
			# djb2 hash algorithm
			var h = 5381
			var i = _first_byte
			var my_items = _items
			var max = last_byte
			while i <= max do
				h = (h << 5) + h + my_items[i].to_i
				i += 1
			end
			hash_cache = h
		end
		return hash_cache.as(not null)
	end
	redef fun substrings do return new FlatSubstringsIter(self)
end
# Regular Nit UTF-8 strings
private class UnicodeFlatString
	super FlatString
	init full_data(items: CString, byte_length, from, length: Int) do
		self._items = items
		self._length = length
		self._byte_length = byte_length
		_first_byte = from
		_bytepos = from
	end
	redef fun substring_from(from) do
		if from >= self._length then return empty
		if from <= 0 then return self
		var c = char_to_byte_index(from)
		var st = c - _first_byte
		var fln = byte_length - st
		return new FlatString.full(items, fln, c, _length - from)
	end
end
# Special cases of String where all the characters are ASCII-based
#
# Optimizes access operations to O(1) complexity.
private class ASCIIFlatString
	super FlatString
	init full_data(items: CString, byte_length, from, length: Int) do
		self._items = items
		self._length = length
		self._byte_length = byte_length
		_first_byte = from
		_bytepos = from
	end
	redef fun [](idx) do
		assert idx < _byte_length and idx >= 0
		return _items[idx + _first_byte].code_point
	end
	redef fun substring(from, count) do
		var ln = _length
		if count <= 0 then return ""
		if (count + from) > ln then count = ln - from
		if count <= 0 then return ""
		if from < 0 then
			count += from
			if count <= 0 then return ""
			from = 0
		end
		return new ASCIIFlatString.full_data(_items, count, from + _first_byte, count)
	end
	redef fun reversed do
		var b = new FlatBuffer.with_capacity(_byte_length + 1)
		var i = _length - 1
		while i >= 0 do
			b.add self[i]
			i -= 1
		end
		var s = b.to_s.as(FlatString)
		return s
	end
	redef fun char_to_byte_index(index) do return index + _first_byte
	redef fun substring_impl(from, count, end_index) do
		return new ASCIIFlatString.full_data(_items, count, from + _first_byte, count)
	end
	redef fun fetch_char_at(i) do return _items[i + _first_byte].code_point
end
private class FlatStringCharReverseIterator
	super IndexedIterator[Char]
	var target: FlatString
	var curr_pos: Int
	redef fun is_ok do return curr_pos >= 0
	redef fun item do return target[curr_pos]
	redef fun next do curr_pos -= 1
	redef fun index do return curr_pos
end
private class FlatStringCharIterator
	super IndexedIterator[Char]
	var target: FlatString
	var max: Int is noautoinit
	var curr_pos: Int
	init do max = target._length - 1
	redef fun is_ok do return curr_pos <= max
	redef fun item do return target[curr_pos]
	redef fun next do curr_pos += 1
	redef fun index do return curr_pos
end
private class FlatStringCharView
	super StringCharView
	redef type SELFTYPE: FlatString
	redef fun [](index) do return target[index]
	redef fun iterator_from(start) do return new FlatStringCharIterator(target, start)
	redef fun reverse_iterator_from(start) do return new FlatStringCharReverseIterator(target, start)
end
private class FlatStringByteReverseIterator
	super IndexedIterator[Int]
	var target: FlatString
	var target_items: CString is noautoinit
	var curr_pos: Int
	init
	do
		var tgt = target
		target_items = tgt._items
		curr_pos += tgt._first_byte
	end
	redef fun is_ok do return curr_pos >= target._first_byte
	redef fun item do return target_items[curr_pos]
	redef fun next do curr_pos -= 1
	redef fun index do return curr_pos - target._first_byte
end
private class FlatStringByteIterator
	super IndexedIterator[Int]
	var target: FlatString
	var target_items: CString is noautoinit
	var curr_pos: Int
	init
	do
		var tgt = target
		target_items = tgt._items
		curr_pos += tgt._first_byte
	end
	redef fun is_ok do return curr_pos <= target.last_byte
	redef fun item do return target_items[curr_pos]
	redef fun next do curr_pos += 1
	redef fun index do return curr_pos - target._first_byte
end
private class FlatStringByteView
	super StringByteView
	redef type SELFTYPE: FlatString
	redef fun [](index)
	do
		# Check that the index (+ _first_byte) is not larger than last_byte
		# In other terms, if the index is valid
		var target = _target
		assert index >= 0 and index < target._byte_length
		var ind = index + target._first_byte
		return target._items[ind]
	end
	redef fun iterator_from(start) do return new FlatStringByteIterator(target, start)
	redef fun reverse_iterator_from(start) do return new FlatStringByteReverseIterator(target, start)
end
redef class Buffer
	redef new do return new FlatBuffer
	redef new with_cap(i) do return new FlatBuffer.with_capacity(i)
end
# Mutable strings of characters.
class FlatBuffer
	super FlatText
	super Buffer
	redef fun chars do return new FlatBufferCharView(self)
	redef fun bytes do return new FlatBufferByteView(self)
	private var capacity = 0
	redef fun fast_cstring do return _items.fast_cstring(0)
	redef fun substrings do return new FlatSubstringsIter(self)
	# Re-copies the `CString` into a new one and sets it as the new `Buffer`
	#
	# This happens when an operation modifies the current `Buffer` and
	# the Copy-On-Write flag `written` is set at true.
	private fun reset do
		var nns = new CString(capacity)
		if _byte_length != 0 then _items.copy_to(nns, _byte_length, 0, 0)
		_items = nns
		written = false
	end
	# Shifts the content of the buffer by `len` bytes to the right, starting at byte `from`
	#
	# Internal only, does not modify _byte_length or length, this is the caller's responsability
	private fun rshift_bytes(from: Int, len: Int) do
		var oit = _items
		var nit = _items
		var bt = _byte_length
		if bt + len > capacity then
			capacity = capacity * 2 + 2
			nit = new CString(capacity)
			oit.copy_to(nit, 0, 0, from)
		end
		oit.copy_to(nit, bt - from, from, from + len)
	end
	# Shifts the content of the buffer by `len` bytes to the left, starting at `from`
	#
	# Internal only, does not modify _byte_length or length, this is the caller's responsability
	private fun lshift_bytes(from: Int, len: Int) do
		var it = _items
		it.copy_to(it, _byte_length - from, from, from - len)
	end
	redef fun []=(index, item)
	do
		assert index >= 0 and index <= _length
		if written then reset
		if index == _length then
			add item
			return
		end
		var it = _items
		var ip = it.char_to_byte_index(index)
		var c = it.char_at(ip)
		var clen = c.u8char_len
		var itemlen = item.u8char_len
		var size_diff = itemlen - clen
		if size_diff > 0 then
			rshift_bytes(ip + clen, size_diff)
		else if size_diff < 0 then
			lshift_bytes(ip + clen, -size_diff)
		end
		_byte_length += size_diff
		it.set_char_at(ip, item)
	end
	redef fun insert(s, pos) do
		assert pos >= 0 and pos <= length
		if pos == length then
			append s
			return
		end
		var slen = s.byte_length
		enlarge(byte_length + slen)
		var it = _items
		var shpos = it.char_to_byte_index(pos)
		rshift_bytes(shpos, slen)
		s.copy_to_native(it, slen, 0, shpos)
		length += s.length
		byte_length += slen
	end
	redef fun insert_char(c, pos) do
		assert pos >= 0 and pos <= length
		if pos == length then
			add c
			return
		end
		var clen = c.u8char_len
		enlarge(byte_length + clen)
		var it = _items
		var shpos = it.char_to_byte_index(pos)
		rshift_bytes(shpos, clen)
		it.set_char_at(shpos, c)
		length += 1
		byte_length += clen
	end
	redef fun add(c)
	do
		if written then reset
		var clen = c.u8char_len
		var bt = _byte_length
		enlarge(bt + clen)
		_items.set_char_at(bt, c)
		_byte_length += clen
		_length += 1
	end
	redef fun clear do
		_byte_length = 0
		_length = 0
		if written then
			_capacity = 16
			reset
		end
	end
	redef fun empty do return new Buffer
	redef fun enlarge(cap)
	do
		var c = capacity
		if cap <= c then return
		if c <= 16 then c = 16
		while c <= cap do c = c * 2
		# The COW flag can be set at false here, since
		# it does a copy of the current `Buffer`
		written = false
		var bln = _byte_length
		var a = new CString(c)
		if bln > 0 then
			var it = _items
			if bln > 0 then it.copy_to(a, bln, 0, 0)
		end
		_items = a
		capacity = c
	end
	redef fun to_s
	do
		written = true
		var bln = _byte_length
		if bln == 0 then _items = new CString(1)
		return new FlatString.full(_items, bln, 0, _length)
	end
	redef fun to_cstring
	do
		var bln = _byte_length
		var new_native = new CString(bln + 1)
		new_native[bln] = 0
		if _length > 0 then _items.copy_to(new_native, bln, 0, 0)
		return new_native
	end
	# Create a new empty string.
	init do end
	# Low-level creation a new buffer with given data.
	#
	# `_items` will be used as is, without copy, to store the characters of the buffer.
	# Aliasing issues is the responsibility of the caller.
	#
	# If `_items` is shared, `written` should be set to true after the creation
	# so that a modification will do a copy-on-write.
	private init with_infos(items: CString, capacity, byte_length, length: Int)
	do
		self._items = items
		self.capacity = capacity
		self._byte_length = byte_length
		self._length = length
	end
	# Create a new string copied from `s`.
	init from(s: Text)
	do
		_items = new CString(s.byte_length)
		for i in s.substrings do i._items.copy_to(_items, i._byte_length, first_byte, 0)
		_byte_length = s.byte_length
		_length = s.length
		_capacity = _byte_length
	end
	# Create a new empty string with a given capacity.
	init with_capacity(cap: Int)
	do
		assert cap >= 0
		_items = new CString(cap)
		capacity = cap
		_byte_length = 0
	end
	redef fun append(s)
	do
		if s.is_empty then return
		var sl = s.byte_length
		var nln = _byte_length + sl
		enlarge(nln)
		if s isa FlatText then
			s._items.copy_to(_items, sl, s.first_byte, _byte_length)
		else
			for i in s.substrings do append i
			return
		end
		_byte_length = nln
		_length += s.length
	end
	# Copies the content of self in `dest`
	fun copy(start: Int, len: Int, dest: Buffer, new_start: Int)
	do
		var self_chars = self.chars
		var dest_chars = dest.chars
		for i in [0..len-1] do
			dest_chars[new_start+i] = self_chars[start+i]
		end
	end
	redef fun substring(from, count)
	do
		assert count >= 0
		if from < 0 then from = 0
		if (from + count) > _length then count = _length - from
		if count <= 0 then return new Buffer
		var its = _items
		var bytefrom = its.char_to_byte_index(from)
		var byteto = its.char_to_byte_index(count + from - 1)
		byteto += its.char_at(byteto).u8char_len - 1
		var byte_length = byteto - bytefrom + 1
		var r_items = new CString(byte_length)
		its.copy_to(r_items, byte_length, bytefrom, 0)
		return new FlatBuffer.with_infos(r_items, byte_length, byte_length, count)
	end
	redef fun append_substring_impl(s, from, length) do
		if length <= 0 then return
		if not s isa FlatText then
			super
			return
		end
		var sits = s._items
		var bytest = s.char_to_byte_index(from)
		var bytend = s.char_to_byte_index(from + length - 1)
		var btln = bytend - bytest + sits.char_at(bytend).u8char_len
		enlarge(btln + _byte_length)
		sits.copy_to(_items, btln, bytest, _byte_length)
		_byte_length += btln
		_length += length
	end
	redef fun remove_at(p, len) do
		if len == null then len = 1
		if len == 0 then return
		var its = _items
		var bst = char_to_byte_index(p)
		var bend = char_to_byte_index(p + len - 1)
		bend += its.char_at(bend).u8char_len
		var blen = bend - bst
		lshift_bytes(bend, bend - bst)
		byte_length -= blen
		length -= len
	end
	redef fun reverse
	do
		written = false
		var ns = new FlatBuffer.with_capacity(capacity)
		for i in chars.reverse_iterator do ns.add i
		_items = ns._items
	end
	redef fun times(repeats)
	do
		var bln = _byte_length
		var x = new FlatString.full(_items, bln, 0, _length)
		for i in [1 .. repeats[ do
			append(x)
		end
	end
	redef fun upper
	do
		if written then reset
		for i in [0 .. _length[ do self[i] = self[i].to_upper
	end
	redef fun lower
	do
		if written then reset
		for i in [0 .. _length[ do self[i] = self[i].to_lower
	end
end
private class FlatBufferByteReverseIterator
	super IndexedIterator[Int]
	var target: FlatBuffer
	var target_items: CString is noautoinit
	var curr_pos: Int
	init do target_items = target._items
	redef fun index do return curr_pos
	redef fun is_ok do return curr_pos >= 0
	redef fun item do return target_items[curr_pos]
	redef fun next do curr_pos -= 1
end
private class FlatBufferByteView
	super BufferByteView
	redef type SELFTYPE: FlatBuffer
	redef fun [](index) do return target._items[index]
	redef fun iterator_from(pos) do return new FlatBufferByteIterator(target, pos)
	redef fun reverse_iterator_from(pos) do return new FlatBufferByteReverseIterator(target, pos)
end
private class FlatBufferByteIterator
	super IndexedIterator[Int]
	var target: FlatBuffer
	var target_items: CString is noautoinit
	var curr_pos: Int
	init do if isset target._items then target_items = target._items
	redef fun index do return curr_pos
	redef fun is_ok do return curr_pos < target._byte_length
	redef fun item do return target_items[curr_pos]
	redef fun next do curr_pos += 1
end
private class FlatBufferCharReverseIterator
	super IndexedIterator[Char]
	var target: FlatBuffer
	var curr_pos: Int
	redef fun index do return curr_pos
	redef fun is_ok do return curr_pos >= 0
	redef fun item do return target[curr_pos]
	redef fun next do curr_pos -= 1
end
private class FlatBufferCharView
	super BufferCharView
	redef type SELFTYPE: FlatBuffer
	redef fun [](index) do return target[index]
	redef fun []=(index, item)
	do
		assert index >= 0 and index <= length
		if index == length then
			add(item)
			return
		end
		target[index] = item
	end
	redef fun push(c)
	do
		target.add(c)
	end
	redef fun add(c)
	do
		target.add(c)
	end
	fun enlarge(cap: Int)
	do
		target.enlarge(cap)
	end
	redef fun append(s)
	do
		var s_length = s.length
		if target.capacity < s.length then enlarge(s_length + target._length)
		for i in s do target.add i
	end
	redef fun iterator_from(pos) do return new FlatBufferCharIterator(target, pos)
	redef fun reverse_iterator_from(pos) do return new FlatBufferCharReverseIterator(target, pos)
end
private class FlatBufferCharIterator
	super IndexedIterator[Char]
	var target: FlatBuffer
	var max: Int is noautoinit
	var curr_pos: Int
	init do max = target._length - 1
	redef fun index do return curr_pos
	redef fun is_ok do return curr_pos <= max
	redef fun item do return target[curr_pos]
	redef fun next do curr_pos += 1
end
redef class CString
	# Get a `String` from the data at `self` copied into Nit memory
	#
	# Require: `self` is a null-terminated string.
	redef fun to_s do return to_s_unsafe
	# Get a `String` from `byte_length` bytes at `self` copied into Nit memory
	#
	# The string is cleaned.
	fun to_s_with_length(byte_length: Int): String do return to_s_unsafe(byte_length)
	redef fun to_s_unsafe(byte_length, char_length, copy, clean)
	do
		byte_length = byte_length or else cstring_length
		clean = clean or else true
		copy = copy or else true
		# Clean?
		var str = null
		if clean then
			str = clean_utf8(byte_length)
			char_length = str.length
		else
			char_length = char_length or else utf8_length(0, byte_length)
		end
		# Copy? (if not already copied by `clean_utf8`)
		if copy and (str == null or str.items == self) then
			var new_cstr = new CString(byte_length + 1)
			copy_to(new_cstr, byte_length, 0, 0)
			new_cstr[byte_length] = 0
			str = new FlatString.full(new_cstr, byte_length, 0, char_length)
		end
		if str == null then
			str = new FlatString.full(self, byte_length, 0, char_length)
		end
		return str
	end
	# Cleans a CString if necessary
	fun clean_utf8(len: Int): FlatString do
		var replacements: nullable Array[Int] = null
		var end_length = len
		var pos = 0
		var chr_ln = 0
		var rem = len
		while rem > 0 do
			while rem >= 4 do
				var i = fetch_4_chars(pos)
				if i & 0x80808080u32 != 0u32 then break
				pos += 4
				chr_ln += 4
				rem -= 4
			end
			if rem == 0 then break
			var b = self[pos]
			if b & 0x80 == 0x00 then
				pos += 1
				chr_ln += 1
				rem -= 1
				continue
			end
			var nxst = length_of_char_at(pos)
			var ok_st: Bool
			if nxst == 1 then
				ok_st = b & 0x80 == 0
			else if nxst == 2 then
				ok_st = b & 0xE0 == 0xC0
			else if nxst == 3 then
				ok_st = b & 0xF0 == 0xE0
			else
				ok_st = b & 0xF8 == 0xF0
			end
			if not ok_st then
				if replacements == null then replacements = new Array[Int]
				replacements.add pos
				end_length += 2
				pos += 1
				rem -= 1
				chr_ln += 1
				continue
			end
			var ok_c: Bool
			var c = char_at(pos)
			var cp = c.code_point
			if nxst == 1 then
				ok_c = cp >= 0 and cp <= 0x7F
			else if nxst == 2 then
				ok_c = cp >= 0x80 and cp <= 0x7FF
			else if nxst == 3 then
				ok_c = cp >= 0x800 and cp <= 0xFFFF
				ok_c = ok_c and not (cp >= 0xD800 and cp <= 0xDFFF) and cp != 0xFFFE and cp != 0xFFFF
			else
				ok_c = cp >= 0x10000 and cp <= 0x10FFFF
			end
			if not ok_c then
				if replacements == null then replacements = new Array[Int]
				replacements.add pos
				end_length += 2
				pos += 1
				chr_ln += 1
				rem -= 1
				continue
			end
			var clen = c.u8char_len
			pos += clen
			rem -= clen
			chr_ln += 1
		end
		var ret = self
		if end_length != len then
			ret = new CString(end_length)
			var old_repl = 0
			var off = 0
			var repls = replacements.as(not null)
			var r = repls.items.as(not null)
			var imax = repls.length
			for i in [0 .. imax[ do
				var repl_pos = r[i]
				var chkln = repl_pos - old_repl
				copy_to(ret, chkln, old_repl, off)
				off += chkln
				ret[off] = 0xEF
				ret[off + 1] = 0xBF
				ret[off + 2] = 0xBD
				old_repl = repl_pos + 1
				off += 3
			end
			copy_to(ret, len - old_repl, old_repl, off)
		end
		return new FlatString.full(ret, end_length, 0, chr_ln)
	end
	# Sets the next bytes at position `pos` to the value of `c`, encoded in UTF-8
	#
	# Very unsafe, make sure to have room for this char prior to calling this function.
	private fun set_char_at(pos: Int, c: Char) do
		var cp = c.code_point
		if cp < 128 then
			self[pos] = cp
			return
		end
		var ln = c.u8char_len
		if ln == 2 then
			self[pos] = 0xC0 | ((cp & 0x7C0) >> 6)
			self[pos + 1] = 0x80 | (cp & 0x3F)
		else if ln == 3 then
			self[pos] = 0xE0 | ((cp & 0xF000) >> 12)
			self[pos + 1] = 0x80 | ((cp & 0xFC0) >> 6)
			self[pos + 2] = 0x80 | (cp & 0x3F)
		else if ln == 4 then
			self[pos] = 0xF0 | ((cp & 0x1C0000) >> 18)
			self[pos + 1] = 0x80 | ((cp & 0x3F000) >> 12)
			self[pos + 2] = 0x80 | ((cp & 0xFC0) >> 6)
			self[pos + 3] = 0x80 | (cp & 0x3F)
		end
	end
end
redef class Int
	# return displayable int in base 10 and signed
	#
	#     assert 1.to_s            == "1"
	#     assert (-123).to_s       == "-123"
	redef fun to_s do
		# Fast case for common numbers
		if self == 0 then return "0"
		if self == 1 then return "1"
		var nslen = int_to_s_len
		var ns = new CString(nslen + 1)
		ns[nslen] = 0
		native_int_to_s(ns, nslen + 1)
		return new FlatString.full(ns, nslen, 0, nslen)
	end
end
redef class Array[E]
	# Fast implementation
	redef fun plain_to_s
	do
		var l = _length
		if l == 0 then return ""
		var its = _items.as(not null)
		var first = its[0]
		if l == 1 then if first == null then return "" else return first.to_s
		var na = new NativeArray[String](l)
		var i = 0
		var sl = 0
		var mypos = 0
		while i < l do
			var itsi = its[i]
			if itsi == null then
				i += 1
				continue
			end
			var tmp = itsi.to_s
			sl += tmp.byte_length
			na[mypos] = tmp
			i += 1
			mypos += 1
		end
		var ns = new CString(sl + 1)
		ns[sl] = 0
		i = 0
		var off = 0
		while i < mypos do
			var tmp = na[i]
			if tmp isa FlatString then
				var tpl = tmp._byte_length
				tmp._items.copy_to(ns, tpl, tmp._first_byte, off)
				off += tpl
			else
				for j in tmp.substrings do
					var s = j.as(FlatString)
					var slen = s._byte_length
					s._items.copy_to(ns, slen, s._first_byte, off)
					off += slen
				end
			end
			i += 1
		end
		return new FlatString.with_infos(ns, sl, 0)
	end
end
redef class NativeArray[E]
	redef fun native_to_s do
		assert self isa NativeArray[String]
		var l = length
		var na = self
		var i = 0
		var sl = 0
		var mypos = 0
		while i < l do
			sl += na[i].byte_length
			i += 1
			mypos += 1
		end
		var ns = new CString(sl + 1)
		ns[sl] = 0
		i = 0
		var off = 0
		while i < mypos do
			var tmp = na[i]
			if tmp isa FlatString then
				var tpl = tmp._byte_length
				tmp._items.copy_to(ns, tpl, tmp._first_byte, off)
				off += tpl
			else
				for j in tmp.substrings do
					var s = j.as(FlatString)
					var slen = s._byte_length
					s._items.copy_to(ns, slen, s._first_byte, off)
					off += slen
				end
			end
			i += 1
		end
		return new FlatString.with_infos(ns, sl, 0)
	end
end
redef class Map[K,V]
	redef fun join(sep, couple_sep)
	do
		if is_empty then return ""
		var s = new Buffer # Result
		# Concat first item
		var i = iterator
		var k = i.key
		var e = i.item
		s.append("{k or else "<null>"}{couple_sep}{e or else "<null>"}")
		# Concat other _items
		i.next
		while i.is_ok do
			s.append(sep)
			k = i.key
			e = i.item
			s.append("{k or else "<null>"}{couple_sep}{e or else "<null>"}")
			i.next
		end
		return s.to_s
	end
end
lib/core/text/flat.nit:11,1--1594,3