<commit_before>#ifndef __lang_Array__
#define __lang_Array__

#include "Enumerable.js"
#include "Hash.js"

#ifdef BROWSER_LEGACY

////////////////////////////////////////////////////////////////////////////////
// Array Legacy

/**
 * Simulate stanadard Array methods on legacy browsers.
 * All these methods explicitely alter length, as they might be used for
 * array-like objects (e.g. the HtmlElements array).
 */
if (!Array.prototype.push) {
	Array.inject({
		push: function() {
			for (var i = 0, l = arguments.length; i < l; ++i)
				this[this.length++] = arguments[i];
			return this.length;
		},

		pop: function() {
			var i = this.length - 1;
			var old = this[i];
			delete this[i];
			this.length = i;
			return old;
		},

		shift: function() {
			var old = this[0];
			for (var i = 0, l = this.length - 1; i < l; ++i)
				this[i] = this[i + 1];
			delete this[this.length - 1];
			this.length--;
			return old;
		},

		unshift: function() {
			var len = this.length, num = arguments.length;
			this.length += num;
			for (var i = len - 1; i >= 0; i--)
				this[i + num] = this[i];
			for (i = 0; i < num; ++i)
				this[i] = arguments[i];
			return this.length;
		},

		splice: function(start, del) {
			var res = new Array(del), len = this.length;
			// Collect all the removed elements.
			for (var i = 0; i < del; ++i)
				res[i] = this[i + start];
			var num = arguments.length - 2;
			if (num > 0) del -= num;
			if (del > 0) {
				// Move the entries up by the amount of entries to remove.
				for (i = start, l = len - del; i < l; i ++)
					this[i] = this[i + del];
				// Delete the entries that are not used any more.
				// This is needed for pseudo arrays.
				for (i = len - del; i < len; ++i)
					delete this[i];
				this.length = len - del;
			} else {
				// Negative del means there are more new entries than old
				// entries to remove.
				// Adjust length first for speed up on native arrays,
				// by forcing reallocation to the righ sice.
				this.length = len - del;
				// Move the entries down by the emount of new entries - the 
				// amount of entries to remove. 
				for (i = len - 1; i >= start; i--)
					this[i - del] = this[i];
			}
			// Add the new entries
			if (num > 0)
				for (i = 0; i < num; ++i)
					this[i + start] = arguments[i + 2];
			return res;
		},

		/**
		 * On legacy IE, slice does not work correctly with negative indices.
		 */
		slice: function(start, end) {
			if (start < 0) start += this.length;
			if (end < 0) end += this.length;
			else if (end == null) end = this.length;
			var res = new Array(end - start);
			for (var i = start; i < end; ++i)
				res[i - start] = this[i];
			return res;
		}
	});
}

#endif // BROWSER_LEGACY

////////////////////////////////////////////////////////////////////////////////
// Array

