// ******************** FlopCpp ********************************************** // File: MP_index.hpp // $Id$ // Author: Tim Helge Hultberg (thh@mat.ua.pt) // Copyright (C) 2003 Tim Helge Hultberg // All Rights Reserved. // **************************************************************************** #ifndef _MP_index_hpp_ #define _MP_index_hpp_ #include "MP_utilities.hpp" #include "MP_constant.hpp" namespace flopc { class MP_index; class MP_domain; class MP_set; /** @brief Internal representation of a index @ingroup INTERNAL_USE @note FOR INTERNAL USE: This is not normally used directly by the calling code. */ class MP_index_base { friend class Handle; friend class MP_index_exp; public: virtual int evaluate() const = 0; virtual MP_index* getIndex() const = 0; virtual MP_domain getDomain(MP_set* s) const = 0; // virtual void display()const; protected: MP_index_base() : count(0) {} virtual ~MP_index_base() {} private: int count; }; /** @brief Representation of an index. @ingroup PublicInterface This is one of the main public interface classes. It is used to iterate through, or index into an MP_domain. It is also used to share the 'current' index offsets between expressions which share an index. @li these can be built stand-alone @li these are sometime constructed as needed. @li there is a special "empty" which is a unique constant. \ This constant is used when defaulting passed parameters for \ extra dimensions which are unused. */ class MP_index : public MP_index_base { friend class MP_domain_set; template friend class MP_domain_subset; public: /// Default constructor. MP_index() : index(0), instantiated(false) {} int evaluate() const { return index; } /// returns a reference to the distinct "empty" index. static MP_index &getEmpty(); /// returns a reference to the distinct "wildcard" index. static MP_index &Any(); private: /** interrogate state of instatiation of data. */ bool isInstantiated() const { return instantiated; } /** Setter for the index. @todo should this assert "instatiated"? */ void assign(int i) { index = i; } /** unsetter for instatiated. */ void unInstantiate() { instantiated = false; } /** setter for instatiated. */ void instantiate() { instantiated = true; } /** getter for MP_index * data type. @todo should this be virtual? */ MP_index* getIndex() const { return const_cast(this); } /// Getter for domain over which this index is applied. virtual MP_domain getDomain(MP_set* s) const; static MP_index& Empty; static MP_index& Any_index; int index; bool instantiated; }; /// returns a Constant as a result of addition of two MP_index values. Constant operator+(MP_index& a, MP_index& b); /// returns a Constant as a result of a difference of two MP_index values. Constant operator-(MP_index& a, MP_index& b); /** returns an index expression from a difference between an MP_index and an integer. (i-5) */ MP_index_exp operator-(MP_index& i,const int& j); /** returns an index expression from a sum between an MP_index and an integer. (i+5) */ MP_index_exp operator+(MP_index& i,const int& j); /** returns an index expression from a sum between an MP_index and a Constant. */ MP_index_exp operator+(MP_index& i,const Constant& j); /** returns an index expression from a product between an MP_index and a Constant. */ MP_index_exp operator*(MP_index& i,const Constant& j); class SUBSETREF; /** @brief Representation of an expression involving an index. @ingroup PublicInterface This is one of the main public interface classes. It is used to create complex arrangements of index values.
Index expressions can involve: @li constants @li other indexes @li subset references @li other index expressions.
There is a unique 'empty' version for use in defaulting extra dimensions. */ class MP_index_exp : public Handle { public: /// For internal use. MP_index_exp(MP_index_base* r) : Handle(r) {} /// create an index expression from a constant integer. MP_index_exp(int i=0); /// create an index expression from a Constant MP_index_exp(const Constant& c); /// create an index expression from an MP_index. MP_index_exp(MP_index& i); /** create an index expression from a SUBSETREF @todo internal? or explain? */ MP_index_exp(const SUBSETREF& d); /// copy constructor from another MP_index_exp MP_index_exp(const MP_index_exp& other); virtual ~MP_index_exp() {} /// Return the unique empty expression. static const MP_index_exp &getEmpty(); private: static MP_index_exp Empty; }; /** @brief Internal representation of an index expression @ingroup INTERNAL_USE @note FOR INTERNAL USE: This is not normally used directly by the calling code. @see operator*(MP_index& i, const Constant & j); */ class MP_index_mult : public MP_index_base { friend MP_index_exp operator*(MP_index& i,const Constant& j); private: MP_index_mult(MP_index& i, const Constant& j) : left(i), right(j) {} int evaluate() const { return left->evaluate()*int(right->evaluate()); } MP_index* getIndex() const { return left->getIndex(); } virtual MP_domain getDomain(MP_set* s) const; MP_index_exp left; Constant right; }; /** @brief Internal representation of an index expression @ingroup INTERNAL_USE @note FOR INTERNAL USE: This is not normally used directly by the calling code. @see operator+(MP_index& i, const Constant & j); */ class MP_index_sum : public MP_index_base { friend MP_index_exp operator+(MP_index& i,const Constant& j); friend MP_index_exp operator+(MP_index& i,const int& j); private: MP_index_sum(MP_index& i, const Constant& j) : left(i), right(j) {} int evaluate() const { return left->evaluate()+int(right->evaluate()); } MP_index* getIndex() const { return left->getIndex(); } virtual MP_domain getDomain(MP_set* s) const; MP_index_exp left; Constant right; }; /** @brief Internal representation of an index expression @ingroup INTERNAL_USE @note FOR INTERNAL USE: This is not normally used directly by the calling code. @see operator+(MP_index& i, const Constant & j); */ class MP_index_dif : public MP_index_base { friend MP_index_exp operator-(MP_index& i,const Constant& j); friend MP_index_exp operator-(MP_index& i,const int& j); private: MP_index_dif(MP_index& i, const Constant& j) : left(i), right(j) {} int evaluate() const { return left->evaluate()-int(right->evaluate()); } MP_index* getIndex() const { return left->getIndex(); } virtual MP_domain getDomain(MP_set* s) const; MP_index_exp left; Constant right; }; } // End of namespace flopc #endif