WIP reorganize the ordering relation on assets
(should simplify handling of comparisons at various places)
This commit is contained in:
parent
3d2791b91e
commit
162976a4cf
2 changed files with 68 additions and 53 deletions
|
|
@ -39,7 +39,7 @@
|
|||
** value. For example the asset::Media#getID returns an ID<Media>. By using the
|
||||
** templated query function AssetManager#getAsset, we can get at references to the more
|
||||
** specific subinterface asset::media just by using the ID value in a typesafe manner.
|
||||
** This helps avoiding dynamic typing and switch-on-type, leading to much more robust,
|
||||
** This helps avoiding dynamic typing and switch-on-type, leading to more robust,
|
||||
** extensible and clear code.
|
||||
**
|
||||
** (Implementation detail: as g++ is not able to handle member function template
|
||||
|
|
@ -65,6 +65,7 @@
|
|||
#include <vector>
|
||||
#include <set>
|
||||
#include <tr1/memory>
|
||||
#include <boost/operators.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
|
||||
|
|
@ -128,12 +129,14 @@ namespace asset
|
|||
* asset::Effect, asset::Codec, asset::Track, asset::Dataset.
|
||||
* @note Assets objects have a strict unique identity and because of this are non-copyable.
|
||||
* You can not create an Asset derived object without registering it with the AssetManager
|
||||
* automatically. I is possible to copy the PAsset (smart pointer) though.
|
||||
* automatically. It is possible to copy the PAsset (smart pointer) though.
|
||||
*
|
||||
* @since 09/2007
|
||||
* @author Ichthyo
|
||||
*/
|
||||
class Asset : private boost::noncopyable
|
||||
class Asset
|
||||
: boost::totally_ordered< Asset,
|
||||
boost::noncopyable>
|
||||
{
|
||||
public:
|
||||
|
||||
|
|
@ -142,6 +145,7 @@ namespace asset
|
|||
* sufficiently identifying any given Asset.
|
||||
*/
|
||||
struct Ident
|
||||
: boost::totally_ordered<Ident>
|
||||
{
|
||||
/** element ID, comprehensible but sanitized.
|
||||
* The tuple (category, name, org) is unique.
|
||||
|
|
@ -174,20 +178,13 @@ namespace asset
|
|||
const string& o = "lumi",
|
||||
const uint ver=1);
|
||||
|
||||
|
||||
int compare (const Ident& other) const;
|
||||
|
||||
/** @note equality ignores version differences */
|
||||
bool operator== (const Ident& other) const
|
||||
{
|
||||
return org == other.org
|
||||
&& name == other.name
|
||||
&& category == other.category;
|
||||
}
|
||||
bool operator!= (const Ident& other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
int compare (const Ident& other) const;
|
||||
|
||||
bool operator== (const Ident& oi) const { return compare (oi) ==0; }
|
||||
bool operator< (const Ident& oi) const { return compare (oi) < 0; }
|
||||
|
||||
operator string () const;
|
||||
};
|
||||
|
||||
|
|
@ -197,11 +194,16 @@ namespace asset
|
|||
public:
|
||||
const Ident ident; ///< Asset identification tuple
|
||||
|
||||
virtual const ID<Asset>& getID() const { return id; }
|
||||
|
||||
virtual const ID<Asset>& getID() const { return id; }
|
||||
|
||||
|
||||
bool operator== (const Asset& oa) const { return ident == oa.ident; }
|
||||
bool operator< (const Asset& oa) const { return ident < oa.ident; }
|
||||
|
||||
virtual operator string () const;
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
const ID<Asset> id; ///< Asset primary key.
|
||||
|
||||
|
|
@ -293,6 +295,20 @@ namespace asset
|
|||
|
||||
|
||||
|
||||
/* ====== ordering of Assets and Asset-Pointers ====== */
|
||||
|
||||
/** ordering of Assets is based on the ordering
|
||||
* of Ident tuples, which are supposed to be unique.
|
||||
* @note version info is irrelevant */
|
||||
inline int
|
||||
Asset::Ident::compare (const Asset::Ident& oi) const
|
||||
{
|
||||
int res;
|
||||
if (0 != (res=category.compare (oi.category))) return res;
|
||||
if (0 != (res=org.compare (oi.org))) return res;
|
||||
return name.compare (oi.name);
|
||||
}
|
||||
|
||||
/** promote subtype-ptr to PAsset, e.g. for comparing */
|
||||
template<class A>
|
||||
inline const PcAsset
|
||||
|
|
@ -304,30 +320,27 @@ namespace asset
|
|||
/** ordering of Asset smart ptrs based on Ident tuple.
|
||||
* @todo currently supporting only smart_ptr<Asset>.
|
||||
* @todo should better be done using boost::operator */
|
||||
inline bool operator== (const PcAsset& a1, const PcAsset& a2) { return a1 && a2 && ( 0==a1->ident.compare(a2->ident));}
|
||||
inline bool operator< (const PcAsset& a1, const PcAsset& a2) { return a1 && a2 && (-1==a1->ident.compare(a2->ident));}
|
||||
inline bool operator> (const PcAsset& a1, const PcAsset& a2) { return a2 < a1; }
|
||||
inline bool operator>= (const PcAsset& a1, const PcAsset& a2) { return !(a1 < a2); }
|
||||
inline bool operator<= (const PcAsset& a1, const PcAsset& a2) { return !(a1 > a2); }
|
||||
inline bool operator!= (const PcAsset& a1, const PcAsset& a2) { return !(a1== a2); }
|
||||
inline bool operator== (PcAsset const& a1, PcAsset const& a2) { return a1 && a2 && ( (*a1) == (*a2));}
|
||||
inline bool operator< (PcAsset const& a1, PcAsset const& a2) { return a1 && a2 && ( (*a1) < (*a2));}
|
||||
|
||||
inline bool operator== (const PAsset& a1, const PAsset& a2) { return pAsset(a1) == pAsset(a2); }
|
||||
inline bool operator< (const PAsset& a1, const PAsset& a2) { return pAsset(a1) < pAsset(a2); }
|
||||
inline bool operator> (const PAsset& a1, const PAsset& a2) { return pAsset(a1) > pAsset(a2); }
|
||||
inline bool operator>= (const PAsset& a1, const PAsset& a2) { return pAsset(a1) >= pAsset(a2); }
|
||||
inline bool operator<= (const PAsset& a1, const PAsset& a2) { return pAsset(a1) <= pAsset(a2); }
|
||||
inline bool operator!= (const PAsset& a1, const PAsset& a2) { return pAsset(a1) != pAsset(a2); }
|
||||
|
||||
/** ordering of Asset Ident tuples.
|
||||
* @note version is irrelevant */
|
||||
inline int
|
||||
Asset::Ident::compare (const Asset::Ident& oi) const
|
||||
{
|
||||
int res;
|
||||
if (0 != (res=category.compare (oi.category))) return res;
|
||||
if (0 != (res=org.compare (oi.org))) return res;
|
||||
return name.compare (oi.name);
|
||||
}
|
||||
template<class PA1, class PA2>
|
||||
inline bool operator== (PA1 const& a1, PA2 const& a2) { return pAsset(a1) == pAsset(a2); }
|
||||
|
||||
template<class PA1, class PA2>
|
||||
inline bool operator< (PA1 const& a1, PA2 const& a2) { return pAsset(a1) < pAsset(a2); }
|
||||
|
||||
|
||||
/** build ordering of Asset shared pointers on the ordering of the pointed to assets.
|
||||
* Because we can't define member operators for shared-ptrs, we explicitly instantiate
|
||||
* the boost ordering concept template for all Asset kinds we want to use...
|
||||
*/
|
||||
template<class PTR>
|
||||
struct asset_total_ordering : public boost::totally_ordered<PTR>
|
||||
{ };
|
||||
|
||||
template struct asset_total_ordering<PAsset>;
|
||||
template struct asset_total_ordering<PcAsset>;
|
||||
|
||||
|
||||
|
||||
/** convienient for debugging */
|
||||
|
|
|
|||
|
|
@ -26,8 +26,7 @@
|
|||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/lambda/lambda.hpp>
|
||||
//#include <boost/function.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/lambda/bind.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <set>
|
||||
|
|
@ -43,9 +42,9 @@ namespace util
|
|||
{
|
||||
using util::for_each;
|
||||
using boost::lambda::_1;
|
||||
// using boost::function;
|
||||
using boost::lambda::bind;
|
||||
using boost::lexical_cast;
|
||||
using boost::bind;
|
||||
|
||||
|
||||
|
||||
template<class COLL>
|
||||
|
|
@ -57,7 +56,6 @@ namespace util
|
|||
cout << "]\n";
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
killerselector (string description, uint candidate)
|
||||
{
|
||||
|
|
@ -68,31 +66,35 @@ namespace util
|
|||
|
||||
class RemoveFromSet_test : public Test
|
||||
{
|
||||
virtual void run (Arg arg)
|
||||
virtual void
|
||||
run (Arg arg)
|
||||
{
|
||||
test_remove (" nothing ");
|
||||
test_remove ("0");
|
||||
test_remove ("9");
|
||||
test_remove ("5");
|
||||
test_remove ("0 2 4 6 8");
|
||||
test_remove ("1 3 5 7 9");
|
||||
test_remove ("0 2 4 6 8 ");
|
||||
test_remove (" 1 3 5 7 9");
|
||||
test_remove ("0 1 2 3 4 5 6 7 8 9");
|
||||
test_remove ("0 1 2 3 4 5 6 7 8 ");
|
||||
test_remove (" 1 2 3 4 5 6 7 8 9");
|
||||
test_remove ("0 1 2 3 4 6 7 8 9");
|
||||
}
|
||||
|
||||
/** @test populate a test set, remove the denoted elements
|
||||
* and print the result
|
||||
*/
|
||||
|
||||
/** @test populate a test set,
|
||||
* remove the denoted elements
|
||||
* and print the result... */
|
||||
void
|
||||
test_remove (string elems_to_remove)
|
||||
{
|
||||
std::set<uint> theSet;
|
||||
for (int i=0; i<10; ++i)
|
||||
theSet.push_back (i);
|
||||
theSet.insert (i);
|
||||
|
||||
util::remove_if (theSet, bind( killerselector, elems_to_remove, _1));
|
||||
|
||||
cout << "removed " << elems_to_remove << " ---> ";
|
||||
show (theSet);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue