#ifndef ALL_POINTERS_HPP
#define ALL_POINTERS_HPP

// Need to eventually replace any_pointer with all_pointer

namespace __g {

  struct all_pointer
  {
    all_pointer(int type_size)
      : content(0), type_size(type_size)
    {
    }

    all_pointer(void* ptr, int type_size)
      : content(ptr), type_size(type_size)
    {
    }

    all_pointer(const all_pointer & other) 
      : content(other.content), type_size(other.type_size) { }

    //~all_pointer() { }

    all_pointer& operator++() {
      content += type_size;
      return *this;
    }
    all_pointer& operator--() {
      content -= type_size;
      return *this;
    }
    void* operator*() const { return content; }
    void* operator[](std::ptrdiff_t n) const {
      return content + (type_size * n);
    }
    all_pointer operator+(std::ptrdiff_t n) const {
      return all_pointer(content + (type_size * n), type_size);
    }
    all_pointer operator-(std::ptrdiff_t) const {
      return all_pointer(content - (type_size * n), type_size);
    }
    std::ptrdiff_t operator-(const all_pointer& other) const {
      return (content - other.content) / type_size;
    }
    bool operator==(const all_pointer& other) const
      { return content == other.content; }
    bool operator!=(const all_pointer& other) const
      { return content != other.content; }
    bool operator<(const all_pointer& other) const
      { return content < other.content; }
    bool operator<=(const all_pointer& other) const
      { return content <= other.content; }
    bool operator>(const all_pointer& other) const
      { return content > other.content; }
    bool operator>=(const all_pointer& other) const
      { return content >= other.content; }
    operator void*() const { return content; }

    all_pointer & swap(all_pointer & rhs)
    {
      std::swap(content, rhs.content);
      std::swap(type_size, rhs.type_size);
      return *this;
    }

    template<typename ValueType>
    all_pointer & operator=(const ValueType & rhs)
    {
      all_pointer(rhs).swap(*this);
      return *this;
    }

    all_pointer & operator=(const all_pointer & rhs)
    {
      all_pointer(rhs).swap(*this);
      return *this;
    }

    bool empty() const
    {
      return !content;
    }

    void* content;
    int type_size;
  };



} // namespace __g

#endif // ALL_POINTERS_HPP

