/* * Copyright (c) 2019 Szabolcs Horvát. * * See the file LICENSE.txt for copying permission. */ #ifndef LTEMPLATE_HELPERS_H #define LTEMPLATE_HELPERS_H #include "LTemplate.h" #include #include #include namespace mma { namespace detail { // Functions for getting and setting arguments and return values template inline TensorRef getTensor(MArgument marg) { return MArgument_getMTensor(marg); } template inline void setTensor(MArgument marg, TensorRef &val) { MArgument_setMTensor(marg, val.tensor()); } template inline SparseArrayRef getSparseArray(MArgument marg) { return MArgument_getMSparseArray(marg); } template inline void setSparseArray(MArgument marg, SparseArrayRef &val) { MArgument_setMSparseArray(marg, val.sparseArray()); } template inline ImageRef getImage(MArgument marg) { return MArgument_getMImage(marg); } template inline Image3DRef getImage3D(MArgument marg) { return MArgument_getMImage(marg); } inline GenericImageRef getGenericImage(MArgument marg) { return MArgument_getMImage(marg); } inline GenericImage3DRef getGenericImage3D(MArgument marg) { return MArgument_getMImage(marg); } template inline void setImage(MArgument marg, ImageRef &val) { MArgument_setMImage(marg, val.image()); } template inline void setImage3D(MArgument marg, Image3DRef &val) { MArgument_setMImage(marg, val.image()); } inline void setGenericImage(MArgument marg, GenericImageRef &val) { MArgument_setMImage(marg, val.image()); } inline void setGenericImage3D(MArgument marg, GenericImage3DRef &val) { MArgument_setMImage(marg, val.image()); } #ifdef LTEMPLATE_RAWARRAY template inline RawArrayRef getRawArray(MArgument marg) { return MArgument_getMRawArray(marg); } inline GenericRawArrayRef getGenericRawArray(MArgument marg) { return MArgument_getMRawArray(marg); } template inline void setRawArray(MArgument marg, RawArrayRef &val) { MArgument_setMRawArray(marg, val.rawArray()); } inline void setGenericRawArray(MArgument marg, GenericRawArrayRef &val) { MArgument_setMRawArray(marg, val.rawArray()); } #endif // LTEMPLATE_RAWARRAY #ifdef LTEMPLATE_NUMERICARRAY template inline NumericArrayRef getNumericArray(MArgument marg) { return MArgument_getMNumericArray(marg); } inline GenericNumericArrayRef getGenericNumericArray(MArgument marg) { return MArgument_getMNumericArray(marg); } template inline void setNumericArray(MArgument marg, NumericArrayRef &val) { MArgument_setMNumericArray(marg, val.numericArray()); } inline void setGenericNumericArray(MArgument marg, GenericNumericArrayRef &val) { MArgument_setMNumericArray(marg, val.numericArray()); } #endif // LTEMPLATE_NUMERICARRAY inline complex_t getComplex(MArgument marg) { mcomplex c = MArgument_getComplex(marg); return complex_t(c.ri[0], c.ri[1]); } inline void setComplex(MArgument marg, complex_t val) { mcomplex *c = reinterpret_cast(&val); MArgument_setComplex(marg, *c); } inline const char *getString(MArgument marg) { return const_cast(MArgument_getUTF8String(marg)); } inline void setString(MArgument marg, const char *val) { MArgument_setUTF8String(marg, const_cast(val)); } template inline IntTensorRef get_collection(const Collection &collection) { IntTensorRef ids = makeVector(collection.size()); typename Collection::const_iterator i = collection.begin(); mint *j = ids.begin(); for (; i != collection.end(); ++i, ++j) *j = i->first; return ids; } template class getObject { std::map &collection; public: explicit getObject(std::map &coll) : collection(coll) { } T & operator () (MArgument marg) { return *(collection[MArgument_getInteger(marg)]); } }; // Underlying stream buffer for mma::mout class MBuffer : public std::streambuf { std::vector buf; public: explicit MBuffer(std::size_t buf_size = 4096) : buf(buf_size + 1) { setp(&buf.front(), &buf.back()); } protected: int sync(); int_type overflow(int_type ch); private: MBuffer(const MBuffer &); MBuffer & operator = (const MBuffer &); }; // Used with RAII to ensure that mma::mout is flushed before the exit of any top-level function. struct MOutFlushGuard { ~MOutFlushGuard() { mout.flush(); } }; // Handles unknown exceptions in top-level functions. inline void handleUnknownException(const char *what, const char *funname) { std::ostringstream msg; msg << "Unknown exception caught in " << funname << ". The library may be in an inconsistent state. It is recommended that you restart the kernel now to avoid instability."; if (what) msg << '\n' << what; message(msg.str(), M_ERROR); } } // namespace detail } // namespace mma #endif // LTEMPLATE_HELPERS_H