/* xtype.h */

#ifndef XTYPE__H
#define XTYPE__H

#include "types.h"
#include "symbol_tdefs.h"
#include "units.h"

struct dc_data;

/* extended type 
   - allows size checking for matrices/vector
   - enum checking for symbolic types
   - unit checking
 */
union xtype_inf {
  int dim[2]; /* for dc_matrix dims */
  dc_svec_tag svec; /* for dc_symbol */
};

struct xtype {
  dc_type T; /* type of object */
  dc_type subT; /* sub_type of object */

  xtype_inf inf; /* which part of inf accessed depends on T and subT */
  unit_vec uv; /* only used if has_units() is true */

  bool operator==( const xtype & ) const;
  bool operator!=( const xtype &xt ) const { return !( *this == xt ); }
  xtype &operator=( const xtype & );
  bool has_units( void ) const;
};

/* cxtype is an abbreviation for const xtype & */
typedef const xtype &cxtype;

ostream &operator<<( ostream &, cxtype );

/* - true iff from can be cast to to
   - assumes a type w/out units cannot be cast to one w/ units or vice-versa */
bool castable( cxtype from, cxtype to );

/* does not cast units since if units do not match, castable fails */
dc_data *cast( dc_data &d, cxtype to );

#endif
