src/imslib/src/ims/utils/matrix.h
21130c8c
 // this header defines template object matrix, and also necessary row
 #ifndef IMS_MATRIX_H
 #define IMS_MATRIX_H
 
 #include <vector>
 
 namespace ims {
 
 ////////////////////////////////////////////////////////////////////////////////
 // row type necessary for matrix
 
 template < typename T , typename A = std::allocator<T> >
 class row {
 public:
 	//some typedefs (see Stroustrup pp 471)
 	typedef T value_type;
 	typedef typename A::size_type size_type;
 	typedef std::vector<value_type, A> data_type;
 
 	//iterators
 	//typedef data_type::iterator iterator;
 	typedef typename data_type::const_iterator const_iterator;
 	
 	//references
 	typedef typename A::reference reference;
 	typedef typename A::const_reference const_reference;
 
 	//constructors
 	row (size_type m, value_type v = value_type()) { data = std::vector<value_type> (m,v); } 
 
 	//index access
 	reference			operator[] (size_type j) { return data[j]; }
 	const_reference		operator[] (size_type j) const { return data[j]; }
 
 	//get iterators
 	const_iterator	begin() const { return data.begin(); }
 	const_iterator	end() const { return data.end(); }
 
 	//misc
 	size_type		size() const { return data.size(); }
 private:
 	//data field
 	data_type data;
 };
 
 
 template < typename T, typename A = std::allocator<T> >
 class matrix {
 public:
 	//some typedefs (see Stroustrup pp 471)
 	typedef T value_type;
 	typedef typename A::size_type size_type;
 	typedef row<value_type> row_type;
 	typedef std::vector<row_type> data_type;
 
 	//row iteratorsessene
 //	typedef typename data_type::iterator row_iterator;
 	typedef typename data_type::const_iterator const_row_iterator;
 
 	//row reference types
 	typedef row_type& row_reference;
 	typedef const row_reference const_row_reference;
 
 	//constructors
 	matrix (size_type n, size_type m, value_type v = value_type()) { data = data_type (n, row_type (m, v)); }
 
 	//index access
 	//TODO: not good to give a reference to row, cause so, user is abled to change it
 	row_reference		operator[] (size_type i) { return data[i]; }
 	const_row_reference	operator[] (size_type i) const { return data[i]; }
 
 	//get row iterator (if it works, we only take const_iterator)
 	const_row_iterator		rows_begin() const { return data.begin(); }
 	const_row_iterator		rows_end() const { return data.end(); }
 	
 	//misc
 	size_type		rows () const { return size_type (data.size()); }
 	size_type		cols () const;
 private:
 	//data field
 	data_type data;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 //functions
 template < typename T, typename A >
 typename matrix<T,A>::size_type matrix<T,A>::cols() const
 {
 	//TODO: somehow try to maintain original row_size for each row
 	return size_type ((data.front()).size());
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 //IO functions
 
 //row
 //I
 /*
 template <typename T, typename A>
 std::istream& operator>> (std::istream& s, const row<T,A>& r)
 {
 	T x;
 	char t;
 
 	//read in until not more
 	while (s >> x >> t)
 		r.push_back(x);
 
 	s.clear();
 	//ATTENTION: for the moment only unix compatible
 	if (t  = '\n') {
 		//all ok, pushback last element
 		r.push_back(x);
 	}
 	else {
 		//nothing ok
 		s.clear(ios_base::badbit);
 	}
 
 	return s;		
 }
 */
 
 //O
 template <typename T, typename A>
 std::ostream& operator<< (std::ostream& s, const row<T,A>& r)
 {
 	typename row<T,A>::const_iterator it = r.begin();
 
 	//for now, we just write a tab as separator
 	for ( ; it < r.end(); ++it) {
 		s << *it;
 		if (it != (r.end()-1)) s << '\t';
 	}
 
 	return s;		
 }
 
 //matrix
 //I
 /*
 template <typename T, typename A>
 std::istream& operator>> (std::istream& s, const matrix<T,A>& m)
 {
 	typename matrix<T,A>::const_row_iterator it = m.rows_begin();
 
 	for ( ; it < m.rows_end(); ++it)
 		s << *it << '\n';
 
 	return s;
 }
 */
 
 //O
 template <typename T, typename A>
 std::ostream& operator<< (std::ostream& s, const matrix<T,A>& m)
 {
 	typename matrix<T,A>::const_row_iterator it = m.rows_begin();
 
 	for ( ; it < m.rows_end(); ++it)
 		s << *it << '\n';
 
 	return s;
 }
 
 }; // namespace ims
 
 #endif