#include #include #include #include #include "defs.hh" #include "bboxset.hh" #include "vect.hh" using namespace std; // Input template void vect::input (istream& is) { skipws (is); consume (is, '['); for (int d=0; d> (*this)[d]; assert (is.good()); if (d void vect::output (ostream& os) const { os << "["; for (int d=0; d MPI_Datatype vect::mpi_datatype () const { static bool initialised = false; static MPI_Datatype newtype; if (not initialised) { vect const& s = *this; #define ENTRY(type, name) \ { \ sizeof s.name / sizeof(type), /* count elements */ \ (char*)&s.name - (char*)&s, /* offsetof doesn't work (why?) */ \ dist::mpi_datatype(), /* find MPI datatype */ \ STRINGIFY(name), /* field name */ \ STRINGIFY(type), /* type name */ \ } dist::mpi_struct_descr_t const descr[] = { ENTRY(T, elt), {1, sizeof s, MPI_UB, "MPI_UB", "MPI_UB"} }; #undef ENTRY ostringstream buf; buf << "vect<" << typeid(T).name() << "," << D << ">"; newtype = dist::create_mpi_datatype (sizeof descr / sizeof descr[0], descr, buf.str().c_str(), sizeof s); initialised = true; } return newtype; } // Specialise some constructors for lower dimensions // These functions are declared, but must not be used. // NOTE: __builtin_unreachable() triggers a bug in the OSX linker; we // therefore use assert(0) instead. template<> vect::vect (const int& x, const int& y) { assert(0); } template<> vect::vect (const int& x, const int& y) { assert(0); } template<> vect::vect (const int& x, const int& y) { assert(0); } template<> vect::vect (const int& x, const int& y) { assert(0); } template<> vect::vect (const int& x, const int& y, const int& z) { assert(0); } template<> vect::vect (const int& x, const int& y, const int& z) { assert(0); } template<> vect::vect (const int& x, const int& y, const int& z) { assert(0); } template<> vect::vect (const int& x, const int& y, const int& z) { assert(0); } template<> vect::vect (const int& x, const int& y, const int& z, const int& t) { assert(0); } template<> vect::vect (const int& x, const int& y, const int& z, const int& t) { assert(0); } template<> vect::vect (const int& x, const int& y, const int& z, const int& t) { assert(0); } template<> vect::vect (const int& x, const int& y, const int& z, const int& t) { assert(0); } // Note: We need all dimensions all the time. template class vect; template class vect; template class vect; template class vect; template class vect; template void vect::input (istream& is); template void vect::input (istream& is); template void vect,dim>::input (istream& is); template void vect,2>::input (istream& is); template void vect,2>::input (istream& is); template void vect::output (ostream& os) const; template void vect::output (ostream& os) const; template void vect::output (ostream& os) const; template void vect::output (ostream& os) const; template void vect::output (ostream& os) const; template void vect,dim>::output (ostream& os) const; template void vect,dim>::output (ostream& os) const; template void vect,2>::output (ostream& os) const; template void vect,2>::output (ostream& os) const; template void vect,2>::output (ostream& os) const; template void vect,2>,dim>::output (ostream& os) const; // Instantiate for bboxset class #define DEFINE_FAKE_VECT_OPERATIONS(T,D) \ template<> vect vect::dir (const int d) { assert(0); } \ template<> vect vect::seq () { assert(0); } \ template<> vect vect::seq (const int n) { assert(0); } \ template<> vect vect::seq (const int n, const int s) { assert(0); } \ template<> vect& vect::operator*= (const vect&) { assert(0); } \ template<> vect& vect::operator*= (const T&) { assert(0); } \ template<> vect& vect::operator/= (const vect&) { assert(0); } \ template<> vect& vect::operator/= (const T&) { assert(0); } \ template<> vect& vect::operator%= (const vect&) { assert(0); } \ template<> vect& vect::operator%= (const T&) { assert(0); } \ template<> vect& vect::operator^= (const vect&) { assert(0); } \ template<> vect& vect::operator^= (const T&) { assert(0); } \ template<> vect vect::operator+ () const { assert(0); } \ template<> vect vect::operator- () const { assert(0); } \ template<> vect vect::operator~ () const { assert(0); } \ template class vect; \ template size_t memoryof (const vect&); \ template istream& operator>> (istream& is, vect&); \ template ostream& operator<< (ostream& os, const vect&); // need typedefs since macro calls can't have commas in arguments typedef bboxset T1; typedef vect,2> T2; DEFINE_FAKE_VECT_OPERATIONS(T1,dim) DEFINE_FAKE_VECT_OPERATIONS(T2,dim) #undef DEFINE_FAKE_VECT_OPERATIONS