core/vbl/vbl_sparse_array_base.h
Go to the documentation of this file.
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_