2010-11-08 04:48:50 +01:00
|
|
|
/*
|
|
|
|
|
OUTPUT-MAPPING.hpp - generic interface for translation of output designations
|
|
|
|
|
|
|
|
|
|
Copyright (C) Lumiera.org
|
|
|
|
|
2010, Hermann Vosseler <Ichthyostega@web.de>
|
|
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
|
modify it under the terms of the GNU General Public License as
|
|
|
|
|
published by the Free Software Foundation; either version 2 of the
|
|
|
|
|
License, or (at your option) any later version.
|
|
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef PROC_MOBJECT_OUTPUT_MAPPING_H
|
|
|
|
|
#define PROC_MOBJECT_OUTPUT_MAPPING_H
|
|
|
|
|
|
|
|
|
|
#include "proc/mobject/output-designation.hpp"
|
2010-11-24 06:21:32 +01:00
|
|
|
#include "lib/meta/function.hpp"
|
2010-11-27 03:59:07 +01:00
|
|
|
#include "lib/bool-checkable.hpp"
|
2010-11-25 05:35:50 +01:00
|
|
|
#include "lib/query.hpp"
|
2010-11-27 06:01:31 +01:00
|
|
|
#include "lib/util.hpp"
|
2010-11-24 06:21:32 +01:00
|
|
|
|
2010-11-27 03:59:07 +01:00
|
|
|
#include <boost/noncopyable.hpp>
|
2010-11-27 04:21:39 +01:00
|
|
|
#include <boost/operators.hpp>
|
2010-11-27 06:01:31 +01:00
|
|
|
#include <map>
|
2010-11-27 03:59:07 +01:00
|
|
|
|
2010-11-08 04:48:50 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace mobject {
|
2010-11-25 05:35:50 +01:00
|
|
|
|
2010-11-24 06:21:32 +01:00
|
|
|
namespace { // Helper to extract and rebind definition types
|
|
|
|
|
|
2010-11-25 04:52:49 +01:00
|
|
|
using std::tr1::function;
|
2010-11-27 06:01:31 +01:00
|
|
|
using util::contains;
|
2010-11-25 04:52:49 +01:00
|
|
|
|
2010-11-24 06:21:32 +01:00
|
|
|
template<class DEF>
|
2010-11-25 04:52:49 +01:00
|
|
|
class _def
|
2010-11-24 06:21:32 +01:00
|
|
|
{
|
2010-11-25 04:52:49 +01:00
|
|
|
typedef asset::ID<asset::Pipe> PId;
|
2010-11-24 06:21:32 +01:00
|
|
|
|
|
|
|
|
template<typename FUN>
|
|
|
|
|
struct Rebind;
|
|
|
|
|
|
|
|
|
|
template<typename RET>
|
|
|
|
|
struct Rebind<RET(DEF::*)(PId)>
|
|
|
|
|
{
|
|
|
|
|
typedef RET Res;
|
|
|
|
|
};
|
|
|
|
|
|
2010-11-25 04:52:49 +01:00
|
|
|
typedef typeof(&DEF::output) OutputMappingMemberFunc; // GCC extension: "typeof"
|
|
|
|
|
typedef Rebind<OutputMappingMemberFunc> Rebinder;
|
2010-11-24 06:21:32 +01:00
|
|
|
|
2010-11-25 04:52:49 +01:00
|
|
|
public:
|
|
|
|
|
typedef typename Rebinder::Res Target;
|
2010-11-25 05:35:50 +01:00
|
|
|
typedef function<Target(PId)> OutputMappingFunc;
|
|
|
|
|
|
2010-11-24 06:21:32 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
}
|
2010-11-08 04:48:50 +01:00
|
|
|
|
2010-11-25 05:35:50 +01:00
|
|
|
using lumiera::Query;
|
2010-11-27 06:01:31 +01:00
|
|
|
using asset::HashVal;
|
2010-11-25 05:35:50 +01:00
|
|
|
|
2010-11-08 04:48:50 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* OutputMapping is a facility to resolve output designations.
|
|
|
|
|
* For a given specification, resolution to the desired
|
|
|
|
|
* target specification may be derived. Here, the
|
|
|
|
|
* type of the target specification is defined
|
|
|
|
|
* through the type parameter.
|
|
|
|
|
*
|
2010-11-27 06:01:31 +01:00
|
|
|
* \par definition of specific mapping behaviour
|
|
|
|
|
*
|
|
|
|
|
* This is an generic map-like container, acting as Interface to be used
|
|
|
|
|
* in the signature of API functions either providing or requiring a Mapping.
|
|
|
|
|
* For each distinct usage situation, an instantiation of this template should
|
|
|
|
|
* be created, providing a <i>definition context</i> as template parameter.
|
|
|
|
|
* Instances of this concrete mapping type may then be default constructed
|
|
|
|
|
* and copied freely. The definition context is supposed to provide
|
|
|
|
|
* - a functor \c DEF::output usable as function pipe-ID --> Target
|
|
|
|
|
* - the concrete output-functor also defines the concrete Target type,
|
|
|
|
|
* which will be returned when accessing the OutputMapping
|
2010-11-08 04:48:50 +01:00
|
|
|
*/
|
2010-11-23 03:40:11 +01:00
|
|
|
template<class DEF>
|
2010-11-08 04:48:50 +01:00
|
|
|
class OutputMapping
|
2010-11-27 06:01:31 +01:00
|
|
|
: public DEF
|
2010-11-08 04:48:50 +01:00
|
|
|
{
|
2010-11-25 04:52:49 +01:00
|
|
|
typedef _def<DEF> Setup;
|
|
|
|
|
|
2010-11-25 05:35:50 +01:00
|
|
|
typedef asset::ID<asset::Pipe> PId;
|
|
|
|
|
typedef asset::PPipe PPipe;
|
|
|
|
|
|
2010-11-27 06:01:31 +01:00
|
|
|
/* == mapping table storage == */
|
|
|
|
|
std::map<HashVal,HashVal> table_;
|
|
|
|
|
|
2010-11-08 04:48:50 +01:00
|
|
|
public:
|
2010-11-25 05:35:50 +01:00
|
|
|
typedef typename Setup::Target Target;
|
|
|
|
|
|
2010-11-27 06:01:31 +01:00
|
|
|
// using default ctor and copy operations
|
2010-11-25 05:35:50 +01:00
|
|
|
|
2010-11-27 06:01:31 +01:00
|
|
|
size_t size() const { return table_.size(); }
|
|
|
|
|
bool empty() const { return 0 == size(); }
|
|
|
|
|
void clear() { table_.clear(); }
|
2010-11-25 05:35:50 +01:00
|
|
|
|
2010-11-27 06:01:31 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @internal transient resolution wrapper to be exposed by map-style access.
|
|
|
|
|
* A Resolver instance represents an output mapping result, yet to be fully resolved.
|
|
|
|
|
* It is created on the stack by the OutputMapping container and internally wired
|
|
|
|
|
* back to the container and the actually stored value (pipe-ID-hash) in the table.
|
|
|
|
|
* Actually retrieving the result value by the client code triggers invocation
|
|
|
|
|
* of the specific resolution functor, embedded in the definition context DEF,
|
|
|
|
|
* which was given when instantiating the OutputMapping template.
|
|
|
|
|
*/
|
2010-11-25 05:35:50 +01:00
|
|
|
class Resolver
|
2010-11-27 03:59:07 +01:00
|
|
|
: public lib::BoolCheckable<Resolver
|
2010-11-27 04:21:39 +01:00
|
|
|
, boost::equality_comparable<Resolver, Target,
|
|
|
|
|
boost::equality_comparable<Resolver>
|
2010-11-27 06:01:31 +01:00
|
|
|
> >
|
2010-11-25 05:35:50 +01:00
|
|
|
{
|
2010-11-27 06:01:31 +01:00
|
|
|
OutputMapping& thisMapping_;
|
|
|
|
|
HashVal& pID_;
|
|
|
|
|
|
|
|
|
|
Resolver (OutputMapping& container, HashVal& resultVal)
|
|
|
|
|
: thisMapping_(container)
|
|
|
|
|
, pID_(resultVal)
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
friend class OutputMapping;
|
|
|
|
|
|
|
|
|
|
/* copy by clients prohibited */
|
|
|
|
|
Resolver& operator= (Resolver const&);
|
|
|
|
|
|
2010-11-27 03:59:07 +01:00
|
|
|
|
2010-11-27 06:01:31 +01:00
|
|
|
Target
|
|
|
|
|
resolve() const
|
|
|
|
|
{
|
|
|
|
|
REQUIRE (pID_);
|
|
|
|
|
PId targetPipeID (pID_);
|
|
|
|
|
return thisMapping_.resolve (targetPipeID);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
2010-11-27 03:59:07 +01:00
|
|
|
void
|
|
|
|
|
operator= (PId newId2map)
|
2010-11-25 05:35:50 +01:00
|
|
|
{
|
2010-11-27 06:01:31 +01:00
|
|
|
pID_ = newId2map;
|
2010-11-25 05:35:50 +01:00
|
|
|
}
|
2010-11-27 03:59:07 +01:00
|
|
|
|
|
|
|
|
void
|
|
|
|
|
operator= (PPipe newPipe2map)
|
2010-11-25 05:35:50 +01:00
|
|
|
{
|
2010-11-27 06:01:31 +01:00
|
|
|
REQUIRE (newPipe2map);
|
|
|
|
|
pID_ = newPipe2map->getID();
|
2010-11-25 05:35:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
operator Target()
|
|
|
|
|
{
|
2010-11-27 06:01:31 +01:00
|
|
|
return resolve();
|
2010-11-25 05:35:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
2010-11-27 03:59:07 +01:00
|
|
|
isValid() const
|
2010-11-25 05:35:50 +01:00
|
|
|
{
|
2010-11-27 06:01:31 +01:00
|
|
|
return bool(pID_);
|
2010-11-25 05:35:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2010-11-27 04:21:39 +01:00
|
|
|
/* === equality comparisons (boost::operators) === */
|
|
|
|
|
|
|
|
|
|
friend bool
|
|
|
|
|
operator== (Resolver const& a, Resolver const& b)
|
|
|
|
|
{
|
2010-11-27 06:01:31 +01:00
|
|
|
return a.pID_ == b.pID_;
|
|
|
|
|
} // note: Resolver depends on tempate parameter DEF
|
|
|
|
|
// All instances of DEF are considered equivalent!
|
2010-11-27 04:21:39 +01:00
|
|
|
friend bool
|
|
|
|
|
operator== (Resolver const& rr, Target const& tval)
|
|
|
|
|
{
|
2010-11-27 06:01:31 +01:00
|
|
|
return rr.resolve() == tval;
|
2010-11-27 04:21:39 +01:00
|
|
|
}
|
2010-11-25 05:35:50 +01:00
|
|
|
};
|
|
|
|
|
|
2010-11-27 06:01:31 +01:00
|
|
|
Resolver
|
|
|
|
|
operator[] (PId sourcePipeID)
|
2010-11-25 05:35:50 +01:00
|
|
|
{
|
2010-11-27 06:01:31 +01:00
|
|
|
if (!contains (table_, sourcePipeID))
|
|
|
|
|
{
|
|
|
|
|
UNIMPLEMENTED ("how to resolve");
|
|
|
|
|
}
|
|
|
|
|
return buildResolutionWrapper (sourcePipeID);
|
2010-11-25 05:35:50 +01:00
|
|
|
}
|
|
|
|
|
|
2010-11-27 06:01:31 +01:00
|
|
|
Resolver
|
2010-11-25 05:35:50 +01:00
|
|
|
operator[] (PPipe const& pipe)
|
|
|
|
|
{
|
|
|
|
|
REQUIRE (pipe);
|
|
|
|
|
return (*this) [pipe->getID()];
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-27 06:01:31 +01:00
|
|
|
Resolver
|
2010-11-25 05:35:50 +01:00
|
|
|
operator[] (Query<asset::Pipe> const& query4pipe)
|
|
|
|
|
{
|
|
|
|
|
UNIMPLEMENTED ("lookup by extended query");
|
2010-11-27 06:01:31 +01:00
|
|
|
HashVal hash4query;
|
|
|
|
|
HashVal resulting_targetPipeID;
|
|
|
|
|
table_[hash4query] = resulting_targetPipeID;
|
|
|
|
|
return buildResolutionWrapper (hash4query);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
Target
|
|
|
|
|
resolve (PId resultingPipeID)
|
|
|
|
|
{
|
|
|
|
|
return DEF::output(resultingPipeID);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Resolver
|
|
|
|
|
buildResolutionWrapper (HashVal tableSlot)
|
|
|
|
|
{
|
|
|
|
|
ASSERT (contains (table_, tableSlot));
|
|
|
|
|
return Resolver (*this, table_[tableSlot]);
|
2010-11-25 05:35:50 +01:00
|
|
|
}
|
2010-11-08 04:48:50 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-11-25 05:35:50 +01:00
|
|
|
|
2010-11-08 04:48:50 +01:00
|
|
|
} // namespace mobject
|
|
|
|
|
#endif
|