/* -*- c++ -*- */
#ifndef AKAXISO_TYPES_H__
#define AKAXISO_TYPES_H__

/** @file akaxiso/classes/types.h */
#include <akaxiso/configuration.h>
#include <akaxiso/iosfwd.h>
#include <akaxiso/exception.h>

/** akaxiso data model namespace */
namespace aka2 {

  // id for namespaces.
  typedef long id_type;
  extern const id_type unregistered_token;
  extern const id_type xml_ns_token;
  extern const id_type empty_token;

  class preconditions;
  class document_factory;
  class type_registry;

  const preconditions& system_preconditions();
  document_factory &system_document_factory();
  type_registry &system_type_registry();


  enum schematype_id {
    simpletype_id = 1,
    simplecontent_id,
    array_id,
    sequence_id,
    choice_id,
    all_id,
    ptrmember_id,
    enclose_id,
    disclose_id,
    any_id,
    any_array_id,
    any_attribute_id,
    fixed_id
  };

  struct attribute_types;
  class any_member;
  class qname;


  /** operator for element */
  struct element_op {
    virtual ~element_op() {}
    virtual schematype_id get_schematype() const = 0;
    virtual const qname& get_typename() const = 0;
    virtual bool equals(const void *lhs, const void *rhs) const = 0;
    virtual const attribute_types *get_attribute_types() const = 0;
    virtual const any_member *get_anyattr_type() const = 0;

    virtual void construct(void *e) const = 0;
    virtual void copy_construct(void *e, const void *src) const = 0;
    virtual void destruct(void *e) const = 0;
    virtual size_t class_size() const = 0;

    void *create() const {
      void *dest = ::operator new(class_size());
      construct(dest);
      return dest;
    }

    void *replicate(const void *src) const {
      void *dest = ::operator new(class_size());
      copy_construct(dest, src);
      return dest;
    }

    void destroy(void *e) const {
      destruct(e);
      ::operator delete(e);
    }

    void copy(void *e, const void *src) const {
      destruct(e);
      copy_construct(e, src);
    }

  };


} // namespace aka2

/** XML typeinfo namespace */
namespace xiso {
  template<class T> struct leaf;
}

/** version-independent alias namespace for aka2. */
namespace aka = aka2;

#endif /* AKAXISO_TYPES_H__ */
