template<class T> void cython_iadd(T* a, T* b) {
  *a += *b;
}

template<class T> void cython_isub(T* a, T* b) {
  *a -= *b;
}

// template<class T> void cython_imul_dbl(T* a, double b) {
//   *a *= b;
// }

// template<class T> void cython_idiv_dbl(T* a, double b) {
//   *a /= b;
// }

template<class T> T* cython_add(T* a, T* b) {
  return new T(*a + *b);
}

template<class T> T* cython_sub(T* a, T* b) {
  return new T(*a - *b);
}

template<class T> auto* cython_div(T* a, T* b) {
  return (*a / *b).newclone();
}

template<class T> bool cython_eq(T* a, T* b) {
  return *a == *b;
}

template<class T> bool cython_ne(T* a, T* b) {
  return *a != *b;
}

template<class T> auto* cython_eff(T* a, T* b) {
  return efficiency(*a, *b).newclone();
}

template<class T, typename... Args> auto* cython_est(T* a, const Args& ...args) {
  return (*a).mkEstimate(args...).newclone();
}

template<class T, typename... Args> auto* cython_effn(T* a, const Args& ...args) {
  return (*a).mkBinnedEffNumEntries(args...).newclone();
}

template<class T, typename... Args> auto* cython_hist(T* a, const Args& ...args) {
  return (*a).mkHisto(args...).newclone();
}
