00001 // This is core/vbl/vbl_sparse_array_base.h 00002 #ifndef vbl_sparse_array_base_h_ 00003 #define vbl_sparse_array_base_h_ 00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE 00005 #pragma interface 00006 #endif 00007 //: 00008 // \file 00009 // \brief base class for sparse arrays. 00010 // \author Ian Scott, Manchester ISBE 00011 // \date 10 April 2001 00012 00013 #include <vcl_functional.h> 00014 #include <vcl_map.h> 00015 #include <vcl_cstddef.h> 00016 00017 //: A fully featured sparse array which devolves indexing to its templated type 00018 // If you just want an ordinary sparse array use vbl_sparse_array_1d, 00019 // vbl_sparse_array_2d, or vbl_sparse_array_3d. 00020 // 00021 // Design Decision: Advanced Users only. 00022 // 00023 // The sparse array design has as much of the code as possible in this 00024 // templated base class. This allows us to code harden this class 00025 // while leaving the three derived classes in vbl, simple, easy to 00026 // understand and use. 00027 // I rejected to use templating over the number of dimensions because 00028 // this can lead into recursive templating which is in theory very nice, 00029 // but in practice very horrible. It also makes the interface rather 00030 // unintuitive. 00031 // If you are worried about the speed aspects of using a pair of integers 00032 // instead of a single encoded integer, then you can create 00033 // an encoder class as the index type, and use it directly, or hide the 00034 // details by writing a specialising derivative of vbl_sparse_array_base. 00035 00036 template <class T, class Index> 00037 class vbl_sparse_array_base 00038 { 00039 protected: 00040 //: The type of the storage 00041 typedef vcl_map<Index, T, vcl_less<Index> > Map; 00042 //: This stores a compact list of the values. 00043 Map storage_; 00044 00045 public: 00046 00047 typedef vcl_size_t size_type; 00048 00049 //: Return contents at (i) 00050 T & operator () (Index i) { return storage_[i]; } 00051 00052 //: Return contents at (i). Asserts that (i) is non-empty. 00053 T const& operator () (Index i) const; 00054 00055 //: Erase element at location (i). Assertion failure if not yet filled. 00056 void erase(Index ); 00057 00058 //: Return true if location (i) has been filled. 00059 bool fullp(Index ) const; 00060 00061 //: Put a value into location (i). 00062 bool put(Index , const T& ); 00063 00064 //: Return the address of location (i). 0 if not yet filled. 00065 T* get_addr(Index); 00066 00067 //: Empty the sparse matrix. 00068 void clear(); 00069 00070 //: The type of iterators into the efficient storage 00071 typedef typename Map::const_iterator const_iterator; 00072 00073 //: Return number of locations that have been assigned a value using "put". 00074 size_type count_nonempty() const { return storage_.size(); } 00075 00076 //: The type of objects used to index the sparse array 00077 typedef Index Index_type; 00078 00079 //: The type of values stored by the sparse array 00080 typedef T T_type; 00081 00082 //: The type of values of the controlled sequence 00083 // The value_type is a vcl_pair<Index_type, typename T_type> 00084 typedef typename Map::value_type sequence_value_type; 00085 00086 //: A bidirectional iterator pointing at the first non-empty element 00087 // If the array is empty it points just beyond the end. 00088 const_iterator begin() const { return storage_.begin(); } 00089 00090 //: A bidirectional iterator pointing just beyond last non-empty element. 00091 const_iterator end() const { return storage_.end(); } 00092 }; 00093 00094 #endif // vbl_sparse_array_base_h_