/*
 *  Copyright (c) 2010 Cyrille Berger <cberger@cberger.net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * either version 2, or (at your option) any later version of the License.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#ifndef _CAUCHY_TYPE_H_
#define _CAUCHY_TYPE_H_

namespace Cauchy {
  class Type {
    public:
      enum DataType {
        LOGICAL,
        SINGLE,
        DOUBLE,
        INTEGER,
        INT8,
        UINT8,
        INT16,
        UINT16,
        INT32,
        UINT32,
        INT64,
        UINT64,
        COMPLEX,
        MATRIX,
        RANGE,
        STRING,
        UNKNOWN,
        VOID,
        FUNCTION_POINTER
      };
      static const Type* Logical;
      static const Type* Single;
      static const Type* Double;
      static const Type* Int8;
      static const Type* UInt8;
      static const Type* Int16;
      static const Type* UInt16;
      static const Type* Int32;
      static const Type* UInt32;
      static const Type* Int64;
      static const Type* UInt64;
      static const Type* Range;
      static const Type* InfiniteRange;
      static const Type* String;
      static const Type* Unknown;
      static const Type* Void;
      static const Type* defaultType();
      static const Type* complexType(const Type* type);
      static const Type* matrixType(const Type* type);
      static const Type* optype(const Type* r1, const Type* r2);
      static const Type* functionHandleType(const Type* ret, const Type* arg);
    private:
      Type(DataType type);
      ~Type();
    public:
      DataType dataType() const;
      const Type* embeddedType() const;
      bool isMatrix() const;
      bool isComplex() const;
      bool isNumber() const;
      bool isFunctionPointer() const;
      const Type* returnType() const;
    private:
      struct Private;
      Private* const d;
  };
}

#endif
