stlab.adobe.com Adobe Systems Incorporated

rset.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_RSET_HPP
00010 #define ADOBE_RSET_HPP
00011 
00012 /*************************************************************************************************/
00013 
00014 #include <adobe/config.hpp>
00015 
00016 #include <functional>
00017 #include <stdexcept>
00018 #include <utility>
00019 #include <vector>
00020 
00021 #include <boost/type_traits.hpp>
00022 #include <boost/utility/enable_if.hpp>
00023 
00024 /*************************************************************************************************/
00025 
00026 namespace adobe {
00027 
00028 /*************************************************************************************************/
00029 
00047 template <typename Type1,
00048           typename Type2,
00049           typename Type1Equality = std::equal_to<Type1>,
00050           typename Type2Equality = std::equal_to<Type2> >
00051 class rset
00052 {
00053 public:
00054     typedef Type1                              first_type;
00055     typedef Type2                              second_type;
00056     typedef Type1Equality                      first_compare_type;
00057     typedef Type2Equality                      second_compare_type;
00058     typedef std::pair<first_type, second_type> value_type;
00059     typedef std::vector<value_type>            set_type;
00060     typedef typename set_type::iterator        iterator;
00061     typedef typename set_type::const_iterator  const_iterator;
00062     typedef typename set_type::reference       reference;
00063     typedef typename set_type::const_reference const_reference;
00064 
00065     rset() :
00066         pred1_m(Type1Equality()),
00067         pred2_m(Type2Equality())
00068     { }
00069 
00070     rset(const rset& rhs) :
00071         set_m(rhs.set_m),
00072         pred1_m(rhs.pred1_m),
00073         pred2_m(rhs.pred2_m)
00074     { }
00075 
00076     rset& operator= (const rset& rhs)
00077     {
00078         set_m = rhs.set_m;
00079         pred1_m = rhs.pred1_m;
00080         pred2_m = rhs.pred2_m;
00081 
00082         return *this;
00083     }
00084 
00085     inline first_compare_type  first_compare() const  { return pred1_m; }
00086     inline second_compare_type second_compare() const { return pred2_m; }
00087 
00088     inline bool        empty() const { return set_m.empty(); }
00089     inline std::size_t size() const  { return set_m.size(); }
00090 
00091     inline void push_back(const value_type& value)
00092     { set_m.push_back(value); }
00093 
00094     inline void push_back(const first_type& first, const second_type& second)
00095     { push_back(value_type(first, second)); }
00096 
00097     inline iterator begin() { return set_m.begin(); }
00098     inline iterator end()   { return set_m.end(); }
00099 
00100     inline const_iterator begin() const { return set_m.begin(); }
00101     inline const_iterator end() const   { return set_m.end(); }
00102 
00103     inline reference at(std::size_t n)             { assert(n < size()); return set_m[n]; }
00104     inline const_reference at(std::size_t n) const { assert(n < size()); return set_m[n]; }
00105 
00106     first_type& find1(const second_type& key)
00107     {
00108         for (iterator iter(begin()), last(end()); iter != last; ++iter)
00109             if (pred2_m(key, iter->second))
00110                 return iter->first;
00111 
00112         throw std::runtime_error("find2 key not found in set");
00113     }
00114 
00115     inline const first_type& find1(const second_type& key) const
00116     { return const_cast<rset*>(this)->find1(key); }
00117 
00118     second_type& find2(const first_type& key)
00119     {
00120         for (iterator iter(begin()), last(end()); iter != last; ++iter)
00121             if (pred1_m(key, iter->first))
00122                 return iter->second;
00123 
00124         throw std::runtime_error("find1 key not found in set");
00125     }
00126 
00127     inline const second_type& find2(const first_type& key) const
00128     { return const_cast<rset*>(this)->find2(key); }
00129 
00130     inline typename boost::disable_if<boost::is_same<first_type, second_type>, second_type>::type&
00131     operator[] (const first_type& key)
00132     { return find2(key); }
00133 
00134     inline const typename boost::disable_if<boost::is_same<first_type, second_type>, second_type>::type&
00135     operator[] (const first_type& key) const
00136     { return find2(key); }
00137 
00138     inline typename boost::disable_if<boost::is_same<first_type, second_type>, first_type>::type&
00139     operator[] (const second_type& key)
00140     { return find1(key); }
00141 
00142     inline const typename boost::disable_if<boost::is_same<first_type, second_type>, first_type>::type&
00143     operator[] (const second_type& key) const
00144     { return find1(key); }
00145 
00146 private:
00147     set_type            set_m;
00148     first_compare_type  pred1_m;
00149     second_compare_type pred2_m;
00150 };
00151 
00152 /*************************************************************************************************/
00153 
00154 template <typename Type1, typename Type2,
00155           typename Type1Equality, typename Type2Equality>
00156 bool operator== (const rset<Type1, Type2, Type1Equality, Type2Equality>& x,
00157                  const rset<Type1, Type2, Type1Equality, Type2Equality>& y)
00158 {
00159     typedef rset<Type1, Type2, Type1Equality, Type2Equality> set_type;
00160     typedef typename set_type::const_iterator                iterator;
00161     typedef typename set_type::first_compare_type            first_compare_type;
00162     typedef typename set_type::second_compare_type           second_compare_type;
00163 
00164     if (x.size() != y.size())
00165         return false;
00166 
00167     iterator            x_iter(x.begin());
00168     iterator            x_last(x.end());
00169     iterator            y_iter(y.begin());
00170     first_compare_type  pred1(x.first_compare());
00171     second_compare_type pred2(x.second_compare());
00172 
00173     for (; x_iter != x_last; ++x_iter, ++y_iter)
00174         if (!pred1(x_iter->first, y_iter->first) ||
00175             !pred2(x_iter->second, y_iter->second))
00176             return false;
00177 
00178     return true;
00179 }
00180 
00181 template <typename Type1, typename Type2,
00182           typename Type1Equality, typename Type2Equality>
00183 inline bool operator!= (const rset<Type1, Type2, Type1Equality, Type2Equality>& x,
00184                         const rset<Type1, Type2, Type1Equality, Type2Equality>& y)
00185 { return !(x == y); }
00186 
00187 /*************************************************************************************************/
00188 
00189 template <typename Type1, typename Type2,
00190           typename Type1Equality, typename Type2Equality>
00191 bool operator< (const rset<Type1, Type2, Type1Equality, Type2Equality>& x,
00192                 const rset<Type1, Type2, Type1Equality, Type2Equality>& y)
00193 {
00194     typedef typename rset<Type1, Type2, Type1Equality, Type2Equality>::reference reference;
00195 
00196     const std::size_t x_size(x.size());
00197     const std::size_t y_size(y.size());
00198 
00199     for (std::size_t i(0); ; ++i)
00200     {
00201         if (i >= y_size)
00202             return false;
00203 
00204         if (i >= x_size)
00205             return true;
00206 
00207         reference x_ref(x.at(i));
00208         reference y_ref(y.at(i));
00209 
00210         if (y_ref.first < x_ref.first ||
00211                 (y_ref.first == x_ref.first && y_ref.second < x_ref.second))
00212             return false;
00213 
00214         if (x_ref.first < y_ref.first ||
00215                 (x_ref.first == y_ref.first && x_ref.second < y_ref.second))
00216             return true;
00217     }
00218 }
00219 
00220 template <typename Type1, typename Type2,
00221           typename Type1Equality, typename Type2Equality>
00222 inline bool operator> (const rset<Type1, Type2, Type1Equality, Type2Equality>& x,
00223                        const rset<Type1, Type2, Type1Equality, Type2Equality>& y)
00224 { return y < x; }
00225 
00226 template <typename Type1, typename Type2,
00227           typename Type1Equality, typename Type2Equality>
00228 inline bool operator<= (const rset<Type1, Type2, Type1Equality, Type2Equality>& x,
00229                         const rset<Type1, Type2, Type1Equality, Type2Equality>& y)
00230 { return !(y < x); }
00231 
00232 template <typename Type1, typename Type2,
00233           typename Type1Equality, typename Type2Equality>
00234 inline bool operator>= (const rset<Type1, Type2, Type1Equality, Type2Equality>& x,
00235                         const rset<Type1, Type2, Type1Equality, Type2Equality>& y)
00236 { return !(x < y); } 
00237 
00238 /*************************************************************************************************/
00239 
00240 } // namespace adobe
00241 
00242 /*************************************************************************************************/
00243 
00244 // ADOBE_RSET_HPP
00245 #endif
00246 
00247 /*************************************************************************************************/

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