include/util/debug/map.hpp

Go to the documentation of this file.
00001 #ifndef OBJMGR_MAP__HPP
00002 #define OBJMGR_MAP__HPP
00003 
00004 #include <corelib/ncbistd.hpp>
00005 #include <corelib/ncbicntr.hpp>
00006 #include <map>
00007 
00008 BEGIN_NCBI_SCOPE
00009 
00010 #define R_WRAP(Type, Call, Declaration) \
00011     Type Declaration \
00012         { \
00013             Type ret; \
00014             RLock(); \
00015             ret = m_Container.Call; \
00016             RUnlock(); \
00017             return ret; \
00018         }
00019 #define R_WRAP_VOID(Call, Declaration) \
00020     void Declaration \
00021         { \
00022             RLock(); \
00023             m_Container.Call; \
00024             RUnlock(); \
00025         }
00026 #define W_WRAP(Type, Call, Declaration) \
00027     Type Declaration \
00028         { \
00029             Type ret; \
00030             WLock(); \
00031             ret = m_Container.Call; \
00032             WUnlock(); \
00033             return ret; \
00034         }
00035 #define W_WRAP_VOID(Call, Declaration) \
00036     void Declaration \
00037         { \
00038             WLock(); \
00039             m_Container.Call; \
00040             WUnlock(); \
00041         }
00042 
00043 template<class Container>
00044 class map_checker
00045 {
00046     typedef Container container_type;
00047     typedef map_checker<Container> this_type;
00048 
00049 public:
00050     typedef typename container_type::size_type size_type;
00051     typedef typename container_type::key_type key_type;
00052     typedef typename container_type::value_type value_type;
00053     typedef typename container_type::const_iterator const_iterator;
00054     typedef typename container_type::iterator iterator;
00055 
00056 protected:
00057     typedef pair<const_iterator, const_iterator> const_iterator_pair;
00058     typedef pair<iterator, iterator> iterator_pair;
00059     typedef pair<iterator, bool> iterator_bool;
00060 
00061     container_type m_Container;
00062     mutable CAtomicCounter_WithAutoInit m_WCounter;
00063     mutable CAtomicCounter_WithAutoInit m_RCounter;
00064 
00065 public:
00066 
00067     void RLock() const
00068         {
00069             if ( m_RCounter.Add(1) <= 0 || m_WCounter.Get() != 0 )
00070                 abort();
00071         }
00072     void RUnlock() const
00073         {
00074             if ( m_WCounter.Get() != 0 || m_RCounter.Add(-1) < 0 )
00075                 abort();
00076         }
00077     void WLock() const
00078         {
00079             if ( m_WCounter.Add(1) != 1 || m_RCounter.Get() != 0 )
00080                 abort();
00081         }
00082     void WUnlock() const
00083         {
00084             if ( m_RCounter.Get() != 0 || m_WCounter.Add(-1) != 0 )
00085                 abort();
00086         }
00087 
00088     iterator check(iterator pos)
00089         {
00090             if ( pos != m_Container.end() ) {
00091                 iterator it = m_Container.find(pos->first);
00092                 if ( it != pos )
00093                     abort();
00094             }
00095             return pos;
00096         }
00097 
00098     map_checker()
00099         {
00100         }
00101     ~map_checker()
00102         {
00103             WLock();
00104         }
00105     map_checker(const this_type& m)
00106         {
00107             *this = m;
00108         }
00109     this_type& operator=(const this_type& m)
00110         {
00111             WLock();
00112             m.RLock();
00113             m_Container = m.m_Container;
00114             m.RUnlock();
00115             WUnlock();
00116             return *this;
00117         }
00118     void swap(this_type& m)
00119         {
00120             WLock();
00121             m.WLock();
00122             m_Container.swap(m);
00123             m.WUnlock();
00124             WUnlock();
00125         }
00126 
00127     bool operator==(const this_type& m) const
00128         {
00129             bool ret;
00130             RLock();
00131             m.RLock();
00132             ret = m_Container == m.m_Container;
00133             m.RUnlock();
00134             RUnlock();
00135             return ret;
00136         }
00137     bool operator<(const this_type& m) const
00138         {
00139             bool ret;
00140             RLock();
00141             m.RLock();
00142             ret = m_Container < m.m_Container;
00143             m.RUnlock();
00144             RUnlock();
00145             return ret;
00146         }
00147 
00148     R_WRAP(size_type, size(), size() const);
00149     R_WRAP(bool, empty(), empty() const);
00150 
00151     R_WRAP(const_iterator, begin(), begin() const);
00152     R_WRAP(const_iterator, end(), end() const);
00153     R_WRAP(const_iterator, find(key), find(const key_type& key) const);
00154     R_WRAP(const_iterator, lower_bound(key), lower_bound(const key_type& key) const);
00155     R_WRAP(const_iterator, upper_bound(key), upper_bound(const key_type& key) const);
00156     R_WRAP(const_iterator_pair, equal_range(key), equal_range(const key_type& key) const);
00157 
00158     R_WRAP(iterator, begin(), begin());
00159     R_WRAP(iterator, end(), end());
00160     R_WRAP(iterator, find(key), find(const key_type& key));
00161     R_WRAP(iterator, lower_bound(key), lower_bound(const key_type& key));
00162     R_WRAP(iterator, upper_bound(key), upper_bound(const key_type& key));
00163     R_WRAP(iterator_pair, equal_range(key), equal_range(const key_type& key));
00164 
00165     W_WRAP(iterator_bool, insert(val), insert(const value_type& val));
00166     W_WRAP(iterator, insert(check(pos), val), insert(iterator pos, const value_type& val));
00167     W_WRAP_VOID(erase(check(pos)), erase(iterator pos));
00168     W_WRAP(size_type, erase(key), erase(const key_type& key));
00169     W_WRAP_VOID(clear(), clear());
00170 
00171     typename container_type::mapped_type& operator[](const key_type& key)
00172         {
00173             WLock();
00174             typename container_type::mapped_type& ret = m_Container[key];
00175             WUnlock();
00176             return ret;
00177         }
00178 };
00179 
00180 
00181 template<class Container>
00182 class multimap_checker
00183 {
00184     typedef Container container_type;
00185     typedef multimap_checker<Container> this_type;
00186 
00187 public:
00188     typedef typename container_type::size_type size_type;
00189     typedef typename container_type::key_type key_type;
00190     typedef typename container_type::value_type value_type;
00191     typedef typename container_type::const_iterator const_iterator;
00192     typedef typename container_type::iterator iterator;
00193 
00194 protected:
00195     typedef pair<const_iterator, const_iterator> const_iterator_pair;
00196     typedef pair<iterator, iterator> iterator_pair;
00197     typedef pair<iterator, bool> iterator_bool;
00198 
00199     container_type m_Container;
00200     mutable CAtomicCounter_WithAutoInit m_WCounter;
00201     mutable CAtomicCounter_WithAutoInit m_RCounter;
00202 
00203 public:
00204 
00205     void RLock() const
00206         {
00207             if ( m_RCounter.Add(1) <= 0 || m_WCounter.Get() != 0 )
00208                 abort();
00209         }
00210     void RUnlock() const
00211         {
00212             if ( m_WCounter.Get() != 0 || m_RCounter.Add(-1) < 0 )
00213                 abort();
00214         }
00215     void WLock() const
00216         {
00217             if ( m_WCounter.Add(1) != 1 || m_RCounter.Get() != 0 )
00218                 abort();
00219         }
00220     void WUnlock() const
00221         {
00222             if ( m_RCounter.Get() != 0 || m_WCounter.Add(-1) != 0 )
00223                 abort();
00224         }
00225 
00226     iterator check(iterator pos)
00227         {
00228             if ( pos != m_Container.end() ) {
00229                 iterator it = m_Container.find(pos->first);
00230                 while ( it != m_Container.end() && it != pos && it->first == pos->first )
00231                     ++it;
00232                 if ( it != pos )
00233                     abort();
00234             }
00235             return pos;
00236         }
00237 
00238     multimap_checker()
00239         {
00240         }
00241     ~multimap_checker()
00242         {
00243             WLock();
00244         }
00245     multimap_checker(const this_type& m)
00246         {
00247             *this = m;
00248         }
00249     this_type& operator=(const this_type& m)
00250         {
00251             WLock();
00252             m.RLock();
00253             m_Container = m.m_Container;
00254             m.RUnlock();
00255             WUnlock();
00256             return *this;
00257         }
00258     void swap(this_type& m)
00259         {
00260             WLock();
00261             m.WLock();
00262             m_Container.swap(m);
00263             m.WUnlock();
00264             WUnlock();
00265         }
00266 
00267     bool operator==(const this_type& m) const
00268         {
00269             bool ret;
00270             RLock();
00271             m.RLock();
00272             ret = m_Container == m.m_Container;
00273             m.RUnlock();
00274             RUnlock();
00275             return ret;
00276         }
00277     bool operator<(const this_type& m) const
00278         {
00279             bool ret;
00280             RLock();
00281             m.RLock();
00282             ret = m_Container < m.m_Container;
00283             m.RUnlock();
00284             RUnlock();
00285             return ret;
00286         }
00287 
00288     R_WRAP(size_type, size(), size() const);
00289     R_WRAP(bool, empty(), empty() const);
00290 
00291     R_WRAP(const_iterator, begin(), begin() const);
00292     R_WRAP(const_iterator, end(), end() const);
00293     R_WRAP(const_iterator, find(key), find(const key_type& key) const);
00294     R_WRAP(const_iterator, lower_bound(key), lower_bound(const key_type& key) const);
00295     R_WRAP(const_iterator, upper_bound(key), upper_bound(const key_type& key) const);
00296     R_WRAP(const_iterator_pair, equal_range(key), equal_range(const key_type& key) const);
00297 
00298     R_WRAP(iterator, begin(), begin());
00299     R_WRAP(iterator, end(), end());
00300     R_WRAP(iterator, find(key), find(const key_type& key));
00301     R_WRAP(iterator, lower_bound(key), lower_bound(const key_type& key));
00302     R_WRAP(iterator, upper_bound(key), upper_bound(const key_type& key));
00303     R_WRAP(iterator_pair, equal_range(key), equal_range(const key_type& key));
00304 
00305     W_WRAP(iterator, insert(val), insert(const value_type& val));
00306     W_WRAP(iterator, insert(check(pos), val), insert(iterator pos, const value_type& val));
00307     W_WRAP_VOID(erase(check(pos)), erase(iterator pos));
00308     W_WRAP(size_type, erase(key), erase(const key_type& key));
00309     W_WRAP_VOID(clear(), clear());
00310 };
00311 
00312 
00313 template<class Container>
00314 class rangemultimap_checker : public multimap_checker<Container>
00315 {
00316     typedef Container container_type;
00317 public:
00318     typedef typename container_type::key_type key_type;
00319     typedef typename container_type::range_type range_type;
00320     typedef typename container_type::iterator iterator;
00321     typedef typename container_type::const_iterator constiterator;
00322 
00323     R_WRAP(iterator, begin(), begin());
00324     R_WRAP(const_iterator, begin(), begin() const);
00325     R_WRAP(iterator, begin(range), begin(const range_type& range));
00326     R_WRAP(const_iterator, begin(range), begin(const range_type& range) const);
00327 };
00328 
00329 
00330 
00331 #undef R_WRAP
00332 #undef R_WRAP_VOID
00333 #undef W_WRAP
00334 #undef W_WRAP_VOID
00335 
00336 template<typename Key, typename T, typename Compare = less<Key> >
00337 class map : public map_checker< std::map<Key, T, Compare> >
00338 {
00339 };
00340 
00341 
00342 template<typename Key, typename T, typename Compare = less<Key> >
00343 class multimap : public multimap_checker< std::multimap<Key, T, Compare> >
00344 {
00345 };
00346 
00347 
00348 END_NCBI_SCOPE
00349 
00350 #endif//OBJMGR_MAP__HPP
00351 
00352 

Generated on Sun Dec 6 22:15:57 2009 for NCBI C++ ToolKit by  doxygen 1.4.6
Modified on Mon Dec 07 16:20:49 2009 by modify_doxy.py rev. 173732