Correction on AddField prototype

Correction on AddField prototype

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//
USING XSharp.RDD.Enums
/// Definition for the interface that each RDD must implement
/// <seealso cref="T:XSharp.Workarea"/>
INTERFACE XSharp.RDD.IRdd
	// Navigation
	/// Evaluate a code block for each row.
	/// <param name="info">object containing the information about which rows to visit.</param>
	METHOD DbEval(info AS DbEvalInfo)		AS LOGIC
	/// Position the cursor to the first logical row.
	METHOD GoTop()							AS LOGIC
	/// Position the cursor to the last logical row.
	METHOD GoBottom()						AS LOGIC
	/// Position the cursor to a specific, physical row.
	/// <param name="nRec">The row number of the new cursor position.</param>
	METHOD GoTo(nRec AS LONG)				AS LOGIC
	/// Position the cursor to a specific, physical identity.
	/// <param name="oRec">The row ID of the new cursor position.</param>
	METHOD GoToId(oRec AS OBJECT)			AS LOGIC
	/// Position the cursor relative to its current position.
	/// <param name="nToSkip">The number of rows to skip.  If this argument is positive, the cursor moves forward (toward the end-of-file).  If it is negative, the cursor moves backward (toward the beginning-of-file).</param>
	METHOD Skip(nToSkip AS INT)				AS LOGIC
	/// Position the cursor, respecting scope and filter conditions.
	/// <param name="nToSkip">The number of rows to skip.  If this argument is positive, the cursor moves forward (toward the end-of-file).  If it is negative, the cursor moves backward (toward the beginning-of-file).</param>
	METHOD SkipFilter(nToSkip AS INT)		AS LOGIC
	/// Position the cursor regardless of scope and filter conditions.
	/// <param name="nToSkip">The number of rows to skip.  If this argument is positive, the cursor moves forward (toward the end-of-file).  If it is negative, the cursor moves backward (toward the beginning-of-file).</param>
	METHOD SkipRaw(nToSkip AS INT)			AS LOGIC
	/// Position the cursor relative to its current position within the current scope.
	/// <param name="nToSkip">The number of rows to skip.  If this argument is positive, the cursor moves forward (toward the end-of-file).  If it is negative, the cursor moves backward (toward the beginning-of-file).</param>
	METHOD SkipScope(nToSkip AS INT)		AS LOGIC

	// Append and Delete
	/// Append a blank row and position the cursor to the new row.
	/// <param name="lReleaseLock">A flag that is TRUE if you want to clear all pending row locks before appending the new row and FALSE if you want to add the new row to the end of the current lock list.</param>
	METHOD Append(lReleaseLock AS LOGIC)	AS LOGIC
	/// Mark the row at the current cursor position for deletion.
	METHOD Delete()							AS LOGIC
	/// Retrieve the RDD's record buffer as array of bytes.
	METHOD GetRec()							AS BYTE[]
	/// Physically remove rows marked for deletion.
	METHOD Pack()							AS LOGIC
	/// Replace the row at the current cursor position with the contents of a byte array.
	/// <param name="aRec">The buffer containing the information that you want to write.</param>
	/// <note>The buffer should have at least the # of bytes that matches the current record size.</note>
	METHOD PutRec(aRec AS BYTE[])			AS LOGIC
	/// Remove the deletion marker from the row at the current cursor position.
	METHOD Recall()							AS LOGIC
	/// Physically remove all rows from a table.
	METHOD Zap()							AS LOGIC

	// Open and Close
	/// Close a table.
	METHOD Close() 							AS LOGIC
	/// Create a table.
	/// <param name="info">object describing the file to create.</param>
	METHOD Create(info AS DbOpenInfo)		AS LOGIC
	/// Open a table.
	/// <param name="info">object describing the file to open.</param>
	METHOD Open(info AS DbOpenInfo)			AS LOGIC

	// Filtering and Scoping
	/// Clear the active filter condition.
	METHOD ClearFilter() 					AS LOGIC
	/// Clear the active locate condition.
	METHOD ClearScope() 					AS LOGIC
	/// Goto the next record based on the corrent locate condition.
	METHOD Continue()						AS LOGIC
	//METHOD CountScope(pOpt as PTR)		AS LONG
	/// Retrieve the active locate condition.
	METHOD GetScope()						AS DbScopeInfo
	/// Retrieve information about a scope.
	/// <param name="nOrdinal"> A value that determines the type of information to retrieve.</param>
	METHOD ScopeInfo(nOrdinal AS LONG)		AS OBJECT
	/// Set the filter condition.
	METHOD SetFilter(info AS DbFilterInfo)	AS LOGIC
	/// Set the locate condition.
	/// <param name="info">object  containing the scope information.</param>
	METHOD SetScope(info AS DbScopeInfo)	AS LOGIC

	// Fields
	/// Add a column.
	METHOD AddField(info AS RddFieldInfo)	AS LOGIC
	/// Add columns defined in an array.
	METHOD CreateFields(aFields AS RddFieldInfo[]) AS LOGIC
	/// Return the ONE based field index for a field name.
	METHOD FieldIndex(fieldName AS STRING)	AS LONG
	/// Retrieve and optionally change information about a column.
	METHOD FieldInfo(nFldPos AS LONG, nOrdinal AS LONG, oNewValue AS OBJECT) AS OBJECT
	/// Retrieve a column name based on its ONE based column number.
	/// <param name="nFldPos">The ONE based number of the column whose name you want to obtain.</param>
	METHOD FieldName(nFldPos AS LONG)		AS STRING
	// Read & Write
	/// Get a value for the specified column.
	/// <param name="nFldPos">1 based column number for which the value should be retrieved.</param>
	METHOD GetValue(nFldPos AS LONG)		AS OBJECT
	/// Get the value for a column and write (export) it to an external file.
	/// <param name="nFldPos">1 based column number for which the value should be retrieved.</param>
	/// <param name="fileName">Name of the file that needs to be written to.</param>
	METHOD GetValueFile(nFldPos AS LONG, fileName AS STRING) AS LOGIC
	/// Get the length of the for the specified column.
	/// <param name="nFldPos">1 based column number for which the length should be retrieved.</param>
	METHOD GetValueLength(nFldPos AS LONG)	AS LONG
	/// Flush the changes to the table, its indexes and memo file.
	METHOD Flush() 							AS LOGIC
	/// Write the contents of a work area's memory to the data store (usually a disk).
	METHOD GoCold()							AS LOGIC
	/// Mark a data buffer as hot, indicating that it needs to be written to the data store.
	METHOD GoHot()							AS LOGIC
	/// Write a value for a specified column
	/// <param name="nFldPos">1 based column number for which the value should be written.</param>
	/// <param name="oValue">New value that needs to written to the table this column.</param>
	METHOD PutValue(nFldPos AS LONG, oValue AS OBJECT) AS LOGIC
	/// Read (Import) a value from an external file and write it to the specified column.
	/// <param name="nFldPos">1 based column number for which the value should be written.</param>
	/// <param name="fileName">Name of the file that needs to be read from.</param>
	METHOD PutValueFile(nFldPos AS LONG, fileName AS STRING) AS LOGIC

	// Locking
	/// Add a newly appended row to the list of locked rows.
	/// <param name="uiMode">An enum value specifying the kind of lock to acquire.</param>
	METHOD AppendLock(uiMode AS DbLockMode) AS LOGIC
	/// Lock or unlock the header of a database file.
	/// <param name="uiMode">An enum value specifying the kind of lock to acquire.</param>
	METHOD HeaderLock(uiMode AS DbLockMode) AS LOGIC
	/// Perform a lock.
	/// <param name="uiMode">An object specifying the kind of lock to acquire.</param>
	METHOD Lock(uiMode AS DBLOCKINFO)		AS LOGIC
	/// Release locks.
	/// <param name="oRecId">The row number to unlock.  This argument is provided for drivers that support multiple row locks.  By convention, a value of zero indicates that all rows should be unlocked.</param>
	METHOD UnLock(oRecId AS OBJECT)			AS LOGIC

	// Memo File Access
	/// Close the memo file
	METHOD CloseMemFile() 					AS LOGIC
	/// Create the memo file
	/// <param name="info">object describing the file to create.</param>
	METHOD CreateMemFile(info AS DbOpenInfo) AS LOGIC
	/// Open the memo file
	/// <param name="info">object describing the file to open.</param>
	METHOD OpenMemFile(info AS DbOpenInfo) 		AS LOGIC

	// Indexes

	/// Set the condition for the next Index Creation
    /// <param name="info">An object containing information for the order condition.</param>
    METHOD OrderCondition(info AS DbOrderCondInfo) AS LOGIC

	/// Create a new index or tag.
	/// <param name="info">An object containing information for order creation.</param>
    METHOD OrderCreate(info AS DbOrderCreateInfo) AS LOGIC

	/// Delete an index or tag.
	/// <param name="info">An object containing information about the order to remove.</param>
	METHOD OrderDestroy(info AS DbOrderInfo) AS LOGIC

	/// Retrieve information about the current index.
	/// <param name="nOrdinal"></param>
	METHOD OrderInfo(nOrdinal AS LONG) AS OBJECT

	/// Open an index file and add to the list of open indexes for the current workarea.
	/// <param name="info">An object containing information about the orderlist (file)  to add.</param>
	METHOD OrderListAdd(info AS DbOrderInfo) AS LOGIC

	/// Close an index file and remove it from the list of open indexes for the current workarea.
	/// <param name="info"></param>
	/// <param name="info">An object containing information about the orderlist (file) to delete.</param>
	METHOD OrderListDelete(info AS DbOrderInfo) AS LOGIC

	/// Set focus to another index in the list open indexes for the current workarea.
	/// <param name="info">An object containing information about the order to select.</param>
	METHOD OrderListFocus(info AS DbOrderInfo) AS LOGIC

	/// Rebuild all indexes for the current workarea.
	METHOD OrderListRebuild() AS LOGIC

	/// Perform a seek operation on the current selected index for the current workarea.
	/// <param name="info">An object containing containing the necessary seek information.</param>
	METHOD Seek(info AS DbSeekInfo) AS LOGIC

	// Relations

	/// Report the initialization of a relation.
	/// <param name="info">An object containing information about the relation</param>
	METHOD ChildEnd(info AS DbRelInfo)				AS LOGIC

	/// Report the initialization of a relation.
	/// <param name="info">An object containing information about the relation</param>
	METHOD ChildStart(info AS DbRelInfo)			AS LOGIC

	/// Post a pending relational movement, indicating that the specified child work area has been affected by a parental movement.
	/// <param name="info">An object containing information about the relation</param>
	METHOD ChildSync(info AS DbRelInfo)				AS LOGIC

	/// Clear relations.
	METHOD ClearRel()								AS LOGIC

	/// Force all pending relational seeks to be performed.
	METHOD ForceRel()								AS LOGIC

	/// Retrieve the logical number of a related work area.
	/// <param name="nRelNum">The ONE based relation number for which to obtain the logical number.</param>
	METHOD RelArea(nRelNum AS LONG)					AS LONG

	/// Evaluate a code block against the relation in a work area.
	/// <param name="info">An object containing information about the relation</param>
	METHOD RelEval(info AS DbRelInfo)				AS LOGIC

	/// Retrieve the key expression of a relation.
	/// <param name="nRelNum">The ONE based relation number for which to obtain the key expression. </param>
	METHOD RelText(nRelNum AS LONG)					AS STRING

	/// Set a relation.
	/// <param name="info">An object containing information about the relation</param>
	METHOD SetRel(info AS DbRelInfo)				AS LOGIC

	/// Force relational movement in child work areas to synchronize them with the parent work area.
	METHOD SyncChildren()							AS LOGIC

	// Bulk Operations
	/// Physically reorder a table.
	/// <param name="info">An object containing information about now to sort the table.</param>
	METHOD Sort(info AS DbSortInfo)					AS LOGIC

	/// Copy one or more rows from one work area to another.
	/// <param name="info">An object containing information about the transfer of data.</param>
    METHOD Trans(info AS DbTransInfo) 				AS LOGIC

	/// Copy a single row from one work area to another.
	/// <param name="info">An object containing information about the transfer of data.</param>
    METHOD TransRec(info AS DbTransInfo) 			AS LOGIC

	// Blob
	/// Retrieve information about a memo column.
	METHOD BlobInfo(uiPos AS DWORD, uiOrdinal AS DWORD) AS OBJECT

	// CodeBlock Support
	/// Compile an expression.
	/// <param name="sBlock">The expression to compile.</param>

	METHOD Compile(sBlock AS STRING)				AS LOGIC
	/// Evaluate a code block.
	/// <param name="sBlock">The code block to evaluate.</param>
	METHOD EvalBlock(oBlock AS ICodeBlock)			AS OBJECT

	// Info
	/// Retrieve and optionally change information about a work area.
	METHOD Info(nOrdinal AS LONG, oNewValue AS OBJECT) AS OBJECT
	/// Retrieve and optionally change information about a row.
	METHOD RecInfo(oRecID AS OBJECT, nOrdinal AS LONG, oNewValue AS OBJECT) AS OBJECT

	// Properties
	/// Retrieve the alias name.
	PROPERTY Alias 		AS STRING	GET
	/// Retrieve the workarea number.
	PROPERTY Area		as LONG		GET
	/// Is the table at the logical beginning-of-file.
	PROPERTY BoF 		AS LOGIC	GET
	/// Is the current row deleted?
	PROPERTY Deleted 	AS LOGIC	GET
	/// Driver (RDD) name of the object.
    PROPERTY Driver     AS STRING	GET
	/// Is the table at the logical end-of-file.
    PROPERTY EoF 		AS LOGIC	GET
	/// Is the workarea opened Exclusively
	PROPERTY Exclusive	AS LOGIC	GET
	/// The # of fields in the current workarea.
	PROPERTY FieldCount AS LONG		GET
	/// The filter condition as a string.
	PROPERTY FilterText	AS STRING	GET
	/// The outcome of the last search operation.
	PROPERTY Found		AS LOGIC	GET SET
	/// The number of rows.
	PROPERTY RecCount	AS LONG		GET
	/// The row identifier at the current cursor position.
	PROPERTY RecId		AS OBJECT	GET		// Does not have to be numeric.
	/// The physical row identifier at the current cursor position.
	PROPERTY RecNo		AS LONG		GET
	/// Is the current workarea opened Shared?
	PROPERTY Shared		AS LOGIC	GET
	/// The Name of the current RDD
	PROPERTY SysName	AS STRING	GET

