00001 #ifndef CORELIB___NCBI_UTILITY__HPP
00002 #define CORELIB___NCBI_UTILITY__HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <corelib/ncbistd.hpp>
00040 #include <corelib/ncbi_limits.h>
00041 #include <algorithm>
00042 #include <memory>
00043 #include <map>
00044
00045
00046
00047 BEGIN_NCBI_SCOPE
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 template <class T>
00059 struct p_equal_to : public binary_function
00060 <const T*, const T*, bool>
00061 {
00062 #if defined(NCBI_COMPILER_MIPSPRO) || defined(NCBI_COMPILER_VISUALAGE)
00063
00064 typedef const T* first_argument_type;
00065 typedef const T* second_argument_type;
00066 #endif
00067
00068
00069 bool operator() (const typename p_equal_to::first_argument_type& x,
00070 const typename p_equal_to::second_argument_type& y) const
00071 { return *x == *y; }
00072 };
00073
00074
00075 template <class T>
00076 struct PPtrLess : public binary_function<T, T, bool>
00077 {
00078 #if defined(NCBI_COMPILER_MIPSPRO) || defined(NCBI_COMPILER_VISUALAGE)
00079
00080 typedef T first_argument_type;
00081 typedef T second_argument_type;
00082 #endif
00083 bool operator() (const T& x, const T& y) const
00084 { return *x < *y; }
00085 };
00086
00087
00088 template <class Pair>
00089 struct pair_equal_to : public binary_function
00090 <Pair, typename Pair::second_type, bool>
00091 {
00092 bool operator() (const Pair& x,
00093 const typename Pair::second_type& y) const
00094 { return x.second == y; }
00095 };
00096
00097
00098 template<class X>
00099 inline X* NotNull(X* object)
00100 {
00101 if ( !object ) {
00102 NCBI_THROW(CCoreException,eNullPtr,kEmptyStr);
00103 }
00104 return object;
00105 }
00106
00107
00108 template<class Key, class Element>
00109 inline Element GetMapElement(const map<Key, Element>& m, const Key& key,
00110 const Element& def = 0)
00111 {
00112 typename map<Key, Element>::const_iterator ptr = m.find(key);
00113 if ( ptr !=m.end() )
00114 return ptr->second;
00115 return def;
00116 }
00117
00118
00119 template<class Key, class Element>
00120 inline void SetMapElement(map<Key, Element*>& m, const Key& key, Element* data)
00121 {
00122 if ( data )
00123 m[key] = data;
00124 else
00125 m.erase(key);
00126 }
00127
00128
00129 template<class Key, class Element>
00130 inline bool InsertMapElement(map<Key, Element*>& m,
00131 const Key& key, Element* data)
00132 {
00133 return m.insert(map<Key, Element*>::value_type(key, data)).second;
00134 }
00135
00136
00137 template<class Key>
00138 inline string GetMapString(const map<Key, string>& m, const Key& key)
00139 {
00140 typename map<Key, string>::const_iterator ptr = m.find(key);
00141 if ( ptr != m.end() )
00142 return ptr->second;
00143 return string();
00144 }
00145
00146
00147 template<class Key>
00148 inline void SetMapString(map<Key, string>& m,
00149 const Key& key, const string& data)
00150 {
00151 if ( !data.empty() )
00152 m[key] = data;
00153 else
00154 m.erase(key);
00155 }
00156
00157
00158
00159 template<class Cnt>
00160 inline void DeleteElements( Cnt& cnt )
00161 {
00162 for ( typename Cnt::iterator i = cnt.begin(); i != cnt.end(); ++i ) {
00163 delete *i;
00164 }
00165 cnt.clear();
00166 }
00167
00168
00169
00170 template<class Key, class Element>
00171 inline void DeleteElements(map<Key, Element*>& m)
00172 {
00173 for ( typename map<Key, Element*>::iterator i = m.begin(); i != m.end();
00174 ++i ) {
00175 delete i->second;
00176 }
00177 m.clear();
00178 }
00179
00180
00181
00182 template<class Key, class Element>
00183 inline void DeleteElements(multimap<Key, Element*>& m)
00184 {
00185 for ( typename map<Key, Element*>::iterator i = m.begin(); i != m.end();
00186 ++i ) {
00187 delete i->second;
00188 }
00189 m.clear();
00190 }
00191
00192
00193
00194 template<class Result, class Source, class ToKey>
00195 inline
00196 Result&
00197 AutoMap(auto_ptr<Result>& cache, const Source& source, const ToKey& toKey)
00198 {
00199 Result* ret = cache.get();
00200 if ( !ret ) {
00201 cache.reset(ret = new Result);
00202 for ( typename Source::const_iterator i = source.begin();
00203 i != source.end();
00204 ++i ) {
00205 ret->insert(Result::value_type(toKey.GetKey(*i), *i));
00206 }
00207 }
00208 return *ret;
00209 }
00210
00211
00212 template<class Value>
00213 struct CNameGetter
00214 {
00215 const string& GetKey(const Value* value) const
00216 {
00217 return value->GetName();
00218 }
00219 };
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 template <typename T, typename F>
00232 class CBestChoiceTracker : public unary_function<T, void>
00233 {
00234 public:
00235
00236 CBestChoiceTracker(F func) : m_Func(func), m_Value(T()), m_Score(kMax_Int)
00237 { }
00238
00239
00240 void operator() (const T& x)
00241 {
00242 int score = m_Func(x);
00243 if (score < m_Score) {
00244 m_Value = x;
00245 m_Score = score;
00246 }
00247 }
00248
00249
00250 const T& GetBestChoice() { return m_Value; }
00251
00252 private:
00253 F m_Func;
00254 T m_Value;
00255 int m_Score;
00256 };
00257
00258
00259
00260
00261 template <typename C, typename F>
00262 inline
00263 typename C::value_type
00264 FindBestChoice(const C& container, F score_func)
00265 {
00266 typedef typename C::value_type T;
00267 CBestChoiceTracker<T, F> tracker(score_func);
00268 ITERATE (typename C, it, container) {
00269 tracker(*it);
00270 }
00271 return tracker.GetBestChoice();
00272 }
00273
00274
00275 END_NCBI_SCOPE
00276
00277 #if !defined(HAVE_IS_SORTED)
00278
00279
00280
00281
00282
00283
00284
00285 BEGIN_STD_SCOPE
00286
00287 template <class Iterator>
00288 bool is_sorted(Iterator iter1, Iterator iter2)
00289 {
00290 Iterator prev = iter1;
00291 for (++iter1; iter1 != iter2; ++iter1, ++prev) {
00292 if (*iter1 < *prev) {
00293 return false;
00294 }
00295 }
00296 return true;
00297 }
00298
00299
00300 template <class Iterator, class Predicate>
00301 bool is_sorted(Iterator iter1, Iterator iter2, Predicate pred)
00302 {
00303 Iterator prev = iter1;
00304 for (++iter1; iter1 != iter2; ++iter1, ++prev) {
00305 if (pred(*iter1, *prev)) {
00306 return false;
00307 }
00308 }
00309 return true;
00310 }
00311
00312
00313 END_STD_SCOPE
00314
00315 #endif // !defined(HAVE_IS_SORTED)
00316
00317
00318
00319
00320
00321 #endif
00322
00323