/** * @file sparse_array.h * Auto-expanding sparse array type * * @remark Copyright 2007 OProfile authors * @remark Copyright (c) International Business Machines, 2007. * @remark Read the file COPYING * * @author Dave Nomura <dcnltc@us.ibm.com> */ #ifndef SPARSE_ARRAY_H #define SPARSE_ARRAY_H template <typename I, typename T> class sparse_array { public: typedef std::map<I, T> container_type; typedef typename container_type::size_type size_type; /** * Index into the map for a value. * NOTE: since std::map does/can not have a const member function for * operator[], this const member function simply returns 0 for * profile classes that aren't represented in the map. * This member function will only be invoked for queries of the * sparse array. */ T operator[](size_type index) const { typename container_type::const_iterator it = container.find(index); if (it != container.end()) return it->second; else return 0; } /** * Index into the vector for a value. If the index is larger than * the current max index, a new array entry is created. */ T & operator[](size_type index) { return container[index]; } /** * vectorized += operator */ sparse_array & operator+=(sparse_array const & rhs) { typename container_type::const_iterator it = rhs.container.begin(); typename container_type::const_iterator it_end = rhs.container.end(); for ( ; it != it_end; it++) container[it->first] += it->second; return *this; } /** * vectorized -= operator, overflow shouldn't occur during substraction * (iow: for each components lhs[i] >= rhs[i] */ sparse_array & operator-=(sparse_array const & rhs) { typename container_type::const_iterator it = rhs.container.begin(); typename container_type::const_iterator it_end = rhs.container.end(); for ( ; it != it_end; it++) container[it->first] -= it->second; return *this; } /** * return the maximum index of the array + 1 or 0 if the array * is empty. */ size_type size() const { if (container.size() == 0) return 0; typename container_type::const_iterator last = container.end(); --last; return last->first + 1; } /// return true if all elements have the default constructed value bool zero() const { typename container_type::const_iterator it = container.begin(); typename container_type::const_iterator it_end = container.end(); for ( ; it != it_end; it++) if (it->second != 0) return false; return true; } private: container_type container; }; #endif // SPARSE_ARRAY_H