Operator Is (Run-Time Type Information)

Check if an object is compatible to a type derived from its compile-time 
type
(in the context of inheritance)

Syntax
	result = expression Is  typename

Parameters
	expression
		The expression to check, an object of a type that is directly or 
		indirectly derived from KeyPgObjectObject using KeyPgExtendsExtends.
	typename
		The child type to check for. This type must be directly or indirectly 
		derived from the type of expression (the compile-time type of the 
		object).

Return Value
	Returns negative one (-1) if the expression is an object of real-type 
	typename or one of its base-types derived from the expression type, or 
	zero (0) if it's an object of an incompatible type.

Description
	The Is operator must be used in conjunction with inheritance in order to 
	check compatibility between objects and types from an inheritance 
	structure extending the built-in KeyPgObjectObject type.

	The Is operator is a binary operator that checks whether an object is 
	compatible to its derived types at run-time. Because Is relies on 
	Run-Time Type Information (RTTI), it can only be used with types that 
	are derived from the built-in KeyPgObjectObject type using KeyPgExtendsExtends. The compiler 
	disallows using Is for checks that can be solved at compile-time.

	The Is operator is successful not only for the real-type (the "lowest"), 
	but also for its base-types, as long as they are still below the type of 
	expression (the compile-time type). In order to determine the real-type, 
	all possibilities from lowest to highest must be checked.

	Extending the built-in KeyPgObjectObject type allows to add an extra hidden vtable 
	pointer field at the top of the KeyPgTypeType. The vtable is used to access 
	information for run-time type identification used by the Is operator.

	This operator cannot be overloaded.

Example
	Type Vehicle Extends Object
	   As String Name
	End Type

	Type Car Extends Vehicle
	End Type

	Type Cabriolet Extends Car
	End Type

	Type Bike Extends Vehicle
	End Type

	Sub identify(ByVal p As Object Ptr)
	   Print "Identifying:"

	   '' Not a Vehicle object?
	   If Not (*p Is Vehicle) Then
	      Print , "unknown object"
	      Return
	   End If

	   '' The cast is safe, because we know it's a Vehicle object
	   Print , "name: " & CPtr(Vehicle Ptr, p)->Name

	   If *p Is Car Then
	      Print , "It's a car"
	   End If

	   If *p Is Cabriolet Then
	      Print , "It's a cabriolet"
	   End If

	   If *p Is Bike Then
	      Print , "It's a bike"
	   End If
	End Sub

	Dim As Car ford
	ford.name = "Ford"
	identify(@ford)

	Dim As Cabriolet porsche
	porsche.name = "Porsche"
	identify(@porsche)

	Dim As Bike mountainbike
	mountainbike.name = "Mountain Bike"
	identify(@mountainbike)

	Dim As Vehicle v
	v.name = "some unknown vehicle"
	identify(@v)

	Dim As Object o
	identify(@o)

Differences from QB
	* New to FreeBASIC

See also
	* KeyPgExtendsExtends
	* KeyPgExtendsZstringExtends Zstring
	* KeyPgExtendsWstringExtends Wstring
	* KeyPgObjectObject
	* KeyPgIsIs (Select Case)
	* KeyPgTypeofTypeOf
 
