#ifndef ASCXX_SET_H #define ASCXX_SET_H #include #include #include "symchar.h" #include "config.h" extern "C"{ #include #include #include } /** This C++ template defines ASCXX_Set and ASCXX_Set which can hold instance-variable sets (struct set_t) (as opposed to 'struct Set' which is different!). It has to be a template because the element type is different, so the element accessor functions are different. In python, this class can be wrapped in a more elegant way, see ascend.i for details. */ class Empty{ // empty class for use in ASCXX_Set }; template class ASCXX_Set{ private: const struct set_t *s; public: ASCXX_Set(){ throw std::runtime_error("Can't create new ASCXX_Set objects"); } ASCXX_Set(const struct set_t *s) : s(s){ if(!isCorrectType()){ throw std::runtime_error("Invalid set creation"); } } const bool isCorrectType() const; unsigned long length() const{ return Cardinality(s); } const T operator[](const unsigned long &index) const; inline const T at(const unsigned long &index) const{ return (*this)[index]; } }; template<> const bool ASCXX_Set::isCorrectType() const; template<> const bool ASCXX_Set::isCorrectType() const; template<> const bool ASCXX_Set::isCorrectType() const; template std::ostream& operator<< (std::ostream& os, const ASCXX_Set& s){ os << "[ "; bool first=true; for(int i=1; i<= s.length(); ++i){ if(!first)os << ", "; else first=false; os << T(s[i]); } os << "]"; return os; } template<> const long ASCXX_Set::operator[](const unsigned long &i) const; template<> const SymChar ASCXX_Set::operator[](const unsigned long &i) const; template<> const Empty ASCXX_Set::operator[](const unsigned long &i) const; #endif