class EL_OBJECT_FACTORY
Client examples: LIBRARY_OVERRIDE_GENERATOR ; SINE_WAVE_INTEGRATION_APP ; TYPE_TEST_SET
Factory for instances of Eiffel classes conforming to parameter G
Tuple arguments act as type manifests with each type A, B, C.. conforming to G. A contract ensures all types conform. Typically you would create the tuple like this:
Types: TUPLE [A, B, C ..] once create Result end
note
description: "[
Factory for instances of Eiffel classes conforming to parameter `G'
Tuple arguments act as type manifests with each type `A, B, C..' conforming to `G'.
A contract ensures all types conform. Typically you would create the tuple like this:
Types: TUPLE [A, B, C ..]
once
create Result
end
]"
author: "Finnian Reilly"
copyright: "Copyright (c) 2001-2022 Finnian Reilly"
contact: "finnian at eiffel hyphen loop dot com"
license: "MIT license (See: en.wikipedia.org/wiki/MIT_License)"
date: "2024-09-22 9:33:42 GMT (Sunday 22nd September 2024)"
revision: "32"
class
EL_OBJECT_FACTORY [G]
inherit
ANY
redefine
default_create
end
EL_STRING_GENERAL_ROUTINES
EL_MODULE_EIFFEL
create
make, default_create
feature {NONE} -- Initialization
default_create
do
create types_indexed_by_name.make_equal (5)
create default_alias.make_empty
end
make (mapping_table: ARRAY [TUPLE [name: READABLE_STRING_GENERAL; type: TYPE [G]]])
require
not_empty: not mapping_table.is_empty
local
key: ZSTRING
do
default_create
types_indexed_by_name.accommodate (mapping_table.count)
across mapping_table as map loop
key := as_zstring (map.item.name)
if map.cursor_index = 1 then
default_alias := key
end
types_indexed_by_name [key] := map.item.type
end
end
feature -- Factory
new_item_from_type (type: TYPE [G]): detachable G
-- new item from dynamic type `type_id'
do
Result := new_item_from_type_id (type.type_id)
end
new_item_from_type_id (type_id: INTEGER): detachable G
-- new item from dynamic type `type_id'
require
valid_type_id: valid_type_id (type_id)
do
if type_id >= 0 and then attached {G} Eiffel.new_instance_of (type_id) as new then
Result := new
end
end
new_item_from_alias (a_alias: READABLE_STRING_GENERAL): detachable G
-- uninitialized instance for type corresponding to `type_alias'
-- or else instance for `default_alias' if `type_alias' cannot be found
require
valid_type: a_alias /= default_alias implies valid_alias (a_alias)
valid_default_type: a_alias = default_alias implies valid_alias (default_alias)
do
if types_indexed_by_name.has_general_key (a_alias) then
Result := new_item_from_type (types_indexed_by_name.found_item)
else
Result := new_item_from_alias (default_alias)
end
end
new_item_from_name (class_name: READABLE_STRING_GENERAL): detachable G
--
require
valid_type: valid_name (class_name)
do
if attached Eiffel.dynamic_type_from_string (class_name) as type_id then
Result := new_item_from_type_id (type_id)
end
end
feature -- Access
alias_names: EL_ZSTRING_LIST
do
create Result.make_from_special (types_indexed_by_name.key_list.area)
end
count: INTEGER
do
Result := types_indexed_by_name.count
end
default_alias: ZSTRING
feature -- Element change
force (type: TYPE [G]; name: ZSTRING)
do
types_indexed_by_name.force (type, name)
end
put (type: TYPE [G]; name: ZSTRING)
do
types_indexed_by_name.put (type, name)
end
feature -- Contract support
has_alias (a_alias: READABLE_STRING_GENERAL): BOOLEAN
do
Result := types_indexed_by_name.has_general (a_alias)
end
valid_alias (a_alias: READABLE_STRING_GENERAL): BOOLEAN
do
if types_indexed_by_name.has_general_key (a_alias) then
Result := valid_name (types_indexed_by_name.found_item)
end
end
valid_name (class_name: READABLE_STRING_GENERAL): BOOLEAN
do
if not class_name.is_empty then
Result := valid_type_id (Eiffel.dynamic_type_from_string (class_name))
end
end
valid_type_id (type_id: INTEGER): BOOLEAN
do
Result := {ISE_RUNTIME}.type_conforms_to (type_id, ({G}).type_id)
end
feature {NONE} -- Internal attributes
types_indexed_by_name: EL_ZSTRING_HASH_TABLE [TYPE [G]]
-- map of alias names to types
end