From: Michael Andres Date: Mon, 9 Jan 2006 00:54:29 +0000 (+0000) Subject: - Added devel.ma/testdrafts X-Git-Tag: BASE-SuSE-SLE-10-SP2-Branch~3471 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d934f68d49f9e70090c1f891e389fceacbd0ee0c;p=platform%2Fupstream%2Flibzypp.git - Added devel.ma/testdrafts - Added class zypp::CapMatch. Tri state value returned from Capability::matches. - Added class zypp::Edition::Range. Defines ranges based on Rel and Edition. Provides method overlaps, to test whether two Edition::Ranges overlap (have at least one Edition in common). - Added 'CapMatch Capability::matches( const Capability & rhs ) const' and adjusted capability implementations accordingly. (except splits) - Added CapTraits (capability implementation) to define CapabilityImpl kinds and Ptr types. - Added traits for RW/RWCOW_pointer, defining the wrapped smart pointer type and how to detect whether it is shared (refount != 1). --- diff --git a/devel/devel.ma/Main.cc b/devel/devel.ma/Main.cc index e80e1d1..33b23fd 100644 --- a/devel/devel.ma/Main.cc +++ b/devel/devel.ma/Main.cc @@ -4,6 +4,8 @@ #include #include +#include + using namespace std; using namespace zypp; @@ -40,6 +42,15 @@ ostream & operator<<( ostream & str, const istream & obj ) { << (obj.bad() ? 'B' : '_'); } +namespace zypp +{ + + + +} + +using namespace zypp; + /****************************************************************** ** ** FUNCTION NAME : main @@ -47,17 +58,49 @@ ostream & operator<<( ostream & str, const istream & obj ) { */ int main( int argc, char * argv[] ) { - --argc; - ++argv; - if ( ! argc ) - { - cerr << "Usage: prognme " << endl; - return 1; - } - string file( argv[0] ); - INT << "===[START]==========================================" << endl; + Edition::Range any; + DBG << any << endl; + + Edition l( "1.0" ); + Edition r( "2.0" ); + +#define R(O,E) Edition::Range( Rel::O, E ) + +#define NONE(E) R(NONE,E) +#define ANY(E) R(ANY,E) +#define LT(E) R(LT,E) +#define LE(E) R(LE,E) +#define EQ(E) R(EQ,E) +#define GE(E) R(GE,E) +#define GT(E) R(GT,E) +#define NE(E) R(NE,E) + +#define OV(L,R) DBG << #L << " <> " << #R << " ==> " << Edition::Range::overlaps( L, R ) << endl + + ERR << "Omitting Rel::NE" << endl; + +#define OVALL( L ) \ + DBG << "----------------------------" << endl; \ + OV( L, NONE(r) ); \ + OV( L, ANY(r) ); \ + OV( L, LT(r) ); \ + OV( L, LE(r) ); \ + OV( L, EQ(r) ); \ + OV( L, GE(r) ); \ + OV( L, GT(r) ); \ + DBG << "----------------------------" << endl; + + OVALL( NONE(l) ); + OVALL( ANY(l) ); + OVALL( LT(l) ); + OVALL( LE(l) ); + OVALL( EQ(l) ); + OVALL( GE(l) ); + OVALL( GT(l) ); + + // same for l > r and l == r INT << "===[END]============================================" << endl; return 0; diff --git a/devel/devel.ma/testdrafts/CapMatch.cc b/devel/devel.ma/testdrafts/CapMatch.cc new file mode 100644 index 0000000..c9ffe6f --- /dev/null +++ b/devel/devel.ma/testdrafts/CapMatch.cc @@ -0,0 +1,108 @@ +#include +#include + +#include +#include + +#include + +using namespace std; +using namespace zypp; + +// work around flaw in y2logview +template + void printOnHack( const _Tp & obj ) + { + MIL << obj << endl; + }; + +/////////////////////////////////////////////////////////////////// +// Just for the stats +struct Measure +{ + time_t _begin; + Measure() + : _begin( time(NULL) ) + { + USR << "START MEASURE..." << endl; + } + ~Measure() + { + USR << "DURATION: " << (time(NULL)-_begin) << " sec." << endl; + } +}; + +/////////////////////////////////////////////////////////////////// +// Print stream status +ostream & operator<<( ostream & str, const istream & obj ) { + return str + << (obj.good() ? 'g' : '_') + << (obj.eof() ? 'e' : '_') + << (obj.fail() ? 'F' : '_') + << (obj.bad() ? 'B' : '_'); +} + +namespace zypp +{ + + + +} + +using namespace zypp; + +/****************************************************************** +** +** FUNCTION NAME : main +** FUNCTION TYPE : int +*/ +int main( int argc, char * argv[] ) +{ + INT << "===[START]==========================================" << endl; + + CapMatch u( CapMatch::irrelevant ); + CapMatch y(true); + CapMatch n(false); + +#define OUT(X) DBG << #X << " " << (X) << endl + + OUT( u ); + OUT( u == y ); + OUT( u != y ); + + OUT( u == true ); + OUT( u == false ); + OUT( true == u ); + OUT( false == u ); + + OUT( u && y ); + OUT( u && n ); + OUT( u && u ); + + OUT( y && y ); + OUT( y && n ); + OUT( y && u ); + + OUT( n && y ); + OUT( n && n ); + OUT( n && u ); + + OUT( u || y ); + OUT( u || n ); + OUT( u || u ); + + OUT( y || y ); + OUT( y || n ); + OUT( y || u ); + + OUT( n || y ); + OUT( n || n ); + OUT( n || u ); + + OUT( !u ); + OUT( !y ); + OUT( !n ); + + INT << "===[END]============================================" << endl; + return 0; +} diff --git a/devel/devel.ma/testdrafts/EditionRangeOvelap.cc b/devel/devel.ma/testdrafts/EditionRangeOvelap.cc new file mode 100644 index 0000000..33b23fd --- /dev/null +++ b/devel/devel.ma/testdrafts/EditionRangeOvelap.cc @@ -0,0 +1,107 @@ +#include +#include + +#include +#include + +#include + +using namespace std; +using namespace zypp; + +// work around flaw in y2logview +template + void printOnHack( const _Tp & obj ) + { + MIL << obj << endl; + }; + +/////////////////////////////////////////////////////////////////// +// Just for the stats +struct Measure +{ + time_t _begin; + Measure() + : _begin( time(NULL) ) + { + USR << "START MEASURE..." << endl; + } + ~Measure() + { + USR << "DURATION: " << (time(NULL)-_begin) << " sec." << endl; + } +}; + +/////////////////////////////////////////////////////////////////// +// Print stream status +ostream & operator<<( ostream & str, const istream & obj ) { + return str + << (obj.good() ? 'g' : '_') + << (obj.eof() ? 'e' : '_') + << (obj.fail() ? 'F' : '_') + << (obj.bad() ? 'B' : '_'); +} + +namespace zypp +{ + + + +} + +using namespace zypp; + +/****************************************************************** +** +** FUNCTION NAME : main +** FUNCTION TYPE : int +*/ +int main( int argc, char * argv[] ) +{ + INT << "===[START]==========================================" << endl; + + Edition::Range any; + DBG << any << endl; + + Edition l( "1.0" ); + Edition r( "2.0" ); + +#define R(O,E) Edition::Range( Rel::O, E ) + +#define NONE(E) R(NONE,E) +#define ANY(E) R(ANY,E) +#define LT(E) R(LT,E) +#define LE(E) R(LE,E) +#define EQ(E) R(EQ,E) +#define GE(E) R(GE,E) +#define GT(E) R(GT,E) +#define NE(E) R(NE,E) + +#define OV(L,R) DBG << #L << " <> " << #R << " ==> " << Edition::Range::overlaps( L, R ) << endl + + ERR << "Omitting Rel::NE" << endl; + +#define OVALL( L ) \ + DBG << "----------------------------" << endl; \ + OV( L, NONE(r) ); \ + OV( L, ANY(r) ); \ + OV( L, LT(r) ); \ + OV( L, LE(r) ); \ + OV( L, EQ(r) ); \ + OV( L, GE(r) ); \ + OV( L, GT(r) ); \ + DBG << "----------------------------" << endl; + + OVALL( NONE(l) ); + OVALL( ANY(l) ); + OVALL( LT(l) ); + OVALL( LE(l) ); + OVALL( EQ(l) ); + OVALL( GE(l) ); + OVALL( GT(l) ); + + // same for l > r and l == r + + INT << "===[END]============================================" << endl; + return 0; +} diff --git a/zypp/CapMatch.cc b/zypp/CapMatch.cc new file mode 100644 index 0000000..e3a77e5 --- /dev/null +++ b/zypp/CapMatch.cc @@ -0,0 +1,41 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/CapMatch.cc + * +*/ +#include +//#include "zypp/base/Logger.h" + +#include "zypp/CapMatch.h" + +using std::endl; + +/////////////////////////////////////////////////////////////////// +namespace zypp +{ ///////////////////////////////////////////////////////////////// + + const CapMatch CapMatch::yes( true ); + const CapMatch CapMatch::no( false ); + const CapMatch CapMatch::irrelevant; + + /****************************************************************** + ** + ** FUNCTION NAME : operator<< + ** FUNCTION TYPE : std::ostream & + */ + std::ostream & operator<<( std::ostream & str, const CapMatch & obj ) + { + if ( obj._result == CapMatch::IRRELEVANT ) + return str << "IRRELEVANT"; + return str << ( obj._result == CapMatch::MATCH ? "MATCH" : "NOMATCH" ); + } + + ///////////////////////////////////////////////////////////////// +} // namespace zypp +/////////////////////////////////////////////////////////////////// diff --git a/zypp/CapMatch.h b/zypp/CapMatch.h new file mode 100644 index 0000000..d7d4d84 --- /dev/null +++ b/zypp/CapMatch.h @@ -0,0 +1,99 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/CapMatch.h + * +*/ +#ifndef ZYPP_CAPMATCH_H +#define ZYPP_CAPMATCH_H + +#include + +/////////////////////////////////////////////////////////////////// +namespace zypp +{ ///////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // + // CLASS NAME : CapMatch + // + /** Tri state Capability match result. + * CapMatch::irrelevant denotes a result value that should be ignored. + * Therfore it behaves neutral when used in ! && || expressions. + * \code + * CapMatch any + * (CapMatch::irrelevant && any) == any // true + * (CapMatch::irrelevant || any) == any // true + * ( !CapMatch::irrelevant ) == CapMatch::irrelevant // true + * \endcode + */ + class CapMatch + { + enum Result { NOMATCH, MATCH, IRRELEVANT }; + + public: + + CapMatch( bool val_r ) + : _result( val_r ? MATCH : NOMATCH ) + {} + + static const CapMatch yes; + static const CapMatch no; + static const CapMatch irrelevant; + + friend bool operator==( const CapMatch & lhs, const CapMatch & rhs ) + { return lhs._result == rhs._result; } + + friend bool operator!=( const CapMatch & lhs, const CapMatch & rhs ) + { return lhs._result != rhs._result; } + + friend CapMatch operator!( const CapMatch & lhs ) + { + if ( lhs._result == CapMatch::IRRELEVANT ) + return lhs; + return !(lhs._result == CapMatch::MATCH); + } + + friend CapMatch operator&&( const CapMatch & lhs, const CapMatch & rhs ) + { + if ( lhs._result == CapMatch::IRRELEVANT ) + return rhs; + if ( rhs._result == CapMatch::IRRELEVANT ) + return lhs; + return (lhs._result == CapMatch::MATCH) + && (rhs._result == CapMatch::MATCH); + } + + friend CapMatch operator||( const CapMatch & lhs, const CapMatch & rhs ) + { + if ( lhs._result == CapMatch::IRRELEVANT ) + return rhs; + if ( rhs._result == CapMatch::IRRELEVANT ) + return lhs; + return (lhs._result == CapMatch::MATCH) + || (rhs._result == CapMatch::MATCH); + } + + friend std::ostream & operator<<( std::ostream & str, const CapMatch & obj ); + + private: + CapMatch() + : _result( IRRELEVANT ) + {} + + Result _result; + }; + /////////////////////////////////////////////////////////////////// + + /** \relates CapMatch Stream output */ + std::ostream & operator<<( std::ostream & str, const CapMatch & obj ); + + ///////////////////////////////////////////////////////////////// +} // namespace zypp +/////////////////////////////////////////////////////////////////// +#endif // ZYPP_CAPMATCH_H diff --git a/zypp/Capability.cc b/zypp/Capability.cc index 6c68956..687dc58 100644 --- a/zypp/Capability.cc +++ b/zypp/Capability.cc @@ -50,13 +50,21 @@ namespace zypp const Resolvable::Kind & Capability::refers() const { return _pimpl->refers(); } + bool Capability::relevant() const + { return _pimpl->relevant(); } + + CapMatch Capability::matches( const Capability & rhs ) const + { return _pimpl->matches( rhs._pimpl.getPtr() ); } + std::string Capability::asString() const { return _pimpl->asString(); } - + /** \bug How is this supposed to work? What's the name of + * an OR capability or a Conditiona or a Split? + */ std::string Capability::name() const { return "CapabilityName"; }//return _pimpl->name(); } - + /****************************************************************** ** ** FUNCTION NAME : operator<< diff --git a/zypp/Capability.h b/zypp/Capability.h index 647f70c..cc5a76d 100644 --- a/zypp/Capability.h +++ b/zypp/Capability.h @@ -18,6 +18,7 @@ #include "zypp/base/PtrTypes.h" #include "zypp/Resolvable.h" +#include "zypp/CapMatch.h" /////////////////////////////////////////////////////////////////// namespace zypp @@ -31,6 +32,7 @@ namespace zypp /////////////////////////////////////////////////////////////////// class CapFactory; + struct CapMatchContext {}; /////////////////////////////////////////////////////////////////// // @@ -100,16 +102,28 @@ namespace zypp /** Kind of Resolvable the Capability refers to. */ const Resolvable::Kind & refers() const; + /** Whether to consider this Capability. + * Evaluates the Capabilities pre-condition (if any), and + * returns whether the condition applies. If not, the Capability + * is to be ignored. + */ + bool relevant() const; + + /** Return whether the Capabilities match. + * If either Capability is not \ref relevant, CapMatch::irrelevant + * is returned. + */ + CapMatch matches( const Capability & rhs ) const; + /** More or less human readable representation as string. */ std::string asString() const; - /** More or less humal readable name of the dependency */ + /** More or less human readable name of the dependency */ std::string name() const; - private: /** Pointer to implementation */ - RW_pointer _pimpl; + RW_pointer > _pimpl; }; /////////////////////////////////////////////////////////////////// diff --git a/zypp/Edition.cc b/zypp/Edition.cc index 90741e7..e4a2ec9 100644 --- a/zypp/Edition.cc +++ b/zypp/Edition.cc @@ -335,6 +335,63 @@ namespace zypp return rpmverscmp( lhs.release(), rhs.release() ); } + /////////////////////////////////////////////////////////////////// + // + // CLASS NAME : Edition::Range + // + /////////////////////////////////////////////////////////////////// + + bool Edition::Range::overlaps( const Range & lhs, const Range & rhs ) + { + if ( lhs.op == Rel::NONE || rhs.op == Rel::NONE ) + return false; + if ( lhs.op == Rel::ANY || rhs.op == Rel::ANY ) + return true; + + int cmp = Edition::compare( lhs.edition, rhs.edition ); + + // FIX: omitting the Rel::NE case :( + + if ( cmp < 0 ) + { + // lhs < rhs: either lhs includes greater values or rhs includes lower. + return( lhs.op == Rel::GT + || lhs.op == Rel::GE + || rhs.op == Rel::LT + || rhs.op == Rel::LE ); + } + + if ( cmp > 0 ) + { + // lhs > rhs: either lhs includes lower values or rhs includes greater. + return( lhs.op == Rel::LT + || lhs.op == Rel::LE + || rhs.op == Rel::GT + || rhs.op == Rel::GE ); + } + + // lhs == rhs: either both ranges include Rel::EQ, or both head + // into the same direction. + if ( ( lhs.op == Rel::LE || lhs.op == Rel::EQ || lhs.op == Rel::GE ) + && ( rhs.op == Rel::LE || rhs.op == Rel::EQ || rhs.op == Rel::GE ) ) + return true; + if ( ( lhs.op == Rel::LT && ( rhs.op == Rel::LT || rhs.op == Rel::LE ) ) + || ( lhs.op == Rel::GT && ( rhs.op == Rel::GT || rhs.op == Rel::GE ) ) + || ( rhs.op == Rel::LT && ( lhs.op == Rel::LT || lhs.op == Rel::LE ) ) + || ( rhs.op == Rel::GT && ( lhs.op == Rel::GT || lhs.op == Rel::GE ) ) ) + return true; + // else + return false; + } + + std::ostream & operator<<( std::ostream & str, const Edition::Range & obj ) + { + str << '[' << obj.op; + if ( ! ( obj.op == Rel::ANY || obj.op == Rel::NONE ) ) + str << obj.edition; + return str << ']'; + } + ///////////////////////////////////////////////////////////////// } // namespace zypp /////////////////////////////////////////////////////////////////// diff --git a/zypp/Edition.h b/zypp/Edition.h index 4439d8a..f93562c 100644 --- a/zypp/Edition.h +++ b/zypp/Edition.h @@ -131,6 +131,9 @@ namespace zypp */ static int compare( const Edition & lhs, const Edition & rhs ); + /* A range defined by \ref Rel and \ref Edition. */ + struct Range; + /* Binary operator functor comparing Edition. */ struct Less; @@ -175,6 +178,68 @@ namespace zypp /////////////////////////////////////////////////////////////////// // + // CLASS NAME : Edition::Range + // + /** A range defined by \ref Rel and \ref Edition. + * + * Two ranges \ref overlap, if they have at least one Edition in common. + * Rnages defined by \ref Rel::NONE and \ref Rel::ANY are special, and + * their Edition is not taken into account. + * + * \ref Rel::NONE never overlaps. + * + * \ref Rel::ANY overlaps any range except \ref Rel::NONE. + * + * The other ranges overlap as you may expect it. + * + * \todo overlaps does not treat Rel::NE correct. + */ + struct Edition::Range + { + Rel op; + Edition edition; + + /** Default ctor: \ref Rel::ANY. */ + Range() + : op( Rel::ANY ) + {} + + /** Ctor taking \ref Edition (\ref Rel::EQ). */ + Range( const Edition & edition_r ) + : op( Rel::EQ ) + , edition( edition_r ) + {} + + /** Ctor taking \ref Rel and \ref Edition. */ + Range( Rel op_r, const Edition & edition_r ) + : op( op_r ) + , edition( edition_r ) + {} + + /** Return whether two Ranges overlap. */ + bool overlaps( const Range & rhs ) const + { return overlaps( *this, rhs ); } + + /** Return whether two Ranges overlap. */ + static bool overlaps( const Range & lhs, const Range & rhs ); + + friend bool operator==( const Range & lhs, const Range & rhs ) + { + return( lhs.op == rhs.op + && ( lhs.op == Rel::ANY || lhs.op == Rel::NONE + || lhs.edition == rhs.edition ) ); + } + + friend bool operator!=( const Range & lhs, const Range & rhs ) + { return ! ( lhs == rhs ); } + }; + /////////////////////////////////////////////////////////////////// + + /** \relates Edition::Range Stream output. */ + std::ostream & operator<<( std::ostream & str, const Edition::Range & obj ); + + /////////////////////////////////////////////////////////////////// + // // CLASS NAME : Edition::Less // /** Binary operator functor comparing Edition. diff --git a/zypp/Makefile.am b/zypp/Makefile.am index 422a4ce..51e8373 100644 --- a/zypp/Makefile.am +++ b/zypp/Makefile.am @@ -10,6 +10,7 @@ include_HEADERS = NeedAType.h \ ByteCount.h \ Capability.h \ CapFactory.h \ + CapMatch.h \ CapSet.h \ CountryCode.h \ Date.h \ @@ -50,6 +51,7 @@ lib@PACKAGE@_la_SOURCES = \ ByteCount.cc \ Capability.cc \ CapFactory.cc \ + CapMatch.cc \ CapSet.cc \ CountryCode.cc \ Date.cc \ diff --git a/zypp/base/PtrTypes.h b/zypp/base/PtrTypes.h index f3f015d..4d0360a 100644 --- a/zypp/base/PtrTypes.h +++ b/zypp/base/PtrTypes.h @@ -59,13 +59,42 @@ namespace zypp /////////////////////////////////////////////////////////////////// // + // RW_pointer traits + // + /////////////////////////////////////////////////////////////////// + namespace rw_pointer { + + template + struct Shared + { + typedef shared_ptr<_D> _Ptr; + typedef shared_ptr _constPtr; + /** Check whether pointer is shared. */ + bool isShared( const _constPtr & ptr_r ) + { return ptr_r.use_count() > 1; } + }; + + template + struct Intrusive + { + typedef intrusive_ptr<_D> _Ptr; + typedef intrusive_ptr _constPtr; + /** Check whether pointer is shared. */ + bool isShared( const _constPtr & ptr_r ) + { return ptr_r && (ptr_r->refCount() > 1); } + }; + } + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // // CLASS NAME : RW_pointer // /** Wrapper for \c const correct access via \ref ZYPP_SMART_PTR. * - * zypp::RW_pointer\<_D,_Ptr> stores a \ref ZYPP_SMART_PTR - * of type \c _Ptr, which must be convertible into a _D *. Pointer - * style access (via \c -> and \c *) offers a const _D * in const + * zypp::RW_pointer\<_D,_Traits> stores a \ref ZYPP_SMART_PTR + * of type \c _Traits::_Ptr, which must be convertible into a _D *. + * Pointer style access (via \c -> and \c *) offers a const _D * in const * a context, otherwise a _D *. Thus \em RW_ means \em read/write, * as you get a different type, dependent on whether you're allowed to * read or write. @@ -74,7 +103,10 @@ namespace zypp * RW_pointer prevents const interface methods from accidentally calling * nonconst implementation methods. * - * The second template argument defaults to _Ptr = shared_ptr<_D>. + * The second template argument defaults to + * _Traits = rw_pointer::Shared<_D> thus wraping a + * shared_ptr<_D>. To wrap an intrusive_ptr<_D> + * use rw_pointer::Intrusive<_D>. * * \see zypp::RWCOW_pointer for 'copy on write' functionality. * @@ -95,10 +127,12 @@ namespace zypp * }; * \endcode */ - template > + template > struct RW_pointer { - typedef _D element_type; + typedef typename _Traits::_Ptr _Ptr; + typedef typename _Traits::_constPtr _constPtr; + typedef typename _Ptr::unspecified_bool_type unspecified_bool_type; explicit RW_pointer( typename _Ptr::element_type * dptr = 0 ) @@ -122,6 +156,9 @@ namespace zypp void swap( _Ptr & rhs ) { _dptr.swap( rhs ); } + operator unspecified_bool_type() const + { return _dptr; } + const _D & operator*() const { return *_dptr; }; @@ -140,6 +177,13 @@ namespace zypp _D * get() { return _dptr.get(); } + public: + _constPtr getPtr() const + { return _dptr; } + + _Ptr getPtr() + { return _dptr; } + private: _Ptr _dptr; }; @@ -172,10 +216,11 @@ namespace zypp * * See \ref RW_pointer. */ - template > + template > struct RWCOW_pointer { - typedef _D element_type; + typedef typename _Traits::_Ptr _Ptr; + typedef typename _Traits::_constPtr _constPtr; typedef typename _Ptr::unspecified_bool_type unspecified_bool_type; explicit @@ -221,11 +266,18 @@ namespace zypp _D * get() { assertUnshared(); return _dptr.get(); } + public: + _constPtr getPtr() const + { return _dptr; } + + _Ptr getPtr() + { assertUnshared(); return _dptr; } + private: void assertUnshared() { - if ( rwcowIsShared( _dptr ) ) + if ( _Traits().isShared( _dptr ) ) { _dptr.reset( rwcowClone( _dptr.get() ) ); } @@ -236,19 +288,6 @@ namespace zypp }; /////////////////////////////////////////////////////////////////// - /** \relates RWCOW_pointer Check whether pointer is shared. */ - template - inline bool rwcowIsShared( const shared_ptr<_D> & ptr_r ) - { return ptr_r.use_count() > 1; } - - /** \relates RWCOW_pointer Check whether pointer is shared. - * \todo Quite zypp specific assumption that intrusive_ptr - * is derived from zypp::base::ReferenceCounted. - */ - template - inline bool rwcowIsShared( const intrusive_ptr<_D> & ptr_r ) - { return ptr_r && (ptr_r->refCount() > 1); } - /** \relates RWCOW_pointer Clone the underlying object. * Calls \a rhs -\>clone(). Being defined as a * function outside \ref RWCOW_pointer allows to overload diff --git a/zypp/capability/CapTraits.cc b/zypp/capability/CapTraits.cc new file mode 100644 index 0000000..024aeac --- /dev/null +++ b/zypp/capability/CapTraits.cc @@ -0,0 +1,42 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/capability/CapTraits.cc + * +*/ + +#include "zypp/capability/CapTraits.h" + +/////////////////////////////////////////////////////////////////// +namespace zypp +{ ///////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////// + namespace capability + { ///////////////////////////////////////////////////////////////// + + template<> + const CapTraitsBase::KindType CapTraits ::kind( "NullCap" ); + template<> + const CapTraitsBase::KindType CapTraits ::kind( "FileCap" ); + template<> + const CapTraitsBase::KindType CapTraits ::kind( "NamedCap" ); + template<> + const CapTraitsBase::KindType CapTraits ::kind( "VersionedCap" ); + template<> + const CapTraitsBase::KindType CapTraits ::kind( "SplitCap" ); + template<> + const CapTraitsBase::KindType CapTraits ::kind( "OrCap" ); + template<> + const CapTraitsBase::KindType CapTraits::kind( "ConditionalCap" ); + + ///////////////////////////////////////////////////////////////// + } // namespace capability + /////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////// +} // namespace zypp +/////////////////////////////////////////////////////////////////// diff --git a/zypp/capability/CapTraits.h b/zypp/capability/CapTraits.h new file mode 100644 index 0000000..e865264 --- /dev/null +++ b/zypp/capability/CapTraits.h @@ -0,0 +1,54 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/capability/CapTraits.h + * +*/ +#ifndef ZYPP_CAPABILITY_CAPTRAITS_H +#define ZYPP_CAPABILITY_CAPTRAITS_H + +#include "zypp/base/PtrTypes.h" +#include "zypp/base/KindOf.h" + +/////////////////////////////////////////////////////////////////// +namespace zypp +{ ///////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////// + namespace capability + { ///////////////////////////////////////////////////////////////// + + class CapabilityImpl; + + /** Base of CapTraits. Defines the Resolvable::Kind type. */ + struct CapTraitsBase + { + typedef KindOf KindType; + }; + + class NullCap; + class FileCap; + class NamedCap; + class VersionedCap; + class SplitCap; + class OrCap; + class ConditionalCap; + + /** CapTraits. Defines common types and the Kind value. */ + template + struct CapTraits : public CapTraitsBase + { + static const KindType kind; + }; + + ///////////////////////////////////////////////////////////////// + } // namespace capability + /////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////// +} // namespace zypp +/////////////////////////////////////////////////////////////////// +#endif // ZYPP_CAPABILITY_CAPTRAITS_H diff --git a/zypp/capability/Capabilities.h b/zypp/capability/Capabilities.h index f631b87..44a3849 100644 --- a/zypp/capability/Capabilities.h +++ b/zypp/capability/Capabilities.h @@ -14,10 +14,12 @@ #include "zypp/capability/CapabilityImpl.h" +#include "zypp/capability/NullCap.h" #include "zypp/capability/FileCap.h" #include "zypp/capability/NamedCap.h" -#include "zypp/capability/NullCap.h" -#include "zypp/capability/SplitCap.h" #include "zypp/capability/VersionedCap.h" +#include "zypp/capability/SplitCap.h" +//#include "zypp/capability/OrCap.h" +//#include "zypp/capability/ConditionalCap.h" #endif // ZYPP_CAPABILITY_CAPABILITIES_H diff --git a/zypp/capability/CapabilityImpl.cc b/zypp/capability/CapabilityImpl.cc index 80fc00a..85fe163 100644 --- a/zypp/capability/CapabilityImpl.cc +++ b/zypp/capability/CapabilityImpl.cc @@ -37,7 +37,7 @@ namespace zypp // METHOD NAME : CapabilityImpl::capImplOrderLess // METHOD TYPE : bool // - bool CapabilityImpl::capImplOrderLess( const CapabilityImpl::constPtr & rhs ) const + bool CapabilityImpl::capImplOrderLess( const constPtr & rhs ) const { return asString() < rhs->asString(); } diff --git a/zypp/capability/CapabilityImpl.h b/zypp/capability/CapabilityImpl.h index b376785..deee523 100644 --- a/zypp/capability/CapabilityImpl.h +++ b/zypp/capability/CapabilityImpl.h @@ -14,9 +14,11 @@ #include "zypp/base/ReferenceCounted.h" #include "zypp/base/NonCopyable.h" -#include "zypp/base/KindOf.h" + +#include "zypp/capability/CapTraits.h" #include "zypp/Resolvable.h" // maybe ResTraits are sufficient? +#include "zypp/CapMatch.h" /////////////////////////////////////////////////////////////////// namespace zypp @@ -26,17 +28,12 @@ namespace zypp { ///////////////////////////////////////////////////////////////// DEFINE_PTR_TYPE(CapabilityImpl) - namespace solver - { - typedef void * Context_constPtr; - } - - /////////////////////////////////////////////////////////////////// // // CLASS NAME : CapabilityImpl // - /** Abstract base for Capability implementations. */ + /** Abstract base for Capability implementations. + */ class CapabilityImpl : public base::ReferenceCounted, private base::NonCopyable { public: @@ -44,7 +41,7 @@ namespace zypp typedef CapabilityImpl_Ptr Ptr; typedef CapabilityImpl_constPtr constPtr; - typedef KindOf Kind; + typedef CapTraitsBase::KindType Kind; public: /** Ctor taking the kind of Resolvable \c this refers to.*/ @@ -58,12 +55,51 @@ namespace zypp const Resolvable::Kind & refers() const { return _refers; } + /** Relevant per default. */ + virtual bool relevant() const + { return true; } + + /** Return whether the Capabilities match. + * \note We rely on Capability passing non NULL pointers. + */ + virtual CapMatch matches( const constPtr & rhs ) const = 0; + /** More or less human readable representation as string. */ virtual std::string asString() const = 0; - /** */ - virtual bool matches( Resolvable::constPtr resolvable_r, - solver::Context_constPtr solverContext_r ) const = 0; + protected: // Match helpers + /** Implementation dependent value. */ + virtual std::string value() const + { return std::string(); } + + /** Implementation dependent value. */ + virtual Edition::Range editionRange() const + { return Edition::Range(); } + + bool sameKind( const constPtr & rhs ) const + { return kind() == rhs->kind(); } + + bool sameRefers( const constPtr & rhs ) const + { return _refers == rhs->_refers; } + + bool sameKindAndRefers( const constPtr & rhs ) const + { return sameKind( rhs ) && sameRefers( rhs ); } + + /** Match by value if \a condition_r is \c true. */ + bool matchValueIf( bool condition_r, const constPtr & rhs ) const + { return condition_r && value() == rhs->value(); } + + /** Match by value. */ + bool matchValue( const constPtr & rhs ) const + { return matchValueIf( true, rhs ); } + + /** Match by editionRange if \a condition_r is \c true. */ + bool matchEditionRangeIf( bool condition_r, const constPtr & rhs ) const + { return condition_r && editionRange().overlaps( rhs->editionRange() ); } + + /** Match by editionRange. */ + bool matchEditionRange( const constPtr & rhs ) const + { return matchEditionRangeIf( true, rhs ); } protected: /** Helper for stream output. */ @@ -82,10 +118,21 @@ namespace zypp * * \todo make it pure virt? */ - virtual bool capImplOrderLess( const CapabilityImpl::constPtr & rhs ) const; // = 0; + virtual bool capImplOrderLess( const constPtr & rhs ) const; }; /////////////////////////////////////////////////////////////////// + /** Test whether a CapabilityImpl is of a certain Kind. + * \code + * isKind(cap); + * \endcode + */ + template + inline bool isKind( const CapabilityImpl::constPtr & cap ) + { return cap && cap->kind() == CapTraits<_Cap>::kind; } + + /////////////////////////////////////////////////////////////////// + /** Ordering relation used by ::CapFactory to unify CapabilityImpl. */ struct CapImplOrder : public std::binary_function { diff --git a/zypp/capability/ConditionalCap.h b/zypp/capability/ConditionalCap.h index ca31021..845e88e 100644 --- a/zypp/capability/ConditionalCap.h +++ b/zypp/capability/ConditionalCap.h @@ -25,13 +25,12 @@ namespace zypp // // CLASS NAME : ConditionalCap // - /** */ + /** \toto Implement it. */ class ConditionalCap : public CapabilityImpl { public: - /** */ - bool matches( constResolvablePtr resolvable_r, - solver::Context_constPtr solverContext_r ) + /** Return whether the Capabilities match. */ + virtual CapMatch matches( const CapabilityImpl & rhs ) const { return false; } }; /////////////////////////////////////////////////////////////////// diff --git a/zypp/capability/FileCap.cc b/zypp/capability/FileCap.cc index 3d76dc3..6de5bae 100644 --- a/zypp/capability/FileCap.cc +++ b/zypp/capability/FileCap.cc @@ -20,19 +20,17 @@ namespace zypp namespace capability { ///////////////////////////////////////////////////////////////// - const CapabilityImpl::Kind FileCap::_kind( "FileCap" ); - const CapabilityImpl::Kind & FileCap::kind() const - { return _kind; } + { return CapTraits::kind; } + + CapMatch FileCap::matches( const constPtr & rhs ) const + { return matchValueIf( sameKindAndRefers( rhs ), rhs ); } std::string FileCap::asString() const { return _fname; } - bool FileCap::matches( Resolvable::constPtr resolvable_r, - solver::Context_constPtr solverContext_r ) const - { - return false; - } + std::string FileCap::value() const + { return _fname; } ///////////////////////////////////////////////////////////////// } // namespace capability diff --git a/zypp/capability/FileCap.h b/zypp/capability/FileCap.h index 3cd5cff..4c624a9 100644 --- a/zypp/capability/FileCap.h +++ b/zypp/capability/FileCap.h @@ -27,11 +27,13 @@ namespace zypp // /** A \c filename matching if some Resolvable provides it. * - * \todo Actually we have to look into the Resolable filelist as well. + * \todo Check whether we have to look into the Resolable filelist as well. */ class FileCap : public CapabilityImpl { public: + typedef FileCap Self; + /** Ctor */ FileCap( const Resolvable::Kind & refers_r, const std::string & fname_r ) : CapabilityImpl( refers_r ) @@ -42,17 +44,18 @@ namespace zypp /** */ virtual const Kind & kind() const; + /** Return whether the Capabilities match. */ + virtual CapMatch matches( const constPtr & rhs ) const; + /** */ virtual std::string asString() const; - /** */ - bool matches( Resolvable::constPtr resolvable_r, - solver::Context_constPtr solverContext_r ) const; + protected: + /** Implementation dependent value. */ + virtual std::string value() const; private: /** */ - static const Kind _kind; - /** */ std::string _fname; }; /////////////////////////////////////////////////////////////////// diff --git a/zypp/capability/Makefile.am b/zypp/capability/Makefile.am index 14f32cf..34d9351 100644 --- a/zypp/capability/Makefile.am +++ b/zypp/capability/Makefile.am @@ -7,6 +7,7 @@ SUBDIRS = include_HEADERS = \ CapabilityImpl.h\ + CapTraits.h \ Capabilities.h \ \ ConditionalCap.h\ @@ -23,6 +24,7 @@ noinst_LTLIBRARIES = lib@PACKAGE@_capability.la lib@PACKAGE@_capability_la_SOURCES = \ CapabilityImpl.cc \ + CapTraits.cc \ \ FileCap.cc \ NamedCap.cc \ diff --git a/zypp/capability/NamedCap.cc b/zypp/capability/NamedCap.cc index ac4af0a..a8ba6db 100644 --- a/zypp/capability/NamedCap.cc +++ b/zypp/capability/NamedCap.cc @@ -20,20 +20,32 @@ namespace zypp namespace capability { ///////////////////////////////////////////////////////////////// - const CapabilityImpl::Kind NamedCap::_kind( "NamedCap" ); - const CapabilityImpl::Kind & NamedCap::kind() const - { return _kind; } + { return CapTraits::kind; } std::string NamedCap::asString() const { return _name; } - bool NamedCap::matches( Resolvable::constPtr resolvable_r, - solver::Context_constPtr solverContext_r ) const + CapMatch NamedCap::matches( const constPtr & rhs ) const { + if ( sameRefers( rhs ) ) + { + if ( sameKind( rhs ) ) + { + return matchValue( rhs ); + } + else if ( isKind( rhs ) ) + { + // matchEditionRange in case VersionedCap has Rel::NONE + return matchValue( rhs ) && matchEditionRange( rhs ); + } + } return false; } + std::string NamedCap::value() const + { return _name; } + ///////////////////////////////////////////////////////////////// } // namespace capability /////////////////////////////////////////////////////////////////// diff --git a/zypp/capability/NamedCap.h b/zypp/capability/NamedCap.h index 0900cc1..b4c158f 100644 --- a/zypp/capability/NamedCap.h +++ b/zypp/capability/NamedCap.h @@ -25,13 +25,12 @@ namespace zypp // // CLASS NAME : NamedCap // - /** A \c name matching if some Resolvable provides it. - * - * \todo implement matches(). - */ + /** A \c name matching if some Resolvable provides it. */ class NamedCap : public CapabilityImpl { public: + typedef NamedCap Self; + /** Ctor */ NamedCap( const Resolvable::Kind & refers_r, const std::string & name_r ) : CapabilityImpl( refers_r ) @@ -41,17 +40,18 @@ namespace zypp /** */ virtual const Kind & kind() const; + /** Return whether the Capabilities match. */ + virtual CapMatch matches( const constPtr & rhs ) const; + /** */ virtual std::string asString() const; - /** */ - virtual bool matches( Resolvable::constPtr resolvable_r, - solver::Context_constPtr solverContext_r ) const; + protected: + /** Implementation dependent value. */ + virtual std::string value() const; private: /** */ - static const Kind _kind; - /** */ std::string _name; }; /////////////////////////////////////////////////////////////////// diff --git a/zypp/capability/NullCap.cc b/zypp/capability/NullCap.cc index 823b2f0..ce737a3 100644 --- a/zypp/capability/NullCap.cc +++ b/zypp/capability/NullCap.cc @@ -20,8 +20,6 @@ namespace zypp namespace capability { ///////////////////////////////////////////////////////////////// - const CapabilityImpl::Kind NullCap::_kind( "NullCap" ); - CapabilityImpl_Ptr NullCap::_instance; /////////////////////////////////////////////////////////////////// @@ -38,17 +36,14 @@ namespace zypp } const CapabilityImpl::Kind & NullCap::kind() const - { return _kind; } + { return CapTraits::kind; } + + CapMatch NullCap::matches( const constPtr & rhs ) const + { return sameKind( rhs ); } std::string NullCap::asString() const { return std::string(); } - bool NullCap::matches( Resolvable::constPtr resolvable_r, - solver::Context_constPtr solverContext_r ) const - { - return false; - } - ///////////////////////////////////////////////////////////////// } // namespace capability /////////////////////////////////////////////////////////////////// diff --git a/zypp/capability/NullCap.h b/zypp/capability/NullCap.h index ef94aad..055574b 100644 --- a/zypp/capability/NullCap.h +++ b/zypp/capability/NullCap.h @@ -29,8 +29,6 @@ namespace zypp * * It's a singleton, so you can't construct one. Call \ref instance to * get a CapabilityImpl_Ptr to the NullCap. - * - * \todo implement matches(). */ class NullCap : public CapabilityImpl { @@ -45,20 +43,21 @@ namespace zypp NullCap(); public: + typedef NullCap Self; + /** */ virtual const Kind & kind() const; - /** */ - virtual std::string asString() const; + /** Return whether the Capabilities match. + * A NullCap matches NullCap only. + */ + virtual CapMatch matches( const constPtr & rhs ) const; /** */ - virtual bool matches( Resolvable::constPtr resolvable_r, - solver::Context_constPtr solverContext_r ) const; + virtual std::string asString() const; private: - /** */ - static const Kind _kind; - /** */ + /** Singleton */ static CapabilityImpl_Ptr _instance; }; /////////////////////////////////////////////////////////////////// diff --git a/zypp/capability/OrCap.h b/zypp/capability/OrCap.h index bd968eb..bb4f009 100644 --- a/zypp/capability/OrCap.h +++ b/zypp/capability/OrCap.h @@ -25,13 +25,12 @@ namespace zypp // // CLASS NAME : OrCap // - /** */ + /** \toto Implement it. */ class OrCap : public CapabilityImpl { public: - /** */ - bool matches( constResolvablePtr resolvable_r, - solver::Context_constPtr solverContext_r ) + /** Return whether the Capabilities match. */ + virtual CapMatch matches( const CapabilityImpl & rhs ) const { return false; } }; /////////////////////////////////////////////////////////////////// diff --git a/zypp/capability/SplitCap.cc b/zypp/capability/SplitCap.cc index ffcd990..7e09227 100644 --- a/zypp/capability/SplitCap.cc +++ b/zypp/capability/SplitCap.cc @@ -20,18 +20,15 @@ namespace zypp namespace capability { ///////////////////////////////////////////////////////////////// - const CapabilityImpl::Kind SplitCap::_kind( "SplitCap" ); - const CapabilityImpl::Kind & SplitCap::kind() const - { return _kind; } + { return CapTraits::kind; } std::string SplitCap::asString() const { return _name + ":" + _path; } - bool SplitCap::matches( Resolvable::constPtr resolvable_r, - solver::Context_constPtr solverContext_r ) const + CapMatch SplitCap::matches( const constPtr & rhs ) const { - return false; + return CapMatch::irrelevant; } ///////////////////////////////////////////////////////////////// diff --git a/zypp/capability/SplitCap.h b/zypp/capability/SplitCap.h index 03a7b40..6bcc678 100644 --- a/zypp/capability/SplitCap.h +++ b/zypp/capability/SplitCap.h @@ -41,6 +41,8 @@ namespace zypp class SplitCap : public CapabilityImpl { public: + typedef SplitCap Self; + /** Ctor */ SplitCap( const Resolvable::Kind & refers_r, const std::string & name_r, @@ -53,17 +55,14 @@ namespace zypp /** */ virtual const Kind & kind() const; - /** */ - virtual std::string asString() const; + /** Return whether the Capabilities match. */ + virtual CapMatch matches( const constPtr & rhs ) const; /** */ - virtual bool matches( Resolvable::constPtr resolvable_r, - solver::Context_constPtr solverContext_r ) const; + virtual std::string asString() const; private: /** */ - static const Kind _kind; - /** */ std::string _name; /** */ std::string _path; diff --git a/zypp/capability/VersionedCap.cc b/zypp/capability/VersionedCap.cc index d52e48a..2b43ae0 100644 --- a/zypp/capability/VersionedCap.cc +++ b/zypp/capability/VersionedCap.cc @@ -20,10 +20,8 @@ namespace zypp namespace capability { ///////////////////////////////////////////////////////////////// - const CapabilityImpl::Kind VersionedCap::_kind( "VersionedCap" ); - const CapabilityImpl::Kind & VersionedCap::kind() const - { return _kind; } + { return CapTraits::kind; } std::string VersionedCap::asString() const { @@ -34,12 +32,22 @@ namespace zypp return ret += _edition.asString(); } - bool VersionedCap::matches( Resolvable::constPtr resolvable_r, - solver::Context_constPtr solverContext_r ) const + CapMatch VersionedCap::matches( const constPtr & rhs ) const { + if ( sameRefers( rhs ) + && ( sameKind( rhs ) || isKind( rhs ) ) ) + { + return matchEditionRange( rhs ); + } return false; } + std::string VersionedCap::value() const + { return _name; } + + Edition::Range VersionedCap::editionRange() const + { return Edition::Range( _op, _edition ); } + ///////////////////////////////////////////////////////////////// } // namespace capability /////////////////////////////////////////////////////////////////// diff --git a/zypp/capability/VersionedCap.h b/zypp/capability/VersionedCap.h index ca90f03..1dd1954 100644 --- a/zypp/capability/VersionedCap.h +++ b/zypp/capability/VersionedCap.h @@ -29,6 +29,8 @@ namespace zypp class VersionedCap : public CapabilityImpl { public: + typedef VersionedCap Self; + /** Ctor */ VersionedCap( const Resolvable::Kind & refers_r, const std::string & name_r, @@ -43,17 +45,21 @@ namespace zypp /** */ virtual const Kind & kind() const; + /** Return whether the Capabilities match. */ + virtual CapMatch matches( const constPtr & rhs ) const; + /** */ virtual std::string asString() const; - /** */ - bool matches( Resolvable::constPtr resolvable_r, - solver::Context_constPtr solverContext_r ) const; + protected: + /** Implementation dependent value. */ + virtual std::string value() const; + + /** Implementation dependent value. */ + virtual Edition::Range editionRange() const; private: /** */ - static const Kind _kind; - /** */ std::string _name; /** */ Rel _op; diff --git a/zypp/solver/detail/QueueItemConflict.cc b/zypp/solver/detail/QueueItemConflict.cc index ab03e58..dbec017 100644 --- a/zypp/solver/detail/QueueItemConflict.cc +++ b/zypp/solver/detail/QueueItemConflict.cc @@ -211,7 +211,7 @@ conflict_process_cb (ResItem_constPtr resItem, const Capability & cap, void *dat Capability maybe_upgrade_dep = factory.parse ( resItem->kind(), resItem->name(), Rel::ANY, - Edition::noepoch); + Edition::noedition ); info->world->foreachProvidingResItem (maybe_upgrade_dep, upgrade_candidates_cb, (void *)&upgrade_info);