END INTERFACE

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//
USING XSharp.RDD.Enums
/// Definition for the interface that each RDD must implement
/// <seealso cref="T:XSharp.Workarea"/>
INTERFACE XSharp.RDD.IRdd
	// Navigation
	/// Evaluate a code block for each row.
	/// <param name="info">object containing the information about which rows to visit.</param>
	METHOD DbEval(info AS DbEvalInfo)		AS LOGIC
	/// Position the cursor to the first logical row.
	METHOD GoTop()							AS LOGIC
	/// Position the cursor to the last logical row.
	METHOD GoBottom()						AS LOGIC
	/// Position the cursor to a specific, physical row.
	/// <param name="nRec">The row number of the new cursor position.</param>
	METHOD GoTo(nRec AS LONG)				AS LOGIC
	/// Position the cursor to a specific, physical identity.
	/// <param name="oRec">The row ID of the new cursor position.</param>
	METHOD GoToId(oRec AS OBJECT)			AS LOGIC
	/// Position the cursor relative to its current position.
	/// <param name="nToSkip">The number of rows to skip.  If this argument is positive, the cursor moves forward (toward the end-of-file).  If it is negative, the cursor moves backward (toward the beginning-of-file).</param>
	METHOD Skip(nToSkip AS INT)				AS LOGIC
	/// Position the cursor, respecting scope and filter conditions.
	/// <param name="nToSkip">The number of rows to skip.  If this argument is positive, the cursor moves forward (toward the end-of-file).  If it is negative, the cursor moves backward (toward the beginning-of-file).</param>
	METHOD SkipFilter(nToSkip AS INT)		AS LOGIC
	/// Position the cursor regardless of scope and filter conditions.
	/// <param name="nToSkip">The number of rows to skip.  If this argument is positive, the cursor moves forward (toward the end-of-file).  If it is negative, the cursor moves backward (toward the beginning-of-file).</param>
	METHOD SkipRaw(nToSkip AS INT)			AS LOGIC
	/// Position the cursor relative to its current position within the current scope.
	/// <param name="nToSkip">The number of rows to skip.  If this argument is positive, the cursor moves forward (toward the end-of-file).  If it is negative, the cursor moves backward (toward the beginning-of-file).</param>
	METHOD SkipScope(nToSkip AS INT)		AS LOGIC

	// Append and Delete
	/// Append a blank row and position the cursor to the new row.
	/// <param name="lReleaseLock">A flag that is TRUE if you want to clear all pending row locks before appending the new row and FALSE if you want to add the new row to the end of the current lock list.</param>
	METHOD Append(lReleaseLock AS LOGIC)	AS LOGIC
	/// Mark the row at the current cursor position for deletion.
	METHOD Delete()							AS LOGIC
	/// Retrieve the RDD's record buffer as array of bytes.
	METHOD GetRec()							AS BYTE[]
	/// Physically remove rows marked for deletion.
	METHOD Pack()							AS LOGIC
	/// Replace the row at the current cursor position with the contents of a byte array.
	/// <param name="aRec">The buffer containing the information that you want to write.</param>
	/// <note>The buffer should have at least the # of bytes that matches the current record size.</note>
	METHOD PutRec(aRec AS BYTE[])			AS LOGIC
	/// Remove the deletion marker from the row at the current cursor position.
	METHOD Recall()							AS LOGIC
	/// Physically remove all rows from a table.
	METHOD Zap()							AS LOGIC

	// Open and Close
	/// Close a table.
	METHOD Close() 							AS LOGIC
	/// Create a table.
	/// <param name="info">object describing the file to create.</param>
	METHOD Create(info AS DbOpenInfo)		AS LOGIC
	/// Open a table.
	/// <param name="info">object describing the file to open.</param>
	METHOD Open(info AS DbOpenInfo)			AS LOGIC

	// Filtering and Scoping
	/// Clear the active filter condition.
	METHOD ClearFilter() 					AS LOGIC
	/// Clear the active locate condition.
	METHOD ClearScope() 					AS LOGIC
	/// Goto the next record based on the corrent locate condition.
	METHOD Continue()						AS LOGIC
	//METHOD CountScope(pOpt as PTR)		AS LONG
	/// Retrieve the active locate condition.
	METHOD GetScope()						AS DbScopeInfo
	/// Retrieve information about a scope.
	/// <param name="nOrdinal"> A value that determines the type of information to retrieve.</param>
	METHOD ScopeInfo(nOrdinal AS LONG)		AS OBJECT
	/// Set the filter condition.
	METHOD SetFilter(info AS DbFilterInfo)	AS LOGIC
	/// Set the locate condition.
	/// <param name="info">object  containing the scope information.</param>
	METHOD SetScope(info AS DbScopeInfo)	AS LOGIC

	// Fields
	/// Add a column.
	METHOD AddField(info AS DbFieldInfo)	AS LOGIC
	/// Add columns defined in an array.
	METHOD CreateFields(aFields AS RddFieldInfo[]) AS LOGIC
	/// Return the ONE based field index for a field name.
	METHOD FieldIndex(fieldName AS STRING)	AS LONG
	/// Retrieve and optionally change information about a column.
	METHOD FieldInfo(nFldPos AS LONG, nOrdinal AS LONG, oNewValue AS OBJECT) AS OBJECT
	/// Retrieve a column name based on its ONE based column number.
	/// <param name="nFldPos">The ONE based number of the column whose name you want to obtain.</param>
	METHOD FieldName(nFldPos AS LONG)		AS STRING
	// Read & Write
	/// Get a value for the specified column.
	/// <param name="nFldPos">1 based column number for which the value should be retrieved.</param>
	METHOD GetValue(nFldPos AS LONG)		AS OBJECT
	/// Get the value for a column and write (export) it to an external file.
	/// <param name="nFldPos">1 based column number for which the value should be retrieved.</param>
	/// <param name="fileName">Name of the file that needs to be written to.</param>
	METHOD GetValueFile(nFldPos AS LONG, fileName AS STRING) AS LOGIC
	/// Get the length of the for the specified column.
	/// <param name="nFldPos">1 based column number for which the length should be retrieved.</param>
	METHOD GetValueLength(nFldPos AS LONG)	AS LONG
	/// Flush the changes to the table, its indexes and memo file.
	METHOD Flush() 							AS LOGIC
	/// Write the contents of a work area's memory to the data store (usually a disk).
	METHOD GoCold()							AS LOGIC
	/// Mark a data buffer as hot, indicating that it needs to be written to the data store.
	METHOD GoHot()							AS LOGIC
	/// Write a value for a specified column
	/// <param name="nFldPos">1 based column number for which the value should be written.</param>
	/// <param name="oValue">New value that needs to written to the table this column.</param>
	METHOD PutValue(nFldPos AS LONG, oValue AS OBJECT) AS LOGIC
	/// Read (Import) a value from an external file and write it to the specified column.
	/// <param name="nFldPos">1 based column number for which the value should be written.</param>
	/// <param name="fileName">Name of the file that needs to be read from.</param>
	METHOD PutValueFile(nFldPos AS LONG, fileName AS STRING) AS LOGIC

	// Locking
	/// Add a newly appended row to the list of locked rows.
	/// <param name="uiMode">An enum value specifying the kind of lock to acquire.</param>
	METHOD AppendLock(uiMode AS DbLockMode) AS LOGIC
	/// Lock or unlock the header of a database file.
	/// <param name="uiMode">An enum value specifying the kind of lock to acquire.</param>
	METHOD HeaderLock(uiMode AS DbLockMode) AS LOGIC
	/// Perform a lock.
	/// <param name="uiMode">An object specifying the kind of lock to acquire.</param>
	METHOD Lock(uiMode AS DBLOCKINFO)		AS LOGIC
	/// Release locks.
	/// <param name="oRecId">The row number to unlock.  This argument is provided for drivers that support multiple row locks.  By convention, a value of zero indicates that all rows should be unlocked.</param>
	METHOD UnLock(oRecId AS OBJECT)			AS LOGIC

	// Memo File Access
	/// Close the memo file
	METHOD CloseMemFile() 					AS LOGIC
	/// Create the memo file
	/// <param name="info">object describing the file to create.</param>
	METHOD CreateMemFile(info AS DbOpenInfo) AS LOGIC
	/// Open the memo file
	/// <param name="info">object describing the file to open.</param>
	METHOD OpenMemFile(info AS DbOpenInfo) 		AS LOGIC

	// Indexes

	/// Set the condition for the next Index Creation
    /// <param name="info">An object containing information for the order condition.</param>
    METHOD OrderCondition(info AS DbOrderCondInfo) AS LOGIC

	/// Create a new index or tag.
	/// <param name="info">An object containing information for order creation.</param>
    METHOD OrderCreate(info AS DbOrderCreateInfo) AS LOGIC

	/// Delete an index or tag.
	/// <param name="info">An object containing information about the order to remove.</param>
	METHOD OrderDestroy(info AS DbOrderInfo) AS LOGIC

	/// Retrieve information about the current index.
	/// <param name="nOrdinal"></param>
	METHOD OrderInfo(nOrdinal AS LONG) AS OBJECT

	/// Open an index file and add to the list of open indexes for the current workarea.
	/// <param name="info">An object containing information about the orderlist (file)  to add.</param>
	METHOD OrderListAdd(info AS DbOrderInfo) AS LOGIC

	/// Close an index file and remove it from the list of open indexes for the current workarea.
	/// <param name="info"></param>
	/// <param name="info">An object containing information about the orderlist (file) to delete.</param>
	METHOD OrderListDelete(info AS DbOrderInfo) AS LOGIC

	/// Set focus to another index in the list open indexes for the current workarea.
	/// <param name="info">An object containing information about the order to select.</param>
	METHOD OrderListFocus(info AS DbOrderInfo) AS LOGIC

	/// Rebuild all indexes for the current workarea.
	METHOD OrderListRebuild() AS LOGIC

	/// Perform a seek operation on the current selected index for the current workarea.
	/// <param name="info">An object containing containing the necessary seek information.</param>
	METHOD Seek(info AS DbSeekInfo) AS LOGIC

	// Relations

	/// Report the initialization of a relation.
	/// <param name="info">An object containing information about the relation</param>
	METHOD ChildEnd(info AS DbRelInfo)				AS LOGIC

	/// Report the initialization of a relation.
	/// <param name="info">An object containing information about the relation</param>
	METHOD ChildStart(info AS DbRelInfo)			AS LOGIC

	/// Post a pending relational movement, indicating that the specified child work area has been affected by a parental movement.
	/// <param name="info">An object containing information about the relation</param>
	METHOD ChildSync(info AS DbRelInfo)				AS LOGIC

	/// Clear relations.
	METHOD ClearRel()								AS LOGIC

	/// Force all pending relational seeks to be performed.
	METHOD ForceRel()								AS LOGIC

	/// Retrieve the logical number of a related work area.
	/// <param name="nRelNum">The ONE based relation number for which to obtain the logical number.</param>
	METHOD RelArea(nRelNum AS LONG)					AS LONG

	/// Evaluate a code block against the relation in a work area.
	/// <param name="info">An object containing information about the relation</param>
	METHOD RelEval(info AS DbRelInfo)				AS LOGIC

	/// Retrieve the key expression of a relation.
	/// <param name="nRelNum">The ONE based relation number for which to obtain the key expression. </param>
	METHOD RelText(nRelNum AS LONG)					AS STRING

	/// Set a relation.
	/// <param name="info">An object containing information about the relation</param>
	METHOD SetRel(info AS DbRelInfo)				AS LOGIC

	/// Force relational movement in child work areas to synchronize them with the parent work area.
	METHOD SyncChildren()							AS LOGIC

	// Bulk Operations
	/// Physically reorder a table.
	/// <param name="info">An object containing information about now to sort the table.</param>
	METHOD Sort(info AS DbSortInfo)					AS LOGIC

	/// Copy one or more rows from one work area to another.
	/// <param name="info">An object containing information about the transfer of data.</param>
    METHOD Trans(info AS DbTransInfo) 				AS LOGIC

	/// Copy a single row from one work area to another.
	/// <param name="info">An object containing information about the transfer of data.</param>
    METHOD TransRec(info AS DbTransInfo) 			AS LOGIC

	// Blob
	/// Retrieve information about a memo column.
	METHOD BlobInfo(uiPos AS DWORD, uiOrdinal AS DWORD) AS OBJECT

	// CodeBlock Support
	/// Compile an expression.
	/// <param name="sBlock">The expression to compile.</param>

	METHOD Compile(sBlock AS STRING)				AS LOGIC
	/// Evaluate a code block.
	/// <param name="sBlock">The code block to evaluate.</param>
	METHOD EvalBlock(oBlock AS ICodeBlock)			AS OBJECT

	// Info
	/// Retrieve and optionally change information about a work area.
	METHOD Info(nOrdinal AS LONG, oNewValue AS OBJECT) AS OBJECT
	/// Retrieve and optionally change information about a row.
	METHOD RecInfo(oRecID AS OBJECT, nOrdinal AS LONG, oNewValue AS OBJECT) AS OBJECT

	// Properties
	/// Retrieve the alias name.
	PROPERTY Alias 		AS STRING	GET
	/// Retrieve the workarea number.
	PROPERTY Area		as LONG		GET
	/// Is the table at the logical beginning-of-file.
	PROPERTY BoF 		AS LOGIC	GET
	/// Is the current row deleted?
	PROPERTY Deleted 	AS LOGIC	GET
	/// Driver (RDD) name of the object.
    PROPERTY Driver     AS STRING	GET
	/// Is the table at the logical end-of-file.
    PROPERTY EoF 		AS LOGIC	GET
	/// Is the workarea opened Exclusively
	PROPERTY Exclusive	AS LOGIC	GET
	/// The # of fields in the current workarea.
	PROPERTY FieldCount AS LONG		GET
	/// The filter condition as a string.
	PROPERTY FilterText	AS STRING	GET
	/// The outcome of the last search operation.
	PROPERTY Found		AS LOGIC	GET SET
	/// The number of rows.
	PROPERTY RecCount	AS LONG		GET
	/// The row identifier at the current cursor position.
	PROPERTY RecId		AS OBJECT	GET		// Does not have to be numeric.
	/// The physical row identifier at the current cursor position.
	PROPERTY RecNo		AS LONG		GET
	/// Is the current workarea opened Shared?
	PROPERTY Shared		AS LOGIC	GET
	/// The Name of the current RDD
	PROPERTY SysName	AS STRING	GET

