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

#include <akaxiso/classes/qname.h>
#include <vector>

namespace aka2 {

  enum getter_type {
    accessor_type = 1,
    ptr_type,
    null_type
  };

  struct member_getter {
    member_getter(getter_type t) : type_(t) {}
    virtual ~member_getter(){}
    getter_type get_type() const { return type_; }
  private:
    getter_type type_;
  };

  struct ptr_getter : public member_getter {
    ptr_getter(int offset) : member_getter(ptr_type), offset_(offset) {}
    void* get_member(void *e) const { 
      int address = reinterpret_cast<unsigned int>(e) + offset_;
      return reinterpret_cast<void*>(address);
    }
    const void* get_member(const void* e) const {
      int address = reinterpret_cast<unsigned int>(e) + offset_;
      return reinterpret_cast<const void*>(address);
    }
  protected:
    int offset_;
  };

  struct accessor_getter : public member_getter {
    accessor_getter() : member_getter(accessor_type) {}
    virtual void get(const void *elm, void *cache) const = 0;
    virtual void set(void *elm, const void *cache) const = 0;
  };


  template<class P, class T, class V>
  inline member_getter *create_ptr_getter(const P *, V T::* m) {
    P* p = reinterpret_cast<P*>(1024);
    int offset = reinterpret_cast<int>(& (p->*m)) - reinterpret_cast<int>(p);
    return new ptr_getter(offset);
  }

  struct null_getter : public member_getter {
     null_getter() : member_getter(null_type) {}
  };

}


#endif
