LUMIERA.clone/src/proc/mobject/session/query-resolver.hpp

190 lines
4.6 KiB
C++
Raw Normal View History

/*
QUERY-RESOLVER.hpp - interface for discovering contents of a scope
Copyright (C) Lumiera.org
2009, 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 MOBJECT_SESSION_QUERY_RESOLVER_H
#define MOBJECT_SESSION_QUERY_RESOLVER_H
//#include "proc/mobject/mobject.hpp"
//#include "proc/mobject/placement.hpp"
2009-10-24 00:23:22 +02:00
#include "lib/typed-counter.hpp"
#include "lib/iter-adapter.hpp"
2009-10-24 00:23:22 +02:00
#include "lib/util.hpp"
//#include <vector>
//#include <string>
//using std::vector;
//using std::string;
namespace mobject {
namespace session {
2009-10-24 00:23:22 +02:00
using util::unConst;
// class Scope;
class QueryResolver;
/**
* TODO type comment
2009-10-24 00:23:22 +02:00
* Query ABC
*/
2009-10-24 00:23:22 +02:00
class Goal
{
public:
2009-10-24 00:23:22 +02:00
virtual ~Goal() {}
2009-10-24 00:23:22 +02:00
enum Kind
{ GENERIC = 0
, DISCOVERY
};
2009-10-24 00:23:22 +02:00
struct QueryID
{
Kind kind;
size_t type;
};
2009-10-24 00:23:22 +02:00
QueryID getQID() { return id_; }
2009-10-24 00:23:22 +02:00
class Result
{
void *cur_;
protected:
template<typename RES>
RES& access()
{
REQUIRE (cur_);
return *reinterpret_cast<RES*> (cur_);
}
};
2009-10-24 00:23:22 +02:00
static bool hasNext (const Goal* thisQuery, Result& pos) { return unConst(thisQuery)->isValid(pos); } ////TICKET #375
static void iterNext (const Goal* thisQuery, Result& pos) { return unConst(thisQuery)->nextResult(pos);}
protected:
2009-10-24 00:23:22 +02:00
QueryID id_;
Goal (QueryID qid)
: id_(quid)
{ }
/* iteration control */
2009-10-24 00:23:22 +02:00
virtual bool isValid (Result& pos) =0; /////TODO danger of template bloat?
virtual Result const& nextResult(Result& pos) =0;
};
/** Context used for generating type-IDs to denote
* the specific result types of issued queries */
typedef lib::TypedContext<Goal::Result> ResultType;
/**
* TODO type comment
* Concrete query to yield specifically typed result elements
*/
template<class RES>
class Query
: public Goal
{
static QueryID
defineQueryTypeID ()
{
QueryID id = {Goal::GENERIC, ResultType::ID<RES>::get()};
return id;
}
public:
Query()
: Goal (defineQueryTypeID())
{ }
/* results retrieval */
class Cursor : public Goal::Result
{
public:
RES& operator* () { return access<RES>(); }
RES* operator->() { return & access<RES>(); }
};
typedef lib::IterAdapter<Cursor,Goal> iterator;
operator iterator() ;
iterator operator() (QueryResolver const& resolver);
};
/**
* TODO type comment
*/
class QueryResolver
{
public:
2009-10-24 00:23:22 +02:00
virtual ~QueryResolver() ;
/** issue a query to retrieve contents
2009-10-24 00:23:22 +02:00
* The query is handed over internally to a suitable resolver implementation.
* After returning, results can be obtained from the query by iteration.
* @throw lumiera::Error subclass if query evaluation flounders.
* This might be broken logic, invalid input, misconfiguration
* or failure of an external facility used for resolution.
* @note a query may yield no results, in which case the iterator is empty.
*/
2009-10-24 00:23:22 +02:00
void issue (Goal& query);
2009-10-24 00:23:22 +02:00
protected:
virtual bool canHandleQuery (Goal::QueryID qID) const =0;
};
///////////////////////////TODO currently just fleshing the API
2009-10-24 00:23:22 +02:00
template<typename RES>
inline typename Query<RES>::iterator
Query<RES>::operator() (QueryResolver const& resolver)
{
resolver.issue (*this);
return *this;
}
template<typename RES>
Query<RES>::operator iterator()
{
UNIMPLEMENTED ("how to get the result iterator");
}
}} // namespace mobject::session
#endif