#include <iosfwd>
#include <functional>
+#include <set>
#include <string>
+#include "zypp/base/String.h"
+#include "zypp/base/Iterator.h"
+
+#include "zypp/IdStringType.h"
+#include "zypp/RelCompare.h"
+
///////////////////////////////////////////////////////////////////
namespace zypp
{ /////////////////////////////////////////////////////////////////
// CLASS NAME : Arch
//
/** Architecture.
- * \todo improve compatibleWith implementation
- * \todo unify strings and optimize opertor==
*/
class Arch
{
public:
- /** Default ctor 'noarch' */
+ /** Default ctor \ref Arc_noarch. */
Arch();
- /** Ctor from string. */
- explicit
- Arch( const std::string & rhs );
- /** Dtor */
- ~Arch()
- {}
+
+ /** Ctor taking Arch as string. */
+ explicit Arch( IdString::IdType id_r );
+ explicit Arch( const IdString & idstr_r );
+ explicit Arch( const std::string & str_r );
+ explicit Arch( const char * cstr_r );
+
+ public:
+ /** \name IdStringType like interface.
+ * We can't use the complete \ref IdStringType mixin until
+ * _doCompare can be redefined on any level, not just as char*.
+ */
+ //@{
/** String representation of Arch. */
- const std::string & asString() const
- { return _value; }
+ IdString idStr() const;
+ /** \overload */
+ const std::string & asString() const;
+ /** \overload */
+ const char * c_str() const
+ { return asString().c_str(); }
+
+ /** Test for an empty Arch (this is \ref Arch_epmty, not \ref Arch_noarch ). */
+ bool empty() const
+ { return asString().empty(); }
+
+ /** Size of the string representation. */
+ unsigned size() const
+ { return asString().size(); }
+
+ /** Expert backdoor. */
+ IdString::IdType id() const
+ { return idStr().id(); }
+ //@}
+
+ public:
+ /** Whether this is a buitin (or known) architecture.
+ * Used e.g. in \ref Capability to determine whether
+ * some trailing \c ".string" is part ot the name or
+ * restriction to an architecture.
+ */
+ bool isBuiltIn() const;
public:
/** Compatibility relation.
- * \return \c True iff \c this is compatible with \a rhs.
+ * \return \c True iff \c this is compatible with \a targetArch_r.
+ * \code
+ * Arch_noarch.compatibleWith( ... ) ==> always true;
+ * Arch_i686.compatibleWith( Arch_x86_64 ) ==> true;
+ * Arch_x86_64.compatibleWith( Arch_i686 ) ==> false;
+ * \endcode
*/
- bool compatibleWith( const Arch & rhs ) const;
+ bool compatibleWith( const Arch & targetArch_r ) const;
- /** Order on Arch (arbitrary).
- * \todo Adjust logical operators below to follow compare.
+ /**
+ * \return the arch before noarch if it's not a multilib arch
+ * (e.g. x86_64,sparc64v,sparc64,ppc64,s390x).
*/
- int compare( const Arch & rhs ) const
- { return _value.compare( rhs._value ); }
+ Arch baseArch() const;
- /** Architecture of the current working system
- * \return \c Arch.
- * \todo Eliminate this, it's not task of a data type to
- * detect and define what the system architecture is.
+ /** \overload static version. */
+ static Arch baseArch( const Arch & targetArch_r )
+ { return targetArch_r.baseArch(); }
+
+ /** Arch comparison.
+ * Compatible architectures are treated as \c less (i.e. <tt>i686>i386>noarch</tt>).
+ * So \c Arch_noarch is the least Arch. Equivalent architectures
+ * (compatible in both directions) are ordered arbitrary.
+ */
+ int compare( const Arch & rhs ) const;
+
+ /** Arch comparison (static version). */
+ static int compare( const Arch & lhs, const Arch & rhs )
+ { return lhs.compare( rhs ); }
+
+ public:
+ /** Reversed arch order, best Arch first. */
+ typedef std::set<Arch,CompareByGT<Arch> > CompatSet;
+
+ /** Return a set of all Arch's \ref compatibleWith a \a targetArch_r.
+ * \note The set is ordered according to compare, thus iterating
+ * will start at \a targetArch_r and end with \c Arch_noarch.
+ * \code
+ * Arch::CompatSet cset( Arch::compatSet( Arch_x86_64 ) );
+ *
+ * cout << str::join( make_transform_iterator( cset.begin(), std::mem_fun_ref(&Arch::asString) ),
+ * make_transform_iterator( cset.end(), std::mem_fun_ref(&Arch::asString) ) )
+ * << endl;
+ *
+ * // Prints: x86_64 athlon i686 i586 i486 i386 noarch
+ * \endcode
*/
- static const Arch System;
+ static CompatSet compatSet( const Arch & targetArch_r );
+
+ /** */
+ static std::string asString( const CompatSet & cset )
+ {
+ return str::join( make_transform_iterator( cset.begin(), std::mem_fun_ref(&Arch::asString) ),
+ make_transform_iterator( cset.end(), std::mem_fun_ref(&Arch::asString) ) );
+ }
+ public:
+ struct CompatEntry;
private:
- /** String representation of Arch. */
- std::string _value;
+ Arch( const CompatEntry & );
+ const CompatEntry * _entry;
};
///////////////////////////////////////////////////////////////////
* like \c Arch::i386.
*/
//@{
+ /** \relates Arch
+ * This is an empty \ref Arch represented by an empty string.
+ * Sometimes used to indicate an any or an unknown Arch. Don't
+ * confuse this with \ref Arch_noarch, which is in fact an
+ * architecture.
+ */
+ extern const Arch Arch_empty;
+
/** \relates Arch */
extern const Arch Arch_noarch;
- extern const Arch Arch_src;
+
+ /** \relates Arch */
+ extern const Arch Arch_pentium4;
+ /** \relates Arch */
+ extern const Arch Arch_pentium3;
/** \relates Arch */
extern const Arch Arch_x86_64;
extern const Arch Arch_s390;
/** \relates Arch */
+ extern const Arch Arch_ppc64le;
+
+ /** \relates Arch */
+ extern const Arch Arch_ppc64p7;
+ /** \relates Arch */
extern const Arch Arch_ppc64;
/** \relates Arch */
extern const Arch Arch_ppc;
/** \relates Arch */
extern const Arch Arch_ia64;
- //@}
- ///////////////////////////////////////////////////////////////////
+ /** \relates Arch */
+ extern const Arch Arch_alphaev67;
+ /** \relates Arch */
+ extern const Arch Arch_alphaev6;
+ /** \relates Arch */
+ extern const Arch Arch_alphapca56;
+ /** \relates Arch */
+ extern const Arch Arch_alphaev56;
+ /** \relates Arch */
+ extern const Arch Arch_alphaev5;
+ /** \relates Arch */
+ extern const Arch Arch_alpha;
+
+ /** \relates Arch */
+ extern const Arch Arch_sparc64v;
+ /** \relates Arch */
+ extern const Arch Arch_sparc64;
+ /** \relates Arch */
+ extern const Arch Arch_sparcv9v;
+ /** \relates Arch */
+ extern const Arch Arch_sparcv9;
+ /** \relates Arch */
+ extern const Arch Arch_sparcv8;
+ /** \relates Arch */
+ extern const Arch Arch_sparc;
+
+ /** \relates Arch */
+ extern const Arch Arch_aarch64;
+ /** \relates Arch */
+ extern const Arch Arch_armv7tnhl;
+ /** \relates Arch */
+ extern const Arch Arch_armv7thl;
+ /** \relates Arch */
+ extern const Arch Arch_armv7nhl;
+ /** \relates Arch */
+ extern const Arch Arch_armv7hl;
+ /** \relates Arch */
+ extern const Arch Arch_armv7l;
+ /** \relates Arch */
+ extern const Arch Arch_armv6hl;
+ /** \relates Arch */
+ extern const Arch Arch_armv6l;
+ /** \relates Arch */
+ extern const Arch Arch_armv5tejl;
+ /** \relates Arch */
+ extern const Arch Arch_armv5tel;
+ /** \relates Arch */
+ extern const Arch Arch_armv5l;
+ /** \relates Arch */
+ extern const Arch Arch_armv4tl;
+ /** \relates Arch */
+ extern const Arch Arch_armv4l;
+ /** \relates Arch */
+ extern const Arch Arch_armv3l;
+
+ /** \relates Arch */
+ extern const Arch Arch_sh3;
+
+ /** \relates Arch */
+ extern const Arch Arch_sh4;
+ /** \relates Arch */
+ extern const Arch Arch_sh4a;
- inline Arch::Arch()
- : _value( Arch_noarch._value )
- {}
+ /** \relates Arch */
+ extern const Arch Arch_m68k;
+ //@}
///////////////////////////////////////////////////////////////////
inline std::ostream & operator<<( std::ostream & str, const Arch & obj )
{ return str << obj.asString(); }
- /** \name Comparison based on string value. */
+ /** \relates Arch XML output. */
+ inline std::ostream & dumpAsXmlOn( std::ostream & str, const Arch & obj )
+ { return str << "<arch>" << obj << "</arch>"; }
+
+ /** \name Equality based on string value. */
//@{
/** \relates Arch */
inline bool operator==( const Arch & lhs, const Arch & rhs )
///////////////////////////////////////////////////////////////////
namespace std
{ /////////////////////////////////////////////////////////////////
- /** \relates Arch Default order for std::container based on string value.*/
+ /** \relates zypp::Arch Default order for std::container based Arch::compare.*/
template<>
inline bool less<zypp::Arch>::operator()( const zypp::Arch & lhs, const zypp::Arch & rhs ) const
- { return lhs.asString() < rhs.asString(); }
+ { return lhs.compare( rhs ) < 0; }
/////////////////////////////////////////////////////////////////
} // namespace zypp
///////////////////////////////////////////////////////////////////