Property definitions

core $ MapRead :: defaultinit
# MapRead are abstract associative collections: `key` -> `item`.
interface MapRead[K, V]
	# Get the item at `key`
	#
	#     var x = new HashMap[String, Int]
	#     x["four"] = 4
	#     assert x["four"] == 4
	#     # assert x["five"] #=> abort
	#
	# If the key is not in the map, `provide_default_value` is called (that aborts by default)
	# See `get_or_null` and `get_or_default` for safe variations.
	fun [](key: nullable Object): V is abstract

	# Get the item at `key` or null if `key` is not in the map.
	#
	#     var x = new HashMap[String, Int]
	#     x["four"] = 4
	#     assert x.get_or_null("four") == 4
	#     assert x.get_or_null("five") == null
	#
	# Note: use `has_key` and `[]` if you need the distinction between a key associated with null, and no key.
	fun get_or_null(key: nullable Object): nullable V
	do
		if has_key(key) then return self[key]
		return null
	end

	# Get the item at `key` or return `default` if not in map
	#
	#     var x = new HashMap[String, Int]
	#     x["four"] = 4
	#     assert x.get_or_default("four", 40) == 4
	#     assert x.get_or_default("five", 50) == 50
	#
	fun get_or_default(key: nullable Object, default: V): V
	do
		if has_key(key) then return self[key]
		return default
	end

	# Is there an item associated with `key`?
	#
	#     var x = new HashMap[String, Int]
	#     x["four"] = 4
	#     assert x.has_key("four") == true
	#     assert x.has_key("five") == false
	#
	# By default it is a synonymous to `keys.has` but could be redefined with a direct implementation.
	fun has_key(key: nullable Object): Bool do return self.keys.has(key)

	# Get a new iterator on the map.
	fun iterator: MapIterator[K, V] is abstract

	# Return the point of view of self on the values only.
	# Note that `self` and `values` are views on the same data;
	# therefore any modification of one is visible on the other.
	#
	#     var x = new HashMap[String, Int]
	#     x["four"] = 4
	#     assert x.values.has(4) == true
	#     assert x.values.has(5) == false
	fun values: Collection[V] is abstract

	# Return the point of view of self on the keys only.
	# Note that `self` and `keys` are views on the same data;
	# therefore any modification of one is visible on the other.
	#
	#     var x = new HashMap[String, Int]
	#     x["four"] = 4
	#     assert x.keys.has("four") == true
	#     assert x.keys.has("five") == false
	fun keys: Collection[K] is abstract

	# Is there no item in the collection?
	#
	#     var x = new HashMap[String, Int]
	#     assert x.is_empty  == true
	#     x["four"] = 4
	#     assert x.is_empty  == false
	fun is_empty: Bool is abstract

	# Alias for `not is_empty`.
	#
	# Some people prefer to have conditions grammatically easier to read.
	#
	#     var map = new HashMap[String, Int]
	#     assert map.not_empty == false
	#     map["one"] = 1
	#     assert map.not_empty == true
	fun not_empty: Bool do return not self.is_empty

	# Number of items in the collection.
	#
	#     var x = new HashMap[String, Int]
	#     assert x.length  == 0
	#     x["four"] = 4
	#     assert x.length  == 1
	#     x["five"] = 5
	#     assert x.length  == 2
	fun length: Int is abstract

	# Called by the underling implementation of `[]` to provide a default value when a `key` has no value
	# By default the behavior is to abort.
	#
	# Note: the value is returned *as is*, implementations may want to store the value in the map before returning it
	# @toimplement
	protected fun provide_default_value(key: nullable Object): V do abort

	# Does `self` and `other` have the same keys associated with the same values?
	#
	# ~~~
	# var a = new HashMap[String, Int]
	# var b = new ArrayMap[Object, Numeric]
	# assert a == b
	# a["one"] = 1
	# assert a != b
	# b["one"] = 1
	# assert a == b
	# b["one"] = 2
	# assert a != b
	# ~~~
	redef fun ==(other)
	do
		if not other isa MapRead[nullable Object, nullable Object] then return false
		if other.length != self.length then return false
		for k, v in self do
			if not other.has_key(k) then return false
			if other[k] != v then return false
		end
		return true
	end

	# A hashcode based on the hashcode of the keys and the values.
	#
	# ~~~
	# var a = new HashMap[String, Int]
	# var b = new ArrayMap[Object, Numeric]
	# a["one"] = 1
	# b["one"] = 1
	# assert a.hash == b.hash
	# ~~~
	redef fun hash
	do
		var res = length
		for k, v in self do
			if k != null then res += k.hash * 7
			if v != null then res += v.hash * 11
		end
		return res
	end
end
lib/core/collection/abstract_collection.nit:532,1--682,3