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

#include <akaxiso/classes/types.h>
#include <akaxiso/classes/member.h>

namespace aka2 {

  /** node */
  struct node {
    friend struct const_node;
    explicit node() : e_(0), op_(0) {}
    explicit node(void *e, const element_op &op) 
      : e_(e), op_(&op) { }
    const element_op &op() const { return *op_; }
    void *ptr() const { return e_; }
    bool empty() const { return e_ == 0; }

    void destroy() {
      op_->destroy(e_);
      e_ = 0;
    }

    schematype_id get_schematype() const {
      return op_->get_schematype();
    }

  private:
    void* e_;
    const element_op *op_;
  };

  /** const_node */
  struct const_node {
    explicit const_node() : e_(0), op_(0) {}
    const_node(const node &nd) : e_(nd.e_), op_(nd.op_) {  }
    explicit const_node(const void *e, const element_op &op)  : e_(e), op_(&op) {  }
    const void *ptr() const { return e_; }
    const element_op &op() const { return *op_; }
    bool empty() const { return e_ == 0; }

    schematype_id get_schematype() const {
      return op_->get_schematype();
    }
  private:
    const void* e_;
    const element_op *op_;
  };
}

#endif
