yast2-storage

StorageTmpl.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) [2004-2009] Novell, Inc.
00003  *
00004  * All Rights Reserved.
00005  *
00006  * This program is free software; you can redistribute it and/or modify it
00007  * under the terms of version 2 of the GNU General Public License as published
00008  * by the Free Software Foundation.
00009  *
00010  * This program is distributed in the hope that it will be useful, but WITHOUT
00011  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
00013  * more details.
00014  *
00015  * You should have received a copy of the GNU General Public License along
00016  * with this program; if not, contact Novell, Inc.
00017  *
00018  * To contact Novell about this file by physical or electronic mail, you may
00019  * find current contact information at www.novell.com.
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