#ifndef scalar_vec_ATYPE_LTYPE_RTYPE_OPNAME
#define scalar_vec_ATYPE_LTYPE_RTYPE_OPNAME
static IA_DiscreteImage<ATYPE>
scalar_vec_bo_OPNAME(LTYPE lhs,const IA_VectorDI<RTYPE> *rhs)
{
    const IA_IntPointSet domain = rhs->domain();
    const unsigned sz = domain.card();
    ATYPE *const vec = new ATYPE[sz];

    {
	ATYPE *ds = vec;
	const RTYPE *rs = rhs->vec;
	for (unsigned i=0; i<sz; i++) {
	    *(ds++) = SUBOP(lhs, *(rs++));
	}
    }
    return IA_DiscreteImage<ATYPE>(domain, vec, sz, 1);
}
#endif // scalar_vec_ATYPE_LTYPE_RTYPE_OPNAME

// scalar-scalar operation is trivial

#ifndef scalar_iter_ATYPE_LTYPE_RTYPE_OPNAME
#define scalar_iter_ATYPE_LTYPE_RTYPE_OPNAME
static IA_DiscreteImage<ATYPE>
scalar_iter_bo_OPNAME(LTYPE lhs,IA_DiscreteImage<RTYPE> rhs)
{
    const IA_IntPointSet domain = rhs.domain();
    const unsigned sz = domain.card();
    ATYPE *const vec = new ATYPE[sz];

    {
	ATYPE *ds = vec;
	RTYPE rtmp;
	IA_DIVIter<RTYPE>	riter(rhs);
	for (unsigned i=0; i<sz; i++) {
	    riter(rtmp);
	    *(ds++) = SUBOP(lhs, rtmp);
	}
    }
    return IA_DiscreteImage<ATYPE>(domain, vec, sz, 1);
}
#endif // scalar_iter_ATYPE_LTYPE_RTYPE_OPNAME

IA_DiscreteImage<ATYPE>
OP (LTYPE lhs, const IA_DiscreteImage<RTYPE> &rhs)
{
    if (rhs.type() == IA_VectorDI<RTYPE>::s_type()) {
	return scalar_vec_bo_OPNAME(lhs,(IA_VectorDI<RTYPE> *)rhs.bdip);
    } else if (rhs.type() == IA_ConstDI<RTYPE>::s_type()) {
	return IA_DiscreteImage<ATYPE> (rhs.domain(), SUBOP(lhs, ((IA_ConstDI<RTYPE> *)rhs.bdip)->value));
    } else {
	return scalar_iter_bo_OPNAME(lhs,rhs);
    }
}
