#ifndef GCIFLOAT_HF
#define GCIFLOAT_HF TRUE
/*=========================================================================
 * Copyright (C) VMware, Inc. 1986-2011.  All Rights Reserved.
 *
 * Name - gcifloat.hf
 *
 * $Id: gcifloat.hf,v 1.7 2008-01-09 22:51:03 stever Exp $
 *
 *  Macros, constants and functions for accessing the bodies of instances
 *  of GemStone classes Float and SmallFloat.
 *   
 *  Use of things defined in this file may be needed if GciFetchBytes 
 *  is used to retrieve the bodies of GemStone Floats or SmallFloats, or 
 *  if the application desires to implement a GemStone class that is a byte
 *  array of native floats.
 *
 *  Entries in this file are used in the implementation of Traversal
 *  functions, GciCreateByteObj, and in GciStoreBytesInstanceOf
 *========================================================================
 */

/* See gcicmn.ht for gcifloat macro definitions */
#include "gcicmn.ht"

/* no more includes. KEEP THIS LINE */

/*
 * The following constants are defined so we have control of values 
 * used for exceptional floats. These values conform to IEEE 754, and do not 
 * depend on compiler peculiarities.
 *
 *  GciFloatPlusInfinityVal 
 *  GciFloatMinusInfinityVal
 *  GciFloatPlusQuietNanVal
 *  GciFloatMinusQuietNanVal
 *  GciFloatPlusSignalingNanVal
 *  GciFloatMinusSignalingNanVal
 *
 *=========================================================================
 */

extern "C" {

EXTERN_GCI_DEC(double) GciFloatPlusInfinityVal(void);
EXTERN_GCI_DEC(double) GciFloatMinusInfinityVal(void);
EXTERN_GCI_DEC(double) GciFloatPlusQuietNanVal(void);
EXTERN_GCI_DEC(double) GciFloatMinusQuietNanVal(void);
EXTERN_GCI_DEC(double) GciFloatPlusSignalingNanVal(void);
EXTERN_GCI_DEC(double) GciFloatMinusSignalingNanVal(void);

/*=========================================================================
 * GciFloatKindSign
 *
 * Returns the GciFloatKindEType of the argument for a normal or positive 
 * float.  Returns  (-1 * (GciFloatKindEType of the argument) for a float 
 * which has its sign bit set and which is an exceptional value.  An
 * exceptional value is either a NaN or an Infinity.
 *=========================================================================
 */  

  EXTERN_GCI_DEC(int)
GciFloatKindSign(double aReal);

/*=========================================================================
 * GciFloatIsNaN
 *
 *   returns TRUE if the argument is a NaN , FALSE otherwise
 *=========================================================================
 */
  EXTERN_GCI_DEC(BoolType)
GciFloatIsNaN(double *floatPtr);

/*=========================================================================
 * GciFloatSwizzleRead
 *
 *   swizzles the argument in-place. returns the argument
 *
 *  These functions have no effect on platforms where FLG_IEEE_LITTLE
 *   is not defined.  (i.e. they have no effect except on Intel CPU)
 *=========================================================================
 */
/* convert from DBF to Intel format */
  EXTERN_GCI_DEC(double*)
GciFloatSwizzleRead(double *floatPtr);

/* convert from Intel to DBF format */
static inline double* GciFloatSwizzleWrite(double *floatPtr) {
  return GciFloatSwizzleRead(floatPtr);
}

/*=========================================================================
 * GciFloatSwizzleReadSingle, 
 *   swizzles the argument in-place.  The function result is equal to the
 *   argument, and is provided for convenience in building macros
 *
 *   The  single precision float must be cast to the argument type shown
 *   to avoid its promotion to a double.
 *
 *  These functions have no effect on platforms where FLG_IEEE_LITTLE
 *   is not defined.  (i.e. they have no effect except on Intel CPU)
 *=========================================================================
 */
/* convert from DBF to Intel format */
  EXTERN_GCI_DEC(unsigned int*)
GciFloatSwizzleReadSingle(unsigned int *floatPtr); 

/* convert from Intel to DBF format */
static inline unsigned int* GciFloatSwizzleWriteSingle(unsigned int  *floatPtr) {
  return GciFloatSwizzleReadSingle(floatPtr);
}

} /* extern "C" */

#endif /* GCIFLOAT_HF */