END INTERFACE


[Runtime] Currency constructor was broken because of change for #876

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//
USING System
USING System.Runtime.InteropServices
USING System.Runtime.CompilerServices
USING System.Diagnostics
USING System.Runtime.Serialization

BEGIN NAMESPACE XSharp
    // use explicit layout so we can compact the size into 12 bytes
    // Type is Immutable, so has no settable properties
    /// <summary>Internal type that implements the FoxPro Compatible CURRENCY type.
    /// This type has many operators and implicit converters that normally are never directly called from user code.
    /// The data in this type is stored as a System.Decimal with 4 decimal places
    /// </summary>
    /// <seealso cref="__Float"/>
    /// <seealso cref="System.Decimal"/>
    [DebuggerDisplay("{ToDebugString(),nq}")];
    [Serializable];
    PUBLIC STRUCTURE __Currency IMPLEMENTS IConvertible,;
        IFormattable, ;
        IComparable<__Currency>, ;
        IEquatable<__Currency>, ;
        IComparable,            ;
        ISerializable

        [DebuggerBrowsable(DebuggerBrowsableState.Never)];
        PRIVATE INITONLY _value AS System.Decimal

        #region constructors
        /// <include file="RTComments.xml" path="Comments/Constructor/*" />
        /// <param name="r8">Real8 value to convert to a FLOAT</param>
        [DebuggerStepThroughAttribute] [MethodImpl(MethodImplOptions.AggressiveInlining)];
        CONSTRUCTOR (r8 AS REAL8)
            SELF:_value    := Math.Round((Decimal)r8,4)

        /// <include file="RTComments.xml" path="Comments/Constructor/*" />
        [MethodImpl(MethodImplOptions.AggressiveInlining)];
        CONSTRUCTOR (d AS System.Decimal)
            SELF:_value    := Math.Round(d,4)
        /// <include file="RTComments.xml" path="Comments/Constructor/*" />
        [DebuggerStepThroughAttribute] [MethodImpl(MethodImplOptions.AggressiveInlining)];
        CONSTRUCTOR (f AS IFloat)
            SELF:_value		:= Math.Round((Decimal)f:Value,4)

        #endregion
        #region Properties
        /// <summary>Decimal (System.Decimal) value</summary>
        [DebuggerBrowsable(DebuggerBrowsableState.Never)];
        PROPERTY @@Value    AS System.Decimal	GET _value
        #endregion

        #region Equality Operators
        /// <inheritdoc />
        OVERRIDE METHOD Equals(rhs AS OBJECT  ) AS LOGIC
            LOCAL result AS LOGIC
            IF rhs != NULL .AND. rhs IS CURRENCY
                result := SELF:Equals( (CURRENCY) rhs)
            ELSE
                result := FALSE
            ENDIF
            RETURN result

        /// <inheritdoc />
        METHOD Equals(rhs AS CURRENCY ) AS LOGIC
            RETURN SELF:Value == rhs:Value

            /// <inheritdoc />
        OVERRIDE METHOD GetHashCode() AS INT
            RETURN SELF:_value:GetHashCode()

            /// <exclude />
        METHOD GetTypeCode() AS TypeCode
            RETURN TypeCode.Decimal

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR ==(lhs AS CURRENCY, rhs AS CURRENCY) AS LOGIC
            RETURN lhs:Equals(rhs)

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR !=(lhs AS CURRENCY, rhs AS CURRENCY) AS LOGIC
            RETURN ! lhs:Equals(rhs)
            #endregion

        #region Comparison Operators
        /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR >(lhs AS CURRENCY, rhs AS CURRENCY) AS LOGIC
            RETURN lhs:_value > rhs:_value

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR <(lhs AS CURRENCY, rhs AS CURRENCY) AS LOGIC
            RETURN lhs:_value < rhs:_value

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR >=(lhs AS CURRENCY, rhs AS CURRENCY) AS LOGIC
            RETURN lhs:_value >= rhs:_value

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR <=(lhs AS CURRENCY, rhs AS CURRENCY) AS LOGIC
            RETURN lhs:_value <= rhs:_value

            #endregion

        #region Implicit Converters
        /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(b AS BYTE) AS CURRENCY
            RETURN CURRENCY{(Decimal) b}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(sb AS SByte) AS CURRENCY
            RETURN CURRENCY{(Decimal) sb}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(si AS SHORT) AS CURRENCY
            RETURN CURRENCY{(Decimal)si}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(w AS WORD) AS CURRENCY
            RETURN CURRENCY{(Decimal)w}
            /// <include file="RTComments.xml" path="Comments/Converter/*" />

        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(i AS INT) AS CURRENCY
            RETURN CURRENCY{(Decimal)i}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(dw AS DWORD) AS CURRENCY
            RETURN CURRENCY{(Decimal)dw}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(i64 AS INT64) AS CURRENCY
            RETURN CURRENCY{(Decimal)i64}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(ui64 AS UINT64) AS CURRENCY
            RETURN CURRENCY{(Decimal)ui64}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(r4 AS REAL4) AS CURRENCY
            RETURN CURRENCY{(REAL8)r4}

        /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(r8 AS REAL8) AS CURRENCY
            RETURN CURRENCY{r8}

        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(fl AS FLOAT) AS CURRENCY
            RETURN CURRENCY{fl:Value}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(val AS System.Decimal) AS CURRENCY
            RETURN CURRENCY{val}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(c  AS CURRENCY) AS REAL8
            RETURN (REAL8) c:_value

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(c  AS CURRENCY) AS REAL4
            RETURN (REAL4) c:_value

        /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(c  AS CURRENCY) AS FLOAT
            RETURN FLOAT{ (REAL8) c:_value, -1, 4}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(c  AS CURRENCY) AS System.Decimal
            RETURN c:_value

        #endregion
        #region Explicit Converters
        /// <include file="RTComments.xml" path="Comments/Converter/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR EXPLICIT(c  AS CURRENCY) AS BYTE
            IF RuntimeState.CompilerOptionVO11
                RETURN Convert.ToByte(c:_value)
            ENDIF
            RETURN (BYTE) c:_value
            /// <include file="RTComments.xml" path="Comments/Converter/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR EXPLICIT(c AS CURRENCY) AS SByte
            RETURN (SByte) c:_value
            /// <include file="RTComments.xml" path="Comments/Converter/*" />

        [DebuggerStepThroughAttribute];
        STATIC OPERATOR EXPLICIT(c  AS CURRENCY) AS SHORT
            IF RuntimeState.CompilerOptionVO11
                RETURN Convert.ToInt16(c:_value)
            ENDIF
            RETURN (SHORT)c:_value

            /// <include file="RTComments.xml" path="Comments/Converter/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR EXPLICIT(c  AS CURRENCY) AS WORD
            RETURN (WORD) c:_value
            /// <include file="RTComments.xml" path="Comments/Converter/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR EXPLICIT(c  AS CURRENCY) AS LONG
            IF RuntimeState.CompilerOptionVO11
                RETURN Convert.ToInt32(c:_value)
            ENDIF
            RETURN (LONG) c:_value
            /// <include file="RTComments.xml" path="Comments/Converter/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR EXPLICIT(c  AS CURRENCY) AS DWORD
            RETURN (DWORD) c:_value
            /// <include file="RTComments.xml" path="Comments/Converter/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR EXPLICIT(c  AS CURRENCY) AS INT64
            IF RuntimeState.CompilerOptionVO11
                RETURN Convert.ToInt64(c:_value)
            ENDIF
            RETURN (INT64) c:_value

            /// <include file="RTComments.xml" path="Comments/Converter/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR EXPLICIT(c  AS CURRENCY) AS UINT64
            RETURN (UINT64) c:_value

            #endregion

        #region Numeric Operators
        /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR +(c  AS CURRENCY) AS CURRENCY
            RETURN c

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR -(c  AS CURRENCY) AS CURRENCY
            RETURN CURRENCY{ -c:_value}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR+(lhs AS CURRENCY, rhs AS CURRENCY) AS CURRENCY
            RETURN lhs:Add(rhs)

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR+(lhs AS CURRENCY, rhs AS USUAL) AS CURRENCY
            RETURN lhs:Add(rhs)

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR+(lhs AS USUAL, rhs AS CURRENCY) AS CURRENCY
            RETURN rhs:Add(lhs)

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR-(lhs AS CURRENCY, rhs AS CURRENCY) AS CURRENCY
            RETURN lhs:Subtract(rhs)

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR-(lhs AS CURRENCY, rhs AS USUAL) AS CURRENCY
            RETURN lhs:Subtract(rhs)

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR-(lhs AS USUAL, rhs AS CURRENCY) AS CURRENCY
            // set decimals for LHS to 0, so max decmals is decimals right
            local lr8 AS Real8
            LOCAL rr8 AS Real8
            lr8 := (Real8) lhs
            rr8 := (Real8) rhs
            RETURN CURRENCY{lr8}:Subtract(rr8)

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR*(lhs AS CURRENCY, rhs AS CURRENCY) AS CURRENCY
            RETURN CURRENCY{ lhs:_value * rhs:_value}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR/(lhs AS CURRENCY, rhs AS CURRENCY) AS CURRENCY
            RETURN CURRENCY{ lhs:_value / rhs:_value}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR%(lhs AS CURRENCY, rhs AS CURRENCY) AS CURRENCY
            RETURN CURRENCY{ lhs:_value % rhs:_value}

            #endregion
        #region Unary Operators
        /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR ++ (c  AS CURRENCY) AS CURRENCY
            RETURN CURRENCY{c:_value+1}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR -- (c  AS CURRENCY) AS CURRENCY
            RETURN CURRENCY{c:_value-1}
            #endregion

        #region Explicit casts. Used inside Transform
        /// <exclude />
        METHOD CastToInt() AS INT
            RETURN (INT)(SELF:_value)

            /// <exclude />
        METHOD CastToInt64() AS INT64
            RETURN (INT64)(SELF:_value)

            #endregion
        #region Add and Subtract
        /// <exclude />
        METHOD Add(rhs AS CURRENCY) AS CURRENCY
            RETURN CURRENCY{ SELF:_value + rhs:_value}

            /// <exclude />
        METHOD Add(rhs AS USUAL) AS CURRENCY
            LOCAL result AS CURRENCY
            IF rhs:IsFloat
                result := SELF:Add ( (CURRENCY) rhs)
            ELSEIF rhs:IsDecimal
                result := SELF:Add ( (System.Decimal) rhs)
            ELSEIF rhs:IsCurrency
                result := SELF:Add ( (CURRENCY) rhs)
            ELSEIF  rhs:IsLong
                result := CURRENCY{ SELF:_value + (LONG) rhs}
            ELSE
                THROW Error.ArgumentError(__ENTITY__,Nameof(rhs), "Argument is not numeric")
            ENDIF
            RETURN result

            /// <exclude />
        METHOD Subtract(rhs AS CURRENCY) AS CURRENCY
            RETURN CURRENCY{ SELF:_value - rhs:_value}

            /// <exclude />
        METHOD Subtract(rhs AS USUAL) AS CURRENCY
            LOCAL result AS CURRENCY
            IF rhs:IsFloat
                result := SELF:Subtract( (CURRENCY) rhs)
            ELSEIF rhs:IsDecimal
                result := SELF:Subtract( (System.Decimal) rhs)
            ELSEIF rhs:IsCurrency
                result := SELF:Subtract( (CURRENCY) rhs)
            ELSEIF  rhs:IsLong
                result := CURRENCY{ SELF:_value - (LONG) rhs}
            ELSE
                THROW Error.ArgumentError(__ENTITY__,Nameof(rhs), "Argument is not numeric")
            ENDIF
            RETURN result

            #endregion

        #region IConvertable
        /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToBoolean(provider AS System.IFormatProvider) AS LOGIC
            RETURN _value ==  0.0m

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToByte(provider AS System.IFormatProvider) AS BYTE
            RETURN ((IConvertible) _value):ToByte(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToChar(provider AS System.IFormatProvider) AS CHAR
            RETURN ((IConvertible) _value):ToChar(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToDateTime(provider AS System.IFormatProvider) AS System.DateTime
            RETURN ((IConvertible) _value):ToDateTime(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToDecimal(provider AS System.IFormatProvider) AS Decimal
            RETURN ((IConvertible) _value):ToDecimal(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToDouble(provider AS System.IFormatProvider) AS REAL8
            RETURN ((IConvertible) _value):ToDouble(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToInt16(provider AS System.IFormatProvider) AS SHORT
            RETURN ((IConvertible) _value):ToInt16(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToInt32(provider AS System.IFormatProvider) AS LONG
            RETURN ((IConvertible) _value):ToInt32(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToInt64(provider AS System.IFormatProvider) AS INT64
            RETURN ((IConvertible) _value):ToInt64(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToSByte(provider AS System.IFormatProvider) AS SByte
            RETURN ((IConvertible) _value):ToSByte(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToSingle(provider AS System.IFormatProvider) AS REAL4
            RETURN ((IConvertible) _value):ToSingle(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToType(conversionType AS System.Type, provider AS System.IFormatProvider) AS OBJECT
            RETURN ((IConvertible) _value):ToType(conversionType, provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToUInt16(provider AS System.IFormatProvider) AS WORD
            RETURN ((IConvertible) _value):ToUInt16(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToUInt32(provider AS System.IFormatProvider) AS DWORD
            RETURN ((IConvertible) _value):ToUInt32(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToUInt64(provider AS System.IFormatProvider) AS UINT64
            RETURN ((IConvertible) _value):ToUInt64(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToString(provider AS System.IFormatProvider) AS STRING
            RETURN ((IConvertible) _value):ToString(provider)
            #endregion
        #region IFormattable
        /// <inheritdoc cref="System.Double.ToString"/>
        PUBLIC OVERRIDE METHOD ToString() AS STRING
            RETURN SELF:ToString("0.0000")

        /// <inheritdoc cref="System.Double.ToString"/>
        PUBLIC METHOD ToString(sFormat AS STRING) AS STRING
            RETURN _value:ToString(sFormat)

            /// <inheritdoc />
        PUBLIC METHOD ToString(format AS STRING, provider AS System.IFormatProvider) AS STRING
            RETURN ((IFormattable) _value):ToString(format, provider)

        INTERNAL METHOD ToDebugString() AS STRING
            RETURN SELF:ToString("0.0000")

        #endregion

        #region IComparable
        /// <inheritdoc />
        PUBLIC METHOD CompareTo(rhs AS CURRENCY) AS INT
            RETURN _value:CompareTo( rhs:_value)

            /// <inheritdoc />
        PUBLIC METHOD CompareTo(rhs AS OBJECT) AS INT
            RETURN SELF:CompareTo( (CURRENCY) rhs)
            #endregion

        #region ISerializable
        /// <inheritdoc/>
        PUBLIC METHOD GetObjectData(info AS SerializationInfo, context AS StreamingContext) AS VOID
            IF info == NULL
                THROW System.ArgumentException{"info"}
            ENDIF
            info:AddValue("Value", SELF:_value)
            RETURN
        /// <include file="RTComments.xml" path="Comments/SerializeConstructor/*" />
        CONSTRUCTOR (info AS SerializationInfo, context AS StreamingContext)
            IF info == NULL
                THROW System.ArgumentException{"info"}
            ENDIF
            SELF:_value   := info:GetDecimal("Value")
        #endregion

    END STRUCTURE

END NAMESPACE

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//
USING System
USING System.Runtime.InteropServices
USING System.Runtime.CompilerServices
USING System.Diagnostics
USING System.Runtime.Serialization

BEGIN NAMESPACE XSharp
    // use explicit layout so we can compact the size into 12 bytes
    // Type is Immutable, so has no settable properties
    /// <summary>Internal type that implements the FoxPro Compatible CURRENCY type.
    /// This type has many operators and implicit converters that normally are never directly called from user code.
    /// The data in this type is stored as a System.Decimal with 4 decimal places
    /// </summary>
    /// <seealso cref="__Float"/>
    /// <seealso cref="System.Decimal"/>
    [DebuggerDisplay("{ToDebugString(),nq}")];
    [Serializable];
    PUBLIC STRUCTURE __Currency IMPLEMENTS IConvertible,;
        IFormattable, ;
        IComparable<__Currency>, ;
        IEquatable<__Currency>, ;
        IComparable,            ;
        ISerializable

        [DebuggerBrowsable(DebuggerBrowsableState.Never)];
        PRIVATE INITONLY _value AS System.Decimal

        #region constructors
        /// <include file="RTComments.xml" path="Comments/Constructor/*" />
        /// <param name="r8">Real8 value to convert to a FLOAT</param>
        [DebuggerStepThroughAttribute] [MethodImpl(MethodImplOptions.AggressiveInlining)];
        CONSTRUCTOR (r8 AS REAL8)
            SELF:_value    := Math.Round((Decimal)r8,4)

        /// <include file="RTComments.xml" path="Comments/Constructor/*" />
        [MethodImpl(MethodImplOptions.AggressiveInlining)];
        CONSTRUCTOR (d AS System.Decimal)
            SELF:_value    := Math.Round(d,4)
        /// <include file="RTComments.xml" path="Comments/Constructor/*" />
        [DebuggerStepThroughAttribute] [MethodImpl(MethodImplOptions.AggressiveInlining)];
        CONSTRUCTOR (f AS IFloat)
            SELF:_value		:= Math.Round((Decimal)f:Value,4)

        #endregion
        #region Properties
        /// <summary>Decimal (System.Decimal) value</summary>
        [DebuggerBrowsable(DebuggerBrowsableState.Never)];
        PROPERTY @@Value    AS System.Decimal	GET _value
        #endregion

        #region Equality Operators
        /// <inheritdoc />
        OVERRIDE METHOD Equals(rhs AS OBJECT  ) AS LOGIC
            LOCAL result AS LOGIC
            IF rhs != NULL .AND. rhs IS CURRENCY
                result := SELF:Equals( (CURRENCY) rhs)
            ELSE
                result := FALSE
            ENDIF
            RETURN result

        /// <inheritdoc />
        METHOD Equals(rhs AS CURRENCY ) AS LOGIC
            RETURN SELF:Value == rhs:Value

            /// <inheritdoc />
        OVERRIDE METHOD GetHashCode() AS INT
            RETURN SELF:_value:GetHashCode()

            /// <exclude />
        METHOD GetTypeCode() AS TypeCode
            RETURN TypeCode.Decimal

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR ==(lhs AS CURRENCY, rhs AS CURRENCY) AS LOGIC
            RETURN lhs:Equals(rhs)

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR !=(lhs AS CURRENCY, rhs AS CURRENCY) AS LOGIC
            RETURN ! lhs:Equals(rhs)
            #endregion

        #region Comparison Operators
        /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR >(lhs AS CURRENCY, rhs AS CURRENCY) AS LOGIC
            RETURN lhs:_value > rhs:_value

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR <(lhs AS CURRENCY, rhs AS CURRENCY) AS LOGIC
            RETURN lhs:_value < rhs:_value

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR >=(lhs AS CURRENCY, rhs AS CURRENCY) AS LOGIC
            RETURN lhs:_value >= rhs:_value

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR <=(lhs AS CURRENCY, rhs AS CURRENCY) AS LOGIC
            RETURN lhs:_value <= rhs:_value

            #endregion

        #region Implicit Converters
        /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(b AS BYTE) AS CURRENCY
            RETURN CURRENCY{(Decimal) b}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(sb AS SByte) AS CURRENCY
            RETURN CURRENCY{(Decimal) sb}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(si AS SHORT) AS CURRENCY
            RETURN CURRENCY{(Decimal)si}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(w AS WORD) AS CURRENCY
            RETURN CURRENCY{(Decimal)w}
            /// <include file="RTComments.xml" path="Comments/Converter/*" />

        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(i AS INT) AS CURRENCY
            RETURN CURRENCY{(Decimal)i}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(dw AS DWORD) AS CURRENCY
            RETURN CURRENCY{(Decimal)dw}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(i64 AS INT64) AS CURRENCY
            RETURN CURRENCY{(Decimal)i64}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(ui64 AS UINT64) AS CURRENCY
            RETURN CURRENCY{(Decimal)ui64}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(r4 AS REAL4) AS CURRENCY
            RETURN CURRENCY{(REAL8)r4}

        /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(r8 AS REAL8) AS CURRENCY
            RETURN CURRENCY{r8}

        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(fl AS FLOAT) AS CURRENCY
            RETURN CURRENCY{fl:Value}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(val AS System.Decimal) AS CURRENCY
            RETURN CURRENCY{val}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(c  AS CURRENCY) AS REAL8
            RETURN (REAL8) c:_value

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(c  AS CURRENCY) AS REAL4
            RETURN (REAL4) c:_value

        /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(c  AS CURRENCY) AS FLOAT
            RETURN FLOAT{ (REAL8) c:_value, -1, 4}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(c  AS CURRENCY) AS System.Decimal
            RETURN c:_value

        #endregion
        #region Explicit Converters
        /// <include file="RTComments.xml" path="Comments/Converter/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR EXPLICIT(c  AS CURRENCY) AS BYTE
            IF RuntimeState.CompilerOptionVO11
                RETURN Convert.ToByte(c:_value)
            ENDIF
            RETURN (BYTE) c:_value
            /// <include file="RTComments.xml" path="Comments/Converter/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR EXPLICIT(c AS CURRENCY) AS SByte
            RETURN (SByte) c:_value
            /// <include file="RTComments.xml" path="Comments/Converter/*" />

        [DebuggerStepThroughAttribute];
        STATIC OPERATOR EXPLICIT(c  AS CURRENCY) AS SHORT
            IF RuntimeState.CompilerOptionVO11
                RETURN Convert.ToInt16(c:_value)
            ENDIF
            RETURN (SHORT)c:_value

            /// <include file="RTComments.xml" path="Comments/Converter/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR EXPLICIT(c  AS CURRENCY) AS WORD
            RETURN (WORD) c:_value
            /// <include file="RTComments.xml" path="Comments/Converter/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR EXPLICIT(c  AS CURRENCY) AS LONG
            IF RuntimeState.CompilerOptionVO11
                RETURN Convert.ToInt32(c:_value)
            ENDIF
            RETURN (LONG) c:_value
            /// <include file="RTComments.xml" path="Comments/Converter/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR EXPLICIT(c  AS CURRENCY) AS DWORD
            RETURN (DWORD) c:_value
            /// <include file="RTComments.xml" path="Comments/Converter/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR EXPLICIT(c  AS CURRENCY) AS INT64
            IF RuntimeState.CompilerOptionVO11
                RETURN Convert.ToInt64(c:_value)
            ENDIF
            RETURN (INT64) c:_value

            /// <include file="RTComments.xml" path="Comments/Converter/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR EXPLICIT(c  AS CURRENCY) AS UINT64
            RETURN (UINT64) c:_value

            #endregion

        #region Numeric Operators
        /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR +(c  AS CURRENCY) AS CURRENCY
            RETURN c

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR -(c  AS CURRENCY) AS CURRENCY
            RETURN CURRENCY{ -c:_value}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR+(lhs AS CURRENCY, rhs AS CURRENCY) AS CURRENCY
            RETURN lhs:Add(rhs)

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR+(lhs AS CURRENCY, rhs AS USUAL) AS CURRENCY
            RETURN lhs:Add(rhs)

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR+(lhs AS USUAL, rhs AS CURRENCY) AS CURRENCY
            RETURN rhs:Add(lhs)

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR-(lhs AS CURRENCY, rhs AS CURRENCY) AS CURRENCY
            RETURN lhs:Subtract(rhs)

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR-(lhs AS CURRENCY, rhs AS USUAL) AS CURRENCY
            RETURN lhs:Subtract(rhs)

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR-(lhs AS USUAL, rhs AS CURRENCY) AS CURRENCY
            // set decimals for LHS to 0, so max decmals is decimals right
            RETURN CURRENCY{lhs}:Subtract(rhs)

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR*(lhs AS CURRENCY, rhs AS CURRENCY) AS CURRENCY
            RETURN CURRENCY{ lhs:_value * rhs:_value}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR/(lhs AS CURRENCY, rhs AS CURRENCY) AS CURRENCY
            RETURN CURRENCY{ lhs:_value / rhs:_value}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR%(lhs AS CURRENCY, rhs AS CURRENCY) AS CURRENCY
            RETURN CURRENCY{ lhs:_value % rhs:_value}

            #endregion
        #region Unary Operators
        /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR ++ (c  AS CURRENCY) AS CURRENCY
            RETURN CURRENCY{c:_value+1}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR -- (c  AS CURRENCY) AS CURRENCY
            RETURN CURRENCY{c:_value-1}
            #endregion

        #region Explicit casts. Used inside Transform
        /// <exclude />
        METHOD CastToInt() AS INT
            RETURN (INT)(SELF:_value)

            /// <exclude />
        METHOD CastToInt64() AS INT64
            RETURN (INT64)(SELF:_value)

            #endregion
        #region Add and Subtract
        /// <exclude />
        METHOD Add(rhs AS CURRENCY) AS CURRENCY
            RETURN CURRENCY{ SELF:_value + rhs:_value}

            /// <exclude />
        METHOD Add(rhs AS USUAL) AS CURRENCY
            LOCAL result AS CURRENCY
            IF rhs:IsFloat
                result := SELF:Add ( (CURRENCY) rhs)
            ELSEIF rhs:IsDecimal
                result := SELF:Add ( (System.Decimal) rhs)
            ELSEIF rhs:IsCurrency
                result := SELF:Add ( (CURRENCY) rhs)
            ELSEIF  rhs:IsLong
                result := CURRENCY{ SELF:_value + (LONG) rhs}
            ELSE
                THROW Error.ArgumentError(__ENTITY__,Nameof(rhs), "Argument is not numeric")
            ENDIF
            RETURN result

            /// <exclude />
        METHOD Subtract(rhs AS CURRENCY) AS CURRENCY
            RETURN CURRENCY{ SELF:_value - rhs:_value}

            /// <exclude />
        METHOD Subtract(rhs AS USUAL) AS CURRENCY
            LOCAL result AS CURRENCY
            IF rhs:IsFloat
                result := SELF:Subtract( (CURRENCY) rhs)
            ELSEIF rhs:IsDecimal
                result := SELF:Subtract( (System.Decimal) rhs)
            ELSEIF rhs:IsCurrency
                result := SELF:Subtract( (CURRENCY) rhs)
            ELSEIF  rhs:IsLong
                result := CURRENCY{ SELF:_value - (LONG) rhs}
            ELSE
                THROW Error.ArgumentError(__ENTITY__,Nameof(rhs), "Argument is not numeric")
            ENDIF
            RETURN result

            #endregion

        #region IConvertable
        /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToBoolean(provider AS System.IFormatProvider) AS LOGIC
            RETURN _value ==  0.0m

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToByte(provider AS System.IFormatProvider) AS BYTE
            RETURN ((IConvertible) _value):ToByte(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToChar(provider AS System.IFormatProvider) AS CHAR
            RETURN ((IConvertible) _value):ToChar(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToDateTime(provider AS System.IFormatProvider) AS System.DateTime
            RETURN ((IConvertible) _value):ToDateTime(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToDecimal(provider AS System.IFormatProvider) AS Decimal
            RETURN ((IConvertible) _value):ToDecimal(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToDouble(provider AS System.IFormatProvider) AS REAL8
            RETURN ((IConvertible) _value):ToDouble(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToInt16(provider AS System.IFormatProvider) AS SHORT
            RETURN ((IConvertible) _value):ToInt16(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToInt32(provider AS System.IFormatProvider) AS LONG
            RETURN ((IConvertible) _value):ToInt32(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToInt64(provider AS System.IFormatProvider) AS INT64
            RETURN ((IConvertible) _value):ToInt64(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToSByte(provider AS System.IFormatProvider) AS SByte
            RETURN ((IConvertible) _value):ToSByte(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToSingle(provider AS System.IFormatProvider) AS REAL4
            RETURN ((IConvertible) _value):ToSingle(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToType(conversionType AS System.Type, provider AS System.IFormatProvider) AS OBJECT
            RETURN ((IConvertible) _value):ToType(conversionType, provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToUInt16(provider AS System.IFormatProvider) AS WORD
            RETURN ((IConvertible) _value):ToUInt16(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToUInt32(provider AS System.IFormatProvider) AS DWORD
            RETURN ((IConvertible) _value):ToUInt32(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToUInt64(provider AS System.IFormatProvider) AS UINT64
            RETURN ((IConvertible) _value):ToUInt64(provider)

            /// <inheritdoc />
        PUBLIC METHOD IConvertible.ToString(provider AS System.IFormatProvider) AS STRING
            RETURN ((IConvertible) _value):ToString(provider)
            #endregion
        #region IFormattable
        /// <inheritdoc cref="System.Double.ToString"/>
        PUBLIC OVERRIDE METHOD ToString() AS STRING
            RETURN SELF:ToString("0.0000")

        /// <inheritdoc cref="System.Double.ToString"/>
        PUBLIC METHOD ToString(sFormat AS STRING) AS STRING
            RETURN _value:ToString(sFormat)

            /// <inheritdoc />
        PUBLIC METHOD ToString(format AS STRING, provider AS System.IFormatProvider) AS STRING
            RETURN ((IFormattable) _value):ToString(format, provider)

        INTERNAL METHOD ToDebugString() AS STRING
            RETURN SELF:ToString("0.0000")

        #endregion

        #region IComparable
        /// <inheritdoc />
        PUBLIC METHOD CompareTo(rhs AS CURRENCY) AS INT
            RETURN _value:CompareTo( rhs:_value)

            /// <inheritdoc />
        PUBLIC METHOD CompareTo(rhs AS OBJECT) AS INT
            RETURN SELF:CompareTo( (CURRENCY) rhs)
            #endregion

        #region ISerializable
        /// <inheritdoc/>
        PUBLIC METHOD GetObjectData(info AS SerializationInfo, context AS StreamingContext) AS VOID
            IF info == NULL
                THROW System.ArgumentException{"info"}
            ENDIF
            info:AddValue("Value", SELF:_value)
            RETURN
        /// <include file="RTComments.xml" path="Comments/SerializeConstructor/*" />
        CONSTRUCTOR (info AS SerializationInfo, context AS StreamingContext)
            IF info == NULL
                THROW System.ArgumentException{"info"}
            ENDIF
            SELF:_value   := info:GetDecimal("Value")
        #endregion

    END STRUCTURE

END NAMESPACE