functionality.
- Fixed Dependencies to perform COW.
- Added Debug.h: Debuging tools which should not be used in released code.
- Added debug::TraceCAD. Debug aid to trace object creation, assign and
destruction.
-#include <iostream>
-#include <ctime>
-
-#include <fstream>
-#include <list>
-#include <string>
-#include <zypp/base/Logger.h>
-#include <zypp/base/String.h>
-#include <zypp/base/PtrTypes.h>
-
-#include <zypp/CapFactory.h>
-#include <zypp/CapSet.h>
-
-using namespace std;
-using namespace zypp;
-
-// work around flaw in y2logview
-template<class _Tp>
- void printOnHack( const _Tp & obj )
- {
- MIL << obj << endl;
- };
+#include <iosfwd>
+#include "zypp/base/PtrTypes.h"
///////////////////////////////////////////////////////////////////
-// Just for the stats
-struct Measure
+// MyClass.h
+///////////////////////////////////////////////////////////////////
+namespace zypp
{
- time_t _begin;
- Measure()
- : _begin( time(NULL) )
- {
- USR << "START MEASURE..." << endl;
- }
- ~Measure()
+ ///////////////////////////////////////////////////////////////////
+ class MyClass
+ ///////////////////////////////////////////////////////////////////
{
- 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' : '_');
-}
+ public:
+ /** Implementation */
+ struct Impl;
-///////////////////////////////////////////////////////////////////
-// Return one line from stream
-std::string getline( std::istream & str )
-{
- static const unsigned tmpBuffLen = 1024;
- static char tmpBuff[tmpBuffLen];
- string ret;
- do {
- str.clear();
- str.getline( tmpBuff, tmpBuffLen ); // always writes '\0' terminated
- ret += tmpBuff;
- } while( str.rdstate() == ios::failbit );
+ public:
+ MyClass( int val = 0 );
- return ret;
-}
+ int get() const;
-///////////////////////////////////////////////////////////////////
-// Simple lineparser: Call function do_r for each line.
-template<class _Function>
- _Function & forEachLine( std::istream & str_r, _Function & do_r )
- {
- while ( str_r )
- {
- std::string l = getline( str_r );
- if ( ! (str_r.fail() || str_r.bad()) )
- {
- // l contains valid data to be consumed.
- do_r( l );
- }
- }
- return do_r;
- }
+ void set( int val );
-///////////////////////////////////////////////////////////////////
-// Fits forEachLine. A simple 'do' function
-void collect( const std::string & linre_r )
-{
- DBG << linre_r << endl;
+ private:
+ /** Pointer to implementation */
+ RWCOW_pointer<Impl> _pimpl;
+ };
+ ///////////////////////////////////////////////////////////////////
}
///////////////////////////////////////////////////////////////////
-// Fits forEachLine. A simple 'do' functor counting lines as base.
-/*
- Line processing is prepared by providing 'virtual void doConsume(std::string)'.
- That's what a derived Collector will overload.
- */
-struct Collector : public std::unary_function<const std::string &, void>
-{
- unsigned _lineNo;
- Collector()
- : _lineNo( 0 )
- {}
- virtual ~Collector()
- {}
- virtual void doConsume( const std::string & line_r )
- {}
- void operator()( const std::string & line_r )
- {
- ++_lineNo;
- if ( ! (_lineNo % 10000) )
- DBG << "Got " << _lineNo << " lines..." << endl;
- doConsume( line_r );
- }
-};
+
+
+
///////////////////////////////////////////////////////////////////
-// Fits forEachLine. An impatient collector ;)
-struct ImpatientCollector : public Collector
-{
- virtual void doConsume( const std::string & line_r )
- {
- if ( _lineNo == 1234 )
- ZYPP_THROW( "takes to long" );
- }
-};
+// MyClass.cc
///////////////////////////////////////////////////////////////////
-// Fits forEachLine. Almost usefull collector.
-/*
- Note that it's still a functor 'void operator()( const std::string & )'.
+#include <zypp/base/Debug.h>
- On every invocation the string is parsed into a Capability, and the
- Capability is stored in a CapSet.
+using std::endl;
- Exceptions building the Capability are caught and collected in a
- Failure list. It's a matter of taste whether to immediately abort,
- or to parse to the end check for collected errors then. Room for
- improvement.
-
- see enhacedCollectorUsage().
-*/
-struct EnhacedCollector : public Collector
+namespace zypp
{
- // Stores line number, original string and Exception
- struct Failure
+ ///////////////////////////////////////////////////////////////////
+ struct MyClass::Impl : public debug::TraceCAD<Impl>
+ ///////////////////////////////////////////////////////////////////
{
- unsigned _lineNo;
- std::string _line;
- Exception _excpt;
- Failure( unsigned lineNo_r,
- const std::string & line_r, const Exception & excpt_r )
- : _lineNo( lineNo_r ), _line( line_r ), _excpt( excpt_r )
+ Impl( int val = 0 )
+ : _value( val )
{}
- };
- typedef std::list<Failure> FailedList;
+ int _value;
- CapFactory _factory;
- unsigned _capLines;
- CapSet _caps;
- FailedList _failures;
+ private:
+ friend Impl * rwcowClone<Impl>( const Impl * rhs );
+ /** clone for RWCOW_pointer */
+ Impl * clone() const
+ { return new Impl( *this ); }
+ };
+ ///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ // class MyClass
+ ///////////////////////////////////////////////////////////////////
- EnhacedCollector()
- : _capLines( 0 )
+ MyClass::MyClass( int val )
+ : _pimpl( new Impl( val ) )
{}
- void makeCap( const string & line_r )
- {
- ++_capLines; // count attempts
- try
- {
- // bulid Package deps.
- _caps.insert( _factory.parse( ResTraits<Package>::kind, line_r ) );
- }
- catch( Exception & excpt_r )
- {
- _failures.push_back( Failure(_lineNo, line_r, excpt_r) );
- }
- }
+ int MyClass::get() const
+ { return _pimpl->_value; }
- virtual void doConsume( const std::string & line_r )
- {
- makeCap( line_r );
- }
-};
+ void MyClass::set( int val )
+ { _pimpl->_value = val; }
-// Print a Failure
-ostream & operator<<( ostream & str, const EnhacedCollector::Failure & obj )
-{
- return str << str::form( "[%u] \"%s\" ==> %s",
- obj._lineNo,
- obj._line.c_str(),
- obj._excpt.asString().c_str() );
-}
-
-// Print EnhacedCollector stats
-ostream & operator<<( ostream & str, const EnhacedCollector & obj )
-{
- str << "Lines parsed : " << obj._lineNo << endl;
- str << "Cap lines : " << obj._capLines << endl;
- str << "Capabilites : " << obj._caps.size() << endl;
- str << "Parse errors : " << obj._failures.size() << endl;
- if ( obj._failures.size() )
- {
- copy( obj._failures.begin(), obj._failures.end(),
- ostream_iterator<EnhacedCollector::Failure>(ERR,"\n") );
- //-something-we-should-not-do-unless-....---------^^^
- }
- return str;
}
-
///////////////////////////////////////////////////////////////////
-// Fits forEachLine.
-/*
- Within a packages file, not every line defines a Capability. So
- EnhacedCollector is refined to turn Capability collection on and
- off, as appropriate. A dumb version simply storing all Capabilities
- defined somewhere in the packages file.
-*/
-struct PackageParseCollector : public EnhacedCollector
-{
- static std::string _rxStrDeps;
- static str::regex _rxDepOn;
- static str::regex _rxDepOff;
-
- str::smatch _what;
- bool _consume;
-
- PackageParseCollector()
- : _consume( false )
- {}
-
- bool matches( const string & line_r, const str::regex & rx_r )
- {
- return str::regex_match( line_r.begin(), line_r.end(), rx_r );
- }
-
- virtual void doConsume( const std::string & line_r )
- {
- if ( _consume )
- {
- if ( matches( line_r, _rxDepOff ) )
- {
- _consume = false;
- }
- else
- {
- EnhacedCollector::doConsume( line_r );
- }
- }
- else if ( matches( line_r, _rxDepOn ) )
- {
- _consume = true;
- }
- }
-};
-
-std::string PackageParseCollector::_rxStrDeps( "(Req|Prq|Prv|Con|Obs)" );
-str::regex PackageParseCollector::_rxDepOn ( str::form( "\\+%s:", _rxStrDeps.c_str() ) );
-str::regex PackageParseCollector::_rxDepOff( str::form( "-%s:", _rxStrDeps.c_str() ) );
/******************************************************************
**
-** FUNCTION NAME : enhacedCollectorUsage
-** FUNCTION TYPE :
-*/
-void enhacedCollectorUsage()
-{
- // EnhacedCollector: Simply collect strings which are expected to
- // be Capabilities. Error handling is delayed by collecting failures.
- EnhacedCollector collector;
- collector( "" );
- collector( "foo baa kaa" );
- collector( "/bin/sh" );
- collector( "/bin/sh" );
- collector( "/bin/sh" );
- collector( "/bin/sh" );
-
- MIL << collector << endl;
- MIL << "Capabilities found:" << endl;
- for_each( collector._caps.begin(), collector._caps.end(),
- printOnHack<Capability> );
-}
-
-/******************************************************************
**
** FUNCTION NAME : main
** FUNCTION TYPE : int
+**
+** DESCRIPTION :
*/
int main( int argc, char * argv[] )
{
- string file( "packages" );
-
INT << "===[START]==========================================" << endl;
+ using zypp::MyClass;
+
+ MyClass c;
+ MyClass d( c );
+ MyClass e( d );
- // dump PackageParseCollector: open the file, and build Capabilities
- // from each appropriate line. Collecting failures.
+ MIL << "c.get" << c.get() << endl;
+ MIL << "d.get" << d.get() << endl;
+ MIL << "e.get" << e.get() << endl;
- ifstream str( file.c_str() );
- (str?DBG:ERR) << file << ": " << str << endl;
- shared_ptr<Measure> duration( new Measure );
+ DBG << "will d.set( 4 )..." << endl;
+ d.set( 4 );
+ DBG << "done d.set( 4 )" << endl;
- PackageParseCollector datacollect;
- try
- {
- forEachLine( str, datacollect );
- }
- catch ( Exception & excpt_r )
- {
- // Note: Exceptions building a Capability are caught. So this is
- // something different. Maybe a bored ImpatientCollector.
- ZYPP_CAUGHT( excpt_r );
- ERR << "Parse error at line " << datacollect._lineNo << ": " << excpt_r << endl;
- return 1;
- }
+ MIL << "c.get" << c.get() << endl;
+ MIL << "d.get" << d.get() << endl;
+ MIL << "e.get" << e.get() << endl;
- duration.reset();
- DBG << file << ": " << str << endl;
+ DBG << "will d.set( 5 )..." << endl;
+ d.set( 5 );
+ DBG << "done d.set( 5 )" << endl;
- MIL << datacollect << endl;
- MIL << CapFactory() << endl;
+ MIL << "c.get" << c.get() << endl;
+ MIL << "d.get" << d.get() << endl;
+ MIL << "e.get" << e.get() << endl;
- //MIL << "Capabilities found:" << endl;
- //for_each( datacollect._caps.begin(), datacollect._caps.end(),
- // printOnHack<Capability> );
+ DBG << "will c.set( 1 )..." << endl;
+ c.set( 5 );
+ DBG << "done c.set( c )" << endl;
+
+ MIL << "c.get" << c.get() << endl;
+ MIL << "d.get" << d.get() << endl;
+ MIL << "e.get" << e.get() << endl;
INT << "===[END]============================================" << endl;
return 0;
}
+
+#if 0
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ namespace debug
+ { /////////////////////////////////////////////////////////////////
+
+ template<>
+ void watchCAD( WatchCADBase::What what_r,
+ const WatchCAD<Dependencies::Impl> & self_r,
+ const WatchCAD<Dependencies::Impl> & rhs_r )
+ {
+ switch( what_r )
+ {
+ case WatchCADBase::CTOR:
+ case WatchCADBase::DTOR:
+ SEC << self_r << what_r << std::endl;
+ break;
+ case WatchCADBase::COPYCTOR:
+ case WatchCADBase::ASSIGN:
+ SEC << self_r << what_r << "( "
+ << dynamic_cast<const Dependencies::Impl &>(rhs_r)
+ << ")" << std::endl;
+ break;
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////
+ } // namespace debug
+ ///////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif
#include "zypp/base/PtrTypes.h"
$(nsopen)
-${INDENT}///////////////////////////////////////////////////////////////////
-${INDENT}namespace detail
-${INDENT}{ /////////////////////////////////////////////////////////////////
-${INDENT} DEFINE_PTR_TYPE(${CLASS}Impl)
-${INDENT} /////////////////////////////////////////////////////////////////
-${INDENT}} // namespace detail
-${INDENT}///////////////////////////////////////////////////////////////////
${INDENT}///////////////////////////////////////////////////////////////////
${INDENT}//
${INDENT}/** */
${INDENT}class ${CLASS}
${INDENT}{
+${INDENT} friend std::ostream & operator<<( std::ostream & str, const ${CLASS} & obj )
+${INDENT}public:
+${INDENT} /** Implementation */
+${INDENT} class Impl;
+
${INDENT}public:
${INDENT} /** Default ctor */
${INDENT} ${CLASS}();
-${INDENT} /** Factory ctor */
-${INDENT} explicit
-${INDENT} ${CLASS}( detail::${CLASS}ImplPtr impl_r );
${INDENT} /** Dtor */
${INDENT} ~${CLASS}();
+${INDENT}public:
+
${INDENT}private:
${INDENT} /** Pointer to implementation */
-${INDENT} detail::${CLASS}ImplPtr _pimpl;
-${INDENT}public:
-${INDENT} /** Avoid a bunch of friend decl. */
-${INDENT} detail::const${CLASS}ImplPtr sayFriend() const;
+${INDENT} RWCOW_pointer<Impl> _pimpl;
${INDENT}};
${INDENT}///////////////////////////////////////////////////////////////////
${INDENT}/** \relates ${CLASS} Stream output */
-${INDENT}extern std::ostream & operator<<( std::ostream & str, const ${CLASS} & obj );
+${INDENT}std::ostream & operator<<( std::ostream & str, const ${CLASS} & obj );
$(nsclose)
#endif // $INCLUDE_DEF
cat <<EOF
$(intro $CLASS_CC)
#include <iostream>
+//#include "zypp/base/Logger.h"
-#include "zypp/base/ReferenceCounted.h"
-#include "zypp/base/NonCopyable.h"
#include "${INCLUDE_H}"
-using namespace std;
+using std::endl;
$(nsopen)
${INDENT}///////////////////////////////////////////////////////////////////
-${INDENT}namespace detail
-${INDENT}{ /////////////////////////////////////////////////////////////////
-
-${INDENT} ///////////////////////////////////////////////////////////////////
-${INDENT} //
-${INDENT} // CLASS NAME : ${CLASS}Impl
-${INDENT} //
-${INDENT} /** ${CLASS} implementation */
-${INDENT} struct ${CLASS}Impl : public base::ReferenceCounted, private base::NonCopyable
-${INDENT} {
-${INDENT} /** Default ctor*/
-${INDENT} ${CLASS}Impl();
-${INDENT} /** Dtor */
-${INDENT} ~${CLASS}Impl();
-${INDENT} };
-${INDENT} ///////////////////////////////////////////////////////////////////
-${INDENT} IMPL_PTR_TYPE(${CLASS}Impl)
-${INDENT} ///////////////////////////////////////////////////////////////////
-
-${INDENT} /** \relates ${CLASS}Impl Stream output */
-${INDENT} inline std::ostream & operator<<( std::ostream & str, const ${CLASS}Impl & obj )
-${INDENT} {
-${INDENT} return str << "${CLASS}Impl";
-${INDENT} }
-
-${INDENT} /////////////////////////////////////////////////////////////////
-${INDENT}} // namespace detail
+${INDENT}//
+${INDENT}// CLASS NAME : ${CLASS}::Impl
+${INDENT}//
+${INDENT}/** ${CLASS} implementation. */
+${INDENT}struct ${CLASS}::Impl
+${INDENT}{
+
+${INDENT}public:
+${INDENT} /** Offer default Impl. */
+${INDENT} static shared_ptr<Impl> nullimpl()
+${INDENT} { if ( ! _nullimpl ) _nullimpl.reset( new Impl ); return _nullimpl; }
+
+${INDENT}private:
+${INDENT} /** Default Impl. */
+${INDENT} static shared_ptr<Impl> _nullimpl;
+
+${INDENT}private:
+${INDENT} friend Impl * rwcowClone<Impl>( const Impl * rhs );
+${INDENT} /** clone for RWCOW_pointer */
+${INDENT} Impl * clone() const
+${INDENT} { return new Impl( *this ); }
+${INDENT}};
+${INDENT}///////////////////////////////////////////////////////////////////
+
+${INDENT}shared_ptr<${CLASS}::Impl> ${CLASS}::Impl::_nullimpl;
+
${INDENT}///////////////////////////////////////////////////////////////////
+${INDENT}/** \relates ${CLASS}::Impl Stream output */
+${INDENT}inline std::ostream & operator<<( std::ostream & str, const ${CLASS}::Impl & obj )
+${INDENT}{
+${INDENT} return str << "${CLASS}::Impl";
+${INDENT}}
+
${INDENT}///////////////////////////////////////////////////////////////////
${INDENT}//
${INDENT}// CLASS NAME : ${CLASS}
${INDENT}// METHOD TYPE : Ctor
${INDENT}//
${INDENT}${CLASS}::${CLASS}()
-${INDENT}{}
-
-${INDENT}///////////////////////////////////////////////////////////////////
-${INDENT}//
-${INDENT}// METHOD NAME : ${CLASS}::${CLASS}
-${INDENT}// METHOD TYPE : Ctor
-${INDENT}//
-${INDENT}${CLASS}::${CLASS}( detail::${CLASS}ImplPtr impl_r )
-${INDENT}: _pimpl( impl_r )
+${INDENT}: _pimpl( Impl::nullimpl() )
${INDENT}{}
${INDENT}///////////////////////////////////////////////////////////////////
${INDENT}${CLASS}::~${CLASS}()
${INDENT}{}
-${INDENT}///////////////////////////////////////////////////////////////////
-${INDENT}//
-${INDENT}// METHOD NAME : ${CLASS}::sayFriend
-${INDENT}// METHOD TYPE : detail::const${CLASS}ImplPtr
-${INDENT}//
-${INDENT}detail::const${CLASS}ImplPtr ${CLASS}::sayFriend() const
-${INDENT}{ return _pimpl; }
-
${INDENT}/******************************************************************
${INDENT}**
${INDENT}** FUNCTION NAME : operator<<
${INDENT}*/
${INDENT}std::ostream & operator<<( std::ostream & str, const ${CLASS} & obj )
${INDENT}{
-${INDENT} return str << *obj.sayFriend();
+${INDENT} return str << *obj._pimpl;
${INDENT}}
$(nsclose)
#include "zypp/Dependencies.h"
#include "zypp/CapSet.h"
-using namespace std;
+using std::endl;
///////////////////////////////////////////////////////////////////
namespace zypp
{ /////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
- namespace detail
- { /////////////////////////////////////////////////////////////////
-
- ///////////////////////////////////////////////////////////////////
- //
- // CLASS NAME : DependenciesImpl
- //
- /** Dependencies implementation */
- struct DependenciesImpl : public base::ReferenceCounted, private base::NonCopyable
- {
- /** */
- CapSet _provides;
- /** */
- CapSet _prerequires;
- /** */
- CapSet _requires;
- /** */
- CapSet _conflicts;
- /** */
- CapSet _obsoletes;
- /** */
- CapSet _recommends;
- /** */
- CapSet _suggests;
- /** */
- CapSet _freshens;
-
- static DependenciesImpl_Ptr nodeps()
- {
- if ( !_nodeps ) { _nodeps = new DependenciesImpl; _nodeps->ref(); }
- return _nodeps;
- }
-
- private:
- static DependenciesImpl_Ptr _nodeps;
- };
- ///////////////////////////////////////////////////////////////////
- IMPL_PTR_TYPE(DependenciesImpl)
- DependenciesImpl_Ptr DependenciesImpl::_nodeps;
- ///////////////////////////////////////////////////////////////////
-
- /** \relates DependenciesImpl Stream output */
- inline std::ostream & operator<<( std::ostream & str, const DependenciesImpl & obj )
- {
- str << "PROVIDES:" << endl << obj._provides;
- str << "PREREQUIRES:" << endl << obj._prerequires;
- str << "REQUIRES:" << endl << obj._requires;
- str << "CONFLICTS:" << endl << obj._conflicts;
- str << "OBSOLETES:" << endl << obj._obsoletes;
- str << "RECOMMENDS:" << endl << obj._recommends;
- str << "SUGGESTS:" << endl << obj._suggests;
- str << "FRESHENS:" << endl << obj._freshens;
- return str;
- }
-
- /////////////////////////////////////////////////////////////////
- } // namespace detail
+ //
+ // CLASS NAME : Dependencies::Impl
+ //
+ /** Dependencies implementation. */
+ struct Dependencies::Impl
+ {
+ /** */
+ CapSet _provides;
+ /** */
+ CapSet _prerequires;
+ /** */
+ CapSet _requires;
+ /** */
+ CapSet _conflicts;
+ /** */
+ CapSet _obsoletes;
+ /** */
+ CapSet _recommends;
+ /** */
+ CapSet _suggests;
+ /** */
+ CapSet _freshens;
+
+ public:
+ /** Offer default Impl. */
+ static shared_ptr<Impl> nullimpl()
+ { if ( ! _nullimpl ) _nullimpl.reset( new Impl ); return _nullimpl; }
+
+ private:
+ /** Default Impl: empty sets. */
+ static shared_ptr<Impl> _nullimpl;
+
+ private:
+ friend Impl * rwcowClone<Impl>( const Impl * rhs );
+ /** clone for RWCOW_pointer */
+ Impl * clone() const
+ { return new Impl( *this ); }
+ };
///////////////////////////////////////////////////////////////////
+ shared_ptr<Dependencies::Impl> Dependencies::Impl::_nullimpl;
+
///////////////////////////////////////////////////////////////////
- //
- // CLASS NAME : Dependencies
- //
+
+ /** \relates DependenciesImpl Stream output */
+ inline std::ostream & operator<<( std::ostream & str, const Dependencies::Impl & obj )
+ {
+ str << "PROVIDES:" << endl << obj._provides;
+ str << "PREREQUIRES:" << endl << obj._prerequires;
+ str << "REQUIRES:" << endl << obj._requires;
+ str << "CONFLICTS:" << endl << obj._conflicts;
+ str << "OBSOLETES:" << endl << obj._obsoletes;
+ str << "RECOMMENDS:" << endl << obj._recommends;
+ str << "SUGGESTS:" << endl << obj._suggests;
+ str << "FRESHENS:" << endl << obj._freshens;
+ return str;
+ }
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
//
- // METHOD NAME : Dependencies::Dependencies
- // METHOD TYPE : Ctor
+ // CLASS NAME : Dependencies
//
- Dependencies::Dependencies()
- : _pimpl( detail::DependenciesImpl::nodeps() )
- {}
+ ///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
//
// METHOD NAME : Dependencies::Dependencies
// METHOD TYPE : Ctor
//
- Dependencies::Dependencies( detail::DependenciesImpl_Ptr impl_r )
- : _pimpl( impl_r ? impl_r : detail::DependenciesImpl::nodeps() )
+ Dependencies::Dependencies()
+ : _pimpl( Impl::nullimpl() )
{}
///////////////////////////////////////////////////////////////////
Dependencies::~Dependencies()
{}
- ///////////////////////////////////////////////////////////////////
- //
- // METHOD NAME : Dependencies::sayFriend
- // METHOD TYPE : detail::DependenciesImplconstPtr
- //
- detail::DependenciesImpl_constPtr Dependencies::sayFriend() const
- { return _pimpl; }
-
const CapSet & Dependencies::provides() const
{ return _pimpl->_provides; }
const CapSet & Dependencies::freshens() const
{ return _pimpl->_freshens; }
-#define ZYPP_DEPENDENCIES_COW \
-if(_pimpl->refCount()>1) \
-{ \
- detail::DependenciesImpl_Ptr _cow_tmp = new detail::DependenciesImpl; \
- _cow_tmp->_provides = _pimpl->_provides; \
- _cow_tmp->_prerequires = _pimpl->_prerequires; \
- _cow_tmp->_requires = _pimpl->_requires; \
- _cow_tmp->_conflicts = _pimpl->_conflicts; \
- _cow_tmp->_obsoletes = _pimpl->_obsoletes; \
- _cow_tmp->_recommends = _pimpl->_recommends; \
- _cow_tmp->_suggests = _pimpl->_suggests; \
- _cow_tmp->_freshens = _pimpl->_freshens; \
- _pimpl= _cow_tmp;\
-}
-
void Dependencies::setProvides( const CapSet & val_r )
- { ZYPP_DEPENDENCIES_COW; _pimpl->_provides = val_r; }
+ { _pimpl->_provides = val_r; }
void Dependencies::setPrerequires( const CapSet & val_r )
- { ZYPP_DEPENDENCIES_COW; _pimpl->_prerequires = val_r; }
+ { _pimpl->_prerequires = val_r; }
void Dependencies::setRequires( const CapSet & val_r )
- { ZYPP_DEPENDENCIES_COW; _pimpl->_requires = val_r; }
+ { _pimpl->_requires = val_r; }
void Dependencies::setConflicts( const CapSet & val_r )
- { ZYPP_DEPENDENCIES_COW; _pimpl->_conflicts = val_r; }
+ { _pimpl->_conflicts = val_r; }
void Dependencies::setObsoletes( const CapSet & val_r )
- { ZYPP_DEPENDENCIES_COW; _pimpl->_obsoletes = val_r; }
+ { _pimpl->_obsoletes = val_r; }
void Dependencies::setRecommends( const CapSet & val_r )
- { ZYPP_DEPENDENCIES_COW; _pimpl->_recommends = val_r; }
+ { _pimpl->_recommends = val_r; }
void Dependencies::setSuggests( const CapSet & val_r )
- { ZYPP_DEPENDENCIES_COW; _pimpl->_suggests = val_r; }
+ { _pimpl->_suggests = val_r; }
void Dependencies::setFreshens( const CapSet & val_r )
- { ZYPP_DEPENDENCIES_COW; _pimpl->_freshens = val_r; }
+ { _pimpl->_freshens = val_r; }
/******************************************************************
**
*/
std::ostream & operator<<( std::ostream & str, const Dependencies & obj )
{
- return str << *obj.sayFriend();
+ return str << *obj._pimpl;
}
/////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
namespace zypp
{ /////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////
- namespace detail
- { /////////////////////////////////////////////////////////////////
- DEFINE_PTR_TYPE(DependenciesImpl)
- /////////////////////////////////////////////////////////////////
- } // namespace detail
- ///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
//
// CLASS NAME : Dependencies
//
- /** */
+ /**
+ * \invariant No NULL _pimpl.
+ */
class Dependencies
{
+ friend std::ostream & operator<<( std::ostream & str, const Dependencies & obj );
+ public:
+
+ /** Implementation */
+ struct Impl;
+
public:
/** Default ctor */
Dependencies();
- /** Factory ctor */
- explicit
- Dependencies( detail::DependenciesImpl_Ptr impl_r );
/** Dtor */
~Dependencies();
private:
/** Pointer to implementation */
- detail::DependenciesImpl_Ptr _pimpl;
- public:
- /** Avoid a bunch of friend decl. */
- detail::DependenciesImpl_constPtr sayFriend() const;
+ RWCOW_pointer<Impl> _pimpl;
};
///////////////////////////////////////////////////////////////////
//
// CLASS NAME : Edition::Impl
//
- /** Edition implementation */
+ /** Edition implementation.
+ * \todo Unifiy Impl in Edition::noedition and Edition::Edition()
+ */
struct Edition::Impl
{
Impl()
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/base/Debug.h
+ *
+ * Debuging tools which should not be used in released code.
+*/
+#warning ZYPP_BASE_DEBUG_H included
+#ifndef ZYPP_BASE_DEBUG_H
+#define ZYPP_BASE_DEBUG_H
+
+#include <iostream>
+#include "zypp/base/Logger.h"
+#include "zypp/base/PtrTypes.h"
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ namespace debug
+ { /////////////////////////////////////////////////////////////////
+
+#define TAG INT << __PRETTY_FUNCTION__ << std::endl
+
+ ///////////////////////////////////////////////////////////////////
+ struct TraceCADBase
+ {
+ enum What { CTOR, COPYCTOR, ASSIGN, DTOR, PING };
+ };
+
+ inline std::ostream & operator<<( std::ostream & str, const TraceCADBase & obj )
+ { return str << "TraceCAD[" << &obj << "] "; }
+
+ inline std::ostream & operator<<( std::ostream & str, TraceCADBase::What obj )
+ {
+ switch( obj )
+ {
+ case TraceCADBase::CTOR: return str << "CTOR";
+ case TraceCADBase::COPYCTOR: return str << "COPYCTOR";
+ case TraceCADBase::ASSIGN: return str << "ASSIGN";
+ case TraceCADBase::DTOR: return str << "DTOR";
+ case TraceCADBase::PING: return str << "PING";
+ }
+ return str;
+ }
+
+ template<class _Tp>
+ struct TraceCAD : public TraceCADBase
+ {
+ TraceCAD()
+ { traceCAD( CTOR, *this, *this ); }
+
+ TraceCAD( const TraceCAD & rhs )
+ { traceCAD( COPYCTOR, *this, rhs ); }
+
+ TraceCAD & operator=( const TraceCAD & rhs )
+ { traceCAD( ASSIGN, *this, rhs ); return *this; }
+
+ virtual ~TraceCAD()
+ { traceCAD( DTOR, *this, *this ); }
+
+ void _PING() const
+ { traceCAD( PING, *this, *this ); }
+ };
+
+ template<class _Tp>
+ void traceCAD( TraceCADBase::What what_r,
+ const TraceCAD<_Tp> & self_r,
+ const TraceCAD<_Tp> & rhs_r )
+ {
+ switch( what_r )
+ {
+ case TraceCADBase::CTOR:
+ case TraceCADBase::DTOR:
+ case TraceCADBase::PING:
+ INT << self_r << what_r << std::endl;
+ break;
+ case TraceCADBase::COPYCTOR:
+ case TraceCADBase::ASSIGN:
+ INT << self_r << what_r << "( " << rhs_r << ")" << std::endl;
+ break;
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////
+ } // namespace debug
+ ///////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZYPP_BASE_DEBUG_H
## ##################################################
include_HEADERS = \
+ Debug.h \
KindOf.h \
Logger.h \
Exception.h \
/** */
using boost::weak_ptr;
- /** Use boost::intrusive_ptr as Ptr type*/
+ /** Use boost::intrusive_ptr as Ptr type */
using boost::intrusive_ptr;
using boost::static_pointer_cast;
*
* Forwarding access from an interface to an implemantation class, an
* RW_pointer prevents const interface methods from accidentally calling
- * nonconst implementation methods. In case you have to do so, call
- * unconst to get the <tt>_D *</tt>.
+ * nonconst implementation methods.
*
* The second template argument defaults to <tt>_Ptr = shared_ptr<_D></tt>.
+ *
+ * \see zypp::RWCOW_pointer for 'copy on write' functionality.
+ *
* \code
* #include "zypp/base/PtrTypes.h"
*
* void baa() const { _pimpl->... } // is Impl const *
* };
* \endcode
- * \todo refine ctor and assign.
*/
template<class _D, class _Ptr = shared_ptr<_D> >
struct RW_pointer
: _dptr( dptr )
{}
- _D & operator*() { return *_dptr; }
- const _D & operator*() const { return *_dptr; };
- _D * operator->() { return _dptr.get(); }
- const _D * operator->() const { return _dptr.get(); }
- _D * get() { return _dptr.get(); }
- const _D * get() const { return _dptr.get(); }
+ void reset()
+ { _dptr.reset(); }
+
+ void reset( typename _Ptr::element_type * dptr )
+ { _dptr.reset( dptr ); }
+
+ void swap( RW_pointer & rhs )
+ { _dptr.swap( rhs._dptr ); }
+
+ void swap( _Ptr & rhs )
+ { _dptr.swap( rhs ); }
+
+ const _D & operator*() const
+ { return *_dptr; };
+
+ const _D * operator->() const
+ { return _dptr.get(); }
- _D * unconst() const { return _dptr.get(); }
+ const _D * get() const
+ { return _dptr.get(); }
+ _D & operator*()
+ { return *_dptr; }
+
+ _D * operator->()
+ { return _dptr.get(); }
+
+ _D * get()
+ { return _dptr.get(); }
+
+ private:
_Ptr _dptr;
};
+ ///////////////////////////////////////////////////////////////////
/** \relates RW_pointer Stream output.
*
}
///////////////////////////////////////////////////////////////////
- /** Wrapper for \c const correct access via pointer.
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : RWCOW_pointer
+ //
+ /** \ref RW_pointer supporting 'copy on write' functionality.
*
- * Template specialization of RW_pointer, storing a raw <tt>_P *</tt>,
- * which must be convertible into a <tt>_D *</tt>.
+ * \em Write access to the underlying object creates a copy, iff
+ * the object is shared.
*
- * \note The object pointed to will \b not be deleted. If you need
- * automatic cleanup, use a \ref ZYPP_SMART_PTR instead of a
- * raw pointer.
+ * See \ref RW_pointer.
*/
- template<class _D,class _P>
- struct RW_pointer<_D,_P*>
+ template<class _D, class _Ptr = shared_ptr<_D> >
+ struct RWCOW_pointer
{
typedef _D element_type;
+ typedef typename _Ptr::unspecified_bool_type unspecified_bool_type;
+
+ explicit
+ RWCOW_pointer( typename _Ptr::element_type * dptr = 0 )
+ : _dptr( dptr )
+ {}
explicit
- RW_pointer( _P * dptr = 0 )
+ RWCOW_pointer( _Ptr dptr )
: _dptr( dptr )
{}
- _D & operator*() { return *_dptr; }
- const _D & operator*() const { return *_dptr; };
- _D * operator->() { return _dptr; }
- const _D * operator->() const { return _dptr; }
- _D * get() { return _dptr; }
- const _D * get() const { return _dptr; }
+ void reset()
+ { _dptr.reset(); }
+
+ void reset( typename _Ptr::element_type * dptr )
+ { _dptr.reset( dptr ); }
+
+ void swap( RWCOW_pointer & rhs )
+ { _dptr.swap( rhs._dptr ); }
+
+ void swap( _Ptr & rhs )
+ { _dptr.swap( rhs ); }
+
+ operator unspecified_bool_type() const
+ { return _dptr; }
+
+ const _D & operator*() const
+ { return *_dptr; };
+
+ const _D * operator->() const
+ { return _dptr.get(); }
- _D * unconst() const { return _dptr; }
+ const _D * get() const
+ { return _dptr.get(); }
- _P * _dptr;
+ _D & operator*()
+ { assertUnshared(); return *_dptr; }
+
+ _D * operator->()
+ { assertUnshared(); return _dptr.get(); }
+
+ _D * get()
+ { assertUnshared(); return _dptr.get(); }
+
+ private:
+
+ void assertUnshared()
+ {
+ if ( rwcowIsShared( _dptr ) )
+ {
+ _dptr.reset( rwcowClone( _dptr.get() ) );
+ }
+ }
+
+ private:
+ _Ptr _dptr;
};
+ ///////////////////////////////////////////////////////////////////
+
+ /** \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
+ * it, in case a specific \a _D does not have <tt>clone()</tt>.
+ */
+ template<class _D>
+ inline _D * rwcowClone( const _D * rhs )
+ { return rhs->clone(); }
+
+ ///////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////
+ /** \relates RWCOW_pointer Stream output.
+ *
+ * Print the \c _D object the RWCOW_pointer refers, or \c "NULL"
+ * if the pointer is \c NULL.
+ */
+ template<class _D, class _Ptr>
+ inline std::ostream &
+ operator<<( std::ostream & str, const RWCOW_pointer<_D, _Ptr> & obj )
+ {
+ if ( obj.get() )
+ return str << *obj.get();
+ return str << std::string("NULL");
+ }
+
+ ///////////////////////////////////////////////////////////////////
/*@}*/
{ return *this; }
public:
- /** Reurn reference counter value. */
+ /** Return reference counter value. */
unsigned refCount() const
{ return _counter; }