stlab.adobe.com Adobe Systems Incorporated

table_index.hpp

Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2007 Adobe Systems Incorporated
00003     Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
00004     or a copy at http://stlab.adobe.com/licenses.html)
00005 */
00006 
00007 /*************************************************************************************************/
00008 
00009 #ifndef ADOBE_TABLE_INDEX_HPP
00010 #define ADOBE_TABLE_INDEX_HPP
00011 
00012 /*************************************************************************************************/
00013 
00014 #include <adobe/config.hpp>
00015 
00016 #include <functional>
00017 #include <stdexcept>
00018 #include <vector>
00019 
00020 #include <boost/operators.hpp>
00021 #include <boost/iterator/indirect_iterator.hpp>
00022 #include <boost/iterator/transform_iterator.hpp>
00023 #include <boost/next_prior.hpp>
00024 #include <boost/type_traits/remove_reference.hpp>
00025 
00026 #include <adobe/algorithm/count.hpp>
00027 #include <adobe/algorithm/equal_range.hpp>
00028 #include <adobe/algorithm/lower_bound.hpp>
00029 #include <adobe/algorithm/sort.hpp>
00030 #include <adobe/algorithm/unique.hpp>
00031 #include <adobe/algorithm/upper_bound.hpp>
00032 
00033 #include <adobe/closed_hash.hpp>
00034 #include <adobe/functional.hpp>
00035 
00036 /*************************************************************************************************/
00037 
00038 namespace adobe {
00039 
00040 /*************************************************************************************************/
00041 
00531 template <  typename T,                     // models Regular
00532             typename H = boost::hash<T>,    // models UnaryFunction key_type -> size_t
00533             typename C = std::equal_to<T>,  // models EqualityComparison(key_type, key_type)
00534             typename P = identity<T> >      // models UnaryFunction T -> key_type
00535 class hash_index
00536 {
00537  public:
00538     typedef T                                                               value_type;
00539     typedef P                                                               key_function_type;
00540 
00541     typedef typename boost::remove_reference<typename key_function_type::result_type>::type
00542                                                                             key_type;
00543 
00544     typedef H                                                               hasher;
00545     typedef C                                                               key_equal;
00546     typedef value_type*                                                     pointer;
00547     typedef const value_type*                                               const_pointer;
00548     typedef value_type&                                                     reference;
00549     typedef const value_type&                                               const_reference;
00550     typedef std::size_t                                                     size_type;
00551     typedef std::ptrdiff_t                                                  difference_type;
00552 
00553     typedef unary_compose< key_function_type, indirect<value_type> >    indirect_key_function_type;
00554 
00555     typedef closed_hash_set<pointer, indirect_key_function_type, hasher, key_equal>
00556                                                                             index_type;
00557 
00558     typedef boost::indirect_iterator<typename index_type::iterator>         iterator;
00559     typedef boost::indirect_iterator<typename index_type::const_iterator>   const_iterator;
00560     typedef std::reverse_iterator<iterator>                                 reverse_iterator;
00561     typedef std::reverse_iterator<const_iterator>                           const_reverse_iterator;
00562 
00563     /*
00564         REVISIT (sparent@adobe.com) : This is a very limited set of constructors - need to have a 
00565         general strategy for which constructors to provide.
00566     */
00567 
00568 
00569     hash_index() { }
00570 
00571     /*
00572         NOTE: The constructor is templatized so things like mem_fun are not necessary. 
00573     */
00574 
00575     template <typename F> // F is convertible to key_function_type
00576     hash_index(hasher hf, key_equal eq, F kf) :
00577         index_m(0, hf, eq, compose(key_function_type(kf), indirect<value_type>()))
00578     { }
00579 
00580     //allocator_type get_allocator() const;
00581     size_type max_size() const { return index_m.max_size(); }
00582     
00583     size_type size() const { return index_m.size(); }
00584     bool      empty() const { return index_m.empty(); }
00585     size_type capacity() const { return index_m.capacity(); }
00586 
00587     void reserve(size_type n) { index_m.reserve(); }
00588     
00589     iterator begin() { return iterator(index_m.begin()); }
00590     iterator end() { return iterator(index_m.end()); }
00591 
00592     const_iterator begin() const { return const_iterator(index_m.begin()); }
00593     const_iterator end() const { return const_iterator(index_m.end()); }
00594     
00595     reverse_iterator rbegin() { return reverse_iterator(index_m.rbegin()); }
00596     reverse_iterator rend() { return reverse_iterator(index_m.rend()); }
00597 
00598     const_reverse_iterator rbegin() const { return const_reverse_iterator(index_m.rbegin()); }
00599     const_reverse_iterator rend() const { return const_reverse_iterator(index_m.rend()); }
00600         
00601     std::pair<iterator, bool> insert(value_type& x)
00602     {
00603         std::pair<typename index_type::iterator, bool> result = index_m.insert(&x);
00604         return std::make_pair(iterator(result.first), result.second);
00605     }
00606 
00607     template <typename I>
00608     void insert(I f, I l)
00609     {
00610         index_m.insert( boost::make_transform_iterator(f, pointer_to<value_type>()),
00611                         boost::make_transform_iterator(l, pointer_to<value_type>()));
00612     }
00613     
00614     iterator insert(iterator i, value_type& x)
00615     {
00616         return iterator(index_m.insert(i, &x));
00617     }
00618     
00619     iterator erase(iterator i) { return index_m.erase(i.base()); }
00620     size_type erase(const key_type& x) { return index_m.erase(x); }
00621 
00622     void clear() { index_m.clear(); }
00623     
00624     index_type& index() { return index_m; }
00625     const index_type& index() const { return index_m; }
00626 
00627     iterator        find(const key_type& x) { return iterator(index_m.find(x)); }
00628     const_iterator  find(const key_type& x) const { return const_iterator(index_m.find(x)); }
00629     size_type       count(const key_type& x) const { return index_m.count(x); }
00630     
00631     iterator        lower_bound(const key_type& x) { return iterator(index_m.lower_bound()); }
00632     const_iterator  lower_bound(const key_type& x) const
00633     { return const_iterator(index_m.lower_bound()); }
00634     iterator        upper_bound(const key_type& x) { return iterator(index_m.upper_bound()); }
00635     const_iterator  upper_bound(const key_type& x) const
00636     { return const_iterator(index_m.upper_bound()); }
00637     
00638     std::pair<iterator, iterator> equal_range(const key_type& x)
00639     {
00640         std::pair<typename index_type::iterator, typename index_type::iterator> result = index_m.equal_range(x);
00641         return std::make_pair(iterator(result.first), iterator(result.second));
00642     }
00643     std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
00644     {
00645         std::pair<typename index_type::const_iterator, typename index_type::const_iterator> result
00646                 = index_m.equal_range(x);
00647 
00648         return std::make_pair(const_iterator(result.first), const_iterator(result.second));
00649     }
00650 
00651     key_function_type key_function() const { return index_m.key_function(); }
00652     hasher hash_function() const { return index_m.hash_function(); }
00653     key_equal key_eq() const { return index_m.key_eq(); }
00654 
00655     friend void swap(hash_index& x, hash_index& y)
00656     {
00657         swap(x.index_m, y.index_m);
00658     }
00659  private:
00660 
00661     index_type              index_m;
00662 };
00663 
00664 /*************************************************************************************************/
00665 
00666 template    <   typename Key,       // models Regular
00667                 typename T,         // models Regular
00668                 typename Transform  = mem_data_t<T, const Key>, // models UnaryFunction Key(T)
00669                 typename Compare    = std::less<Key>    // models BinaryFunction bool(Key, Key)
00670             >
00671 class table_index
00672 {
00673     
00674  public:
00675     typedef typename std::vector<T*>                index_type;
00676     typedef Transform                               transform_type;
00677     
00678     typedef Key                                     key_type;
00679     typedef T                                       value_type;
00680     typedef Compare                                 key_compare; // Revisit?
00681 //  typedef Allocator                               allocator_type;
00682     typedef T&                                      reference;
00683     typedef const T&                                const_reference;
00684     typedef typename index_type::size_type          size_type;
00685     typedef typename index_type::difference_type    difference_type;
00686     typedef T*                                      pointer;
00687     typedef const T*                                const_pointer;
00688     
00689     typedef boost::indirect_iterator<typename index_type::iterator>         iterator;
00690     typedef boost::indirect_iterator<typename index_type::const_iterator>   const_iterator;
00691     typedef std::reverse_iterator<iterator>                                 reverse_iterator;
00692     typedef std::reverse_iterator<const_iterator>                           const_reverse_iterator;
00693     
00694     template <class TransformPrimitive>
00695     explicit table_index(TransformPrimitive transform, const key_compare& compare = key_compare()) :
00696         transform_m(transform),
00697         compare_m(compare)
00698     { }
00699     explicit table_index(const transform_type&, const key_compare& = key_compare());
00700     
00701     template <typename InputIterator, typename TransformPrimitive>
00702     table_index(    InputIterator first,
00703                     InputIterator last,
00704                     TransformPrimitive transform,
00705                     const key_compare& compare = key_compare()) :
00706             transform_m(transform),
00707             compare_m(compare)
00708     {
00709         insert(begin(), first, last);
00710     }
00711 
00712     //allocator_type get_allocator() const;
00713     size_type max_size() const;
00714     
00715     size_type size() const;
00716     bool      empty() const;
00717     
00718     iterator        begin();
00719     const_iterator  begin() const;
00720     iterator        end();
00721     const_iterator  end() const;
00722     
00723     reverse_iterator        rbegin();
00724     const_reverse_iterator  rbegin() const;
00725     reverse_iterator        rend();
00726     const_reverse_iterator  rend() const;
00727     
00728     const_reference at(size_type n) const;
00729     reference       at(size_type n);
00730     
00731     reference       front();
00732     const_reference front() const;
00733     reference       back();
00734     const_reference back() const;
00735     
00736     void push_back(value_type&);
00737     void pop_back();
00738     
00739     iterator insert(iterator, value_type&);
00740     template <class InputIterator>
00741         void insert(iterator position, InputIterator first, InputIterator last);
00742         
00743     iterator erase(iterator location);
00744     iterator erase(iterator first, iterator last);
00745     void clear();
00746     
00747     index_type& index();
00748     const index_type& index() const;
00749     
00750     /*
00751         REVISIT (sparent) : If we wanted to allow sort() and unique() - and other algoriths to
00752         operate directly on the index rather than being built in, what would be required of the
00753         index interface?
00754     */
00755     
00756     void sort();
00757     
00758     // Operations on a sorted index.
00759     
00760     void unique();
00761 
00762     reference       operator[](const key_type&);
00763     const_reference operator[](const key_type&) const;
00764     
00765     iterator        find(const key_type& x);
00766     const_iterator  find(const key_type& x) const;
00767     size_type       count(const key_type& x) const;
00768     
00769     iterator        lower_bound(const key_type& x);
00770     const_iterator  lower_bound(const key_type& x) const;
00771     iterator        upper_bound(const key_type& x);
00772     const_iterator  upper_bound(const key_type& x) const;
00773     
00774     std::pair<iterator, iterator>               equal_range(const key_type& x);
00775     std::pair<const_iterator, const_iterator>   equal_range(const key_type& x) const;
00776 
00777     transform_type transform() const { return transform_m; }
00778 
00779     friend void swap(table_index& x, table_index& y)
00780     {
00781         swap(x.transform_m, y.transform_m);
00782         swap(x.compare_m, y.compare_m);
00783         swap(x.index_m, y.index_m);
00784     }
00785  private:
00786 
00787 #ifndef ADOBE_NO_DOCUMENTATION
00788     struct indirect_compare_t : std::binary_function<pointer, pointer, bool>
00789     {
00790         typedef bool result_type;
00791     
00792         indirect_compare_t(transform_type& transform, const key_compare& compare) :
00793             transform_m(transform),
00794             compare_m(compare)
00795         { }
00796 
00797         bool operator () (pointer x, pointer y) const
00798         {
00799             return compare_m(transform_m(*x), transform_m(*y));
00800         }
00801 
00802      private:
00803         transform_type                  transform_m; /* REVISIT (sparent) : want reference here? */
00804         key_compare                     compare_m;
00805     };
00806     
00807 #endif
00808  
00809     transform_type          transform_m;
00810     key_compare             compare_m;
00811     index_type              index_m;
00812 };
00813 
00814 /*************************************************************************************************/
00815 
00816 template <class Key, class T, class Compare, class Transform>
00817 table_index<Key, T, Compare, Transform>::table_index(   const transform_type&   transform, 
00818                                                         const key_compare&      compare) :
00819     transform_m(transform),
00820     compare_m(compare)
00821 { }
00822 
00823 /*************************************************************************************************/
00824 
00825 template <class Key, class T, class Compare, class Transform>
00826 inline typename table_index<Key, T, Compare, Transform>::iterator
00827         table_index<Key, T, Compare, Transform>::begin()
00828 {
00829     return iterator(index_m.begin());
00830 }
00831 
00832 /*************************************************************************************************/
00833 
00834 template <class Key, class T, class Compare, class Transform>
00835 inline typename table_index<Key, T, Compare, Transform>::const_iterator
00836         table_index<Key, T, Compare, Transform>::begin() const
00837 {
00838     return const_iterator(index_m.begin());
00839 }
00840     
00841 /*************************************************************************************************/
00842 
00843 template <class Key, class T, class Compare, class Transform>
00844 inline typename table_index<Key, T, Compare, Transform>::iterator 
00845         table_index<Key, T, Compare, Transform>::end()
00846 {
00847     return iterator(index_m.end());
00848 }
00849     
00850 /*************************************************************************************************/
00851 
00852 template <class Key, class T, class Compare, class Transform>
00853 inline typename table_index<Key, T, Compare, Transform>::const_iterator 
00854         table_index<Key, T, Compare, Transform>::end() const
00855 {
00856     return const_iterator(index_m.end());
00857 }
00858 
00859 /*************************************************************************************************/
00860 
00861 template <class Key, class T, class Compare, class Transform>
00862 inline typename table_index<Key, T, Compare, Transform>::reverse_iterator
00863         table_index<Key, T, Compare, Transform>::rbegin()
00864 {
00865     return reverse_iterator(index_m.rbegin());
00866 }
00867 
00868 /*************************************************************************************************/
00869 
00870 template <class Key, class T, class Compare, class Transform>
00871 inline typename table_index<Key, T, Compare, Transform>::const_reverse_iterator
00872         table_index<Key, T, Compare, Transform>::rbegin() const
00873 {
00874     return const_reverse_iterator(index_m.rbegin());
00875 }
00876     
00877 /*************************************************************************************************/
00878 
00879 template <class Key, class T, class Compare, class Transform>
00880 inline typename table_index<Key, T, Compare, Transform>::reverse_iterator 
00881         table_index<Key, T, Compare, Transform>::rend()
00882 {
00883     return reverse_iterator(index_m.rend());
00884 }
00885     
00886 /*************************************************************************************************/
00887 
00888 template <class Key, class T, class Compare, class Transform>
00889 inline typename table_index<Key, T, Compare, Transform>::const_reverse_iterator 
00890         table_index<Key, T, Compare, Transform>::rend() const
00891 {
00892     return reverse_iterator(index_m.rend());
00893 }
00894 
00895 /*************************************************************************************************/
00896 
00897 template <class Key, class T, class Compare, class Transform>
00898 inline typename table_index<Key, T, Compare, Transform>::size_type
00899         table_index<Key, T, Compare, Transform>::max_size() const
00900 {
00901     return index_m.max_size();
00902 }
00903 
00904 /*************************************************************************************************/
00905 
00906 template <class Key, class T, class Compare, class Transform>
00907 inline typename table_index<Key, T, Compare, Transform>::size_type
00908         table_index<Key, T, Compare, Transform>::size() const
00909 {
00910     return index_m.size();
00911 }
00912 
00913 /*************************************************************************************************/
00914 
00915 template <class Key, class T, class Compare, class Transform>
00916 inline bool table_index<Key, T, Compare, Transform>::empty() const
00917 {
00918     return index_m.empty();
00919 }
00920 
00921 /*************************************************************************************************/
00922 
00923 template <class Key, class T, class Compare, class Transform>
00924 inline void table_index<Key, T, Compare, Transform>::push_back(value_type& x)
00925 {
00926     index_m.push_back(&x);
00927 }
00928 
00929 /*************************************************************************************************/
00930 
00931 template <class Key, class T, class Compare, class Transform>
00932 inline void table_index<Key, T, Compare, Transform>::pop_back()
00933 {
00934     index_m.pop_back();
00935 }
00936 
00937 /*************************************************************************************************/
00938 
00939 template <class Key, class T, class Compare, class Transform>
00940 inline typename table_index<Key, T, Compare, Transform>::iterator
00941         table_index<Key, T, Compare, Transform>::insert(iterator position, value_type& x)
00942 {
00943     return index_m.insert(position, &x);
00944 }
00945 
00946 /*************************************************************************************************/
00947 
00948 /*
00949     REVISIT (sparent) : We should be able to greatly improve the table_index class - this function
00950     in particular could be much more efficient.
00951 */
00952 
00953 template <class Key, class T, class Compare, class Transform>
00954 template <class InputIterator>
00955 inline void table_index<Key, T, Compare, Transform>::insert(iterator position, InputIterator first, InputIterator last)
00956 {
00957     typename index_type::iterator iter = position.base();
00958     
00959     while (first != last) {
00960         iter = index_m.insert(iter, &*first);
00961         ++iter;
00962         ++first;
00963     }
00964 }
00965 
00966 /*************************************************************************************************/
00967 
00968 template <class Key, class T, class Compare, class Transform>
00969 inline typename table_index<Key, T, Compare, Transform>::iterator
00970         table_index<Key, T, Compare, Transform>::erase(iterator position)
00971 {
00972     return index_m.erase(position.base());
00973 }
00974 
00975 /*************************************************************************************************/
00976 
00977 template <class Key, class T, class Compare, class Transform>
00978 inline typename table_index<Key, T, Compare, Transform>::iterator
00979         table_index<Key, T, Compare, Transform>::erase(iterator first, iterator last)
00980 {
00981     return index_m.erase(first.base(), last.base());
00982 }
00983 
00984 /*************************************************************************************************/
00985 
00986 template <class Key, class T, class Compare, class Transform>
00987 inline void table_index<Key, T, Compare, Transform>::clear()
00988 {
00989     index_m.clear();
00990 }
00991 
00992 /*************************************************************************************************/
00993 
00994 template <class Key, class T, class Compare, class Transform>
00995 void table_index<Key, T, Compare, Transform>::sort()
00996 {
00997     adobe::sort(index_m, indirect_compare_t(transform_m, compare_m));
00998 }
00999 
01000 /*************************************************************************************************/
01001 
01002 template <class Key, class T, class Compare, class Transform>
01003 void table_index<Key, T, Compare, Transform>::unique()
01004 {
01005     typename index_type::iterator i (adobe::unique(index_m, indirect_compare_t(transform_m, compare_m)));
01006     index_m.erase(i, index_m.end());
01007 }
01008 
01009 /*************************************************************************************************/
01010 
01011 template <class Key, class T, class Compare, class Transform>
01012 inline typename table_index<Key, T, Compare, Transform>::reference
01013         table_index<Key, T, Compare, Transform>::at(const size_type n)
01014 {
01015     return *index_m.at(n);
01016 }
01017 
01018 /*************************************************************************************************/
01019 
01020 template <class Key, class T, class Compare, class Transform>
01021 inline typename table_index<Key, T, Compare, Transform>::const_reference
01022         table_index<Key, T, Compare, Transform>::at(const size_type n) const
01023 {
01024     return *index_m.at(n);
01025 }
01026 
01027 /*************************************************************************************************/
01028 
01029 template <class Key, class T, class Compare, class Transform>
01030 inline typename table_index<Key, T, Compare, Transform>::reference
01031         table_index<Key, T, Compare, Transform>::operator [] (const key_type& key)
01032 {
01033     iterator iter (find(key));
01034     
01035     if (iter == end())
01036         throw std::range_error("Key not present in table.");
01037     
01038     return *iter;
01039 }
01040 
01041 /*************************************************************************************************/
01042 
01043 template <class Key, class T, class Compare, class Transform>
01044 inline typename table_index<Key, T, Compare, Transform>::const_reference
01045         table_index<Key, T, Compare, Transform>::operator [] (const key_type& key) const
01046 {
01047     const_iterator iter(find(key));
01048     
01049     if (iter == end())
01050         throw std::range_error("Key not present in table.");
01051     
01052     return *iter;
01053 }
01054 
01055 /*************************************************************************************************/
01056 
01057 template <class Key, class T, class Compare, class Transform>
01058 inline typename table_index<Key, T, Compare, Transform>::iterator
01059         table_index<Key, T, Compare, Transform>::find(const key_type& key)
01060 {
01061     typename index_type::iterator iter = lower_bound(key).base();
01062     
01063     if (iter != index_m.end() && transform_m(**iter) != key)
01064         iter = index_m.end();
01065 
01066     return iter;
01067 }
01068 
01069 /*************************************************************************************************/
01070 
01071 template <class Key, class T, class Compare, class Transform>
01072 inline typename table_index<Key, T, Compare, Transform>::const_iterator
01073         table_index<Key, T, Compare, Transform>::find(const key_type& key) const
01074 {
01075     typename index_type::const_iterator iter = lower_bound(key).base();
01076     
01077     if (iter != index_m.end() && transform_m(**iter) != key)
01078         iter = index_m.end();
01079 
01080     return iter;
01081 }
01082 
01083 /*************************************************************************************************/
01084 
01085 template <class Key, class T, class Compare, class Transform>
01086 inline typename table_index<Key, T, Compare, Transform>::size_type
01087         table_index<Key, T, Compare, Transform>::count(const key_type& key) const
01088 {
01089     return adobe::count_if(index_m, bound_predicate_t(key, transform_m, compare_m));
01090 }
01091 
01092 /*************************************************************************************************/
01093 
01094 template <class Key, class T, class Compare, class Transform>
01095 inline typename table_index<Key, T, Compare, Transform>::iterator
01096         table_index<Key, T, Compare, Transform>::lower_bound(const key_type& key)
01097 {
01098     return adobe::lower_bound(index_m, key, compare_m,
01099         boost::bind(transform_m, bind(indirect<value_type>(), _1)));
01100 }
01101 
01102 /*************************************************************************************************/
01103 
01104 template <class Key, class T, class Compare, class Transform>
01105 inline typename table_index<Key, T, Compare, Transform>::const_iterator
01106         table_index<Key, T, Compare, Transform>::lower_bound(const key_type& key) const
01107 {
01108     return adobe::lower_bound(index_m, key, compare_m,
01109         boost::bind(transform_m, bind(indirect<value_type>(), _1)));
01110 }
01111 
01112 /*************************************************************************************************/
01113 
01114 template <class Key, class T, class Compare, class Transform>
01115 inline typename table_index<Key, T, Compare, Transform>::iterator
01116         table_index<Key, T, Compare, Transform>::upper_bound(const key_type& key)
01117 {
01118     return adobe::upper_bound(index_m, key, compare_m,
01119         boost::bind(transform_m, bind(indirect<value_type>(), _1)));
01120 }
01121 
01122 /*************************************************************************************************/
01123 
01124 template <class Key, class T, class Compare, class Transform>
01125 inline typename table_index<Key, T, Compare, Transform>::const_iterator
01126         table_index<Key, T, Compare, Transform>::upper_bound(const key_type& key) const
01127 {
01128     return adobe::upper_bound(index_m, key, compare_m,
01129         boost::bind(transform_m, bind(indirect<value_type>(), _1)));
01130 }
01131 
01132 /*************************************************************************************************/
01133 
01134 template <class Key, class T, class Compare, class Transform>
01135 inline std::pair<   typename table_index<Key, T, Compare, Transform>::iterator,
01136                     typename table_index<Key, T, Compare, Transform>::iterator>
01137         table_index<Key, T, Compare, Transform>::equal_range(const key_type& key)
01138 {
01139     return adobe::equal_range(index_m, key, compare_m,
01140         boost::bind(transform_m, bind(indirect<value_type>(), _1)));
01141 }
01142 
01143 /*************************************************************************************************/
01144 
01145 template <class Key, class T, class Compare, class Transform>
01146 inline std::pair<   typename table_index<Key, T, Compare, Transform>::const_iterator,
01147                     typename table_index<Key, T, Compare, Transform>::const_iterator>
01148         table_index<Key, T, Compare, Transform>::equal_range(const key_type& key) const
01149 {
01150     return adobe::equal_range(index_m, key, compare_m,
01151         boost::bind(transform_m, bind(indirect<value_type>(), _1)));
01152 }
01153 
01154 /*************************************************************************************************/
01155 
01156 template <class Key, class T, class Compare, class Transform>
01157 inline typename table_index<Key, T, Compare, Transform>::index_type&
01158         table_index<Key, T, Compare, Transform>::index()
01159 {
01160     return index_m;
01161 }
01162 
01163 /*************************************************************************************************/
01164 
01165 template <class Key, class T, class Compare, class Transform>
01166 inline const typename table_index<Key, T, Compare, Transform>::index_type&
01167         table_index<Key, T, Compare, Transform>::index() const
01168 {
01169     return index_m;
01170 }
01171 
01172 /*************************************************************************************************/
01173 
01174 } // namespace adobe
01175     
01176 /*************************************************************************************************/
01177 
01178 #endif
01179 
01180 /*************************************************************************************************/

Copyright © 2006-2007 Adobe Systems Incorporated.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy.

Search powered by Google