Operator

Declares or defines an overloaded operator.

Syntax
   { Type | Class | Union } typename
      Declare Operator Cast () [ ByRef ] As datatype
      Declare Operator @ () [ ByRef ] As datatype Ptr
      Declare Operator assignment_op ( [ ByRef | ByVal ] rhs As datatype )
      Declare Operator [] ( index As datatype ) [ ByRef ] As datatype
      Declare Operator New ( size As UInteger ) As Any Ptr
      Declare Operator New[] ( size As UInteger ) As Any Ptr
      Declare Operator Delete ( buf  As Any Ptr )
      Declare Operator Delete[] ( buf  As Any Ptr )
   End { Type | Class | Union }

   { Type | Class | Union } typename
      Declare Operator For ()
      Declare Operator For ( [ ByRef | ByVal ] stp As typename )
      Declare Operator Step ()
      Declare Operator Step ( [ ByRef | ByVal ] stp As typename )
      Declare Operator Next ( [ ByRef | ByVal ] cond As typename ) As 
      Integer
      Declare Operator Next ( [ ByRef | ByVal ] cond As typename, [ ByRef | 
      ByVal ] stp As typename ) As Integer
   End { Type | Class | Union }

   Declare Operator unary_op ( [ ByRef | ByVal ] rhs As datatype ) As 
   datatype
   Declare Operator binary_op ( [ ByRef | ByVal ] lhs As datatype, [ ByRef 
   | ByVal ] rhs As datatype ) As datatype

   Operator typename.Cast () [ ByRef ] As datatype [ Export ]
   Operator typename.@ () [ ByRef ] As datatype Ptr [ Export ]
   Operator typename.assignment_op ( [ ByRef | ByVal ] rhs As datatype ) [ 
   Export ]
   Operator typename.[] ( index As datatype ) [ ByRef ] As datatype [ Export
   ]
   Operator unary_op ( [ ByRef | ByVal ] rhs As datatype ) As datatype [ 
   Export ]
   Operator binary_op ( [ ByRef | ByVal ] lhs As datatype, [ ByRef | ByVal 
   ] rhs As datatype ) As datatype [ Export ]
   Operator typename.New ( size as uinteger ) As Any Ptr [ Export ]
   Operator typename.New[] ( size As UInteger ) As Any Ptr [ Export ]
   Operator typename.Delete ( buf  As Any Ptr ) [ Export ]
   Operator typename.Delete[] ( buf  As Any Ptr ) [ Export ]

Parameters
   typename 
      Name of the Type, Class, Union, or Enum.
   assignment_op 
      let += -= *= &= /= \= mod= shl= shr= and= or= xor= imp= eqv= ^=
   unary_op
      - not * -> abs sgn fix frac int exp log sin asin cos acos tan atn len 
      sqr
   binary_op
      + - * & / \ mod shl shr and or xor imp eqv ^ = <> < > <= >=

Description
   The built in operators like =, +, and cast have predefined behaviors 
   when used in expressions.  These operators can be overloaded to do 
   something other than predefined operations when at least one of the 
   arguments to the operator is a Type, Class, Enum, or Union data type.

   Operators are just functions.  The operator '+' has functionality like 
   Function Plus( A as DataType, B as DataType ) as DataType.  See 
   Operator Overloading for more information.  Operators can be overloaded 
   to accept different data types as parameters.  The Cast Operator is the 
   only operator (or function) that can be declared multiple times when 
   only the return type differs, but not the same as the Type, Class, or 
   Union it is declared in (for not explicit usage, the compiler may decide 
   which cast overload to call based on how the object is used).

   Non-static operator members are declared inside the Type, Class, or Union
   .  Global operators are declared outside.  All operator definitions 
   (procedure bodies) must appear outside.

   Let, Cast, and other assignment operators must be declared inside the 
   Type, Class, or Union.  As all non-static member procedures, they have 
   passed a hidden This parameter.

   Unary operators must be declared outside the Type, Class, or Union and 
   have a return data type explicitly declared.  Unary operators can be 
   overloaded to return any valid data type, except for 
   Operator -> (Pointer To Member Access) which must return a Type, Class, 
   or Union data type.

   Binary operators must be declared outside the Type, Class, or Union and 
   have a return data type explicitly declared.  Binary operators can be 
   overloaded with valid data types, including for relational operators, 
   which can also return any valid data type.

   Let refers to the assignment operator, as in LET a=b. The Let keyword is 
   omitted in common practice, and is not allowed in the -lang fb dialect.  
   However, Let() can be used to assign the fields of a UDT to multiple 
   variables.

   See For, Step, and Next for more information on overloading the For..Next
   statement for use with user defined types.

   Although declared inside the Type, Class, or Union, the member operators 
   New, New[], Delete, and Delete[] are always static, even if not 
   explicitly declared (Static keyword is unnecessary but allowed).

