=begin

	MetaRuby
	file: ProcAsArray (sample for HollowArray usage)

	Copyright (c) 2001 by Mathieu Bouchard
	Licensed under the same license as Ruby.

=end

require "Hollow/Array"

# usage: ProcAsArray.new(n) {|x| .... }
# where x will be in range 0...n
# faking a _frozen_ array of length n
# the array 'contents' are not stored anywhere, not even cached.
# (note: "freeze" works now)

# example 1:
# a = ProcAsArray.new(14) {|x| ((.5+1.25**.5)**x / 5**.5).round }
#     #=> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233]
# a.length     #=> 14
# a[3..8]      #=> [2, 3, 5, 8, 13, 21]
# a.index(89)  #=> 11

# example 2:
# v = 3**10; a = ProcAsArray.new(v.size*8) {|x| v[x] }
# (see also: BitArray)

class ProcAsArray

	class<<self; def [](*v); new.replace v; end; end

	def initialize(n,&proc)
		@length = n
		@proc = proc
		super()
		freeze
	end

	module Implementation
		def length; @length; end
		def get(i); @proc.call i; end
		def get_seq(i,n); (i...i+n).map {|x| @proc.call x }; end

		@@big_error = "FROZEN!!! (should NOT get here)"
		def put(i,v);       raise NotImplementedError @@big_error; end
		def put_seq(i,n,v); raise NotImplementedError @@big_error; end
	end

	include HollowArray
	include Implementation
	include SimpleArrayP::Contract # for safety

# disabling this feature that does not work yet
#	# defining this to create an instance of Array, not ProcAsArray
#	def dup
#		to_a
#	end
end
