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

#include <akaxiso/classes/traits.h>

namespace aka2 {
  

  template<class V, class VL>
  struct ptrmember_op_dispatcher : public ptrmember_op {
  public:
    virtual schematype_id get_schematype() const { return ptrmember_id; }
    virtual const qname& get_typename() const { return VL::typename_; }
    virtual const attribute_types *get_attribute_types() const { return 0; } 
    virtual void* create() const { assert(!"Must not be called."); return 0; }
    virtual void  destroy(void *elm) const { assert(!"Must not be called."); }
    virtual bool equals(const void *lhs, const void *rhs) const {
      return ptrmember_equals(lhs, rhs, dispatcher_);
    }
    virtual void copy(void *dest, const void *src) const {
      ptrmember_copy(dest, src, dispatcher_);
    }
    
    virtual void set_null(void *elm) const { 
      *static_cast<void**>(elm) = 0;
    }
    virtual void *create_member(void *elm) const { 
      V** v = static_cast<V**>(elm);
      if (*v == 0)
	*v = new V;
      return *v;
    }
    virtual void destroy_member(void *elm) const { 
      V** v = static_cast<V**>(elm);
      if (*v != 0)
	delete *v;
      *v = 0;
    }
    virtual bool  is_null(const void *elm) const { 
      return *static_cast<V* const*>(elm) == 0;
    }

    virtual void *dereference(void *elm) const {
      return *static_cast<V**>(elm);
    }
    virtual const void *dereference(const void *elm) const {
      return *static_cast<const V* const *>(elm);
    }
    virtual const element_op& get_value_op() const {
      return VL::dispatcher_;
    };

    static ptrmember_op_dispatcher<V, VL> dispatcher_;
  };

  template<class V, class VL>
  ptrmember_op_dispatcher<V, VL> ptrmember_op_dispatcher<V, VL>::dispatcher_;


}

#endif
