00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef STORAGE_TMPL_H
00024 #define STORAGE_TMPL_H
00025
00026 #include <functional>
00027 #include <ostream>
00028 #include <fstream>
00029 #include <sstream>
00030 #include <list>
00031 #include <map>
00032 #include <deque>
00033 #include <iostream>
00034
00035 #include "storage/IterPair.h"
00036 #include "storage/FilterIterator.h"
00037 #include "storage/DerefIterator.h"
00038 #include "storage/AppUtil.h"
00039
00040 namespace storage
00041 {
00042
00043 template< class Value >
00044 class CheckFnc
00045 {
00046 public:
00047 CheckFnc( bool (* ChkFnc)( Value& )=NULL ) : m_check(ChkFnc) {}
00048 bool operator()(Value& d) const
00049 { return(m_check==NULL || (*m_check)(d)); }
00050 private:
00051 bool (* m_check)( Value& d );
00052 };
00053
00054 template< class Pred, class Iter >
00055 class ContainerIter : public FilterIterator< Pred, Iter >
00056 {
00057 typedef FilterIterator< Pred, Iter > _bclass;
00058 public:
00059 ContainerIter() : _bclass() {}
00060 ContainerIter( const Iter& b, const Iter& e, const Pred& p,
00061 bool atend=false ) :
00062 _bclass(b, e, p, atend ) {}
00063 ContainerIter( const IterPair<Iter>& pair, const Pred& p,
00064 bool atend=false ) :
00065 _bclass(pair, p, atend ) {}
00066 template< class It >
00067 ContainerIter( const It& i) : _bclass( i.begin(), i.end(), i.pred() )
00068 { this->m_cur=i.cur(); }
00069 };
00070
00071 template< class Pred, class Iter, class Value >
00072 class ContainerDerIter : public DerefIterator<Iter,Value>
00073 {
00074 typedef DerefIterator<Iter,Value> _bclass;
00075 public:
00076 ContainerDerIter() : _bclass() {}
00077 ContainerDerIter( const _bclass& i ) : _bclass(i) {}
00078 template< class It >
00079 ContainerDerIter( const It& i) : _bclass( i )
00080 { this->m_cur=i.cur(); }
00081 };
00082
00083 template< class Iter, class CastResult >
00084 class CastIterator : public Iter
00085 {
00086 public:
00087 typedef CastResult value_type;
00088 typedef CastResult& reference;
00089 typedef CastResult* pointer;
00090
00091 CastIterator() : Iter() {}
00092 CastIterator( const Iter& i ) : Iter( i ) {}
00093 template< class It >
00094 CastIterator( const It& i ) : Iter( i ) {}
00095 CastResult operator*() const
00096 {
00097 return( static_cast<CastResult>(Iter::operator*()) );
00098 }
00099 CastResult* operator->() const
00100 {
00101 return( static_cast<CastResult*>(Iter::operator->()) );
00102 }
00103 CastIterator& operator++()
00104 {
00105 Iter::operator++(); return(*this);
00106 }
00107 CastIterator operator++(int)
00108 {
00109 y2war( "Expensive ++ CastIterator" );
00110 CastIterator tmp(*this);
00111 Iter::operator++();
00112 return(tmp);
00113 }
00114 CastIterator& operator--()
00115 {
00116 Iter::operator--(); return(*this);
00117 }
00118 CastIterator operator--(int)
00119 {
00120 y2war( "Expensive -- CastIterator" );
00121 CastIterator tmp(*this);
00122 Iter::operator--();
00123 return(tmp);
00124 }
00125 };
00126
00127 template < class Checker, class ContIter, class Iter, class Value >
00128 class CheckerIterator : public ContIter
00129 {
00130 public:
00131 CheckerIterator() {};
00132 CheckerIterator( const Iter& b, const Iter& e,
00133 bool (* CheckFnc)( const Value& )=NULL,
00134 bool atend=false ) :
00135 ContIter( b, e, Checker( CheckFnc ), atend ) {}
00136 CheckerIterator( const IterPair<Iter>& p,
00137 bool (* CheckFnc)( const Value& )=NULL,
00138 bool atend=false ) :
00139 ContIter( p, Checker( CheckFnc ), atend ) {}
00140 template<class It>
00141 CheckerIterator( const It& i ) :
00142 ContIter( i.begin(), i.end(), Checker(i.pred()), false )
00143 { this->m_cur=i.cur(); }
00144 };
00145
00146
00147 template<class Num> string decString(Num number)
00148 {
00149 static_assert(std::is_integral<Num>::value, "not integral");
00150
00151 std::ostringstream num_str;
00152 classic(num_str);
00153 num_str << number;
00154 return num_str.str();
00155 }
00156
00157 template<class Num> string hexString(Num number)
00158 {
00159 static_assert(std::is_integral<Num>::value, "not integral");
00160
00161 std::ostringstream num_str;
00162 classic(num_str);
00163 num_str << std::hex << number;
00164 return num_str.str();
00165 }
00166
00167 template<class Value> void operator>>(const string& d, Value& v)
00168 {
00169 std::istringstream Data(d);
00170 classic(Data);
00171 Data >> v;
00172 }
00173
00174 template<class Value> std::ostream& operator<<( std::ostream& s, const std::list<Value>& l )
00175 {
00176 s << "<";
00177 for( typename std::list<Value>::const_iterator i=l.begin(); i!=l.end(); i++ )
00178 {
00179 if( i!=l.begin() )
00180 s << " ";
00181 s << *i;
00182 }
00183 s << ">";
00184 return( s );
00185 }
00186
00187 template<class Value> std::ostream& operator<<( std::ostream& s, const std::deque<Value>& l )
00188 {
00189 s << "<";
00190 for( typename std::deque<Value>::const_iterator i=l.begin(); i!=l.end(); i++ )
00191 {
00192 if( i!=l.begin() )
00193 s << " ";
00194 s << *i;
00195 }
00196 s << ">";
00197 return( s );
00198 }
00199
00200 template<class F, class S> std::ostream& operator<<( std::ostream& s, const std::pair<F,S>& p )
00201 {
00202 s << "[" << p.first << ":" << p.second << "]";
00203 return( s );
00204 }
00205
00206 template<class Key, class Value> std::ostream& operator<<( std::ostream& s, const std::map<Key,Value>& m )
00207 {
00208 s << "<";
00209 for( typename std::map<Key,Value>::const_iterator i=m.begin(); i!=m.end(); i++ )
00210 {
00211 if( i!=m.begin() )
00212 s << " ";
00213 s << i->first << ":" << i->second;
00214 }
00215 s << ">";
00216 return( s );
00217 }
00218
00219
00220 template <typename Type>
00221 void logDiff(std::ostream& log, const char* text, const Type& lhs, const Type& rhs)
00222 {
00223 static_assert(!std::is_enum<Type>::value, "is enum");
00224
00225 if (lhs != rhs)
00226 log << " " << text << ":" << lhs << "-->" << rhs;
00227 }
00228
00229 template <typename Type>
00230 void logDiffHex(std::ostream& log, const char* text, const Type& lhs, const Type& rhs)
00231 {
00232 static_assert(std::is_integral<Type>::value, "not integral");
00233
00234 if (lhs != rhs)
00235 log << " " << text << ":" << std::hex << lhs << "-->" << rhs << std::dec;
00236 }
00237
00238 template <typename Type>
00239 void logDiffEnum(std::ostream& log, const char* text, const Type& lhs, const Type& rhs)
00240 {
00241 static_assert(std::is_enum<Type>::value, "not enum");
00242
00243 if (lhs != rhs)
00244 log << " " << text << ":" << toString(lhs) << "-->" << toString(rhs);
00245 }
00246
00247 inline
00248 void logDiff(std::ostream& log, const char* text, bool lhs, bool rhs)
00249 {
00250 if (lhs != rhs)
00251 {
00252 if (rhs)
00253 log << " -->" << text;
00254 else
00255 log << " " << text << "-->";
00256 }
00257 }
00258
00259
00260 template<class Type>
00261 bool
00262 read_sysfs_property(const string& path, Type& value, bool log_error = true)
00263 {
00264 std::ifstream file(path.c_str());
00265 classic(file);
00266 file >> value;
00267 file.close();
00268
00269 if (file.fail())
00270 {
00271 if (log_error)
00272 y2err("reading " << path << " failed");
00273 return false;
00274 }
00275
00276 return true;
00277 }
00278
00279
00280 template<class Type>
00281 struct deref_less : public std::binary_function<const Type*, const Type*, bool>
00282 {
00283 bool operator()(const Type* x, const Type* y) const { return *x < *y; }
00284 };
00285
00286
00287 template<class Type>
00288 struct deref_equal_to : public std::binary_function<const Type*, const Type*, bool>
00289 {
00290 bool operator()(const Type* x, const Type* y) const { return *x == *y; }
00291 };
00292
00293
00294 template <class Type>
00295 void pointerIntoSortedList(list<Type*>& l, Type* e)
00296 {
00297 l.insert(lower_bound(l.begin(), l.end(), e, deref_less<Type>()), e);
00298 }
00299
00300
00301 template <class Type>
00302 void clearPointerList(list<Type*>& l)
00303 {
00304 for (typename list<Type*>::iterator i = l.begin(); i != l.end(); ++i)
00305 delete *i;
00306 l.clear();
00307 }
00308
00309
00310 template <typename ListType, typename Type>
00311 bool contains(const ListType& l, const Type& value)
00312 {
00313 return find(l.begin(), l.end(), value) != l.end();
00314 }
00315
00316
00317 template <typename ListType, typename Predicate>
00318 bool contains_if(const ListType& l, Predicate pred)
00319 {
00320 return find_if(l.begin(), l.end(), pred) != l.end();
00321 }
00322
00323
00324 template<typename Map, typename Key, typename Value>
00325 typename Map::iterator mapInsertOrReplace(Map& m, const Key& k, const Value& v)
00326 {
00327 typename Map::iterator pos = m.lower_bound(k);
00328 if (pos != m.end() && !typename Map::key_compare()(k, pos->first))
00329 pos->second = v;
00330 else
00331 pos = m.insert(pos, typename Map::value_type(k, v));
00332 return pos;
00333 }
00334
00335 template<typename List, typename Value>
00336 typename List::const_iterator addIfNotThere(List& l, const Value& v)
00337 {
00338 typename List::const_iterator pos = find( l.begin(), l.end(), v );
00339 if (pos == l.end() )
00340 pos = l.insert(l.end(), v);
00341 return pos;
00342 }
00343
00344
00345 template <class InputIterator1, class InputIterator2>
00346 bool equalContent(InputIterator1 first1, InputIterator1 last1,
00347 InputIterator2 first2, InputIterator2 last2)
00348 {
00349 while (first1 != last1 && first2 != last2)
00350 {
00351 if (!first1->equalContent(*first2))
00352 return false;
00353 ++first1;
00354 ++first2;
00355 }
00356 return first1 == last1 && first2 == last2;
00357 }
00358
00359
00360 template <class InputIterator1, class InputIterator2>
00361 void logVolumesDifference(std::ostream& log, InputIterator1 first1, InputIterator1 last1,
00362 InputIterator2 first2, InputIterator2 last2)
00363 {
00364 for (InputIterator1 i = first1; i != last1; ++i)
00365 {
00366 InputIterator2 j = first2;
00367 while (j != last2 && (i->device() != j->device() || i->created() != j->created()))
00368 ++j;
00369 if (j != last2)
00370 {
00371 if (!i->equalContent(*j))
00372 {
00373 i->logDifference(log, *j);
00374 log << std::endl;
00375 }
00376 }
00377 else
00378 {
00379 log << " -->" << *i << std::endl;
00380 }
00381 }
00382
00383 for (InputIterator2 i = first2; i != last2; ++i)
00384 {
00385 InputIterator1 j = first1;
00386 while (j != last1 && (i->device() != j->device() || i->created() != j->created()))
00387 ++j;
00388 if (j == last1)
00389 {
00390 log << " <--" << *i << std::endl;
00391 }
00392 }
00393 }
00394
00395
00396 template <class T, unsigned int sz>
00397 inline unsigned int lengthof (T (&)[sz]) { return sz; }
00398
00399 template <class Type>
00400 void printtype(Type type)
00401 {
00402 std::cout << __PRETTY_FUNCTION__ << std::endl;
00403 }
00404
00405 }
00406
00407 #endif