Array.inject(new function() {
	var proto = Array.prototype;
	// Do not use Hash.create, as this produces as Hash that hides all Enumerable
	// methods from #inject, since they define _hide!
	// ( var fields = Hash.create(Enumerable, {...}) )
	// Instead, use the generics in Hash to fill a normal object.

	var fields = Hash.merge({}, Enumerable, {
		_HIDE
		_generics: true,
		// tell Base.type what to return for arrays.
		_type: 'array',

		/**
		 * Returns the index of the given object if found, -1 otherwise.
		 */
		indexOf: proto.indexOf || function(obj, i) {
			i = i || 0;
			if (i < 0) i = Math.max(0, this.length + i);
			for (var l = this.length; i < l; ++i)
				if (this[i] == obj) return i;
			return -1;
		},

		/**
		 * Returns the last index of the given object if found, -1 otherwise.
		 */
		lastIndexOf: proto.lastIndexOf || function(obj, i) {
			i = i != null ? i : this.length - 1;
			if (i < 0) i = Math.max(0, this.length + i);
			for (; i >= 0; i--)
				if (this[i] == obj) return i;
			return -1;
		},

		/*
		 * Faster, array-optimized versions of filter, map, every, and some,
		 * relying on the native definitions if available.
		 */
		filter: ITERATE(proto.filter || function(iter, bind, that) {
			var res = [];
			for (var i = 0, l = this.length; i < l; ++i)
				if (ITERATOR(iter, bind, this[i], i, that, __filter))
					res[res.length] = this[i];
			return res;
		}, '__filter'),

		map: ITERATE(proto.map || function(iter, bind, that) {
			var res = new Array(this.length);
			for (var i = 0, l = this.length; i < l; ++i)
				res[i] = ITERATOR(iter, bind, this[i], i, that, __map);
			return res;
		}, '__map'),

		every: ITERATE(proto.every || function(iter, bind, that) {
			for (var i = 0, l = this.length; i < l; ++i)
				if (!ITERATOR(iter, bind, this[i], i, that, __every))
					return false;
			return true;
		}, '__every'),

		some: ITERATE(proto.some || function(iter, bind, that) {
			for (var i = 0, l = this.length; i < l; ++i)
				if (ITERATOR(iter, bind, this[i], i, that, __some))
					return true;
			return false;
		}, '__some'),

		reduce: proto.reduce || function(fn, value) {
			var i = 0;
			if (arguments.length < 2 && this.length) value = this[i++];
			for (var l = this.length; i < l; i++)
				value = fn.call(null, value, this[i], i, this);
			return value;
		},

		findEntry: function(iter, bind) {
			// Use the faster indexOf in case we're not using iterator functions.
			if (iter && !/^(function|regexp)$/.test(Base.type(iter))) {
				var i = this.indexOf(iter);
				// Pretend we were using a iterator function returning true when 
				// the value matches iter, false otherwise.
				// See Enumerable#findEntry for more explanations.
				return { key: i != -1 ? i : null, value: this[i], result: i != -1 };
			}
			// Do not use this.base, as we might call this on non-arrays
			return Enumerable.findEntry.call(this, iter, bind);
		},

		remove: function(iter, bind) {
			var entry = this.findEntry(iter, bind);
			if (entry.key != null)
				this.splice(entry.key, 1);
			return entry.value;
		},

		/**
		 * Overrides the definition in Enumerable.toArray with a more efficient
		 * version.
		 */
		toArray: function() {
#ifdef BROWSER
			var res = this.concat([]);
			// fix Opoera bug where arguments are arrays but do not
			// concatenate correctly (a new array is returned with [0] == this).
			return res[0] == this ? Enumerable.toArray.call(this) : res;
#else // !BROWSER
			return this.concat([]);
#endif // !BROWSER
		},<commit_msg>Added Array#contains as a short-cut to indexOf != -1.<commit_after>#ifndef __lang_Array__
#define __lang_Array__

#include "Enumerable.js"
#include "Hash.js"

#ifdef BROWSER_LEGACY

////////////////////////////////////////////////////////////////////////////////
// Array Legacy

/**
 * Simulate stanadard Array methods on legacy browsers.
 * All these methods explicitely alter length, as they might be used for
 * array-like objects (e.g. the HtmlElements array).
 */
if (!Array.prototype.push) {
	Array.inject({
		push: function() {
			for (var i = 0, l = arguments.length; i < l; ++i)
				this[this.length++] = arguments[i];
			return this.length;
		},

		pop: function() {
			var i = this.length - 1;
			var old = this[i];
			delete this[i];
			this.length = i;
			return old;
		},

		shift: function() {
			var old = this[0];
			for (var i = 0, l = this.length - 1; i < l; ++i)
				this[i] = this[i + 1];
			delete this[this.length - 1];
			this.length--;
			return old;
		},

		unshift: function() {
			var len = this.length, num = arguments.length;
			this.length += num;
			for (var i = len - 1; i >= 0; i--)
				this[i + num] = this[i];
			for (i = 0; i < num; ++i)
				this[i] = arguments[i];
			return this.length;
		},

		splice: function(start, del) {
			var res = new Array(del), len = this.length;
			// Collect all the removed elements.
			for (var i = 0; i < del; ++i)
				res[i] = this[i + start];
			var num = arguments.length - 2;
			if (num > 0) del -= num;
			if (del > 0) {
				// Move the entries up by the amount of entries to remove.
				for (i = start, l = len - del; i < l; i ++)
					this[i] = this[i + del];
				// Delete the entries that are not used any more.
				// This is needed for pseudo arrays.
				for (i = len - del; i < len; ++i)
					delete this[i];
				this.length = len - del;
			} else {
				// Negative del means there are more new entries than old
				// entries to remove.
				// Adjust length first for speed up on native arrays,
				// by forcing reallocation to the righ sice.
				this.length = len - del;
				// Move the entries down by the emount of new entries - the 
				// amount of entries to remove. 
				for (i = len - 1; i >= start; i--)
					this[i - del] = this[i];
			}
			// Add the new entries
			if (num > 0)
				for (i = 0; i < num; ++i)
					this[i + start] = arguments[i + 2];
			return res;
		},

		/**
		 * On legacy IE, slice does not work correctly with negative indices.
		 */
		slice: function(start, end) {
			if (start < 0) start += this.length;
			if (end < 0) end += this.length;
			else if (end == null) end = this.length;
			var res = new Array(end - start);
			for (var i = start; i < end; ++i)
				res[i - start] = this[i];
			return res;
		}
	});
}

#endif // BROWSER_LEGACY

////////////////////////////////////////////////////////////////////////////////
// Array

Array.inject(new function() {
	var proto = Array.prototype;
	// Do not use Hash.create, as this produces as Hash that hides all Enumerable
	// methods from #inject, since they define _hide!
	// ( var fields = Hash.create(Enumerable, {...}) )
	// Instead, use the generics in Hash to fill a normal object.

	var fields = Hash.merge({}, Enumerable, {
		_HIDE
		_generics: true,
		// tell Base.type what to return for arrays.
		_type: 'array',

		/**
		 * Returns the index of the given object if found, -1 otherwise.
		 *
		 * TODO: Why is this here and not in browser legacy above?
		 */
		indexOf: proto.indexOf || function(obj, i) {
			i = i || 0;
			if (i < 0) i = Math.max(0, this.length + i);
			for (var l = this.length; i < l; ++i)
				if (this[i] == obj) return i;
			return -1;
		},

		/**
		 * Returns the last index of the given object if found, -1 otherwise.
		 *
		 * TODO: Why is this here and not in browser legacy above?
		 */
		lastIndexOf: proto.lastIndexOf || function(obj, i) {
			i = i != null ? i : this.length - 1;
			if (i < 0) i = Math.max(0, this.length + i);
			for (; i >= 0; i--)
				if (this[i] == obj) return i;
			return -1;
		},

		/*
		 * Faster, array-optimized versions of filter, map, every, and some,
		 * relying on the native definitions if available.
		 */
		filter: ITERATE(proto.filter || function(iter, bind, that) {
			var res = [];
			for (var i = 0, l = this.length; i < l; ++i)
				if (ITERATOR(iter, bind, this[i], i, that, __filter))
					res[res.length] = this[i];
			return res;
		}, '__filter'),

		map: ITERATE(proto.map || function(iter, bind, that) {
			var res = new Array(this.length);
			for (var i = 0, l = this.length; i < l; ++i)
				res[i] = ITERATOR(iter, bind, this[i], i, that, __map);
			return res;
		}, '__map'),

		every: ITERATE(proto.every || function(iter, bind, that) {
			for (var i = 0, l = this.length; i < l; ++i)
				if (!ITERATOR(iter, bind, this[i], i, that, __every))
					return false;
			return true;
		}, '__every'),

		some: ITERATE(proto.some || function(iter, bind, that) {
			for (var i = 0, l = this.length; i < l; ++i)
				if (ITERATOR(iter, bind, this[i], i, that, __some))
					return true;
			return false;
		}, '__some'),

		reduce: proto.reduce || function(fn, value) {
			var i = 0;
			if (arguments.length < 2 && this.length) value = this[i++];
			for (var l = this.length; i < l; i++)
				value = fn.call(null, value, this[i], i, this);
			return value;
		},

		findEntry: function(iter, bind) {
			// Use the faster indexOf in case we're not using iterator functions.
			if (iter && !/^(function|regexp)$/.test(Base.type(iter))) {
				var i = this.indexOf(iter);
				// Pretend we were using a iterator function returning true when 
				// the value matches iter, false otherwise.
				// See Enumerable#findEntry for more explanations.
				return { key: i != -1 ? i : null, value: this[i], result: i != -1 };
			}
			// Do not use this.base, as we might call this on non-arrays
			return Enumerable.findEntry.call(this, iter, bind);
		},

		remove: function(iter, bind) {
			var entry = this.findEntry(iter, bind);
			if (entry.key != null)
				this.splice(entry.key, 1);
			return entry.value;
		},

		contains: function(obj) {
			return this.indexOf(obj) != -1;
		},

		/**
		 * Overrides the definition in Enumerable.toArray with a more efficient
		 * version.
		 */
		toArray: function() {
#ifdef BROWSER
			var res = this.concat([]);
			// fix Opoera bug where arguments are arrays but do not
			// concatenate correctly (a new array is returned with [0] == this).
			return res[0] == this ? Enumerable.toArray.call(this) : res;
#else // !BROWSER
			return this.concat([]);
#endif // !BROWSER
		},
{'fraction_non_alphanumeric': 0.17497085114652158, 'fraction_numerical': 0.006684803731053245, 'mean_word_length': 2.3522668056279312, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1631163', 'n_tokens_mistral': 5141, 'n_tokens_neox': 4325, 'n_words': 1540}