Example
   '' operator1.bas

   Type Vector2D
     As Single x, y

     '' Return a string containing the vector data.
     Declare Operator Cast() As String

     '' Multiply the vector by a scalar.
     Declare Operator *= ( ByVal rhs As Single )
   End Type

   '' Allow two vectors to be able to be added together.
   Declare Operator + ( ByRef lhs As Vector2D, ByRef rhs As Vector2D ) As Vector2D

   '' Return the modulus (single) of the vector using the overloaded operator abs().
   Declare Operator Abs (  ByRef rhs As Vector2D ) As Single

   Operator Vector2D.cast () As String
     Return "(" + Str(x) + ", " + Str(y) + ")"
   End Operator

   Operator Vector2D.*= ( ByVal rhs As Single )
     This.x *= rhs
     This.y *= rhs
   End Operator

   Operator + ( ByRef lhs As Vector2D, ByRef rhs As Vector2D ) As Vector2D
     Return Type<Vector2D>( lhs.x + rhs.x, lhs.y + rhs.y )
   End Operator

   Operator Abs ( ByRef rhs As Vector2D ) As Single
     Return Sqr( rhs.x * rhs.x + rhs.y * rhs.y )
   End Operator

   Dim a As Vector2D = Type<Vector2D>( 1.2, 3.4 )
   Dim b As Vector2D = Type<Vector2D>( 8.9, 6.7 )
   Dim c As Vector2D = Type<Vector2D>( 4.3, 5.6 )

   Print "a = "; a, "abs(a) ="; Abs( a )
   Print "b = "; b, "abs(b) ="; Abs( b )
   Print "a + b = "; a + b, "abs(a+b) ="; Abs( a + b )
   Print "c = "; c, "abs(c) ="; Abs( c )
   Print "'c *= 3'"
   c *= 3
   Print "c = "; c, "abs(c) ="; Abs( c )

   Small use case of the operator "[]": simplest smart pointers for byte 
   buffers.
   '' operator3.bas

   '' A smart pointer is an object which behaves like a pointer but does more than a pointer:
   '' - This object is flexible as a pointer and has the advantage of being an object,
   ''   like constructor and destructor called automatically.
   '' - Therefore, the destructor of the smart pointer will be automatically called
   ''   when this object goes out of scope, and it will delete the user pointer.

   '' Example of simplest smart pointers for byte buffers:
   '' - Constructor and destructor allow to allocate, deallocate, and resize the byte buffer.
   '' - Pointer index operator allows to access buffer elements.
   '' - Copy-constructor and let-operator are just declared in private section,
   ''   in order to disallow copy construction and any assignment.

   Type smartByteBuffer
     Public:
      Declare Constructor (ByVal size As UInteger = 0)
      Declare Operator [] (ByVal index As UInteger) ByRef As Byte
      Declare Destructor ()
     Private:
      Declare Constructor (ByRef rhs As smartByteBuffer)
      Declare Operator Let (ByRef rhs As smartByteBuffer)
      Dim As Byte Ptr psbb
   End Type

   Constructor smartByteBuffer (ByVal size As UInteger = 0)
     This.destructor()
     If size > 0 Then
      This.psbb = New Byte[size]
      Print "Byte buffer allocated"
     End If
   End Constructor

   Operator smartByteBuffer.[] (ByVal index As UInteger) ByRef As Byte
     Return This.psbb[index]
   End Operator

   Destructor smartByteBuffer ()
     If This.psbb > 0 Then
      Delete[] This.psbb
      This.psbb = 0
      Print "Byte buffer deallocated"
     End If
   End Destructor

   Scope
     Dim As smartByteBuffer sbb = smartByteBuffer(256)
     For I As Integer = 0 To 255
      sbb[I] = I - 128
     Next I
     Print
     For I As Integer = 0 To 255
      Print Using "#####"; sbb[I];
     Next I
     Print
   End Scope

Dialect Differences
   * Only available in the -lang fb dialect.

See also
   * Class
   * Union
   * Type
   * Coercion and Conversion

