LUMIERA.clone/src/common/query/query-resolver.hpp

169 lines
4.7 KiB
C++
Raw Normal View History

/*
QUERY-RESOLVER.hpp - framework for resolving generic queries
2010-12-17 23:28:49 +01:00
Copyright: clarify and simplify the file headers * Lumiera source code always was copyrighted by individual contributors * there is no entity "Lumiera.org" which holds any copyrights * Lumiera source code is provided under the GPL Version 2+ == Explanations == Lumiera as a whole is distributed under Copyleft, GNU General Public License Version 2 or above. For this to become legally effective, the ''File COPYING in the root directory is sufficient.'' The licensing header in each file is not strictly necessary, yet considered good practice; attaching a licence notice increases the likeliness that this information is retained in case someone extracts individual code files. However, it is not by the presence of some text, that legally binding licensing terms become effective; rather the fact matters that a given piece of code was provably copyrighted and published under a license. Even reformatting the code, renaming some variables or deleting parts of the code will not alter this legal situation, but rather creates a derivative work, which is likewise covered by the GPL! The most relevant information in the file header is the notice regarding the time of the first individual copyright claim. By virtue of this initial copyright, the first author is entitled to choose the terms of licensing. All further modifications are permitted and covered by the License. The specific wording or format of the copyright header is not legally relevant, as long as the intention to publish under the GPL remains clear. The extended wording was based on a recommendation by the FSF. It can be shortened, because the full terms of the license are provided alongside the distribution, in the file COPYING.
2024-11-17 23:42:55 +01:00
Copyright (C)
2009, Hermann Vosseler <Ichthyostega@web.de>
2010-12-17 23:28:49 +01:00
Copyright: clarify and simplify the file headers * Lumiera source code always was copyrighted by individual contributors * there is no entity "Lumiera.org" which holds any copyrights * Lumiera source code is provided under the GPL Version 2+ == Explanations == Lumiera as a whole is distributed under Copyleft, GNU General Public License Version 2 or above. For this to become legally effective, the ''File COPYING in the root directory is sufficient.'' The licensing header in each file is not strictly necessary, yet considered good practice; attaching a licence notice increases the likeliness that this information is retained in case someone extracts individual code files. However, it is not by the presence of some text, that legally binding licensing terms become effective; rather the fact matters that a given piece of code was provably copyrighted and published under a license. Even reformatting the code, renaming some variables or deleting parts of the code will not alter this legal situation, but rather creates a derivative work, which is likewise covered by the GPL! The most relevant information in the file header is the notice regarding the time of the first individual copyright claim. By virtue of this initial copyright, the first author is entitled to choose the terms of licensing. All further modifications are permitted and covered by the License. The specific wording or format of the copyright header is not legally relevant, as long as the intention to publish under the GPL remains clear. The extended wording was based on a recommendation by the FSF. It can be shortened, because the full terms of the license are provided alongside the distribution, in the file COPYING.
2024-11-17 23:42:55 +01:00
  **Lumiera** 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. See the file COPYING for further details.
2010-12-17 23:28:49 +01:00
*/
/** @file query-resolver.hpp
** framework and to resolve logical queries.
** This header defines a family of interfaces and classes
** to integrate resolution of logical, rules based queries into generic
** implementation code. The concrete facility actually to resolve such queries
** is abstracted away as QueryResolver. A prominent usage example is the session,
** which allows to query for elements "somewhere within the model"
**
*/
#ifndef LUMIERA_QUERY_RESOLVER_H
#define LUMIERA_QUERY_RESOLVER_H
#include "lib/iter-adapter.hpp"
#include "common/query.hpp"
#include "lib/nocopy.hpp"
#include <functional>
#include <memory>
#include <string>
using std::function;
namespace lumiera {
using std::unique_ptr;
using std::string;
2009-10-24 00:23:22 +02:00
class Resolution;
2009-10-24 00:23:22 +02:00
class QueryResolver;
class QueryDispatcher;
2009-10-24 00:23:22 +02:00
/** Allow to take and transfer ownership of a result set */
typedef std::shared_ptr<Resolution> PReso;
2025-06-07 23:59:57 +02:00
/**
* ABC representing the result set
* of an individual query resolution
*/
class Resolution
: util::NonCopyable
{
2009-10-29 21:59:02 +01:00
public:
typedef Goal::Result Result;
virtual ~Resolution();
/** IterAdapter attached here */
2009-10-29 21:59:02 +01:00
friend bool
checkPoint (PReso const&, Result const& pos)
{
return bool(pos);
}
2009-10-29 21:59:02 +01:00
friend void
iterNext (PReso& resultSet, Result& pos)
{
resultSet->nextResult(pos);
}
2009-10-29 21:59:02 +01:00
virtual Result prepareResolution() =0;
protected:
virtual void nextResult(Result& pos) =0;
};
/**
* Interface: a facility for resolving (some kind of) queries
* A concrete subclass has the ability to create Resolution instances
* in response to specific queries of some kind, [if applicable](\ref QueryResolver::canHandle).
* Every resolution mechanism is expected to enrol by calling #installResolutionCase.
* Such a registration is considered permanent; a factory function gets stored,
* assuming that the entity to implement this function remains available
* up to the end of Lumiera main(). The kind of query and a suitable
* resolver is determined by the QueryID, which includes a type-ID.
* Thus the implementation might downcast query and resultset.
*/
class QueryResolver
: util::NonCopyable
{
unique_ptr<QueryDispatcher> dispatcher_;
public:
2009-10-24 00:23:22 +02:00
virtual ~QueryResolver() ;
virtual operator string () const =0; ///< short characterisation of the actual facility
/** 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.
* @return concrete Resolution of the query (ResultSet), \em managed by smart-pointer.
2009-10-24 00:23:22 +02:00
* @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.
*/
PReso issue (Goal const& query) const;
bool canHandle (Goal const&) const;
protected: /* ===== API for concrete query resolvers ===== */
virtual bool canHandleQuery (Goal::QueryID const&) const =0;
using ResolutionMechanism = function<Resolution*(Goal const&)>;
void installResolutionCase (Goal::QueryID const&,
ResolutionMechanism);
2009-10-24 00:23:22 +02:00
QueryResolver();
};
2009-10-24 00:23:22 +02:00
template<typename RES>
inline typename Query<RES>::iterator
Query<RES>::resolveBy (QueryResolver const& resolver) const
{
PReso resultSet = resolver.issue (*this);
Result first = resultSet->prepareResolution();
Cursor& start = static_cast<Cursor&> (first); // note: type RES must be compatible!
return iterator (resultSet, start);
}
/** notational convenience shortcut,
* synonymous to Query<RES>::resolveBy() */
template<typename RES>
inline typename Query<RES>::iterator
Query<RES>::operator() (QueryResolver const& resolver) const
{
return resolveBy (resolver);
}
2009-10-24 00:23:22 +02:00
inline bool
2009-11-13 04:52:48 +01:00
QueryResolver::canHandle(Goal const& query) const
{
return canHandleQuery (query.getQID());
}
} // namespace lumiera
#endif