#include <zypp/base/Logger.h>
#include <zypp/base/Exception.h>
+#include <zypp/Edition.h>
+
using namespace std;
using namespace zypp;
<< (obj.bad() ? 'B' : '_');
}
+namespace zypp
+{
+
+
+
+}
+
+using namespace zypp;
+
/******************************************************************
**
** FUNCTION NAME : main
*/
int main( int argc, char * argv[] )
{
- --argc;
- ++argv;
- if ( ! argc )
- {
- cerr << "Usage: prognme <packages file>" << 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;
--- /dev/null
+#include <iostream>
+#include <ctime>
+
+#include <zypp/base/Logger.h>
+#include <zypp/base/Exception.h>
+
+#include <zypp/CapMatch.h>
+
+using namespace std;
+using namespace zypp;
+
+// work around flaw in y2logview
+template<class _Tp>
+ 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;
+}
--- /dev/null
+#include <iostream>
+#include <ctime>
+
+#include <zypp/base/Logger.h>
+#include <zypp/base/Exception.h>
+
+#include <zypp/Edition.h>
+
+using namespace std;
+using namespace zypp;
+
+// work around flaw in y2logview
+template<class _Tp>
+ 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;
+}
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/CapMatch.cc
+ *
+*/
+#include <iostream>
+//#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
+///////////////////////////////////////////////////////////////////
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/CapMatch.h
+ *
+*/
+#ifndef ZYPP_CAPMATCH_H
+#define ZYPP_CAPMATCH_H
+
+#include <iosfwd>
+
+///////////////////////////////////////////////////////////////////
+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 <tt>! && ||</tt> 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
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<<
#include "zypp/base/PtrTypes.h"
#include "zypp/Resolvable.h"
+#include "zypp/CapMatch.h"
///////////////////////////////////////////////////////////////////
namespace zypp
///////////////////////////////////////////////////////////////////
class CapFactory;
+ struct CapMatchContext {};
///////////////////////////////////////////////////////////////////
//
/** 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<Impl,Impl_Ptr> _pimpl;
+ RW_pointer<Impl,rw_pointer::Intrusive<Impl> > _pimpl;
};
///////////////////////////////////////////////////////////////////
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
///////////////////////////////////////////////////////////////////
*/
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;
///////////////////////////////////////////////////////////////////
//
+ // 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.
ByteCount.h \
Capability.h \
CapFactory.h \
+ CapMatch.h \
CapSet.h \
CountryCode.h \
Date.h \
ByteCount.cc \
Capability.cc \
CapFactory.cc \
+ CapMatch.cc \
CapSet.cc \
CountryCode.cc \
Date.cc \
///////////////////////////////////////////////////////////////////
//
+ // RW_pointer traits
+ //
+ ///////////////////////////////////////////////////////////////////
+ namespace rw_pointer {
+
+ template<class _D>
+ struct Shared
+ {
+ typedef shared_ptr<_D> _Ptr;
+ typedef shared_ptr<const _D> _constPtr;
+ /** Check whether pointer is shared. */
+ bool isShared( const _constPtr & ptr_r )
+ { return ptr_r.use_count() > 1; }
+ };
+
+ template<class _D>
+ struct Intrusive
+ {
+ typedef intrusive_ptr<_D> _Ptr;
+ typedef intrusive_ptr<const _D> _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<tt>\<_D,_Ptr></tt> stores a \ref ZYPP_SMART_PTR
- * of type \c _Ptr, which must be convertible into a <tt>_D *</tt>. Pointer
- * style access (via \c -> and \c *) offers a <tt>const _D *</tt> in const
+ * zypp::RW_pointer<tt>\<_D,_Traits></tt> stores a \ref ZYPP_SMART_PTR
+ * of type \c _Traits::_Ptr, which must be convertible into a <tt>_D *</tt>.
+ * Pointer style access (via \c -> and \c *) offers a <tt>const _D *</tt> in const
* a context, otherwise a <tt>_D *</tt>. Thus \em RW_ means \em read/write,
* as you get a different type, dependent on whether you're allowed to
* read or write.
* RW_pointer prevents const interface methods from accidentally calling
* nonconst implementation methods.
*
- * The second template argument defaults to <tt>_Ptr = shared_ptr<_D></tt>.
+ * The second template argument defaults to
+ * <tt>_Traits = rw_pointer::Shared<_D></tt> thus wraping a
+ * <tt>shared_ptr<_D></tt>. To wrap an <tt>intrusive_ptr<_D></tt>
+ * use <tt>rw_pointer::Intrusive<_D></tt>.
*
* \see zypp::RWCOW_pointer for 'copy on write' functionality.
*
* };
* \endcode
*/
- template<class _D, class _Ptr = shared_ptr<_D> >
+ template<class _D, class _Traits = rw_pointer::Shared<_D> >
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 )
void swap( _Ptr & rhs )
{ _dptr.swap( rhs ); }
+ operator unspecified_bool_type() const
+ { return _dptr; }
+
const _D & operator*() const
{ return *_dptr; };
_D * get()
{ return _dptr.get(); }
+ public:
+ _constPtr getPtr() const
+ { return _dptr; }
+
+ _Ptr getPtr()
+ { return _dptr; }
+
private:
_Ptr _dptr;
};
*
* See \ref RW_pointer.
*/
- template<class _D, class _Ptr = shared_ptr<_D> >
+ template<class _D, class _Traits = rw_pointer::Shared<_D> >
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
_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() ) );
}
};
///////////////////////////////////////////////////////////////////
- /** \relates RWCOW_pointer Check whether pointer is shared. */
- template<class _D>
- 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<class _D>
- 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 <tt>-\>clone()</tt>. Being defined as a
* function outside \ref RWCOW_pointer allows to overload
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/capability/CapTraits.cc
+ *
+*/
+
+#include "zypp/capability/CapTraits.h"
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ namespace capability
+ { /////////////////////////////////////////////////////////////////
+
+ template<>
+ const CapTraitsBase::KindType CapTraits<NullCap> ::kind( "NullCap" );
+ template<>
+ const CapTraitsBase::KindType CapTraits<FileCap> ::kind( "FileCap" );
+ template<>
+ const CapTraitsBase::KindType CapTraits<NamedCap> ::kind( "NamedCap" );
+ template<>
+ const CapTraitsBase::KindType CapTraits<VersionedCap> ::kind( "VersionedCap" );
+ template<>
+ const CapTraitsBase::KindType CapTraits<SplitCap> ::kind( "SplitCap" );
+ template<>
+ const CapTraitsBase::KindType CapTraits<OrCap> ::kind( "OrCap" );
+ template<>
+ const CapTraitsBase::KindType CapTraits<ConditionalCap>::kind( "ConditionalCap" );
+
+ /////////////////////////////////////////////////////////////////
+ } // namespace capability
+ ///////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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<CapabilityImpl> KindType;
+ };
+
+ class NullCap;
+ class FileCap;
+ class NamedCap;
+ class VersionedCap;
+ class SplitCap;
+ class OrCap;
+ class ConditionalCap;
+
+ /** CapTraits. Defines common types and the Kind value. */
+ template<typename _Cap>
+ struct CapTraits : public CapTraitsBase
+ {
+ static const KindType kind;
+ };
+
+ /////////////////////////////////////////////////////////////////
+ } // namespace capability
+ ///////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZYPP_CAPABILITY_CAPTRAITS_H
#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
// 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();
}
#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
{ /////////////////////////////////////////////////////////////////
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:
typedef CapabilityImpl_Ptr Ptr;
typedef CapabilityImpl_constPtr constPtr;
- typedef KindOf<Capability> Kind;
+ typedef CapTraitsBase::KindType Kind;
public:
/** Ctor taking the kind of Resolvable \c this refers to.*/
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. */
*
* \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<FileCap>(cap);
+ * \endcode
+ */
+ template<class _Cap>
+ 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<CapabilityImpl::constPtr, CapabilityImpl::constPtr, bool>
{
//
// 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; }
};
///////////////////////////////////////////////////////////////////
namespace capability
{ /////////////////////////////////////////////////////////////////
- const CapabilityImpl::Kind FileCap::_kind( "FileCap" );
-
const CapabilityImpl::Kind & FileCap::kind() const
- { return _kind; }
+ { return CapTraits<Self>::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
//
/** 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 )
/** */
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;
};
///////////////////////////////////////////////////////////////////
include_HEADERS = \
CapabilityImpl.h\
+ CapTraits.h \
Capabilities.h \
\
ConditionalCap.h\
lib@PACKAGE@_capability_la_SOURCES = \
CapabilityImpl.cc \
+ CapTraits.cc \
\
FileCap.cc \
NamedCap.cc \
namespace capability
{ /////////////////////////////////////////////////////////////////
- const CapabilityImpl::Kind NamedCap::_kind( "NamedCap" );
-
const CapabilityImpl::Kind & NamedCap::kind() const
- { return _kind; }
+ { return CapTraits<Self>::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<VersionedCap>( rhs ) )
+ {
+ // matchEditionRange in case VersionedCap has Rel::NONE
+ return matchValue( rhs ) && matchEditionRange( rhs );
+ }
+ }
return false;
}
+ std::string NamedCap::value() const
+ { return _name; }
+
/////////////////////////////////////////////////////////////////
} // namespace capability
///////////////////////////////////////////////////////////////////
//
// 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 )
/** */
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;
};
///////////////////////////////////////////////////////////////////
namespace capability
{ /////////////////////////////////////////////////////////////////
- const CapabilityImpl::Kind NullCap::_kind( "NullCap" );
-
CapabilityImpl_Ptr NullCap::_instance;
///////////////////////////////////////////////////////////////////
}
const CapabilityImpl::Kind & NullCap::kind() const
- { return _kind; }
+ { return CapTraits<Self>::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
///////////////////////////////////////////////////////////////////
*
* 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
{
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;
};
///////////////////////////////////////////////////////////////////
//
// 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; }
};
///////////////////////////////////////////////////////////////////
namespace capability
{ /////////////////////////////////////////////////////////////////
- const CapabilityImpl::Kind SplitCap::_kind( "SplitCap" );
-
const CapabilityImpl::Kind & SplitCap::kind() const
- { return _kind; }
+ { return CapTraits<Self>::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;
}
/////////////////////////////////////////////////////////////////
class SplitCap : public CapabilityImpl
{
public:
+ typedef SplitCap Self;
+
/** Ctor */
SplitCap( const Resolvable::Kind & refers_r,
const std::string & name_r,
/** */
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;
namespace capability
{ /////////////////////////////////////////////////////////////////
- const CapabilityImpl::Kind VersionedCap::_kind( "VersionedCap" );
-
const CapabilityImpl::Kind & VersionedCap::kind() const
- { return _kind; }
+ { return CapTraits<Self>::kind; }
std::string VersionedCap::asString() const
{
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<NamedCap>( 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
///////////////////////////////////////////////////////////////////
class VersionedCap : public CapabilityImpl
{
public:
+ typedef VersionedCap Self;
+
/** Ctor */
VersionedCap( const Resolvable::Kind & refers_r,
const std::string & name_r,
/** */
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;
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);