#include "any.h"

using namespace aka2;

any_op any_op::dispatcher_;
any_array_op any_array_op::dispatcher_;

bool any_op::equals(const void *lhs, const void *rhs) const {
  const any &lany = *static_cast<const any*>(lhs);
  const any &rany = *static_cast<const any*>(rhs);
  bool res = (lany.tagname_ == rany.tagname_) && (lany.value_ == rany.value_);
  if (!res)
    return false;
  return any_array_op::dispatcher_.equals(&lany.children_, &rany.children_);
}

void any_op::copy(void *dest, const void *src) const {
  any &destany = *static_cast<any*>(dest);
  const any &srcany = *static_cast<const any*>(src);

  destany.tagname_ = srcany.tagname_;
  destany.value_ = srcany.value_;
  any_array_op::dispatcher_.copy(&destany.children_, &srcany.children_);
}


bool any_array_op::equals(const void *lhs, const void *rhs) const {
  const any_array& larray = *static_cast<const any_array*>(lhs);
  const any_array& rarray = *static_cast<const any_array*>(rhs);

  if (larray.size() != rarray.size())
    return false;
  
  any_array::const_iterator lit = larray.begin();
  any_array::const_iterator rit = rarray.begin();

  while ((larray.end() != lit) && (rarray.end() != rit)) {
    bool res = any_op::dispatcher_.equals(&*lit, &*rit);
    if (!res)
      return false;
  }
  assert((larray.end() == lit) && (rarray.end() == rit));
  return true;
}

void any_array_op::copy(void *dest, const void *src) const {

  any_array& destarray = *static_cast<any_array*>(dest);
  const any_array& srcarray = *static_cast<const any_array*>(src);

  destarray.clear(); // !!!!!!!!!!!

  for (any_array::const_iterator it = srcarray.begin();
       it != srcarray.end(); ++it) {
    destarray.push_back(*it);
  }
}
