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 /*************************************************************************************************/ |